Merge branch 'MDL-68586-format_topics_code_prechecks' of https://gitlab.com/drlikm/moodle

This commit is contained in:
Jun Pataleta
2020-07-22 23:26:24 +08:00
10 changed files with 205 additions and 157 deletions
@@ -15,7 +15,7 @@
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Specialised restore for format_topics
* Specialised restore for Topics course format.
*
* @package format_topics
* @category backup
@@ -26,9 +26,9 @@
defined('MOODLE_INTERNAL') || die();
/**
* Specialised restore for format_topics
* Specialised restore for Topics course format.
*
* Processes 'numsections' from the old backup files and hides sections that used to be "orphaned"
* Processes 'numsections' from the old backup files and hides sections that used to be "orphaned".
*
* @package format_topics
* @category backup
@@ -53,7 +53,7 @@ class restore_format_topics_plugin extends restore_format_plugin {
}
/**
* Creates a dummy path element in order to be able to execute code after restore
* Creates a dummy path element in order to be able to execute code after restore.
*
* @return restore_path_element[]
*/
@@ -76,16 +76,20 @@ class restore_format_topics_plugin extends restore_format_plugin {
}
/**
* Dummy process method
* Dummy process method.
*
* @return void
*/
public function process_dummy_course() {
}
/**
* Executed after course restore is complete
* Executed after course restore is complete.
*
* This method is only executed if course configuration was overridden
* This method is only executed if course configuration was overridden.
*
* @return void
*/
public function after_restore_course() {
global $DB;
@@ -13,29 +13,36 @@
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Privacy Subsystem implementation for format_topics.
* Privacy Subsystem implementation for Topics course format.
*
* @package format_topics
* @copyright 2018 Carlos Escobedo <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace format_topics\privacy;
defined('MOODLE_INTERNAL') || die();
use core_privacy\local\metadata\null_provider;
/**
* Privacy Subsystem for format_topics implementing null_provider.
* Privacy Subsystem for Topics course format implementing null_provider.
*
* @copyright 2018 Carlos Escobedo <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider implements \core_privacy\local\metadata\null_provider {
class provider implements null_provider {
/**
* Get the language string identifier with the component's language
* file to explain why this plugin stores no data.
*
* @return string
*/
public static function get_reason() : string {
public static function get_reason(): string {
return 'privacy:metadata';
}
}
+3 -3
View File
@@ -15,7 +15,7 @@
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Upgrade scripts for course format "Topics"
* Upgrade scripts for Topics course format.
*
* @package format_topics
* @copyright 2017 Marina Glancy
@@ -25,9 +25,9 @@
defined('MOODLE_INTERNAL') || die();
/**
* Upgrade script for format_topics
* Upgrade script for Topics course format.
*
* @param int $oldversion the version we are upgrading from
* @param int|float $oldversion the version we are upgrading from
* @return bool result
*/
function xmldb_format_topics_upgrade($oldversion) {
+20 -22
View File
@@ -1,11 +1,11 @@
// Javascript functions for Topics course format
// Javascript functions for Topics course format.
M.course = M.course || {};
M.course.format = M.course.format || {};
/**
* Get sections config for this format
* Get sections config for this format.
*
* The section structure is:
* <ul class="topics">
@@ -18,50 +18,48 @@ M.course.format = M.course.format || {};
*/
M.course.format.get_config = function() {
return {
container_node : 'ul',
container_class : 'topics',
section_node : 'li',
section_class : 'section'
container_node: 'ul',
container_class: 'topics',
section_node: 'li',
section_class: 'section'
};
}
};
/**
* Swap section
* Swap section.
*
* @param {YUI} Y YUI3 instance
* @param {string} node1 node to swap to
* @param {string} node2 node to swap with
* @return {NodeList} section list
*/
M.course.format.swap_sections = function(Y, node1, node2) {
var CSS = {
COURSECONTENT : 'course-content',
SECTIONADDMENUS : 'section_add_menus'
COURSECONTENT: 'course-content',
SECTIONADDMENUS: 'section_add_menus'
};
var sectionlist = Y.Node.all('.'+CSS.COURSECONTENT+' '+M.course.format.get_section_selector(Y));
var sectionlist = Y.Node.all('.' + CSS.COURSECONTENT + ' ' + M.course.format.get_section_selector(Y));
// Swap the non-ajax menus, noting these are not always present (depends on theme and user prefs).
if (sectionlist.item(node1).one('.'+CSS.SECTIONADDMENUS)) {
sectionlist.item(node1).one('.'+CSS.SECTIONADDMENUS).swap(sectionlist.item(node2).one('.'+CSS.SECTIONADDMENUS));
if (sectionlist.item(node1).one('.' + CSS.SECTIONADDMENUS)) {
sectionlist.item(node1).one('.' + CSS.SECTIONADDMENUS).swap(sectionlist.item(node2).one('.' + CSS.SECTIONADDMENUS));
}
}
};
/**
* Process sections after ajax response
* Process sections after ajax response.
*
* @param {YUI} Y YUI3 instance
* @param {NodeList} sectionlist of sections
* @param {array} response ajax response
* @param {string} sectionfrom first affected section
* @param {string} sectionto last affected section
* @return void
*/
M.course.format.process_sections = function(Y, sectionlist, response, sectionfrom, sectionto) {
var CSS = {
SECTIONNAME : 'sectionname'
SECTIONNAME: 'sectionname'
},
SELECTORS = {
SECTIONLEFTSIDE : '.left .section-handle .icon'
SECTIONLEFTSIDE: '.left .section-handle .icon'
};
if (response.action == 'move') {
@@ -78,15 +76,15 @@ M.course.format.process_sections = function(Y, sectionlist, response, sectionfro
for (var i = sectionfrom; i <= sectionto; i++) {
// Update section title.
var content = Y.Node.create('<span>' + response.sectiontitles[i] + '</span>');
sectionlist.item(i).all('.'+CSS.SECTIONNAME).setHTML(content);
sectionlist.item(i).all('.' + CSS.SECTIONNAME).setHTML(content);
// Update the drag handle.
ele = sectionlist.item(i).one(SELECTORS.SECTIONLEFTSIDE).ancestor('.section-handle');
str = ele.getAttribute('title');
stridx = str.lastIndexOf(' ');
newstr = str.substr(0, stridx +1) + i;
newstr = str.substr(0, stridx + 1) + i;
ele.setAttribute('title', newstr);
// Update the aria-label for the section.
sectionlist.item(i).setAttribute('aria-label', content.get('innerText').trim());
}
}
}
};
+5 -5
View File
@@ -15,7 +15,7 @@
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Topics course format. Display the whole course as "topics" made of modules.
* Topics course format. Display the whole course as "topics" made of modules.
*
* @package format_topics
* @copyright 2006 The Open University
@@ -28,20 +28,20 @@ defined('MOODLE_INTERNAL') || die();
require_once($CFG->libdir.'/filelib.php');
require_once($CFG->libdir.'/completionlib.php');
// Horrible backwards compatible parameter aliasing..
// Horrible backwards compatible parameter aliasing.
if ($topic = optional_param('topic', 0, PARAM_INT)) {
$url = $PAGE->url;
$url->param('section', $topic);
debugging('Outdated topic param passed to course/view.php', DEBUG_DEVELOPER);
redirect($url);
}
// End backwards-compatible aliasing..
// End backwards-compatible aliasing.
$context = context_course::instance($course->id);
// Retrieve course format option fields and add them to the $course object.
$course = course_get_format($course)->get_course();
if (($marker >=0) && has_capability('moodle/course:setcurrentsection', $context) && confirm_sesskey()) {
if (($marker >= 0) && has_capability('moodle/course:setcurrentsection', $context) && confirm_sesskey()) {
$course->marker = $marker;
course_set_marker($course->id, $marker);
}
@@ -57,5 +57,5 @@ if (!empty($displaysection)) {
$renderer->print_multiple_section_page($course, null, null, null, null);
}
// Include course format js module
// Include course format js module.
$PAGE->requires->js('/course/format/topics/format.js');
@@ -1,5 +1,4 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
@@ -16,7 +15,7 @@
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Strings for component 'format_topics', language 'en', branch 'MOODLE_20_STABLE'
* Strings for component Topics course format.
*
* @package format_topics
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
+67 -51
View File
@@ -15,7 +15,7 @@
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* This file contains main class for the course format Topic
* This file contains main class for Topics course format.
*
* @since Moodle 2.0
* @package format_topics
@@ -26,8 +26,10 @@
defined('MOODLE_INTERNAL') || die();
require_once($CFG->dirroot. '/course/format/lib.php');
use core\output\inplace_editable;
/**
* Main class for the Topics course format
* Main class for the Topics course format.
*
* @package format_topics
* @copyright 2012 Marina Glancy
@@ -36,7 +38,7 @@ require_once($CFG->dirroot. '/course/format/lib.php');
class format_topics extends format_base {
/**
* Returns true if this course format uses sections
* Returns true if this course format uses sections.
*
* @return bool
*/
@@ -47,7 +49,7 @@ class format_topics extends format_base {
/**
* Returns the display name of the given section that the course prefers.
*
* Use section name is specified by user. Otherwise use default ("Topic #")
* Use section name is specified by user. Otherwise use default ("Topic #").
*
* @param int|stdClass $section Section object from database or just field section.section
* @return string Display name that the course format prefers, e.g. "Topic 2"
@@ -56,7 +58,7 @@ class format_topics extends format_base {
$section = $this->get_section($section);
if ((string)$section->name !== '') {
return format_string($section->name, true,
array('context' => context_course::instance($this->courseid)));
['context' => context_course::instance($this->courseid)]);
} else {
return $this->get_default_section_name($section);
}
@@ -84,7 +86,7 @@ class format_topics extends format_base {
}
/**
* The URL to use for the specified course (with section)
* The URL to use for the specified course (with section).
*
* @param int|stdClass $section Section object from database or just field course_sections.section
* if omitted the course view page is returned
@@ -93,10 +95,10 @@ class format_topics extends format_base {
* 'sr' (int) used by multipage formats to specify to which section to return
* @return null|moodle_url
*/
public function get_view_url($section, $options = array()) {
public function get_view_url($section, $options = []) {
global $CFG;
$course = $this->get_course();
$url = new moodle_url('/course/view.php', array('id' => $course->id));
$url = new moodle_url('/course/view.php', ['id' => $course->id]);
$sr = null;
if (array_key_exists('sr', $options)) {
@@ -131,7 +133,7 @@ class format_topics extends format_base {
}
/**
* Returns the information about the ajax support in the given source format
* Returns the information about the ajax support in the given source format.
*
* The returned object's property (boolean)capable indicates that
* the course format supports Moodle course ajax features.
@@ -145,14 +147,15 @@ class format_topics extends format_base {
}
/**
* Loads all of the course sections into the navigation
* Loads all of the course sections into the navigation.
*
* @param global_navigation $navigation
* @param navigation_node $node The course node within the navigation
* @return void
*/
public function extend_course_navigation($navigation, navigation_node $node) {
global $PAGE;
// if section is specified in course/view.php, make sure it is expanded in navigation
// If section is specified in course/view.php, make sure it is expanded in navigation.
if ($navigation->includesectionnum === false) {
$selectedsection = optional_param('section', null, PARAM_INT);
if ($selectedsection !== null && (!defined('AJAX_SCRIPT') || AJAX_SCRIPT == '0') &&
@@ -161,7 +164,7 @@ class format_topics extends format_base {
}
}
// check if there are callbacks to extend course navigation
// Check if there are callbacks to extend course navigation.
parent::extend_course_navigation($navigation, $node);
// We want to remove the general section if it is empty.
@@ -179,15 +182,15 @@ class format_topics extends format_base {
}
/**
* Custom action after section has been moved in AJAX mode
* Custom action after section has been moved in AJAX mode.
*
* Used in course/rest.php
*
* @return array This will be passed in ajax respose
*/
function ajax_section_move() {
public function ajax_section_move() {
global $PAGE;
$titles = array();
$titles = [];
$course = $this->get_course();
$modinfo = get_fast_modinfo($course);
$renderer = $this->get_renderer($PAGE);
@@ -196,24 +199,24 @@ class format_topics extends format_base {
$titles[$number] = $renderer->section_title($section, $course);
}
}
return array('sectiontitles' => $titles, 'action' => 'move');
return ['sectiontitles' => $titles, 'action' => 'move'];
}
/**
* Returns the list of blocks to be automatically added for the newly created course
* Returns the list of blocks to be automatically added for the newly created course.
*
* @return array of default blocks, must contain two keys BLOCK_POS_LEFT and BLOCK_POS_RIGHT
* each of values is an array of block names (for left and right side columns)
*/
public function get_default_blocks() {
return array(
BLOCK_POS_LEFT => array(),
BLOCK_POS_RIGHT => array()
);
return [
BLOCK_POS_LEFT => [],
BLOCK_POS_RIGHT => [],
];
}
/**
* Definitions of the additional options that this course format uses for course
* Definitions of the additional options that this course format uses for course.
*
* Topics format uses the following options:
* - coursedisplay
@@ -226,44 +229,44 @@ class format_topics extends format_base {
static $courseformatoptions = false;
if ($courseformatoptions === false) {
$courseconfig = get_config('moodlecourse');
$courseformatoptions = array(
'hiddensections' => array(
$courseformatoptions = [
'hiddensections' => [
'default' => $courseconfig->hiddensections,
'type' => PARAM_INT,
),
'coursedisplay' => array(
],
'coursedisplay' => [
'default' => $courseconfig->coursedisplay,
'type' => PARAM_INT,
),
);
],
];
}
if ($foreditform && !isset($courseformatoptions['coursedisplay']['label'])) {
$courseformatoptionsedit = array(
'hiddensections' => array(
$courseformatoptionsedit = [
'hiddensections' => [
'label' => new lang_string('hiddensections'),
'help' => 'hiddensections',
'help_component' => 'moodle',
'element_type' => 'select',
'element_attributes' => array(
array(
'element_attributes' => [
[
0 => new lang_string('hiddensectionscollapsed'),
1 => new lang_string('hiddensectionsinvisible')
)
),
),
'coursedisplay' => array(
],
],
],
'coursedisplay' => [
'label' => new lang_string('coursedisplay'),
'element_type' => 'select',
'element_attributes' => array(
array(
'element_attributes' => [
[
COURSE_DISPLAY_SINGLEPAGE => new lang_string('coursedisplay_single'),
COURSE_DISPLAY_MULTIPAGE => new lang_string('coursedisplay_multi')
)
),
COURSE_DISPLAY_MULTIPAGE => new lang_string('coursedisplay_multi'),
],
],
'help' => 'coursedisplay',
'help_component' => 'moodle',
)
);
],
];
$courseformatoptions = array_merge_recursive($courseformatoptions, $courseformatoptionsedit);
}
return $courseformatoptions;
@@ -301,7 +304,7 @@ class format_topics extends format_base {
}
/**
* Updates format options for a course
* Updates format options for a course.
*
* In case if course format was changed to 'topics', we try to copy options
* 'coursedisplay' and 'hiddensections' from the previous format.
@@ -328,7 +331,7 @@ class format_topics extends format_base {
}
/**
* Whether this format allows to delete sections
* Whether this format allows to delete sections.
*
* Do not call this function directly, instead use {@link course_can_delete_section()}
*
@@ -340,17 +343,17 @@ class format_topics extends format_base {
}
/**
* Prepares the templateable object to display section name
* Prepares the templateable object to display section name.
*
* @param \section_info|\stdClass $section
* @param bool $linkifneeded
* @param bool $editable
* @param null|lang_string|string $edithint
* @param null|lang_string|string $editlabel
* @return \core\output\inplace_editable
* @return inplace_editable
*/
public function inplace_editable_render_section_name($section, $linkifneeded = true,
$editable = null, $edithint = null, $editlabel = null) {
$editable = null, $edithint = null, $editlabel = null) {
if (empty($edithint)) {
$edithint = new lang_string('editsectionname', 'format_topics');
}
@@ -383,6 +386,19 @@ class format_topics extends format_base {
return !$section->section || $section->visible;
}
/**
* Callback used in WS core_course_edit_section when teacher performs an AJAX action on a section (show/hide).
*
* Access to the course is already validated in the WS but the callback has to make sure
* that particular action is allowed by checking capabilities
*
* Course formats should register.
*
* @param section_info|stdClass $section
* @param string $action
* @param int $sr
* @return null|array any data for the Javascript post-processor (must be json-encodeable)
*/
public function section_action($section, $action, $sr) {
global $PAGE;
@@ -413,12 +429,12 @@ class format_topics extends format_base {
}
/**
* Implements callback inplace_editable() allowing to edit values in-place
* Implements callback inplace_editable() allowing to edit values in-place.
*
* @param string $itemtype
* @param int $itemid
* @param mixed $newvalue
* @return \core\output\inplace_editable
* @return inplace_editable
*/
function format_topics_inplace_editable($itemtype, $itemid, $newvalue) {
global $DB, $CFG;
@@ -426,7 +442,7 @@ function format_topics_inplace_editable($itemtype, $itemid, $newvalue) {
if ($itemtype === 'sectionname' || $itemtype === 'sectionnamenl') {
$section = $DB->get_record_sql(
'SELECT s.* FROM {course_sections} s JOIN {course} c ON s.course = c.id WHERE s.id = ? AND c.format = ?',
array($itemid, 'topics'), MUST_EXIST);
[$itemid, 'topics'], MUST_EXIST);
return course_get_format($section->course)->inplace_editable_update_section_name($section, $itemtype, $newvalue);
}
}
+42 -29
View File
@@ -23,7 +23,6 @@
* @since Moodle 2.3
*/
defined('MOODLE_INTERNAL') || die();
require_once($CFG->dirroot.'/course/format/renderer.php');
@@ -36,7 +35,7 @@ require_once($CFG->dirroot.'/course/format/renderer.php');
class format_topics_renderer extends format_section_renderer_base {
/**
* Constructor method, calls the parent constructor
* Constructor method, calls the parent constructor.
*
* @param moodle_page $page
* @param string $target one of rendering target constants
@@ -44,21 +43,24 @@ class format_topics_renderer extends format_section_renderer_base {
public function __construct(moodle_page $page, $target) {
parent::__construct($page, $target);
// Since format_topics_renderer::section_edit_control_items() only displays the 'Highlight' control when editing mode is on
// we need to be sure that the link 'Turn editing mode on' is available for a user who does not have any other managing capability.
// Since format_topics_renderer::section_edit_control_items() only displays the 'Highlight' control
// when editing mode is on we need to be sure that the link 'Turn editing mode on' is available for a user
// who does not have any other managing capability.
$page->set_other_editing_capability('moodle/course:setcurrentsection');
}
/**
* Generate the starting container html for a list of sections
* Generate the starting container html for a list of sections.
*
* @return string HTML to output.
*/
protected function start_section_list() {
return html_writer::start_tag('ul', array('class' => 'topics'));
return html_writer::start_tag('ul', ['class' => 'topics']);
}
/**
* Generate the closing container html for a list of sections
* Generate the closing container html for a list of sections.
*
* @return string HTML to output.
*/
protected function end_section_list() {
@@ -66,7 +68,8 @@ class format_topics_renderer extends format_section_renderer_base {
}
/**
* Generate the title for this section page
* Generate the title for this section page.
*
* @return string the page title
*/
protected function page_title() {
@@ -74,9 +77,9 @@ class format_topics_renderer extends format_section_renderer_base {
}
/**
* Generate the section title, wraps it in a link to the section page if page is to be displayed on a separate page
* Generate the section title, wraps it in a link to the section page if page is to be displayed on a separate page.
*
* @param stdClass $section The course_section entry from DB
* @param section_info|stdClass $section The course_section entry from DB
* @param stdClass $course The course entry from DB
* @return string HTML to output.
*/
@@ -85,10 +88,10 @@ class format_topics_renderer extends format_section_renderer_base {
}
/**
* Generate the section title to be displayed on the section page, without a link
* Generate the section title to be displayed on the section page, without a link.
*
* @param stdClass $section The course_section entry from DB
* @param stdClass $course The course entry from DB
* @param section_info|stdClass $section The course_section entry from DB
* @param int|stdClass $course The course entry from DB
* @return string HTML to output.
*/
public function section_title_without_link($section, $course) {
@@ -96,16 +99,16 @@ class format_topics_renderer extends format_section_renderer_base {
}
/**
* Generate the edit control items of a section
* Generate the edit control items of a section.
*
* @param stdClass $course The course entry from DB
* @param stdClass $section The course_section entry from DB
* @param int|stdClass $course The course entry from DB
* @param section_info|stdClass $section The course_section entry from DB
* @param bool $onsectionpage true if being printed on a section page
* @return array of edit control items
*/
protected function section_edit_control_items($course, $section, $onsectionpage = false) {
if (!$this->page->user_is_editing()) {
return array();
return [];
}
$coursecontext = context_course::instance($course->id);
@@ -117,24 +120,34 @@ class format_topics_renderer extends format_section_renderer_base {
}
$url->param('sesskey', sesskey());
$controls = array();
$controls = [];
if ($section->section && has_capability('moodle/course:setcurrentsection', $coursecontext)) {
if ($course->marker == $section->section) { // Show the "light globe" on/off.
$url->param('marker', 0);
$highlightoff = get_string('highlightoff');
$controls['highlight'] = array('url' => $url, "icon" => 'i/marked',
'name' => $highlightoff,
'pixattr' => array('class' => ''),
'attr' => array('class' => 'editing_highlight',
'data-action' => 'removemarker'));
$controls['highlight'] = [
'url' => $url,
'icon' => 'i/marked',
'name' => $highlightoff,
'pixattr' => ['class' => ''],
'attr' => [
'class' => 'editing_highlight',
'data-action' => 'removemarker'
],
];
} else {
$url->param('marker', $section->section);
$highlight = get_string('highlight');
$controls['highlight'] = array('url' => $url, "icon" => 'i/marker',
'name' => $highlight,
'pixattr' => array('class' => ''),
'attr' => array('class' => 'editing_highlight',
'data-action' => 'setmarker'));
$controls['highlight'] = [
'url' => $url,
'icon' => 'i/marker',
'name' => $highlight,
'pixattr' => ['class' => ''],
'attr' => [
'class' => 'editing_highlight',
'data-action' => 'setmarker'
],
];
}
}
@@ -142,7 +155,7 @@ class format_topics_renderer extends format_section_renderer_base {
// If the edit key exists, we are going to insert our controls after it.
if (array_key_exists("edit", $parentcontrols)) {
$merged = array();
$merged = [];
// We can't use splice because we are using associative arrays.
// Step through the array and merge the arrays.
foreach ($parentcontrols as $key => $action) {
@@ -15,7 +15,7 @@
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* format_topics related unit tests
* Topics course format related unit tests.
*
* @package format_topics
* @copyright 2015 Marina Glancy
@@ -28,7 +28,7 @@ global $CFG;
require_once($CFG->dirroot . '/course/lib.php');
/**
* format_topics related unit tests
* Topics course format related unit tests.
*
* @package format_topics
* @copyright 2015 Marina Glancy
@@ -38,6 +38,8 @@ class format_topics_testcase extends advanced_testcase {
/**
* Tests for format_topics::get_section_name method with default section names.
*
* @return void
*/
public function test_get_section_name() {
global $DB;
@@ -46,11 +48,11 @@ class format_topics_testcase extends advanced_testcase {
// Generate a course with 5 sections.
$generator = $this->getDataGenerator();
$numsections = 5;
$course = $generator->create_course(array('numsections' => $numsections, 'format' => 'topics'),
array('createsections' => true));
$course = $generator->create_course(['numsections' => $numsections, 'format' => 'topics'],
['createsections' => true]);
// Get section names for course.
$coursesections = $DB->get_records('course_sections', array('course' => $course->id));
$coursesections = $DB->get_records('course_sections', ['course' => $course->id]);
// Test get_section_name with default section names.
$courseformat = course_get_format($course);
@@ -62,6 +64,8 @@ class format_topics_testcase extends advanced_testcase {
/**
* Tests for format_topics::get_section_name method with modified section names.
*
* @return void
*/
public function test_get_section_name_customised() {
global $DB;
@@ -70,11 +74,11 @@ class format_topics_testcase extends advanced_testcase {
// Generate a course with 5 sections.
$generator = $this->getDataGenerator();
$numsections = 5;
$course = $generator->create_course(array('numsections' => $numsections, 'format' => 'topics'),
array('createsections' => true));
$course = $generator->create_course(['numsections' => $numsections, 'format' => 'topics'],
['createsections' => true]);
// Get section names for course.
$coursesections = $DB->get_records('course_sections', array('course' => $course->id));
$coursesections = $DB->get_records('course_sections', ['course' => $course->id]);
// Modify section names.
$customname = "Custom Section";
@@ -84,7 +88,7 @@ class format_topics_testcase extends advanced_testcase {
}
// Requery updated section names then test get_section_name.
$coursesections = $DB->get_records('course_sections', array('course' => $course->id));
$coursesections = $DB->get_records('course_sections', ['course' => $course->id]);
$courseformat = course_get_format($course);
foreach ($coursesections as $section) {
// Assert that with modified section names, get_section_name returns the modified section name.
@@ -94,6 +98,8 @@ class format_topics_testcase extends advanced_testcase {
/**
* Tests for format_topics::get_default_section_name.
*
* @return void
*/
public function test_get_default_section_name() {
global $DB;
@@ -102,11 +108,11 @@ class format_topics_testcase extends advanced_testcase {
// Generate a course with 5 sections.
$generator = $this->getDataGenerator();
$numsections = 5;
$course = $generator->create_course(array('numsections' => $numsections, 'format' => 'topics'),
array('createsections' => true));
$course = $generator->create_course(['numsections' => $numsections, 'format' => 'topics'],
['createsections' => true]);
// Get section names for course.
$coursesections = $DB->get_records('course_sections', array('course' => $course->id));
$coursesections = $DB->get_records('course_sections', ['course' => $course->id]);
// Test get_default_section_name with default section names.
$courseformat = course_get_format($course);
@@ -122,7 +128,9 @@ class format_topics_testcase extends advanced_testcase {
}
/**
* Test web service updating section name
* Test web service updating section name.
*
* @return void
*/
public function test_update_inplace_editable() {
global $CFG, $DB, $PAGE;
@@ -131,9 +139,9 @@ class format_topics_testcase extends advanced_testcase {
$this->resetAfterTest();
$user = $this->getDataGenerator()->create_user();
$this->setUser($user);
$course = $this->getDataGenerator()->create_course(array('numsections' => 5, 'format' => 'topics'),
array('createsections' => true));
$section = $DB->get_record('course_sections', array('course' => $course->id, 'section' => 2));
$course = $this->getDataGenerator()->create_course(['numsections' => 5, 'format' => 'topics'],
['createsections' => true]);
$section = $DB->get_record('course_sections', ['course' => $course->id, 'section' => 2]);
// Call webservice without necessary permissions.
try {
@@ -145,41 +153,43 @@ class format_topics_testcase extends advanced_testcase {
}
// Change to teacher and make sure that section name can be updated using web service update_inplace_editable().
$teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher'));
$teacherrole = $DB->get_record('role', ['shortname' => 'editingteacher']);
$this->getDataGenerator()->enrol_user($user->id, $course->id, $teacherrole->id);
$res = core_external::update_inplace_editable('format_topics', 'sectionname', $section->id, 'New section name');
$res = external_api::clean_returnvalue(core_external::update_inplace_editable_returns(), $res);
$this->assertEquals('New section name', $res['value']);
$this->assertEquals('New section name', $DB->get_field('course_sections', 'name', array('id' => $section->id)));
$this->assertEquals('New section name', $DB->get_field('course_sections', 'name', ['id' => $section->id]));
}
/**
* Test callback updating section name
* Test callback updating section name.
*
* @return void
*/
public function test_inplace_editable() {
global $DB, $PAGE;
$this->resetAfterTest();
$user = $this->getDataGenerator()->create_user();
$course = $this->getDataGenerator()->create_course(array('numsections' => 5, 'format' => 'topics'),
array('createsections' => true));
$teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher'));
$course = $this->getDataGenerator()->create_course(['numsections' => 5, 'format' => 'topics'],
['createsections' => true]);
$teacherrole = $DB->get_record('role', ['shortname' => 'editingteacher']);
$this->getDataGenerator()->enrol_user($user->id, $course->id, $teacherrole->id);
$this->setUser($user);
$section = $DB->get_record('course_sections', array('course' => $course->id, 'section' => 2));
$section = $DB->get_record('course_sections', ['course' => $course->id, 'section' => 2]);
// Call callback format_topics_inplace_editable() directly.
$tmpl = component_callback('format_topics', 'inplace_editable', array('sectionname', $section->id, 'Rename me again'));
$tmpl = component_callback('format_topics', 'inplace_editable', ['sectionname', $section->id, 'Rename me again']);
$this->assertInstanceOf('core\output\inplace_editable', $tmpl);
$res = $tmpl->export_for_template($PAGE->get_renderer('core'));
$this->assertEquals('Rename me again', $res['value']);
$this->assertEquals('Rename me again', $DB->get_field('course_sections', 'name', array('id' => $section->id)));
$this->assertEquals('Rename me again', $DB->get_field('course_sections', 'name', ['id' => $section->id]));
// Try updating using callback from mismatching course format.
try {
$tmpl = component_callback('format_weeks', 'inplace_editable', array('sectionname', $section->id, 'New name'));
component_callback('format_weeks', 'inplace_editable', ['sectionname', $section->id, 'New name']);
$this->fail('Exception expected');
} catch (moodle_exception $e) {
$this->assertEquals(1, preg_match('/^Can\'t find data record in database/', $e->getMessage()));
@@ -200,9 +210,9 @@ class format_topics_testcase extends advanced_testcase {
$this->setTimezone('UTC');
$params = array('format' => 'topics', 'numsections' => 5, 'startdate' => 1445644800);
$params = ['format' => 'topics', 'numsections' => 5, 'startdate' => 1445644800];
$course = $this->getDataGenerator()->create_course($params);
$category = $DB->get_record('course_categories', array('id' => $course->category));
$category = $DB->get_record('course_categories', ['id' => $course->category]);
$args = [
'course' => $course,
@@ -226,7 +236,9 @@ class format_topics_testcase extends advanced_testcase {
}
/**
* Test for get_view_url() to ensure that the url is only given for the correct cases
* Test for get_view_url() to ensure that the url is only given for the correct cases.
*
* @return void
*/
public function test_get_view_url() {
global $CFG;
@@ -236,8 +248,8 @@ class format_topics_testcase extends advanced_testcase {
// Generate a course with two sections (0 and 1) and two modules.
$generator = $this->getDataGenerator();
$course1 = $generator->create_course(array('format' => 'topics'));
course_create_sections_if_missing($course1, array(0, 1));
$course1 = $generator->create_course(['format' => 'topics']);
course_create_sections_if_missing($course1, [0, 1]);
$data = (object)['id' => $course1->id];
$format = course_get_format($course1);
+2 -3
View File
@@ -15,10 +15,9 @@
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Version details
* Version details.
*
* @package format
* @subpackage topics
* @package format_topics
* @copyright 1999 onwards Martin Dougiamas (http://dougiamas.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/