Completed
Push — master ( 3c62d6...8f3f49 )
by mw
14s
created

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