EntityLookupTrait - Add isDefined and getDefinition methods
authorcolemanw <coleman@civicrm.org>
Mon, 4 Sep 2023 01:05:37 +0000 (21:05 -0400)
committercolemanw <coleman@civicrm.org>
Mon, 4 Sep 2023 01:07:29 +0000 (21:07 -0400)
Civi/API/EntityLookupTrait.php
tests/phpunit/Civi/API/EntityLookupTest.php

index b45dc9b9daa844b5b50fb0688d710acedd6c1a8a..7f452a3c2a0d7712b372d63761a45642297f62d9 100644 (file)
@@ -44,6 +44,26 @@ trait EntityLookupTrait {
     $this->entityLookupValues[$nickname] = [];
   }
 
+  /**
+   * Check if an entity can be looked up
+   *
+   * @param string $nickname
+   * @return bool
+   */
+  public function isDefined(string $nickname): bool {
+    return !is_null($this->getDefinition($nickname));
+  }
+
+  /**
+   * Retrieve entity definition (entityName string, identifier [keys/values])
+   *
+   * @param string $nickname
+   * @return array{entityName: string, identifier: array}|null
+   */
+  protected function getDefinition(string $nickname): ?array {
+    return $this->entityLookupDefinitions[$nickname] ?? NULL;
+  }
+
   /**
    * Retrieve a field value for a defined entity
    *
@@ -54,31 +74,31 @@ trait EntityLookupTrait {
    * @throws \CRM_Core_Exception
    */
   public function lookup(string $nickname, string $fieldName) {
-    if (!isset($this->entityLookupValues[$nickname])) {
+    $definition = $this->getDefinition($nickname);
+    if (!$definition) {
       throw new \CRM_Core_Exception(sprintf('Cannot lookup entity "%s" before it has been defined.', $nickname));
     }
     // Simply return an id - no need for any queries
-    if (isset($this->entityLookupDefinitions[$nickname]['identifier'][$fieldName])) {
-      return $this->entityLookupDefinitions[$nickname]['identifier'][$fieldName];
+    if (isset($definition['identifier'][$fieldName])) {
+      return $definition['identifier'][$fieldName];
     }
     // Return stored value from previous lookup
     if (array_key_exists($fieldName, $this->entityLookupValues[$nickname])) {
       return $this->entityLookupValues[$nickname][$fieldName];
     }
-    $entityName = $this->entityLookupDefinitions[$nickname]['entityName'];
     $params = [
       'select' => [$fieldName],
       'where' => [],
       'checkPermissions' => FALSE,
     ];
-    foreach ($this->entityLookupDefinitions[$nickname]['identifier'] as $key => $val) {
+    foreach ($definition['identifier'] as $key => $val) {
       $params['where'][] = [$key, '=', $val];
     }
     // Initial load - prefetch all core fields to reduce # of subsequent queries
     if (!$this->entityLookupValues[$nickname]) {
       $params['select'][] = '*';
       // Contact email is commonly needed by forms so prefetch it as well
-      if ($entityName === 'Contact') {
+      if ($definition['entityName'] === 'Contact') {
         $params['select'][] = 'email_primary.*';
       }
     }
@@ -88,7 +108,7 @@ trait EntityLookupTrait {
       $parts[count($parts) - 1] = '*';
       $params['select'][] = implode('.', $parts);
     }
-    $retrieved = civicrm_api4($entityName, 'get', $params)->single();
+    $retrieved = civicrm_api4($definition['entityName'], 'get', $params)->single();
     $this->entityLookupValues[$nickname] += $retrieved;
     return $this->entityLookupValues[$nickname][$fieldName] ?? NULL;
   }
index 954c4face8c5816cd54fe2740d8162e2c01e3df4..3f0509d00af2d1f1f551f12a451430beea3f002b 100644 (file)
@@ -9,10 +9,17 @@ class EntityLookupTest extends \CiviUnitTestCase {
     $bob = $this->createTestEntity('Contact', ['first_name' => 'Bob', 'last_name' => 'One', 'gender_id:name' => 'Male', 'email_primary.email' => 'bob@one.test']);
     $jan = $this->createTestEntity('Contact', ['first_name' => 'Jan', 'last_name' => 'Two', 'gender_id:name' => 'Female', 'external_identifier' => uniqid()]);
     $this->define('Contact', 'Bob', ['id' => $bob['id']]);
+    $this->assertFalse($this->isDefined('Jan'));
     $this->define('Contact', 'Jan', ['external_identifier' => $jan['external_identifier']]);
+    $this->assertTrue($this->isDefined('Jan'));
+    $this->assertEquals($bob['id'], $this->getDefinition('Bob')['identifier']['id']);
+    $this->assertEquals('Contact', $this->getDefinition('Jan')['entityName']);
+    $this->assertNull($this->getDefinition('Jim'));
+    $this->assertFalse($this->isDefined('Jim'));
     $this->assertEquals('One', $this->lookup('Bob', 'last_name'));
     $this->assertEquals('bob@one.test', $this->lookup('Bob', 'email_primary.email'));
     $this->assertEquals('Male', $this->lookup('Bob', 'gender_id:name'));
+    $this->assertEquals($jan['id'], $this->lookup('Jan', 'id'));
     $this->assertEquals('Two', $this->lookup('Jan', 'last_name'));
     $this->assertEquals('Female', $this->lookup('Jan', 'gender_id:name'));
   }