summaryrefslogtreecommitdiff
path: root/www/wiki/extensions/SemanticMediaWiki/src/DataValues/MonolingualTextValue.php
diff options
context:
space:
mode:
Diffstat (limited to 'www/wiki/extensions/SemanticMediaWiki/src/DataValues/MonolingualTextValue.php')
-rw-r--r--www/wiki/extensions/SemanticMediaWiki/src/DataValues/MonolingualTextValue.php363
1 files changed, 363 insertions, 0 deletions
diff --git a/www/wiki/extensions/SemanticMediaWiki/src/DataValues/MonolingualTextValue.php b/www/wiki/extensions/SemanticMediaWiki/src/DataValues/MonolingualTextValue.php
new file mode 100644
index 00000000..2233ef7d
--- /dev/null
+++ b/www/wiki/extensions/SemanticMediaWiki/src/DataValues/MonolingualTextValue.php
@@ -0,0 +1,363 @@
+<?php
+
+namespace SMW\DataValues;
+
+use SMW\ApplicationFactory;
+use SMW\DataValueFactory;
+use SMW\DataValues\ValueFormatters\DataValueFormatter;
+use SMW\DIProperty;
+use SMW\DIWikiPage;
+use SMW\Localizer;
+use SMWContainerSemanticData as ContainerSemanticData;
+use SMWDataItem as DataItem;
+use SMWDataValue as DataValue;
+use SMWDIBlob as DIBlob;
+use SMWDIContainer as DIContainer;
+
+/**
+ * MonolingualTextValue requires two components, a language code and a
+ * text.
+ *
+ * A text `foo@en` is expected to be invoked with a BCP47 language
+ * code tag and a language dependent text component.
+ *
+ * Internally, the value is stored as container object that represents
+ * the language code and text as separate entities in order to be queried
+ * individually.
+ *
+ * External output representation depends on the context (wiki, html)
+ * whether the language code is omitted or not.
+ *
+ * @license GNU GPL v2+
+ * @since 2.4
+ *
+ * @author mwjames
+ */
+class MonolingualTextValue extends AbstractMultiValue {
+
+ /**
+ * DV identifier
+ */
+ const TYPE_ID = '_mlt_rec';
+
+ /**
+ * @var DIProperty[]|null
+ */
+ private static $properties = null;
+
+ /**
+ * @param string $typeid
+ */
+ public function __construct( $typeid = '' ) {
+ parent::__construct( self::TYPE_ID );
+ }
+
+ /**
+ * @see AbstractMultiValue::setFieldProperties
+ *
+ * @param DIProperty[] $properties
+ */
+ public function setFieldProperties( array $properties ) {
+ // Keep the interface while the properties for this type
+ // are fixed.
+ }
+
+ /**
+ * @see AbstractMultiValue::getProperties
+ *
+ * @param DIProperty[] $properties
+ */
+ public function getProperties() {
+ self::$properties;
+ }
+
+ /**
+ * @since 2.5
+ *
+ * @param $userValue
+ * @param string $languageCode
+ *
+ * @return string
+ */
+ public function getTextWithLanguageTag( $text, $languageCode ) {
+ return $text . '@' . Localizer::asBCP47FormattedLanguageCode( $languageCode );
+ }
+
+ /**
+ * @see DataValue::parseUserValue
+ * @note called by DataValue::setUserValue
+ *
+ * @param string $userValue
+ */
+ protected function parseUserValue( $userValue ) {
+
+ list( $text, $languageCode ) = $this->getValuesFromString( $userValue );
+
+ $languageCodeValue = $this->newLanguageCodeValue( $languageCode );
+
+ if (
+ ( $languageCode !== '' && $languageCodeValue->getErrors() !== [] ) ||
+ ( $languageCode === '' && $this->isEnabledFeature( SMW_DV_MLTV_LCODE ) ) ) {
+ $this->addError( $languageCodeValue->getErrors() );
+ return;
+ }
+
+ $dataValues = [];
+
+ foreach ( $this->getPropertyDataItems() as $property ) {
+
+ if (
+ ( $languageCode === '' && $property->getKey() === '_LCODE' ) ||
+ ( $text === '' && $property->getKey() === '_TEXT' ) ) {
+ continue;
+ }
+
+ $value = $text;
+
+ if ( $property->getKey() === '_LCODE' ) {
+ $value = $languageCode;
+ }
+
+ $dataValue = DataValueFactory::getInstance()->newDataValueByProperty(
+ $property,
+ $value,
+ false,
+ $this->m_contextPage
+ );
+
+ $this->addError( $dataValue->getErrors() );
+
+ $dataValues[] = $dataValue;
+ }
+
+ // Generate a hash from the normalized representation so that foo@en being
+ // the same as foo@EN independent of a user input
+ $containerSemanticData = $this->newContainerSemanticData( $text . '@' . $languageCode );
+
+ foreach ( $dataValues as $dataValue ) {
+ $containerSemanticData->addDataValue( $dataValue );
+ }
+
+ // Remember the data to extend the sortkey
+ $containerSemanticData->setExtensionData( 'sort.data', implode( ';', [ $text, $languageCode ] ) );
+
+ $this->m_dataitem = new DIContainer( $containerSemanticData );
+ }
+
+ /**
+ * @note called by MonolingualTextValueDescriptionDeserializer::deserialize
+ * and MonolingualTextValue::parseUserValue
+ *
+ * No explicit check is made on the validity of a language code and is
+ * expected to be done before calling this method.
+ *
+ * @since 2.4
+ *
+ * @param string $userValue
+ *
+ * @return array
+ */
+ public function getValuesFromString( $userValue ) {
+ return $this->dataValueServiceFactory->getValueParser( $this )->parse( $userValue );
+ }
+
+ /**
+ * @see DataValue::loadDataItem
+ *
+ * @param DataItem $dataItem
+ *
+ * @return boolean
+ */
+ protected function loadDataItem( DataItem $dataItem ) {
+
+ if ( $dataItem->getDIType() === DataItem::TYPE_CONTAINER ) {
+ $this->m_dataitem = $dataItem;
+ return true;
+ } elseif ( $dataItem->getDIType() === DataItem::TYPE_WIKIPAGE ) {
+ $semanticData = new ContainerSemanticData( $dataItem );
+ $semanticData->copyDataFrom( ApplicationFactory::getInstance()->getStore()->getSemanticData( $dataItem ) );
+ $this->m_dataitem = new DIContainer( $semanticData );
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * @see DataValue::getShortWikiText
+ */
+ public function getShortWikiText( $linker = null ) {
+ return $this->dataValueServiceFactory->getValueFormatter( $this )->format( DataValueFormatter::WIKI_SHORT, $linker );
+ }
+
+ /**
+ * @see DataValue::getShortHTMLText
+ */
+ public function getShortHTMLText( $linker = null ) {
+ return $this->dataValueServiceFactory->getValueFormatter( $this )->format( DataValueFormatter::HTML_SHORT, $linker );
+ }
+
+ /**
+ * @see DataValue::getLongWikiText
+ */
+ public function getLongWikiText( $linker = null ) {
+ return $this->dataValueServiceFactory->getValueFormatter( $this )->format( DataValueFormatter::WIKI_LONG, $linker );
+ }
+
+ /**
+ * @see DataValue::getLongHTMLText
+ */
+ public function getLongHTMLText( $linker = null ) {
+ return $this->dataValueServiceFactory->getValueFormatter( $this )->format( DataValueFormatter::HTML_LONG, $linker );
+ }
+
+ /**
+ * @see DataValue::getWikiValue
+ */
+ public function getWikiValue() {
+ return $this->dataValueServiceFactory->getValueFormatter( $this )->format( DataValueFormatter::VALUE );
+ }
+
+ /**
+ * @since 2.4
+ * @note called by AbstractRecordValue::getPropertyDataItems
+ *
+ * @return DIProperty[]
+ */
+ public function getPropertyDataItems() {
+
+ if ( self::$properties !== null && self::$properties !== [] ) {
+ return self::$properties;
+ }
+
+ foreach ( [ '_TEXT', '_LCODE' ] as $id ) {
+ self::$properties[] = new DIProperty( $id );
+ }
+
+ return self::$properties;
+ }
+
+ /**
+ * @since 2.4
+ *
+ * {@inheritDoc}
+ */
+ public function getDataItems() {
+ return parent::getDataItems();
+ }
+
+ /**
+ * @since 2.4
+ *
+ * @param string $languageCode
+ *
+ * @return DataValue|null
+ */
+ public function getTextValueByLanguage( $languageCode ) {
+
+ if ( ( $list = $this->toArray() ) === [] ) {
+ return null;
+ }
+
+ if ( $list['_LCODE'] !== Localizer::asBCP47FormattedLanguageCode( $languageCode ) ) {
+ return null;
+ }
+
+ if ( $list['_TEXT'] === '' ) {
+ return null;
+ }
+
+ $dataValue = DataValueFactory::getInstance()->newDataValueByItem(
+ new DIBlob( $list['_TEXT'] ),
+ new DIProperty( '_TEXT' )
+ );
+
+ return $dataValue;
+ }
+
+ /**
+ * @since 2.5
+ *
+ * @return array
+ */
+ public function toArray() {
+
+ if ( !$this->isValid() || $this->getDataItem() === [] ) {
+ return [];
+ }
+
+ $semanticData = $this->getDataItem()->getSemanticData();
+
+ $list = [
+ '_TEXT' => '',
+ '_LCODE' => ''
+ ];
+
+ $dataItems = $semanticData->getPropertyValues( new DIProperty( '_TEXT' ) );
+ $dataItem = reset( $dataItems );
+
+ if ( $dataItem !== false ) {
+ $list['_TEXT'] = $dataItem->getString();
+ }
+
+ $dataItems = $semanticData->getPropertyValues( new DIProperty( '_LCODE' ) );
+ $dataItem = reset( $dataItems );
+
+ if ( $dataItem !== false ) {
+ $list['_LCODE'] = $dataItem->getString();
+ }
+
+ return $list;
+ }
+
+ /**
+ * @since 2.5
+ *
+ * @return string
+ */
+ public function toString() {
+
+ if ( !$this->isValid() || $this->getDataItem() === [] ) {
+ return '';
+ }
+
+ $list = $this->toArray();
+
+ return $list['_TEXT'] . '@' . $list['_LCODE'];
+ }
+
+ private function newContainerSemanticData( $value ) {
+
+ if ( $this->m_contextPage === null ) {
+ $containerSemanticData = ContainerSemanticData::makeAnonymousContainer();
+ $containerSemanticData->skipAnonymousCheck();
+ } else {
+ $subobjectName = '_ML' . md5( $value );
+
+ $subject = new DIWikiPage(
+ $this->m_contextPage->getDBkey(),
+ $this->m_contextPage->getNamespace(),
+ $this->m_contextPage->getInterwiki(),
+ $subobjectName
+ );
+
+ $containerSemanticData = new ContainerSemanticData( $subject );
+ }
+
+ return $containerSemanticData;
+ }
+
+ private function newLanguageCodeValue( $languageCode ) {
+
+ $languageCodeValue = new LanguageCodeValue();
+
+ if ( $this->m_property !== null ) {
+ $languageCodeValue->setProperty( $this->m_property );
+ }
+
+ $languageCodeValue->setUserValue( $languageCode );
+
+ return $languageCodeValue;
+ }
+
+}