/** * Update sub-SemanticData as part of doDataUpdate. * * @since 1.8 * @param SMWSemanticData $data */ protected function updateSubSemanticData(SMWSemanticData $data) { $subDatas = $data->getSubSemanticData(); foreach ($subDatas as $subobject => $subData) { $this->doDataUpdate($subData); } $subobjects = $this->getSubobjects($data->getSubject()); foreach ($subobjects as $smw_id => $subobject) { if (!array_key_exists($subobject->getSubobjectName(), $subDatas)) { $this->deleteSemanticData($subobject); } } //TODO run delete job (this should find out what ids are not needed and delete them) }
/** * 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; }
/** * 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); } }
/** * @see SemanticData::getSubSemanticData * * @note SubSemanticData are added only on request to avoid unnecessary DB * transactions * * @since 2.0 */ public function getSubSemanticData() { if ($this->subSemanticDataInitialized) { return parent::getSubSemanticData(); } $this->subSemanticDataInitialized = true; foreach ($this->getProperties() as $property) { // #619 Do not resolve subobjects for redirects if ($property->findPropertyTypeID() !== '__sob' || $this->isRedirect()) { continue; } $this->addSubSemanticDataToInternalCache($property); } return parent::getSubSemanticData(); }