Personal tools




Extension:FileSync.php

From OrganicDesign Wiki

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','1.0.0, 2009-03-15');
 
$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
		if ( count( $this->paths ) ) {
			$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 ) {
		if ( count( $this->paths ) ) {
			$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 );
	}
}
 
/**
 * 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( $langCode, $wgFileSyncMagic );
	return true;
}

The GNU Project Debian Linux Ubuntu Linux Wikipedia Affiliate Button MediaWiki