Personal tools


Extension:Backup.php

From OrganicDesign

Jump to: navigation, search
Image:legacy.png
Legacy: This article describes a concept that has been superseded in the course of ongoing development on the Organic Design wiki. Please do not develop this any further or base work on this concept, this is only useful for a historic record of work done. You may find a link to the currently used concept or function in this article, if not you can contact the author to find out what has taken the place of this legacy item.


<?php
# Extension:Backup
# - Licenced under LGPL (http://www.gnu.org/copyleft/lesser.html)
# - Author:  [http://www.organicdesign.co.nz/nad User:Nad]
# - Started: 2007-06-09
# - This is a SpecialPage which acts as an in-wiki interface to backup.pl which reduces the backup/compress/distribute queue
 
if (!defined('MEDIAWIKI')) die('Not an entry point.');
 
define('BACKUPS_VERSION','0.0.1, 2007-06-18');
 
$wgExtensionFunctions[] = 'wfSetupBackup';
 
$wgExtensionCredits['specialpage'][] = array(
	'name'        => 'Special:Backup',
	'author'      => '[http://www.organicdesign.co.nz/nad User:Nad]',
	'description' => 'A special page for backing up and restoring multiple wikis on a server',
	'url'         => 'http://www.mediawiki.org/wiki/Extension:Backup_&_Restore',
	'version'     => BACKUPS_VERSION
	);
 
require_once "$IP/includes/SpecialPage.php";
 
# Define a new class based on the SpecialPage class
class SpecialBackup extends SpecialPage {
 
	# Constructor
	function SpecialBackup() {
		SpecialPage::SpecialPage('Backup','sysop');
		}
 
	# Override SpecialPage::execute()
	# - $param is from the URL, eg Special:Backups/param
	function execute($param) {
		global $wgOut,$wgRequest;
		$title = Title::makeTitle(NS_SPECIAL,'Backup');
 
		# create a sortable table for all wiki's found and accessible in mysql
		$cols = array('ID','Name','Domains','DB','Status','Version','Backup-cycle','Delete','Backup','Repair');
		$wgOut->addWikiText(wfMsg('backup_wikilist'));
		$wgOut->addHTML('<form><table class="sortable"><tr><th>'.join('</th><th>',$cols).'</tr>');
		foreach ($this->getWikiList() as $wiki) {
			$wgOut->addHTML("<tr>$something</tr>");
			}
 
		# create a sortable table of all backup files which could be restored
		# - each row has same cols as above +backup-filename -backup -delete
		$cols = array('File','ID','Name','Domains','DB','Status','Version','Backup-cycle','Delete','Backup');
		$wgOut->addWikiText(wfMsg('backup_backuplist'));
		$wgOut->addHTML('<form><table class="sortable"><tr><th>'.join('</th><th>',$cols).'</tr>');
		foreach ($backups as $backup) {
			$wgOut->addHTML("<tr>$something</tr>");
			}
 
		# "Next >" or "Commit"
		$wgOut->addHTML(wfElement('input',array('type' => 'submit','name' => 'backup_next',   'value' => wfMsg('backup_next'))));
		$wgOut->addHTML(wfElement('input',array('type' => 'submit','name' => 'backup_commit', 'value' => wfMsg('backup_commit'))));
		$wgOut->addHTML(wfElement('input',array('type' => 'hidden','name' => 'backup_title',  'value' => $this->title)));
		$wgOut->addHTML('</table></form>');
 
		# Add list of jobs to be committed by changes (if submitted with "next")
		if ($wgRequest->getText('backup_next')) {
			$jobs = submit();
			if (count($jobs) > 0) {
				$wgOut->addWikiText(wfMsg('backup_commitlist'));
				foreach ($jobs as $job) {
					$wgOut->addWikiText("*$job");
					}
				}
			else $wgOut->addWikiText(wfMsg('backup_nojobs'));
			}
 
		# Queue the jobs if form posted with "commit"
		if ($wgRequest->getText('backup_commit')) submit(true);
 
		# add list of backup.pl job queue (and link to MW log of completed items)
		$wgOut->addWikiText(wfMsg('backup_activelist'));
		$jobs = file(dirname(__FILE__).'/jobs');
		if (count($jobs) > 0) {
			foreach ($jobs as $job) {
				$wgOut->addWikiText("*$job");
				}
			}
		else $wgOut->addWikiText(wfMsg('backup_nojobs'));
		}
 
	# Process posted form
	function submit($queue = false) {
		$jobs = array();
		foreach ($wikis as $wiki) {
			# todo: work out jobs from fields changed
			if ($queue) {
				# queue the job
				}
			}
		return $jobs;
		}
 
	# Get list from DB's and LocalSettings files
	# - it scans DB's as well so that orphans with no LocalSettings can be handled too
	function getWikiList() {
 
		# Make a hash of all databases and their tables;
		$db = &wfGetDB(DB_SLAVE);
		$databases = array();
		$dblist = mysql_list_dbs($db);
		for ($i = 0; $i < mysql_num_rows($dblist); $i++) {
			$database = mysql_db_name($dblist,$i);
			$databases[$database] = array();
			$db->query("SHOW TABLES FROM $database");
			while ($row = mysql_fetch_row($result)) $databases[$database][] = $row[0];
			}
 
		# These tables have been the same since version 1.4
		$testtables = array(
			'archive',
			'categorylinks',
			'hitcounter',
			'image',
			'interwiki',
			'ipblocks',
			'math',
			'querycache',
			'recentchanges',
			'searchindex',
			'sitestats',
			'text',
			'user',
			'user_newtalk',
			'watchlist'
			);
 
		# Scan for table prefixes
		$prefixes = array();
		foreach ($databases as $database => $tables) foreach ($tables as $table)
			if (ereg("^(.*)$testtables[0]$",$table,$prefix)) $prefixes[] = array($database,$prefix[1]);
 
		# Scan the prefixes for all having a complete set of tables
		$mediawikis = array();
		foreach ($prefixes as $p) {
			list($database,$prefix) = $p;
			$match = true;
			foreach ($testtables as $test) if (!in_array($prefix.$test,$databases[$database])) $match = false;
			if ($match) $mediawikis[] = array('database' => $database,'prefix' => $prefix);
			}
 
		# todo: import instances found in settings dir
 
		return $mediawikis;
		}
 
	}
 
# Called from $wgExtensionFunctions array when initialising extensions
function wfSetupBackup() {
	global $wgLanguageCode,$wgMessageCache;
 
	# Add the messages used by the specialpage
	if ($wgLanguageCode == 'en') {
		$wgMessageCache->addMessages(array(
			'backup'            => "Backup & Restore",
			'backup_wikilist'   => "=== List of wikis ===\n*''the '''ID''' is used for file/dir name and db-prefix\n",
			'backup_backuplist' => "=== List of backups and templates ===",
			'backup_commitlist' => "The changes you've submitted result in the following jobs:",
			'backup_activelist' => "The following jobs are currently executing:",
			'backup_next'       => "Next >",
			'backup_commit'     => "Commit",
			'backup_nojobs'     => "''There are no jobs in the list.''"
			));
		}
 
	# Add the specialpage to the environment
	SpecialPage::addPage(new SpecialBackup());
	}
?>