2ae22002 |
1 | <?php // $Id$ |
da6f8763 |
2 | /** |
3 | * formslib.php - library of classes for creating forms in Moodle, based on PEAR QuickForms. |
da1320da |
4 | * |
5 | * To use formslib then you will want to create a new file purpose_form.php eg. edit_form.php |
6 | * and you want to name your class something like {modulename}_{purpose}_form. Your class will |
7 | * extend moodleform overriding abstract classes definition and optionally defintion_after_data |
8 | * and validation. |
9 | * |
10 | * See examples of use of this library in course/edit.php and course/edit_form.php |
11 | * |
12 | * A few notes : |
13 | * form defintion is used for both printing of form and processing and should be the same |
14 | * for both or you may lose some submitted data which won't be let through. |
15 | * you should be using setType for every form element except select, radio or checkbox |
16 | * elements, these elements clean themselves. |
17 | * |
18 | * |
da6f8763 |
19 | * @author Jamie Pratt |
da6f8763 |
20 | * @license http://www.gnu.org/copyleft/gpl.html GNU Public License |
21 | */ |
22 | |
7fc1a27d |
23 | //setup.php icludes our hacked pear libs first |
da6f8763 |
24 | require_once 'HTML/QuickForm.php'; |
25 | require_once 'HTML/QuickForm/DHTMLRulesTableless.php'; |
26 | require_once 'HTML/QuickForm/Renderer/Tableless.php'; |
27 | |
a83ad946 |
28 | require_once $CFG->libdir.'/filelib.php'; |
f6ac3e0a |
29 | require_once $CFG->libdir.'/uploadlib.php'; // TODO: remove |
49292f8c |
30 | |
832e13f1 |
31 | define('EDITOR_UNLIMITED_FILES', -1); |
32 | |
a23f0aaf |
33 | /** |
34 | * Callback called when PEAR throws an error |
35 | * |
36 | * @param PEAR_Error $error |
37 | */ |
38 | function pear_handle_error($error){ |
39 | echo '<strong>'.$error->GetMessage().'</strong> '.$error->getUserInfo(); |
40 | echo '<br /> <strong>Backtrace </strong>:'; |
41 | print_object($error->backtrace); |
42 | } |
43 | |
864cc1de |
44 | if ($CFG->debug >= DEBUG_ALL){ |
a23f0aaf |
45 | PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, 'pear_handle_error'); |
864cc1de |
46 | } |
47 | |
8e7cebb0 |
48 | function form_init_date_js() { |
49 | global $CFG; |
50 | static $done = false; |
51 | if (!$done) { |
b1ba4d22 |
52 | //TODO: this is NOT xhtml strict, we will need something like require_css() |
8e7cebb0 |
53 | echo '<style type="text/css">'; |
b1ba4d22 |
54 | echo '@import "' . $CFG->httpswwwroot . '/lib/yui/assets/skins/sam/calendar.css";'; |
8e7cebb0 |
55 | echo '</style>'; |
56 | require_js(array('yui_yahoo', 'yui_dom', 'yui_event', 'yui_calendar', 'yui_container')); |
57 | print_delayed_js_call(1, 'init_date_selectors', array(get_string('firstdayofweek'))); |
58 | $done = true; |
59 | } |
60 | } |
f07b9627 |
61 | |
05f5c40c |
62 | /** |
da1320da |
63 | * Moodle specific wrapper that separates quickforms syntax from moodle code. You won't directly |
6073a598 |
64 | * use this class you should write a class definition which extends this class or a more specific |
da1320da |
65 | * subclass such a moodleform_mod for each form you want to display and/or process with formslib. |
66 | * |
67 | * You will write your own definition() method which performs the form set up. |
05f5c40c |
68 | */ |
7f40a229 |
69 | class moodleform { |
172dd12c |
70 | protected $_formname; // form name |
3c7656b4 |
71 | /** |
72 | * quickform object definition |
73 | * |
74 | * @var MoodleQuickForm |
75 | */ |
172dd12c |
76 | protected $_form; |
3c7656b4 |
77 | /** |
78 | * globals workaround |
79 | * |
80 | * @var array |
81 | */ |
172dd12c |
82 | protected $_customdata; |
4f51f48f |
83 | /** |
84 | * definition_after_data executed flag |
85 | * @var definition_finalized |
86 | */ |
172dd12c |
87 | protected $_definition_finalized = false; |
ebd3c7ac |
88 | |
da1320da |
89 | /** |
90 | * The constructor function calls the abstract function definition() and it will then |
91 | * process and clean and attempt to validate incoming data. |
92 | * |
93 | * It will call your custom validate method to validate data and will also check any rules |
94 | * you have specified in definition using addRule |
95 | * |
96 | * The name of the form (id attribute of the form) is automatically generated depending on |
97 | * the name you gave the class extending moodleform. You should call your class something |
98 | * like |
99 | * |
4f51f48f |
100 | * @param mixed $action the action attribute for the form. If empty defaults to auto detect the |
101 | * current url. If a moodle_url object then outputs params as hidden variables. |
da1320da |
102 | * @param array $customdata if your form defintion method needs access to data such as $course |
103 | * $cm, etc. to construct the form definition then pass it in this array. You can |
104 | * use globals for somethings. |
105 | * @param string $method if you set this to anything other than 'post' then _GET and _POST will |
106 | * be merged and used as incoming data to the form. |
107 | * @param string $target target frame for form submission. You will rarely use this. Don't use |
108 | * it if you don't need to as the target attribute is deprecated in xhtml |
109 | * strict. |
110 | * @param mixed $attributes you can pass a string of html attributes here or an array. |
111 | * @return moodleform |
112 | */ |
4f51f48f |
113 | function moodleform($action=null, $customdata=null, $method='post', $target='', $attributes=null, $editable=true) { |
a23f0aaf |
114 | if (empty($action)){ |
115 | $action = strip_querystring(qualified_me()); |
116 | } |
f07b9627 |
117 | |
72f46d11 |
118 | $this->_formname = get_class($this); // '_form' suffix kept in order to prevent collisions of form id and other element |
7f40a229 |
119 | $this->_customdata = $customdata; |
5bc97c98 |
120 | $this->_form =& new MoodleQuickForm($this->_formname, $method, $action, $target, $attributes); |
4f51f48f |
121 | if (!$editable){ |
122 | $this->_form->hardFreeze(); |
123 | } |
7f40a229 |
124 | |
125 | $this->definition(); |
126 | |
127 | $this->_form->addElement('hidden', 'sesskey', null); // automatic sesskey protection |
128 | $this->_form->setDefault('sesskey', sesskey()); |
5bc97c98 |
129 | $this->_form->addElement('hidden', '_qf__'.$this->_formname, null); // form submission marker |
130 | $this->_form->setDefault('_qf__'.$this->_formname, 1); |
131 | $this->_form->_setDefaultRuleMessages(); |
7f40a229 |
132 | |
133 | // we have to know all input types before processing submission ;-) |
134 | $this->_process_submission($method); |
7f40a229 |
135 | } |
05f5c40c |
136 | |
2c412890 |
137 | /** |
da1320da |
138 | * To autofocus on first form element or first element with error. |
2c412890 |
139 | * |
8dec2253 |
140 | * @param string $name if this is set then the focus is forced to a field with this name |
141 | * |
2c412890 |
142 | * @return string javascript to select form element with first error or |
da1320da |
143 | * first element if no errors. Use this as a parameter |
144 | * when calling print_header |
2c412890 |
145 | */ |
46f3921e |
146 | function focus($name=NULL) { |
9403060a |
147 | $form =& $this->_form; |
46f3921e |
148 | $elkeys = array_keys($form->_elementIndex); |
149 | $error = false; |
9403060a |
150 | if (isset($form->_errors) && 0 != count($form->_errors)){ |
151 | $errorkeys = array_keys($form->_errors); |
152 | $elkeys = array_intersect($elkeys, $errorkeys); |
46f3921e |
153 | $error = true; |
2c412890 |
154 | } |
46f3921e |
155 | |
156 | if ($error or empty($name)) { |
157 | $names = array(); |
158 | while (empty($names) and !empty($elkeys)) { |
159 | $el = array_shift($elkeys); |
160 | $names = $form->_getElNamesRecursive($el); |
161 | } |
162 | if (!empty($names)) { |
163 | $name = array_shift($names); |
164 | } |
8dec2253 |
165 | } |
46f3921e |
166 | |
167 | $focus = ''; |
168 | if (!empty($name)) { |
169 | $focus = 'forms[\''.$form->getAttribute('id').'\'].elements[\''.$name.'\']'; |
9403060a |
170 | } |
46f3921e |
171 | |
9403060a |
172 | return $focus; |
173 | } |
7f40a229 |
174 | |
05f5c40c |
175 | /** |
176 | * Internal method. Alters submitted data to be suitable for quickforms processing. |
177 | * Must be called when the form is fully set up. |
178 | */ |
7f40a229 |
179 | function _process_submission($method) { |
180 | $submission = array(); |
181 | if ($method == 'post') { |
182 | if (!empty($_POST)) { |
183 | $submission = $_POST; |
184 | } |
185 | } else { |
186 | $submission = array_merge_recursive($_GET, $_POST); // emulate handling of parameters in xxxx_param() |
187 | } |
188 | |
189 | // following trick is needed to enable proper sesskey checks when using GET forms |
5bc97c98 |
190 | // the _qf__.$this->_formname serves as a marker that form was actually submitted |
191 | if (array_key_exists('_qf__'.$this->_formname, $submission) and $submission['_qf__'.$this->_formname] == 1) { |
7f40a229 |
192 | if (!confirm_sesskey()) { |
c3f9ee10 |
193 | print_error('invalidsesskey'); |
7f40a229 |
194 | } |
05f5c40c |
195 | $files = $_FILES; |
7f40a229 |
196 | } else { |
197 | $submission = array(); |
05f5c40c |
198 | $files = array(); |
7f40a229 |
199 | } |
200 | |
05f5c40c |
201 | $this->_form->updateSubmission($submission, $files); |
7f40a229 |
202 | } |
203 | |
05f5c40c |
204 | /** |
4287fc0d |
205 | * Internal method. Validates all old-style uploaded files. |
05f5c40c |
206 | */ |
89489cfe |
207 | function _validate_files(&$files) { |
172dd12c |
208 | global $CFG, $COURSE; |
209 | |
89489cfe |
210 | $files = array(); |
211 | |
49292f8c |
212 | if (empty($_FILES)) { |
213 | // we do not need to do any checks because no files were submitted |
89489cfe |
214 | // note: server side rules do not work for files - use custom verification in validate() instead |
49292f8c |
215 | return true; |
216 | } |
49292f8c |
217 | |
172dd12c |
218 | $errors = array(); |
219 | $filenames = array(); |
49292f8c |
220 | |
221 | // now check that we really want each file |
222 | foreach ($_FILES as $elname=>$file) { |
172dd12c |
223 | $required = $this->_form->isElementRequired($elname); |
89489cfe |
224 | |
172dd12c |
225 | if ($file['error'] == 4 and $file['size'] == 0) { |
226 | if ($required) { |
227 | $errors[$elname] = get_string('required'); |
49292f8c |
228 | } |
172dd12c |
229 | unset($_FILES[$elname]); |
230 | continue; |
231 | } |
232 | |
a83ad946 |
233 | if (!empty($file['error'])) { |
234 | $errors[$elname] = file_get_upload_error($file['error']); |
172dd12c |
235 | unset($_FILES[$elname]); |
236 | continue; |
237 | } |
238 | |
239 | if (!is_uploaded_file($file['tmp_name'])) { |
240 | // TODO: improve error message |
241 | $errors[$elname] = get_string('error'); |
242 | unset($_FILES[$elname]); |
243 | continue; |
244 | } |
245 | |
246 | if (!$this->_form->elementExists($elname) or !$this->_form->getElementType($elname)=='file') { |
247 | // hmm, this file was not requested |
248 | unset($_FILES[$elname]); |
249 | continue; |
250 | } |
251 | |
252 | /* |
253 | // TODO: rethink the file scanning |
254 | if ($CFG->runclamonupload) { |
255 | if (!clam_scan_moodle_file($_FILES[$elname], $COURSE)) { |
256 | $errors[$elname] = $_FILES[$elname]['uploadlog']; |
257 | unset($_FILES[$elname]); |
258 | continue; |
259 | } |
260 | } |
261 | */ |
262 | $filename = clean_param($_FILES[$elname]['name'], PARAM_FILE); |
263 | if ($filename === '') { |
264 | // TODO: improve error message - wrong chars |
265 | $errors[$elname] = get_string('error'); |
266 | unset($_FILES[$elname]); |
267 | continue; |
49292f8c |
268 | } |
172dd12c |
269 | if (in_array($filename, $filenames)) { |
270 | // TODO: improve error message - duplicate name |
271 | $errors[$elname] = get_string('error'); |
272 | unset($_FILES[$elname]); |
273 | continue; |
274 | } |
275 | $filenames[] = $filename; |
276 | $_FILES[$elname]['name'] = $filename; |
277 | |
278 | $files[$elname] = $_FILES[$elname]['tmp_name']; |
49292f8c |
279 | } |
280 | |
281 | // return errors if found |
172dd12c |
282 | if (count($errors) == 0){ |
49292f8c |
283 | return true; |
89489cfe |
284 | |
49292f8c |
285 | } else { |
89489cfe |
286 | $files = array(); |
49292f8c |
287 | return $errors; |
288 | } |
289 | } |
290 | |
05f5c40c |
291 | /** |
da1320da |
292 | * Load in existing data as form defaults. Usually new entry defaults are stored directly in |
293 | * form definition (new entry form); this function is used to load in data where values |
294 | * already exist and data is being edited (edit entry form). |
05f5c40c |
295 | * |
294ce987 |
296 | * note: $slashed param removed |
297 | * |
05f5c40c |
298 | * @param mixed $default_values object or array of default values |
299 | * @param bool $slased true if magic quotes applied to data values |
300 | */ |
294ce987 |
301 | function set_data($default_values) { |
7f40a229 |
302 | if (is_object($default_values)) { |
303 | $default_values = (array)$default_values; |
304 | } |
294ce987 |
305 | $this->_form->setDefaults($default_values); |
7f40a229 |
306 | } |
307 | |
feaf5d06 |
308 | function set_upload_manager($um=false) { |
172dd12c |
309 | debugging('Not used anymore, please fix code!'); |
c80a13c7 |
310 | } |
311 | |
05f5c40c |
312 | /** |
313 | * Check that form was submitted. Does not check validity of submitted data. |
314 | * |
315 | * @return bool true if form properly submitted |
316 | */ |
7f40a229 |
317 | function is_submitted() { |
318 | return $this->_form->isSubmitted(); |
319 | } |
320 | |
a23f0aaf |
321 | function no_submit_button_pressed(){ |
322 | static $nosubmit = null; // one check is enough |
323 | if (!is_null($nosubmit)){ |
324 | return $nosubmit; |
325 | } |
326 | $mform =& $this->_form; |
327 | $nosubmit = false; |
f07b9627 |
328 | if (!$this->is_submitted()){ |
329 | return false; |
330 | } |
a23f0aaf |
331 | foreach ($mform->_noSubmitButtons as $nosubmitbutton){ |
332 | if (optional_param($nosubmitbutton, 0, PARAM_RAW)){ |
333 | $nosubmit = true; |
334 | break; |
335 | } |
336 | } |
337 | return $nosubmit; |
338 | } |
339 | |
340 | |
05f5c40c |
341 | /** |
342 | * Check that form data is valid. |
343 | * |
344 | * @return bool true if form data valid |
345 | */ |
7f40a229 |
346 | function is_validated() { |
49292f8c |
347 | static $validated = null; // one validation is enough |
3ba2c187 |
348 | $mform =& $this->_form; |
f07b9627 |
349 | |
4f51f48f |
350 | //finalize the form definition before any processing |
351 | if (!$this->_definition_finalized) { |
352 | $this->_definition_finalized = true; |
353 | $this->definition_after_data(); |
354 | } |
355 | |
9aa022fe |
356 | if ($this->no_submit_button_pressed()){ |
357 | return false; |
358 | } elseif ($validated === null) { |
3ba2c187 |
359 | $internal_val = $mform->validate(); |
89489cfe |
360 | |
361 | $files = array(); |
362 | $file_val = $this->_validate_files($files); |
363 | if ($file_val !== true) { |
364 | if (!empty($file_val)) { |
365 | foreach ($file_val as $element=>$msg) { |
366 | $mform->setElementError($element, $msg); |
367 | } |
368 | } |
369 | $file_val = false; |
370 | } |
371 | |
4287fc0d |
372 | $data = $mform->exportValues(); |
89489cfe |
373 | $moodle_val = $this->validation($data, $files); |
a78890d5 |
374 | if ((is_array($moodle_val) && count($moodle_val)!==0)) { |
375 | // non-empty array means errors |
376 | foreach ($moodle_val as $element=>$msg) { |
377 | $mform->setElementError($element, $msg); |
7f40a229 |
378 | } |
a78890d5 |
379 | $moodle_val = false; |
380 | |
381 | } else { |
382 | // anything else means validation ok |
383 | $moodle_val = true; |
7f40a229 |
384 | } |
89489cfe |
385 | |
49292f8c |
386 | $validated = ($internal_val and $moodle_val and $file_val); |
7f40a229 |
387 | } |
9aa022fe |
388 | return $validated; |
7f40a229 |
389 | } |
390 | |
19110c57 |
391 | /** |
392 | * Return true if a cancel button has been pressed resulting in the form being submitted. |
393 | * |
394 | * @return boolean true if a cancel button has been pressed |
395 | */ |
396 | function is_cancelled(){ |
397 | $mform =& $this->_form; |
a23f0aaf |
398 | if ($mform->isSubmitted()){ |
399 | foreach ($mform->_cancelButtons as $cancelbutton){ |
400 | if (optional_param($cancelbutton, 0, PARAM_RAW)){ |
401 | return true; |
402 | } |
19110c57 |
403 | } |
404 | } |
405 | return false; |
406 | } |
407 | |
05f5c40c |
408 | /** |
da1320da |
409 | * Return submitted data if properly submitted or returns NULL if validation fails or |
410 | * if there is no submitted data. |
172dd12c |
411 | * |
294ce987 |
412 | * note: $slashed param removed |
05f5c40c |
413 | * |
05f5c40c |
414 | * @return object submitted data; NULL if not valid or not submitted |
415 | */ |
294ce987 |
416 | function get_data() { |
19110c57 |
417 | $mform =& $this->_form; |
3ba2c187 |
418 | |
7f40a229 |
419 | if ($this->is_submitted() and $this->is_validated()) { |
294ce987 |
420 | $data = $mform->exportValues(); |
5bc97c98 |
421 | unset($data['sesskey']); // we do not need to return sesskey |
422 | unset($data['_qf__'.$this->_formname]); // we do not need the submission marker too |
7f40a229 |
423 | if (empty($data)) { |
424 | return NULL; |
425 | } else { |
426 | return (object)$data; |
427 | } |
428 | } else { |
429 | return NULL; |
430 | } |
431 | } |
432 | |
4f51f48f |
433 | /** |
434 | * Return submitted data without validation or NULL if there is no submitted data. |
294ce987 |
435 | * note: $slashed param removed |
4f51f48f |
436 | * |
4f51f48f |
437 | * @return object submitted data; NULL if not submitted |
438 | */ |
294ce987 |
439 | function get_submitted_data() { |
4f51f48f |
440 | $mform =& $this->_form; |
441 | |
442 | if ($this->is_submitted()) { |
294ce987 |
443 | $data = $mform->exportValues(); |
4f51f48f |
444 | unset($data['sesskey']); // we do not need to return sesskey |
445 | unset($data['_qf__'.$this->_formname]); // we do not need the submission marker too |
446 | if (empty($data)) { |
447 | return NULL; |
448 | } else { |
449 | return (object)$data; |
450 | } |
451 | } else { |
452 | return NULL; |
453 | } |
454 | } |
455 | |
05f5c40c |
456 | /** |
457 | * Save verified uploaded files into directory. Upload process can be customised from definition() |
172dd12c |
458 | * NOTE: please use save_stored_file() or save_file() |
05f5c40c |
459 | */ |
49292f8c |
460 | function save_files($destination) { |
172dd12c |
461 | debugging('Not used anymore, please fix code! Use save_stored_file() or save_file() instead'); |
49292f8c |
462 | return false; |
463 | } |
2b63df96 |
464 | |
feaf5d06 |
465 | /** |
172dd12c |
466 | * Returns name of uploaded file. |
467 | * @param string $elname, first element if null |
feaf5d06 |
468 | * @return mixed false in case of failure, string if ok |
469 | */ |
172dd12c |
470 | function get_new_filename($elname=null) { |
4287fc0d |
471 | global $USER; |
472 | |
172dd12c |
473 | if (!$this->is_submitted() or !$this->is_validated()) { |
474 | return false; |
475 | } |
476 | |
477 | if (is_null($elname)) { |
478 | if (empty($_FILES)) { |
479 | return false; |
480 | } |
481 | reset($_FILES); |
482 | $elname = key($_FILES); |
483 | } |
4287fc0d |
484 | |
485 | if (empty($elname)) { |
486 | return false; |
487 | } |
488 | |
489 | $element = $this->_form->getElement($elname); |
490 | |
491 | if ($element instanceof MoodleQuickForm_filepicker) { |
492 | $values = $this->_form->exportValues($elname); |
493 | if (empty($values[$elname])) { |
494 | return false; |
495 | } |
496 | $draftid = $values[$elname]; |
497 | $fs = get_file_storage(); |
498 | $context = get_context_instance(CONTEXT_USER, $USER->id); |
499 | if (!$files = $fs->get_area_files($context->id, 'user_draft', $draftid, 'id DESC', false)) { |
500 | return false; |
501 | } |
502 | $file = reset($files); |
503 | return $file->get_filename(); |
504 | } |
505 | |
172dd12c |
506 | if (!isset($_FILES[$elname])) { |
507 | return false; |
508 | } |
509 | |
510 | return $_FILES[$elname]['name']; |
feaf5d06 |
511 | } |
512 | |
b6b1d1ca |
513 | /** |
172dd12c |
514 | * Save file to standard filesystem |
515 | * @param string $elname name of element |
516 | * @param string $pathname full path name of file |
517 | * @param bool $override override file if exists |
518 | * @return bool success |
b6b1d1ca |
519 | */ |
172dd12c |
520 | function save_file($elname, $pathname, $override=false) { |
4287fc0d |
521 | global $USER; |
b6b1d1ca |
522 | |
4287fc0d |
523 | if (!$this->is_submitted() or !$this->is_validated()) { |
b6b1d1ca |
524 | return false; |
525 | } |
526 | |
172dd12c |
527 | if (file_exists($pathname)) { |
528 | if ($override) { |
529 | if (!@unlink($pathname)) { |
530 | return false; |
531 | } |
532 | } else { |
533 | return false; |
534 | } |
535 | } |
4287fc0d |
536 | |
537 | $element = $this->_form->getElement($elname); |
538 | |
539 | if ($element instanceof MoodleQuickForm_filepicker) { |
540 | $values = $this->_form->exportValues($elname); |
541 | if (empty($values[$elname])) { |
542 | return false; |
543 | } |
544 | $draftid = $values[$elname]; |
545 | $fs = get_file_storage(); |
546 | $context = get_context_instance(CONTEXT_USER, $USER->id); |
547 | if (!$files = $fs->get_area_files($context->id, 'user_draft', $draftid, 'id DESC', false)) { |
548 | return false; |
549 | } |
550 | $file = reset($files); |
551 | |
552 | return $file->copy_content_to($pathname); |
553 | |
554 | } else if (isset($_FILES[$elname])) { |
555 | return copy($_FILES[$elname]['tmp_name'], $pathname); |
172dd12c |
556 | } |
557 | |
4287fc0d |
558 | return false; |
172dd12c |
559 | } |
560 | |
561 | /** |
562 | * Save file to local filesystem pool |
563 | * @param string $elname name of element |
924ddb15 |
564 | * @param int $newcontextid |
565 | * @param string $newfilearea |
566 | * @param string $newfilepath |
567 | * @param string $newfilename - use specified filename, if not specified name of uploaded file used |
49583e9e |
568 | * @param bool $overwrite - overwrite file if exists |
924ddb15 |
569 | * @param int $newuserid - new userid if required |
172dd12c |
570 | * @return mixed stored_file object or false if error; may throw exception if duplicate found |
571 | */ |
f6172562 |
572 | function save_stored_file($elname, $newcontextid, $newfilearea, $newitemid, $newfilepath='/', |
49583e9e |
573 | $newfilename=null, $overwrite=false, $newuserid=null) { |
924ddb15 |
574 | global $USER; |
575 | |
172dd12c |
576 | if (!$this->is_submitted() or !$this->is_validated()) { |
89489cfe |
577 | return false; |
172dd12c |
578 | } |
89489cfe |
579 | |
924ddb15 |
580 | if (empty($newuserid)) { |
581 | $newuserid = $USER->id; |
89489cfe |
582 | } |
b6b1d1ca |
583 | |
4287fc0d |
584 | $element = $this->_form->getElement($elname); |
585 | $fs = get_file_storage(); |
172dd12c |
586 | |
4287fc0d |
587 | if ($element instanceof MoodleQuickForm_filepicker) { |
588 | $values = $this->_form->exportValues($elname); |
589 | if (empty($values[$elname])) { |
590 | return false; |
591 | } |
592 | $draftid = $values[$elname]; |
593 | $context = get_context_instance(CONTEXT_USER, $USER->id); |
594 | if (!$files = $fs->get_area_files($context->id, 'user_draft', $draftid, 'id DESC', false)) { |
595 | return false; |
596 | } |
597 | $file = reset($files); |
598 | if (is_null($newfilename)) { |
599 | $newfilename = $file->get_filename(); |
600 | } |
172dd12c |
601 | |
4287fc0d |
602 | if ($overwrite) { |
603 | if ($oldfile = $fs->get_file($newcontextid, $newfilearea, $newitemid, $newfilepath, $newfilename)) { |
604 | if (!$oldfile->delete()) { |
605 | return false; |
606 | } |
924ddb15 |
607 | } |
608 | } |
609 | |
4287fc0d |
610 | $file_record = array('contextid'=>$newcontextid, 'filearea'=>$newfilearea, 'itemid'=>$newitemid, |
611 | 'filepath'=>$newfilepath, 'filename'=>$newfilename, 'userid'=>$newuserid); |
612 | return $fs->create_file_from_storedfile($file_record, $file); |
924ddb15 |
613 | |
4287fc0d |
614 | } else if (isset($_FILES[$elname])) { |
615 | $filename = is_null($newfilename) ? $_FILES[$elname]['name'] : $newfilename; |
172dd12c |
616 | |
4287fc0d |
617 | if ($overwrite) { |
618 | if ($oldfile = $fs->get_file($newcontextid, $newfilearea, $newitemid, $newfilepath, $newfilename)) { |
619 | if (!$oldfile->delete()) { |
620 | return false; |
621 | } |
622 | } |
924ddb15 |
623 | } |
4287fc0d |
624 | |
625 | $file_record = array('contextid'=>$newcontextid, 'filearea'=>$newfilearea, 'itemid'=>$newitemid, |
626 | 'filepath'=>$newfilepath, 'filename'=>$newfilename, 'userid'=>$newuserid); |
627 | return $fs->create_file_from_pathname($file_record, $_FILES[$elname]['tmp_name']); |
924ddb15 |
628 | } |
629 | |
630 | return false; |
172dd12c |
631 | } |
632 | |
633 | /** |
634 | * Get content of uploaded file. |
635 | * @param $element name of file upload element |
636 | * @return mixed false in case of failure, string if ok |
637 | */ |
638 | function get_file_content($elname) { |
4287fc0d |
639 | global $USER; |
640 | |
172dd12c |
641 | if (!$this->is_submitted() or !$this->is_validated()) { |
642 | return false; |
643 | } |
644 | |
4287fc0d |
645 | $element = $this->_form->getElement($elname); |
646 | |
647 | if ($element instanceof MoodleQuickForm_filepicker) { |
648 | $values = $this->_form->exportValues($elname); |
649 | if (empty($values[$elname])) { |
650 | return false; |
651 | } |
652 | $draftid = $values[$elname]; |
653 | $fs = get_file_storage(); |
654 | $context = get_context_instance(CONTEXT_USER, $USER->id); |
655 | if (!$files = $fs->get_area_files($context->id, 'user_draft', $draftid, 'id DESC', false)) { |
656 | return false; |
657 | } |
658 | $file = reset($files); |
659 | |
660 | return $file->get_content(); |
661 | |
662 | } else if (isset($_FILES[$elname])) { |
663 | return file_get_contents($_FILES[$elname]['tmp_name']); |
b6b1d1ca |
664 | } |
172dd12c |
665 | |
4287fc0d |
666 | return false; |
b6b1d1ca |
667 | } |
668 | |
05f5c40c |
669 | /** |
670 | * Print html form. |
671 | */ |
7f40a229 |
672 | function display() { |
4f51f48f |
673 | //finalize the form definition if not yet done |
674 | if (!$this->_definition_finalized) { |
675 | $this->_definition_finalized = true; |
676 | $this->definition_after_data(); |
677 | } |
7f40a229 |
678 | $this->_form->display(); |
679 | } |
680 | |
49292f8c |
681 | /** |
05f5c40c |
682 | * Abstract method - always override! |
49292f8c |
683 | * |
684 | * If you need special handling of uploaded files, create instance of $this->_upload_manager here. |
685 | */ |
7f40a229 |
686 | function definition() { |
3c0b6b16 |
687 | print_error('mustbeoverriden', 'form', '', get_class($this)); |
7f40a229 |
688 | } |
2c412890 |
689 | |
c08ac016 |
690 | /** |
05f5c40c |
691 | * Dummy stub method - override if you need to setup the form depending on current |
beac4717 |
692 | * values. This method is called after definition(), data submission and set_data(). |
05f5c40c |
693 | * All form setup that is dependent on form values should go in here. |
c08ac016 |
694 | */ |
695 | function definition_after_data(){ |
c08ac016 |
696 | } |
7f40a229 |
697 | |
05f5c40c |
698 | /** |
699 | * Dummy stub method - override if you needed to perform some extra validation. |
700 | * If there are errors return array of errors ("fieldname"=>"error message"), |
701 | * otherwise true if ok. |
38f394b2 |
702 | * |
89489cfe |
703 | * Server side rules do not work for uploaded files, implement serverside rules here if needed. |
704 | * |
05f5c40c |
705 | * @param array $data array of ("fieldname"=>value) of submitted data |
89489cfe |
706 | * @param array $files array of uploaded files "element_name"=>tmp_file_path |
a78890d5 |
707 | * @return array of "element_name"=>"error_description" if there are errors, |
708 | * or an empty array if everything is OK (true allowed for backwards compatibility too). |
05f5c40c |
709 | */ |
89489cfe |
710 | function validation($data, $files) { |
13ccb7bd |
711 | return array(); |
7f40a229 |
712 | } |
ebd3c7ac |
713 | |
616b549a |
714 | /** |
715 | * Method to add a repeating group of elements to a form. |
716 | * |
717 | * @param array $elementobjs Array of elements or groups of elements that are to be repeated |
718 | * @param integer $repeats no of times to repeat elements initially |
719 | * @param array $options Array of options to apply to elements. Array keys are element names. |
720 | * This is an array of arrays. The second sets of keys are the option types |
721 | * for the elements : |
722 | * 'default' - default value is value |
723 | * 'type' - PARAM_* constant is value |
724 | * 'helpbutton' - helpbutton params array is value |
725 | * 'disabledif' - last three moodleform::disabledIf() |
726 | * params are value as an array |
727 | * @param string $repeathiddenname name for hidden element storing no of repeats in this form |
728 | * @param string $addfieldsname name for button to add more fields |
729 | * @param int $addfieldsno how many fields to add at a time |
271ffe3f |
730 | * @param string $addstring name of button, {no} is replaced by no of blanks that will be added. |
6f3b54c8 |
731 | * @param boolean $addbuttoninside if true, don't call closeHeaderBefore($addfieldsname). Default false. |
a23f0aaf |
732 | * @return int no of repeats of element in this page |
616b549a |
733 | */ |
6f3b54c8 |
734 | function repeat_elements($elementobjs, $repeats, $options, $repeathiddenname, |
735 | $addfieldsname, $addfieldsno=5, $addstring=null, $addbuttoninside=false){ |
271ffe3f |
736 | if ($addstring===null){ |
737 | $addstring = get_string('addfields', 'form', $addfieldsno); |
738 | } else { |
739 | $addstring = str_ireplace('{no}', $addfieldsno, $addstring); |
740 | } |
ebd3c7ac |
741 | $repeats = optional_param($repeathiddenname, $repeats, PARAM_INT); |
742 | $addfields = optional_param($addfieldsname, '', PARAM_TEXT); |
743 | if (!empty($addfields)){ |
744 | $repeats += $addfieldsno; |
745 | } |
ebd3c7ac |
746 | $mform =& $this->_form; |
a23f0aaf |
747 | $mform->registerNoSubmitButton($addfieldsname); |
ebd3c7ac |
748 | $mform->addElement('hidden', $repeathiddenname, $repeats); |
749 | //value not to be overridden by submitted value |
750 | $mform->setConstants(array($repeathiddenname=>$repeats)); |
414f7bee |
751 | $namecloned = array(); |
752 | for ($i = 0; $i < $repeats; $i++) { |
ebd3c7ac |
753 | foreach ($elementobjs as $elementobj){ |
985f0ddd |
754 | $elementclone = fullclone($elementobj); |
7b41a4a9 |
755 | $name = $elementclone->getName(); |
414f7bee |
756 | $namecloned[] = $name; |
757 | if (!empty($name)) { |
86aab05c |
758 | $elementclone->setName($name."[$i]"); |
759 | } |
414f7bee |
760 | if (is_a($elementclone, 'HTML_QuickForm_header')) { |
761 | $value = $elementclone->_text; |
271ffe3f |
762 | $elementclone->setValue(str_replace('{no}', ($i+1), $value)); |
763 | |
764 | } else { |
765 | $value=$elementclone->getLabel(); |
766 | $elementclone->setLabel(str_replace('{no}', ($i+1), $value)); |
ebd3c7ac |
767 | |
768 | } |
7b41a4a9 |
769 | |
ebd3c7ac |
770 | $mform->addElement($elementclone); |
771 | } |
772 | } |
773 | for ($i=0; $i<$repeats; $i++) { |
774 | foreach ($options as $elementname => $elementoptions){ |
775 | $pos=strpos($elementname, '['); |
776 | if ($pos!==FALSE){ |
777 | $realelementname = substr($elementname, 0, $pos+1)."[$i]"; |
778 | $realelementname .= substr($elementname, $pos+1); |
779 | }else { |
780 | $realelementname = $elementname."[$i]"; |
781 | } |
782 | foreach ($elementoptions as $option => $params){ |
783 | |
784 | switch ($option){ |
785 | case 'default' : |
786 | $mform->setDefault($realelementname, $params); |
787 | break; |
ebd3c7ac |
788 | case 'helpbutton' : |
789 | $mform->setHelpButton($realelementname, $params); |
790 | break; |
791 | case 'disabledif' : |
414f7bee |
792 | foreach ($namecloned as $num => $name){ |
793 | if ($params[0] == $name){ |
794 | $params[0] = $params[0]."[$i]"; |
795 | break; |
796 | } |
797 | } |
9aa022fe |
798 | $params = array_merge(array($realelementname), $params); |
799 | call_user_func_array(array(&$mform, 'disabledIf'), $params); |
800 | break; |
801 | case 'rule' : |
802 | if (is_string($params)){ |
803 | $params = array(null, $params, null, 'client'); |
804 | } |
805 | $params = array_merge(array($realelementname), $params); |
806 | call_user_func_array(array(&$mform, 'addRule'), $params); |
ebd3c7ac |
807 | break; |
808 | |
809 | } |
810 | } |
811 | } |
812 | } |
271ffe3f |
813 | $mform->addElement('submit', $addfieldsname, $addstring); |
a23f0aaf |
814 | |
6f3b54c8 |
815 | if (!$addbuttoninside) { |
816 | $mform->closeHeaderBefore($addfieldsname); |
817 | } |
ebd3c7ac |
818 | |
19194f82 |
819 | return $repeats; |
ebd3c7ac |
820 | } |
6073a598 |
821 | |
822 | /** |
823 | * Adds a link/button that controls the checked state of a group of checkboxes. |
824 | * @param int $groupid The id of the group of advcheckboxes this element controls |
825 | * @param string $text The text of the link. Defaults to "select all/none" |
826 | * @param array $attributes associative array of HTML attributes |
827 | * @param int $originalValue The original general state of the checkboxes before the user first clicks this element |
828 | */ |
172dd12c |
829 | function add_checkbox_controller($groupid, $buttontext, $attributes, $originalValue = 0) { |
6073a598 |
830 | global $CFG; |
831 | if (empty($text)) { |
832 | $text = get_string('selectallornone', 'form'); |
833 | } |
834 | |
835 | $mform = $this->_form; |
836 | $select_value = optional_param('checkbox_controller'. $groupid, null, PARAM_INT); |
837 | |
838 | if ($select_value == 0 || is_null($select_value)) { |
839 | $new_select_value = 1; |
840 | } else { |
841 | $new_select_value = 0; |
842 | } |
843 | |
844 | $mform->addElement('hidden', "checkbox_controller$groupid"); |
845 | $mform->setConstants(array("checkbox_controller$groupid" => $new_select_value)); |
172dd12c |
846 | |
6073a598 |
847 | // Locate all checkboxes for this group and set their value, IF the optional param was given |
848 | if (!is_null($select_value)) { |
849 | foreach ($this->_form->_elements as $element) { |
850 | if ($element->getAttribute('class') == "checkboxgroup$groupid") { |
851 | $mform->setConstants(array($element->getAttribute('name') => $select_value)); |
852 | } |
853 | } |
854 | } |
855 | |
856 | $checkbox_controller_name = 'nosubmit_checkbox_controller' . $groupid; |
857 | $mform->registerNoSubmitButton($checkbox_controller_name); |
172dd12c |
858 | |
6073a598 |
859 | // Prepare Javascript for submit element |
860 | $js = "\n//<![CDATA[\n"; |
861 | if (!defined('HTML_QUICKFORM_CHECKBOXCONTROLLER_EXISTS')) { |
862 | $js .= <<<EOS |
863 | function html_quickform_toggle_checkboxes(group) { |
864 | var checkboxes = getElementsByClassName(document, 'input', 'checkboxgroup' + group); |
865 | var newvalue = false; |
866 | var global = eval('html_quickform_checkboxgroup' + group + ';'); |
867 | if (global == 1) { |
172dd12c |
868 | eval('html_quickform_checkboxgroup' + group + ' = 0;'); |
6073a598 |
869 | newvalue = ''; |
870 | } else { |
172dd12c |
871 | eval('html_quickform_checkboxgroup' + group + ' = 1;'); |
6073a598 |
872 | newvalue = 'checked'; |
873 | } |
874 | |
875 | for (i = 0; i < checkboxes.length; i++) { |
172dd12c |
876 | checkboxes[i].checked = newvalue; |
6073a598 |
877 | } |
878 | } |
879 | EOS; |
880 | define('HTML_QUICKFORM_CHECKBOXCONTROLLER_EXISTS', true); |
881 | } |
882 | $js .= "\nvar html_quickform_checkboxgroup$groupid=$originalValue;\n"; |
172dd12c |
883 | |
6073a598 |
884 | $js .= "//]]>\n"; |
172dd12c |
885 | |
6073a598 |
886 | require_once("$CFG->libdir/form/submitlink.php"); |
887 | $submitlink = new MoodleQuickForm_submitlink($checkbox_controller_name, $attributes); |
888 | $submitlink->_js = $js; |
889 | $submitlink->_onclick = "html_quickform_toggle_checkboxes($groupid); return false;"; |
172dd12c |
890 | $mform->addElement($submitlink); |
6073a598 |
891 | $mform->setDefault($checkbox_controller_name, $text); |
892 | } |
893 | |
a23f0aaf |
894 | /** |
1d284fbd |
895 | * Use this method to a cancel and submit button to the end of your form. Pass a param of false |
a23f0aaf |
896 | * if you don't want a cancel button in your form. If you have a cancel button make sure you |
897 | * check for it being pressed using is_cancelled() and redirecting if it is true before trying to |
beac4717 |
898 | * get data with get_data(). |
a23f0aaf |
899 | * |
900 | * @param boolean $cancel whether to show cancel button, default true |
a23f0aaf |
901 | * @param string $submitlabel label for submit button, defaults to get_string('savechanges') |
902 | */ |
1d284fbd |
903 | function add_action_buttons($cancel = true, $submitlabel=null){ |
a23f0aaf |
904 | if (is_null($submitlabel)){ |
905 | $submitlabel = get_string('savechanges'); |
906 | } |
907 | $mform =& $this->_form; |
1d284fbd |
908 | if ($cancel){ |
909 | //when two elements we need a group |
a23f0aaf |
910 | $buttonarray=array(); |
911 | $buttonarray[] = &$mform->createElement('submit', 'submitbutton', $submitlabel); |
1d284fbd |
912 | $buttonarray[] = &$mform->createElement('cancel'); |
a23f0aaf |
913 | $mform->addGroup($buttonarray, 'buttonar', '', array(' '), false); |
4f51f48f |
914 | $mform->closeHeaderBefore('buttonar'); |
a23f0aaf |
915 | } else { |
916 | //no group needed |
917 | $mform->addElement('submit', 'submitbutton', $submitlabel); |
4f51f48f |
918 | $mform->closeHeaderBefore('submitbutton'); |
a23f0aaf |
919 | } |
920 | } |
7f40a229 |
921 | } |
922 | |
da1320da |
923 | /** |
924 | * You never extend this class directly. The class methods of this class are available from |
6073a598 |
925 | * the private $this->_form property on moodleform and its children. You generally only |
da1320da |
926 | * call methods on this class from within abstract methods that you override on moodleform such |
927 | * as definition and definition_after_data |
928 | * |
929 | */ |
7f40a229 |
930 | class MoodleQuickForm extends HTML_QuickForm_DHTMLRulesTableless { |
931 | var $_types = array(); |
50ef8eb9 |
932 | var $_dependencies = array(); |
19110c57 |
933 | /** |
934 | * Array of buttons that if pressed do not result in the processing of the form. |
935 | * |
936 | * @var array |
937 | */ |
938 | var $_noSubmitButtons=array(); |
939 | /** |
940 | * Array of buttons that if pressed do not result in the processing of the form. |
941 | * |
942 | * @var array |
943 | */ |
944 | var $_cancelButtons=array(); |
7f40a229 |
945 | |
19194f82 |
946 | /** |
947 | * Array whose keys are element names. If the key exists this is a advanced element |
948 | * |
949 | * @var array |
950 | */ |
951 | var $_advancedElements = array(); |
952 | |
953 | /** |
954 | * Whether to display advanced elements (on page load) |
955 | * |
956 | * @var boolean |
957 | */ |
958 | var $_showAdvanced = null; |
959 | |
f07b9627 |
960 | /** |
961 | * The form name is derrived from the class name of the wrapper minus the trailing form |
962 | * It is a name with words joined by underscores whereas the id attribute is words joined by |
963 | * underscores. |
964 | * |
965 | * @var unknown_type |
966 | */ |
967 | var $_formName = ''; |
43914931 |
968 | |
4f51f48f |
969 | /** |
970 | * String with the html for hidden params passed in as part of a moodle_url object for the action. Output in the form. |
971 | * |
972 | * @var string |
973 | */ |
974 | var $_pageparams = ''; |
975 | |
da6f8763 |
976 | /** |
977 | * Class constructor - same parameters as HTML_QuickForm_DHTMLRulesTableless |
978 | * @param string $formName Form's name. |
979 | * @param string $method (optional)Form's method defaults to 'POST' |
4f51f48f |
980 | * @param mixed $action (optional)Form's action - string or moodle_url |
da6f8763 |
981 | * @param string $target (optional)Form's target defaults to none |
982 | * @param mixed $attributes (optional)Extra attributes for <form> tag |
983 | * @param bool $trackSubmit (optional)Whether to track if the form was submitted by adding a special hidden field |
984 | * @access public |
985 | */ |
7f40a229 |
986 | function MoodleQuickForm($formName, $method, $action, $target='', $attributes=null){ |
dcf6d93c |
987 | global $CFG; |
988 | |
271ffe3f |
989 | static $formcounter = 1; |
7f40a229 |
990 | |
da6f8763 |
991 | HTML_Common::HTML_Common($attributes); |
da6f8763 |
992 | $target = empty($target) ? array() : array('target' => $target); |
f07b9627 |
993 | $this->_formName = $formName; |
4f51f48f |
994 | if (is_a($action, 'moodle_url')){ |
995 | $this->_pageparams = $action->hidden_params_out(); |
996 | $action = $action->out(true); |
997 | } else { |
998 | $this->_pageparams = ''; |
999 | } |
da6f8763 |
1000 | //no 'name' atttribute for form in xhtml strict : |
1327f08e |
1001 | $attributes = array('action'=>$action, 'method'=>$method, |
1002 | 'accept-charset'=>'utf-8', 'id'=>'mform'.$formcounter) + $target; |
271ffe3f |
1003 | $formcounter++; |
da6f8763 |
1004 | $this->updateAttributes($attributes); |
da6f8763 |
1005 | |
7f40a229 |
1006 | //this is custom stuff for Moodle : |
da6f8763 |
1007 | $oldclass= $this->getAttribute('class'); |
1008 | if (!empty($oldclass)){ |
1009 | $this->updateAttributes(array('class'=>$oldclass.' mform')); |
1010 | }else { |
80f962df |
1011 | $this->updateAttributes(array('class'=>'mform')); |
da6f8763 |
1012 | } |
653f890d |
1013 | $this->_reqHTML = '<img class="req" title="'.get_string('requiredelement', 'form').'" alt="'.get_string('requiredelement', 'form').'" src="'.$CFG->pixpath.'/req.gif'.'" />'; |
1014 | $this->_advancedHTML = '<img class="adv" title="'.get_string('advancedelement', 'form').'" alt="'.get_string('advancedelement', 'form').'" src="'.$CFG->pixpath.'/adv.gif'.'" />'; |
5bff0855 |
1015 | $this->setRequiredNote(get_string('somefieldsrequired', 'form', '<img alt="'.get_string('requiredelement', 'form').'" src="'.$CFG->pixpath.'/req.gif'.'" />')); |
1016 | //(Help file doesn't add anything) helpbutton('requiredelement', get_string('requiredelement', 'form'), 'moodle', true, false, '', true)); |
19194f82 |
1017 | } |
1018 | |
a23f0aaf |
1019 | /** |
1020 | * Use this method to indicate an element in a form is an advanced field. If items in a form |
1021 | * are marked as advanced then 'Hide/Show Advanced' buttons will automatically be displayed in the |
1022 | * form so the user can decide whether to display advanced form controls. |
1023 | * |
1024 | * If you set a header element to advanced then all elements it contains will also be set as advanced. |
1025 | * |
1026 | * @param string $elementName group or element name (not the element name of something inside a group). |
1027 | * @param boolean $advanced default true sets the element to advanced. False removes advanced mark. |
1028 | */ |
1029 | function setAdvanced($elementName, $advanced=true){ |
1030 | if ($advanced){ |
1031 | $this->_advancedElements[$elementName]=''; |
1032 | } elseif (isset($this->_advancedElements[$elementName])) { |
1033 | unset($this->_advancedElements[$elementName]); |
1034 | } |
1035 | if ($advanced && $this->getElementType('mform_showadvanced_last')===false){ |
1036 | $this->setShowAdvanced(); |
1037 | $this->registerNoSubmitButton('mform_showadvanced'); |
1038 | |
1039 | $this->addElement('hidden', 'mform_showadvanced_last'); |
1040 | } |
1041 | } |
1042 | /** |
1043 | * Set whether to show advanced elements in the form on first displaying form. Default is not to |
1044 | * display advanced elements in the form until 'Show Advanced' is pressed. |
1045 | * |
1046 | * You can get the last state of the form and possibly save it for this user by using |
1047 | * value 'mform_showadvanced_last' in submitted data. |
1048 | * |
1049 | * @param boolean $showadvancedNow |
1050 | */ |
1051 | function setShowAdvanced($showadvancedNow = null){ |
1052 | if ($showadvancedNow === null){ |
1053 | if ($this->_showAdvanced !== null){ |
1054 | return; |
1055 | } else { //if setShowAdvanced is called without any preference |
1056 | //make the default to not show advanced elements. |
f07b9627 |
1057 | $showadvancedNow = get_user_preferences( |
1058 | moodle_strtolower($this->_formName.'_showadvanced', 0)); |
a23f0aaf |
1059 | } |
a23f0aaf |
1060 | } |
1061 | //value of hidden element |
1062 | $hiddenLast = optional_param('mform_showadvanced_last', -1, PARAM_INT); |
1063 | //value of button |
1064 | $buttonPressed = optional_param('mform_showadvanced', 0, PARAM_RAW); |
1065 | //toggle if button pressed or else stay the same |
1066 | if ($hiddenLast == -1) { |
1067 | $next = $showadvancedNow; |
1068 | } elseif ($buttonPressed) { //toggle on button press |
1069 | $next = !$hiddenLast; |
1070 | } else { |
1071 | $next = $hiddenLast; |
1072 | } |
1073 | $this->_showAdvanced = $next; |
f07b9627 |
1074 | if ($showadvancedNow != $next){ |
1075 | set_user_preference($this->_formName.'_showadvanced', $next); |
1076 | } |
a23f0aaf |
1077 | $this->setConstants(array('mform_showadvanced_last'=>$next)); |
19194f82 |
1078 | } |
1079 | function getShowAdvanced(){ |
1080 | return $this->_showAdvanced; |
1081 | } |
1082 | |
19194f82 |
1083 | |
1084 | /** |
1085 | * Accepts a renderer |
1086 | * |
1087 | * @param HTML_QuickForm_Renderer An HTML_QuickForm_Renderer object |
1088 | * @since 3.0 |
1089 | * @access public |
1090 | * @return void |
1091 | */ |
46f3921e |
1092 | function accept(&$renderer) { |
19194f82 |
1093 | if (method_exists($renderer, 'setAdvancedElements')){ |
1094 | //check for visible fieldsets where all elements are advanced |
1095 | //and mark these headers as advanced as well. |
1096 | //And mark all elements in a advanced header as advanced |
1097 | $stopFields = $renderer->getStopFieldSetElements(); |
1098 | $lastHeader = null; |
1099 | $lastHeaderAdvanced = false; |
1100 | $anyAdvanced = false; |
1101 | foreach (array_keys($this->_elements) as $elementIndex){ |
1102 | $element =& $this->_elements[$elementIndex]; |
46f3921e |
1103 | |
1104 | // if closing header and any contained element was advanced then mark it as advanced |
19194f82 |
1105 | if ($element->getType()=='header' || in_array($element->getName(), $stopFields)){ |
46f3921e |
1106 | if ($anyAdvanced && !is_null($lastHeader)){ |
19194f82 |
1107 | $this->setAdvanced($lastHeader->getName()); |
1108 | } |
1109 | $lastHeaderAdvanced = false; |
46f3921e |
1110 | unset($lastHeader); |
1111 | $lastHeader = null; |
19194f82 |
1112 | } elseif ($lastHeaderAdvanced) { |
1113 | $this->setAdvanced($element->getName()); |
1114 | } |
46f3921e |
1115 | |
19194f82 |
1116 | if ($element->getType()=='header'){ |
1117 | $lastHeader =& $element; |
1118 | $anyAdvanced = false; |
1119 | $lastHeaderAdvanced = isset($this->_advancedElements[$element->getName()]); |
1120 | } elseif (isset($this->_advancedElements[$element->getName()])){ |
1121 | $anyAdvanced = true; |
1122 | } |
1123 | } |
46f3921e |
1124 | // the last header may not be closed yet... |
1125 | if ($anyAdvanced && !is_null($lastHeader)){ |
1126 | $this->setAdvanced($lastHeader->getName()); |
1127 | } |
19194f82 |
1128 | $renderer->setAdvancedElements($this->_advancedElements); |
19194f82 |
1129 | |
19194f82 |
1130 | } |
1131 | parent::accept($renderer); |
1132 | } |
1133 | |
19194f82 |
1134 | |
19194f82 |
1135 | |
1136 | function closeHeaderBefore($elementName){ |
1137 | $renderer =& $this->defaultRenderer(); |
1138 | $renderer->addStopFieldsetElements($elementName); |
da6f8763 |
1139 | } |
bb40325e |
1140 | |
da1320da |
1141 | /** |
1142 | * Should be used for all elements of a form except for select, radio and checkboxes which |
1143 | * clean their own data. |
1144 | * |
1145 | * @param string $elementname |
1146 | * @param integer $paramtype use the constants PARAM_*. |
1147 | * * PARAM_CLEAN is deprecated and you should try to use a more specific type. |
1148 | * * PARAM_TEXT should be used for cleaning data that is expected to be plain text. |
1149 | * It will strip all html tags. But will still let tags for multilang support |
1150 | * through. |
1151 | * * PARAM_RAW means no cleaning whatsoever, it is used mostly for data from the |
1152 | * html editor. Data from the editor is later cleaned before display using |
1153 | * format_text() function. PARAM_RAW can also be used for data that is validated |
1154 | * by some other way or printed by p() or s(). |
1155 | * * PARAM_INT should be used for integers. |
1156 | * * PARAM_ACTION is an alias of PARAM_ALPHA and is used for hidden fields specifying |
1157 | * form actions. |
1158 | */ |
7f40a229 |
1159 | function setType($elementname, $paramtype) { |
1160 | $this->_types[$elementname] = $paramtype; |
1161 | } |
49292f8c |
1162 | |
da1320da |
1163 | /** |
1164 | * See description of setType above. This can be used to set several types at once. |
1165 | * |
1166 | * @param array $paramtypes |
1167 | */ |
c56f1826 |
1168 | function setTypes($paramtypes) { |
1169 | $this->_types = $paramtypes + $this->_types; |
1170 | } |
49292f8c |
1171 | |
1172 | function updateSubmission($submission, $files) { |
1173 | $this->_flagSubmitted = false; |
1174 | |
7f40a229 |
1175 | if (empty($submission)) { |
1176 | $this->_submitValues = array(); |
7f40a229 |
1177 | } else { |
1178 | foreach ($submission as $key=>$s) { |
1179 | if (array_key_exists($key, $this->_types)) { |
1180 | $submission[$key] = clean_param($s, $this->_types[$key]); |
1181 | } |
1182 | } |
294ce987 |
1183 | $this->_submitValues = $submission; |
7f40a229 |
1184 | $this->_flagSubmitted = true; |
1185 | } |
1186 | |
49292f8c |
1187 | if (empty($files)) { |
1188 | $this->_submitFiles = array(); |
1189 | } else { |
49292f8c |
1190 | $this->_submitFiles = $files; |
1191 | $this->_flagSubmitted = true; |
1192 | } |
1193 | |
2c412890 |
1194 | // need to tell all elements that they need to update their value attribute. |
1195 | foreach (array_keys($this->_elements) as $key) { |
1196 | $this->_elements[$key]->onQuickFormEvent('updateValue', null, $this); |
1197 | } |
7f40a229 |
1198 | } |
1199 | |
da6f8763 |
1200 | function getReqHTML(){ |
1201 | return $this->_reqHTML; |
1202 | } |
7f40a229 |
1203 | |
19194f82 |
1204 | function getAdvancedHTML(){ |
1205 | return $this->_advancedHTML; |
1206 | } |
1207 | |
7f40a229 |
1208 | /** |
da1320da |
1209 | * Initializes a default form value. Used to specify the default for a new entry where |
beac4717 |
1210 | * no data is loaded in using moodleform::set_data() |
7f40a229 |
1211 | * |
294ce987 |
1212 | * note: $slashed param removed |
1213 | * |
7f40a229 |
1214 | * @param string $elementname element name |
1215 | * @param mixed $values values for that element name |
7f40a229 |
1216 | * @access public |
1217 | * @return void |
1218 | */ |
294ce987 |
1219 | function setDefault($elementName, $defaultValue){ |
1220 | $this->setDefaults(array($elementName=>$defaultValue)); |
7f40a229 |
1221 | } // end func setDefault |
da6f8763 |
1222 | /** |
c56f1826 |
1223 | * Add an array of buttons to the form |
7f40a229 |
1224 | * @param array $buttons An associative array representing help button to attach to |
da6f8763 |
1225 | * to the form. keys of array correspond to names of elements in form. |
7f40a229 |
1226 | * |
da6f8763 |
1227 | * @access public |
1228 | */ |
d4fe14d3 |
1229 | function setHelpButtons($buttons, $suppresscheck=false, $function='helpbutton'){ |
7f40a229 |
1230 | |
c56f1826 |
1231 | foreach ($buttons as $elementname => $button){ |
d4fe14d3 |
1232 | $this->setHelpButton($elementname, $button, $suppresscheck, $function); |
da6f8763 |
1233 | } |
1234 | } |
c56f1826 |
1235 | /** |
da1320da |
1236 | * Add a single button. |
c56f1826 |
1237 | * |
1238 | * @param string $elementname name of the element to add the item to |
d4fe14d3 |
1239 | * @param array $button - arguments to pass to function $function |
c56f1826 |
1240 | * @param boolean $suppresscheck - whether to throw an error if the element |
1241 | * doesn't exist. |
d4fe14d3 |
1242 | * @param string $function - function to generate html from the arguments in $button |
c56f1826 |
1243 | */ |
d4fe14d3 |
1244 | function setHelpButton($elementname, $button, $suppresscheck=false, $function='helpbutton'){ |
c56f1826 |
1245 | if (array_key_exists($elementname, $this->_elementIndex)){ |
1246 | //_elements has a numeric index, this code accesses the elements by name |
1247 | $element=&$this->_elements[$this->_elementIndex[$elementname]]; |
1248 | if (method_exists($element, 'setHelpButton')){ |
d4fe14d3 |
1249 | $element->setHelpButton($button, $function); |
c56f1826 |
1250 | }else{ |
1251 | $a=new object(); |
1252 | $a->name=$element->getName(); |
1253 | $a->classname=get_class($element); |
1254 | print_error('nomethodforaddinghelpbutton', 'form', '', $a); |
1255 | } |
1256 | }elseif (!$suppresscheck){ |
1257 | print_error('nonexistentformelements', 'form', '', $elementname); |
2c412890 |
1258 | } |
c56f1826 |
1259 | } |
7f40a229 |
1260 | |
cc444336 |
1261 | /** |
1262 | * Set constant value not overriden by _POST or _GET |
1263 | * note: this does not work for complex names with [] :-( |
1264 | * @param string $elname name of element |
1265 | * @param mixed $value |
1266 | * @return void |
1267 | */ |
1268 | function setConstant($elname, $value) { |
1269 | $this->_constantValues = HTML_QuickForm::arrayMerge($this->_constantValues, array($elname=>$value)); |
1270 | $element =& $this->getElement($elname); |
1271 | $element->onQuickFormEvent('updateValue', null, $this); |
1272 | } |
1273 | |
294ce987 |
1274 | function exportValues($elementList = null){ |
0ffb4cc7 |
1275 | $unfiltered = array(); |
1276 | if (null === $elementList) { |
1277 | // iterate over all elements, calling their exportValue() methods |
98af2d1d |
1278 | $emptyarray = array(); |
0ffb4cc7 |
1279 | foreach (array_keys($this->_elements) as $key) { |
1280 | if ($this->_elements[$key]->isFrozen() && !$this->_elements[$key]->_persistantFreeze){ |
98af2d1d |
1281 | $value = $this->_elements[$key]->exportValue($emptyarray, true); |
0ffb4cc7 |
1282 | } else { |
1283 | $value = $this->_elements[$key]->exportValue($this->_submitValues, true); |
1284 | } |
1285 | |
1286 | if (is_array($value)) { |
1287 | // This shit throws a bogus warning in PHP 4.3.x |
1288 | $unfiltered = HTML_QuickForm::arrayMerge($unfiltered, $value); |
1289 | } |
1290 | } |
1291 | } else { |
1292 | if (!is_array($elementList)) { |
1293 | $elementList = array_map('trim', explode(',', $elementList)); |
1294 | } |
1295 | foreach ($elementList as $elementName) { |
1296 | $value = $this->exportValue($elementName); |
1297 | if (PEAR::isError($value)) { |
1298 | return $value; |
1299 | } |
4287fc0d |
1300 | //oh, stock QuickFOrm was returning array of arrays! |
1301 | $unfiltered = HTML_QuickForm::arrayMerge($unfiltered, $value); |
0ffb4cc7 |
1302 | } |
1303 | } |
7f40a229 |
1304 | |
294ce987 |
1305 | return $unfiltered; |
da6f8763 |
1306 | } |
f07b9627 |
1307 | /** |
1308 | * Adds a validation rule for the given field |
1309 | * |
1310 | * If the element is in fact a group, it will be considered as a whole. |
1311 | * To validate grouped elements as separated entities, |
1312 | * use addGroupRule instead of addRule. |
1313 | * |
1314 | * @param string $element Form element name |
1315 | * @param string $message Message to display for invalid data |
1316 | * @param string $type Rule type, use getRegisteredRules() to get types |
1317 | * @param string $format (optional)Required for extra rule data |
1318 | * @param string $validation (optional)Where to perform validation: "server", "client" |
1319 | * @param boolean $reset Client-side validation: reset the form element to its original value if there is an error? |
1320 | * @param boolean $force Force the rule to be applied, even if the target form element does not exist |
1321 | * @since 1.0 |
1322 | * @access public |
1323 | * @throws HTML_QuickForm_Error |
1324 | */ |
1325 | function addRule($element, $message, $type, $format=null, $validation='server', $reset = false, $force = false) |
1326 | { |
1327 | parent::addRule($element, $message, $type, $format, $validation, $reset, $force); |
1328 | if ($validation == 'client') { |
1329 | $this->updateAttributes(array('onsubmit' => 'try { var myValidator = validate_' . $this->_formName . '; } catch(e) { return true; } return myValidator(this);')); |
1330 | } |
1331 | |
1332 | } // end func addRule |
1333 | /** |
1334 | * Adds a validation rule for the given group of elements |
1335 | * |
1336 | * Only groups with a name can be assigned a validation rule |
1337 | * Use addGroupRule when you need to validate elements inside the group. |
1338 | * Use addRule if you need to validate the group as a whole. In this case, |
1339 | * the same rule will be applied to all elements in the group. |
1340 | * Use addRule if you need to validate the group against a function. |
1341 | * |
1342 | * @param string $group Form group name |
1343 | * @param mixed $arg1 Array for multiple elements or error message string for one element |
1344 | * @param string $type (optional)Rule type use getRegisteredRules() to get types |
1345 | * @param string $format (optional)Required for extra rule data |
1346 | * @param int $howmany (optional)How many valid elements should be in the group |
1347 | * @param string $validation (optional)Where to perform validation: "server", "client" |
1348 | * @param bool $reset Client-side: whether to reset the element's value to its original state if validation failed. |
1349 | * @since 2.5 |
1350 | * @access public |
1351 | * @throws HTML_QuickForm_Error |
1352 | */ |
1353 | function addGroupRule($group, $arg1, $type='', $format=null, $howmany=0, $validation = 'server', $reset = false) |
1354 | { |
1355 | parent::addGroupRule($group, $arg1, $type, $format, $howmany, $validation, $reset); |
1356 | if (is_array($arg1)) { |
3a298174 |
1357 | foreach ($arg1 as $rules) { |
f07b9627 |
1358 | foreach ($rules as $rule) { |
1359 | $validation = (isset($rule[3]) && 'client' == $rule[3])? 'client': 'server'; |
1360 | |
1361 | if ('client' == $validation) { |
1362 | $this->updateAttributes(array('onsubmit' => 'try { var myValidator = validate_' . $this->_formName . '; } catch(e) { return true; } return myValidator(this);')); |
1363 | } |
1364 | } |
1365 | } |
1366 | } elseif (is_string($arg1)) { |
1367 | |
1368 | if ($validation == 'client') { |
3a298174 |
1369 | $this->updateAttributes(array('onsubmit' => 'try { var myValidator = validate_' . $this->_formName . '; } catch(e) { return true; } return myValidator(this);')); |
f07b9627 |
1370 | } |
1371 | } |
1372 | } // end func addGroupRule |
1373 | |
1374 | // }}} |
5bc97c98 |
1375 | /** |
1376 | * Returns the client side validation script |
1377 | * |
1378 | * The code here was copied from HTML_QuickForm_DHTMLRulesTableless who copied it from HTML_QuickForm |
1379 | * and slightly modified to run rules per-element |
1380 | * Needed to override this because of an error with client side validation of grouped elements. |
1381 | * |
1382 | * @access public |
1383 | * @return string Javascript to perform validation, empty string if no 'client' rules were added |
1384 | */ |
1385 | function getValidationScript() |
1386 | { |
1387 | if (empty($this->_rules) || empty($this->_attributes['onsubmit'])) { |
1388 | return ''; |
1389 | } |
1390 | |
1391 | include_once('HTML/QuickForm/RuleRegistry.php'); |
1392 | $registry =& HTML_QuickForm_RuleRegistry::singleton(); |
1393 | $test = array(); |
1394 | $js_escape = array( |
1395 | "\r" => '\r', |
1396 | "\n" => '\n', |
1397 | "\t" => '\t', |
1398 | "'" => "\\'", |
1399 | '"' => '\"', |
1400 | '\\' => '\\\\' |
1401 | ); |
1402 | |
1403 | foreach ($this->_rules as $elementName => $rules) { |
1404 | foreach ($rules as $rule) { |
1405 | if ('client' == $rule['validation']) { |
da1320da |
1406 | unset($element); //TODO: find out how to properly initialize it |
5bc97c98 |
1407 | |
1408 | $dependent = isset($rule['dependent']) && is_array($rule['dependent']); |
1409 | $rule['message'] = strtr($rule['message'], $js_escape); |
1410 | |
1411 | if (isset($rule['group'])) { |
1412 | $group =& $this->getElement($rule['group']); |
1413 | // No JavaScript validation for frozen elements |
1414 | if ($group->isFrozen()) { |
1415 | continue 2; |
1416 | } |
1417 | $elements =& $group->getElements(); |
1418 | foreach (array_keys($elements) as $key) { |
1419 | if ($elementName == $group->getElementName($key)) { |
1420 | $element =& $elements[$key]; |
1421 | break; |
1422 | } |
1423 | } |
1424 | } elseif ($dependent) { |
1425 | $element = array(); |
1426 | $element[] =& $this->getElement($elementName); |
3a298174 |
1427 | foreach ($rule['dependent'] as $elName) { |
5bc97c98 |
1428 | $element[] =& $this->getElement($elName); |
1429 | } |
1430 | } else { |
1431 | $element =& $this->getElement($elementName); |
1432 | } |
1433 | // No JavaScript validation for frozen elements |
1434 | if (is_object($element) && $element->isFrozen()) { |
1435 | continue 2; |
1436 | } elseif (is_array($element)) { |
1437 | foreach (array_keys($element) as $key) { |
1438 | if ($element[$key]->isFrozen()) { |
1439 | continue 3; |
1440 | } |
1441 | } |
1442 | } |
1443 | // Fix for bug displaying errors for elements in a group |
1444 | //$test[$elementName][] = $registry->getValidationScript($element, $elementName, $rule); |
1445 | $test[$elementName][0][] = $registry->getValidationScript($element, $elementName, $rule); |
1446 | $test[$elementName][1]=$element; |
1447 | //end of fix |
1448 | } |
1449 | } |
1450 | } |
7c77033f |
1451 | |
1452 | // Fix for MDL-9524. If you don't do this, then $element may be left as a reference to one of the fields in |
1453 | // the form, and then that form field gets corrupted by the code that follows. |
1454 | unset($element); |
1455 | |
5bc97c98 |
1456 | $js = ' |
1457 | <script type="text/javascript"> |
1458 | //<![CDATA[ |
1cbb09f1 |
1459 | |
1460 | var skipClientValidation = false; |
1461 | |
5bc97c98 |
1462 | function qf_errorHandler(element, _qfMsg) { |
1463 | div = element.parentNode; |
1464 | if (_qfMsg != \'\') { |
e35c9eeb |
1465 | var errorSpan = document.getElementById(\'id_error_\'+element.name); |
e7004d05 |
1466 | if (!errorSpan) { |
1467 | errorSpan = document.createElement("span"); |
e35c9eeb |
1468 | errorSpan.id = \'id_error_\'+element.name; |
1469 | errorSpan.className = "error"; |
fed13a5e |
1470 | element.parentNode.insertBefore(errorSpan, element.parentNode.firstChild); |
5bc97c98 |
1471 | } |
fed13a5e |
1472 | |
e7004d05 |
1473 | while (errorSpan.firstChild) { |
1474 | errorSpan.removeChild(errorSpan.firstChild); |
5bc97c98 |
1475 | } |
2c412890 |
1476 | |
e7004d05 |
1477 | errorSpan.appendChild(document.createTextNode(_qfMsg.substring(3))); |
e35c9eeb |
1478 | errorSpan.appendChild(document.createElement("br")); |
5bc97c98 |
1479 | |
1480 | if (div.className.substr(div.className.length - 6, 6) != " error" |
1481 | && div.className != "error") { |
1482 | div.className += " error"; |
1483 | } |
1484 | |
1485 | return false; |
1486 | } else { |
e35c9eeb |
1487 | var errorSpan = document.getElementById(\'id_error_\'+element.name); |
e7004d05 |
1488 | if (errorSpan) { |
1489 | errorSpan.parentNode.removeChild(errorSpan); |
5bc97c98 |
1490 | } |
1491 | |
1492 | if (div.className.substr(div.className.length - 6, 6) == " error") { |
1493 | div.className = div.className.substr(0, div.className.length - 6); |
1494 | } else if (div.className == "error") { |
1495 | div.className = ""; |
1496 | } |
1497 | |
1498 | return true; |
1499 | } |
1500 | }'; |
1501 | $validateJS = ''; |
1502 | foreach ($test as $elementName => $jsandelement) { |
1503 | // Fix for bug displaying errors for elements in a group |
1504 | //unset($element); |
1505 | list($jsArr,$element)=$jsandelement; |
1506 | //end of fix |
1507 | $js .= ' |
f07b9627 |
1508 | function validate_' . $this->_formName . '_' . $elementName . '(element) { |
5bc97c98 |
1509 | var value = \'\'; |
1510 | var errFlag = new Array(); |
1511 | var _qfGroups = {}; |
1512 | var _qfMsg = \'\'; |
1513 | var frm = element.parentNode; |
cd350b53 |
1514 | while (frm && frm.nodeName.toUpperCase() != "FORM") { |
5bc97c98 |
1515 | frm = frm.parentNode; |
1516 | } |
1517 | ' . join("\n", $jsArr) . ' |
1518 | return qf_errorHandler(element, _qfMsg); |
1519 | } |
1520 | '; |
1521 | $validateJS .= ' |
2ef7c374 |
1522 | ret = validate_' . $this->_formName . '_' . $elementName.'(frm.elements[\''.$elementName.'\']) && ret; |
1523 | if (!ret && !first_focus) { |
1524 | first_focus = true; |
1525 | frm.elements[\''.$elementName.'\'].focus(); |
1526 | } |
1527 | '; |
4f51f48f |
1528 | |
5bc97c98 |
1529 | // Fix for bug displaying errors for elements in a group |
1530 | //unset($element); |
1531 | //$element =& $this->getElement($elementName); |
1532 | //end of fix |
f07b9627 |
1533 | $valFunc = 'validate_' . $this->_formName . '_' . $elementName . '(this)'; |
5bc97c98 |
1534 | $onBlur = $element->getAttribute('onBlur'); |
1535 | $onChange = $element->getAttribute('onChange'); |
1536 | $element->updateAttributes(array('onBlur' => $onBlur . $valFunc, |
1537 | 'onChange' => $onChange . $valFunc)); |
1538 | } |
e7004d05 |
1539 | // do not rely on frm function parameter, because htmlarea breaks it when overloading the onsubmit method |
5bc97c98 |
1540 | $js .= ' |
f07b9627 |
1541 | function validate_' . $this->_formName . '(frm) { |
1cbb09f1 |
1542 | if (skipClientValidation) { |
1543 | return true; |
1544 | } |
5bc97c98 |
1545 | var ret = true; |
4f51f48f |
1546 | |
0befbdfd |
1547 | var frm = document.getElementById(\''. $this->_attributes['id'] .'\') |
2ef7c374 |
1548 | var first_focus = false; |
5bc97c98 |
1549 | ' . $validateJS . '; |
1550 | return ret; |
1551 | } |
1552 | //]]> |
1553 | </script>'; |
1554 | return $js; |
1555 | } // end func getValidationScript |
1556 | function _setDefaultRuleMessages(){ |
1557 | foreach ($this->_rules as $field => $rulesarr){ |
1558 | foreach ($rulesarr as $key => $rule){ |
1559 | if ($rule['message']===null){ |
1560 | $a=new object(); |
1561 | $a->format=$rule['format']; |
1562 | $str=get_string('err_'.$rule['type'], 'form', $a); |
1563 | if (strpos($str, '[[')!==0){ |
1564 | $this->_rules[$field][$key]['message']=$str; |
2c412890 |
1565 | } |
5bc97c98 |
1566 | } |
1567 | } |
1568 | } |
1569 | } |
bb40325e |
1570 | |
d01a38cb |
1571 | function getLockOptionEndScript(){ |
dd07bbac |
1572 | |
1573 | $iname = $this->getAttribute('id').'items'; |
f4ba7e1a |
1574 | $js = '<script type="text/javascript">'."\n"; |
5e87b920 |
1575 | $js .= '//<![CDATA['."\n"; |
dd07bbac |
1576 | $js .= "var $iname = Array();\n"; |
1577 | |
1578 | foreach ($this->_dependencies as $dependentOn => $conditions){ |
1579 | $js .= "{$iname}['$dependentOn'] = Array();\n"; |
1580 | foreach ($conditions as $condition=>$values) { |
1581 | $js .= "{$iname}['$dependentOn']['$condition'] = Array();\n"; |
1582 | foreach ($values as $value=>$dependents) { |
1583 | $js .= "{$iname}['$dependentOn']['$condition']['$value'] = Array();\n"; |
1584 | $i = 0; |
1585 | foreach ($dependents as $dependent) { |
1586 | $elements = $this->_getElNamesRecursive($dependent); |
46f3921e |
1587 | if (empty($elements)) { |
1588 | // probably element inside of some group |
1589 | $elements = array($dependent); |
1590 | } |
dd07bbac |
1591 | foreach($elements as $element) { |
1592 | if ($element == $dependentOn) { |
1593 | continue; |
1594 | } |
1595 | $js .= "{$iname}['$dependentOn']['$condition']['$value'][$i]='$element';\n"; |
1596 | $i++; |
1597 | } |
11f260f4 |
1598 | } |
1599 | } |
50ef8eb9 |
1600 | } |
dd07bbac |
1601 | } |
d01a38cb |
1602 | $js .="lockoptionsallsetup('".$this->getAttribute('id')."');\n"; |
5e87b920 |
1603 | $js .='//]]>'."\n"; |
50ef8eb9 |
1604 | $js .='</script>'."\n"; |
1605 | return $js; |
bb40325e |
1606 | } |
d01a38cb |
1607 | |
46f3921e |
1608 | function _getElNamesRecursive($element) { |
1609 | if (is_string($element)) { |
4f51f48f |
1610 | if (!$this->elementExists($element)) { |
1611 | return array(); |
1612 | } |
46f3921e |
1613 | $element = $this->getElement($element); |
d01a38cb |
1614 | } |
46f3921e |
1615 | |
1616 | if (is_a($element, 'HTML_QuickForm_group')) { |
1617 | $elsInGroup = $element->getElements(); |
9403060a |
1618 | $elNames = array(); |
d01a38cb |
1619 | foreach ($elsInGroup as $elInGroup){ |
e850ec48 |
1620 | if (is_a($elInGroup, 'HTML_QuickForm_group')) { |
1621 | // not sure if this would work - groups nested in groups |
1622 | $elNames = array_merge($elNames, $this->_getElNamesRecursive($elInGroup)); |
1623 | } else { |
1624 | $elNames[] = $element->getElementName($elInGroup->getName()); |
1625 | } |
d01a38cb |
1626 | } |
46f3921e |
1627 | |
1628 | } else if (is_a($element, 'HTML_QuickForm_header')) { |
1629 | return array(); |
1630 | |
1631 | } else if (is_a($element, 'HTML_QuickForm_hidden')) { |
1632 | return array(); |
1633 | |
1634 | } else if (method_exists($element, 'getPrivateName')) { |
1635 | return array($element->getPrivateName()); |
1636 | |
1637 | } else { |
1638 | $elNames = array($element->getName()); |
d01a38cb |
1639 | } |
d01a38cb |
1640 | |
46f3921e |
1641 | return $elNames; |
50ef8eb9 |
1642 | } |
46f3921e |
1643 | |
6e372b25 |
1644 | /** |
1645 | * Adds a dependency for $elementName which will be disabled if $condition is met. |
9403060a |
1646 | * If $condition = 'notchecked' (default) then the condition is that the $dependentOn element |
1647 | * is not checked. If $condition = 'checked' then the condition is that the $dependentOn element |
31a6c06c |
1648 | * is checked. If $condition is something else (like "eq" for equals) then it is checked to see if the value |
1649 | * of the $dependentOn element is $condition (such as equal) to $value. |
6e372b25 |
1650 | * |
1651 | * @param string $elementName the name of the element which will be disabled |
1652 | * @param string $dependentOn the name of the element whose state will be checked for |
1653 | * condition |
1654 | * @param string $condition the condition to check |
19110c57 |
1655 | * @param mixed $value used in conjunction with condition. |
6e372b25 |
1656 | */ |
dd07bbac |
1657 | function disabledIf($elementName, $dependentOn, $condition = 'notchecked', $value='1'){ |
1658 | if (!array_key_exists($dependentOn, $this->_dependencies)) { |
1659 | $this->_dependencies[$dependentOn] = array(); |
1660 | } |
1661 | if (!array_key_exists($condition, $this->_dependencies[$dependentOn])) { |
1662 | $this->_dependencies[$dependentOn][$condition] = array(); |
1663 | } |
1664 | if (!array_key_exists($value, $this->_dependencies[$dependentOn][$condition])) { |
1665 | $this->_dependencies[$dependentOn][$condition][$value] = array(); |
1666 | } |
1667 | $this->_dependencies[$dependentOn][$condition][$value][] = $elementName; |
bb40325e |
1668 | } |
dd07bbac |
1669 | |
a23f0aaf |
1670 | function registerNoSubmitButton($buttonname){ |
1671 | $this->_noSubmitButtons[]=$buttonname; |
1672 | } |
dd07bbac |
1673 | |
a23f0aaf |
1674 | function isNoSubmitButton($buttonname){ |
1675 | return (array_search($buttonname, $this->_noSubmitButtons)!==FALSE); |
19110c57 |
1676 | } |
dd07bbac |
1677 | |
19110c57 |
1678 | function _registerCancelButton($addfieldsname){ |
1679 | $this->_cancelButtons[]=$addfieldsname; |
1680 | } |
acc9c3e0 |
1681 | /** |
1682 | * Displays elements without HTML input tags. |
1683 | * This method is different to freeze() in that it makes sure no hidden |
cc444336 |
1684 | * elements are included in the form. |
1685 | * Note: If you want to make sure the submitted value is ignored, please use setDefaults(). |
acc9c3e0 |
1686 | * |
4af06dda |
1687 | * This function also removes all previously defined rules. |
1688 | * |
acc9c3e0 |
1689 | * @param mixed $elementList array or string of element(s) to be frozen |
1690 | * @since 1.0 |
1691 | * @access public |
1692 | * @throws HTML_QuickForm_Error |
1693 | */ |
1694 | function hardFreeze($elementList=null) |
1695 | { |
1696 | if (!isset($elementList)) { |
1697 | $this->_freezeAll = true; |
1698 | $elementList = array(); |
1699 | } else { |
1700 | if (!is_array($elementList)) { |
1701 | $elementList = preg_split('/[ ]*,[ ]*/', $elementList); |
1702 | } |
1703 | $elementList = array_flip($elementList); |
1704 | } |
1705 | |
1706 | foreach (array_keys($this->_elements) as $key) { |
1707 | $name = $this->_elements[$key]->getName(); |
1708 | if ($this->_freezeAll || isset($elementList[$name])) { |
1709 | $this->_elements[$key]->freeze(); |
1710 | $this->_elements[$key]->setPersistantFreeze(false); |
1711 | unset($elementList[$name]); |
4af06dda |
1712 | |
1713 | // remove all rules |
1714 | $this->_rules[$name] = array(); |
1715 | // if field is required, remove the rule |
1716 | $unset = array_search($name, $this->_required); |
1717 | if ($unset !== false) { |
1718 | unset($this->_required[$unset]); |
1719 | } |
acc9c3e0 |
1720 | } |
1721 | } |
1722 | |
1723 | if (!empty($elementList)) { |
1724 | return PEAR::raiseError(null, QUICKFORM_NONEXIST_ELEMENT, null, E_USER_WARNING, "Nonexistant element(s): '" . implode("', '", array_keys($elementList)) . "' in HTML_QuickForm::freeze()", 'HTML_QuickForm_Error', true); |
1725 | } |
1726 | return true; |
4f51f48f |
1727 | } |
1728 | /** |
1729 | * Hard freeze all elements in a form except those whose names are in $elementList or hidden elements in a form. |
1730 | * |
1731 | * This function also removes all previously defined rules of elements it freezes. |
1732 | * |
1733 | * @param array $elementList array or string of element(s) not to be frozen |
1734 | * @since 1.0 |
1735 | * @access public |
1736 | * @throws HTML_QuickForm_Error |
1737 | */ |
1738 | function hardFreezeAllVisibleExcept($elementList) |
1739 | { |
1740 | $elementList = array_flip($elementList); |
1741 | foreach (array_keys($this->_elements) as $key) { |
1742 | $name = $this->_elements[$key]->getName(); |
1743 | $type = $this->_elements[$key]->getType(); |
56015454 |
1744 | |
4f51f48f |
1745 | if ($type == 'hidden'){ |
1746 | // leave hidden types as they are |
1747 | } elseif (!isset($elementList[$name])) { |
1748 | $this->_elements[$key]->freeze(); |
1749 | $this->_elements[$key]->setPersistantFreeze(false); |
1750 | |
1751 | // remove all rules |
1752 | $this->_rules[$name] = array(); |
1753 | // if field is required, remove the rule |
1754 | $unset = array_search($name, $this->_required); |
1755 | if ($unset !== false) { |
1756 | unset($this->_required[$unset]); |
1757 | } |
1758 | } |
1759 | } |
1760 | return true; |
1761 | } |
1762 | /** |
1763 | * Tells whether the form was already submitted |
1764 | * |
1765 | * This is useful since the _submitFiles and _submitValues arrays |
1766 | * may be completely empty after the trackSubmit value is removed. |
1767 | * |
1768 | * @access public |
1769 | * @return bool |
1770 | */ |
1771 | function isSubmitted() |
1772 | { |
1773 | return parent::isSubmitted() && (!$this->isFrozen()); |
1774 | } |
da6f8763 |
1775 | } |
1776 | |
e24b7f85 |
1777 | |
da6f8763 |
1778 | /** |
7f40a229 |
1779 | * A renderer for MoodleQuickForm that only uses XHTML and CSS and no |
da6f8763 |
1780 | * table tags, extends PEAR class HTML_QuickForm_Renderer_Tableless |
7f40a229 |
1781 | * |
da6f8763 |
1782 | * Stylesheet is part of standard theme and should be automatically included. |
1783 | * |
1784 | * @author Jamie Pratt <me@jamiep.org> |
1785 | * @license gpl license |
1786 | */ |
7f40a229 |
1787 | class MoodleQuickForm_Renderer extends HTML_QuickForm_Renderer_Tableless{ |
da6f8763 |
1788 | |
1789 | /** |
1790 | * Element template array |
1791 | * @var array |
1792 | * @access private |
1793 | */ |
1794 | var $_elementTemplates; |
49c53687 |
1795 | /** |
1796 | * Template used when opening a hidden fieldset |
1797 | * (i.e. a fieldset that is opened when there is no header element) |
1798 | * @var string |
1799 | * @access private |
1800 | */ |
c02345e3 |
1801 | var $_openHiddenFieldsetTemplate = "\n\t<fieldset class=\"hidden\"><div>"; |
19194f82 |
1802 | /** |
1803 | * Header Template string |
1804 | * @var string |
1805 | * @access private |
1806 | */ |
1807 | var $_headerTemplate = |
c02345e3 |
1808 | "\n\t\t<legend class=\"ftoggler\">{header}</legend>\n\t\t<div class=\"advancedbutton\">{advancedimg}{button}</div><div class=\"fcontainer clearfix\">\n\t\t"; |
7f40a229 |
1809 | |
49c53687 |
1810 | /** |
bc9ec4a6 |
1811 | * Template used when opening a fieldset |
1812 | * @var string |
1813 | * @access private |
1814 | */ |
1815 | var $_openFieldsetTemplate = "\n\t<fieldset class=\"clearfix\" {id}>"; |
1816 | |
1817 | /** |
49c53687 |
1818 | * Template used when closing a fieldset |
1819 | * @var string |
1820 | * @access private |
1821 | */ |
c02345e3 |
1822 | var $_closeFieldsetTemplate = "\n\t\t</div></fieldset>"; |
42f248e6 |
1823 | |
49c53687 |
1824 | /** |
1825 | * Required Note template string |
1826 | * @var string |
1827 | * @access private |
1828 | */ |
7f40a229 |
1829 | var $_requiredNoteTemplate = |
6ba2c73d |
1830 | "\n\t\t<div class=\"fdescription required\">{requiredNote}</div>"; |
7f40a229 |
1831 | |
19194f82 |
1832 | var $_advancedElements = array(); |
1833 | |
1834 | /** |
1835 | * Whether to display advanced elements (on page load) |
1836 | * |
1837 | * @var integer 1 means show 0 means hide |
1838 | */ |
1839 | var $_showAdvanced; |
1840 | |
7f40a229 |
1841 | function MoodleQuickForm_Renderer(){ |
42f248e6 |
1842 | // switch next two lines for ol li containers for form items. |
49c7f3a8 |
1843 | // $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>'); |
9aa022fe |
1844 | $this->_elementTemplates = array( |
f8b9ac74 |
1845 | 'default'=>"\n\t\t".'<div class="fitem {advanced}<!-- BEGIN required --> required<!-- END required -->"><div class="fitemtitle"><label>{label}<!-- BEGIN required -->{req}<!-- END required -->{advancedimg} {help}</label></div><div class="felement {type}<!-- BEGIN error --> error<!-- END error -->"><!-- BEGIN error --><span class="error">{error}</span><br /><!-- END error -->{element}</div></div>', |
49c7f3a8 |
1846 | |
f9f9be73 |
1847 | 'fieldset'=>"\n\t\t".'<div class="fitem {advanced}<!-- BEGIN required --> required<!-- END required -->"><div class="fitemtitle"><div class="fgrouplabel"><label>{label}<!-- BEGIN required -->{req}<!-- END required -->{advancedimg} {help}</label></div></div><fieldset class="felement {type}<!-- BEGIN error --> error<!-- END error -->"><!-- BEGIN error --><span class="error">{error}</span><br /><!-- END error -->{element}</fieldset></div>', |
4f51f48f |
1848 | |
f9f9be73 |
1849 | 'static'=>"\n\t\t".'<div class="fitem {advanced}"><div class="fitemtitle"><div class="fstaticlabel"><label>{label}<!-- BEGIN required -->{req}<!-- END required -->{advancedimg} {help}</label></div></div><div class="felement fstatic <!-- BEGIN error --> error<!-- END error -->"><!-- BEGIN error --><span class="error">{error}</span><br /><!-- END error -->{element} </div></div>', |
43914931 |
1850 | |
1ae1941e |
1851 | 'warning'=>"\n\t\t".'<div class="fitem {advanced}">{element}</div>', |
1852 | |
4f51f48f |
1853 | 'nodisplay'=>''); |
da6f8763 |
1854 | |
1855 | parent::HTML_QuickForm_Renderer_Tableless(); |
1856 | } |
7f40a229 |
1857 | |
19194f82 |
1858 | function setAdvancedElements($elements){ |
1859 | $this->_advancedElements = $elements; |
1860 | } |
1861 | |
1862 | /** |
1863 | * What to do when starting the form |
1864 | * |
1865 | * @param MoodleQuickForm $form |
1866 | */ |
da6f8763 |
1867 | function startForm(&$form){ |
9403060a |
1868 | $this->_reqHTML = $form->getReqHTML(); |
1869 | $this->_elementTemplates = str_replace('{req}', $this->_reqHTML, $this->_elementTemplates); |
19194f82 |
1870 | $this->_advancedHTML = $form->getAdvancedHTML(); |
1871 | $this->_showAdvanced = $form->getShowAdvanced(); |
da6f8763 |
1872 | parent::startForm($form); |
4f51f48f |
1873 | if ($form->isFrozen()){ |
1874 | $this->_formTemplate = "\n<div class=\"mform frozen\">\n{content}\n</div>"; |
1875 | } else { |
1876 | $this->_hiddenHtml .= $form->_pageparams; |
1877 | } |
1878 | |
1879 | |
da6f8763 |
1880 | } |
7f40a229 |
1881 | |
da6f8763 |
1882 | function startGroup(&$group, $required, $error){ |
1883 | if (method_exists($group, 'getElementTemplateType')){ |
e249661f |
1884 | $html = $this->_elementTemplates[$group->getElementTemplateType()]; |
da6f8763 |
1885 | }else{ |
1886 | $html = $this->_elementTemplates['default']; |
7f40a229 |
1887 | |
da6f8763 |
1888 | } |
19194f82 |
1889 | if ($this->_showAdvanced){ |
1890 | $advclass = ' advanced'; |
1891 | } else { |
1892 | $advclass = ' advanced hide'; |
1893 | } |
1894 | if (isset($this->_advancedElements[$group->getName()])){ |
1895 | $html =str_replace(' {advanced}', $advclass, $html); |
1896 | $html =str_replace('{advancedimg}', $this->_advancedHTML, $html); |
1897 | } else { |
1898 | $html =str_replace(' {advanced}', '', $html); |
1899 | $html =str_replace('{advancedimg}', '', $html); |
1900 | } |
da6f8763 |
1901 | if (method_exists($group, 'getHelpButton')){ |
1902 | $html =str_replace('{help}', $group->getHelpButton(), $html); |
1903 | }else{ |
1904 | $html =str_replace('{help}', '', $html); |
da6f8763 |
1905 | } |
e7004d05 |
1906 | $html =str_replace('{name}', $group->getName(), $html); |
49c53687 |
1907 | $html =str_replace('{type}', 'fgroup', $html); |
7f40a229 |
1908 | |
da6f8763 |
1909 | $this->_templates[$group->getName()]=$html; |
1910 | // Fix for bug in tableless quickforms that didn't allow you to stop a |
1911 | // fieldset before a group of elements. |
1912 | // if the element name indicates the end of a fieldset, close the fieldset |
1913 | if ( in_array($group->getName(), $this->_stopFieldsetElements) |
1914 | && $this->_fieldsetsOpen > 0 |
1915 | ) { |
1916 | $this->_html .= $this->_closeFieldsetTemplate; |
1917 | $this->_fieldsetsOpen--; |
1918 | } |
1919 | parent::startGroup($group, $required, $error); |
1920 | } |
7f40a229 |
1921 | |
da6f8763 |
1922 | function renderElement(&$element, $required, $error){ |
172dd12c |
1923 | //manipulate id of all elements before rendering |
86aab05c |
1924 | if (!is_null($element->getAttribute('id'))) { |
1925 | $id = $element->getAttribute('id'); |
1926 | } else { |
1927 | $id = $element->getName(); |
1928 | } |
1929 | //strip qf_ prefix and replace '[' with '_' and strip ']' |
1930 | $id = preg_replace(array('/^qf_|\]/', '/\[/'), array('', '_'), $id); |
1931 | if (strpos($id, 'id_') !== 0){ |
1932 | $element->updateAttributes(array('id'=>'id_'.$id)); |
1933 | } |
1934 | |
1935 | //adding stuff to place holders in template |
172dd12c |
1936 | //check if this is a group element first |
906ebc4b |
1937 | if (($this->_inGroup) and !empty($this->_groupElementTemplate)) { |
3493eb15 |
1938 | // so it gets substitutions for *each* element |
1ae1941e |
1939 | $html = $this->_groupTemplates[$element->getName()]; |
906ebc4b |
1940 | } |
1941 | elseif (method_exists($element, 'getElementTemplateType')){ |
da6f8763 |
1942 | $html = $this->_elementTemplates[$element->getElementTemplateType()]; |
1943 | }else{ |
1944 | $html = $this->_elementTemplates['default']; |
19194f82 |
1945 | } |
1946 | if ($this->_showAdvanced){ |
1947 | $advclass = ' advanced'; |
1948 | } else { |
1949 | $advclass = ' advanced hide'; |
1950 | } |
1951 | if (isset($this->_advancedElements[$element->getName()])){ |
1952 | $html =str_replace(' {advanced}', $advclass, $html); |
1953 | } else { |
1954 | $html =str_replace(' {advanced}', '', $html); |
1955 | } |
1956 | if (isset($this->_advancedElements[$element->getName()])||$element->getName() == 'mform_showadvanced'){ |
1957 | $html =str_replace('{advancedimg}', $this->_advancedHTML, $html); |
1958 | } else { |
1959 | $html =str_replace('{advancedimg}', '', $html); |
da6f8763 |
1960 | } |
49c53687 |
1961 | $html =str_replace('{type}', 'f'.$element->getType(), $html); |
e7004d05 |
1962 | $html =str_replace('{name}', $element->getName(), $html); |
da6f8763 |
1963 | if (method_exists($element, 'getHelpButton')){ |
9403060a |
1964 | $html = str_replace('{help}', $element->getHelpButton(), $html); |
da6f8763 |
1965 | }else{ |
9403060a |
1966 | $html = str_replace('{help}', '', $html); |
7f40a229 |
1967 | |
da6f8763 |
1968 | } |
906ebc4b |
1969 | if (($this->_inGroup) and !empty($this->_groupElementTemplate)) { |
1970 | $this->_groupElementTemplate = $html; |
41b6d001 |
1971 | } |
906ebc4b |
1972 | elseif (!isset($this->_templates[$element->getName()])) { |
1973 | $this->_templates[$element->getName()] = $html; |
172dd12c |
1974 | } |
1975 | |
da6f8763 |
1976 | parent::renderElement($element, $required, $error); |
1977 | } |
19194f82 |
1978 | |
bb40325e |
1979 | function finishForm(&$form){ |
4f51f48f |
1980 | if ($form->isFrozen()){ |
1981 | $this->_hiddenHtml = ''; |
1982 | } |
bb40325e |
1983 | parent::finishForm($form); |
4f51f48f |
1984 | if ((!$form->isFrozen()) && ('' != ($script = $form->getLockOptionEndScript()))) { |
1985 | // add a lockoptions script |
bb40325e |
1986 | $this->_html = $this->_html . "\n" . $script; |
1987 | } |
1988 | } |
19194f82 |
1989 | /** |
1990 | * Called when visiting a header element |
1991 | * |
1992 | * @param object An HTML_QuickForm_header element being visited |
1993 | * @access public |
1994 | * @return void |
1995 | */ |
1996 | function renderHeader(&$header) { |
1997 | $name = $header->getName(); |
1998 | |
1999 | $id = empty($name) ? '' : ' id="' . $name . '"'; |
78354cec |
2000 | $id = preg_replace(array('/\]/', '/\[/'), array('', '_'), $id); |
19194f82 |
2001 | if (is_null($header->_text)) { |
2002 | $header_html = ''; |
2003 | } elseif (!empty($name) && isset($this->_templates[$name])) { |
2004 | $header_html = str_replace('{header}', $header->toHtml(), $this->_templates[$name]); |
2005 | } else { |
2006 | $header_html = str_replace('{header}', $header->toHtml(), $this->_headerTemplate); |
2007 | } |
2008 | |
2009 | if (isset($this->_advancedElements[$name])){ |
2010 | $header_html =str_replace('{advancedimg}', $this->_advancedHTML, $header_html); |
2011 | } else { |
2012 | $header_html =str_replace('{advancedimg}', '', $header_html); |
2013 | } |
2014 | $elementName='mform_showadvanced'; |
2015 | if ($this->_showAdvanced==0){ |
2016 | $buttonlabel = get_string('showadvanced', 'form'); |
2017 | } else { |
2018 | $buttonlabel = get_string('hideadvanced', 'form'); |
2019 | } |
2020 | |
2021 | if (isset($this->_advancedElements[$name])){ |
cd350b53 |
2022 | require_js(array('yui_yahoo', 'yui_event')); |
7c9b1d31 |
2023 | // this is tricky - the first submit button on form is "clicked" if user presses enter |
2024 | // we do not want to "submit" using advanced button if javascript active |
7c9b1d31 |
2025 | $button_nojs = '<input name="'.$elementName.'" value="'.$buttonlabel.'" type="submit" />'; |
cd350b53 |
2026 | |
2027 | $buttonlabel = addslashes_js($buttonlabel); |
2028 | $showtext = addslashes_js(get_string('showadvanced', 'form')); |
2029 | $hidetext = addslashes_js(get_string('hideadvanced', 'form')); |
2030 | $button = '<script id="' . $name . '_script" type="text/javascript">' . " |
2031 | showAdvancedInit('{$name}_script', '$elementName', '$buttonlabel', '$hidetext', '$showtext'); |
2032 | " . '</script><noscript><div style="display:inline">'.$button_nojs.'</div></noscript>'; // the extra div should fix xhtml validation |
172dd12c |
2033 | |
7c9b1d31 |
2034 | $header_html = str_replace('{button}', $button, $header_html); |
19194f82 |
2035 | } else { |
7c9b1d31 |
2036 | $header_html = str_replace('{button}', '', $header_html); |
19194f82 |
2037 | } |
2038 | |
2039 | if ($this->_fieldsetsOpen > 0) { |
2040 | $this->_html .= $this->_closeFieldsetTemplate; |
2041 | $this->_fieldsetsOpen--; |
2042 | } |
2043 | |
2044 | $openFieldsetTemplate = str_replace('{id}', $id, $this->_openFieldsetTemplate); |
2045 | if ($this->_showAdvanced){ |
2046 | $advclass = ' class="advanced"'; |
2047 | } else { |
2048 | $advclass = ' class="advanced hide"'; |
2049 | } |
2050 | if (isset($this->_advancedElements[$name])){ |
2051 | $openFieldsetTemplate = str_replace('{advancedclass}', $advclass, $openFieldsetTemplate); |
2052 | } else { |
2053 | $openFieldsetTemplate = str_replace('{advancedclass}', '', $openFieldsetTemplate); |
2054 | } |
2055 | $this->_html .= $openFieldsetTemplate . $header_html; |
2056 | $this->_fieldsetsOpen++; |
2057 | } // end func renderHeader |
2058 | |
2059 | function getStopFieldsetElements(){ |
2060 | return $this->_stopFieldsetElements; |
2061 | } |
da6f8763 |
2062 | } |
2063 | |
da6f8763 |
2064 | |
9403060a |
2065 | $GLOBALS['_HTML_QuickForm_default_renderer'] =& new MoodleQuickForm_Renderer(); |
da6f8763 |
2066 | |
c583482c |
2067 | // Please keep this list in alphabetical order. |
2068 | MoodleQuickForm::registerElementType('advcheckbox', "$CFG->libdir/form/advcheckbox.php", 'MoodleQuickForm_advcheckbox'); |
2069 | MoodleQuickForm::registerElementType('button', "$CFG->libdir/form/button.php", 'MoodleQuickForm_button'); |
2070 | MoodleQuickForm::registerElementType('cancel', "$CFG->libdir/form/cancel.php", 'MoodleQuickForm_cancel'); |
7f40a229 |
2071 | MoodleQuickForm::registerElementType('checkbox', "$CFG->libdir/form/checkbox.php", 'MoodleQuickForm_checkbox'); |
c583482c |
2072 | MoodleQuickForm::registerElementType('choosecoursefile', "$CFG->libdir/form/choosecoursefile.php", 'MoodleQuickForm_choosecoursefile'); |
2073 | MoodleQuickForm::registerElementType('choosecoursefileorimsrepo', "$CFG->libdir/form/choosecoursefileorimsrepo.php", 'MoodleQuickForm_choosecoursefileorimsrepo'); |
2074 | MoodleQuickForm::registerElementType('date_selector', "$CFG->libdir/form/dateselector.php", 'MoodleQuickForm_date_selector'); |
2075 | MoodleQuickForm::registerElementType('date_time_selector', "$CFG->libdir/form/datetimeselector.php", 'MoodleQuickForm_date_time_selector'); |
32fa2272 |
2076 | MoodleQuickForm::registerElementType('duration', "$CFG->libdir/form/duration.php", 'MoodleQuickForm_duration'); |
c583482c |
2077 | MoodleQuickForm::registerElementType('editor', "$CFG->libdir/form/editor.php", 'MoodleQuickForm_editor'); |
7f40a229 |
2078 | MoodleQuickForm::registerElementType('file', "$CFG->libdir/form/file.php", 'MoodleQuickForm_file'); |
241431cd |
2079 | MoodleQuickForm::registerElementType('filemanager', "$CFG->libdir/form/filemanager.php", 'MoodleQuickForm_filemanager'); |
c5704ec6 |
2080 | MoodleQuickForm::registerElementType('filepicker', "$CFG->libdir/form/filepicker.php", 'MoodleQuickForm_filepicker'); |
c583482c |
2081 | MoodleQuickForm::registerElementType('format', "$CFG->libdir/form/format.php", 'MoodleQuickForm_format'); |
7f40a229 |
2082 | MoodleQuickForm::registerElementType('group', "$CFG->libdir/form/group.php", 'MoodleQuickForm_group'); |
c583482c |
2083 | MoodleQuickForm::registerElementType('header', "$CFG->libdir/form/header.php", 'MoodleQuickForm_header'); |
2084 | MoodleQuickForm::registerElementType('hidden', "$CFG->libdir/form/hidden.php", 'MoodleQuickForm_hidden'); |
2085 | MoodleQuickForm::registerElementType('htmleditor', "$CFG->libdir/form/htmleditor.php", 'MoodleQuickForm_htmleditor'); |
2086 | MoodleQuickForm::registerElementType('modgrade', "$CFG->libdir/form/modgrade.php", 'MoodleQuickForm_modgrade'); |
2087 | MoodleQuickForm::registerElementType('modvisible', "$CFG->libdir/form/modvisible.php", 'MoodleQuickForm_modvisible'); |
7f40a229 |
2088 | MoodleQuickForm::registerElementType('password', "$CFG->libdir/form/password.php", 'MoodleQuickForm_password'); |
4f51f48f |
2089 | MoodleQuickForm::registerElementType('passwordunmask', "$CFG->libdir/form/passwordunmask.php", 'MoodleQuickForm_passwordunmask'); |
c583482c |
2090 | MoodleQuickForm::registerElementType('questioncategory', "$CFG->libdir/form/questioncategory.php", 'MoodleQuickForm_questioncategory'); |
7f40a229 |
2091 | MoodleQuickForm::registerElementType('radio', "$CFG->libdir/form/radio.php", 'MoodleQuickForm_radio'); |
c583482c |
2092 | MoodleQuickForm::registerElementType('recaptcha', "$CFG->libdir/form/recaptcha.php", 'MoodleQuickForm_recaptcha'); |
7f40a229 |
2093 | MoodleQuickForm::registerElementType('select', "$CFG->libdir/form/select.php", 'MoodleQuickForm_select'); |
4f51f48f |
2094 | MoodleQuickForm::registerElementType('selectgroups', "$CFG->libdir/form/selectgroups.php", 'MoodleQuickForm_selectgroups'); |
c583482c |
2095 | MoodleQuickForm::registerElementType('selectwithlink', "$CFG->libdir/form/selectwithlink.php", 'MoodleQuickForm_selectwithlink'); |
2096 | MoodleQuickForm::registerElementType('selectyesno', "$CFG->libdir/form/selectyesno.php", 'MoodleQuickForm_selectyesno'); |
2097 | MoodleQuickForm::registerElementType('static', "$CFG->libdir/form/static.php", 'MoodleQuickForm_static'); |
2098 | MoodleQuickForm::registerElementType('submit', "$CFG->libdir/form/submit.php", 'MoodleQuickForm_submit'); |
6073a598 |
2099 | MoodleQuickForm::registerElementType('submitlink', "$CFG->libdir/form/submitlink.php", 'MoodleQuickForm_submitlink'); |
9f1c9dfc |
2100 | MoodleQuickForm::registerElementType('tags', "$CFG->libdir/form/tags.php", 'MoodleQuickForm_tags'); |
7f40a229 |
2101 | MoodleQuickForm::registerElementType('text', "$CFG->libdir/form/text.php", 'MoodleQuickForm_text'); |
2102 | MoodleQuickForm::registerElementType('textarea', "$CFG->libdir/form/textarea.php", 'MoodleQuickForm_textarea'); |
1ae1941e |
2103 | MoodleQuickForm::registerElementType('warning', "$CFG->libdir/form/warning.php", 'MoodleQuickForm_warning'); |
49c7f3a8 |
2104 | ?> |