Differences Between: [Versions 310 and 400] [Versions 310 and 401] [Versions 310 and 402] [Versions 310 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['duedate'] && $data['cutoffdate']) { 345 if ($data['duedate'] > $data['cutoffdate']) { 346 $errors['cutoffdate'] = get_string('cutoffdatevalidation', 'forum'); 347 } 348 } 349 350 $this->validation_forum_grade($data, $files, $errors); 351 352 return $errors; 353 } 354 355 /** 356 * Handle definition after data for grade settings. 357 * 358 * @param array $data 359 * @param array $files 360 * @param array $errors 361 */ 362 private function validation_forum_grade(array $data, array $files, array $errors) { 363 global $COURSE; 364 365 $mform =& $this->_form; 366 367 $component = "mod_forum"; 368 $itemname = 'forum'; 369 $itemnumber = component_gradeitems::get_itemnumber_from_itemname($component, $itemname); 370 $gradefieldname = component_gradeitems::get_field_name_for_itemnumber($component, $itemnumber, 'grade'); 371 $gradepassfieldname = component_gradeitems::get_field_name_for_itemnumber($component, $itemnumber, 'grade'); 372 373 $gradeitem = grade_item::fetch([ 374 'itemtype' => 'mod', 375 'itemmodule' => $data['modulename'], 376 'iteminstance' => $data['instance'], 377 'itemnumber' => $itemnumber, 378 'courseid' => $COURSE->id, 379 ]); 380 381 if ($mform->elementExists('cmidnumber') && $this->_cm) { 382 if (!grade_verify_idnumber($data['cmidnumber'], $COURSE->id, $gradeitem, $this->_cm)) { 383 $errors['cmidnumber'] = get_string('idnumbertaken'); 384 } 385 } 386 387 // Check that the grade pass is a valid number. 388 $gradepassvalid = false; 389 if (isset($data[$gradepassfieldname])) { 390 if (unformat_float($data[$gradepassfieldname], true) === false) { 391 $errors[$gradepassfieldname] = get_string('err_numeric', 'form'); 392 } else { 393 $gradepassvalid = true; 394 } 395 } 396 397 // Grade to pass: ensure that the grade to pass is valid for points and scales. 398 // If we are working with a scale, convert into a positive number for validation. 399 if ($gradepassvalid && isset($data[$gradepassfieldname]) && (!empty($data[$gradefieldname]))) { 400 $grade = $data[$gradefieldname]; 401 if (unformat_float($data[$gradepassfieldname]) > $grade) { 402 $errors[$gradepassfieldname] = get_string('gradepassgreaterthangrade', 'grades', $grade); 403 } 404 } 405 } 406 407 function data_preprocessing(&$default_values) { 408 parent::data_preprocessing($default_values); 409 410 // Set up the completion checkboxes which aren't part of standard data. 411 // We also make the default value (if you turn on the checkbox) for those 412 // numbers to be 1, this will not apply unless checkbox is ticked. 413 $default_values['completiondiscussionsenabled']= 414 !empty($default_values['completiondiscussions']) ? 1 : 0; 415 if (empty($default_values['completiondiscussions'])) { 416 $default_values['completiondiscussions']=1; 417 } 418 $default_values['completionrepliesenabled']= 419 !empty($default_values['completionreplies']) ? 1 : 0; 420 if (empty($default_values['completionreplies'])) { 421 $default_values['completionreplies']=1; 422 } 423 // Tick by default if Add mode or if completion posts settings is set to 1 or more. 424 if (empty($this->_instance) || !empty($default_values['completionposts'])) { 425 $default_values['completionpostsenabled'] = 1; 426 } else { 427 $default_values['completionpostsenabled'] = 0; 428 } 429 if (empty($default_values['completionposts'])) { 430 $default_values['completionposts']=1; 431 } 432 } 433 434 /** 435 * Add custom completion rules. 436 * 437 * @return array Array of string IDs of added items, empty array if none 438 */ 439 public function add_completion_rules() { 440 $mform =& $this->_form; 441 442 $group=array(); 443 $group[] =& $mform->createElement('checkbox', 'completionpostsenabled', '', get_string('completionposts','forum')); 444 $group[] =& $mform->createElement('text', 'completionposts', '', array('size'=>3)); 445 $mform->setType('completionposts',PARAM_INT); 446 $mform->addGroup($group, 'completionpostsgroup', get_string('completionpostsgroup','forum'), array(' '), false); 447 $mform->disabledIf('completionposts','completionpostsenabled','notchecked'); 448 449 $group=array(); 450 $group[] =& $mform->createElement('checkbox', 'completiondiscussionsenabled', '', get_string('completiondiscussions','forum')); 451 $group[] =& $mform->createElement('text', 'completiondiscussions', '', array('size'=>3)); 452 $mform->setType('completiondiscussions',PARAM_INT); 453 $mform->addGroup($group, 'completiondiscussionsgroup', get_string('completiondiscussionsgroup','forum'), array(' '), false); 454 $mform->disabledIf('completiondiscussions','completiondiscussionsenabled','notchecked'); 455 456 $group=array(); 457 $group[] =& $mform->createElement('checkbox', 'completionrepliesenabled', '', get_string('completionreplies','forum')); 458 $group[] =& $mform->createElement('text', 'completionreplies', '', array('size'=>3)); 459 $mform->setType('completionreplies',PARAM_INT); 460 $mform->addGroup($group, 'completionrepliesgroup', get_string('completionrepliesgroup','forum'), array(' '), false); 461 $mform->disabledIf('completionreplies','completionrepliesenabled','notchecked'); 462 463 return array('completiondiscussionsgroup','completionrepliesgroup','completionpostsgroup'); 464 } 465 466 function completion_rule_enabled($data) { 467 return (!empty($data['completiondiscussionsenabled']) && $data['completiondiscussions']!=0) || 468 (!empty($data['completionrepliesenabled']) && $data['completionreplies']!=0) || 469 (!empty($data['completionpostsenabled']) && $data['completionposts']!=0); 470 } 471 472 /** 473 * Return submitted data if properly submitted or returns NULL if validation fails or 474 * if there is no submitted data. 475 * 476 * Do not override this method, override data_postprocessing() instead. 477 * 478 * @return object submitted data; NULL if not valid or not submitted or cancelled 479 */ 480 public function get_data() { 481 $data = parent::get_data(); 482 if ($data) { 483 $itemname = 'forum'; 484 $component = 'mod_forum'; 485 $gradepassfieldname = component_gradeitems::get_field_name_for_itemname($component, $itemname, 'gradepass'); 486 487 // Convert the grade pass value - we may be using a language which uses commas, 488 // rather than decimal points, in numbers. These need to be converted so that 489 // they can be added to the DB. 490 if (isset($data->{$gradepassfieldname})) { 491 $data->{$gradepassfieldname} = unformat_float($data->{$gradepassfieldname}); 492 } 493 } 494 495 return $data; 496 } 497 498 /** 499 * Allows module to modify the data returned by form get_data(). 500 * This method is also called in the bulk activity completion form. 501 * 502 * Only available on moodleform_mod. 503 * 504 * @param stdClass $data the form data to be modified. 505 */ 506 public function data_postprocessing($data) { 507 parent::data_postprocessing($data); 508 // Turn off completion settings if the checkboxes aren't ticked 509 if (!empty($data->completionunlocked)) { 510 $autocompletion = !empty($data->completion) && $data->completion==COMPLETION_TRACKING_AUTOMATIC; 511 if (empty($data->completiondiscussionsenabled) || !$autocompletion) { 512 $data->completiondiscussions = 0; 513 } 514 if (empty($data->completionrepliesenabled) || !$autocompletion) { 515 $data->completionreplies = 0; 516 } 517 if (empty($data->completionpostsenabled) || !$autocompletion) { 518 $data->completionposts = 0; 519 } 520 } 521 } 522 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body