CRM-13672 - Add alerts for security releases
authorColeman Watts <coleman@civicrm.org>
Sat, 20 Dec 2014 02:54:28 +0000 (21:54 -0500)
committerColeman Watts <coleman@civicrm.org>
Tue, 30 Dec 2014 01:42:08 +0000 (20:42 -0500)
Support the new json output from latest.civicrm.org and display security alerts.
Also adds finer-grained control over how version alerts are displayed.

CRM/Admin/Form/Setting.php
CRM/Admin/Form/Setting/Miscellaneous.php
CRM/Core/Config/Variables.php
CRM/Core/Invoke.php
CRM/Utils/VersionCheck.php
settings/Core.setting.php
templates/CRM/Admin/Form/Setting/Miscellaneous.tpl
templates/CRM/common/footer.tpl

index ad9056d2bf812b0580d7bfe1ca0fb12779a8322f..bca622fbbe690b5ad518e43d92b925740901bb99 100644 (file)
@@ -139,20 +139,22 @@ class CRM_Admin_Form_Setting extends CRM_Core_Form {
 
     foreach ($this->_settings as $setting => $group){
       $settingMetaData = civicrm_api('setting', 'getfields', array('version' => 3, 'name' => $setting));
-      if(isset($settingMetaData['values'][$setting]['quick_form_type'])){
-        $add = 'add' . $settingMetaData['values'][$setting]['quick_form_type'];
+      $props = $settingMetaData['values'][$setting];
+      if(isset($props['quick_form_type'])){
+        $add = 'add' . $props['quick_form_type'];
         if($add == 'addElement'){
           $this->$add(
-            $settingMetaData['values'][$setting]['html_type'],
+            $props['html_type'],
             $setting,
-            ts($settingMetaData['values'][$setting]['title']),
-            CRM_Utils_Array::value('html_attributes', $settingMetaData['values'][$setting], array())
+            ts($props['title']),
+            CRM_Utils_Array::value($props['html_type'] == 'select' ? 'option_values' : 'html_attributes', $props, array()),
+            $props['html_type'] == 'select' ? CRM_Utils_Array::value('html_attributes', $props) : NULL
           );
         }
         else{
-          $this->$add($setting, ts($settingMetaData['values'][$setting]['title']));
+          $this->$add($setting, ts($props['title']));
         }
-        $this->assign("{$setting}_description", ts($settingMetaData['values'][$setting]['description']));
+        $this->assign("{$setting}_description", ts($props['description']));
         if($setting == 'max_attachments'){
           //temp hack @todo fix to get from metadata
           $this->addRule('max_attachments', ts('Value should be a positive number'), 'positiveInteger');
index bf8513508b304d5c406a49a5359a02039ed14531..f5b03e0d74b2c3c44799e5da6cc72353b6c7aced 100644 (file)
@@ -43,6 +43,7 @@ class CRM_Admin_Form_Setting_Miscellaneous extends CRM_Admin_Form_Setting {
     'max_attachments' => CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME,
     'contact_undelete' => CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME,
     'versionAlert' => CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME,
+    'securityUpdateAlert' => CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME,
     'versionCheck' => CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME,
     'empoweredBy' => CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME,
     'maxFileSize' => CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME,
index f05464dd7e53a1895a7a345d921faa0a577b25aa..de6cc2c2b1062d81bb3b8f51a6c30d03b02ebc28 100644 (file)
@@ -324,13 +324,6 @@ class CRM_Core_Config_Variables extends CRM_Core_Config_Defaults {
    */
   public $logging = FALSE;
 
-  /**
-   * Whether CiviCRM should check for newer versions
-   *
-   * @var boolean
-   */
-  public $versionCheck = TRUE;
-
   /**
    * Whether public pages should display "empowered by CiviCRM"
    *
index d7c3b39a3e63ffd8ff209fabe4731cd2f77bd5e3..497d552639f8c1b6687e5ba7a4269e5d448c7697 100644 (file)
@@ -367,15 +367,21 @@ class CRM_Core_Invoke {
   /**
    * Show the message about CiviCRM versions
    *
-   * @param obj: $template (reference)
+   * @param CRM_Core_Smarty $template
    */
   static function versionCheck($template) {
     if (CRM_Core_Config::isUpgradeMode()) {
       return;
     }
-    $versionCheck = CRM_Utils_VersionCheck::singleton();
-    $newerVersion = $versionCheck->newerVersion();
+    $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);
   }
 
   /**
index 15a9572f970bfeecd648dfd15dbaa257fb2cecf4..973246a82379c0ac14916f09c0d92c2b1b5021c7 100644 (file)
  */
 class CRM_Utils_VersionCheck {
   CONST
-    LATEST_VERSION_AT = 'http://latest.civicrm.org/stable.php',
+    PINGBACK_URL = 'http://latest.civicrm.org/stable.php?format=json',
     // timeout for when the connection or the server is slow
     CHECK_TIMEOUT = 5,
     // relative to $civicrm_root
     LOCALFILE_NAME = 'civicrm-version.php',
     // relative to $config->uploadDir
-    CACHEFILE_NAME = 'latest-version-cache.txt',
+    CACHEFILE_NAME = 'version-info-cache.json',
     // cachefile expiry time (in seconds) - one day
     CACHEFILE_EXPIRE = 86400;
 
@@ -61,18 +61,32 @@ 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;
+
+  /**
+   * Info about available versions
+   *
+   * @var array
+   */
+  public $versionInfo = array();
 
   /**
    * Pingback params
    *
-   * @var string
+   * @var array
    */
   protected $stats = array();
+  
+  /**
+   * Path to cache file
+   *
+   * @var string
+   */
+  protected $cacheFile;
 
   /**
    * Class constructor
@@ -83,63 +97,46 @@ class CRM_Utils_VersionCheck {
     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);
+    }
+    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();
+      }
+    }
+    // Make sure version info is in ascending order for easier comparisons
+    ksort($this->versionInfo, SORT_NUMERIC);
+  }
 
-        // 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<br />" . ts('Please check your system file permissions.'),
-                ts('File Error'), 'error');
-            }
-            return;
-          }
-          fwrite($fp, $this->latestVersion);
-          fclose($fp);
+  /**
+   * Magic property accessor
+   * @param $variable
+   * @return mixed
+   */
+  function __get($variable) {
+    switch ($variable) {
+      case "localVersionStatus":
+        if ($this->localVersion && $this->versionInfo) {
+          $versionInfo = CRM_Utils_Array::value($this->localMajorVersion, $this->versionInfo);
+          return CRM_Utils_Array::value('status', $versionInfo);
         }
-      }
+        return NULL;
     }
+    return NULL;
   }
 
   /**
@@ -157,20 +154,75 @@ class 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";
+  }
+
+  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) {
+          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
    */
-  public function newerVersion() {
-    if ($this->latestVersion) {
-      if ((version_compare($this->localVersion, $this->latestVersion) < 0)
-        && CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME, 'versionAlert', NULL, TRUE)) {
-        return $this->latestVersion;
+  public function isNewerVersionAvailable() {
+    $newerVersion = NULL;
+    if ($this->versionInfo && $this->localVersion) {
+      // If using an alpha or beta, find the absolute latest available
+      $latest = end($this->versionInfo);
+      // Otherwise find the latest stable version available
+      if ($this->localVersionStatus != 'testing') {
+        foreach ($this->versionInfo as $majorVersion) {
+          if ($majorVersion['status'] == 'stable') {
+            $latest = $majorVersion;
+          }
+        }
+      }
+      if ($latest && !empty($latest['releases'])) {
+        foreach ($latest['releases'] as $release) {
+          if (version_compare($this->localVersion, $release['version']) < 0) {
+            $newerVersion = $release['version'];
+          }
+        }
       }
     }
-    return NULL;
+    return $newerVersion;
   }
 
   /**
@@ -178,21 +230,64 @@ 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);
+    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))
-        . '<br />' . ts('<a href="%1">Download Now</a>', array(1 => 'http://civicrm.org/download'));
-        $session->setStatus($msg, ts('Update Available'));
+        $msg = ts('This version of CiviCRM requires a security update.') .
+          '<ul>
+            <li><a href="https://civicrm.org/advisory">' . ts('Read advisory') . '</a></li>
+            <li><a href="https://civicrm.org/download">' . ts('Download now') . '</a></li>
+          </ul>';
+        $session->setStatus($msg, ts('Security Alert'));
       }
     }
+    elseif (CRM_Core_Permission::check('administer CiviCRM') && $versionAlertSetting > 1) {
+      $newerVersion = $this->isNewerVersionAvailable();
+      if ($newerVersion) {
+        $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 => $newerVersion))
+          . '<br /><a href="https://civicrm.org/download">' . ts('Download now') . '</a>';
+          $session->setStatus($msg, ts('Update Available'), 'info');
+        }
+      }
+    }
+  }
+
+  /**
+   * Collect info about the site to be sent as pingback data
+   */
+  private function getSiteStats() {
+    $config = CRM_Core_Config::singleton();
+    $siteKey = md5(defined('CIVICRM_SITE_KEY') ? CIVICRM_SITE_KEY : '');
+
+    // Calorie-free pingback for alphas
+    $this->stats = array('version' => $this->localVersion);
+
+    // Non-alpha versions get the full treatment
+    if ($this->localVersion && !strpos($this->localVersion, 'alpha')) {
+      $this->stats += array(
+        'hash' => md5($siteKey . $config->userFrameworkBaseURL),
+        '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*'),
+      );
+      $this->getPayProcStats();
+      $this->getEntityStats();
+      $this->getExtensionStats();
+    }
   }
 
   /**
    * Get active payment processor types
    */
-  private function payProcStats() {
+  private function getPayProcStats() {
     $dao = new CRM_Financial_DAO_PaymentProcessor;
     $dao->is_active = 1;
     $dao->find();
@@ -206,14 +301,13 @@ class CRM_Utils_VersionCheck {
     }
     // add the .-separated list of the processor types
     $this->stats['PPTypes'] = implode(',', array_unique($ppTypes));
-
   }
 
   /**
    * Fetch counts from entity tables
    * Add info to the 'entities' array
    */
-  private function entityStats() {
+  private function getEntityStats() {
     $tables = array(
       'CRM_Activity_DAO_Activity' => 'is_test = 0',
       'CRM_Case_DAO_Case' => 'is_deleted = 0',
@@ -254,7 +348,7 @@ class CRM_Utils_VersionCheck {
    * Fetch stats about enabled components/extensions
    * Add info to the 'extensions' array
    */
-  private function extensionStats() {
+  private function getExtensionStats() {
     // Core components
     $config = CRM_Core_Config::singleton();
     foreach ($config->enableComponents as $comp) {
@@ -281,6 +375,7 @@ class CRM_Utils_VersionCheck {
   /**
    * Send the request to civicrm.org
    * Set timeout and suppress errors
+   * Store results in the cache file
    */
   private function pingBack() {
     ini_set('default_socket_timeout', self::CHECK_TIMEOUT);
@@ -292,14 +387,48 @@ class CRM_Utils_VersionCheck {
       ),
     );
     $ctx = stream_context_create($params);
-    $this->latestVersion = @file_get_contents(self::LATEST_VERSION_AT, FALSE, $ctx);
-    if (!preg_match('/^\d+\.\d+\.\d+$/', $this->latestVersion)) {
-      $this->latestVersion = NULL;
-    }
-    else {
-      $this->latestVersion = trim($this->latestVersion);
+    $rawJson = @file_get_contents(self::PINGBACK_URL, FALSE, $ctx);
+    $versionInfo = $rawJson ? json_decode($rawJson, TRUE) : NULL;
+    // 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->writeCacheFile($rawJson);
+      $this->versionInfo = $versionInfo;
     }
     ini_restore('default_socket_timeout');
   }
 
+  /**
+   * @return bool
+   */
+  private function readCacheFile() {
+    $expiryTime = time() - self::CACHEFILE_EXPIRE;
+
+    // if there's a cachefile and it's not stale, use it
+    if (file_exists($this->cacheFile) && (filemtime($this->cacheFile) > $expiryTime)) {
+      $this->versionInfo = (array) json_decode(file_get_contents($this->cacheFile), TRUE);
+      return TRUE;
+    }
+    return FALSE;
+  }
+
+  /**
+   * Save version info to file
+   * @param string $contents
+   */
+  private function writeCacheFile($contents) {
+    $fp = @fopen($this->cacheFile, 'w');
+    if (!$fp) {
+      if (CRM_Core_Permission::check('administer CiviCRM')) {
+        CRM_Core_Session::setStatus(
+          ts('Unable to write file') . ": $this->cacheFile<br />" . ts('Please check your system file permissions.'),
+          ts('File Error'), 'error');
+      }
+      return;
+    }
+    fwrite($fp, $contents);
+    fclose($fp);
+  }
+
 }
index 449c8d1ba549eb1e51489dbe35b2f58a30893d79..ffd41021b338b6e0cca80a3e1e713ba9384f4c6f 100644 (file)
@@ -355,43 +355,67 @@ return array (
     'group_name' => 'CiviCRM Preferences',
     'group' => 'core',
     'name' => 'versionAlert',
-    'type' => 'Boolean',
-    'quick_form_type' => 'YesNo',
+    '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' => 1,
     'add' => '4.3',
     'title' => 'New Version Alerts',
     'is_domain' => 1,
     'is_contact' => 0,
-    'description' => 'Displays an on-screen alert to users with "Administer CiviCRM" permissions when a new version of CiviCRM is available. This setting will only work if the "Version Check & Statistics Reporting" setting is enabled.',
+    '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',
     'name' => 'versionCheck',
-    'prefetch' => 1,  // prefetch causes it to be cached in config settings. Usually this is a transitional setting. Some things like urls are permanent. Remove this comment if you have assessed & it should be permanent
-    'config_only'=> 1, //@todo - see https://wiki.civicrm.org/confluence/display/CRMDOC/Settings+Reference#SettingsReference-Convertingaconfigobjecttoasetting on removing this deprecated value
     'type' => 'Boolean',
     'quick_form_type' => 'YesNo',
     'default' => 1,
     'add' => '4.3',
-    'title' => 'Version Check & Statistics Reporting',
+    'title' => 'Automatically Check for Updates',
     'is_domain' => 1,
     'is_contact' => 0,
-    'description' => "If enabled, CiviCRM automatically checks availablity of a newer version of the software. New version alerts will be displayed on the main CiviCRM Administration page.
-When enabled, statistics about your CiviCRM installation are reported anonymously to the CiviCRM team to assist in prioritizing ongoing development efforts. The following information is gathered: CiviCRM version, versions of PHP, MySQL and framework (Drupal/Joomla/standalone), and default language. Counts (but no actual data) of the following record types are reported: contacts, activities, cases, relationships, contributions, contribution pages, contribution products, contribution widgets, discounts, price sets, profiles, events, participants, tell-a-friend pages, grants, mailings, memberships, membership blocks, pledges, pledge blocks and active payment processor types.",
+    'description' => "",
     'help_text' => null,
   ),
   'securityAlert' => array(
     'group_name' => 'CiviCRM Preferences',
     'group' => 'core',
-    'name' => 'versionCheck',
-    'prefetch' => 0,
+    'name' => 'securityAlert',
     'type' => 'Boolean',
     'quick_form_type' => 'YesNo',
     'default' => 1,
     'add' => '4.4',
-    'title' => 'Security Alerts',
+    'title' => 'Security Audits',
     'is_domain' => 1,
     'is_contact' => 0,
     'description' => "If enabled, CiviCRM will automatically run checks for significant mis-configurations such as ineffective file protections.",
index 7b9f82177c766c1ec8f20afcadaced2b66422980..7b3f84a9db44d4e2e2e8b2961b42b8f6fa54d05e 100644 (file)
                 <p class="description">{ts 1="http://wkhtmltopdf.org/"}<a href="%1">wkhtmltopdf is an alternative utility for generating PDF's</a> which may provide better performance especially if you are generating a large number of PDF letters or receipts. Your system administrator will need to download and install this utility, and enter the executable path here.{/ts}</p>
             </td>
         </tr>
-        <tr class="crm-miscellaneous-form-block-versionAlert">
-            <td class="label">{$form.versionAlert.label}</td>
-            <td>{$form.versionAlert.html}<br />
-                <p class="description">{ts}Displays an on-screen alert to users with "Administer CiviCRM" permissions when a new version of CiviCRM is available. This setting will only work if the "Version Check &amp; Statistics Reporting" setting is enabled.{/ts}</p></td>
-        </tr>
         <tr class="crm-miscellaneous-form-block-versionCheck">
             <td class="label">{$form.versionCheck.label}</td>
             <td>{$form.versionCheck.html}<br />
                 <p class="description">{ts}When enabled, statistics about your CiviCRM installation are reported anonymously to the CiviCRM team to assist in prioritizing ongoing development efforts. The following information is gathered: CiviCRM version, versions of PHP, MySQL and framework (Drupal/Joomla/standalone), and default language. Counts (but no actual data) of the following record types are reported: contacts, activities, cases, relationships, contributions, contribution pages, contribution products, contribution widgets, discounts, price sets, profiles, events, participants, tell-a-friend pages, grants, mailings, memberships, membership blocks, pledges, pledge blocks and active payment processor types.{/ts}</p></td>
         </tr>
+        <tr class="crm-miscellaneous-form-block-securityUpdateAlert">
+          <td class="label">{$form.securityUpdateAlert.label}</td>
+          <td>{$form.securityUpdateAlert.html}<br />
+            <p class="description">{ts}Alert site admins about security advisories. <strong>Strongly recommended.</strong>{/ts}</p></td>
+        </tr>
+        <tr class="crm-miscellaneous-form-block-versionAlert">
+          <td class="label">{$form.versionAlert.label}</td>
+          <td>{$form.versionAlert.html}<br />
+            <p class="description">{ts}Alert site admins about all new CiviCRM releases.{/ts}</p></td>
+        </tr>
         <tr class="crm-miscellaneous-form-block-empoweredBy">
             <td class="label">{$form.empoweredBy.label}</td>
             <td>{$form.empoweredBy.html}<br />
         </table>
            <div class="crm-submit-buttons">{include file="CRM/common/formButtons.tpl" location="bottom"}</div>
 </div>
+{literal}
+<script type="text/javascript">
+  CRM.$(function($) {
+    'use strict';
+    $('input[name=versionCheck][value=0]').change(function() {
+      if ($(this).is(':checked')) {
+        CRM.confirm({message: {/literal}"{ts escape='js'}Disabling this option will prevent CiviCRM from checking for important security updates. Are you sure?{/ts}"{literal}})
+          .on('crmConfirm:no', function() {
+            $('input[name=versionCheck][value=0]').prop('checked', false);
+            $('input[name=versionCheck][value=1]').prop('checked', true);
+          })
+      }
+    });
+    $('select[name=securityUpdateAlert]').change(function() {
+      if ($(this).val() == '0') {
+        CRM.confirm({message: {/literal}"{ts escape='js'}Disabling this option will prevent CiviCRM from checking for important security updates. Are you sure?{/ts}"{literal}})
+          .on('crmConfirm:no', function() {
+            $('select[name=securityUpdateAlert]').val('3');
+          })
+      }
+    });
+  });
+</script>
+{/literal}
\ No newline at end of file
index c0715938951aa73de5c3b2c9107a7c6f2ed867a5..97273b1ab13796afee1632b0ea263c14c6910b30 100644 (file)
 <div class="crm-footer" id="civicrm-footer">
   {crmVersion assign=version}
   {ts 1=$version}Powered by CiviCRM %1.{/ts}
-  {if !empty($newer_civicrm_version)}
+  {if !empty($security_update)}
+    <span class="status crm-error">
+      <a href="https://civicrm.org/advisory">{ts}Security update required.{/ts}</a></span>
+  {elseif !empty($newer_civicrm_version)}
     <span class="status">{ts 1=$newer_civicrm_version}A newer version (%1){/ts}
-    <a href="http://civicrm.org/download">{ts}is available for download{/ts}</a>.</span>
+    <a href="https://civicrm.org/download">{ts}is available for download{/ts}</a>.</span>
   {/if}
   {ts 1='http://www.gnu.org/licenses/agpl-3.0.html'}CiviCRM is openly available under the <a href='%1'>GNU AGPL License</a>.{/ts}<br/>
-  <a href="http://civicrm.org/download">{ts}Download CiviCRM.{/ts}</a> &nbsp; &nbsp;
+  <a href="https://civicrm.org/download">{ts}Download CiviCRM.{/ts}</a> &nbsp; &nbsp;
   <a href="http://issues.civicrm.org/jira/browse/CRM?report=com.atlassian.jira.plugin.system.project:roadmap-panel">{ts}View issues and report bugs.{/ts}</a> &nbsp; &nbsp;
   {docURL page="" text="Online documentation."}
 </div>