summaryrefslogtreecommitdiff
path: root/www/wiki/extensions/SemanticMediaWiki/includes/dataitems/SMW_DI_Container.php
blob: f7f230e52a0e31da53031675a7bcf97ba097b2a4 (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
<?php
/**
 * @ingroup SMWDataItems
 */

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 SMWContainerSemanticData. 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 SMWContainerSemanticData.
 *
 * @since 1.6
 *
 * @author Markus Krötzsch
 * @ingroup SMWDataItems
 */
class SMWDIContainer extends SMWDataItem {

	/**
	 * Internal value.
	 *
	 * @var SMWSemanticData
	 */
	protected $m_semanticData;

	/**
	 * Constructor. The given SMWContainerSemanticData object will be owned
	 * by the constructed object afterwards, and in particular will not
	 * allow further changes.
	 *
	 * @param $semanticData SMWContainerSemanticData
	 */
	public function __construct( SMWContainerSemanticData $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 SMWContainerSemanticData ) ) {
			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();
	}
}