Personal tools


Extension:FileSync.php

From OrganicDesign

Jump to: navigation, search
<?php
# Extension:FileSync
# - Licenced under LGPL (http://www.gnu.org/copyleft/lesser.html)
# - Author: [http://www.organicdesign.co.nz/nad User:Nad]
# - Started: 2007-08-02
 
if (!defined('MEDIAWIKI')) die('Not an entry point.');
 
define('FILESYNC_VERSION','0.0.3, 2007-09-03');
 
$wgFileSyncMagic               = "filesync";
$wgExtensionFunctions[]        = 'wfSetupFileSync';
$wgHooks['LanguageGetMagic'][] = 'wfFileSyncLanguageGetMagic';
 
$wgExtensionCredits['parserhook'][] = array(
	'name'        => 'FileSync',
	'author'      => '[http://www.organicdesign.co.nz/nad User:Nad]',
	'description' => 'A template which can be added to an article to make it synchronise with a file',
	'url'         => 'http://www.organicdesign.co.nz/Extension:FileSync',
	'version'     => FILESYNC_VERSION
	);
 
class FileSync {
 
	var $args;
	var $paths;
 
	# Constructor - add hooks and initialise class
	function FileSync() {
		global $wgHooks,$wgParser,$wgFileSyncMagic;
		$wgParser->setFunctionHook($wgFileSyncMagic,array($this,'magicFilesync'));
		$wgHooks['ArticleSaveComplete'][]  = $this;
		$wgHooks['ArticleDelete'][]        = $this;
		$this->args  = array();
		$this->paths = array();
		}
 
	# Reduce the magic and obtain the args and paths
	function magicFilesync(&$parser) {
		global $wgTitle,$wgOut,$wgSiteNotice;
		$parser->mOutput->mCacheTime = -1;
		$filesync = "'''[[MW:Extension:FileSync|FileSync]]'''";
 
		# Extract paths and args
		foreach (func_get_args() as $arg) if (!is_object($arg)) {
			if (preg_match('/^(.+?)\\s*=\\s*(.+)$/',$arg,$match)) $this->args[$match[1]] = $match[2];
			else $this->paths[] = $arg;
			}
 
		# Display the file updated message if sent
		if (isset($_REQUEST['filesyncupdated'])) {
			$comment = $_REQUEST['filesyncupdated'];
			$wgSiteNotice .= '{'."{warning|$filesync: $comment}".'}';
			return '';
			}
 
		# Exit now if not a normal view request
		if (isset($_REQUEST['action']) || isset($_REQUEST['oldid'])) return '';
 
		# Check if master file has changed and if so, update the article
		$file = $this->paths[0];
		if (file_exists($file)) {
			$wgSiteNotice .= '{'."{info|$filesync: This article is automatically synchronised with the file '''$file'''}".'}';
			$article = new Article($wgTitle);
			$atext   = trim($article->getContent());
			$ftext   = trim(file_get_contents($file));
			if ($atext !== $ftext) {
				$comment = "Article updated from file '''$file'''";
				$article->doEdit($ftext,$comment);
				$wgOut->redirect($wgTitle->getLocalURL("filesyncupdated=$comment"));
				}
			}
		else $wgSiteNotice .= '{'."{warning|$filesync: File '''$file''' does not exist!}".'}';
 
		return '';
		}
 
	# Update any associated files with the new content
	# - templates are expanded so that filepaths are known
	function onArticleSaveComplete(&$article,&$user,&$text) {
 
		# Don't do any processing of files unless sysop
		if (!in_array('sysop',$user->getGroups())) return true;
 
		# Preprocess the text so that the paths are evaluated
		$this->preprocess($article);
 
		# If the article content is now different than the file, update the file
		$file = $this->paths[0];
		if (file_exists($file)) {
			$atext = trim($text);
			$ftext = trim(file_get_contents($file));
			if ($atext !== $ftext) file_put_contents($file,$atext);
			}
 
		return true;
		}
 
	# Get any filepaths before deleting the article (can only delete if sysop)
	function onArticleDelete(&$article,&$user,$reason) {
		global $wgHooks;
		if (in_array('sysop',$user->getGroups())) {
			$this->preprocess($article);
			$wgHooks['ArticleDeleteComplete'][] = $this;
			}
		return true;
		}
 
	# If the delete completes properly, delete the associated file
	function onArticleDeleteComplete(&$article,&$user,&$reason) {
		$file   = $this->paths[0];
		$reason = "(also deleting $file) $reason";
		if (file_exists($file)) unlink($file);
		return true;
		}
 
	# Preprocess the text so that the paths are evaluated and templates expanded ready for writing to files
	function preprocess(&$article) {
		$title   = $article->getTitle();
		$text    = $article->getContent();
		$parser  = new Parser;
		$opt     = new ParserOptions;
		return $parser->preprocess($text,$title,$opt);
		}
 
	# Needed in some versions to prevent Special:Version from breaking
	function __toString() { return 'FileSync'; }
	}
 
# Called from $wgExtensionFunctions array when initialising extensions
function wfSetupFileSync() {
	global $wgFileSync;
	$wgFileSync = new FileSync();
	}
 
# Needed in MediaWiki >1.8.0 for magic word hooks to work properly
function wfFileSyncLanguageGetMagic(&$magicWords,$langCode = 0) {
	global $wgFileSyncMagic;
	$magicWords[$wgFileSyncMagic] = array(0,$wgFileSyncMagic);
	return true;
	}
?>