/** * @see SMWStore::deleteSubject * * @since 1.8 * @param Title $title */ public function deleteSubject(Title $title) { // @deprecated since 2.1, use 'SMW::SQLStore::BeforeDeleteSubjectComplete' wfRunHooks('SMWSQLStore3::deleteSubjectBefore', array($this->store, $title)); wfRunHooks('SMW::SQLStore::BeforeDeleteSubjectComplete', array($this->store, $title)); $id = $this->store->getObjectIds()->getSMWPageID($title->getDBkey(), $title->getNamespace(), $title->getInterwiki(), '', false); $emptySemanticData = new SemanticData(DIWikiPage::newFromTitle($title)); $subobjects = $this->getSubobjects($emptySemanticData->getSubject()); $this->doDataUpdate($emptySemanticData); if ($title->getNamespace() === SMW_NS_CONCEPT) { // make sure to clear caches $db = $this->store->getConnection(); $db->delete('smw_fpt_conc', array('s_id' => $id), 'SMW::deleteSubject::Conc'); $db->delete(SMWSQLStore3::CONCEPT_CACHE_TABLE, array('o_id' => $id), 'SMW::deleteSubject::Conccache'); } // Mark subject/subobjects with a special IW, the final removal is being // triggered by the `ByIdDataRebuildDispatcher` $this->store->getObjectIds()->updateInterwikiField($id, $emptySemanticData->getSubject(), SMW_SQL3_SMWDELETEIW); foreach ($subobjects as $smw_id => $subobject) { $this->store->getObjectIds()->updateInterwikiField($smw_id, $subobject, SMW_SQL3_SMWDELETEIW); } // 1.9.0.1 // The update of possible associative entities is handled by DeleteSubjectJob which is invoked during // the ArticleDelete hook // @deprecated since 2.1, use 'SMW::SQLStore::AfterDeleteSubjectComplete' wfRunHooks('SMWSQLStore3::deleteSubjectAfter', array($this->store, $title)); wfRunHooks('SMW::SQLStore::AfterDeleteSubjectComplete', array($this->store, $title)); }
/** * @since 1.0 * * @return WikiPage */ public function getWikiPage() { if ($this->page === null) { $this->page = $this->appFactory->newWikiPage($this->semanticData->getSubject()->getTitle()); //$this->loadRegisteredObject( 'WikiPage' ); } return $this->page; }
/** * @since 2.1 * * @return SemanticData */ public function asEntity() { $semanticData = new SemanticData($this->asSubject()); $semanticData->addDataValue($this->getLocatedInValue()); $countryCategory = new CountryCategory(); $semanticData->addDataValue($countryCategory->getCategoryValue()); return $semanticData; }
private function doSerialize(SemanticData $semanticData) { $data = array('subject' => $semanticData->getSubject()->getSerialization(), 'data' => $this->serializeProperty($semanticData)); $subobjects = $this->serializeSubobject($semanticData->getSubSemanticData()); if ($subobjects !== array()) { $data['sobj'] = $subobjects; } return $data; }
public function testAddAnnotationOnMockShortUrl() { $title = Title::newFromText(__METHOD__); $semanticData = new SemanticData(DIWikiPage::newFromTitle($title)); $instance = $this->getMock('\\SESP\\Annotator\\ShortUrlAnnotator', array('hasShortUrlUtils', 'getShortUrl'), array($semanticData)); $instance->expects($this->once())->method('hasShortUrlUtils')->will($this->returnValue(true)); $instance->expects($this->once())->method('getShortUrl')->with($this->equalTo($title))->will($this->returnValue('example.org')); $instance->setShortUrlPrefix('foo'); $instance->addAnnotation(); $this->assertArrayHasKey(PropertyRegistry::getInstance()->getPropertyId('_SHORTURL'), $semanticData->getProperties()); }
/** * @since 1.0 * * @return boolean */ public function addAnnotation() { if (!$this->hasShortUrlUtils()) { throw new RuntimeException('Expected class ShortUrlUtils to be available'); } $shortURL = $this->getShortUrl($this->semanticData->getSubject()->getTitle()); if ($shortURL !== null) { $this->semanticData->addPropertyObjectValue(new DIProperty(PropertyRegistry::getInstance()->getPropertyId('_SHORTURL')), new DIUri('http', $shortURL, '', '')); } return true; }
public function testRedirectTragetLookupForExistingEntry() { $property = new DIProperty('RedirectLookupForExistingEntry'); $semanticData = new SemanticData(new DIWikiPage(__METHOD__, NS_MAIN, '')); $semanticData->addDataValue(DataValueFactory::getInstance()->newPropertyObjectValue($property, 'Bar')); $this->store->doSparqlDataUpdate($semanticData); $expNsResource = new ExpNsResource('RedirectLookupForExistingEntry', Exporter::getNamespaceUri('property'), 'property'); $instance = new RedirectLookup($this->sparqlDatabase); $instance->clear(); $exists = null; $this->assertSame($expNsResource, $instance->findRedirectTargetResource($expNsResource, $exists)); $this->assertTrue($exists); }
public function testRoundtripOfSerializedSemanticDataAfterStoreUpdate() { $subject = DIWikiPage::newFromTitle(Title::newFromText(__METHOD__)); $semanticDataBeforeUpdate = new SemanticData($subject); $subobject = new Subobject($subject->getTitle()); $subobject->setEmptyContainerForId('SomeSubobjectToSerialize'); $subobject->getSemanticData()->addDataValue(DataValueFactory::getInstance()->newPropertyValue('Foo', 'Bar')); $semanticDataBeforeUpdate->addSubobject($subobject); $this->getStore()->updateData($semanticDataBeforeUpdate); $semanticDataAfterUpdate = $this->getStore()->getSemanticData($subject); $serializerFactory = new SerializerFactory(); $this->assertEquals($semanticDataAfterUpdate->getHash(), $serializerFactory->deserialize($serializerFactory->serialize($semanticDataAfterUpdate))->getHash()); }
/** * @since 2.0 * * @return SemanticData */ public function getSemanticData(DIWikiPage $subject) { $requestOptions = new RequestOptions(); $requestOptions->sort = true; $semanticData = new SemanticData($subject); $incomingProperties = $this->store->getInProperties($subject, $requestOptions); foreach ($incomingProperties as $property) { $values = $this->store->getPropertySubjects($property, null); foreach ($values as $value) { $semanticData->addPropertyObjectValue($property, $value); } } return $semanticData; }
/** * @since 2.1 * * @return SemanticData */ public function asEntity() { $semanticData = new SemanticData($this->asSubject()); $semanticData->addDataValue($this->getAreaValue()); $semanticData->addDataValue($this->getAverageHighTemperatureValue()); $semanticData->addDataValue($this->getPopulationValue()); $semanticData->addDataValue($this->getPopulationDensityValue()); $semanticData->addDataValue($this->getLocatedInValue()); $semanticData->addDataValue($this->getFoundedValue()); $semanticData->addSubobject($this->getDemographics()); $cityCategory = new CityCategory(); $semanticData->addDataValue($cityCategory->getCategoryValue()); return $semanticData; }
/** * @since 1.9.2 * * @return SemanticData */ public function fetchIncomingDataFromStore() { $requestOptions = new \SMWRequestOptions(); $requestOptions->sort = true; $subject = $this->getPageData()->getSubject(); $semanticData = new SemanticData($subject); $incomingProperties = $this->getStore()->getInProperties($subject, $requestOptions); foreach ($incomingProperties as $property) { $values = $this->getStore()->getPropertySubjects($property, null); foreach ($values as $value) { $semanticData->addPropertyObjectValue($property, $value); } } return $semanticData; }
public function testDoSparqlDataUpdateOnMockBaseStore() { $semanticData = new SemanticData(new DIWikiPage(__METHOD__, NS_MAIN)); $semanticData->addPropertyObjectValue(new DIProperty('Foo'), $semanticData->getSubject()); $repositoryResult = $this->getMockBuilder('\\SMW\\SPARQLStore\\QueryEngine\\RepositoryResult')->disableOriginalConstructor()->getMock(); $baseStore = $this->getMockBuilder('\\SMW\\Store')->disableOriginalConstructor()->getMockForAbstractClass(); $sparqlDatabase = $this->getMockBuilder('\\SMWSparqlDatabase')->disableOriginalConstructor()->getMock(); $sparqlDatabase->expects($this->atLeastOnce())->method('select')->will($this->returnValue($repositoryResult)); $sparqlDatabase->expects($this->once())->method('insertData'); $connectionManager = $this->getMockBuilder('\\SMW\\ConnectionManager')->disableOriginalConstructor()->getMock(); $connectionManager->expects($this->any())->method('getConnection')->will($this->returnValue($sparqlDatabase)); $instance = new SPARQLStore($baseStore); $instance->setConnectionManager($connectionManager); $instance->doSparqlDataUpdate($semanticData); }
/** * @since 2.4 * * @param SemanticData $semanticData * * @return string */ public static function createFromSemanticData(SemanticData $semanticData) { $hash = array(); $hash[] = $semanticData->getSubject()->getSerialization(); foreach ($semanticData->getProperties() as $property) { $hash[] = $property->getKey(); foreach ($semanticData->getPropertyValues($property) as $di) { $hash[] = $di->getSerialization(); } } foreach ($semanticData->getSubSemanticData() as $data) { $hash[] = $data->getHash(); } sort($hash); return md5(implode('#', $hash)); }
private function notifyDispatcher($addJob = true) { if ($addJob && !$this->hasDiff) { $dispatchContext = EventHandler::getInstance()->newDispatchContext(); $dispatchContext->set('subject', $this->semanticData->getSubject()); EventHandler::getInstance()->getEventDispatcher()->dispatch('property.specification.change', $dispatchContext); $this->hasDiff = true; } }
private function doRealUpdate() { $this->store->setUpdateJobsEnabledState($this->updateJobsEnabledState); if ($this->processSemantics) { $this->store->updateData($this->semanticData); } else { $this->store->clearData($this->semanticData->getSubject()); } return true; }
/** * @see SMWStore::deleteSubject * * @since 1.8 * @param Title $title */ public function deleteSubject(Title $title) { // @deprecated since 2.1, use 'SMW::SQLStore::BeforeDeleteSubjectComplete' \Hooks::run('SMWSQLStore3::deleteSubjectBefore', array($this->store, $title)); \Hooks::run('SMW::SQLStore::BeforeDeleteSubjectComplete', array($this->store, $title)); // Fetch all possible matches (including any duplicates created by // incomplete rollback or DB deadlock) $ids = $this->store->getObjectIds()->getListOfIdMatchesFor($title->getDBkey(), $title->getNamespace(), $title->getInterwiki()); $subject = DIWikiPage::newFromTitle($title); $emptySemanticData = new SemanticData($subject); $this->entitySubobjectListIterator->setSubject($emptySemanticData->getSubject()); $subobjects = $this->entitySubobjectListIterator->getIterator(); $this->doDataUpdate($emptySemanticData); foreach ($ids as $id) { $this->doDelete($id, $subject, $subobjects); } // @deprecated since 2.1, use 'SMW::SQLStore::AfterDeleteSubjectComplete' \Hooks::run('SMWSQLStore3::deleteSubjectAfter', array($this->store, $title)); \Hooks::run('SMW::SQLStore::AfterDeleteSubjectComplete', array($this->store, $title)); }
/** * @see SMWStore::deleteSubject * * @since 1.8 * @param Title $title */ public function deleteSubject(Title $title) { // @deprecated since 2.1, use 'SMW::SQLStore::BeforeDeleteSubjectComplete' \Hooks::run('SMWSQLStore3::deleteSubjectBefore', array($this->store, $title)); \Hooks::run('SMW::SQLStore::BeforeDeleteSubjectComplete', array($this->store, $title)); // Fetch all possible matches (including any duplicates created by // incomplete rollback or DB deadlock) $ids = $this->store->getObjectIds()->getListOfIdMatchesFor($title->getDBkey(), $title->getNamespace(), $title->getInterwiki()); $subject = DIWikiPage::newFromTitle($title); $emptySemanticData = new SemanticData($subject); $subobjects = $this->getSubobjects($emptySemanticData->getSubject()); $this->doDataUpdate($emptySemanticData); foreach ($ids as $id) { $this->doDeleteReferencesFor($id, $subject, $subobjects); } // 1.9.0.1 // The update of possible associative entities is handled by DeleteSubjectJob which is invoked during // the ArticleDelete hook // @deprecated since 2.1, use 'SMW::SQLStore::AfterDeleteSubjectComplete' \Hooks::run('SMWSQLStore3::deleteSubjectAfter', array($this->store, $title)); \Hooks::run('SMW::SQLStore::AfterDeleteSubjectComplete', array($this->store, $title)); }
/** * @return array */ public function typeChangeSemanticDataProvider() { $provider = array(); $title = \Title::newFromText(__METHOD__); // #0 Single entry $foo = new SemanticData(DIWikiPage::newFromTitle($title)); $foo->addDataValue(DataValueFactory::getInstance()->newPropertyValue('Has fooQuex', 'Bar')); $provider[] = array($foo, 'Has_fooQuex'); // #1 Single subobject entry $foo = new SemanticData(DIWikiPage::newFromTitle($title)); $subobject = new Subobject($title); $subobject->setSemanticData('Foo'); $subobject->addDataValue(DataValueFactory::getInstance()->newPropertyValue('Has fomQuex', 'Bam')); $foo->addPropertyObjectValue($subobject->getProperty(), $subobject->getContainer()); $provider[] = array($foo, 'Has_fomQuex'); // #2 Combined $foo = new SemanticData(DIWikiPage::newFromTitle($title)); $foo->addDataValue(DataValueFactory::getInstance()->newPropertyValue('Has fooQuex', 'Bar')); $foo->addPropertyObjectValue($subobject->getProperty(), $subobject->getContainer()); $provider[] = array($foo, 'Has_fomQuex'); return $provider; }
public function testDeleteFor() { $subject = new DIWikiPage('Foobar', NS_MAIN, '', 'abc'); $semanticData = new SemanticData($subject); $semanticData->addPropertyObjectValue(new DIProperty('_REDI'), new DIWikiPage('Bar', NS_MAIN)); $store = $this->getMockBuilder('\\SMW\\SQLStore\\SQLStore')->disableOriginalConstructor()->getMock(); $container = $this->getMockBuilder('\\Onoi\\BlobStore\\Container')->disableOriginalConstructor()->getMock(); $container->expects($this->at(0))->method('has')->with($this->stringContains('sd:'))->will($this->returnValue(true)); $container->expects($this->at(1))->method('get')->with($this->stringContains('sd:'))->will($this->returnValue($semanticData)); $container->expects($this->at(2))->method('has')->with($this->stringContains('list'))->will($this->returnValue(true)); $container->expects($this->at(3))->method('get')->with($this->stringContains('list'))->will($this->returnValue(array('abc', '123'))); $blobStore = $this->getMockBuilder('\\Onoi\\BlobStore\\BlobStore')->disableOriginalConstructor()->getMock(); $blobStore->expects($this->any())->method('canUse')->will($this->returnValue(true)); $blobStore->expects($this->atLeastOnce())->method('read')->will($this->returnValue($container)); $blobStore->expects($this->exactly(4))->method('delete'); $instance = new CachedValueLookupStore($store, $blobStore); $instance->setValueLookupFeatures(SMW_VL_SD); $instance->deleteFor($subject); }
/** * Creates a Semantic Data object with the incoming properties instead of the * usual outproperties. * * @return array(SMWSemanticData, bool) The semantic data including all inproperties, and if there are more inproperties left */ private function getInData() { $indata = new SemanticData($this->subject->getDataItem()); $propRequestOptions = new RequestOptions(); $propRequestOptions->sort = true; $propRequestOptions->limit = $this->incomingPropertiesCount; if ($this->offset > 0) { $propRequestOptions->offset = $this->offset; } $incomingProperties = $this->store->getInProperties($this->subject->getDataItem(), $propRequestOptions); $more = false; if (count($incomingProperties) == $this->incomingPropertiesCount) { $more = true; array_pop($incomingProperties); // drop the last one } $valRequestOptions = new RequestOptions(); $valRequestOptions->sort = true; $valRequestOptions->limit = $this->incomingValuesCount; foreach ($incomingProperties as $property) { $values = $this->store->getPropertySubjects($property, $this->subject->getDataItem(), $valRequestOptions); foreach ($values as $value) { $indata->addPropertyObjectValue($property, $value); } } // Added in 2.3 // Whether to show a more link or not can be set via // SMW::Browse::BeforeIncomingPropertyValuesFurtherLinkCreate \Hooks::run('SMW::Browse::AfterIncomingPropertiesLookupComplete', array($this->store, $indata, $valRequestOptions)); return array($indata, $more); }
/** * Remove data about a subobject. * If the removed data is not about a subobject of this object, * it will silently be ignored (nothing to remove). Likewise, * removing data that is not present does not change anything. * * @since 1.8 * @param SMWSemanticData */ public function removeSubSemanticData(SemanticData $semanticData) { if ($semanticData->getSubject()->getDBkey() !== $this->getSubject()->getDBkey()) { return; } $subobjectName = $semanticData->getSubject()->getSubobjectName(); if ($this->hasSubSemanticData($subobjectName)) { $this->subSemanticData[$subobjectName]->removeDataFrom($semanticData); if ($this->subSemanticData[$subobjectName]->isEmpty()) { unset($this->subSemanticData[$subobjectName]); } } }
/** * Update the semantic data stored for some individual. The data is * given as a SemanticData object, which contains all semantic data * for one particular subject. * * @param SemanticData $semanticData */ public function updateData(SemanticData $semanticData) { /** * @since 1.6 */ wfRunHooks('SMWStore::updateDataBefore', array($this, $semanticData)); // Invalidate the page, so data stored on it gets displayed immediately in queries. $pageUpdater = ApplicationFactory::getInstance()->newMwCollaboratorFactory()->newPageUpdater(); if ($GLOBALS['smwgAutoRefreshSubject'] && $pageUpdater->canUpdate()) { $pageUpdater->addPage($semanticData->getSubject()->getTitle()); $pageUpdater->doPurgeParserCache(); $pageUpdater->doPurgeHtmlCache(); } $this->doDataUpdate($semanticData); /** * @since 1.6 */ wfRunHooks('SMWStore::updateDataAfter', array($this, $semanticData)); }
/** * @see SemanticData::addDataValue * * @since 1.9 * * @param SMWDataValue $dataValue */ public function addDataValue(DataValue $dataValue) { $this->semanticData->addDataValue($dataValue); $this->addError($this->semanticData->getErrors()); }
/** * Update the Sparql back-end, without taking any subobject data into account. * * @param SemanticData $semanticData */ private function doSparqlFlatDataUpdate(SemanticData $semanticData) { $turtleTriplesBuilder = new TurtleTriplesBuilder($semanticData, new RedirectLookup($this->getConnection())); $turtleTriplesBuilder->setTriplesChunkSize(80); if (!$turtleTriplesBuilder->hasTriplesForUpdate()) { return; } if ($semanticData->getSubject()->getSubobjectName() === '') { $this->doSparqlDataDelete($semanticData->getSubject()); } foreach ($turtleTriplesBuilder->getChunkedTriples() as $chunkedTriples) { $this->getConnection()->insertData($chunkedTriples, $turtleTriplesBuilder->getPrefixes()); } }
/** * @dataProvider dataValueDataProvider */ public function testAddDataValues($dataValues, $expected) { $title = Title::newFromText(__METHOD__); $instance = new SemanticData(DIWikiPage::newFromTitle($title)); foreach ($dataValues as $dataValue) { $instance->addDataValue($dataValue); } if ($expected['error'] > 0) { return $this->assertCount($expected['error'], $instance->getErrors()); } $this->semanticDataValidator->assertThatPropertiesAreSet($expected, $instance); }
private function handleYetUnknownRedirectTarget(SemanticData $semanticData, DIWikiPage $target) { // Only keep the reference to safeguard that even in case of a text keeping // its annotations there are removed from the Store. A redirect is not // expected to contain any other annotation other than that of the redirect // target $subject = $semanticData->getSubject(); $semanticData = new SemanticData($subject); $semanticData->addPropertyObjectValue(new DIProperty('_REDI'), $target); // Force a manual changeTitle before the general update otherwise // #redirect can cause an inconsistent data container as observed in #895 $this->store->changeTitle($subject->getTitle(), $target->getTitle(), $subject->getTitle()->getArticleID(), $target->getTitle()->getArticleID()); $dispatchContext = EventHandler::getInstance()->newDispatchContext(); $dispatchContext->set('title', $subject->getTitle()); EventHandler::getInstance()->getEventDispatcher()->dispatch('factbox.cache.delete', $dispatchContext); return $semanticData; }
/** * Retrieve a copy of the semantic data for a wiki page, possibly filtering * it so that only essential properties are included (in some cases, we only * want to export stub information about a page). * We make a copy of the object since we may want to add more data later on * and we do not want to modify the store's result which may be used for * caching purposes elsewhere. */ protected function getSemanticData(SMWDIWikiPage $diWikiPage, $core_props_only) { // Issue 619 // Resolve the redirect target and return a container with information // about the redirect if ($diWikiPage->getTitle() !== null && $diWikiPage->getTitle()->isRedirect()) { try { $redirectTarget = $this->getDeepRedirectTargetResolver()->findRedirectTargetFor($diWikiPage->getTitle()); } catch (\Exception $e) { $redirectTarget = null; } // Couldn't resolve the redirect which is most likely caused by a // circular redirect therefore we give up if ($redirectTarget === null) { return null; } $semData = new SemanticData($diWikiPage); $semData->addPropertyObjectValue(new DIProperty('_REDI'), DIWikiPage::newFromTitle($redirectTarget)); return $semData; } $semdata = \SMW\StoreFactory::getStore()->getSemanticData($diWikiPage, $core_props_only ? array('__spu', '__typ', '__imp') : false); // advise store to retrieve only core things if ($core_props_only) { // be sure to filter all non-relevant things that may still be present in the retrieved $result = new SMWSemanticData($diWikiPage); foreach (array('_URI', '_TYPE', '_IMPO') as $propid) { $prop = new SMW\DIProperty($propid); $values = $semdata->getPropertyValues($prop); foreach ($values as $dv) { $result->addPropertyObjectValue($prop, $dv); } } } else { $result = clone $semdata; } return $result; }
/** * Renders table content for a given SMWSemanticData object * * @since 1.9 * * @param SMWSemanticData $semanticData */ protected function getTableContent(SemanticData $semanticData) { Profiler::In(__METHOD__); // Do exclude some tags from processing otherwise the display // can become distorted due to unresolved/open tags (see Bug 23185) $excluded = array('table', 'tr', 'th', 'td', 'dl', 'dd', 'ul', 'li', 'ol', 'b', 'sup', 'sub'); $attributes = array(); foreach ($semanticData->getProperties() as $propertyDi) { $propertyDv = $this->dataValueFactory->newDataItemValue($propertyDi, null); if (!$propertyDi->isShown()) { // showing this is not desired, hide continue; } elseif ($propertyDi->isUserDefined()) { // User defined property (@note the preg_replace is a slight // hack to ensure that the left column does not get too narrow) $propertyDv->setCaption(preg_replace('/[ ]/u', ' ', $propertyDv->getWikiValue(), 2)); $attributes['property'] = array('class' => 'smwpropname'); $attributes['values'] = array('class' => 'smwprops'); } elseif ($propertyDv->isVisible()) { // Predefined property $attributes['property'] = array('class' => 'smwspecname'); $attributes['values'] = array('class' => 'smwspecs'); } else { // predefined, internal property // @codeCoverageIgnoreStart continue; // @codeCoverageIgnoreEnd } $valuesHtml = array(); foreach ($semanticData->getPropertyValues($propertyDi) as $dataItem) { $dataValue = $this->dataValueFactory->newDataItemValue($dataItem, $propertyDi); $dataValue->setServiceLinksRenderState(false); if ($dataValue->isValid()) { $valuesHtml[] = Sanitizer::removeHTMLtags($dataValue->getLongWikiText(true), null, array(), array(), $excluded) . $dataValue->getInfolinkText(SMW_OUTPUT_WIKI); } } // Invoke table content $this->tableBuilder->addCell($propertyDv->getShortWikiText(true), $attributes['property']); $this->tableBuilder->addCell($this->messageBuilder->listToCommaSeparatedText($valuesHtml), $attributes['values']); $this->tableBuilder->addRow(); } Profiler::Out(__METHOD__); }
protected function doDataUpdate(SemanticData $semanticData) { $this->cachedValueLookupStore->deleteFor($semanticData->getSubject()); $this->getWriter()->doDataUpdate($semanticData); $this->tryToInvalidateCachedListLookupEntryFor($semanticData->getSubject()); }
private function assertThatSemanticDataIsIndeedEmpty(SemanticData $semanticData) { $property = new DIProperty('_SKEY'); foreach ($semanticData->getPropertyValues($property) as $dataItem) { $semanticData->removePropertyObjectValue($property, $dataItem); } return $semanticData->isEmpty(); }