URL: http://metabolomics.jp/
*/
if ( !defined( 'MEDIAWIKI' ) ) {
die( 'This file is a MediaWiki extension, see Persistency.php.' );
}
$wgExtensionFunctions[] = 'efSetupPersistency';
$wgExtensionCredits['parserhook'][] = array(
'name' => 'Persistency',
'version' => '0.4',
'author' => 'K, Suwa',
'description' => 'Link and page which receive template and arguments',
'url' => 'http://metabolomics.jp/wiki/Help:Extension/Persistency',
);
$wgHooks['LanguageGetMagic'][] = 'efPersistencyLanguageGetMagic';
$wgHooks['ParserAfterStrip'][] = 'efPersistencyUpdatePage';
$wgHooks['InternalParseBeforeLinks'][] = 'efPersistencyChangePage';
$wgHooks['ArticleSave'][] = 'efPersistencyUpdateAll';
$wgHooks['ParserBeforeStrip'][] = 'efPersistencyRemoveString';
global $egPersNamespace, $egPersFlag, $egPersUpdateStr;
$egPersNamespace = "Persist";
$egPersFlag = 0;
$egPersUpdateStr = "__UPDATE_ALL_PERSISTENCIES__";
require_once( "$IP/includes/JobQueue.php" );
class PersistencyUpdateJob extends Job {
function __construct( $title, $params, $id = 0 ) {
parent::__construct( 'updatePersistency', $title, $params, $id );
}
function run() {
if( !ereg( '^[0-9]+$', $this->params['argc'] ) ){
return false;
}
$template = $this->params['template'];
if( strlen( $this->params['separator'] ) == 0 )
$this->params['separator'] = ';';
$args = split( $this->params['separator'], $this->params['args'], $this->params['argc'] );
$tmpTitle = $this->title;
$tmpArticle = MediaWiki::articleFromTitle( $tmpTitle );
$tmpText = "{{subst:" . $template . "|" . implode( "|", $args ) . "}}";
if( $tmpArticle->exists() )
$tmpArticle->doEdit( $tmpText, '', EDIT_UPDATE );
else
$tmpArticle->doEdit( $tmpText, '', EDIT_NEW );
if( strcmp( $this->params['recursive'], "false" ) == 0 )
return true;
$nextContent = "";
$nowikiStr = "__PERSIST_NOWIKI__";
while( true ) {
$tmpArticle->clear();
$tmpContent = $tmpArticle->getContent();
# process -
$nowikiData = array();
while( ( $start = stripos( $tmpContent, "" ) ) !== FALSE ) {
$end = stripos( $tmpContent, "", $start + 8 );
$nowikiData[] = substr( $tmpContent, $start, $end + 9 );
$tmpContent = substr( $tmpContent, 0, $start ) . $nowikiStr . substr( $tmpContent, $end + 9 );
}
$nextContent = preg_replace( "/{{(?!subst:|{)/", "{{subst:", $tmpContent );
for( $i = 0; $i < count( $nowikiData ); $i ++ ){
$nextContent = preg_replace( "/" . $nowikiStr . "/", $nowikiData[$i], $nextContent, 1 );
}
$tmpArticle->doEdit( $nextContent, '', EDIT_UPDATE );
if( strcmp( $tmpArticle->getContent(), $nextContent ) == 0 )
break;
}
$tmpArticle->doEdit( str_replace( "{{subst:", "{{", $tmpContent ), EDIT_UPDATE );
return true;
}
}
function efPersistencyRemoveString( &$parser, &$text, &$strip_state ) {
global $egPersUpdateStr;
if( strpos( $text, $egPersUpdateStr ) !== FALSE ) {
# remove $egPersUpdateStr
$text = str_replace( $egPersUpdateStr, '', $text );
}
return true;
}
function efPersistencyUpdateAll( &$parser, &$user, &$text, &$summary, $minor, $watch, $sectionanchor, &$flags ) {
global $wgUser, $wgExtraNamespaces, $egPersUpdateStr, $egPersNamespace;
if( $wgUser->isLoggedIn() == false )
return true;
$procText = $text;
while( ( $start = stripos( $procText, "" ) ) !== FALSE ) {
$end = stripos( $procText, "", $start + 8 );
if( $end === FALSE ){
$procText = substr( $procText, 0, $start );
break;
}
$procText = substr( $procText, 0, $start ) . substr( $procText, $end + 9 );
}
if( strpos( $procText, $egPersUpdateStr ) !== FALSE ) {
$index = 0;
# get namespace number
$namespaceNumber = array_search( $egPersNamespace, $wgExtraNamespaces );
if( $namespaceNumber === FALSE )
return true;
# process
while( ( $start = stripos( $procText, "" ) ) !== FALSE ){
$end = stripos( $procText, "", $start + 8 );
$procText = substr( $procText, 0, $start ) . substr( $procText, $end + 9 );
}
$jobs = array();
while( ( $start = stripos( $procText, "{{#" . $egPersNamespace . ":", $index ) ) !== FALSE ) {
$count = 2;
# get
for( $end = $start + 11; $count > 0 && $end < strlen( $procText ); $end ++ ) {
$c = substr( $procText, $end, 2 );
if( strcmp( $c, "}}" ) == 0 )
$count = $count - 2;
if( strcmp( $c, "{{" ) == 0 )
$count = $count + 2;
}
if( $count != 0 )
return true;
$end ++;
$data = substr( $procText, $start + 11, $end - $start - 13 );
$datas = split( "\|", $data );
if( count( $datas ) < 5 || count( $datas ) > 7 )
return true;
if( count( $datas ) == 5 )
$datas[5] = ';';
if( count( $datas ) == 6 )
$datas[6] = 'true';
# setup insert data
$title = Title::makeTitleSafe( $namespaceNumber, $datas[0] );
$params['template'] = $datas[2];
$params['argc'] = $datas[3];
$params['args'] = $datas[4];
$params['separator'] = $datas[5];
$params['recursive'] = $datas[6];
$jobs[] = new PersistencyUpdateJob( $title, $params );
# search previous data
$dbr = wfGetDB( DB_READ );
$res = $dbr->select( 'job', 'job_id', 'job_cmd = \'updatePersistency\' and job_namespace = ' . $namespaceNumber . ' and job_title = \'' . $title->getText() . '\'' );
$num = $dbr->numRows( $res );
if( $num > 0 ){
while( $row = $dbr->fetchObject( $res ) ) {
$ids[] = $row->job_id;
}
$dbr->freeResult( $res );
# delete previous data
$dbw = wfGetDB( DB_MASTER );
for( $i = 0; $i < count( $ids ); $i ++ ) {
$dbw->begin();
$dbw->delete( 'job', array( job_id => $ids[$i] ) );
$dbw->immediateCommit();
}
} else {
$dbr->freeResult( $res );
}
$index = $end;
}
# insert data
if( count( $jobs ) > 0 )
Job::batchInsert( $jobs );
}
return true;
}
function efPersistencyChangePage( &$parser, &$text, $strip_state ) {
global $wgUser, $wgTitle, $egPersNamespace, $egPersFlag, $wgExtraNamespaces;
if( $wgUser->isLoggedIn() == true && ereg( "^$egPersNamespace:.*$", $wgTitle ) ){
if( $egPersFlag == 2 ){
$text = $parser->mStripState->unstripGeneral( $text );
return true;
}
if( $egPersFlag != 1 )
return true;
$egPersFlag = 3;
$text = $parser->mStripState->unstripGeneral( $text );
# create title amd search namespace number
$title = str_replace( "$egPersNamespace:", "", str_replace( " ", "_", $wgTitle ) );
$ns = array_keys( $wgExtraNamespaces, $egPersNamespace );
# update or create page
$t = Title::makeTitleSafe( $ns[0], $title );
$article = MediaWiki::articleFromTitle( $t );
if( $article->exists() ){
# update database
$article->doEdit( $text, '', EDIT_UPDATE );
} else {
# create new page
$article->doEdit( $text, '', EDIT_NEW );
}
# } else if( $wgUser->loadFromDatabase() == true && $egPersFlag == 2 && ereg( "^$egPersNamespace:.*$", $wgTitle ) ){
# $egPersFlag = 3;
# $text = $parser->mStripState->unstripGeneral( $text );
}
return true;
}
function efPersistencyUpdatePage( &$parser, &$text, $strip_state ) {
global $wgTitle, $wgRequest, $wgUser, $egParamPrefix, $egPersNamespace, $egPersFlag, $wgExtraNamespaces;
if( !isset( $egParamPrefix ) )
$egParamPrefix = "my_";
# get post data
$template = $wgRequest->getText( $egParamPrefix . "template" );
$argc = $wgRequest->getText( $egParamPrefix . "argc" );
$args = $wgRequest->getText( $egParamPrefix . "args" );
$sep = $wgRequest->getText( $egParamPrefix . "sep" );
$recursive = $wgRequest->getText( $egParamPrefix . "recursive" );
$outputType = $parser->mOutputType;
$htmlType = Parser::OT_HTML;
$parser->disableCache();
if( $wgUser->isLoggedIn() == true && $egPersFlag == 0 && ereg( "^$egPersNamespace:.*$", $wgTitle ) &&
isset( $template ) && isset( $argc ) && isset( $args ) &&
strlen( $template ) > 0 && ereg( '^[0-9]+$', $argc ) && strlen( $args ) > 0 &&
$outputType == $htmlType ){
# check separator
if( !isset( $sep ) || strlen( $sep ) == 0 )
$sep = ";";
if( strcmp( $recursive, "false" ) == 0 )
$egPersFlag = 2;
else
$egPersFlag = 1;
# set date
# $today = getdate();
# $year = $today["year"];
# $month = $today["mon"];
# $day = $today["mday"];
# set wiki code
$html = "";#"
Last-update: $year-$month-$day
";
$html .= '{{';
$html .= $template;
$data = split( $sep, $args );
for( $i = 0; $i < $argc && $i < count( $data ); $i ++ ){
$html .= "|$data[$i]";
}
$html .= "}}";
$text = $html;
if( strcmp( $recursive, "false" ) == 0 ) {
# create title amd search namespace number
$title = str_replace( "$egPersNamespace:", "", str_replace( " ", "_", $wgTitle ) );
$ns = array_keys( $wgExtraNamespaces, $egPersNamespace );
$updateText = "{{subst:" . substr( $text, 2 );
# update or create page
$t = Title::makeTitleSafe( $ns[0], $title );
$article = MediaWiki::articleFromTitle( $t );
if( $article->exists() ){
# update database
$article->doEdit( $updateText, '', EDIT_UPDATE );
} else {
# create new page
$article->doEdit( $updateText, '', EDIT_NEW );
}
#$text = $article->getContent();
}
}
return true;
}
class PersistencyFunctions {
/**
* persist link
* e.g. {{#persist:page|title|template|argc|args|sep}} =>
*
*
* @param $parser Parser Parent parser
* @param $page string page to jump
* @param $title string label of button
* @param $template string using template
* @param $argc int count of args
* @param $args string arguments
* @param $sep separator of arguments. default is ';'
* @return string Parts string
*/
function persist( &$parser, $page = '', $title = '', $template = '', $argc = 0, $args = '', $sep = ';', $recursive = true ) {
global $wgScriptPath, $wgArticlePath, $egPersNamespace;
if( strlen( $page ) == 0 || strlen( $title ) == 0 || strlen( $template ) == 0 )
return '';
if( isset( $wgArticlePath ) )
$base = str_replace( "$1", "", $wgArticlePath );
else
$base = $wgScriptPath . "/";
$html = "{{#formtag:form|action=\"$base$egPersNamespace:$page\"|\n";
$html .= "{{#formtag:input|type=\"hidden\" name=\"template\" value=\"$template\"}}\n";
$html .= "{{#formtag:input|type=\"hidden\" name=\"args\" value=\"$args\"}}\n";
$html .= "{{#formtag:input|type=\"hidden\" name=\"argc\" value=\"$argc\"}}\n";
$html .= "{{#formtag:input|type=\"hidden\" name=\"sep\" value=\"$sep\"}}\n";
$html .= "{{#formtag:input|type=\"hidden\" name=\"recursive\" value=\"$recursive\"}}\n";
$html .= "{{#formtag:input|type=\"submit\" value=\"$title\"}}\n";
$html .= "}}\n";
if( method_exists( $parser, 'preprocessToDom' ) ){
# mw 1.12 or later
return array( $parser->preprocessToDom( $html ), 'isChildObj' => true );
}
# mw 1.11 or under
return $html;
}
}
function efSetupPersistency() {
global $wgParser, $wgJobClasses;
$wgPersistency = new PersistencyFunctions;
$wgParser->setFunctionHook( 'persist', array( &$wgPersistency, 'persist' ) );
$wgJobClasses['updatePersistency'] = 'PersistencyUpdateJob';
}
function efPersistencyLanguageGetMagic( &$magicWords, $langCode ) {
$magicWords['persist'] = array( 0, 'persist' );
return true;
}