2 rcs_id('$Id: Ploticus.php,v 1.2 2004-06-02 19:37:07 rurban Exp $');
4 Copyright 2004 $ThePhpWikiProgrammingTeam
6 This file is part of PhpWiki.
8 PhpWiki is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 PhpWiki is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with PhpWiki; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 * The Ploticus plugin passes all its arguments to the ploticus
25 * binary and displays the result as PNG, GIF, EPS or SVG.
26 * Ploticus is a free, GPL, non-interactive software package
27 * for producing plots, charts, and graphics from data.
28 * See http://ploticus.sourceforge.net/doc/welcome.html
30 * @Author: Reini Urban
33 * - For windows you need either a gd library with GIF support or
34 * a ploticus with PNG support. This comes only with the cygwin built.
35 * - We support only images supported by GD so far (PNG most likely).
36 * No EPS, PS, SVG or SVGZ support due to limitations in WikiPluginCached.
39 <?plugin Ploticus device=png [ploticus options...]
40 multiline ploticus script ...
42 * or without any script:
43 <?plugin Ploticus -prefab vbars data=myfile.dat delim=tab y=1 clickmapurl="http://mywiki.url/wiki/?pagename=@2" clickmaplabel="@3" -csmap ?>
45 * TODO: PloticusSql - create intermediate data from SQL. Similar to SqlResult, just in graphic form.
46 * For example to proeduce nice looking pagehit statistics or ratings statistics.
50 define('PLOTICUS_EXE','pl.exe');
52 define('PLOTICUS_EXE','/usr/local/bin/pl');
54 require_once "lib/WikiPluginCached.php";
56 class WikiPlugin_Ploticus
57 extends WikiPluginCached
60 * Sets plugin type to MAP if -csmap (-map or -mapdemo or -csmapdemo not supported)
61 * or HTML if the imagetype is not supported by GD (EPS, SVG, SVGZ) (not yet)
62 * or IMAGE if device = png, gif or jpeg
64 function getPluginType() {
65 if (!empty($this->_args['-csmap']))
66 return PLUGIN_CACHED_MAP; // not yet tested
68 return PLUGIN_CACHED_IMG_INLINE;
73 function getDescription () {
74 return _("Ploticus image creation");
76 function managesValidators() {
79 function getVersion() {
80 return preg_replace("/[Revision: $]/", '',
83 function getDefaultArguments() {
85 'device' => 'png', // png,gif,svgz,svg,...
91 function handle_plugin_args_cruft(&$argstr, &$args) {
92 $this->source = $argstr;
95 * Sets the expire time to one day (so the image producing
96 * functions are called seldomly) or to about two minutes
97 * if a help screen is created.
99 function getExpire($dbi, $argarray, $request) {
100 if (!empty($argarray['help']))
101 return '+120'; // 2 minutes
102 return sprintf('+%d', 3*86000); // approx 3 days
106 * Sets the imagetype according to user wishes and
107 * relies on WikiPluginCached to catch illegal image
109 * (I feel unsure whether this option is reasonable in
110 * this case, because png will definitely have the
113 * @return string 'png', 'jpeg', 'gif'
115 function getImageType($dbi, $argarray, $request) {
116 return $argarray['device'];
120 * This gives an alternative text description of
123 function getAlt($dbi, $argstr, $request) {
124 return (!empty($this->_args['alt'])) ? $this->_args['alt']
125 : $this->getDescription();
129 * Returns an image containing a usage description of the plugin.
131 * TODO: -csmap pointing to the Ploticus documentation at sf.net.
132 * @return string image handle
134 function helpImage() {
135 $def = $this->defaultArguments();
136 $other_imgtypes = $GLOBALS['CacheParams']['imgtypes'];
137 unset ($other_imgtypes[$def['imgtype']]);
139 '<?plugin Ploticus ' .
140 'device' => ' = "' . $def['device'] . "(default)|" . join('|',$GLOBALS['CacheParams']['imgtypes']).'"',
141 'alt' => ' = "alternate text"',
142 '-csmap' => ' bool: clickable map?',
143 'help' => ' bool: displays this screen',
144 '...' => ' all further lines below the first plugin line ',
145 '' => ' and inside the tags are the ploticus script.',
149 foreach($helparr as $alignright => $alignleft) {
150 $length = max($length, strlen($alignright));
153 foreach($helparr as $alignright => $alignleft) {
154 $helptext .= substr(' '
155 . $alignright, -$length).$alignleft."\n";
157 return $this->text2img($helptext, 4, array(1, 0, 0),
158 array(255, 255, 255));
161 function newFilterThroughCmd($input, $commandLine) {
162 $descriptorspec = array(
163 0 => array("pipe", "r"), // stdin is a pipe that the child will read from
164 1 => array("pipe", "w"), // stdout is a pipe that the child will write to
165 2 => array("pipe", "w"), // stdout is a pipe that the child will write to
168 $process = proc_open("$commandLine", $descriptorspec, $pipes);
169 if (is_resource($process)) {
170 // $pipes now looks like this:
171 // 0 => writeable handle connected to child stdin
172 // 1 => readable handle connected to child stdout
173 // 2 => readable handle connected to child stderr
174 fwrite($pipes[0], $input);
177 while(!feof($pipes[1])) {
178 $buf .= fgets($pipes[1], 1024);
182 while(!feof($pipes[2])) {
183 $stderr .= fgets($pipes[2], 1024);
186 // It is important that you close any pipes before calling
187 // proc_close in order to avoid a deadlock
188 $return_value = proc_close($process);
189 if (empty($buf)) printXML($this->error($stderr));
194 /* PHP versions < 4.3
195 * TODO: via temp file looks more promising
197 function OldFilterThroughCmd($input, $commandLine) {
198 $input = str_replace ("\\", "\\\\", $input);
199 $input = str_replace ("\"", "\\\"", $input);
200 $input = str_replace ("\$", "\\\$", $input);
201 $input = str_replace ("`", "\`", $input);
202 $input = str_replace ("'", "\'", $input);
203 //$input = str_replace (";", "\;", $input);
205 $pipe = popen("echo \"$input\"|$commandLine", 'r');
207 print "pipe failed.";
211 while (!feof($pipe)) {
212 $output .= fread($pipe, 1024);
218 function getImage($dbi, $argarray, $request) {
219 //extract($this->getArgs($argstr, $request));
220 //extract($argarray);
221 $source =& $this->source;
222 if (!empty($source)) {
224 $cacheparams = $GLOBALS['CacheParams'];
225 $tempfiles = tempnam($cacheparams['cache_dir'], 'Ploticus');
226 $gif = $argarray['device'];
227 $args = " -stdin -$gif -o $tempfiles.$gif";
228 if (!empty($argarray['-csmap'])) {
229 $args .= " -csmap -mapfile $tempfiles.map";
230 $this->_mapfile = "$tempfiles.map";
232 $commandLine = PLOTICUS_EXE . "$args";
233 if (check_php_version(4,3,0))
234 $code = $this->newFilterThroughCmd($source, $commandLine);
236 $code = $this->oldFilterThroughCmd($source, $commandLine);
238 // return $this->error(fmt("Couldn't start commandline '%s'", $commandLine));
239 if (! file_exists("$tempfiles.$gif") )
240 return $this->error(fmt("Ploticus error: Outputfile '%s' not created", $tempfiles.$gif));
241 $ImageCreateFromFunc = "ImageCreateFrom$gif";
242 $img = $ImageCreateFromFunc( "$tempfiles.$gif" );
245 return $this->error(fmt("empty source"));
249 function getMap($dbi, $argarray, $request) {
250 $img = $this->getImage($dbi, $argarray, $request);
251 return array($this->_mapfile, $img);
255 // $Log: not supported by cvs2svn $
256 // Revision 1.1 2004/06/02 19:12:42 rurban
257 // new Ploticus plugin
266 // c-hanging-comment-ender-p: nil
267 // indent-tabs-mode: nil