diff --git a/Civi/RemoteTools/Api4/Action/AbstractRemoteGetFieldsAction.php b/Civi/RemoteTools/Api4/Action/AbstractRemoteGetFieldsAction.php index d00af36..da6017b 100644 --- a/Civi/RemoteTools/Api4/Action/AbstractRemoteGetFieldsAction.php +++ b/Civi/RemoteTools/Api4/Action/AbstractRemoteGetFieldsAction.php @@ -20,19 +20,39 @@ namespace Civi\RemoteTools\Api4\Action; use Civi\Api4\Generic\BasicGetFieldsAction; -use Civi\RemoteTools\Api4\Action\Traits\ActionHandlerRunTrait; +use Civi\Api4\Generic\Result; +use Civi\RemoteTools\Api4\Action\Traits\ActionHandlerTrait; use Civi\RemoteTools\Api4\Action\Traits\RemoteContactIdParameterOptionalTrait; use Civi\RemoteTools\Api4\Action\Traits\ResolvedContactIdOptionalTrait; +use Civi\RemoteTools\Api4\Util\WhereUtil; /** * @api */ -abstract class AbstractRemoteGetFieldsAction extends BasicGetFieldsAction { +abstract class AbstractRemoteGetFieldsAction extends BasicGetFieldsAction implements RemoteActionInterface { - use ActionHandlerRunTrait; + use ActionHandlerTrait; use RemoteContactIdParameterOptionalTrait; use ResolvedContactIdOptionalTrait; + /** + * @phpstan-return array + * + * @throws \Civi\RemoteTools\Exception\ActionHandlerNotFoundException + */ + protected function getRecords(): array { + // Ensure required for the filtering done by BasicGetFieldsAction are + // available. + $originalSelect = $this->select; + if ([] !== $this->select) { + $this->select = array_unique(array_merge($this->select, WhereUtil::getFields($this->where))); + } + $result = $this->getHandlerResult(); + $this->select = $originalSelect; + + return $result instanceof Result ? $result->getArrayCopy() : $result; + } + } diff --git a/Civi/RemoteTools/Api4/Action/RemoteGetFieldsAction.php b/Civi/RemoteTools/Api4/Action/RemoteGetFieldsAction.php index cf51d86..f72f12a 100644 --- a/Civi/RemoteTools/Api4/Action/RemoteGetFieldsAction.php +++ b/Civi/RemoteTools/Api4/Action/RemoteGetFieldsAction.php @@ -19,7 +19,6 @@ namespace Civi\RemoteTools\Api4\Action; -use Civi\Api4\Generic\Result; use Civi\RemoteTools\Api4\Action\Traits\ProfileParameterOptionalTrait; use Civi\RemoteTools\Exception\ActionHandlerNotFoundException; @@ -39,21 +38,17 @@ class RemoteGetFieldsAction extends AbstractRemoteGetFieldsAction implements Pro // Called by API explorer and SearchKit, so parameters need to be optional. use ProfileParameterOptionalTrait; - public function _run(Result $result): void { + protected function getRecords(): array { try { - $this->doRun($result); + return parent::getRecords(); } - // @phpstan-ignore-next-line catch (ActionHandlerNotFoundException $e) { if (NULL !== $this->profile) { throw $e; } - if ('getFields' === $this->action) { - $result->exchangeArray($this->fields()); - } - elseif ($this->select !== ['row_count']) { - $result[] = [ + return [ + [ 'default_value' => NULL, 'type' => 'Field', 'entity' => $this->getEntityName(), @@ -65,12 +60,8 @@ public function _run(Result $result): void { 'data_type' => 'Integer', 'options' => FALSE, 'label' => 'ID', - ]; - } - - if (in_array('row_count', $this->select, TRUE)) { - $result->setCountMatched($result->count()); - } + ], + ]; } } diff --git a/Civi/RemoteTools/Api4/Util/WhereUtil.php b/Civi/RemoteTools/Api4/Util/WhereUtil.php new file mode 100644 index 0000000..95ffba4 --- /dev/null +++ b/Civi/RemoteTools/Api4/Util/WhereUtil.php @@ -0,0 +1,55 @@ +. + */ + +declare(strict_types = 1); + +namespace Civi\RemoteTools\Api4\Util; + +/** + * @phpstan-type whereT list, 2?: mixed}> + * "list" is actually a condition of a composite condition so we have + * a recursion that cannot be expressed in a phpstan type. The third entry is + * not given for composite conditions. + * + * @codeCoverageIgnore + */ +final class WhereUtil { + + /** + * @phpstan-param whereT $where + * + * @phpstan-return array + * Field names used in where. + */ + public static function getFields(array $where): array { + $fields = []; + + foreach ($where as $clause) { + if (is_array($clause[1])) { + // Composite condition. + // @phpstan-ignore argument.type + $fields = array_merge($fields, self::getFields($clause[1])); + } + else { + $fields[] = $clause[0]; + } + } + + return array_unique($fields); + } + +}