From 06576a03bb691d7083d105db63ccbda9af24fc94 Mon Sep 17 00:00:00 2001 From: Andrew Hunt Date: Tue, 28 Apr 2015 20:12:37 -0400 Subject: [PATCH] CRM-13823 Rewrite version check ---------------------------------------- * CRM-13823: Admin Status Page https://issues.civicrm.org/jira/browse/CRM-13823 --- CRM/Core/BAO/StatusPreference.php | 2 +- CRM/Core/Invoke.php | 28 +++-- CRM/Utils/Check.php | 2 +- CRM/Utils/Check/Env.php | 71 ++++++++++--- CRM/Utils/VersionCheck.php | 106 ++++++++++++------- css/civicrm.css | 6 ++ settings/Core.setting.php | 36 +------ templates/CRM/common/footer.tpl | 10 +- tests/phpunit/CRM/Utils/versionCheckTest.php | 31 ++++-- 9 files changed, 180 insertions(+), 112 deletions(-) diff --git a/CRM/Core/BAO/StatusPreference.php b/CRM/Core/BAO/StatusPreference.php index 7765c28f85..907770ee59 100644 --- a/CRM/Core/BAO/StatusPreference.php +++ b/CRM/Core/BAO/StatusPreference.php @@ -46,7 +46,7 @@ class CRM_Core_BAO_StatusPreference extends CRM_Core_DAO_StatusPreference { * @return array */ public static function create($params) { - $statusPreference = new CRM_Core_DAO_StatusPreference(); + $statusPreference = new CRM_Core_BAO_StatusPreference(); // Default severity level to ignore is 0 (DEBUG). if (!$params['ignore_severity']) { diff --git a/CRM/Core/Invoke.php b/CRM/Core/Invoke.php index 7cc88fc74a..17076553e1 100644 --- a/CRM/Core/Invoke.php +++ b/CRM/Core/Invoke.php @@ -257,7 +257,7 @@ class CRM_Core_Invoke { } else { $template->assign('urlIsPublic', FALSE); - self::versionCheck($template); + self::statusCheck($template); } if (isset($item['return_url'])) { @@ -344,24 +344,20 @@ class CRM_Core_Invoke { } /** - * Show the message about CiviCRM versions. + * Show status in the footer * * @param CRM_Core_Smarty $template */ - public static function versionCheck($template) { - if (CRM_Core_Config::isUpgradeMode()) { - return; - } - $newerVersion = $securityUpdate = NULL; - if (CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME, 'versionAlert', NULL, 1) & 1) { - $newerVersion = CRM_Utils_VersionCheck::singleton()->isNewerVersionAvailable(); - } - if (CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME, 'securityUpdateAlert', NULL, 3) & 1) { - $securityUpdate = CRM_Utils_VersionCheck::singleton()->isSecurityUpdateAvailable(); - } - $template->assign('newer_civicrm_version', $newerVersion); - $template->assign('security_update', $securityUpdate); - } + public static function statusCheck($template) { + if (CRM_Core_Config::isUpgradeMode()) { + return; + } + $statusSeverity = 0; + $statusMessage = ts('System status OK'); + // TODO: get status from CRM_Utils_Check, if cached + $template->assign('footer_status_severity', $statusSeverity); + $template->assign('footer_status_message', $statusMessage); + } /** * @param bool $triggerRebuild diff --git a/CRM/Utils/Check.php b/CRM/Utils/Check.php index e65d1bf56a..47ab63200d 100644 --- a/CRM/Utils/Check.php +++ b/CRM/Utils/Check.php @@ -118,7 +118,7 @@ class CRM_Utils_Check { if ($aSeverity == $bSeverity) { return strcmp($a->getName(), $b->getName()); } - return (self::severityMap($aSeverity) > self::severityMap($bSeverity)); + return (self::severityMap($aSeverity) < self::severityMap($bSeverity)); } /** diff --git a/CRM/Utils/Check/Env.php b/CRM/Utils/Check/Env.php index 5203ccc633..205ced75c5 100644 --- a/CRM/Utils/Check/Env.php +++ b/CRM/Utils/Check/Env.php @@ -46,7 +46,8 @@ class CRM_Utils_Check_Env { $this->checkOutboundMail(), $this->checkDomainNameEmail(), $this->checkDefaultMailbox(), - $this->checkLastCron() + $this->checkLastCron(), + $this->checkVersion() ); return $messages; } @@ -223,7 +224,7 @@ class CRM_Utils_Check_Env { ts('Cron Not Running'), \Psr\Log\LogLevel::WARNING ); - $message->addHelp(ts('Learn more in the Administrator\'s Guide supplement', array(1 => 'http://book.civicrm.org/user/advanced-configuration/email-system-configuration/'))); + $message->addHelp(ts('Learn more in the Administrator\'s Guide supplement', array(1 => 'http://wiki.civicrm.org/confluence/display/CRMDOC/Managing+Scheduled+Jobs'))); $messages[] = $message; } else { @@ -233,7 +234,7 @@ class CRM_Utils_Check_Env { ts('Cron Not Running'), \Psr\Log\LogLevel::ERROR ); - $message->addHelp(ts('Learn more in the Administrator\'s Guide supplement', array(1 => 'http://book.civicrm.org/user/advanced-configuration/email-system-configuration/'))); + $message->addHelp(ts('Learn more in the Administrator\'s Guide supplement', array(1 => 'http://wiki.civicrm.org/confluence/display/CRMDOC/Managing+Scheduled+Jobs'))); $messages[] = $message; } @@ -248,19 +249,61 @@ class CRM_Utils_Check_Env { public function checkVersion() { $messages = array(); - // check turned off: - // return message with status of notice saying check is turned off - - // up-to-date - // return message with status of info saying it's okay + if (CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME, 'versionAlert', NULL, 1)) { + $vc = CRM_Utils_VersionCheck::singleton(); + $newerVersion = $vc->isNewerVersionAvailable(); + + if ($newerVersion['version']) { + $vInfo = array( + 1 => $newerVersion['version'], + 2 => $vc->localVersion, + ); + if ($newerVersion['status'] == 'lts') { + $vInfo[1] .= ' ' . ts('(long-term support)'); // LTS = long-term support version + } + + if ($newerVersion['upgrade'] == 'security') { + // For most new versions, just make them notice + $severity = \Psr\Log\LogLevel::CRITICAL; + $message = ts('New security release %1 is available. The site is currently running %2.', $vInfo); + } + elseif ($newerVersion['status'] == 'eol') { + // Warn about EOL + $severity = \Psr\Log\LogLevel::WARNING; + $message = ts('New version %1 is available. The site is currently running %2, which has reached its end of life.', $vInfo); + } + else { + // For most new versions, just make them notice + $severity = \Psr\Log\LogLevel::NOTICE; + $message = ts('New version %1 is available. The site is currently running %2.', $vInfo); + } + } + else { + $vNum = $vc->localVersion; + if ($newerVersion['status'] == 'lts') { + $vNum .= ' ' . ts('(long-term support)'); // LTS = long-term support version + } - // new non-security release - // warning + $severity = \Psr\Log\LogLevel::INFO; + $message = ts('Version %1 is up-to-date.', array(1 => $vNum)); + } - // new security release - // critical + $messages[] = new CRM_Utils_Check_Message( + 'checkVersion', + $message, + ts('Update Status'), + $severity + ); + } + else { + $messages[] = new CRM_Utils_Check_Message( + 'checkVersion', + ts('The check for new versions of CiviCRM has been disabled.'), + ts('Update Check Disabled'), + \Psr\Log\LogLevel::NOTICE + ); + } - // release is eol - // error + return $messages; } } diff --git a/CRM/Utils/VersionCheck.php b/CRM/Utils/VersionCheck.php index e41f9ffaf2..6b7e07960e 100644 --- a/CRM/Utils/VersionCheck.php +++ b/CRM/Utils/VersionCheck.php @@ -173,50 +173,78 @@ class CRM_Utils_VersionCheck { return "$a.$b"; } - /** - * @return bool - */ - public function isSecurityUpdateAvailable() { - $thisVersion = $this->getReleaseInfo($this->localVersion); - $localVersionDate = CRM_Utils_Array::value('date', $thisVersion, 0); - foreach ($this->versionInfo as $majorVersion) { - foreach ($majorVersion['releases'] as $release) { - if (!empty($release['security']) && $release['date'] > $localVersionDate - && version_compare($this->localVersion, $release['version']) < 0 - ) { - if (!$this->ignoreDate || $this->ignoreDate < $release['date']) { - return TRUE; - } - } - } - } - } /** * Get the latest version number if it's newer than the local one * - * @return string|null - * Returns version number of the latest release if it is greater than the local version + * @return array + * Returns version number of the latest release if it is greater than the local version, + * along with the type of upgrade (regular/security) needed and the status of the major + * version */ public function isNewerVersionAvailable() { - $newerVersion = NULL; + $return = array( + 'version' => NULL, + 'upgrade' => NULL, + 'status' => NULL, + ); + if ($this->versionInfo && $this->localVersion) { - foreach ($this->versionInfo as $majorVersionNumber => $majorVersion) { - $release = $this->checkBranchForNewVersion($majorVersion); - if ($release) { - // If we have a release with the same majorVersion as local, return it - if ($majorVersionNumber == $this->localMajorVersion) { - return $release; - } - // Search outside the local majorVersion (excluding non-stable) - elseif ($majorVersion['status'] != 'testing') { - // We found a new release but don't return yet, keep searching newer majorVersions - $newerVersion = $release; - } + if (isset($this->versionInfo[$this->localMajorVersion])) { + switch(CRM_Utils_Array::value('status', $this->versionInfo[$this->localMajorVersion])) { + case 'stable': + case 'lts': + case 'testing': + // look for latest version in this major version + $releases = $this->checkBranchForNewVersion($this->versionInfo[$this->localMajorVersion]); + if ($releases['newest']) { + $return['version'] = $releases['newest']; + + // check for intervening security releases + $return['upgrade'] = ($releases['security']) ? 'security' : 'regular'; + } + break; + + case 'eol': + default: + // look for latest version ever + foreach ($this->versionInfo as $majorVersionNumber => $majorVersion) { + if ($majorVersionNumber < $this->localMajorVersion || $majorVersion['status'] == 'testing') { + continue; + } + $releases = $this->checkBranchForNewVersion($this->versionInfo[$majorVersionNumber]); + + if ($releases['newest']) { + $return['version'] = $releases['newest']; + + // check for intervening security releases + $return['upgrade'] = ($releases['security'] || $return['upgrade'] == 'security') ? 'security' : 'regular'; + } + } + } + $return['status'] = $this->versionInfo[$this->localMajorVersion]['status']; + } + else { + // Figure if the version is really old or really new + $wayOld = TRUE; + + foreach ($this->versionInfo as $majorVersionNumber => $majorVersion) { + $wayOld = ($this->localMajorVersion < $majorVersionNumber); + } + + if ($wayOld) { + $releases = $this->checkBranchForNewVersion($majorVersion); + + $return = array( + 'version' => $releases['newest'], + 'upgrade' => 'security', + 'status' => 'eol', + ); } } } - return $newerVersion; + + return $return; } /** @@ -224,12 +252,18 @@ class CRM_Utils_VersionCheck { * @return null|string */ private function checkBranchForNewVersion($majorVersion) { - $newerVersion = NULL; + $newerVersion = array( + 'newest' => NULL, + 'security' => NULL, + ); if (!empty($majorVersion['releases'])) { foreach ($majorVersion['releases'] as $release) { if (version_compare($this->localVersion, $release['version']) < 0) { if (!$this->ignoreDate || $this->ignoreDate < $release['date']) { - $newerVersion = $release['version']; + $newerVersion['newest'] = $release['version']; + if (CRM_Utils_Array::value('security',$release)) { + $newerVersion['security'] = $release['version']; + } } } } diff --git a/css/civicrm.css b/css/civicrm.css index 6d059b5251..c9db0487d8 100644 --- a/css/civicrm.css +++ b/css/civicrm.css @@ -649,6 +649,12 @@ input.crm-form-entityref { padding: 4px; } +.crm-container .status.crm-ok { + border-color: #B0D730; + background-color: #F1F8EB; + color: #3E3E3E; +} + .crm-container .crm-footer { font-size: 0.8em; } diff --git a/settings/Core.setting.php b/settings/Core.setting.php index 2ab2010d06..9e44978be4 100644 --- a/settings/Core.setting.php +++ b/settings/Core.setting.php @@ -356,15 +356,8 @@ return array( 'group_name' => 'CiviCRM Preferences', 'group' => 'core', 'name' => 'versionAlert', - 'type' => 'Integer', - 'quick_form_type' => 'Element', - 'html_type' => 'select', - 'option_values' => array( - ts('Disabled'), - ts('Display In Page Footer'), - ts('Display As Popup Alert'), - ts('Page Footer + Popup Alert'), - ), + 'type' => 'Boolean', + 'quick_form_type' => 'YesNo', 'default' => 1, 'add' => '4.3', 'title' => 'New Version Alerts', @@ -373,27 +366,6 @@ return array( 'description' => "", 'help_text' => NULL, ), - 'securityUpdateAlert' => array( - 'group_name' => 'CiviCRM Preferences', - 'group' => 'core', - 'name' => 'securityUpdateAlert', - 'type' => 'Integer', - 'quick_form_type' => 'Element', - 'html_type' => 'select', - 'option_values' => array( - ts('Disabled'), - ts('Display In Page Footer'), - ts('Display As Popup Alert'), - ts('Page Footer + Popup Alert'), - ), - 'default' => 3, - 'add' => '4.6', - 'title' => 'Security Update Alerts', - 'is_domain' => 1, - 'is_contact' => 0, - 'description' => "", - 'help_text' => NULL, - ), 'versionCheck' => array( 'group_name' => 'CiviCRM Preferences', 'group' => 'core', @@ -432,10 +404,10 @@ return array( 'quick_form_type' => 'YesNo', 'default' => 1, 'add' => '4.4', - 'title' => 'Security Audits', + 'title' => 'Status Alerts', 'is_domain' => 1, 'is_contact' => 0, - 'description' => "If enabled, CiviCRM will automatically run checks for significant mis-configurations such as ineffective file protections.", + 'description' => "If enabled, CiviCRM will display pop-up notifications (no more than once per day) for security and misconfiguration issues identified in the system check.", 'help_text' => NULL, ), 'doNotAttachPDFReceipt' => array( diff --git a/templates/CRM/common/footer.tpl b/templates/CRM/common/footer.tpl index 229c9ef096..20a5cdd059 100644 --- a/templates/CRM/common/footer.tpl +++ b/templates/CRM/common/footer.tpl @@ -31,12 +31,10 @@