gplx/mediawiki/extensions/SemanticMediaWiki/includes/dataitems/SMW_DI_Container.php

141 lines
3.8 KiB
PHP

<?php
/**
* @ingroup SMWDataItems
*/
use SMW\DataModel\ContainerSemanticData;
use SMW\DIProperty;
use SMW\Exception\DataItemException;
use SMWDIBlob as DIBlob;
/**
* This class implements container data items that can store SMWSemanticData
* objects. Containers are not dataitems in the proper sense: they do not
* represent a single, opaque value that can be assigned to a property. Rather,
* a container represents a "subobject" with a number of property-value
* assignments. When a container is stored, these individual data assignments
* are stored -- the data managed by SMW never contains any "container", just
* individual property assignments for the subobject. Likewise, when a container
* is used in search, it is interpreted as a patterns of possible property
* assignments, and this pattern is searched for.
*
* The data encapsulated in a container data item is essentially an
* SMWSemanticData object of class ContainerSemanticData. This class allows
* the subject to be kept anonymous if not known (if no context page is
* available for finding a suitable subobject name). See the repsective
* documentation for details.
*
* Being a mere placeholder/template for other data, an SMWDIContainer is not
* immutable as the other basic data items. New property-value pairs can always
* be added to the internal ContainerSemanticData.
*
* @since 1.6
*
* @author Markus Krötzsch
* @ingroup SMWDataItems
*/
class SMWDIContainer extends SMWDataItem {
/**
* Internal value.
*
* @var SMWSemanticData
*/
protected $m_semanticData;
/**
* Constructor. The given ContainerSemanticData object will be owned
* by the constructed object afterwards, and in particular will not
* allow further changes.
*
* @param $semanticData ContainerSemanticData
*/
public function __construct( ContainerSemanticData $semanticData ) {
$this->m_semanticData = $semanticData;
}
public function getDIType() {
return SMWDataItem::TYPE_CONTAINER;
}
public function getSemanticData() {
return $this->m_semanticData;
}
public function getSortKey() {
return '';
}
/**
* @since 2.5
*
* @param string $sortKey
*/
public function setSortKey( $sortKey ) {
$this->m_semanticData->addPropertyObjectValue(
new DIProperty( '_SKEY' ),
new DIBlob( $this->m_semanticData->getSubject()->getSortKey() . '#' . $sortKey )
);
}
public function getSerialization() {
return serialize( $this->m_semanticData );
}
/**
* Get a hash string for this data item.
*
* @return string
*/
public function getHash() {
$hash = $this->getValueHash( $this->m_semanticData );
sort( $hash );
return md5( implode( '#', $hash ) );
// We want a value hash, not an entity hash!!
// return $this->m_semanticData->getHash();
}
private function getValueHash( $semanticData ) {
$hash = [];
foreach ( $semanticData->getProperties() as $property ) {
$hash[] = $property->getKey();
foreach ( $semanticData->getPropertyValues( $property ) as $di ) {
$hash[] = $di->getHash();
}
}
foreach ( $semanticData->getSubSemanticData() as $data ) {
$hash[] = $this->getValueHash( $data );
}
return $hash;
}
/**
* Create a data item from the provided serialization string and type
* ID.
*
* @return SMWDIContainer
*/
public static function doUnserialize( $serialization ) {
/// TODO May issue an E_NOTICE when problems occur; catch this
$data = unserialize( $serialization );
if ( !( $data instanceof ContainerSemanticData ) ) {
throw new DataItemException( "Could not unserialize SMWDIContainer from the given string." );
}
return new SMWDIContainer( $data );
}
public function equals( SMWDataItem $di ) {
if ( $di->getDIType() !== SMWDataItem::TYPE_CONTAINER ) {
return false;
}
return $di->getSerialization() === $this->getSerialization();
}
}