MDL-44070 Conditional availability enhancements (7): forms
authorsam marshall <s.marshall@open.ac.uk>
Wed, 26 Mar 2014 11:49:44 +0000 (11:49 +0000)
committersam marshall <s.marshall@open.ac.uk>
Mon, 7 Apr 2014 19:11:52 +0000 (20:11 +0100)
Changes to the module and section editing forms to use the new
fields and JavaScript.

course/editsection.php
course/editsection_form.php
course/modedit.php
course/modlib.php
course/moodleform_mod.php

index 54db939..f3765a4 100644 (file)
@@ -49,25 +49,33 @@ $mform = course_get_format($course->id)->editsection_form($PAGE->url,
         array('cs' => $sectioninfo, 'editoroptions' => $editoroptions));
 // set current value, make an editable copy of section_info object
 // this will retrieve all format-specific options as well
-$mform->set_data(convert_to_array($sectioninfo));
+$initialdata = convert_to_array($sectioninfo);
+if (!empty($CFG->enableavailability)) {
+    $initialdata['availabilityconditionsjson'] = $sectioninfo->availability;
+}
+$mform->set_data($initialdata);
 
 if ($mform->is_cancelled()){
     // Form cancelled, return to course.
     redirect(course_get_url($course, $section, array('sr' => $sectionreturn)));
 } else if ($data = $mform->get_data()) {
     // Data submitted and validated, update and return to course.
+
+    // For consistency, we set the availability field to 'null' if it is empty.
+    if (!empty($CFG->enableavailability)) {
+        // Renamed field.
+        $data->availability = $data->availabilityconditionsjson;
+        unset($data->availabilityconditionsjson);
+        if ($data->availability === '') {
+            $data->availability = null;
+        }
+    }
     $DB->update_record('course_sections', $data);
     rebuild_course_cache($course->id, true);
     if (isset($data->section)) {
         // Usually edit form does not change relative section number but just in case.
         $sectionnum = $data->section;
     }
-    if (!empty($CFG->enableavailability)) {
-        // Update grade and completion conditions.
-        $sectioninfo = get_fast_modinfo($course)->get_section_info($sectionnum);
-        condition_info_section::update_section_from_form($sectioninfo, $data);
-        rebuild_course_cache($course->id, true);
-    }
     course_get_format($course->id)->update_section_format_options($data);
 
     // Set section info, as this might not be present in form_data.
index 7161284..c614470 100644 (file)
@@ -60,241 +60,22 @@ class editsection_form extends moodleform {
         $context = context_course::instance($course->id);
 
         if (!empty($CFG->enableavailability)) {
-            $mform->addElement('header', 'availabilityconditions', get_string('availabilityconditions', 'condition'));
+            $mform->addElement('header', 'availabilityconditions',
+                    get_string('restrictaccess', 'availability'));
             $mform->setExpanded('availabilityconditions', false);
-            // String used by conditions more than once
-            $strcondnone = get_string('none', 'condition');
-            // Grouping conditions - only if grouping is enabled at site level
-            if (!empty($CFG->enablegroupmembersonly)) {
-                $options = array();
-                if ($groupings = $DB->get_records('groupings', array('courseid' => $course->id))) {
-                    foreach ($groupings as $grouping) {
-                        $options[$grouping->id] = format_string(
-                                $grouping->name, true, array('context' => $context));
-                    }
-                }
-                core_collator::asort($options);
-                $options = array(0 => get_string('none')) + $options;
-                $mform->addElement('select', 'groupingid', get_string('groupingsection', 'group'), $options);
-                $mform->addHelpButton('groupingid', 'groupingsection', 'group');
-            }
-
-            // Available from/to defaults to midnight because then the display
-            // will be nicer where it tells users when they can access it (it
-            // shows only the date and not time).
-            $date = usergetdate(time());
-            $midnight = make_timestamp($date['year'], $date['mon'], $date['mday']);
-
-            // Date and time conditions.
-            $mform->addElement('date_time_selector', 'availablefrom',
-                    get_string('availablefrom', 'condition'),
-                    array('optional' => true, 'defaulttime' => $midnight));
-            $mform->addElement('date_time_selector', 'availableuntil',
-                    get_string('availableuntil', 'condition'),
-                    array('optional' => true, 'defaulttime' => $midnight));
-
-            // Conditions based on grades
-            $gradeoptions = array();
-            $items = grade_item::fetch_all(array('courseid' => $course->id));
-            $items = $items ? $items : array();
-            foreach ($items as $id => $item) {
-                $gradeoptions[$id] = $item->get_name();
-            }
-            asort($gradeoptions);
-            $gradeoptions = array(0 => $strcondnone) + $gradeoptions;
-
-            $grouparray = array();
-            $grouparray[] = $mform->createElement('select', 'conditiongradeitemid', '', $gradeoptions);
-            $grouparray[] = $mform->createElement('static', '', '',
-                    ' ' . get_string('grade_atleast', 'condition').' ');
-            $grouparray[] = $mform->createElement('text', 'conditiongrademin', '', array('size' => 3));
-            $grouparray[] = $mform->createElement('static', '', '',
-                    '% ' . get_string('grade_upto', 'condition') . ' ');
-            $grouparray[] = $mform->createElement('text', 'conditiongrademax', '', array('size' => 3));
-            $grouparray[] = $mform->createElement('static', '', '', '%');
-            $group = $mform->createElement('group', 'conditiongradegroup',
-                    get_string('gradecondition', 'condition'), $grouparray);
 
-            // Get full version (including condition info) of section object
-            $ci = new condition_info_section($this->_customdata['cs']);
-            $fullcs = $ci->get_full_section();
-            $count = count($fullcs->conditionsgrade) + 1;
-
-            // Grade conditions
-            $this->repeat_elements(array($group), $count, array(
-                'conditiongradegroup[conditiongrademin]' => array('type' => PARAM_RAW),
-                'conditiongradegroup[conditiongrademax]' => array('type' => PARAM_RAW)
-                ), 'conditiongraderepeats', 'conditiongradeadds', 2, get_string('addgrades', 'condition'), true);
-            $mform->addHelpButton('conditiongradegroup[0]', 'gradecondition', 'condition');
-
-            // Conditions based on user fields
-            $operators = condition_info::get_condition_user_field_operators();
-            $useroptions = condition_info::get_condition_user_fields(array('context' => $context));
-            asort($useroptions);
-
-            $useroptions = array(0 => $strcondnone) + $useroptions;
-            $grouparray = array();
-            $grouparray[] =& $mform->createElement('select', 'conditionfield', '', $useroptions);
-            $grouparray[] =& $mform->createElement('select', 'conditionfieldoperator', '', $operators);
-            $grouparray[] =& $mform->createElement('text', 'conditionfieldvalue');
-            $group = $mform->createElement('group', 'conditionfieldgroup', get_string('userfield', 'condition'), $grouparray);
-
-            $fieldcount = count($fullcs->conditionsfield) + 1;
-
-            $this->repeat_elements(array($group), $fieldcount,  array(
-                'conditionfieldgroup[conditionfieldvalue]' => array('type' => PARAM_RAW)),
-                'conditionfieldrepeats', 'conditionfieldadds', 2, get_string('adduserfields', 'condition'), true);
-            $mform->addHelpButton('conditionfieldgroup[0]', 'userfield', 'condition');
-
-            // Conditions based on completion
-            $completion = new completion_info($course);
-            if ($completion->is_enabled()) {
-                $completionoptions = array();
-                $modinfo = get_fast_modinfo($course);
-                foreach ($modinfo->cms as $id => $cm) {
-                    // Add each course-module if it:
-                    // (a) has completion turned on
-                    // (b) does not belong to current course-section
-                    if ($cm->completion && ($fullcs->id != $cm->section)) {
-                        $completionoptions[$id] = $cm->name;
-                    }
-                }
-                asort($completionoptions);
-                $completionoptions = array(0 => $strcondnone) +
-                        $completionoptions;
-
-                $completionvalues = array(
-                    COMPLETION_COMPLETE => get_string('completion_complete', 'condition'),
-                    COMPLETION_INCOMPLETE => get_string('completion_incomplete', 'condition'),
-                    COMPLETION_COMPLETE_PASS => get_string('completion_pass', 'condition'),
-                    COMPLETION_COMPLETE_FAIL => get_string('completion_fail', 'condition'));
-
-                $grouparray = array();
-                $grouparray[] = $mform->createElement('select', 'conditionsourcecmid', '',
-                        $completionoptions);
-                $grouparray[] = $mform->createElement('select', 'conditionrequiredcompletion', '',
-                        $completionvalues);
-                $group = $mform->createElement('group', 'conditioncompletiongroup',
-                        get_string('completioncondition', 'condition'), $grouparray);
-
-                $count = count($fullcs->conditionscompletion) + 1;
-                $this->repeat_elements(array($group), $count, array(),
-                        'conditioncompletionrepeats', 'conditioncompletionadds', 2,
-                        get_string('addcompletions', 'condition'), true);
-                $mform->addHelpButton('conditioncompletiongroup[0]',
-                        'completionconditionsection', 'condition');
-            }
-
-            // Availability conditions - set up form values
-            if (!empty($CFG->enableavailability)) {
-                $num = 0;
-                foreach ($fullcs->conditionsgrade as $gradeitemid => $minmax) {
-                    $groupelements = $mform->getElement(
-                            'conditiongradegroup[' . $num . ']')->getElements();
-                    $groupelements[0]->setValue($gradeitemid);
-                    $groupelements[2]->setValue(is_null($minmax->min) ? '' :
-                            format_float($minmax->min, 5, true, true));
-                    $groupelements[4]->setValue(is_null($minmax->max) ? '' :
-                            format_float($minmax->max, 5, true, true));
-                    $num++;
-                }
-
-                $num = 0;
-                foreach ($fullcs->conditionsfield as $fieldid => $data) {
-                    $groupelements = $mform->getElement(
-                            'conditionfieldgroup[' . $num . ']')->getElements();
-                    $groupelements[0]->setValue($fieldid);
-                    $groupelements[1]->setValue(is_null($data->operator) ? '' :
-                            $data->operator);
-                    $groupelements[2]->setValue(is_null($data->value) ? '' :
-                            $data->value);
-                    $num++;
-                }
-
-                if ($completion->is_enabled()) {
-                    $num = 0;
-                    foreach ($fullcs->conditionscompletion as $othercmid => $state) {
-                        $groupelements = $mform->getElement('conditioncompletiongroup[' . $num . ']')->getElements();
-                        $groupelements[0]->setValue($othercmid);
-                        $groupelements[1]->setValue($state);
-                        $num++;
-                    }
-                }
-            }
-
-            // Do we display availability info to students?
-            $showhide = array(
-                CONDITION_STUDENTVIEW_SHOW => get_string('showavailabilitysection_show', 'condition'),
-                CONDITION_STUDENTVIEW_HIDE => get_string('showavailabilitysection_hide', 'condition'));
-            $mform->addElement('select', 'showavailability',
-                    get_string('showavailabilitysection', 'condition'), $showhide);
+            // Availability field. This is just a textarea; the user interface
+            // interaction is all implemented in JavaScript. The field is named
+            // availabilityconditionsjson for consistency with moodleform_mod.
+            $mform->addElement('textarea', 'availabilityconditionsjson',
+                    get_string('accessrestrictions', 'availability'));
+            \core_availability\frontend::include_all_javascript($course, null,
+                    $this->_customdata['cs']);
         }
 
         $this->add_action_buttons();
     }
 
-    public function validation($data, $files) {
-        $errors = parent::validation($data, $files);
-        // Conditions: Don't let them set dates which make no sense
-        if (array_key_exists('availablefrom', $data) &&
-                $data['availablefrom'] && $data['availableuntil'] &&
-                $data['availablefrom'] >= $data['availableuntil']) {
-            $errors['availablefrom'] = get_string('badavailabledates', 'condition');
-        }
-
-        // Conditions: Verify that the grade conditions are numbers, and make sense.
-        if (array_key_exists('conditiongradegroup', $data)) {
-            foreach ($data['conditiongradegroup'] as $i => $gradedata) {
-                if ($gradedata['conditiongrademin'] !== '' &&
-                        !is_numeric(unformat_float($gradedata['conditiongrademin']))) {
-                    $errors["conditiongradegroup[{$i}]"] = get_string('gradesmustbenumeric', 'condition');
-                    continue;
-                }
-                if ($gradedata['conditiongrademax'] !== '' &&
-                        !is_numeric(unformat_float($gradedata['conditiongrademax']))) {
-                    $errors["conditiongradegroup[{$i}]"] = get_string('gradesmustbenumeric', 'condition');
-                    continue;
-                }
-                if ($gradedata['conditiongrademin'] !== '' && $gradedata['conditiongrademax'] !== '' &&
-                        unformat_float($gradedata['conditiongrademax']) <= unformat_float($gradedata['conditiongrademin'])) {
-                    $errors["conditiongradegroup[{$i}]"] = get_string('badgradelimits', 'condition');
-                    continue;
-                }
-                if ($gradedata['conditiongrademin'] === '' && $gradedata['conditiongrademax'] === '' &&
-                        $gradedata['conditiongradeitemid']) {
-                    $errors["conditiongradegroup[{$i}]"] = get_string('gradeitembutnolimits', 'condition');
-                    continue;
-                }
-                if (($gradedata['conditiongrademin'] !== '' || $gradedata['conditiongrademax'] !== '') &&
-                        !$gradedata['conditiongradeitemid']) {
-                    $errors["conditiongradegroup[{$i}]"] = get_string('gradelimitsbutnoitem', 'condition');
-                    continue;
-                }
-            }
-        }
-
-        // Conditions: Verify that the user profile field has not been declared more than once
-        if (array_key_exists('conditionfieldgroup', $data)) {
-            // Array to store the existing fields
-            $arrcurrentfields = array();
-            // Error message displayed if any condition is declared more than once. We use lang string because
-            // this way we don't actually generate the string unless there is an error.
-            $stralreadydeclaredwarning = new lang_string('fielddeclaredmultipletimes', 'condition');
-            foreach ($data['conditionfieldgroup'] as $i => $fielddata) {
-                if ($fielddata['conditionfield'] == 0) { // Don't need to bother if none is selected
-                    continue;
-                }
-                if (in_array($fielddata['conditionfield'], $arrcurrentfields)) {
-                    $errors["conditionfieldgroup[{$i}]"] = $stralreadydeclaredwarning->out();
-                }
-                // Add the field to the array
-                $arrcurrentfields[] = $fielddata['conditionfield'];
-            }
-        }
-
-        return $errors;
-    }
-
     /**
      * Load in existing data as form defaults
      *
@@ -337,4 +118,16 @@ class editsection_form extends moodleform {
         }
         return $data;
     }
+
+    public function validation($data, $files) {
+        global $CFG;
+        $errors = array();
+
+        // Availability: Check availability field does not have errors.
+        if (!empty($CFG->enableavailability)) {
+            \core_availability\frontend::report_validation_errors($data, $errors);
+        }
+
+        return $errors;
+    }
 }
index 83b33ce..a769cca 100644 (file)
@@ -160,9 +160,7 @@ if (!empty($add)) {
     $data->completionusegrade = is_null($cm->completiongradeitemnumber) ? 0 : 1;
     $data->showdescription    = $cm->showdescription;
     if (!empty($CFG->enableavailability)) {
-        $data->availablefrom      = $cm->availablefrom;
-        $data->availableuntil     = $cm->availableuntil;
-        $data->showavailability   = $cm->showavailability;
+        $data->availabilityconditionsjson = $cm->availability;
     }
 
     if (plugin_supports('mod', $data->modulename, FEATURE_MOD_INTRO, true)) {
index e950cd4..ced162c 100644 (file)
@@ -75,9 +75,17 @@ function add_moduleinfo($moduleinfo, $course, $mform = null) {
         $newcm->completionexpected        = $moduleinfo->completionexpected;
     }
     if(!empty($CFG->enableavailability)) {
-        $newcm->availablefrom             = $moduleinfo->availablefrom;
-        $newcm->availableuntil            = $moduleinfo->availableuntil;
-        $newcm->showavailability          = $moduleinfo->showavailability;
+        // This code is used both when submitting the form, which uses a long
+        // name to avoid clashes, and by unit test code which uses the real
+        // name in the table.
+        $newcm->availability = null;
+        if (property_exists($moduleinfo, 'availabilityconditionsjson')) {
+            if ($moduleinfo->availabilityconditionsjson !== '') {
+                $newcm->availability = $moduleinfo->availabilityconditionsjson;
+            }
+        } else if (property_exists($moduleinfo, 'availability')) {
+            $newcm->availability = $moduleinfo->availability;
+        }
     }
     if (isset($moduleinfo->showdescription)) {
         $newcm->showdescription = $moduleinfo->showdescription;
@@ -139,11 +147,6 @@ function add_moduleinfo($moduleinfo, $course, $mform = null) {
     // So we have to update one of them twice.
     $sectionid = course_add_cm_to_section($course, $moduleinfo->coursemodule, $moduleinfo->section);
 
-    // Set up conditions.
-    if ($CFG->enableavailability) {
-        condition_info::update_cm_from_form((object)array('id'=>$moduleinfo->coursemodule), $moduleinfo, false);
-    }
-
     // Trigger event based on the action we did.
     $event = \core\event\course_module_created::create(array(
          'courseid' => $course->id,
@@ -473,10 +476,18 @@ function update_moduleinfo($cm, $moduleinfo, $course, $mform = null) {
         $cm->completionexpected        = $moduleinfo->completionexpected;
     }
     if (!empty($CFG->enableavailability)) {
-        $cm->availablefrom             = $moduleinfo->availablefrom;
-        $cm->availableuntil            = $moduleinfo->availableuntil;
-        $cm->showavailability          = $moduleinfo->showavailability;
-        condition_info::update_cm_from_form($cm,$moduleinfo,true);
+        // This code is used both when submitting the form, which uses a long
+        // name to avoid clashes, and by unit test code which uses the real
+        // name in the table.
+        if (property_exists($moduleinfo, 'availabilityconditionsjson')) {
+            if ($moduleinfo->availabilityconditionsjson !== '') {
+                $cm->availability = $moduleinfo->availabilityconditionsjson;
+            } else {
+                $cm->availability = null;
+            }
+        } else if (property_exists($moduleinfo, 'availability')) {
+            $cm->availability = $moduleinfo->availability;
+        }
     }
     if (isset($moduleinfo->showdescription)) {
         $cm->showdescription = $moduleinfo->showdescription;
index 9b54833..d505f38 100644 (file)
@@ -258,49 +258,13 @@ abstract class moodleform_mod extends moodleform {
             }
         }
 
-        // Availability conditions
-        if (!empty($CFG->enableavailability) && $this->_cm) {
-            $ci = new condition_info($this->_cm);
-            $fullcm=$ci->get_full_course_module();
-
-            $num=0;
-            foreach($fullcm->conditionsgrade as $gradeitemid=>$minmax) {
-                $groupelements=$mform->getElement('conditiongradegroup['.$num.']')->getElements();
-                $groupelements[0]->setValue($gradeitemid);
-                $groupelements[2]->setValue(is_null($minmax->min) ? '' :
-                        format_float($minmax->min, 5, true, true));
-                $groupelements[4]->setValue(is_null($minmax->max) ? '' :
-                        format_float($minmax->max, 5, true, true));
-                $num++;
-            }
-
-            $num = 0;
-            foreach($fullcm->conditionsfield as $field => $details) {
-                $groupelements = $mform->getElement('conditionfieldgroup['.$num.']')->getElements();
-                $groupelements[0]->setValue($field);
-                $groupelements[1]->setValue(is_null($details->operator) ? '' : $details->operator);
-                $groupelements[2]->setValue(is_null($details->value) ? '' : $details->value);
-                $num++;
-            }
-
-            if ($completion->is_enabled()) {
-                $num=0;
-                foreach($fullcm->conditionscompletion as $othercmid=>$state) {
-                    $groupelements=$mform->getElement('conditioncompletiongroup['.$num.']')->getElements();
-                    $groupelements[0]->setValue($othercmid);
-                    $groupelements[1]->setValue($state);
-                    $num++;
-                }
-            }
-        }
-
         // Freeze admin defaults if required (and not different from default)
         $this->apply_admin_locked_flags();
     }
 
     // form verification
     function validation($data, $files) {
-        global $COURSE, $DB;
+        global $COURSE, $DB, $CFG;
         $errors = parent::validation($data, $files);
 
         $mform =& $this->_form;
@@ -341,61 +305,9 @@ abstract class moodleform_mod extends moodleform {
             }
         }
 
-        // Conditions: Don't let them set dates which make no sense
-        if (array_key_exists('availablefrom', $data) &&
-            $data['availablefrom'] && $data['availableuntil'] &&
-            $data['availablefrom'] >= $data['availableuntil']) {
-            $errors['availablefrom'] = get_string('badavailabledates', 'condition');
-        }
-
-        // Conditions: Verify that the grade conditions are numbers, and make sense.
-        if (array_key_exists('conditiongradegroup', $data)) {
-            foreach ($data['conditiongradegroup'] as $i => $gradedata) {
-                if ($gradedata['conditiongrademin'] !== '' &&
-                        !is_numeric(unformat_float($gradedata['conditiongrademin']))) {
-                    $errors["conditiongradegroup[{$i}]"] = get_string('gradesmustbenumeric', 'condition');
-                    continue;
-                }
-                if ($gradedata['conditiongrademax'] !== '' &&
-                        !is_numeric(unformat_float($gradedata['conditiongrademax']))) {
-                    $errors["conditiongradegroup[{$i}]"] = get_string('gradesmustbenumeric', 'condition');
-                    continue;
-                }
-                if ($gradedata['conditiongrademin'] !== '' && $gradedata['conditiongrademax'] !== '' &&
-                        unformat_float($gradedata['conditiongrademax']) <= unformat_float($gradedata['conditiongrademin'])) {
-                    $errors["conditiongradegroup[{$i}]"] = get_string('badgradelimits', 'condition');
-                    continue;
-                }
-                if ($gradedata['conditiongrademin'] === '' && $gradedata['conditiongrademax'] === '' &&
-                        $gradedata['conditiongradeitemid']) {
-                    $errors["conditiongradegroup[{$i}]"] = get_string('gradeitembutnolimits', 'condition');
-                    continue;
-                }
-                if (($gradedata['conditiongrademin'] !== '' || $gradedata['conditiongrademax'] !== '') &&
-                        !$gradedata['conditiongradeitemid']) {
-                    $errors["conditiongradegroup[{$i}]"] = get_string('gradelimitsbutnoitem', 'condition');
-                    continue;
-                }
-            }
-        }
-
-        // Conditions: Verify that the user profile field has not been declared more than once
-        if (array_key_exists('conditionfieldgroup', $data)) {
-            // Array to store the existing fields
-            $arrcurrentfields = array();
-            // Error message displayed if any condition is declared more than once. We use lang string because
-            // this way we don't actually generate the string unless there is an error.
-            $stralreadydeclaredwarning = new lang_string('fielddeclaredmultipletimes', 'condition');
-            foreach ($data['conditionfieldgroup'] as $i => $fielddata) {
-                if ($fielddata['conditionfield'] == 0) { // Don't need to bother if none is selected
-                    continue;
-                }
-                if (in_array($fielddata['conditionfield'], $arrcurrentfields)) {
-                    $errors["conditionfieldgroup[{$i}]"] = $stralreadydeclaredwarning->out();
-                }
-                // Add the field to the array
-                $arrcurrentfields[] = $fielddata['conditionfield'];
-            }
+        // Availability: Check availability field does not have errors.
+        if (!empty($CFG->enableavailability)) {
+            \core_availability\frontend::report_validation_errors($data, $errors);
         }
 
         return $errors;
@@ -521,129 +433,23 @@ abstract class moodleform_mod extends moodleform {
         }
 
         if (!empty($CFG->enableavailability)) {
-            // String used by conditions
-            $strnone = get_string('none','condition');
-            // Conditional availability
-
-            // Available from/to defaults to midnight because then the display
-            // will be nicer where it tells users when they can access it (it
-            // shows only the date and not time).
-            $date = usergetdate(time());
-            $midnight = make_timestamp($date['year'], $date['mon'], $date['mday']);
-
-            // From/until controls
+            // Availability field. This is just a textarea; the user interface
+            // interaction is all implemented in JavaScript.
             $mform->addElement('header', 'availabilityconditionsheader',
-                    get_string('availabilityconditions', 'condition'));
-            $mform->addElement('date_time_selector', 'availablefrom',
-                    get_string('availablefrom', 'condition'),
-                    array('optional' => true, 'defaulttime' => $midnight));
-            $mform->addHelpButton('availablefrom', 'availablefrom', 'condition');
-            $mform->addElement('date_time_selector', 'availableuntil',
-                    get_string('availableuntil', 'condition'),
-                    array('optional' => true, 'defaulttime' => $midnight));
-
-            // Conditions based on grades
-            $gradeoptions = array();
-            $items = grade_item::fetch_all(array('courseid'=>$COURSE->id));
-            $items = $items ? $items : array();
-            foreach($items as $id=>$item) {
-                // Do not include grades for current item
-                if (!empty($this->_cm) && $this->_cm->instance == $item->iteminstance
-                    && $this->_cm->modname == $item->itemmodule
-                    && $item->itemtype == 'mod') {
-                    continue;
-                }
-                $gradeoptions[$id] = $item->get_name();
-            }
-            asort($gradeoptions);
-            $gradeoptions = array(0 => $strnone) + $gradeoptions;
-
-            $grouparray = array();
-            $grouparray[] =& $mform->createElement('select','conditiongradeitemid','',$gradeoptions);
-            $grouparray[] =& $mform->createElement('static', '', '',' '.get_string('grade_atleast','condition').' ');
-            $grouparray[] =& $mform->createElement('text', 'conditiongrademin','',array('size'=>3));
-            $grouparray[] =& $mform->createElement('static', '', '','% '.get_string('grade_upto','condition').' ');
-            $grouparray[] =& $mform->createElement('text', 'conditiongrademax','',array('size'=>3));
-            $grouparray[] =& $mform->createElement('static', '', '','%');
-            $group = $mform->createElement('group','conditiongradegroup',
-                get_string('gradecondition', 'condition'),$grouparray);
-
-            // Get version with condition info and store it so we don't ask
-            // twice
-            if(!empty($this->_cm)) {
-                $ci = new condition_info($this->_cm, CONDITION_MISSING_EXTRATABLE);
-                $this->_cm = $ci->get_full_course_module();
-                $count = count($this->_cm->conditionsgrade)+1;
-                $fieldcount = count($this->_cm->conditionsfield) + 1;
-            } else {
-                $count = 1;
-                $fieldcount = 1;
-            }
-
-            $this->repeat_elements(array($group), $count, array(
-                'conditiongradegroup[conditiongrademin]' => array('type' => PARAM_RAW),
-                'conditiongradegroup[conditiongrademax]' => array('type' => PARAM_RAW)
-                ), 'conditiongraderepeats', 'conditiongradeadds', 2, get_string('addgrades', 'condition'), true);
-            $mform->addHelpButton('conditiongradegroup[0]', 'gradecondition', 'condition');
-
-            // Conditions based on user fields
-            $operators = condition_info::get_condition_user_field_operators();
-            $useroptions = condition_info::get_condition_user_fields(
-                    array('context' => $this->context));
-            asort($useroptions);
-
-            $useroptions = array(0 => $strnone) + $useroptions;
-            $grouparray = array();
-            $grouparray[] =& $mform->createElement('select', 'conditionfield', '', $useroptions);
-            $grouparray[] =& $mform->createElement('select', 'conditionfieldoperator', '', $operators);
-            $grouparray[] =& $mform->createElement('text', 'conditionfieldvalue');
-            $group = $mform->createElement('group', 'conditionfieldgroup', get_string('userfield', 'condition'), $grouparray);
-
-            $this->repeat_elements(array($group), $fieldcount, array(
-                'conditionfieldgroup[conditionfieldvalue]' => array('type' => PARAM_RAW)),
-                'conditionfieldrepeats', 'conditionfieldadds', 2, get_string('adduserfields', 'condition'), true);
-            $mform->addHelpButton('conditionfieldgroup[0]', 'userfield', 'condition');
-
-            // Conditions based on completion
-            $completion = new completion_info($COURSE);
-            if ($completion->is_enabled()) {
-                $completionoptions = array();
+                    get_string('restrictaccess', 'availability'));
+            // Note: This field cannot be named 'availability' because that
+            // conflicts with fields in existing modules (such as assign).
+            // So it uses a long name that will not conflict.
+            $mform->addElement('textarea', 'availabilityconditionsjson',
+                    get_string('accessrestrictions', 'availability'));
+            // The _cm variable may not be a proper cm_info, so get one from modinfo.
+            if ($this->_cm) {
                 $modinfo = get_fast_modinfo($COURSE);
-                foreach($modinfo->cms as $id=>$cm) {
-                    // Add each course-module if it:
-                    // (a) has completion turned on
-                    // (b) is not the same as current course-module
-                    if ($cm->completion && (empty($this->_cm) || $this->_cm->id != $id)) {
-                        $completionoptions[$id]=$cm->name;
-                    }
-                }
-                asort($completionoptions);
-                $completionoptions = array(0 => $strnone) + $completionoptions;
-
-                $completionvalues=array(
-                    COMPLETION_COMPLETE=>get_string('completion_complete','condition'),
-                    COMPLETION_INCOMPLETE=>get_string('completion_incomplete','condition'),
-                    COMPLETION_COMPLETE_PASS=>get_string('completion_pass','condition'),
-                    COMPLETION_COMPLETE_FAIL=>get_string('completion_fail','condition'));
-
-                $grouparray = array();
-                $grouparray[] =& $mform->createElement('select','conditionsourcecmid','',$completionoptions);
-                $grouparray[] =& $mform->createElement('select','conditionrequiredcompletion','',$completionvalues);
-                $group = $mform->createElement('group','conditioncompletiongroup',
-                    get_string('completioncondition', 'condition'),$grouparray);
-
-                $count = empty($this->_cm) ? 1 : count($this->_cm->conditionscompletion)+1;
-                $this->repeat_elements(array($group),$count,array(),
-                    'conditioncompletionrepeats','conditioncompletionadds',2,
-                    get_string('addcompletions','condition'),true);
-                $mform->addHelpButton('conditioncompletiongroup[0]', 'completioncondition', 'condition');
+                $cm = $modinfo->get_cm($this->_cm->id);
+            } else {
+                $cm = null;
             }
-
-            // Do we display availability info to students?
-            $mform->addElement('select', 'showavailability', get_string('showavailability', 'condition'),
-                    array(CONDITION_STUDENTVIEW_SHOW=>get_string('showavailability_show', 'condition'),
-                    CONDITION_STUDENTVIEW_HIDE=>get_string('showavailability_hide', 'condition')));
-            $mform->setDefault('showavailability', CONDITION_STUDENTVIEW_SHOW);
+            \core_availability\frontend::include_all_javascript($COURSE, $cm);
         }
 
         // Conditional activities: completion tracking section