MDL-35263 Converting course formats to OOP

- added class format_base as the base for all course formats
- added class format_site for the pseudo-format 'site' used for displaying activities on the front page
- added class format_legacy that overrides format_base functions with calling old-style 'callback_xxx' functions
- replaced all usage of 'callback_xxx' functions with format_base methods
- made arguments of get_section_name(), get_course_url() more flexible
- deprecated function get_generic_section_name(), it's contents is moved to format_base
- global_navigation::format_display_course_content() is removed, plugins can supress the sections navigations using extend_course_navigation()
This commit is contained in:
Marina Glancy
2012-09-28 13:42:27 +08:00
parent 5d6285c220
commit ee7084e950
9 changed files with 671 additions and 190 deletions
+181
View File
@@ -0,0 +1,181 @@
<?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/>.
/**
* Course format class to allow plugins developed for Moodle 2.3 to work in the new API
*
* @package core_course
* @copyright 2012 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die;
/**
* Course format class to allow plugins developed for Moodle 2.3 to work in the new API
*
* @package core_course
* @copyright 2012 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class format_legacy extends format_base {
/**
* Returns true if this course format uses sections
*
* This function calls function callback_FORMATNAME_uses_sections() if it exists
*
* @return bool
*/
function uses_sections() {
global $CFG;
// Note that lib.php in course format folder is already included by now
$featurefunction = 'callback_'.$this->format.'_uses_sections';
if (function_exists($featurefunction)) {
return $featurefunction();
}
return false;
}
/**
* Returns the display name of the given section that the course prefers.
*
* This function calls function callback_FORMATNAME_get_section_name() if it exists
*
* @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"
*/
function get_section_name($section) {
// Use course formatter callback if it exists
$namingfunction = 'callback_'.$this->format.'_get_section_name';
if (function_exists($namingfunction) && ($course = $this->get_course())) {
return $namingfunction($course, $this->get_section($section));
}
// else, default behavior:
return parent::get_section_name($section);
}
/**
* The URL to use for the specified course (with section)
*
* This function calls function callback_FORMATNAME_get_section_url() if it exists
*
* @param int|stdClass $section Section object from database or just field course_sections.section
* if omitted the course view page is returned
* @param array $options options for view URL. At the moment core uses:
* 'navigation' (bool) if true and section has no separate page, the function returns null
* '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()) {
// Use course formatter callback if it exists
$featurefunction = 'callback_'.$this->format.'_get_section_url';
if (function_exists($featurefunction) && ($course = $this->get_course())) {
if (is_object($section)) {
$sectionnum = $section->section;
} else {
$sectionnum = $section;
}
if ($sectionnum) {
$url = $featurefunction($course, $sectionnum);
if ($url || !empty($options['navigation'])) {
return $url;
}
}
}
// else, default behavior:
return parent::get_view_url($section, $options);
}
/**
* Returns the information about the ajax support in the given source format
*
* This function calls function callback_FORMATNAME_ajax_support() if it exists
*
* The returned object's property (boolean)capable indicates that
* the course format supports Moodle course ajax features.
* The property (array)testedbrowsers can be used as a parameter for {@see ajaxenabled()}.
*
* @return stdClass
*/
function supports_ajax() {
// set up default values
$ajaxsupport = parent::supports_ajax();
// get the information from the course format library
$featurefunction = 'callback_'.$this->format.'_ajax_support';
if (function_exists($featurefunction)) {
$formatsupport = $featurefunction();
if (isset($formatsupport->capable)) {
$ajaxsupport->capable = $formatsupport->capable;
}
if (is_array($formatsupport->testedbrowsers)) {
$ajaxsupport->testedbrowsers = $formatsupport->testedbrowsers;
}
}
return $ajaxsupport;
}
/**
* Loads all of the course sections into the navigation
*
* First this function calls callback_FORMATNAME_display_content() if it exists to check
* if the navigation should be extended at all
*
* Then it calls function callback_FORMATNAME_load_content() if it exist to actually extend
* navigation
*
* By default the parent method is called
*
* @param global_navigation $navigation
* @param navigation_node $node The course node within the navigation
* @return array Array of sections where each element also contains the element 'sectionnode'
* referring to the corresponding section node
*/
public function extend_course_navigation(&$navigation, navigation_node $node) {
// check if there are callbacks to extend course navigation
$displayfunc = 'callback_'.$this->format.'_display_content';
if (function_exists($displayfunc) && !$displayfunc()) {
return array();
}
$featurefunction = 'callback_'.$this->format.'_load_content';
if (function_exists($featurefunction) && ($course = $this->get_course())) {
return $featurefunction($navigation, $course, $node);
} else {
return parent::extend_navigation($navigation, $node);
}
}
/**
* Custom action after section has been moved in AJAX mode
*
* Used in course/rest.php
*
* This function calls function callback_FORMATNAME_ajax_section_move() if it exists
*
* @return array This will be passed in ajax respose
*/
function ajax_section_move() {
$featurefunction = 'callback_'.$this->format.'_ajax_section_move';
if (function_exists($featurefunction) && ($course = $this->get_course())) {
return $featurefunction($course);
} else {
return parent::ajax_section_move();
}
}
}
+426
View File
@@ -0,0 +1,426 @@
<?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/>.
/**
* Base class for course format plugins
*
* @package core_course
* @copyright 2012 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die;
/**
* Returns an instance of format class (extending format_base) for given course
*
* @param int|stdClass $courseorid either course id or
* an object that has the property 'format' and may contain property 'id'
* @return format_base
*/
function course_get_format($courseorid) {
return format_base::instance($courseorid);
}
/**
* Base class for course formats
*
* Each course format must declare class
* class format_FORMATNAME extends format_base {}
* in file lib.php
*
* For each course just one instance of this class is created and it will always be returned by
* course_get_format($courseorid). Format may store it's specific course-dependent options in
* variables of this class.
*
* In rare cases instance of child class may be created just for format without course id
* i.e. to check if format supports AJAX.
*
* Also course formats may extend class section_info and overwrite
* format_base::build_section_cache() to return more information about sections.
*
* If you are upgrading from Moodle 2.3 start with copying the class format_legacy and renaming
* it to format_FORMATNAME, then move the code from your callback functions into
* appropriate functions of the class.
*
* @package core_course
* @copyright 2012 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
abstract class format_base {
/** @var int Id of the course in this instance (maybe 0) */
protected $courseid;
/** @var string format used for this course. Please note that it can be different from
* course.format field if course referes to non-existing of disabled format */
protected $format;
/** @var stdClass data for course object, please use {@link format_base::get_course()} */
protected $course = false;
/** @var array cached instances */
private static $instances = array();
/**
* Creates a new instance of class
*
* Please use {@link course_get_format($courseorid)} to get an instance of the format class
*
* @param string $format
* @param int $courseid
* @return format_base
*/
protected function __construct($format, $courseid) {
$this->format = $format;
$this->courseid = $courseid;
}
/**
* Validates course format and returns either itself or default format name
*
* @param string $format
* @return string
*/
protected static final function get_used_format($format) {
if ($format === 'site') {
return $format;
}
$plugins = get_plugin_list('format'); // TODO filter only enabled
if (isset($plugins[$format])) {
return $format;
}
// Else return default format
$defaultformat = reset($plugins); // TODO get default format from config
debugging('Format plugin format_'.$format.' is not found or is not enabled. Using default format_'.$defaultformat);
return $defaultformat;
}
/**
* Get class name for the format
*
* If course format xxx does not declare class format_xxx, format_legacy will be returned.
* This function also includes lib.php file from corresponding format plugin
*
* @param string $format
* @return string
*/
protected static final function get_class_name($format) {
global $CFG;
static $classnames = array('site' => 'format_site');
if (!isset($classnames[$format])) {
$plugins = get_plugin_list('format');
$usedformat = self::get_used_format($format);
if (file_exists($plugins[$usedformat].'/lib.php')) {
require_once $plugins[$usedformat].'/lib.php';
}
$classnames[$format] = 'format_'. $usedformat;
if (!class_exists($classnames[$format])) {
require_once $CFG->dirroot.'/course/format/formatlegacy.php';
$classnames[$format] = 'format_legacy';
}
}
return $classnames[$format];
}
/**
* Returns an instance of the class
*
* @todo use MUC for caching of instances, limit the number of cached instances
*
* @param int|stdClass $courseorid either course id or
* an object that has the property 'format' and may contain property 'id'
* @return format_base
*/
public static final function instance($courseorid) {
global $DB;
if (!is_object($courseorid)) {
$courseid = (int)$courseorid;
if ($courseid && isset(self::$instances[$courseid]) && count(self::$instances[$courseid]) == 1) {
$format = reset(array_keys(self::$instances[$courseid]));
} else {
$format = $DB->get_field('course', 'format', array('id' => $courseid), MUST_EXIST);
}
} else {
$format = $courseorid->format;
if (isset($courseorid->id)) {
$courseid = (int)$courseorid->id;
} else {
$courseid = 0;
}
}
// validate that format exists and enabled, use default otherwise
$format = self::get_used_format($format);
if (!isset(self::$instances[$courseid][$format])) {
$classname = self::get_class_name($format);
self::$instances[$courseid][$format] = new $classname($format, $courseid);
}
return self::$instances[$courseid][$format];
}
/**
* Resets cache for the course (or all caches)
* To be called from {@link rebuild_course_cache()}
*
* @param int $courseid
*/
public static final function reset_course_cache($courseid = 0) {
if ($courseid) {
if (isset(self::$instances[$courseid])) {
foreach (self::$instances[$courseid] as $format => $object) {
// in case somebody keeps the reference to course format object
self::$instances[$courseid][$format]->course = false;
}
unset(self::$instances[$courseid]);
}
} else {
self::$instances = array();
}
}
/**
* Returns the format name used by this course
*
* @return string
*/
public final function get_format() {
return $this->format;
}
/**
* Returns id of the course (0 if course is not specified)
*
* @return int
*/
public final function get_courseid() {
return $this->courseid;
}
/**
* Returns a record from course database table plus additional fields
* that course format defines
*
* @return stdClass
*/
public function get_course() {
global $DB;
if (!$this->courseid) {
return null;
}
if ($this->course === false) {
$this->course = $DB->get_record('course', array('id' => $this->courseid));
}
return $this->course;
}
/**
* Returns true if this course format uses sections
*
* This function may be called without specifying the course id
* i.e. in {@link course_format_uses_sections()}
*
* Developers, note that if course format does use sections there should be defined a language
* string with the name 'sectionname' defining what the section relates to in the format, i.e.
* $string['sectionname'] = 'Topic';
* or
* $string['sectionname'] = 'Week';
*
* @return bool
*/
public function uses_sections() {
return false;
}
/**
* Returns a list of sections used in the course
*
* This is a shortcut to get_fast_modinfo()->get_section_info_all()
* @see get_fast_modinfo()
* @see course_modinfo::get_section_info_all()
*
* @return array of section_info objects
*/
public final function get_sections() {
if ($course = $this->get_course()) {
$modinfo = get_fast_modinfo($course);
return $modinfo->get_section_info_all();
}
return array();
}
/**
* Returns information about section used in course
*
* @param int|stdClass $section either section number (field course_section.section) or row from course_section table
* @param int $strictness
* @return section_info
*/
public final function get_section($section, $strictness = IGNORE_MISSING) {
if (is_object($section)) {
$sectionnum = $section->section;
} else {
$sectionnum = $section;
}
$sections = $this->get_sections();
if (array_key_exists($sectionnum, $sections)) {
return $sections[$sectionnum];
}
if ($strictness == MUST_EXIST) {
throw new moodle_exception('sectionnotexist');
}
return null;
}
/**
* Returns the display name of the given section that the course prefers.
*
* @param int|stdClass $section Section object from database or just field course_sections.section
* @return Display name that the course format prefers, e.g. "Topic 2"
*/
public function get_section_name($section) {
if (is_object($section)) {
$sectionnum = $section->section;
} else {
$sectionnum = $section;
}
return get_string('sectionname', 'format_'.$this->format) . ' ' . $sectionnum;
}
/**
* 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.
* The property (array)testedbrowsers can be used as a parameter for {@see ajaxenabled()}.
*
* @return stdClass
*/
public function supports_ajax() {
// no support by default
$ajaxsupport = new stdClass();
$ajaxsupport->capable = false;
$ajaxsupport->testedbrowsers = array();
return $ajaxsupport;
}
/**
* Custom action after section has been moved in AJAX mode
*
* Used in course/rest.php
*
* @return array This will be passed in ajax respose
*/
public function ajax_section_move() {
return null;
}
/**
* The URL to use for the specified course (with section)
*
* Please note that course view page /course/view.php?id=COURSEID is hardcoded in many
* places in core and contributed modules. If course format wants to change the location
* of the view script, it is not enough to change just this function. Do not forget
* to add proper redirection.
*
* @param int|stdClass $section Section object from database or just field course_sections.section
* if null the course view page is returned
* @param array $options options for view URL. At the moment core uses:
* 'navigation' (bool) if true and section has no separate page, the function returns null
* '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()) {
$course = $this->get_course();
$url = new moodle_url('/course/view.php', array('id' => $course->id));
$sr = null;
if (array_key_exists('sr', $options)) {
$sr = $options['sr'];
}
if (is_object($section)) {
$sectionno = $section->section;
} else {
$sectionno = $section;
}
if ($sectionno !== null) {
if ($sr !== null) {
if ($sr) {
$usercoursedisplay = COURSE_DISPLAY_MULTIPAGE;
$sectionno = $sr;
} else {
$usercoursedisplay = COURSE_DISPLAY_SINGLEPAGE;
}
} else {
$usercoursedisplay = $course->coursedisplay;
}
if ($sectionno != 0 && $usercoursedisplay == COURSE_DISPLAY_MULTIPAGE) {
$url->param('section', $sectionno);
} else {
if (!empty($options['navigation'])) {
return null;
}
$url->set_anchor('section-'.$sectionno);
}
}
return $url;
}
/**
* Loads all of the course sections into the navigation
*
* By default the method {@link global_navigation::load_generic_course_sections()} is called
*
* @param global_navigation $navigation
* @param navigation_node $node The course node within the navigation
* @return array Array of sections where each element also contains the element 'sectionnode'
* referring to the corresponding section node
*/
public function extend_course_navigation(&$navigation, navigation_node $node) {
if ($course = $this->get_course()) {
return $navigation->load_generic_course_sections($course, $node);
}
return array();
}
}
/**
* Pseudo course format used for the site main page
*
* @package core_course
* @copyright 2012 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class format_site extends format_base {
/**
* Returns the display name of the given section that the course prefers.
*
* @param int|stdClass $section Section object from database or just field section.section
* @return Display name that the course format prefers, e.g. "Topic 2"
*/
function get_section_name($section) {
return get_string('site');
}
/**
* For this fake course referring to the whole site, the site homepage is always returned
* regardless of arguments
*
* @param int|stdClass $section
* @param array $options
* @return null|moodle_url
*/
public function get_view_url($section, $options = array()) {
return new moodle_url('/');
}
}
+4
View File
@@ -4,6 +4,10 @@ Overview of this plugin type at http://docs.moodle.org/dev/Course_formats
=== 2.4 ===
Course format API has been changed significantly. Instead of implementing callbacks course formats
may overwrite the class format_base. See format_legacy class for a template for upgrading course
format.
* Function settings_navigation::add_course_editing_links() is completely removed, course format
functions callback_XXXX_request_key() are no longer used (where XXXX is the course format name)
+21 -110
View File
@@ -29,6 +29,7 @@ defined('MOODLE_INTERNAL') || die;
require_once($CFG->libdir.'/completionlib.php');
require_once($CFG->libdir.'/filelib.php');
require_once($CFG->dirroot.'/course/dnduploadlib.php');
require_once($CFG->dirroot.'/course/format/lib.php');
define('COURSE_MAX_LOGS_PER_PAGE', 1000); // records
define('COURSE_MAX_RECENT_PERIOD', 172800); // Two days, in seconds
@@ -3654,68 +3655,29 @@ function move_category($category, $newparentcat) {
}
/**
* Returns the display name of the given section that the course prefers.
* Returns the display name of the given section that the course prefers
*
* This function utilizes a callback that can be implemented within the course
* formats lib.php file to customize the display name that is used to reference
* the section.
* Implementation of this function is provided by course format
* @see format_base::get_section_name()
*
* By default (if callback is not defined) the method
* {@see get_numeric_section_name} is called instead.
*
* @param stdClass $course The course to get the section name for
* @param stdClass $section Section object from database
* @return Display name that the course format prefers, e.g. "Week 2"
*
* @see get_generic_section_name
* @param int|stdClass $courseorid The course to get the section name for (object or just course id)
* @param int|stdClass $section Section object from database or just field course_sections.section
* @return string Display name that the course format prefers, e.g. "Week 2"
*/
function get_section_name(stdClass $course, stdClass $section) {
global $CFG;
/// Inelegant hack for bug 3408
if ($course->format == 'site') {
return get_string('site');
}
// Use course formatter callback if it exists
$namingfile = $CFG->dirroot.'/course/format/'.$course->format.'/lib.php';
$namingfunction = 'callback_'.$course->format.'_get_section_name';
if (!function_exists($namingfunction) && file_exists($namingfile)) {
require_once $namingfile;
}
if (function_exists($namingfunction)) {
return $namingfunction($course, $section);
}
// else, default behavior:
return get_generic_section_name($course->format, $section);
function get_section_name($courseorid, $section) {
return course_get_format($courseorid)->get_section_name($section);
}
/**
* Gets the generic section name for a courses section.
* Tells if current course format uses sections
*
* @param string $format Course format ID e.g. 'weeks' $course->format
* @param stdClass $section Section object from database
* @return Display name that the course format prefers, e.g. "Week 2"
* @return bool
*/
function get_generic_section_name($format, stdClass $section) {
return get_string('sectionname', "format_$format") . ' ' . $section->section;
}
function course_format_uses_sections($format) {
global $CFG;
$featurefile = $CFG->dirroot.'/course/format/'.$format.'/lib.php';
$featurefunction = 'callback_'.$format.'_uses_sections';
if (!function_exists($featurefunction) && file_exists($featurefile)) {
require_once $featurefile;
}
if (function_exists($featurefunction)) {
return $featurefunction();
}
return false;
$course = new stdClass();
$course->format = $format;
return course_get_format($course)->uses_sections();
}
/**
@@ -3729,30 +3691,9 @@ function course_format_uses_sections($format) {
* @return stdClass
*/
function course_format_ajax_support($format) {
global $CFG;
// set up default values
$ajaxsupport = new stdClass();
$ajaxsupport->capable = false;
$ajaxsupport->testedbrowsers = array();
// get the information from the course format library
$featurefile = $CFG->dirroot.'/course/format/'.$format.'/lib.php';
$featurefunction = 'callback_'.$format.'_ajax_support';
if (!function_exists($featurefunction) && file_exists($featurefile)) {
require_once $featurefile;
}
if (function_exists($featurefunction)) {
$formatsupport = $featurefunction();
if (isset($formatsupport->capable)) {
$ajaxsupport->capable = $formatsupport->capable;
}
if (is_array($formatsupport->testedbrowsers)) {
$ajaxsupport->testedbrowsers = $formatsupport->testedbrowsers;
}
}
return $ajaxsupport;
$course = new stdClass();
$course->format = $format;
return course_get_format($course)->supports_ajax();
}
/**
@@ -4598,44 +4539,14 @@ function include_course_ajax($course, $usedmodules = array(), $enabledmodules =
/**
* The URL to use for the specified course (with section)
*
* @param stdClass $course The course to get the section name for
* @param int $sectionno The section number to return a link to
* @param int|stdClass $courseorid The course to get the section name for (either object or just course id)
* @param int|stdClass $section Section object from database or just field course_sections.section
* if omitted the course view page is returned
* @param array $options options for view URL. At the moment core uses:
* 'navigation' (bool) if true and section has no separate page, the function returns null
* 'sr' (int) used by multipage formats to specify to which section to return
* @return moodle_url The url of course
*/
function course_get_url($course, $sectionno = null, $options = array()) {
if ($course->id == SITEID) {
return new moodle_url('/');
}
$url = new moodle_url('/course/view.php', array('id' => $course->id));
$sr = null;
if (array_key_exists('sr', $options)) {
$sr = $options['sr'];
}
if ($sectionno !== null) {
if ($sr !== null) {
if ($sr) {
$usercoursedisplay = COURSE_DISPLAY_MULTIPAGE;
$sectionno = $sr;
} else {
$usercoursedisplay = COURSE_DISPLAY_SINGLEPAGE;
}
} else {
$usercoursedisplay = $course->coursedisplay;
}
if ($sectionno != 0 && $usercoursedisplay == COURSE_DISPLAY_MULTIPAGE) {
$url->param('section', $sectionno);
} else {
if (!empty($options['navigation'])) {
return null;
}
$url->set_anchor('section-'.$sectionno);
}
}
return $url;
function course_get_url($courseorid, $section = null, $options = array()) {
return course_get_format($courseorid)->get_view_url($section, $options);
}
+3 -7
View File
@@ -91,13 +91,9 @@ switch($requestmethod) {
require_capability('moodle/course:movesections', $coursecontext);
move_section_to($course, $id, $value);
// See if format wants to do something about it
$libfile = $CFG->dirroot.'/course/format/'.$course->format.'/lib.php';
$functionname = 'callback_'.$course->format.'_ajax_section_move';
if (!function_exists($functionname) && file_exists($libfile)) {
require_once $libfile;
}
if (function_exists($functionname)) {
echo json_encode($functionname($course));
$response = course_get_format($course)->ajax_section_move();
if ($response !== null) {
echo json_encode($response);
}
break;
}
+17
View File
@@ -2907,3 +2907,20 @@ function textlib_get_instance() {
return new textlib();
}
/**
* Gets the generic section name for a courses section
*
* The global function is deprecated. Each course format can define their own generic section name
*
* @deprecated since 2.4
* @see get_section_name()
* @see format_base::get_section_name()
*
* @param string $format Course format ID e.g. 'weeks' $course->format
* @param stdClass $section Section object from database
* @return Display name that the course format prefers, e.g. "Week 2"
*/
function get_generic_section_name($format, stdClass $section) {
debugging('get_generic_section_name() is deprecated. Please use appropriate functionality from class format_base', DEBUG_DEVELOPER);
return get_string('sectionname', "format_$format") . ' ' . $section->section;
}
+5
View File
@@ -1235,6 +1235,11 @@ function rebuild_course_cache($courseid=0, $clearonly=false) {
// Destroy navigation caches
navigation_cache::destroy_volatile_caches();
if (class_exists('format_base')) {
// if file containing class is not loaded, there is no cache there anyway
format_base::reset_course_cache($courseid);
}
if ($clearonly) {
if (empty($courseid)) {
$DB->set_field('course', 'modinfo', null);
+9 -73
View File
@@ -1252,10 +1252,8 @@ class global_navigation extends navigation_node {
}
// Add the essentials such as reports etc...
$this->add_course_essentials($coursenode, $course);
if ($this->format_display_course_content($course->format)) {
// Load the course sections
$sections = $this->load_course_sections($course, $coursenode);
}
// Extend course navigation with it's sections/activities
$this->load_course_sections($course, $coursenode);
if (!$coursenode->contains_active_node() && !$coursenode->search_for_active_node()) {
$coursenode->make_active();
}
@@ -1384,7 +1382,7 @@ class global_navigation extends navigation_node {
break;
}
$this->add_course_essentials($coursenode, $course);
$sections = $this->load_course_sections($course, $coursenode);
$this->load_course_sections($course, $coursenode);
break;
}
@@ -1486,32 +1484,6 @@ class global_navigation extends navigation_node {
return $this->showcategories;
}
/**
* Checks the course format to see whether it wants the navigation to load
* additional information for the course.
*
* This function utilises a callback that can exist within the course format lib.php file
* The callback should be a function called:
* callback_{formatname}_display_content()
* It doesn't get any arguments and should return true if additional content is
* desired. If the callback doesn't exist we assume additional content is wanted.
*
* @param string $format The course format
* @return bool
*/
protected function format_display_course_content($format) {
global $CFG;
$formatlib = $CFG->dirroot.'/course/format/'.$format.'/lib.php';
if (file_exists($formatlib)) {
require_once($formatlib);
$displayfunc = 'callback_'.$format.'_display_content';
if (function_exists($displayfunc) && !$displayfunc()) {
return $displayfunc();
}
}
return true;
}
/**
* Loads the courses in Moodle into the navigation.
*
@@ -1898,20 +1870,8 @@ class global_navigation extends navigation_node {
*/
protected function load_course_sections(stdClass $course, navigation_node $coursenode) {
global $CFG;
$structurefile = $CFG->dirroot.'/course/format/'.$course->format.'/lib.php';
$structurefunc = 'callback_'.$course->format.'_load_content';
if (function_exists($structurefunc)) {
return $structurefunc($this, $course, $coursenode);
} else if (file_exists($structurefile)) {
require_once $structurefile;
if (function_exists($structurefunc)) {
return $structurefunc($this, $course, $coursenode);
} else {
return $this->load_generic_course_sections($course, $coursenode);
}
} else {
return $this->load_generic_course_sections($course, $coursenode);
}
require_once($CFG->dirroot.'/course/lib.php');
return course_get_format($course)->extend_course_navigation($this, $coursenode);
}
/**
@@ -1980,26 +1940,14 @@ class global_navigation extends navigation_node {
*
* @param stdClass $course
* @param navigation_node $coursenode
* @param string $courseformat The course format
* @return array An array of course section nodes
*/
public function load_generic_course_sections(stdClass $course, navigation_node $coursenode, $courseformat='unknown') {
public function load_generic_course_sections(stdClass $course, navigation_node $coursenode) {
global $CFG, $DB, $USER, $SITE;
require_once($CFG->dirroot.'/course/lib.php');
list($sections, $activities) = $this->generate_sections_and_activities($course);
$namingfunction = 'callback_'.$courseformat.'_get_section_name';
$namingfunctionexists = (function_exists($namingfunction));
$urlfunction = 'callback_'.$courseformat.'_get_section_url';
if (function_exists($urlfunction)) {
// This code path is deprecated but we decided not to warn developers as
// major changes are likely to follow in 2.4. See MDL-32504.
} else {
$urlfunction = null;
}
$key = 0;
if (defined('AJAX_SCRIPT') && AJAX_SCRIPT == '0' && $this->page->url->compare(new moodle_url('/course/view.php'), URL_MATCH_BASE)) {
$key = optional_param('section', $key, PARAM_INT);
@@ -2016,19 +1964,9 @@ class global_navigation extends navigation_node {
continue;
}
if ($namingfunctionexists) {
$sectionname = $namingfunction($course, $section, $sections);
} else {
$sectionname = get_string('section').' '.$section->section;
}
$sectionname = get_section_name($course, $section);
$url = course_get_url($course, $section->section, array('navigation' => true));
$url = null;
if ($urlfunction) {
// pre 2.3 style format url
$url = $urlfunction($course->id, $section->section);
}else{
$url = course_get_url($course, $section->section, array('navigation' => true));
}
$sectionnode = $coursenode->add($sectionname, $url, navigation_node::TYPE_SECTION, null, $section->id);
$sectionnode->nodetype = navigation_node::NODETYPE_BRANCH;
$sectionnode->hidden = (!$section->visible || !$section->available);
@@ -2863,9 +2801,7 @@ class global_navigation_for_ajax extends global_navigation {
$this->page->set_context(context_course::instance($course->id));
$coursenode = $this->add_course($course);
$this->add_course_essentials($coursenode, $course);
if ($this->format_display_course_content($course->format)) {
$this->load_course_sections($course, $coursenode);
}
$this->load_course_sections($course, $coursenode);
break;
case self::TYPE_SECTION :
$sql = 'SELECT c.*, cs.section AS sectionnumber
+5
View File
@@ -7,6 +7,11 @@ information provided here is intended especially for developers.
and page_generic_activity.
* use $CFG->googlemapkey3 instead of removed $CFG->googlemapkey and migrate to Google Maps API V3
* Function settings_navigation::add_course_editing_links() is completely removed
* function get_generic_section_name() is deprecated
* function global_navigation::format_display_course_content() is removed completely (the
functionality is moved to course format class)
* in the function global_navigation::load_generic_course_sections() the argument $courseformat is
removed
YUI changes:
* moodle-enrol-notification has been renamed to moodle-core-notification