These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | use SMW\DataValueFactory; |
||
4 | use SMW\InTextAnnotationParser; |
||
5 | use SMW\Query\PrintRequest; |
||
6 | use SMW\Query\TemporaryEntityListAccumulator; |
||
7 | use SMWDataItem as DataItem; |
||
8 | use SMWDIBlob as DIBlob; |
||
9 | |||
10 | /** |
||
11 | * Container for the contents of a single result field of a query result, |
||
12 | * i.e. basically an array of SMWDataItems with some additional parameters. |
||
13 | * The content of the array is fetched on demand only. |
||
14 | * |
||
15 | * @ingroup SMWQuery |
||
16 | * |
||
17 | * @author Markus Krötzsch |
||
18 | * @author Jeroen De Dauw < [email protected] > |
||
19 | */ |
||
20 | class SMWResultArray { |
||
21 | |||
22 | /** |
||
23 | * @var PrintRequest |
||
24 | */ |
||
25 | private $mPrintRequest; |
||
26 | |||
27 | /** |
||
28 | * @var SMWDIWikiPage |
||
29 | */ |
||
30 | private $mResult; |
||
31 | |||
32 | /** |
||
33 | * @var SMWStore |
||
34 | */ |
||
35 | private $mStore; |
||
36 | |||
37 | /** |
||
38 | * @var SMWDataItem[]|false |
||
39 | */ |
||
40 | private $mContent; |
||
41 | |||
42 | /** |
||
43 | * @var TemporaryEntityListAccumulator|null |
||
44 | */ |
||
45 | private $temporaryEntityListAccumulator; |
||
46 | |||
47 | static private $catCacheObj = false; |
||
48 | static private $catCache = false; |
||
49 | |||
50 | /** |
||
51 | * Constructor. |
||
52 | * |
||
53 | * @param SMWDIWikiPage $resultPage |
||
54 | * @param PrintRequest $printRequest |
||
55 | * @param SMWStore $store |
||
56 | */ |
||
57 | 81 | public function __construct( SMWDIWikiPage $resultPage, PrintRequest $printRequest, SMWStore $store ) { |
|
58 | 81 | $this->mResult = $resultPage; |
|
59 | 81 | $this->mPrintRequest = $printRequest; |
|
60 | 81 | $this->mStore = $store; |
|
61 | 81 | $this->mContent = false; |
|
62 | 81 | } |
|
63 | |||
64 | /** |
||
65 | * Get the SMWStore object that this result is based on. |
||
66 | * |
||
67 | * @return SMWStore |
||
68 | */ |
||
69 | public function getStore() { |
||
70 | return $this->mStore; |
||
71 | } |
||
72 | |||
73 | /** |
||
74 | * Returns the SMWDIWikiPage object to which this SMWResultArray refers. |
||
75 | * If you only care for those objects, consider using SMWQueryResult::getResults() |
||
76 | * directly. |
||
77 | * |
||
78 | * @return SMWDIWikiPage |
||
79 | */ |
||
80 | 1 | public function getResultSubject() { |
|
81 | 1 | return $this->mResult; |
|
82 | } |
||
83 | |||
84 | /** |
||
85 | * Temporary track what entities are used while being instantiated, so an external |
||
86 | * service can have access to the list without requiring to resolve the objects |
||
87 | * independently. |
||
88 | * |
||
89 | * @since 2.4 |
||
90 | * |
||
91 | * @return TemporaryEntityListAccumulator |
||
92 | */ |
||
93 | 81 | public function setEntityListAccumulator( TemporaryEntityListAccumulator $temporaryEntityListAccumulator ) { |
|
94 | 81 | $this->temporaryEntityListAccumulator = $temporaryEntityListAccumulator; |
|
95 | 81 | } |
|
96 | |||
97 | /** |
||
98 | * Returns an array of SMWDataItem objects that contain the results of |
||
99 | * the given print request for the given result object. |
||
100 | * |
||
101 | * @return SMWDataItem[]|false |
||
102 | */ |
||
103 | 4 | public function getContent() { |
|
104 | 4 | $this->loadContent(); |
|
105 | 4 | return $this->mContent; |
|
106 | } |
||
107 | |||
108 | /** |
||
109 | * Return a PrintRequest object describing what is contained in this |
||
110 | * result set. |
||
111 | * |
||
112 | * @return PrintRequest |
||
113 | */ |
||
114 | 50 | public function getPrintRequest() { |
|
115 | 50 | return $this->mPrintRequest; |
|
116 | } |
||
117 | |||
118 | /** |
||
119 | * Compatibility alias for getNextDatItem(). |
||
120 | * @deprecated since 1.6. Call getNextDataValue() or getNextDataItem() directly as needed. Method will vanish before SMW 1.7. |
||
121 | */ |
||
122 | public function getNextObject() { |
||
123 | return $this->getNextDataValue(); |
||
124 | } |
||
125 | |||
126 | /** |
||
127 | * Return the next SMWDataItem object or false if no further object exists. |
||
128 | * |
||
129 | * @since 1.6 |
||
130 | * |
||
131 | * @return SMWDataItem|false |
||
132 | */ |
||
133 | 81 | public function getNextDataItem() { |
|
134 | 81 | $this->loadContent(); |
|
135 | 81 | $result = current( $this->mContent ); |
|
136 | |||
137 | 81 | if ( $this->temporaryEntityListAccumulator !== null && $result instanceof DataItem ) { |
|
138 | 81 | $this->temporaryEntityListAccumulator->addToEntityList( null, $result ); |
|
139 | } |
||
140 | |||
141 | 81 | next( $this->mContent ); |
|
142 | 81 | return $result; |
|
143 | } |
||
144 | |||
145 | /** |
||
146 | * Set the internal pointer of the array of SMWDataItem objects to its first |
||
147 | * element. Return the first SMWDataItem object or false if the array is |
||
148 | * empty. |
||
149 | * |
||
150 | * @since 1.7.1 |
||
151 | * |
||
152 | * @return SMWDataItem|false |
||
153 | */ |
||
154 | public function reset() { |
||
155 | $this->loadContent(); |
||
156 | return reset( $this->mContent ); |
||
157 | } |
||
158 | |||
159 | /** |
||
160 | * Return an SMWDataValue object for the next SMWDataItem object or |
||
161 | * false if no further object exists. |
||
162 | * |
||
163 | * @since 1.6 |
||
164 | * |
||
165 | * @return SMWDataValue|false |
||
166 | */ |
||
167 | 78 | public function getNextDataValue() { |
|
168 | 78 | $dataItem = $this->getNextDataItem(); |
|
169 | |||
170 | 78 | if ( $dataItem === false ) { |
|
171 | 77 | return false; |
|
172 | } |
||
173 | |||
174 | 78 | if ( $this->mPrintRequest->getMode() == PrintRequest::PRINT_PROP && |
|
175 | 78 | strpos( $this->mPrintRequest->getTypeID(), '_rec' ) !== false && |
|
176 | 78 | $this->mPrintRequest->getParameter( 'index' ) !== false ) { |
|
177 | // Not efficient, but correct: we need to find the right property for |
||
178 | // the selected index of the record here. |
||
179 | 3 | $pos = $this->mPrintRequest->getParameter( 'index' ) - 1; |
|
180 | |||
181 | 3 | $recordValue = DataValueFactory::getInstance()->newDataValueByItem( |
|
182 | $dataItem, |
||
183 | 3 | $this->mPrintRequest->getData()->getDataItem() |
|
184 | ); |
||
185 | |||
186 | 3 | $diProperties = $recordValue->getPropertyDataItems(); |
|
0 ignored issues
–
show
|
|||
187 | |||
188 | 3 | if ( array_key_exists( $pos, $diProperties ) && |
|
189 | 3 | !is_null( $diProperties[$pos] ) ) { |
|
190 | 3 | $diProperty = $diProperties[$pos]; |
|
191 | } else { |
||
192 | 3 | $diProperty = null; |
|
193 | } |
||
194 | 78 | } elseif ( $this->mPrintRequest->getMode() == PrintRequest::PRINT_PROP ) { |
|
195 | 70 | $diProperty = $this->mPrintRequest->getData()->getDataItem(); |
|
196 | } else { |
||
197 | 53 | $diProperty = null; |
|
198 | } |
||
199 | |||
200 | // refs #1314 |
||
201 | 78 | if ( $this->mPrintRequest->getMode() == PrintRequest::PRINT_PROP && |
|
202 | 78 | strpos( $this->mPrintRequest->getTypeID(), '_txt' ) !== false && |
|
203 | 78 | $dataItem instanceof DIBlob ) { |
|
204 | 18 | $dataItem = new DIBlob( |
|
205 | 18 | InTextAnnotationParser::removeAnnotation( $dataItem->getString() ) |
|
206 | ); |
||
207 | } |
||
208 | |||
209 | 78 | $dataValue = DataValueFactory::getInstance()->newDataValueByItem( |
|
210 | $dataItem, |
||
211 | $diProperty |
||
212 | ); |
||
213 | |||
214 | 78 | $dataValue->setContextPage( |
|
215 | 78 | $this->mResult |
|
216 | ); |
||
217 | |||
218 | 78 | if ( $this->mPrintRequest->getOutputFormat() ) { |
|
219 | 15 | $dataValue->setOutputFormat( $this->mPrintRequest->getOutputFormat() ); |
|
220 | } |
||
221 | |||
222 | 78 | if ( $this->temporaryEntityListAccumulator !== null && $dataItem instanceof DataItem ) { |
|
223 | 78 | $this->temporaryEntityListAccumulator->addToEntityList( $diProperty, $dataItem ); |
|
224 | } |
||
225 | |||
226 | 78 | return $dataValue; |
|
227 | } |
||
228 | |||
229 | /** |
||
230 | * Return the main text representation of the next SMWDataItem object |
||
231 | * in the specified format, or false if no further object exists. |
||
232 | * |
||
233 | * The parameter $linker controls linking of title values and should |
||
234 | * be some Linker object (or NULL for no linking). |
||
235 | * |
||
236 | * @param integer $outputMode |
||
237 | * @param mixed $linker |
||
238 | * |
||
239 | * @return string|false |
||
240 | */ |
||
241 | 10 | public function getNextText( $outputMode, $linker = null ) { |
|
242 | 10 | $dataValue = $this->getNextDataValue(); |
|
243 | 10 | if ( $dataValue !== false ) { // Print data values. |
|
244 | 10 | return $dataValue->getShortText( $outputMode, $linker ); |
|
245 | } else { |
||
246 | 10 | return false; |
|
247 | } |
||
248 | } |
||
249 | |||
250 | /** |
||
251 | * Load results of the given print request and result subject. This is only |
||
252 | * done when needed. |
||
253 | */ |
||
254 | 81 | protected function loadContent() { |
|
255 | 81 | if ( $this->mContent !== false ) { |
|
256 | 80 | return; |
|
257 | } |
||
258 | |||
259 | 81 | switch ( $this->mPrintRequest->getMode() ) { |
|
260 | 81 | case PrintRequest::PRINT_THIS: // NOTE: The limit is ignored here. |
|
261 | 53 | $this->mContent = array( $this->mResult ); |
|
262 | 53 | break; |
|
263 | 75 | case PrintRequest::PRINT_CATS: |
|
264 | // Always recompute cache here to ensure output format is respected. |
||
265 | 3 | self::$catCache = $this->mStore->getPropertyValues( $this->mResult, |
|
266 | 3 | new SMW\DIProperty( '_INST' ), $this->getRequestOptions( false ) ); |
|
267 | 3 | self::$catCacheObj = $this->mResult->getHash(); |
|
268 | |||
269 | 3 | $limit = $this->mPrintRequest->getParameter( 'limit' ); |
|
270 | 3 | $this->mContent = ( $limit === false ) ? ( self::$catCache ) : |
|
271 | array_slice( self::$catCache, 0, $limit ); |
||
272 | 3 | break; |
|
273 | 74 | case PrintRequest::PRINT_PROP: |
|
274 | 74 | $propertyValue = $this->mPrintRequest->getData(); |
|
275 | 74 | if ( $propertyValue->isValid() ) { |
|
276 | 74 | $this->mContent = $this->mStore->getPropertyValues( $this->mResult, |
|
277 | 74 | $propertyValue->getDataItem(), $this->getRequestOptions() ); |
|
278 | } else { |
||
279 | $this->mContent = array(); |
||
280 | } |
||
281 | |||
282 | // Print one component of a multi-valued string. |
||
283 | // Known limitation: the printrequest still is of type _rec, so if printers check |
||
284 | // for this then they will not recognize that it returns some more concrete type. |
||
285 | 74 | if ( strpos( $this->mPrintRequest->getTypeID(), '_rec' ) !== false && |
|
286 | 74 | ( $this->mPrintRequest->getParameter( 'index' ) !== false ) ) { |
|
287 | 3 | $pos = $this->mPrintRequest->getParameter( 'index' ) - 1; |
|
288 | 3 | $newcontent = array(); |
|
289 | |||
290 | 3 | foreach ( $this->mContent as $diContainer ) { |
|
291 | 3 | /* SMWRecordValue */ $recordValue = DataValueFactory::getInstance()->newDataValueByItem( $diContainer, $propertyValue->getDataItem() ); |
|
292 | 3 | $dataItems = $recordValue->getDataItems(); |
|
0 ignored issues
–
show
|
|||
293 | |||
294 | 3 | if ( array_key_exists( $pos, $dataItems ) && |
|
295 | 3 | ( !is_null( $dataItems[$pos] ) ) ) { |
|
296 | 3 | $newcontent[] = $dataItems[$pos]; |
|
297 | } |
||
298 | } |
||
299 | |||
300 | 3 | $this->mContent = $newcontent; |
|
301 | } |
||
302 | 74 | break; |
|
303 | case PrintRequest::PRINT_CCAT: ///NOTE: The limit is ignored here. |
||
304 | if ( self::$catCacheObj != $this->mResult->getHash() ) { |
||
305 | self::$catCache = $this->mStore->getPropertyValues( $this->mResult, new SMW\DIProperty( '_INST' ) ); |
||
306 | self::$catCacheObj = $this->mResult->getHash(); |
||
307 | } |
||
308 | |||
309 | $found = false; |
||
310 | $prkey = $this->mPrintRequest->getData()->getDBkey(); |
||
311 | |||
312 | foreach ( self::$catCache as $cat ) { |
||
313 | if ( $cat->getDBkey() == $prkey ) { |
||
314 | $found = true; |
||
315 | break; |
||
316 | } |
||
317 | } |
||
318 | $this->mContent = array( new SMWDIBoolean( $found ) ); |
||
319 | break; |
||
320 | default: $this->mContent = array(); // Unknown print request. |
||
321 | } |
||
322 | |||
323 | 81 | reset( $this->mContent ); |
|
324 | |||
325 | 81 | } |
|
326 | |||
327 | /** |
||
328 | * Make a request option object based on the given parameters, and |
||
329 | * return NULL if no such object is required. The parameter defines |
||
330 | * if the limit should be taken into account, which is not always desired |
||
331 | * (especially if results are to be cached for future use). |
||
332 | * |
||
333 | * @param boolean $useLimit |
||
334 | * |
||
335 | * @return SMWRequestOptions|null |
||
336 | */ |
||
337 | 75 | protected function getRequestOptions( $useLimit = true ) { |
|
338 | 75 | $limit = $useLimit ? $this->mPrintRequest->getParameter( 'limit' ) : false; |
|
339 | 75 | $order = trim( $this->mPrintRequest->getParameter( 'order' ) ); |
|
340 | |||
341 | // Important: use "!=" for order, since trim() above does never return "false", use "!==" for limit since "0" is meaningful here. |
||
342 | 75 | if ( ( $limit !== false ) || ( $order != false ) ) { |
|
343 | 2 | $options = new SMWRequestOptions(); |
|
344 | |||
345 | 2 | if ( $limit !== false ) { |
|
346 | 1 | $options->limit = trim( $limit ); |
|
347 | } |
||
348 | |||
349 | 2 | if ( ( $order == 'descending' ) || ( $order == 'reverse' ) || ( $order == 'desc' ) ) { |
|
350 | 2 | $options->sort = true; |
|
351 | 2 | $options->ascending = false; |
|
352 | 1 | } elseif ( ( $order == 'ascending' ) || ( $order == 'asc' ) ) { |
|
353 | 1 | $options->sort = true; |
|
354 | 2 | $options->ascending = true; |
|
355 | } |
||
356 | } else { |
||
357 | 73 | $options = null; |
|
358 | } |
||
359 | |||
360 | 75 | return $options; |
|
361 | } |
||
362 | |||
363 | } |
||
364 |
This check marks calls to methods that do not seem to exist on an object.
This is most likely the result of a method being renamed without all references to it being renamed likewise.