Skip to content

Commit

Permalink
Fix remote getFields action
Browse files Browse the repository at this point in the history
* `RemoteActionInterface` was missing as implemented in
`AbstractRemoteGetFieldsAction` so remote contact ID weren't resolved.
* `AbstractRemoteGetFieldsAction` now extends `BasicGetFieldsAction` so
the phpdoc type hint of `AbstractEntity::getFields()` is matched.
  • Loading branch information
Dominic Tubach committed Dec 13, 2024
1 parent 945703e commit 1648025
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 18 deletions.
26 changes: 23 additions & 3 deletions Civi/RemoteTools/Api4/Action/AbstractRemoteGetFieldsAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -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<int|string, mixed>
*
* @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;
}

}
21 changes: 6 additions & 15 deletions Civi/RemoteTools/Api4/Action/RemoteGetFieldsAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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(),
Expand All @@ -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());
}
],
];
}
}

Expand Down
55 changes: 55 additions & 0 deletions Civi/RemoteTools/Api4/Util/WhereUtil.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php
/*
* Copyright (C) 2024 SYSTOPIA GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation in version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

declare(strict_types = 1);

namespace Civi\RemoteTools\Api4\Util;

/**
* @phpstan-type whereT list<array{string, string|list<mixed>, 2?: mixed}>
* "list<mixed>" 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<string>
* 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);
}

}

0 comments on commit 1648025

Please sign in to comment.