Extension:Semantic Compound Queries/code

<?php /** * SemanticCompoundQueries.php * * Defines a parser function, #compound_query, that takes in a set of * inline queries and displays them together. The syntax resemles that of * Semantic MediaWiki's #ask, but with more than one query, and with the * elements of each query delimited by semicolons instead of pipes. Elements * that are common across all sub-queries, like 'format=' and 'width=' * (for maps) should be placed after all sub-queries. * * Sample query: * * * @file * @ingroup SemanticCompoundQueries * @author Yaron Koren */

if (!defined('MEDIAWIKI')) die;

define('SCQ_VERSION', '0.1');

$wgExtensionCredits['parserhook'][]= array(	'name'	=> 'Semantic Compound Queries',	'version'	=> SCQ_VERSION,	'author'	=> 'Yaron Koren',	'url'	=> 'http://www.mediawiki.org/wiki/Extension:Semantic_Compound_Queries',	'description'	=> 'A parser function that displays multiple semantic queries at the same time', );

$wgExtensionFunctions[] = 'scqgParserFunctions'; $wgHooks['LanguageGetMagic'][] = 'scqgLanguageGetMagic';

function scqgParserFunctions { global $wgHooks, $wgParser; if( defined( 'MW_SUPPORTS_PARSERFIRSTCALLINIT' ) ) { $wgHooks['ParserFirstCallInit'][] = 'scqgRegisterParser'; } else { if ( class_exists( 'StubObject' ) && !StubObject::isRealObject( $wgParser ) ) { $wgParser->_unstub; }		SemanticCompoundQueries::registerParserFunctions( $wgParser ); } }

function scqgRegisterParser(&$parser) { $parser->setFunctionHook( 'compound_query', array('SemanticCompoundQueries','doCompoundQuery') ); return true; // always return true, in order not to stop MW's hook processing! }

function scqgLanguageGetMagic( &$magicWords, $langCode = "en" ) { switch ( $langCode ) { default: $magicWords['compound_query'] = array ( 0, 'compound_query' ); }	return true; }

/** * Subclass of SMWQueryResult - this class was mostly created in order to * get around an inconvenient print-request-compatibility check in * SMWQueryResult::addRow * * @ingroup SemanticCompoundQueries */ class SCQQueryResult extends SMWQueryResult {

function addResult($new_result) { // create an array of the pages already in this query result, // so that we can check against it to make sure that pages // aren't included twice $existing_page_names = array; while ($row = $this->getNext) { if ($row[0] instanceof SMWResultArray) { $content = $row[0]->getContent; $existing_page_names[] = $content[0]->getLongText(SMW_OUTPUT_WIKI); }		}		while (($row = $new_result->getNext) !== false) { $row[0]->display_options = $new_result->display_options; $content = $row[0]->getContent; $page_name = $content[0]->getLongText(SMW_OUTPUT_WIKI); if (! in_array($page_name, $existing_page_names)) $this->m_content[] = $row; }		reset($this->m_content); } }

/** * Class that holds static functions for handling compound queries. * This class is heavily based on Semantic MediaWiki's SMWQueryProcessor, * and calls that class's functions when possible. * * @ingroup SemanticCompoundQueries */ class SemanticCompoundQueries {

public static function registerParserFunctions(&$parser) { $parser->setFunctionHook( 'compound_query', array('SemanticCompoundQueries','doCompoundQuery') ); return true; // always return true, in order not to stop MW's hook processing! }

/**	 */	static public function doCompoundQuery(&$parser) { global $smwgQEnabled, $smwgIQRunningNumber; if ($smwgQEnabled) { $smwgIQRunningNumber++; $params = func_get_args; array_shift( $params ); // we already know the $parser ... $other_params = array; $query_result = null; foreach ($params as $param) { // very primitive heuristic - if the parameter // includes a square bracket, then it's a				// sub-query; otherwise it's a regular parameter if (strpos($param, '[') !== false) { $sub_params = explode(';', $param); $next_result = SemanticCompoundQueries::getQueryResultFromFunctionParams($sub_params, SMW_OUTPUT_WIKI); if ($query_result == null) $query_result = new SCQQueryResult($next_result->getPrintRequests, new SMWQuery); $query_result->addResult($next_result); } else { $parts = explode('=', $param, 2); if (count($parts) >= 2) { $other_params[strtolower(trim($parts[0]))] = $parts[1]; // don't trim here, some params care for " " }				}			}			$result = SemanticCompoundQueries::getResultFromQueryResult($query_result, $other_params, null, SMW_OUTPUT_WIKI); } else { wfLoadExtensionMessages('SemanticMediaWiki'); $result = smwfEncodeMessages(array(wfMsgForContent('smw_iq_disabled'))); }		return $result; }

static function getQueryResultFromFunctionParams($rawparams, $outputmode, $context = SMWQueryProcessor::INLINE_QUERY, $showmode = false) { SMWQueryProcessor::processFunctionParams($rawparams,$querystring,$params,$printouts,$showmode); return SemanticCompoundQueries::getQueryResultFromQueryString($querystring,$params,$printouts, SMW_OUTPUT_WIKI, $context); }

/**	 * Combine the values from two SMWQueryResult objects into one */	static function mergeSMWQueryResults($result1, $result2) { if ($result1 == null) { $result1 = new SMWQueryResult($result2->getPrintRequests, new SMWQuery); }		$existing_page_names = array; while ($row = $result1->getNext) { if ($row[0] instanceof SMWResultArray) { $content = $row[0]->getContent; $existing_page_names[] = $content[0]->getLongText(SMW_OUTPUT_WIKI); }		}		while (($row = $result2->getNext) !== false) { $row[0]->display_options = $result2->display_options; $content = $row[0]->getContent; $page_name = $content[0]->getLongText(SMW_OUTPUT_WIKI); if (! in_array($page_name, $existing_page_names)) $result1->addRow($row); }		return $result1; }

// this method is an exact copy of SMWQueryProcessor's function, // but it needs to be duplicated because there it's protected static function getResultFormat($params) { $format = 'auto'; if (array_key_exists('format', $params)) { $format = strtolower(trim($params['format'])); global $smwgResultFormats; if ( !array_key_exists($format, $smwgResultFormats) ) { $format = 'auto'; // If it is an unknown format, defaults to list/table again }		}		return $format; }

static function getQueryResultFromQueryString($querystring, $params, $extraprintouts, $outputmode, $context = SMWQueryProcessor::INLINE_QUERY) { wfProfileIn('SemanticCompoundQueries::getQueryResultFromQueryString'); $query = SMWQueryProcessor::createQuery($querystring, $params, $context, null, $extraprintouts); $query_result = smwfGetStore->getQueryResult($query); $query_result->display_options = array; foreach ($params as $key => $value) { // special handling for 'icon' field, since it requires // conversion of a name to a URL if ($key == 'icon') { $icon_title = Title::newFromText($value); $icon_image_page = new ImagePage($icon_title); $icon_url = $icon_image_page->getDisplayedFile->getURL; $query_result->display_options['icon'] = $icon_url; } else { $query_result->display_options[$key] = $value; }		}

wfProfileOut('SemanticCompoundQueries::getQueryResultFromQueryString'); return $query_result; }

/*	 * Matches getResultFromQueryResult from SMWQueryProcessor, * except that formats of type 'debug' and 'count' aren't handled */	static function getResultFromQueryResult($res, $params, $extraprintouts, $outputmode, $context = SMWQueryProcessor::INLINE_QUERY, $format = '') { wfProfileIn('SemanticCompoundQueries::getResultFromQueryResult'); $format = SemanticCompoundQueries::getResultFormat($params); $printer = SMWQueryProcessor::getResultPrinter($format, $context, $res); $result = $printer->getResult($res, $params, $outputmode); wfProfileOut('SemanticCompoundQueries::getResultFromQueryResult'); return $result; } }