APIv4 - Add CoreUtil::isType() helper
authorcolemanw <coleman@civicrm.org>
Thu, 19 Oct 2023 19:08:38 +0000 (15:08 -0400)
committercolemanw <coleman@civicrm.org>
Thu, 19 Oct 2023 19:08:38 +0000 (15:08 -0400)
Helper function avoids verbose coding pattern.

CRM/Core/ManagedEntities.php
Civi/Api4/Generic/Traits/DAOActionTrait.php
Civi/Api4/Generic/Traits/SavedSearchInspectorTrait.php
Civi/Api4/Utils/CoreUtil.php
ext/search_kit/Civi/Api4/Action/SearchDisplay/AbstractRunAction.php
tests/phpunit/api/v4/Entity/ConformanceTest.php
tools/extensions/phpstorm/Civi/PhpStorm/Api4Generator.php

index f080c45e949115bfb17470d7f2f1d12706cd1a24..09ea4c76a247698e81fc8a5e5ced44242c26485e 100644 (file)
@@ -153,7 +153,7 @@ class CRM_Core_ManagedEntities {
     // Fetch default values for fields that are writeable
     $condition = [['type', '=', 'Field'], ['readonly', 'IS EMPTY'], ['default_value', '!=', 'now']];
     // Exclude "weight" as that auto-adjusts
-    if (in_array('SortableEntity', CoreUtil::getInfoItem($item['entity_type'], 'type'), TRUE)) {
+    if (CoreUtil::isType($item['entity_type'], 'SortableEntity')) {
       $weightCol = CoreUtil::getInfoItem($item['entity_type'], 'order_by');
       $condition[] = ['name', '!=', $weightCol];
     }
@@ -302,7 +302,7 @@ class CRM_Core_ManagedEntities {
       $idField = CoreUtil::getIdFieldName($item['entity_type']);
       $params['values'][$idField] = $item['entity_id'];
       // Exclude "weight" as that auto-adjusts
-      if (in_array('SortableEntity', CoreUtil::getInfoItem($item['entity_type'], 'type'), TRUE)) {
+      if (CoreUtil::isType($item['entity_type'], 'SortableEntity')) {
         $weightCol = CoreUtil::getInfoItem($item['entity_type'], 'order_by');
         unset($params['values'][$weightCol]);
       }
index feabd9bc4914a349f272136e39ebfae00e3a2f87..3a7d72c4e891d4c6ca0019ef569f525470a865dd 100644 (file)
@@ -102,7 +102,7 @@ trait DAOActionTrait {
   protected function writeObjects($items) {
     $updateWeights = FALSE;
     // Adjust weights for sortable entities
-    if (in_array('SortableEntity', CoreUtil::getInfoItem($this->getEntityName(), 'type'))) {
+    if (CoreUtil::isType($this->getEntityName(), 'SortableEntity')) {
       $weightField = CoreUtil::getInfoItem($this->getEntityName(), 'order_by');
       // Only take action if updating a single record, or if no weights are specified in any record
       // This avoids messing up a bulk update with multiple recalculations
index 92487d91ba5b33af4a6db62c7ae438514fa88619..f10c09e818ee9f672c41dc62afe9fb16f1d32a31 100644 (file)
@@ -148,7 +148,7 @@ trait SavedSearchInspectorTrait {
    */
   private function getQuery() {
     if (!isset($this->_selectQuery) && !empty($this->savedSearch['api_entity'])) {
-      if (!in_array('DAOEntity', CoreUtil::getInfoItem($this->savedSearch['api_entity'], 'type'), TRUE)) {
+      if (!CoreUtil::isType($this->savedSearch['api_entity'], 'DAOEntity')) {
         return $this->_selectQuery = FALSE;
       }
       $api = Request::create($this->savedSearch['api_entity'], 'get', $this->savedSearch['api_params']);
index 80abe31d5de6ca6555238cc7a792e8c7bc7a2f5f..b8945e94ca84428f838ed8735c8e1decfed9adcd 100644 (file)
@@ -90,6 +90,20 @@ class CoreUtil {
     return $provider->getEntities()[$entityName][$keyToReturn] ?? NULL;
   }
 
+  /**
+   * Check if entity is of given type.
+   *
+   * @param string $entityName
+   *   e.g. 'Contact'
+   * @param string $entityType
+   *   e.g. 'SortableEntity'
+   * @return bool
+   */
+  public static function isType(string $entityName, string $entityType): bool {
+    $entityTypes = (array) self::getInfoItem($entityName, 'type');
+    return in_array($entityType, $entityTypes, TRUE);
+  }
+
   /**
    * Get name of unique identifier, typically "id"
    * @param string $entityName
index 02037c290a66dbd7acd1e89371e197ccb7bc48f5..69acf8e3ff2470fe4ae2178fee0f8b1aaaabbaee 100644 (file)
@@ -1147,7 +1147,7 @@ abstract class AbstractRunAction extends \Civi\Api4\Generic\AbstractAction {
     }
     // Add primary key field if actions are enabled
     // (only needed for non-dao entities, as Api4SelectQuery will auto-add the id)
-    if (!in_array('DAOEntity', CoreUtil::getInfoItem($this->savedSearch['api_entity'], 'type')) &&
+    if (!CoreUtil::isType($this->savedSearch['api_entity'], 'DAOEntity') &&
       (!empty($this->display['settings']['actions']) || !empty($this->display['settings']['draggable']))
     ) {
       $this->addSelectExpression(CoreUtil::getIdFieldName($this->savedSearch['api_entity']));
index 7c656b61f6bc794b2cf235ceda9c1b4ac54a442c..37cae606159aac39a99d90a81d61b6883558120c 100644 (file)
@@ -441,7 +441,7 @@ class ConformanceTest extends Api4TestBase implements HookInterface {
       $deleteResult = $deleteAction->execute();
     });
 
-    if (in_array('DAOEntity', CoreUtil::getInfoItem($entityName, 'type'))) {
+    if (CoreUtil::isType($entityName, 'DAOEntity')) {
       // We should have emitted an event.
       $hookEntity = ($entityName === 'Contact') ? 'Individual' : $entityName;/* ooph */
       $this->assertContains("pre.{$hookEntity}.delete", $log, "$entityName should emit hook_civicrm_pre() for deletions");
@@ -520,7 +520,7 @@ class ConformanceTest extends Api4TestBase implements HookInterface {
    * @return bool
    */
   protected function isReadOnly($entityName) {
-    return in_array('ReadOnlyEntity', CoreUtil::getInfoItem($entityName, 'type'), TRUE);
+    return CoreUtil::isType($entityName, 'ReadOnlyEntity');
   }
 
   /**
index 532d315180817d823ef0d58660d0fc7c1c8006d7..04d2dae43ff510925172f933237f82be2c73007f 100644 (file)
@@ -34,11 +34,13 @@ class Api4Generator extends AutoService implements EventSubscriberInterface {
     $entities = Entity::get(FALSE)->addSelect('name')->execute()->column('name');
     $actions = ['get', 'save', 'create', 'update', 'delete', 'replace', 'revert', 'export', 'autocomplete', 'getFields', 'getActions', 'checkAccess'];
     $properties = Entity::getFields(FALSE)->addOrderBy('name')->execute()->column('name');
+    $entityTypes = Entity::getFields(FALSE)->addWhere('name', '=', 'type')->setLoadOptions(TRUE)->execute()->first()['options'] ?? [];
 
     $builder = new PhpStormMetadata('api4', __CLASS__);
     $builder->registerArgumentsSet('api4Entities', ...$entities);
     $builder->registerArgumentsSet('api4Actions', ...$actions);
     $builder->registerArgumentsSet('api4Properties', ...$properties);
+    $builder->registerArgumentsSet('api4EntityTypes', ...array_values($entityTypes));
 
     // Define arguments for core functions
     $builder->addExpectedArguments('\civicrm_api4()', 0, 'api4Entities');
@@ -52,6 +54,8 @@ class Api4Generator extends AutoService implements EventSubscriberInterface {
     $builder->addExpectedArguments('\Civi\Api4\Utils\CoreUtil::getTableName()', 0, 'api4Entities');
     $builder->addExpectedArguments('\Civi\Api4\Utils\CoreUtil::getCustomGroupExtends()', 0, 'api4Entities');
     $builder->addExpectedArguments('\Civi\Api4\Utils\CoreUtil::getRefCount()', 0, 'api4Entities');
+    $builder->addExpectedArguments('\Civi\Api4\Utils\CoreUtil::isType()', 0, 'api4Entities');
+    $builder->addExpectedArguments('\Civi\Api4\Utils\CoreUtil::isType()', 1, 'api4EntityTypes');
     $builder->addExpectedArguments('\Civi\Api4\Utils\CoreUtil::checkAccessDelegated()', 0, 'api4Entities');
     $builder->addExpectedArguments('\Civi\Api4\Utils\CoreUtil::checkAccessDelegated()', 1, 'api4Actions');
     $builder->addExpectedArguments('\Civi\API\EntityLookupTrait::define()', 0, 'api4Entities');