SearchKit - Fix enable/disable links in displays
authorcolemanw <coleman@civicrm.org>
Thu, 29 Feb 2024 22:03:14 +0000 (17:03 -0500)
committercolemanw <coleman@civicrm.org>
Fri, 1 Mar 2024 03:28:09 +0000 (22:28 -0500)
This fixes task-based links (enable, disable, etc) when used as buttons, dropdowns, etc. in search displays

ext/search_kit/Civi/Api4/Action/SearchDisplay/AbstractRunAction.php
ext/search_kit/tests/phpunit/api/v4/SearchDisplay/SearchRunTest.php

index ccc7cf20bc1099beae4829d8f0d8ec978cf1e80c..cce62e357ce7937fd684c35982223270203f412c 100644 (file)
@@ -554,17 +554,17 @@ abstract class AbstractRunAction extends \Civi\Api4\Generic\AbstractAction {
       return NULL;
     }
     $link['text'] = $text ?? $this->replaceTokens($link['text'], $data, 'view');
-    // Will return null if `$link[path]` is empty or if any tokens do not resolve
-    $path = $this->replaceTokens($link['path'], $data, 'url');
-    if ($path) {
-      $link['url'] = $this->getUrl($path);
-      $keys = ['url', 'text', 'title', 'target', 'icon', 'style', 'autoOpen'];
-    }
-    elseif (!empty($link['task'])) {
+    if (!empty($link['task'])) {
       $keys = ['task', 'text', 'title', 'icon', 'style'];
     }
     else {
-      return NULL;
+      $path = $this->replaceTokens($link['path'], $data, 'url');
+      if (!$path) {
+        // Return null if `$link[path]` is empty or if any tokens do not resolve
+        return NULL;
+      }
+      $link['url'] = $this->getUrl($path);
+      $keys = ['url', 'text', 'title', 'target', 'icon', 'style', 'autoOpen'];
     }
     $link = array_intersect_key($link, array_flip($keys));
     return array_filter($link, function($value) {
@@ -793,7 +793,7 @@ abstract class AbstractRunAction extends \Civi\Api4\Generic\AbstractAction {
           $data = \CRM_Utils_JS::getRawProps($task['crmPopup']['data']);
           // Find the special key that combines selected ids and replace it with id token
           $idsKey = array_search("ids.join(',')", $data);
-          unset($data[$idsKey]);
+          unset($data[$idsKey], $link['task']);
           $amp = strpos($link['path'], '?') ? '&' : '?';
           $link['path'] .= $amp . $idField . '=[' . $link['prefix'] . $idKey . ']';
           // Add the rest of the data items
index 33a88ab3aaaddd8dbc696d23b18ed040dfb9a9ef..d2637ea2a2511161ff77ea68832b5da5bde0378e 100644 (file)
@@ -391,15 +391,74 @@ class SearchRunTest extends Api4TestBase implements TransactionalInterface {
     $this->assertEquals('fa-external-link', $result[0]['columns'][1]['links'][0]['icon']);
     // 2nd link is to the native SK bulk-update task
     $this->assertArrayNotHasKey('url', $result[0]['columns'][1]['links'][1]);
+    $this->assertArrayNotHasKey('action', $result[0]['columns'][1]['links'][1]);
     $this->assertEquals('update', $result[0]['columns'][1]['links'][1]['task']);
     $this->assertEquals('fa-pencil', $result[0]['columns'][1]['links'][1]['icon']);
     // 3rd link is a popup link to the delete contribution quickform
+    $this->assertArrayNotHasKey('task', $result[0]['columns'][1]['links'][2]);
     $this->assertStringContainsString('action=delete&id=' . $contributions[0]['id'], $result[0]['columns'][1]['links'][2]['url']);
     $this->assertEquals('crm-popup', $result[0]['columns'][1]['links'][2]['target']);
     $this->assertEquals('fa-trash', $result[0]['columns'][1]['links'][2]['icon']);
     $this->assertEquals('Delete', $result[0]['columns'][1]['links'][2]['title']);
   }
 
+  public function testEnableDisableTaskLinks():void {
+    $contributionPage = $this->createTestRecord('ContributionPage');
+    $params = [
+      'checkPermissions' => FALSE,
+      'return' => 'page:1',
+      'savedSearch' => [
+        'api_entity' => 'ContributionPage',
+        'api_params' => [
+          'version' => 4,
+          'select' => ['title'],
+          'where' => [['id', '=', $contributionPage['id']]],
+        ],
+      ],
+      'display' => [
+        'type' => 'table',
+        'label' => 'testDisplay',
+        'settings' => [
+          'actions' => TRUE,
+          'pager' => [],
+          'columns' => [
+            [
+              'key' => 'title',
+              'label' => 'Title',
+              'dataType' => 'String',
+              'type' => 'field',
+            ],
+            [
+              'type' => 'buttons',
+              'links' => [
+                [
+                  'entity' => 'ContributionPage',
+                  'task' => 'enable',
+                  'icon' => 'fa-pencil',
+                ],
+                [
+                  'entity' => 'ContributionPage',
+                  'task' => 'disable',
+                  'icon' => 'fa-pencil',
+                ],
+              ],
+            ],
+          ],
+          'sort' => [
+            ['id', 'ASC'],
+          ],
+        ],
+      ],
+    ];
+    $result = civicrm_api4('SearchDisplay', 'run', $params);
+    $this->assertEquals(1, $result->count());
+    // Native SK tasks should not have a url
+    $this->assertArrayNotHasKey('url', $result[0]['columns'][1]['links'][1]);
+    $this->assertArrayNotHasKey('action', $result[0]['columns'][1]['links'][1]);
+    $this->assertEquals('disable', $result[0]['columns'][1]['links'][1]['task']);
+    $this->assertEquals('fa-pencil', $result[0]['columns'][1]['links'][1]['icon']);
+  }
+
   public function testRelationshipCacheLinks():void {
     $case = $this->createTestRecord('Case');
     $relationships = $this->saveTestRecords('Relationship', [