Difference between revisions of "Ploticus extension"

From FollowTheScore
Jump to: navigation, search
(New page: Note that we use a slightly enhaced version of ''Ploticus''. The main difference is that our version can take data from an embedded template. You will find ''Ploticus 1.1'' in one of the ...)
 
Line 5: Line 5:
 
Until then, here is the source:
 
Until then, here is the source:
  
<pre><nowiki>
+
<pre>
 
<?php
 
<?php
  
Line 156: Line 156:
 
}
 
}
 
?>
 
?>
</nowiki></pre>
+
</pre>

Revision as of 10:38, 21 November 2007

Note that we use a slightly enhaced version of Ploticus. The main difference is that our version can take data from an embedded template.

You will find Ploticus 1.1 in one of the next DPL versions.

Until then, here is the source:

<?php

/**
* Ploticus.php
* Ploticus extension for just-in-time graph generation
* This extension is inspired from the EasyTimeline and the Gnuplot extensions.
* Copyright Flavien Scheurer, October 2007
* Minor Modifications by Gero Scholz, December 2007 
* 
* Tested on:
* 	- MediaWiki 1.11.0
* 	- Apache 2.2.4 on Windows Server 2003
* 	- PHP 5.2.4
* 	- Not tested on *nix but should work ok by switching path separator from \ to /.
* Requirements:
* 	- Ploticus 2.33 (http://ploticus.sourceforge.net/doc/download.html).
* Syntax:
* 	<ploticus>...</ploticus> or {{#ploticus: ... }}
* Script handbook:
* 	http://ploticus.sourceforge.net/doc/scripthome.html
* Installation:
*   - Create directory 'yourWiki/extensions/Ploticus'
*	- Install Ploticus under 'yourWiki/extensions/Ploticus/linux' or 'yourWiki/extensions/Ploticus/windows'
*     To use any other location (avoid spaces in the path) adapt the execution path appropriately
* 	- Add in LocalSettings.php:
*		require_once("$IP/extensions/Ploticus/Ploticus.php");
*		$wgPloticusSettings->exePath = "$IP/extensions/Ploticus/linux/bin/pl";
*		# $wgPloticusSettings->exePath = "$IP/extensions/Ploticus/windows/bin/pl.exe";
*		$wgPloticusSettings->imageFormat = 'png';  // use 'gif' for windows
* Todo:
* 	- Add support for clickable maps.
* 	- Cleanup previous generaget files in the Ploticus folder.
* 	- Add support for pretty PNG.
* Warning:
* 	- Designed with security in mind, but this is my first public PHP script and should be reviewed!
*
*
* @version 1.0
*			initial version
* @version 1.1
*			allow the extension to be used also as a parser function; thus templates can be used
*           to take data from
*
*/
define('PLOTICUS_VERSION', '0.2');               // current version 

if (!defined('MEDIAWIKI')) die();

class PloticusSettings {
	function PloticusSettings () {
		// Set path to the Ploticus executable (should be overridden in LocalSettings.php).
		// $this->exePath = '/mywiki/extensions/Ploticus/linux/bin/pl';
		$this->exePath = '/mywiki/extensions/Ploticus/windows/bin/pl.exe';
		
		// Set the image format (gif by default, png not supported on Windows, svg not supported on IE 6, 
		//                       gif not supported by precompiled linux binary).
		// $this->imageFormat = 'png';  // png or svgz = typical setting for linux
		$this->imageFormat = 'gif';		//         gif = typical setting for windows
	}
}

$wgPloticusSettings 			= new PloticusSettings;

$wgExtensionFunctions[] 		= 'wfPloticusExtension';
$wgHooks['LanguageGetMagic'][]	= 'wfPloticus_Magic';

$wgExtensionCredits['parserhook'][] = array(
	'name' 		=> 'Ploticus',
  	'version' 	=>  WGRAPH_VERSION,
	'author' 	=> 'Flavien Scheurer',
	'url' 		=> 'http://www.mediawiki.org/wiki/Extension:Ploticus',
	'description' => 'Ploticus extension for just-in-time graph generation<br/>'.
					 'Syntax is <ploticus>...</ploticus><br/>'.
					 'Script handbook: http://ploticus.sourceforge.net/doc/scripthome.html',
	);

function wfPloticusExtension() {
	global $wgParser;
	$wgParser->setHook('ploticus', 'renderPloticus');
	# add a parser function hook
	$wgParser->setFunctionHook( 'ploticus', 'renderPloticusPF' );
}

function wfPloticus_Magic( &$magicWords, $langCode ) {
        $magicWords['ploticus'] = array( 0, 'ploticus' );
        return true;
}

function renderPloticusPF( &$parser ) {
	$numargs = func_num_args();
	$arg_list = func_get_args();
	if ($numargs < 2) return ('!! #ploticus: empty script. !!');
	
	// we must get the generated HTML through the parser->strip() function
	// is there a better way for this?
	global $wgRawHtml;
	$wgRawHtml = true;
	return '<html>'.renderPloticus($arg_list[1]).'</html>';
}

function renderPloticus( $ploticusData ) {
	global $wgPloticusSettings, $wgUploadDirectory, $wgUploadPath;
	// Remove potentially dangerous keywords.
	$replaces = array('`'  => '', 'system' => '', 'shell' => '');
	$ploticusData = strtr($ploticusData, $replaces);
	// Create the image directory.
	$ploticusDirectory = $wgUploadDirectory . '/ploticus/';
	if (!is_dir($ploticusDirectory)) {
		mkdir($ploticusDirectory, 0777); 
		chmod($ploticusDirectory, 0777);
	}
	// Generate a file name based on the hashed ploticus data.
	$name = md5($ploticusData);
	$graphFile = $ploticusDirectory . $name . '.' . $wgPloticusSettings->imageFormat;
	$graphURL = $wgUploadPath . '/ploticus/' . $name . '.' . $wgPloticusSettings->imageFormat;
	// Check if a previous plot is available.
	if (!file_exists($graphFile)) {
		$dataFile = $ploticusDirectory . $name . '.plo';
		$errorFile = $ploticusDirectory . $name . '.txt';
		// Verify that Ploticus is installed.
		if (!file_exists($wgPloticusSettings->exePath)) {
			return ('<p><strong>Error: Could not find Ploticus in <em>' . $wgPloticusSettings->exePath . '</em></strong></p>');
		}
		// Write the ploticus data to a file.
		$handle = fopen($dataFile, 'w');
		fwrite($handle, $ploticusData);
		fclose($handle);
		//Set the command line.
		$commandline = wfEscapeShellArg($wgPloticusSettings->exePath) .
			' -' . $wgPloticusSettings->imageFormat .
			' ' . wfEscapeShellArg($dataFile) .
			' -o ' . wfEscapeShellArg($graphFile) .
			' 2>' . wfEscapeShellArg($errorFile);
		// Execute Ploticus.
		wfShellExec($commandline);
		// Read the error messages from the error file.
		$errorData = file_get_contents($errorFile);
		// Delete the ploticus data and error files.
		if (file_exists($dataFile)) { unlink($dataFile);}
		if (file_exists($errorFile)) { unlink($errorFile);}
	}
	// Prepare the output.
	if (isset($errorData) && $errorData != '') {
		return ('<p><strong>Error processing Ploticus data:</strong><br/><pre>' . $errorData . '
</p>');

} else {

return ('

<img src="' . $graphURL . '" alt="Ploticus Chart">

');

} } ?> </pre>