Extension:Infobox Data Capture

What can this extension do?
Enables template designers to store typed data in the database for query and retrieval.

Usage
Creates a parser function called #dataentry with two arguments:


 * Title: The name of the block of data to be stored.
 * Key-value pairs: A '\n' deliminated list of key-value pairs separated by '='.

Installation
Add the database table `infoboxdata`, move the code to the extensions folder and include the code in LocalSettings.php.

Database Table Addition
Requires one table called _infoboxdata.

CREATE TABLE .`_infoboxdata` (  `ib_from` int(8) unsigned NOT NULL default '0',  `ib_title` varbinary(255) NOT NULL default ,  `ib_instance` int(11) NOT NULL default '7',  `ib_attribute` varbinary(255) NOT NULL default ,  `ib_value` blob NOT NULL,  KEY `ib_from` (`ib_from`,`ib_title`,`ib_instance`,`ib_attribute`),  KEY `ib_title` (`ib_title`,`ib_from`) ) ENGINE=MyISAM DEFAULT CHARSET=binary;

Changes to LocalSettings.php
require_once("$IP/extensions/InfoboxData/InfoboxData.php");

Code
<?php

$wgKeyValuePairs = array;

$wgHooks['ArticleSaveComplete'][] = 'saveInfoboxData'; $wgHooks['ArticleDeleteComplete'][] = 'deleteInfoboxData';

$wgExtensionFunctions[] = 'wfDataEntryParserFunction_Setup'; $wgHooks['LanguageGetMagic'][]      = 'wfDataEntryParserFunction_Magic';
 * 1) Define a setup function
 * 1) Add a hook to initialise the magic word

function wfDataEntryParserFunction_Setup { global $wgParser; # Set a function hook associating the "example" magic word with our function $wgParser->setFunctionHook( 'dataentry', 'wfDataEntryParserFunction_Render' ); }

function wfDataEntryParserFunction_Magic( &$magicWords, $langCode ) { # Add the magic word $magicWords['dataentry'] = array( 0, 'dataentry' ); # unless we return true, other parser functions extensions won't get loaded. return true; }

function wfDataEntryParserFunction_Render( &$parser, $title, $args ) { $dataPairs = explode("\n", $args); $keyValuePairs = parseKeyValuePairs( $dataPairs ); addKeyValuePairs($title, $keyValuePairs); $output = ""; return $output; }

function addKeyValuePairs( $title, $args) { global $wgKeyValuePairs; if ( !isset( $wgKeyValuePairs[$title] ) ) { $wgKeyValuePairs[$title] = array; }	if($args) { array_push ($wgKeyValuePairs[$title], $args); } }

function parseKeyValuePairs( $args ) { $assocArgs = array; $index = 1; foreach( $args as $arg ) { $eqpos = strpos( $arg, '=' ); if ( $eqpos === false ) { $assocArgs[$index++] = $arg; } else { $name = trim( substr( $arg, 0, $eqpos ) ); $value = trim( substr( $arg, $eqpos+1 ) ); if ( $value === false ) { wfDebug("value is false bizo.\n\n"); $value = ''; }			if (( $name !== false ) && $value) { $assocArgs[$name] = $value; }		}	}		return $assocArgs; }

function saveInfoboxData(&$article, &$user, &$text, &$summary, &$minoredit, &$watchthis, &$sectionanchor, &$flags) { global $wgKeyValuePairs; # Update the links tables $ibd = new InfoboxDataUpdate( $article->getTitle, $wgKeyValuePairs ); $ibd->doUpdate; }

function deleteInfoboxData(&$article, &$user, $reason) { $dbw =& wfGetDB( DB_MASTER ); $dbw->delete( 'infoboxdata', array( 'ib_from' => $article->getID ) ); }

/** * Modeled after LinksUpdate from 1.9.3 * Can't use ParserOutput object because called from ArticleSaveComplete hook * @package MediaWiki */ class InfoboxDataUpdate {

/**@*/

/**	 * Constructor * Initialize private variables * @param $title Title object * @param $infoboxData 3-D array holding key value pairs for multiple data blocks */	function InfoboxDataUpdate( $title, $infoboxData) { global $wgAntiLockFlags;

if ( $wgAntiLockFlags & ALF_NO_LINK_LOCK ) { $this->mOptions = array; } else { $this->mOptions = array( 'FOR UPDATE' ); }		$this->mDb =& wfGetDB( DB_MASTER );

$this->mTitle = $title; $this->mId = $title->getArticleID;

$this->mInfoboxData = $infoboxData; }

/**	 * Update link tables with outgoing links from an updated article */	function doUpdate { $this->doDumbUpdate; }

/**	 * Link update which clears the previous entries and inserts new ones * May be slower or faster depending on level of lock contention and write speed of DB * Also useful where link table corruption needs to be repaired, e.g. in refreshLinks.php */	function doDumbUpdate { $fname = 'InfoboxData::doDumbUpdate'; wfProfileIn( $fname ); $this->dumbTableUpdate( 'infoboxdata', $this->getInfoboxDataInsertions, 'ib_from' ); wfProfileOut( $fname ); }

function dumbTableUpdate( $table, $insertions, $fromField ) { $fname = 'InfoboxData::dumbTableUpdate'; $this->mDb->delete( $table, array( $fromField => $this->mId ), $fname ); if ( count( $insertions ) ) { # The link array was constructed without FOR UPDATE, so there may be collisions # This may cause minor link table inconsistencies, which is better than # crippling the site with lock contention. $this->mDb->insert( $table, $insertions, $fname, array( 'IGNORE' ) ); }	}

/**	 * Get an array of data from dataentry tags insertions. Like getLinkInsertions * @private */	function getInfoboxDataInsertions( $existing = array ) { wfProfileIn( __METHOD__ ); $arr = array; foreach( $this->mInfoboxData as $title => $infoboxes ) { foreach ( $infoboxes as $instance => $infobox ) { foreach ( $infobox as $arg => $value ) { $arr[] = array(						'ib_from'     => $this->mId,						'ib_title'     => $title,						'ib_instance'  => $instance,						'ib_attribute' => $arg,						'ib_value'     => $value					); }			}		}		wfProfileOut( __METHOD__ ); return $arr; } } ?>