mirror of
https://github.com/moodle/moodle.git
synced 2025-01-18 05:58:34 +01:00
1eb8ee32bb
MDL-78806 core: Remove redundant site name on page titles * With the site name now being appended to the page titles, there is no need to manually append the page titles.
2423 lines
101 KiB
PHP
2423 lines
101 KiB
PHP
<?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/>.
|
|
|
|
/**
|
|
* Renderer for use with the course section and all the goodness that falls
|
|
* within it.
|
|
*
|
|
* This renderer should contain methods useful to courses, and categories.
|
|
*
|
|
* @package moodlecore
|
|
* @copyright 2010 Sam Hemelryk
|
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
|
*/
|
|
|
|
/**
|
|
* The core course renderer
|
|
*
|
|
* Can be retrieved with the following:
|
|
* $renderer = $PAGE->get_renderer('core','course');
|
|
*/
|
|
class core_course_renderer extends plugin_renderer_base {
|
|
const COURSECAT_SHOW_COURSES_NONE = 0; /* do not show courses at all */
|
|
const COURSECAT_SHOW_COURSES_COUNT = 5; /* do not show courses but show number of courses next to category name */
|
|
const COURSECAT_SHOW_COURSES_COLLAPSED = 10;
|
|
const COURSECAT_SHOW_COURSES_AUTO = 15; /* will choose between collapsed and expanded automatically */
|
|
const COURSECAT_SHOW_COURSES_EXPANDED = 20;
|
|
const COURSECAT_SHOW_COURSES_EXPANDED_WITH_CAT = 30;
|
|
|
|
const COURSECAT_TYPE_CATEGORY = 0;
|
|
const COURSECAT_TYPE_COURSE = 1;
|
|
|
|
/**
|
|
* A cache of strings
|
|
* @var stdClass
|
|
*/
|
|
protected $strings;
|
|
|
|
/**
|
|
* Whether a category content is being initially rendered with children. This is mainly used by the
|
|
* core_course_renderer::corsecat_tree() to render the appropriate action for the Expand/Collapse all link on
|
|
* page load.
|
|
* @var bool
|
|
*/
|
|
protected $categoryexpandedonload = false;
|
|
|
|
/**
|
|
* Override the constructor so that we can initialise the string cache
|
|
*
|
|
* @param moodle_page $page
|
|
* @param string $target
|
|
*/
|
|
public function __construct(moodle_page $page, $target) {
|
|
$this->strings = new stdClass;
|
|
$courseid = $page->course->id;
|
|
parent::__construct($page, $target);
|
|
}
|
|
|
|
/**
|
|
* @deprecated since 3.2
|
|
*/
|
|
protected function add_modchoosertoggle() {
|
|
throw new coding_exception('core_course_renderer::add_modchoosertoggle() can not be used anymore.');
|
|
}
|
|
|
|
/**
|
|
* Renders course info box.
|
|
*
|
|
* @param stdClass $course
|
|
* @return string
|
|
*/
|
|
public function course_info_box(stdClass $course) {
|
|
$content = '';
|
|
$content .= $this->output->box_start('generalbox info');
|
|
$chelper = new coursecat_helper();
|
|
$chelper->set_show_courses(self::COURSECAT_SHOW_COURSES_EXPANDED);
|
|
$content .= $this->coursecat_coursebox($chelper, $course);
|
|
$content .= $this->output->box_end();
|
|
return $content;
|
|
}
|
|
|
|
/**
|
|
* Renderers a structured array of courses and categories into a nice XHTML tree structure.
|
|
*
|
|
* @deprecated since 2.5
|
|
*
|
|
* Please see http://docs.moodle.org/dev/Courses_lists_upgrade_to_2.5
|
|
*
|
|
* @param array $ignored argument ignored
|
|
* @return string
|
|
*/
|
|
public final function course_category_tree(array $ignored) {
|
|
debugging('Function core_course_renderer::course_category_tree() is deprecated, please use frontpage_combo_list()', DEBUG_DEVELOPER);
|
|
return $this->frontpage_combo_list();
|
|
}
|
|
|
|
/**
|
|
* Renderers a category for use with course_category_tree
|
|
*
|
|
* @deprecated since 2.5
|
|
*
|
|
* Please see http://docs.moodle.org/dev/Courses_lists_upgrade_to_2.5
|
|
*
|
|
* @param array $category
|
|
* @param int $depth
|
|
* @return string
|
|
*/
|
|
protected final function course_category_tree_category(stdClass $category, $depth=1) {
|
|
debugging('Function core_course_renderer::course_category_tree_category() is deprecated', DEBUG_DEVELOPER);
|
|
return '';
|
|
}
|
|
|
|
/**
|
|
* Render a modchooser.
|
|
*
|
|
* @param renderable $modchooser The chooser.
|
|
* @return string
|
|
*/
|
|
public function render_modchooser(renderable $modchooser) {
|
|
return $this->render_from_template('core_course/modchooser', $modchooser->export_for_template($this));
|
|
}
|
|
|
|
/**
|
|
* @deprecated since 3.9
|
|
*/
|
|
public function course_modchooser() {
|
|
throw new coding_exception('course_modchooser() can not be used anymore, please use course_activitychooser() instead.');
|
|
}
|
|
|
|
/**
|
|
* Build the HTML for the module chooser javascript popup.
|
|
*
|
|
* @param int $courseid The course id to fetch modules for.
|
|
* @return string
|
|
*/
|
|
public function course_activitychooser($courseid) {
|
|
|
|
if (!$this->page->requires->should_create_one_time_item_now('core_course_modchooser')) {
|
|
return '';
|
|
}
|
|
|
|
// Build an object of config settings that we can then hook into in the Activity Chooser.
|
|
$chooserconfig = (object) [
|
|
'tabmode' => get_config('core', 'activitychoosertabmode'),
|
|
];
|
|
$this->page->requires->js_call_amd('core_course/activitychooser', 'init', [$courseid, $chooserconfig]);
|
|
|
|
return '';
|
|
}
|
|
|
|
/**
|
|
* Build the HTML for a specified set of modules
|
|
*
|
|
* @param array $modules A set of modules as used by the
|
|
* course_modchooser_module function
|
|
* @return string The composed HTML for the module
|
|
*/
|
|
protected function course_modchooser_module_types($modules) {
|
|
debugging('Method core_course_renderer::course_modchooser_module_types() is deprecated, ' .
|
|
'see core_course_renderer::render_modchooser().', DEBUG_DEVELOPER);
|
|
return '';
|
|
}
|
|
|
|
/**
|
|
* Return the HTML for the specified module adding any required classes
|
|
*
|
|
* @param object $module An object containing the title, and link. An
|
|
* icon, and help text may optionally be specified. If the module
|
|
* contains subtypes in the types option, then these will also be
|
|
* displayed.
|
|
* @param array $classes Additional classes to add to the encompassing
|
|
* div element
|
|
* @return string The composed HTML for the module
|
|
*/
|
|
protected function course_modchooser_module($module, $classes = array('option')) {
|
|
debugging('Method core_course_renderer::course_modchooser_module() is deprecated, ' .
|
|
'see core_course_renderer::render_modchooser().', DEBUG_DEVELOPER);
|
|
return '';
|
|
}
|
|
|
|
protected function course_modchooser_title($title, $identifier = null) {
|
|
debugging('Method core_course_renderer::course_modchooser_title() is deprecated, ' .
|
|
'see core_course_renderer::render_modchooser().', DEBUG_DEVELOPER);
|
|
return '';
|
|
}
|
|
|
|
/**
|
|
* Renders HTML for displaying the sequence of course module editing buttons
|
|
*
|
|
* @deprecated since Moodle 4.0 MDL-72656 - please do not use this function any more.
|
|
*
|
|
* @see course_get_cm_edit_actions()
|
|
*
|
|
* @param action_link[] $actions Array of action_link objects
|
|
* @param cm_info $mod The module we are displaying actions for.
|
|
* @param array $displayoptions additional display options:
|
|
* ownerselector => A JS/CSS selector that can be used to find an cm node.
|
|
* If specified the owning node will be given the class 'action-menu-shown' when the action
|
|
* menu is being displayed.
|
|
* donotenhance => If set to true the action menu that gets displayed won't be enhanced by JS.
|
|
* @return string
|
|
*/
|
|
public function course_section_cm_edit_actions($actions, cm_info $mod = null, $displayoptions = array()) {
|
|
global $CFG;
|
|
|
|
debugging(
|
|
'course_section_cm_edit_actions is deprecated. Use core_courseformat\\output\\local\\content\\cm\\controlmenu instead.',
|
|
DEBUG_DEVELOPER
|
|
);
|
|
|
|
if (empty($actions)) {
|
|
return '';
|
|
}
|
|
|
|
if (isset($displayoptions['ownerselector'])) {
|
|
$ownerselector = $displayoptions['ownerselector'];
|
|
} else if ($mod) {
|
|
$ownerselector = '#module-'.$mod->id;
|
|
} else {
|
|
debugging('You should upgrade your call to '.__FUNCTION__.' and provide $mod', DEBUG_DEVELOPER);
|
|
$ownerselector = 'li.activity';
|
|
}
|
|
|
|
$menu = new action_menu();
|
|
$menu->set_owner_selector($ownerselector);
|
|
$menu->set_menu_trigger(get_string('edit'));
|
|
|
|
foreach ($actions as $action) {
|
|
if ($action instanceof action_menu_link) {
|
|
$action->add_class('cm-edit-action');
|
|
}
|
|
$menu->add($action);
|
|
}
|
|
$menu->attributes['class'] .= ' section-cm-edit-actions commands';
|
|
|
|
// Prioritise the menu ahead of all other actions.
|
|
$menu->prioritise = true;
|
|
|
|
return $this->render($menu);
|
|
}
|
|
|
|
/**
|
|
* Renders HTML for the menus to add activities and resources to the current course
|
|
*
|
|
* Renders the ajax control (the link which when clicked produces the activity chooser modal). No noscript fallback.
|
|
*
|
|
* @param stdClass $course
|
|
* @param int $section relative section number (field course_sections.section)
|
|
* @param int $sectionreturn The section to link back to
|
|
* @param array $displayoptions additional display options, for example blocks add
|
|
* option 'inblock' => true, suggesting to display controls vertically
|
|
* @return string
|
|
*/
|
|
function course_section_add_cm_control($course, $section, $sectionreturn = null, $displayoptions = array()) {
|
|
// Check to see if user can add menus.
|
|
if (!has_capability('moodle/course:manageactivities', context_course::instance($course->id))
|
|
|| !$this->page->user_is_editing()) {
|
|
return '';
|
|
}
|
|
|
|
$data = [
|
|
'sectionid' => $section,
|
|
'sectionreturn' => $sectionreturn
|
|
];
|
|
$ajaxcontrol = $this->render_from_template('course/activitychooserbutton', $data);
|
|
|
|
// Load the JS for the modal.
|
|
$this->course_activitychooser($course->id);
|
|
|
|
return $ajaxcontrol;
|
|
}
|
|
|
|
/**
|
|
* Renders html to display a course search form
|
|
*
|
|
* @param string $value default value to populate the search field
|
|
* @return string
|
|
*/
|
|
public function course_search_form($value = '') {
|
|
|
|
$data = [
|
|
'action' => \core_search\manager::get_course_search_url(),
|
|
'btnclass' => 'btn-primary',
|
|
'inputname' => 'q',
|
|
'searchstring' => get_string('searchcourses'),
|
|
'hiddenfields' => (object) ['name' => 'areaids', 'value' => 'core_course-course'],
|
|
'query' => $value
|
|
];
|
|
return $this->render_from_template('core/search_input', $data);
|
|
}
|
|
|
|
/**
|
|
* @deprecated since Moodle 3.11
|
|
*/
|
|
public function course_section_cm_completion() {
|
|
throw new coding_exception(__FUNCTION__ . ' is deprecated. Use the activity_completion output component instead.');
|
|
}
|
|
|
|
/**
|
|
* Checks if course module has any conditions that may make it unavailable for
|
|
* all or some of the students
|
|
*
|
|
* @deprecated since Moodle 4.0 MDL-72656 - please do not use this function any more.
|
|
*
|
|
* @param cm_info $mod
|
|
* @return bool
|
|
*/
|
|
public function is_cm_conditionally_hidden(cm_info $mod) {
|
|
global $CFG;
|
|
|
|
debugging(
|
|
'is_cm_conditionally_hidden is deprecated. Use \core_availability\info_module::is_available_for_all instead',
|
|
DEBUG_DEVELOPER
|
|
);
|
|
|
|
$conditionalhidden = false;
|
|
if (!empty($CFG->enableavailability)) {
|
|
$info = new \core_availability\info_module($mod);
|
|
$conditionalhidden = !$info->is_available_for_all();
|
|
}
|
|
return $conditionalhidden;
|
|
}
|
|
|
|
/**
|
|
* Renders html to display a name with the link to the course module on a course page
|
|
*
|
|
* If module is unavailable for user but still needs to be displayed
|
|
* in the list, just the name is returned without a link
|
|
*
|
|
* Note, that for course modules that never have separate pages (i.e. labels)
|
|
* this function return an empty string
|
|
*
|
|
* @deprecated since Moodle 4.0 MDL-72656 - please do not use this function any more.
|
|
*
|
|
* @param cm_info $mod
|
|
* @param array $displayoptions
|
|
* @return string
|
|
*/
|
|
public function course_section_cm_name(cm_info $mod, $displayoptions = array()) {
|
|
debugging(
|
|
'course_section_cm_name is deprecated. Use core_courseformat\\output\\local\\content\\cm\\cmname class instead.',
|
|
DEBUG_DEVELOPER
|
|
);
|
|
|
|
if (!$mod->is_visible_on_course_page() || !$mod->url) {
|
|
// Nothing to be displayed to the user.
|
|
return '';
|
|
}
|
|
|
|
list($linkclasses, $textclasses) = $this->course_section_cm_classes($mod);
|
|
$groupinglabel = $mod->get_grouping_label($textclasses);
|
|
|
|
// Render element that allows to edit activity name inline.
|
|
$format = course_get_format($mod->course);
|
|
$cmnameclass = $format->get_output_classname('content\\cm\\cmname');
|
|
// Mod inplace name editable.
|
|
$cmname = new $cmnameclass(
|
|
$format,
|
|
$mod->get_section_info(),
|
|
$mod,
|
|
null,
|
|
$displayoptions
|
|
);
|
|
|
|
$renderer = $format->get_renderer($this->page);
|
|
return $renderer->render($cmname) . $groupinglabel;
|
|
}
|
|
|
|
/**
|
|
* Returns the CSS classes for the activity name/content
|
|
*
|
|
* @deprecated since Moodle 4.0 MDL-72656 - please do not use this function any more.
|
|
*
|
|
* For items which are hidden, unavailable or stealth but should be displayed
|
|
* to current user ($mod->is_visible_on_course_page()), we show those as dimmed.
|
|
* Students will also see as dimmed activities names that are not yet available
|
|
* but should still be displayed (without link) with availability info.
|
|
*
|
|
* @param cm_info $mod
|
|
* @return array array of two elements ($linkclasses, $textclasses)
|
|
*/
|
|
protected function course_section_cm_classes(cm_info $mod) {
|
|
|
|
debugging(
|
|
'course_section_cm_classes is deprecated. Now it is part of core_courseformat\\output\\local\\content\\cm ',
|
|
DEBUG_DEVELOPER
|
|
);
|
|
|
|
$format = course_get_format($mod->course);
|
|
|
|
$cmclass = $format->get_output_classname('content\\cm');
|
|
$cmoutput = new $cmclass(
|
|
$format,
|
|
$mod->get_section_info(),
|
|
$mod,
|
|
);
|
|
return [
|
|
$cmoutput->get_link_classes(),
|
|
$cmoutput->get_text_classes(),
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Renders html to display a name with the link to the course module on a course page
|
|
*
|
|
* If module is unavailable for user but still needs to be displayed
|
|
* in the list, just the name is returned without a link
|
|
*
|
|
* Note, that for course modules that never have separate pages (i.e. labels)
|
|
* this function return an empty string
|
|
*
|
|
* @deprecated since Moodle 4.0 MDL-72656 - please do not use this function any more.
|
|
*
|
|
* @param cm_info $mod
|
|
* @param array $displayoptions
|
|
* @return string
|
|
*/
|
|
public function course_section_cm_name_title(cm_info $mod, $displayoptions = array()) {
|
|
|
|
debugging(
|
|
'course_section_cm_name_title is deprecated. Use core_courseformat\\output\\local\\cm\\title class instead.',
|
|
DEBUG_DEVELOPER
|
|
);
|
|
|
|
$output = '';
|
|
$url = $mod->url;
|
|
if (!$mod->is_visible_on_course_page() || !$url) {
|
|
// Nothing to be displayed to the user.
|
|
return $output;
|
|
}
|
|
|
|
//Accessibility: for files get description via icon, this is very ugly hack!
|
|
$instancename = $mod->get_formatted_name();
|
|
$altname = $mod->modfullname;
|
|
// Avoid unnecessary duplication: if e.g. a forum name already
|
|
// includes the word forum (or Forum, etc) then it is unhelpful
|
|
// to include that in the accessible description that is added.
|
|
if (false !== strpos(core_text::strtolower($instancename),
|
|
core_text::strtolower($altname))) {
|
|
$altname = '';
|
|
}
|
|
// File type after name, for alphabetic lists (screen reader).
|
|
if ($altname) {
|
|
$altname = get_accesshide(' '.$altname);
|
|
}
|
|
|
|
list($linkclasses, $textclasses) = $this->course_section_cm_classes($mod);
|
|
|
|
// Get on-click attribute value if specified and decode the onclick - it
|
|
// has already been encoded for display (puke).
|
|
$onclick = htmlspecialchars_decode($mod->onclick, ENT_QUOTES);
|
|
|
|
// Display link itself.
|
|
$instancename = html_writer::tag('span', $instancename . $altname, ['class' => 'instancename ml-1']);
|
|
|
|
$imageicon = html_writer::empty_tag('img', ['src' => $mod->get_icon_url(),
|
|
'class' => 'activityicon', 'alt' => '', 'role' => 'presentation', 'aria-hidden' => 'true']);
|
|
$imageicon = html_writer::tag('span', $imageicon, ['class' => 'activityiconcontainer courseicon']);
|
|
$activitylink = $imageicon . $instancename;
|
|
|
|
if ($mod->uservisible) {
|
|
$output .= html_writer::link($url, $activitylink, array('class' => 'aalink' . $linkclasses, 'onclick' => $onclick));
|
|
} else {
|
|
// We may be displaying this just in order to show information
|
|
// about visibility, without the actual link ($mod->is_visible_on_course_page()).
|
|
$output .= html_writer::tag('div', $activitylink, array('class' => $textclasses));
|
|
}
|
|
return $output;
|
|
}
|
|
|
|
/**
|
|
* Renders html to display the module content on the course page (i.e. text of the labels)
|
|
*
|
|
* @deprecated since Moodle 4.0 MDL-72656 - please do not use this function any more.
|
|
*
|
|
* @param cm_info $mod
|
|
* @param array $displayoptions
|
|
* @return string
|
|
*/
|
|
public function course_section_cm_text(cm_info $mod, $displayoptions = array()) {
|
|
|
|
debugging(
|
|
'course_section_cm_text is deprecated. Now it is part of core_courseformat\\output\\local\\content\\cm ',
|
|
DEBUG_DEVELOPER
|
|
);
|
|
|
|
$output = '';
|
|
if (!$mod->is_visible_on_course_page()) {
|
|
// nothing to be displayed to the user
|
|
return $output;
|
|
}
|
|
$content = $mod->get_formatted_content(array('overflowdiv' => true, 'noclean' => true));
|
|
list($linkclasses, $textclasses) = $this->course_section_cm_classes($mod);
|
|
if ($mod->url && $mod->uservisible) {
|
|
if ($content) {
|
|
// If specified, display extra content after link.
|
|
$output = html_writer::tag('div', $content, array('class' =>
|
|
trim('contentafterlink ' . $textclasses)));
|
|
}
|
|
} else {
|
|
$groupinglabel = $mod->get_grouping_label($textclasses);
|
|
|
|
// No link, so display only content.
|
|
$output = html_writer::tag('div', $content . $groupinglabel,
|
|
array('class' => 'contentwithoutlink ' . $textclasses));
|
|
}
|
|
return $output;
|
|
}
|
|
|
|
/**
|
|
* Displays availability info for a course section or course module
|
|
*
|
|
* @deprecated since Moodle 4.0 MDL-72656 - please do not use this function any more.
|
|
* @param string $text
|
|
* @param string $additionalclasses
|
|
* @return string
|
|
*/
|
|
public function availability_info($text, $additionalclasses = '') {
|
|
|
|
debugging(
|
|
'availability_info is deprecated. Use core_courseformat\\output\\local\\content\\section\\availability instead',
|
|
DEBUG_DEVELOPER
|
|
);
|
|
|
|
$data = ['text' => $text, 'classes' => $additionalclasses];
|
|
$additionalclasses = array_filter(explode(' ', $additionalclasses));
|
|
|
|
if (in_array('ishidden', $additionalclasses)) {
|
|
$data['ishidden'] = 1;
|
|
|
|
} else if (in_array('isstealth', $additionalclasses)) {
|
|
$data['isstealth'] = 1;
|
|
|
|
} else if (in_array('isrestricted', $additionalclasses)) {
|
|
$data['isrestricted'] = 1;
|
|
|
|
if (in_array('isfullinfo', $additionalclasses)) {
|
|
$data['isfullinfo'] = 1;
|
|
}
|
|
}
|
|
|
|
return $this->render_from_template('core/availability_info', $data);
|
|
}
|
|
|
|
/**
|
|
* Renders HTML to show course module availability information (for someone who isn't allowed
|
|
* to see the activity itself, or for staff)
|
|
*
|
|
* @deprecated since Moodle 4.0 MDL-72656 - please do not use this function any more.
|
|
* @param cm_info $mod
|
|
* @param array $displayoptions
|
|
* @return string
|
|
*/
|
|
public function course_section_cm_availability(cm_info $mod, $displayoptions = array()) {
|
|
|
|
debugging(
|
|
'course_section_cm_availability is deprecated. Use core_courseformat\\output\\local\\content\\cm\\availability instead',
|
|
DEBUG_DEVELOPER
|
|
);
|
|
|
|
$format = course_get_format($mod->course);
|
|
|
|
$availabilityclass = $format->get_output_classname('content\\cm\\availability');
|
|
$availability = new $availabilityclass(
|
|
$format,
|
|
$mod->get_section_info(),
|
|
$mod,
|
|
);
|
|
$renderer = $format->get_renderer($this->page);
|
|
return $renderer->render($availability);
|
|
}
|
|
|
|
/**
|
|
* Renders HTML to display one course module for display within a section.
|
|
*
|
|
* @deprecated since 4.0 - use core_course output components or course_format::course_section_updated_cm_item instead.
|
|
*
|
|
* This function calls:
|
|
* {@link core_course_renderer::course_section_cm()}
|
|
*
|
|
* @param stdClass $course
|
|
* @param completion_info $completioninfo
|
|
* @param cm_info $mod
|
|
* @param int|null $sectionreturn
|
|
* @param array $displayoptions
|
|
* @return String
|
|
*/
|
|
public function course_section_cm_list_item($course, &$completioninfo, cm_info $mod, $sectionreturn, $displayoptions = []) {
|
|
|
|
debugging(
|
|
'course_section_cm_list_item is deprecated. Use renderer course_section_updated_cm_item instead',
|
|
DEBUG_DEVELOPER
|
|
);
|
|
|
|
$output = '';
|
|
if ($modulehtml = $this->course_section_cm($course, $completioninfo, $mod, $sectionreturn, $displayoptions)) {
|
|
$modclasses = 'activity ' . $mod->modname . ' modtype_' . $mod->modname . ' ' . $mod->extraclasses;
|
|
$output .= html_writer::tag('li', $modulehtml, array('class' => $modclasses, 'id' => 'module-' . $mod->id));
|
|
}
|
|
return $output;
|
|
}
|
|
|
|
/**
|
|
* Renders HTML to display one course module in a course section
|
|
*
|
|
* This includes link, content, availability, completion info and additional information
|
|
* that module type wants to display (i.e. number of unread forum posts)
|
|
*
|
|
* @deprecated since 4.0 MDL-72656 - use core_course output components instead.
|
|
*
|
|
* @param stdClass $course
|
|
* @param completion_info $completioninfo
|
|
* @param cm_info $mod
|
|
* @param int|null $sectionreturn
|
|
* @param array $displayoptions
|
|
* @return string
|
|
*/
|
|
public function course_section_cm($course, &$completioninfo, cm_info $mod, $sectionreturn, $displayoptions = []) {
|
|
|
|
debugging(
|
|
'course_section_cm is deprecated. Use core_courseformat\\output\\content\\cm output class instead.',
|
|
DEBUG_DEVELOPER
|
|
);
|
|
|
|
if (!$mod->is_visible_on_course_page()) {
|
|
return '';
|
|
}
|
|
|
|
$format = course_get_format($course);
|
|
$modinfo = $format->get_modinfo();
|
|
// Output renderers works only with real section_info objects.
|
|
if ($sectionreturn) {
|
|
$format->set_section_number($sectionreturn);
|
|
}
|
|
$section = $modinfo->get_section_info($format->get_section_number());
|
|
|
|
$cmclass = $format->get_output_classname('content\\cm');
|
|
$cm = new $cmclass($format, $section, $mod, $displayoptions);
|
|
// The course outputs works with format renderers, not with course renderers.
|
|
$renderer = $format->get_renderer($this->page);
|
|
$data = $cm->export_for_template($renderer);
|
|
return $this->output->render_from_template('core_courseformat/local/content/cm', $data);
|
|
}
|
|
|
|
/**
|
|
* Message displayed to the user when they try to access unavailable activity following URL
|
|
*
|
|
* This method is a very simplified version of {@link course_section_cm()} to be part of the error
|
|
* notification only. It also does not check if module is visible on course page or not.
|
|
*
|
|
* The message will be displayed inside notification!
|
|
*
|
|
* @param cm_info $cm
|
|
* @return string
|
|
*/
|
|
public function course_section_cm_unavailable_error_message(cm_info $cm) {
|
|
if ($cm->uservisible) {
|
|
return null;
|
|
}
|
|
if (!$cm->availableinfo) {
|
|
return get_string('activityiscurrentlyhidden');
|
|
}
|
|
|
|
$altname = get_accesshide(' ' . $cm->modfullname);
|
|
$name = html_writer::empty_tag('img', array('src' => $cm->get_icon_url(),
|
|
'class' => 'iconlarge activityicon', 'alt' => ' ', 'role' => 'presentation')) .
|
|
html_writer::tag('span', ' '.$cm->get_formatted_name() . $altname, array('class' => 'instancename'));
|
|
$formattedinfo = \core_availability\info::format_info($cm->availableinfo, $cm->get_course());
|
|
return html_writer::div($name, 'activityinstance-error') .
|
|
html_writer::div($formattedinfo, 'availabilityinfo-error');
|
|
}
|
|
|
|
/**
|
|
* Renders HTML to display a list of course modules in a course section
|
|
* Also displays "move here" controls in Javascript-disabled mode.
|
|
*
|
|
* @deprecated since 4.0 MDL-72656 - use core_course output components instead.
|
|
*
|
|
* This function calls {@link core_course_renderer::course_section_cm()}
|
|
*
|
|
* @param stdClass $course course object
|
|
* @param int|stdClass|section_info $section relative section number or section object
|
|
* @param int $sectionreturn section number to return to
|
|
* @param int $displayoptions
|
|
* @return void
|
|
*/
|
|
public function course_section_cm_list($course, $section, $sectionreturn = null, $displayoptions = []) {
|
|
global $USER;
|
|
|
|
debugging('course_section_cm_list is deprecated. Use core_courseformat\\output\\local\\content\\section\\cmlist '.
|
|
'classes instead.', DEBUG_DEVELOPER);
|
|
|
|
$output = '';
|
|
|
|
$format = course_get_format($course);
|
|
$modinfo = $format->get_modinfo();
|
|
|
|
if (is_object($section)) {
|
|
$section = $modinfo->get_section_info($section->section);
|
|
} else {
|
|
$section = $modinfo->get_section_info($section);
|
|
}
|
|
$completioninfo = new completion_info($course);
|
|
|
|
// check if we are currently in the process of moving a module with JavaScript disabled
|
|
$ismoving = $format->show_editor() && ismoving($course->id);
|
|
|
|
if ($ismoving) {
|
|
$strmovefull = strip_tags(get_string("movefull", "", "'$USER->activitycopyname'"));
|
|
}
|
|
|
|
// Get the list of modules visible to user (excluding the module being moved if there is one)
|
|
$moduleshtml = [];
|
|
if (!empty($modinfo->sections[$section->section])) {
|
|
foreach ($modinfo->sections[$section->section] as $modnumber) {
|
|
$mod = $modinfo->cms[$modnumber];
|
|
|
|
if ($ismoving and $mod->id == $USER->activitycopy) {
|
|
// do not display moving mod
|
|
continue;
|
|
}
|
|
|
|
if ($modulehtml = $this->course_section_cm_list_item($course,
|
|
$completioninfo, $mod, $sectionreturn, $displayoptions)) {
|
|
$moduleshtml[$modnumber] = $modulehtml;
|
|
}
|
|
}
|
|
}
|
|
|
|
$sectionoutput = '';
|
|
if (!empty($moduleshtml) || $ismoving) {
|
|
foreach ($moduleshtml as $modnumber => $modulehtml) {
|
|
if ($ismoving) {
|
|
$movingurl = new moodle_url('/course/mod.php', array('moveto' => $modnumber, 'sesskey' => sesskey()));
|
|
$sectionoutput .= html_writer::tag('li',
|
|
html_writer::link($movingurl, '', array('title' => $strmovefull, 'class' => 'movehere')),
|
|
array('class' => 'movehere'));
|
|
}
|
|
|
|
$sectionoutput .= $modulehtml;
|
|
}
|
|
|
|
if ($ismoving) {
|
|
$movingurl = new moodle_url('/course/mod.php', array('movetosection' => $section->id, 'sesskey' => sesskey()));
|
|
$sectionoutput .= html_writer::tag('li',
|
|
html_writer::link($movingurl, '', array('title' => $strmovefull, 'class' => 'movehere')),
|
|
array('class' => 'movehere'));
|
|
}
|
|
}
|
|
|
|
// Always output the section module list.
|
|
$output .= html_writer::tag('ul', $sectionoutput, array('class' => 'section img-text'));
|
|
|
|
return $output;
|
|
}
|
|
|
|
/**
|
|
* Displays a custom list of courses with paging bar if necessary
|
|
*
|
|
* If $paginationurl is specified but $totalcount is not, the link 'View more'
|
|
* appears under the list.
|
|
*
|
|
* If both $paginationurl and $totalcount are specified, and $totalcount is
|
|
* bigger than count($courses), a paging bar is displayed above and under the
|
|
* courses list.
|
|
*
|
|
* @param array $courses array of course records (or instances of core_course_list_element) to show on this page
|
|
* @param bool $showcategoryname whether to add category name to the course description
|
|
* @param string $additionalclasses additional CSS classes to add to the div.courses
|
|
* @param moodle_url $paginationurl url to view more or url to form links to the other pages in paging bar
|
|
* @param int $totalcount total number of courses on all pages, if omitted $paginationurl will be displayed as 'View more' link
|
|
* @param int $page current page number (defaults to 0 referring to the first page)
|
|
* @param int $perpage number of records per page (defaults to $CFG->coursesperpage)
|
|
* @return string
|
|
*/
|
|
public function courses_list($courses, $showcategoryname = false, $additionalclasses = null, $paginationurl = null, $totalcount = null, $page = 0, $perpage = null) {
|
|
global $CFG;
|
|
// create instance of coursecat_helper to pass display options to function rendering courses list
|
|
$chelper = new coursecat_helper();
|
|
if ($showcategoryname) {
|
|
$chelper->set_show_courses(self::COURSECAT_SHOW_COURSES_EXPANDED_WITH_CAT);
|
|
} else {
|
|
$chelper->set_show_courses(self::COURSECAT_SHOW_COURSES_EXPANDED);
|
|
}
|
|
if ($totalcount !== null && $paginationurl !== null) {
|
|
// add options to display pagination
|
|
if ($perpage === null) {
|
|
$perpage = $CFG->coursesperpage;
|
|
}
|
|
$chelper->set_courses_display_options(array(
|
|
'limit' => $perpage,
|
|
'offset' => ((int)$page) * $perpage,
|
|
'paginationurl' => $paginationurl,
|
|
));
|
|
} else if ($paginationurl !== null) {
|
|
// add options to display 'View more' link
|
|
$chelper->set_courses_display_options(array('viewmoreurl' => $paginationurl));
|
|
$totalcount = count($courses) + 1; // has to be bigger than count($courses) otherwise link will not be displayed
|
|
}
|
|
$chelper->set_attributes(array('class' => $additionalclasses));
|
|
$content = $this->coursecat_courses($chelper, $courses, $totalcount);
|
|
return $content;
|
|
}
|
|
|
|
/**
|
|
* Returns HTML to display course name.
|
|
*
|
|
* @param coursecat_helper $chelper
|
|
* @param core_course_list_element $course
|
|
* @return string
|
|
*/
|
|
protected function course_name(coursecat_helper $chelper, core_course_list_element $course): string {
|
|
$content = '';
|
|
if ($chelper->get_show_courses() >= self::COURSECAT_SHOW_COURSES_EXPANDED) {
|
|
$nametag = 'h3';
|
|
} else {
|
|
$nametag = 'div';
|
|
}
|
|
$coursename = $chelper->get_course_formatted_name($course);
|
|
$coursenamelink = html_writer::link(new moodle_url('/course/view.php', ['id' => $course->id]),
|
|
$coursename, ['class' => $course->visible ? 'aalink' : 'aalink dimmed']);
|
|
$content .= html_writer::tag($nametag, $coursenamelink, ['class' => 'coursename']);
|
|
// If we display course in collapsed form but the course has summary or course contacts, display the link to the info page.
|
|
$content .= html_writer::start_tag('div', ['class' => 'moreinfo']);
|
|
if ($chelper->get_show_courses() < self::COURSECAT_SHOW_COURSES_EXPANDED) {
|
|
if ($course->has_summary() || $course->has_course_contacts() || $course->has_course_overviewfiles()
|
|
|| $course->has_custom_fields()) {
|
|
$url = new moodle_url('/course/info.php', ['id' => $course->id]);
|
|
$image = $this->output->pix_icon('i/info', $this->strings->summary);
|
|
$content .= html_writer::link($url, $image, ['title' => $this->strings->summary]);
|
|
// Make sure JS file to expand course content is included.
|
|
$this->coursecat_include_js();
|
|
}
|
|
}
|
|
$content .= html_writer::end_tag('div');
|
|
return $content;
|
|
}
|
|
|
|
/**
|
|
* Returns HTML to display course enrolment icons.
|
|
*
|
|
* @param core_course_list_element $course
|
|
* @return string
|
|
*/
|
|
protected function course_enrolment_icons(core_course_list_element $course): string {
|
|
$content = '';
|
|
if ($icons = enrol_get_course_info_icons($course)) {
|
|
$content .= html_writer::start_tag('div', ['class' => 'enrolmenticons']);
|
|
foreach ($icons as $icon) {
|
|
$content .= $this->render($icon);
|
|
}
|
|
$content .= html_writer::end_tag('div');
|
|
}
|
|
return $content;
|
|
}
|
|
|
|
/**
|
|
* Displays one course in the list of courses.
|
|
*
|
|
* This is an internal function, to display an information about just one course
|
|
* please use {@link core_course_renderer::course_info_box()}
|
|
*
|
|
* @param coursecat_helper $chelper various display options
|
|
* @param core_course_list_element|stdClass $course
|
|
* @param string $additionalclasses additional classes to add to the main <div> tag (usually
|
|
* depend on the course position in list - first/last/even/odd)
|
|
* @return string
|
|
*/
|
|
protected function coursecat_coursebox(coursecat_helper $chelper, $course, $additionalclasses = '') {
|
|
if (!isset($this->strings->summary)) {
|
|
$this->strings->summary = get_string('summary');
|
|
}
|
|
if ($chelper->get_show_courses() <= self::COURSECAT_SHOW_COURSES_COUNT) {
|
|
return '';
|
|
}
|
|
if ($course instanceof stdClass) {
|
|
$course = new core_course_list_element($course);
|
|
}
|
|
$content = '';
|
|
$classes = trim('coursebox clearfix '. $additionalclasses);
|
|
if ($chelper->get_show_courses() < self::COURSECAT_SHOW_COURSES_EXPANDED) {
|
|
$classes .= ' collapsed';
|
|
}
|
|
|
|
// .coursebox
|
|
$content .= html_writer::start_tag('div', array(
|
|
'class' => $classes,
|
|
'data-courseid' => $course->id,
|
|
'data-type' => self::COURSECAT_TYPE_COURSE,
|
|
));
|
|
|
|
$content .= html_writer::start_tag('div', array('class' => 'info'));
|
|
$content .= $this->course_name($chelper, $course);
|
|
$content .= $this->course_enrolment_icons($course);
|
|
$content .= html_writer::end_tag('div');
|
|
|
|
$content .= html_writer::start_tag('div', array('class' => 'content'));
|
|
$content .= $this->coursecat_coursebox_content($chelper, $course);
|
|
$content .= html_writer::end_tag('div');
|
|
|
|
$content .= html_writer::end_tag('div'); // .coursebox
|
|
return $content;
|
|
}
|
|
|
|
/**
|
|
* Returns HTML to display course summary.
|
|
*
|
|
* @param coursecat_helper $chelper
|
|
* @param core_course_list_element $course
|
|
* @return string
|
|
*/
|
|
protected function course_summary(coursecat_helper $chelper, core_course_list_element $course): string {
|
|
$content = '';
|
|
if ($course->has_summary()) {
|
|
$content .= html_writer::start_tag('div', ['class' => 'summary']);
|
|
$content .= $chelper->get_course_formatted_summary($course,
|
|
array('overflowdiv' => true, 'noclean' => true, 'para' => false));
|
|
$content .= html_writer::end_tag('div');
|
|
}
|
|
return $content;
|
|
}
|
|
|
|
/**
|
|
* Returns HTML to display course contacts.
|
|
*
|
|
* @param core_course_list_element $course
|
|
* @return string
|
|
*/
|
|
protected function course_contacts(core_course_list_element $course) {
|
|
$content = '';
|
|
if ($course->has_course_contacts()) {
|
|
$content .= html_writer::start_tag('ul', ['class' => 'teachers']);
|
|
foreach ($course->get_course_contacts() as $coursecontact) {
|
|
$rolenames = array_map(function ($role) {
|
|
return $role->displayname;
|
|
}, $coursecontact['roles']);
|
|
$name = html_writer::tag('span', implode(", ", $rolenames).': ', ['class' => 'font-weight-bold']);
|
|
$name .= html_writer::link(
|
|
\core_user::get_profile_url($coursecontact['user'], context_system::instance()),
|
|
$coursecontact['username']
|
|
);
|
|
$content .= html_writer::tag('li', $name);
|
|
}
|
|
$content .= html_writer::end_tag('ul');
|
|
}
|
|
return $content;
|
|
}
|
|
|
|
/**
|
|
* Returns HTML to display course overview files.
|
|
*
|
|
* @param core_course_list_element $course
|
|
* @return string
|
|
*/
|
|
protected function course_overview_files(core_course_list_element $course): string {
|
|
global $CFG;
|
|
|
|
$contentimages = $contentfiles = '';
|
|
foreach ($course->get_course_overviewfiles() as $file) {
|
|
$isimage = $file->is_valid_image();
|
|
$url = moodle_url::make_file_url("$CFG->wwwroot/pluginfile.php",
|
|
'/' . $file->get_contextid() . '/' . $file->get_component() . '/' .
|
|
$file->get_filearea() . $file->get_filepath() . $file->get_filename(), !$isimage);
|
|
if ($isimage) {
|
|
$contentimages .= html_writer::tag('div',
|
|
html_writer::empty_tag('img', ['src' => $url, 'alt' => '']),
|
|
['class' => 'courseimage']);
|
|
} else {
|
|
$image = $this->output->pix_icon(file_file_icon($file), $file->get_filename(), 'moodle');
|
|
$filename = html_writer::tag('span', $image, ['class' => 'fp-icon']).
|
|
html_writer::tag('span', $file->get_filename(), ['class' => 'fp-filename']);
|
|
$contentfiles .= html_writer::tag('span',
|
|
html_writer::link($url, $filename),
|
|
['class' => 'coursefile fp-filename-icon text-break']);
|
|
}
|
|
}
|
|
return $contentimages . $contentfiles;
|
|
}
|
|
|
|
/**
|
|
* Returns HTML to display course category name.
|
|
*
|
|
* @param coursecat_helper $chelper
|
|
* @param core_course_list_element $course
|
|
* @return string
|
|
*/
|
|
protected function course_category_name(coursecat_helper $chelper, core_course_list_element $course): string {
|
|
$content = '';
|
|
// Display course category if necessary (for example in search results).
|
|
if ($chelper->get_show_courses() == self::COURSECAT_SHOW_COURSES_EXPANDED_WITH_CAT) {
|
|
if ($cat = core_course_category::get($course->category, IGNORE_MISSING)) {
|
|
$content .= html_writer::start_tag('div', ['class' => 'coursecat']);
|
|
$content .= html_writer::tag('span', get_string('category').': ', ['class' => 'font-weight-bold']);
|
|
$content .= html_writer::link(new moodle_url('/course/index.php', ['categoryid' => $cat->id]),
|
|
$cat->get_formatted_name(), ['class' => $cat->visible ? '' : 'dimmed']);
|
|
$content .= html_writer::end_tag('div');
|
|
}
|
|
}
|
|
return $content;
|
|
}
|
|
|
|
/**
|
|
* Returns HTML to display course custom fields.
|
|
*
|
|
* @param core_course_list_element $course
|
|
* @return string
|
|
*/
|
|
protected function course_custom_fields(core_course_list_element $course): string {
|
|
$content = '';
|
|
if ($course->has_custom_fields()) {
|
|
$handler = core_course\customfield\course_handler::create();
|
|
$customfields = $handler->display_custom_fields_data($course->get_custom_fields());
|
|
$content .= \html_writer::tag('div', $customfields, ['class' => 'customfields-container']);
|
|
}
|
|
return $content;
|
|
}
|
|
|
|
/**
|
|
* Returns HTML to display course content (summary, course contacts and optionally category name)
|
|
*
|
|
* This method is called from coursecat_coursebox() and may be re-used in AJAX
|
|
*
|
|
* @param coursecat_helper $chelper various display options
|
|
* @param stdClass|core_course_list_element $course
|
|
* @return string
|
|
*/
|
|
protected function coursecat_coursebox_content(coursecat_helper $chelper, $course) {
|
|
if ($chelper->get_show_courses() < self::COURSECAT_SHOW_COURSES_EXPANDED) {
|
|
return '';
|
|
}
|
|
if ($course instanceof stdClass) {
|
|
$course = new core_course_list_element($course);
|
|
}
|
|
$content = \html_writer::start_tag('div', ['class' => 'd-flex']);
|
|
$content .= $this->course_overview_files($course);
|
|
$content .= \html_writer::start_tag('div', ['class' => 'flex-grow-1']);
|
|
$content .= $this->course_summary($chelper, $course);
|
|
$content .= $this->course_contacts($course);
|
|
$content .= $this->course_category_name($chelper, $course);
|
|
$content .= $this->course_custom_fields($course);
|
|
$content .= \html_writer::end_tag('div');
|
|
$content .= \html_writer::end_tag('div');
|
|
return $content;
|
|
}
|
|
|
|
/**
|
|
* Renders the list of courses
|
|
*
|
|
* This is internal function, please use {@link core_course_renderer::courses_list()} or another public
|
|
* method from outside of the class
|
|
*
|
|
* If list of courses is specified in $courses; the argument $chelper is only used
|
|
* to retrieve display options and attributes, only methods get_show_courses(),
|
|
* get_courses_display_option() and get_and_erase_attributes() are called.
|
|
*
|
|
* @param coursecat_helper $chelper various display options
|
|
* @param array $courses the list of courses to display
|
|
* @param int|null $totalcount total number of courses (affects display mode if it is AUTO or pagination if applicable),
|
|
* defaulted to count($courses)
|
|
* @return string
|
|
*/
|
|
protected function coursecat_courses(coursecat_helper $chelper, $courses, $totalcount = null) {
|
|
global $CFG;
|
|
if ($totalcount === null) {
|
|
$totalcount = count($courses);
|
|
}
|
|
if (!$totalcount) {
|
|
// Courses count is cached during courses retrieval.
|
|
return '';
|
|
}
|
|
|
|
if ($chelper->get_show_courses() == self::COURSECAT_SHOW_COURSES_AUTO) {
|
|
// In 'auto' course display mode we analyse if number of courses is more or less than $CFG->courseswithsummarieslimit
|
|
if ($totalcount <= $CFG->courseswithsummarieslimit) {
|
|
$chelper->set_show_courses(self::COURSECAT_SHOW_COURSES_EXPANDED);
|
|
} else {
|
|
$chelper->set_show_courses(self::COURSECAT_SHOW_COURSES_COLLAPSED);
|
|
}
|
|
}
|
|
|
|
// prepare content of paging bar if it is needed
|
|
$paginationurl = $chelper->get_courses_display_option('paginationurl');
|
|
$paginationallowall = $chelper->get_courses_display_option('paginationallowall');
|
|
if ($totalcount > count($courses)) {
|
|
// there are more results that can fit on one page
|
|
if ($paginationurl) {
|
|
// the option paginationurl was specified, display pagingbar
|
|
$perpage = $chelper->get_courses_display_option('limit', $CFG->coursesperpage);
|
|
$page = $chelper->get_courses_display_option('offset') / $perpage;
|
|
$pagingbar = $this->paging_bar($totalcount, $page, $perpage,
|
|
$paginationurl->out(false, array('perpage' => $perpage)));
|
|
if ($paginationallowall) {
|
|
$pagingbar .= html_writer::tag('div', html_writer::link($paginationurl->out(false, array('perpage' => 'all')),
|
|
get_string('showall', '', $totalcount)), array('class' => 'paging paging-showall'));
|
|
}
|
|
} else if ($viewmoreurl = $chelper->get_courses_display_option('viewmoreurl')) {
|
|
// the option for 'View more' link was specified, display more link
|
|
$viewmoretext = $chelper->get_courses_display_option('viewmoretext', new lang_string('viewmore'));
|
|
$morelink = html_writer::tag(
|
|
'div',
|
|
html_writer::link($viewmoreurl, $viewmoretext, ['class' => 'btn btn-secondary']),
|
|
['class' => 'paging paging-morelink']
|
|
);
|
|
}
|
|
} else if (($totalcount > $CFG->coursesperpage) && $paginationurl && $paginationallowall) {
|
|
// there are more than one page of results and we are in 'view all' mode, suggest to go back to paginated view mode
|
|
$pagingbar = html_writer::tag('div', html_writer::link($paginationurl->out(false, array('perpage' => $CFG->coursesperpage)),
|
|
get_string('showperpage', '', $CFG->coursesperpage)), array('class' => 'paging paging-showperpage'));
|
|
}
|
|
|
|
// display list of courses
|
|
$attributes = $chelper->get_and_erase_attributes('courses');
|
|
$content = html_writer::start_tag('div', $attributes);
|
|
|
|
if (!empty($pagingbar)) {
|
|
$content .= $pagingbar;
|
|
}
|
|
|
|
$coursecount = 0;
|
|
foreach ($courses as $course) {
|
|
$coursecount ++;
|
|
$classes = ($coursecount%2) ? 'odd' : 'even';
|
|
if ($coursecount == 1) {
|
|
$classes .= ' first';
|
|
}
|
|
if ($coursecount >= count($courses)) {
|
|
$classes .= ' last';
|
|
}
|
|
$content .= $this->coursecat_coursebox($chelper, $course, $classes);
|
|
}
|
|
|
|
if (!empty($pagingbar)) {
|
|
$content .= $pagingbar;
|
|
}
|
|
if (!empty($morelink)) {
|
|
$content .= $morelink;
|
|
}
|
|
|
|
$content .= html_writer::end_tag('div'); // .courses
|
|
return $content;
|
|
}
|
|
|
|
/**
|
|
* Renders the list of subcategories in a category
|
|
*
|
|
* @param coursecat_helper $chelper various display options
|
|
* @param core_course_category $coursecat
|
|
* @param int $depth depth of the category in the current tree
|
|
* @return string
|
|
*/
|
|
protected function coursecat_subcategories(coursecat_helper $chelper, $coursecat, $depth) {
|
|
global $CFG;
|
|
$subcategories = array();
|
|
if (!$chelper->get_categories_display_option('nodisplay')) {
|
|
$subcategories = $coursecat->get_children($chelper->get_categories_display_options());
|
|
}
|
|
$totalcount = $coursecat->get_children_count();
|
|
if (!$totalcount) {
|
|
// Note that we call core_course_category::get_children_count() AFTER core_course_category::get_children()
|
|
// to avoid extra DB requests.
|
|
// Categories count is cached during children categories retrieval.
|
|
return '';
|
|
}
|
|
|
|
// prepare content of paging bar or more link if it is needed
|
|
$paginationurl = $chelper->get_categories_display_option('paginationurl');
|
|
$paginationallowall = $chelper->get_categories_display_option('paginationallowall');
|
|
if ($totalcount > count($subcategories)) {
|
|
if ($paginationurl) {
|
|
// the option 'paginationurl was specified, display pagingbar
|
|
$perpage = $chelper->get_categories_display_option('limit', $CFG->coursesperpage);
|
|
$page = $chelper->get_categories_display_option('offset') / $perpage;
|
|
$pagingbar = $this->paging_bar($totalcount, $page, $perpage,
|
|
$paginationurl->out(false, array('perpage' => $perpage)));
|
|
if ($paginationallowall) {
|
|
$pagingbar .= html_writer::tag('div', html_writer::link($paginationurl->out(false, array('perpage' => 'all')),
|
|
get_string('showall', '', $totalcount)), array('class' => 'paging paging-showall'));
|
|
}
|
|
} else if ($viewmoreurl = $chelper->get_categories_display_option('viewmoreurl')) {
|
|
// the option 'viewmoreurl' was specified, display more link (if it is link to category view page, add category id)
|
|
if ($viewmoreurl->compare(new moodle_url('/course/index.php'), URL_MATCH_BASE)) {
|
|
$viewmoreurl->param('categoryid', $coursecat->id);
|
|
}
|
|
$viewmoretext = $chelper->get_categories_display_option('viewmoretext', new lang_string('viewmore'));
|
|
$morelink = html_writer::tag('div', html_writer::link($viewmoreurl, $viewmoretext),
|
|
array('class' => 'paging paging-morelink'));
|
|
}
|
|
} else if (($totalcount > $CFG->coursesperpage) && $paginationurl && $paginationallowall) {
|
|
// there are more than one page of results and we are in 'view all' mode, suggest to go back to paginated view mode
|
|
$pagingbar = html_writer::tag('div', html_writer::link($paginationurl->out(false, array('perpage' => $CFG->coursesperpage)),
|
|
get_string('showperpage', '', $CFG->coursesperpage)), array('class' => 'paging paging-showperpage'));
|
|
}
|
|
|
|
// display list of subcategories
|
|
$content = html_writer::start_tag('div', array('class' => 'subcategories'));
|
|
|
|
if (!empty($pagingbar)) {
|
|
$content .= $pagingbar;
|
|
}
|
|
|
|
foreach ($subcategories as $subcategory) {
|
|
$content .= $this->coursecat_category($chelper, $subcategory, $depth + 1);
|
|
}
|
|
|
|
if (!empty($pagingbar)) {
|
|
$content .= $pagingbar;
|
|
}
|
|
if (!empty($morelink)) {
|
|
$content .= $morelink;
|
|
}
|
|
|
|
$content .= html_writer::end_tag('div');
|
|
return $content;
|
|
}
|
|
|
|
/**
|
|
* Make sure that javascript file for AJAX expanding of courses and categories content is included
|
|
*/
|
|
protected function coursecat_include_js() {
|
|
if (!$this->page->requires->should_create_one_time_item_now('core_course_categoryexpanderjsinit')) {
|
|
return;
|
|
}
|
|
|
|
// We must only load this module once.
|
|
$this->page->requires->yui_module('moodle-course-categoryexpander',
|
|
'Y.Moodle.course.categoryexpander.init');
|
|
}
|
|
|
|
/**
|
|
* Returns HTML to display the subcategories and courses in the given category
|
|
*
|
|
* This method is re-used by AJAX to expand content of not loaded category
|
|
*
|
|
* @param coursecat_helper $chelper various display options
|
|
* @param core_course_category $coursecat
|
|
* @param int $depth depth of the category in the current tree
|
|
* @return string
|
|
*/
|
|
protected function coursecat_category_content(coursecat_helper $chelper, $coursecat, $depth) {
|
|
$content = '';
|
|
// Subcategories
|
|
$content .= $this->coursecat_subcategories($chelper, $coursecat, $depth);
|
|
|
|
// AUTO show courses: Courses will be shown expanded if this is not nested category,
|
|
// and number of courses no bigger than $CFG->courseswithsummarieslimit.
|
|
$showcoursesauto = $chelper->get_show_courses() == self::COURSECAT_SHOW_COURSES_AUTO;
|
|
if ($showcoursesauto && $depth) {
|
|
// this is definitely collapsed mode
|
|
$chelper->set_show_courses(self::COURSECAT_SHOW_COURSES_COLLAPSED);
|
|
}
|
|
|
|
// Courses
|
|
if ($chelper->get_show_courses() > core_course_renderer::COURSECAT_SHOW_COURSES_COUNT) {
|
|
$courses = array();
|
|
if (!$chelper->get_courses_display_option('nodisplay')) {
|
|
$courses = $coursecat->get_courses($chelper->get_courses_display_options());
|
|
}
|
|
if ($viewmoreurl = $chelper->get_courses_display_option('viewmoreurl')) {
|
|
// the option for 'View more' link was specified, display more link (if it is link to category view page, add category id)
|
|
if ($viewmoreurl->compare(new moodle_url('/course/index.php'), URL_MATCH_BASE)) {
|
|
$chelper->set_courses_display_option('viewmoreurl', new moodle_url($viewmoreurl, array('categoryid' => $coursecat->id)));
|
|
}
|
|
}
|
|
$content .= $this->coursecat_courses($chelper, $courses, $coursecat->get_courses_count());
|
|
}
|
|
|
|
if ($showcoursesauto) {
|
|
// restore the show_courses back to AUTO
|
|
$chelper->set_show_courses(self::COURSECAT_SHOW_COURSES_AUTO);
|
|
}
|
|
|
|
return $content;
|
|
}
|
|
|
|
/**
|
|
* Returns HTML to display a course category as a part of a tree
|
|
*
|
|
* This is an internal function, to display a particular category and all its contents
|
|
* use {@link core_course_renderer::course_category()}
|
|
*
|
|
* @param coursecat_helper $chelper various display options
|
|
* @param core_course_category $coursecat
|
|
* @param int $depth depth of this category in the current tree
|
|
* @return string
|
|
*/
|
|
protected function coursecat_category(coursecat_helper $chelper, $coursecat, $depth) {
|
|
// open category tag
|
|
$classes = array('category');
|
|
if (empty($coursecat->visible)) {
|
|
$classes[] = 'dimmed_category';
|
|
}
|
|
if ($chelper->get_subcat_depth() > 0 && $depth >= $chelper->get_subcat_depth()) {
|
|
// do not load content
|
|
$categorycontent = '';
|
|
$classes[] = 'notloaded';
|
|
if ($coursecat->get_children_count() ||
|
|
($chelper->get_show_courses() >= self::COURSECAT_SHOW_COURSES_COLLAPSED && $coursecat->get_courses_count())) {
|
|
$classes[] = 'with_children';
|
|
$classes[] = 'collapsed';
|
|
}
|
|
} else {
|
|
// load category content
|
|
$categorycontent = $this->coursecat_category_content($chelper, $coursecat, $depth);
|
|
$classes[] = 'loaded';
|
|
if (!empty($categorycontent)) {
|
|
$classes[] = 'with_children';
|
|
// Category content loaded with children.
|
|
$this->categoryexpandedonload = true;
|
|
}
|
|
}
|
|
|
|
// Make sure JS file to expand category content is included.
|
|
$this->coursecat_include_js();
|
|
|
|
$content = html_writer::start_tag('div', array(
|
|
'class' => join(' ', $classes),
|
|
'data-categoryid' => $coursecat->id,
|
|
'data-depth' => $depth,
|
|
'data-showcourses' => $chelper->get_show_courses(),
|
|
'data-type' => self::COURSECAT_TYPE_CATEGORY,
|
|
));
|
|
|
|
// category name
|
|
$categoryname = $coursecat->get_formatted_name();
|
|
$categoryname = html_writer::link(new moodle_url('/course/index.php',
|
|
array('categoryid' => $coursecat->id)),
|
|
$categoryname);
|
|
if ($chelper->get_show_courses() == self::COURSECAT_SHOW_COURSES_COUNT
|
|
&& ($coursescount = $coursecat->get_courses_count())) {
|
|
$categoryname .= html_writer::tag('span', ' ('. $coursescount.')',
|
|
array('title' => get_string('numberofcourses'), 'class' => 'numberofcourse'));
|
|
}
|
|
$content .= html_writer::start_tag('div', array('class' => 'info'));
|
|
|
|
$content .= html_writer::tag(($depth > 1) ? 'h4' : 'h3', $categoryname, array('class' => 'categoryname aabtn'));
|
|
$content .= html_writer::end_tag('div'); // .info
|
|
|
|
// add category content to the output
|
|
$content .= html_writer::tag('div', $categorycontent, array('class' => 'content'));
|
|
|
|
$content .= html_writer::end_tag('div'); // .category
|
|
|
|
// Return the course category tree HTML
|
|
return $content;
|
|
}
|
|
|
|
/**
|
|
* Returns HTML to display a tree of subcategories and courses in the given category
|
|
*
|
|
* @param coursecat_helper $chelper various display options
|
|
* @param core_course_category $coursecat top category (this category's name and description will NOT be added to the tree)
|
|
* @return string
|
|
*/
|
|
protected function coursecat_tree(coursecat_helper $chelper, $coursecat) {
|
|
// Reset the category expanded flag for this course category tree first.
|
|
$this->categoryexpandedonload = false;
|
|
$categorycontent = $this->coursecat_category_content($chelper, $coursecat, 0);
|
|
if (empty($categorycontent)) {
|
|
return '';
|
|
}
|
|
|
|
// Start content generation
|
|
$content = '';
|
|
$attributes = $chelper->get_and_erase_attributes('course_category_tree clearfix');
|
|
$content .= html_writer::start_tag('div', $attributes);
|
|
|
|
if ($coursecat->get_children_count()) {
|
|
$classes = array(
|
|
'collapseexpand', 'aabtn'
|
|
);
|
|
|
|
// Check if the category content contains subcategories with children's content loaded.
|
|
if ($this->categoryexpandedonload) {
|
|
$classes[] = 'collapse-all';
|
|
$linkname = get_string('collapseall');
|
|
} else {
|
|
$linkname = get_string('expandall');
|
|
}
|
|
|
|
// Only show the collapse/expand if there are children to expand.
|
|
$content .= html_writer::start_tag('div', array('class' => 'collapsible-actions'));
|
|
$content .= html_writer::link('#', $linkname, array('class' => implode(' ', $classes)));
|
|
$content .= html_writer::end_tag('div');
|
|
$this->page->requires->strings_for_js(array('collapseall', 'expandall'), 'moodle');
|
|
}
|
|
|
|
$content .= html_writer::tag('div', $categorycontent, array('class' => 'content'));
|
|
|
|
$content .= html_writer::end_tag('div'); // .course_category_tree
|
|
|
|
return $content;
|
|
}
|
|
|
|
/**
|
|
* Renders HTML to display particular course category - list of it's subcategories and courses
|
|
*
|
|
* Invoked from /course/index.php
|
|
*
|
|
* @param int|stdClass|core_course_category $category
|
|
*/
|
|
public function course_category($category) {
|
|
global $CFG;
|
|
$usertop = core_course_category::user_top();
|
|
if (empty($category)) {
|
|
$coursecat = $usertop;
|
|
} else if (is_object($category) && $category instanceof core_course_category) {
|
|
$coursecat = $category;
|
|
} else {
|
|
$coursecat = core_course_category::get(is_object($category) ? $category->id : $category);
|
|
}
|
|
$site = get_site();
|
|
$actionbar = new \core_course\output\category_action_bar($this->page, $coursecat);
|
|
$output = $this->render_from_template('core_course/category_actionbar', $actionbar->export_for_template($this));
|
|
|
|
if (core_course_category::is_simple_site()) {
|
|
// There is only one category in the system, do not display link to it.
|
|
$strfulllistofcourses = get_string('fulllistofcourses');
|
|
$this->page->set_title($strfulllistofcourses);
|
|
} else if (!$coursecat->id || !$coursecat->is_uservisible()) {
|
|
$strcategories = get_string('categories');
|
|
$this->page->set_title($strcategories);
|
|
} else {
|
|
$strfulllistofcourses = get_string('fulllistofcourses');
|
|
$this->page->set_title($strfulllistofcourses);
|
|
}
|
|
|
|
// Print current category description
|
|
$chelper = new coursecat_helper();
|
|
if ($description = $chelper->get_category_formatted_description($coursecat)) {
|
|
$output .= $this->box($description, array('class' => 'generalbox info'));
|
|
}
|
|
|
|
// Prepare parameters for courses and categories lists in the tree
|
|
$chelper->set_show_courses(self::COURSECAT_SHOW_COURSES_AUTO)
|
|
->set_attributes(array('class' => 'category-browse category-browse-'.$coursecat->id));
|
|
|
|
$coursedisplayoptions = array();
|
|
$catdisplayoptions = array();
|
|
$browse = optional_param('browse', null, PARAM_ALPHA);
|
|
$perpage = optional_param('perpage', $CFG->coursesperpage, PARAM_INT);
|
|
$page = optional_param('page', 0, PARAM_INT);
|
|
$baseurl = new moodle_url('/course/index.php');
|
|
if ($coursecat->id) {
|
|
$baseurl->param('categoryid', $coursecat->id);
|
|
}
|
|
if ($perpage != $CFG->coursesperpage) {
|
|
$baseurl->param('perpage', $perpage);
|
|
}
|
|
$coursedisplayoptions['limit'] = $perpage;
|
|
$catdisplayoptions['limit'] = $perpage;
|
|
if ($browse === 'courses' || !$coursecat->get_children_count()) {
|
|
$coursedisplayoptions['offset'] = $page * $perpage;
|
|
$coursedisplayoptions['paginationurl'] = new moodle_url($baseurl, array('browse' => 'courses'));
|
|
$catdisplayoptions['nodisplay'] = true;
|
|
$catdisplayoptions['viewmoreurl'] = new moodle_url($baseurl, array('browse' => 'categories'));
|
|
$catdisplayoptions['viewmoretext'] = new lang_string('viewallsubcategories');
|
|
} else if ($browse === 'categories' || !$coursecat->get_courses_count()) {
|
|
$coursedisplayoptions['nodisplay'] = true;
|
|
$catdisplayoptions['offset'] = $page * $perpage;
|
|
$catdisplayoptions['paginationurl'] = new moodle_url($baseurl, array('browse' => 'categories'));
|
|
$coursedisplayoptions['viewmoreurl'] = new moodle_url($baseurl, array('browse' => 'courses'));
|
|
$coursedisplayoptions['viewmoretext'] = new lang_string('viewallcourses');
|
|
} else {
|
|
// we have a category that has both subcategories and courses, display pagination separately
|
|
$coursedisplayoptions['viewmoreurl'] = new moodle_url($baseurl, array('browse' => 'courses', 'page' => 1));
|
|
$catdisplayoptions['viewmoreurl'] = new moodle_url($baseurl, array('browse' => 'categories', 'page' => 1));
|
|
}
|
|
$chelper->set_courses_display_options($coursedisplayoptions)->set_categories_display_options($catdisplayoptions);
|
|
|
|
// Display course category tree.
|
|
$output .= $this->coursecat_tree($chelper, $coursecat);
|
|
|
|
return $output;
|
|
}
|
|
|
|
/**
|
|
* Serves requests to /course/category.ajax.php
|
|
*
|
|
* In this renderer implementation it may expand the category content or
|
|
* course content.
|
|
*
|
|
* @return string
|
|
* @throws coding_exception
|
|
*/
|
|
public function coursecat_ajax() {
|
|
global $DB, $CFG;
|
|
|
|
$type = required_param('type', PARAM_INT);
|
|
|
|
if ($type === self::COURSECAT_TYPE_CATEGORY) {
|
|
// This is a request for a category list of some kind.
|
|
$categoryid = required_param('categoryid', PARAM_INT);
|
|
$showcourses = required_param('showcourses', PARAM_INT);
|
|
$depth = required_param('depth', PARAM_INT);
|
|
|
|
$category = core_course_category::get($categoryid);
|
|
|
|
$chelper = new coursecat_helper();
|
|
$baseurl = new moodle_url('/course/index.php', array('categoryid' => $categoryid));
|
|
$coursedisplayoptions = array(
|
|
'limit' => $CFG->coursesperpage,
|
|
'viewmoreurl' => new moodle_url($baseurl, array('browse' => 'courses', 'page' => 1))
|
|
);
|
|
$catdisplayoptions = array(
|
|
'limit' => $CFG->coursesperpage,
|
|
'viewmoreurl' => new moodle_url($baseurl, array('browse' => 'categories', 'page' => 1))
|
|
);
|
|
$chelper->set_show_courses($showcourses)->
|
|
set_courses_display_options($coursedisplayoptions)->
|
|
set_categories_display_options($catdisplayoptions);
|
|
|
|
return $this->coursecat_category_content($chelper, $category, $depth);
|
|
} else if ($type === self::COURSECAT_TYPE_COURSE) {
|
|
// This is a request for the course information.
|
|
$courseid = required_param('courseid', PARAM_INT);
|
|
|
|
$course = $DB->get_record('course', array('id' => $courseid), '*', MUST_EXIST);
|
|
|
|
$chelper = new coursecat_helper();
|
|
$chelper->set_show_courses(self::COURSECAT_SHOW_COURSES_EXPANDED);
|
|
return $this->coursecat_coursebox_content($chelper, $course);
|
|
} else {
|
|
throw new coding_exception('Invalid request type');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Renders html to display search result page
|
|
*
|
|
* @param array $searchcriteria may contain elements: search, blocklist, modulelist, tagid
|
|
* @return string
|
|
*/
|
|
public function search_courses($searchcriteria) {
|
|
global $CFG;
|
|
$content = '';
|
|
|
|
$search = '';
|
|
if (!empty($searchcriteria['search'])) {
|
|
$search = $searchcriteria['search'];
|
|
}
|
|
$content .= $this->course_search_form($search);
|
|
|
|
if (!empty($searchcriteria)) {
|
|
// print search results
|
|
|
|
$displayoptions = array('sort' => array('displayname' => 1));
|
|
// take the current page and number of results per page from query
|
|
$perpage = optional_param('perpage', 0, PARAM_RAW);
|
|
if ($perpage !== 'all') {
|
|
$displayoptions['limit'] = ((int)$perpage <= 0) ? $CFG->coursesperpage : (int)$perpage;
|
|
$page = optional_param('page', 0, PARAM_INT);
|
|
$displayoptions['offset'] = $displayoptions['limit'] * $page;
|
|
}
|
|
// options 'paginationurl' and 'paginationallowall' are only used in method coursecat_courses()
|
|
$displayoptions['paginationurl'] = new moodle_url('/course/search.php', $searchcriteria);
|
|
$displayoptions['paginationallowall'] = true; // allow adding link 'View all'
|
|
|
|
$class = 'course-search-result';
|
|
foreach ($searchcriteria as $key => $value) {
|
|
if (!empty($value)) {
|
|
$class .= ' course-search-result-'. $key;
|
|
}
|
|
}
|
|
$chelper = new coursecat_helper();
|
|
$chelper->set_show_courses(self::COURSECAT_SHOW_COURSES_EXPANDED_WITH_CAT)->
|
|
set_courses_display_options($displayoptions)->
|
|
set_search_criteria($searchcriteria)->
|
|
set_attributes(array('class' => $class));
|
|
|
|
$courses = core_course_category::search_courses($searchcriteria, $chelper->get_courses_display_options());
|
|
$totalcount = core_course_category::search_courses_count($searchcriteria);
|
|
$courseslist = $this->coursecat_courses($chelper, $courses, $totalcount);
|
|
|
|
if (!$totalcount) {
|
|
if (!empty($searchcriteria['search'])) {
|
|
$content .= $this->heading(get_string('nocoursesfound', '', $searchcriteria['search']));
|
|
} else {
|
|
$content .= $this->heading(get_string('novalidcourses'));
|
|
}
|
|
} else {
|
|
$content .= $this->heading(get_string('searchresults'). ": $totalcount");
|
|
$content .= $courseslist;
|
|
}
|
|
}
|
|
return $content;
|
|
}
|
|
|
|
/**
|
|
* Renders html to print list of courses tagged with particular tag
|
|
*
|
|
* @param int $tagid id of the tag
|
|
* @param bool $exclusivemode if set to true it means that no other entities tagged with this tag
|
|
* are displayed on the page and the per-page limit may be bigger
|
|
* @param int $fromctx context id where the link was displayed, may be used by callbacks
|
|
* to display items in the same context first
|
|
* @param int $ctx context id where to search for records
|
|
* @param bool $rec search in subcontexts as well
|
|
* @param array $displayoptions
|
|
* @return string empty string if no courses are marked with this tag or rendered list of courses
|
|
*/
|
|
public function tagged_courses($tagid, $exclusivemode = true, $ctx = 0, $rec = true, $displayoptions = null) {
|
|
global $CFG;
|
|
if (empty($displayoptions)) {
|
|
$displayoptions = array();
|
|
}
|
|
$showcategories = !core_course_category::is_simple_site();
|
|
$displayoptions += array('limit' => $CFG->coursesperpage, 'offset' => 0);
|
|
$chelper = new coursecat_helper();
|
|
$searchcriteria = array('tagid' => $tagid, 'ctx' => $ctx, 'rec' => $rec);
|
|
$chelper->set_show_courses($showcategories ? self::COURSECAT_SHOW_COURSES_EXPANDED_WITH_CAT :
|
|
self::COURSECAT_SHOW_COURSES_EXPANDED)->
|
|
set_search_criteria($searchcriteria)->
|
|
set_courses_display_options($displayoptions)->
|
|
set_attributes(array('class' => 'course-search-result course-search-result-tagid'));
|
|
// (we set the same css class as in search results by tagid)
|
|
if ($totalcount = core_course_category::search_courses_count($searchcriteria)) {
|
|
$courses = core_course_category::search_courses($searchcriteria, $chelper->get_courses_display_options());
|
|
if ($exclusivemode) {
|
|
return $this->coursecat_courses($chelper, $courses, $totalcount);
|
|
} else {
|
|
$tagfeed = new core_tag\output\tagfeed();
|
|
$img = $this->output->pix_icon('i/course', '');
|
|
foreach ($courses as $course) {
|
|
$url = course_get_url($course);
|
|
$imgwithlink = html_writer::link($url, $img);
|
|
$coursename = html_writer::link($url, $course->get_formatted_name());
|
|
$details = '';
|
|
if ($showcategories && ($cat = core_course_category::get($course->category, IGNORE_MISSING))) {
|
|
$details = get_string('category').': '.
|
|
html_writer::link(new moodle_url('/course/index.php', array('categoryid' => $cat->id)),
|
|
$cat->get_formatted_name(), array('class' => $cat->visible ? '' : 'dimmed'));
|
|
}
|
|
$tagfeed->add($imgwithlink, $coursename, $details);
|
|
}
|
|
return $this->output->render_from_template('core_tag/tagfeed', $tagfeed->export_for_template($this->output));
|
|
}
|
|
}
|
|
return '';
|
|
}
|
|
|
|
/**
|
|
* Returns HTML to display one remote course
|
|
*
|
|
* @param stdClass $course remote course information, contains properties:
|
|
id, remoteid, shortname, fullname, hostid, summary, summaryformat, cat_name, hostname
|
|
* @return string
|
|
*/
|
|
protected function frontpage_remote_course(stdClass $course) {
|
|
$url = new moodle_url('/auth/mnet/jump.php', array(
|
|
'hostid' => $course->hostid,
|
|
'wantsurl' => '/course/view.php?id='. $course->remoteid
|
|
));
|
|
|
|
$output = '';
|
|
$output .= html_writer::start_tag('div', array('class' => 'coursebox remotecoursebox clearfix'));
|
|
$output .= html_writer::start_tag('div', array('class' => 'info'));
|
|
$output .= html_writer::start_tag('h3', array('class' => 'coursename'));
|
|
$output .= html_writer::link($url, format_string($course->fullname), array('title' => get_string('entercourse')));
|
|
$output .= html_writer::end_tag('h3'); // .name
|
|
$output .= html_writer::tag('div', '', array('class' => 'moreinfo'));
|
|
$output .= html_writer::end_tag('div'); // .info
|
|
$output .= html_writer::start_tag('div', array('class' => 'content'));
|
|
$output .= html_writer::start_tag('div', array('class' => 'summary'));
|
|
$options = new stdClass();
|
|
$options->noclean = true;
|
|
$options->para = false;
|
|
$options->overflowdiv = true;
|
|
$output .= format_text($course->summary, $course->summaryformat, $options);
|
|
$output .= html_writer::end_tag('div'); // .summary
|
|
$addinfo = format_string($course->hostname) . ' : '
|
|
. format_string($course->cat_name) . ' : '
|
|
. format_string($course->shortname);
|
|
$output .= html_writer::tag('div', $addinfo, array('class' => 'remotecourseinfo'));
|
|
$output .= html_writer::end_tag('div'); // .content
|
|
$output .= html_writer::end_tag('div'); // .coursebox
|
|
return $output;
|
|
}
|
|
|
|
/**
|
|
* Returns HTML to display one remote host
|
|
*
|
|
* @param array $host host information, contains properties: name, url, count
|
|
* @return string
|
|
*/
|
|
protected function frontpage_remote_host($host) {
|
|
$output = '';
|
|
$output .= html_writer::start_tag('div', array('class' => 'coursebox remotehost clearfix'));
|
|
$output .= html_writer::start_tag('div', array('class' => 'info'));
|
|
$output .= html_writer::start_tag('h3', array('class' => 'name'));
|
|
$output .= html_writer::link($host['url'], s($host['name']), array('title' => s($host['name'])));
|
|
$output .= html_writer::end_tag('h3'); // .name
|
|
$output .= html_writer::tag('div', '', array('class' => 'moreinfo'));
|
|
$output .= html_writer::end_tag('div'); // .info
|
|
$output .= html_writer::start_tag('div', array('class' => 'content'));
|
|
$output .= html_writer::start_tag('div', array('class' => 'summary'));
|
|
$output .= $host['count'] . ' ' . get_string('courses');
|
|
$output .= html_writer::end_tag('div'); // .content
|
|
$output .= html_writer::end_tag('div'); // .coursebox
|
|
return $output;
|
|
}
|
|
|
|
/**
|
|
* Returns HTML to print list of courses user is enrolled to for the frontpage
|
|
*
|
|
* Also lists remote courses or remote hosts if MNET authorisation is used
|
|
*
|
|
* @return string
|
|
*/
|
|
public function frontpage_my_courses() {
|
|
global $USER, $CFG, $DB;
|
|
|
|
if (!isloggedin() or isguestuser()) {
|
|
return '';
|
|
}
|
|
|
|
$output = '';
|
|
$courses = enrol_get_my_courses('summary, summaryformat');
|
|
$rhosts = array();
|
|
$rcourses = array();
|
|
if (!empty($CFG->mnet_dispatcher_mode) && $CFG->mnet_dispatcher_mode==='strict') {
|
|
$rcourses = get_my_remotecourses($USER->id);
|
|
$rhosts = get_my_remotehosts();
|
|
}
|
|
|
|
if (!empty($courses) || !empty($rcourses) || !empty($rhosts)) {
|
|
|
|
$chelper = new coursecat_helper();
|
|
$totalcount = count($courses);
|
|
if (count($courses) > $CFG->frontpagecourselimit) {
|
|
// There are more enrolled courses than we can display, display link to 'My courses'.
|
|
$courses = array_slice($courses, 0, $CFG->frontpagecourselimit, true);
|
|
$chelper->set_courses_display_options(array(
|
|
'viewmoreurl' => new moodle_url('/my/courses.php'),
|
|
'viewmoretext' => new lang_string('mycourses')
|
|
));
|
|
} else if (core_course_category::top()->is_uservisible()) {
|
|
// All enrolled courses are displayed, display link to 'All courses' if there are more courses in system.
|
|
$chelper->set_courses_display_options(array(
|
|
'viewmoreurl' => new moodle_url('/course/index.php'),
|
|
'viewmoretext' => new lang_string('fulllistofcourses')
|
|
));
|
|
$totalcount = $DB->count_records('course') - 1;
|
|
}
|
|
$chelper->set_show_courses(self::COURSECAT_SHOW_COURSES_EXPANDED)->
|
|
set_attributes(array('class' => 'frontpage-course-list-enrolled'));
|
|
$output .= $this->coursecat_courses($chelper, $courses, $totalcount);
|
|
|
|
// MNET
|
|
if (!empty($rcourses)) {
|
|
// at the IDP, we know of all the remote courses
|
|
$output .= html_writer::start_tag('div', array('class' => 'courses'));
|
|
foreach ($rcourses as $course) {
|
|
$output .= $this->frontpage_remote_course($course);
|
|
}
|
|
$output .= html_writer::end_tag('div'); // .courses
|
|
} elseif (!empty($rhosts)) {
|
|
// non-IDP, we know of all the remote servers, but not courses
|
|
$output .= html_writer::start_tag('div', array('class' => 'courses'));
|
|
foreach ($rhosts as $host) {
|
|
$output .= $this->frontpage_remote_host($host);
|
|
}
|
|
$output .= html_writer::end_tag('div'); // .courses
|
|
}
|
|
}
|
|
return $output;
|
|
}
|
|
|
|
/**
|
|
* Returns HTML to print list of available courses for the frontpage
|
|
*
|
|
* @return string
|
|
*/
|
|
public function frontpage_available_courses() {
|
|
global $CFG;
|
|
|
|
$chelper = new coursecat_helper();
|
|
$chelper->set_show_courses(self::COURSECAT_SHOW_COURSES_EXPANDED)->
|
|
set_courses_display_options(array(
|
|
'recursive' => true,
|
|
'limit' => $CFG->frontpagecourselimit,
|
|
'viewmoreurl' => new moodle_url('/course/index.php'),
|
|
'viewmoretext' => new lang_string('fulllistofcourses')));
|
|
|
|
$chelper->set_attributes(array('class' => 'frontpage-course-list-all'));
|
|
$courses = core_course_category::top()->get_courses($chelper->get_courses_display_options());
|
|
$totalcount = core_course_category::top()->get_courses_count($chelper->get_courses_display_options());
|
|
if (!$totalcount && !$this->page->user_is_editing() && has_capability('moodle/course:create', context_system::instance())) {
|
|
// Print link to create a new course, for the 1st available category.
|
|
return $this->add_new_course_button();
|
|
}
|
|
return $this->coursecat_courses($chelper, $courses, $totalcount);
|
|
}
|
|
|
|
/**
|
|
* Returns HTML to the "add new course" button for the page
|
|
*
|
|
* @return string
|
|
*/
|
|
public function add_new_course_button() {
|
|
global $CFG;
|
|
// Print link to create a new course, for the 1st available category.
|
|
$output = $this->container_start('buttons');
|
|
$url = new moodle_url('/course/edit.php', array('category' => $CFG->defaultrequestcategory, 'returnto' => 'topcat'));
|
|
$output .= $this->single_button($url, get_string('addnewcourse'), 'get');
|
|
$output .= $this->container_end('buttons');
|
|
return $output;
|
|
}
|
|
|
|
/**
|
|
* Returns HTML to print tree with course categories and courses for the frontpage
|
|
*
|
|
* @return string
|
|
*/
|
|
public function frontpage_combo_list() {
|
|
global $CFG;
|
|
// TODO MDL-10965 improve.
|
|
$tree = core_course_category::top();
|
|
if (!$tree->get_children_count()) {
|
|
return '';
|
|
}
|
|
$chelper = new coursecat_helper();
|
|
$chelper->set_subcat_depth($CFG->maxcategorydepth)->
|
|
set_categories_display_options(array(
|
|
'limit' => $CFG->coursesperpage,
|
|
'viewmoreurl' => new moodle_url('/course/index.php',
|
|
array('browse' => 'categories', 'page' => 1))
|
|
))->
|
|
set_courses_display_options(array(
|
|
'limit' => $CFG->coursesperpage,
|
|
'viewmoreurl' => new moodle_url('/course/index.php',
|
|
array('browse' => 'courses', 'page' => 1))
|
|
))->
|
|
set_attributes(array('class' => 'frontpage-category-combo'));
|
|
return $this->coursecat_tree($chelper, $tree);
|
|
}
|
|
|
|
/**
|
|
* Returns HTML to print tree of course categories (with number of courses) for the frontpage
|
|
*
|
|
* @return string
|
|
*/
|
|
public function frontpage_categories_list() {
|
|
global $CFG;
|
|
// TODO MDL-10965 improve.
|
|
$tree = core_course_category::top();
|
|
if (!$tree->get_children_count()) {
|
|
return '';
|
|
}
|
|
$chelper = new coursecat_helper();
|
|
$chelper->set_subcat_depth($CFG->maxcategorydepth)->
|
|
set_show_courses(self::COURSECAT_SHOW_COURSES_COUNT)->
|
|
set_categories_display_options(array(
|
|
'limit' => $CFG->coursesperpage,
|
|
'viewmoreurl' => new moodle_url('/course/index.php',
|
|
array('browse' => 'categories', 'page' => 1))
|
|
))->
|
|
set_attributes(array('class' => 'frontpage-category-names'));
|
|
return $this->coursecat_tree($chelper, $tree);
|
|
}
|
|
|
|
/**
|
|
* Renders the activity information.
|
|
*
|
|
* Defer to template.
|
|
*
|
|
* @deprecated since Moodle 4.3 MDL-78744
|
|
* @todo MDL-78926 This method will be deleted in Moodle 4.7
|
|
* @param \core_course\output\activity_information $page
|
|
* @return string html for the page
|
|
*/
|
|
public function render_activity_information(\core_course\output\activity_information $page) {
|
|
debugging('render_activity_information method is deprecated.', DEBUG_DEVELOPER);
|
|
$data = $page->export_for_template($this->output);
|
|
return $this->output->render_from_template('core_course/activity_info', $data);
|
|
}
|
|
|
|
/**
|
|
* Renders the activity navigation.
|
|
*
|
|
* Defer to template.
|
|
*
|
|
* @param \core_course\output\activity_navigation $page
|
|
* @return string html for the page
|
|
*/
|
|
public function render_activity_navigation(\core_course\output\activity_navigation $page) {
|
|
$data = $page->export_for_template($this->output);
|
|
return $this->output->render_from_template('core_course/activity_navigation', $data);
|
|
}
|
|
|
|
/**
|
|
* Display waiting information about backup size during uploading backup process
|
|
* @param object $backupfile the backup stored_file
|
|
* @return $html string
|
|
*/
|
|
public function sendingbackupinfo($backupfile) {
|
|
$sizeinfo = new stdClass();
|
|
$sizeinfo->total = number_format($backupfile->get_filesize() / 1000000, 2);
|
|
$html = html_writer::tag('div', get_string('sendingsize', 'hub', $sizeinfo),
|
|
array('class' => 'courseuploadtextinfo'));
|
|
return $html;
|
|
}
|
|
|
|
/**
|
|
* Hub information (logo - name - description - link)
|
|
* @param object $hubinfo
|
|
* @return string html code
|
|
*/
|
|
public function hubinfo($hubinfo) {
|
|
$screenshothtml = html_writer::empty_tag('img',
|
|
array('src' => $hubinfo['imgurl'], 'alt' => $hubinfo['name']));
|
|
$hubdescription = html_writer::tag('div', $screenshothtml,
|
|
array('class' => 'hubscreenshot'));
|
|
|
|
$hubdescription .= html_writer::tag('a', $hubinfo['name'],
|
|
array('class' => 'hublink', 'href' => $hubinfo['url'],
|
|
'onclick' => 'this.target="_blank"'));
|
|
|
|
$hubdescription .= html_writer::tag('div', format_text($hubinfo['description'], FORMAT_PLAIN),
|
|
array('class' => 'hubdescription'));
|
|
$hubdescription = html_writer::tag('div', $hubdescription, array('class' => 'hubinfo clearfix'));
|
|
|
|
return $hubdescription;
|
|
}
|
|
|
|
/**
|
|
* Output frontpage summary text and frontpage modules (stored as section 1 in site course)
|
|
*
|
|
* This may be disabled in settings
|
|
*
|
|
* @return string
|
|
*/
|
|
public function frontpage_section1() {
|
|
global $SITE, $USER;
|
|
|
|
$output = '';
|
|
$editing = $this->page->user_is_editing();
|
|
|
|
if ($editing) {
|
|
// Make sure section with number 1 exists.
|
|
course_create_sections_if_missing($SITE, 1);
|
|
}
|
|
|
|
$modinfo = get_fast_modinfo($SITE);
|
|
$section = $modinfo->get_section_info(1);
|
|
|
|
|
|
if (($section && (!empty($modinfo->sections[1]) or !empty($section->summary))) or $editing) {
|
|
|
|
$format = course_get_format($SITE);
|
|
$frontpageclass = $format->get_output_classname('content\\frontpagesection');
|
|
$frontpagesection = new $frontpageclass($format, $section);
|
|
|
|
// The course outputs works with format renderers, not with course renderers.
|
|
$renderer = $format->get_renderer($this->page);
|
|
$output .= $renderer->render($frontpagesection);
|
|
}
|
|
|
|
return $output;
|
|
}
|
|
|
|
/**
|
|
* Output news for the frontpage (extract from site-wide news forum)
|
|
*
|
|
* @param stdClass $forum record from db table 'forum' that represents the site news forum
|
|
* @return string
|
|
*/
|
|
protected function frontpage_news($forum) {
|
|
global $CFG, $SITE, $SESSION, $USER;
|
|
require_once($CFG->dirroot .'/mod/forum/lib.php');
|
|
|
|
$output = '';
|
|
|
|
if (isloggedin()) {
|
|
$SESSION->fromdiscussion = $CFG->wwwroot;
|
|
$subtext = '';
|
|
if (\mod_forum\subscriptions::is_subscribed($USER->id, $forum)) {
|
|
if (!\mod_forum\subscriptions::is_forcesubscribed($forum)) {
|
|
$subtext = get_string('unsubscribe', 'forum');
|
|
}
|
|
} else {
|
|
$subtext = get_string('subscribe', 'forum');
|
|
}
|
|
$suburl = new moodle_url('/mod/forum/subscribe.php', array('id' => $forum->id, 'sesskey' => sesskey()));
|
|
$output .= html_writer::tag('div', html_writer::link($suburl, $subtext), array('class' => 'subscribelink'));
|
|
}
|
|
|
|
$coursemodule = get_coursemodule_from_instance('forum', $forum->id);
|
|
$context = context_module::instance($coursemodule->id);
|
|
|
|
$entityfactory = mod_forum\local\container::get_entity_factory();
|
|
$forumentity = $entityfactory->get_forum_from_stdclass($forum, $context, $coursemodule, $SITE);
|
|
|
|
$rendererfactory = mod_forum\local\container::get_renderer_factory();
|
|
$discussionsrenderer = $rendererfactory->get_frontpage_news_discussion_list_renderer($forumentity);
|
|
$cm = \cm_info::create($coursemodule);
|
|
return $output . $discussionsrenderer->render($USER, $cm, null, null, 0, $SITE->newsitems);
|
|
}
|
|
|
|
/**
|
|
* Renders part of frontpage with a skip link (i.e. "My courses", "Site news", etc.)
|
|
*
|
|
* @param string $skipdivid
|
|
* @param string $contentsdivid
|
|
* @param string $header Header of the part
|
|
* @param string $contents Contents of the part
|
|
* @return string
|
|
*/
|
|
protected function frontpage_part($skipdivid, $contentsdivid, $header, $contents) {
|
|
if (strval($contents) === '') {
|
|
return '';
|
|
}
|
|
$output = html_writer::link('#' . $skipdivid,
|
|
get_string('skipa', 'access', core_text::strtolower(strip_tags($header))),
|
|
array('class' => 'skip-block skip aabtn'));
|
|
|
|
// Wrap frontpage part in div container.
|
|
$output .= html_writer::start_tag('div', array('id' => $contentsdivid));
|
|
$output .= $this->heading($header);
|
|
|
|
$output .= $contents;
|
|
|
|
// End frontpage part div container.
|
|
$output .= html_writer::end_tag('div');
|
|
|
|
$output .= html_writer::tag('span', '', array('class' => 'skip-block-to', 'id' => $skipdivid));
|
|
return $output;
|
|
}
|
|
|
|
/**
|
|
* Outputs contents for frontpage as configured in $CFG->frontpage or $CFG->frontpageloggedin
|
|
*
|
|
* @return string
|
|
*/
|
|
public function frontpage() {
|
|
global $CFG, $SITE;
|
|
|
|
$output = '';
|
|
|
|
if (isloggedin() and !isguestuser() and isset($CFG->frontpageloggedin)) {
|
|
$frontpagelayout = $CFG->frontpageloggedin;
|
|
} else {
|
|
$frontpagelayout = $CFG->frontpage;
|
|
}
|
|
|
|
foreach (explode(',', $frontpagelayout) as $v) {
|
|
switch ($v) {
|
|
// Display the main part of the front page.
|
|
case FRONTPAGENEWS:
|
|
if ($SITE->newsitems) {
|
|
// Print forums only when needed.
|
|
require_once($CFG->dirroot .'/mod/forum/lib.php');
|
|
if (($newsforum = forum_get_course_forum($SITE->id, 'news')) &&
|
|
($forumcontents = $this->frontpage_news($newsforum))) {
|
|
$newsforumcm = get_fast_modinfo($SITE)->instances['forum'][$newsforum->id];
|
|
$output .= $this->frontpage_part('skipsitenews', 'site-news-forum',
|
|
$newsforumcm->get_formatted_name(), $forumcontents);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case FRONTPAGEENROLLEDCOURSELIST:
|
|
$mycourseshtml = $this->frontpage_my_courses();
|
|
if (!empty($mycourseshtml)) {
|
|
$output .= $this->frontpage_part('skipmycourses', 'frontpage-course-list',
|
|
get_string('mycourses'), $mycourseshtml);
|
|
}
|
|
break;
|
|
|
|
case FRONTPAGEALLCOURSELIST:
|
|
$availablecourseshtml = $this->frontpage_available_courses();
|
|
$output .= $this->frontpage_part('skipavailablecourses', 'frontpage-available-course-list',
|
|
get_string('availablecourses'), $availablecourseshtml);
|
|
break;
|
|
|
|
case FRONTPAGECATEGORYNAMES:
|
|
$output .= $this->frontpage_part('skipcategories', 'frontpage-category-names',
|
|
get_string('categories'), $this->frontpage_categories_list());
|
|
break;
|
|
|
|
case FRONTPAGECATEGORYCOMBO:
|
|
$output .= $this->frontpage_part('skipcourses', 'frontpage-category-combo',
|
|
get_string('courses'), $this->frontpage_combo_list());
|
|
break;
|
|
|
|
case FRONTPAGECOURSESEARCH:
|
|
$output .= $this->box($this->course_search_form(''), 'd-flex justify-content-center');
|
|
break;
|
|
|
|
}
|
|
$output .= '<br />';
|
|
}
|
|
|
|
return $output;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Class storing display options and functions to help display course category and/or courses lists
|
|
*
|
|
* This is a wrapper for core_course_category objects that also stores display options
|
|
* and functions to retrieve sorted and paginated lists of categories/courses.
|
|
*
|
|
* If theme overrides methods in core_course_renderers that access this class
|
|
* it may as well not use this class at all or extend it.
|
|
*
|
|
* @package core
|
|
* @copyright 2013 Marina Glancy
|
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
|
*/
|
|
class coursecat_helper {
|
|
/** @var string [none, collapsed, expanded] how (if) display courses list */
|
|
protected $showcourses = 10; /* core_course_renderer::COURSECAT_SHOW_COURSES_COLLAPSED */
|
|
/** @var int depth to expand subcategories in the tree (deeper subcategories will be loaded by AJAX or proceed to category page by clicking on category name) */
|
|
protected $subcatdepth = 1;
|
|
/** @var array options to display courses list */
|
|
protected $coursesdisplayoptions = array();
|
|
/** @var array options to display subcategories list */
|
|
protected $categoriesdisplayoptions = array();
|
|
/** @var array additional HTML attributes */
|
|
protected $attributes = array();
|
|
/** @var array search criteria if the list is a search result */
|
|
protected $searchcriteria = null;
|
|
|
|
/**
|
|
* Sets how (if) to show the courses - none, collapsed, expanded, etc.
|
|
*
|
|
* @param int $showcourses SHOW_COURSES_NONE, SHOW_COURSES_COLLAPSED, SHOW_COURSES_EXPANDED, etc.
|
|
* @return coursecat_helper
|
|
*/
|
|
public function set_show_courses($showcourses) {
|
|
$this->showcourses = $showcourses;
|
|
// Automatically set the options to preload summary and coursecontacts for core_course_category::get_courses()
|
|
// and core_course_category::search_courses().
|
|
$this->coursesdisplayoptions['summary'] = $showcourses >= core_course_renderer::COURSECAT_SHOW_COURSES_AUTO;
|
|
$this->coursesdisplayoptions['coursecontacts'] = $showcourses >= core_course_renderer::COURSECAT_SHOW_COURSES_EXPANDED;
|
|
$this->coursesdisplayoptions['customfields'] = $showcourses >= core_course_renderer::COURSECAT_SHOW_COURSES_COLLAPSED;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Returns how (if) to show the courses - none, collapsed, expanded, etc.
|
|
*
|
|
* @return int - COURSECAT_SHOW_COURSES_NONE, COURSECAT_SHOW_COURSES_COLLAPSED, COURSECAT_SHOW_COURSES_EXPANDED, etc.
|
|
*/
|
|
public function get_show_courses() {
|
|
return $this->showcourses;
|
|
}
|
|
|
|
/**
|
|
* Sets the maximum depth to expand subcategories in the tree
|
|
*
|
|
* deeper subcategories may be loaded by AJAX or proceed to category page by clicking on category name
|
|
*
|
|
* @param int $subcatdepth
|
|
* @return coursecat_helper
|
|
*/
|
|
public function set_subcat_depth($subcatdepth) {
|
|
$this->subcatdepth = $subcatdepth;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Returns the maximum depth to expand subcategories in the tree
|
|
*
|
|
* deeper subcategories may be loaded by AJAX or proceed to category page by clicking on category name
|
|
*
|
|
* @return int
|
|
*/
|
|
public function get_subcat_depth() {
|
|
return $this->subcatdepth;
|
|
}
|
|
|
|
/**
|
|
* Sets options to display list of courses
|
|
*
|
|
* Options are later submitted as argument to core_course_category::get_courses() and/or core_course_category::search_courses()
|
|
*
|
|
* Options that core_course_category::get_courses() accept:
|
|
* - recursive - return courses from subcategories as well. Use with care,
|
|
* this may be a huge list!
|
|
* - summary - preloads fields 'summary' and 'summaryformat'
|
|
* - coursecontacts - preloads course contacts
|
|
* - customfields - preloads custom fields data
|
|
* - isenrolled - preloads indication whether this user is enrolled in the course
|
|
* - sort - list of fields to sort. Example
|
|
* array('idnumber' => 1, 'shortname' => 1, 'id' => -1)
|
|
* will sort by idnumber asc, shortname asc and id desc.
|
|
* Default: array('sortorder' => 1)
|
|
* Only cached fields may be used for sorting!
|
|
* - offset
|
|
* - limit - maximum number of children to return, 0 or null for no limit
|
|
*
|
|
* Options summary and coursecontacts are filled automatically in the set_show_courses()
|
|
*
|
|
* Also renderer can set here any additional options it wants to pass between renderer functions.
|
|
*
|
|
* @param array $options
|
|
* @return coursecat_helper
|
|
*/
|
|
public function set_courses_display_options($options) {
|
|
$this->coursesdisplayoptions = $options;
|
|
$this->set_show_courses($this->showcourses); // this will calculate special display options
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Sets one option to display list of courses
|
|
*
|
|
* @see coursecat_helper::set_courses_display_options()
|
|
*
|
|
* @param string $key
|
|
* @param mixed $value
|
|
* @return coursecat_helper
|
|
*/
|
|
public function set_courses_display_option($key, $value) {
|
|
$this->coursesdisplayoptions[$key] = $value;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Return the specified option to display list of courses
|
|
*
|
|
* @param string $optionname option name
|
|
* @param mixed $defaultvalue default value for option if it is not specified
|
|
* @return mixed
|
|
*/
|
|
public function get_courses_display_option($optionname, $defaultvalue = null) {
|
|
if (array_key_exists($optionname, $this->coursesdisplayoptions)) {
|
|
return $this->coursesdisplayoptions[$optionname];
|
|
} else {
|
|
return $defaultvalue;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns all options to display the courses
|
|
*
|
|
* This array is usually passed to {@link core_course_category::get_courses()} or
|
|
* {@link core_course_category::search_courses()}
|
|
*
|
|
* @return array
|
|
*/
|
|
public function get_courses_display_options() {
|
|
return $this->coursesdisplayoptions;
|
|
}
|
|
|
|
/**
|
|
* Sets options to display list of subcategories
|
|
*
|
|
* Options 'sort', 'offset' and 'limit' are passed to core_course_category::get_children().
|
|
* Any other options may be used by renderer functions
|
|
*
|
|
* @param array $options
|
|
* @return coursecat_helper
|
|
*/
|
|
public function set_categories_display_options($options) {
|
|
$this->categoriesdisplayoptions = $options;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Return the specified option to display list of subcategories
|
|
*
|
|
* @param string $optionname option name
|
|
* @param mixed $defaultvalue default value for option if it is not specified
|
|
* @return mixed
|
|
*/
|
|
public function get_categories_display_option($optionname, $defaultvalue = null) {
|
|
if (array_key_exists($optionname, $this->categoriesdisplayoptions)) {
|
|
return $this->categoriesdisplayoptions[$optionname];
|
|
} else {
|
|
return $defaultvalue;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns all options to display list of subcategories
|
|
*
|
|
* This array is usually passed to {@link core_course_category::get_children()}
|
|
*
|
|
* @return array
|
|
*/
|
|
public function get_categories_display_options() {
|
|
return $this->categoriesdisplayoptions;
|
|
}
|
|
|
|
/**
|
|
* Sets additional general options to pass between renderer functions, usually HTML attributes
|
|
*
|
|
* @param array $attributes
|
|
* @return coursecat_helper
|
|
*/
|
|
public function set_attributes($attributes) {
|
|
$this->attributes = $attributes;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Return all attributes and erases them so they are not applied again
|
|
*
|
|
* @param string $classname adds additional class name to the beginning of $attributes['class']
|
|
* @return array
|
|
*/
|
|
public function get_and_erase_attributes($classname) {
|
|
$attributes = $this->attributes;
|
|
$this->attributes = array();
|
|
if (empty($attributes['class'])) {
|
|
$attributes['class'] = '';
|
|
}
|
|
$attributes['class'] = $classname . ' '. $attributes['class'];
|
|
return $attributes;
|
|
}
|
|
|
|
/**
|
|
* Sets the search criteria if the course is a search result
|
|
*
|
|
* Search string will be used to highlight terms in course name and description
|
|
*
|
|
* @param array $searchcriteria
|
|
* @return coursecat_helper
|
|
*/
|
|
public function set_search_criteria($searchcriteria) {
|
|
$this->searchcriteria = $searchcriteria;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Returns formatted and filtered description of the given category
|
|
*
|
|
* @param core_course_category $coursecat category
|
|
* @param stdClass|array $options format options, by default [noclean,overflowdiv],
|
|
* if context is not specified it will be added automatically
|
|
* @return string|null
|
|
*/
|
|
public function get_category_formatted_description($coursecat, $options = null) {
|
|
if ($coursecat->id && $coursecat->is_uservisible() && !empty($coursecat->description)) {
|
|
if (!isset($coursecat->descriptionformat)) {
|
|
$descriptionformat = FORMAT_MOODLE;
|
|
} else {
|
|
$descriptionformat = $coursecat->descriptionformat;
|
|
}
|
|
if ($options === null) {
|
|
$options = array('noclean' => true, 'overflowdiv' => true);
|
|
} else {
|
|
$options = (array)$options;
|
|
}
|
|
$context = context_coursecat::instance($coursecat->id);
|
|
if (!isset($options['context'])) {
|
|
$options['context'] = $context;
|
|
}
|
|
$text = file_rewrite_pluginfile_urls($coursecat->description,
|
|
'pluginfile.php', $context->id, 'coursecat', 'description', null);
|
|
return format_text($text, $descriptionformat, $options);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Returns given course's summary with proper embedded files urls and formatted
|
|
*
|
|
* @param core_course_list_element $course
|
|
* @param array|stdClass $options additional formatting options
|
|
* @return string
|
|
*/
|
|
public function get_course_formatted_summary($course, $options = array()) {
|
|
global $CFG;
|
|
require_once($CFG->libdir. '/filelib.php');
|
|
if (!$course->has_summary()) {
|
|
return '';
|
|
}
|
|
$options = (array)$options;
|
|
$context = context_course::instance($course->id);
|
|
if (!isset($options['context'])) {
|
|
// TODO see MDL-38521
|
|
// option 1 (current), page context - no code required
|
|
// option 2, system context
|
|
// $options['context'] = context_system::instance();
|
|
// option 3, course context:
|
|
// $options['context'] = $context;
|
|
// option 4, course category context:
|
|
// $options['context'] = $context->get_parent_context();
|
|
}
|
|
$summary = file_rewrite_pluginfile_urls($course->summary, 'pluginfile.php', $context->id, 'course', 'summary', null);
|
|
$summary = format_text($summary, $course->summaryformat, $options, $course->id);
|
|
if (!empty($this->searchcriteria['search'])) {
|
|
$summary = highlight($this->searchcriteria['search'], $summary);
|
|
}
|
|
return $summary;
|
|
}
|
|
|
|
/**
|
|
* Returns course name as it is configured to appear in courses lists formatted to course context
|
|
*
|
|
* @param core_course_list_element $course
|
|
* @param array|stdClass $options additional formatting options
|
|
* @return string
|
|
*/
|
|
public function get_course_formatted_name($course, $options = array()) {
|
|
$options = (array)$options;
|
|
if (!isset($options['context'])) {
|
|
$options['context'] = context_course::instance($course->id);
|
|
}
|
|
$name = format_string(get_course_display_name_for_list($course), true, $options);
|
|
if (!empty($this->searchcriteria['search'])) {
|
|
$name = highlight($this->searchcriteria['search'], $name);
|
|
}
|
|
return $name;
|
|
}
|
|
}
|