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