Merge pull request #17150 from civicrm/5.25
[civicrm-core.git] / Civi / Api4 / Generic / Result.php
CommitLineData
19b53e5b
C
1<?php
2/*
3 +--------------------------------------------------------------------+
41498ac5 4 | Copyright CiviCRM LLC. All rights reserved. |
19b53e5b 5 | |
41498ac5
TO
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 |
19b53e5b
C
9 +--------------------------------------------------------------------+
10 */
11
12namespace Civi\Api4\Generic;
13
14/**
15 * Container for api results.
c2adedc1
CW
16 *
17 * The Result object has three functions:
18 *
19 * 1. Store the results of the API call (accessible via ArrayAccess).
20 * 2. Store metadata like the Entity & Action names.
21 * - Note: some actions extend the Result object to store extra metadata.
22 * For example, BasicReplaceAction returns ReplaceResult which includes the additional $deleted property to list any items deleted by the operation.
23 * 3. Provide convenience methods like `$result->first()` and `$result->indexBy($field)`.
19b53e5b 24 */
e26fdc3f 25class Result extends \ArrayObject implements \JsonSerializable {
19b53e5b
C
26 /**
27 * @var string
28 */
29 public $entity;
30 /**
31 * @var string
32 */
33 public $action;
b65fa6dc
CW
34 /**
35 * @var array
36 */
37 public $debug;
19b53e5b
C
38 /**
39 * Api version
40 * @var int
41 */
42 public $version = 4;
43
44 private $indexedBy;
45
46 /**
47 * Return first result.
48 * @return array|null
49 */
50 public function first() {
51 foreach ($this as $values) {
52 return $values;
53 }
54 return NULL;
55 }
56
57 /**
58 * Return last result.
59 * @return array|null
60 */
61 public function last() {
62 $items = $this->getArrayCopy();
63 return array_pop($items);
64 }
65
66 /**
67 * @param int $index
68 * @return array|null
69 */
70 public function itemAt($index) {
71 $length = $index < 0 ? 0 - $index : $index + 1;
72 if ($length > count($this)) {
73 return NULL;
74 }
75 return array_slice(array_values($this->getArrayCopy()), $index, 1)[0];
76 }
77
78 /**
79 * Re-index the results array (which by default is non-associative)
80 *
81 * Drops any item from the results that does not contain the specified key
82 *
83 * @param string $key
84 * @return $this
85 * @throws \API_Exception
86 */
87 public function indexBy($key) {
88 $this->indexedBy = $key;
89 if (count($this)) {
90 $newResults = [];
91 foreach ($this as $values) {
92 if (isset($values[$key])) {
93 $newResults[$values[$key]] = $values;
94 }
95 }
96 if (!$newResults) {
97 throw new \API_Exception("Key $key not found in api results");
98 }
99 $this->exchangeArray($newResults);
100 }
101 return $this;
102 }
103
104 /**
105 * Returns the number of results
106 *
107 * @return int
108 */
109 public function count() {
110 $count = parent::count();
111 if ($count == 1 && is_array($this->first()) && array_keys($this->first()) == ['row_count']) {
112 return $this->first()['row_count'];
113 }
114 return $count;
115 }
116
117 /**
118 * Reduce each result to one field
119 *
120 * @param $name
121 * @return array
122 */
123 public function column($name) {
124 return array_column($this->getArrayCopy(), $name, $this->indexedBy);
125 }
126
e26fdc3f
CW
127 /**
128 * @return array
129 */
130 public function jsonSerialize() {
131 return $this->getArrayCopy();
132 }
133
19b53e5b 134}