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:
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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,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
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user