From 0085db838e229409372d5c996f9cc129a3fd0ece Mon Sep 17 00:00:00 2001 From: CiviCRM Date: Mon, 4 Jan 2016 19:21:15 -0800 Subject: [PATCH] CRM-16860 - SystemInstallEvent - Fire event on first page run Example: This is a pre-requisite for tracking merge-friendly upgrade tracking; during the initial installation, we need to flag any pre-existing upgrades to avoid subsequent execution. --- CRM/Core/Config.php | 63 +++++++++++++++++++ .../Incremental/sql/4.7.beta6.mysql.tpl | 3 + Civi/Core/Container.php | 2 + Civi/Core/Event/SystemInstallEvent.php | 41 ++++++++++++ Civi/Core/InstallationCanary.php | 59 +++++++++++++++++ 5 files changed, 168 insertions(+) create mode 100644 Civi/Core/Event/SystemInstallEvent.php create mode 100644 Civi/Core/InstallationCanary.php diff --git a/CRM/Core/Config.php b/CRM/Core/Config.php index 4bae70288f..79757178ea 100644 --- a/CRM/Core/Config.php +++ b/CRM/Core/Config.php @@ -122,6 +122,8 @@ class CRM_Core_Config extends CRM_Core_Config_MagicMerge { self::$_singleton->getSettings(); Civi::service('settings_manager')->useDefaults(); + + self::$_singleton->handleFirstRun(); } } return self::$_singleton; @@ -470,4 +472,65 @@ class CRM_Core_Config extends CRM_Core_Config_MagicMerge { self::$_singleton = NULL; } + /** + * Conditionally fire an event during the first page run. + * + * The install system is currently implemented several times, so it's hard to add + * new installation logic. We use a poor-man's method to detect the first run. + * + * Situations to test: + * - New installation + * - Upgrade from an old version (predating first-run tracker) + * - Upgrade from an old version (with first-run tracking) + */ + public function handleFirstRun() { + // Ordinarily, we prefetch settings en masse and find that the system is already installed. + // No extra SQL queries required. + if (Civi::settings()->get('installed')) { + return; + } + + // Q: How should this behave during testing? + if (defined('CIVICRM_TEST')) { + return; + } + + // If schema hasn't been loaded yet, then do nothing. Don't want to interfere + // with the existing installers. NOTE: If we change the installer pageflow, + // then we may want to modify this behavior. + if (!CRM_Core_DAO::checkTableExists('civicrm_domain')) { + return; + } + + // If we're handling an upgrade, then the system has already been used, so this + // is not the first run. + if (CRM_Core_Config::isUpgradeMode()) { + return; + } + $dao = CRM_Core_DAO::executeQuery('SELECT version FROM civicrm_domain'); + while ($dao->fetch()) { + if ($dao->version && version_compare($dao->version, CRM_Utils_System::version(), '<')) { + return; + } + } + + // The installation flag is stored in civicrm_setting, which is domain-aware. The + // flag could have been stored under a different domain. + $dao = CRM_Core_DAO::executeQuery(' + SELECT domain_id, value FROM civicrm_setting + WHERE is_domain = 1 AND name = "installed" + '); + while ($dao->fetch()) { + $value = unserialize($dao->value); + if (!empty($value)) { + Civi::settings()->set('installed', 1); + return; + } + } + + // OK, this looks new. + Civi::service('dispatcher')->dispatch(\Civi\Core\Event\SystemInstallEvent::EVENT_NAME, new \Civi\Core\Event\SystemInstallEvent()); + Civi::settings()->set('installed', 1); + } + } diff --git a/CRM/Upgrade/Incremental/sql/4.7.beta6.mysql.tpl b/CRM/Upgrade/Incremental/sql/4.7.beta6.mysql.tpl index 23d481cf68..8a2455de92 100644 --- a/CRM/Upgrade/Incremental/sql/4.7.beta6.mysql.tpl +++ b/CRM/Upgrade/Incremental/sql/4.7.beta6.mysql.tpl @@ -17,3 +17,6 @@ WHERE is_multiple_registrations = 1; -- CRM-17752 ALTER TABLE `civicrm_financial_trxn` ADD INDEX `UI_ftrxn_trxn_id` (`trxn_id`); + +SELECT @domainID := min(id) FROM civicrm_domain; +INSERT INTO civicrm_setting(name, value, domain_id, is_domain) values ('installed', 'i:1;', @domainID, 1); \ No newline at end of file diff --git a/Civi/Core/Container.php b/Civi/Core/Container.php index cc34390e59..fdcf1b1559 100644 --- a/Civi/Core/Container.php +++ b/Civi/Core/Container.php @@ -1,6 +1,7 @@ addListener(SystemInstallEvent::EVENT_NAME, array('\Civi\Core\InstallationCanary', 'check')); $dispatcher->addListener('hook_civicrm_post::Activity', array('\Civi\CCase\Events', 'fireCaseChange')); $dispatcher->addListener('hook_civicrm_post::Case', array('\Civi\CCase\Events', 'fireCaseChange')); $dispatcher->addListener('hook_civicrm_caseChange', array('\Civi\CCase\Events', 'delegateToXmlListeners')); diff --git a/Civi/Core/Event/SystemInstallEvent.php b/Civi/Core/Event/SystemInstallEvent.php new file mode 100644 index 0000000000..614b8e9a07 --- /dev/null +++ b/Civi/Core/Event/SystemInstallEvent.php @@ -0,0 +1,41 @@ +info('Creating canary table'); + \CRM_Core_DAO::executeQuery('CREATE TABLE civicrm_install_canary (id int(10) unsigned NOT NULL)'); + } + +} -- 2.25.1