These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | /** |
||
4 | * This group contains all parts of SMW that relate to the processing of datavalues |
||
5 | * of various types. |
||
6 | * |
||
7 | * @defgroup SMWDataValues SMWDataValues |
||
8 | * @ingroup SMW |
||
9 | */ |
||
10 | use SMW\ApplicationFactory; |
||
11 | use SMW\DataValues\ValueFormatterRegistry; |
||
12 | use SMW\DataValues\ValueValidatorRegistry; |
||
13 | use SMW\Deserializers\DVDescriptionDeserializerRegistry; |
||
14 | use SMW\Message; |
||
15 | use SMW\Options; |
||
16 | use SMW\Localizer; |
||
17 | use SMW\Query\QueryComparator; |
||
18 | |||
19 | /** |
||
20 | * Objects of this type represent all that is known about a certain user-provided |
||
21 | * data value, especially its various representations as strings, tooltips, |
||
22 | * numbers, etc. Objects can be created as "emtpy" containers of a certain type, |
||
23 | * but are then usually filled with data to present one particular data value. |
||
24 | * |
||
25 | * Data values have two chief representation forms: the user-facing syntax and the |
||
26 | * internal representation. In user syntax, every value is (necessarily) a single |
||
27 | * string, however complex the value is. For example, a string such as "Help:editing" |
||
28 | * may represent a wiki page called "Editing" in the namespace for "Help". The |
||
29 | * internal representation may be any numerical array of strings and numbers. In the |
||
30 | * example, it might be array("Editing",12), where 12 is the number used for identifying |
||
31 | * the namespace "Help:". Of course, the internal representation could also use a single |
||
32 | * string value, such as in array("Help:Editing"), but this might be less useful for |
||
33 | * certain operations (e.g. filterng by namespace). Moreover, all values that are |
||
34 | * restored from the database are given in the internal format, so it wise to choose a |
||
35 | * format that allows for very fast and easy processing without unnecessary parsing. |
||
36 | * |
||
37 | * The main functions of data value objects are: |
||
38 | * - setUserValue() which triggers parseUserValue() to process a user-level string. |
||
39 | * |
||
40 | * In addition, there are a number of get-functions that provide useful output versions |
||
41 | * for displaying and serializing the value. |
||
42 | * |
||
43 | * @ingroup SMWDataValues |
||
44 | * |
||
45 | * @author Markus Krötzsch |
||
46 | */ |
||
47 | abstract class SMWDataValue { |
||
48 | |||
49 | /** |
||
50 | * Associated data item. This is the reference to the immutable object |
||
51 | * that represents the current data content. All other data stored here |
||
52 | * is only about presentation and parsing, but is not relevant to the |
||
53 | * actual data that is represented (and stored later on). |
||
54 | * |
||
55 | * This variable must always be set to some data item, even if there |
||
56 | * have been errors in initialising the data. |
||
57 | * @var SMWDataItem |
||
58 | */ |
||
59 | protected $m_dataitem; |
||
60 | |||
61 | /** |
||
62 | * The property for which this value is constructed or null if none |
||
63 | * given. Property pages are used to make settings that affect parsing |
||
64 | * and display, hence it is sometimes needed to know them. |
||
65 | * |
||
66 | * @var SMWDIProperty |
||
67 | */ |
||
68 | protected $m_property = null; |
||
69 | |||
70 | /** |
||
71 | * Wiki page in the context of which the value is to be interpreted, or |
||
72 | * null if not given (or not on a page). This information is used to |
||
73 | * parse user values such as "#subsection" which only make sense when |
||
74 | * used on a certain page. |
||
75 | * |
||
76 | * @var SMWDIWikiPage |
||
77 | */ |
||
78 | protected $m_contextPage = null; |
||
79 | |||
80 | /** |
||
81 | * The text label to be used for output or false if none given. |
||
82 | * @var string |
||
83 | */ |
||
84 | protected $m_caption; |
||
85 | |||
86 | /** |
||
87 | * The type id for this value object. |
||
88 | * @var string |
||
89 | */ |
||
90 | protected $m_typeid; |
||
91 | |||
92 | /** |
||
93 | * Array of SMWInfolink objects. |
||
94 | * @var array |
||
95 | */ |
||
96 | protected $m_infolinks = array(); |
||
97 | |||
98 | /** |
||
99 | * Output formatting string, false when not set. |
||
100 | * @see setOutputFormat() |
||
101 | * @var mixed |
||
102 | */ |
||
103 | protected $m_outformat = false; |
||
104 | |||
105 | /** |
||
106 | * Used to control the addition of the standard search link. |
||
107 | * @var boolean |
||
108 | */ |
||
109 | private $mHasSearchLink; |
||
110 | |||
111 | /** |
||
112 | * Used to control service link creation. |
||
113 | * @var boolean |
||
114 | */ |
||
115 | private $mHasServiceLinks; |
||
116 | |||
117 | /** |
||
118 | * Array of error text messages. Private to allow us to track error insertion |
||
119 | * (PHP's count() is too slow when called often) by using $mHasErrors. |
||
120 | * @var array |
||
121 | */ |
||
122 | private $mErrors = array(); |
||
123 | |||
124 | /** |
||
125 | * Boolean indicating if there where any errors. |
||
126 | * Should be modified accordingly when modifying $mErrors. |
||
127 | * @var boolean |
||
128 | */ |
||
129 | private $mHasErrors = false; |
||
130 | |||
131 | /** |
||
132 | * @var boolean |
||
133 | */ |
||
134 | private $serviceLinksRenderState = true; |
||
135 | |||
136 | /** |
||
137 | * Extraneous services and object container |
||
138 | * |
||
139 | * @var array |
||
140 | */ |
||
141 | private $extraneousFunctions = array(); |
||
142 | |||
143 | /** |
||
144 | * @var Options |
||
145 | */ |
||
146 | private $options; |
||
147 | |||
148 | /** |
||
149 | * @var boolean |
||
150 | */ |
||
151 | protected $approximateValue = false; |
||
152 | |||
153 | /** |
||
154 | * @var ValueConstraintValidator |
||
155 | */ |
||
156 | private $valueConstraintValidator = null; |
||
157 | |||
158 | /** |
||
159 | * Constructor. |
||
160 | * |
||
161 | * @param string $typeid |
||
162 | */ |
||
163 | 205 | public function __construct( $typeid ) { |
|
164 | 205 | $this->m_typeid = $typeid; |
|
165 | 205 | } |
|
166 | |||
167 | ///// Set methods ///// |
||
168 | |||
169 | /** |
||
170 | * Set the user value (and compute other representations if possible). |
||
171 | * The given value is a string as supplied by some user. An alternative |
||
172 | * label for printout might also be specified. |
||
173 | * |
||
174 | * The third argument was added in SMW 1.9 and should not be used from outside SMW. |
||
175 | * |
||
176 | * @param string $value |
||
177 | * @param mixed $caption |
||
178 | * @param boolean $approximateValue |
||
179 | */ |
||
180 | 189 | public function setUserValue( $value, $caption = false, $approximateValue = false ) { |
|
181 | |||
182 | 189 | $this->m_dataitem = null; |
|
183 | 189 | $this->mErrors = array(); // clear errors |
|
184 | 189 | $this->mHasErrors = false; |
|
185 | 189 | $this->m_infolinks = array(); // clear links |
|
186 | 189 | $this->mHasSearchLink = false; |
|
187 | 189 | $this->mHasServiceLinks = false; |
|
188 | 189 | $this->m_caption = is_string( $caption ) ? trim( $caption ) : false; |
|
0 ignored issues
–
show
|
|||
189 | 189 | $this->approximateValue = $approximateValue; |
|
190 | |||
191 | |||
192 | 189 | $this->parseUserValue( $value ); // may set caption if not set yet, depending on datavalue |
|
193 | |||
194 | // The following checks for Strip markers generated by MediaWiki to handle special content, |
||
195 | // from parser and extension tags e.g. <pre>,<nowiki>,<math>,<source>. |
||
196 | // See https://en.wikipedia.org/wiki/Help:Strip_markers |
||
197 | // In general, we are not prepared to handle such content properly, and we |
||
198 | // also have no means of obtaining the user input at this point. Hence the assignment |
||
199 | // just fails, even if parseUserValue() above might not have noticed this issue. |
||
200 | // Note: \x07 was used in MediaWiki 1.11.0, \x7f is used now (backwards compatiblity, b/c) |
||
201 | 189 | if ( ( strpos( $value, "\x7f" ) !== false ) || ( strpos( $value, "\x07" ) !== false ) ) { |
|
202 | $this->addError( wfMessage( 'smw_parseerror' )->inContentLanguage()->text() ); |
||
203 | } |
||
204 | |||
205 | 189 | if ( $this->isValid() && !$approximateValue ) { |
|
206 | 188 | $this->checkAllowedValues(); |
|
207 | } |
||
208 | |||
209 | 189 | } |
|
210 | |||
211 | /** |
||
212 | * Set the actual data contained in this object. The method returns |
||
213 | * true if this was successful (requiring the type of the dataitem |
||
214 | * to match the data value). If false is returned, the data value is |
||
215 | * left unchanged (the data item was rejected). |
||
216 | * |
||
217 | * @note Even if this function returns true, the data value object |
||
218 | * might become invalid if the content of the data item caused errors |
||
219 | * in spite of it being of the right basic type. False is only returned |
||
220 | * if the data item is fundamentally incompatible with the data value. |
||
221 | * |
||
222 | * @param $dataitem SMWDataItem |
||
223 | * @return boolean |
||
224 | */ |
||
225 | 146 | public function setDataItem( SMWDataItem $dataItem ) { |
|
226 | 146 | $this->m_dataitem = null; |
|
227 | 146 | $this->mErrors = $this->m_infolinks = array(); |
|
228 | 146 | $this->mHasErrors = $this->mHasSearchLink = $this->mHasServiceLinks = $this->m_caption = false; |
|
229 | 146 | return $this->loadDataItem( $dataItem ); |
|
230 | } |
||
231 | |||
232 | /** |
||
233 | * Specify the property to which this value refers. Property pages are |
||
234 | * used to make settings that affect parsing and display, hence it is |
||
235 | * sometimes needed to know them. |
||
236 | * |
||
237 | * @since 1.6 |
||
238 | * |
||
239 | * @param SMWDIProperty $property |
||
240 | */ |
||
241 | 184 | public function setProperty( SMWDIProperty $property ) { |
|
242 | 184 | $this->m_property = $property; |
|
243 | 184 | } |
|
244 | |||
245 | /** |
||
246 | * Returns the property to which this value refers. |
||
247 | * |
||
248 | * @since 1.8 |
||
249 | * |
||
250 | * @return SMWDIProperty|null |
||
251 | */ |
||
252 | 198 | public function getProperty() { |
|
253 | 198 | return $this->m_property; |
|
254 | } |
||
255 | |||
256 | /** |
||
257 | * Specify the wiki page to which this value refers. This information is |
||
258 | * used to parse user values such as "#subsection" which only make sense |
||
259 | * when used on a certain page. |
||
260 | * |
||
261 | * @since 1.7 |
||
262 | * |
||
263 | * @param SMWDIWikiPage|null $contextPage |
||
264 | */ |
||
265 | 180 | public function setContextPage( SMWDIWikiPage $contextPage = null ) { |
|
266 | 180 | $this->m_contextPage = $contextPage; |
|
267 | |||
268 | 180 | $this->setOption( |
|
269 | 180 | 'content.language', |
|
270 | 180 | Localizer::getInstance()->getPreferredContentLanguage( $contextPage )->getCode() |
|
271 | ); |
||
272 | 180 | } |
|
273 | |||
274 | /** |
||
275 | * @since 2.4 |
||
276 | * |
||
277 | * @return DIWikiPage|null |
||
278 | */ |
||
279 | 173 | public function getContextPage() { |
|
280 | 173 | return $this->m_contextPage; |
|
281 | } |
||
282 | |||
283 | /** |
||
284 | * @since 2.4 |
||
285 | * |
||
286 | * @return Options $options |
||
287 | */ |
||
288 | 202 | public function setOptions( Options $options ) { |
|
289 | 202 | foreach ( $options->getOptions() as $key => $value ) { |
|
290 | 202 | $this->setOption( $key, $value ); |
|
291 | } |
||
292 | 202 | } |
|
293 | |||
294 | /** |
||
295 | * @since 2.4 |
||
296 | * |
||
297 | * @return string $key |
||
298 | * @param mxied $value |
||
299 | */ |
||
300 | 202 | public function setOption( $key, $value ) { |
|
301 | |||
302 | 202 | if ( $this->options === null ) { |
|
303 | 202 | $this->options = new Options(); |
|
304 | } |
||
305 | |||
306 | 202 | $this->options->set( $key, $value ); |
|
307 | 202 | } |
|
308 | |||
309 | /** |
||
310 | * @since 2.4 |
||
311 | * |
||
312 | * @param string $key |
||
313 | * |
||
314 | * @return mixed|false |
||
315 | */ |
||
316 | 187 | public function getOptionValueFor( $key ) { |
|
317 | |||
318 | 187 | if ( $this->options !== null && $this->options->has( $key ) ) { |
|
319 | 187 | return $this->options->get( $key ); |
|
320 | } |
||
321 | |||
322 | 60 | return false; |
|
323 | } |
||
324 | |||
325 | /** |
||
326 | * @since 2.4 |
||
327 | * |
||
328 | * @param integer $feature |
||
329 | * |
||
330 | * @return boolean |
||
331 | */ |
||
332 | 185 | public function isEnabledFeature( $feature ) { |
|
333 | 185 | return ( $this->getOptionValueFor( 'smwgDVFeatures' ) & $feature ) != 0; |
|
334 | } |
||
335 | |||
336 | /** |
||
337 | * Change the caption (the text used for displaying this datavalue). The given |
||
338 | * value must be a string. |
||
339 | * |
||
340 | * @param string $caption |
||
341 | */ |
||
342 | 92 | public function setCaption( $caption ) { |
|
343 | 92 | $this->m_caption = $caption; |
|
344 | 92 | } |
|
345 | |||
346 | /** |
||
347 | * @since 2.4 |
||
348 | * |
||
349 | * @param string $caption |
||
350 | */ |
||
351 | 85 | public function getCaption() { |
|
352 | 85 | return $this->m_caption; |
|
353 | } |
||
354 | |||
355 | /** |
||
356 | * Adds a single SMWInfolink object to the m_infolinks array. |
||
357 | * |
||
358 | * @param SMWInfolink $link |
||
359 | */ |
||
360 | public function addInfolink( SMWInfolink $link ) { |
||
361 | $this->m_infolinks[] = $link; |
||
362 | } |
||
363 | |||
364 | /** |
||
365 | * Servicelinks are special kinds of infolinks that are created from |
||
366 | * current parameters and in-wiki specification of URL templates. This |
||
367 | * method adds the current property's servicelinks found in the |
||
368 | * messages. The number and content of the parameters is depending on |
||
369 | * the datatype, and the service link message is usually crafted with a |
||
370 | * particular datatype in mind. |
||
371 | */ |
||
372 | 3 | public function addServiceLinks() { |
|
373 | 3 | if ( $this->mHasServiceLinks ) { |
|
374 | return; |
||
375 | } |
||
376 | |||
377 | 3 | if ( !is_null( $this->m_property ) ) { |
|
378 | 3 | $propertyDiWikiPage = $this->m_property->getDiWikiPage(); |
|
379 | } |
||
380 | |||
381 | 3 | if ( is_null( $this->m_property ) || is_null( $propertyDiWikiPage ) ) { |
|
382 | return; // no property known, or not associated with a page |
||
383 | } |
||
384 | |||
385 | 3 | $args = $this->getServiceLinkParams(); |
|
386 | |||
387 | 3 | if ( $args === false ) { |
|
388 | 3 | return; // no services supported |
|
389 | } |
||
390 | |||
391 | array_unshift( $args, '' ); // add a 0 element as placeholder |
||
392 | $servicelinks = \SMW\StoreFactory::getStore()->getPropertyValues( $propertyDiWikiPage, new SMW\DIProperty( '_SERV' ) ); |
||
393 | |||
394 | foreach ( $servicelinks as $dataItem ) { |
||
395 | if ( !( $dataItem instanceof SMWDIBlob ) ) { |
||
396 | continue; |
||
397 | } |
||
398 | |||
399 | $args[0] = 'smw_service_' . str_replace( ' ', '_', $dataItem->getString() ); // messages distinguish ' ' from '_' |
||
400 | $text = call_user_func_array( 'wfMessage', $args )->inContentLanguage()->text(); |
||
401 | $links = preg_split( "/[\n][\s]?/u", $text ); |
||
402 | |||
403 | foreach ( $links as $link ) { |
||
404 | $linkdat = explode( '|', $link, 2 ); |
||
405 | |||
406 | if ( count( $linkdat ) == 2 ) { |
||
407 | $this->addInfolink( SMWInfolink::newExternalLink( $linkdat[0], trim( $linkdat[1] ) ) ); |
||
408 | } |
||
409 | } |
||
410 | } |
||
411 | $this->mHasServiceLinks = true; |
||
412 | } |
||
413 | |||
414 | /** |
||
415 | * Define a particular output format. Output formats are user-supplied strings |
||
416 | * that the datavalue may (or may not) use to customise its return value. For |
||
417 | * example, quantities with units of measurement may interpret the string as |
||
418 | * a desired output unit. In other cases, the output format might be built-in |
||
419 | * and subject to internationalisation (which the datavalue has to implement). |
||
420 | * In any case, an empty string resets the output format to the default. |
||
421 | * |
||
422 | * There is one predefined output format that all datavalues should respect: the |
||
423 | * format '-' indicates "plain" output that is most useful for further processing |
||
424 | * the value in a template. It should not use any wiki markup or beautification, |
||
425 | * and it should also avoid localization to the current language. When users |
||
426 | * explicitly specify an empty format string in a query, it is normalized to "-" |
||
427 | * to avoid confusion. Note that empty format strings are not interpreted in |
||
428 | * this way when directly passed to this function. |
||
429 | * |
||
430 | * @param string $formatString |
||
431 | */ |
||
432 | 94 | public function setOutputFormat( $formatString ) { |
|
433 | 94 | $this->m_outformat = $formatString; // just store it, subclasses may or may not use this |
|
434 | 94 | } |
|
435 | |||
436 | /** |
||
437 | * @since 2.4 |
||
438 | * |
||
439 | * @return string |
||
440 | */ |
||
441 | 46 | public function getOutputFormat() { |
|
442 | 46 | return $this->m_outformat; |
|
443 | } |
||
444 | |||
445 | /** |
||
446 | * Add a new error string or array of such strings to the error list. |
||
447 | * |
||
448 | * @note Errors should not be escaped here in any way, in contradiction to what |
||
449 | * the docs used to say here in 1.5 and before. Escaping should happen at the output. |
||
450 | * |
||
451 | * @param mixed $error A single string, or array of strings. |
||
452 | */ |
||
453 | 116 | public function addError( $error ) { |
|
454 | 116 | if ( is_array( $error ) ) { |
|
455 | 94 | $this->mErrors = array_merge( $this->mErrors, $error ); |
|
456 | 94 | $this->mHasErrors = $this->mHasErrors || ( count( $error ) > 0 ); |
|
457 | } else { |
||
458 | 32 | $this->mErrors[] = $error; |
|
459 | 32 | $this->mHasErrors = true; |
|
460 | } |
||
461 | 116 | } |
|
462 | |||
463 | /** |
||
464 | * @since 2.4 |
||
465 | * |
||
466 | * @param $parameters |
||
467 | * @param integer|null $type |
||
468 | * @param integer|null $language |
||
469 | */ |
||
470 | 19 | public function addErrorMsg( $parameters, $type = null, $language = null ) { |
|
471 | 19 | $this->addError( Message::get( $parameters, $type, $language ) ); |
|
472 | 19 | } |
|
473 | |||
474 | /** |
||
475 | * @since 2.4 |
||
476 | */ |
||
477 | public function clearErrors() { |
||
478 | $this->mErrors = array(); |
||
479 | $this->mHasErrors = false; |
||
480 | } |
||
481 | |||
482 | ///// Abstract processing methods ///// |
||
483 | |||
484 | /** |
||
485 | * Initialise the datavalue from the given value string. |
||
486 | * The format of this strings might be any acceptable user input |
||
487 | * and especially includes the output of getWikiValue(). |
||
488 | * |
||
489 | * @param string $value |
||
490 | */ |
||
491 | abstract protected function parseUserValue( $value ); |
||
492 | |||
493 | /** |
||
494 | * Set the actual data contained in this object. The method returns |
||
495 | * true if this was successful (requiring the type of the dataitem |
||
496 | * to match the data value). If false is returned, the data value is |
||
497 | * left unchanged (the data item was rejected). |
||
498 | * |
||
499 | * @note Even if this function returns true, the data value object |
||
500 | * might become invalid if the content of the data item caused errors |
||
501 | * in spite of it being of the right basic type. False is only returned |
||
502 | * if the data item is fundamentally incompatible with the data value. |
||
503 | * |
||
504 | * @since 1.6 |
||
505 | * |
||
506 | * @param SMWDataItem $dataItem |
||
507 | * |
||
508 | * @return boolean |
||
509 | */ |
||
510 | abstract protected function loadDataItem( SMWDataItem $dataItem ); |
||
511 | |||
512 | |||
513 | ///// Query support ///// |
||
514 | |||
515 | /** |
||
516 | * @see DataValueDescriptionDeserializer::deserialize |
||
517 | * |
||
518 | * @note Descriptions of values need to know their property to be able to |
||
519 | * create a parsable wikitext version of a query condition again. Thus it |
||
520 | * might be necessary to call setProperty() before using this method. |
||
521 | * |
||
522 | * @param string $value |
||
523 | * |
||
524 | * @return Description |
||
525 | * @throws InvalidArgumentException |
||
526 | */ |
||
527 | 93 | public function getQueryDescription( $value ) { |
|
528 | |||
529 | 93 | $descriptionDeserializer = DVDescriptionDeserializerRegistry::getInstance()->getDescriptionDeserializerFor( $this ); |
|
530 | 93 | $description = $descriptionDeserializer->deserialize( $value ); |
|
531 | |||
532 | 93 | foreach ( $descriptionDeserializer->getErrors() as $error ) { |
|
533 | 1 | $this->addError( $error ); |
|
534 | } |
||
535 | |||
536 | 93 | return $description; |
|
537 | } |
||
538 | |||
539 | /** |
||
540 | * Returns a DataValueFormatter that was matched and dispatched for the current |
||
541 | * DV instance. |
||
542 | * |
||
543 | * @since 2.4 |
||
544 | * |
||
545 | * @return DataValueFormatter |
||
546 | */ |
||
547 | 115 | public function getDataValueFormatter() { |
|
548 | 115 | return ValueFormatterRegistry::getInstance()->getDataValueFormatterFor( $this ); |
|
549 | } |
||
550 | |||
551 | /** |
||
552 | * @since 2.4 |
||
553 | * |
||
554 | * @return PropertySpecificationLookup |
||
555 | */ |
||
556 | 174 | public function getPropertySpecificationLookup() { |
|
557 | 174 | return ApplicationFactory::getInstance()->getPropertySpecificationLookup(); |
|
558 | } |
||
559 | |||
560 | /** |
||
561 | * @deprecated 2.3 |
||
562 | * @see DescriptionDeserializer::prepareValue |
||
563 | * |
||
564 | * This method should no longer be used for direct public access, instead a |
||
565 | * DataValue is expected to register a DescriptionDeserializer with |
||
566 | * DVDescriptionDeserializerRegistry. |
||
567 | * |
||
568 | * FIXME as of 2.3, SMGeoCoordsValue still uses this method and requires |
||
569 | * migration before 3.0 |
||
570 | */ |
||
571 | static public function prepareValue( &$value, &$comparator ) { |
||
572 | $comparator = QueryComparator::getInstance()->extractComparatorFromString( $value ); |
||
573 | } |
||
574 | |||
575 | ///// Get methods ///// |
||
576 | |||
577 | /** |
||
578 | * Get the actual data contained in this object or null if the data is |
||
579 | * not defined (due to errors or due to not being set at all). |
||
580 | * @note Most implementations ensure that a data item is always set, |
||
581 | * even if errors occurred, to avoid additional checks for not |
||
582 | * accessing null. Hence, one must not assume that a non-null return |
||
583 | * value here implies that isValid() returns true. |
||
584 | * |
||
585 | * @since 1.6 |
||
586 | * |
||
587 | * @return SMWDataItem|SMWDIError |
||
588 | */ |
||
589 | 191 | public function getDataItem() { |
|
590 | |||
591 | 191 | if ( $this->isValid() ) { |
|
592 | 191 | return $this->m_dataitem; |
|
593 | } |
||
594 | |||
595 | 1 | return new SMWDIError( $this->mErrors ); |
|
596 | } |
||
597 | |||
598 | /** |
||
599 | * @since 2.2 |
||
600 | * |
||
601 | * @return string |
||
602 | */ |
||
603 | public function __toString() { |
||
604 | return $this->getDataItem()->getSerialization(); |
||
605 | } |
||
606 | |||
607 | /** |
||
608 | * Returns a short textual representation for this data value. If the value |
||
609 | * was initialised from a user supplied string, then this original string |
||
610 | * should be reflected in this short version (i.e. no normalisation should |
||
611 | * normally happen). There might, however, be additional parts such as code |
||
612 | * for generating tooltips. The output is in wiki text. |
||
613 | * |
||
614 | * The parameter $linked controls linking of values such as titles and should |
||
615 | * be non-NULL and non-false if this is desired. |
||
616 | */ |
||
617 | abstract public function getShortWikiText( $linked = null ); |
||
618 | |||
619 | /** |
||
620 | * Returns a short textual representation for this data value. If the value |
||
621 | * was initialised from a user supplied string, then this original string |
||
622 | * should be reflected in this short version (i.e. no normalisation should |
||
623 | * normally happen). There might, however, be additional parts such as code |
||
624 | * for generating tooltips. The output is in HTML text. |
||
625 | * |
||
626 | * The parameter $linker controls linking of values such as titles and should |
||
627 | * be some Linker object (or NULL for no linking). |
||
628 | */ |
||
629 | abstract public function getShortHTMLText( $linker = null ); |
||
630 | |||
631 | /** |
||
632 | * Return the long textual description of the value, as printed for |
||
633 | * example in the factbox. If errors occurred, return the error message |
||
634 | * The result always is a wiki-source string. |
||
635 | * |
||
636 | * The parameter $linked controls linking of values such as titles and should |
||
637 | * be non-NULL and non-false if this is desired. |
||
638 | */ |
||
639 | abstract public function getLongWikiText( $linked = null ); |
||
640 | |||
641 | /** |
||
642 | * Return the long textual description of the value, as printed for |
||
643 | * example in the factbox. If errors occurred, return the error message |
||
644 | * The result always is an HTML string. |
||
645 | * |
||
646 | * The parameter $linker controls linking of values such as titles and should |
||
647 | * be some Linker object (or NULL for no linking). |
||
648 | */ |
||
649 | abstract public function getLongHTMLText( $linker = null ); |
||
650 | |||
651 | /** |
||
652 | * Returns a short textual representation for this data value. If the value |
||
653 | * was initialised from a user supplied string, then this original string |
||
654 | * should be reflected in this short version (i.e. no normalisation should |
||
655 | * normally happen). There might, however, be additional parts such as code |
||
656 | * for generating tooltips. The output is in the specified format. |
||
657 | * |
||
658 | * The parameter $linker controls linking of values such as titles and should |
||
659 | * be some Linker object (for HTML output), or NULL for no linking. |
||
660 | */ |
||
661 | 47 | public function getShortText( $outputformat, $linker = null ) { |
|
662 | switch ( $outputformat ) { |
||
663 | 47 | case SMW_OUTPUT_WIKI: |
|
664 | 47 | return $this->getShortWikiText( $linker ); |
|
665 | case SMW_OUTPUT_HTML: |
||
666 | case SMW_OUTPUT_FILE: |
||
667 | default: |
||
668 | return $this->getShortHTMLText( $linker ); |
||
669 | } |
||
670 | } |
||
671 | |||
672 | /** |
||
673 | * Return the long textual description of the value, as printed for |
||
674 | * example in the factbox. If errors occurred, return the error message. |
||
675 | * The output is in the specified format. |
||
676 | * |
||
677 | * The parameter $linker controls linking of values such as titles and should |
||
678 | * be some Linker object (for HTML output), or NULL for no linking. |
||
679 | */ |
||
680 | public function getLongText( $outputformat, $linker = null ) { |
||
681 | switch ( $outputformat ) { |
||
682 | case SMW_OUTPUT_WIKI: |
||
683 | return $this->getLongWikiText( $linker ); |
||
684 | case SMW_OUTPUT_HTML: |
||
685 | case SMW_OUTPUT_FILE: |
||
686 | default: |
||
687 | return $this->getLongHTMLText( $linker ); |
||
688 | } |
||
689 | } |
||
690 | |||
691 | /** |
||
692 | * Return text serialisation of info links. Ensures more uniform layout |
||
693 | * throughout wiki (Factbox, Property pages, ...). |
||
694 | * |
||
695 | * @param integer $outputformat Element of the SMW_OUTPUT_ enum |
||
696 | * @param $linker |
||
697 | * |
||
698 | * @return string |
||
699 | */ |
||
700 | 4 | public function getInfolinkText( $outputformat, $linker = null ) { |
|
701 | 4 | $result = ''; |
|
702 | 4 | $first = true; |
|
703 | 4 | $extralinks = array(); |
|
704 | |||
705 | switch ( $outputformat ) { |
||
706 | 4 | case SMW_OUTPUT_WIKI: |
|
707 | 1 | foreach ( $this->getInfolinks() as $link ) { |
|
708 | 1 | if ( $first ) { |
|
709 | 1 | $result .= '<!-- --> ' . $link->getWikiText(); |
|
710 | // the comment is needed to prevent MediaWiki from linking URL-strings together with the nbsps! |
||
711 | 1 | $first = false; |
|
712 | } else { |
||
713 | 1 | $extralinks[] = $link->getWikiText(); |
|
714 | } |
||
715 | } |
||
716 | 1 | break; |
|
717 | |||
718 | 3 | case SMW_OUTPUT_HTML: case SMW_OUTPUT_FILE: default: |
|
0 ignored issues
–
show
The case body in a switch statement must start on the line following the statement.
According to the PSR-2, the body of a case statement must start on the line immediately following the case statement. switch ($expr) {
case "A":
doSomething(); //right
break;
case "B":
doSomethingElse(); //wrong
break;
} To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.
Loading history...
|
|||
719 | 3 | foreach ( $this->getInfolinks() as $link ) { |
|
720 | 3 | if ( $first ) { |
|
721 | 3 | $result .= '  ' . $link->getHTML( $linker ); |
|
722 | 3 | $first = false; |
|
723 | } else { |
||
724 | 3 | $extralinks[] = $link->getHTML( $linker ); |
|
725 | } |
||
726 | } |
||
727 | 3 | break; |
|
728 | } |
||
729 | |||
730 | 4 | if ( count( $extralinks ) > 0 ) { |
|
731 | $result .= smwfEncodeMessages( $extralinks, 'service', '', false ); |
||
732 | } |
||
733 | |||
734 | // #1453 SMW::on/off will break any potential link therefore just don't even try |
||
735 | 4 | return strpos( $result, 'SMW::off' ) !== false || strpos( $result, 'SMW::on' ) !== false ? '' : $result; |
|
736 | } |
||
737 | |||
738 | /** |
||
739 | * Return the plain wiki version of the value, or |
||
740 | * FALSE if no such version is available. The returned |
||
741 | * string suffices to reobtain the same DataValue |
||
742 | * when passing it as an input string to setUserValue(). |
||
743 | */ |
||
744 | abstract public function getWikiValue(); |
||
745 | |||
746 | /** |
||
747 | * Return a short string that unambiguously specify the type of this |
||
748 | * value. This value will globally be used to identify the type of a |
||
749 | * value (in spite of the class it actually belongs to, which can still |
||
750 | * implement various types). |
||
751 | */ |
||
752 | 128 | public function getTypeID() { |
|
753 | 128 | return $this->m_typeid; |
|
754 | } |
||
755 | |||
756 | /** |
||
757 | * @since 2.1 |
||
758 | * @param boolean $renderState |
||
759 | */ |
||
760 | 1 | public function setServiceLinksRenderState( $renderState = true ) { |
|
761 | 1 | $this->serviceLinksRenderState = $renderState; |
|
762 | 1 | } |
|
763 | |||
764 | /** |
||
765 | * Return an array of SMWLink objects that provide additional resources |
||
766 | * for the given value. Captions can contain some HTML markup which is |
||
767 | * admissible for wiki text, but no more. Result might have no entries |
||
768 | * but is always an array. |
||
769 | */ |
||
770 | 4 | public function getInfolinks() { |
|
771 | 4 | if ( $this->isValid() && !is_null( $this->m_property ) ) { |
|
772 | 4 | if ( !$this->mHasSearchLink ) { // add default search link |
|
773 | 4 | $this->mHasSearchLink = true; |
|
774 | 4 | $this->m_infolinks[] = SMWInfolink::newPropertySearchLink( '+', |
|
775 | 4 | $this->m_property->getLabel(), $this->getWikiValue() ); |
|
776 | } |
||
777 | |||
778 | 4 | if ( !$this->mHasServiceLinks && $this->serviceLinksRenderState ) { // add further service links |
|
779 | 3 | $this->addServiceLinks(); |
|
780 | } |
||
781 | } |
||
782 | |||
783 | 4 | return $this->m_infolinks; |
|
784 | } |
||
785 | |||
786 | /** |
||
787 | * Overwritten by callers to supply an array of parameters that can be used for |
||
788 | * creating servicelinks. The number and content of values in the parameter array |
||
789 | * may vary, depending on the concrete datatype. |
||
790 | */ |
||
791 | 3 | protected function getServiceLinkParams() { |
|
792 | 3 | return false; |
|
793 | } |
||
794 | |||
795 | /** |
||
796 | * Return a string that identifies the value of the object, and that can |
||
797 | * be used to compare different value objects. |
||
798 | * Possibly overwritten by subclasses (e.g. to ensure that returned |
||
799 | * value is normalized first) |
||
800 | * |
||
801 | * @return string |
||
802 | */ |
||
803 | public function getHash() { |
||
804 | return $this->isValid() ? $this->m_dataitem->getHash() : implode( "\t", $this->mErrors ); |
||
805 | } |
||
806 | |||
807 | /** |
||
808 | * Convenience method that checks if the value that is used to sort |
||
809 | * data of this type is numeric. This only works if the value is set. |
||
810 | * |
||
811 | * @return boolean |
||
812 | */ |
||
813 | public function isNumeric() { |
||
814 | if ( isset( $this->m_dataitem ) ) { |
||
815 | return is_numeric( $this->m_dataitem->getSortKey() ); |
||
816 | } else { |
||
817 | return false; |
||
818 | } |
||
819 | } |
||
820 | |||
821 | /** |
||
822 | * Return true if a value was defined and understood by the given type, |
||
823 | * and false if parsing errors occurred or no value was given. |
||
824 | * |
||
825 | * @return boolean |
||
826 | */ |
||
827 | 201 | public function isValid() { |
|
828 | 201 | return !$this->mHasErrors && isset( $this->m_dataitem ); |
|
829 | } |
||
830 | |||
831 | /** |
||
832 | * Whether a datavalue can be used or not (can be made more restrictive then |
||
833 | * isValid). |
||
834 | * |
||
835 | * @note Validity defines a processable state without any technical restrictions |
||
836 | * while usability is determined by its accessibility to a context |
||
837 | * (permission, convention etc.) |
||
838 | * |
||
839 | * @since 2.2 |
||
840 | * |
||
841 | * @return boolean |
||
842 | */ |
||
843 | 162 | public function canUse() { |
|
844 | 162 | return true; |
|
845 | } |
||
846 | |||
847 | /** |
||
848 | * @note Normally set by the DataValueFactory, or during tests |
||
849 | * |
||
850 | * @since 2.3 |
||
851 | * |
||
852 | * @param array |
||
853 | */ |
||
854 | 202 | public function setExtraneousFunctions( array $extraneousFunctions ) { |
|
855 | 202 | $this->extraneousFunctions = $extraneousFunctions; |
|
856 | 202 | } |
|
857 | |||
858 | /** |
||
859 | * @since 2.3 |
||
860 | * |
||
861 | * @param string $name |
||
862 | * @param array $parameters |
||
863 | * |
||
864 | * @return mixed |
||
865 | * @throws RuntimeException |
||
866 | */ |
||
867 | public function getExtraneousFunctionFor( $name, array $parameters = array() ) { |
||
868 | |||
869 | if ( isset( $this->extraneousFunctions[$name] ) && is_callable( $this->extraneousFunctions[$name] ) ) { |
||
870 | return call_user_func_array( $this->extraneousFunctions[$name], $parameters ); |
||
871 | } |
||
872 | |||
873 | throw new RuntimeException( "$name is not registered as extraneous function." ); |
||
874 | } |
||
875 | |||
876 | /** |
||
877 | * Return a string that displays all error messages as a tooltip, or |
||
878 | * an empty string if no errors happened. |
||
879 | * |
||
880 | * @return string |
||
881 | */ |
||
882 | 13 | public function getErrorText() { |
|
883 | 13 | return smwfEncodeMessages( $this->mErrors ); |
|
884 | } |
||
885 | |||
886 | /** |
||
887 | * Return an array of error messages, or an empty array |
||
888 | * if no errors occurred. |
||
889 | * |
||
890 | * @return array |
||
891 | */ |
||
892 | 158 | public function getErrors() { |
|
893 | 158 | return $this->mErrors; |
|
894 | } |
||
895 | |||
896 | /** |
||
897 | * Check if property is range restricted and, if so, whether the current value is allowed. |
||
898 | * Creates an error if the value is illegal. |
||
899 | */ |
||
900 | 188 | protected function checkAllowedValues() { |
|
901 | 188 | ValueValidatorRegistry::getInstance()->getConstraintValueValidator()->validate( $this ); |
|
902 | 188 | } |
|
903 | |||
904 | /** |
||
905 | * @since 2.4 |
||
906 | * |
||
907 | * @param string $value |
||
908 | * |
||
909 | * @return string |
||
910 | */ |
||
911 | 36 | protected function convertDoubleWidth( $value ) { |
|
912 | 36 | return Localizer::convertDoubleWidth( $value ); |
|
913 | } |
||
914 | |||
915 | } |
||
916 |
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.
For example, imagine you have a variable
$accountId
that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to theid
property of an instance of theAccount
class. This class holds a proper account, so the id value must no longer be false.Either this assignment is in error or a type check should be added for that assignment.