Completed
Push — master ( f6d793...f59128 )
by mw
15s
created

SMWDataValue::getLanguageCode()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 1
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\Query\QueryComparator;
17
18
/**
19
 * Objects of this type represent all that is known about a certain user-provided
20
 * data value, especially its various representations as strings, tooltips,
21
 * numbers, etc.  Objects can be created as "emtpy" containers of a certain type,
22
 * but are then usually filled with data to present one particular data value.
23
 *
24
 * Data values have two chief representation forms: the user-facing syntax and the
25
 * internal representation. In user syntax, every value is (necessarily) a single
26
 * string, however complex the value is. For example, a string such as "Help:editing"
27
 * may represent a wiki page called "Editing" in the namespace for "Help". The
28
 * internal representation may be any numerical array of strings and numbers. In the
29
 * example, it might be array("Editing",12), where 12 is the number used for identifying
30
 * the namespace "Help:". Of course, the internal representation could also use a single
31
 * string value, such as in array("Help:Editing"), but this might be less useful for
32
 * certain operations (e.g. filterng by namespace). Moreover, all values that are
33
 * restored from the database are given in the internal format, so it wise to choose a
34
 * format that allows for very fast and easy processing without unnecessary parsing.
35
 *
36
 * The main functions of data value objects are:
37
 * - setUserValue() which triggers parseUserValue() to process a user-level string.
38
 *
39
 * In addition, there are a number of get-functions that provide useful output versions
40
 * for displaying and serializing the value.
41
 *
42
 * @ingroup SMWDataValues
43
 *
44
 * @author Markus Krötzsch
45
 */
46
abstract class SMWDataValue {
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
47
48
	/**
49
	 * Associated data item. This is the reference to the immutable object
50
	 * that represents the current data content. All other data stored here
51
	 * is only about presentation and parsing, but is not relevant to the
52
	 * actual data that is represented (and stored later on).
53
	 *
54
	 * This variable must always be set to some data item, even if there
55
	 * have been errors in initialising the data.
56
	 * @var SMWDataItem
57
	 */
58
	protected $m_dataitem;
59
60
	/**
61
	 * The property for which this value is constructed or null if none
62
	 * given. Property pages are used to make settings that affect parsing
63
	 * and display, hence it is sometimes needed to know them.
64
	 *
65
	 * @var SMWDIProperty
66
	 */
67
	protected $m_property = null;
68
69
	/**
70
	 * Wiki page in the context of which the value is to be interpreted, or
71
	 * null if not given (or not on a page). This information is used to
72
	 * parse user values such as "#subsection" which only make sense when
73
	 * used on a certain page.
74
	 *
75
	 * @var SMWDIWikiPage
76
	 */
77
	protected $m_contextPage = null;
78
79
	/**
80
	 * The text label to be used for output or false if none given.
81
	 * @var string
82
	 */
83
	protected $m_caption;
84
85
	/**
86
	 * The type id for this value object.
87
	 * @var string
88
	 */
89
	protected $m_typeid;
90
91
	/**
92
	 * Array of SMWInfolink objects.
93
	 * @var array
94
	 */
95
	protected $m_infolinks = array();
96
97
	/**
98
	 * Output formatting string, false when not set.
99
	 * @see setOutputFormat()
100
	 * @var mixed
101
	 */
102
	protected $m_outformat = false;
103
104
	/**
105
	 * @var string
106
	 */
107
	private $languageCode = '';
108
109
	/**
110
	 * Used to control the addition of the standard search link.
111
	 * @var boolean
112
	 */
113
	private $mHasSearchLink;
114
115
	/**
116
	 * Used to control service link creation.
117
	 * @var boolean
118
	 */
119
	private $mHasServiceLinks;
120
121
	/**
122
	 * Array of error text messages. Private to allow us to track error insertion
123
	 * (PHP's count() is too slow when called often) by using $mHasErrors.
124
	 * @var array
125
	 */
126
	private $mErrors = array();
127
128
	/**
129
	 * Boolean indicating if there where any errors.
130
	 * Should be modified accordingly when modifying $mErrors.
131
	 * @var boolean
132
	 */
133
	private $mHasErrors = false;
134
135
	/**
136
	 * @var boolean
137
	 */
138
	private $serviceLinksRenderState = true;
139
140
	/**
141
	 * Extraneous services and object container
142
	 *
143
	 * @var array
144
	 */
145
	private $extraneousFunctions = array();
146
147
	/**
148
	 * @var Options
149
	 */
150
	private $options;
151
152
	/**
153
	 * Indicates whether a value is being used by a query condition or not which
154
	 * can lead to a modified validation of a value.
155
	 *
156
	 * @var boolean
157
	 */
158
	protected $isUsedByQueryCondition = false;
159
160
	/**
161
	 * @var boolean
162
	 */
163
	protected $approximateValue = false;
164
165
	/**
166
	 * @var ValueConstraintValidator
167
	 */
168
	private $valueConstraintValidator = null;
0 ignored issues
show
Unused Code introduced by
The property $valueConstraintValidator is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
169
170
	/**
171
	 * Constructor.
172
	 *
173
	 * @param string $typeid
174
	 */
175 185
	public function __construct( $typeid ) {
176 185
		$this->m_typeid = $typeid;
177 185
	}
178
179
///// Set methods /////
180
181
	/**
182
	 * Set the user value (and compute other representations if possible).
183
	 * The given value is a string as supplied by some user. An alternative
184
	 * label for printout might also be specified.
185
	 *
186
	 * The third argument was added in SMW 1.9 and should not be used from outside SMW.
187
	 *
188
	 * @param string $value
189
	 * @param mixed $caption
190
	 * @param boolean $approximateValue
191
	 */
192 170
	public function setUserValue( $value, $caption = false, $approximateValue = false ) {
193
194 170
		$this->m_dataitem = null;
195 170
		$this->mErrors = array(); // clear errors
196 170
		$this->mHasErrors = false;
197 170
		$this->m_infolinks = array(); // clear links
198 170
		$this->mHasSearchLink = false;
199 170
		$this->mHasServiceLinks = false;
200 170
		$this->m_caption = is_string( $caption ) ? trim( $caption ) : false;
0 ignored issues
show
Documentation Bug introduced by
It seems like is_string($caption) ? trim($caption) : false can also be of type false. However, the property $m_caption is declared as type string. Maybe add an additional type check?

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 the id property of an instance of the Account 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.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
201 170
		$this->approximateValue = $approximateValue;
202
203
204 170
		$this->parseUserValue( $value ); // may set caption if not set yet, depending on datavalue
205
206
		// The following checks for Strip markers generated by MediaWiki to handle special content,
207
		// from parser and extension tags e.g. <pre>,<nowiki>,<math>,<source>.
208
		// See https://en.wikipedia.org/wiki/Help:Strip_markers
209
		// In general, we are not prepared to handle such content properly, and we
210
		// also have no means of obtaining the user input at this point. Hence the assignment
211
		// just fails, even if parseUserValue() above might not have noticed this issue.
212
		// Note: \x07 was used in MediaWiki 1.11.0, \x7f is used now (backwards compatiblity, b/c)
213 170
		if ( ( strpos( $value, "\x7f" ) !== false ) || ( strpos( $value, "\x07" ) !== false ) ) {
214
			$this->addError( wfMessage( 'smw_parseerror' )->inContentLanguage()->text() );
215
		}
216
217 170
		if ( $this->isValid() && !$approximateValue ) {
218 169
			$this->checkAllowedValues();
219
		}
220
221 170
	}
222
223
	/**
224
	 * Set the actual data contained in this object. The method returns
225
	 * true if this was successful (requiring the type of the dataitem
226
	 * to match the data value). If false is returned, the data value is
227
	 * left unchanged (the data item was rejected).
228
	 *
229
	 * @note Even if this function returns true, the data value object
230
	 * might become invalid if the content of the data item caused errors
231
	 * in spite of it being of the right basic type. False is only returned
232
	 * if the data item is fundamentally incompatible with the data value.
233
	 *
234
	 * @param $dataitem SMWDataItem
235
	 * @return boolean
236
	 */
237 126
	public function setDataItem( SMWDataItem $dataItem ) {
238 126
		$this->m_dataitem = null;
239 126
		$this->mErrors = $this->m_infolinks = array();
240 126
		$this->mHasErrors = $this->mHasSearchLink = $this->mHasServiceLinks = $this->m_caption = false;
0 ignored issues
show
Documentation Bug introduced by
The property $m_caption was declared of type string, but false is of type false. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
241 126
		return $this->loadDataItem( $dataItem );
242
	}
243
244
	/**
245
	 * @since 2.3
246
	 *
247
	 * @param boolean $usedByQueryCondition
248
	 */
249 66
	public function setQueryConditionUsage( $usedByQueryCondition ) {
250 66
		$this->isUsedByQueryCondition = (bool)$usedByQueryCondition;
251 66
	}
252
253
	/**
254
	 * Specify the property to which this value refers. Property pages are
255
	 * used to make settings that affect parsing and display, hence it is
256
	 * sometimes needed to know them.
257
	 *
258
	 * @since 1.6
259
	 *
260
	 * @param SMWDIProperty $property
261
	 */
262 167
	public function setProperty( SMWDIProperty $property ) {
263 167
		$this->m_property = $property;
264 167
	}
265
266
	/**
267
	 * Returns the property to which this value refers.
268
	 *
269
	 * @since 1.8
270
	 *
271
	 * @return SMWDIProperty|null
272
	 */
273 179
	public function getProperty() {
274 179
		return $this->m_property;
275
	}
276
277
	/**
278
	 * @since 2.4
279
	 *
280
	 * @param string $languageCode
281
	 */
282 63
	public function setLanguageCode( $languageCode ) {
283 63
		$this->languageCode = $languageCode;
284 63
	}
285
286
	/**
287
	 * @since 2.4
288
	 *
289
	 * @return string
290
	 */
291 12
	public function getLanguageCode() {
292 12
		return $this->languageCode;
293
	}
294
295
	/**
296
	 * Specify the wiki page to which this value refers. This information is
297
	 * used to parse user values such as "#subsection" which only make sense
298
	 * when used on a certain page.
299
	 *
300
	 * @since 1.7
301
	 *
302
	 * @param SMWDIWikiPage $contextPage
303
	 */
304 145
	public function setContextPage( SMWDIWikiPage $contextPage ) {
305 145
		$this->m_contextPage = $contextPage;
306 145
	}
307
308
	/**
309
	 * @since 2.4
310
	 *
311
	 * @return DIWikiPage|null
312
	 */
313 169
	public function getContextPage() {
314 169
		return $this->m_contextPage;
315
	}
316
317
	/**
318
	 * @since 2.4
319
	 *
320
	 * @return Options $options
321
	 */
322 182
	public function setOptions( Options $options ) {
323 182
		$this->options = $options;
324 182
	}
325
326
	/**
327
	 * @since 2.4
328
	 *
329
	 * @param string $key
330
	 *
331
	 * @return mixed|false
332
	 */
333 166
	public function getOptionValueFor( $key ) {
334
335 166
		if ( $this->options !== null && $this->options->has( $key ) ) {
336 166
			return $this->options->get( $key );
337
		}
338
339 4
		return false;
340
	}
341
342
	/**
343
	 * @since 2.4
344
	 *
345
	 * @param integer $feature
346
	 *
347
	 * @return boolean
348
	 */
349 156
	public function isEnabledFeature( $feature ) {
350 156
		return ( $this->getOptionValueFor( 'smwgDVFeatures' ) & $feature ) != 0;
351
	}
352
353
	/**
354
	 * Change the caption (the text used for displaying this datavalue). The given
355
	 * value must be a string.
356
	 *
357
	 * @param string $caption
358
	 */
359 84
	public function setCaption( $caption ) {
360 84
		$this->m_caption = $caption;
361 84
	}
362
363
	/**
364
	 * @since 2.4
365
	 *
366
	 * @param string $caption
0 ignored issues
show
Bug introduced by
There is no parameter named $caption. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
367
	 */
368 69
	public function getCaption() {
369 69
		return $this->m_caption;
370
	}
371
372
	/**
373
	 * Adds a single SMWInfolink object to the m_infolinks array.
374
	 *
375
	 * @param SMWInfolink $link
376
	 */
377
	public function addInfolink( SMWInfolink $link ) {
378
		$this->m_infolinks[] = $link;
379
	}
380
381
	/**
382
	 * Servicelinks are special kinds of infolinks that are created from
383
	 * current parameters and in-wiki specification of URL templates. This
384
	 * method adds the current property's servicelinks found in the
385
	 * messages. The number and content of the parameters is depending on
386
	 * the datatype, and the service link message is usually crafted with a
387
	 * particular datatype in mind.
388
	 */
389
	public function addServiceLinks() {
390
		if ( $this->mHasServiceLinks ) {
391
			return;
392
		}
393
394
		if ( !is_null( $this->m_property ) ) {
395
			$propertyDiWikiPage = $this->m_property->getDiWikiPage();
396
		}
397
398
		if ( is_null( $this->m_property ) || is_null( $propertyDiWikiPage ) ) {
0 ignored issues
show
Bug introduced by
The variable $propertyDiWikiPage does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
399
			return; // no property known, or not associated with a page
400
		}
401
402
		$args = $this->getServiceLinkParams();
403
404
		if ( $args === false ) {
405
			return; // no services supported
406
		}
407
408
		array_unshift( $args, '' ); // add a 0 element as placeholder
409
		$servicelinks = \SMW\StoreFactory::getStore()->getPropertyValues( $propertyDiWikiPage, new SMW\DIProperty( '_SERV' ) );
410
411
		foreach ( $servicelinks as $dataItem ) {
412
			if ( !( $dataItem instanceof SMWDIBlob ) ) {
413
				continue;
414
			}
415
416
			$args[0] = 'smw_service_' . str_replace( ' ', '_', $dataItem->getString() ); // messages distinguish ' ' from '_'
417
			$text = call_user_func_array( 'wfMessage', $args )->inContentLanguage()->text();
418
			$links = preg_split( "/[\n][\s]?/u", $text );
419
420
			foreach ( $links as $link ) {
421
				$linkdat = explode( '|', $link, 2 );
422
423
				if ( count( $linkdat ) == 2 ) {
424
					$this->addInfolink( SMWInfolink::newExternalLink( $linkdat[0], trim( $linkdat[1] ) ) );
425
				}
426
			}
427
		}
428
		$this->mHasServiceLinks = true;
429
	}
430
431
	/**
432
	 * Define a particular output format. Output formats are user-supplied strings
433
	 * that the datavalue may (or may not) use to customise its return value. For
434
	 * example, quantities with units of measurement may interpret the string as
435
	 * a desired output unit. In other cases, the output format might be built-in
436
	 * and subject to internationalisation (which the datavalue has to implement).
437
	 * In any case, an empty string resets the output format to the default.
438
	 *
439
	 * There is one predefined output format that all datavalues should respect: the
440
	 * format '-' indicates "plain" output that is most useful for further processing
441
	 * the value in a template. It should not use any wiki markup or beautification,
442
	 * and it should also avoid localization to the current language. When users
443
	 * explicitly specify an empty format string in a query, it is normalized to "-"
444
	 * to avoid confusion. Note that empty format strings are not interpreted in
445
	 * this way when directly passed to this function.
446
	 *
447
	 * @param string $formatString
448
	 */
449 84
	public function setOutputFormat( $formatString ) {
450 84
		$this->m_outformat = $formatString; // just store it, subclasses may or may not use this
451 84
	}
452
453
	/**
454
	 * @since 2.4
455
	 *
456
	 * @return string
457
	 */
458 12
	public function getOutputFormat() {
459 12
		return $this->m_outformat;
460
	}
461
462
	/**
463
	 * Add a new error string or array of such strings to the error list.
464
	 *
465
	 * @note Errors should not be escaped here in any way, in contradiction to what
466
	 * the docs used to say here in 1.5 and before. Escaping should happen at the output.
467
	 *
468
	 * @param mixed $error A single string, or array of strings.
469
	 */
470 102
	public function addError( $error ) {
471 102
		if ( is_array( $error ) ) {
472 84
			$this->mErrors = array_merge( $this->mErrors, $error );
473 84
			$this->mHasErrors = $this->mHasErrors || ( count( $error ) > 0 );
474
		} else {
475 28
			$this->mErrors[] = $error;
476 28
			$this->mHasErrors = true;
477
		}
478 102
	}
479
480
	/**
481
	 * @since 2.4
482
	 *
483
	 * @param $parameters
484
	 * @param integer|null $type
485
	 * @param integer|null $language
486
	 */
487 5
	public function addErrorMsg( $parameters, $type = null, $language = null ) {
488 5
		$this->addError( Message::get( $parameters, $type, $language ) );
489 5
	}
490
491
	/**
492
	 * @since 2.4
493
	 */
494
	public function clearErrors() {
495
		$this->mErrors = array();
496
		$this->mHasErrors = false;
497
	}
498
499
///// Abstract processing methods /////
500
501
	/**
502
	 * Initialise the datavalue from the given value string.
503
	 * The format of this strings might be any acceptable user input
504
	 * and especially includes the output of getWikiValue().
505
	 *
506
	 * @param string $value
507
	 */
508
	abstract protected function parseUserValue( $value );
509
510
	/**
511
	 * Set the actual data contained in this object. The method returns
512
	 * true if this was successful (requiring the type of the dataitem
513
	 * to match the data value). If false is returned, the data value is
514
	 * left unchanged (the data item was rejected).
515
	 *
516
	 * @note Even if this function returns true, the data value object
517
	 * might become invalid if the content of the data item caused errors
518
	 * in spite of it being of the right basic type. False is only returned
519
	 * if the data item is fundamentally incompatible with the data value.
520
	 *
521
	 * @since 1.6
522
	 *
523
	 * @param SMWDataItem $dataItem
524
	 *
525
	 * @return boolean
526
	 */
527
	abstract protected function loadDataItem( SMWDataItem $dataItem );
528
529
530
///// Query support /////
531
532
	/**
533
	 * @see DataValueDescriptionDeserializer::deserialize
534
	 *
535
	 * @note Descriptions of values need to know their property to be able to
536
	 * create a parsable wikitext version of a query condition again. Thus it
537
	 * might be necessary to call setProperty() before using this method.
538
	 *
539
	 * @param string $value
540
	 *
541
	 * @return Description
542
	 * @throws InvalidArgumentException
543
	 */
544 86
	public function getQueryDescription( $value ) {
545
546 86
		$descriptionDeserializer = DVDescriptionDeserializerRegistry::getInstance()->getDescriptionDeserializerFor( $this );
547 86
		$description = $descriptionDeserializer->deserialize( $value );
548
549 86
		foreach ( $descriptionDeserializer->getErrors() as $error ) {
550 1
			$this->addError( $error );
551
		}
552
553 86
		return $description;
554
	}
555
556
	/**
557
	 * Returns a DataValueFormatter that was matched and dispatched for the current
558
	 * DV instance.
559
	 *
560
	 * @since 2.4
561
	 *
562
	 * @return DataValueFormatter
563
	 */
564 98
	public function getDataValueFormatter() {
565 98
		return ValueFormatterRegistry::getInstance()->getDataValueFormatterFor( $this );
566
	}
567
568
	/**
569
	 * @since 2.4
570
	 *
571
	 * @return PropertySpecificationLookup
572
	 */
573 157
	public function getPropertySpecificationLookup() {
574 157
		return ApplicationFactory::getInstance()->getPropertySpecificationLookup();
575
	}
576
577
	/**
578
	 * @deprecated 2.3
579
	 * @see DescriptionDeserializer::prepareValue
580
	 *
581
	 * This method should no longer be used for direct public access, instead a
582
	 * DataValue is expected to register a DescriptionDeserializer with
583
	 * DVDescriptionDeserializerRegistry.
584
	 *
585
	 * FIXME as of 2.3, SMGeoCoordsValue still uses this method and requires
586
	 * migration before 3.0
587
	 */
588
	static public function prepareValue( &$value, &$comparator ) {
0 ignored issues
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
589
		$comparator = QueryComparator::getInstance()->extractComparatorFromString( $value );
590
	}
591
592
///// Get methods /////
593
594
	/**
595
	 * Get the actual data contained in this object or null if the data is
596
	 * not defined (due to errors or due to not being set at all).
597
	 * @note Most implementations ensure that a data item is always set,
598
	 * even if errors occurred, to avoid additional checks for not
599
	 * accessing null. Hence, one must not assume that a non-null return
600
	 * value here implies that isValid() returns true.
601
	 *
602
	 * @since 1.6
603
	 *
604
	 * @return SMWDataItem|SMWDIError
605
	 */
606 173
	public function getDataItem() {
607
608 173
		if ( $this->isValid() ) {
609 173
			return $this->m_dataitem;
610
		}
611
612 1
		return new SMWDIError( $this->mErrors );
613
	}
614
615
	/**
616
	 * @since 2.2
617
	 *
618
	 * @return string
619
	 */
620
	public function __toString() {
621
		return $this->getDataItem()->getSerialization();
622
	}
623
624
	/**
625
	 * Returns a short textual representation for this data value. If the value
626
	 * was initialised from a user supplied string, then this original string
627
	 * should be reflected in this short version (i.e. no normalisation should
628
	 * normally happen). There might, however, be additional parts such as code
629
	 * for generating tooltips. The output is in wiki text.
630
	 *
631
	 * The parameter $linked controls linking of values such as titles and should
632
	 * be non-NULL and non-false if this is desired.
633
	 */
634
	abstract public function getShortWikiText( $linked = null );
635
636
	/**
637
	 * Returns a short textual representation for this data value. If the value
638
	 * was initialised from a user supplied string, then this original string
639
	 * should be reflected in this short version (i.e. no normalisation should
640
	 * normally happen). There might, however, be additional parts such as code
641
	 * for generating tooltips. The output is in HTML text.
642
	 *
643
	 * The parameter $linker controls linking of values such as titles and should
644
	 * be some Linker object (or NULL for no linking).
645
	 */
646
	abstract public function getShortHTMLText( $linker = null );
647
648
	/**
649
	 * Return the long textual description of the value, as printed for
650
	 * example in the factbox. If errors occurred, return the error message
651
	 * The result always is a wiki-source string.
652
	 *
653
	 * The parameter $linked controls linking of values such as titles and should
654
	 * be non-NULL and non-false if this is desired.
655
	 */
656
	abstract public function getLongWikiText( $linked = null );
657
658
	/**
659
	 * Return the long textual description of the value, as printed for
660
	 * example in the factbox. If errors occurred, return the error message
661
	 * The result always is an HTML string.
662
	 *
663
	 * The parameter $linker controls linking of values such as titles and should
664
	 * be some Linker object (or NULL for no linking).
665
	 */
666
	abstract public function getLongHTMLText( $linker = null );
667
668
	/**
669
	 * Returns a short textual representation for this data value. If the value
670
	 * was initialised from a user supplied string, then this original string
671
	 * should be reflected in this short version (i.e. no normalisation should
672
	 * normally happen). There might, however, be additional parts such as code
673
	 * for generating tooltips. The output is in the specified format.
674
	 *
675
	 * The parameter $linker controls linking of values such as titles and should
676
	 * be some Linker object (for HTML output), or NULL for no linking.
677
	 */
678 42
	public function getShortText( $outputformat, $linker = null ) {
679
		switch ( $outputformat ) {
680 42
			case SMW_OUTPUT_WIKI:
681 42
				return $this->getShortWikiText( $linker );
682
			case SMW_OUTPUT_HTML:
683
			case SMW_OUTPUT_FILE:
684
			default:
685
				return $this->getShortHTMLText( $linker );
686
		}
687
	}
688
689
	/**
690
	 * Return the long textual description of the value, as printed for
691
	 * example in the factbox. If errors occurred, return the error message.
692
	 * The output is in the specified format.
693
	 *
694
	 * The parameter $linker controls linking of values such as titles and should
695
	 * be some Linker object (for HTML output), or NULL for no linking.
696
	 */
697
	public function getLongText( $outputformat, $linker = null ) {
698
		switch ( $outputformat ) {
699
			case SMW_OUTPUT_WIKI:
700
				return $this->getLongWikiText( $linker );
701
			case SMW_OUTPUT_HTML:
702
			case SMW_OUTPUT_FILE:
703
			default:
704
				return $this->getLongHTMLText( $linker );
705
		}
706
	}
707
708
	/**
709
	 * Return text serialisation of info links. Ensures more uniform layout
710
	 * throughout wiki (Factbox, Property pages, ...).
711
	 *
712
	 * @param integer $outputformat Element of the SMW_OUTPUT_ enum
713
	 * @param $linker
714
	 *
715
	 * @return string
716
	 */
717 1
	public function getInfolinkText( $outputformat, $linker = null ) {
718 1
		$result = '';
719 1
		$first = true;
720 1
		$extralinks = array();
721
722
		switch ( $outputformat ) {
723 1
			case SMW_OUTPUT_WIKI:
724 1
				foreach ( $this->getInfolinks() as $link ) {
725 1
					if ( $first ) {
726 1
						$result .= '<!-- -->  ' . $link->getWikiText();
727
							// the comment is needed to prevent MediaWiki from linking URL-strings together with the nbsps!
728 1
						$first = false;
729
					} else {
730 1
						$extralinks[] = $link->getWikiText();
731
					}
732
				}
733 1
				break;
734
735
			case SMW_OUTPUT_HTML: case SMW_OUTPUT_FILE: default:
0 ignored issues
show
Coding Style introduced by
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...
736
				foreach ( $this->getInfolinks() as $link ) {
737
					if ( $first ) {
738
						$result .= '&#160;&#160;' . $link->getHTML( $linker );
739
						$first = false;
740
					} else {
741
						$extralinks[] = $link->getHTML( $linker );
742
					}
743
				}
744
				break;
745
		}
746
747 1
		if ( count( $extralinks ) > 0 ) {
748
			$result .= smwfEncodeMessages( $extralinks, 'service', '', false );
749
		}
750
751
		// #1453 SMW::on/off will break any potential link therefore just don't even try
752 1
		return strpos( $result, 'SMW::off' ) !== false || strpos( $result, 'SMW::on' ) !== false ? '' : $result;
753
	}
754
755
	/**
756
	 * Return the plain wiki version of the value, or
757
	 * FALSE if no such version is available. The returned
758
	 * string suffices to reobtain the same DataValue
759
	 * when passing it as an input string to setUserValue().
760
	 */
761
	abstract public function getWikiValue();
762
763
	/**
764
	 * Return a short string that unambiguously specify the type of this
765
	 * value. This value will globally be used to identify the type of a
766
	 * value (in spite of the class it actually belongs to, which can still
767
	 * implement various types).
768
	 */
769 112
	public function getTypeID() {
770 112
		return $this->m_typeid;
771
	}
772
773
	/**
774
	 * @since 2.1
775
	 * @param boolean $renderState
776
	 */
777 1
	public function setServiceLinksRenderState( $renderState = true ) {
778 1
		$this->serviceLinksRenderState = $renderState;
779 1
	}
780
781
	/**
782
	 * Return an array of SMWLink objects that provide additional resources
783
	 * for the given value. Captions can contain some HTML markup which is
784
	 * admissible for wiki text, but no more. Result might have no entries
785
	 * but is always an array.
786
	 */
787 1
	public function getInfolinks() {
788 1
		if ( $this->isValid() && !is_null( $this->m_property ) ) {
789 1
			if ( !$this->mHasSearchLink ) { // add default search link
790 1
				$this->mHasSearchLink = true;
791 1
				$this->m_infolinks[] = SMWInfolink::newPropertySearchLink( '+',
792 1
					$this->m_property->getLabel(), $this->getWikiValue() );
793
			}
794
795 1
			if ( !$this->mHasServiceLinks && $this->serviceLinksRenderState ) { // add further service links
796
				$this->addServiceLinks();
797
			}
798
		}
799
800 1
		return $this->m_infolinks;
801
	}
802
803
	/**
804
	 * Overwritten by callers to supply an array of parameters that can be used for
805
	 * creating servicelinks. The number and content of values in the parameter array
806
	 * may vary, depending on the concrete datatype.
807
	 */
808
	protected function getServiceLinkParams() {
809
		return false;
810
	}
811
812
	/**
813
	 * Return a string that identifies the value of the object, and that can
814
	 * be used to compare different value objects.
815
	 * Possibly overwritten by subclasses (e.g. to ensure that returned
816
	 * value is normalized first)
817
	 *
818
	 * @return string
819
	 */
820
	public function getHash() {
821
		return $this->isValid() ? $this->m_dataitem->getHash() : implode( "\t", $this->mErrors );
822
	}
823
824
	/**
825
	 * Convenience method that checks if the value that is used to sort
826
	 * data of this type is numeric. This only works if the value is set.
827
	 *
828
	 * @return boolean
829
	 */
830
	public function isNumeric() {
831
		if ( isset( $this->m_dataitem ) ) {
832
			return is_numeric( $this->m_dataitem->getSortKey() );
833
		} else {
834
			return false;
835
		}
836
	}
837
838
	/**
839
	 * Return true if a value was defined and understood by the given type,
840
	 * and false if parsing errors occurred or no value was given.
841
	 *
842
	 * @return boolean
843
	 */
844 182
	public function isValid() {
845 182
		return !$this->mHasErrors && isset( $this->m_dataitem );
846
	}
847
848
	/**
849
	 * Whether a datavalue can be used or not (can be made more restrictive then
850
	 * isValid).
851
	 *
852
	 * @note Validity defines a processable state without any technical restrictions
853
	 * while usability is determined by its accessibility to a context
854
	 * (permission, convention etc.)
855
	 *
856
	 * @since  2.2
857
	 *
858
	 * @return boolean
859
	 */
860 145
	public function canUse() {
861 145
		return true;
862
	}
863
864
	/**
865
	 * @note Normally set by the DataValueFactory, or during tests
866
	 *
867
	 * @since 2.3
868
	 *
869
	 * @param array
870
	 */
871 182
	public function setExtraneousFunctions( array $extraneousFunctions ) {
872 182
		$this->extraneousFunctions = $extraneousFunctions;
873 182
	}
874
875
	/**
876
	 * @since 2.3
877
	 *
878
	 * @param string $name
879
	 * @param array $parameters
880
	 *
881
	 * @return mixed
882
	 * @throws RuntimeException
883
	 */
884
	public function getExtraneousFunctionFor( $name, array $parameters = array() ) {
885
886
		if ( isset( $this->extraneousFunctions[$name] ) && is_callable( $this->extraneousFunctions[$name] ) ) {
887
			return call_user_func_array( $this->extraneousFunctions[$name], $parameters );
888
		}
889
890
		throw new RuntimeException( "$name is not registered as extraneous function." );
891
	}
892
893
	/**
894
	 * Return a string that displays all error messages as a tooltip, or
895
	 * an empty string if no errors happened.
896
	 *
897
	 * @return string
898
	 */
899 10
	public function getErrorText() {
900 10
		return smwfEncodeMessages( $this->mErrors );
901
	}
902
903
	/**
904
	 * Return an array of error messages, or an empty array
905
	 * if no errors occurred.
906
	 *
907
	 * @return array
908
	 */
909 142
	public function getErrors() {
910 142
		return $this->mErrors;
911
	}
912
913
	/**
914
	 * Check if property is range restricted and, if so, whether the current value is allowed.
915
	 * Creates an error if the value is illegal.
916
	 */
917 169
	protected function checkAllowedValues() {
918 169
		ValueValidatorRegistry::getInstance()->getConstraintValueValidator()->validate( $this );
0 ignored issues
show
Documentation introduced by
$this is of type this<SMWDataValue>, but the function expects a object<SMW\DataValues\ValueValidators\DataValue>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
919 169
	}
920
921
}
922