da6f8763 |
1 | <?php |
2 | /** |
3 | * formslib.php - library of classes for creating forms in Moodle, based on PEAR QuickForms. |
4 | * THIS IS NOT YET PART OF THE MOODLE API, IT IS HERE FOR TESTING ONLY |
5 | * @author Jamie Pratt |
6 | * @version $Id$ |
7 | * @license http://www.gnu.org/copyleft/gpl.html GNU Public License |
8 | */ |
9 | |
10 | //point pear include path to moodles lib/pear so that includes and requires will search there for files before anywhere else. |
11 | if (FALSE===strstr(ini_get('include_path'), $CFG->libdir.'/pear' )){ |
12 | ini_set('include_path', $CFG->libdir.'/pear' . PATH_SEPARATOR . ini_get('include_path')); |
13 | } |
14 | require_once 'HTML/QuickForm.php'; |
15 | require_once 'HTML/QuickForm/DHTMLRulesTableless.php'; |
16 | require_once 'HTML/QuickForm/Renderer/Tableless.php'; |
17 | |
864cc1de |
18 | if ($CFG->debug >= DEBUG_ALL){ |
19 | PEAR::setErrorHandling(PEAR_ERROR_PRINT); |
20 | } |
21 | |
da6f8763 |
22 | class moodleform extends HTML_QuickForm_DHTMLRulesTableless{ |
23 | /** |
24 | * Class constructor - same parameters as HTML_QuickForm_DHTMLRulesTableless |
25 | * @param string $formName Form's name. |
26 | * @param string $method (optional)Form's method defaults to 'POST' |
27 | * @param string $action (optional)Form's action |
28 | * @param string $target (optional)Form's target defaults to none |
29 | * @param mixed $attributes (optional)Extra attributes for <form> tag |
30 | * @param bool $trackSubmit (optional)Whether to track if the form was submitted by adding a special hidden field |
31 | * @access public |
32 | */ |
33 | function moodleform($formName='', $method='post', $action='', $target='', $attributes=null){ |
34 | global $CFG; |
35 | //we need to override the constructor, we don't call the parent constructor |
36 | //at all because it strips slashes depending on the magic quotes setting |
37 | //whereas Moodle already has added slashes whether magic quotes is on or not. |
38 | |
39 | //also added check for sesskey and added sesskey to all forms |
40 | //and told class to ask Moodle for the max upload file size |
41 | HTML_Common::HTML_Common($attributes); |
42 | $method = (strtoupper($method) == 'GET') ? 'get' : 'post'; |
43 | $action = ($action == '') ? $_SERVER['PHP_SELF'] : $action; |
44 | $target = empty($target) ? array() : array('target' => $target); |
45 | //no 'name' atttribute for form in xhtml strict : |
46 | $attributes = array('action'=>$action, 'method'=>$method, 'id'=>$formName) + $target; |
47 | $this->updateAttributes($attributes); |
48 | //check for sesskey for this form |
49 | //if it is not present then we don't accept any input |
50 | if (isset($_REQUEST['_qf__' . $formName])) { |
51 | $this->_submitValues = $this->_recursiveFilter('stripslashes', 'get' == $method? $_GET: $_POST); |
52 | foreach ($_FILES as $keyFirst => $valFirst) { |
53 | foreach ($valFirst as $keySecond => $valSecond) { |
54 | if ('name' == $keySecond) { |
55 | $this->_submitFiles[$keyFirst][$keySecond] = $this->_recursiveFilter('stripslashes', $valSecond); |
56 | } else { |
57 | $this->_submitFiles[$keyFirst][$keySecond] = $valSecond; |
58 | } |
59 | } |
60 | } |
61 | |
62 | $this->_flagSubmitted = count($this->_submitValues) > 0 || count($this->_submitFiles) > 0; |
63 | } |
64 | |
65 | //check sesskey |
66 | if ($this->_flagSubmitted){ |
67 | confirm_sesskey($this->_submitValues['_qf__' . $formName]); |
68 | } |
69 | unset($this->_submitValues['_qf__' . $formName]); |
70 | //add sesskey to all forms |
71 | $this->addElement('hidden', '_qf__' . $formName, sesskey()); |
72 | |
73 | if (preg_match('/^([0-9]+)([a-zA-Z]*)$/', get_max_upload_file_size(), $matches)) { |
74 | // see http://www.php.net/manual/en/faq.using.php#faq.using.shorthandbytes |
75 | switch (strtoupper($matches['2'])) { |
76 | case 'G': |
77 | $this->_maxFileSize = $matches['1'] * 1073741824; |
78 | break; |
79 | case 'M': |
80 | $this->_maxFileSize = $matches['1'] * 1048576; |
81 | break; |
82 | case 'K': |
83 | $this->_maxFileSize = $matches['1'] * 1024; |
84 | break; |
85 | default: |
86 | $this->_maxFileSize = $matches['1']; |
87 | } |
88 | } |
89 | //this is custom stuff for Moodle : |
90 | $oldclass= $this->getAttribute('class'); |
91 | if (!empty($oldclass)){ |
92 | $this->updateAttributes(array('class'=>$oldclass.' mform')); |
93 | }else { |
80f962df |
94 | $this->updateAttributes(array('class'=>'mform')); |
da6f8763 |
95 | } |
96 | $this->_helpImageURL="$CFG->wwwroot/lib/form/req.gif"; |
97 | $this->_reqHTML = |
98 | helpbutton('requiredelement', get_string('requiredelement', 'form'),'moodle', |
99 | true, false, '', true, '<img alt="'.get_string('requiredelement', 'form').'" src="'. |
100 | $this->_helpImageURL.'" />'); |
101 | $this->setRequiredNote(get_string('denotesreq', 'form', $this->getReqHTML())); |
102 | } |
103 | function getReqHTML(){ |
104 | return $this->_reqHTML; |
105 | } |
106 | /** |
107 | * Class constructor - same parameters as HTML_QuickForm_DHTMLRulesTableless |
108 | * @param array $buttons An associative array representing help button to attach to |
109 | * to the form. keys of array correspond to names of elements in form. |
110 | * |
111 | * @access public |
112 | */ |
42f248e6 |
113 | function setHelpButtons($buttons, $suppresscheck=false){ |
da6f8763 |
114 | |
115 | foreach ($this->_elements as $no => $element){ |
116 | if (array_key_exists($element->getName(), $buttons)){ |
117 | |
80f962df |
118 | if (method_exists($element, 'setHelpButton')){ |
119 | $this->_elements[$no]->setHelpButton($buttons[$element->getName()]); |
120 | }else{ |
121 | $a=new object(); |
122 | $a->name=$element->getName(); |
123 | $a->classname=get_class($element); |
124 | print_error('nomethodforaddinghelpbutton', 'form', '', $a); |
125 | } |
da6f8763 |
126 | unset($buttons[$element->getName()]); |
127 | } |
128 | |
129 | } |
130 | if (count($buttons)&& !$suppresscheck){ |
131 | print_error('nonexistentformelements', 'form', '', join(', ', array_keys($buttons))); |
132 | } |
133 | } |
42f248e6 |
134 | function acceptGet(){ |
135 | $names=func_get_args(); |
136 | foreach ($names as $name){ |
137 | //if no form data is submitted then the page has just beeen loaded |
138 | //so we get the page param value from $_GET |
139 | if (!$this->_flagSubmitted && isset($_GET[$name])){ |
140 | $this->_submitValues[$name]=$_GET[$name]; |
141 | } |
da6f8763 |
142 | } |
da6f8763 |
143 | } |
42f248e6 |
144 | function required_param($element, $paramtype){ |
145 | $value = $this->getSubmitValue($element); |
146 | if (null !== $value) { |
147 | if (false === strpos($element, '[')) { |
148 | return $this->_submitValues[$element] = $this->_clean_param($value, $paramtype); |
149 | } else { |
150 | $idx = "['" . str_replace(array(']', '['), array('', "']['"), $element) . "']"; |
151 | eval("return \$this->_submitValues{$idx} = \$this->_clean_param(\$value, \$paramtype);"); |
152 | } |
153 | }else{ |
154 | //could print name of param but better not to for security? |
155 | print_error('missingrequiredfield', 'error'); |
156 | } |
157 | } |
158 | function optional_param($element, $default, $paramtype){ |
159 | $value = $this->getSubmitValue($element); |
160 | if (null === $value) { |
161 | return $default; |
162 | } |
163 | if (false === strpos($element, '[')) { |
164 | return $this->_submitValues[$element] = $this->_clean_param($value, $paramtype); |
165 | } else { |
166 | $idx = "['" . str_replace(array(']', '['), array('', "']['"), $element) . "']"; |
167 | eval("return \$this->_submitValues{$idx} = \$this->_clean_param(\$value, \$paramtype);"); |
168 | } |
169 | } |
170 | function clean_param($elementList, $paramtype){ |
171 | $value = $this->getSubmitValue($element); |
172 | if (false === strpos($element, '[')) { |
173 | return $this->_submitValues[$element] = $this->_clean_param($value, $paramtype); |
174 | } else { |
175 | $idx = "['" . str_replace(array(']', '['), array('', "']['"), $element) . "']"; |
176 | eval("return \$this->_submitValues{$idx} = \$this->_clean_param(\$value, \$paramtype);"); |
177 | } |
178 | } |
179 | function _clean_param($value, $paramtype){ |
180 | //clean_param function in moodlelib expects vars with slashes |
181 | $value=$this->_recursiveFilter('addslashes', $value); |
182 | $value=clean_param($value, $paramtype); |
183 | return $this->_recursiveFilter('stripslashes', $value); |
184 | } |
185 | |
da6f8763 |
186 | function exportValue($element, $addslashes=true){ |
187 | $unfiltered=parent::exportValue($element); |
188 | if ($addslashes){ |
42f248e6 |
189 | return $this->_recursiveFilter('addslashes',$unfiltered); |
da6f8763 |
190 | } else { |
191 | return $unfiltered; |
192 | } |
193 | } |
42f248e6 |
194 | function exportValues($elementList= null, $addslashes=true){ |
da6f8763 |
195 | $unfiltered=parent::exportValues($elementList); |
196 | if ($addslashes){ |
42f248e6 |
197 | return $this->_recursiveFilter('addslashes',$unfiltered); |
da6f8763 |
198 | } else { |
199 | return $unfiltered; |
200 | } |
201 | } |
230a910a |
202 | /** |
203 | * Initializes a default form value |
204 | * |
205 | * @param string $elementname element name |
206 | * @param mixed $values values for that element name |
207 | * @param mixed $filter (optional) filter(s) to apply to default value |
208 | * @access public |
209 | * @return void |
210 | */ |
211 | function setDefault($elementName='', $defaultValue = null, $filter = null){ |
212 | $this->setDefaults(array($elementName =>$defaultValue), $filter); |
213 | } // end func setDefault |
214 | /** |
215 | * Returns 'safe' elements' values |
216 | * |
217 | * Unlike getSubmitValues(), this will return only the values |
218 | * corresponding to the elements present in the form. |
219 | * This function also runs validate() and returns false if the form doesn't validate |
220 | * |
221 | * @param mixed Array/string of element names, whose values we want. If not set then return all elements. |
222 | * @access public |
223 | * @return object An object with property values set to elements' values |
224 | * @throws HTML_QuickForm_Error |
225 | */ |
226 | function data_submitted($elementList = null, $addslashes=true){ |
227 | if (!$this->validate()){ |
228 | return false; |
229 | }else{ |
230 | return (object)$this->exportValues($elementList, $addslashes); |
231 | } |
232 | } |
da6f8763 |
233 | } |
234 | |
235 | /** |
236 | * A renderer for moodleform that only uses XHTML and CSS and no |
237 | * table tags, extends PEAR class HTML_QuickForm_Renderer_Tableless |
238 | * |
239 | * Stylesheet is part of standard theme and should be automatically included. |
240 | * |
241 | * @author Jamie Pratt <me@jamiep.org> |
242 | * @license gpl license |
243 | */ |
244 | class moodleform_renderer extends HTML_QuickForm_Renderer_Tableless{ |
245 | |
246 | /** |
247 | * Element template array |
248 | * @var array |
249 | * @access private |
250 | */ |
251 | var $_elementTemplates; |
42f248e6 |
252 | |
49c53687 |
253 | // uncomment templates below and edit formslib.php for |
42f248e6 |
254 | // ol li containers for form items. |
255 | |
49c53687 |
256 | /** |
257 | * Template used when opening a hidden fieldset |
258 | * (i.e. a fieldset that is opened when there is no header element) |
259 | * @var string |
260 | * @access private |
261 | */ |
262 | var $_openHiddenFieldsetTemplate = "\n\t<fieldset class=\"hidden\">"; |
42f248e6 |
263 | // var $_openHiddenFieldsetTemplate = "\n\t<fieldset class=\"hidden\">\n\t\t<ol>"; |
264 | // /** |
265 | // * Header Template string |
266 | // * @var string |
267 | // * @access private |
268 | // */ |
269 | // var $_headerTemplate = |
270 | // "\n\t\t<legend>{header}</legend>\n\t\t<ol>"; |
49c53687 |
271 | // var $_headerTemplate = |
272 | // "\n\t\t<legend>{header}</legend>\n\t\t<ol>"; |
273 | /** |
274 | * Template used when closing a fieldset |
275 | * @var string |
276 | * @access private |
277 | */ |
278 | var $_closeFieldsetTemplate = "\n\t\t</fieldset>"; |
42f248e6 |
279 | // var $_closeFieldsetTemplate = "\n\t\t</ol>\n\t</fieldset>"; |
280 | |
49c53687 |
281 | /** |
282 | * Required Note template string |
283 | * @var string |
284 | * @access private |
285 | */ |
286 | var $_requiredNoteTemplate = |
287 | "\n\t\t<div class=\"fdescription\">{requiredNote}</div>"; |
da6f8763 |
288 | function moodleform_renderer(){ |
42f248e6 |
289 | // switch next two lines for ol li containers for form items. |
49c53687 |
290 | // $this->_elementTemplates=array('default'=>"\n\t\t<li class=\"fitem\"><label>{label}{help}<!-- BEGIN required -->{req}<!-- END required --></label><div class=\"qfelement<!-- BEGIN error --> error<!-- END error --> {type}\"><!-- BEGIN error --><span class=\"error\">{error}</span><br /><!-- END error -->{element}</div></li>"); |
15fdf619 |
291 | $this->_elementTemplates=array('default'=>"\n\t\t<div class=\"fitem\"><label>{label}{help}<!-- BEGIN required -->{req}<!-- END required --></label><div class=\"felement<!-- BEGIN error --> error<!-- END error --> {type}\"><!-- BEGIN error --><span class=\"error\">{error}</span><br /><!-- END error -->{element}</div></div>", |
292 | 'fieldset'=>"\n\t\t<div class=\"fitem\"><label>{label}{help}<!-- BEGIN required -->{req}<!-- END required --></label><fieldset class=\"felement<!-- BEGIN error --> error<!-- END error --> {type}\"><!-- BEGIN error --><span class=\"error\">{error}</span><br /><!-- END error -->{element}</fieldset></div>"); |
da6f8763 |
293 | |
294 | parent::HTML_QuickForm_Renderer_Tableless(); |
295 | } |
296 | function startForm(&$form){ |
297 | $this->_reqHTML=$form->getReqHTML(); |
298 | $this->_elementTemplates=str_replace('{req}', $this->_reqHTML, $this->_elementTemplates); |
299 | parent::startForm($form); |
300 | } |
301 | function startGroup(&$group, $required, $error){ |
302 | if (method_exists($group, 'getElementTemplateType')){ |
e249661f |
303 | $html = $this->_elementTemplates[$group->getElementTemplateType()]; |
da6f8763 |
304 | }else{ |
305 | $html = $this->_elementTemplates['default']; |
306 | |
307 | } |
308 | if (method_exists($group, 'getHelpButton')){ |
309 | $html =str_replace('{help}', $group->getHelpButton(), $html); |
310 | }else{ |
311 | $html =str_replace('{help}', '', $html); |
312 | |
313 | } |
49c53687 |
314 | $html =str_replace('{type}', 'fgroup', $html); |
80f962df |
315 | |
da6f8763 |
316 | $this->_templates[$group->getName()]=$html; |
317 | // Fix for bug in tableless quickforms that didn't allow you to stop a |
318 | // fieldset before a group of elements. |
319 | // if the element name indicates the end of a fieldset, close the fieldset |
320 | if ( in_array($group->getName(), $this->_stopFieldsetElements) |
321 | && $this->_fieldsetsOpen > 0 |
322 | ) { |
323 | $this->_html .= $this->_closeFieldsetTemplate; |
324 | $this->_fieldsetsOpen--; |
325 | } |
326 | parent::startGroup($group, $required, $error); |
327 | } |
328 | function renderElement(&$element, $required, $error){ |
329 | if (method_exists($element, 'getElementTemplateType')){ |
330 | $html = $this->_elementTemplates[$element->getElementTemplateType()]; |
331 | }else{ |
332 | $html = $this->_elementTemplates['default']; |
333 | |
334 | } |
49c53687 |
335 | $html =str_replace('{type}', 'f'.$element->getType(), $html); |
da6f8763 |
336 | if (method_exists($element, 'getHelpButton')){ |
337 | $html=str_replace('{help}', $element->getHelpButton(), $html); |
338 | }else{ |
339 | $html=str_replace('{help}', '', $html); |
340 | |
341 | } |
342 | $this->_templates[$element->getName()]=$html; |
230a910a |
343 | if (!is_null($element->getAttribute('id'))) { |
344 | $id = $element->getAttribute('id'); |
345 | } else { |
346 | $id = $element->getName(); |
347 | } |
348 | $element->updateAttributes(array('id'=>'id_'.$id)); |
da6f8763 |
349 | parent::renderElement($element, $required, $error); |
350 | } |
351 | |
352 | |
353 | } |
354 | |
42f248e6 |
355 | /*class moodleform_filter{ |
da6f8763 |
356 | var $paramtype; |
357 | var $default; |
42f248e6 |
358 | function moodleform_filter($paramtype, $default=NULL){ |
da6f8763 |
359 | $this->paramtype=$paramtype; |
360 | $this->default=$default; |
361 | } |
362 | function required_param($value){ |
363 | if (isset($value)) { |
364 | $param = $value; |
365 | } else { |
366 | error('A required parameter was missing'); |
367 | } |
368 | |
369 | return $this->clean_param($param); |
370 | } |
371 | function optional_param($value){ |
372 | if (!isset($value)) { |
373 | return $this->default; |
374 | } |
375 | return $this->clean_param($value); |
376 | } |
42f248e6 |
377 | |
378 | } */ |
da6f8763 |
379 | |
380 | $GLOBALS['_HTML_QuickForm_default_renderer']=& new moodleform_renderer(); |
381 | |
382 | moodleform::registerElementType('checkbox', "$CFG->libdir/form/checkbox.php", 'moodleform_checkbox'); |
383 | moodleform::registerElementType('file', "$CFG->libdir/form/file.php", 'moodleform_file'); |
384 | moodleform::registerElementType('group', "$CFG->libdir/form/group.php", 'moodleform_group'); |
385 | moodleform::registerElementType('password', "$CFG->libdir/form/password.php", 'moodleform_password'); |
386 | moodleform::registerElementType('radio', "$CFG->libdir/form/radio.php", 'moodleform_radio'); |
387 | moodleform::registerElementType('select', "$CFG->libdir/form/select.php", 'moodleform_select'); |
388 | moodleform::registerElementType('text', "$CFG->libdir/form/text.php", 'moodleform_text'); |
389 | moodleform::registerElementType('textarea', "$CFG->libdir/form/textarea.php", 'moodleform_textarea'); |
390 | moodleform::registerElementType('date_selector', "$CFG->libdir/form/dateselector.php", 'moodleform_date_selector'); |
e9d39a32 |
391 | moodleform::registerElementType('date_time_selector', "$CFG->libdir/form/datetimeselector.php", 'moodleform_date_time_selector'); |
da6f8763 |
392 | moodleform::registerElementType('htmleditor', "$CFG->libdir/form/htmleditor.php", 'moodleform_htmleditor'); |
f8857b49 |
393 | moodleform::registerElementType('static', "$CFG->libdir/form/static.php", 'moodleform_static'); |
42f248e6 |
394 | moodleform::registerElementType('hidden', "$CFG->libdir/form/hidden.php", 'moodleform_hidden'); |
da6f8763 |
395 | |
864cc1de |
396 | |
da6f8763 |
397 | ?> |