Completed
Push — master ( 9eae06...a41cb5 )
by mw
16s
created

src/DataValues/MonolingualTextValue.php (1 issue)

Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace SMW\DataValues;
4
5
use SMW\ApplicationFactory;
6
use SMW\DataValueFactory;
7
use SMW\DataValues\ValueFormatters\DataValueFormatter;
8
use SMW\DataValues\ValueParsers\MonolingualTextValueParser;
9
use SMW\DIProperty;
10
use SMW\DIWikiPage;
11
use SMW\Localizer;
12
use SMWContainerSemanticData as ContainerSemanticData;
13
use SMWDataItem as DataItem;
14
use SMWDataValue as DataValue;
15
use SMWDIContainer as DIContainer;
16
17
/**
18
 * MonolingualTextValue requires two components, a language code and a
19
 * text.
20
 *
21
 * A text `foo@en` is expected to be invoked with a BCP47 language
22
 * code tag and a language dependent text component.
23
 *
24
 * Internally, the value is stored as container object that represents
25
 * the language code and text as separate entities in order to be queried
26
 * individually.
27
 *
28
 * External output representation depends on the context (wiki, html)
29
 * whether the language code is omitted or not.
30
 *
31
 * @license GNU GPL v2+
32
 * @since 2.4
33
 *
34
 * @author mwjames
35
 */
36
class MonolingualTextValue extends DataValue {
37
38
	/**
39
	 * @var DIProperty[]|null
40
	 */
41
	private static $properties = null;
42
43
	/**
44
	 * @var MonolingualTextValueParser
45
	 */
46
	private $monolingualTextValueParser = null;
47
48
	/**
49
	 * @param string $typeid
50
	 */
51 18
	public function __construct( $typeid = '' ) {
52 18
		parent::__construct( '_mlt_rec' );
53 18
	}
54
55
	/**
56
	 * @see RecordValue::setFieldProperties
57
	 *
58
	 * @param DIProperty[] $properties
59
	 */
60
	public function setFieldProperties( array $properties ) {
0 ignored issues
show
The parameter $properties is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
61
		// Keep the interface while the properties for this type
62
		// are fixed.
63
	}
64
65
	/**
66
	 * @see DataValue::parseUserValue
67
	 * @note called by DataValue::setUserValue
68
	 *
69
	 * @param string $userValue
70
	 */
71 16
	protected function parseUserValue( $userValue ) {
72
73 16
		list( $text, $languageCode ) = $this->getValuesFromString( $userValue );
74
75 16
		$languageCodeValue = $this->newLanguageCodeValue( $languageCode );
76
77
		if (
78 16
			( $languageCode !== '' && $languageCodeValue->getErrors() !== array() ) ||
79 16
			( $languageCode === '' && $this->isEnabledFeature( SMW_DV_MLTV_LCODE ) ) ) {
80 3
			$this->addError( $languageCodeValue->getErrors() );
81 3
			return;
82
		}
83
84 13
		$dataValues = array();
85
86 13
		foreach ( $this->getPropertyDataItems() as $property ) {
87
88
			if (
89 13
				( $languageCode === '' && $property->getKey() === '_LCODE' ) ||
90 13
				( $text === '' && $property->getKey() === '_TEXT' ) ) {
91 1
				continue;
92
			}
93
94 13
			$value = $text;
95
96 13
			if ( $property->getKey() === '_LCODE' ) {
97 12
				$value = $languageCode;
98
			}
99
100 13
			$dataValue = DataValueFactory::getInstance()->newDataValueByProperty(
101
				$property,
102
				$value,
103 13
				false,
104 13
				$this->m_contextPage
105
			);
106
107 13
			$dataValues[] = $dataValue;
108
		}
109
110
		// Generate a hash from the normalized representation so that foo@en being
111
		// the same as foo@EN independent of a user input
112 13
		$containerSemanticData = $this->newContainerSemanticData( $text . '@' . $languageCode );
113
114 13
		foreach ( $dataValues as $dataValue ) {
115 13
			$containerSemanticData->addDataValue( $dataValue );
116
		}
117
118 13
		$this->m_dataitem = new DIContainer( $containerSemanticData );
119 13
	}
120
121
	/**
122
	 * @note called by MonolingualTextValueDescriptionDeserializer::deserialize
123
	 * and MonolingualTextValue::parseUserValue
124
	 *
125
	 * No explicit check is made on the validity of a language code and is
126
	 * expected to be done before calling this method.
127
	 *
128
	 * @since 2.4
129
	 *
130
	 * @param string $userValue
131
	 *
132
	 * @return array
133
	 */
134 16
	public function getValuesFromString( $userValue ) {
135 16
		return $this->getValueParser()->parse( $userValue );
136
	}
137
138
	/**
139
	 * @see DataValue::loadDataItem
140
	 *
141
	 * @param DataItem $dataItem
142
	 *
143
	 * @return boolean
144
	 */
145 5
	protected function loadDataItem( DataItem $dataItem ) {
146
147 5
		if ( $dataItem->getDIType() === DataItem::TYPE_CONTAINER ) {
148
			$this->m_dataitem = $dataItem;
149
			return true;
150 5
		} elseif ( $dataItem->getDIType() === DataItem::TYPE_WIKIPAGE ) {
151 5
			$semanticData = new ContainerSemanticData( $dataItem );
152 5
			$semanticData->copyDataFrom( ApplicationFactory::getInstance()->getStore()->getSemanticData( $dataItem ) );
153 5
			$this->m_dataitem = new DIContainer( $semanticData );
154 5
			return true;
155
		}
156
157 1
		return false;
158
	}
159
160
	/**
161
	 * @see DataValue::getShortWikiText
162
	 */
163 9
	public function getShortWikiText( $linker = null ) {
164 9
		return $this->getDataValueFormatter()->format( DataValueFormatter::WIKI_SHORT, $linker );
165
	}
166
167
	/**
168
	 * @see DataValue::getShortHTMLText
169
	 */
170
	public function getShortHTMLText( $linker = null ) {
171
		return $this->getDataValueFormatter()->format( DataValueFormatter::HTML_SHORT, $linker );
172
	}
173
174
	/**
175
	 * @see DataValue::getLongWikiText
176
	 */
177
	public function getLongWikiText( $linker = null ) {
178
		return $this->getDataValueFormatter()->format( DataValueFormatter::WIKI_LONG, $linker );
179
	}
180
181
	/**
182
	 * @see DataValue::getLongHTMLText
183
	 */
184
	public function getLongHTMLText( $linker = null ) {
185
		return $this->getDataValueFormatter()->format( DataValueFormatter::HTML_LONG, $linker );
186
	}
187
188
	/**
189
	 * @see DataValue::getWikiValue
190
	 */
191 5
	public function getWikiValue() {
192 5
		return $this->getDataValueFormatter()->format( DataValueFormatter::VALUE );
193
	}
194
195
	/**
196
	 * @since 2.4
197
	 * @note called by SMWResultArray::getNextDataValue
198
	 *
199
	 * @return DIProperty[]
200
	 */
201 14
	public static function getPropertyDataItems() {
202
203 14
		if ( self::$properties !== null && self::$properties !== array() ) {
204 13
			return self::$properties;
205
		}
206
207 1
		foreach ( array( '_TEXT', '_LCODE' ) as  $id ) {
208 1
			self::$properties[] = new DIProperty( $id );
209
		}
210
211 1
		return self::$properties;
212
	}
213
214
	/**
215
	 * @since 2.4
216
	 * @note called by SMWResultArray::loadContent
217
	 *
218
	 * @return DataItem[]
219
	 */
220 2
	public function getDataItems() {
221
222 2
		if ( !$this->isValid() ) {
223
			return array();
224
		}
225
226 2
		$result = array();
227 2
		$index = 0;
228
229 2
		foreach ( $this->getPropertyDataItems() as $diProperty ) {
230 2
			$values = $this->getDataItem()->getSemanticData()->getPropertyValues( $diProperty );
231 2
			if ( count( $values ) > 0 ) {
232 2
				$result[$index] = reset( $values );
233
			} else {
234
				$result[$index] = null;
235
			}
236 2
			$index += 1;
237
		}
238
239 2
		return $result;
240
	}
241
242
	/**
243
	 * @since 2.4
244
	 *
245
	 * @return DataValue|null
246
	 */
247 4
	public function getTextValueByLanguage( $languageCode ) {
248
249 4
		if ( !$this->isValid() || $this->getDataItem() === array() ) {
250
			return null;
251
		}
252
253 4
		$semanticData = $this->getDataItem()->getSemanticData();
254
255 4
		$dataItems = $semanticData->getPropertyValues( new DIProperty( '_LCODE' ) );
256 4
		$dataItem = reset( $dataItems );
257
258 4
		if ( $dataItem === false || ( $dataItem->getString() !== Localizer::asBCP47FormattedLanguageCode( $languageCode ) ) ) {
259 1
			return null;
260
		}
261
262 3
		$dataItems = $semanticData->getPropertyValues( new DIProperty( '_TEXT' ) );
263 3
		$dataItem = reset( $dataItems );
264
265 3
		if ( $dataItem === false ) {
266
			return null;
267
		}
268
269 3
		$dataValue = DataValueFactory::getInstance()->newDataValueByItem(
270
			$dataItem,
271 3
			new DIProperty( '_TEXT' )
272
		);
273
274 3
		return $dataValue;
275
	}
276
277 13
	private function newContainerSemanticData( $value ) {
278
279 13
		if ( $this->m_contextPage === null ) {
280 4
			$containerSemanticData = ContainerSemanticData::makeAnonymousContainer();
281 4
			$containerSemanticData->skipAnonymousCheck();
282
		} else {
283 9
			$subobjectName = '_ML' . md5( $value );
284
285 9
			$subject = new DIWikiPage(
286 9
				$this->m_contextPage->getDBkey(),
287 9
				$this->m_contextPage->getNamespace(),
288 9
				$this->m_contextPage->getInterwiki(),
289
				$subobjectName
290
			);
291
292 9
			$containerSemanticData = new ContainerSemanticData( $subject );
293
		}
294
295 13
		return $containerSemanticData;
296
	}
297
298 16
	private function newLanguageCodeValue( $languageCode ) {
299
300 16
		$languageCodeValue = new LanguageCodeValue();
301
302 16
		if ( $this->m_property !== null ) {
303 9
			$languageCodeValue->setProperty( $this->m_property );
304
		}
305
306 16
		$languageCodeValue->setUserValue( $languageCode );
307
308 16
		return $languageCodeValue;
309
	}
310
311 16
	private function getValueParser() {
312
313 16
		if ( $this->monolingualTextValueParser === null ) {
314 16
			$this->monolingualTextValueParser = ValueParserFactory::getInstance()->newMonolingualTextValueParser();
315
		}
316
317 16
		return $this->monolingualTextValueParser;
318
	}
319
320
}
321