Commit | Line | Data |
---|---|---|
aa6c1ced | 1 | <?php |
e24b7f85 | 2 | require_once ($CFG->libdir.'/formslib.php'); |
516c5eca | 3 | require_once($CFG->libdir.'/completionlib.php'); |
61fceb86 | 4 | |
e24b7f85 | 5 | /** |
6 | * This class adds extra methods to form wrapper specific to be used for module | |
cce2762c | 7 | * add / update forms mod/{modname}/mod_form.php replaced deprecated mod/{modname}/mod.html |
e24b7f85 | 8 | */ |
7b5bd060 | 9 | abstract class moodleform_mod extends moodleform { |
9a105989 | 10 | /** Current data */ |
11 | protected $current; | |
e24b7f85 | 12 | /** |
13 | * Instance of the module that is being updated. This is the id of the {prefix}{modulename} | |
14 | * record. Can be used in form definition. Will be "" if this is an 'add' form and not an | |
15 | * update one. | |
16 | * | |
17 | * @var mixed | |
18 | */ | |
42f103be | 19 | protected $_instance; |
e24b7f85 | 20 | /** |
21 | * Section of course that module instance will be put in or is in. | |
24f41672 | 22 | * This is always the section number itself (column 'section' from 'course_sections' table). |
e24b7f85 | 23 | * |
24 | * @var mixed | |
25 | */ | |
42f103be | 26 | protected $_section; |
e24b7f85 | 27 | /** |
7e85563d | 28 | * Course module record of the module that is being updated. Will be null if this is an 'add' form and not an |
e24b7f85 | 29 | * update one. |
30 | * | |
31 | * @var mixed | |
32 | */ | |
42f103be | 33 | protected $_cm; |
4b86bb08 | 34 | /** |
35 | * List of modform features | |
36 | */ | |
42f103be | 37 | protected $_features; |
4e781c7b | 38 | /** |
39 | * @var array Custom completion-rule elements, if enabled | |
40 | */ | |
42f103be | 41 | protected $_customcompletionelements; |
42 | /** | |
43 | * @var string name of module | |
44 | */ | |
45 | protected $_modname; | |
09f8d75e | 46 | /** current context, course or module depends if already exists*/ |
47 | protected $context; | |
e24b7f85 | 48 | |
1d50dd13 AD |
49 | /** a flag indicating whether outcomes are being used*/ |
50 | protected $_outcomesused; | |
51 | ||
9a105989 | 52 | function moodleform_mod($current, $section, $cm, $course) { |
53 | $this->current = $current; | |
54 | $this->_instance = $current->instance; | |
55 | $this->_section = $section; | |
56 | $this->_cm = $cm; | |
09f8d75e | 57 | if ($this->_cm) { |
58 | $this->context = get_context_instance(CONTEXT_MODULE, $this->_cm->id); | |
59 | } else { | |
60 | $this->context = get_context_instance(CONTEXT_COURSE, $course->id); | |
61 | } | |
aa6c1ced | 62 | |
42f103be | 63 | // Guess module name |
64 | $matches = array(); | |
65 | if (!preg_match('/^mod_([^_]+)_mod_form$/', get_class($this), $matches)) { | |
66 | debugging('Use $modname parameter or rename form to mod_xx_mod_form, where xx is name of your module'); | |
67 | print_error('unknownmodulename'); | |
68 | } | |
69 | $this->_modname = $matches[1]; | |
70 | $this->init_features(); | |
e24b7f85 | 71 | parent::moodleform('modedit.php'); |
72 | } | |
71ee4471 | 73 | |
42f103be | 74 | protected function init_features() { |
75 | global $CFG; | |
76 | ||
fbaea88f | 77 | $this->_features = new stdClass(); |
42f103be | 78 | $this->_features->groups = plugin_supports('mod', $this->_modname, FEATURE_GROUPS, true); |
79 | $this->_features->groupings = plugin_supports('mod', $this->_modname, FEATURE_GROUPINGS, false); | |
36f3228c | 80 | $this->_features->groupmembersonly = (!empty($CFG->enablegroupmembersonly) and plugin_supports('mod', $this->_modname, FEATURE_GROUPMEMBERSONLY, false)); |
42f103be | 81 | $this->_features->outcomes = (!empty($CFG->enableoutcomes) and plugin_supports('mod', $this->_modname, FEATURE_GRADE_OUTCOMES, true)); |
82 | $this->_features->hasgrades = plugin_supports('mod', $this->_modname, FEATURE_GRADE_HAS_GRADE, false); | |
83 | $this->_features->idnumber = plugin_supports('mod', $this->_modname, FEATURE_IDNUMBER, true); | |
dc5c2bd9 | 84 | $this->_features->introeditor = plugin_supports('mod', $this->_modname, FEATURE_MOD_INTRO, true); |
42f103be | 85 | $this->_features->defaultcompletion = plugin_supports('mod', $this->_modname, FEATURE_MODEDIT_DEFAULT_COMPLETION, true); |
16306628 | 86 | $this->_features->rating = plugin_supports('mod', $this->_modname, FEATURE_RATE, false); |
8c40662e | 87 | $this->_features->showdescription = plugin_supports('mod', $this->_modname, FEATURE_SHOW_DESCRIPTION, false); |
42f103be | 88 | |
89 | $this->_features->gradecat = ($this->_features->outcomes or $this->_features->hasgrades); | |
b11f9da6 | 90 | $this->_features->advancedgrading = plugin_supports('mod', $this->_modname, FEATURE_ADVANCED_GRADING, false); |
42f103be | 91 | } |
92 | ||
e24b7f85 | 93 | /** |
a7f7e52f | 94 | * Only available on moodleform_mod. |
e24b7f85 | 95 | * |
96 | * @param array $default_values passed by reference | |
97 | */ | |
a7f7e52f | 98 | function data_preprocessing(&$default_values){ |
a09aeee4 AD |
99 | if (empty($default_values['scale'])) { |
100 | $default_values['assessed'] = 0; | |
101 | } | |
102 | ||
103 | if (empty($default_values['assessed'])){ | |
a09aeee4 AD |
104 | $default_values['ratingtime'] = 0; |
105 | } else { | |
a09aeee4 AD |
106 | $default_values['ratingtime']= |
107 | ($default_values['assesstimestart'] && $default_values['assesstimefinish']) ? 1 : 0; | |
108 | } | |
e24b7f85 | 109 | } |
71ee4471 | 110 | |
4b86bb08 | 111 | /** |
112 | * Each module which defines definition_after_data() must call this method using parent::definition_after_data(); | |
113 | */ | |
71ee4471 | 114 | function definition_after_data() { |
4b86bb08 | 115 | global $CFG, $COURSE; |
71ee4471 | 116 | $mform =& $this->_form; |
117 | ||
118 | if ($id = $mform->getElementValue('update')) { | |
119 | $modulename = $mform->getElementValue('modulename'); | |
120 | $instance = $mform->getElementValue('instance'); | |
121 | ||
4b86bb08 | 122 | if ($this->_features->gradecat) { |
123 | $gradecat = false; | |
124 | if (!empty($CFG->enableoutcomes) and $this->_features->outcomes) { | |
16306628 AD |
125 | $outcomes = grade_outcome::fetch_all_available($COURSE->id); |
126 | if (!empty($outcomes)) { | |
4b86bb08 | 127 | $gradecat = true; |
128 | } | |
129 | } | |
16306628 AD |
130 | |
131 | $items = grade_item::fetch_all(array('itemtype'=>'mod', 'itemmodule'=>$modulename,'iteminstance'=>$instance, 'courseid'=>$COURSE->id)); | |
132 | //will be no items if, for example, this activity supports ratings but rating aggregate type == no ratings | |
133 | if (!empty($items)) { | |
4b86bb08 | 134 | foreach ($items as $item) { |
135 | if (!empty($item->outcomeid)) { | |
136 | $elname = 'outcome_'.$item->outcomeid; | |
137 | if ($mform->elementExists($elname)) { | |
138 | $mform->hardFreeze($elname); // prevent removing of existing outcomes | |
139 | } | |
140 | } | |
141 | } | |
16306628 | 142 | |
4b86bb08 | 143 | foreach ($items as $item) { |
144 | if (is_bool($gradecat)) { | |
145 | $gradecat = $item->categoryid; | |
146 | continue; | |
71ee4471 | 147 | } |
4b86bb08 | 148 | if ($gradecat != $item->categoryid) { |
149 | //mixed categories | |
150 | $gradecat = false; | |
151 | break; | |
152 | } | |
153 | } | |
154 | } | |
155 | ||
156 | if ($gradecat === false) { | |
157 | // items and outcomes in different categories - remove the option | |
16306628 | 158 | // TODO: add a "Mixed categories" text instead of removing elements with no explanation |
4b86bb08 | 159 | if ($mform->elementExists('gradecat')) { |
160 | $mform->removeElement('gradecat'); | |
16306628 AD |
161 | if ($this->_features->rating) { |
162 | //if supports ratings then the max grade dropdown wasnt added so the grade box can be removed entirely | |
163 | $mform->removeElement('modstandardgrade'); | |
164 | } | |
71ee4471 | 165 | } |
166 | } | |
167 | } | |
168 | } | |
24f41672 | 169 | |
a78890d5 | 170 | if ($COURSE->groupmodeforce) { |
171 | if ($mform->elementExists('groupmode')) { | |
24f41672 | 172 | $mform->hardFreeze('groupmode'); // groupmode can not be changed if forced from course settings |
173 | } | |
174 | } | |
a104debf | 175 | |
6d02b265 | 176 | // Don't disable/remove groupingid if it is currently set to something, |
177 | // otherwise you cannot turn it off at same time as turning off other | |
178 | // option (MDL-30764) | |
179 | if (empty($this->_cm) || !$this->_cm->groupingid) { | |
180 | if ($mform->elementExists('groupmode') and !$mform->elementExists('groupmembersonly') and empty($COURSE->groupmodeforce)) { | |
181 | $mform->disabledIf('groupingid', 'groupmode', 'eq', NOGROUPS); | |
182 | ||
183 | } else if (!$mform->elementExists('groupmode') and $mform->elementExists('groupmembersonly')) { | |
184 | $mform->disabledIf('groupingid', 'groupmembersonly', 'notchecked'); | |
185 | ||
186 | } else if (!$mform->elementExists('groupmode') and !$mform->elementExists('groupmembersonly')) { | |
187 | // groupings have no use without groupmode or groupmembersonly | |
188 | if ($mform->elementExists('groupingid')) { | |
189 | $mform->removeElement('groupingid'); | |
190 | } | |
a104debf | 191 | } |
192 | } | |
4e781c7b | 193 | |
194 | // Completion: If necessary, freeze fields | |
61fceb86 | 195 | $completion = new completion_info($COURSE); |
196 | if ($completion->is_enabled()) { | |
4e781c7b | 197 | // If anybody has completed the activity, these options will be 'locked' |
198 | $completedcount = empty($this->_cm) | |
199 | ? 0 | |
200 | : $completion->count_user_data($this->_cm); | |
201 | ||
61fceb86 | 202 | $freeze = false; |
203 | if (!$completedcount) { | |
204 | if ($mform->elementExists('unlockcompletion')) { | |
4e781c7b | 205 | $mform->removeElement('unlockcompletion'); |
206 | } | |
91d0bb0a SM |
207 | // Automatically set to unlocked (note: this is necessary |
208 | // in order to make it recalculate completion once the option | |
209 | // is changed, maybe someone has completed it now) | |
210 | $mform->getElement('completionunlocked')->setValue(1); | |
4e781c7b | 211 | } else { |
212 | // Has the element been unlocked? | |
61fceb86 | 213 | if ($mform->exportValue('unlockcompletion')) { |
4e781c7b | 214 | // Yes, add in warning text and set the hidden variable |
215 | $mform->insertElementBefore( | |
61fceb86 | 216 | $mform->createElement('static', 'completedunlocked', |
217 | get_string('completedunlocked', 'completion'), | |
218 | get_string('completedunlockedtext', 'completion')), | |
4e781c7b | 219 | 'unlockcompletion'); |
220 | $mform->removeElement('unlockcompletion'); | |
221 | $mform->getElement('completionunlocked')->setValue(1); | |
222 | } else { | |
223 | // No, add in the warning text with the count (now we know | |
224 | // it) before the unlock button | |
225 | $mform->insertElementBefore( | |
61fceb86 | 226 | $mform->createElement('static', 'completedwarning', |
227 | get_string('completedwarning', 'completion'), | |
228 | get_string('completedwarningtext', 'completion', $completedcount)), | |
4e781c7b | 229 | 'unlockcompletion'); |
61fceb86 | 230 | $freeze = true; |
4e781c7b | 231 | } |
aa6c1ced | 232 | } |
4e781c7b | 233 | |
61fceb86 | 234 | if ($freeze) { |
4e781c7b | 235 | $mform->freeze('completion'); |
61fceb86 | 236 | if ($mform->elementExists('completionview')) { |
4e781c7b | 237 | $mform->freeze('completionview'); // don't use hardFreeze or checkbox value gets lost |
238 | } | |
61fceb86 | 239 | if ($mform->elementExists('completionusegrade')) { |
4e781c7b | 240 | $mform->freeze('completionusegrade'); |
241 | } | |
242 | $mform->freeze($this->_customcompletionelements); | |
aa6c1ced | 243 | } |
4e781c7b | 244 | } |
82bd6a5e | 245 | |
246 | // Availability conditions | |
247 | if (!empty($CFG->enableavailability) && $this->_cm) { | |
248 | $ci = new condition_info($this->_cm); | |
249 | $fullcm=$ci->get_full_course_module(); | |
250 | ||
251 | $num=0; | |
252 | foreach($fullcm->conditionsgrade as $gradeitemid=>$minmax) { | |
253 | $groupelements=$mform->getElement('conditiongradegroup['.$num.']')->getElements(); | |
254 | $groupelements[0]->setValue($gradeitemid); | |
ce4dfd27 | 255 | $groupelements[2]->setValue(is_null($minmax->min) ? '' : |
256 | format_float($minmax->min, 5, true, true)); | |
257 | $groupelements[4]->setValue(is_null($minmax->max) ? '' : | |
258 | format_float($minmax->max, 5, true, true)); | |
82bd6a5e | 259 | $num++; |
260 | } | |
261 | ||
262 | if ($completion->is_enabled()) { | |
263 | $num=0; | |
264 | foreach($fullcm->conditionscompletion as $othercmid=>$state) { | |
265 | $groupelements=$mform->getElement('conditioncompletiongroup['.$num.']')->getElements(); | |
266 | $groupelements[0]->setValue($othercmid); | |
267 | $groupelements[1]->setValue($state); | |
268 | $num++; | |
269 | } | |
270 | } | |
271 | } | |
71ee4471 | 272 | } |
273 | ||
60243313 | 274 | // form verification |
a78890d5 | 275 | function validation($data, $files) { |
32648682 | 276 | global $COURSE, $DB; |
a78890d5 | 277 | $errors = parent::validation($data, $files); |
60243313 | 278 | |
273eb2f5 | 279 | $mform =& $this->_form; |
280 | ||
60243313 | 281 | $errors = array(); |
282 | ||
273eb2f5 | 283 | if ($mform->elementExists('name')) { |
284 | $name = trim($data['name']); | |
285 | if ($name == '') { | |
286 | $errors['name'] = get_string('required'); | |
287 | } | |
e04ff2d5 | 288 | } |
289 | ||
60243313 | 290 | $grade_item = grade_item::fetch(array('itemtype'=>'mod', 'itemmodule'=>$data['modulename'], |
291 | 'iteminstance'=>$data['instance'], 'itemnumber'=>0, 'courseid'=>$COURSE->id)); | |
292 | if ($data['coursemodule']) { | |
32648682 | 293 | $cm = $DB->get_record('course_modules', array('id'=>$data['coursemodule'])); |
60243313 | 294 | } else { |
295 | $cm = null; | |
296 | } | |
297 | ||
273eb2f5 | 298 | if ($mform->elementExists('cmidnumber')) { |
299 | // verify the idnumber | |
204175c5 | 300 | if (!grade_verify_idnumber($data['cmidnumber'], $COURSE->id, $grade_item, $cm)) { |
273eb2f5 | 301 | $errors['cmidnumber'] = get_string('idnumbertaken'); |
302 | } | |
60243313 | 303 | } |
aa6c1ced | 304 | |
4e781c7b | 305 | // Completion: Don't let them choose automatic completion without turning |
306 | // on some conditions | |
61fceb86 | 307 | if (array_key_exists('completion', $data) && $data['completion']==COMPLETION_TRACKING_AUTOMATIC) { |
308 | if (empty($data['completionview']) && empty($data['completionusegrade']) && | |
4e781c7b | 309 | !$this->completion_rule_enabled($data)) { |
61fceb86 | 310 | $errors['completion'] = get_string('badautocompletion', 'completion'); |
4e781c7b | 311 | } |
312 | } | |
60243313 | 313 | |
a561d96e | 314 | // Conditions: Don't let them set dates which make no sense |
aa6c1ced PS |
315 | if (array_key_exists('availablefrom', $data) && |
316 | $data['availablefrom'] && $data['availableuntil'] && | |
6282381d | 317 | $data['availablefrom'] >= $data['availableuntil']) { |
a561d96e | 318 | $errors['availablefrom'] = get_string('badavailabledates', 'condition'); |
319 | } | |
aa6c1ced | 320 | |
af4e4408 TH |
321 | // Conditions: Verify that the grade conditions are numbers, and make sense. |
322 | if (array_key_exists('conditiongradegroup', $data)) { | |
323 | foreach ($data['conditiongradegroup'] as $i => $gradedata) { | |
ce4dfd27 | 324 | if ($gradedata['conditiongrademin'] !== '' && |
325 | !is_numeric(unformat_float($gradedata['conditiongrademin']))) { | |
af4e4408 TH |
326 | $errors["conditiongradegroup[{$i}]"] = get_string('gradesmustbenumeric', 'condition'); |
327 | continue; | |
328 | } | |
ce4dfd27 | 329 | if ($gradedata['conditiongrademax'] !== '' && |
330 | !is_numeric(unformat_float($gradedata['conditiongrademax']))) { | |
af4e4408 TH |
331 | $errors["conditiongradegroup[{$i}]"] = get_string('gradesmustbenumeric', 'condition'); |
332 | continue; | |
333 | } | |
334 | if ($gradedata['conditiongrademin'] !== '' && $gradedata['conditiongrademax'] !== '' && | |
f84e58d8 | 335 | unformat_float($gradedata['conditiongrademax']) <= unformat_float($gradedata['conditiongrademin'])) { |
af4e4408 TH |
336 | $errors["conditiongradegroup[{$i}]"] = get_string('badgradelimits', 'condition'); |
337 | continue; | |
338 | } | |
339 | if ($gradedata['conditiongrademin'] === '' && $gradedata['conditiongrademax'] === '' && | |
340 | $gradedata['conditiongradeitemid']) { | |
341 | $errors["conditiongradegroup[{$i}]"] = get_string('gradeitembutnolimits', 'condition'); | |
342 | continue; | |
343 | } | |
344 | if (($gradedata['conditiongrademin'] !== '' || $gradedata['conditiongrademax'] !== '') && | |
345 | !$gradedata['conditiongradeitemid']) { | |
346 | $errors["conditiongradegroup[{$i}]"] = get_string('gradelimitsbutnoitem', 'condition'); | |
347 | continue; | |
348 | } | |
349 | } | |
350 | } | |
351 | ||
a78890d5 | 352 | return $errors; |
60243313 | 353 | } |
354 | ||
e24b7f85 | 355 | /** |
356 | * Load in existing data as form defaults. Usually new entry defaults are stored directly in | |
357 | * form definition (new entry form); this function is used to load in data where values | |
358 | * already exist and data is being edited (edit entry form). | |
359 | * | |
360 | * @param mixed $default_values object or array of default values | |
361 | */ | |
32db0d42 | 362 | function set_data($default_values) { |
e24b7f85 | 363 | if (is_object($default_values)) { |
364 | $default_values = (array)$default_values; | |
365 | } | |
82bd6a5e | 366 | |
aa6c1ced | 367 | $this->data_preprocessing($default_values); |
82bd6a5e | 368 | parent::set_data($default_values); |
e24b7f85 | 369 | } |
71ee4471 | 370 | |
e24b7f85 | 371 | /** |
372 | * Adds all the standard elements to a form to edit the settings for an activity module. | |
e24b7f85 | 373 | */ |
42f103be | 374 | function standard_coursemodule_elements(){ |
c18269c7 | 375 | global $COURSE, $CFG, $DB; |
e24b7f85 | 376 | $mform =& $this->_form; |
f3b783f4 | 377 | |
1d50dd13 | 378 | $this->_outcomesused = false; |
42f103be | 379 | if ($this->_features->outcomes) { |
f3b783f4 | 380 | if ($outcomes = grade_outcome::fetch_all_available($COURSE->id)) { |
1d50dd13 | 381 | $this->_outcomesused = true; |
f3b783f4 | 382 | $mform->addElement('header', 'modoutcomes', get_string('outcomes', 'grades')); |
383 | foreach($outcomes as $outcome) { | |
384 | $mform->addElement('advcheckbox', 'outcome_'.$outcome->id, $outcome->get_name()); | |
385 | } | |
386 | } | |
387 | } | |
388 | ||
36f3228c | 389 | |
16306628 | 390 | if ($this->_features->rating) { |
63e87951 | 391 | require_once($CFG->dirroot.'/rating/lib.php'); |
b47dcdf0 | 392 | $rm = new rating_manager(); |
63e87951 AD |
393 | |
394 | $mform->addElement('header', 'modstandardratings', get_string('ratings', 'rating')); | |
a09aeee4 | 395 | |
750925e2 | 396 | $permission=CAP_ALLOW; |
f9cd798c AD |
397 | $rolenamestring = null; |
398 | if (!empty($this->_cm)) { | |
399 | $context = get_context_instance(CONTEXT_MODULE, $this->_cm->id); | |
0d54a398 | 400 | |
f9cd798c AD |
401 | $rolenames = get_role_names_with_caps_in_context($context, array('moodle/rating:rate', 'mod/'.$this->_cm->modname.':rate')); |
402 | $rolenamestring = implode(', ', $rolenames); | |
403 | } else { | |
404 | $rolenamestring = get_string('capabilitychecknotavailable','rating'); | |
0d54a398 | 405 | } |
f9cd798c | 406 | $mform->addElement('static', 'rolewarning', get_string('rolewarning','rating'), $rolenamestring); |
bbf27733 | 407 | $mform->addHelpButton('rolewarning', 'rolewarning', 'rating'); |
a09aeee4 | 408 | |
63e87951 | 409 | $mform->addElement('select', 'assessed', get_string('aggregatetype', 'rating') , $rm->get_aggregate_types()); |
a09aeee4 | 410 | $mform->setDefault('assessed', 0); |
d90dd973 | 411 | $mform->addHelpButton('assessed', 'aggregatetype', 'rating'); |
a09aeee4 | 412 | |
63e87951 | 413 | $mform->addElement('modgrade', 'scale', get_string('scale'), false); |
a09aeee4 AD |
414 | $mform->disabledIf('scale', 'assessed', 'eq', 0); |
415 | ||
d90dd973 | 416 | $mform->addElement('checkbox', 'ratingtime', get_string('ratingtime', 'rating')); |
a09aeee4 AD |
417 | $mform->disabledIf('ratingtime', 'assessed', 'eq', 0); |
418 | ||
419 | $mform->addElement('date_time_selector', 'assesstimestart', get_string('from')); | |
420 | $mform->disabledIf('assesstimestart', 'assessed', 'eq', 0); | |
421 | $mform->disabledIf('assesstimestart', 'ratingtime'); | |
422 | ||
423 | $mform->addElement('date_time_selector', 'assesstimefinish', get_string('to')); | |
424 | $mform->disabledIf('assesstimefinish', 'assessed', 'eq', 0); | |
425 | $mform->disabledIf('assesstimefinish', 'ratingtime'); | |
426 | } | |
427 | ||
16306628 AD |
428 | //doing this here means splitting up the grade related settings on the lesson settings page |
429 | //$this->standard_grading_coursemodule_elements(); | |
430 | ||
24e25bc1 | 431 | $mform->addElement('header', 'modstandardelshdr', get_string('modstandardels', 'form')); |
4b86bb08 | 432 | if ($this->_features->groups) { |
a78890d5 | 433 | $options = array(NOGROUPS => get_string('groupsnone'), |
434 | SEPARATEGROUPS => get_string('groupsseparate'), | |
435 | VISIBLEGROUPS => get_string('groupsvisible')); | |
ddd9f926 DM |
436 | $mform->addElement('select', 'groupmode', get_string('groupmode', 'group'), $options, NOGROUPS); |
437 | $mform->addHelpButton('groupmode', 'groupmode', 'group'); | |
e24b7f85 | 438 | } |
24f41672 | 439 | |
98da6021 PS |
440 | if ($this->_features->groupings or $this->_features->groupmembersonly) { |
441 | //groupings selector - used for normal grouping mode or also when restricting access with groupmembersonly | |
442 | $options = array(); | |
443 | $options[0] = get_string('none'); | |
444 | if ($groupings = $DB->get_records('groupings', array('courseid'=>$COURSE->id))) { | |
445 | foreach ($groupings as $grouping) { | |
446 | $options[$grouping->id] = format_string($grouping->name); | |
24f41672 | 447 | } |
448 | } | |
98da6021 | 449 | $mform->addElement('select', 'groupingid', get_string('grouping', 'group'), $options); |
ddd9f926 | 450 | $mform->addHelpButton('groupingid', 'grouping', 'group'); |
98da6021 PS |
451 | $mform->setAdvanced('groupingid'); |
452 | } | |
e04ff2d5 | 453 | |
98da6021 PS |
454 | if ($this->_features->groupmembersonly) { |
455 | $mform->addElement('checkbox', 'groupmembersonly', get_string('groupmembersonly', 'group')); | |
ddd9f926 | 456 | $mform->addHelpButton('groupmembersonly', 'groupmembersonly', 'group'); |
98da6021 | 457 | $mform->setAdvanced('groupmembersonly'); |
24f41672 | 458 | } |
459 | ||
e24b7f85 | 460 | $mform->addElement('modvisible', 'visible', get_string('visible')); |
af189935 PS |
461 | if (!empty($this->_cm)) { |
462 | $context = get_context_instance(CONTEXT_MODULE, $this->_cm->id); | |
463 | if (!has_capability('moodle/course:activityvisibility', $context)) { | |
464 | $mform->hardFreeze('visible'); | |
465 | } | |
466 | } | |
b5ab55dd | 467 | |
468 | if ($this->_features->idnumber) { | |
469 | $mform->addElement('text', 'cmidnumber', get_string('idnumbermod')); | |
ddd9f926 | 470 | $mform->addHelpButton('cmidnumber', 'idnumbermod'); |
b5ab55dd | 471 | } |
71ee4471 | 472 | |
82bd6a5e | 473 | if (!empty($CFG->enableavailability)) { |
474 | // Conditional availability | |
6282381d | 475 | |
476 | // Available from/to defaults to midnight because then the display | |
477 | // will be nicer where it tells users when they can access it (it | |
478 | // shows only the date and not time). | |
479 | $date = usergetdate(time()); | |
480 | $midnight = make_timestamp($date['year'], $date['mon'], $date['mday']); | |
481 | ||
482 | // From/until controls | |
483 | $mform->addElement('header', 'availabilityconditionsheader', | |
484 | get_string('availabilityconditions', 'condition')); | |
485 | $mform->addElement('date_time_selector', 'availablefrom', | |
486 | get_string('availablefrom', 'condition'), | |
487 | array('optional' => true, 'defaulttime' => $midnight)); | |
f1c5b522 | 488 | $mform->addHelpButton('availablefrom', 'availablefrom', 'condition'); |
6282381d | 489 | $mform->addElement('date_time_selector', 'availableuntil', |
490 | get_string('availableuntil', 'condition'), | |
491 | array('optional' => true, 'defaulttime' => $midnight)); | |
82bd6a5e | 492 | |
493 | // Conditions based on grades | |
42f103be | 494 | $gradeoptions = array(); |
495 | $items = grade_item::fetch_all(array('courseid'=>$COURSE->id)); | |
496 | $items = $items ? $items : array(); | |
82bd6a5e | 497 | foreach($items as $id=>$item) { |
d030fa7b | 498 | // Do not include grades for current item |
499 | if (!empty($this->_cm) && $this->_cm->instance == $item->iteminstance | |
500 | && $this->_cm->modname == $item->itemmodule | |
501 | && $item->itemtype == 'mod') { | |
502 | continue; | |
503 | } | |
42f103be | 504 | $gradeoptions[$id] = $item->get_name(); |
82bd6a5e | 505 | } |
506 | asort($gradeoptions); | |
42f103be | 507 | $gradeoptions = array(0=>get_string('none','condition'))+$gradeoptions; |
82bd6a5e | 508 | |
42f103be | 509 | $grouparray = array(); |
82bd6a5e | 510 | $grouparray[] =& $mform->createElement('select','conditiongradeitemid','',$gradeoptions); |
9271e424 | 511 | $grouparray[] =& $mform->createElement('static', '', '',' '.get_string('grade_atleast','condition').' '); |
82bd6a5e | 512 | $grouparray[] =& $mform->createElement('text', 'conditiongrademin','',array('size'=>3)); |
75564228 | 513 | $grouparray[] =& $mform->createElement('static', '', '','% '.get_string('grade_upto','condition').' '); |
82bd6a5e | 514 | $grouparray[] =& $mform->createElement('text', 'conditiongrademax','',array('size'=>3)); |
75564228 | 515 | $grouparray[] =& $mform->createElement('static', '', '','%'); |
aa6c1ced | 516 | $group = $mform->createElement('group','conditiongradegroup', |
82bd6a5e | 517 | get_string('gradecondition', 'condition'),$grouparray); |
518 | ||
519 | // Get version with condition info and store it so we don't ask | |
520 | // twice | |
aa6c1ced | 521 | if(!empty($this->_cm)) { |
42f103be | 522 | $ci = new condition_info($this->_cm, CONDITION_MISSING_EXTRATABLE); |
523 | $this->_cm = $ci->get_full_course_module(); | |
524 | $count = count($this->_cm->conditionsgrade)+1; | |
82bd6a5e | 525 | } else { |
42f103be | 526 | $count = 1; |
82bd6a5e | 527 | } |
528 | ||
42f103be | 529 | $this->repeat_elements(array($group), $count, array(), 'conditiongraderepeats', 'conditiongradeadds', 2, |
530 | get_string('addgrades', 'condition'), true); | |
59f19480 | 531 | $mform->addHelpButton('conditiongradegroup[0]', 'gradecondition', 'condition'); |
82bd6a5e | 532 | |
533 | // Conditions based on completion | |
534 | $completion = new completion_info($COURSE); | |
535 | if ($completion->is_enabled()) { | |
42f103be | 536 | $completionoptions = array(); |
537 | $modinfo = get_fast_modinfo($COURSE); | |
82bd6a5e | 538 | foreach($modinfo->cms as $id=>$cm) { |
d030fa7b | 539 | // Add each course-module if it: |
540 | // (a) has completion turned on | |
541 | // (b) is not the same as current course-module | |
542 | if ($cm->completion && (empty($this->_cm) || $this->_cm->id != $id)) { | |
fe44022d | 543 | $completionoptions[$id]=$cm->name; |
544 | } | |
82bd6a5e | 545 | } |
546 | asort($completionoptions); | |
42f103be | 547 | $completionoptions = array(0=>get_string('none','condition'))+$completionoptions; |
82bd6a5e | 548 | |
549 | $completionvalues=array( | |
550 | COMPLETION_COMPLETE=>get_string('completion_complete','condition'), | |
551 | COMPLETION_INCOMPLETE=>get_string('completion_incomplete','condition'), | |
552 | COMPLETION_COMPLETE_PASS=>get_string('completion_pass','condition'), | |
553 | COMPLETION_COMPLETE_FAIL=>get_string('completion_fail','condition')); | |
554 | ||
aa6c1ced | 555 | $grouparray = array(); |
82bd6a5e | 556 | $grouparray[] =& $mform->createElement('select','conditionsourcecmid','',$completionoptions); |
557 | $grouparray[] =& $mform->createElement('select','conditionrequiredcompletion','',$completionvalues); | |
aa6c1ced | 558 | $group = $mform->createElement('group','conditioncompletiongroup', |
82bd6a5e | 559 | get_string('completioncondition', 'condition'),$grouparray); |
560 | ||
42f103be | 561 | $count = empty($this->_cm) ? 1 : count($this->_cm->conditionscompletion)+1; |
82bd6a5e | 562 | $this->repeat_elements(array($group),$count,array(), |
563 | 'conditioncompletionrepeats','conditioncompletionadds',2, | |
564 | get_string('addcompletions','condition'),true); | |
ddd9f926 | 565 | $mform->addHelpButton('conditioncompletiongroup[0]', 'completioncondition', 'condition'); |
82bd6a5e | 566 | } |
567 | ||
aa6c1ced PS |
568 | // Do we display availability info to students? |
569 | $mform->addElement('select', 'showavailability', get_string('showavailability', 'condition'), | |
570 | array(CONDITION_STUDENTVIEW_SHOW=>get_string('showavailability_show', 'condition'), | |
82bd6a5e | 571 | CONDITION_STUDENTVIEW_HIDE=>get_string('showavailability_hide', 'condition'))); |
aa6c1ced | 572 | $mform->setDefault('showavailability', CONDITION_STUDENTVIEW_SHOW); |
82bd6a5e | 573 | } |
574 | ||
aa6c1ced | 575 | // Conditional activities: completion tracking section |
82bd6a5e | 576 | if(!isset($completion)) { |
577 | $completion = new completion_info($COURSE); | |
578 | } | |
61fceb86 | 579 | if ($completion->is_enabled()) { |
3fbe0e8a | 580 | $mform->addElement('header', 'activitycompletionheader', get_string('activitycompletion', 'completion')); |
4e781c7b | 581 | |
582 | // Unlock button for if people have completed it (will | |
583 | // be removed in definition_after_data if they haven't) | |
61fceb86 | 584 | $mform->addElement('submit', 'unlockcompletion', get_string('unlockcompletion', 'completion')); |
4e781c7b | 585 | $mform->registerNoSubmitButton('unlockcompletion'); |
61fceb86 | 586 | $mform->addElement('hidden', 'completionunlocked', 0); |
d18e0fe6 | 587 | $mform->setType('completionunlocked', PARAM_INT); |
82bd6a5e | 588 | |
aa6c1ced PS |
589 | $mform->addElement('select', 'completion', get_string('completion', 'completion'), |
590 | array(COMPLETION_TRACKING_NONE=>get_string('completion_none', 'completion'), | |
61fceb86 | 591 | COMPLETION_TRACKING_MANUAL=>get_string('completion_manual', 'completion'))); |
61fceb86 | 592 | $mform->setDefault('completion', $this->_features->defaultcompletion |
4e781c7b | 593 | ? COMPLETION_TRACKING_MANUAL |
594 | : COMPLETION_TRACKING_NONE); | |
c8dcb793 | 595 | $mform->addHelpButton('completion', 'completion', 'completion'); |
4e781c7b | 596 | |
597 | // Automatic completion once you view it | |
61fceb86 | 598 | $gotcompletionoptions = false; |
9593d8b8 | 599 | if (plugin_supports('mod', $this->_modname, FEATURE_COMPLETION_TRACKS_VIEWS, false)) { |
61fceb86 | 600 | $mform->addElement('checkbox', 'completionview', get_string('completionview', 'completion'), |
ddd9f926 | 601 | get_string('completionview_desc', 'completion')); |
61fceb86 | 602 | $mform->disabledIf('completionview', 'completion', 'ne', COMPLETION_TRACKING_AUTOMATIC); |
603 | $gotcompletionoptions = true; | |
4e781c7b | 604 | } |
605 | ||
606 | // Automatic completion once it's graded | |
9593d8b8 | 607 | if (plugin_supports('mod', $this->_modname, FEATURE_GRADE_HAS_GRADE, false)) { |
61fceb86 | 608 | $mform->addElement('checkbox', 'completionusegrade', get_string('completionusegrade', 'completion'), |
ddd9f926 | 609 | get_string('completionusegrade_desc', 'completion')); |
61fceb86 | 610 | $mform->disabledIf('completionusegrade', 'completion', 'ne', COMPLETION_TRACKING_AUTOMATIC); |
af455aa0 | 611 | $mform->addHelpButton('completionusegrade', 'completionusegrade', 'completion'); |
61fceb86 | 612 | $gotcompletionoptions = true; |
4e781c7b | 613 | } |
614 | ||
615 | // Automatic completion according to module-specific rules | |
616 | $this->_customcompletionelements = $this->add_completion_rules(); | |
61fceb86 | 617 | foreach ($this->_customcompletionelements as $element) { |
aa6c1ced | 618 | $mform->disabledIf($element, 'completion', 'ne', COMPLETION_TRACKING_AUTOMATIC); |
4e781c7b | 619 | } |
620 | ||
621 | $gotcompletionoptions = $gotcompletionoptions || | |
622 | count($this->_customcompletionelements)>0; | |
623 | ||
624 | // Automatic option only appears if possible | |
61fceb86 | 625 | if ($gotcompletionoptions) { |
4e781c7b | 626 | $mform->getElement('completion')->addOption( |
61fceb86 | 627 | get_string('completion_automatic', 'completion'), |
4e781c7b | 628 | COMPLETION_TRACKING_AUTOMATIC); |
aa6c1ced | 629 | } |
4e781c7b | 630 | |
631 | // Completion expected at particular date? (For progress tracking) | |
61fceb86 | 632 | $mform->addElement('date_selector', 'completionexpected', get_string('completionexpected', 'completion'), array('optional'=>true)); |
ddd9f926 | 633 | $mform->addHelpButton('completionexpected', 'completionexpected', 'completion'); |
aa6c1ced | 634 | $mform->disabledIf('completionexpected', 'completion', 'eq', COMPLETION_TRACKING_NONE); |
4e781c7b | 635 | } |
636 | ||
e24b7f85 | 637 | $this->standard_hidden_coursemodule_elements(); |
638 | } | |
aa6c1ced | 639 | |
4e781c7b | 640 | /** |
641 | * Can be overridden to add custom completion rules if the module wishes | |
642 | * them. If overriding this, you should also override completion_rule_enabled. | |
643 | * <p> | |
644 | * Just add elements to the form as needed and return the list of IDs. The | |
645 | * system will call disabledIf and handle other behaviour for each returned | |
646 | * ID. | |
647 | * @return array Array of string IDs of added items, empty array if none | |
648 | */ | |
649 | function add_completion_rules() { | |
650 | return array(); | |
651 | } | |
652 | ||
653 | /** | |
654 | * Called during validation. Override to indicate, based on the data, whether | |
655 | * a custom completion rule is enabled (selected). | |
656 | * | |
657 | * @param array $data Input data (not yet validated) | |
658 | * @return bool True if one or more rules is enabled, false if none are; | |
659 | * default returns false | |
660 | */ | |
54352ac9 | 661 | function completion_rule_enabled($data) { |
4e781c7b | 662 | return false; |
663 | } | |
e24b7f85 | 664 | |
665 | function standard_hidden_coursemodule_elements(){ | |
666 | $mform =& $this->_form; | |
667 | $mform->addElement('hidden', 'course', 0); | |
668 | $mform->setType('course', PARAM_INT); | |
669 | ||
670 | $mform->addElement('hidden', 'coursemodule', 0); | |
671 | $mform->setType('coursemodule', PARAM_INT); | |
672 | ||
673 | $mform->addElement('hidden', 'section', 0); | |
674 | $mform->setType('section', PARAM_INT); | |
675 | ||
676 | $mform->addElement('hidden', 'module', 0); | |
677 | $mform->setType('module', PARAM_INT); | |
678 | ||
679 | $mform->addElement('hidden', 'modulename', ''); | |
aff24313 | 680 | $mform->setType('modulename', PARAM_PLUGIN); |
e24b7f85 | 681 | |
682 | $mform->addElement('hidden', 'instance', 0); | |
683 | $mform->setType('instance', PARAM_INT); | |
684 | ||
685 | $mform->addElement('hidden', 'add', 0); | |
686 | $mform->setType('add', PARAM_ALPHA); | |
687 | ||
688 | $mform->addElement('hidden', 'update', 0); | |
689 | $mform->setType('update', PARAM_INT); | |
19110c57 | 690 | |
691 | $mform->addElement('hidden', 'return', 0); | |
692 | $mform->setType('return', PARAM_BOOL); | |
a41b1d96 FM |
693 | |
694 | $mform->addElement('hidden', 'sr', 0); | |
695 | $mform->setType('sr', PARAM_INT); | |
e24b7f85 | 696 | } |
697 | ||
60d5a2e4 | 698 | public function standard_grading_coursemodule_elements() { |
16306628 | 699 | global $COURSE, $CFG; |
1d50dd13 AD |
700 | $mform =& $this->_form; |
701 | ||
16306628 | 702 | if ($this->_features->hasgrades) { |
1d50dd13 | 703 | |
16306628 AD |
704 | if (!$this->_features->rating || $this->_features->gradecat) { |
705 | $mform->addElement('header', 'modstandardgrade', get_string('grade')); | |
706 | } | |
707 | ||
708 | //if supports grades and grades arent being handled via ratings | |
709 | if (!$this->_features->rating) { | |
710 | $mform->addElement('modgrade', 'grade', get_string('grade')); | |
711 | $mform->setDefault('grade', 100); | |
712 | } | |
1d50dd13 | 713 | |
b11f9da6 DM |
714 | if ($this->_features->advancedgrading |
715 | and !empty($this->current->_advancedgradingdata['methods']) | |
716 | and !empty($this->current->_advancedgradingdata['areas'])) { | |
717 | ||
718 | if (count($this->current->_advancedgradingdata['areas']) == 1) { | |
719 | // if there is just one gradable area (most cases), display just the selector | |
720 | // without its name to make UI simplier | |
721 | $areadata = reset($this->current->_advancedgradingdata['areas']); | |
722 | $areaname = key($this->current->_advancedgradingdata['areas']); | |
723 | $mform->addElement('select', 'advancedgradingmethod_'.$areaname, | |
724 | get_string('gradingmethod', 'core_grading'), $this->current->_advancedgradingdata['methods']); | |
6832a102 | 725 | $mform->addHelpButton('advancedgradingmethod_'.$areaname, 'gradingmethod', 'core_grading'); |
b11f9da6 DM |
726 | |
727 | } else { | |
728 | // the module defines multiple gradable areas, display a selector | |
729 | // for each of them together with a name of the area | |
730 | $areasgroup = array(); | |
731 | foreach ($this->current->_advancedgradingdata['areas'] as $areaname => $areadata) { | |
732 | $areasgroup[] = $mform->createElement('select', 'advancedgradingmethod_'.$areaname, | |
733 | $areadata['title'], $this->current->_advancedgradingdata['methods']); | |
734 | $areasgroup[] = $mform->createElement('static', 'advancedgradingareaname_'.$areaname, '', $areadata['title']); | |
735 | } | |
736 | $mform->addGroup($areasgroup, 'advancedgradingmethodsgroup', get_string('gradingmethods', 'core_grading'), | |
737 | array(' ', '<br />'), false); | |
738 | } | |
739 | } | |
740 | ||
1d50dd13 | 741 | if ($this->_features->gradecat) { |
71c4154a TH |
742 | $mform->addElement('select', 'gradecat', |
743 | get_string('gradecategoryonmodform', 'grades'), | |
744 | grade_get_categories_menu($COURSE->id, $this->_outcomesused)); | |
745 | $mform->addHelpButton('gradecat', 'gradecategoryonmodform', 'grades'); | |
1d50dd13 AD |
746 | } |
747 | } | |
748 | } | |
749 | ||
dc5c2bd9 | 750 | function add_intro_editor($required=false, $customlabel=null) { |
751 | if (!$this->_features->introeditor) { | |
752 | // intro editor not supported in this module | |
753 | return; | |
754 | } | |
755 | ||
756 | $mform = $this->_form; | |
757 | $label = is_null($customlabel) ? get_string('moduleintro') : $customlabel; | |
758 | ||
09f8d75e | 759 | $mform->addElement('editor', 'introeditor', $label, null, array('maxfiles'=>EDITOR_UNLIMITED_FILES, 'noclean'=>true, 'context'=>$this->context)); |
dc5c2bd9 | 760 | $mform->setType('introeditor', PARAM_RAW); // no XSS prevention here, users must be trusted |
761 | if ($required) { | |
762 | $mform->addRule('introeditor', get_string('required'), 'required', null, 'client'); | |
763 | } | |
8c40662e | 764 | |
765 | // If the 'show description' feature is enabled, this checkbox appears | |
766 | // below the intro. | |
767 | if ($this->_features->showdescription) { | |
768 | $mform->addElement('checkbox', 'showdescription', get_string('showdescription')); | |
769 | $mform->addHelpButton('showdescription', 'showdescription'); | |
770 | } | |
dc5c2bd9 | 771 | } |
772 | ||
6b467109 | 773 | /** |
774 | * Overriding formslib's add_action_buttons() method, to add an extra submit "save changes and return" button. | |
b5ab55dd | 775 | * |
776 | * @param bool $cancel show cancel button | |
777 | * @param string $submitlabel null means default, false means none, string is label text | |
778 | * @param string $submit2label null means default, false means none, string is label text | |
6b467109 | 779 | * @return void |
b5ab55dd | 780 | */ |
6b467109 | 781 | function add_action_buttons($cancel=true, $submitlabel=null, $submit2label=null) { |
782 | if (is_null($submitlabel)) { | |
783 | $submitlabel = get_string('savechangesanddisplay'); | |
784 | } | |
b5ab55dd | 785 | |
6b467109 | 786 | if (is_null($submit2label)) { |
787 | $submit2label = get_string('savechangesandreturntocourse'); | |
788 | } | |
b5ab55dd | 789 | |
dc5c2bd9 | 790 | $mform = $this->_form; |
b5ab55dd | 791 | |
792 | // elements in a row need a group | |
793 | $buttonarray = array(); | |
794 | ||
795 | if ($submit2label !== false) { | |
796 | $buttonarray[] = &$mform->createElement('submit', 'submitbutton2', $submit2label); | |
797 | } | |
798 | ||
799 | if ($submitlabel !== false) { | |
800 | $buttonarray[] = &$mform->createElement('submit', 'submitbutton', $submitlabel); | |
801 | } | |
802 | ||
6b467109 | 803 | if ($cancel) { |
804 | $buttonarray[] = &$mform->createElement('cancel'); | |
805 | } | |
806 | ||
807 | $mform->addGroup($buttonarray, 'buttonar', '', array(' '), false); | |
de6f158f | 808 | $mform->setType('buttonar', PARAM_RAW); |
6b467109 | 809 | $mform->closeHeaderBefore('buttonar'); |
810 | } | |
e24b7f85 | 811 | } |
812 | ||
aa6c1ced | 813 |