X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=CRM%2FUtils%2FVersionCheck.php;h=f7f19905e84299e472cb60b0cbc97dc376560aa9;hb=ed5a0ff7196e306e1319bd3f5913fdb068974daa;hp=14121ae1cb8c707aa882dff89b10c3a7182a60fa;hpb=0ec03e9fabc23b802ac80cb68c44b5abaf7f8585;p=civicrm-core.git
diff --git a/CRM/Utils/VersionCheck.php b/CRM/Utils/VersionCheck.php
index 14121ae1cb..f7f19905e8 100644
--- a/CRM/Utils/VersionCheck.php
+++ b/CRM/Utils/VersionCheck.php
@@ -1,7 +1,7 @@
uploadDir
- CACHEFILE_NAME = 'latest-version-cache.txt',
+ CACHEFILE_NAME = 'version-info-cache.json',
// cachefile expiry time (in seconds) - one day
CACHEFILE_EXPIRE = 86400;
@@ -61,84 +61,72 @@ class CRM_Utils_VersionCheck {
public $localVersion = NULL;
/**
- * The latest version of CiviCRM
+ * The major version (branch name) of the local version
*
* @var string
*/
- public $latestVersion = NULL;
+ public $localMajorVersion;
/**
- * Pingback params
+ * User setting to skip updates prior to a certain date
*
* @var string
*/
+ public $ignoreDate;
+
+ /**
+ * Info about available versions
+ *
+ * @var array
+ */
+ public $versionInfo = array();
+
+ /**
+ * Pingback params
+ *
+ * @var array
+ */
protected $stats = array();
/**
- * Class constructor
+ * Path to cache file
*
- * @access private
+ * @var string
+ */
+ protected $cacheFile;
+
+ /**
+ * Class constructor
*/
- function __construct() {
+ public function __construct() {
global $civicrm_root;
$config = CRM_Core_Config::singleton();
- $localfile = $civicrm_root . DIRECTORY_SEPARATOR . self::LOCALFILE_NAME;
- $cachefile = $config->uploadDir . self::CACHEFILE_NAME;
+ $localFile = $civicrm_root . DIRECTORY_SEPARATOR . self::LOCALFILE_NAME;
+ $this->cacheFile = $config->uploadDir . self::CACHEFILE_NAME;
- if (file_exists($localfile)) {
- require_once ($localfile);
- if (function_exists('civicrmVersion')) {
- $info = civicrmVersion();
- $this->localVersion = trim($info['version']);
- }
+ if (file_exists($localFile)) {
+ require_once $localFile;
}
- if ($config->versionCheck) {
- $expiryTime = time() - self::CACHEFILE_EXPIRE;
-
- // if there's a cachefile and it's not stale use it to
- // read the latestVersion, else read it from the Internet
- if (file_exists($cachefile) && (filemtime($cachefile) > $expiryTime)) {
- $this->latestVersion = trim(file_get_contents($cachefile));
- }
- else {
- $siteKey = md5(defined('CIVICRM_SITE_KEY') ? CIVICRM_SITE_KEY : '');
-
- $this->stats = array(
- 'hash' => md5($siteKey . $config->userFrameworkBaseURL),
- 'version' => $this->localVersion,
- 'uf' => $config->userFramework,
- 'lang' => $config->lcMessages,
- 'co' => $config->defaultContactCountry,
- 'ufv' => $config->userFrameworkVersion,
- 'PHP' => phpversion(),
- 'MySQL' => CRM_CORE_DAO::singleValueQuery('SELECT VERSION()'),
- 'communityMessagesUrl' => CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME, 'communityMessagesUrl', NULL, '*default*'),
- );
-
- // Add usage stats
- $this->payProcStats();
- $this->entityStats();
- $this->extensionStats();
+ if (function_exists('civicrmVersion')) {
+ $info = civicrmVersion();
+ $this->localVersion = trim($info['version']);
+ $this->localMajorVersion = $this->getMajorVersion($this->localVersion);
+ }
+ // Populate $versionInfo
+ if (CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME, 'versionCheck', NULL, 1)) {
+ // Use cached data if available and not stale
+ if (!$this->readCacheFile()) {
+ // Collect stats for pingback
+ $this->getSiteStats();
// Get the latest version and send site info
$this->pingBack();
-
- // Update cache file
- if ($this->latestVersion) {
- $fp = @fopen($cachefile, 'w');
- if (!$fp) {
- if (CRM_Core_Permission::check('administer CiviCRM')) {
- CRM_Core_Session::setStatus(
- ts('Unable to write file') . ":$cachefile
" . ts('Please check your system file permissions.'),
- ts('File Error'), 'error');
- }
- return;
- }
- fwrite($fp, $this->latestVersion);
- fclose($fp);
- }
}
+ $this->ignoreDate = CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME, 'versionCheckIgnoreDate');
+
+ // Sort version info in ascending order for easier comparisons
+ ksort($this->versionInfo, SORT_NUMERIC);
}
}
@@ -150,26 +138,103 @@ class CRM_Utils_VersionCheck {
*
* @return CRM_Utils_VersionCheck
*/
- static function &singleton() {
+ public static function &singleton() {
if (!isset(self::$_singleton)) {
self::$_singleton = new CRM_Utils_VersionCheck();
}
return self::$_singleton;
}
+ /**
+ * Finds the release info for a minor version
+ * @param string $version
+ * @return array|null
+ */
+ public function getReleaseInfo($version) {
+ $majorVersion = $this->getMajorVersion($version);
+ if (isset($this->versionInfo[$majorVersion])) {
+ foreach ($this->versionInfo[$majorVersion]['releases'] as $info) {
+ if ($info['version'] == $version) {
+ return $info;
+ }
+ }
+ }
+ return NULL;
+ }
+
+ /**
+ * @param $minorVersion
+ * @return string
+ */
+ public function getMajorVersion($minorVersion) {
+ if (!$minorVersion) {
+ return NULL;
+ }
+ list($a, $b) = explode('.', $minorVersion);
+ 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 the newer version's number, or null if the versions are equal
+ * Returns version number of the latest release if it is greater than the local version
*/
- public function newerVersion() {
- if ($this->latestVersion) {
- if (version_compare($this->localVersion, $this->latestVersion) < 0) {
- return $this->latestVersion;
+ public function isNewerVersionAvailable() {
+ $newerVersion = 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;
+ }
+ }
}
}
- return NULL;
+ return $newerVersion;
+ }
+
+ /**
+ * @param $majorVersion
+ * @return null|string
+ */
+ private function checkBranchForNewVersion($majorVersion) {
+ $newerVersion = 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'];
+ }
+ }
+ }
+ }
+ return $newerVersion;
}
/**
@@ -177,21 +242,71 @@ class CRM_Utils_VersionCheck {
* Show the message once a day
*/
public function versionAlert() {
- if (CRM_Core_Permission::check('administer CiviCRM') && $this->newerVersion()
- && CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME, 'versionAlert', NULL, TRUE)) {
+ $versionAlertSetting = CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME, 'versionAlert', NULL, 1);
+ $securityAlertSetting = CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME, 'securityUpdateAlert', NULL, 3);
+ $settingsUrl = CRM_Utils_System::url('civicrm/admin/setting/misc', 'reset=1', FALSE, NULL, FALSE, FALSE, TRUE);
+ if (CRM_Core_Permission::check('administer CiviCRM') && $securityAlertSetting > 1 && $this->isSecurityUpdateAvailable()) {
$session = CRM_Core_Session::singleton();
if ($session->timer('version_alert', 24 * 60 * 60)) {
- $msg = ts('A newer version of CiviCRM is available: %1', array(1 => $this->latestVersion))
- . '
' . ts('Download Now', array(1 => 'http://civicrm.org/download'));
- $session->setStatus($msg, ts('Update Available'));
+ $msg = ts('This version of CiviCRM requires a security update.') .
+ '