summaryrefslogtreecommitdiff
path: root/www/wiki/extensions/SemanticMediaWiki/includes/dataitems/SMW_DataItem.php
blob: 961379569c619620e5e6c241deeac67f767ca35b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
<?php

use SMW\Options;

/**
 * This group contains all parts of SMW that relate to the processing of dataitems
 * of various types.
 *
 * @defgroup SMWDataItems SMWDataItems
 * @ingroup SMW
 */

/**
 * Objects of this type represent all that is known about a certain piece of
 * data that could act as the value of some property. Data items only represent
 * the stored data, and are thus at the core of SMW's data model. Data items
 * are always immutable, i.e. they must not be changed after creation (and this
 * is mostly enforced by the API with some minor exceptions).
 *
 * The set of available data items is fixed and cannot be extended. These are
 * the kinds of information that SMW can process. Their concrete use and
 * handling might depend on the context in which they are used. In particular,
 * property values may be influences by settings made for their property. This
 * aspect, however, is not part of the data item API.
 *
 * @since 1.6
 *
 * @ingroup SMWDataItems
 */
abstract class SMWDataItem {

	/// Data item ID that can be used to indicate that no data item class is appropriate
	const TYPE_NOTYPE    = 0;
	/// Data item ID for SMWDINumber
	const TYPE_NUMBER    = 1;
	/// Data item ID for SMWDIBlob
	const TYPE_BLOB      = 2;
	///  Data item ID for SMWDIBoolean
	const TYPE_BOOLEAN   = 4;
	///  Data item ID for SMWDIUri
	const TYPE_URI       = 5;
	///  Data item ID for SMWDITimePoint
	const TYPE_TIME      = 6;
	///  Data item ID for SMWDIGeoCoord
	const TYPE_GEO       = 7;
	///  Data item ID for SMWDIContainer
	const TYPE_CONTAINER = 8;
	///  Data item ID for SMWDIWikiPage
	const TYPE_WIKIPAGE  = 9;
	///  Data item ID for SMWDIConcept
	const TYPE_CONCEPT   = 10;
	///  Data item ID for SMWDIProperty
	const TYPE_PROPERTY  = 11;
	///  Data item ID for SMWDIError
	const TYPE_ERROR     = 12;

	/**
	 * @var Options
	 */
	private $options = null;

	/**
	 * Convenience method that returns a constant that defines the concrete
	 * class that implements this data item. Used to switch when processing
	 * data items.
	 * @return integer that specifies the basic type of data item
	 */
	abstract public function getDIType();

	/**
	 * Return a value that can be used for sorting data of this type.
	 * If the data is of a numerical type, the sorting must be done in
	 * numerical order. If the data is a string, the data must be sorted
	 * alphabetically.
	 *
	 * @note Every data item returns a sort key, even if there is no
	 * natural linear order for the type. SMW must order listed data
	 * in some way in any case. If there is a natural order (e.g. for
	 * Booleans where false < true), then the sortkey must agree with
	 * this order (e.g. for Booleans where false maps to 0, and true
	 * maps to 1).
	 *
	 * @note Wiki pages are a special case in SMW. They are ordered by a
	 * sortkey that is assigned to them as a property value. When pages are
	 * sorted, this data should be used if possible.
	 *
	 * @return float|string
	 */
	abstract public function getSortKey();

	/**
	 * Method to compare two SMWDataItems
	 * This should result true only if they are of the same DI type
	 * and have the same internal value
	 *
	 * @since 1.8
	 *
	 * @param SMWDataItem $di
	 * @return boolean
	 */
	abstract public function equals( SMWDataItem $di );

	/**
	 * Create a data item that represents the sortkey, i.e. either an
	 * SMWDIBlob or an SMWDINumber. For efficiency, these subclasses
	 * overwrite this method to return themselves.
	 *
	 * @return SMWDataItem
	 */
	public function getSortKeyDataItem() {
		$sortKey = $this->getSortKey();

		if ( is_numeric( $sortKey ) ) {
			return new SMWDINumber( $sortKey );
		}

		return new SMWDIBlob( $sortKey );
	}

	/**
	 * Get a UTF-8 encoded string serialization of this data item.
	 * The serialisation should be concise and need not be pretty, but it
	 * must allow unserialization. Each subclass of SMWDataItem implements
	 * a static method doUnserialize() for this purpose.
	 * @return string
	 */
	abstract public function getSerialization();

	/**
	 * Get a hash string for this data item. Might be overwritten in
	 * subclasses to obtain shorter or more efficient hashes.
	 *
	 * @return string
	 */
	public function getHash() {
		return $this->getSerialization();
	}

	/**
	 * @since 2.1
	 *
	 * @return string
	 */
	public function __toString() {
		return $this->getSerialization();
	}

	/**
	 * Create a data item of the given dataitem ID based on the the
	 * provided serialization string and (optional) typeid.
	 *
	 * @param integer $diType dataitem ID
	 * @param string $serialization
	 *
	 * @return SMWDataItem
	 */
	public static function newFromSerialization( $diType, $serialization ) {
		$diClass = self::getDataItemClassNameForId( $diType );
		return call_user_func( [ $diClass, 'doUnserialize' ], $serialization );
	}

	/**
	 * Gets the class name of the data item that has the provided type id.
	 *
	 * @param integer $diType Element of the SMWDataItem::TYPE_ enum
	 *
	 * @throws InvalidArgumentException
	 *
	 * @return string
	 */
	public static function getDataItemClassNameForId( $diType ) {
		switch ( $diType ) {
			case self::TYPE_NUMBER:
				return SMWDINumber::class;
			case self::TYPE_BLOB:
				return SMWDIBlob::class;
			case self::TYPE_BOOLEAN:
				return SMWDIBoolean::class;
			case self::TYPE_URI:
				return SMWDIUri::class;
			case self::TYPE_TIME:
				return SMWDITime::class;
			case self::TYPE_GEO:
				return SMWDIGeoCoord::class;
			case self::TYPE_CONTAINER:
				return SMWDIContainer::class;
			case self::TYPE_WIKIPAGE:
				return SMWDIWikiPage::class;
			case self::TYPE_CONCEPT:
				return SMWDIConcept::class;
			case self::TYPE_PROPERTY:
				return SMWDIProperty::class;
			case self::TYPE_ERROR:
				return SMWDIError::class;
			case self::TYPE_NOTYPE: default:
				throw new InvalidArgumentException( "The value \"$diType\" is not a valid dataitem ID." );
		}
	}

	/**
	 * @since 2.5
	 *
	 * @param string $key
	 * @param string $value
	 */
	public function setOption( $key, $value ) {

		if ( !$this->options instanceof Options ) {
			$this->options = new Options();
		}

		$this->options->set( $key, $value );
	}

	/**
	 * @since 2.5
	 *
	 * @param string $key
	 * @param string|null $default
	 *
	 * @return mixed
	 */
	public function getOption( $key, $default = null ) {

		if ( !$this->options instanceof Options ) {
			$this->options = new Options();
		}

		if ( $this->options->has( $key ) ) {
			return $this->options->get( $key );
		}

		return $default;
	}

}