m_diProperties; } /** * @since 2.3 * * @param string $value * * @return array */ public function getValuesFromString( $value ) { // #664 / T17732 $value = str_replace( "\;", "-3B", $value ); // Bug 21926 / T23926 // Values that use html entities are encoded with a semicolon $value = htmlspecialchars_decode( $value, ENT_QUOTES ); $values = preg_split( '/[\s]*;[\s]*/u', trim( $value ) ); return str_replace( "-3B", ";", $values ); } protected function parseUserValue( $value ) { if ( $value === '' ) { $this->addErrorMsg( [ 'smw_novalues' ] ); return; } $containerSemanticData = $this->newContainerSemanticData( $value ); $sortKeys = []; $values = $this->getValuesFromString( $value ); $valueIndex = 0; // index in value array $propertyIndex = 0; // index in property list $empty = true; foreach ( $this->getPropertyDataItems() as $diProperty ) { if ( !array_key_exists( $valueIndex, $values ) || $this->getErrors() !== [] ) { break; // stop if there are no values left } // generating the DVs: if ( ( $values[$valueIndex] === '' ) || ( $values[$valueIndex] == '?' ) ) { // explicit omission $valueIndex++; } else { $dataValue = DataValueFactory::getInstance()->newDataValueByProperty( $diProperty, $values[$valueIndex], false, $containerSemanticData->getSubject() ); if ( $dataValue->isValid() ) { // valid DV: keep $containerSemanticData->addPropertyObjectValue( $diProperty, $dataValue->getDataItem() ); $sortKeys[] = $dataValue->getDataItem()->getSortKey(); $valueIndex++; $empty = false; } elseif ( ( count( $values ) - $valueIndex ) == ( count( $this->m_diProperties ) - $propertyIndex ) ) { $containerSemanticData->addPropertyObjectValue( $diProperty, $dataValue->getDataItem() ); $this->addError( $dataValue->getErrors() ); ++$valueIndex; } } ++$propertyIndex; } if ( $empty && $this->getErrors() === [] ) { $this->addErrorMsg( [ 'smw_novalues' ] ); } // Remember the data to extend the sortkey $containerSemanticData->setExtensionData( 'sort.data', implode( ';', $sortKeys ) ); $this->m_dataitem = new DIContainer( $containerSemanticData ); } /** * @see SMWDataValue::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; } else { return false; } } public function getShortWikiText( $linked = null ) { if ( $this->m_caption !== false ) { return $this->m_caption; } return $this->makeOutputText( 0, $linked ); } public function getShortHTMLText( $linker = null ) { if ( $this->m_caption !== false ) { return $this->m_caption; } return $this->makeOutputText( 1, $linker ); } public function getLongWikiText( $linked = null ) { return $this->makeOutputText( 2, $linked ); } public function getLongHTMLText( $linker = null ) { return $this->makeOutputText( 3, $linker ); } public function getWikiValue() { return $this->makeOutputText( 4 ); } /** * Make sure that the content is reset in this case. * @todo This is not a full reset yet (the case that property is changed after a value * was set does not occur in the normal flow of things, hence this has low priority). */ public function setProperty( DIProperty $property ) { parent::setProperty( $property ); $this->m_diProperties = null; } /** * @since 2.1 * * @param DIProperty[] $properties */ public function setFieldProperties( array $properties ) { foreach ( $properties as $property ) { if ( $property instanceof DIProperty ) { $this->m_diProperties[] = $property; } } } /** * @since 1.6 * * {@inheritDoc} */ public function getDataItems() { return parent::getDataItems(); } /** * Return the array (list) of properties that the individual entries of * this datatype consist of. * * @since 1.6 * * @todo I18N for error message. * * @return array of DIProperty */ public function getPropertyDataItems() { if ( $this->m_diProperties !== null ) { return $this->m_diProperties; } $this->m_diProperties = $this->getFieldProperties( $this->m_property ); if ( $this->m_diProperties === [] ) { // TODO internalionalize $this->addError( 'The list of properties to be used for the data fields has not been specified properly.' ); } return $this->m_diProperties; } protected function makeOutputText( $type = 0, $linker = null ) { if ( !$this->isValid() ) { return ( ( $type == 0 ) || ( $type == 1 ) ) ? '' : $this->getErrorText(); } $result = ''; $i = 0; foreach ( $this->getPropertyDataItems() as $propertyDataItem ) { if ( $i == 1 ) { $result .= ( $type == 4 ) ? '; ' : ' ('; } elseif ( $i > 1 ) { $result .= ( $type == 4 ) ? '; ' : ', '; } ++$i; $propertyValues = $this->m_dataitem->getSemanticData()->getPropertyValues( $propertyDataItem ); // combining this with next line violates PHP strict standards $dataItem = reset( $propertyValues ); if ( $dataItem !== false ) { $dataValue = DataValueFactory::getInstance()->newDataValueByItem( $dataItem, $propertyDataItem ); $result .= $this->makeValueOutputText( $type, $dataValue, $linker ); } else { $result .= '?'; } } if ( ( $i > 1 ) && ( $type != 4 ) ) { $result .= ')'; } return $result; } protected function makeValueOutputText( $type, SMWDataValue $dataValue, $linker ) { switch ( $type ) { case 0: return $dataValue->getShortWikiText( $linker ); case 1: return $dataValue->getShortHTMLText( $linker ); case 2: return $dataValue->getShortWikiText( $linker ); case 3: return $dataValue->getShortHTMLText( $linker ); case 4: return str_replace( ";", "\;", $dataValue->getWikiValue() ); } } private function newContainerSemanticData( $value ) { if ( $this->m_contextPage === null ) { $containerSemanticData = ContainerSemanticData::makeAnonymousContainer(); $containerSemanticData->skipAnonymousCheck(); } else { $subobjectName = '_' . hash( 'md4', $value, false ); // md4 is probably fastest of PHP's hashes $subject = new DIWikiPage( $this->m_contextPage->getDBkey(), $this->m_contextPage->getNamespace(), $this->m_contextPage->getInterwiki(), $subobjectName ); $containerSemanticData = new ContainerSemanticData( $subject ); } return $containerSemanticData; } }