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