/**
	 * Create exportable data from a given semantic data record.
	 *
	 * @param $semdata SMWSemanticData
	 * @return SMWExpData
	 */
	static public function makeExportData( SMWSemanticData $semdata ) {
		self::initBaseURIs();
		$subject = $semdata->getSubject();
		if ( $subject->getNamespace() == SMW_NS_PROPERTY ) {
			$types = $semdata->getPropertyValues( new SMWDIProperty( '_TYPE' ) );
		} else {
			$types = array();
		}
		$result = self::makeExportDataForSubject( $subject, end( $types ) );
		foreach ( $semdata->getProperties() as $property ) {
			self::addPropertyValues( $property, $semdata->getPropertyValues( $property ), $result, $subject );
		}
		return $result;
	}
 /**
  * Create an array of rows to insert into property tables in order to
  * store the given SMWSemanticData. The given $sid (subject page id) is
  * used directly and must belong to the subject of the data container.
  * Sortkeys are ignored since they are not stored in a property table
  * but in the ID table.
  *
  * The returned array uses property table names as keys and arrays of
  * table rows as values. Each table row is an array mapping column
  * names to values.
  *
  * @note Property tables that do not use ids as subjects are ignored.
  * This just excludes redirects that are handled differently anyway;
  * it would not make a difference to include them here.
  *
  * @since 1.8
  * @param integer $sid
  * @param SMWSemanticData $data
  * @param DatabaseBase $dbr used for reading only
  * @return array
  */
 protected function preparePropertyTableInserts($sid, SMWSemanticData $data, DatabaseBase $dbr)
 {
     $updates = array();
     $subject = $data->getSubject();
     $propertyTables = SMWSQLStore3::getPropertyTables();
     foreach ($data->getProperties() as $property) {
         $tableId = SMWSQLStore3::findPropertyTableID($property);
         if (is_null($tableId)) {
             // not stored in a property table, e.g., sortkeys
             continue;
         }
         $propertyTable = $propertyTables[$tableId];
         if (!$propertyTable->usesIdSubject()) {
             // not using subject ids, e.g., redirects
             continue;
         }
         $insertValues = array('s_id' => $sid);
         if (!$propertyTable->isFixedPropertyTable()) {
             $insertValues['p_id'] = $this->store->smwIds->makeSMWPropertyID($property);
         }
         foreach ($data->getPropertyValues($property) as $di) {
             if ($di instanceof SMWDIError) {
                 // ignore error values
                 continue;
             }
             if (!array_key_exists($propertyTable->getName(), $updates)) {
                 $updates[$propertyTable->getName()] = array();
             }
             $diHandler = $this->store->getDataItemHandlerForDIType($di->getDIType());
             // Note that array_merge creates a new array; not overwriting past entries here
             $insertValues = array_merge($insertValues, $diHandler->getInsertValues($di));
             $insertValueKey = self::makeDatabaseRowKey($insertValues);
             $updates[$propertyTable->getName()][$insertValueKey] = $insertValues;
         }
     }
     // Special handling of Concepts
     if ($subject->getNamespace() == SMW_NS_CONCEPT && $subject->getSubobjectName() == '') {
         $this->prepareConceptTableInserts($sid, $updates, $dbr);
     }
     return $updates;
 }
 /**
  * Change the object to become an exact copy of the given
  * SMWSemanticData object. This is used to make other types of
  * SMWSemanticData into an SMWContainerSemanticData. To copy objects of
  * the same type, PHP clone() should be used.
  *
  * @since 1.7
  *
  * @param $semanticData SMWSemanticData object to copy from
  */
 public function copyDataFrom(SMWSemanticData $semanticData)
 {
     $this->mSubject = $semanticData->getSubject();
     $this->mProperties = $semanticData->getProperties();
     $this->mPropVals = array();
     foreach ($this->mProperties as $property) {
         $this->mPropVals[$property->getKey()] = $semanticData->getPropertyValues($property);
     }
     $this->mHasVisibleProps = $semanticData->hasVisibleProperties();
     $this->mHasVisibleSpecs = $semanticData->hasVisibleSpecialProperties();
     $this->mNoDuplicates = $semanticData->mNoDuplicates;
 }
Exemple #4
0
 /**
  * This function creates wiki text suitable for rendering a Factbox for a given
  * SMWSemanticData object that holds all relevant data. It also checks whether the
  * given setting of $showfactbox requires displaying the given data at all.
  * 
  * @param SMWSemanticData $semdata
  * @param boolean $showfactbox
  * 
  * @return string
  */
 public static function getFactboxText(SMWSemanticData $semdata, $showfactbox = SMW_FACTBOX_NONEMPTY)
 {
     global $wgContLang;
     wfProfileIn('SMWFactbox::printFactbox (SMW)');
     switch ($showfactbox) {
         case SMW_FACTBOX_HIDDEN:
             // never show
             wfProfileOut('SMWFactbox::printFactbox (SMW)');
             return '';
         case SMW_FACTBOX_SPECIAL:
             // show only if there are special properties
             if (!$semdata->hasVisibleSpecialProperties()) {
                 wfProfileOut('SMWFactbox::printFactbox (SMW)');
                 return '';
             }
             break;
         case SMW_FACTBOX_NONEMPTY:
             // show only if non-empty
             if (!$semdata->hasVisibleProperties()) {
                 wfProfileOut('SMWFactbox::printFactbox (SMW)');
                 return '';
             }
             break;
             // case SMW_FACTBOX_SHOWN: // just show ...
     }
     // actually build the Factbox text:
     $text = '';
     if (wfRunHooks('smwShowFactbox', array(&$text, $semdata))) {
         $subjectDv = SMWDataValueFactory::newDataItemValue($semdata->getSubject(), null);
         SMWOutputs::requireResource('ext.smw.style');
         $rdflink = SMWInfolink::newInternalLink(wfMessage('smw_viewasrdf')->inContentLanguage()->text(), $wgContLang->getNsText(NS_SPECIAL) . ':ExportRDF/' . $subjectDv->getWikiValue(), 'rdflink');
         $browselink = SMWInfolink::newBrowsingLink($subjectDv->getText(), $subjectDv->getWikiValue(), 'swmfactboxheadbrowse');
         $text .= '<div class="smwfact">' . '<span class="smwfactboxhead">' . wfMessage('smw_factbox_head', $browselink->getWikiText())->inContentLanguage()->text() . '</span>' . '<span class="smwrdflink">' . $rdflink->getWikiText() . '</span>' . '<table class="smwfacttable">' . "\n";
         foreach ($semdata->getProperties() as $propertyDi) {
             $propertyDv = SMWDataValueFactory::newDataItemValue($propertyDi, null);
             if (!$propertyDi->isShown()) {
                 // showing this is not desired, hide
                 continue;
             } elseif ($propertyDi->isUserDefined()) {
                 // user defined property
                 $propertyDv->setCaption(preg_replace('/[ ]/u', '&#160;', $propertyDv->getWikiValue(), 2));
                 /// NOTE: the preg_replace is a slight hack to ensure that the left column does not get too narrow
                 $text .= '<tr><td class="smwpropname">' . $propertyDv->getShortWikiText(true) . '</td><td class="smwprops">';
             } elseif ($propertyDv->isVisible()) {
                 // predefined property
                 $text .= '<tr><td class="smwspecname">' . $propertyDv->getShortWikiText(true) . '</td><td class="smwspecs">';
             } else {
                 // predefined, internal property
                 continue;
             }
             $propvalues = $semdata->getPropertyValues($propertyDi);
             $valuesHtml = array();
             foreach ($propvalues as $dataItem) {
                 $dataValue = SMWDataValueFactory::newDataItemValue($dataItem, $propertyDi);
                 if ($dataValue->isValid()) {
                     $valuesHtml[] = $dataValue->getLongWikiText(true) . $dataValue->getInfolinkText(SMW_OUTPUT_WIKI);
                 }
             }
             $text .= $GLOBALS['wgLang']->listToText($valuesHtml);
             $text .= '</td></tr>';
         }
         $text .= '</table></div>';
     }
     wfProfileOut('SMWFactbox::printFactbox (SMW)');
     return $text;
 }
 public function updateData(SMWSemanticData $data, $store)
 {
     //get list of properties which are set by this article
     //todo: think about only querying for modified properties
     $properties = $data->getProperties();
     foreach ($properties as $name => $property) {
         //ignore internal properties
         if (!$property->isUserDefined() || $name == QRC_HQID_LABEL) {
             unset($properties[$name]);
         }
     }
     //determine differences between the new and the original semantic data
     global $wgTitle;
     if ($wgTitle) {
         $originalData = $store->getSemanticData($wgTitle);
         foreach ($originalData->getProperties() as $oName => $oProperty) {
             if (array_key_exists($oName, $properties)) {
                 $oValues = $originalData->getPropertyValues($oProperty);
                 $values = $data->getPropertyValues($properties[$oName]);
                 if (count($oValues) == count($values)) {
                     $oWikiValues = array();
                     foreach ($oValues as $key => $value) {
                         $oWikiValues[$value->getWikiValue()] = true;
                     }
                     $wikiValues = array();
                     foreach ($values as $key => $value) {
                         $wikiValues[$value->getWikiValue()] = true;
                     }
                     $unset = true;
                     foreach (array_keys($values) as $value) {
                         if (!array_key_exists($value, $oWikiValues)) {
                             $unset = false;
                             break;
                         }
                     }
                     if ($unset) {
                         unset($properties[$oName]);
                     }
                 }
                 //echo('<pre>'.print_r($oProperty, true).'</pre>');
                 //echo('<pre>'.print_r(, true).'</pre>');
             } else {
                 if ($oProperty->isUserDefined() && $name != QRC_HQID_LABEL) {
                     $properties[$oName] = $oProperty;
                 }
             }
         }
     }
     //deal with categories and determine which queries to update
     $categories = array();
     global $wgParser;
     if ($wgParser && $wgParser->getOutput() && $wgTitle) {
         $categories = $wgParser->getOutput()->getCategories();
         $originalCategories = $wgTitle->getParentCategories();
         //echo('<pre>'.print_r($originalCategories, true).'</pre>');
         foreach (array_keys($originalCategories) as $category) {
             $category = substr($category, strpos($category, ':') + 1);
             if (array_key_exists($category, $categories)) {
                 unset($categories[$category]);
             } else {
                 $categories[$category] = true;
             }
         }
     }
     //echo('<pre>'.print_r(array_keys($categories), true).'</pre>');
     //echo('<pre>'.print_r(array_keys($properties), true).'</pre>');
     if (count($properties) > 0 || count($categories) > 0) {
         //query for all articles that use a query which depends on one of the properties
         $queryString = SMWQRCQueryManagementHandler::getInstance()->getSearchQueriesAffectedByDataModification(array_keys($properties), array_keys($categories));
         SMWQueryProcessor::processFunctionParams(array($queryString), $queryString, $params, $printouts);
         $query = SMWQueryProcessor::createQuery($queryString, $params);
         $queryResults = $this->getQueryResult($query, true, false)->getResults();
         //get query ids which have to be invalidated
         $queryIds = array();
         foreach ($queryResults as $queryResult) {
             $semanticData = $store->getSemanticData($queryResult);
             $invalidatePC = false;
             $tQueryIds = SMWQRCQueryManagementHandler::getInstance()->getIdsOfQueriesUsingProperty($semanticData, $properties);
             if (count($tQueryIds) > 0) {
                 $invalidatePC = true;
             }
             $queryIds = array_merge($queryIds, $tQueryIds);
             $tQueryIds = SMWQRCQueryManagementHandler::getInstance()->getIdsOfQueriesUsingCategory($semanticData, $categories);
             if (count($tQueryIds) > 0) {
                 $invalidatePC = true;
             }
             $queryIds = array_merge($queryIds, $tQueryIds);
             global $invalidateParserCache, $showInvalidatedCacheEntries;
             if ($invalidatePC && $invalidateParserCache && !$showInvalidatedCacheEntries) {
                 $title = $queryResult->getTitle();
                 $title->invalidateCache();
             }
         }
         $qrcStore = SMWQRCStore::getInstance()->getDB();
         $qrcStore->invalidateQueryData($queryIds);
     }
     return $store->doUpdateData($data);
 }
Exemple #6
0
 /**
  * Removes data from the given SMWSemanticData.
  * If the subject of the data that is to be removed is not equal to the
  * subject of this SMWSemanticData, it will just be ignored (nothing to
  * remove). Likewise, removing data that is not present does not change
  * anything.
  *
  * @since 1.8
  *
  * @param $semanticData SMWSemanticData
  */
 public function removeDataFrom(SMWSemanticData $semanticData)
 {
     if (!$this->mSubject->equals($semanticData->getSubject())) {
         return;
     }
     foreach ($semanticData->getProperties() as $property) {
         $values = $semanticData->getPropertyValues($property);
         foreach ($values as $dataItem) {
             $this->removePropertyObjectValue($property, $dataItem);
         }
     }
     foreach ($semanticData->getSubSemanticData() as $semData) {
         $this->removeSubSemanticData($semData);
     }
 }
 /**
  * Get the array of all properties that have stored values.
  *
  * @return array of SMWDIProperty objects
  */
 public function getProperties()
 {
     $this->unstubProperties();
     return parent::getProperties();
 }
 /**
  * Extend the given update array to account for the data in the
  * SMWSemanticData object. The subject page of the data container is
  * ignored, and the given $sid (subject page id) is used directly. If
  * this ID is 0, then $subject is used to find an ID. This is usually
  * the case for all internal objects that are created in writing
  * container values.
  *
  * The function returns the id that was used for writing. Especially,
  * any newly created internal id is returned.
  *
  * @param $updates array
  * @param $data SMWSemanticData
  * @param $sid integer pre-computed id if available or 0 if ID should be sought
  * @param $subject SMWDIWikiPage subject to which the data refers
  */
 protected function prepareDBUpdates(&$updates, SMWSemanticData $data, $sid, SMWDIWikiPage $subject)
 {
     $subSemanticData = $data->getSubSemanticData();
     if ($sid == 0) {
         $sid = $this->makeSMWPageID($subject->getDBkey(), $subject->getNamespace(), $subject->getInterwiki(), $subject->getSubobjectName(), true, str_replace('_', ' ', $subject->getDBkey()) . $subject->getSubobjectName());
     }
     $proptables = self::getPropertyTables();
     foreach ($data->getProperties() as $property) {
         if ($property->getKey() == '_SKEY' || $property->getKey() == '_REDI') {
             continue;
             // skip these here, we store them differently
         }
         $tableid = self::findPropertyTableID($property);
         $proptable = $proptables[$tableid];
         foreach ($data->getPropertyValues($property) as $di) {
             if ($di instanceof SMWDIError) {
                 // error values, ignore
                 continue;
             }
             // redirects were treated above
             // To support compatibility with the new handling of Subobjects
             if ($di->getDIType() == SMWDataItem::TYPE_WIKIPAGE && array_key_exists($di->getSubobjectName(), $subSemanticData)) {
                 $di = new SMWDIContainer($subSemanticData[$di->getSubobjectName()]);
             }
             ///TODO check needed if subject is null (would happen if a user defined proptable with !idsubject was used on an internal object -- currently this is not possible
             $uvals = $proptable->idsubject ? array('s_id' => $sid) : array('s_title' => $subject->getDBkey(), 's_namespace' => $subject->getNamespace());
             if ($proptable->fixedproperty == false) {
                 $uvals['p_id'] = $this->makeSMWPropertyID($property);
             }
             if ($di instanceof SMWDIContainer) {
                 // process subobjects recursively
                 $subObject = $di->getSemanticData()->getSubject();
                 $subObjectId = $this->prepareDBUpdates($updates, $di->getSemanticData(), 0, $subObject);
                 // Note: tables for container objects MUST have objectfields == array(<somename> => 'p')
                 reset($proptable->objectfields);
                 $uvals[key($proptable->objectfields)] = $subObjectId;
             } else {
                 $dbkeys = SMWCompatibilityHelpers::getDBkeysFromDataItem($di);
                 reset($dbkeys);
                 foreach ($proptable->objectfields as $fieldname => $typeid) {
                     if ($typeid != 'p') {
                         $uvals[$fieldname] = current($dbkeys);
                     } else {
                         $uvals[$fieldname] = $this->makeSMWPageID($di->getDBkey(), $di->getNamespace(), $di->getInterwiki(), $di->getSubobjectName());
                     }
                     next($dbkeys);
                 }
             }
             if (!array_key_exists($proptable->name, $updates)) {
                 $updates[$proptable->name] = array();
             }
             $updates[$proptable->name][] = $uvals;
         }
     }
     return $sid;
 }
	private function process( SMWSemanticData $answer ) {
		$this->getResult()->addValue( array( 'smwwriteable' ), 'title', $answer->getSubject()->getWikiValue() );
		$properties = $answer->getProperties();
		foreach ( $properties as $property ) {
			$values = $answer->getPropertyValues( $property );
			$valuestrings = array();
			foreach ( $values as $value ) $valuestrings[] = $value->getWikiValue();
			$this->getResult()->setIndexedTagName( $valuestrings, 'value' );
			$this->getResult()->addValue( array( 'smwwriteable', 'properties' ), $property->getWikiValue(), $valuestrings );
		}
	}
 /**
  * Extend the given update array to account for the data in the
  * SMWSemanticData object. The subject page of the data container is
  * ignored, and the given $sid (subject page id) is used directly. If
  * this ID is 0, then $subject is used to find an ID. This is usually
  * the case for all internal objects (subobjects) that are created in
  * writing sub-SemanticData.
  *
  * The function returns the id that was used for writing. Especially,
  * any newly created internal id is returned.
  *
  * @param $updates array
  * @param $data SMWSemanticData
  * @param $sid integer pre-computed id if available or 0 if ID should be sought
  * @param $subject SMWDIWikiPage subject to which the data refers
  */
 protected function prepareDBUpdates(&$updates, SMWSemanticData $data, $sid, SMWDIWikiPage $subject)
 {
     if ($sid == 0) {
         $sid = $this->store->smwIds->makeSMWPageID($subject->getDBkey(), $subject->getNamespace(), $subject->getInterwiki(), $subject->getSubobjectName(), true, str_replace('_', ' ', $subject->getDBkey()) . $subject->getSubobjectName());
     }
     $proptables = SMWSQLStore3::getPropertyTables();
     foreach ($data->getProperties() as $property) {
         if ($property->getKey() == '_SKEY' || $property->getKey() == '_REDI') {
             continue;
             // skip these here, we store them differently
         }
         $tableid = SMWSQLStore3::findPropertyTableID($property);
         $proptable = $proptables[$tableid];
         ///TODO check needed if subject is null (would happen if a user defined proptable with !idsubject was used on an internal object -- currently this is not possible
         $uvals = $proptable->idsubject ? array('s_id' => $sid) : array('s_title' => $subject->getDBkey(), 's_namespace' => $subject->getNamespace());
         if ($proptable->fixedproperty == false) {
             $uvals['p_id'] = $this->store->smwIds->makeSMWPropertyID($property);
         }
         foreach ($data->getPropertyValues($property) as $di) {
             if ($di instanceof SMWDIError) {
                 // error values, ignore
                 continue;
             }
             $diHandler = $this->store->getDataItemHandlerForDIType($di->getDIType());
             $uvals = array_merge($uvals, $diHandler->getInsertValues($di));
             if (!array_key_exists($proptable->name, $updates)) {
                 $updates[$proptable->name] = array();
             }
             $updates[$proptable->name][] = $uvals;
         }
     }
     // Special handling of Concepts
     if ($subject->getNamespace() == SMW_NS_CONCEPT && $subject->getSubobjectName() == '') {
         if (array_key_exists('smw_fpt_conc', $updates) && count($updates['smw_fpt_conc']) != 0) {
             $updates['smw_fpt_conc'] = end($updates['smw_fpt_conc']);
             unset($updates['smw_fpt_conc']['cache_date']);
             unset($updates['smw_fpt_conc']['cache_count']);
         } else {
             $updates['smw_fpt_conc'] = array('concept_txt' => '', 'concept_docu' => '', 'concept_features' => 0, 'concept_size' => -1, 'concept_depth' => -1);
         }
     }
     return $sid;
 }
Exemple #11
0
 /**
  * This function is used for storing a SMWSemanticData Item in the Solr
  * Index
  *
  * @param SMWSemanticData $data
  */
 public function parseSemanticData(SMWSemanticData $data)
 {
     $solritem = new SolrDoc();
     $solritem->addField('pagetitle', $data->getSubject()->getTitle()->getText());
     $solritem->addField('namespace', $data->getSubject()->getNamespace());
     $solritem->addField('dbkey', $data->getSubject()->getDBkey());
     $solritem->addField('interwiki', $data->getSubject()->getInterwiki());
     $solritem->addField('subobjectname', $data->getSubject()->getSubobjectName());
     foreach ($data->getProperties() as $property) {
         if ($property->getKey() == '_SKEY' || $property->getKey() == '_REDI') {
             continue;
             // skip these here, we store them differently
         }
         $propertyName = $property->getLabel();
         foreach ($data->getPropertyValues($property) as $di) {
             if ($di instanceof SMWDIError) {
                 // error values, ignore
                 continue;
             }
             switch ($di->getDIType()) {
                 case 0:
                     //	  /// Data item ID that can be used to indicate that no data item class is appropriate
                     //	const TYPE_NOTYPE = 0;
                     break;
                 case 1:
                     //	/// Data item ID for SMWDINumber
                     //	const TYPE_NUMBER = 1;
                     $solritem->addField($propertyName . '_i', $di->getNumber());
                     $solritem->addSortField($propertyName . '_i', $di->getNumber());
                     break;
                 case 2:
                     //	/// Data item ID for SMWDIString
                     //	const TYPE_STRING = 2;
                     $solritem->addField($propertyName . '_t', $di->getString());
                     $solritem->addSortField($propertyName . '_t', $di->getString());
                     break;
                 case 3:
                     //	///  Data item ID for SMWDIBlob
                     //	const TYPE_BLOB = 3;
                     $solritem->addField($propertyName . '_t', $di->getString());
                     $solritem->addSortField($propertyName . '_t', $di->getString());
                     break;
                 case 4:
                     //	///  Data item ID for SMWDIBoolean
                     //	const TYPE_BOOLEAN = 4;
                     $solritem->addField($propertyName . '_b', $di->getBoolean());
                     $solritem->addSortField($propertyName . '_b', $di->getBoolean());
                     break;
                 case 5:
                     //	///  Data item ID for SMWDIUri
                     //	const TYPE_URI = 5;
                     $solritem->addField($propertyName . '_t', $di->getURI());
                     $solritem->addSortField($propertyName . '_t', $di->getURI());
                     break;
                 case 6:
                     //	///  Data item ID for SMWDITimePoint
                     //	const TYPE_TIME = 6;
                     $date = $di->getYear() . '-' . $di->getMonth() . '-' . $di->getDay() . 'T' . $di->getHour() . ':' . $di->getMinute() . ':' . $di->getSecond() . 'Z';
                     $solritem->addField($propertyName . '_dt', $date);
                     $solritem->addSortField($propertyName . '_dt', $date);
                     break;
                 case 7:
                     //	///  Data item ID for SMWDIGeoCoord
                     //	const TYPE_GEO = 7;
                     // TODO: Implement range Search in SOLR
                     $solritem->addField($propertyName . '_lat', $di->getLatitude());
                     $solritem->addField($propertyName . '_lng', $di->getLongitude());
                     break;
                 case 8:
                     //	///  Data item ID for SMWDIContainer
                     //	const TYPE_CONTAINER = 8
                     // TODO: What the hell is this used for?
                     $data->getSubject()->getTitle()->getText() . ' : ';
                     break;
                 case 9:
                     //	///  Data item ID for SMWDIWikiPage
                     //	const TYPE_WIKIPAGE = 9;
                     $ns = $di->getNamespace();
                     if ($ns == 0) {
                         $solritem->addField($propertyName . '_s', $di->getTitle());
                     } elseif ($ns == 14) {
                         $title = $di->getTitle();
                         $solritem->addField('category', substr($title, stripos($title, ':') + 1));
                     }
                     break;
                 case 10:
                     //	///  Data item ID for SMWDIConcept
                     //	const TYPE_CONCEPT = 10;
                     $data->getSubject()->getTitle()->getText() . ' : ';
                     break;
                 case 11:
                     //	///  Data item ID for SMWDIProperty
                     //	const TYPE_PROPERTY = 11;
                     $data->getSubject()->getTitle()->getText() . ' : ';
                     break;
                 case 12:
                     //	///  Data item ID for SMWDIError
                     //	const TYPE_ERROR = 12;
                     $data->getSubject()->getTitle()->getText() . ' : ';
                     break;
                 default:
                     break;
             }
         }
     }
     $this->addDoc($solritem);
 }
 /**
  * Create exportable data from a given semantic data record.
  *
  * @param $semdata SMWSemanticData
  * @return SMWExpData
  */
 public static function makeExportData(SMWSemanticData $semdata)
 {
     self::initBaseURIs();
     $subject = $semdata->getSubject();
     // Make sure to use the canonical form, a localized representation
     // should not carry a reference to a subject (e.g invoked as incoming
     // property caused by a different user language)
     if ($subject->getNamespace() === SMW_NS_PROPERTY && $subject->getSubobjectName() === '') {
         $subject = DIProperty::newFromUserLabel($subject->getDBKey())->getCanonicalDiWikiPage();
     }
     // #1690 Couldn't match a CanonicalDiWikiPage which is most likely caused
     // by an outdated pre-defined property therefore use the original subject
     if ($subject->getDBKey() === '') {
         $subject = $semdata->getSubject();
     }
     // #649 Alwways make sure to have a least one valid sortkey
     if (!$semdata->getPropertyValues(new DIProperty('_SKEY')) && $subject->getSortKey() !== '') {
         $semdata->addPropertyObjectValue(new DIProperty('_SKEY'), new SMWDIBlob($subject->getSortKey()));
     }
     $result = self::makeExportDataForSubject($subject);
     foreach ($semdata->getProperties() as $property) {
         self::addPropertyValues($property, $semdata->getPropertyValues($property), $result, $subject);
     }
     return $result;
 }
	/**
	 * Takes the request and turns requests like ***, s** and sp* into actual
	 * remove and add requests which are saved in this objects remove and add
	 * value.
	 *
	 * @param SMWSemanticData $remove All the facts meant to be removed
	 * @param SMWSemanticData $add All the facts meant to be added
	 */
	private function normalizeRequest( SMWSemanticData $remove, SMWSemanticData $add ) {

		$this->initCurrent();
		$this->initUpdateable();
		$this->initFixed();

		// if remove = ***, then nothing needs to be removed
		if ( $this->nosubject ) {
			$this->remove = new SMWWriterData();
			$this->add = new SMWWriterData();
			$this->add->copySemanticData( $add );

			// for each spv in a :
			$propertiesAdd = $this->add->getPropertynames();
			foreach ( $propertiesAdd as $propertyname ) {
				$values = $this->add->getPropertyValues( $propertyname );
				foreach ( $values as $value ) {
				// if spv in current : a -= spv
				if ( $this->current->contains( $propertyname, $value ) )
					$this->add->removePropertynameValue( $propertyname, $value );
				}
			}
			return;
		}

		// rr = requested to remove and removable
		$rr = new SMWWriterData();
		// rc = requested to remove but constant
		$rc = new SMWWriterData();
		// rx = requested to remove but not existent
		$rx = new SMWWriterData();

		// if remove = s**
		if ( count( $remove->getProperties() ) == 0 ) {
			$rr->copy( $this->updateable );
			$rc->copy( $this->fixed );
		} else {
			$properties = $remove->getProperties();
			foreach ( $properties as $property ) {
				if ( !$property->isUserDefined() ) continue;
				$propertyname = $property->getWikiValue();
				$values = $remove->getPropertyValues( $property );
				// is sp*?
				$vals = $values;
				foreach ( $values as $value ) {
					if ( count( $values ) > 1 ) break;
					$hash = $value->getHash();
					if ( empty( $hash ) )
						$vals = $this->current->getPropertyValues( $property );
				}
				// and spo
				foreach ( $vals as $value )
					if ( $this->updateable->contains( $propertyname, $value ) )
						$rr->addPropertyValue( $property, $value );
					elseif ( $this->fixed->contains( $propertyname, $value ) )
						$rc->addPropertyValue( $property, $value );
					else
						$rx->addPropertyValue( $property, $value );
			}
		}

		// a = what to add
		$a = new SMWWriterData();
		$a->copySemanticData( $add );

		// if ATOM and rx not empty : raise error
		if ( ( $this->flags & SMWWriter::ATOMIC_CHANGE ) && ( count( $rx->getPropertynames() ) > 0 ) ) {
			$this->addError( "There is metadata that was asked to be removed, but does not exist." );
			return;
		}

		// for each spv in a :
		$propertiesAdd = $a->getPropertynames();
		foreach ( $propertiesAdd as $propertyname ) {
			$values = $a->getPropertyValues( $propertyname );
			foreach ( $values as $value ) {
				// if spv in rr : rr -= spv, a -= spv
				if ( $rr->contains( $propertyname, $value ) ) {
					$rr->removePropertynameValue( $propertyname, $value );
					$a->removePropertynameValue( $propertyname, $value );
				}
				// if spv in rc : rc -= spv, a -= spv
				if ( $rc->contains( $propertyname, $value ) ) {
					$rc->removePropertynameValue( $propertyname, $value );
					$a->removePropertynameValue( $propertyname, $value );
				}
				// if spv in current : a -= spv
				if ( $this->current->contains( $propertyname, $value ) )
					$a->removePropertynameValue( $propertyname, $value );
			}
		}


		// if ATOM and not CONSTIGNORE and rc not empty : raise error
		if ( ( $this->flags & SMWWriter::ATOMIC_CHANGE ) && !( $this->flags & SMWWriter::IGNORE_CONSTANT ) && ( count( $rc->getPropertynames() ) > 0 ) ) {
			$this->addError( "There is metadata that was asked to be removed, but cannot be removed." );
			return;
		}

		$this->add = $a;
		$this->remove = $rr;
	}
 /**
  * Create exportable data from a given semantic data record.
  *
  * @param $semdata SMWSemanticData
  * @return SMWExpData
  */
 public static function makeExportData(SMWSemanticData $semdata)
 {
     self::initBaseURIs();
     $subject = $semdata->getSubject();
     // #649 Alwways make sure to have a least one valid sortkey
     if (!$semdata->getPropertyValues(new DIProperty('_SKEY')) && $subject->getSortKey() !== '') {
         $semdata->addPropertyObjectValue(new DIProperty('_SKEY'), new SMWDIBlob($subject->getSortKey()));
     }
     $result = self::makeExportDataForSubject($subject);
     foreach ($semdata->getProperties() as $property) {
         self::addPropertyValues($property, $semdata->getPropertyValues($property), $result, $subject);
     }
     return $result;
 }
 /**
  * Add all data from the given SMWSemanticData.
  *
  * @since 1.7
  *
  * @param $semanticData SMWSemanticData object to copy from
  */
 public function importDataFrom(SMWSemanticData $semanticData)
 {
     // Shortcut when copying into empty objects that don't ask for more duplicate elimination:
     if (count($this->mProperties) == 0 && $semanticData->mNoDuplicates >= $this->mNoDuplicates) {
         $this->mProperties = $semanticData->getProperties();
         $this->mPropVals = array();
         foreach ($this->mProperties as $property) {
             $this->mPropVals[$property->getKey()] = $semanticData->getPropertyValues($property);
         }
         $this->mHasVisibleProps = $semanticData->hasVisibleProperties();
         $this->mHasVisibleSpecs = $semanticData->hasVisibleSpecialProperties();
     } else {
         foreach ($semanticData->getProperties() as $property) {
             $values = $semanticData->getPropertyValues($property);
             foreach ($values as $dataItem) {
                 $this->addPropertyObjectValue($property, $dataItem);
             }
         }
     }
 }
	/**
	 * Creates the HTML table displaying the data of one subject.
	 *
	 * @param[in] $data SMWSemanticData  The data to be displayed
	 * @param[in] $left bool  Should properties be displayed on the left side?
	 * @param[in] $incoming bool  Is this an incoming? Or an outgoing?
	 *
	 * @return A string containing the HTML with the factbox
	 */
	private function displayData( SMWSemanticData $data, $left = true, $incoming = false ) {
		// Some of the CSS classes are different for the left or the right side.
		// In this case, there is an "i" after the "smwb-". This is set here.
		$ccsPrefix = $left ? 'smwb-' : 'smwb-i';

		$html = "<table class=\"{$ccsPrefix}factbox\" cellpadding=\"0\" cellspacing=\"0\">\n";

		$diProperties = $data->getProperties();
		$noresult = true;
		foreach ( $diProperties as $diProperty ) {
			$dvProperty = SMWDataValueFactory::newDataItemValue( $diProperty, null );

			if ( $dvProperty->isVisible() ) {
				$dvProperty->setCaption( $this->getPropertyLabel( $dvProperty, $incoming ) );
				$proptext = $dvProperty->getShortHTMLText( smwfGetLinker() ) . "\n";
			} elseif ( $diProperty->getKey() == '_INST' ) {
				$proptext = smwfGetLinker()->specialLink( 'Categories' );
			} elseif ( $diProperty->getKey() == '_REDI' ) {
				$proptext = smwfGetLinker()->specialLink( 'Listredirects', 'isredirect' );
			} else {
				continue; // skip this line
			}

			$head  = "<th>" . $proptext . "</th>\n";

			$body  = "<td>\n";

			$values = $data->getPropertyValues( $diProperty );
			if ( $incoming && ( count( $values ) >= SMWSpecialBrowse::$incomingvaluescount ) ) {
				$moreIncoming = true;
				array_pop( $values );
			} else {
				$moreIncoming = false;
			}

			$first = true;
			foreach ( $values as $di ) {
				if ( $first ) {
					$first = false;
				} else {
					$body .= ', ';
				}

				if ( $incoming ) {
					$dv = SMWDataValueFactory::newDataItemValue( $di, null );
				} else {
					$dv = SMWDataValueFactory::newDataItemValue( $di, $diProperty );
				}
				$body .= "<span class=\"{$ccsPrefix}value\">" .
				         $this->displayValue( $dvProperty, $dv, $incoming ) . "</span>\n";
			}

			if ( $moreIncoming ) { // link to the remaining incoming pages:
				$body .= Html::element(
					'a',
					array(
						'href' => SpecialPage::getSafeTitleFor( 'SearchByProperty' )->getLocalURL( array(
							 'property' => $dvProperty->getWikiValue(),
							 'value' => $this->subject->getWikiValue()
						) )
					),
					wfMsg( "smw_browse_more" )
				);

			}

			$body .= "</td>\n";

			// display row
			$html .= "<tr class=\"{$ccsPrefix}propvalue\">\n" .
					( $left ? ( $head . $body ):( $body . $head ) ) . "</tr>\n";
			$noresult = false;
		} // end foreach properties

		if ( $noresult ) {
			$html .= "<tr class=\"smwb-propvalue\"><th> &#160; </th><td><em>" .
			         wfMsg( $incoming ? 'smw_browse_no_incoming':'smw_browse_no_outgoing' ) . "</em></td></tr>\n";
		}
		$html .= "</table>\n";
		return $html;
	}
 public function doDataUpdate(SMWSemanticData $data)
 {
     wfProfileIn("SMWSQLStoreLight::updateData (SMW)");
     wfRunHooks('SMWSQLStoreLight::updateDataBefore', array($this, $data));
     $subject = $data->getSubject();
     $this->deleteSemanticData($subject);
     $sid = $subject->getTitle()->getArticleID();
     $updates = array();
     // collect data for bulk updates; format: tableid => updatearray
     foreach ($data->getProperties() as $property) {
         $tablename = SMWSQLStoreLight::findPropertyTableName($property);
         if ($tablename === '') {
             continue;
         }
         foreach ($data->getPropertyValues($property) as $dv) {
             if (!$dv->isValid()) {
                 continue;
             }
             if ($dv instanceof SMWContainerValue) {
                 continue;
                 // subobjects not supported in this store right now; maybe could simply be PHP serialized
             } else {
                 $uvals = array('pageid' => $sid, 'propname' => $property->getDBkey(), 'value' => $tablename == 'smwsimple_special' ? reset($dv->getDBkeys()) : serialize($dv->getDBkeys()));
             }
             if (!array_key_exists($tablename, $updates)) {
                 $updates[$tablename] = array();
             }
             $updates[$tablename][] = $uvals;
         }
     }
     $db = wfGetDB(DB_MASTER);
     foreach ($updates as $tablename => $uvals) {
         $db->insert($tablename, $uvals, "SMW::updateData{$tablename}");
     }
     // Finally update caches (may be important if jobs are directly following this call)
     $this->m_semdata[$sid] = clone $data;
     $this->m_sdstate[$sid] = array('smwsimple_data' => true, 'smwsimple_special' => true);
     // everything that one can know
     wfRunHooks('SMWSQLStoreLight::updateDataAfter', array($this, $data));
     wfProfileOut("SMWSQLStoreLight::updateData (SMW)");
 }
 /**
  * Creates and returns a new SMWChangeSet from 2 SMWSemanticData objects.
  * 
  * @param SMWSemanticData $old
  * @param SMWSemanticData $new
  * @param array $filterProperties Optional list of properties (string serializations) to filter on. Null for no filtering.
  * 
  * @return SMWChangeSet
  */
 public static function newFromSemanticData(SMWSemanticData $old, SMWSemanticData $new, array $filterProperties = null)
 {
     $subject = $old->getSubject();
     if ($subject != $new->getSubject()) {
         return new self($subject);
     }
     $changes = new SWLPropertyChanges();
     $insertions = new SMWSemanticData($subject);
     $deletions = new SMWSemanticData($subject);
     $oldProperties = array();
     $newProperties = array();
     foreach ($old->getProperties() as $property) {
         if (is_null($filterProperties) || in_array($property->getLabel(), $filterProperties)) {
             $oldProperties[] = $property;
         }
     }
     foreach ($new->getProperties() as $property) {
         if (is_null($filterProperties) || in_array($property->getLabel(), $filterProperties)) {
             $newProperties[] = $property;
         }
     }
     // Find the deletions.
     self::findSingleDirectionChanges($deletions, $oldProperties, $old, $newProperties, $filterProperties);
     // Find the insertions.
     self::findSingleDirectionChanges($insertions, $newProperties, $new, $oldProperties, $filterProperties);
     foreach ($oldProperties as $propertyKey => $diProperty) {
         $oldDataItems = array();
         $newDataItems = array();
         // Populate the data item arrays using keys that are their hash, so matches can be found.
         // Note: this code assumes there are no duplicates.
         foreach ($old->getPropertyValues($diProperty) as $dataItem) {
             $oldDataItems[$dataItem->getHash()] = $dataItem;
         }
         foreach ($new->getPropertyValues($diProperty) as $dataItem) {
             $newDataItems[$dataItem->getHash()] = $dataItem;
         }
         $foundMatches = array();
         // Find values that are both in the old and new version.
         foreach (array_keys($oldDataItems) as $hash) {
             if (array_key_exists($hash, $newDataItems)) {
                 $foundMatches[] = $hash;
             }
         }
         // Remove the values occuring in both sets, so only changes remain.
         foreach ($foundMatches as $foundMatch) {
             unset($oldDataItems[$foundMatch]);
             unset($newDataItems[$foundMatch]);
         }
         // Find which group is biggest, so it's easy to loop over all values of the smallest.
         $oldIsBigger = count($oldDataItems) > count($newDataItems);
         $bigGroup = $oldIsBigger ? $oldDataItems : $newDataItems;
         $smallGroup = $oldIsBigger ? $newDataItems : $oldDataItems;
         // Add all one-to-one changes.
         while ($dataItem = array_shift($smallGroup)) {
             $changes->addPropertyObjectChange($diProperty, new SWLPropertyChange($dataItem, array_shift($bigGroup)));
         }
         // If the bigger group is not-equal to the smaller one, items will be left,
         // that are either insertions or deletions, depending on the group.
         if (count($bigGroup > 0)) {
             $semanticData = $oldIsBigger ? $deletions : $insertions;
             foreach ($bigGroup as $dataItem) {
                 $semanticData->addPropertyObjectValue($diProperty, $dataItem);
             }
         }
     }
     return new self($subject, $changes, $insertions, $deletions);
 }
Exemple #19
0
/**
 * Callback function for the hook 'smwShowFactbox'. It is called when SMW creates
 * the factbox for an article.
 * This method replaces the whole factbox with a tabbed version that contains
 * the original factbox in one tab and the derived facts in another.
 *
 * @param string $text
 * 		The HTML for the tabbed factbox is returned in this parameter
 * @param SMWSemanticData $semdata
 * 		All static facts for the article
 * @return bool
 * 		<false> : This means that SMW's factbox is completely replaced.
 */
function smwfAddDerivedFacts(&$text, $semdata)
{
    global $smwgHaloScriptPath, $wgContLang;
    wfLoadExtensionMessages('SemanticMediaWiki');
    SMWOutputs::requireHeadItem(SMW_HEADER_STYLE);
    $rdflink = SMWInfolink::newInternalLink(wfMsgForContent('smw_viewasrdf'), $wgContLang->getNsText(NS_SPECIAL) . ':ExportRDF/' . $semdata->getSubject()->getWikiValue(), 'rdflink');
    $browselink = SMWInfolink::newBrowsingLink($semdata->getSubject()->getText(), $semdata->getSubject()->getWikiValue(), 'swmfactboxheadbrowse');
    $fbText = '<div class="smwfact">' . '<span class="smwfactboxhead">' . wfMsgForContent('smw_factbox_head', $browselink->getWikiText()) . '</span>' . '<span class="smwrdflink">' . $rdflink->getWikiText() . '</span>' . '<table class="smwfacttable">' . "\n";
    foreach ($semdata->getProperties() as $property) {
        if (!$property->isShown()) {
            // showing this is not desired, hide
            continue;
        } elseif ($property->isUserDefined()) {
            // user defined property
            $property->setCaption(preg_replace('/[ ]/u', '&nbsp;', $property->getWikiValue(), 2));
            /// NOTE: the preg_replace is a slight hack to ensure that the left column does not get too narrow
            $fbText .= '<tr><td class="smwpropname">' . $property->getLongWikiText(true) . '</td><td class="smwprops">';
        } elseif ($property->isVisible()) {
            // predefined property
            $fbText .= '<tr><td class="smwspecname">' . $property->getLongWikiText(true) . '</td><td class="smwspecs">';
        } else {
            // predefined, internal property
            continue;
        }
        $propvalues = $semdata->getPropertyValues($property);
        $l = count($propvalues);
        $i = 0;
        foreach ($propvalues as $propvalue) {
            if ($i != 0) {
                if ($i > $l - 2) {
                    $fbText .= wfMsgForContent('smw_finallistconjunct') . ' ';
                } else {
                    $fbText .= ', ';
                }
            }
            $i += 1;
            $fbText .= $propvalue->getLongWikiText(true) . $propvalue->getInfolinkText(SMW_OUTPUT_WIKI);
        }
        $fbText .= '</td></tr>';
    }
    $fbText .= '</table></div>';
    $text = '<div id="smw_dft_rendered_boxcontent"> <br />' . '<table>' . '<tr>' . '<td id="dftTab1" class="dftTabActive">' . str_replace(' ', '&nbsp;', wfMsg('smw_df_static_tab')) . '</td>' . '<td class="dftTabSpacer">&nbsp;</td>' . '<td id="dftTab2" class="dftTabInactive">' . str_replace(' ', '&nbsp;', wfMsg('smw_df_derived_tab')) . '</td>' . '<td class="dftTabSpacer" width="100%"></td>' . '</tr>' . '<tr>' . '<td colspan="4" class="dftTabCont">' . '<div id="dftTab1Content" >' . $fbText . '</div>' . '<div id="dftTab2Content" style="display:none">' . '<div id="dftTab2ContentInnerDiv">' . wfMsg('smw_df_loading_df') . '</div>' . '</div>' . '</td>' . '</tr>' . '</table>' . '</div>';
    return false;
}