dev/core#1578 - Fix APIv4 chaining with custom fields
authorColeman Watts <coleman@civicrm.org>
Thu, 16 Jul 2020 19:51:49 +0000 (15:51 -0400)
committerColeman Watts <coleman@civicrm.org>
Thu, 16 Jul 2020 19:51:49 +0000 (15:51 -0400)
Civi/Api4/Provider/ActionObjectProvider.php
tests/phpunit/api/v4/Action/ChainTest.php
tests/phpunit/api/v4/Action/EventTest.php

index 9fa607c65e3d3c3ee282f7ddf0985b256e99cc4f..ced568e7b795b5c48957b8829515b247476f6450 100644 (file)
@@ -116,7 +116,8 @@ class ActionObjectProvider implements EventSubscriberInterface, ProviderInterfac
       }
     }
     elseif (is_string($val) && strlen($val) > 1 && substr($val, 0, 1) === '$') {
-      $val = \CRM_Utils_Array::pathGet($result, explode('.', substr($val, 1)));
+      $key = substr($val, 1);
+      $val = $result[$key] ?? \CRM_Utils_Array::pathGet($result, explode('.', $key));
     }
   }
 
index cb94d7486618dffbce7d371e3d4a19757fbb550d..82508e4dd8070ab0d845f9a96d06e70953358d52 100644 (file)
 namespace api\v4\Action;
 
 use api\v4\UnitTestCase;
+use Civi\Api4\Activity;
+use Civi\Api4\Contact;
+use Civi\Api4\CustomField;
+use Civi\Api4\CustomGroup;
 
 /**
  * @group headless
  */
 class ChainTest extends UnitTestCase {
 
+  public function tearDown() {
+    $result = CustomField::delete()
+      ->setCheckPermissions(FALSE)
+      ->addWhere('name', '=', 'FavPerson')
+      ->addChain('group', CustomGroup::delete()->addWhere('name', '=', 'TestActCus'))
+      ->execute();
+    parent::tearDown();
+  }
+
   public function testGetActionsWithFields() {
     $actions = \Civi\Api4\Activity::getActions()
       ->addChain('fields', \Civi\Api4\Activity::getFields()->setAction('$name'), 'name')
@@ -55,7 +68,7 @@ class ChainTest extends UnitTestCase {
     $firstName = uniqid('cwtf');
     $lastName = uniqid('cwtl');
 
-    $contact = \Civi\Api4\Contact::create()
+    $contact = Contact::create()
       ->addValue('first_name', $firstName)
       ->addValue('last_name', $lastName)
       ->addChain('group', \Civi\Api4\Group::create()->addValue('title', '$display_name'), 0)
@@ -69,4 +82,46 @@ class ChainTest extends UnitTestCase {
     $this->assertEquals($contact['group']['id'], $contact['check_group'][0]['group_id']);
   }
 
+  public function testWithContactRef() {
+    CustomGroup::create()
+      ->setCheckPermissions(FALSE)
+      ->addValue('name', 'TestActCus')
+      ->addValue('extends', 'Activity')
+      ->addChain('field1', CustomField::create()
+        ->addValue('label', 'FavPerson')
+        ->addValue('custom_group_id', '$id')
+        ->addValue('html_type', 'Autocomplete-Select')
+        ->addValue('data_type', 'ContactReference')
+      )
+      ->execute();
+
+    $sourceId = Contact::create()->addValue('first_name', 'Source')->execute()->first()['id'];
+
+    $created = Contact::create()
+      ->setCheckPermissions(FALSE)
+      ->addValue('first_name', 'Fav')
+      ->addChain('activity', Activity::create()
+        ->addValue('activity_type_id:name', 'Meeting')
+        ->addValue('source_contact_id', $sourceId)
+        ->addValue('TestActCus.FavPerson', '$id'),
+      0)
+      ->execute()->first();
+
+    $found = Activity::get()
+      ->addSelect('TestActCus.*')
+      ->addWhere('id', '=', $created['activity']['id'])
+      ->addChain('contact', Contact::get()
+        // Test that we can access an array key with a dot in it (and it won't be confused with dot notation)
+        ->addWhere('id', '=', '$TestActCus.FavPerson'),
+      0)
+      ->addChain('contact2', Contact::get()
+        // Test that we can access a value within an array using dot notation
+        ->addWhere('id', '=', '$contact.id'),
+      0)
+      ->execute()->first();
+
+    $this->assertEquals('Fav', $found['contact']['first_name']);
+    $this->assertEquals('Fav', $found['contact2']['first_name']);
+  }
+
 }
index d432706ddc0ee5a9c7cb4c7a443e0ea941de5c2d..e61c0b70b38397fee55553f19e23149f79cb41f4 100644 (file)
@@ -29,9 +29,11 @@ class EventTest extends \api\v4\UnitTestCase {
    * @throws \Civi\API\Exception\UnauthorizedException
    */
   public function testTemplateFilterByDefault() {
-    Event::create()->setValues(['template_title' => 'Big Event', 'is_template' => 1, 'start_date' => 'now', 'event_type_id' => 'Meeting'])->execute();
-    Event::create()->setValues(['title' => 'Bigger Event', 'start_date' => 'now', 'event_type_id' => 'Meeting'])->execute();
-    $this->assertEquals(1, Event::get()->selectRowCount()->execute()->count());
+    $t = Event::create()->setValues(['template_title' => 'Big Event', 'is_template' => 1, 'start_date' => 'now', 'event_type_id:name' => 'Meeting'])->execute()->first();
+    $e = Event::create()->setValues(['title' => 'Bigger Event', 'start_date' => 'now', 'event_type_id:name' => 'Meeting'])->execute()->first();
+    $result = (array) Event::get()->execute()->column('id');
+    $this->assertContains($e['id'], $result);
+    $this->assertNotContains($t['id'], $result);
   }
 
 }