From b0932d1e5538debbc203c00554ba852288392847 Mon Sep 17 00:00:00 2001 From: Coleman Watts Date: Thu, 26 Mar 2020 16:52:10 -0400 Subject: [PATCH] APIv4 - Preserve order when expanding select wildcards --- Civi/Api4/Generic/AbstractGetAction.php | 13 +++++++----- .../api/v4/Action/BasicActionsTest.php | 21 +++++++++++++++++++ 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/Civi/Api4/Generic/AbstractGetAction.php b/Civi/Api4/Generic/AbstractGetAction.php index e9f892c2af..d82e7071b1 100644 --- a/Civi/Api4/Generic/AbstractGetAction.php +++ b/Civi/Api4/Generic/AbstractGetAction.php @@ -80,12 +80,15 @@ abstract class AbstractGetAction extends AbstractQueryAction { * @throws \API_Exception */ protected function expandSelectClauseWildcards() { - foreach ($this->select as $item) { - if (strpos($item, '*') !== FALSE && strpos($item, '.') === FALSE) { - $this->select = array_diff($this->select, [$item]); - $this->select = array_unique(array_merge($this->select, SelectUtil::getMatchingFields($item, array_column($this->entityFields(), 'name')))); - } + $wildFields = array_filter($this->select, function($item) { + return strpos($item, '*') !== FALSE && strpos($item, '.') === FALSE; + }); + foreach ($wildFields as $item) { + $pos = array_search($item, array_values($this->select)); + $matches = SelectUtil::getMatchingFields($item, array_column($this->entityFields(), 'name')); + array_splice($this->select, $pos, 1, $matches); } + $this->select = array_unique($this->select); } /** diff --git a/tests/phpunit/api/v4/Action/BasicActionsTest.php b/tests/phpunit/api/v4/Action/BasicActionsTest.php index ace6f05bf8..21b181f7d4 100644 --- a/tests/phpunit/api/v4/Action/BasicActionsTest.php +++ b/tests/phpunit/api/v4/Action/BasicActionsTest.php @@ -197,4 +197,25 @@ class BasicActionsTest extends UnitTestCase { $this->assertTrue($isFieldSelected->invoke($get, 'group')); } + public function testWildcardSelect() { + MockBasicEntity::delete()->addWhere('id', '>', 0)->execute(); + + $records = [ + ['group' => 'one', 'color' => 'red', 'shape' => 'round', 'size' => 'med', 'weight' => 10], + ['group' => 'two', 'color' => 'blue', 'shape' => 'round', 'size' => 'med', 'weight' => 20], + ]; + MockBasicEntity::save()->setRecords($records)->execute(); + + foreach (MockBasicEntity::get()->addSelect('*')->execute() as $result) { + ksort($result); + $this->assertEquals(['color', 'group', 'id', 'shape', 'size', 'weight'], array_keys($result)); + } + + $result = MockBasicEntity::get() + ->addSelect('*e', 'weig*ht') + ->execute() + ->first(); + $this->assertEquals(['shape', 'size', 'weight'], array_keys($result)); + } + } -- 2.25.1