From OrganicDesign Wiki
<?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;
}