Skip to content

Commit

Permalink
MDL-83527 core_courseformat: refactor section action menu
Browse files Browse the repository at this point in the history
  • Loading branch information
ferranrecio committed Oct 24, 2024
1 parent ecfcf00 commit b1a0bd4
Show file tree
Hide file tree
Showing 3 changed files with 365 additions and 4 deletions.
239 changes: 239 additions & 0 deletions course/format/classes/output/local/content/basecontrolmenu.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
use core\output\named_templatable;
use core_courseformat\base as course_format;
use core_courseformat\output\local\courseformat_named_templatable;
use context_course;
use moodle_url;
use pix_icon;
use renderable;
Expand Down Expand Up @@ -48,12 +49,21 @@ abstract class basecontrolmenu implements named_templatable, renderable {
/** @var cm_info the course module class */
protected $mod;

/** @var stdClass the course instance */
protected stdClass $course;

/** @var context_course the course context */
protected $coursecontext;

/** @var string the menu ID */
protected $menuid;

/** @var action_menu the action menu */
protected $menu;

/** @var moodle_url The base URL for the course or the section */
protected moodle_url $baseurl;

/**
* Constructor.
*
Expand All @@ -67,6 +77,9 @@ public function __construct(course_format $format, section_info $section, ?cm_in
$this->section = $section;
$this->mod = $mod;
$this->menuid = $menuid;
$this->course = $format->get_course();
$this->coursecontext = $format->get_context();
$this->baseurl = $format->get_view_url($format->get_sectionnum(), ['navigation' => true]);
}

/**
Expand Down Expand Up @@ -134,6 +147,10 @@ protected function format_controls(array $controls): ?action_menu {
$menu->attributes['class'] .= ' section-actions';
$menu->attributes['data-sectionid'] = $this->section->id;
foreach ($controls as $value) {
// Actions not available for the user can be null.
if ($value === null) {
continue;
}
$url = empty($value['url']) ? '' : $value['url'];
$icon = empty($value['icon']) ? '' : $value['icon'];
$name = empty($value['name']) ? '' : $value['name'];
Expand All @@ -160,4 +177,226 @@ protected function format_controls(array $controls): ?action_menu {
public function section_control_items() {
return [];
}

// Section items.

/**
* Retrieves the view item for the section control menu.
*
* @return array|null The menu item array if applicable, otherwise null.
*/
protected function get_section_view_item(): ?array {
global $PAGE;
// Only show the view link if we are not already in the section view page.
if ($this->format->get_sectionid() == $this->section->id) {
return null;
}
return [
'url' => new moodle_url('/course/section.php', ['id' => $this->section->id]),
'icon' => 'i/viewsection',
'name' => get_string('view'),
'pixattr' => ['class' => ''],
'attr' => ['class' => 'icon view'],
];
}

/**
* Retrieves the edit item for the section control menu.
*
* @return array|null The menu item array if applicable, otherwise null.
*/
protected function get_section_edit_item(): ?array {
if (!has_capability('moodle/course:update', $this->coursecontext)) {
return null;
}
$params = ['id' => $this->section->id];
$params['sr'] = $this->section->section;
return [
'url' => new moodle_url('/course/editsection.php', $params),
'icon' => 'i/settings',
'name' => get_string('editsection'),
'pixattr' => ['class' => ''],
'attr' => ['class' => 'icon edit'],
];
}

/**
* Retrieves the duplicate item for the section control menu.
*
* @return array|null The menu item array if applicable, otherwise null.
*/
protected function get_section_duplicate_item(): ?array {
if (
$this->section->sectionnum == 0
|| !has_capability('moodle/course:update', $this->coursecontext)
) {
return null;
}
$url = clone($this->baseurl);
$url->param('sectionid', $this->section->id);
$url->param('duplicatesection', 1);
$url->param('sesskey', sesskey());
return [
'url' => $url,
'icon' => 't/copy',
'name' => get_string('duplicate'),
'pixattr' => ['class' => ''],
'attr' => ['class' => 'icon duplicate'],
];
}

/**
* Retrieves the get_section_visibility_menu_item item for the section control menu.
*
* @return array|null The menu item array if applicable, otherwise null.
*/
protected function get_section_visibility_item(): ?array {
if (
$this->section->sectionnum == 0
|| !has_capability('moodle/course:sectionvisibility', $this->coursecontext)
) {
return null;
}
$sectionreturn = $this->format->get_sectionnum();

$url = clone($this->baseurl);

$strhide = get_string('hide');
$strshow = get_string('show');

if ($this->section->visible) {
$url->param('hide', $this->section->sectionnum);
return [
'url' => $url,
'icon' => 'i/show',
'name' => $strhide,
'pixattr' => ['class' => ''],
'attr' => [
'class' => 'icon editing_showhide',
'data-sectionreturn' => $sectionreturn,
'data-action' => 'sectionHide',
'data-id' => $this->section->id,
'data-icon' => 'i/show',
'data-swapname' => $strshow,
'data-swapicon' => 'i/hide',
],
];
} else {
$url->param('show', $this->section->sectionnum);
return [
'url' => $url,
'icon' => 'i/hide',
'name' => $strshow,
'pixattr' => ['class' => ''],
'attr' => [
'class' => 'icon editing_showhide',
'data-sectionreturn' => $sectionreturn,
'data-action' => 'sectionShow',
'data-id' => $this->section->id,
'data-icon' => 'i/hide',
'data-swapname' => $strhide,
'data-swapicon' => 'i/show',
],
];
}
}

/**
* Retrieves the move item for the section control menu.
*
* @return array|null The menu item array if applicable, otherwise null.
*/
protected function get_section_movesection_item(): ?array {
if (
$this->section->sectionnum == 0
|| $this->format->get_sectionid()
|| !has_capability('moodle/course:movesections', $this->coursecontext)
) {
return null;
}

$url = clone ($this->baseurl);
$url->param('movesection', $this->section->sectionnum);
$url->param('section', $this->section->sectionnum);
return [
'url' => $url,
'icon' => 'i/dragdrop',
'name' => get_string('move'),
'pixattr' => ['class' => ''],
'attr' => [
// This tool requires ajax and will appear only when the frontend state is ready.
'class' => 'icon move waitstate',
'data-action' => 'moveSection',
'data-id' => $this->section->id,
],
];
}

/**
* Retrieves the permalink item for the section control menu.
*
* @return array|null The menu item array if applicable, otherwise null.
*/
protected function get_section_permalink_item(): ?array {
if (!has_any_capability(
[
'moodle/course:movesections',
'moodle/course:update',
'moodle/course:sectionvisibility',
],
$this->coursecontext
)
) {
return null;
}

$url = new moodle_url(
'/course/section.php',
['id' => $this->section->id]
);
return [
'url' => $url,
'icon' => 'i/link',
'name' => get_string('sectionlink', 'course'),
'pixattr' => ['class' => ''],
'attr' => [
'class' => 'icon',
'data-action' => 'permalink',
],
];
}

/**
* Retrieves the delete item for the section control menu.
*
* @return array|null The menu item array if applicable, otherwise null.
*/
protected function get_section_delete_item(): ?array {
if (!course_can_delete_section($this->format->get_course(), $this->section)) {
return null;
}

$params = [
'id' => $this->section->id,
'delete' => 1,
'sesskey' => sesskey(),
];
$params['sr'] ??= $this->format->get_sectionnum();

$url = new moodle_url(
'/course/editsection.php',
$params,
);
return [
'url' => $url,
'icon' => 'i/delete',
'name' => get_string('delete'),
'pixattr' => ['class' => ''],
'attr' => [
'class' => 'icon editing_delete text-danger',
'data-action' => 'deleteSection',
'data-id' => $this->section->id,
],
];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,17 +57,110 @@ public function get_default_action_menu(\renderer_base $output): ?action_menu {
return $this->format_controls($controls);
}

/**
* Generate the edit control items of a section.
*
* @return array of edit control items
*/
public function delegated_control_items() {
// TODO remove this if as part of MDL-83530.
if (!$this->format->supports_components()) {
return $this->delegated_control_items_legacy();
}

$controls = [];
$controls['view'] = $this->get_section_view_item();
$controls['edit'] = $this->get_section_edit_item();
$controls['visibility'] = $this->get_section_visibility_item();
$controls['movesection'] = $this->get_cm_move_item();
$controls['permalink'] = $this->get_section_permalink_item();
$controls['delete'] = $this->get_cm_delete_menu_item();

return $controls;
}

/**
* Generates the delete item for a course module.
*
* @return array|null The menu item array if applicable, otherwise null.
*/
protected function get_cm_delete_menu_item(): ?array {
// Delete deletes the module.
if (!has_capability('moodle/course:manageactivities', $this->coursecontext)) {
return null;
}

$url = new moodle_url('/course/mod.php');
$url->param('sesskey', sesskey());
$url->param('delete', $this->mod->id);
$url->param('sr', $this->mod->sectionnum);

return [
'url' => $url,
'icon' => 't/delete',
'name' => get_string('delete'),
'pixattr' => ['class' => ''],
'attr' => [
'class' => 'editing_delete text-danger',
'data-action' => 'cmDelete',
'data-sectionreturn' => $this->format->get_sectionnum(),
'data-id' => $this->mod->id,
],
];
}

/**
* Generates the move item for a course module.
*
* @return array|null The menu item array if applicable, otherwise null.
*/
protected function get_cm_move_item(): ?array {
// Only show the move link if we are not already in the section view page.
if (
$this->format->get_sectionid() == $this->section->id
|| !has_capability('moodle/course:manageactivities', $this->coursecontext)
) {
return null;
}
return [
'url' => $this->baseurl,
'icon' => 'i/dragdrop',
'name' => get_string('move'),
'pixattr' => ['class' => ''],
'attr' => [
// This tool requires ajax and will appear only when the frontend state is ready.
'class' => 'editing_movecm waitstate',
'data-action' => 'moveCm',
'data-id' => $this->mod->id,
],
];
}

/**
* Retrieves the get_section_visibility_menu_item item for the section control menu.
*
* @return array|null The menu item array if applicable, otherwise null.
*/
protected function get_section_visibility_item(): ?array {
// Disabling show and hide when the parent section is not visible
// reduces the complexity of the delegated section visibility logic.
$parentsection = $this->mod->get_section_info();
if (!$parentsection->visible) {
return null;
}
return parent::get_section_visibility_item();
}

/**
* Generate the edit control items of a section.
*
* It is not clear this kind of controls are still available in 4.0 so, for now, this
* method is almost a clone of the previous section_control_items from the course/renderer.php.
*
* This method must remain public until the final deprecation of section_edit_control_items.
*
* @todo Remove this method in Moodle 6.0 (MDL-83530).
* @return array of edit control items
*/
public function delegated_control_items() {
protected function delegated_control_items_legacy(): array {
global $USER;

$format = $this->format;
Expand Down
Loading

0 comments on commit b1a0bd4

Please sign in to comment.