Extension:RecordAdmin
<?php
- Extension:RecordAdmin
Template:PhpCategory:Extensions created with Template:SpecialPage
- - Licenced under LGPL (http://www.gnu.org/copyleft/lesser.html)
- - Author: User:Nad
if (!defined('MEDIAWIKI')) die('Not an entry point.');
define('RECORDADMIN_VERSION','0.0.1, 2007-10-17');
$wgRecordAdminCategory = 'Records';
$wgExtensionFunctions[] = 'wfSetupRecordAdmin';
$wgExtensionCredits['specialpage'][] = array( 'name' => 'Special:RecordAdmin', 'author' => 'User:Nad', 'description' => 'A special page for finding and editing record articles using a form', 'url' => 'http://www.organicdesign.co.nz/Extension:SpecialExample', 'version' => RECORDADMIN_VERSION );
require_once "$IP/includes/SpecialPage.php";
- Define a new class based on the SpecialPage class
class SpecialRecordAdmin extends SpecialPage {
# Constructor function __construct() { SpecialPage::SpecialPage( 'RecordAdmin', # name as seen in links etc 'sysop', # user rights required true, # listed in special:specialpages false, # function called by execute() - defaults to wfSpecial{$name} false, # file included by execute() - defaults to Special{$name}.php, only used if no function false # includable ); }
# Override SpecialPage::execute() # - $param is from the URL, eg Special:RecordAdmin/param function execute($param) { global $wgOut, $wgRequest, $wgRecordAdminCategory; $this->setHeaders(); $type = $wgRequest->getText('wpType') or $type = $param; $record = $wgRequest->getText('wpRecord'); $title = Title::makeTitle(NS_SPECIAL, 'RecordAdmin'); $wpTitle = $wgRequest->getText('wpTitle');
# Get posted form values if any $posted = array(); foreach ($_POST as $k => $v) if (ereg('^ra_(.+)$', $k, $m)) $posted[$m[1]] = $v;
# Read in the form for this record type if one has been selected # - extract only the content from between the form tags and remove the submit input if ($type) { $form = new Article(Title::newFromText("Form:$type")); $form = $form->getContent(); $form = preg_replace('#<input.+?type=[\'"]?submit["\']?.+?/(input| *)>#', , $form); $form = preg_replace('#^.+?<form.+?>#s', , $form); $form = preg_replace('#</form>.+?$#s', , $form); $form = preg_replace('#name=[\'"](.+?)["\']#s', 'name="ra_$1"', $form); }
# If no type selected, render select list of record types from Category:Records if (empty($type)) { $wgOut->addWikiText("== Select the type of record to search for ==\n");
$options = ; $dbr = &wfGetDB(DB_SLAVE); $cl = $dbr->tableName('categorylinks'); $cat = $dbr->addQuotes($wgRecordAdminCategory); $res = $dbr->select($cl, 'cl_from', "cl_to = $cat", __METHOD__, array('ORDER BY' => 'cl_sortkey')); while ($row = $dbr->fetchRow($res)) $options .= '<option>'.Title::newFromID($row[0])->getText().'</option>';
$wgOut->addHTML(wfElement('form', array('action' => $title->getLocalURL('action=submit'), 'method' => 'post'), null)); $wgOut->addHTML("<select name='wpType'>$options</select> "); $wgOut->addHTML(wfElement('input', array('type' => 'submit', 'value' => 'Submit')).'</form>'); }
# Record type known, but no record selected, render form for searching elseif (empty($record)) {
# Populate the form with the posted values foreach ($posted as $k => $v) $form = str_replace("name=\"ra_$k\"", "name=\"ra_$k\" value='$v'", $form);
# Render the form $wgOut->addWikiText("== Search for a $type record ==\n"); $wgOut->addHTML(wfElement('form', array('action' => $title->getLocalURL('action=submit'), 'method' => 'post'), null)); $wgOut->addHTML( 'Record Name: ' . wfElement('input', array('name' => 'wpTitle', 'size' => 30, 'value' => $wpTitle)) );
$wgOut->addHTML("\n
\n");
$wgOut->addHTML($form); $wgOut->addHTML(wfElement('input', array('type' => 'hidden', 'name' => 'wpType', 'value' => $type)));
$wgOut->addHTML('
');
$wgOut->addHTML(wfElement('input', array('type' => 'submit', 'value' => 'Search')).'</form>');
# Render results if form has been posted if (count($posted)) {
# Select records which use the template and exhibit a matching title and other fields $records = array(); $dbr = &wfGetDB(DB_SLAVE); $tl = $dbr->tableName('templatelinks'); $ty = $dbr->addQuotes($type); $res = $dbr->select($tl, 'tl_from', "tl_namespace = 10 AND tl_title = $ty", __METHOD__); while ($row = $dbr->fetchRow($res)) { $t = Title::newFromID($row[0]); $ttext = $t->getText(); if (empty($wpTitle) || eregi($wpTitle, $t)) { $a = new Article($t); $text = $a->getContent(); $match = true; foreach ($posted as $k => $v) if ($v) if (!(preg_match("|$k\s*=\s*(.+)\s*$|mi", $text, $m) && eregi($v, $m[1]))) $match = false; if ($match) $records[] = $ttext; } }
# Print the list of results as links to edit records
$wgOut->addWikiText("
\n== $type records matching search query ==\n");
if (count($records)) {
$list = ;
foreach ($records as $r) {
$list .= "
\n";
}
$wgOut->addHTML("
- $list
");
} else $wgOut->addWikiText("no results\n"); } }
# A specific record has been selected, render form for updating else { $wgOut->addWikiText("== Editing \"$record\" ==\n"); $article = new Article(Title::newFromText("$type:$record")); $text = $article->fetchContent();
# Update article if form posted if (count($posted)) {
# Get the location and length of the record braces to replace foreach ($this->examineBraces($text) as $brace) if ($brace['NAME'] == $type) $braces = $brace;
# Attempt to save the article $summary = "RecordAdmin: $type properties updated"; $replace = ; foreach ($posted as $k => $v) if ($v) $replace .= "| $k = $v\n"; $replace = $replace ? "Template:"."$type\n$replace" : "Template:"."$type"; $text = substr_replace($text, $replace, $braces['OFFSET'], $braces['LENGTH']); $success = $article->doEdit($text, $summary, EDIT_UPDATE);
# Report success or error
if ($success) $wgOut->addHTML("
\n"); else $wgOut->addHTML("
\n");
$wgOut->addHTML("
\n");
}
# Populate the form with the current values in the article preg_match_all("|\|\s*(.+?)\s*=\s*(.+?)$|m", $text, $m); foreach ($m[1] as $i => $k) $form = eregi_replace("name=\"ra_$k\"", "name=\"ra_$k\" value='{$m[2][$i]}'", $form);
# Render the form $wgOut->addHTML(wfElement('form', array('action' => $title->getLocalURL('action=submit'), 'method' => 'post'), null)); $wgOut->addHTML($form); $wgOut->addHTML(wfElement('input', array('type' => 'hidden', 'name' => 'wpType', 'value' => $type))); $wgOut->addHTML(wfElement('input', array('type' => 'hidden', 'name' => 'wpRecord', 'value' => $record)));
$wgOut->addHTML('
');
$wgOut->addHTML(wfElement('input', array('type' => 'submit', 'value' => 'Save')).'</form>'); }
}
function examineBraces(&$content) { $braces = array(); $depths = array(); $depth = 1; $index = 0; while (preg_match('/\\{\\{\\s*([#a-z0-9_]*)|\\}\\}/is', $content, $match, PREG_OFFSET_CAPTURE, $index)) { $index = $match[0][1]+2; if ($match[0][0] == '}}') { $brace =& $braces[$depths[$depth-1]]; $brace['LENGTH'] = $match[0][1]-$brace['OFFSET']+2; $brace['DEPTH'] = $depth--; } else { $depths[$depth++] = count($braces); $braces[] = array( 'NAME' => $match[1][0], 'OFFSET' => $match[0][1] ); } } return $braces; }
}
- Called from $wgExtensionFunctions array when initialising extensions
function wfSetupRecordAdmin() { global $wgLanguageCode, $wgMessageCache;
# Add the messages used by the specialpage if ($wgLanguageCode == 'en') { $wgMessageCache->addMessages(array( 'recordadmin' => 'Record administration' )); }
# Add the specialpage to the environment SpecialPage::addPage(new SpecialRecordAdmin()); }