Merge branch 'MDL-36412-master' of git://github.com/sammarshallou/moodle
[moodle.git] / course / editsection_form.php
1 <?php
3 if (!defined('MOODLE_INTERNAL')) {
4     die('Direct access to this script is forbidden.');    ///  It must be included from a Moodle page
5 }
7 require_once($CFG->libdir.'/formslib.php');
8 require_once($CFG->libdir.'/filelib.php');
9 require_once($CFG->libdir.'/completionlib.php');
10 require_once($CFG->libdir.'/gradelib.php');
12 /**
13  * Default form for editing course section
14  *
15  * Course format plugins may specify different editing form to use
16  */
17 class editsection_form extends moodleform {
19     function definition() {
21         $mform  = $this->_form;
22         $course = $this->_customdata['course'];
23         $mform->addElement('checkbox', 'usedefaultname', get_string('sectionusedefaultname'));
24         $mform->setDefault('usedefaultname', true);
26         $mform->addElement('text', 'name', get_string('sectionname'), array('size'=>'30'));
27         $mform->setType('name', PARAM_TEXT);
28         $mform->disabledIf('name','usedefaultname','checked');
30         /// Prepare course and the editor
32         $mform->addElement('editor', 'summary_editor', get_string('summary'), null, $this->_customdata['editoroptions']);
33         $mform->addHelpButton('summary_editor', 'summary');
34         $mform->setType('summary_editor', PARAM_RAW);
36         $mform->addElement('hidden', 'id');
37         $mform->setType('id', PARAM_INT);
39         // additional fields that course format has defined
40         $courseformat = course_get_format($course);
41         $formatoptions = $courseformat->section_format_options(true);
42         if (!empty($formatoptions)) {
43             $elements = $courseformat->create_edit_form_elements($mform, true);
44         }
46         $mform->_registerCancelButton('cancel');
47     }
49     public function definition_after_data() {
50         global $CFG, $DB;
52         $mform  = $this->_form;
53         $course = $this->_customdata['course'];
55         if (!empty($CFG->enableavailability)) {
56             $mform->addElement('header', '', get_string('availabilityconditions', 'condition'));
57             // String used by conditions more than once
58             $strcondnone = get_string('none', 'condition');
59             // Grouping conditions - only if grouping is enabled at site level
60             if (!empty($CFG->enablegroupmembersonly)) {
61                 $options = array();
62                 $options[0] = get_string('none');
63                 if ($groupings = $DB->get_records('groupings', array('courseid' => $course->id))) {
64                     foreach ($groupings as $grouping) {
65                         $context = context_course::instance($course->id);
66                         $options[$grouping->id] = format_string(
67                                 $grouping->name, true, array('context' => $context));
68                     }
69                 }
70                 $mform->addElement('select', 'groupingid', get_string('groupingsection', 'group'), $options);
71                 $mform->addHelpButton('groupingid', 'groupingsection', 'group');
72             }
74             // Available from/to defaults to midnight because then the display
75             // will be nicer where it tells users when they can access it (it
76             // shows only the date and not time).
77             $date = usergetdate(time());
78             $midnight = make_timestamp($date['year'], $date['mon'], $date['mday']);
80             // Date and time conditions.
81             $mform->addElement('date_time_selector', 'availablefrom',
82                     get_string('availablefrom', 'condition'),
83                     array('optional' => true, 'defaulttime' => $midnight));
84             $mform->addElement('date_time_selector', 'availableuntil',
85                     get_string('availableuntil', 'condition'),
86                     array('optional' => true, 'defaulttime' => $midnight));
88             // Conditions based on grades
89             $gradeoptions = array();
90             $items = grade_item::fetch_all(array('courseid' => $course->id));
91             $items = $items ? $items : array();
92             foreach ($items as $id => $item) {
93                 $gradeoptions[$id] = $item->get_name();
94             }
95             asort($gradeoptions);
96             $gradeoptions = array(0 => $strcondnone) + $gradeoptions;
98             $grouparray = array();
99             $grouparray[] = $mform->createElement('select', 'conditiongradeitemid', '', $gradeoptions);
100             $grouparray[] = $mform->createElement('static', '', '',
101                     ' ' . get_string('grade_atleast', 'condition').' ');
102             $grouparray[] = $mform->createElement('text', 'conditiongrademin', '', array('size' => 3));
103             $grouparray[] = $mform->createElement('static', '', '',
104                     '% ' . get_string('grade_upto', 'condition') . ' ');
105             $grouparray[] = $mform->createElement('text', 'conditiongrademax', '', array('size' => 3));
106             $grouparray[] = $mform->createElement('static', '', '', '%');
107             $group = $mform->createElement('group', 'conditiongradegroup',
108                     get_string('gradecondition', 'condition'), $grouparray);
110             // Get full version (including condition info) of section object
111             $ci = new condition_info_section($this->_customdata['cs']);
112             $fullcs = $ci->get_full_section();
113             $count = count($fullcs->conditionsgrade) + 1;
115             // Grade conditions
116             $this->repeat_elements(array($group), $count, array(), 'conditiongraderepeats',
117                     'conditiongradeadds', 2, get_string('addgrades', 'condition'), true);
118             $mform->addHelpButton('conditiongradegroup[0]', 'gradecondition', 'condition');
120             // Conditions based on user fields
121             $operators = condition_info::get_condition_user_field_operators();
122             $useroptions = condition_info::get_condition_user_fields();
123             asort($useroptions);
125             $useroptions = array(0 => $strcondnone) + $useroptions;
126             $grouparray = array();
127             $grouparray[] =& $mform->createElement('select', 'conditionfield', '', $useroptions);
128             $grouparray[] =& $mform->createElement('select', 'conditionfieldoperator', '', $operators);
129             $grouparray[] =& $mform->createElement('text', 'conditionfieldvalue');
130             $mform->setType('conditionfieldvalue', PARAM_RAW);
131             $group = $mform->createElement('group', 'conditionfieldgroup', get_string('userfield', 'condition'), $grouparray);
133             $fieldcount = count($fullcs->conditionsfield) + 1;
135             $this->repeat_elements(array($group), $fieldcount, array(), 'conditionfieldrepeats', 'conditionfieldadds', 2,
136                                    get_string('adduserfields', 'condition'), true);
137             $mform->addHelpButton('conditionfieldgroup[0]', 'userfield', 'condition');
139             // Conditions based on completion
140             $completion = new completion_info($course);
141             if ($completion->is_enabled()) {
142                 $completionoptions = array();
143                 $modinfo = get_fast_modinfo($course);
144                 foreach ($modinfo->cms as $id => $cm) {
145                     // Add each course-module if it:
146                     // (a) has completion turned on
147                     // (b) does not belong to current course-section
148                     if ($cm->completion && ($fullcs->id != $cm->section)) {
149                         $completionoptions[$id] = $cm->name;
150                     }
151                 }
152                 asort($completionoptions);
153                 $completionoptions = array(0 => $strcondnone) +
154                         $completionoptions;
156                 $completionvalues = array(
157                     COMPLETION_COMPLETE => get_string('completion_complete', 'condition'),
158                     COMPLETION_INCOMPLETE => get_string('completion_incomplete', 'condition'),
159                     COMPLETION_COMPLETE_PASS => get_string('completion_pass', 'condition'),
160                     COMPLETION_COMPLETE_FAIL => get_string('completion_fail', 'condition'));
162                 $grouparray = array();
163                 $grouparray[] = $mform->createElement('select', 'conditionsourcecmid', '',
164                         $completionoptions);
165                 $grouparray[] = $mform->createElement('select', 'conditionrequiredcompletion', '',
166                         $completionvalues);
167                 $group = $mform->createElement('group', 'conditioncompletiongroup',
168                         get_string('completioncondition', 'condition'), $grouparray);
170                 $count = count($fullcs->conditionscompletion) + 1;
171                 $this->repeat_elements(array($group), $count, array(),
172                         'conditioncompletionrepeats', 'conditioncompletionadds', 2,
173                         get_string('addcompletions', 'condition'), true);
174                 $mform->addHelpButton('conditioncompletiongroup[0]',
175                         'completionconditionsection', 'condition');
176             }
178             // Availability conditions - set up form values
179             if (!empty($CFG->enableavailability)) {
180                 $num = 0;
181                 foreach ($fullcs->conditionsgrade as $gradeitemid => $minmax) {
182                     $groupelements = $mform->getElement(
183                             'conditiongradegroup[' . $num . ']')->getElements();
184                     $groupelements[0]->setValue($gradeitemid);
185                     $groupelements[2]->setValue(is_null($minmax->min) ? '' :
186                             format_float($minmax->min, 5, true, true));
187                     $groupelements[4]->setValue(is_null($minmax->max) ? '' :
188                             format_float($minmax->max, 5, true, true));
189                     $num++;
190                 }
192                 $num = 0;
193                 foreach ($fullcs->conditionsfield as $fieldid => $data) {
194                     $groupelements = $mform->getElement(
195                             'conditionfieldgroup[' . $num . ']')->getElements();
196                     $groupelements[0]->setValue($fieldid);
197                     $groupelements[1]->setValue(is_null($data->operator) ? '' :
198                             $data->operator);
199                     $groupelements[2]->setValue(is_null($data->value) ? '' :
200                             $data->value);
201                     $num++;
202                 }
204                 if ($completion->is_enabled()) {
205                     $num = 0;
206                     foreach ($fullcs->conditionscompletion as $othercmid => $state) {
207                         $groupelements = $mform->getElement('conditioncompletiongroup[' . $num . ']')->getElements();
208                         $groupelements[0]->setValue($othercmid);
209                         $groupelements[1]->setValue($state);
210                         $num++;
211                     }
212                 }
213             }
215             // Do we display availability info to students?
216             $showhide = array(
217                 CONDITION_STUDENTVIEW_SHOW => get_string('showavailabilitysection_show', 'condition'),
218                 CONDITION_STUDENTVIEW_HIDE => get_string('showavailabilitysection_hide', 'condition'));
219             $mform->addElement('select', 'showavailability',
220                     get_string('showavailabilitysection', 'condition'), $showhide);
221         }
223         $this->add_action_buttons();
224     }
226     public function validation($data, $files) {
227         $errors = parent::validation($data, $files);
228         // Conditions: Don't let them set dates which make no sense
229         if (array_key_exists('availablefrom', $data) &&
230                 $data['availablefrom'] && $data['availableuntil'] &&
231                 $data['availablefrom'] >= $data['availableuntil']) {
232             $errors['availablefrom'] = get_string('badavailabledates', 'condition');
233         }
235         // Conditions: Verify that the grade conditions are numbers, and make sense.
236         if (array_key_exists('conditiongradegroup', $data)) {
237             foreach ($data['conditiongradegroup'] as $i => $gradedata) {
238                 if ($gradedata['conditiongrademin'] !== '' &&
239                         !is_numeric(unformat_float($gradedata['conditiongrademin']))) {
240                     $errors["conditiongradegroup[{$i}]"] = get_string('gradesmustbenumeric', 'condition');
241                     continue;
242                 }
243                 if ($gradedata['conditiongrademax'] !== '' &&
244                         !is_numeric(unformat_float($gradedata['conditiongrademax']))) {
245                     $errors["conditiongradegroup[{$i}]"] = get_string('gradesmustbenumeric', 'condition');
246                     continue;
247                 }
248                 if ($gradedata['conditiongrademin'] !== '' && $gradedata['conditiongrademax'] !== '' &&
249                         unformat_float($gradedata['conditiongrademax']) <= unformat_float($gradedata['conditiongrademin'])) {
250                     $errors["conditiongradegroup[{$i}]"] = get_string('badgradelimits', 'condition');
251                     continue;
252                 }
253                 if ($gradedata['conditiongrademin'] === '' && $gradedata['conditiongrademax'] === '' &&
254                         $gradedata['conditiongradeitemid']) {
255                     $errors["conditiongradegroup[{$i}]"] = get_string('gradeitembutnolimits', 'condition');
256                     continue;
257                 }
258                 if (($gradedata['conditiongrademin'] !== '' || $gradedata['conditiongrademax'] !== '') &&
259                         !$gradedata['conditiongradeitemid']) {
260                     $errors["conditiongradegroup[{$i}]"] = get_string('gradelimitsbutnoitem', 'condition');
261                     continue;
262                 }
263             }
264         }
266         // Conditions: Verify that the user profile field has not been declared more than once
267         if (array_key_exists('conditionfieldgroup', $data)) {
268             // Array to store the existing fields
269             $arrcurrentfields = array();
270             // Error message displayed if any condition is declared more than once. We use lang string because
271             // this way we don't actually generate the string unless there is an error.
272             $stralreadydeclaredwarning = new lang_string('fielddeclaredmultipletimes', 'condition');
273             foreach ($data['conditionfieldgroup'] as $i => $fielddata) {
274                 if ($fielddata['conditionfield'] == 0) { // Don't need to bother if none is selected
275                     continue;
276                 }
277                 if (in_array($fielddata['conditionfield'], $arrcurrentfields)) {
278                     $errors["conditionfieldgroup[{$i}]"] = $stralreadydeclaredwarning->out();
279                 }
280                 // Add the field to the array
281                 $arrcurrentfields[] = $fielddata['conditionfield'];
282             }
283         }
285         return $errors;
286     }
288     /**
289      * Load in existing data as form defaults
290      *
291      * @param stdClass|array $default_values object or array of default values
292      */
293     function set_data($default_values) {
294         if (!is_object($default_values)) {
295             // we need object for file_prepare_standard_editor
296             $default_values = (object)$default_values;
297         }
298         $editoroptions = $this->_customdata['editoroptions'];
299         $default_values = file_prepare_standard_editor($default_values, 'summary', $editoroptions,
300                 $editoroptions['context'], 'course', 'section', $default_values->id);
301         $default_values->usedefaultname = (is_null($default_values->name));
302         parent::set_data($default_values);
303     }
305     /**
306      * Return submitted data if properly submitted or returns NULL if validation fails or
307      * if there is no submitted data.
308      *
309      * @return object submitted data; NULL if not valid or not submitted or cancelled
310      */
311     function get_data() {
312         $data = parent::get_data();
313         if ($data !== null) {
314             $editoroptions = $this->_customdata['editoroptions'];
315             if (!empty($data->usedefaultname)) {
316                 $data->name = null;
317             }
318             $data = file_postupdate_standard_editor($data, 'summary', $editoroptions,
319                     $editoroptions['context'], 'course', 'section', $data->id);
320             $course = $this->_customdata['course'];
321             foreach (course_get_format($course)->section_format_options() as $option => $unused) {
322                 // fix issue with unset checkboxes not being returned at all
323                 if (!isset($data->$option)) {
324                     $data->$option = null;
325                 }
326             }
327         }
328         return $data;
329     }