Merge pull request #15826 from seamuslee001/dev_core_183_dedupe
[civicrm-core.git] / Civi / Api4 / Generic / Result.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
5 | |
6 | This work is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
9 +--------------------------------------------------------------------+
10 */
11
12 namespace Civi\Api4\Generic;
13
14 /**
15 * Container for api results.
16 */
17 class Result extends \ArrayObject {
18 /**
19 * @var string
20 */
21 public $entity;
22 /**
23 * @var string
24 */
25 public $action;
26 /**
27 * Api version
28 * @var int
29 */
30 public $version = 4;
31
32 private $indexedBy;
33
34 /**
35 * Return first result.
36 * @return array|null
37 */
38 public function first() {
39 foreach ($this as $values) {
40 return $values;
41 }
42 return NULL;
43 }
44
45 /**
46 * Return last result.
47 * @return array|null
48 */
49 public function last() {
50 $items = $this->getArrayCopy();
51 return array_pop($items);
52 }
53
54 /**
55 * @param int $index
56 * @return array|null
57 */
58 public function itemAt($index) {
59 $length = $index < 0 ? 0 - $index : $index + 1;
60 if ($length > count($this)) {
61 return NULL;
62 }
63 return array_slice(array_values($this->getArrayCopy()), $index, 1)[0];
64 }
65
66 /**
67 * Re-index the results array (which by default is non-associative)
68 *
69 * Drops any item from the results that does not contain the specified key
70 *
71 * @param string $key
72 * @return $this
73 * @throws \API_Exception
74 */
75 public function indexBy($key) {
76 $this->indexedBy = $key;
77 if (count($this)) {
78 $newResults = [];
79 foreach ($this as $values) {
80 if (isset($values[$key])) {
81 $newResults[$values[$key]] = $values;
82 }
83 }
84 if (!$newResults) {
85 throw new \API_Exception("Key $key not found in api results");
86 }
87 $this->exchangeArray($newResults);
88 }
89 return $this;
90 }
91
92 /**
93 * Returns the number of results
94 *
95 * @return int
96 */
97 public function count() {
98 $count = parent::count();
99 if ($count == 1 && is_array($this->first()) && array_keys($this->first()) == ['row_count']) {
100 return $this->first()['row_count'];
101 }
102 return $count;
103 }
104
105 /**
106 * Reduce each result to one field
107 *
108 * @param $name
109 * @return array
110 */
111 public function column($name) {
112 return array_column($this->getArrayCopy(), $name, $this->indexedBy);
113 }
114
115 }