Afform - Optimize Get by checking type before parsing html or loading custom data
authorColeman Watts <coleman@civicrm.org>
Mon, 30 Aug 2021 12:31:11 +0000 (08:31 -0400)
committerColeman Watts <coleman@civicrm.org>
Mon, 30 Aug 2021 12:33:42 +0000 (08:33 -0400)
Sometimes afforms are fetched by type, e.g. `cv api4 Afform.get +w type=search`
Previously this would load all html files and custom data groups before
discarding the ones not of type search.
Now it will skip irrelevant files.

ext/afform/core/Civi/Api4/Action/Afform/Get.php

index 2d4fa6e86a1ddc9b7672881f94390dc08634ac09..1b4120d4e4b6c33ccc63f23d07b359976a91cc10 100644 (file)
@@ -19,17 +19,22 @@ class Get extends \Civi\Api4\Generic\BasicGetAction {
     $scanner = \Civi::service('afform_scanner');
     $getComputed = $this->_isFieldSelected('has_local') || $this->_isFieldSelected('has_base');
     $getLayout = $this->_isFieldSelected('layout');
+    $values = [];
 
     // This helps optimize lookups by file/module/directive name
-    $toGet = array_filter([
+    $getNames = array_filter([
       'name' => $this->_itemsToGet('name'),
       'module_name' => $this->_itemsToGet('module_name'),
       'directive_name' => $this->_itemsToGet('directive_name'),
     ]);
+    $getTypes = $this->_itemsToGet('type');
 
-    $names = $toGet['name'] ?? array_keys($scanner->findFilePaths());
+    $names = $getNames['name'] ?? array_keys($scanner->findFilePaths());
 
-    $values = $this->getAutoGenerated($names, $toGet, $getLayout);
+    // Get autogenerated blocks if type block is not excluded
+    if (!$getTypes || in_array('block', $getTypes, TRUE)) {
+      $values = $this->getAutoGenerated($names, $getNames, $getLayout);
+    }
 
     if ($this->checkPermissions) {
       $names = array_filter($names, [$this, 'checkPermission']);
@@ -41,13 +46,18 @@ class Get extends \Civi\Api4\Generic\BasicGetAction {
         'module_name' => _afform_angular_module_name($name, 'camel'),
         'directive_name' => _afform_angular_module_name($name, 'dash'),
       ];
-      foreach ($toGet as $key => $get) {
-        if (!in_array($info[$key], $get)) {
+      // Skip if afform does not match requested name
+      foreach ($getNames as $key => $names) {
+        if (!in_array($info[$key], $names)) {
           continue 2;
         }
       }
       $record = $scanner->getMeta($name);
-      if (!$record && !isset($values[$name])) {
+      // Skip if afform does not exist or is not of requested type(s)
+      if (
+        (!$record && !isset($values[$name])) ||
+        ($getTypes && !in_array($record['type'], $getTypes, TRUE))
+      ) {
         continue;
       }
       $values[$name] = array_merge($values[$name] ?? [], $record ?? [], $info);
@@ -81,28 +91,27 @@ class Get extends \Civi\Api4\Generic\BasicGetAction {
   /**
    * Generates afform blocks from custom field sets.
    *
-   * @param $names
-   * @param $toGet
-   * @param $getLayout
+   * @param array $names
+   * @param array $getNames
+   * @param bool $getLayout
    * @return array
    * @throws \API_Exception
    */
-  protected function getAutoGenerated(&$names, $toGet, $getLayout) {
+  protected function getAutoGenerated(&$names, $getNames, $getLayout) {
     $values = $groupNames = [];
-    foreach ($toGet['name'] ?? [] as $name) {
+    foreach ($getNames['name'] ?? [] as $name) {
       if (strpos($name, 'afblockCustom_') === 0 && strlen($name) > 13) {
         $groupNames[] = substr($name, 14);
       }
     }
     // Early return if this api call is fetching afforms by name and those names are not custom-related
-    if ((!empty($toGet['name']) && !$groupNames)
-      || (!empty($toGet['module_name']) && !strstr(implode(' ', $toGet['module_name']), 'afblockCustom'))
-      || (!empty($toGet['directive_name']) && !strstr(implode(' ', $toGet['directive_name']), 'afblock-custom'))
+    if ((!empty($getNames['name']) && !$groupNames)
+      || (!empty($getNames['module_name']) && !strstr(implode(' ', $getNames['module_name']), 'afblockCustom'))
+      || (!empty($getNames['directive_name']) && !strstr(implode(' ', $getNames['directive_name']), 'afblock-custom'))
     ) {
       return $values;
     }
-    $customApi = CustomGroup::get()
-      ->setCheckPermissions(FALSE)
+    $customApi = CustomGroup::get(FALSE)
       ->addSelect('name', 'title', 'help_pre', 'help_post', 'extends', 'max_multiple')
       ->addWhere('is_multiple', '=', 1)
       ->addWhere('is_active', '=', 1);