Merge branch 'MDL-73762-master' of https://github.com/ferranrecio/moodle
This commit is contained in:
@@ -319,6 +319,20 @@ abstract class base {
|
||||
return $this->course;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the course display value for the current course.
|
||||
*
|
||||
* Formats extending topics or weeks will use coursedisplay as this setting name
|
||||
* so they don't need to override the method. However, if the format uses a different
|
||||
* display logic it must override this method to ensure the core renderers know
|
||||
* if a COURSE_DISPLAY_MULTIPAGE or COURSE_DISPLAY_SINGLEPAGE is being used.
|
||||
*
|
||||
* @return int The current value (COURSE_DISPLAY_MULTIPAGE or COURSE_DISPLAY_SINGLEPAGE)
|
||||
*/
|
||||
public function get_course_display(): int {
|
||||
return $this->get_course()->coursedisplay ?? COURSE_DISPLAY_SINGLEPAGE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current course modinfo.
|
||||
*
|
||||
|
||||
@@ -28,7 +28,6 @@ use core_courseformat\base as course_format;
|
||||
use course_modinfo;
|
||||
use renderable;
|
||||
use templatable;
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
* Base class to render a course format.
|
||||
|
||||
@@ -54,11 +54,16 @@ class addsection implements renderable, templatable {
|
||||
/**
|
||||
* 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
|
||||
* @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 {
|
||||
|
||||
// If no editor must be displayed, just return an empty structure.
|
||||
if (!$this->format->show_editor()) {
|
||||
return new stdClass();
|
||||
}
|
||||
|
||||
$format = $this->format;
|
||||
$course = $format->get_course();
|
||||
$options = $format->get_format_options();
|
||||
@@ -66,63 +71,14 @@ class addsection implements renderable, templatable {
|
||||
$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;
|
||||
}
|
||||
|
||||
// Component based formats handle add section button in the frontend.
|
||||
$show = ($lastsection < $maxsections) || course_get_format($course)->supports_components();
|
||||
$show = ($lastsection < $maxsections) || $format->supports_components();
|
||||
|
||||
$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()]
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
$data = $this->get_num_sections_data($output, $lastsection, $maxsections);
|
||||
} else if (course_get_format($course)->uses_sections() && $show) {
|
||||
// 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,
|
||||
];
|
||||
$data = $this->get_add_section_data($output, $lastsection, $maxsections);
|
||||
}
|
||||
|
||||
if (count((array)$data)) {
|
||||
@@ -131,4 +87,79 @@ class addsection implements renderable, templatable {
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the legacy num section add/remove section buttons data.
|
||||
*
|
||||
* 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).
|
||||
*
|
||||
* @param \renderer_base $output typically, the renderer that's calling this function
|
||||
* @param int $lastsection the last section number
|
||||
* @param int $maxsections the maximum number of sections
|
||||
* @return stdClass data context for a mustache template
|
||||
*/
|
||||
protected function get_num_sections_data(\renderer_base $output, int $lastsection, int $maxsections): stdClass {
|
||||
$format = $this->format;
|
||||
$course = $format->get_course();
|
||||
$data = new stdClass();
|
||||
|
||||
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()]
|
||||
),
|
||||
];
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the add section button data.
|
||||
*
|
||||
* 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'.
|
||||
*
|
||||
* @param \renderer_base $output typically, the renderer that's calling this function
|
||||
* @param int $lastsection the last section number
|
||||
* @param int $maxsections the maximum number of sections
|
||||
* @return stdClass data context for a mustache template
|
||||
*/
|
||||
protected function get_add_section_data(\renderer_base $output, int $lastsection, int $maxsections): stdClass {
|
||||
$format = $this->format;
|
||||
$course = $format->get_course();
|
||||
$data = new stdClass();
|
||||
|
||||
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,
|
||||
];
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,16 +25,16 @@
|
||||
namespace core_courseformat\output\local\content;
|
||||
|
||||
use cm_info;
|
||||
use context_module;
|
||||
use core\activity_dates;
|
||||
use core_availability\info_module;
|
||||
use core_completion\cm_completion_details;
|
||||
use core_courseformat\base as course_format;
|
||||
use core_course\output\activity_information;
|
||||
use renderable;
|
||||
use renderer_base;
|
||||
use section_info;
|
||||
use stdClass;
|
||||
use templatable;
|
||||
use \core_availability\info_module;
|
||||
|
||||
/**
|
||||
* Base class to render a course module inside a course format.
|
||||
@@ -84,9 +84,12 @@ class cm implements renderable, templatable {
|
||||
$this->format = $format;
|
||||
$this->section = $section;
|
||||
$this->mod = $mod;
|
||||
$this->displayoptions = $displayoptions;
|
||||
|
||||
// Add extra display options.
|
||||
$this->load_classes();
|
||||
$displayoptions['linkclasses'] = $this->get_link_classes();
|
||||
$displayoptions['textclasses'] = $this->get_text_classes();
|
||||
$this->displayoptions = $displayoptions;
|
||||
|
||||
// Get the necessary classes.
|
||||
$this->cmnameclass = $format->get_output_classname('content\\cm\\cmname');
|
||||
@@ -97,138 +100,206 @@ class cm implements renderable, templatable {
|
||||
/**
|
||||
* 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
|
||||
* @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;
|
||||
$section = $this->section;
|
||||
public function export_for_template(renderer_base $output): stdClass {
|
||||
$mod = $this->mod;
|
||||
$displayoptions = $this->displayoptions;
|
||||
$course = $mod->get_course();
|
||||
|
||||
// Fetch completion details.
|
||||
$showcompletionconditions = $course->showcompletionconditions == COMPLETION_SHOW_CONDITIONS;
|
||||
$completiondetails = cm_completion_details::get_instance($mod, $USER->id, $showcompletionconditions);
|
||||
|
||||
// Fetch activity dates.
|
||||
$activitydates = [];
|
||||
if ($course->showactivitydates) {
|
||||
$activitydates = activity_dates::get_dates_for_module($mod, $USER->id);
|
||||
}
|
||||
|
||||
$displayoptions['linkclasses'] = $this->get_link_classes();
|
||||
$displayoptions['textclasses'] = $this->get_text_classes();
|
||||
|
||||
// Grouping activity.
|
||||
$groupinglabel = $mod->get_grouping_label($displayoptions['textclasses']);
|
||||
|
||||
$activityinfodata = (object) ['hasdates' => false, 'hascompletion' => false];
|
||||
// - There are activity dates to be shown; or
|
||||
// - Completion info needs to be displayed
|
||||
// * The activity tracks completion; AND
|
||||
// * The showcompletionconditions setting is enabled OR an activity that tracks manual completion needs the manual
|
||||
// completion button to be displayed on the course homepage.
|
||||
$showcompletioninfo = $completiondetails->has_completion() && ($showcompletionconditions ||
|
||||
(!$completiondetails->is_automatic() && $completiondetails->show_manual_completion()));
|
||||
if ($showcompletioninfo || !empty($activitydates)) {
|
||||
$activityinfo = new activity_information($mod, $completiondetails, $activitydates);
|
||||
$activityinfodata = $activityinfo->export_for_template($output);
|
||||
}
|
||||
|
||||
// Mod inplace name editable.
|
||||
$cmname = new $this->cmnameclass(
|
||||
$format,
|
||||
$this->section,
|
||||
$mod,
|
||||
$format->show_editor(),
|
||||
$this->displayoptions
|
||||
);
|
||||
|
||||
// Mod availability.
|
||||
$availability = new $this->availabilityclass(
|
||||
$format,
|
||||
$this->section,
|
||||
$mod,
|
||||
$this->displayoptions
|
||||
);
|
||||
|
||||
$modavailability = $availability->export_for_template($output);
|
||||
|
||||
$data = (object)[
|
||||
'cmname' => $cmname->export_for_template($output),
|
||||
'grouping' => $groupinglabel,
|
||||
'afterlink' => $mod->afterlink,
|
||||
'altcontent' => $mod->get_formatted_content(['overflowdiv' => true, 'noclean' => true]),
|
||||
'modavailability' => $mod->visible ? $modavailability : null,
|
||||
'grouping' => $mod->get_grouping_label($displayoptions['textclasses']),
|
||||
'modname' => get_string('pluginname', 'mod_' . $mod->modname),
|
||||
'url' => $mod->url,
|
||||
'activityinfo' => $activityinfodata,
|
||||
'activityname' => $mod->get_formatted_name(),
|
||||
'textclasses' => $displayoptions['textclasses'],
|
||||
'classlist' => []
|
||||
'classlist' => [],
|
||||
];
|
||||
|
||||
if (!empty($mod->indent) && $format->uses_indentation()) {
|
||||
$data->indent = $mod->indent;
|
||||
if ($mod->indent > 15) {
|
||||
$data->hugeindent = true;
|
||||
}
|
||||
}
|
||||
|
||||
$data->altcontent = (empty($data->altcontent)) ? false : $data->altcontent;
|
||||
|
||||
$data->hasname = !empty($data->cmname['displayvalue']);
|
||||
// Add partial data segments.
|
||||
$haspartials = [];
|
||||
$haspartials['cmname'] = $this->add_cm_name_data($data, $output);
|
||||
$haspartials['availability'] = $this->add_availability_data($data, $output);
|
||||
$haspartials['alternative'] = $this->add_alternative_content_data($data, $output);
|
||||
$haspartials['completion'] = $this->add_completion_data($data, $output);
|
||||
$haspartials['editor'] = $this->add_editor_data($data, $output);
|
||||
$this->add_format_data($data, $haspartials, $output);
|
||||
|
||||
// Calculated fields.
|
||||
if (!empty($data->url)) {
|
||||
$data->hasurl = true;
|
||||
}
|
||||
|
||||
if (!$mod->visible) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add course module name attributes to the data structure.
|
||||
*
|
||||
* @param stdClass $data the current cm data reference
|
||||
* @param renderer_base $output typically, the renderer that's calling this function
|
||||
* @return bool if the cm has name data
|
||||
*/
|
||||
protected function add_cm_name_data(stdClass &$data, renderer_base $output): bool {
|
||||
// Mod inplace name editable.
|
||||
$cmname = new $this->cmnameclass(
|
||||
$this->format,
|
||||
$this->section,
|
||||
$this->mod,
|
||||
$this->format->show_editor(),
|
||||
$this->displayoptions
|
||||
);
|
||||
$data->cmname = $cmname->export_for_template($output);
|
||||
$data->hasname = !empty($data->cmname['displayvalue']);
|
||||
return $data->hasname;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the module availability to the data structure.
|
||||
*
|
||||
* @param stdClass $data the current cm data reference
|
||||
* @param renderer_base $output typically, the renderer that's calling this function
|
||||
* @return bool if the cm has mod availability
|
||||
*/
|
||||
protected function add_availability_data(stdClass &$data, renderer_base $output): bool {
|
||||
if (!$this->mod->visible) {
|
||||
$data->modavailability = null;
|
||||
return false;
|
||||
}
|
||||
// Mod availability output class.
|
||||
$availability = new $this->availabilityclass(
|
||||
$this->format,
|
||||
$this->section,
|
||||
$this->mod,
|
||||
$this->displayoptions
|
||||
);
|
||||
$modavailability = $availability->export_for_template($output);
|
||||
$data->modavailability = $modavailability;
|
||||
return $availability->has_availability($output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the alternative content to the data structure.
|
||||
*
|
||||
* @param stdClass $data the current cm data reference
|
||||
* @param renderer_base $output typically, the renderer that's calling this function
|
||||
* @return bool if the cm has alternative content
|
||||
*/
|
||||
protected function add_alternative_content_data(stdClass &$data, renderer_base $output): bool {
|
||||
$altcontent = $this->mod->get_formatted_content(
|
||||
['overflowdiv' => true, 'noclean' => true]
|
||||
);
|
||||
$data->altcontent = (empty($altcontent)) ? false : $altcontent;
|
||||
$data->afterlink = $this->mod->afterlink;
|
||||
return !empty($data->altcontent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add activity completion information to the data structure.
|
||||
*
|
||||
* @param stdClass $data the current cm data reference
|
||||
* @param renderer_base $output typically, the renderer that's calling this function
|
||||
* @return bool the module has completion information
|
||||
*/
|
||||
protected function add_completion_data(stdClass &$data, renderer_base $output): bool {
|
||||
global $USER;
|
||||
$course = $this->mod->get_course();
|
||||
// Fetch completion details.
|
||||
$showcompletionconditions = $course->showcompletionconditions == COMPLETION_SHOW_CONDITIONS;
|
||||
$completiondetails = cm_completion_details::get_instance($this->mod, $USER->id, $showcompletionconditions);
|
||||
|
||||
// Fetch activity dates.
|
||||
$activitydates = [];
|
||||
if ($course->showactivitydates) {
|
||||
$activitydates = activity_dates::get_dates_for_module($this->mod, $USER->id);
|
||||
}
|
||||
|
||||
$activityinfodata = (object) ['hasdates' => false, 'hascompletion' => false];
|
||||
// There are activity dates to be shown; or
|
||||
// Completion info needs to be displayed
|
||||
// * The activity tracks completion; AND
|
||||
// * The showcompletionconditions setting is enabled OR an activity that tracks manual
|
||||
// completion needs the manual completion button to be displayed on the course homepage.
|
||||
$showcompletioninfo = $completiondetails->has_completion() && ($showcompletionconditions ||
|
||||
(!$completiondetails->is_automatic() && $completiondetails->show_manual_completion()));
|
||||
if ($showcompletioninfo || !empty($activitydates)) {
|
||||
$activityinfo = new activity_information($this->mod, $completiondetails, $activitydates);
|
||||
$activityinfodata = $activityinfo->export_for_template($output);
|
||||
}
|
||||
|
||||
$data->activityinfo = $activityinfodata;
|
||||
return $activityinfodata->hascompletion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add activity information to the data structure.
|
||||
*
|
||||
* @param stdClass $data the current cm data reference
|
||||
* @param bool[] $haspartials the result of loading partial data elements
|
||||
* @param renderer_base $output typically, the renderer that's calling this function
|
||||
* @return bool if the cm has format data
|
||||
*/
|
||||
protected function add_format_data(stdClass &$data, array $haspartials, renderer_base $output): bool {
|
||||
$result = false;
|
||||
// Legacy indentation.
|
||||
if (!empty($this->mod->indent) && $this->format->uses_indentation()) {
|
||||
$data->indent = $this->mod->indent;
|
||||
if ($this->mod->indent > 15) {
|
||||
$data->hugeindent = true;
|
||||
$result = true;
|
||||
}
|
||||
}
|
||||
// Stealth and hidden from student.
|
||||
if (!$this->mod->visible) {
|
||||
// This module is hidden but current user has capability to see it.
|
||||
$data->modhiddenfromstudents = true;
|
||||
} else if ($mod->is_stealth()) {
|
||||
$result = true;
|
||||
} else if ($this->mod->is_stealth()) {
|
||||
// This module is available but is normally not displayed on the course page
|
||||
// (this user can see it because they can manage it).
|
||||
$data->modstealth = true;
|
||||
$result = true;
|
||||
}
|
||||
|
||||
if ($mod->modname == 'label' &&
|
||||
!$modavailability->hasmodavailability &&
|
||||
!$activityinfodata->hascompletion &&
|
||||
// Special inline activity format.
|
||||
if (
|
||||
$this->mod->has_custom_cmlist_item() &&
|
||||
!$haspartials['availability'] &&
|
||||
!$haspartials['completion'] &&
|
||||
!isset($data->modhiddenfromstudents) &&
|
||||
!isset($data->modstealth) &&
|
||||
!$format->show_editor()
|
||||
) {
|
||||
!$this->format->show_editor()
|
||||
) {
|
||||
$data->modinline = true;
|
||||
$result = true;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
$returnsection = $format->get_section_number();
|
||||
|
||||
if ($format->show_editor()) {
|
||||
// Edit actions.
|
||||
$controlmenu = new $this->controlmenuclass(
|
||||
$format,
|
||||
$this->section,
|
||||
$mod,
|
||||
$this->displayoptions
|
||||
);
|
||||
$data->controlmenu = $controlmenu->export_for_template($output);
|
||||
|
||||
if ($format->supports_components()) {
|
||||
$data->moveicon = $output->pix_icon('i/dragdrop', '', 'moodle', ['class' => 'editing_move dragicon']);
|
||||
} else {
|
||||
// Add the legacy YUI move link.
|
||||
$data->moveicon = course_get_cm_move($mod, $returnsection);
|
||||
}
|
||||
|
||||
// Move and select options.
|
||||
$modcontext = context_module::instance($mod->id);
|
||||
/**
|
||||
* Add course editor attributes to the data structure.
|
||||
*
|
||||
* @param stdClass $data the current cm data reference
|
||||
* @param renderer_base $output typically, the renderer that's calling this function
|
||||
* @return bool if the cm has editor data
|
||||
*/
|
||||
protected function add_editor_data(stdClass &$data, renderer_base $output): bool {
|
||||
if (!$this->format->show_editor()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $data;
|
||||
$returnsection = $this->format->get_section_number();
|
||||
// Edit actions.
|
||||
$controlmenu = new $this->controlmenuclass(
|
||||
$this->format,
|
||||
$this->section,
|
||||
$this->mod,
|
||||
$this->displayoptions
|
||||
);
|
||||
$data->controlmenu = $controlmenu->export_for_template($output);
|
||||
if (!$this->format->supports_components()) {
|
||||
// Add the legacy YUI move link.
|
||||
$data->moveicon = course_get_cm_move($this->mod, $returnsection);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -236,7 +307,6 @@ class cm implements renderable, templatable {
|
||||
*
|
||||
*/
|
||||
protected function load_classes() {
|
||||
|
||||
$mod = $this->mod;
|
||||
|
||||
$linkclasses = '';
|
||||
|
||||
@@ -53,6 +53,12 @@ class availability extends section_avalability {
|
||||
/** @var array optional display options */
|
||||
protected $displayoptions;
|
||||
|
||||
/** @var bool the has availability attribute name */
|
||||
protected $hasavailabilityname;
|
||||
|
||||
/** @var stdClass|null the instance export data */
|
||||
protected $data = null;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
@@ -66,86 +72,91 @@ class availability extends section_avalability {
|
||||
$this->section = $section;
|
||||
$this->mod = $mod;
|
||||
$this->displayoptions = $displayoptions;
|
||||
$this->hasavailabilityname = 'hasmodavailability';
|
||||
}
|
||||
|
||||
/**
|
||||
* Export this data so it can be used as the context for a mustache template.
|
||||
* Get the availability data to 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 {
|
||||
|
||||
$data = (object)[
|
||||
'info' => $this->get_info($output),
|
||||
'hasmodavailability' => false,
|
||||
];
|
||||
|
||||
if (!empty($data->info)) {
|
||||
$data->hasmodavailability = true;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the availability HTML form the course renderer.
|
||||
*
|
||||
* @param \renderer_base $output typically, the renderer that's calling this function
|
||||
* @return string the availability HTML
|
||||
* @return array the availability data.
|
||||
*/
|
||||
protected function get_info(\renderer_base $output): array {
|
||||
global $CFG;
|
||||
if (!$this->mod->is_visible_on_course_page()) {
|
||||
// Nothing to be displayed to the user.
|
||||
return [];
|
||||
}
|
||||
if (!$this->mod->uservisible) {
|
||||
return $this->user_availability_info($output);
|
||||
}
|
||||
|
||||
$format = $this->format;
|
||||
$mod = $this->mod;
|
||||
$section = $this->section;
|
||||
return $this->conditional_availability_info($output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current user availability data.
|
||||
*
|
||||
* This is a student who is not allowed to see the module but might be allowed
|
||||
* to see availability info (i.e. "Available from ...").
|
||||
*
|
||||
* @param \renderer_base $output typically, the renderer that's calling this function
|
||||
* @return array the availability data.
|
||||
*/
|
||||
protected function user_availability_info(\renderer_base $output): array {
|
||||
if (empty($this->mod->availableinfo)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$info = [];
|
||||
$formattedinfo = \core_availability\info::format_info(
|
||||
$this->mod->availableinfo,
|
||||
$this->mod->get_course()
|
||||
);
|
||||
$info[] = $this->availability_info($formattedinfo, 'isrestricted');
|
||||
return $info;
|
||||
}
|
||||
|
||||
if (!$mod->is_visible_on_course_page()) {
|
||||
// Nothing to be displayed to the user.
|
||||
return $info;
|
||||
}
|
||||
|
||||
if (!$mod->uservisible) {
|
||||
// This is a student who is not allowed to see the module but might be allowed
|
||||
// to see availability info (i.e. "Available from ...").
|
||||
if (!empty($mod->availableinfo)) {
|
||||
$formattedinfo = \core_availability\info::format_info(
|
||||
$mod->availableinfo,
|
||||
$mod->get_course()
|
||||
);
|
||||
$info[] = $this->availability_info($formattedinfo, 'isrestricted');
|
||||
}
|
||||
return $info;
|
||||
}
|
||||
/**
|
||||
* Get the activity availability data to display.
|
||||
*
|
||||
* @param \renderer_base $output typically, the renderer that's calling this function
|
||||
* @return array the availability data.
|
||||
*/
|
||||
protected function conditional_availability_info(\renderer_base $output): array {
|
||||
global $CFG;
|
||||
|
||||
// This is a teacher who is allowed to see module but still should see the
|
||||
// information that module is not available to all/some students.
|
||||
$mod = $this->mod;
|
||||
$modcontext = $mod->context;
|
||||
$canviewhidden = has_capability('moodle/course:viewhiddenactivities', $modcontext);
|
||||
|
||||
if ($canviewhidden && !empty($CFG->enableavailability)) {
|
||||
// Display information about conditional availability.
|
||||
// Don't add availability information if user is not editing and activity is hidden.
|
||||
if ($mod->visible || $format->show_editor()) {
|
||||
$hidinfoclass = 'isrestricted isfullinfo';
|
||||
if (!$mod->visible) {
|
||||
$hidinfoclass .= ' hide';
|
||||
}
|
||||
$ci = new info_module($mod);
|
||||
$fullinfo = $ci->get_full_information();
|
||||
if ($fullinfo) {
|
||||
$formattedinfo = info::format_info(
|
||||
$fullinfo,
|
||||
$mod->get_course()
|
||||
);
|
||||
$info[] = $this->availability_info($formattedinfo, $hidinfoclass);
|
||||
}
|
||||
}
|
||||
if (!$canviewhidden || empty($CFG->enableavailability)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// Display information about conditional availability.
|
||||
// Don't add availability information if user is not editing and activity is hidden.
|
||||
if (!$mod->visible && !$this->format->show_editor()) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$ci = new info_module($mod);
|
||||
$fullinfo = $ci->get_full_information();
|
||||
if (!$fullinfo) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$info = [];
|
||||
$hidinfoclass = 'isrestricted isfullinfo';
|
||||
if (!$mod->visible) {
|
||||
$hidinfoclass .= ' hide';
|
||||
}
|
||||
$formattedinfo = info::format_info(
|
||||
$fullinfo,
|
||||
$mod->get_course()
|
||||
);
|
||||
$info[] = $this->availability_info($formattedinfo, $hidinfoclass);
|
||||
|
||||
return $info;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,9 +27,10 @@ namespace core_courseformat\output\local\content;
|
||||
use core_courseformat\base as course_format;
|
||||
use context_course;
|
||||
use renderable;
|
||||
use templatable;
|
||||
use renderer_base;
|
||||
use section_info;
|
||||
use stdClass;
|
||||
use templatable;
|
||||
|
||||
/**
|
||||
* Base class to render a course section.
|
||||
@@ -44,7 +45,7 @@ class section implements renderable, templatable {
|
||||
protected $format;
|
||||
|
||||
/** @var section_info the section info */
|
||||
protected $thissection;
|
||||
protected $section;
|
||||
|
||||
/** @var section header output class */
|
||||
protected $headerclass;
|
||||
@@ -73,16 +74,23 @@ class section implements renderable, templatable {
|
||||
/** @var bool if the title is hidden for some reason */
|
||||
protected $hidecontrols = false;
|
||||
|
||||
/** @var bool if the section is considered stealth */
|
||||
protected $isstealth = false;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param course_format $format the course format
|
||||
* @param section_info $thissection the section info
|
||||
* @param section_info $section the section info
|
||||
*/
|
||||
public function __construct(course_format $format, section_info $thissection) {
|
||||
public function __construct(course_format $format, section_info $section) {
|
||||
$this->format = $format;
|
||||
$this->thissection = $thissection;
|
||||
$this->section = $section;
|
||||
|
||||
if ($section->section > $format->get_last_section_number()) {
|
||||
$this->isstealth = true;
|
||||
}
|
||||
|
||||
// Load output classes names from format.
|
||||
$this->headerclass = $format->get_output_classname('content\\section\\header');
|
||||
@@ -118,129 +126,211 @@ class section implements renderable, templatable {
|
||||
* @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 {
|
||||
public function export_for_template(renderer_base $output): stdClass {
|
||||
global $USER;
|
||||
|
||||
$format = $this->format;
|
||||
$course = $format->get_course();
|
||||
$thissection = $this->thissection;
|
||||
$singlesection = $format->get_section_number();
|
||||
$context = context_course::instance($course->id);
|
||||
$section = $this->section;
|
||||
|
||||
$summary = new $this->summaryclass($format, $thissection);
|
||||
$availability = new $this->availabilityclass($format, $thissection);
|
||||
$summary = new $this->summaryclass($format, $section);
|
||||
|
||||
$data = (object)[
|
||||
'num' => $thissection->section ?? '0',
|
||||
'id' => $thissection->id,
|
||||
'sectionreturnid' => $singlesection,
|
||||
'num' => $section->section ?? '0',
|
||||
'id' => $section->id,
|
||||
'sectionreturnid' => $format->get_section_number(),
|
||||
'insertafter' => false,
|
||||
'summary' => $summary->export_for_template($output),
|
||||
'availability' => $availability->export_for_template($output),
|
||||
'restrictionlock' => !empty($thissection->availableinfo),
|
||||
'highlightedlabel' => $format->get_section_highlighted_name(),
|
||||
'sitehome' => $course->id == SITEID,
|
||||
];
|
||||
|
||||
// Check if it is a stealth sections (orphaned).
|
||||
if ($thissection->section > $format->get_last_section_number()) {
|
||||
$data->isstealth = true;
|
||||
$data->ishidden = true;
|
||||
$haspartials = [];
|
||||
$haspartials['availability'] = $this->add_availability_data($data, $output);
|
||||
$haspartials['visibility'] = $this->add_visibility_data($data, $output);
|
||||
$haspartials['editor'] = $this->add_editor_data($data, $output);
|
||||
$haspartials['header'] = $this->add_header_data($data, $output);
|
||||
$haspartials['cm'] = $this->add_cm_data($data, $output);
|
||||
$this->add_format_data($data, $haspartials, $output);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the section header to the data structure.
|
||||
*
|
||||
* @param stdClass $data the current cm data reference
|
||||
* @param renderer_base $output typically, the renderer that's calling this function
|
||||
* @return bool if the cm has name data
|
||||
*/
|
||||
protected function add_header_data(stdClass &$data, renderer_base $output): bool {
|
||||
if (!empty($this->hidetitle)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($format->show_editor()) {
|
||||
if (empty($this->hidecontrols)) {
|
||||
$controlmenu = new $this->controlmenuclass($format, $thissection);
|
||||
$data->controlmenu = $controlmenu->export_for_template($output);
|
||||
}
|
||||
if (empty($data->isstealth)) {
|
||||
$data->cmcontrols = $output->course_section_add_cm_control($course, $thissection->section, $singlesection);
|
||||
}
|
||||
}
|
||||
$section = $this->section;
|
||||
$format = $this->format;
|
||||
|
||||
$coursedisplay = $course->coursedisplay ?? COURSE_DISPLAY_SINGLEPAGE;
|
||||
$data->iscoursedisplaymultipage = ($coursedisplay == COURSE_DISPLAY_MULTIPAGE);
|
||||
|
||||
if ($data->num === 0 && !$data->iscoursedisplaymultipage) {
|
||||
$data->collapsemenu = true;
|
||||
}
|
||||
|
||||
if ($course->id == SITEID) {
|
||||
$data->sitehome = true;
|
||||
}
|
||||
|
||||
$data->contentcollapsed = false;
|
||||
$preferences = $format->get_sections_preferences();
|
||||
if (isset($preferences[$thissection->id])) {
|
||||
$sectionpreferences = $preferences[$thissection->id];
|
||||
if (!empty($sectionpreferences->contentcollapsed)) {
|
||||
$data->contentcollapsed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($thissection->section == 0) {
|
||||
// Section zero is always visible only as a cmlist.
|
||||
$cmlist = new $this->cmlistclass($format, $thissection);
|
||||
$data->cmlist = $cmlist->export_for_template($output);
|
||||
|
||||
$header = new $this->headerclass($format, $thissection);
|
||||
if (empty($this->hidetitle)) {
|
||||
$data->header = $header->export_for_template($output);
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
$header = new $this->headerclass($format, $section);
|
||||
$headerdata = $header->export_for_template($output);
|
||||
|
||||
// When a section is displayed alone the title goes over the section, not inside it.
|
||||
$header = new $this->headerclass($format, $thissection);
|
||||
if ($section->section != 0 && $section->section == $format->get_section_number()) {
|
||||
$data->singleheader = $headerdata;
|
||||
} else {
|
||||
$data->header = $headerdata;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!$thissection->visible) {
|
||||
/**
|
||||
* Add the section cm list to the data structure.
|
||||
*
|
||||
* @param stdClass $data the current cm data reference
|
||||
* @param renderer_base $output typically, the renderer that's calling this function
|
||||
* @return bool if the cm has name data
|
||||
*/
|
||||
protected function add_cm_data(stdClass &$data, renderer_base $output): bool {
|
||||
$result = false;
|
||||
|
||||
$section = $this->section;
|
||||
$format = $this->format;
|
||||
|
||||
$showsummary = ($section->section != 0 &&
|
||||
$section->section != $format->get_section_number() &&
|
||||
$format->get_course_display() == COURSE_DISPLAY_MULTIPAGE &&
|
||||
!$format->show_editor()
|
||||
);
|
||||
|
||||
$showcmlist = $section->uservisible;
|
||||
|
||||
// Add activities summary if necessary.
|
||||
if ($showsummary) {
|
||||
$cmsummary = new $this->cmsummaryclass($format, $section);
|
||||
$data->cmsummary = $cmsummary->export_for_template($output);
|
||||
$data->onlysummary = true;
|
||||
$result = true;
|
||||
|
||||
if (!$format->is_section_current($section)) {
|
||||
// In multipage, only the current section (and the section zero) has elements.
|
||||
$showcmlist = false;
|
||||
}
|
||||
}
|
||||
// Add the cm list.
|
||||
if ($showcmlist) {
|
||||
$cmlist = new $this->cmlistclass($format, $section);
|
||||
$data->cmlist = $cmlist->export_for_template($output);
|
||||
$result = true;
|
||||
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the section availability to the data structure.
|
||||
*
|
||||
* @param stdClass $data the current cm data reference
|
||||
* @param renderer_base $output typically, the renderer that's calling this function
|
||||
* @return bool if the cm has name data
|
||||
*/
|
||||
protected function add_availability_data(stdClass &$data, renderer_base $output): bool {
|
||||
$availability = new $this->availabilityclass($this->format, $this->section);
|
||||
$data->availability = $availability->export_for_template($output);
|
||||
$data->restrictionlock = !empty($this->section->availableinfo);
|
||||
$data->hasavailability = $availability->has_availability($output);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the section vibility information to the data structure.
|
||||
*
|
||||
* @param stdClass $data the current cm data reference
|
||||
* @param renderer_base $output typically, the renderer that's calling this function
|
||||
* @return bool if the cm has name data
|
||||
*/
|
||||
protected function add_visibility_data(stdClass &$data, renderer_base $output): bool {
|
||||
global $USER;
|
||||
$result = false;
|
||||
$course = $this->format->get_course();
|
||||
$context = context_course::instance($course->id);
|
||||
// Check if it is a stealth sections (orphaned).
|
||||
if ($this->isstealth) {
|
||||
$data->isstealth = true;
|
||||
$data->ishidden = true;
|
||||
$result = true;
|
||||
}
|
||||
if (!$this->section->visible) {
|
||||
$data->ishidden = true;
|
||||
$data->notavailable = true;
|
||||
if (has_capability('moodle/course:viewhiddensections', $context, $USER)) {
|
||||
$data->hiddenfromstudents = true;
|
||||
$data->notavailable = false;
|
||||
$result = true;
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
if ($thissection->section == $singlesection) {
|
||||
if (empty($this->hidetitle)) {
|
||||
$data->singleheader = $header->export_for_template($output);
|
||||
}
|
||||
} else {
|
||||
if (empty($this->hidetitle)) {
|
||||
$data->header = $header->export_for_template($output);
|
||||
}
|
||||
|
||||
// Add activities summary if necessary.
|
||||
if (!$format->show_editor() && $course->coursedisplay == COURSE_DISPLAY_MULTIPAGE) {
|
||||
$cmsummary = new $this->cmsummaryclass($format, $thissection);
|
||||
$data->cmsummary = $cmsummary->export_for_template($output);
|
||||
|
||||
$data->onlysummary = true;
|
||||
if (!$format->is_section_current($thissection)) {
|
||||
// In multipage, only the current section (and the section zero) has elements.
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Add the section editor attributes to the data structure.
|
||||
*
|
||||
* @param stdClass $data the current cm data reference
|
||||
* @param renderer_base $output typically, the renderer that's calling this function
|
||||
* @return bool if the cm has name data
|
||||
*/
|
||||
protected function add_editor_data(stdClass &$data, renderer_base $output): bool {
|
||||
if (!$this->format->show_editor()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Add the cm list.
|
||||
if ($thissection->uservisible) {
|
||||
$cmlist = new $this->cmlistclass($format, $thissection);
|
||||
$data->cmlist = $cmlist->export_for_template($output);
|
||||
$course = $this->format->get_course();
|
||||
if (empty($this->hidecontrols)) {
|
||||
$controlmenu = new $this->controlmenuclass($this->format, $this->section);
|
||||
$data->controlmenu = $controlmenu->export_for_template($output);
|
||||
}
|
||||
|
||||
$data->hasavailability = false;
|
||||
if (isset($data->availability->hasavailability)) {
|
||||
$data->hasavailability = $data->availability->hasavailability;
|
||||
}
|
||||
|
||||
if ($format->is_section_current($thissection)) {
|
||||
$data->highlighted = true;
|
||||
$data->currentlink = get_accesshide(
|
||||
get_string('currentsection', 'format_'.$format->get_format())
|
||||
if (!$this->isstealth) {
|
||||
$data->cmcontrols = $output->course_section_add_cm_control(
|
||||
$course,
|
||||
$this->section->section,
|
||||
$this->format->get_section_number()
|
||||
);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return $data;
|
||||
/**
|
||||
* Add the section format attributes to the data structure.
|
||||
*
|
||||
* @param stdClass $data the current cm data reference
|
||||
* @param bool[] $haspartials the result of loading partial data elements
|
||||
* @param renderer_base $output typically, the renderer that's calling this function
|
||||
* @return bool if the cm has name data
|
||||
*/
|
||||
protected function add_format_data(stdClass &$data, array $haspartials, renderer_base $output): bool {
|
||||
$section = $this->section;
|
||||
$format = $this->format;
|
||||
|
||||
$data->iscoursedisplaymultipage = ($format->get_course_display() == COURSE_DISPLAY_MULTIPAGE);
|
||||
|
||||
if ($data->num === 0 && !$data->iscoursedisplaymultipage) {
|
||||
$data->collapsemenu = true;
|
||||
}
|
||||
|
||||
$data->contentcollapsed = false;
|
||||
$preferences = $format->get_sections_preferences();
|
||||
if (isset($preferences[$section->id])) {
|
||||
$sectionpreferences = $preferences[$section->id];
|
||||
if (!empty($sectionpreferences->contentcollapsed)) {
|
||||
$data->contentcollapsed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($format->is_section_current($section)) {
|
||||
$data->highlighted = true;
|
||||
$data->currentlink = get_accesshide(
|
||||
get_string('currentsection', 'format_' . $format->get_format())
|
||||
);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,6 +48,12 @@ class availability implements renderable, templatable {
|
||||
/** @var section_info the section object */
|
||||
protected $section;
|
||||
|
||||
/** @var string the has availability attribute name */
|
||||
protected $hasavailabilityname;
|
||||
|
||||
/** @var stdClass|null the instance export data */
|
||||
protected $data = null;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
@@ -57,6 +63,7 @@ class availability implements renderable, templatable {
|
||||
public function __construct(course_format $format, section_info $section) {
|
||||
$this->format = $format;
|
||||
$this->section = $section;
|
||||
$this->hasavailabilityname = 'hasavailability';
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -66,16 +73,40 @@ class availability implements renderable, templatable {
|
||||
* @return stdClass data context for a mustache template
|
||||
*/
|
||||
public function export_for_template(\renderer_base $output): stdClass {
|
||||
$this->build_export_data($output);
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if the output has availability info to display.
|
||||
*
|
||||
* @param \renderer_base $output typically, the renderer that's calling this function
|
||||
* @return bool if the element has availability data to display
|
||||
*/
|
||||
public function has_availability(\renderer_base $output): bool {
|
||||
$this->build_export_data($output);
|
||||
$attributename = $this->hasavailabilityname;
|
||||
return $this->data->$attributename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Protected method to build the export data.
|
||||
*
|
||||
* @param \renderer_base $output typically, the renderer that's calling this function
|
||||
*/
|
||||
protected function build_export_data(\renderer_base $output) {
|
||||
if (!empty($this->data)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$data = (object)[
|
||||
'info' => $this->get_info($output),
|
||||
];
|
||||
|
||||
if (!empty($data->info)) {
|
||||
$data->hasavailability = true;
|
||||
}
|
||||
$attributename = $this->hasavailabilityname;
|
||||
$data->$attributename = !empty($data->info);
|
||||
|
||||
return $data;
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -75,7 +75,7 @@ class header implements renderable, templatable {
|
||||
|
||||
$data->title = $output->section_title_without_link($section, $course);
|
||||
|
||||
$coursedisplay = $course->coursedisplay ?? COURSE_DISPLAY_SINGLEPAGE;
|
||||
$coursedisplay = $format->get_course_display();
|
||||
$data->headerdisplaymultipage = false;
|
||||
if ($coursedisplay == COURSE_DISPLAY_MULTIPAGE) {
|
||||
$data->headerdisplaymultipage = true;
|
||||
|
||||
@@ -1038,7 +1038,7 @@ abstract class section_renderer extends core_course_renderer {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!$format->show_editor() && $course->coursedisplay == COURSE_DISPLAY_MULTIPAGE) {
|
||||
if (!$format->show_editor() && $format->get_course_display() == COURSE_DISPLAY_MULTIPAGE) {
|
||||
// Display section summary only.
|
||||
echo $this->section_summary($thissection, $course, null);
|
||||
} else {
|
||||
|
||||
@@ -126,7 +126,7 @@ class format_legacy extends core_courseformat\base {
|
||||
$usercoursedisplay = COURSE_DISPLAY_SINGLEPAGE;
|
||||
}
|
||||
} else {
|
||||
$usercoursedisplay = $course->coursedisplay;
|
||||
$usercoursedisplay = $course->coursedisplay ?? COURSE_DISPLAY_SINGLEPAGE;
|
||||
}
|
||||
if ($sectionno != 0 && $usercoursedisplay == COURSE_DISPLAY_MULTIPAGE) {
|
||||
$url->param('section', $sectionno);
|
||||
@@ -268,11 +268,11 @@ class format_legacy extends core_courseformat\base {
|
||||
'type' => PARAM_INT,
|
||||
),
|
||||
'hiddensections' => array(
|
||||
'default' => $courseconfig->hiddensections,
|
||||
'default' => $courseconfig->hiddensections ?? 0,
|
||||
'type' => PARAM_INT,
|
||||
),
|
||||
'coursedisplay' => array(
|
||||
'default' => $courseconfig->coursedisplay,
|
||||
'default' => $courseconfig->coursedisplay ?? COURSE_DISPLAY_SINGLEPAGE,
|
||||
'type' => PARAM_INT,
|
||||
),
|
||||
);
|
||||
|
||||
@@ -135,7 +135,7 @@ class format_topics extends core_courseformat\base {
|
||||
$usercoursedisplay = COURSE_DISPLAY_SINGLEPAGE;
|
||||
}
|
||||
} else {
|
||||
$usercoursedisplay = $course->coursedisplay;
|
||||
$usercoursedisplay = $course->coursedisplay ?? COURSE_DISPLAY_SINGLEPAGE;
|
||||
}
|
||||
if ($sectionno != 0 && $usercoursedisplay == COURSE_DISPLAY_MULTIPAGE) {
|
||||
$url->param('section', $sectionno);
|
||||
|
||||
@@ -6,6 +6,7 @@ Overview of this plugin type at http://docs.moodle.org/dev/Course_formats
|
||||
* New core_courseformat\base::uses_course_index() to define whether the course format uses course index or not.
|
||||
* New core_courseformat\base::supports_components() to specify if the format is compatible with reactive components.
|
||||
* New core_courseformat\base::uses_indentation() to specify if the format is compatible with activity indentation.
|
||||
* New core_courseformat\base::get_course_display() if the course uses COURSE_DISPLAY_SINGLEPAGE or COURSE_DISPLAY_MULTIPAGE layout.
|
||||
|
||||
=== 3.10 ===
|
||||
* Added the missing callback supports_ajax() to format_social.
|
||||
|
||||
@@ -145,7 +145,7 @@ class format_weeks extends core_courseformat\base {
|
||||
$usercoursedisplay = COURSE_DISPLAY_SINGLEPAGE;
|
||||
}
|
||||
} else {
|
||||
$usercoursedisplay = $course->coursedisplay;
|
||||
$usercoursedisplay = $course->coursedisplay ?? COURSE_DISPLAY_SINGLEPAGE;
|
||||
}
|
||||
if ($sectionno != 0 && $usercoursedisplay == COURSE_DISPLAY_MULTIPAGE) {
|
||||
$url->param('section', $sectionno);
|
||||
@@ -268,7 +268,7 @@ class format_weeks extends core_courseformat\base {
|
||||
'type' => PARAM_INT,
|
||||
),
|
||||
'coursedisplay' => array(
|
||||
'default' => $courseconfig->coursedisplay,
|
||||
'default' => $courseconfig->coursedisplay ?? COURSE_DISPLAY_SINGLEPAGE,
|
||||
'type' => PARAM_INT,
|
||||
),
|
||||
'automaticenddate' => array(
|
||||
|
||||
@@ -1117,6 +1117,11 @@ class cm_info implements IteratorAggregate {
|
||||
*/
|
||||
private $contentisformatted;
|
||||
|
||||
/**
|
||||
* @var bool True if the content has a special course item display like labels.
|
||||
*/
|
||||
private $customcmlistitem;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
@@ -1189,6 +1194,7 @@ class cm_info implements IteratorAggregate {
|
||||
'course' => 'get_course_id',
|
||||
'coursegroupmode' => 'get_course_groupmode',
|
||||
'coursegroupmodeforce' => 'get_course_groupmodeforce',
|
||||
'customcmlistitem' => 'has_custom_cmlist_item',
|
||||
'effectivegroupmode' => 'get_effective_groupmode',
|
||||
'extra' => false,
|
||||
'groupingid' => false,
|
||||
@@ -1400,6 +1406,19 @@ class cm_info implements IteratorAggregate {
|
||||
return format_text($this->content, FORMAT_HTML, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the module custom cmlist item flag.
|
||||
*
|
||||
* Activities like label uses this flag to indicate that it should be
|
||||
* displayed as a custom course item instead of a tipical activity card.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has_custom_cmlist_item(): bool {
|
||||
$this->obtain_view_data();
|
||||
return $this->customcmlistitem ?? false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter method for property $name, ensures that dynamic data is obtained.
|
||||
*
|
||||
@@ -1788,6 +1807,18 @@ class cm_info implements IteratorAggregate {
|
||||
$this->uservisible = $uservisible;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the 'customcmlistitem' flag
|
||||
*
|
||||
* This can be used (by setting true) to prevent the course from rendering the
|
||||
* activity item as a regular activity card. This is applied to activities like labels.
|
||||
*
|
||||
* @param bool $customcmlistitem if the cmlist item of that activity has a special dysplay other than a card.
|
||||
*/
|
||||
public function set_custom_cmlist_item(bool $customcmlistitem) {
|
||||
$this->customcmlistitem = $customcmlistitem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the 'available' flag and related details. This flag is normally used to make
|
||||
* course modules unavailable until a certain date or condition is met. (When a course
|
||||
|
||||
@@ -70,6 +70,15 @@ function label_add_instance($label) {
|
||||
return $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the special label display on course page.
|
||||
*
|
||||
* @param cm_info $cm Course-module object
|
||||
*/
|
||||
function label_cm_info_view(cm_info $cm) {
|
||||
$cm->set_custom_cmlist_item(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an object containing all the necessary data,
|
||||
* (defined by the form in mod_form.php) this function
|
||||
|
||||
Reference in New Issue
Block a user