[TASK] Streamline phpdoc annotations in EXT:extbase
[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\Object\ObjectManagerInterface;
18 use TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper;
19 use TYPO3\CMS\Extbase\Persistence\QueryResultInterface;
20
21 /**
22 * A lazy result list that is returned by Query::execute()
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 * @var ObjectManagerInterface
53 */
54 protected $objectManager;
55
56 /**
57 * @param ObjectManagerInterface $objectManager
58 */
59 public function injectObjectManager(ObjectManagerInterface $objectManager)
60 {
61 $this->objectManager = $objectManager;
62 }
63
64 /**
65 * @param \TYPO3\CMS\Extbase\Persistence\PersistenceManagerInterface $persistenceManager
66 */
67 public function injectPersistenceManager(\TYPO3\CMS\Extbase\Persistence\PersistenceManagerInterface $persistenceManager)
68 {
69 $this->persistenceManager = $persistenceManager;
70 }
71
72 /**
73 * Constructor
74 *
75 * @param \TYPO3\CMS\Extbase\Persistence\QueryInterface $query
76 */
77 public function __construct(\TYPO3\CMS\Extbase\Persistence\QueryInterface $query)
78 {
79 $this->query = $query;
80 }
81
82 /**
83 * Object initialization called when object is created with ObjectManager, after constructor
84 */
85 public function initializeObject()
86 {
87 $this->dataMapper = $this->objectManager->get(DataMapper::class, $this->query);
88 }
89
90 /**
91 * Loads the objects this QueryResult is supposed to hold
92 */
93 protected function initialize()
94 {
95 if (!is_array($this->queryResult)) {
96 $this->queryResult = $this->dataMapper->map($this->query->getType(), $this->persistenceManager->getObjectDataByQuery($this->query));
97 }
98 }
99
100 /**
101 * Returns a clone of the query object
102 *
103 * @return \TYPO3\CMS\Extbase\Persistence\QueryInterface
104 */
105 public function getQuery()
106 {
107 return clone $this->query;
108 }
109
110 /**
111 * Returns the first object in the result set
112 *
113 * @return object
114 */
115 public function getFirst()
116 {
117 if (is_array($this->queryResult)) {
118 $queryResult = $this->queryResult;
119 reset($queryResult);
120 } else {
121 $query = $this->getQuery();
122 $query->setLimit(1);
123 $queryResult = $this->dataMapper->map($query->getType(), $this->persistenceManager->getObjectDataByQuery($query));
124 }
125 $firstResult = current($queryResult);
126 if ($firstResult === false) {
127 $firstResult = null;
128 }
129 return $firstResult;
130 }
131
132 /**
133 * Returns the number of objects in the result
134 *
135 * @return int The number of matching objects
136 */
137 public function count()
138 {
139 if ($this->numberOfResults === null) {
140 if (is_array($this->queryResult)) {
141 $this->numberOfResults = count($this->queryResult);
142 } else {
143 $this->numberOfResults = $this->persistenceManager->getObjectCountByQuery($this->query);
144 }
145 }
146 return $this->numberOfResults;
147 }
148
149 /**
150 * Returns an array with the objects in the result set
151 *
152 * @return array
153 */
154 public function toArray()
155 {
156 $this->initialize();
157 return iterator_to_array($this);
158 }
159
160 /**
161 * This method is needed to implement the ArrayAccess interface,
162 * but it isn't very useful as the offset has to be an integer
163 *
164 * @param mixed $offset
165 * @return bool
166 * @see ArrayAccess::offsetExists()
167 */
168 public function offsetExists($offset)
169 {
170 $this->initialize();
171 return isset($this->queryResult[$offset]);
172 }
173
174 /**
175 * @param mixed $offset
176 * @return mixed
177 * @see ArrayAccess::offsetGet()
178 */
179 public function offsetGet($offset)
180 {
181 $this->initialize();
182 return $this->queryResult[$offset] ?? null;
183 }
184
185 /**
186 * This method has no effect on the persisted objects but only on the result set
187 *
188 * @param mixed $offset
189 * @param mixed $value
190 * @see ArrayAccess::offsetSet()
191 */
192 public function offsetSet($offset, $value)
193 {
194 $this->initialize();
195 $this->queryResult[$offset] = $value;
196 }
197
198 /**
199 * This method has no effect on the persisted objects but only on the result set
200 *
201 * @param mixed $offset
202 * @see ArrayAccess::offsetUnset()
203 */
204 public function offsetUnset($offset)
205 {
206 $this->initialize();
207 unset($this->queryResult[$offset]);
208 }
209
210 /**
211 * @return mixed
212 * @see Iterator::current()
213 */
214 public function current()
215 {
216 $this->initialize();
217 return current($this->queryResult);
218 }
219
220 /**
221 * @return mixed
222 * @see Iterator::key()
223 */
224 public function key()
225 {
226 $this->initialize();
227 return key($this->queryResult);
228 }
229
230 /**
231 * @see Iterator::next()
232 */
233 public function next()
234 {
235 $this->initialize();
236 next($this->queryResult);
237 }
238
239 /**
240 * @see Iterator::rewind()
241 */
242 public function rewind()
243 {
244 $this->initialize();
245 reset($this->queryResult);
246 }
247
248 /**
249 * @return bool
250 * @see Iterator::valid()
251 */
252 public function valid()
253 {
254 $this->initialize();
255 return current($this->queryResult) !== false;
256 }
257
258 /**
259 * Ensures that the objectManager, persistenceManager and dataMapper are back when loading the QueryResult
260 * from the cache
261 * @internal only to be used within Extbase, not part of TYPO3 Core API.
262 */
263 public function __wakeup()
264 {
265 $objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\Object\ObjectManager::class);
266 $this->persistenceManager = $objectManager->get(\TYPO3\CMS\Extbase\Persistence\PersistenceManagerInterface::class);
267 }
268
269 /**
270 * @return array
271 * @internal only to be used within Extbase, not part of TYPO3 Core API.
272 */
273 public function __sleep()
274 {
275 return ['query'];
276 }
277 }