From 589e1936a81ae7223dcb842d93370de3bb0b394b Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Tue, 25 Feb 2020 19:42:47 -0800 Subject: [PATCH] dev/drupal#4 - Add Civi\Setup::getPendingAction() helper Overview -------- This exposes a new piece of information for downstream consumers of the `civicrm-setup` API. It doesn't change any behaviors or expectations - it merely tracks an extra piece of info. Before ------ The `Civi\Setup` interface does not give any reporting about what's going on. After ----- The `Civi\Setup` interface has a method, `getPendingAction()`, which reports the pending action. Technical Details ----------------- (1) The pending action is strictly singular - it would not be sensible, for example, to have the `installFiles` and `uninstallFiles` actions running at the same time. Thus, the guards within each function. (2) The basic gist of the change - in each of the functions (`{install,uninstall}{Files,Database}`), set the `pendingAction` at the start and unset it at the end. The change looks slightly bigger than it should - because it wraps the existing code within the `try ... finally ...` block. (3) This facilitates dev/drupal#4 and https://github.com/civicrm/civicrm-drupal-8/pull/37 - there were some use-cases in which the auto-install behaviors of `civicrm_install()` and `FlushDrupal8.civi-setup.php` would provoke each other (causing a sort of installer-loop). This change makes it possible to avoid the loop without changing the contracts. --- setup/src/Setup.php | 70 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 62 insertions(+), 8 deletions(-) diff --git a/setup/src/Setup.php b/setup/src/Setup.php index 682b0b712f..fb225ddb25 100644 --- a/setup/src/Setup.php +++ b/setup/src/Setup.php @@ -41,6 +41,11 @@ class Setup { */ protected $log; + /** + * @var string|null + */ + protected $pendingAction = NULL; + // ----- Static initialization ----- /** @@ -189,8 +194,18 @@ class Setup { * @return \Civi\Setup\Event\InstallFilesEvent */ public function installFiles() { - $event = new InstallFilesEvent($this->getModel()); - return $this->getDispatcher()->dispatch('civi.setup.installFiles', $event); + if ($this->pendingAction !== NULL) { + throw new InitException(sprintf("Cannot begin action %s. Already executing %s.", __FUNCTION__, $this->pendingAction)); + } + $this->pendingAction = __FUNCTION__; + + try { + $event = new InstallFilesEvent($this->getModel()); + return $this->getDispatcher()->dispatch('civi.setup.installFiles', $event); + } + finally { + $this->pendingAction = NULL; + } } /** @@ -199,8 +214,18 @@ class Setup { * @return \Civi\Setup\Event\InstallDatabaseEvent */ public function installDatabase() { - $event = new InstallDatabaseEvent($this->getModel()); - return $this->getDispatcher()->dispatch('civi.setup.installDatabase', $event); + if ($this->pendingAction !== NULL) { + throw new InitException(sprintf("Cannot begin action %s. Already executing %s.", __FUNCTION__, $this->pendingAction)); + } + $this->pendingAction = __FUNCTION__; + + try { + $event = new InstallDatabaseEvent($this->getModel()); + return $this->getDispatcher()->dispatch('civi.setup.installDatabase', $event); + } + finally { + $this->pendingAction = NULL; + } } /** @@ -209,8 +234,18 @@ class Setup { * @return \Civi\Setup\Event\UninstallFilesEvent */ public function uninstallFiles() { - $event = new UninstallFilesEvent($this->getModel()); - return $this->getDispatcher()->dispatch('civi.setup.uninstallFiles', $event); + if ($this->pendingAction !== NULL) { + throw new InitException(sprintf("Cannot begin action %s. Already executing %s.", __FUNCTION__, $this->pendingAction)); + } + $this->pendingAction = __FUNCTION__; + + try { + $event = new UninstallFilesEvent($this->getModel()); + return $this->getDispatcher()->dispatch('civi.setup.uninstallFiles', $event); + } + finally { + $this->pendingAction = NULL; + } } /** @@ -219,8 +254,18 @@ class Setup { * @return \Civi\Setup\Event\UninstallDatabaseEvent */ public function uninstallDatabase() { - $event = new UninstallDatabaseEvent($this->getModel()); - return $this->getDispatcher()->dispatch('civi.setup.uninstallDatabase', $event); + if ($this->pendingAction !== NULL) { + throw new InitException(sprintf("Cannot begin action %s. Already executing %s.", __FUNCTION__, $this->pendingAction)); + } + $this->pendingAction = __FUNCTION__; + + try { + $event = new UninstallDatabaseEvent($this->getModel()); + return $this->getDispatcher()->dispatch('civi.setup.uninstallDatabase', $event); + } + finally { + $this->pendingAction = NULL; + } } /** @@ -256,4 +301,13 @@ class Setup { return $this->log; } + /** + * @return NULL|string + * The name of a pending installation action, or NULL if none are active. + * Ex: 'installDatabase', 'uninstallFiles' + */ + public function getPendingAction() { + return $this->pendingAction; + } + } -- 2.25.1