Differences Between: [Versions 310 and 400] [Versions 311 and 400] [Versions 39 and 400] [Versions 400 and 402] [Versions 400 and 403]
1 <?php 2 3 // This file is part of Moodle - http://moodle.org/ 4 // 5 // Moodle is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // Moodle is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU General Public License for more details. 14 // 15 // You should have received a copy of the GNU General Public License 16 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 17 18 /** 19 * @package mod_forum 20 * @copyright Jamie Pratt <me@jamiep.org> 21 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 22 */ 23 24 if (!defined('MOODLE_INTERNAL')) { 25 die('Direct access to this script is forbidden.'); /// It must be included from a Moodle page 26 } 27 28 require_once ($CFG->dirroot.'/course/moodleform_mod.php'); 29 30 use core_grades\component_gradeitems; 31 32 class mod_forum_mod_form extends moodleform_mod { 33 34 function definition() { 35 global $CFG, $COURSE, $DB; 36 37 $mform =& $this->_form; 38 39 //------------------------------------------------------------------------------- 40 $mform->addElement('header', 'general', get_string('general', 'form')); 41 42 $mform->addElement('text', 'name', get_string('forumname', 'forum'), array('size'=>'64')); 43 if (!empty($CFG->formatstringstriptags)) { 44 $mform->setType('name', PARAM_TEXT); 45 } else { 46 $mform->setType('name', PARAM_CLEANHTML); 47 } 48 $mform->addRule('name', null, 'required', null, 'client'); 49 $mform->addRule('name', get_string('maximumchars', '', 255), 'maxlength', 255, 'client'); 50 51 $this->standard_intro_elements(get_string('forumintro', 'forum')); 52 53 $forumtypes = forum_get_forum_types(); 54 core_collator::asort($forumtypes, core_collator::SORT_STRING); 55 $mform->addElement('select', 'type', get_string('forumtype', 'forum'), $forumtypes); 56 $mform->addHelpButton('type', 'forumtype', 'forum'); 57 $mform->setDefault('type', 'general'); 58 59 $mform->addElement('header', 'availability', get_string('availability', 'forum')); 60 61 $name = get_string('duedate', 'forum'); 62 $mform->addElement('date_time_selector', 'duedate', $name, array('optional' => true)); 63 $mform->addHelpButton('duedate', 'duedate', 'forum'); 64 65 $name = get_string('cutoffdate', 'forum'); 66 $mform->addElement('date_time_selector', 'cutoffdate', $name, array('optional' => true)); 67 $mform->addHelpButton('cutoffdate', 'cutoffdate', 'forum'); 68 69 // Attachments and word count. 70 $mform->addElement('header', 'attachmentswordcounthdr', get_string('attachmentswordcount', 'forum')); 71 72 $choices = get_max_upload_sizes($CFG->maxbytes, $COURSE->maxbytes, 0, $CFG->forum_maxbytes); 73 $choices[1] = get_string('uploadnotallowed'); 74 $mform->addElement('select', 'maxbytes', get_string('maxattachmentsize', 'forum'), $choices); 75 $mform->addHelpButton('maxbytes', 'maxattachmentsize', 'forum'); 76 $mform->setDefault('maxbytes', $CFG->forum_maxbytes); 77 78 $choices = array( 79 0 => 0, 80 1 => 1, 81 2 => 2, 82 3 => 3, 83 4 => 4, 84 5 => 5, 85 6 => 6, 86 7 => 7, 87 8 => 8, 88 9 => 9, 89 10 => 10, 90 20 => 20, 91 50 => 50, 92 100 => 100 93 ); 94 $mform->addElement('select', 'maxattachments', get_string('maxattachments', 'forum'), $choices); 95 $mform->addHelpButton('maxattachments', 'maxattachments', 'forum'); 96 $mform->setDefault('maxattachments', $CFG->forum_maxattachments); 97 98 $mform->addElement('selectyesno', 'displaywordcount', get_string('displaywordcount', 'forum')); 99 $mform->addHelpButton('displaywordcount', 'displaywordcount', 'forum'); 100 $mform->setDefault('displaywordcount', 0); 101 102 // Subscription and tracking. 103 $mform->addElement('header', 'subscriptionandtrackinghdr', get_string('subscriptionandtracking', 'forum')); 104 105 $options = forum_get_subscriptionmode_options(); 106 $mform->addElement('select', 'forcesubscribe', get_string('subscriptionmode', 'forum'), $options); 107 $mform->addHelpButton('forcesubscribe', 'subscriptionmode', 'forum'); 108 if (isset($CFG->forum_subscription)) { 109 $defaultforumsubscription = $CFG->forum_subscription; 110 } else { 111 $defaultforumsubscription = FORUM_CHOOSESUBSCRIBE; 112 } 113 $mform->setDefault('forcesubscribe', $defaultforumsubscription); 114 115 $options = array(); 116 $options[FORUM_TRACKING_OPTIONAL] = get_string('trackingoptional', 'forum'); 117 $options[FORUM_TRACKING_OFF] = get_string('trackingoff', 'forum'); 118 if ($CFG->forum_allowforcedreadtracking) { 119 $options[FORUM_TRACKING_FORCED] = get_string('trackingon', 'forum'); 120 } 121 $mform->addElement('select', 'trackingtype', get_string('trackingtype', 'forum'), $options); 122 $mform->addHelpButton('trackingtype', 'trackingtype', 'forum'); 123 $default = $CFG->forum_trackingtype; 124 if ((!$CFG->forum_allowforcedreadtracking) && ($default == FORUM_TRACKING_FORCED)) { 125 $default = FORUM_TRACKING_OPTIONAL; 126 } 127 $mform->setDefault('trackingtype', $default); 128 129 if ($CFG->enablerssfeeds && isset($CFG->forum_enablerssfeeds) && $CFG->forum_enablerssfeeds) { 130 //------------------------------------------------------------------------------- 131 $mform->addElement('header', 'rssheader', get_string('rss')); 132 $choices = array(); 133 $choices[0] = get_string('none'); 134 $choices[1] = get_string('discussions', 'forum'); 135 $choices[2] = get_string('posts', 'forum'); 136 $mform->addElement('select', 'rsstype', get_string('rsstype', 'forum'), $choices); 137 $mform->addHelpButton('rsstype', 'rsstype', 'forum'); 138 if (isset($CFG->forum_rsstype)) { 139 $mform->setDefault('rsstype', $CFG->forum_rsstype); 140 } 141 142 $choices = array(); 143 $choices[0] = '0'; 144 $choices[1] = '1'; 145 $choices[2] = '2'; 146 $choices[3] = '3'; 147 $choices[4] = '4'; 148 $choices[5] = '5'; 149 $choices[10] = '10'; 150 $choices[15] = '15'; 151 $choices[20] = '20'; 152 $choices[25] = '25'; 153 $choices[30] = '30'; 154 $choices[40] = '40'; 155 $choices[50] = '50'; 156 $mform->addElement('select', 'rssarticles', get_string('rssarticles'), $choices); 157 $mform->addHelpButton('rssarticles', 'rssarticles', 'forum'); 158 $mform->hideIf('rssarticles', 'rsstype', 'eq', '0'); 159 if (isset($CFG->forum_rssarticles)) { 160 $mform->setDefault('rssarticles', $CFG->forum_rssarticles); 161 } 162 } 163 164 $mform->addElement('header', 'discussionlocking', get_string('discussionlockingheader', 'forum')); 165 $options = [ 166 0 => get_string('discussionlockingdisabled', 'forum'), 167 1 * DAYSECS => get_string('numday', 'core', 1), 168 1 * WEEKSECS => get_string('numweek', 'core', 1), 169 2 * WEEKSECS => get_string('numweeks', 'core', 2), 170 30 * DAYSECS => get_string('nummonth', 'core', 1), 171 60 * DAYSECS => get_string('nummonths', 'core', 2), 172 90 * DAYSECS => get_string('nummonths', 'core', 3), 173 180 * DAYSECS => get_string('nummonths', 'core', 6), 174 1 * YEARSECS => get_string('numyear', 'core', 1), 175 ]; 176 $mform->addElement('select', 'lockdiscussionafter', get_string('lockdiscussionafter', 'forum'), $options); 177 $mform->addHelpButton('lockdiscussionafter', 'lockdiscussionafter', 'forum'); 178 $mform->disabledIf('lockdiscussionafter', 'type', 'eq', 'single'); 179 180 //------------------------------------------------------------------------------- 181 $mform->addElement('header', 'blockafterheader', get_string('blockafter', 'forum')); 182 $options = array(); 183 $options[0] = get_string('blockperioddisabled','forum'); 184 $options[60*60*24] = '1 '.get_string('day'); 185 $options[60*60*24*2] = '2 '.get_string('days'); 186 $options[60*60*24*3] = '3 '.get_string('days'); 187 $options[60*60*24*4] = '4 '.get_string('days'); 188 $options[60*60*24*5] = '5 '.get_string('days'); 189 $options[60*60*24*6] = '6 '.get_string('days'); 190 $options[60*60*24*7] = '1 '.get_string('week'); 191 $mform->addElement('select', 'blockperiod', get_string('blockperiod', 'forum'), $options); 192 $mform->addHelpButton('blockperiod', 'blockperiod', 'forum'); 193 194 $mform->addElement('text', 'blockafter', get_string('blockafter', 'forum')); 195 $mform->setType('blockafter', PARAM_INT); 196 $mform->setDefault('blockafter', '0'); 197 $mform->addRule('blockafter', null, 'numeric', null, 'client'); 198 $mform->addHelpButton('blockafter', 'blockafter', 'forum'); 199 $mform->hideIf('blockafter', 'blockperiod', 'eq', 0); 200 201 $mform->addElement('text', 'warnafter', get_string('warnafter', 'forum')); 202 $mform->setType('warnafter', PARAM_INT); 203 $mform->setDefault('warnafter', '0'); 204 $mform->addRule('warnafter', null, 'numeric', null, 'client'); 205 $mform->addHelpButton('warnafter', 'warnafter', 'forum'); 206 $mform->hideIf('warnafter', 'blockperiod', 'eq', 0); 207 208 $coursecontext = context_course::instance($COURSE->id); 209 // To be removed (deprecated) with MDL-67526. 210 plagiarism_get_form_elements_module($mform, $coursecontext, 'mod_forum'); 211 212 //------------------------------------------------------------------------------- 213 214 // Add the whole forum grading options. 215 $this->add_forum_grade_settings($mform, 'forum'); 216 217 $this->standard_coursemodule_elements(); 218 //------------------------------------------------------------------------------- 219 // buttons 220 $this->add_action_buttons(); 221 } 222 223 /** 224 * Add the whole forum grade settings to the mform. 225 * 226 * @param \mform $mform 227 * @param string $itemname 228 */ 229 private function add_forum_grade_settings($mform, string $itemname) { 230 global $COURSE; 231 232 $component = "mod_{$this->_modname}"; 233 $defaultgradingvalue = 0; 234 235 $itemnumber = component_gradeitems::get_itemnumber_from_itemname($component, $itemname); 236 $gradefieldname = component_gradeitems::get_field_name_for_itemnumber($component, $itemnumber, 'grade'); 237 $gradecatfieldname = component_gradeitems::get_field_name_for_itemnumber($component, $itemnumber, 'gradecat'); 238 $gradepassfieldname = component_gradeitems::get_field_name_for_itemnumber($component, $itemnumber, 'gradepass'); 239 $sendstudentnotificationsfieldname = component_gradeitems::get_field_name_for_itemnumber($component, $itemnumber, 240 'sendstudentnotifications'); 241 242 // The advancedgradingmethod is different in that it is suffixed with an area name... which is not the 243 // itemnumber. 244 $methodfieldname = "advancedgradingmethod_{$itemname}"; 245 246 $headername = "{$gradefieldname}_header"; 247 $mform->addElement('header', $headername, get_string("grade_{$itemname}_header", $component)); 248 249 $isupdate = !empty($this->_cm); 250 $gradeoptions = [ 251 'isupdate' => $isupdate, 252 'currentgrade' => false, 253 'hasgrades' => false, 254 'canrescale' => false, 255 'useratings' => false, 256 ]; 257 258 if ($isupdate) { 259 $gradeitem = grade_item::fetch([ 260 'itemtype' => 'mod', 261 'itemmodule' => $this->_cm->modname, 262 'iteminstance' => $this->_cm->instance, 263 'itemnumber' => $itemnumber, 264 'courseid' => $COURSE->id, 265 ]); 266 if ($gradeitem) { 267 $gradeoptions['currentgrade'] = $gradeitem->grademax; 268 $gradeoptions['currentgradetype'] = $gradeitem->gradetype; 269 $gradeoptions['currentscaleid'] = $gradeitem->scaleid; 270 $gradeoptions['hasgrades'] = $gradeitem->has_grades(); 271 } 272 } 273 $mform->addElement( 274 'modgrade', 275 $gradefieldname, 276 get_string("{$gradefieldname}_title", $component), 277 $gradeoptions 278 ); 279 $mform->addHelpButton($gradefieldname, 'modgrade', 'grades'); 280 $mform->setDefault($gradefieldname, $defaultgradingvalue); 281 282 if (!empty($this->current->_advancedgradingdata['methods']) && !empty($this->current->_advancedgradingdata['areas'])) { 283 $areadata = $this->current->_advancedgradingdata['areas'][$itemname]; 284 $mform->addElement( 285 'select', 286 $methodfieldname, 287 get_string('gradingmethod', 'core_grading'), 288 $this->current->_advancedgradingdata['methods'] 289 ); 290 $mform->addHelpButton($methodfieldname, 'gradingmethod', 'core_grading'); 291 $mform->hideIf($methodfieldname, "{$gradefieldname}[modgrade_type]", 'eq', 'none'); 292 } 293 294 // Grade category. 295 $mform->addElement( 296 'select', 297 $gradecatfieldname, 298 get_string('gradecategoryonmodform', 'grades'), 299 grade_get_categories_menu($COURSE->id, $this->_outcomesused) 300 ); 301 $mform->addHelpButton($gradecatfieldname, 'gradecategoryonmodform', 'grades'); 302 $mform->hideIf($gradecatfieldname, "{$gradefieldname}[modgrade_type]", 'eq', 'none'); 303 304 // Grade to pass. 305 $mform->addElement('text', $gradepassfieldname, get_string('gradepass', 'grades')); 306 $mform->addHelpButton($gradepassfieldname, 'gradepass', 'grades'); 307 $mform->setDefault($gradepassfieldname, ''); 308 $mform->setType($gradepassfieldname, PARAM_RAW); 309 $mform->hideIf($gradepassfieldname, "{$gradefieldname}[modgrade_type]", 'eq', 'none'); 310 311 $mform->addElement( 312 'selectyesno', 313 $sendstudentnotificationsfieldname, 314 get_string('sendstudentnotificationsdefault', 'forum') 315 ); 316 $mform->addHelpButton($sendstudentnotificationsfieldname, 'sendstudentnotificationsdefault', 'forum'); 317 $mform->hideIf($sendstudentnotificationsfieldname, "{$gradefieldname}[modgrade_type]", 'eq', 'none'); 318 } 319 320 function definition_after_data() { 321 parent::definition_after_data(); 322 $mform =& $this->_form; 323 $type =& $mform->getElement('type'); 324 $typevalue = $mform->getElementValue('type'); 325 326 //we don't want to have these appear as possible selections in the form but 327 //we want the form to display them if they are set. 328 if ($typevalue[0]=='news') { 329 $type->addOption(get_string('namenews', 'forum'), 'news'); 330 $mform->addHelpButton('type', 'namenews', 'forum'); 331 $type->freeze(); 332 $type->setPersistantFreeze(true); 333 } 334 if ($typevalue[0]=='social') { 335 $type->addOption(get_string('namesocial', 'forum'), 'social'); 336 $type->freeze(); 337 $type->setPersistantFreeze(true); 338 } 339 } 340 341 public function validation($data, $files) { 342 $errors = parent::validation($data, $files); 343 344 if ($data['type'] === 'single' && $data['groupmode'] == SEPARATEGROUPS) { 345 $errors['type'] = get_string('cannotusesingletopicandseperategroups', 'forum'); 346 $errors['groupmode'] = get_string('cannotuseseperategroupsandsingletopic', 'forum'); 347 } 348 349 if ($data['duedate'] && $data['cutoffdate']) { 350 if ($data['duedate'] > $data['cutoffdate']) { 351 $errors['cutoffdate'] = get_string('cutoffdatevalidation', 'forum'); 352 } 353 } 354 355 $this->validation_forum_grade($data, $files, $errors); 356 357 return $errors; 358 } 359 360 /** 361 * Handle definition after data for grade settings. 362 * 363 * @param array $data 364 * @param array $files 365 * @param array $errors 366 */ 367 private function validation_forum_grade(array $data, array $files, array $errors) { 368 global $COURSE; 369 370 $mform =& $this->_form; 371 372 $component = "mod_forum"; 373 $itemname = 'forum'; 374 $itemnumber = component_gradeitems::get_itemnumber_from_itemname($component, $itemname); 375 $gradefieldname = component_gradeitems::get_field_name_for_itemnumber($component, $itemnumber, 'grade'); 376 $gradepassfieldname = component_gradeitems::get_field_name_for_itemnumber($component, $itemnumber, 'grade'); 377 378 $gradeitem = grade_item::fetch([ 379 'itemtype' => 'mod', 380 'itemmodule' => $data['modulename'], 381 'iteminstance' => $data['instance'], 382 'itemnumber' => $itemnumber, 383 'courseid' => $COURSE->id, 384 ]); 385 386 if ($mform->elementExists('cmidnumber') && $this->_cm) { 387 if (!grade_verify_idnumber($data['cmidnumber'], $COURSE->id, $gradeitem, $this->_cm)) { 388 $errors['cmidnumber'] = get_string('idnumbertaken'); 389 } 390 } 391 392 // Check that the grade pass is a valid number. 393 $gradepassvalid = false; 394 if (isset($data[$gradepassfieldname])) { 395 if (unformat_float($data[$gradepassfieldname], true) === false) { 396 $errors[$gradepassfieldname] = get_string('err_numeric', 'form'); 397 } else { 398 $gradepassvalid = true; 399 } 400 } 401 402 // Grade to pass: ensure that the grade to pass is valid for points and scales. 403 // If we are working with a scale, convert into a positive number for validation. 404 if ($gradepassvalid && isset($data[$gradepassfieldname]) && (!empty($data[$gradefieldname]))) { 405 $grade = $data[$gradefieldname]; 406 if (unformat_float($data[$gradepassfieldname]) > $grade) { 407 $errors[$gradepassfieldname] = get_string('gradepassgreaterthangrade', 'grades', $grade); 408 } 409 } 410 } 411 412 function data_preprocessing(&$default_values) { 413 parent::data_preprocessing($default_values); 414 415 // Set up the completion checkboxes which aren't part of standard data. 416 // We also make the default value (if you turn on the checkbox) for those 417 // numbers to be 1, this will not apply unless checkbox is ticked. 418 $default_values['completiondiscussionsenabled']= 419 !empty($default_values['completiondiscussions']) ? 1 : 0; 420 if (empty($default_values['completiondiscussions'])) { 421 $default_values['completiondiscussions']=1; 422 } 423 $default_values['completionrepliesenabled']= 424 !empty($default_values['completionreplies']) ? 1 : 0; 425 if (empty($default_values['completionreplies'])) { 426 $default_values['completionreplies']=1; 427 } 428 // Tick by default if Add mode or if completion posts settings is set to 1 or more. 429 if (empty($this->_instance) || !empty($default_values['completionposts'])) { 430 $default_values['completionpostsenabled'] = 1; 431 } else { 432 $default_values['completionpostsenabled'] = 0; 433 } 434 if (empty($default_values['completionposts'])) { 435 $default_values['completionposts']=1; 436 } 437 } 438 439 /** 440 * Add custom completion rules. 441 * 442 * @return array Array of string IDs of added items, empty array if none 443 */ 444 public function add_completion_rules() { 445 $mform =& $this->_form; 446 447 $group=array(); 448 $group[] =& $mform->createElement('checkbox', 'completionpostsenabled', '', get_string('completionposts','forum')); 449 $group[] =& $mform->createElement('text', 'completionposts', '', array('size'=>3)); 450 $mform->setType('completionposts',PARAM_INT); 451 $mform->addGroup($group, 'completionpostsgroup', get_string('completionpostsgroup','forum'), array(' '), false); 452 $mform->disabledIf('completionposts','completionpostsenabled','notchecked'); 453 454 $group=array(); 455 $group[] =& $mform->createElement('checkbox', 'completiondiscussionsenabled', '', get_string('completiondiscussions','forum')); 456 $group[] =& $mform->createElement('text', 'completiondiscussions', '', array('size'=>3)); 457 $mform->setType('completiondiscussions',PARAM_INT); 458 $mform->addGroup($group, 'completiondiscussionsgroup', get_string('completiondiscussionsgroup','forum'), array(' '), false); 459 $mform->disabledIf('completiondiscussions','completiondiscussionsenabled','notchecked'); 460 461 $group=array(); 462 $group[] =& $mform->createElement('checkbox', 'completionrepliesenabled', '', get_string('completionreplies','forum')); 463 $group[] =& $mform->createElement('text', 'completionreplies', '', array('size'=>3)); 464 $mform->setType('completionreplies',PARAM_INT); 465 $mform->addGroup($group, 'completionrepliesgroup', get_string('completionrepliesgroup','forum'), array(' '), false); 466 $mform->disabledIf('completionreplies','completionrepliesenabled','notchecked'); 467 468 return array('completiondiscussionsgroup','completionrepliesgroup','completionpostsgroup'); 469 } 470 471 function completion_rule_enabled($data) { 472 return (!empty($data['completiondiscussionsenabled']) && $data['completiondiscussions']!=0) || 473 (!empty($data['completionrepliesenabled']) && $data['completionreplies']!=0) || 474 (!empty($data['completionpostsenabled']) && $data['completionposts']!=0); 475 } 476 477 /** 478 * Return submitted data if properly submitted or returns NULL if validation fails or 479 * if there is no submitted data. 480 * 481 * Do not override this method, override data_postprocessing() instead. 482 * 483 * @return object submitted data; NULL if not valid or not submitted or cancelled 484 */ 485 public function get_data() { 486 $data = parent::get_data(); 487 if ($data) { 488 $itemname = 'forum'; 489 $component = 'mod_forum'; 490 $gradepassfieldname = component_gradeitems::get_field_name_for_itemname($component, $itemname, 'gradepass'); 491 492 // Convert the grade pass value - we may be using a language which uses commas, 493 // rather than decimal points, in numbers. These need to be converted so that 494 // they can be added to the DB. 495 if (isset($data->{$gradepassfieldname})) { 496 $data->{$gradepassfieldname} = unformat_float($data->{$gradepassfieldname}); 497 } 498 } 499 500 return $data; 501 } 502 503 /** 504 * Allows module to modify the data returned by form get_data(). 505 * This method is also called in the bulk activity completion form. 506 * 507 * Only available on moodleform_mod. 508 * 509 * @param stdClass $data the form data to be modified. 510 */ 511 public function data_postprocessing($data) { 512 parent::data_postprocessing($data); 513 // Turn off completion settings if the checkboxes aren't ticked 514 if (!empty($data->completionunlocked)) { 515 $autocompletion = !empty($data->completion) && $data->completion==COMPLETION_TRACKING_AUTOMATIC; 516 if (empty($data->completiondiscussionsenabled) || !$autocompletion) { 517 $data->completiondiscussions = 0; 518 } 519 if (empty($data->completionrepliesenabled) || !$autocompletion) { 520 $data->completionreplies = 0; 521 } 522 if (empty($data->completionpostsenabled) || !$autocompletion) { 523 $data->completionposts = 0; 524 } 525 } 526 } 527 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body