function renderTimeline( $timelinesrc ){ global $wgUploadDirectory, $wgUploadPath, $IP, $wgTimelineSettings, $wgArticlePath, $wgTmpDirectory, $wgRenderHashAppend; $hash = md5( $timelinesrc ); if ($wgRenderHashAppend != "") $hash = md5( $hash . $wgRenderHashAppend ); $dest = $wgUploadDirectory."/timeline/"; if ( ! is_dir( $dest ) ) { mkdir( $dest, 0777 ); } if ( ! is_dir( $wgTmpDirectory ) ) { mkdir( $wgTmpDirectory, 0777 ); } $fname = $dest . $hash; $previouslyFailed = file_exists( $fname.".err" ); $previouslyRendered = file_exists( $fname.".png" ); $expired = $previouslyRendered && ( filemtime( $fname.".png" ) < wfTimestamp( TS_UNIX, $wgTimelineSettings->epochTimestamp ) ); if ( $expired || ( !$previouslyRendered && !$previouslyFailed ) ){ $handle = fopen($fname, "w"); fwrite($handle, $timelinesrc); fclose($handle); $cmdline = wfEscapeShellArg( $wgTimelineSettings->perlCommand, $wgTimelineSettings->timelineFile ) . " -i " . wfEscapeShellArg( $fname ) . " -m -P " . wfEscapeShellArg( $wgTimelineSettings->ploticusCommand ) . " -T " . wfEscapeShellArg( $wgTmpDirectory ) . " -A " . wfEscapeShellArg( $wgArticlePath ) . " -f " . wfEscapeShellArg( $wgTimelineSettings->fontFile ); wfDebug( "Timeline cmd: $cmdline\n" ); $ret = `{$cmdline}`; unlink($fname); if ( $ret == "" ) { // Message not localized, only relevant during install return "<div id=\"toc\" dir=\"ltr\"><tt>Timeline error. " . "Command line was: " . htmlspecialchars( $cmdline ) . "</tt></div>"; } } @$err = file_get_contents( $fname.".err" ); if ( $err != "" ) { // Convert the error from poorly-sanitized HTML to plain text $err = strtr( $err, array( '</p><p>' => "\n\n", '<p>' => '', '</p>' => '', '<b>' => '', '</b>' => '', '<br>' => "\n" ) ); $err = Sanitizer::decodeCharReferences( $err ); // Now convert back to HTML again $encErr = nl2br( htmlspecialchars( $err ) ); $txt = "<div id=\"toc\" dir=\"ltr\"><tt>$encErr</tt></div>"; } else { @$map = file_get_contents( $fname.".map" ); $map = str_replace( ' >', ' />', $map ); $map = "<map name=\"timeline_" . htmlspecialchars( $hash ) . "\">{$map}</map>"; $map = easyTimelineFixMap( $map ); if (wfIsWindows()) { $ext = "gif"; } else { $ext = "png"; } $url = "{$wgUploadPath}/timeline/{$hash}.{$ext}"; $txt = $map . "<img usemap=\"#timeline_" . htmlspecialchars( $hash ) . "\" " . "src=\"" . htmlspecialchars( $url ) . "\">"; if( $expired ) { // Replacing an older file, we may need to purge the old one. global $wgUseSquid; if( $wgUseSquid ) { $u = new SquidUpdate( array( $url ) ); $u->doUpdate(); } } } return $txt; }
/** * @param $timelinesrc string * @return string */ function wfRenderTimeline($timelinesrc) { global $wgUploadDirectory, $wgUploadPath, $wgArticlePath, $wgTmpDirectory, $wgRenderHashAppend; global $wgTimelineSettings; // Get the backend to store plot data and pngs if ($wgTimelineSettings->fileBackend != '') { $backend = FileBackendGroup::singleton()->get($wgTimelineSettings->fileBackend); } else { $backend = new FSFileBackend(array('name' => 'timeline-backend', 'lockManager' => 'nullLockManager', 'containerPaths' => array('timeline-render' => "{$wgUploadDirectory}/timeline"), 'fileMode' => 777)); } // Get a hash of the plot data $hash = md5($timelinesrc); if ($wgRenderHashAppend != '') { $hash = md5($hash . $wgRenderHashAppend); } // Storage destination path (excluding file extension) $fname = 'mwstore://' . $backend->getName() . "/timeline-render/{$hash}"; // Wikia change - begin wfRunHooks('BeforeRenderTimeline', [&$backend, &$fname, $hash]); // Wikia change - end $previouslyFailed = $backend->fileExists(array('src' => "{$fname}.err")); $previouslyRendered = $backend->fileExists(array('src' => "{$fname}.png")); if ($previouslyRendered) { $timestamp = $backend->getFileTimestamp(array('src' => "{$fname}.png")); $expired = $timestamp < $wgTimelineSettings->epochTimestamp; } else { $expired = false; } // Create a new .map, .png (or .gif), and .err file as needed... if ($expired || !$previouslyRendered && !$previouslyFailed) { if (!is_dir($wgTmpDirectory)) { mkdir($wgTmpDirectory, 0777); } $tmpFile = TempFSFile::factory('timeline_'); if ($tmpFile) { $tmpPath = $tmpFile->getPath(); file_put_contents($tmpPath, $timelinesrc); // store plot data to file // Get command for ploticus to read the user input and output an error, // map, and rendering (png or gif) file under the same dir as the temp file. $cmdline = wfEscapeShellArg($wgTimelineSettings->perlCommand, $wgTimelineSettings->timelineFile) . " -i " . wfEscapeShellArg($tmpPath) . " -m -P " . wfEscapeShellArg($wgTimelineSettings->ploticusCommand) . " -T " . wfEscapeShellArg($wgTmpDirectory) . " -A " . wfEscapeShellArg($wgArticlePath) . " -f " . wfEscapeShellArg($wgTimelineSettings->fontFile); // Actually run the command... wfDebug("Timeline cmd: {$cmdline}\n"); $retVal = null; $ret = wfShellExec($cmdline, $retVal); // Copy the output files into storage... // @TODO: store error files in another container or not at all? $opt = array('force' => 1, 'nonLocking' => 1, 'allowStale' => 1); // performance $backend->prepare(array('dir' => dirname($fname))); $backend->store(array('src' => "{$tmpPath}.map", 'dst' => "{$fname}.map"), $opt); $backend->store(array('src' => "{$tmpPath}.png", 'dst' => "{$fname}.png"), $opt); $backend->store(array('src' => "{$tmpPath}.err", 'dst' => "{$fname}.err"), $opt); } else { return "<div id=\"toc\" dir=\"ltr\"><tt>Timeline error. " . "Could not create temp file</tt></div>"; // ugh } if ($ret == "" || $retVal > 0) { // Message not localized, only relevant during install return "<div id=\"toc\" dir=\"ltr\"><tt>Timeline error. " . "Command line was: " . htmlspecialchars($cmdline) . "</tt></div>"; } } // Wikia change - begin if ($backend->fileExists(array('src' => "{$fname}.err", 'latest' => true))) { $err = $backend->getFileContents(array('src' => "{$fname}.err")); } else { $err = ''; } // Wikia change - end if ($err != "") { // Convert the error from poorly-sanitized HTML to plain text $err = strtr($err, array('</p><p>' => "\n\n", '<p>' => '', '</p>' => '', '<b>' => '', '</b>' => '', '<br>' => "\n")); $err = Sanitizer::decodeCharReferences($err); // Now convert back to HTML again $encErr = nl2br(htmlspecialchars($err)); $txt = "<div id=\"toc\" dir=\"ltr\"><tt>{$encErr}</tt></div>"; } else { // Wikia change - begin if ($backend->fileExists(array('src' => "{$fname}.map", 'latest' => true))) { $map = $backend->getFileContents(array('src' => "{$fname}.map")); } else { $map = ''; } // Wikia change - end $map = str_replace(' >', ' />', $map); $map = "<map name=\"timeline_" . htmlspecialchars($hash) . "\">{$map}</map>"; $map = easyTimelineFixMap($map); $url = "{$wgUploadPath}/timeline/{$hash}.png"; // Wikia change - begin $url = wfReplaceImageServer($url); // Wikia change - end $txt = $map . "<img usemap=\"#timeline_" . htmlspecialchars($hash) . "\" " . "src=\"" . htmlspecialchars($url) . "\">"; if ($expired) { // Replacing an older file, we may need to purge the old one. global $wgUseSquid; if ($wgUseSquid) { $u = new SquidUpdate(array($url)); $u->doUpdate(); } } } return $txt; }