/**
  * @since 2.2
  *
  * @param Description $description
  *
  * @return QuerySegment
  */
 public function interpretDescription(Description $description)
 {
     $query = new QuerySegment();
     $conceptId = $this->querySegmentListBuilder->getStore()->getObjectIds()->getSMWPageID($description->getConcept()->getDBkey(), SMW_NS_CONCEPT, '', '');
     $hash = 'concept-' . $conceptId;
     $this->querySegmentListBuilder->getCircularReferenceGuard()->mark($hash);
     if ($this->querySegmentListBuilder->getCircularReferenceGuard()->isCircularByRecursionFor($hash)) {
         $this->querySegmentListBuilder->addError(wfMessage('smw-query-condition-circular', $description->getQueryString())->text());
         return $query;
     }
     $db = $this->querySegmentListBuilder->getStore()->getConnection('mw.db.queryengine');
     $row = $this->getConceptForId($db, $conceptId);
     // No description found, concept does not exist.
     if ($row === false) {
         $this->querySegmentListBuilder->getCircularReferenceGuard()->unmark('concept-' . $conceptId);
         // keep the above query object, it yields an empty result
         // TODO: announce an error here? (maybe not, since the query processor can check for
         // non-existing concept pages which is probably the main reason for finding nothing here)
         return $query;
     }
     global $smwgQConceptCaching, $smwgQMaxSize, $smwgQMaxDepth, $smwgQFeatures, $smwgQConceptCacheLifetime;
     $may_be_computed = $smwgQConceptCaching == CONCEPT_CACHE_NONE || $smwgQConceptCaching == CONCEPT_CACHE_HARD && ~(~($row->concept_features + 0) | $smwgQFeatures) == 0 && $smwgQMaxSize >= $row->concept_size && $smwgQMaxDepth >= $row->concept_depth;
     if ($row->cache_date && ($row->cache_date > strtotime("now") - $smwgQConceptCacheLifetime * 60 || !$may_be_computed)) {
         // Cached concept, use cache unless it is dead and can be revived.
         $query->joinTable = SMWSQLStore3::CONCEPT_CACHE_TABLE;
         $query->joinfield = "{$query->alias}.s_id";
         $query->where = "{$query->alias}.o_id=" . $db->addQuotes($conceptId);
     } elseif ($row->concept_txt) {
         // Parse description and process it recursively.
         if ($may_be_computed) {
             $qid = $this->querySegmentListBuilder->getQuerySegmentFrom($this->getConceptQueryDescriptionFrom($row->concept_txt));
             if ($qid != -1) {
                 $query = $this->querySegmentListBuilder->findQuerySegment($qid);
             } else {
                 // somehow the concept query is no longer valid; maybe some syntax changed (upgrade) or global settings were modified since storing it
                 $this->querySegmentListBuilder->addError(wfMessage('smw_emptysubquery')->text());
                 // not the right message, but this case is very rare; let us not make detailed messages for this
             }
         } else {
             $this->querySegmentListBuilder->addError(wfMessage('smw_concept_cache_miss', $description->getConcept()->getTitle()->getText())->text());
         }
     }
     // else: no cache, no description (this may happen); treat like empty concept
     $this->querySegmentListBuilder->getCircularReferenceGuard()->unmark($hash);
     return $query;
 }
 /**
  * ProfileAnnotatorDecorator::addPropertyValues
  */
 protected function addPropertyValues()
 {
     $this->addQueryString($this->description->getQueryString());
     $this->addQuerySize($this->description->getSize());
     $this->addQueryDepth($this->description->getDepth());
 }
 /**
  * Extend a given description by a new one, either by adding the new description
  * (if the old one is a container description) or by creating a new container.
  * The parameter $conjunction determines whether the combination of both descriptions
  * should be a disjunction or conjunction.
  *
  * In the special case that the current description is NULL, the new one will just
  * replace the current one.
  *
  * The return value is the expected combined description. The object $currentDescription will
  * also be changed (if it was non-NULL).
  */
 private function getCompoundDescription(Description $currentDescription = null, Description $newDescription = null, $compoundType = SMW_CONJUNCTION_QUERY)
 {
     $notallowedmessage = 'smw_noqueryfeature';
     if ($newDescription instanceof SomeProperty) {
         $allowed = $this->queryFeatures & SMW_PROPERTY_QUERY;
     } elseif ($newDescription instanceof ClassDescription) {
         $allowed = $this->queryFeatures & SMW_CATEGORY_QUERY;
     } elseif ($newDescription instanceof ConceptDescription) {
         $allowed = $this->queryFeatures & SMW_CONCEPT_QUERY;
     } elseif ($newDescription instanceof Conjunction) {
         $allowed = $this->queryFeatures & SMW_CONJUNCTION_QUERY;
         $notallowedmessage = 'smw_noconjunctions';
     } elseif ($newDescription instanceof Disjunction) {
         $allowed = $this->queryFeatures & SMW_DISJUNCTION_QUERY;
         $notallowedmessage = 'smw_nodisjunctions';
     } else {
         $allowed = true;
     }
     if (!$allowed) {
         $this->addErrorWithMsgKey($notallowedmessage, $newDescription->getQueryString());
         return $currentDescription;
     }
     if ($newDescription === null) {
         return $currentDescription;
     } elseif ($currentDescription === null) {
         return $newDescription;
     } else {
         // we already found descriptions
         return $this->newCompoundDescriptionFor($compoundType, $currentDescription, $newDescription);
     }
 }