]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/plugin/WikiFormRich.php
docs
[SourceForge/phpwiki.git] / lib / plugin / WikiFormRich.php
1 <?php // -*-php-*-
2 rcs_id('$Id: WikiFormRich.php,v 1.12 2004-11-24 15:21:19 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  * This is another replacement for MagicPhpWikiURL forms.
25  * Previously encoded with the "phpwiki:" syntax.
26  *
27  * Enhanced WikiForm to be more generic:
28  * - editbox[]          name=.. value=.. text=..
29  * - checkbox[]         name=.. value=0|1 checked text=..
30  * - radiobutton[]      name=.. value=.. text=..
31  * - pulldown[]         name=.. values=.. selected=.. text=..
32  * - hidden[]           name=.. value=..
33  * - action, submit buttontext, optional cancel button (bool)
34  * - method=GET or POST, Default: POST.
35  
36  * values which are constants are evaluated.
37  * The cancel button must be supported by the action. (which?)
38  * improve layout: nobr=1, class=wikiadmin
39  * added pulldown, values from <!plugin-list !>
40
41  Samples:
42    <?plugin WikiFormRich action=dumpserial method=GET 
43             checkbox[] name=include value="all" 
44             editbox[] name=directory value=DEFAULT_DUMP_DIR
45             editbox[] name=pages value=*
46             editbox[] name=exclude value="" ?>
47    <?plugin WikiFormRich action=dumphtml method=GET 
48             editbox[] name=directory value=HTML_DUMP_DIR
49             editbox[] name=pages value="*"
50             editbox[] name=exclude value="" ?>
51    <?plugin WikiFormRich action=loadfile method=GET 
52             editbox[]  name=source value=DEFAULT_WIKI_PGSRC
53             checkbox[] name=overwrite value=1
54             editbox[]  name=exclude value="" ?>
55   <?plugin WikiFormRich action=TitleSearch method=GET class=wikiadmin nobr=1
56            editbox[] name=s text=""
57            checkbox[] name=case_exact
58           checkbox[] name=regex ?>
59   <?plugin WikiFormRich action=FullTextSearch method=GET class=wikiadmin nobr=1
60            editbox[] name=s text=""
61            checkbox[] name=case_exact
62            checkbox[] name=regex ?>
63   <?plugin WikiFormRich action=FuzzyPages method=GET class=wikiadmin nobr=1
64            editbox[] name=s text=""
65            checkbox[] name=case_exact ?>
66   <?plugin WikiFormRich action=AppendText buttontext="AddPlugin"
67            pulldown[] name=text text="Plugins: " value=<!plugin-list BackLinks page=WikiPlugin !>
68            ?>
69   <?plugin WikiFormRich action=AppendText buttontext="AddCategory"
70            pulldown[] name=text text="Categories: " value=<!plugin-list TitleSearch s=Category !>
71            ?>
72 */
73
74 class WikiPlugin_WikiFormRich
75 extends WikiPlugin
76 {
77     function getName () {
78         return "WikiFormRich";
79     }
80     function getDescription () {
81         return _("Provide generic WikiForm input buttons");
82     }
83     function getVersion() {
84         return preg_replace("/[Revision: $]/", '',
85                             "\$Revision: 1.12 $");
86     }
87     function getDefaultArguments() {
88         return array('action' => false,     // required argument
89                      'method' => 'POST',    // or GET
90                      'class'  => false,
91                      'buttontext' => false, // for the submit button. default: action
92                      'cancel' => false,     // boolean if the action supports cancel also
93                      'nobr' => false,       // "no break": linebreaks or not
94                      );
95     }
96
97     function handle_plugin_args_cruft($argstr, $args) {
98         $allowed = array("editbox", "hidden", "checkbox", "radiobutton", "pulldown");
99         // no editbox[] = array(...) allowed (space)
100         $arg_array = preg_split("/\n/", $argstr);
101         // for security we should check this better
102         $arg = '';
103         for ($i = 0; $i < count($arg_array); $i++) {
104             if (preg_match("/^\s*(".join("|",$allowed).")\[\]\s+(.+)\s*$/", $arg_array[$i], $m)) {
105                 $name = $m[1]; // one of the allowed input types
106                 $this->inputbox[][$name] = array(); $j = count($this->inputbox) - 1;
107                 $curargs = $m[2];
108                 // must match name=NAME and also value=<!plugin-list name !>
109                 while (preg_match("/^(\w+)=((?:\".*\")|(?:\w+)|(?:\"?<!plugin-list.+!>\"?))\s*/", $curargs, $m)) {
110                     $attr = $m[1]; $value = $m[2];
111                     $curargs = substr($curargs, strlen($m[0]));
112                     if (preg_match("/^\"(.*)\"$/", $value, $m))
113                         $value = $m[1];
114                     if (in_array($name, array("pulldown","checkbox","radiobutton"))
115                             and preg_match('/^<!plugin-list.+!>$/', $value, $m))
116                     // like pulldown[] name=test value=<!plugin-list BackLinks page=HomePage!>
117                     {
118                         $loader = new WikiPluginLoader();
119                         $markup = null;
120                         $basepage = null;
121                         $plugin_str = preg_replace(array("/^<!/","/!>$/"),array("<?","?>"), $value);
122                         // will return a pagelist object! pulldown,checkbox,radiobutton
123                         $value = $loader->expandPI($plugin_str, $GLOBALS['request'], $markup, $basepage);
124                         if (isa($value, 'PageList')) 
125                             $value = $value->_pages;
126                         elseif (!is_array($value))
127                             trigger_error(sprintf("Invalid argument %s ignored", htmlentities($arg_array[$i])), 
128                                           E_USER_WARNING);
129                     }
130                     elseif (defined($value))
131                         $value = constant($value);
132                     $this->inputbox[$j][$name][$attr] = $value;
133                 }
134                 //trigger_error("not yet finished");
135                 //eval('$this->inputbox[]["'.$m[1].'"]='.$m[2].';');
136             } else {
137                 trigger_error(sprintf("Invalid argument %s ignored",htmlentities($arg_array[$i])), 
138                               E_USER_WARNING);
139             }
140         }
141         return;
142     }
143
144     function run($dbi, $argstr, &$request, $basepage) {
145         extract($this->getArgs($argstr, $request));
146         if (empty($action)) {
147             return $this->error(fmt("A required argument '%s' is missing.", "action"));
148         }
149         $form = HTML::form(array('action' => $request->getPostURL(),
150                                  'method' => $method,
151                                  'class'  => 'wikiadmin',
152                                  'accept-charset' => $GLOBALS['charset']),
153                            HiddenInputs(array('action' => $action)));
154         if ($nobr) $nbsp = HTML::Raw('&nbsp;');
155         foreach ($this->inputbox as $inputbox) {
156             foreach ($inputbox as $inputtype => $input) {
157               switch($inputtype) {
158               case 'checkbox':
159                 $input['type'] = 'checkbox';
160                 if (empty($input['name']))
161                     return $this->error(fmt("A required argument '%s' is missing.",
162                                             "checkbox[][name]"));
163                 if (!isset($input['text'])) 
164                     $input['text'] = gettext($input['name']); //."=".$input['value'];
165                 $text = $input['text'];
166                 unset($input['text']);
167                 if (empty($input['checked'])) {
168                     if ($request->getArg($input['name']))
169                         $input['checked'] = 'checked';
170                 } else {
171                     $input['checked'] = 'checked';
172                 }
173                 if (empty($input['value'])) $input['value'] = 1;
174                 if (is_array($input['value'])) {
175                     $div = HTML::div(array('class' => $class));
176                     $values = $input['value'];
177                     $name = $input['name'];
178                     $input['name'] .= "[]";
179                     foreach ($values as $val) {
180                         // TODO: get checked status from a possible select column?
181                         $input['value'] = $val;
182                         if ($request->getArg($name)) {
183                             if ($request->getArg($name) == $val)
184                                 $input['checked'] = 'checked';
185                             else 
186                                 unset($input['checked']);
187                         }
188                         $text .= (" " . $val);
189                         $div->pushContent(HTML::input($input), $nbsp, $text, $nbsp);
190                         if (!$nobr)
191                             $div->pushContent(HTML::br());
192                     }
193                     $form->pushContent($div);
194                 } else {
195                     if ($nobr)
196                         $form->pushContent(HTML::input($input), $nbsp, $text, $nbsp);
197                     else
198                         $form->pushContent(HTML::div(array('class' => $class), HTML::input($input), $text));
199                 }
200                 break;
201               case 'radiobutton':
202                 $input['type'] = 'radio';
203                 if (empty($input['name']))
204                     return $this->error(fmt("A required argument '%s' is missing.",
205                                             "radiobutton[][name]"));
206                 if (!isset($input['text'])) $input['text'] = gettext($input['name']);
207                 $text = $input['text'];
208                 unset($input['text']);
209                 if ($input['checked']) $input['checked'] = 'checked';
210                 if (is_array($input['value'])) {
211                     $div = HTML::div(array('class' => $class));
212                     $values = $input['value'];
213                     $name = $input['name'];
214                     $input['name'] .= "[]";
215                     foreach ($values as $val) {
216                         // TODO: get checked status from a possible select column?
217                         $input['value'] = $val;
218                         if ($request->getArg($name)) {
219                             if ($request->getArg($name) == $val)
220                                 $input['checked'] = 'checked';
221                             else 
222                                 unset($input['checked']);
223                         }
224                         $text .= (" " . $val);
225                         $div->pushContent(HTML::input($input), $nbsp, $text, $nbsp);
226                         if (!$nobr)
227                             $div->pushContent(HTML::br());
228                     }
229                     $form->pushContent($div);
230                 } else {
231                     if ($nobr)
232                         $form->pushContent(HTML::input($input), $nbsp, $text, $nbsp);
233                     else
234                         $form->pushContent(HTML::div(array('class' => $class), HTML::input($input), $text));
235                 }
236                 break;
237               case 'editbox':
238                 $input['type'] = 'text';
239                 if (empty($input['name']))
240                     return $this->error(fmt("A required argument '%s' is missing.",
241                                             "editbox[][name]"));
242                 if (!isset($input['text'])) $input['text'] = gettext($input['name']);
243                 $text = $input['text'];
244                 if (empty($input['value']) and ($s = $request->getArg($input['name'])))
245                     $input['value'] = $s;
246                 unset($input['text']);
247                 if ($nobr)
248                     $form->pushContent(HTML::input($input), $nbsp, $text, $nbsp);
249                 else
250                     $form->pushContent(HTML::div(array('class' => $class), HTML::input($input), $text));
251                 break;
252               case 'pulldown':
253                 if (empty($input['name']))
254                     return $this->error(fmt("A required argument '%s' is missing.",
255                                             "pulldown[][name]"));
256                 if (!isset($input['text'])) $input['text'] = gettext($input['name']);
257                 $text = $input['text'];
258                 unset($input['text']);
259                 $values = $input['value'];
260                 unset($input['value']);
261                 $select = HTML::select($input);
262                 if (empty($values) and ($s = $request->getArg($input['name']))) {
263                     $select->pushContent(HTML::option(array('value'=> $s), $s));
264                 } elseif (is_array($values)) {
265                     $name = $input['name'];
266                     unset($input['name']);
267                     foreach ($values as $val) {
268                         $input = array('value'=> $val);
269                         if ($request->getArg($name)) {
270                             if ($request->getArg($name) == $val)
271                                 $input['selected'] = 'selected';
272                             else
273                                 unset($input['selected']);
274                         }
275                         $select->pushContent(HTML::option($input, $val));
276                     }
277                 }
278                 $form->pushContent($text, $select);
279                 break;
280               case 'hidden':
281                 $input['type'] = 'hidden';
282                 if (empty($input['name']))
283                     return $this->error(fmt("A required argument '%s' is missing.",
284                                             "hidden[][name]"));
285                 unset($input['text']);
286                 $form->pushContent(HTML::input($input));
287               }
288             }
289         }
290         if ($request->getArg('start_debug'))
291             $form->pushContent(HTML::input(array('name' => 'start_debug',
292                                                  'value' =>  $request->getArg('start_debug'),
293                                                  'type'  => 'hidden')));
294         if (!USE_PATH_INFO)
295             $form->pushContent(HiddenInputs(array('pagename' => $basepage)));
296         if (empty($buttontext)) $buttontext = $action;
297         $submit = Button('submit:', $buttontext, $class);
298         if ($cancel) {
299             $form->pushContent(HTML::span(array('class' => $class),
300                                           $submit, Button('submit:cancel', _("Cancel"), $class)));
301         } else {
302             $form->pushContent(HTML::span(array('class' => $class),
303                                           $submit));
304         }
305         return $form;
306     }
307 };
308
309 // $Log: not supported by cvs2svn $
310 // Revision 1.11  2004/11/24 15:19:57  rurban
311 // allow whitespace in quoted text args
312 //
313 // Revision 1.10  2004/11/24 15:07:49  rurban
314 // added pulldown support, fixed plugin-list whitespace splitting
315 //
316 // Revision 1.9  2004/11/24 13:55:42  rurban
317 // omit unneccessary pagename arg
318 //
319 // Revision 1.8  2004/11/24 10:58:50  rurban
320 // just docs
321 //
322 // Revision 1.7  2004/11/24 10:40:04  rurban
323 // better nobr, allow empty text=""
324 //
325 // Revision 1.5  2004/11/24 10:14:36  rurban
326 // fill-in request args as with plugin-form
327 //
328 // Revision 1.4  2004/11/23 15:17:20  rurban
329 // better support for case_exact search (not caseexact for consistency),
330 // plugin args simplification:
331 //   handle and explode exclude and pages argument in WikiPlugin::getArgs
332 //     and exclude in advance (at the sql level if possible)
333 //   handle sortby and limit from request override in WikiPlugin::getArgs
334 // ListSubpages: renamed pages to maxpages
335 //
336 // Revision 1.3  2004/07/09 13:05:34  rurban
337 // just aesthetics
338 //
339 // Revision 1.2  2004/07/09 10:25:52  rurban
340 // fix the args parser
341 //
342 // Revision 1.1  2004/07/02 11:03:53  rurban
343 // renamed WikiFormMore to WikiFormRich: better syntax, no eval (safer)
344 //
345 // Revision 1.3  2004/07/01 13:59:25  rurban
346 // enhanced to allow arbitrary order of args and stricter eval checking
347 //
348 // Revision 1.2  2004/07/01 13:14:01  rurban
349 // desc only
350 //
351 // Revision 1.1  2004/07/01 13:11:53  rurban
352 // more generic forms
353 //
354
355 // For emacs users
356 // Local Variables:
357 // mode: php
358 // tab-width: 8
359 // c-basic-offset: 4
360 // c-hanging-comment-ender-p: nil
361 // indent-tabs-mode: nil
362 // End:
363 ?>