dev/core#472 Allow for APIv3 to find examples in Extenion folders as well as core
authorSeamus Lee <seamuslee001@gmail.com>
Wed, 24 Oct 2018 23:54:55 +0000 (10:54 +1100)
committerSeamus Lee <seamuslee001@gmail.com>
Mon, 29 Oct 2018 06:02:47 +0000 (17:02 +1100)
Improve inclusion scanning by using get_include_path as suggested by Coleamn and alpha sort the list of entities

Deal with windows directory separators and more helpfully handle the trailing and non trailing slash directories

Further fixes for windows Directory Separators

CRM/Admin/Page/APIExplorer.php

index 678cef4a8f4803c0e9ddf41d56667cfa5206d405..9d5cd46c9a9cbf20777551f72f8965d436168903 100644 (file)
  */
 class CRM_Admin_Page_APIExplorer extends CRM_Core_Page {
 
+  /**
+   * Return unique paths for checking for examples.
+   * @return array
+   */
+  private static function uniquePaths() {
+    // Ensure that paths with trailing slashes are properly dealt with
+    $paths = explode(PATH_SEPARATOR, get_include_path());
+    foreach ($paths as $id => $rawPath) {
+      $pathParts = explode(DIRECTORY_SEPARATOR, $rawPath);
+      foreach ($pathParts as $partId => $part) {
+        if (empty($part)) {
+          unset($pathParts[$partId]);
+        }
+      }
+      $newRawPath = implode(DIRECTORY_SEPARATOR, $pathParts);
+      if ($newRawPath != $rawPath) {
+        $paths[$id] = DIRECTORY_SEPARATOR . $newRawPath;
+      }
+    }
+    $paths = array_unique($paths);
+    return $paths;
+  }
+
+
   /**
    * Run page.
    *
@@ -51,12 +75,20 @@ class CRM_Admin_Page_APIExplorer extends CRM_Core_Page {
     $this->assign('operators', CRM_Core_DAO::acceptedSQLOperators());
 
     // List example directories
+    // use get_include_path to ensure that extensions are captured.
     $examples = array();
-    foreach (scandir(\Civi::paths()->getPath('[civicrm.root]/api/v3/examples')) as $item) {
-      if ($item && strpos($item, '.') === FALSE) {
-        $examples[] = $item;
+    $paths = self::uniquePaths();
+    foreach ($paths as $path) {
+      $dir = \CRM_Utils_File::addTrailingSlash($path) . 'api' . DIRECTORY_SEPARATOR . 'v3' . DIRECTORY_SEPARATOR . 'examples';
+      if (is_dir($dir)) {
+        foreach (scandir($dir) as $item) {
+          if ($item && strpos($item, '.') === FALSE && array_search($item, $examples) === FALSE) {
+            $examples[] = $item;
+          }
+        }
       }
     }
+    sort($examples);
     $this->assign('examples', $examples);
 
     return parent::run();
@@ -78,20 +110,31 @@ class CRM_Admin_Page_APIExplorer extends CRM_Core_Page {
   public static function getExampleFile() {
     if (!empty($_GET['entity']) && strpos($_GET['entity'], '.') === FALSE) {
       $examples = array();
-      foreach (scandir(\Civi::paths()->getPath("[civicrm.root]/api/v3/examples/{$_GET['entity']}")) as $item) {
-        $item = str_replace('.php', '', $item);
-        if ($item && strpos($item, '.') === FALSE) {
-          $examples[] = array('key' => $item, 'value' => $item);
+      $paths = self::uniquePaths();
+      foreach ($paths as $path) {
+        $dir = \CRM_Utils_File::addTrailingSlash($path) . 'api' . DIRECTORY_SEPARATOR . 'v3' . DIRECTORY_SEPARATOR . 'examples' . DIRECTORY_SEPARATOR . $_GET['entity'];
+        if (is_dir($dir)) {
+          foreach (scandir($dir) as $item) {
+            $item = str_replace('.php', '', $item);
+            if ($item && strpos($item, '.') === FALSE) {
+              $examples[] = array('key' => $item, 'value' => $item);
+            }
+          }
         }
       }
       CRM_Utils_JSON::output($examples);
     }
     if (!empty($_GET['file']) && strpos($_GET['file'], '.') === FALSE) {
-      $fileName = \Civi::paths()->getPath("[civicrm.root]/api/v3/examples/{$_GET['file']}.php");
-      if (file_exists($fileName)) {
-        echo file_get_contents($fileName);
+      $paths = self::uniquePaths();
+      $fileFound = FALSE;
+      foreach ($paths as $path) {
+        $fileName = \CRM_Utils_File::addTrailingSlash($path) . 'api' . DIRECTORY_SEPARATOR . 'v3' . DIRECTORY_SEPARATOR . 'examples' . DIRECTORY_SEPARATOR . $_GET['file'] . '.php';
+        if (!$fileFound && file_exists($fileName)) {
+          $fileFound = TRUE;
+          echo file_get_contents($fileName);
+        }
       }
-      else {
+      if (!$fileFound) {
         echo "Not found.";
       }
       CRM_Utils_System::civiExit();