[TASK] Use null coalescing operator where possible
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Classes / Persistence / Generic / QueryResult.php
1 <?php
2 namespace TYPO3\CMS\Extbase\Persistence\Generic;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use TYPO3\CMS\Extbase\Persistence\QueryResultInterface;
18
19 /**
20 * A lazy result list that is returned by Query::execute()
21 *
22 * @api
23 */
24 class QueryResult implements QueryResultInterface
25 {
26 /**
27 * @var \TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper
28 */
29 protected $dataMapper;
30
31 /**
32 * @var \TYPO3\CMS\Extbase\Persistence\PersistenceManagerInterface
33 */
34 protected $persistenceManager;
35
36 /**
37 * @var int|null
38 */
39 protected $numberOfResults;
40
41 /**
42 * @var \TYPO3\CMS\Extbase\Persistence\QueryInterface
43 */
44 protected $query;
45
46 /**
47 * @var array
48 */
49 protected $queryResult;
50
51 /**
52 * @param \TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper $dataMapper
53 */
54 public function injectDataMapper(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper $dataMapper)
55 {
56 $this->dataMapper = $dataMapper;
57 }
58
59 /**
60 * @param \TYPO3\CMS\Extbase\Persistence\PersistenceManagerInterface $persistenceManager
61 */
62 public function injectPersistenceManager(\TYPO3\CMS\Extbase\Persistence\PersistenceManagerInterface $persistenceManager)
63 {
64 $this->persistenceManager = $persistenceManager;
65 }
66
67 /**
68 * Constructor
69 *
70 * @param \TYPO3\CMS\Extbase\Persistence\QueryInterface $query
71 */
72 public function __construct(\TYPO3\CMS\Extbase\Persistence\QueryInterface $query)
73 {
74 $this->query = $query;
75 }
76
77 /**
78 * Loads the objects this QueryResult is supposed to hold
79 */
80 protected function initialize()
81 {
82 if (!is_array($this->queryResult)) {
83 $this->queryResult = $this->dataMapper->map($this->query->getType(), $this->persistenceManager->getObjectDataByQuery($this->query));
84 }
85 }
86
87 /**
88 * Returns a clone of the query object
89 *
90 * @return \TYPO3\CMS\Extbase\Persistence\QueryInterface
91 * @api
92 */
93 public function getQuery()
94 {
95 return clone $this->query;
96 }
97
98 /**
99 * Returns the first object in the result set
100 *
101 * @return object
102 * @api
103 */
104 public function getFirst()
105 {
106 if (is_array($this->queryResult)) {
107 $queryResult = $this->queryResult;
108 reset($queryResult);
109 } else {
110 $query = $this->getQuery();
111 $query->setLimit(1);
112 $queryResult = $this->dataMapper->map($query->getType(), $this->persistenceManager->getObjectDataByQuery($query));
113 }
114 $firstResult = current($queryResult);
115 if ($firstResult === false) {
116 $firstResult = null;
117 }
118 return $firstResult;
119 }
120
121 /**
122 * Returns the number of objects in the result
123 *
124 * @return int The number of matching objects
125 * @api
126 */
127 public function count()
128 {
129 if ($this->numberOfResults === null) {
130 if (is_array($this->queryResult)) {
131 $this->numberOfResults = count($this->queryResult);
132 } else {
133 $this->numberOfResults = $this->persistenceManager->getObjectCountByQuery($this->query);
134 }
135 }
136 return $this->numberOfResults;
137 }
138
139 /**
140 * Returns an array with the objects in the result set
141 *
142 * @return array
143 * @api
144 */
145 public function toArray()
146 {
147 $this->initialize();
148 return iterator_to_array($this);
149 }
150
151 /**
152 * This method is needed to implement the ArrayAccess interface,
153 * but it isn't very useful as the offset has to be an integer
154 *
155 * @param mixed $offset
156 * @return bool
157 * @see ArrayAccess::offsetExists()
158 */
159 public function offsetExists($offset)
160 {
161 $this->initialize();
162 return isset($this->queryResult[$offset]);
163 }
164
165 /**
166 * @param mixed $offset
167 * @return mixed
168 * @see ArrayAccess::offsetGet()
169 */
170 public function offsetGet($offset)
171 {
172 $this->initialize();
173 return $this->queryResult[$offset] ?? null;
174 }
175
176 /**
177 * This method has no effect on the persisted objects but only on the result set
178 *
179 * @param mixed $offset
180 * @param mixed $value
181 * @see ArrayAccess::offsetSet()
182 */
183 public function offsetSet($offset, $value)
184 {
185 $this->initialize();
186 $this->queryResult[$offset] = $value;
187 }
188
189 /**
190 * This method has no effect on the persisted objects but only on the result set
191 *
192 * @param mixed $offset
193 * @see ArrayAccess::offsetUnset()
194 */
195 public function offsetUnset($offset)
196 {
197 $this->initialize();
198 unset($this->queryResult[$offset]);
199 }
200
201 /**
202 * @return mixed
203 * @see Iterator::current()
204 */
205 public function current()
206 {
207 $this->initialize();
208 return current($this->queryResult);
209 }
210
211 /**
212 * @return mixed
213 * @see Iterator::key()
214 */
215 public function key()
216 {
217 $this->initialize();
218 return key($this->queryResult);
219 }
220
221 /**
222 * @see Iterator::next()
223 */
224 public function next()
225 {
226 $this->initialize();
227 next($this->queryResult);
228 }
229
230 /**
231 * @see Iterator::rewind()
232 */
233 public function rewind()
234 {
235 $this->initialize();
236 reset($this->queryResult);
237 }
238
239 /**
240 * @return bool
241 * @see Iterator::valid()
242 */
243 public function valid()
244 {
245 $this->initialize();
246 return current($this->queryResult) !== false;
247 }
248
249 /**
250 * Ensures that the objectManager, persistenceManager and dataMapper are back when loading the QueryResult
251 * from the cache
252 */
253 public function __wakeup()
254 {
255 $objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\Object\ObjectManager::class);
256 $this->persistenceManager = $objectManager->get(\TYPO3\CMS\Extbase\Persistence\PersistenceManagerInterface::class);
257 $this->dataMapper = $objectManager->get(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper::class);
258 }
259
260 /**
261 * @return array
262 */
263 public function __sleep()
264 {
265 return ['query'];
266 }
267 }