Commit 8e7dc424 authored by Ferran Recio Calderó's avatar Ferran Recio Calderó
Browse files

MDL-65974 course: move format renderers to outputs

parent 1c839f90
......@@ -967,7 +967,6 @@ abstract class course_format {
public function editsection_form($action, $customdata = array()) {
global $CFG;
require_once($CFG->dirroot. '/course/editsection_form.php');
$context = context_course::instance($this->courseid);
if (!array_key_exists('course', $customdata)) {
$customdata['course'] = $this->get_course();
}
......@@ -1091,6 +1090,18 @@ abstract class course_format {
return ($sectionnum && ($course = $this->get_course()) && $course->marker == $sectionnum);
}
/**
* return true if the course editor must be displayed.
*
* @return bool true if edit controls must be displayed
*/
public function show_editor(): bool {
global $PAGE;
$course = $this->get_course();
$coursecontext = context_course::instance($course->id);
return $PAGE->user_is_editing() && has_capability('moodle/course:update', $coursecontext);
}
/**
* Allows to specify for modinfo that section is not available even when it is visible and conditionally available.
*
......@@ -1387,16 +1398,13 @@ abstract class course_format {
}
// Load the cmlist output.
$cmitemclass = $this->get_output_classname('section_format\\cmitem');
$renderer = $this->get_renderer($PAGE);
$coursesections = $modinfo->sections;
if (array_key_exists($section->section, $coursesections)) {
$completioninfo = new completion_info($course);
foreach ($coursesections[$section->section] as $cmid) {
$cm = $modinfo->get_cm($cmid);
$cmitem = new $cmitemclass($this, $section, $cm);
$modules[] = $renderer->render($cmitem);
$modules[] = $renderer->course_section_updated_cm_item($this, $section, $cm);
}
}
......
<?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/>.
/**
* Contains the default activity list from a section.
*
* @package core_course
* @copyright 2020 Ferran Recio <ferran@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_course\output;
use core_course\course_format;
use section_info;
use completion_info;
use renderable;
use templatable;
use cm_info;
use stdClass;
/**
* Base class to render a course module inside a course format.
*
* @package core_course
* @copyright 2020 Ferran Recio <ferran@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class cm_format implements renderable, templatable {
/** @var course_format the course format */
protected $format;
/** @var section_info the section object */
private $section;
/** @var cm_info the course module instance */
protected $mod;
/** @var array optional display options */
protected $displayoptions;
/** @var completion_info the course completion */
protected $completioninfo;
/**
* Constructor.
*
* @param course_format $format the course format
* @param section_info $section the section info
* @param completion_info $completioninfo the course completion info
* @param cm_info $mod the course module ionfo
* @param array $displayoptions optional extra display options
*/
public function __construct(course_format $format, section_info $section, completion_info $completioninfo,
cm_info $mod, array $displayoptions = []) {
$this->format = $format;
$this->section = $section;
$this->completioninfo = $completioninfo;
$this->mod = $mod;
$this->displayoptions = $displayoptions;
}
/**
* Export this data so it can be used as the context for a mustache template.
*
* @param renderer_base $output typically, the renderer that's calling this function
* @return stdClass data context for a mustache template
*/
public function export_for_template(\renderer_base $output): stdClass {
$format = $this->format;
$course = $format->get_course();
$mod = $this->mod;
$displayoptions = $this->displayoptions;
$data = (object)[
'cmname' => $output->course_section_cm_name($mod, $displayoptions),
'afterlink' => $mod->afterlink,
'altcontent' => $output->course_section_cm_text($mod, $displayoptions),
'availability' => $output->course_section_cm_availability($mod, $displayoptions),
'url' => $mod->url,
'completion' => $output->course_section_cm_completion(
$course, $this->completioninfo, $mod, $displayoptions
),
];
if (!empty($mod->indent)) {
$data->indent = $mod->indent;
if ($mod->indent > 15) {
$data->hugeindent = true;
}
}
if (!empty($data->cmname)) {
$data->hasname = true;
}
if (!empty($data->url)) {
$data->hasurl = true;
}
$returnsection = $format->get_section_number();
$data->extras = [];
if ($format->show_editor()) {
// Edit actions.
$editactions = course_get_cm_edit_actions($mod, $mod->indent, $returnsection);
$data->extras[] = $output->course_section_cm_edit_actions($editactions, $mod, $displayoptions);
if (!empty($mod->afterediticons)) {
$data->extras[] = $mod->afterediticons;
}
// Move and select options.
$data->moveicon = course_get_cm_move($mod, $returnsection);
}
if (!empty($data->completion) || !empty($data->extras)) {
$data->hasextras = true;
}
return $data;
}
}
<?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/>.
/**
* Contains the main course format out class.
*
* @package core_course
* @copyright 2020 Ferran Recio <ferran@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_course\output;
use core_course\course_format as course_format_base;
use course_modinfo;
use renderable;
use templatable;
use stdClass;
/**
* Base class to render a course format.
*
* @package core_course
* @copyright 2020 Ferran Recio <ferran@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class course_format implements renderable, templatable {
/** @var core_course\course_format the course format class */
protected $format;
/** @var string the section format class */
protected $sectionclass;
/** @var string the add section output class name */
protected $addsectionclass;
/** @var string section navigation class name */
protected $sectionnavigationclass;
/** @var string section selector class name */
protected $sectionselectorclass;
/**
* Constructor.
*
* @param course_format_base $format the coruse format
*/
public function __construct(course_format_base $format) {
$this->format = $format;
// Load output classes names from format.
$this->sectionclass = $format->get_output_classname('section_format');
$this->addsectionclass = $format->get_output_classname('course_format\\addsection');
$this->sectionnavigationclass = $format->get_output_classname('course_format\\sectionnavigation');
$this->sectionselectorclass = $format->get_output_classname('course_format\\sectionselector');
}
/**
* Export this data so it can be used as the context for a mustache template (core/inplace_editable).
*
* @param renderer_base $output typically, the renderer that's calling this function
* @return stdClass data context for a mustache template
*/
public function export_for_template(\renderer_base $output) {
$format = $this->format;
$addsection = new $this->addsectionclass($format);
// Most formats uses section 0 as a separate section so we remove from the list.
$sections = $this->export_sections($output);
$initialsection = '';
if (!empty($sections)) {
$initialsection = array_shift($sections);
}
$data = (object)[
'title' => $format->page_title(), // This method should be in the course_format class.
'initialsection' => $initialsection,
'sections' => $sections,
'numsections' => $addsection->export_for_template($output),
'format' => $format->get_format(),
];
// The single section format has extra navigation.
$singlesection = $this->format->get_section_number();
if ($singlesection) {
$sectionnavigation = new $this->sectionnavigationclass($format, $singlesection);
$data->sectionnavigation = $sectionnavigation->export_for_template($output);
$sectionselector = new $this->sectionselectorclass($format, $sectionnavigation);
$data->sectionselector = $sectionselector->export_for_template($output);
$data->hasnavigation = true;
$data->singlesection = array_shift($data->sections);
}
return $data;
}
/**
* Export sections array data.
*
* @param renderer_base $output typically, the renderer that's calling this function
* @return array data context for a mustache template
*/
protected function export_sections(\renderer_base $output): array {
$format = $this->format;
$course = $format->get_course();
$modinfo = $this->format->get_modinfo();
// Generate section list.
$sections = [];
$stealthsections = [];
$numsections = $format->get_last_section_number();
foreach ($this->get_sections_to_display($modinfo) as $sectionnum => $thissection) {
// The course/view.php check the section existence but the output can be called
// from other parts so we need to check it.
if (!$thissection) {
print_error('unknowncoursesection', 'error', course_get_url($course), format_string($course->fullname));
}
$section = new $this->sectionclass($format, $thissection);
if ($sectionnum > $numsections) {
// Activities inside this section are 'orphaned', this section will be printed as 'stealth' below.
if (!empty($modinfo->sections[$sectionnum])) {
$stealthsections[] = $section->export_for_template($output);
}
continue;
}
// Show the section if the user is permitted to access it, OR if it's not available
// but there is some available info text which explains the reason & should display,
// OR it is hidden but the course has a setting to display hidden sections as unavilable.
$showsection = $thissection->uservisible ||
($thissection->visible && !$thissection->available && !empty($thissection->availableinfo)) ||
(!$thissection->visible && !$course->hiddensections);
if (!$showsection) {
continue;
}
$sections[] = $section->export_for_template($output);
}
if (!empty($stealthsections)) {
$sections = array_merge($sections, $stealthsections);
}
return $sections;
}
/**
* Return an array of sections to display.
*
* This method is used to differentiate between display a specific section
* or a list of them.
*
* @param course_modinfo $modinfo the current course modinfo object
* @return section_info[] an array of section_info to display
*/
private function get_sections_to_display(course_modinfo $modinfo): array {
$singlesection = $this->format->get_section_number();
if ($singlesection) {
return [
$modinfo->get_section_info(0),
$modinfo->get_section_info($singlesection),
];
}
return $modinfo->get_section_info_all();
}
}
<?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/>.
/**
* Contains the default section course format output class.
*
* @package core_course
* @copyright 2020 Ferran Recio <ferran@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_course\output\course_format;
use core_course\course_format;
use renderable;
use templatable;
use moodle_url;
use stdClass;
/**
* Base class to render a course add section buttons.
*
* @package core_course
* @copyright 2020 Ferran Recio <ferran@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class addsection implements renderable, templatable {
/** @var course_format the course format class */
protected $format;
/**
* Constructor.
*
* @param course_format $format the course format
*/
public function __construct(course_format $format) {
$this->format = $format;
}
/**
* Export this data so it can be used as the context for a mustache template.
*
* @param renderer_base $output typically, the renderer that's calling this function
* @return stdClass data context for a mustache template
*/
public function export_for_template(\renderer_base $output): stdClass {
$format = $this->format;
$course = $format->get_course();
$options = $format->get_format_options();
$lastsection = $format->get_last_section_number();
$maxsections = $format->get_max_sections();
$data = new stdClass();
// If no editor must be displayed, just retun an empty structure.
if (!$format->show_editor()) {
return $data;
}
$supportsnumsections = array_key_exists('numsections', $options);
if ($supportsnumsections) {
// Current course format has 'numsections' option, which is very confusing and we suggest course format
// developers to get rid of it (see MDL-57769 on how to do it).
if ($lastsection < $maxsections) {
$data->increase = (object) [
'url' => new moodle_url(
'/course/changenumsections.php',
['courseid' => $course->id, 'increase' => true, 'sesskey' => sesskey()]
),
];
}
if ($course->numsections > 0) {
$data->decrease = (object) [
'url' => new moodle_url(
'/course/changenumsections.php',
['courseid' => $course->id, 'increase' => false, 'sesskey' => sesskey()]
),
];
}
} else if (course_get_format($course)->uses_sections() && $lastsection < $maxsections) {
// Current course format does not have 'numsections' option but it has multiple sections suppport.
// Display the "Add section" link that will insert a section in the end.
// Note to course format developers: inserting sections in the other positions should check both
// capabilities 'moodle/course:update' and 'moodle/course:movesections'.
if (get_string_manager()->string_exists('addsections', 'format_'.$course->format)) {
$addstring = get_string('addsections', 'format_'.$course->format);
} else {
$addstring = get_string('addsections');
}
$params = ['courseid' => $course->id, 'insertsection' => 0, 'sesskey' => sesskey()];
$singlesection = $this->format->get_section_number();
if ($singlesection) {
$params['sectionreturn'] = $singlesection;
}
$data->addsections = (object) [
'url' => new moodle_url('/course/changenumsections.php', $params),
'title' => $addstring,
'newsection' => $maxsections - $lastsection,
];
}
if (count((array)$data)) {
$data->showaddsection = true;
}
return $data;
}
}
<?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/>.
/**
* Contains the default frontpage section displayer.
*
* The frontpage has a different wat of rendering the main topic.
*
* @package core_course
* @copyright 2020 Ferran Recio <ferran@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_course\output\course_format;
use core_course\course_format;
use renderable;
use templatable;
use section_info;
use context_course;
use moodle_url;
use stdClass;
/**
* Represents the frontpage section 1.
*
* @package core_course
* @copyright 2020 Ferran Recio <ferran@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class frontpagesection implements renderable, templatable {
/** @var course_format the course format class */
protected $format;
/** @var section_info the course section class */
protected $section;
/** @var string the section output class name */
protected $sectionclass;
/**
* Constructor.
*
* @param course_format $format the course format
* @param section_info $section the section info
*/
public function __construct(course_format $format, section_info $section) {
$this->format = $format;
$this->section = $section;
// Get the necessary classes.
$this->sectionclass = $format->get_output_classname('section_format');
}
/**
* Export this data so it can be used as the context for a mustache template.
*
* @param renderer_base $output typically, the renderer that's calling this function
* @return stdClass data context for a mustache template
*/
public function export_for_template(\renderer_base $output): stdClass {
global $USER;
$format = $this->format;
$course = $format->get_course();
$context = context_course::instance($course->id);
$section = $this->section;
$sectionoutput = new $this->sectionclass($format, $section);
$sectionoutput->hide_controls();
if (trim($section->name) == '') {
$sectionoutput->hide_title();
}
$data = (object)[
'sections' => [$sectionoutput->export_for_template($output)],
];
if ($format->show_editor() && has_capability('moodle/course:update', $context)) {
$data->showsettings = true;
$data->settingsurl = new moodle_url('/course/editsection.php', ['id' => $section->id]);
}
return $data;
}
}
<?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