示例#1
0
 public function getQueryLink($caption = false)
 {
     $params = array(trim($this->mQuery->getQueryString()));
     foreach ($this->mQuery->getExtraPrintouts() as $printout) {
         //$params[] = '?result.'.$printout->getData().'='.$printout->getLabel();
         $params[] = '?result.' . $printout->getData() . '=' . $printout->getLabel();
     }
     if ($caption == false) {
         smwfLoadExtensionMessages('SemanticMediaWiki');
         $caption = ' ' . wfMsgForContent('smw_iq_moreresults');
         // The space is right here, not in the QPs!
     }
     //unset limit and offset parameter since this is explicitly added by special:ask
     if (array_key_exists('limit', $this->mQuery->params)) {
         unset($this->mQuery->params['limit']);
     }
     if (array_key_exists('offset', $this->mQuery->params)) {
         unset($this->mQuery->params['offset']);
     }
     //add other query params like source and webservice to the link
     $params = array_merge($params, $this->mQuery->params);
     // Note: the initial : prevents SMW from reparsing :: in the query string.
     $result = SMWInfolink::newInternalLink($caption, ':Special:Ask', false, $params);
     return $result;
 }
	/**
	 * Constructor
	 */
	public function __construct() {
		global $smwgBrowseShowAll;
		parent::__construct( 'BrowseWiki', '', true, false, 'default', true );
		smwfLoadExtensionMessages( 'SemanticMediaWiki' );
		if ( $smwgBrowseShowAll ) {
			SWBSpecialBrowseWiki::$incomingvaluescount = 21;
			SWBSpecialBrowseWiki::$incomingpropertiescount = - 1;
		}
	}
 /**
  * Create a new SMWSQLStore2Query object that can be used to obtain results
  * for the given description. The result is stored in $this->m_queries
  * using a numeric key that is returned as a result of the function.
  * Returns -1 if no query was created.
  * @todo The case of nominal classes (top-level SMWValueDescription) still
  * makes some assumptions about the table structure, especially about the
  * name of the joinfield (o_id). Better extend compileAttributeWhere to
  * deal with this case.
  *
  * @param SMWDescription $description
  *
  * @return integer
  */
 protected function compileQueries(SMWDescription $description)
 {
     $qid = SMWSQLStore2Query::$qnum;
     $query = new SMWSQLStore2Query();
     if ($description instanceof SMWSomeProperty) {
         $this->compilePropertyCondition($query, $description->getProperty(), $description->getDescription());
         // Compilation has set type to NOQUERY: drop condition.
         if ($query->type == SMW_SQL2_NOQUERY) {
             $qid = -1;
         }
     } elseif ($description instanceof SMWNamespaceDescription) {
         // TODO: One instance of smw_ids on s_id always suffices (swm_id is KEY)! Doable in execution ... (PERFORMANCE)
         $query->jointable = 'smw_ids';
         $query->joinfield = "{$query->alias}.smw_id";
         $query->where = "{$query->alias}.smw_namespace=" . $this->m_dbs->addQuotes($description->getNamespace());
     } elseif ($description instanceof SMWConjunction || $description instanceof SMWDisjunction) {
         $query->type = $description instanceof SMWConjunction ? SMW_SQL2_CONJUNCTION : SMW_SQL2_DISJUNCTION;
         foreach ($description->getDescriptions() as $subdesc) {
             $sub = $this->compileQueries($subdesc);
             if ($sub >= 0) {
                 $query->components[$sub] = true;
             }
         }
         // All subconditions failed, drop this as well.
         if (count($query->components) == 0) {
             $qid = -1;
         }
     } elseif ($description instanceof SMWClassDescription) {
         $cqid = SMWSQLStore2Query::$qnum;
         $cquery = new SMWSQLStore2Query();
         $cquery->type = SMW_SQL2_CLASS_HIERARCHY;
         $cquery->joinfield = array();
         foreach ($description->getCategories() as $cat) {
             $cid = $this->m_store->getSMWPageID($cat->getDBkey(), NS_CATEGORY, $cat->getInterwiki());
             if ($cid != 0) {
                 $cquery->joinfield[] = $cid;
             }
         }
         if (count($cquery->joinfield) == 0) {
             // Empty result.
             $query->type = SMW_SQL2_VALUE;
             $query->jointable = '';
             $query->joinfield = '';
         } else {
             // Instance query with dicjunction of classes (categories)
             $query->jointable = 'smw_inst2';
             $query->joinfield = "{$query->alias}.s_id";
             $query->components[$cqid] = "{$query->alias}.o_id";
             $this->m_queries[$cqid] = $cquery;
         }
     } elseif ($description instanceof SMWValueDescription) {
         // Only type '_wpg' objects can appear on query level (essentially as nominal classes).
         if ($description->getDatavalue()->getTypeID() == '_wpg') {
             if ($description->getComparator() == SMW_CMP_EQ) {
                 $query->type = SMW_SQL2_VALUE;
                 $oid = $this->m_store->getSMWPageID($description->getDatavalue()->getDBkey(), $description->getDatavalue()->getNamespace(), $description->getDatavalue()->getInterwiki());
                 $query->joinfield = array($oid);
             } else {
                 // Join with smw_ids needed for other comparators (apply to title string).
                 $query->jointable = 'smw_ids';
                 $query->joinfield = "{$query->alias}.smw_id";
                 $value = $description->getDatavalue()->getSortkey();
                 switch ($description->getComparator()) {
                     case SMW_CMP_LEQ:
                         $comp = '<=';
                         break;
                     case SMW_CMP_GEQ:
                         $comp = '>=';
                         break;
                     case SMW_CMP_NEQ:
                         $comp = '!=';
                         break;
                     case SMW_CMP_LIKE:
                     case SMW_CMP_NLKE:
                         $comp = ' LIKE ';
                         if ($description->getComparator() == SMW_CMP_NLKE) {
                             $comp = " NOT{$comp}";
                         }
                         $value = str_replace(array('%', '_', '*', '?'), array('\\%', '\\_', '%', '_'), $value);
                         break;
                 }
                 $query->where = "{$query->alias}.smw_sortkey{$comp}" . $this->m_dbs->addQuotes($value);
             }
         }
     } elseif ($description instanceof SMWConceptDescription) {
         // fetch concept definition and insert it here
         $cid = $this->m_store->getSMWPageID($description->getConcept()->getDBkey(), SMW_NS_CONCEPT, '');
         $row = $this->m_dbs->selectRow('smw_conc2', array('concept_txt', 'concept_features', 'concept_size', 'concept_depth', 'cache_date'), array('s_id' => $cid), 'SMWSQLStore2Queries::compileQueries');
         if ($row === false) {
             // No description found, concept does not exist.
             // 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)
         } else {
             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 = 'smw_conccache';
                 $query->joinfield = "{$query->alias}.s_id";
                 $query->where = "{$query->alias}.o_id=" . $this->m_dbs->addQuotes($cid);
             } elseif ($row->concept_txt) {
                 // Parse description and process it recursively.
                 if ($may_be_computed) {
                     $qp = new SMWQueryParser();
                     // No defaultnamespaces here; If any, these are already in the concept.
                     $desc = $qp->getQueryDescription($row->concept_txt);
                     $qid = $this->compileQueries($desc);
                     if ($qid != -1) {
                         $query = $this->m_queries[$qid];
                     } else {
                         // somehow the concept query is no longer valid; maybe some syntax changed (upgrade) or global settings were modified since storing it
                         smwfLoadExtensionMessages('SemanticMediaWiki');
                         $this->m_errors[] = wfMsg('smw_emptysubquery');
                         // not quite the right message, but this case is very rare; let us not make detailed messages for this
                     }
                 } else {
                     smwfLoadExtensionMessages('SemanticMediaWiki');
                     $this->m_errors[] = wfMsg('smw_concept_cache_miss', $description->getConcept()->getText());
                 }
             }
             // else: no cache, no description (this may happen); treat like empty concept
         }
     } else {
         // (e.g. SMWThingDescription)
         $qid = -1;
         // no condition
     }
     if ($qid >= 0) {
         // Success, keep query object, propagate sortkeys from subqueries.
         $this->m_queries[$qid] = $query;
         if ($query->type != SMW_SQL2_DISJUNCTION) {
             // Sortkeys are killed by disjunctions (not all parts may have them),
             // NOTE: preprocessing might try to push disjunctions downwards to safe sortkey, but this seems to be minor
             foreach ($query->components as $cid => $field) {
                 $query->sortfields = array_merge($this->m_queries[$cid]->sortfields, $query->sortfields);
             }
         }
     }
     return $qid;
 }
 protected function parseUserValue($value)
 {
     // echo "parseUserValue";
     smwfLoadExtensionMessages('SemanticMediaWiki');
     $value = trim($value);
     $this->m_wikitext = $value;
     if ($this->m_caption === false) {
         $this->m_caption = $this->m_wikitext;
     }
     $scheme = $hierpart = $query = $fragment = '';
     if ($value == '') {
         // do not accept empty strings
         $this->addError(wfMsgForContent('smw_emptystring'));
         $this->m_dataitem = new SMWDIUri('http', '//example.com', '', '', $this->m_typeid);
         // define data item to have some value
         return;
     }
     $parts = explode(':', $value, 2);
     // try to split "schema:rest"
     if (count($parts) == 1) {
         // possibly add "http" as default
         $value = 'http://' . $value;
         $parts[1] = $parts[0];
         $parts[0] = 'http';
     }
     // check against blacklist
     $uri_blacklist = explode("\n", wfMsgForContent('smw_uri_blacklist'));
     foreach ($uri_blacklist as $uri) {
         $uri = trim($uri);
         if ($uri == mb_substr($value, 0, mb_strlen($uri))) {
             // disallowed URI!
             $this->addError(wfMsgForContent('smw_baduri', $value));
             $this->m_dataitem = new SMWDIUri('http', '//example.com', '', '', $this->m_typeid);
             // define data item to have some value
             return;
         }
     }
     // decompose general URI components
     $scheme = $parts[0];
     $parts = explode('?', $parts[1], 2);
     // try to split "hier-part?queryfrag"
     if (count($parts) == 2) {
         $hierpart = $parts[0];
         $parts = explode('#', $parts[1], 2);
         // try to split "query#frag"
         $query = $parts[0];
         $fragment = count($parts) == 2 ? $parts[1] : '';
     } else {
         $query = '';
         $parts = explode('#', $parts[0], 2);
         // try to split "hier-part#frag"
         $hierpart = $parts[0];
         $fragment = count($parts) == 2 ? $parts[1] : '';
     }
     // We do not validate the URI characters (the data item will do this) but we do some escaping:
     // encode most characters, but leave special symbols as given by user:
     $hierpart = str_replace(array('%3A', '%2F', '%23', '%40', '%3F', '%3D', '%26', '%25'), array(':', '/', '#', '@', '?', '=', '&', '%'), rawurlencode($hierpart));
     $query = str_replace(array('%3A', '%2F', '%23', '%40', '%3F', '%3D', '%26', '%25'), array(':', '/', '#', '@', '?', '=', '&', '%'), rawurlencode($query));
     $fragment = str_replace(array('%3A', '%2F', '%23', '%40', '%3F', '%3D', '%26', '%25'), array(':', '/', '#', '@', '?', '=', '&', '%'), rawurlencode($fragment));
     /// NOTE: we do not support raw [ (%5D) and ] (%5E), although they are needed for ldap:// (but rarely in a wiki)
     /// NOTE: "+" gets encoded, as it is interpreted as space by most browsers when part of a URL;
     ///       this prevents tel: from working directly, but we have a datatype for this anyway.
     // Now create the URI data item:
     try {
         SWBSpecialBrowseWiki::debug($this->m_typeid, "typeid");
         $this->m_dataitem = new SMWDIUri($scheme, $hierpart, $query, $fragment, $this->m_typeid);
     } catch (SMWDataItemException $e) {
         $this->addError(wfMsgForContent('smw_baduri', $this->m_wikitext));
         $this->m_dataitem = new SMWDIUri('http', '//example.com', '', '', $this->m_typeid);
         // define data item to have some value
     }
 }