These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | /** |
||
3 | * @ingroup SMWDataItems |
||
4 | */ |
||
5 | |||
6 | use SMW\DataItemException; |
||
7 | |||
8 | /** |
||
9 | * Subclass of SMWSemanticData that is used to store the data in SMWDIContainer |
||
10 | * objects. It is special since the subject that the stored property-value pairs |
||
11 | * refer may or may not be specified explicitly. This can be tested with |
||
12 | * hasAnonymousSubject(). When trying to access the subject in anonymous state, |
||
13 | * an Exception will be thrown. Anonymous container data items are used when no |
||
14 | * page context is available, e.g. when specifying such a value in a search form |
||
15 | * where the parent page is not known. |
||
16 | * |
||
17 | * Besides this change, the subclass mainly is needed to restroe the disabled |
||
18 | * serialization of SMWSemanticData. |
||
19 | * |
||
20 | * See also the documentation of SMWDIContainer. |
||
21 | * |
||
22 | * @since 1.6 |
||
23 | * |
||
24 | * @author Markus Krötzsch |
||
25 | * @ingroup SMWDataItems |
||
26 | */ |
||
27 | class SMWContainerSemanticData extends SMWSemanticData { |
||
0 ignored issues
–
show
|
|||
28 | |||
29 | /** |
||
30 | * @var boolean |
||
31 | */ |
||
32 | private $skipAnonymousCheck = false; |
||
33 | |||
34 | /** |
||
35 | * Construct a data container that refers to an anonymous subject. See |
||
36 | * the documentation of the class for details. |
||
37 | * |
||
38 | * @since 1.7 |
||
39 | * |
||
40 | * @param boolean $noDuplicates stating if duplicate data should be avoided |
||
41 | */ |
||
42 | 3 | public static function makeAnonymousContainer( $noDuplicates = true, $skipAnonymousCheck = false ) { |
|
43 | 3 | $subject = new SMWDIWikiPage( 'SMWInternalObject', NS_SPECIAL, '', 'int' ); |
|
44 | 3 | $containerSemanticData = new SMWContainerSemanticData( $subject, $noDuplicates ); |
|
45 | |||
46 | 3 | if ( $skipAnonymousCheck ) { |
|
47 | $containerSemanticData->skipAnonymousCheck(); |
||
48 | } |
||
49 | |||
50 | 3 | return $containerSemanticData; |
|
51 | } |
||
52 | |||
53 | /** |
||
54 | * Restore complete serialization which is disabled in SMWSemanticData. |
||
55 | */ |
||
56 | public function __sleep() { |
||
57 | return array( 'mSubject', 'mProperties', 'mPropVals', |
||
58 | 'mHasVisibleProps', 'mHasVisibleSpecs', 'mNoDuplicates', 'skipAnonymousCheck' ); |
||
59 | } |
||
60 | |||
61 | /** |
||
62 | * @since 2.4 |
||
63 | */ |
||
64 | 3 | public function skipAnonymousCheck() { |
|
65 | 3 | $this->skipAnonymousCheck = true; |
|
66 | 3 | } |
|
67 | |||
68 | /** |
||
69 | * Check if the subject of this container is an anonymous object. |
||
70 | * See the documenation of the class for details. |
||
71 | * |
||
72 | * @return boolean |
||
73 | */ |
||
74 | 138 | public function hasAnonymousSubject() { |
|
75 | 138 | if ( $this->mSubject->getNamespace() == NS_SPECIAL && |
|
76 | 138 | $this->mSubject->getDBkey() == 'SMWInternalObject' && |
|
77 | 138 | $this->mSubject->getInterwiki() === '' && |
|
78 | 138 | $this->mSubject->getSubobjectName() === 'int' ) { |
|
79 | return true; |
||
80 | } else { |
||
81 | 138 | return false; |
|
82 | } |
||
83 | } |
||
84 | |||
85 | /** |
||
86 | * Return subject to which the stored semantic annotation refer to, or |
||
87 | * throw an exception if the subject is anonymous (if the data has not |
||
88 | * been contextualized with setMasterPage() yet). |
||
89 | * |
||
90 | * @return SMWDIWikiPage subject |
||
91 | */ |
||
92 | 138 | public function getSubject() { |
|
93 | |||
94 | 138 | if ( !$this->skipAnonymousCheck && $this->hasAnonymousSubject() ) { |
|
95 | throw new DataItemException("This container has been classified as anonymous and by trying to access its subject (that has not been given any) an exception is raised to inform about the incorrect usage. An anonymous container can only be used for a search pattern match."); |
||
96 | } |
||
97 | |||
98 | 138 | return $this->mSubject; |
|
99 | } |
||
100 | |||
101 | /** |
||
102 | * Change the object to become an exact copy of the given |
||
103 | * SMWSemanticData object. This is used to make other types of |
||
104 | * SMWSemanticData into an SMWContainerSemanticData. To copy objects of |
||
105 | * the same type, PHP clone() should be used. |
||
106 | * |
||
107 | * @since 1.7 |
||
108 | * |
||
109 | * @param $semanticData SMWSemanticData object to copy from |
||
110 | */ |
||
111 | 12 | public function copyDataFrom( SMWSemanticData $semanticData ) { |
|
112 | 12 | $this->mSubject = $semanticData->getSubject(); |
|
113 | 12 | $this->mProperties = $semanticData->getProperties(); |
|
114 | 12 | $this->mPropVals = array(); |
|
115 | 12 | foreach ( $this->mProperties as $property ) { |
|
116 | 12 | $this->mPropVals[$property->getKey()] = $semanticData->getPropertyValues( $property ); |
|
117 | } |
||
118 | 12 | $this->mHasVisibleProps = $semanticData->hasVisibleProperties(); |
|
119 | 12 | $this->mHasVisibleSpecs = $semanticData->hasVisibleSpecialProperties(); |
|
120 | 12 | $this->mNoDuplicates = $semanticData->mNoDuplicates; |
|
121 | 12 | } |
|
122 | |||
123 | } |
||
124 | |||
125 | /** |
||
126 | * This class implements container data items that can store SMWSemanticData |
||
127 | * objects. Containers are not dataitems in the proper sense: they do not |
||
128 | * represent a single, opaque value that can be assigned to a property. Rather, |
||
129 | * a container represents a "subobject" with a number of property-value |
||
130 | * assignments. When a container is stored, these individual data assignments |
||
131 | * are stored -- the data managed by SMW never contains any "container", just |
||
132 | * individual property assignments for the subobject. Likewise, when a container |
||
133 | * is used in search, it is interpreted as a patterns of possible property |
||
134 | * assignments, and this pattern is searched for. |
||
135 | * |
||
136 | * The data encapsulated in a container data item is essentially an |
||
137 | * SMWSemanticData object of class SMWContainerSemanticData. This class allows |
||
138 | * the subject to be kept anonymous if not known (if no context page is |
||
139 | * available for finding a suitable subobject name). See the repsective |
||
140 | * documentation for details. |
||
141 | * |
||
142 | * Being a mere placeholder/template for other data, an SMWDIContainer is not |
||
143 | * immutable as the other basic data items. New property-value pairs can always |
||
144 | * be added to the internal SMWContainerSemanticData. |
||
145 | * |
||
146 | * @since 1.6 |
||
147 | * |
||
148 | * @author Markus Krötzsch |
||
149 | * @ingroup SMWDataItems |
||
150 | */ |
||
151 | class SMWDIContainer extends SMWDataItem { |
||
0 ignored issues
–
show
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...
|
|||
152 | |||
153 | /** |
||
154 | * Internal value. |
||
155 | * |
||
156 | * @var SMWSemanticData |
||
157 | */ |
||
158 | protected $m_semanticData; |
||
159 | |||
160 | /** |
||
161 | * Constructor. The given SMWContainerSemanticData object will be owned |
||
162 | * by the constructed object afterwards, and in particular will not |
||
163 | * allow further changes. |
||
164 | * |
||
165 | * @param $semanticData SMWContainerSemanticData |
||
166 | */ |
||
167 | 138 | public function __construct( SMWContainerSemanticData $semanticData ) { |
|
168 | 138 | $this->m_semanticData = $semanticData; |
|
169 | 138 | } |
|
170 | |||
171 | 4 | public function getDIType() { |
|
172 | 4 | return SMWDataItem::TYPE_CONTAINER; |
|
173 | } |
||
174 | |||
175 | 138 | public function getSemanticData() { |
|
176 | 138 | return $this->m_semanticData; |
|
177 | } |
||
178 | |||
179 | 5 | public function getSortKey() { |
|
180 | 5 | return ''; |
|
181 | } |
||
182 | |||
183 | public function getSerialization() { |
||
184 | return serialize( $this->m_semanticData ); |
||
185 | } |
||
186 | |||
187 | /** |
||
188 | * Get a hash string for this data item. |
||
189 | * |
||
190 | * @return string |
||
191 | */ |
||
192 | 1 | public function getHash() { |
|
193 | |||
194 | 1 | $hash = $this->getValueHash( $this->m_semanticData ); |
|
195 | 1 | sort( $hash ); |
|
196 | |||
197 | 1 | return md5( implode( '#', $hash ) ); |
|
198 | |||
199 | // We want a value hash, not an entity hash!! |
||
200 | // return $this->m_semanticData->getHash(); |
||
201 | } |
||
202 | |||
203 | 1 | private function getValueHash( $semanticData ) { |
|
204 | |||
205 | 1 | $hash = array(); |
|
206 | |||
207 | 1 | foreach ( $semanticData->getProperties() as $property ) { |
|
208 | 1 | $hash[] = $property->getKey(); |
|
209 | |||
210 | 1 | foreach ( $semanticData->getPropertyValues( $property ) as $di ) { |
|
211 | 1 | $hash[] = $di->getHash(); |
|
212 | } |
||
213 | } |
||
214 | |||
215 | 1 | foreach ( $semanticData->getSubSemanticData() as $data ) { |
|
216 | $hash[] = $this->getValueHash( $data ); |
||
217 | } |
||
218 | |||
219 | 1 | return $hash; |
|
220 | } |
||
221 | |||
222 | /** |
||
223 | * Create a data item from the provided serialization string and type |
||
224 | * ID. |
||
225 | * |
||
226 | * @return SMWDIContainer |
||
227 | */ |
||
228 | public static function doUnserialize( $serialization ) { |
||
229 | /// TODO May issue an E_NOTICE when problems occur; catch this |
||
230 | $data = unserialize( $serialization ); |
||
231 | if ( !( $data instanceof SMWContainerSemanticData ) ) { |
||
232 | throw new DataItemException( "Could not unserialize SMWDIContainer from the given string." ); |
||
233 | } |
||
234 | return new SMWDIContainer( $data ); |
||
235 | } |
||
236 | |||
237 | public function equals( SMWDataItem $di ) { |
||
238 | if ( $di->getDIType() !== SMWDataItem::TYPE_CONTAINER ) { |
||
239 | return false; |
||
240 | } |
||
241 | |||
242 | return $di->getSerialization() === $this->getSerialization(); |
||
243 | } |
||
244 | } |
||
245 |
You can fix this by adding a namespace to your class:
When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.