URL: http://metabolomics.jp/ */ if ( !defined( 'MEDIAWIKI' ) ) { die( 'This file is a MediaWiki extension, see ScriptFunctions.php.' ); } $wgExtensionFunctions[] = 'efSetupScriptFunctions'; $wgExtensionCredits['parserhook'][] = array( 'name' => 'ScriptFunctions', 'version' => '0.2', 'author' => 'K, Suwa', 'description' => 'Call outside script', 'url' => 'http://metabolomics.jp/wiki/Help:Extension/ScriptFunctions', ); $wgHooks['LanguageGetMagic'][] = 'efScriptFunctionsLanguageGetMagic'; class ScriptFunctions { // try 1 second. try 10 times; var $TRY_THRESHOLD = 10; var $MAX_FILE_NUM = 10; /** * lua script * e.g. {{#lua:print(stdin)|abc}} => abc * * @param $parser Parser Parent parser * @param $src string lua script * @param $data string argument, use as 'stdin' in lua script * @return string result or error */ function lua( &$parser, $src, $data = '' ) { global $egLuaPath, $egTmpPath; if( strpos( $src, "dofile" ) !== FALSE ) return array( "", 'noparse' => true ); if( !isset( $egLuaPath ) ) return array( "", 'noparse' => true ); if( !isset( $egTmpPath ) ) $egTmpPath = "/tmp"; $prefix = 'mw_ex_lua_'; for( $count = 0; $count < $this->TRY_THRESHOLD; $count ++ ){ $total = 0; $dir = opendir( $egTmpPath ); if( $dir === FALSE ) return array( "", "noparse" => true ); $now = time(); while( ( $fn = readdir( $dir ) ) !== FALSE ){ $abspath = $egTmpPath . DIRECTORY_SEPARATOR . $fn; $name = $fn; if( !is_file( $abspath ) ) continue; if( strncmp( $name, $prefix, 10 ) == 0 ){ # target file $updatetime = filemtime( $abspath ); $elapsetime = $now - $updatetime; if( $elapsetime >= 10 ) // 10seconds unlink( $abspath ); else $total ++; } } closedir( $dir ); if( $total >= $this->MAX_FILE_NUM ){ usleep( 100000 ); // 100ms } else { break; } } if( $count >= $this->TRY_THRESHOLD ){ // failed return array( "", "noparse" => true ); } $start = tempnam( $egTmpPath, $prefix ); $source = tempnam( $egTmpPath, $prefix ); $src = str_replace( '<', '<', $src ); $src = str_replace( '>', '>', $src ); $src = str_replace( '&', '&', $src ); $src = str_replace( '"', '"', $src ); $data = str_replace( '<', '<', $data ); $data = str_replace( '>', '>', $data ); $data = str_replace( '&', '&', $data ); $data = str_replace( '"', '"', $data ); $fh = fopen( $start, "w" ); fwrite( $fh, "io = nil; debug = nil; package = nil; os = nil;\nstdin = [=[$data]=]\ndofile( \"$source\" )" ); fclose( $fh ); $fh = fopen( $source, "w" ); fwrite( $fh, $src ); fclose( $fh ); $res = ""; $handle = popen( "cd $egLuaPath; ./lua $start 2>&1", 'r' ); while( !feof( $handle ) ) $res .= fgets( $handle, 4096 ); pclose( $handle ); unlink( $start ); unlink( $source ); if( method_exists( $parser, 'preprocessToDom' ) ){ # mw 1.12 or later return array( $parser->preprocessToDom( $res ), 'isChildObj' => true ); } return $res; } } function efSetupScriptFunctions() { global $wgParser; $scriptFunctions = new ScriptFunctions; $wgParser->setFunctionHook( 'lua', array( &$scriptFunctions, 'lua' ) ); } function efScriptFunctionsLanguageGetMagic( &$magicWords, $langCode ) { $magicWords['lua'] = array( 0, 'lua' ); return true; }