CRM-17637 - Add poor man's cron fallback for VersionCheck
authorColeman Watts <coleman@civicrm.org>
Thu, 10 Dec 2015 02:13:29 +0000 (21:13 -0500)
committerColeman Watts <coleman@civicrm.org>
Thu, 10 Dec 2015 02:13:29 +0000 (21:13 -0500)
CRM/Utils/Check/Env.php
CRM/Utils/VersionCheck.php
tests/phpunit/CRM/Utils/versionCheckTest.php

index 9e2d829882e55aba680ef2ebe42f99107638f069..89883fe6edfb13051324086ec0fc7f4ec53acfea 100644 (file)
@@ -289,6 +289,7 @@ class CRM_Utils_Check_Env {
   public function checkVersion() {
     $messages = array();
     $vc = new CRM_Utils_VersionCheck();
+    $vc->initialize();
 
     // Show a notice if the version_check job is disabled
     if (empty($vc->cronJob['is_active'])) {
index 443151420d3ce190eb0da178a5b6dcdeedc1ce37..fd6ee3ce2b2b1b12afc1bef7f7c07f82da96e785 100644 (file)
@@ -33,8 +33,9 @@
 class CRM_Utils_VersionCheck {
   const
     PINGBACK_URL = 'http://latest.civicrm.org/stable.php?format=json',
-    // relative to $config->uploadDir
-    CACHEFILE_NAME = '[civicrm.files]/persist/version-info-cache.json';
+    CACHEFILE_NAME = '[civicrm.files]/persist/version-info-cache.json',
+    // after this length of time we fall back on poor-man's cron (7+ days)
+    CACHEFILE_EXPIRE = 605000;
 
   /**
    * The version of the current (local) installation
@@ -87,12 +88,36 @@ class CRM_Utils_VersionCheck {
   public function __construct() {
     $this->localVersion = CRM_Utils_System::version();
     $this->localMajorVersion = $this->getMajorVersion($this->localVersion);
+    $this->cacheFile = Civi::paths()->getPath(self::CACHEFILE_NAME);
+  }
 
+  /**
+   * Self-populates version info
+   */
+  public function initialize() {
     $this->getJob();
 
     // Populate remote $versionInfo from cache file
-    $this->cacheFile = Civi::paths()->getPath(self::CACHEFILE_NAME);
     $this->isInfoAvailable = $this->readCacheFile();
+
+    // Poor-man's cron fallback if scheduled job is enabled but has failed to run
+    $expiryTime = time() - self::CACHEFILE_EXPIRE;
+    if (!empty($this->cronJob['is_active']) &&
+      (!$this->isInfoAvailable || filemtime($this->cacheFile) < $expiryTime)
+    ) {
+      $this->fetch();
+    }
+  }
+
+  /**
+   * Sets $versionInfo
+   *
+   * @param $info
+   */
+  public function setVersionInfo($info) {
+    $this->versionInfo = (array) $info;
+    // Sort version info in ascending order for easier comparisons
+    ksort($this->versionInfo, SORT_NUMERIC);
   }
 
   /**
@@ -362,9 +387,10 @@ class CRM_Utils_VersionCheck {
     // If we couldn't fetch or parse the data $versionInfo will be NULL
     // Otherwise it will be an array and we'll cache it.
     // Note the array may be empty e.g. in the case of a pre-alpha with no releases
-    if ($versionInfo !== NULL) {
+    $this->isInfoAvailable = $versionInfo !== NULL;
+    if ($this->isInfoAvailable) {
       $this->writeCacheFile($rawJson);
-      $this->versionInfo = $versionInfo;
+      $this->setVersionInfo($versionInfo);
     }
   }
 
@@ -373,9 +399,7 @@ class CRM_Utils_VersionCheck {
    */
   private function readCacheFile() {
     if (file_exists($this->cacheFile)) {
-      $this->versionInfo = (array) json_decode(file_get_contents($this->cacheFile), TRUE);
-      // Sort version info in ascending order for easier comparisons
-      ksort($this->versionInfo, SORT_NUMERIC);
+      $this->setVersionInfo(json_decode(file_get_contents($this->cacheFile), TRUE));
       return TRUE;
     }
     return FALSE;
index a85cd2e04f7d43148d151966d8db4c124f4d05d7..8222125803aa93183a50162945f26ceb73b7428f 100644 (file)
@@ -112,7 +112,7 @@ class CRM_Utils_versionCheckTest extends CiviUnitTestCase {
     // These values are set by the constructor but for testing we override them
     $vc->localVersion = $localVersion;
     $vc->localMajorVersion = $vc->getMajorVersion($localVersion);
-    $vc->versionInfo = $versionInfo;
+    $vc->setVersionInfo($versionInfo);
     $available = $vc->isNewerVersionAvailable();
     $this->assertEquals($available['version'], $expectedResult);
   }
@@ -158,7 +158,7 @@ class CRM_Utils_versionCheckTest extends CiviUnitTestCase {
     // These values are set by the constructor but for testing we override them
     $vc->localVersion = $localVersion;
     $vc->localMajorVersion = $vc->getMajorVersion($localVersion);
-    $vc->versionInfo = $versionInfo;
+    $vc->setVersionInfo($versionInfo);
     $available = $vc->isNewerVersionAvailable();
     $this->assertEquals($available['upgrade'], $expectedResult);
   }