284 lines
7.4 KiB
PHP
284 lines
7.4 KiB
PHP
<?php
|
|
|
|
use MediaWiki\Json\JsonUnserializable;
|
|
use MediaWiki\Json\JsonUnserializer;
|
|
use SMW\DIConcept;
|
|
use SMW\DIProperty;
|
|
use SMW\DIWikiPage;
|
|
use SMW\Options;
|
|
use SMW\SemanticData;
|
|
|
|
/**
|
|
* 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 implements JsonUnserializable {
|
|
|
|
/// 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 DIWikiPage
|
|
const TYPE_WIKIPAGE = 9;
|
|
/// Data item ID for DIConcept
|
|
const TYPE_CONCEPT = 10;
|
|
/// Data item ID for DIProperty
|
|
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 int 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 bool
|
|
*/
|
|
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();
|
|
|
|
/**
|
|
* @since 3.1
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getSha1() {
|
|
return sha1( $this->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 int $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 int $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 DIWikiPage::class;
|
|
case self::TYPE_CONCEPT:
|
|
return DIConcept::class;
|
|
case self::TYPE_PROPERTY:
|
|
return DIProperty::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;
|
|
}
|
|
|
|
/**
|
|
* Implements \JsonSerializable.
|
|
*
|
|
* @since 4.0.0
|
|
*
|
|
* @return array
|
|
*/
|
|
public function jsonSerialize(): array {
|
|
# T312589 explicitly calling jsonSerialize() will be unnecessary
|
|
# in the future.
|
|
return [
|
|
'options' => $this->options ? $this->options->jsonSerialize() : null,
|
|
'value' => $this->getSerialization(),
|
|
'_type_' => get_class( $this ),
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Implements JsonUnserializable.
|
|
*
|
|
* @since 4.0.0
|
|
*
|
|
* @param JsonUnserializer $unserializer Unserializer
|
|
* @param array $json JSON to be unserialized
|
|
*
|
|
* @return self
|
|
*/
|
|
public static function newFromJsonArray( JsonUnserializer $unserializer, array $json ) {
|
|
$obj = static::doUnserialize( $json['value'] );
|
|
$obj->options = $json['options'] ? SemanticData::maybeUnserialize( $unserializer, $json['options'] ) : null;
|
|
return $obj;
|
|
}
|
|
|
|
}
|