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