CRM-13823 - Better extension error handling
authorColeman Watts <coleman@civicrm.org>
Wed, 21 Oct 2015 22:33:36 +0000 (18:33 -0400)
committerColeman Watts <coleman@civicrm.org>
Wed, 21 Oct 2015 22:33:36 +0000 (18:33 -0400)
CRM/Admin/Page/Extensions.php
CRM/Extension/Browser.php
CRM/Utils/Check/Env.php
CRM/Utils/HttpClient.php
CRM/Utils/System.php

index 2e3b29aaa41b5dadd823e03a6fb10b669b3e49f6..16adaedba253fa254e414c2200b21f669012aa34 100644 (file)
@@ -205,9 +205,17 @@ class CRM_Admin_Page_Extensions extends CRM_Core_Page_Basic {
     }
     $this->assign('localExtensionRows', $localExtensionRows);
 
+    try {
+      $remoteExtensions = CRM_Extension_System::singleton()->getBrowser()->getExtensions();
+    }
+    catch (CRM_Extension_Exception $e) {
+      $remoteExtensions = array();
+      CRM_Core_Session::setStatus($e->getMessage(), ts('Extension download error'), 'error');
+    }
+
     // build list of available downloads
     $remoteExtensionRows = array();
-    foreach (CRM_Extension_System::singleton()->getBrowser()->getExtensions() as $info) {
+    foreach ($remoteExtensions as $info) {
       $row = (array) $info;
       $row['id'] = $info->key;
       $action = CRM_Core_Action::UPDATE;
index 4e23ff2f6ff50ca4f336ee6286ca854f9b22b069..c8f335403037ebc164e874e3f0e9920be6b36cb7 100644 (file)
@@ -225,6 +225,7 @@ class CRM_Extension_Browser {
    * extensions.
    *
    * @return string
+   * @throws \CRM_Extension_Exception
    */
   private function grabRemoteJson() {
 
@@ -238,37 +239,24 @@ class CRM_Extension_Browser {
     if (FALSE === $this->getRepositoryUrl()) {
       // don't check if the user has configured civi not to check an external
       // url for extensions. See CRM-10575.
-      CRM_Core_Session::setStatus(ts('Not checking remote URL for extensions since ext_repo_url is set to false.'), ts('Check Settings'), 'alert');
       return array();
     }
 
     $filename = $this->cacheDir . DIRECTORY_SEPARATOR . self::CACHE_JSON_FILE;
     $url = $this->getRepositoryUrl() . $this->indexPath;
     $status = CRM_Utils_HttpClient::singleton()->fetch($url, $filename);
-    if ($status !== CRM_Utils_HttpClient::STATUS_OK) {
-      CRM_Core_Session::setStatus(ts('The CiviCRM public extensions directory at %1 could not be contacted - please check your webserver can make external HTTP requests or contact CiviCRM team on <a href="http://forum.civicrm.org/">CiviCRM forum</a>.<br />', array(1 => $this->getRepositoryUrl())), ts('Connection Error'), 'error');
-    }
-    else {
-      // Don't call grabCachedJson here, that would risk infinite recursion
-      $json = file_get_contents($filename);
-    }
-
-    // CRM-13141 There may not be any compatible extensions available for the requested CiviCRM version + CMS. If so, $extdir is empty so just return a notification.
-    if (empty($json)) {
-      $config = CRM_Core_Config::singleton();
-      CRM_Core_Session::setStatus(ts('There are currently no extensions on the CiviCRM public extension directory which are compatible with version %2 (<a href="%1">requested extensions from here</a>). If you want to install an extension which is not marked as compatible, you may be able to <a href="%3">download and install extensions manually</a> (depending on access to your web server).<br />', array(
-        1 => $this->getRepositoryUrl(),
-        2 => CRM_Utils_System::version(),
-        3 => 'http://wiki.civicrm.org/confluence/display/CRMDOC/Extensions',
-      )), ts('No Extensions Available for this Version'), 'info');
-    }
 
     ini_restore('allow_url_fopen');
     ini_restore('default_socket_timeout');
 
     restore_error_handler();
 
-    return $json;
+    if ($status !== CRM_Utils_HttpClient::STATUS_OK) {
+      throw new CRM_Extension_Exception(ts('The CiviCRM public extensions directory at %1 could not be contacted - please check your webserver can make external HTTP requests or contact CiviCRM team on <a href="http://forum.civicrm.org/">CiviCRM forum</a>.', array(1 => $this->getRepositoryUrl())), 'connection_error');
+    }
+
+    // Don't call grabCachedJson here, that would risk infinite recursion
+    return file_get_contents($filename);
   }
 
   /**
index 0f46b848c9062b24e1cefc694415270859e4f34d..27708274e3180abcd74e23c56a4987245c8302b1 100644 (file)
@@ -349,7 +349,6 @@ class CRM_Utils_Check_Env {
     $extensionSystem = CRM_Extension_System::singleton();
     $mapper = $extensionSystem->getMapper();
     $manager = $extensionSystem->getManager();
-    $remotes = $extensionSystem->getBrowser()->getExtensions();
 
     if ($extensionSystem->getDefaultContainer()) {
       $basedir = $extensionSystem->getDefaultContainer()->baseDir;
@@ -399,6 +398,43 @@ class CRM_Utils_Check_Env {
       return $messages;
     }
 
+    if (!$extensionSystem->getBrowser()->isEnabled()) {
+      $messages[] = new CRM_Utils_Check_Message(
+        'checkExtensions',
+        ts('Not checking remote URL for extensions since ext_repo_url is set to false.'),
+        ts('Extensions check disabled'),
+        \Psr\Log\LogLevel::NOTICE
+      );
+      return $messages;
+    }
+
+    try {
+      $remotes = $extensionSystem->getBrowser()->getExtensions();
+    }
+    catch (CRM_Extension_Exception $e) {
+      $messages[] = new CRM_Utils_Check_Message(
+        'checkExtensions',
+        $e->getMessage(),
+        ts('Extension download error'),
+        \Psr\Log\LogLevel::ERROR
+      );
+      return $messages;
+    }
+
+    if (!$remotes) {
+      // CRM-13141 There may not be any compatible extensions available for the requested CiviCRM version + CMS. If so, $extdir is empty so just return a notice.
+      $messages[] = new CRM_Utils_Check_Message(
+        'checkExtensions',
+        ts('There are currently no extensions on the CiviCRM public extension directory which are compatible with version %1. If you want to install an extension which is not marked as compatible, you may be able to <a %2>download and install extensions manually</a> (depending on access to your web server).', array(
+          1 => CRM_Utils_System::majorVersion(),
+          2 => 'href="http://wiki.civicrm.org/confluence/display/CRMDOC/Extensions"',
+        )),
+        ts('No Extensions Available for this Version'),
+        \Psr\Log\LogLevel::NOTICE
+      );
+      return $messages;
+    }
+
     $keys = array_keys($manager->getStatuses());
     sort($keys);
     $severity = 1;
@@ -449,10 +485,6 @@ class CRM_Utils_Check_Env {
     }
 
     // OK, return several data rows
-    // $returnValues = array(
-    //   array('status' => $return, 'message' => $msg),
-    // );
-
     $messages[] = new CRM_Utils_Check_Message(
       'checkExtensions',
       $msg,
index 92aed3c84245229ca9a89dd75d5f6ca20357b3eb..790fb37dd6e0d1a05af667d419a54fd8577ee4fa 100644 (file)
@@ -92,6 +92,7 @@ class CRM_Utils_HttpClient {
 
     $fp = @fopen($localFile, "w");
     if (!$fp) {
+      // Fixme: throw error instead of setting message
       CRM_Core_Session::setStatus(ts('Unable to write to %1.<br />Is the location writable?', array(1 => $localFile)), ts('Write Error'), 'error');
       return self::STATUS_WRITE_ERROR;
     }
@@ -99,8 +100,9 @@ class CRM_Utils_HttpClient {
 
     curl_exec($ch);
     if (curl_errno($ch)) {
+      // Fixme: throw error instead of setting message
       CRM_Core_Session::setStatus(ts('Unable to download extension from %1. Error Message: %2',
-        array(1 => $remoteFile, 2 => curl_error($ch))), ts('Download Error'), 'error');
+        array(1 => $remoteFile, 2 => curl_error($ch))), ts('Extension download error'), 'error');
       return self::STATUS_DL_ERROR;
     }
     else {
index 4501d0146158a19144deea7f36b214c2cb43b422..18d00fb6bc493f268ed4d6316059a5e6a99dcab3 100644 (file)
@@ -1073,6 +1073,16 @@ class CRM_Utils_System {
     return $version;
   }
 
+  /**
+   * Gives the first two parts of the version string E.g. 6.1
+   *
+   * @return string
+   */
+  public static function majorVersion() {
+    list($a, $b) = explode('.', self::version());
+    return "$a.$b";
+  }
+
   /**
    * Determines whether a string is a valid CiviCRM version string.
    *