Passed
Push — master ( 797014...bcb509 )
by
unknown
19:02
created

QueryResult::setQuery()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

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