File: Ploticus.php

package info (click to toggle)
phpwiki 1.3.12p3-5etch1
  • links: PTS
  • area: main
  • in suites: etch
  • size: 16,956 kB
  • ctags: 21,608
  • sloc: php: 82,335; xml: 3,840; sh: 1,522; sql: 1,198; perl: 625; makefile: 562; awk: 28
file content (318 lines) | stat: -rw-r--r-- 11,890 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
<?php // -*-php-*-
rcs_id('$Id: Ploticus.php,v 1.12 2004/12/13 14:37:22 rurban Exp $');
/*
 Copyright 2004 $ThePhpWikiProgrammingTeam

 This file is part of PhpWiki.

 PhpWiki is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.

 PhpWiki is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with PhpWiki; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

/**
 * The Ploticus plugin passes all its arguments to the ploticus 
 * binary and displays the result as PNG, GIF, EPS, SVG or SWF.
 * Ploticus is a free, GPL, non-interactive software package 
 * for producing plots, charts, and graphics from data.
 * See http://ploticus.sourceforge.net/doc/welcome.html
 *
 * @Author: Reini Urban
 *
 * Note: 
 * - For windows you need either a gd library with GIF support or 
 *   a ploticus with PNG support. This comes e.g. with the cygwin build.
 * - We support only images supported by GD so far (PNG most likely). 
 *   No EPS, PS, SWF, SVG or SVGZ support yet, due to limitations in WikiPluginCached.
 *   This will be fixed soon.
 *
 * Usage:
<?plugin Ploticus device=png [ploticus options...]
   multiline ploticus script ...
?>
 * or without any script: (not tested)
<?plugin Ploticus -prefab vbars data=myfile.dat delim=tab y=1 clickmapurl="http://mywiki.url/wiki/?pagename=@2" clickmaplabel="@3" -csmap ?>
 *
 * TODO: PloticusSql - create intermediate data from SQL. Similar to SqlResult, just in graphic form.
 * For example to produce nice looking pagehit statistics or ratings statistics.
 * Ploticus has its own sql support within #getproc data, but this would expose security information.
 */

if (!defined("PLOTICUS_EXE"))
  if (isWindows())
    define('PLOTICUS_EXE','pl.exe');
  else
    define('PLOTICUS_EXE','/usr/local/bin/pl');
//TODO: check $_ENV['PLOTICUS_PREFABS'] and default directory

require_once "lib/WikiPluginCached.php"; 

class WikiPlugin_Ploticus
extends WikiPluginCached
{
    /**
     * Sets plugin type to MAP if -csmap (-map or -mapdemo or -csmapdemo not supported)
     * or HTML if the imagetype is not supported by GD (EPS, SVG, SVGZ) (not yet)
     * or IMG_INLINE if device = png, gif or jpeg
     */
    function getPluginType() {
    	if (!empty($this->_args['-csmap']))
    	    return PLUGIN_CACHED_MAP; // not yet tested
        // produce these on-demand so far, uncached. 
        // will get better support in WikiPluginCached soon.
        // FIXME: html also? what about ''?
        $type = $this->decideImgType($this->_args['device']);
        if ($type == $this->_args['device'])
            return PLUGIN_CACHED_IMG_INLINE;
        $device = strtolower($this->_args['device']);
    	if (in_array($device, array('svg','swf','svgz','eps','ps','pdf','html'))) {
            switch ($this->_args['device']) {
            	case 'svg':
            	case 'svgz':
                   return PLUGIN_CACHED_STATIC | PLUGIN_CACHED_SVG_PNG;
            	case 'swf':
                   return PLUGIN_CACHED_STATIC | PLUGIN_CACHED_SWF;
                default: 
                   return PLUGIN_CACHED_STATIC | PLUGIN_CACHED_HTML;
            }
        }
    	else
            return PLUGIN_CACHED_IMG_INLINE; // normal cached libgd image handles
    }
    function getName () {
        return _("Ploticus");
    }
    function getDescription () {
        return _("Ploticus image creation");
    }
    function managesValidators() {
        return true;
    }
    function getVersion() {
        return preg_replace("/[Revision: $]/", '',
                            "\$Revision: 1.12 $");
    }
    function getDefaultArguments() {
        return array(
                     'device' => 'png', // png,gif,svgz,svg,...
                     '-prefab' => '',
                     '-csmap' => false,
                     'data'    => false, // <!plugin-list !> support
                     'alt'    => false,
                     'help'   => false,
                     );
    }
    function handle_plugin_args_cruft(&$argstr, &$args) {
        $this->source = $argstr;
    }
    /**
     * Sets the expire time to one day (so the image producing
     * functions are called seldomly) or to about two minutes
     * if a help screen is created.
     */
    function getExpire($dbi, $argarray, $request) {
        if (!empty($argarray['help']))
            return '+120'; // 2 minutes
        return sprintf('+%d', 3*86000); // approx 3 days
    }

    /**
     * Sets the imagetype according to user wishes and
     * relies on WikiPluginCached to catch illegal image
     * formats.
     * (I feel unsure whether this option is reasonable in
     *  this case, because png will definitely have the
     *  best results.)
     *
     * @return string 'png', 'jpeg', 'gif'
     */
    function getImageType($dbi, $argarray, $request) {
        return $argarray['device'];
    }

    /**
     * This gives an alternative text description of
     * the image.
     */
    function getAlt($dbi, $argstr, $request) {
        return (!empty($this->_args['alt'])) ? $this->_args['alt']
                                             : $this->getDescription();
    }

    /**
     * Returns an image containing a usage description of the plugin.
     *
     * TODO: -csmap pointing to the Ploticus documentation at sf.net.
     * @return string image handle
     */
    function helpImage() {
        $def = $this->defaultArguments();
        //$other_imgtypes = $GLOBALS['PLUGIN_CACHED_IMGTYPES'];
        //unset ($other_imgtypes[$def['imgtype']]);
        $helparr = array(
            '<?plugin Ploticus ' .
            'device'           => ' = "' . $def['device'] . "(default)|" 
                                  . join('|',$GLOBALS['PLUGIN_CACHED_IMGTYPES']).'"',
            'data'             => ' <!plugin-list !>: pagelist as input',
            'alt'              => ' = "alternate text"',
            '-csmap'           => ' bool: clickable map?',
            'help'             => ' bool: displays this screen',
            '...'              => ' all further lines below the first plugin line ',
            ''                 => ' and inside the tags are the ploticus script.',
            "\n  ?>"
            );
        $length = 0;
        foreach($helparr as $alignright => $alignleft) {
            $length = max($length, strlen($alignright));
        }
        $helptext ='';
        foreach($helparr as $alignright => $alignleft) {
            $helptext .= substr('                                                        '
                                . $alignright, -$length).$alignleft."\n";
        }
        return $this->text2img($helptext, 4, array(1, 0, 0),
                               array(255, 255, 255));
    }

    function withShellCommand($script) {
        $findme  = 'shell';
        $pos = strpos($script, $findme); // uppercase?
        if ($pos === false) 
            return 0;
        return 1;
    }

    function getImage($dbi, $argarray, $request) {
        //extract($this->getArgs($argstr, $request));
        //extract($argarray);
        $source =& $this->source;
        if (!empty($source)) {
            if ($this->withShellCommand($source)) {
                $this->_errortext .= _("shell commands not allowed in Ploticus");
                return false;
            }
            if (is_array($argarray['data'])) { // support <!plugin-list !> pagelists
                $src = "#proc getdata\ndata:";
                $i = 0;
                foreach ($argarray['data'] as $data) {
                    // hash or array?
                    if (is_array($data))
                        $src .= ("\t" . join(" ", $data) . "\n");
                    else
                        $src .= ("\t" . '"' . $data . '" ' . $i++ . "\n");
                }
                $src .= $source;
                $source = $src;
            }
            $tempfile = $this->tempnam('Ploticus');
            unlink($tempfile);
            $gif = $argarray['device'];
            $args = " -stdin -$gif -o $tempfile.$gif";
            if (!empty($argarray['-csmap'])) {
            	$args .= " -csmap -mapfile $tempfile.map";
            	$this->_mapfile = "$tempfile.map";
            }
            if (!empty($argarray['-prefab'])) {
            	//check $_ENV['PLOTICUS_PREFABS'] and default directory
                global $HTTP_ENV_VARS;
                if (empty($HTTP_ENV_VARS['PLOTICUS_PREFABS'])) {
                    if (file_exists("/usr/share/ploticus"))
                        $HTTP_ENV_VARS['PLOTICUS_PREFABS'] = "/usr/share/ploticus";
                }
            	$args .= (" -prefab " . $argarray['-prefab']);
            }
            $code = $this->filterThroughCmd($source, PLOTICUS_EXE . "$args");
            //if (empty($code))
            //    return $this->error(fmt("Couldn't start commandline '%s'", $commandLine));
            sleep(1);
            if (! file_exists("$tempfile.$gif") ) {
                $this->_errortext .= sprintf(_("%s error: outputfile '%s' not created"), 
                                             "Ploticus", "$tempfile.$gif");
                $this->_errortext .= ("\ncmd-line: cat script | " . PLOTICUS_EXE . "$args");
                return false;
            }
            $ImageCreateFromFunc = "ImageCreateFrom$gif";
            if (function_exists($ImageCreateFromFunc))
                return $ImageCreateFromFunc( "$tempfile.$gif" );
            return "$tempfile.$gif";
        } else {
            return $this->error(fmt("empty source"));
        }
    }
    
    // which argument must be set to 'png', for the fallback image when svg will fail on the client.
    // type: SVG_PNG
    function pngArg() {
    	return 'device';
    }
    
    function getMap($dbi, $argarray, $request) {
    	$img = $this->getImage($dbi, $argarray, $request);
    	return array($this->_mapfile, $img);
    }
};

// $Log: Ploticus.php,v $
// Revision 1.12  2004/12/13 14:37:22  rurban
// simplify msg for new GraphViz plugin
//
// Revision 1.11  2004/10/14 13:48:07  rurban
// wait for fs and print failing cmdline
//
// Revision 1.10  2004/10/04 23:43:35  rurban
// honor _ENV PLOTICUS_PREFABS
//
// Revision 1.9  2004/09/26 17:09:23  rurban
// add SVG support for Ploticus (and hopefully all WikiPluginCached types)
// SWF not yet.
//
// Revision 1.8  2004/09/22 15:23:56  rurban
// support <!plugin-list !> pagelist data
// add -prefab arg support
//
// Revision 1.7  2004/09/22 13:46:26  rurban
// centralize upload paths.
// major WikiPluginCached feature enhancement:
//   support _STATIC pages in uploads/ instead of dynamic getimg.php? subrequests.
//   mainly for debugging, cache problems and action=pdf
//
// Revision 1.6  2004/09/07 13:26:31  rurban
// new WikiPluginCached option debug=static and some more sf.net defaults for VisualWiki
//
// Revision 1.5  2004/06/28 16:35:12  rurban
// prevent from shell commands
//
// Revision 1.4  2004/06/19 10:06:38  rurban
// Moved lib/plugincache-config.php to config/*.ini
// use PLUGIN_CACHED_* constants instead of global $CacheParams
//
// Revision 1.3  2004/06/03 09:40:57  rurban
// WikiPluginCache improvements
//
// Revision 1.2  2004/06/02 19:37:07  rurban
// extended description
//
// Revision 1.1  2004/06/02 19:12:42  rurban
// new Ploticus plugin
//
//

// For emacs users
// Local Variables:
// mode: php
// tab-width: 8
// c-basic-offset: 4
// c-hanging-comment-ender-p: nil
// indent-tabs-mode: nil
// End:
?>