Skip to content

Commit

Permalink
MDL-35768 Added format-specific options to edit course and section forms
Browse files Browse the repository at this point in the history
- Course format may define additional fields (format options) to store for course and each section
- Edit course form allows to edit format-specific options and refreshes their list on format change
- Course format may provide it's own form for editing a section
- Default form for editing section allows to edit all format-specific fields
- Class section_info refactored, it defines magic methods such as __get() to access basic section
  information and format-specific options (retrieved only on the first request)
- format_base::update_course_format_options() allows to watch pre-update state of the course,
  format_legacy automatically copies the options with the same names between formats
  • Loading branch information
marinaglancy committed Nov 2, 2012
1 parent 29ac9fc commit fc79ede
Show file tree
Hide file tree
Showing 11 changed files with 635 additions and 97 deletions.
2 changes: 1 addition & 1 deletion course/edit.php
Expand Up @@ -41,7 +41,7 @@
print_error('cannoteditsiteform');
}

$course = $DB->get_record('course', array('id'=>$id), '*', MUST_EXIST);
$course = course_get_format($id)->get_course();
require_login($course);
$category = $DB->get_record('course_categories', array('id'=>$course->category), '*', MUST_EXIST);
$coursecontext = context_course::instance($course->id);
Expand Down
33 changes: 31 additions & 2 deletions course/edit_form.php
Expand Up @@ -10,9 +10,11 @@ class course_edit_form extends moodleform {
protected $context;

function definition() {
global $USER, $CFG, $DB;
global $USER, $CFG, $DB, $PAGE;

$mform = $this->_form;
$PAGE->requires->yui_module('moodle-course-formatchooser', 'M.course.init_formatchooser',
array(array('formid' => $mform->getAttribute('id'))));

$course = $this->_customdata['course']; // this contains the data of this form
$category = $this->_customdata['category'];
Expand Down Expand Up @@ -120,6 +122,10 @@ function definition() {
$mform->addHelpButton('format', 'format');
$mform->setDefault('format', $courseconfig->format);

// button to update format-specific options on format change (will be hidden by JavaScript)
$mform->registerNoSubmitButton('updatecourseformat');
$mform->addElement('submit', 'updatecourseformat', get_string('courseformatudpate'));

$mform->addElement('select', 'coursedisplay', get_string('coursedisplay'),
array(COURSE_DISPLAY_SINGLEPAGE => get_string('coursedisplay_single'),
COURSE_DISPLAY_MULTIPAGE => get_string('coursedisplay_multi')));
Expand Down Expand Up @@ -193,6 +199,9 @@ function definition() {
$mform->addElement('select', 'theme', get_string('forcetheme'), $themes);
}

//--------------------------------------------------------------------------------
$mform->addElement('hidden', 'addcourseformatoptionshere');

//--------------------------------------------------------------------------------
enrol_course_edit_form($mform, $course, $context);

Expand Down Expand Up @@ -310,8 +319,22 @@ function definition_after_data() {
$gr_el =& $mform->getElement('defaultgroupingid');
$gr_el->load($options);
}
}

// add course format options
$formatvalue = $mform->getElementValue('format');
if (is_array($formatvalue) && !empty($formatvalue)) {
$courseformat = course_get_format((object)array('format' => $formatvalue[0]));
$newel = $mform->createElement('header', '', get_string('courseformatoptions', 'moodle',
$courseformat->get_format_name()));
$mform->insertElementBefore($newel, 'addcourseformatoptionshere');

$elements = $courseformat->create_edit_form_elements($mform);
for ($i = 0; $i < count($elements); $i++) {
$mform->insertElementBefore($mform->removeElement($elements[$i]->getName(), false),
'addcourseformatoptionshere');
}
}
}

/// perform some extra moodle validation
function validation($data, $files) {
Expand All @@ -333,6 +356,12 @@ function validation($data, $files) {

$errors = array_merge($errors, enrol_course_edit_validation($data, $this->context));

$courseformat = course_get_format((object)array('format' => $data['format']));
$formaterrors = $courseformat->edit_form_validation($data, $files, $errors);
if (!empty($formaterrors) && is_array($formaterrors)) {
$errors = array_merge($errors, $formaterrors);
}

return $errors;
}
}
Expand Down
76 changes: 28 additions & 48 deletions course/editsection.php
Expand Up @@ -16,7 +16,7 @@
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.

/**
* Edit the introduction of a section
* Edit the section basic information and availability
*
* @copyright 1999 Martin Dougiamas http://dougiamas.com
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
Expand All @@ -25,78 +25,58 @@

require_once("../config.php");
require_once("lib.php");
require_once($CFG->libdir.'/filelib.php');
require_once($CFG->libdir . '/gradelib.php');
require_once($CFG->libdir . '/completionlib.php');
require_once($CFG->libdir . '/conditionlib.php');

require_once('editsection_form.php');

$id = required_param('id',PARAM_INT); // Week/topic ID
$id = required_param('id', PARAM_INT); // course_sections.id
$sectionreturn = optional_param('sr', 0, PARAM_INT);

$PAGE->set_url('/course/editsection.php', array('id'=>$id, 'sr'=> $sectionreturn));

$section = $DB->get_record('course_sections', array('id' => $id), '*', MUST_EXIST);
$course = $DB->get_record('course', array('id' => $section->course), '*', MUST_EXIST);
$sectionnum = $section->section;

require_login($course);
$context = context_course::instance($course->id);
require_capability('moodle/course:update', $context);

$editoroptions = array('context'=>$context ,'maxfiles' => EDITOR_UNLIMITED_FILES, 'maxbytes'=>$CFG->maxbytes, 'trusttext'=>false, 'noclean'=>true);
$section = file_prepare_standard_editor($section, 'summary', $editoroptions, $context, 'course', 'section', $section->id);
$section->usedefaultname = (is_null($section->name));

if (!empty($CFG->enableavailability)) {
// Get section availability conditions from sectioncache.
$modinfo = get_fast_modinfo($course);
$sectioninfo = $modinfo->get_section_info($section->section);
$section->conditionsgrade = $sectioninfo->conditionsgrade;
$section->conditionscompletion = $sectioninfo->conditionscompletion;
$section->conditionsfield = $sectioninfo->conditionsfield;
}

$mform = new editsection_form($PAGE->url, array('course' => $course, 'editoroptions' => $editoroptions,
'cs' => $section, 'showavailability' => $section->showavailability));
$mform->set_data($section); // set current value
// get section_info object with all availability options
$sectioninfo = get_fast_modinfo($course)->get_section_info($sectionnum);

$returnurl = course_get_url($course, $sectionreturn);
$editoroptions = array('context'=>$context ,'maxfiles' => EDITOR_UNLIMITED_FILES, 'maxbytes'=>$CFG->maxbytes, 'trusttext'=>false, 'noclean'=>true);
$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));

/// If data submitted, then process and store.
if ($mform->is_cancelled()){
redirect($returnurl);

// form cancelled, return to course
redirect(course_get_url($course, $section, array('sr' => $sectionreturn)));
} else if ($data = $mform->get_data()) {
if (empty($data->usedefaultname)) {
$section->name = $data->name;
} else {
$section->name = null;
}
$data = file_postupdate_standard_editor($data, 'summary', $editoroptions, $context, 'course', 'section', $section->id);
$section->summary = $data->summary;
$section->summaryformat = $data->summaryformat;
if (!empty($CFG->enableavailability)) {
$section->availablefrom = $data->availablefrom;
$section->availableuntil = $data->availableuntil;
if (isset($data->groupingid)) {
$section->groupingid = $data->groupingid;
}
$section->showavailability = $data->showavailability;
// data submitted and validated, update and return to course
$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;
}
$DB->update_record('course_sections', $section);
if (!empty($CFG->enableavailability)) {
// Update grade and completion conditions
condition_info_section::update_section_from_form($section, $data);
$sectioninfo = get_fast_modinfo($course)->get_section_info($sectionnum);
condition_info_section::update_section_from_form($sectioninfo, $data);
rebuild_course_cache($course->id, true);
}
rebuild_course_cache($course->id);
course_get_format($course->id)->update_section_format_options($data);

add_to_log($course->id, "course", "editsection", "editsection.php?id=$section->id", "$section->section");
add_to_log($course->id, "course", "editsection", "editsection.php?id=$id", "$sectionnum");
$PAGE->navigation->clear_cache();
redirect($returnurl);
redirect(course_get_url($course, $section, array('sr' => $sectionreturn)));
}

$sectionname = get_section_name($course, $section);
// the edit form is displayed for the first time or there was a validation
// error on the previous step. Display the edit form:
$sectionname = get_section_name($course, $sectionnum);
$stredit = get_string('edita', '', " $sectionname");
$strsummaryof = get_string('summaryof', '', " $sectionname");

Expand Down
62 changes: 59 additions & 3 deletions course/editsection_form.php
Expand Up @@ -5,7 +5,15 @@
}

require_once($CFG->libdir.'/formslib.php');

require_once($CFG->libdir.'/filelib.php');
require_once($CFG->libdir.'/completionlib.php');
require_once($CFG->libdir.'/gradelib.php');

/**
* Default form for editing course section
*
* Course format plugins may specify different editing form to use
*/
class editsection_form extends moodleform {

function definition() {
Expand All @@ -28,6 +36,13 @@ function definition() {
$mform->addElement('hidden', 'id');
$mform->setType('id', PARAM_INT);

// additional fields that course format has defined
$courseformat = course_get_format($course);
$formatoptions = $courseformat->section_format_options(true);
if (!empty($formatoptions)) {
$elements = $courseformat->create_edit_form_elements($mform, true);
}

$mform->_registerCancelButton('cancel');
}

Expand Down Expand Up @@ -195,8 +210,6 @@ public function definition_after_data() {
CONDITION_STUDENTVIEW_HIDE => get_string('showavailabilitysection_hide', 'condition'));
$mform->addElement('select', 'showavailability',
get_string('showavailabilitysection', 'condition'), $showhide);

$mform->setDefault('showavailability', $this->_customdata['showavailability']);
}

$this->add_action_buttons();
Expand Down Expand Up @@ -232,4 +245,47 @@ public function validation($data, $files) {

return $errors;
}

/**
* Load in existing data as form defaults
*
* @param stdClass|array $default_values object or array of default values
*/
function set_data($default_values) {
if (!is_object($default_values)) {
// we need object for file_prepare_standard_editor
$default_values = (object)$default_values;
}
$editoroptions = $this->_customdata['editoroptions'];
$default_values = file_prepare_standard_editor($default_values, 'summary', $editoroptions,
$editoroptions['context'], 'course', 'section', $default_values->id);
$default_values->usedefaultname = (is_null($default_values->name));
parent::set_data($default_values);
}

/**
* Return submitted data if properly submitted or returns NULL if validation fails or
* if there is no submitted data.
*
* @return object submitted data; NULL if not valid or not submitted or cancelled
*/
function get_data() {
$data = parent::get_data();
if ($data !== null) {
$editoroptions = $this->_customdata['editoroptions'];
if (!empty($data->usedefaultname)) {
$data->name = null;
}
$data = file_postupdate_standard_editor($data, 'summary', $editoroptions,
$editoroptions['context'], 'course', 'section', $data->id);
$course = $this->_customdata['course'];
foreach (course_get_format($course)->section_format_options() as $option => $unused) {
// fix issue with unset checkboxes not being returned at all
if (!isset($data->$option)) {
$data->$option = null;
}
}
}
return $data;
}
}
25 changes: 25 additions & 0 deletions course/format/formatlegacy.php
Expand Up @@ -202,4 +202,29 @@ public function get_default_blocks() {
}
return parent::get_default_blocks();
}

/**
* Updates format options for a course
*
* Legacy course formats may assume that course format options
* ('coursedisplay', 'numsections' and 'hiddensections') are shared between formats.
* Therefore we make sure to copy them from the previous format
*
* @param stdClass|array $data return value from {@link moodleform::get_data()} or array with data
* @param stdClass $oldcourse if this function is called from {@link update_course()}
* this object contains information about the course before update
* @return bool whether there were any changes to the options values
*/
public function update_course_format_options($data, $oldcourse = null) {
if ($oldcourse !== null) {
$data = (array)$data;
$oldcourse = (array)$oldcourse;
foreach ($this->course_format_options() as $key => $unused) {
if (array_key_exists($key, $oldcourse) && !array_key_exists($key, $data)) {
$data[$key] = $oldcourse[$key];
}
}
}
return $this->update_format_options($data);
}
}

0 comments on commit fc79ede

Please sign in to comment.