Difference between revisions of "Extension:FileSync.php"

From Organic Design wiki
(no caching on sync'd items)
(tidy and fix warning)
 
(8 intermediate revisions by the same user not shown)
Line 1: Line 1:
 
<?php
 
<?php
# Extension:FileSync{{Category:Extensions}}{{php}}
+
# Extension:FileSync{{Category:Extensions|FileSync}}{{php}}
 
# - Licenced under LGPL (http://www.gnu.org/copyleft/lesser.html)
 
# - Licenced under LGPL (http://www.gnu.org/copyleft/lesser.html)
 
# - Author: [http://www.organicdesign.co.nz/nad User:Nad]{{Category:Extensions created with Template:Extension}}
 
# - Author: [http://www.organicdesign.co.nz/nad User:Nad]{{Category:Extensions created with Template:Extension}}
Line 7: Line 7:
 
if (!defined('MEDIAWIKI')) die('Not an entry point.');
 
if (!defined('MEDIAWIKI')) die('Not an entry point.');
  
define('FILESYNC_VERSION','0.0.1, 2007-09-02');
+
define('FILESYNC_VERSION','1.0.0, 2009-03-15');
  
 
$wgFileSyncMagic              = "filesync";
 
$wgFileSyncMagic              = "filesync";
Line 19: Line 19:
 
'url'        => 'http://www.organicdesign.co.nz/Extension:FileSync',
 
'url'        => 'http://www.organicdesign.co.nz/Extension:FileSync',
 
'version'    => FILESYNC_VERSION
 
'version'    => FILESYNC_VERSION
);
+
);
  
 
class FileSync {
 
class FileSync {
Line 26: Line 26:
 
var $paths;
 
var $paths;
  
# Constructor - add hooks and initialise class
+
/**
 +
* Constructor - add hooks and initialise class
 +
*/
 
function FileSync() {
 
function FileSync() {
global $wgHooks,$wgParser,$wgFileSyncMagic;
+
global $wgHooks, $wgParser, $wgFileSyncMagic;
$wgParser->setFunctionHook($wgFileSyncMagic,array($this,'magicFilesync'));
+
$wgParser->setFunctionHook( $wgFileSyncMagic, array( $this, 'magicFilesync' ) );
 
$wgHooks['ArticleSaveComplete'][]  = $this;
 
$wgHooks['ArticleSaveComplete'][]  = $this;
 
$wgHooks['ArticleDelete'][]        = $this;
 
$wgHooks['ArticleDelete'][]        = $this;
 
$this->args  = array();
 
$this->args  = array();
 
$this->paths = array();
 
$this->paths = array();
}
+
}
 
   
 
   
# Reduce the magic and obtain the args and paths
+
/**
function magicFilesync(&$parser) {
+
* Reduce the magic and obtain the args and paths
global $wgTitle;
+
*/
 +
function magicFilesync( &$parser ) {
 +
global $wgTitle, $wgOut, $wgSiteNotice;
 
$parser->mOutput->mCacheTime = -1;
 
$parser->mOutput->mCacheTime = -1;
$filesync = '[[MW:Extension:FileSync|FileSync]]: ';
+
$filesync = "'''[[MW:Extension:FileSync|FileSync]]'''";
  
 
# Extract paths and args
 
# Extract paths and args
foreach (func_get_args() as $arg) if (!is_object($arg)) {
+
foreach ( func_get_args() as $arg ) if ( !is_object( $arg ) ) {
if (preg_match('/^(.+?)\\s*=\\s*(.+)$/',$arg,$match)) $this->args[$match[1]] = $match[2];
+
if ( preg_match( '/^(.+?)\\s*=\\s*(.+)$/', $arg, $match ) ) $this->args[$match[1]] = $match[2];
 
else $this->paths[] = $arg;
 
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
 
# Check if master file has changed and if so, update the article
 
$file = $this->paths[0];
 
$file = $this->paths[0];
if (file_exists($file)) {
+
if ( file_exists( $file ) ) {
$message = '{'."{message|icon=[[Image:Info.png]]|text=$filesync: This article is synchronised with ''$file''}".'}';
+
$wgSiteNotice .= '{'."{info|$filesync: This article is automatically synchronised with the file '''$file'''}".'}';
$article = new Article($wgTitle);
+
$article = new Article( $wgTitle );
$atext  = $article->getContent();
+
$atext  = trim( $article->getContent() );
$ftext  = file_get_contents($file);
+
$ftext  = trim( file_get_contents( $file ) );
if ($atext !== $ftext) {
+
if ( $atext !== $ftext ) {
$comment = "Article updated from $file";
+
$comment = "Article updated from file '''$file'''";
$message = '{'."{message|icon=[[Image:Warning.png]]|text=$filesync: $comment}".'}';
+
$article->doEdit( $ftext,$comment );
$article->doEdit($text,$comment);
+
$wgOut->redirect( $wgTitle->getLocalURL("filesyncupdated=$comment" ) );
}
 
 
}
 
}
else '{'."{message|icon=[[Image:Warning.png]]|text=$filesync: ''$file'' does not exist!}".'}';
+
}
 +
else $wgSiteNotice .= '{'."{warning|$filesync: File '''$file''' does not exist!}".'}';
 +
 
 +
return '';
 +
}
  
return $message;
+
/*
}
+
* Update any associated files with the new content
 +
* - templates are expanded so that filepaths are known
 +
*/
 +
function onArticleSaveComplete( &$article, &$user, &$text ) {
  
# Update any associated files with the new content
+
# Don't do any processing of files unless sysop
# - templates are expanded so that filepaths are known
+
if ( !in_array( 'sysop', $user->getGroups() ) ) return true;
function onArticleSaveComplete(&$article,&$user,&$atext) {
 
  
 
# Preprocess the text so that the paths are evaluated
 
# Preprocess the text so that the paths are evaluated
$this->preprocess($article);
+
$this->preprocess( $article );
  
 
# If the article content is now different than the file, update the file
 
# If the article content is now different than the file, update the file
$file = $this->paths[0];
+
if ( count( $this->paths ) ) {
if (file_exists($file)) {
+
$file = $this->paths[0];
$ftext = file_get_contents($file);
+
if ( file_exists( $file ) ) {
if ($atext !== $ftext) file_put_contents($file,$atext);
+
$atext = trim( $text );
 +
$ftext = trim( file_get_contents( $file ) );
 +
if ( $atext !== $ftext ) file_put_contents( $file, $atext );
 
}
 
}
 +
}
  
 
return true;
 
return true;
}
+
}
  
# Get any filepaths before deleting the article
+
/**
function onArticleDelete(&$article,&$user,$reason) {
+
* Get any filepaths before deleting the article (can only delete if sysop)
 +
*/
 +
function onArticleDelete( &$article, &$user, $reason ) {
 
global $wgHooks;
 
global $wgHooks;
$this->preprocess($article);
+
if ( in_array( 'sysop', $user->getGroups() ) ) {
$wgHooks['ArticleDeleteComplete'][] = $this;
+
$this->preprocess( $article );
 +
$wgHooks['ArticleDeleteComplete'][] = $this;
 +
}
 
return true;
 
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 );
 
}
 
}
 
# 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;
 
return true;
}
+
}
  
# Preprocess the text so that the paths are evaluated and templates expanded ready for writing to files
+
/**
function preprocess(&$article) {
+
* Preprocess the text so that the paths are evaluated and templates expanded ready for writing to files
 +
*/
 +
function preprocess( &$article ) {
 
$title  = $article->getTitle();
 
$title  = $article->getTitle();
 
$text    = $article->getContent();
 
$text    = $article->getContent();
 
$parser  = new Parser;
 
$parser  = new Parser;
 
$opt    = new ParserOptions;
 
$opt    = new ParserOptions;
return $parser->preprocess($text,$title,$opt);
+
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
+
/**
 +
* Called from $wgExtensionFunctions array when initialising extensions
 +
*/
 
function wfSetupFileSync() {
 
function wfSetupFileSync() {
 
global $wgFileSync;
 
global $wgFileSync;
 
$wgFileSync = new FileSync();
 
$wgFileSync = new FileSync();
}
+
}
  
# Needed in MediaWiki >1.8.0 for magic word hooks to work properly
+
/**
function wfFileSyncLanguageGetMagic(&$magicWords,$langCode = 0) {
+
* Needed in MediaWiki >1.8.0 for magic word hooks to work properly
 +
*/
 +
function wfFileSyncLanguageGetMagic( &$magicWords, $langCode = 0 ) {
 
global $wgFileSyncMagic;
 
global $wgFileSyncMagic;
$magicWords[$wgFileSyncMagic] = array(0,$wgFileSyncMagic);
+
$magicWords[$wgFileSyncMagic] = array( $langCode, $wgFileSyncMagic );
 
return true;
 
return true;
}
+
}
?>
 

Latest revision as of 22:17, 14 March 2009

<?php

  1. Extension:FileSync
Info.svg These are the MediaWiki extensions we're using and/or developing. Please refer to the information on the mediawiki.org wiki for installation and usage details. Extensions here which have no corresponding mediawiki article are either not ready for use or have been superseded. You can also browse our extension code in our local Subversion repository or our GitHub mirror.

Template:Php

  1. - Licenced under LGPL (http://www.gnu.org/copyleft/lesser.html)
  2. - Author: User:NadCategory:Extensions created with Template:Extension
  3. - 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' => '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 = "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; }