]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/plugin/Ploticus.php
honor _ENV PLOTICUS_PREFABS
[SourceForge/phpwiki.git] / lib / plugin / Ploticus.php
1 <?php // -*-php-*-
2 rcs_id('$Id: Ploticus.php,v 1.10 2004-10-04 23:43:35 rurban Exp $');
3 /*
4  Copyright 2004 $ThePhpWikiProgrammingTeam
5
6  This file is part of PhpWiki.
7
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.
12
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.
17
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
21  */
22
23 /**
24  * The Ploticus plugin passes all its arguments to the ploticus 
25  * binary and displays the result as PNG, GIF, EPS, SVG or SWF.
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
29  *
30  * @Author: Reini Urban
31  *
32  * Note: 
33  * - For windows you need either a gd library with GIF support or 
34  *   a ploticus with PNG support. This comes e.g. with the cygwin build.
35  * - We support only images supported by GD so far (PNG most likely). 
36  *   No EPS, PS, SWF, SVG or SVGZ support yet, due to limitations in WikiPluginCached.
37  *   This will be fixed soon.
38  *
39  * Usage:
40 <?plugin Ploticus device=png [ploticus options...]
41    multiline ploticus script ...
42 ?>
43  * or without any script: (not tested)
44 <?plugin Ploticus -prefab vbars data=myfile.dat delim=tab y=1 clickmapurl="http://mywiki.url/wiki/?pagename=@2" clickmaplabel="@3" -csmap ?>
45  *
46  * TODO: PloticusSql - create intermediate data from SQL. Similar to SqlResult, just in graphic form.
47  * For example to produce nice looking pagehit statistics or ratings statistics.
48  * Ploticus has its own sql support within #getproc data, but this would expose security information.
49  */
50
51 if (!defined("PLOTICUS_EXE"))
52   if (isWindows())
53     define('PLOTICUS_EXE','pl.exe');
54   else
55     define('PLOTICUS_EXE','/usr/local/bin/pl');
56 //TODO: check $_ENV['PLOTICUS_PREFABS'] and default directory
57
58 require_once "lib/WikiPluginCached.php"; 
59
60 class WikiPlugin_Ploticus
61 extends WikiPluginCached
62 {
63     /**
64      * Sets plugin type to MAP if -csmap (-map or -mapdemo or -csmapdemo not supported)
65      * or HTML if the imagetype is not supported by GD (EPS, SVG, SVGZ) (not yet)
66      * or IMG_INLINE if device = png, gif or jpeg
67      */
68     function getPluginType() {
69         if (!empty($this->_args['-csmap']))
70             return PLUGIN_CACHED_MAP; // not yet tested
71         // produce these on-demand so far, uncached. 
72         // will get better support in WikiPluginCached soon.
73         // FIXME: html also? what about ''?
74         $type = $this->decideImgType($this->_args['device']);
75         if ($type == $this->_args['device'])
76             return PLUGIN_CACHED_IMG_INLINE;
77         $device = strtolower($this->_args['device']);
78         if (in_array($device, array('svg','swf','svgz','eps','ps','pdf','html'))) {
79             switch ($this->_args['device']) {
80                 case 'svg':
81                 case 'svgz':
82                    return PLUGIN_CACHED_STATIC | PLUGIN_CACHED_SVG_PNG;
83                 case 'swf':
84                    return PLUGIN_CACHED_STATIC | PLUGIN_CACHED_SWF;
85                 default: 
86                    return PLUGIN_CACHED_STATIC | PLUGIN_CACHED_HTML;
87             }
88         }
89         else
90             return PLUGIN_CACHED_IMG_INLINE; // normal cached libgd image handles
91     }
92     function getName () {
93         return _("Ploticus");
94     }
95     function getDescription () {
96         return _("Ploticus image creation");
97     }
98     function managesValidators() {
99         return true;
100     }
101     function getVersion() {
102         return preg_replace("/[Revision: $]/", '',
103                             "\$Revision: 1.10 $");
104     }
105     function getDefaultArguments() {
106         return array(
107                      'device' => 'png', // png,gif,svgz,svg,...
108                      '-prefab' => '',
109                      '-csmap' => false,
110                      'data'    => false, // <!plugin-list !> support
111                      'alt'    => false,
112                      'help'   => false,
113                      );
114     }
115     function handle_plugin_args_cruft(&$argstr, &$args) {
116         $this->source = $argstr;
117     }
118     /**
119      * Sets the expire time to one day (so the image producing
120      * functions are called seldomly) or to about two minutes
121      * if a help screen is created.
122      */
123     function getExpire($dbi, $argarray, $request) {
124         if (!empty($argarray['help']))
125             return '+120'; // 2 minutes
126         return sprintf('+%d', 3*86000); // approx 3 days
127     }
128
129     /**
130      * Sets the imagetype according to user wishes and
131      * relies on WikiPluginCached to catch illegal image
132      * formats.
133      * (I feel unsure whether this option is reasonable in
134      *  this case, because png will definitely have the
135      *  best results.)
136      *
137      * @return string 'png', 'jpeg', 'gif'
138      */
139     function getImageType($dbi, $argarray, $request) {
140         return $argarray['device'];
141     }
142
143     /**
144      * This gives an alternative text description of
145      * the image.
146      */
147     function getAlt($dbi, $argstr, $request) {
148         return (!empty($this->_args['alt'])) ? $this->_args['alt']
149                                              : $this->getDescription();
150     }
151
152     /**
153      * Returns an image containing a usage description of the plugin.
154      *
155      * TODO: -csmap pointing to the Ploticus documentation at sf.net.
156      * @return string image handle
157      */
158     function helpImage() {
159         $def = $this->defaultArguments();
160         //$other_imgtypes = $GLOBALS['PLUGIN_CACHED_IMGTYPES'];
161         //unset ($other_imgtypes[$def['imgtype']]);
162         $helparr = array(
163             '<?plugin Ploticus ' .
164             'device'           => ' = "' . $def['device'] . "(default)|" . join('|',$GLOBALS['PLUGIN_CACHED_IMGTYPES']).'"',
165             'data'             => ' <!plugin-list !>: pagelist as input',
166             'alt'              => ' = "alternate text"',
167             '-csmap'           => ' bool: clickable map?',
168             'help'             => ' bool: displays this screen',
169             '...'              => ' all further lines below the first plugin line ',
170             ''                 => ' and inside the tags are the ploticus script.',
171             "\n  ?>"
172             );
173         $length = 0;
174         foreach($helparr as $alignright => $alignleft) {
175             $length = max($length, strlen($alignright));
176         }
177         $helptext ='';
178         foreach($helparr as $alignright => $alignleft) {
179             $helptext .= substr('                                                        '
180                                 . $alignright, -$length).$alignleft."\n";
181         }
182         return $this->text2img($helptext, 4, array(1, 0, 0),
183                                array(255, 255, 255));
184     }
185
186     function withShellCommand($script) {
187         $findme  = 'shell';
188         $pos = strpos($script, $findme); // uppercase?
189         if ($pos === false) 
190             return 0;
191         return 1;
192     }
193
194     function getImage($dbi, $argarray, $request) {
195         //extract($this->getArgs($argstr, $request));
196         //extract($argarray);
197         $source =& $this->source;
198         if (!empty($source)) {
199             if ($this->withShellCommand($source)) {
200                 $this->_errortext .= _("shell commands not allowed in Ploticus");
201                 return false;
202             }
203             if (is_array($argarray['data'])) { // support <!plugin-list !> pagelists
204                 $src = "#proc getdata\ndata:";
205                 $i = 0;
206                 foreach ($argarray['data'] as $data) {
207                     // hash or array?
208                     if (is_array($data))
209                         $src .= ("\t" . join(" ", $data) . "\n");
210                     else
211                         $src .= ("\t" . '"' . $data . '" ' . $i++ . "\n");
212                 }
213                 $src .= $source;
214                 $source = $src;
215             }
216             $tempfile = $this->tempnam('Ploticus');
217             unlink($tempfile);
218             $gif = $argarray['device'];
219             $args = " -stdin -$gif -o $tempfile.$gif";
220             if (!empty($argarray['-csmap'])) {
221                 $args .= " -csmap -mapfile $tempfile.map";
222                 $this->_mapfile = "$tempfile.map";
223             }
224             if (!empty($argarray['-prefab'])) {
225                 //check $_ENV['PLOTICUS_PREFABS'] and default directory
226                 global $HTTP_ENV_VARS;
227                 if (empty($HTTP_ENV_VARS['PLOTICUS_PREFABS'])) {
228                     if (file_exists("/usr/share/ploticus"))
229                         $HTTP_ENV_VARS['PLOTICUS_PREFABS'] = "/usr/share/ploticus";
230                 }
231                 $args .= (" -prefab " . $argarray['-prefab']);
232             }
233             $code = $this->filterThroughCmd($source, PLOTICUS_EXE . "$args");
234             //if (empty($code))
235             //    return $this->error(fmt("Couldn't start commandline '%s'", $commandLine));
236             if (! file_exists("$tempfile.$gif") ) {
237                 $this->_errortext .= sprintf(_("Ploticus error: Outputfile '%s' not created"), "$tempfile.$gif");
238                 return false;
239             }
240             $ImageCreateFromFunc = "ImageCreateFrom$gif";
241             if (function_exists($ImageCreateFromFunc))
242                 return $ImageCreateFromFunc( "$tempfile.$gif" );
243             return "$tempfile.$gif";
244         } else {
245             return $this->error(fmt("empty source"));
246         }
247     }
248     
249     // which argument must be set to 'png', for the fallback image when svg will fail on the client.
250     // type: SVG_PNG
251     function pngArg() {
252         return 'device';
253     }
254     
255     function getMap($dbi, $argarray, $request) {
256         $img = $this->getImage($dbi, $argarray, $request);
257         return array($this->_mapfile, $img);
258     }
259 };
260
261 // $Log: not supported by cvs2svn $
262 // Revision 1.9  2004/09/26 17:09:23  rurban
263 // add SVG support for Ploticus (and hopefully all WikiPluginCached types)
264 // SWF not yet.
265 //
266 // Revision 1.8  2004/09/22 15:23:56  rurban
267 // support <!plugin-list !> pagelist data
268 // add -prefab arg support
269 //
270 // Revision 1.7  2004/09/22 13:46:26  rurban
271 // centralize upload paths.
272 // major WikiPluginCached feature enhancement:
273 //   support _STATIC pages in uploads/ instead of dynamic getimg.php? subrequests.
274 //   mainly for debugging, cache problems and action=pdf
275 //
276 // Revision 1.6  2004/09/07 13:26:31  rurban
277 // new WikiPluginCached option debug=static and some more sf.net defaults for VisualWiki
278 //
279 // Revision 1.5  2004/06/28 16:35:12  rurban
280 // prevent from shell commands
281 //
282 // Revision 1.4  2004/06/19 10:06:38  rurban
283 // Moved lib/plugincache-config.php to config/*.ini
284 // use PLUGIN_CACHED_* constants instead of global $CacheParams
285 //
286 // Revision 1.3  2004/06/03 09:40:57  rurban
287 // WikiPluginCache improvements
288 //
289 // Revision 1.2  2004/06/02 19:37:07  rurban
290 // extended description
291 //
292 // Revision 1.1  2004/06/02 19:12:42  rurban
293 // new Ploticus plugin
294 //
295 //
296
297 // For emacs users
298 // Local Variables:
299 // mode: php
300 // tab-width: 8
301 // c-basic-offset: 4
302 // c-hanging-comment-ender-p: nil
303 // indent-tabs-mode: nil
304 // End:
305 ?>