Extension talk:Data Aggregator

From mediawiki.org

Is there a version of this extension that reverses the rows and columns? So that the template fields are across the top and the rows are for each page? That would be very helpful to me because I need to be able to sort the values in each template field.


My English is very bad. Very good extension. Change the way of presenting the table and row value filter

Example: <da template="RMS/Document" rowtitles='project_number|project_title' excludes="project_number=86323" class="wikitable sortable" category="RMS"></da>

Code:

<?php
/*
 * Data Aggregator - A MediaWiki Extension
 *
 *  Author: Weiming Li (weiming66@gmail.com)
 *    Date: 2010-06-18
 * Version: 0.2
 *
 * The extension: Data Aggregator allows users to aggregate data from different pages, 
 * those pages must be conformed to a unified template. Data Aggregator will pull the 
 * specific data field from those pages and compose it into a single table. This 
 * extension can be widely used in comparison table and automated information aggregation. 
 *
 * A portion of this code is based directly on the extension TemplateTable from C. Shaun Wagner.
 *
 *   Copyright (C) 2010  Weiming Li
 *
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */
 
// Register the tag.
$wgExtensionFunctions[] = "wfDataAggregator";
 
// Extension credits that will show up on Special:Version    
$wgExtensionCredits['other'][] = array(
    'path'         => __FILE__,
	'name'         => 'Data Aggregator',
	'version'      => '0.2',
	'author'       => 'Weiming Li', 
	'url'          => 'http://www.mediawiki.org/wiki/Extension:DataAggregator',
	'description'  => 'This extension enables you to aggregate the data automatically from different pages which are conformed to a unified template.'
);
 
function wfDataAggregator()
{
	global $wgParser;
	$wgParser->setHook("da", "renderTable");
}
 
/**
* This function renders the table.
* $input = text between <da> and </da>
* $argv = key/val array of options in the <da> tag.
*/
function renderTable($input, $argv)
{
	global $wgScript;
	// Check the template is given or not.
	if(!isset($argv["template"])) return "TemplateTable Error: No template given.  Please use the format <tt>&lt;da template='Name Of Template'&gt;...&lt;/da&gt;</tt>";
 
	// Header type.  If "rowtitle" is given, use that.
	// Otherwise, use dynamic row title (every variable used in the template)
	$dynhead = true;
	$rowtitles = array();
	$excludesArray = array();
	$excludeFlag = False;
	if(isset($argv["rowtitles"]))
	{
		$rowtitles = explode("|", $argv["rowtitles"]);
		$dynhead = false;
	}
	
	if(isset($argv["excludes"])) {
		$excludesArray = explode("|",$argv["excludes"]);
		foreach($excludesArray as $excludeValues) {
			list($excludeKey,$excludeVal) = explode("=",$excludeValues);
			$excludesArray[strtolower($excludeKey)] = $excludeVal;
		}
	}
	// Preset output to the input (stuff between <da> and </da>
	$output = $input;
 
	global $wgDBprefix, $wgContLang;
	$namespaceNames = $wgContLang->namespaceNames;
	$data = array();
 
	// If category is set, then query against the db to get pages belong to the specified category
	if (isset($argv["category"]))
	{
		$query = "select * from ".$wgDBprefix."templatelinks left join ".$wgDBprefix."page on ".$wgDBprefix."templatelinks.tl_from=".$wgDBprefix."page.page_id where tl_title='".mysql_escape_string($argv["template"])."' and page.page_id  in (select cl_from from categorylinks where cl_to ='".mysql_escape_string($argv["category"])."') order by page_title";
	}else
	{
		$query = "select * from ".$wgDBprefix."templatelinks left join ".$wgDBprefix."page on ".$wgDBprefix."templatelinks.tl_from=".$wgDBprefix."page.page_id where tl_title='".mysql_escape_string($argv["template"])."' order by page_title";
	}
 
	$result = mysql_query($query);
	while($row = mysql_fetch_object($result))
	{
		$q2 = "select rev_text_id from ".$wgDBprefix."revision where rev_page=".$row->page_id." order by rev_timestamp desc limit 1";
		if(($res2 = mysql_query($q2)) && ($row2 = mysql_fetch_object($res2)))
		{
			$q3 = "select * from ".$wgDBprefix."text where old_id=".$row2->rev_text_id;
			if(($res3 = mysql_query($q3)) && ($row3 = mysql_fetch_object($res3)))
			{
				$row3->old_text = str_replace("\n", " ", $row3->old_text);	# turn the article into one long line
				$start = stripos($row3->old_text, "{{".$argv["template"])+2;	# cursor after first occurence of {{
				$end = strpos($row3->old_text, "}}", $start)-1;			# cursor before first occurence of }}
				if($start === false || $end === false) continue;		# not found -> cancel result processing

				$item = array();
				// create an array from of the template fields
				$kvs = explode( "|", substr($row3->old_text, $start, $end-$start+1) );
				// remove first field: template name
				unset( $kvs[0] );
 
				foreach($kvs as $kv)
				{
					$kv = trim($kv);
					if($kv == "") continue;
					$eq = strpos($kv, "=");
					if($eq === false) continue;
					$key = trim(substr($kv, 0, $eq));
					$val = trim(substr($kv, $eq+1));
					// Check to see if this header is excluded
					if(isset($excludesArray[$key]) &&
						!strcmp(strtolower($excludesArray[$key]), strtolower($val))) {
						$excludeFlag=True;
						break;
					}
					$item[$key] = $val;
					if($dynhead && !in_array($key, $rowtitles)) array_push($rowtitles, $key);
				}
				if(sizeof($item) > 0 && !$excludeFlag){
					$title = str_replace("_", " ", $row->page_title);
					if ( $row->page_namespace != NS_MAIN ) {
						$title = $namespaceNames[$row->page_namespace].":".$title;
						}
					$data[$title] = $item;
					}
				$excludeFlag = False;
			}
		}
	}
 
	// Skip this if there's no data to display.
	// Otherwise, it will create the table
	if(sizeof($data) > 0)
	{
		$output.= "<table";
		foreach($argv as $key=>$val)
		{
			if($key == "template" || $key == "rowtitles" || $key == "category") continue;
			$output.= " $key=\"$val\"";
		}
		$output.= ">\n";
		$output.= "<tr><th>&nbsp;</th>\n";
 		foreach($rowtitles as $rowtitle)
		{
			$output.="<th>".$rowtitle."</th>\n";
		}
		$output.= "</tr>\n";		
		foreach($data as $page=>$item)
		{
			$link = $page;
			$colon = strpos($link, ":");				# page name as link title
			if ( $colon >= 0 ) $link = substr($link, $colon);	# without leading Category:/Wiki:/Special: statements

			// Changing this line will change the text that appears as the article link:
			// $link = "article";

            $output.= "<tr><td><a href='".$wgScript."?title=".urlencode($page)."'>$link</a></td>\n";
			foreach($rowtitles as $rowtitle)
			{
				if(isset($item[$rowtitle]))
					$output.= "<td>".$item[$rowtitle]."</td>\n";
				else
					$output.= "<td>&nbsp;</td>\n";
			}
			$output.= "</tr>\n";
		}
		$output.= "</table>\n";
	}
	else
	{
		// No data found
		$output.= "Template ".$argv["template"]." has no data. Please double check your template name spelling.";
	}
 
	return $output;
}
 
?>