MDL-49642 mod_lesson: Group/user overrides
This commit is contained in:
@@ -233,6 +233,9 @@ class moodle1_mod_lesson_handler extends moodle1_mod_handler {
|
||||
* This is executed when we reach the closing </MOD> tag of our 'lesson' path
|
||||
*/
|
||||
public function on_lesson_end() {
|
||||
// Append empty <overrides> subpath element.
|
||||
$this->write_xml('overrides', array());
|
||||
|
||||
// finish writing lesson.xml
|
||||
$this->xmlwriter->end_tag('lesson');
|
||||
$this->xmlwriter->end_tag('activity');
|
||||
|
||||
@@ -145,6 +145,11 @@ class backup_lesson_activity_structure_step extends backup_activity_structure_st
|
||||
'userid', 'starttime', 'lessontime', 'completed'
|
||||
));
|
||||
|
||||
$overrides = new backup_nested_element('overrides');
|
||||
$override = new backup_nested_element('override', array('id'), array(
|
||||
'groupid', 'userid', 'available', 'deadline', 'timelimit',
|
||||
'review', 'maxattempts', 'retake', 'password'));
|
||||
|
||||
// Now that we have all of the elements created we've got to put them
|
||||
// together correctly.
|
||||
$lesson->add_child($pages);
|
||||
@@ -161,6 +166,8 @@ class backup_lesson_activity_structure_step extends backup_activity_structure_st
|
||||
$highscores->add_child($highscore);
|
||||
$lesson->add_child($timers);
|
||||
$timers->add_child($timer);
|
||||
$lesson->add_child($overrides);
|
||||
$overrides->add_child($override);
|
||||
|
||||
// Set the source table for the elements that aren't reliant on the user
|
||||
// at this point (lesson, lesson_pages, lesson_answers)
|
||||
@@ -171,6 +178,9 @@ class backup_lesson_activity_structure_step extends backup_activity_structure_st
|
||||
// We use SQL here as answers must be ordered by id so that the restore gets them in the right order
|
||||
$answer->set_source_table('lesson_answers', array('pageid' => backup::VAR_PARENTID), 'id ASC');
|
||||
|
||||
// Lesson overrides to backup are different depending of user info.
|
||||
$overrideparams = array('lessonid' => backup::VAR_PARENTID);
|
||||
|
||||
// Check if we are also backing up user information
|
||||
if ($this->get_setting_value('userinfo')) {
|
||||
// Set the source table for elements that are reliant on the user
|
||||
@@ -180,7 +190,9 @@ class backup_lesson_activity_structure_step extends backup_activity_structure_st
|
||||
$grade->set_source_table('lesson_grades', array('lessonid'=>backup::VAR_PARENTID));
|
||||
$highscore->set_source_table('lesson_high_scores', array('lessonid' => backup::VAR_PARENTID));
|
||||
$timer->set_source_table('lesson_timer', array('lessonid' => backup::VAR_PARENTID));
|
||||
$overrideparams['userid'] = backup_helper::is_sqlparam(null); // Without userinfo, skip user overrides.
|
||||
}
|
||||
$override->set_source_table('lesson_overrides', $overrideparams);
|
||||
|
||||
// Annotate the user id's where required.
|
||||
$attempt->annotate_ids('user', 'userid');
|
||||
@@ -188,6 +200,8 @@ class backup_lesson_activity_structure_step extends backup_activity_structure_st
|
||||
$grade->annotate_ids('user', 'userid');
|
||||
$highscore->annotate_ids('user', 'userid');
|
||||
$timer->annotate_ids('user', 'userid');
|
||||
$override->annotate_ids('user', 'userid');
|
||||
$override->annotate_ids('group', 'groupid');
|
||||
|
||||
// Annotate the file areas in user by the lesson module.
|
||||
$lesson->annotate_files('mod_lesson', 'intro', null);
|
||||
|
||||
@@ -48,6 +48,7 @@ class restore_lesson_activity_structure_step extends restore_activity_structure_
|
||||
$paths[] = new restore_path_element('lesson_branch', '/activity/lesson/pages/page/branches/branch');
|
||||
$paths[] = new restore_path_element('lesson_highscore', '/activity/lesson/highscores/highscore');
|
||||
$paths[] = new restore_path_element('lesson_timer', '/activity/lesson/timers/timer');
|
||||
$paths[] = new restore_path_element('lesson_override', '/activity/lesson/overrides/override');
|
||||
}
|
||||
|
||||
// Return the paths wrapped into standard activity structure
|
||||
@@ -204,6 +205,39 @@ class restore_lesson_activity_structure_step extends restore_activity_structure_
|
||||
$newitemid = $DB->insert_record('lesson_timer', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a lesson override restore
|
||||
* @param object $data The data in object form
|
||||
* @return void
|
||||
*/
|
||||
protected function process_lesson_override($data) {
|
||||
global $DB;
|
||||
|
||||
$data = (object)$data;
|
||||
$oldid = $data->id;
|
||||
|
||||
// Based on userinfo, we'll restore user overides or no.
|
||||
$userinfo = $this->get_setting_value('userinfo');
|
||||
|
||||
// Skip user overrides if we are not restoring userinfo.
|
||||
if (!$userinfo && !is_null($data->userid)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$data->lessonid = $this->get_new_parentid('lesson');
|
||||
|
||||
$data->userid = $this->get_mappingid('user', $data->userid);
|
||||
$data->groupid = $this->get_mappingid('group', $data->groupid);
|
||||
|
||||
$data->available = $this->apply_date_offset($data->available);
|
||||
$data->deadline = $this->apply_date_offset($data->deadline);
|
||||
|
||||
$newitemid = $DB->insert_record('lesson_overrides', $data);
|
||||
|
||||
// Add mapping, restore of logs needs it.
|
||||
$this->set_mapping('lesson_override', $oldid, $newitemid);
|
||||
}
|
||||
|
||||
protected function after_execute() {
|
||||
global $DB;
|
||||
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* The mod_lesson group override created event.
|
||||
*
|
||||
* @package mod_lesson
|
||||
* @copyright 2015 Jean-Michel Vedrine
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace mod_lesson\event;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* The mod_lesson group override created event class.
|
||||
*
|
||||
* @property-read array $other {
|
||||
* Extra information about event.
|
||||
*
|
||||
* - int lessonid: the id of the lesson.
|
||||
* - int groupid: the id of the group.
|
||||
* }
|
||||
*
|
||||
* @package mod_lesson
|
||||
* @since Moodle 2.9
|
||||
* @copyright 2015 Jean-Michel Vedrine
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class group_override_created extends \core\event\base {
|
||||
|
||||
/**
|
||||
* Init method.
|
||||
*/
|
||||
protected function init() {
|
||||
$this->data['objecttable'] = 'lesson_overrides';
|
||||
$this->data['crud'] = 'c';
|
||||
$this->data['edulevel'] = self::LEVEL_TEACHING;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns localised general event name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_name() {
|
||||
return get_string('eventoverridecreated', 'mod_lesson');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns description of what happened.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_description() {
|
||||
return "The user with id '$this->userid' created the override with id '$this->objectid' for the lesson with " .
|
||||
"course module id '$this->contextinstanceid' for the group with id '{$this->other['groupid']}'.";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns relevant URL.
|
||||
*
|
||||
* @return \moodle_url
|
||||
*/
|
||||
public function get_url() {
|
||||
return new \moodle_url('/mod/lesson/overrideedit.php', array('id' => $this->objectid));
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom validation.
|
||||
*
|
||||
* @throws \coding_exception
|
||||
* @return void
|
||||
*/
|
||||
protected function validate_data() {
|
||||
parent::validate_data();
|
||||
|
||||
if (!isset($this->other['lessonid'])) {
|
||||
throw new \coding_exception('The \'lessonid\' value must be set in other.');
|
||||
}
|
||||
|
||||
if (!isset($this->other['groupid'])) {
|
||||
throw new \coding_exception('The \'groupid\' value must be set in other.');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* The mod_lesson group override deleted event.
|
||||
*
|
||||
* @package mod_lesson
|
||||
* @copyright 2015 Jean-Michel Vedrine
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
namespace mod_lesson\event;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* The mod_lesson group override deleted event class.
|
||||
*
|
||||
* @property-read array $other {
|
||||
* Extra information about event.
|
||||
*
|
||||
* - int lessonid: the id of the lesson.
|
||||
* - int groupid: the id of the group.
|
||||
* }
|
||||
*
|
||||
* @package mod_lesson
|
||||
* @since Moodle 2.9
|
||||
* @copyright 2015 Jean-Michel vedrine
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class group_override_deleted extends \core\event\base {
|
||||
|
||||
/**
|
||||
* Init method.
|
||||
*/
|
||||
protected function init() {
|
||||
$this->data['objecttable'] = 'lesson_overrides';
|
||||
$this->data['crud'] = 'd';
|
||||
$this->data['edulevel'] = self::LEVEL_TEACHING;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns localised general event name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_name() {
|
||||
return get_string('eventoverridedeleted', 'mod_lesson');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns description of what happened.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_description() {
|
||||
return "The user with id '$this->userid' deleted the override with id '$this->objectid' for the lesson with " .
|
||||
"course module id '$this->contextinstanceid' for the group with id '{$this->other['groupid']}'.";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns relevant URL.
|
||||
*
|
||||
* @return \moodle_url
|
||||
*/
|
||||
public function get_url() {
|
||||
return new \moodle_url('/mod/lesson/overrides.php', array('cmid' => $this->contextinstanceid));
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom validation.
|
||||
*
|
||||
* @throws \coding_exception
|
||||
* @return void
|
||||
*/
|
||||
protected function validate_data() {
|
||||
parent::validate_data();
|
||||
|
||||
if (!isset($this->other['lessonid'])) {
|
||||
throw new \coding_exception('The \'lessonid\' value must be set in other.');
|
||||
}
|
||||
|
||||
if (!isset($this->other['groupid'])) {
|
||||
throw new \coding_exception('The \'groupid\' value must be set in other.');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* The mod_lesson group override updated event.
|
||||
*
|
||||
* @package mod_lesson
|
||||
* @copyright 2015 Jean-Michel Vedrine
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
namespace mod_lesson\event;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* The mod_lesson group override updated event class.
|
||||
*
|
||||
* @property-read array $other {
|
||||
* Extra information about event.
|
||||
*
|
||||
* - int lessonid: the id of the lesson.
|
||||
* - int groupid: the id of the group.
|
||||
* }
|
||||
*
|
||||
* @package mod_lesson
|
||||
* @since Moodle 2.9
|
||||
* @copyright 2015 Jean-Michel Vedrine
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class group_override_updated extends \core\event\base {
|
||||
|
||||
/**
|
||||
* Init method.
|
||||
*/
|
||||
protected function init() {
|
||||
$this->data['objecttable'] = 'lesson_overrides';
|
||||
$this->data['crud'] = 'u';
|
||||
$this->data['edulevel'] = self::LEVEL_TEACHING;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns localised general event name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_name() {
|
||||
return get_string('eventoverrideupdated', 'mod_lesson');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns description of what happened.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_description() {
|
||||
return "The user with id '$this->userid' updated the override with id '$this->objectid' for the lesson with " .
|
||||
"course module id '$this->contextinstanceid' for the group with id '{$this->other['groupid']}'.";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns relevant URL.
|
||||
*
|
||||
* @return \moodle_url
|
||||
*/
|
||||
public function get_url() {
|
||||
return new \moodle_url('/mod/lesson/overrideedit.php', array('id' => $this->objectid));
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom validation.
|
||||
*
|
||||
* @throws \coding_exception
|
||||
* @return void
|
||||
*/
|
||||
protected function validate_data() {
|
||||
parent::validate_data();
|
||||
|
||||
if (!isset($this->other['lessonid'])) {
|
||||
throw new \coding_exception('The \'lessonid\' value must be set in other.');
|
||||
}
|
||||
|
||||
if (!isset($this->other['groupid'])) {
|
||||
throw new \coding_exception('The \'groupid\' value must be set in other.');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* The mod_lesson user override created event.
|
||||
*
|
||||
* @package mod_lesson
|
||||
* @copyright 2015 Jean-Michel Vedrine
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
namespace mod_lesson\event;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* The mod_lesson user override created event class.
|
||||
*
|
||||
* @property-read array $other {
|
||||
* Extra information about event.
|
||||
*
|
||||
* - int lessonid: the id of the lesson.
|
||||
* }
|
||||
*
|
||||
* @package mod_lesson
|
||||
* @since Moodle 2.9
|
||||
* @copyright 2015 Jean-Michel Vedrine
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class user_override_created extends \core\event\base {
|
||||
|
||||
/**
|
||||
* Init method.
|
||||
*/
|
||||
protected function init() {
|
||||
$this->data['objecttable'] = 'lesson_overrides';
|
||||
$this->data['crud'] = 'c';
|
||||
$this->data['edulevel'] = self::LEVEL_TEACHING;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns localised general event name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_name() {
|
||||
return get_string('eventoverridecreated', 'mod_lesson');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns description of what happened.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_description() {
|
||||
return "The user with id '$this->userid' created the override with id '$this->objectid' for the lesson with " .
|
||||
"course module id '$this->contextinstanceid' for the user with id '{$this->relateduserid}'.";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns relevant URL.
|
||||
*
|
||||
* @return \moodle_url
|
||||
*/
|
||||
public function get_url() {
|
||||
return new \moodle_url('/mod/lesson/overrideedit.php', array('id' => $this->objectid));
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom validation.
|
||||
*
|
||||
* @throws \coding_exception
|
||||
* @return void
|
||||
*/
|
||||
protected function validate_data() {
|
||||
parent::validate_data();
|
||||
|
||||
if (!isset($this->relateduserid)) {
|
||||
throw new \coding_exception('The \'relateduserid\' must be set.');
|
||||
}
|
||||
|
||||
if (!isset($this->other['lessonid'])) {
|
||||
throw new \coding_exception('The \'lessonid\' value must be set in other.');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* The mod_lesson user override deleted event.
|
||||
*
|
||||
* @package mod_lesson
|
||||
* @copyright 2015 Jean-Michel Vedrine
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
namespace mod_lesson\event;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* The mod_lesson user override deleted event class.
|
||||
*
|
||||
* @property-read array $other {
|
||||
* Extra information about event.
|
||||
*
|
||||
* - int lessonid: the id of the lesson.
|
||||
* }
|
||||
*
|
||||
* @package mod_lesson
|
||||
* @since Moodle 2.9
|
||||
* @copyright 2015 Jean-Michel Vedrine
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class user_override_deleted extends \core\event\base {
|
||||
|
||||
/**
|
||||
* Init method.
|
||||
*/
|
||||
protected function init() {
|
||||
$this->data['objecttable'] = 'lesson_overrides';
|
||||
$this->data['crud'] = 'd';
|
||||
$this->data['edulevel'] = self::LEVEL_TEACHING;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns localised general event name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_name() {
|
||||
return get_string('eventoverridedeleted', 'mod_lesson');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns description of what happened.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_description() {
|
||||
return "The user with id '$this->userid' deleted the override with id '$this->objectid' for the lesson with " .
|
||||
"course module id '$this->contextinstanceid' for the user with id '{$this->relateduserid}'.";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns relevant URL.
|
||||
*
|
||||
* @return \moodle_url
|
||||
*/
|
||||
public function get_url() {
|
||||
return new \moodle_url('/mod/lesson/overrides.php', array('cmid' => $this->contextinstanceid));
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom validation.
|
||||
*
|
||||
* @throws \coding_exception
|
||||
* @return void
|
||||
*/
|
||||
protected function validate_data() {
|
||||
parent::validate_data();
|
||||
|
||||
if (!isset($this->relateduserid)) {
|
||||
throw new \coding_exception('The \'relateduserid\' must be set.');
|
||||
}
|
||||
|
||||
if (!isset($this->other['lessonid'])) {
|
||||
throw new \coding_exception('The \'lessonid\' value must be set in other.');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* The mod_lesson user override updated event.
|
||||
*
|
||||
* @package mod_lesson
|
||||
* @copyright 2015 Jean-Michel vedrine
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace mod_lesson\event;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* The mod_lesson user override updated event class.
|
||||
*
|
||||
* @property-read array $other {
|
||||
* Extra information about event.
|
||||
*
|
||||
* - int lessonid: the id of the lesson.
|
||||
* }
|
||||
*
|
||||
* @package mod_lesson
|
||||
* @since Moodle 2.9
|
||||
* @copyright 2015 Jean-Michel Vedrine
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class user_override_updated extends \core\event\base {
|
||||
|
||||
/**
|
||||
* Init method.
|
||||
*/
|
||||
protected function init() {
|
||||
$this->data['objecttable'] = 'lesson_overrides';
|
||||
$this->data['crud'] = 'u';
|
||||
$this->data['edulevel'] = self::LEVEL_TEACHING;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns localised general event name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_name() {
|
||||
return get_string('eventoverrideupdated', 'mod_lesson');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns description of what happened.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_description() {
|
||||
return "The user with id '$this->userid' updated the override with id '$this->objectid' for the lesson with " .
|
||||
"course module id '$this->contextinstanceid' for the user with id '{$this->relateduserid}'.";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns relevant URL.
|
||||
*
|
||||
* @return \moodle_url
|
||||
*/
|
||||
public function get_url() {
|
||||
return new \moodle_url('/mod/lesson/overrideedit.php', array('id' => $this->objectid));
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom validation.
|
||||
*
|
||||
* @throws \coding_exception
|
||||
* @return void
|
||||
*/
|
||||
protected function validate_data() {
|
||||
parent::validate_data();
|
||||
|
||||
if (!isset($this->relateduserid)) {
|
||||
throw new \coding_exception('The \'relateduserid\' must be set.');
|
||||
}
|
||||
|
||||
if (!isset($this->other['lessonid'])) {
|
||||
throw new \coding_exception('The \'lessonid\' value must be set in other.');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Group observers.
|
||||
*
|
||||
* @package mod_lesson
|
||||
* @copyright 2015 Jean-Michel Vedrine
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace mod_lesson;
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
require_once($CFG->dirroot . '/mod/lesson/locallib.php');
|
||||
|
||||
/**
|
||||
* Group observers class.
|
||||
*
|
||||
* @package mod_lesson
|
||||
* @copyright 2015 Jean-Michel Vedrine
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class group_observers {
|
||||
|
||||
/**
|
||||
* Flag whether a course reset is in progress or not.
|
||||
*
|
||||
* @var int The course ID.
|
||||
*/
|
||||
protected static $resetinprogress = false;
|
||||
|
||||
/**
|
||||
* A course reset has started.
|
||||
*
|
||||
* @param \core\event\base $event The event.
|
||||
* @return void
|
||||
*/
|
||||
public static function course_reset_started($event) {
|
||||
self::$resetinprogress = $event->courseid;
|
||||
}
|
||||
|
||||
/**
|
||||
* A course reset has ended.
|
||||
*
|
||||
* @param \core\event\base $event The event.
|
||||
* @return void
|
||||
*/
|
||||
public static function course_reset_ended($event) {
|
||||
if (!empty(self::$resetinprogress)) {
|
||||
if (!empty($event->other['reset_options']['reset_groups_remove'])) {
|
||||
lesson_process_group_deleted_in_course($event->courseid);
|
||||
}
|
||||
}
|
||||
|
||||
self::$resetinprogress = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* A group was deleted.
|
||||
*
|
||||
* @param \core\event\base $event The event.
|
||||
* @return void
|
||||
*/
|
||||
public static function group_deleted($event) {
|
||||
if (!empty(self::$resetinprogress)) {
|
||||
// We will take care of that once the course reset ends.
|
||||
return;
|
||||
}
|
||||
lesson_process_group_deleted_in_course($event->courseid);
|
||||
}
|
||||
}
|
||||
@@ -36,6 +36,9 @@ $lesson = new lesson($DB->get_record('lesson', array('id' => $cm->instance), '*'
|
||||
require_login($course, false, $cm);
|
||||
require_sesskey();
|
||||
|
||||
// Apply overrides.
|
||||
$lesson->update_effective_access($USER->id);
|
||||
|
||||
$context = context_module::instance($cm->id);
|
||||
$canmanage = has_capability('mod/lesson:manage', $context);
|
||||
$lessonoutput = $PAGE->get_renderer('mod_lesson');
|
||||
|
||||
@@ -85,5 +85,15 @@ $capabilities = array(
|
||||
'editingteacher' => CAP_ALLOW,
|
||||
'manager' => CAP_ALLOW
|
||||
)
|
||||
)
|
||||
),
|
||||
|
||||
// Edit the lesson overrides.
|
||||
'mod/lesson:manageoverrides' => array(
|
||||
'captype' => 'write',
|
||||
'contextlevel' => CONTEXT_MODULE,
|
||||
'archetypes' => array(
|
||||
'editingteacher' => CAP_ALLOW,
|
||||
'manager' => CAP_ALLOW
|
||||
)
|
||||
),
|
||||
);
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Add event handlers for the lesson
|
||||
*
|
||||
* @package mod_lesson
|
||||
* @category event
|
||||
* @copyright 2015 Jean-Michel Vedrine
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$observers = array(
|
||||
|
||||
array(
|
||||
'eventname' => '\core\event\course_reset_started',
|
||||
'callback' => '\mod_lesson\group_observers::course_reset_started',
|
||||
),
|
||||
array(
|
||||
'eventname' => '\core\event\course_reset_ended',
|
||||
'callback' => '\mod_lesson\group_observers::course_reset_ended',
|
||||
),
|
||||
array(
|
||||
'eventname' => '\core\event\group_deleted',
|
||||
'callback' => '\mod_lesson\group_observers::group_deleted'
|
||||
),
|
||||
);
|
||||
@@ -192,5 +192,26 @@
|
||||
<INDEX NAME="userid" UNIQUE="false" FIELDS="userid"/>
|
||||
</INDEXES>
|
||||
</TABLE>
|
||||
<TABLE NAME="lesson_overrides" COMMENT="The overrides to lesson settings.">
|
||||
<FIELDS>
|
||||
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
|
||||
<FIELD NAME="lessonid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Foreign key references lesson.id"/>
|
||||
<FIELD NAME="groupid" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false" COMMENT="Foreign key references groups.id. Can be null if this is a per-user override."/>
|
||||
<FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false" COMMENT="Foreign key references user.id. Can be null if this is a per-group override."/>
|
||||
<FIELD NAME="available" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false" COMMENT="Time at which students may start attempting this lesson. Can be null, in which case the lesson default is used."/>
|
||||
<FIELD NAME="deadline" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false" COMMENT="Time by which students must have completed their attempt. Can be null, in which case the lesson default is used."/>
|
||||
<FIELD NAME="timelimit" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false" COMMENT="Time limit in seconds. Can be null, in which case the lesson default is used."/>
|
||||
<FIELD NAME="review" TYPE="int" LENGTH="3" NOTNULL="false" SEQUENCE="false"/>
|
||||
<FIELD NAME="maxattempts" TYPE="int" LENGTH="3" NOTNULL="false" SEQUENCE="false"/>
|
||||
<FIELD NAME="retake" TYPE="int" LENGTH="3" NOTNULL="false" SEQUENCE="false"/>
|
||||
<FIELD NAME="password" TYPE="char" LENGTH="32" NOTNULL="false" SEQUENCE="false" COMMENT="Lesson password. Can be null, in which case the lesson default is used."/>
|
||||
</FIELDS>
|
||||
<KEYS>
|
||||
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
|
||||
<KEY NAME="lessonid" TYPE="foreign" FIELDS="lessonid" REFTABLE="lesson" REFFIELDS="id"/>
|
||||
<KEY NAME="groupid" TYPE="foreign" FIELDS="groupid" REFTABLE="groups" REFFIELDS="id"/>
|
||||
<KEY NAME="userid" TYPE="foreign" FIELDS="userid" REFTABLE="user" REFFIELDS="id"/>
|
||||
</KEYS>
|
||||
</TABLE>
|
||||
</TABLES>
|
||||
</XMLDB>
|
||||
|
||||
@@ -263,5 +263,38 @@ function xmldb_lesson_upgrade($oldversion) {
|
||||
upgrade_mod_savepoint(true, 2015032700, 'lesson');
|
||||
}
|
||||
|
||||
if ($oldversion < 2015033100) {
|
||||
|
||||
// Define table lesson_overrides to be created.
|
||||
$table = new xmldb_table('lesson_overrides');
|
||||
|
||||
// Adding fields to table lesson_overrides.
|
||||
$table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
|
||||
$table->add_field('lessonid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
|
||||
$table->add_field('groupid', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
|
||||
$table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
|
||||
$table->add_field('available', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
|
||||
$table->add_field('deadline', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
|
||||
$table->add_field('timelimit', XMLDB_TYPE_INTEGER, '10', null, null, null, null);
|
||||
$table->add_field('review', XMLDB_TYPE_INTEGER, '3', null, null, null, null);
|
||||
$table->add_field('maxattempts', XMLDB_TYPE_INTEGER, '3', null, null, null, null);
|
||||
$table->add_field('retake', XMLDB_TYPE_INTEGER, '3', null, null, null, null);
|
||||
$table->add_field('password', XMLDB_TYPE_CHAR, '32', null, null, null, null);
|
||||
|
||||
// Adding keys to table lesson_overrides.
|
||||
$table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
|
||||
$table->add_key('lessonid', XMLDB_KEY_FOREIGN, array('lessonid'), 'lesson', array('id'));
|
||||
$table->add_key('groupid', XMLDB_KEY_FOREIGN, array('groupid'), 'groups', array('id'));
|
||||
$table->add_key('userid', XMLDB_KEY_FOREIGN, array('userid'), 'user', array('id'));
|
||||
|
||||
// Conditionally launch create table for lesson_overrides.
|
||||
if (!$dbman->table_exists($table)) {
|
||||
$dbman->create_table($table);
|
||||
}
|
||||
|
||||
// Lesson savepoint reached.
|
||||
upgrade_mod_savepoint(true, 2015033100, 'lesson');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -62,6 +62,8 @@ if ($attemptid > 0) {
|
||||
$attempt = $DB->get_record('lesson_attempts', array('id' => $attemptid));
|
||||
$answer = $DB->get_record('lesson_answers', array('lessonid' => $lesson->id, 'pageid' => $attempt->pageid));
|
||||
$user = $DB->get_record('user', array('id' => $attempt->userid));
|
||||
// Apply overrides.
|
||||
$lesson->update_effective_access($user->id);
|
||||
$scoreoptions = array();
|
||||
if ($lesson->custom) {
|
||||
$i = $answer->score;
|
||||
|
||||
@@ -48,6 +48,8 @@ $string['addedaquestionpage'] = 'Added a question page';
|
||||
$string['addedcluster'] = 'Added a cluster';
|
||||
$string['addedendofcluster'] = 'Added an end of cluster';
|
||||
$string['addendofcluster'] = 'Add an end of cluster';
|
||||
$string['addnewgroupoverride'] = 'Add group override';
|
||||
$string['addnewuseroverride'] = 'Add user override';
|
||||
$string['addpage'] = 'Add a page';
|
||||
$string['and'] = 'AND';
|
||||
$string['anchortitle'] = 'Start of main content';
|
||||
@@ -87,6 +89,7 @@ $string['casesensitive_help'] = 'Tick the checkbox to use regular expressions fo
|
||||
$string['classstats'] = 'Class statistics';
|
||||
$string['clicktodownload'] = 'Click on the following link to download the file.';
|
||||
$string['clicktopost'] = 'Click here to post your grade on the High Scores list.';
|
||||
$string['closebeforeopen'] = 'Could not update the lesson. You have specified a close date before the open date.';
|
||||
$string['cluster'] = 'Cluster';
|
||||
$string['clusterjump'] = 'Unseen question within a cluster';
|
||||
$string['clustertitle'] = 'Cluster';
|
||||
@@ -136,6 +139,7 @@ $string['description'] = 'Description';
|
||||
$string['detailedstats'] = 'Detailed statistics';
|
||||
$string['didnotanswerquestion'] = 'Did not answer this question.';
|
||||
$string['didnotreceivecredit'] = 'Did not receive credit';
|
||||
$string['disabled'] = 'Disabled';
|
||||
$string['displaydefaultfeedback'] = 'Use default feedback';
|
||||
$string['displaydefaultfeedback_help'] = 'If enabled, when a response is not found for a particular question, the default response of "That\'s the correct answer" or "That\'s the wrong answer" will be shown.';
|
||||
$string['displayhighscores'] = 'Display high scores';
|
||||
@@ -154,12 +158,14 @@ $string['displayscorewithoutessays'] = 'Your score is {$a->score} (out of {$a->g
|
||||
$string['edit'] = 'Edit';
|
||||
$string['editingquestionpage'] = 'Editing {$a} question page';
|
||||
$string['editlessonsettings'] = 'Edit lesson settings';
|
||||
$string['editoverride'] = 'Edit override';
|
||||
$string['editpage'] = 'Edit page contents';
|
||||
$string['editpagecontent'] = 'Edit page contents';
|
||||
$string['email'] = 'Email';
|
||||
$string['emailallgradedessays'] = 'Email ALL graded essays';
|
||||
$string['emailgradedessays'] = 'Email graded essays';
|
||||
$string['emailsuccess'] = 'Emails sent successfully';
|
||||
$string['enabled'] = 'Enabled';
|
||||
$string['endofbranch'] = 'End of branch';
|
||||
$string['endofcluster'] = 'End of cluster';
|
||||
$string['endofclustertitle'] = 'End of cluster';
|
||||
@@ -185,6 +191,9 @@ $string['eventlessonended'] = 'Lesson ended';
|
||||
$string['eventlessonrestarted'] = 'Lesson restarted';
|
||||
$string['eventlessonresumed'] = 'Lesson resumed';
|
||||
$string['eventlessonstarted'] = 'Lesson started';
|
||||
$string['eventoverridecreated'] = 'Lesson override created';
|
||||
$string['eventoverridedeleted'] = 'Lesson override deleted';
|
||||
$string['eventoverrideupdated'] = 'Lesson override updated';
|
||||
$string['eventpagecreated'] = 'Page created';
|
||||
$string['eventpagemoved'] = 'Page moved';
|
||||
$string['eventpageupdated'] = 'Page updated';
|
||||
@@ -208,6 +217,9 @@ $string['gradebetterthanerror'] = 'Earn a grade better than {$a} percent';
|
||||
$string['gradeessay'] = 'Grade essay questions ({$a->notgradedcount} not graded and {$a->notsentcount} not sent)';
|
||||
$string['gradeis'] = 'Grade is {$a}';
|
||||
$string['gradeoptions'] = 'Grade options';
|
||||
$string['groupoverrides'] = 'Group overrides';
|
||||
$string['groupoverridesdeleted'] = 'Group overrides deleted';
|
||||
$string['groupsnone'] = 'There are no groups in this course';
|
||||
$string['handlingofretakes'] = 'Handling of re-takes';
|
||||
$string['handlingofretakes_help'] = 'If re-takes are allowed, this setting specifies whether the grade for the lesson is the mean or maximum of all attempts.';
|
||||
$string['havenotgradedyet'] = 'Have not graded yet.';
|
||||
@@ -226,6 +238,7 @@ $string['insertedpage'] = 'Inserted page';
|
||||
$string['invalidfile'] = 'Invalid file';
|
||||
$string['invalidid'] = 'No course module ID or lesson ID were passed';
|
||||
$string['invalidlessonid'] = 'lesson ID was incorrect';
|
||||
$string['invalidoverrideid'] = 'Invalid override id';
|
||||
$string['invalidpageid'] = 'Invalid page ID';
|
||||
$string['jump'] = 'Jump';
|
||||
$string['jumps'] = 'Jumps';
|
||||
@@ -243,6 +256,7 @@ $string['lessoncloseson'] = 'Lesson closes on {$a}';
|
||||
$string['lesson:edit'] = 'Edit a lesson activity';
|
||||
$string['lessonformating'] = 'Lesson formatting';
|
||||
$string['lesson:manage'] = 'Manage a lesson activity';
|
||||
$string['lesson:manageoverrides'] = 'Manage lesson overrides';
|
||||
$string['lesson:viewreports'] = 'View lesson reports';
|
||||
$string['lessonmenu'] = 'Lesson menu';
|
||||
$string['lessonnotready'] = 'This lesson is not ready to be taken. Please contact your {$a}.';
|
||||
@@ -310,6 +324,7 @@ $string['nextpage'] = 'Next page';
|
||||
$string['noanswer'] = 'One or more questions have no answer given. Please go back and submit an answer.';
|
||||
$string['noattemptrecordsfound'] = 'No attempt records found: no grade given';
|
||||
$string['nobranchtablefound'] = 'No content page found';
|
||||
$string['noclose'] = 'No close date';
|
||||
$string['nocommentyet'] = 'No comment yet.';
|
||||
$string['nocoursemods'] = 'No activities found';
|
||||
$string['nocredit'] = 'No credit';
|
||||
@@ -318,12 +333,15 @@ $string['noessayquestionsfound'] = 'No essay questions found in this lesson.';
|
||||
$string['nohighscores'] = 'No high scores';
|
||||
$string['nolessonattempts'] = 'No attempts have been made on this lesson.';
|
||||
$string['nolessonattemptsgroup'] = 'No attempts have been made by {$a} group members on this lesson.';
|
||||
$string['none'] = 'None';
|
||||
$string['nooneansweredcorrectly'] = 'No one answered correctly.';
|
||||
$string['nooneansweredthisquestion'] = 'No one answered this question.';
|
||||
$string['nooneenteredthis'] = 'No one entered this.';
|
||||
$string['noonehasanswered'] = 'No one has answered an essay question yet.';
|
||||
$string['noonehasansweredgroup'] = 'No one in {$a} has answered an essay question yet.';
|
||||
$string['noonecheckedthis'] = 'No one checked this.';
|
||||
$string['noopen'] = 'No open date';
|
||||
$string['nooverridedata'] = 'You must override at least one of the lesson settings.';
|
||||
$string['noretake'] = 'You are not allowed to retake this lesson.';
|
||||
$string['normal'] = 'Normal - follow lesson path';
|
||||
$string['notcompleted'] = 'Not completed';
|
||||
@@ -351,6 +369,14 @@ $string['or'] = 'OR';
|
||||
$string['ordered'] = 'Ordered';
|
||||
$string['other'] = 'Other';
|
||||
$string['outof'] = 'Out of {$a}';
|
||||
$string['overridedeletegroupsure'] = 'Are you sure you want to delete the override for group {$a}?';
|
||||
$string['overridedeleteusersure'] = 'Are you sure you want to delete the override for user {$a}?';
|
||||
$string['override'] = 'Override';
|
||||
$string['overridegroup'] = 'Override group';
|
||||
$string['overridegroupeventname'] = '{$a->lesson} - {$a->group}';
|
||||
$string['overrides'] = 'Overrides';
|
||||
$string['overrideuser'] = 'Override user';
|
||||
$string['overrideusereventname'] = '{$a->lesson} - Override';
|
||||
$string['overview'] = 'Overview';
|
||||
$string['overview_help'] = 'A lesson is made up of a number of pages and optionally content pages. A page contains some content and usually ends with a question. Associated with each answer to the question is a jump. The jump can be relative, such as this page or next page, or absolute, specifying any one of the pages in the lesson. A content page is a page containing a set of links to other pages in the lesson, for example a Table of Contents.';
|
||||
$string['page'] = 'Page: {$a}';
|
||||
@@ -398,6 +424,8 @@ $string['rank'] = 'Rank';
|
||||
$string['rawgrade'] = 'Raw grade';
|
||||
$string['receivedcredit'] = 'Received credit';
|
||||
$string['redisplaypage'] = 'Redisplay page';
|
||||
$string['removeallgroupoverrides'] = 'Delete all group overrides';
|
||||
$string['removealluseroverrides'] = 'Delete all user overrides';
|
||||
$string['report'] = 'Report';
|
||||
$string['reports'] = 'Reports';
|
||||
$string['response'] = 'Response';
|
||||
@@ -405,13 +433,16 @@ $string['retakesallowed'] = 'Re-takes allowed';
|
||||
$string['retakesallowed_help'] = 'If enabled, students can attempt the lesson more than once.';
|
||||
$string['returnto'] = 'Return to {$a}';
|
||||
$string['returntocourse'] = 'Return to the course';
|
||||
$string['reverttodefaults'] = 'Revert to lesson defaults';
|
||||
$string['review'] = 'Review';
|
||||
$string['reviewlesson'] = 'Review lesson';
|
||||
$string['reviewquestionback'] = 'Yes, I\'d like to try again';
|
||||
$string['reviewquestioncontinue'] = 'No, I just want to go on to the next question';
|
||||
$string['sanitycheckfailed'] = 'Sanity check failed: This attempt has been deleted';
|
||||
$string['save'] = 'Save';
|
||||
$string['savechanges'] = 'Save changes';
|
||||
$string['savechangesandeol'] = 'Save all changes and go to the end of the lesson.';
|
||||
$string['saveoverrideandstay'] = 'Save and enter another override';
|
||||
$string['savepage'] = 'Save page';
|
||||
$string['score'] = 'Score';
|
||||
$string['score_help'] = 'Score is only used when custom scoring is enabled. Each answer can then be given a numerical point value (positive or negative).';
|
||||
@@ -464,6 +495,9 @@ $string['usemaximum'] = 'Use maximum';
|
||||
$string['usemean'] = 'Use mean';
|
||||
$string['usepassword'] = 'Password protected lesson';
|
||||
$string['usepassword_help'] = 'If enabled, a password is required in order to access the lesson.';
|
||||
$string['useroverridesdeleted'] = 'User overrides deleted';
|
||||
$string['usersnone'] = 'No students have access to this lesson';
|
||||
$string['useroverrides'] = 'User overrides';
|
||||
$string['viewgrades'] = 'View grades';
|
||||
$string['viewhighscores'] = 'View high scores list';
|
||||
$string['viewreports'] = 'View {$a->attempts} completed {$a->student} attempts';
|
||||
|
||||
+220
-45
@@ -95,6 +95,166 @@ function lesson_update_instance($data, $mform) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function updates the events associated to the lesson.
|
||||
* If $override is non-zero, then it updates only the events
|
||||
* associated with the specified override.
|
||||
*
|
||||
* @uses LESSON_MAX_EVENT_LENGTH
|
||||
* @param object $lesson the lesson object.
|
||||
* @param object $override (optional) limit to a specific override
|
||||
*/
|
||||
function lesson_update_events($lesson, $override = null) {
|
||||
global $CFG, $DB;
|
||||
|
||||
require_once($CFG->dirroot . '/calendar/lib.php');
|
||||
|
||||
// Load the old events relating to this lesson.
|
||||
$conds = array('modulename' => 'lesson',
|
||||
'instance' => $lesson->id);
|
||||
if (!empty($override)) {
|
||||
// Only load events for this override.
|
||||
if (isset($override->userid)) {
|
||||
$conds['userid'] = $override->userid;
|
||||
} else {
|
||||
$conds['groupid'] = $override->groupid;
|
||||
}
|
||||
}
|
||||
$oldevents = $DB->get_records('event', $conds);
|
||||
|
||||
// Now make a todo list of all that needs to be updated.
|
||||
if (empty($override)) {
|
||||
// We are updating the primary settings for the lesson, so we
|
||||
// need to add all the overrides.
|
||||
$overrides = $DB->get_records('lesson_overrides', array('lessonid' => $lesson->id));
|
||||
// As well as the original lesson (empty override).
|
||||
$overrides[] = new stdClass();
|
||||
} else {
|
||||
// Just do the one override.
|
||||
$overrides = array($override);
|
||||
}
|
||||
|
||||
foreach ($overrides as $current) {
|
||||
$groupid = isset($current->groupid) ? $current->groupid : 0;
|
||||
$userid = isset($current->userid) ? $current->userid : 0;
|
||||
$available = isset($current->available) ? $current->available : $lesson->available;
|
||||
$deadline = isset($current->deadline) ? $current->deadline : $lesson->deadline;
|
||||
|
||||
// Only add open/close events for an override if they differ from the lesson default.
|
||||
$addopen = empty($current->id) || !empty($current->available);
|
||||
$addclose = empty($current->id) || !empty($current->deadline);
|
||||
|
||||
if (!empty($lesson->coursemodule)) {
|
||||
$cmid = $lesson->coursemodule;
|
||||
} else {
|
||||
$cmid = get_coursemodule_from_instance('lesson', $lesson->id, $lesson->course)->id;
|
||||
}
|
||||
|
||||
$event = new stdClass();
|
||||
$event->description = format_module_intro('lesson', $lesson, $cmid);
|
||||
// Events module won't show user events when the courseid is nonzero.
|
||||
$event->courseid = ($userid) ? 0 : $lesson->course;
|
||||
$event->groupid = $groupid;
|
||||
$event->userid = $userid;
|
||||
$event->modulename = 'lesson';
|
||||
$event->instance = $lesson->id;
|
||||
$event->timestart = $available;
|
||||
$event->timeduration = max($deadline - $available, 0);
|
||||
$event->visible = instance_is_visible('lesson', $lesson);
|
||||
$event->eventtype = 'open';
|
||||
|
||||
// Determine the event name.
|
||||
if ($groupid) {
|
||||
$params = new stdClass();
|
||||
$params->lesson = $lesson->name;
|
||||
$params->group = groups_get_group_name($groupid);
|
||||
if ($params->group === false) {
|
||||
// Group doesn't exist, just skip it.
|
||||
continue;
|
||||
}
|
||||
$eventname = get_string('overridegroupeventname', 'lesson', $params);
|
||||
} else if ($userid) {
|
||||
$params = new stdClass();
|
||||
$params->lesson = $lesson->name;
|
||||
$eventname = get_string('overrideusereventname', 'lesson', $params);
|
||||
} else {
|
||||
$eventname = $lesson->name;
|
||||
}
|
||||
if ($addopen or $addclose) {
|
||||
if ($deadline and $available and $event->timeduration <= LESSON_MAX_EVENT_LENGTH) {
|
||||
// Single event for the whole lesson.
|
||||
if ($oldevent = array_shift($oldevents)) {
|
||||
$event->id = $oldevent->id;
|
||||
} else {
|
||||
unset($event->id);
|
||||
}
|
||||
$event->name = $eventname;
|
||||
// The method calendar_event::create will reuse a db record if the id field is set.
|
||||
calendar_event::create($event);
|
||||
} else {
|
||||
// Separate start and end events.
|
||||
$event->timeduration = 0;
|
||||
if ($available && $addopen) {
|
||||
if ($oldevent = array_shift($oldevents)) {
|
||||
$event->id = $oldevent->id;
|
||||
} else {
|
||||
unset($event->id);
|
||||
}
|
||||
$event->name = $eventname.' ('.get_string('lessonopens', 'lesson').')';
|
||||
// The method calendar_event::create will reuse a db record if the id field is set.
|
||||
calendar_event::create($event);
|
||||
}
|
||||
if ($deadline && $addclose) {
|
||||
if ($oldevent = array_shift($oldevents)) {
|
||||
$event->id = $oldevent->id;
|
||||
} else {
|
||||
unset($event->id);
|
||||
}
|
||||
$event->name = $eventname.' ('.get_string('lessoncloses', 'lesson').')';
|
||||
$event->timestart = $deadline;
|
||||
$event->eventtype = 'close';
|
||||
calendar_event::create($event);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Delete any leftover events.
|
||||
foreach ($oldevents as $badevent) {
|
||||
$badevent = calendar_event::load($badevent);
|
||||
$badevent->delete();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This standard function will check all instances of this module
|
||||
* and make sure there are up-to-date events created for each of them.
|
||||
* If courseid = 0, then every lesson event in the site is checked, else
|
||||
* only lesson events belonging to the course specified are checked.
|
||||
* This function is used, in its new format, by restore_refresh_events()
|
||||
*
|
||||
* @param int $courseid
|
||||
* @return bool
|
||||
*/
|
||||
function lesson_refresh_events($courseid = 0) {
|
||||
global $DB;
|
||||
|
||||
if ($courseid == 0) {
|
||||
if (!$lessons = $DB->get_records('lessons')) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (!$lessons = $DB->get_records('lesson', array('course' => $courseid))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($lessons as $lesson) {
|
||||
lesson_update_events($lesson);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an ID of an instance of this module,
|
||||
@@ -572,50 +732,8 @@ function lesson_process_pre_save(&$lesson) {
|
||||
* @return void
|
||||
**/
|
||||
function lesson_process_post_save(&$lesson) {
|
||||
global $DB, $CFG;
|
||||
require_once($CFG->dirroot.'/calendar/lib.php');
|
||||
require_once($CFG->dirroot . '/mod/lesson/locallib.php');
|
||||
|
||||
if ($events = $DB->get_records('event', array('modulename'=>'lesson', 'instance'=>$lesson->id))) {
|
||||
foreach($events as $event) {
|
||||
$event = calendar_event::load($event->id);
|
||||
$event->delete();
|
||||
}
|
||||
}
|
||||
|
||||
$event = new stdClass;
|
||||
$event->description = $lesson->name;
|
||||
$event->courseid = $lesson->course;
|
||||
$event->groupid = 0;
|
||||
$event->userid = 0;
|
||||
$event->modulename = 'lesson';
|
||||
$event->instance = $lesson->id;
|
||||
$event->eventtype = 'open';
|
||||
$event->timestart = $lesson->available;
|
||||
|
||||
$event->visible = instance_is_visible('lesson', $lesson);
|
||||
|
||||
$event->timeduration = ($lesson->deadline - $lesson->available);
|
||||
|
||||
if ($lesson->deadline and $lesson->available and $event->timeduration <= LESSON_MAX_EVENT_LENGTH) {
|
||||
// Single event for the whole lesson.
|
||||
$event->name = $lesson->name;
|
||||
calendar_event::create(clone($event));
|
||||
} else {
|
||||
// Separate start and end events.
|
||||
$event->timeduration = 0;
|
||||
if ($lesson->available) {
|
||||
$event->name = $lesson->name.' ('.get_string('lessonopens', 'lesson').')';
|
||||
calendar_event::create(clone($event));
|
||||
}
|
||||
|
||||
if ($lesson->deadline) {
|
||||
$event->name = $lesson->name.' ('.get_string('lessoncloses', 'lesson').')';
|
||||
$event->timestart = $lesson->deadline;
|
||||
$event->eventtype = 'close';
|
||||
calendar_event::create(clone($event));
|
||||
}
|
||||
}
|
||||
// Update the events relating to this lesson.
|
||||
lesson_update_events($lesson);
|
||||
}
|
||||
|
||||
|
||||
@@ -628,6 +746,10 @@ function lesson_process_post_save(&$lesson) {
|
||||
function lesson_reset_course_form_definition(&$mform) {
|
||||
$mform->addElement('header', 'lessonheader', get_string('modulenameplural', 'lesson'));
|
||||
$mform->addElement('advcheckbox', 'reset_lesson', get_string('deleteallattempts','lesson'));
|
||||
$mform->addElement('advcheckbox', 'reset_lesson_user_overrides',
|
||||
get_string('removealluseroverrides', 'lesson'));
|
||||
$mform->addElement('advcheckbox', 'reset_lesson_group_overrides',
|
||||
get_string('removeallgroupoverrides', 'lesson'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -636,7 +758,9 @@ function lesson_reset_course_form_definition(&$mform) {
|
||||
* @return array
|
||||
*/
|
||||
function lesson_reset_course_form_defaults($course) {
|
||||
return array('reset_lesson'=>1);
|
||||
return array('reset_lesson' => 1,
|
||||
'reset_lesson_group_overrides' => 1,
|
||||
'reset_lesson_user_overrides' => 1);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -710,8 +834,35 @@ function lesson_reset_userdata($data) {
|
||||
$status[] = array('component'=>$componentstr, 'item'=>get_string('deleteallattempts', 'lesson'), 'error'=>false);
|
||||
}
|
||||
|
||||
// Remove user overrides.
|
||||
if (!empty($data->reset_lesson_user_overrides)) {
|
||||
$DB->delete_records_select('lesson_overrides',
|
||||
'lessonid IN (SELECT id FROM {lesson} WHERE course = ?) AND userid IS NOT NULL', array($data->courseid));
|
||||
$status[] = array(
|
||||
'component' => $componentstr,
|
||||
'item' => get_string('useroverridesdeleted', 'lesson'),
|
||||
'error' => false);
|
||||
}
|
||||
// Remove group overrides.
|
||||
if (!empty($data->reset_lesson_group_overrides)) {
|
||||
$DB->delete_records_select('lesson_overrides',
|
||||
'lessonid IN (SELECT id FROM {lesson} WHERE course = ?) AND groupid IS NOT NULL', array($data->courseid));
|
||||
$status[] = array(
|
||||
'component' => $componentstr,
|
||||
'item' => get_string('groupoverridesdeleted', 'lesson'),
|
||||
'error' => false);
|
||||
}
|
||||
/// updating dates - shift may be negative too
|
||||
if ($data->timeshift) {
|
||||
$DB->execute("UPDATE {lesson_overrides}
|
||||
SET available = available + ?
|
||||
WHERE lessonid IN (SELECT id FROM {lesson} WHERE course = ?)
|
||||
AND available <> 0", array($data->timeshift, $data->courseid));
|
||||
$DB->execute("UPDATE {lesson_overrides}
|
||||
SET deadline = deadline + ?
|
||||
WHERE lessonid IN (SELECT id FROM {lesson} WHERE course = ?)
|
||||
AND deadline <> 0", array($data->timeshift, $data->courseid));
|
||||
|
||||
shift_course_mod_dates('lesson', array('available', 'deadline'), $data->timeshift, $data->courseid);
|
||||
$status[] = array('component'=>$componentstr, 'item'=>get_string('datechanged'), 'error'=>false);
|
||||
}
|
||||
@@ -820,6 +971,30 @@ function lesson_get_completion_state($course, $cm, $userid, $type) {
|
||||
function lesson_extend_settings_navigation($settings, $lessonnode) {
|
||||
global $PAGE, $DB;
|
||||
|
||||
// We want to add these new nodes after the Edit settings node, and before the
|
||||
// Locally assigned roles node. Of course, both of those are controlled by capabilities.
|
||||
$keys = $lessonnode->get_children_key_list();
|
||||
$beforekey = null;
|
||||
$i = array_search('modedit', $keys);
|
||||
if ($i === false and array_key_exists(0, $keys)) {
|
||||
$beforekey = $keys[0];
|
||||
} else if (array_key_exists($i + 1, $keys)) {
|
||||
$beforekey = $keys[$i + 1];
|
||||
}
|
||||
|
||||
if (has_capability('mod/lesson:manageoverrides', $PAGE->cm->context)) {
|
||||
$url = new moodle_url('/mod/lesson/overrides.php', array('cmid' => $PAGE->cm->id));
|
||||
$node = navigation_node::create(get_string('groupoverrides', 'lesson'),
|
||||
new moodle_url($url, array('mode' => 'group')),
|
||||
navigation_node::TYPE_SETTING, null, 'mod_lesson_groupoverrides');
|
||||
$lessonnode->add_node($node, $beforekey);
|
||||
|
||||
$node = navigation_node::create(get_string('useroverrides', 'lesson'),
|
||||
new moodle_url($url, array('mode' => 'user')),
|
||||
navigation_node::TYPE_SETTING, null, 'mod_lesson_useroverrides');
|
||||
$lessonnode->add_node($node, $beforekey);
|
||||
}
|
||||
|
||||
if (has_capability('mod/lesson:edit', $PAGE->cm->context)) {
|
||||
$url = new moodle_url('/mod/lesson/view.php', array('id' => $PAGE->cm->id));
|
||||
$lessonnode->add(get_string('preview', 'lesson'), $url);
|
||||
|
||||
+226
-1
@@ -638,6 +638,31 @@ function lesson_get_media_html($lesson, $context) {
|
||||
return $code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Logic to happen when a/some group(s) has/have been deleted in a course.
|
||||
*
|
||||
* @param int $courseid The course ID.
|
||||
* @return void
|
||||
*/
|
||||
function lesson_process_group_deleted_in_course($courseid) {
|
||||
global $DB;
|
||||
|
||||
// It would be nice if we got the groupid that was deleted.
|
||||
// Instead, we just update all lesson with orphaned group overrides.
|
||||
$sql = "SELECT o.id, o.lesson
|
||||
FROM {lesson_overrides} o
|
||||
JOIN {lesson} lesson ON lesson.id = o.lessonid
|
||||
LEFT JOIN {groups} grp ON grp.id = o.groupid
|
||||
WHERE lesson.course = :courseid
|
||||
AND o.groupid IS NOT NULL
|
||||
AND grp.id IS NULL";
|
||||
$params = array('courseid' => $courseid);
|
||||
$records = $DB->get_records_sql_menu($sql, $params);
|
||||
if (!$records) {
|
||||
return; // Nothing to do.
|
||||
}
|
||||
$DB->delete_records_list('lesson_overrides', 'id', array_keys($records));
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract class that page type's MUST inherit from.
|
||||
@@ -988,6 +1013,8 @@ class lesson extends lesson_base {
|
||||
$cm = get_coursemodule_from_instance('lesson', $this->properties->id, $this->properties->course);
|
||||
$context = context_module::instance($cm->id);
|
||||
|
||||
$this->delete_all_overrides();
|
||||
|
||||
$DB->delete_records("lesson", array("id"=>$this->properties->id));
|
||||
$DB->delete_records("lesson_pages", array("lessonid"=>$this->properties->id));
|
||||
$DB->delete_records("lesson_answers", array("lessonid"=>$this->properties->id));
|
||||
@@ -1011,6 +1038,204 @@ class lesson extends lesson_base {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a lesson override from the database and clears any corresponding calendar events
|
||||
*
|
||||
* @param int $overrideid The id of the override being deleted
|
||||
* @return bool true on success
|
||||
*/
|
||||
public function delete_override($overrideid) {
|
||||
global $CFG, $DB;
|
||||
|
||||
require_once($CFG->dirroot . '/calendar/lib.php');
|
||||
|
||||
$cm = get_coursemodule_from_instance('lesson', $this->properties->id, $this->properties->course);
|
||||
|
||||
$override = $DB->get_record('lesson_overrides', array('id' => $overrideid), '*', MUST_EXIST);
|
||||
|
||||
// Delete the events.
|
||||
$conds = array('modulename' => 'lesson',
|
||||
'instance' => $this->properties->id);
|
||||
if (isset($override->userid)) {
|
||||
$conds['userid'] = $override->userid;
|
||||
} else {
|
||||
$conds['groupid'] = $override->groupid;
|
||||
}
|
||||
$events = $DB->get_records('event', $conds);
|
||||
foreach ($events as $event) {
|
||||
$eventold = calendar_event::load($event);
|
||||
$eventold->delete();
|
||||
}
|
||||
|
||||
$DB->delete_records('lesson_overrides', array('id' => $overrideid));
|
||||
|
||||
// Set the common parameters for one of the events we will be triggering.
|
||||
$params = array(
|
||||
'objectid' => $override->id,
|
||||
'context' => context_module::instance($cm->id),
|
||||
'other' => array(
|
||||
'lessonid' => $override->lessonid
|
||||
)
|
||||
);
|
||||
// Determine which override deleted event to fire.
|
||||
if (!empty($override->userid)) {
|
||||
$params['relateduserid'] = $override->userid;
|
||||
$event = \mod_lesson\event\user_override_deleted::create($params);
|
||||
} else {
|
||||
$params['other']['groupid'] = $override->groupid;
|
||||
$event = \mod_lesson\event\group_override_deleted::create($params);
|
||||
}
|
||||
|
||||
// Trigger the override deleted event.
|
||||
$event->add_record_snapshot('lesson_overrides', $override);
|
||||
$event->trigger();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes all lesson overrides from the database and clears any corresponding calendar events
|
||||
*/
|
||||
public function delete_all_overrides() {
|
||||
global $DB;
|
||||
|
||||
$overrides = $DB->get_records('lesson_overrides', array('lessonid' => $this->properties->id), 'id');
|
||||
foreach ($overrides as $override) {
|
||||
$this->delete_override($override->id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the lesson properties with override information for a user.
|
||||
*
|
||||
* Algorithm: For each lesson setting, if there is a matching user-specific override,
|
||||
* then use that otherwise, if there are group-specific overrides, return the most
|
||||
* lenient combination of them. If neither applies, leave the quiz setting unchanged.
|
||||
*
|
||||
* Special case: if there is more than one password that applies to the user, then
|
||||
* lesson->extrapasswords will contain an array of strings giving the remaining
|
||||
* passwords.
|
||||
*
|
||||
* @param int $userid The userid.
|
||||
*/
|
||||
public function update_effective_access($userid) {
|
||||
global $DB;
|
||||
|
||||
// Check for user override.
|
||||
$override = $DB->get_record('lesson_overrides', array('lessonid' => $this->properties->id, 'userid' => $userid));
|
||||
|
||||
if (!$override) {
|
||||
$override = new stdClass();
|
||||
$override->available = null;
|
||||
$override->deadline = null;
|
||||
$override->timelimit = null;
|
||||
$override->review = null;
|
||||
$override->maxattempts = null;
|
||||
$override->retake = null;
|
||||
$override->password = null;
|
||||
}
|
||||
|
||||
// Check for group overrides.
|
||||
$groupings = groups_get_user_groups($this->properties->course, $userid);
|
||||
|
||||
if (!empty($groupings[0])) {
|
||||
// Select all overrides that apply to the User's groups.
|
||||
list($extra, $params) = $DB->get_in_or_equal(array_values($groupings[0]));
|
||||
$sql = "SELECT * FROM {lesson_overrides}
|
||||
WHERE groupid $extra AND lessonid = ?";
|
||||
$params[] = $this->properties->id;
|
||||
$records = $DB->get_records_sql($sql, $params);
|
||||
|
||||
// Combine the overrides.
|
||||
$availables = array();
|
||||
$deadlines = array();
|
||||
$timelimits = array();
|
||||
$reviews = array();
|
||||
$attempts = array();
|
||||
$retakes = array();
|
||||
$passwords = array();
|
||||
|
||||
foreach ($records as $gpoverride) {
|
||||
if (isset($gpoverride->available)) {
|
||||
$availables[] = $gpoverride->available;
|
||||
}
|
||||
if (isset($gpoverride->deadline)) {
|
||||
$deadlines[] = $gpoverride->deadline;
|
||||
}
|
||||
if (isset($gpoverride->timelimit)) {
|
||||
$timelimits[] = $gpoverride->timelimit;
|
||||
}
|
||||
if (isset($gpoverride->review)) {
|
||||
$reviews[] = $gpoverride->review;
|
||||
}
|
||||
if (isset($gpoverride->maxattempts)) {
|
||||
$attempts[] = $gpoverride->maxattempts;
|
||||
}
|
||||
if (isset($gpoverride->retake)) {
|
||||
$retakes[] = $gpoverride->retake;
|
||||
}
|
||||
if (isset($gpoverride->password)) {
|
||||
$passwords[] = $gpoverride->password;
|
||||
}
|
||||
}
|
||||
// If there is a user override for a setting, ignore the group override.
|
||||
if (is_null($override->available) && count($availables)) {
|
||||
$override->available = min($availables);
|
||||
}
|
||||
if (is_null($override->deadline) && count($deadlines)) {
|
||||
if (in_array(0, $deadlines)) {
|
||||
$override->deadline = 0;
|
||||
} else {
|
||||
$override->deadline = max($deadlines);
|
||||
}
|
||||
}
|
||||
if (is_null($override->timelimit) && count($timelimits)) {
|
||||
if (in_array(0, $timelimits)) {
|
||||
$override->timelimit = 0;
|
||||
} else {
|
||||
$override->timelimit = max($timelimits);
|
||||
}
|
||||
}
|
||||
if (is_null($override->review) && count($reviews)) {
|
||||
$override->review = max($reviews);
|
||||
}
|
||||
if (is_null($override->maxattempts) && count($attempts)) {
|
||||
$override->maxattempts = max($attempts);
|
||||
}
|
||||
if (is_null($override->retake) && count($retakes)) {
|
||||
$override->retake = max($retakes);
|
||||
}
|
||||
if (is_null($override->password) && count($passwords)) {
|
||||
$override->password = array_shift($passwords);
|
||||
if (count($passwords)) {
|
||||
$override->extrapasswords = $passwords;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Merge with lesson defaults.
|
||||
$keys = array('available', 'deadline', 'timelimit', 'maxattempts', 'review', 'retake');
|
||||
foreach ($keys as $key) {
|
||||
if (isset($override->{$key})) {
|
||||
$this->properties->{$key} = $override->{$key};
|
||||
}
|
||||
}
|
||||
|
||||
// Special handling of lesson usepassword and password.
|
||||
if (isset($override->password)) {
|
||||
if ($override->password == '') {
|
||||
$this->properties->usepassword = 0;
|
||||
} else {
|
||||
$this->properties->usepassword = 1;
|
||||
$this->properties->password = $override->password;
|
||||
if (isset($override->extrapasswords)) {
|
||||
$this->properties->extrapasswords = $override->extrapasswords;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches messages from the session that may have been set in previous page
|
||||
* actions.
|
||||
@@ -1452,7 +1677,7 @@ class lesson extends lesson_base {
|
||||
* @return string
|
||||
*/
|
||||
public function time_remaining($starttime) {
|
||||
$timeleft = $starttime + $this->timelimit - time();
|
||||
$timeleft = $starttime + $this->properties->timelimit - time();
|
||||
$hours = floor($timeleft/3600);
|
||||
$timeleft = $timeleft - ($hours * 3600);
|
||||
$minutes = floor($timeleft/60);
|
||||
|
||||
@@ -38,6 +38,10 @@ $lesson = new lesson($DB->get_record('lesson', array('id' => $cm->instance), '*'
|
||||
|
||||
require_login($course, false, $cm);
|
||||
|
||||
|
||||
// Apply overrides.
|
||||
$lesson->update_effective_access($USER->id);
|
||||
|
||||
$context = context_module::instance($cm->id);
|
||||
$canmanage = has_capability('mod/lesson:manage', $context);
|
||||
|
||||
@@ -86,11 +90,25 @@ if (!$canmanage) {
|
||||
if (!empty($userpassword) && (($lesson->password == md5(trim($userpassword))) || ($lesson->password == trim($userpassword)))) {
|
||||
// with or without md5 for backward compatibility (MDL-11090)
|
||||
$USER->lessonloggedin[$lesson->id] = true;
|
||||
$correctpass = true;
|
||||
if ($lesson->highscores) {
|
||||
// Logged in - redirect so we go through all of these checks before starting the lesson.
|
||||
redirect("$CFG->wwwroot/mod/lesson/view.php?id=$cm->id");
|
||||
}
|
||||
} else {
|
||||
} else if (isset($lesson->extrapasswords)) {
|
||||
// Group overrides may have additional passwords.
|
||||
foreach ($lesson->extrapasswords as $password) {
|
||||
if (strcmp($password, md5(trim($userpassword))) === 0 || strcmp($password, trim($userpassword)) === 0) {
|
||||
$correctpass = true;
|
||||
$USER->lessonloggedin[$lesson->id] = true;
|
||||
if ($lesson->highscores) {
|
||||
// Logged in - redirect so we go through all of these checks before starting the lesson.
|
||||
redirect("$CFG->wwwroot/mod/lesson/view.php?id=$cm->id");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!$correctpass) {
|
||||
echo $lessonoutput->header($lesson, $cm);
|
||||
echo $lessonoutput->login_prompt($lesson, $userpassword !== '');
|
||||
echo $lessonoutput->footer();
|
||||
|
||||
@@ -0,0 +1,287 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Settings form for overrides in the lesson module.
|
||||
*
|
||||
* @package mod_lesson
|
||||
* @copyright 2015 Jean-Michel Vedrine
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
require_once($CFG->libdir . '/formslib.php');
|
||||
require_once($CFG->dirroot . '/mod/lesson/mod_form.php');
|
||||
|
||||
|
||||
/**
|
||||
* Form for editing settings overrides.
|
||||
*
|
||||
* @copyright 2015 Jean-Michel Vedrine
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class lesson_override_form extends moodleform {
|
||||
|
||||
/** @var object course module object. */
|
||||
protected $cm;
|
||||
|
||||
/** @var object the lesson settings object. */
|
||||
protected $lesson;
|
||||
|
||||
/** @var context the lesson context. */
|
||||
protected $context;
|
||||
|
||||
/** @var bool editing group override (true) or user override (false). */
|
||||
protected $groupmode;
|
||||
|
||||
/** @var int groupid, if provided. */
|
||||
protected $groupid;
|
||||
|
||||
/** @var int userid, if provided. */
|
||||
protected $userid;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param moodle_url $submiturl the form action URL.
|
||||
* @param object $cm course module object.
|
||||
* @param object $lesson the lesson settings object.
|
||||
* @param object $context the lesson context.
|
||||
* @param bool $groupmode editing group override (true) or user override (false).
|
||||
* @param object $override the override being edited, if it already exists.
|
||||
*/
|
||||
public function __construct($submiturl, $cm, $lesson, $context, $groupmode, $override) {
|
||||
|
||||
$this->cm = $cm;
|
||||
$this->lesson = $lesson;
|
||||
$this->context = $context;
|
||||
$this->groupmode = $groupmode;
|
||||
$this->groupid = empty($override->groupid) ? 0 : $override->groupid;
|
||||
$this->userid = empty($override->userid) ? 0 : $override->userid;
|
||||
|
||||
parent::__construct($submiturl, null, 'post');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Define this form - called by the parent constructor
|
||||
*/
|
||||
protected function definition() {
|
||||
global $CFG, $DB;
|
||||
|
||||
$cm = $this->cm;
|
||||
$mform = $this->_form;
|
||||
|
||||
$mform->addElement('header', 'override', get_string('override', 'lesson'));
|
||||
|
||||
if ($this->groupmode) {
|
||||
// Group override.
|
||||
if ($this->groupid) {
|
||||
// There is already a groupid, so freeze the selector.
|
||||
$groupchoices = array();
|
||||
$groupchoices[$this->groupid] = groups_get_group_name($this->groupid);
|
||||
$mform->addElement('select', 'groupid',
|
||||
get_string('overridegroup', 'lesson'), $groupchoices);
|
||||
$mform->freeze('groupid');
|
||||
} else {
|
||||
// Prepare the list of groups.
|
||||
$groups = groups_get_all_groups($cm->course);
|
||||
if (empty($groups)) {
|
||||
// Generate an error.
|
||||
$link = new moodle_url('/mod/lesson/overrides.php', array('cmid' => $cm->id));
|
||||
print_error('groupsnone', 'lesson', $link);
|
||||
}
|
||||
|
||||
$groupchoices = array();
|
||||
foreach ($groups as $group) {
|
||||
$groupchoices[$group->id] = $group->name;
|
||||
}
|
||||
unset($groups);
|
||||
|
||||
if (count($groupchoices) == 0) {
|
||||
$groupchoices[0] = get_string('none');
|
||||
}
|
||||
|
||||
$mform->addElement('select', 'groupid',
|
||||
get_string('overridegroup', 'lesson'), $groupchoices);
|
||||
$mform->addRule('groupid', get_string('required'), 'required', null, 'client');
|
||||
}
|
||||
} else {
|
||||
// User override.
|
||||
if ($this->userid) {
|
||||
// There is already a userid, so freeze the selector.
|
||||
$user = $DB->get_record('user', array('id' => $this->userid));
|
||||
$userchoices = array();
|
||||
$userchoices[$this->userid] = fullname($user);
|
||||
$mform->addElement('select', 'userid',
|
||||
get_string('overrideuser', 'lesson'), $userchoices);
|
||||
$mform->freeze('userid');
|
||||
} else {
|
||||
// Prepare the list of users.
|
||||
$users = array();
|
||||
list($sort, $sortparams) = users_order_by_sql('u');
|
||||
if (!empty($sortparams)) {
|
||||
throw new coding_exception('users_order_by_sql returned some query parameters. ' .
|
||||
'This is unexpected, and a problem because there is no way to pass these ' .
|
||||
'parameters to get_users_by_capability. See MDL-34657.');
|
||||
}
|
||||
$users = get_enrolled_users($this->context, '', 0,
|
||||
'u.id, u.email, ' . get_all_user_name_fields(true, 'u'),
|
||||
$sort);
|
||||
|
||||
// Filter users based on any fixed restrictions (groups, profile).
|
||||
$info = new \core_availability\info_module($cm);
|
||||
$users = $info->filter_user_list($users);
|
||||
|
||||
if (empty($users)) {
|
||||
// Generate an error.
|
||||
$link = new moodle_url('/mod/lesson/overrides.php', array('cmid' => $cm->id));
|
||||
print_error('usersnone', 'lesson', $link);
|
||||
}
|
||||
|
||||
$userchoices = array();
|
||||
$canviewemail = in_array('email', get_extra_user_fields($this->context));
|
||||
foreach ($users as $id => $user) {
|
||||
if (empty($invalidusers[$id]) || (!empty($override) &&
|
||||
$id == $override->userid)) {
|
||||
if ($canviewemail) {
|
||||
$userchoices[$id] = fullname($user) . ', ' . $user->email;
|
||||
} else {
|
||||
$userchoices[$id] = fullname($user);
|
||||
}
|
||||
}
|
||||
}
|
||||
unset($users);
|
||||
|
||||
if (count($userchoices) == 0) {
|
||||
$userchoices[0] = get_string('none');
|
||||
}
|
||||
$mform->addElement('searchableselector', 'userid',
|
||||
get_string('overrideuser', 'lesson'), $userchoices);
|
||||
$mform->addRule('userid', get_string('required'), 'required', null, 'client');
|
||||
}
|
||||
}
|
||||
|
||||
// Password.
|
||||
// This field has to be above the date and timelimit fields,
|
||||
// otherwise browsers will clear it when those fields are changed.
|
||||
$mform->addElement('passwordunmask', 'password', get_string('usepassword', 'lesson'));
|
||||
$mform->setType('password', PARAM_TEXT);
|
||||
$mform->addHelpButton('password', 'usepassword', 'lesson');
|
||||
$mform->setDefault('password', $this->lesson->password);;
|
||||
|
||||
// Open and close dates.
|
||||
$mform->addElement('date_time_selector', 'available', get_string('available', 'lesson'), array('optional' => true));
|
||||
$mform->setDefault('available', $this->lesson->available);
|
||||
|
||||
$mform->addElement('date_time_selector', 'deadline', get_string('deadline', 'lesson'), array('optional' => true));
|
||||
$mform->setDefault('deadline', $this->lesson->deadline);
|
||||
|
||||
// Lesson time limit.
|
||||
$mform->addElement('duration', 'timelimit',
|
||||
get_string('timelimit', 'lesson'), array('optional' => true));
|
||||
if ($this->lesson->timelimit != 0) {
|
||||
$mform->setDefault('timelimit', 0);
|
||||
} else {
|
||||
$mform->setDefault('timelimit', $this->lesson->timelimit);
|
||||
}
|
||||
|
||||
// Try a question again.
|
||||
$mform->addElement('selectyesno', 'review', get_string('displayreview', 'lesson'));
|
||||
$mform->addHelpButton('review', 'displayreview', 'lesson');
|
||||
$mform->setDefault('review', $this->lesson->review);
|
||||
|
||||
// Number of attempts.
|
||||
$numbers = array();
|
||||
for ($i = 10; $i > 0; $i--) {
|
||||
$numbers[$i] = $i;
|
||||
}
|
||||
$mform->addElement('select', 'maxattempts', get_string('maximumnumberofattempts', 'lesson'), $numbers);
|
||||
$mform->addHelpButton('maxattempts', 'maximumnumberofattempts', 'lesson');
|
||||
$mform->setDefault('maxattempts', $this->lesson->maxattempts);
|
||||
|
||||
// Retake allowed.
|
||||
$mform->addElement('selectyesno', 'retake', get_string('retakesallowed', 'lesson'));
|
||||
$mform->addHelpButton('retake', 'retakesallowed', 'lesson');
|
||||
$mform->setDefault('retake', $this->lesson->retake);
|
||||
|
||||
// Submit buttons.
|
||||
$mform->addElement('submit', 'resetbutton',
|
||||
get_string('reverttodefaults', 'lesson'));
|
||||
|
||||
$buttonarray = array();
|
||||
$buttonarray[] = $mform->createElement('submit', 'submitbutton',
|
||||
get_string('save', 'lesson'));
|
||||
$buttonarray[] = $mform->createElement('submit', 'againbutton',
|
||||
get_string('saveoverrideandstay', 'lesson'));
|
||||
$buttonarray[] = $mform->createElement('cancel');
|
||||
|
||||
$mform->addGroup($buttonarray, 'buttonbar', '', array(' '), false);
|
||||
$mform->closeHeaderBefore('buttonbar');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the submitted form data.
|
||||
*
|
||||
* @param array $data array of ("fieldname"=>value) of submitted data
|
||||
* @param array $files array of uploaded files "element_name"=>tmp_file_path
|
||||
* @return array of "element_name"=>"error_description" if there are errors
|
||||
*/
|
||||
public function validation($data, $files) {
|
||||
global $COURSE, $DB;
|
||||
$errors = parent::validation($data, $files);
|
||||
|
||||
$mform =& $this->_form;
|
||||
$lesson = $this->lesson;
|
||||
|
||||
if ($mform->elementExists('userid')) {
|
||||
if (empty($data['userid'])) {
|
||||
$errors['userid'] = get_string('required');
|
||||
}
|
||||
}
|
||||
|
||||
if ($mform->elementExists('groupid')) {
|
||||
if (empty($data['groupid'])) {
|
||||
$errors['groupid'] = get_string('required');
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that the dates make sense.
|
||||
if (!empty($data['available']) && !empty($data['deadline'])) {
|
||||
if ($data['deadline'] < $data['available'] ) {
|
||||
$errors['deadline'] = get_string('closebeforeopen', 'lesson');
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that at least one lesson setting was changed.
|
||||
$changed = false;
|
||||
$keys = array('available', 'deadline', 'review', 'timelimit', 'maxattempts', 'retake', 'password');
|
||||
foreach ($keys as $key) {
|
||||
if ($data[$key] != $lesson->{$key}) {
|
||||
$changed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$changed) {
|
||||
$errors['available'] = get_string('nooverridedata', 'lesson');
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* This page handles deleting lesson overrides
|
||||
*
|
||||
* @package mod_lesson
|
||||
* @copyright 2015 Jean-Michel vedrine
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
|
||||
require_once(dirname(__FILE__) . '/../../config.php');
|
||||
require_once($CFG->dirroot.'/mod/lesson/lib.php');
|
||||
require_once($CFG->dirroot.'/mod/lesson/locallib.php');
|
||||
require_once($CFG->dirroot.'/mod/lesson/override_form.php');
|
||||
|
||||
$overrideid = required_param('id', PARAM_INT);
|
||||
$confirm = optional_param('confirm', false, PARAM_BOOL);
|
||||
|
||||
if (! $override = $DB->get_record('lesson_overrides', array('id' => $overrideid))) {
|
||||
print_error('invalidoverrideid', 'lesson');
|
||||
}
|
||||
|
||||
$lesson = new lesson($DB->get_record('lesson', array('id' => $override->lessonid), '*', MUST_EXIST));
|
||||
|
||||
if (! $cm = get_coursemodule_from_instance("lesson", $lesson->id, $lesson->course)) {
|
||||
print_error('invalidcoursemodule');
|
||||
}
|
||||
$course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST);
|
||||
|
||||
$context = context_module::instance($cm->id);
|
||||
|
||||
require_login($course, false, $cm);
|
||||
|
||||
// Check the user has the required capabilities to modify an override.
|
||||
require_capability('mod/lesson:manageoverrides', $context);
|
||||
|
||||
$url = new moodle_url('/mod/lesson/overridedelete.php', array('id' => $override->id));
|
||||
$confirmurl = new moodle_url($url, array('id' => $override->id, 'confirm' => 1));
|
||||
$cancelurl = new moodle_url('/mod/lesson/overrides.php', array('cmid' => $cm->id));
|
||||
|
||||
if (!empty($override->userid)) {
|
||||
$cancelurl->param('mode', 'user');
|
||||
}
|
||||
|
||||
// If confirm is set (PARAM_BOOL) then we have confirmation of intention to delete.
|
||||
if ($confirm) {
|
||||
require_sesskey();
|
||||
|
||||
$lesson->delete_override($override->id);
|
||||
|
||||
redirect($cancelurl);
|
||||
}
|
||||
|
||||
// Prepare the page to show the confirmation form.
|
||||
$stroverride = get_string('override', 'lesson');
|
||||
$title = get_string('deletecheck', null, $stroverride);
|
||||
|
||||
$PAGE->set_url($url);
|
||||
$PAGE->set_pagelayout('admin');
|
||||
$PAGE->navbar->add($title);
|
||||
$PAGE->set_title($title);
|
||||
$PAGE->set_heading($course->fullname);
|
||||
|
||||
echo $OUTPUT->header();
|
||||
echo $OUTPUT->heading(format_string($lesson->name, true, array('context' => $context)));
|
||||
|
||||
if ($override->groupid) {
|
||||
$group = $DB->get_record('groups', array('id' => $override->groupid), 'id, name');
|
||||
$confirmstr = get_string("overridedeletegroupsure", "lesson", $group->name);
|
||||
} else {
|
||||
$namefields = get_all_user_name_fields(true);
|
||||
$user = $DB->get_record('user', array('id' => $override->userid),
|
||||
'id, ' . $namefields);
|
||||
$confirmstr = get_string("overridedeleteusersure", "lesson", fullname($user));
|
||||
}
|
||||
|
||||
echo $OUTPUT->confirm($confirmstr, $confirmurl, $cancelurl);
|
||||
|
||||
echo $OUTPUT->footer();
|
||||
@@ -0,0 +1,224 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* This page handles editing and creation of lesson overrides
|
||||
*
|
||||
* @package mod_lesson
|
||||
* @copyright 2015 Jean-Michel Vedrine
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
|
||||
require_once(dirname(__FILE__) . '/../../config.php');
|
||||
require_once($CFG->dirroot.'/mod/lesson/lib.php');
|
||||
require_once($CFG->dirroot.'/mod/lesson/locallib.php');
|
||||
require_once($CFG->dirroot.'/mod/lesson/override_form.php');
|
||||
|
||||
|
||||
$cmid = optional_param('cmid', 0, PARAM_INT);
|
||||
$overrideid = optional_param('id', 0, PARAM_INT);
|
||||
$action = optional_param('action', null, PARAM_ALPHA);
|
||||
$reset = optional_param('reset', false, PARAM_BOOL);
|
||||
|
||||
$override = null;
|
||||
if ($overrideid) {
|
||||
|
||||
if (! $override = $DB->get_record('lesson_overrides', array('id' => $overrideid))) {
|
||||
print_error('invalidoverrideid', 'lesson');
|
||||
}
|
||||
|
||||
$lesson = new lesson($DB->get_record('lesson', array('id' => $override->lessonid), '*', MUST_EXIST));
|
||||
|
||||
list($course, $cm) = get_course_and_cm_from_instance($lesson, 'lesson');
|
||||
|
||||
} else if ($cmid) {
|
||||
list($course, $cm) = get_course_and_cm_from_cmid($cmid, 'lesson');
|
||||
$lesson = new lesson($DB->get_record('lesson', array('id' => $cm->instance), '*', MUST_EXIST));
|
||||
|
||||
} else {
|
||||
print_error('invalidcoursemodule');
|
||||
}
|
||||
$course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST);
|
||||
|
||||
$url = new moodle_url('/mod/lesson/overrideedit.php');
|
||||
if ($action) {
|
||||
$url->param('action', $action);
|
||||
}
|
||||
if ($overrideid) {
|
||||
$url->param('id', $overrideid);
|
||||
} else {
|
||||
$url->param('cmid', $cmid);
|
||||
}
|
||||
|
||||
$PAGE->set_url($url);
|
||||
|
||||
require_login($course, false, $cm);
|
||||
|
||||
$context = context_module::instance($cm->id);
|
||||
|
||||
// Add or edit an override.
|
||||
require_capability('mod/lesson:manageoverrides', $context);
|
||||
|
||||
if ($overrideid) {
|
||||
// Editing an override.
|
||||
$data = clone $override;
|
||||
} else {
|
||||
// Creating a new override.
|
||||
$data = new stdClass();
|
||||
}
|
||||
|
||||
// Merge lesson defaults with data.
|
||||
$keys = array('available', 'deadline', 'review', 'timelimit', 'maxattempts', 'retake', 'password');
|
||||
foreach ($keys as $key) {
|
||||
if (!isset($data->{$key}) || $reset) {
|
||||
$data->{$key} = $lesson->{$key};
|
||||
}
|
||||
}
|
||||
|
||||
// If we are duplicating an override, then clear the user/group and override id
|
||||
// since they will change.
|
||||
if ($action === 'duplicate') {
|
||||
$override->id = null;
|
||||
$override->userid = null;
|
||||
$override->groupid = null;
|
||||
}
|
||||
|
||||
// True if group-based override.
|
||||
$groupmode = !empty($data->groupid) || ($action === 'addgroup' && empty($overrideid));
|
||||
|
||||
$overridelisturl = new moodle_url('/mod/lesson/overrides.php', array('cmid' => $cm->id));
|
||||
if (!$groupmode) {
|
||||
$overridelisturl->param('mode', 'user');
|
||||
}
|
||||
|
||||
// Setup the form.
|
||||
$mform = new lesson_override_form($url, $cm, $lesson, $context, $groupmode, $override);
|
||||
$mform->set_data($data);
|
||||
|
||||
if ($mform->is_cancelled()) {
|
||||
redirect($overridelisturl);
|
||||
|
||||
} else if (optional_param('resetbutton', 0, PARAM_ALPHA)) {
|
||||
$url->param('reset', true);
|
||||
redirect($url);
|
||||
|
||||
} else if ($fromform = $mform->get_data()) {
|
||||
// Process the data.
|
||||
$fromform->lessonid = $lesson->id;
|
||||
|
||||
// Replace unchanged values with null.
|
||||
foreach ($keys as $key) {
|
||||
if ($fromform->{$key} == $lesson->{$key}) {
|
||||
$fromform->{$key} = null;
|
||||
}
|
||||
}
|
||||
|
||||
// See if we are replacing an existing override.
|
||||
$userorgroupchanged = false;
|
||||
if (empty($override->id)) {
|
||||
$userorgroupchanged = true;
|
||||
} else if (!empty($fromform->userid)) {
|
||||
$userorgroupchanged = $fromform->userid !== $override->userid;
|
||||
} else {
|
||||
$userorgroupchanged = $fromform->groupid !== $override->groupid;
|
||||
}
|
||||
|
||||
if ($userorgroupchanged) {
|
||||
$conditions = array(
|
||||
'lessonid' => $lesson->id,
|
||||
'userid' => empty($fromform->userid) ? null : $fromform->userid,
|
||||
'groupid' => empty($fromform->groupid) ? null : $fromform->groupid);
|
||||
if ($oldoverride = $DB->get_record('lesson_overrides', $conditions)) {
|
||||
// There is an old override, so we merge any new settings on top of
|
||||
// the older override.
|
||||
foreach ($keys as $key) {
|
||||
if (is_null($fromform->{$key})) {
|
||||
$fromform->{$key} = $oldoverride->{$key};
|
||||
}
|
||||
}
|
||||
|
||||
$lesson->delete_override($oldoverride->id);
|
||||
}
|
||||
}
|
||||
|
||||
// Set the common parameters for one of the events we may be triggering.
|
||||
$params = array(
|
||||
'context' => $context,
|
||||
'other' => array(
|
||||
'lessonid' => $lesson->id
|
||||
)
|
||||
);
|
||||
if (!empty($override->id)) {
|
||||
$fromform->id = $override->id;
|
||||
$DB->update_record('lesson_overrides', $fromform);
|
||||
|
||||
// Determine which override updated event to fire.
|
||||
$params['objectid'] = $override->id;
|
||||
if (!$groupmode) {
|
||||
$params['relateduserid'] = $fromform->userid;
|
||||
$event = \mod_lesson\event\user_override_updated::create($params);
|
||||
} else {
|
||||
$params['other']['groupid'] = $fromform->groupid;
|
||||
$event = \mod_lesson\event\group_override_updated::create($params);
|
||||
}
|
||||
|
||||
// Trigger the override updated event.
|
||||
$event->trigger();
|
||||
} else {
|
||||
unset($fromform->id);
|
||||
$fromform->id = $DB->insert_record('lesson_overrides', $fromform);
|
||||
|
||||
// Determine which override created event to fire.
|
||||
$params['objectid'] = $fromform->id;
|
||||
if (!$groupmode) {
|
||||
$params['relateduserid'] = $fromform->userid;
|
||||
$event = \mod_lesson\event\user_override_created::create($params);
|
||||
} else {
|
||||
$params['other']['groupid'] = $fromform->groupid;
|
||||
$event = \mod_lesson\event\group_override_created::create($params);
|
||||
}
|
||||
|
||||
// Trigger the override created event.
|
||||
$event->trigger();
|
||||
}
|
||||
|
||||
lesson_update_events($lesson, $fromform);
|
||||
|
||||
if (!empty($fromform->submitbutton)) {
|
||||
redirect($overridelisturl);
|
||||
}
|
||||
|
||||
// The user pressed the 'again' button, so redirect back to this page.
|
||||
$url->remove_params('cmid');
|
||||
$url->param('action', 'duplicate');
|
||||
$url->param('id', $fromform->id);
|
||||
redirect($url);
|
||||
|
||||
}
|
||||
|
||||
// Print the form.
|
||||
$pagetitle = get_string('editoverride', 'lesson');
|
||||
$PAGE->navbar->add($pagetitle);
|
||||
$PAGE->set_pagelayout('admin');
|
||||
$PAGE->set_title($pagetitle);
|
||||
$PAGE->set_heading($course->fullname);
|
||||
echo $OUTPUT->header();
|
||||
echo $OUTPUT->heading(format_string($lesson->name, true, array('context' => $context)));
|
||||
|
||||
$mform->display();
|
||||
|
||||
echo $OUTPUT->footer();
|
||||
@@ -0,0 +1,295 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* This page handles listing of lesson overrides
|
||||
*
|
||||
* @package mod_lesson
|
||||
* @copyright 2015 Jean-Michel Vedrine
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
|
||||
require_once(dirname(__FILE__) . '/../../config.php');
|
||||
require_once($CFG->dirroot.'/mod/lesson/lib.php');
|
||||
require_once($CFG->dirroot.'/mod/lesson/locallib.php');
|
||||
require_once($CFG->dirroot.'/mod/lesson/override_form.php');
|
||||
|
||||
|
||||
$cmid = required_param('cmid', PARAM_INT);
|
||||
$mode = optional_param('mode', '', PARAM_ALPHA); // One of 'user' or 'group', default is 'group'.
|
||||
|
||||
list($course, $cm) = get_course_and_cm_from_cmid($cmid, 'lesson');
|
||||
$lesson = $DB->get_record('lesson', array('id' => $cm->instance), '*', MUST_EXIST);
|
||||
|
||||
// Get the course groups.
|
||||
$groups = groups_get_all_groups($cm->course);
|
||||
if ($groups === false) {
|
||||
$groups = array();
|
||||
}
|
||||
|
||||
// Default mode is "group", unless there are no groups.
|
||||
if ($mode != "user" and $mode != "group") {
|
||||
if (!empty($groups)) {
|
||||
$mode = "group";
|
||||
} else {
|
||||
$mode = "user";
|
||||
}
|
||||
}
|
||||
$groupmode = ($mode == "group");
|
||||
|
||||
$url = new moodle_url('/mod/lesson/overrides.php', array('cmid' => $cm->id, 'mode' => $mode));
|
||||
|
||||
$PAGE->set_url($url);
|
||||
|
||||
require_login($course, false, $cm);
|
||||
|
||||
$context = context_module::instance($cm->id);
|
||||
|
||||
// Check the user has the required capabilities to list overrides.
|
||||
require_capability('mod/lesson:manageoverrides', $context);
|
||||
|
||||
// Display a list of overrides.
|
||||
$PAGE->set_pagelayout('admin');
|
||||
$PAGE->set_title(get_string('overrides', 'lesson'));
|
||||
$PAGE->set_heading($course->fullname);
|
||||
echo $OUTPUT->header();
|
||||
echo $OUTPUT->heading(format_string($lesson->name, true, array('context' => $context)));
|
||||
|
||||
// Delete orphaned group overrides.
|
||||
$sql = 'SELECT o.id
|
||||
FROM {lesson_overrides} o LEFT JOIN {groups} g
|
||||
ON o.groupid = g.id
|
||||
WHERE o.groupid IS NOT NULL
|
||||
AND g.id IS NULL
|
||||
AND o.lessonid = ?';
|
||||
$params = array($lesson->id);
|
||||
$orphaned = $DB->get_records_sql($sql, $params);
|
||||
if (!empty($orphaned)) {
|
||||
$DB->delete_records_list('lesson_overrides', 'id', array_keys($orphaned));
|
||||
}
|
||||
|
||||
// Fetch all overrides.
|
||||
if ($groupmode) {
|
||||
$colname = get_string('group');
|
||||
$sql = 'SELECT o.*, g.name
|
||||
FROM {lesson_overrides} o
|
||||
JOIN {groups} g ON o.groupid = g.id
|
||||
WHERE o.lessonid = :lessonid
|
||||
ORDER BY g.name';
|
||||
$params = array('lessonid' => $lesson->id);
|
||||
} else {
|
||||
$colname = get_string('user');
|
||||
list($sort, $params) = users_order_by_sql('u');
|
||||
$sql = 'SELECT o.*, ' . get_all_user_name_fields(true, 'u') . '
|
||||
FROM {lesson_overrides} o
|
||||
JOIN {user} u ON o.userid = u.id
|
||||
WHERE o.lessonid = :lessonid
|
||||
ORDER BY ' . $sort;
|
||||
$params['lessonid'] = $lesson->id;
|
||||
}
|
||||
|
||||
$overrides = $DB->get_records_sql($sql, $params);
|
||||
|
||||
// Initialise table.
|
||||
$table = new html_table();
|
||||
$table->headspan = array(1, 2, 1);
|
||||
$table->colclasses = array('colname', 'colsetting', 'colvalue', 'colaction');
|
||||
$table->head = array(
|
||||
$colname,
|
||||
get_string('overrides', 'lesson'),
|
||||
get_string('action'),
|
||||
);
|
||||
|
||||
$userurl = new moodle_url('/user/view.php', array());
|
||||
$groupurl = new moodle_url('/group/overview.php', array('id' => $cm->course));
|
||||
|
||||
$overridedeleteurl = new moodle_url('/mod/lesson/overridedelete.php');
|
||||
$overrideediturl = new moodle_url('/mod/lesson/overrideedit.php');
|
||||
|
||||
$hasinactive = false; // Whether there are any inactive overrides.
|
||||
|
||||
foreach ($overrides as $override) {
|
||||
|
||||
$fields = array();
|
||||
$values = array();
|
||||
$active = true;
|
||||
|
||||
// Check for inactive overrides.
|
||||
if (!$groupmode) {
|
||||
if (!is_enrolled($context, $override->userid)) {
|
||||
// User not enrolled.
|
||||
$active = false;
|
||||
} else if (!\core_availability\info_module::is_user_visible($cm, $override->userid)) {
|
||||
// User cannot access the module.
|
||||
$active = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Format available.
|
||||
if (isset($override->available)) {
|
||||
$fields[] = get_string('lessonopens', 'lesson');
|
||||
$values[] = $override->available > 0 ?
|
||||
userdate($override->available) : get_string('noopen', 'lesson');
|
||||
}
|
||||
|
||||
// Format deadline.
|
||||
if (isset($override->deadline)) {
|
||||
$fields[] = get_string('lessoncloses', 'lesson');
|
||||
$values[] = $override->deadline > 0 ?
|
||||
userdate($override->deadline) : get_string('noclose', 'lesson');
|
||||
}
|
||||
|
||||
// Format timelimit.
|
||||
if (isset($override->timelimit)) {
|
||||
$fields[] = get_string('timelimit', 'lesson');
|
||||
$values[] = $override->timelimit > 0 ?
|
||||
format_time($override->timelimit) : get_string('none', 'lesson');
|
||||
}
|
||||
|
||||
// Format option to try a question again.
|
||||
if (isset($override->review)) {
|
||||
$fields[] = get_string('displayreview', 'lesson');
|
||||
$values[] = $override->review ?
|
||||
get_string('yes') : get_string('no');
|
||||
}
|
||||
|
||||
// Format number of attempts.
|
||||
if (isset($override->maxattempts)) {
|
||||
$fields[] = get_string('maximumnumberofattempts', 'lesson');
|
||||
$values[] = $override->maxattempts > 0 ?
|
||||
$override->maxattempts : get_string('unlimited');
|
||||
}
|
||||
|
||||
// Format retake allowed.
|
||||
if (isset($override->retake)) {
|
||||
$fields[] = get_string('retakesallowed', 'lesson');
|
||||
$values[] = $override->retake ?
|
||||
get_string('yes') : get_string('no');
|
||||
}
|
||||
|
||||
// Format password.
|
||||
if (isset($override->password)) {
|
||||
$fields[] = get_string('usepassword', 'lesson');
|
||||
$values[] = $override->password !== '' ?
|
||||
get_string('enabled', 'lesson') : get_string('none', 'lesson');
|
||||
}
|
||||
|
||||
// Icons.
|
||||
$iconstr = '';
|
||||
|
||||
if ($active) {
|
||||
// Edit.
|
||||
$editurlstr = $overrideediturl->out(true, array('id' => $override->id));
|
||||
$iconstr = '<a title="' . get_string('edit') . '" href="'. $editurlstr . '">' .
|
||||
'<img src="' . $OUTPUT->pix_url('t/edit') . '" class="iconsmall" alt="' .
|
||||
get_string('edit') . '" /></a> ';
|
||||
// Duplicate.
|
||||
$copyurlstr = $overrideediturl->out(true,
|
||||
array('id' => $override->id, 'action' => 'duplicate'));
|
||||
$iconstr .= '<a title="' . get_string('copy') . '" href="' . $copyurlstr . '">' .
|
||||
'<img src="' . $OUTPUT->pix_url('t/copy') . '" class="iconsmall" alt="' .
|
||||
get_string('copy') . '" /></a> ';
|
||||
}
|
||||
// Delete.
|
||||
$deleteurlstr = $overridedeleteurl->out(true,
|
||||
array('id' => $override->id, 'sesskey' => sesskey()));
|
||||
$iconstr .= '<a title="' . get_string('delete') . '" href="' . $deleteurlstr . '">' .
|
||||
'<img src="' . $OUTPUT->pix_url('t/delete') . '" class="iconsmall" alt="' .
|
||||
get_string('delete') . '" /></a> ';
|
||||
|
||||
if ($groupmode) {
|
||||
$usergroupstr = '<a href="' . $groupurl->out(true,
|
||||
array('group' => $override->groupid)) . '" >' . $override->name . '</a>';
|
||||
} else {
|
||||
$usergroupstr = '<a href="' . $userurl->out(true,
|
||||
array('id' => $override->userid)) . '" >' . fullname($override) . '</a>';
|
||||
}
|
||||
|
||||
$class = '';
|
||||
if (!$active) {
|
||||
$class = "dimmed_text";
|
||||
$usergroupstr .= '*';
|
||||
$hasinactive = true;
|
||||
}
|
||||
|
||||
$usergroupcell = new html_table_cell();
|
||||
$usergroupcell->rowspan = count($fields);
|
||||
$usergroupcell->text = $usergroupstr;
|
||||
$actioncell = new html_table_cell();
|
||||
$actioncell->rowspan = count($fields);
|
||||
$actioncell->text = $iconstr;
|
||||
|
||||
for ($i = 0; $i < count($fields); ++$i) {
|
||||
$row = new html_table_row();
|
||||
$row->attributes['class'] = $class;
|
||||
if ($i == 0) {
|
||||
$row->cells[] = $usergroupcell;
|
||||
}
|
||||
$cell1 = new html_table_cell();
|
||||
$cell1->text = $fields[$i];
|
||||
$row->cells[] = $cell1;
|
||||
$cell2 = new html_table_cell();
|
||||
$cell2->text = $values[$i];
|
||||
$row->cells[] = $cell2;
|
||||
if ($i == 0) {
|
||||
$row->cells[] = $actioncell;
|
||||
}
|
||||
$table->data[] = $row;
|
||||
}
|
||||
}
|
||||
|
||||
// Output the table and button.
|
||||
echo html_writer::start_tag('div', array('id' => 'lessonoverrides'));
|
||||
if (count($table->data)) {
|
||||
echo html_writer::table($table);
|
||||
}
|
||||
if ($hasinactive) {
|
||||
echo $OUTPUT->notification(get_string('inactiveoverridehelp', 'lesson'), 'dimmed_text');
|
||||
}
|
||||
|
||||
echo html_writer::start_tag('div', array('class' => 'buttons'));
|
||||
$options = array();
|
||||
if ($groupmode) {
|
||||
if (empty($groups)) {
|
||||
// There are no groups.
|
||||
echo $OUTPUT->notification(get_string('groupsnone', 'lesson'), 'error');
|
||||
$options['disabled'] = true;
|
||||
}
|
||||
echo $OUTPUT->single_button($overrideediturl->out(true,
|
||||
array('action' => 'addgroup', 'cmid' => $cm->id)),
|
||||
get_string('addnewgroupoverride', 'lesson'), 'post', $options);
|
||||
} else {
|
||||
$users = array();
|
||||
// See if there are any users in the lesson.
|
||||
$users = get_enrolled_users($context);
|
||||
$info = new \core_availability\info_module($cm);
|
||||
$users = $info->filter_user_list($users);
|
||||
|
||||
if (empty($users)) {
|
||||
// There are no users.
|
||||
echo $OUTPUT->notification(get_string('usersnone', 'lesson'), 'error');
|
||||
$options['disabled'] = true;
|
||||
}
|
||||
echo $OUTPUT->single_button($overrideediturl->out(true,
|
||||
array('action' => 'adduser', 'cmid' => $cm->id)),
|
||||
get_string('addnewuseroverride', 'lesson'), 'get', $options);
|
||||
}
|
||||
echo html_writer::end_tag('div');
|
||||
echo html_writer::end_tag('div');
|
||||
|
||||
// Finish the page.
|
||||
echo $OUTPUT->footer();
|
||||
@@ -410,6 +410,11 @@ if ($action === 'delete') {
|
||||
$userid = optional_param('userid', null, PARAM_INT); // if empty, then will display the general detailed view
|
||||
$try = optional_param('try', null, PARAM_INT);
|
||||
|
||||
if (!empty($userid)) {
|
||||
// Apply overrides.
|
||||
$lesson->update_effective_access($userid);
|
||||
}
|
||||
|
||||
$lessonpages = $lesson->load_all_pages();
|
||||
foreach ($lessonpages as $lessonpage) {
|
||||
if ($lessonpage->prevpageid == 0) {
|
||||
|
||||
@@ -502,4 +502,213 @@ class mod_lesson_events_testcase extends advanced_testcase {
|
||||
$this->assertEventContextNotUsed($event);
|
||||
$this->assertDebuggingNotCalled();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the user override created event.
|
||||
*
|
||||
* There is no external API for creating a user override, so the unit test will simply
|
||||
* create and trigger the event and ensure the event data is returned as expected.
|
||||
*/
|
||||
public function test_user_override_created() {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$this->setAdminUser();
|
||||
$course = $this->getDataGenerator()->create_course();
|
||||
$lesson = $this->getDataGenerator()->create_module('lesson', array('course' => $course->id));
|
||||
|
||||
$params = array(
|
||||
'objectid' => 1,
|
||||
'context' => context_module::instance($lesson->cmid),
|
||||
'other' => array(
|
||||
'lessonid' => $lesson->id
|
||||
)
|
||||
);
|
||||
$event = \mod_lesson\event\user_override_created::create($params);
|
||||
|
||||
// Trigger and capture the event.
|
||||
$sink = $this->redirectEvents();
|
||||
$event->trigger();
|
||||
$events = $sink->get_events();
|
||||
$event = reset($events);
|
||||
|
||||
// Check that the event data is valid.
|
||||
$this->assertInstanceOf('\mod_lesson\event\user_override_created', $event);
|
||||
$this->assertEquals(context_module::instance($lesson->cmid), $event->get_context());
|
||||
$this->assertEventContextNotUsed($event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the group override created event.
|
||||
*
|
||||
* There is no external API for creating a group override, so the unit test will simply
|
||||
* create and trigger the event and ensure the event data is returned as expected.
|
||||
*/
|
||||
public function test_group_override_created() {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$this->setAdminUser();
|
||||
$course = $this->getDataGenerator()->create_course();
|
||||
$lesson = $this->getDataGenerator()->create_module('lesson', array('course' => $course->id));
|
||||
|
||||
$params = array(
|
||||
'objectid' => 1,
|
||||
'context' => context_module::instance($lesson->cmid),
|
||||
'other' => array(
|
||||
'lessonid' => $lesson->id,
|
||||
'groupid' => 2
|
||||
)
|
||||
);
|
||||
$event = \mod_lesson\event\group_override_created::create($params);
|
||||
|
||||
// Trigger and capture the event.
|
||||
$sink = $this->redirectEvents();
|
||||
$event->trigger();
|
||||
$events = $sink->get_events();
|
||||
$event = reset($events);
|
||||
|
||||
// Check that the event data is valid.
|
||||
$this->assertInstanceOf('\mod_lesson\event\group_override_created', $event);
|
||||
$this->assertEquals(context_module::instance($lesson->cmid), $event->get_context());
|
||||
$this->assertEventContextNotUsed($event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the user override updated event.
|
||||
*
|
||||
* There is no external API for updating a user override, so the unit test will simply
|
||||
* create and trigger the event and ensure the event data is returned as expected.
|
||||
*/
|
||||
public function test_user_override_updated() {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$this->setAdminUser();
|
||||
$course = $this->getDataGenerator()->create_course();
|
||||
$lesson = $this->getDataGenerator()->create_module('lesson', array('course' => $course->id));
|
||||
|
||||
$params = array(
|
||||
'objectid' => 1,
|
||||
'relateduserid' => 2,
|
||||
'context' => context_module::instance($lesson->cmid),
|
||||
'other' => array(
|
||||
'lessonid' => $lesson->id
|
||||
)
|
||||
);
|
||||
$event = \mod_lesson\event\user_override_updated::create($params);
|
||||
|
||||
// Trigger and capture the event.
|
||||
$sink = $this->redirectEvents();
|
||||
$event->trigger();
|
||||
$events = $sink->get_events();
|
||||
$event = reset($events);
|
||||
|
||||
// Check that the event data is valid.
|
||||
$this->assertInstanceOf('\mod_lesson\event\user_override_updated', $event);
|
||||
$this->assertEquals(context_module::instance($lesson->cmid), $event->get_context());
|
||||
$expected = array($course->id, 'lesson', 'edit override', 'overrideedit.php?id=1', $lesson->id, $lesson->cmid);
|
||||
$this->assertEventLegacyLogData($expected, $event);
|
||||
$this->assertEventContextNotUsed($event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the group override updated event.
|
||||
*
|
||||
* There is no external API for updating a group override, so the unit test will simply
|
||||
* create and trigger the event and ensure the event data is returned as expected.
|
||||
*/
|
||||
public function test_group_override_updated() {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$this->setAdminUser();
|
||||
$course = $this->getDataGenerator()->create_course();
|
||||
$lesson = $this->getDataGenerator()->create_module('lesson', array('course' => $course->id));
|
||||
|
||||
$params = array(
|
||||
'objectid' => 1,
|
||||
'context' => context_module::instance($lesson->cmid),
|
||||
'other' => array(
|
||||
'lessonid' => $lesson->id,
|
||||
'groupid' => 2
|
||||
)
|
||||
);
|
||||
$event = \mod_lesson\event\group_override_updated::create($params);
|
||||
|
||||
// Trigger and capture the event.
|
||||
$sink = $this->redirectEvents();
|
||||
$event->trigger();
|
||||
$events = $sink->get_events();
|
||||
$event = reset($events);
|
||||
|
||||
// Check that the event data is valid.
|
||||
$this->assertInstanceOf('\mod_lesson\event\group_override_updated', $event);
|
||||
$this->assertEquals(context_module::instance($lesson->cmid), $event->get_context());
|
||||
$expected = array($course->id, 'lesson', 'edit override', 'overrideedit.php?id=1', $lesson->id, $lesson->cmid);
|
||||
$this->assertEventLegacyLogData($expected, $event);
|
||||
$this->assertEventContextNotUsed($event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the user override deleted event.
|
||||
*/
|
||||
public function test_user_override_deleted() {
|
||||
global $DB;
|
||||
|
||||
$this->resetAfterTest();
|
||||
|
||||
$this->setAdminUser();
|
||||
$course = $this->getDataGenerator()->create_course();
|
||||
$lesson = $this->getDataGenerator()->create_module('lesson', array('course' => $course->id));
|
||||
|
||||
// Create an override.
|
||||
$override = new stdClass();
|
||||
$override->lesson = $lesson->id;
|
||||
$override->userid = 2;
|
||||
$override->id = $DB->insert_record('lesson_overrides', $override);
|
||||
|
||||
// Trigger and capture the event.
|
||||
$sink = $this->redirectEvents();
|
||||
$lesson->delete_override($override->id);
|
||||
$events = $sink->get_events();
|
||||
$event = reset($events);
|
||||
|
||||
// Check that the event data is valid.
|
||||
$this->assertInstanceOf('\mod_lesson\event\user_override_deleted', $event);
|
||||
$this->assertEquals(context_module::instance($lesson->cmid), $event->get_context());
|
||||
$expected = array($course->id, 'lesson', 'delete override',
|
||||
'overrides.php?cmid=' . $lesson->cmid, $lesson->id, $lesson->cmid);
|
||||
$this->assertEventLegacyLogData($expected, $event);
|
||||
$this->assertEventContextNotUsed($event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the group override deleted event.
|
||||
*/
|
||||
public function test_group_override_deleted() {
|
||||
global $DB;
|
||||
|
||||
$this->resetAfterTest();
|
||||
|
||||
$this->setAdminUser();
|
||||
$course = $this->getDataGenerator()->create_course();
|
||||
$lesson = $this->getDataGenerator()->create_module('lesson', array('course' => $course->id));
|
||||
|
||||
// Create an override.
|
||||
$override = new stdClass();
|
||||
$override->lesson = $lesson->id;
|
||||
$override->groupid = 2;
|
||||
$override->id = $DB->insert_record('lesson_overrides', $override);
|
||||
|
||||
// Trigger and capture the event.
|
||||
$sink = $this->redirectEvents();
|
||||
$lesson->delete_override($override->id);
|
||||
$events = $sink->get_events();
|
||||
$event = reset($events);
|
||||
|
||||
// Check that the event data is valid.
|
||||
$this->assertInstanceOf('\mod_lesson\event\group_override_deleted', $event);
|
||||
$this->assertEquals(context_module::instance($lesson->cmid), $event->get_context());
|
||||
$expected = array($course->id, 'lesson', 'delete override',
|
||||
'overrides.php?cmid=' . $lesson->cmid, $lesson->id, $lesson->cmid);
|
||||
$this->assertEventLegacyLogData($expected, $event);
|
||||
$this->assertEventContextNotUsed($event);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2015032700; // The current module version (Date: YYYYMMDDXX)
|
||||
$plugin->version = 2015033100; // The current module version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2014110400; // Requires this Moodle version
|
||||
$plugin->component = 'mod_lesson'; // Full name of the plugin (used for diagnostics)
|
||||
$plugin->cron = 0;
|
||||
|
||||
+18
-1
@@ -45,6 +45,9 @@ if ($backtocourse) {
|
||||
redirect(new moodle_url('/course/view.php', array('id'=>$course->id)));
|
||||
}
|
||||
|
||||
// Apply overrides.
|
||||
$lesson->update_effective_access($USER->id);
|
||||
|
||||
// Mark as viewed
|
||||
$completion = new completion_info($course);
|
||||
$completion->set_module_viewed($cm);
|
||||
@@ -85,12 +88,26 @@ if (!$canmanage) {
|
||||
$correctpass = false;
|
||||
if (!empty($userpassword) && (($lesson->password == md5(trim($userpassword))) || ($lesson->password == trim($userpassword)))) {
|
||||
// with or without md5 for backward compatibility (MDL-11090)
|
||||
$correctpass = true;
|
||||
$USER->lessonloggedin[$lesson->id] = true;
|
||||
if ($lesson->highscores) {
|
||||
// Logged in - redirect so we go through all of these checks before starting the lesson.
|
||||
redirect("$CFG->wwwroot/mod/lesson/view.php?id=$cm->id");
|
||||
}
|
||||
} else {
|
||||
} else if (isset($lesson->extrapasswords)) {
|
||||
// Group overrides may have additional passwords.
|
||||
foreach ($lesson->extrapasswords as $password) {
|
||||
if (strcmp($password, md5(trim($userpassword))) === 0 || strcmp($password, trim($userpassword)) === 0) {
|
||||
$correctpass = true;
|
||||
$USER->lessonloggedin[$lesson->id] = true;
|
||||
if ($lesson->highscores) {
|
||||
// Logged in - redirect so we go through all of these checks before starting the lesson.
|
||||
redirect("$CFG->wwwroot/mod/lesson/view.php?id=$cm->id");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!$correctpass) {
|
||||
echo $lessonoutput->header($lesson, $cm, '', false, null, get_string('passwordprotectedlesson', 'lesson', format_string($lesson->name)));
|
||||
echo $lessonoutput->login_prompt($lesson, $userpassword !== '');
|
||||
echo $lessonoutput->footer();
|
||||
|
||||
Reference in New Issue
Block a user