Skip to content

Commit

Permalink
MDL-82767 core_courseformat: new update.php for course non-ajax actions
Browse files Browse the repository at this point in the history
  • Loading branch information
ferranrecio committed Oct 30, 2024
1 parent 7dabba5 commit ff03d4f
Show file tree
Hide file tree
Showing 16 changed files with 750 additions and 131 deletions.
110 changes: 95 additions & 15 deletions course/format/classes/base.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@
use section_info;
use context_course;
use editsection_form;
use moodle_exception;
use coding_exception;
use core\exception\moodle_exception;
use core\exception\coding_exception;
use moodle_url;
use lang_string;
use core_external\external_api;
Expand Down Expand Up @@ -373,6 +373,37 @@ public function get_modinfo(): course_modinfo {
return $this->modinfo;
}

/**
* Return a format state updates instance.
*/
public function get_stateupdates_instance(): \core_courseformat\stateupdates {
$defaultupdatesclass = 'core_courseformat\\stateupdates';
$updatesclass = 'format_' . $this->format . '\\courseformat\\stateupdates';
if (!class_exists($updatesclass)) {
$updatesclass = $defaultupdatesclass;
}

$updates = new $updatesclass($this);
if (!is_a($updates, $defaultupdatesclass)) {
throw new coding_exception("The \"$updatesclass\" class must extend \"$defaultupdatesclass\"");
}

return $updates;
}

/**
* Return a format state actions instance.
* @return \core_courseformat\stateactions
*/
public function get_stateactions_instance(): \core_courseformat\stateactions {
// Get the actions class from the course format.
$actionsclass = 'format_'. $this->format.'\\courseformat\\stateactions';
if (!class_exists($actionsclass)) {
$actionsclass = 'core_courseformat\\stateactions';
}
return new $actionsclass();
}

/**
* Method used in the rendered and during backup instead of legacy 'numsections'
*
Expand Down Expand Up @@ -872,7 +903,7 @@ public function ajax_section_move() {
* of the view script, it is not enough to change just this function. Do not forget
* to add proper redirection.
*
* @param int|stdClass|section_info $section Section object from database or just field course_sections.section
* @param int|stdClass|section_info|null $section Section object from database or just field course_sections.section
* if null the course view page is returned
* @param array $options options for view URL. At the moment core uses:
* 'navigation' (bool) if true and section not empty, the function returns section page; otherwise, it returns course page.
Expand Down Expand Up @@ -911,37 +942,86 @@ public function get_view_url($section, $options = array()) {
return $url;
}

/**
* The URL to update the course format.
*
* If no section is specified, the update will redirect to the general course page.
*
* @param moodle_url|null $returnurl optional custom return url
* @return \moodle_url
*/
public function get_update_url(
string $action,
array $ids = [],
?int $targetsectionid = null,
?int $targetcmid = null,
?moodle_url $returnurl = null
): moodle_url {
$params = [
'courseid' => $this->get_courseid(),
'sesskey' => sesskey(),
'action' => $action,
];

if (count($ids) === 1) {
$params['id'] = reset($ids);
} else {
foreach ($ids as $key => $id) {
$params["ids[]"] = $id;
}
}

if ($targetsectionid) {
$params['sectionid'] = $targetsectionid;
}
if ($targetcmid) {
$params['cmid'] = $targetcmid;
}
if ($returnurl) {
$params['pageurl'] = $returnurl->out_as_local_url();
}
return new moodle_url('/course/format/update.php', $params);
}

/**
* Return the old non-ajax activity action url.
*
* BrowserKit behats tests cannot trigger javascript events,
* so we must translate to an old non-ajax url while non-ajax
* course editing is still supported.
*
* @deprecated since Moodle 5.0
* @todo Remove this method in Moodle 6.0 (MDL-83530).
*
* @param string $action action name the reactive action
* @param cm_info $cm course module
* @return moodle_url
*/
#[\core\attribute\deprecated(
replacement: 'core_courseformat\output\local\content\cm\controlmenu',
since: '5.0',
mdl: 'MDL-83527',
reason: 'Replaced by get_update_url.',
final: true,
)]
public function get_non_ajax_cm_action_url(string $action, cm_info $cm): moodle_url {
\core\deprecation::emit_deprecation_if_present([$this, __FUNCTION__]);
$nonajaxactions = [
'cmDelete' => 'delete',
'cmDuplicate' => 'duplicate',
'cmHide' => 'hide',
'cmShow' => 'show',
'cmStealth' => 'stealth',
'cmDelete' => 'cm_delete',
'cmDuplicate' => 'cm_duplicate',
'cmHide' => 'cm_hide',
'cmShow' => 'cm_show',
'cmStealth' => 'cm_stealth',
];
if (!isset($nonajaxactions[$action])) {
throw new coding_exception('Unknown activity action: ' . $action);
}
$nonajaxaction = $nonajaxactions[$action];
$nonajaxurl = new moodle_url(
'/course/mod.php',
['sesskey' => sesskey(), $nonajaxaction => $cm->id]
return $this->get_update_url(
action: $nonajaxaction,
ids: [$cm->id],
returnurl: $this->get_view_url($this->get_sectionnum(), ['navigation' => true]),
);
if (!is_null($this->get_sectionid())) {
$nonajaxurl->param('sr', $this->get_sectionnum());
}
return $nonajaxurl;
}

/**
Expand Down
27 changes: 5 additions & 22 deletions course/format/classes/external/update_course.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,11 @@

namespace core_courseformat\external;

use core\exception\moodle_exception;
use core_external\external_api;
use core_external\external_function_parameters;
use core_external\external_multiple_structure;
use core_external\external_value;
use moodle_exception;
use coding_exception;
use context_course;
use core_courseformat\base as course_format;

Expand Down Expand Up @@ -106,32 +105,16 @@ public static function execute(string $action, int $courseid, array $ids = [],

self::validate_context(context_course::instance($courseid));

$courseformat = course_get_format($courseid);
$format = course_get_format($courseid);

// Create a course changes tracker object.
$defaultupdatesclass = 'core_courseformat\\stateupdates';
$updatesclass = 'format_' . $courseformat->get_format() . '\\courseformat\\stateupdates';
if (!class_exists($updatesclass)) {
$updatesclass = $defaultupdatesclass;
}
$updates = new $updatesclass($courseformat);

if (!is_a($updates, $defaultupdatesclass)) {
throw new coding_exception("The \"$updatesclass\" class must extend \"$defaultupdatesclass\"");
}

// Get the actions class from the course format.
$actionsclass = 'format_'. $courseformat->get_format().'\\courseformat\\stateactions';
if (!class_exists($actionsclass)) {
$actionsclass = 'core_courseformat\\stateactions';
}
$actions = new $actionsclass();
$updates = $format->get_stateupdates_instance();
$actions = $format->get_stateactions_instance();

if (!is_callable([$actions, $action])) {
throw new moodle_exception("Invalid course state action $action in ".get_class($actions));
}

$course = $courseformat->get_course();
$course = $format->get_course();

// Execute the action.
$actions->$action($updates, $course, $ids, $targetsectionid, $targetcmid);
Expand Down
43 changes: 19 additions & 24 deletions course/format/classes/output/local/content/cm/controlmenu.php
Original file line number Diff line number Diff line change
Expand Up @@ -238,14 +238,10 @@ protected function get_cm_moveend_item(): ?action_menu_link {
return null;
}

$url = new url(
'/course/mod.php',
[
'sesskey' => sesskey(),
'sr' => $this->mod->sectionnum,
'id' => $this->mod->id,
'indent' => 1,
],
$url = $this->format->get_update_url(
action: 'cm_moveright',
ids: [$this->mod->id],
returnurl: $this->baseurl,
);

$icon = (right_to_left()) ? 't/left' : 't/right';
Expand Down Expand Up @@ -274,14 +270,10 @@ protected function get_cm_movestart_item(): ?action_menu_link {
return null;
}

$url = new url(
'/course/mod.php',
[
'sesskey' => sesskey(),
'sr' => $this->mod->sectionnum,
'id' => $this->mod->id,
'indent' => -1,
],
$url = $this->format->get_update_url(
action: 'cm_moveleft',
ids: [$this->mod->id],
returnurl: $this->baseurl,
);

$icon = (right_to_left()) ? 't/right' : 't/left';
Expand Down Expand Up @@ -332,8 +324,14 @@ protected function get_cm_duplicate_item(): ?action_menu_link {
return null;
}

$url = $this->format->get_update_url(
action: 'cm_duplicate',
ids: [$this->mod->id],
returnurl: $this->baseurl,
);

return new action_menu_link_secondary(
url: new url($this->baseurl, ['duplicate' => $this->mod->id]),
url: $url,
icon: new pix_icon('t/copy', ''),
text: get_string('duplicate'),
attributes: [
Expand Down Expand Up @@ -403,13 +401,10 @@ protected function get_cm_delete_item(): ?action_menu_link {
return null;
}

$url = new url(
'/course/mod.php',
[
'sesskey' => sesskey(),
'delete' => $this->mod->id,
'sr' => $this->mod->sectionnum,
],
$url = $this->format->get_update_url(
action: 'cm_delete',
ids: [$this->mod->id],
returnurl: $this->baseurl,
);

return new action_menu_link_secondary(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,13 +178,12 @@ protected function get_section_visibility_item(): ?action_menu_link {
}

$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);
$action = 'section_hide';
$icon = 'i/show';
$name = $strhide;
$attributes = [
Expand All @@ -197,7 +196,7 @@ protected function get_section_visibility_item(): ?action_menu_link {
'data-swapicon' => 'i/hide',
];
} else {
$url->param('show', $this->section->sectionnum);
$action = 'section_show';
$icon = 'i/hide';
$name = $strshow;
$attributes = [
Expand All @@ -211,6 +210,12 @@ protected function get_section_visibility_item(): ?action_menu_link {
];
}

$url = $this->format->get_update_url(
action: $action,
ids: [$this->section->id],
returnurl: $this->baseurl,
);

return new action_menu_link_secondary(
url: $url,
icon: new pix_icon($icon, ''),
Expand Down Expand Up @@ -262,13 +267,10 @@ protected function get_cm_delete_item(): ?action_menu_link {
return null;
}

$url = new url(
'/course/mod.php',
[
'sesskey' => sesskey(),
'delete' => $this->mod->id,
'sr' => $this->mod->sectionnum,
],
$url = $this->format->get_update_url(
action: 'cm_delete',
ids: [$this->mod->id],
returnurl: $this->baseurl,
);

return new action_menu_link_secondary(
Expand Down
26 changes: 17 additions & 9 deletions course/format/classes/output/local/content/cm/groupmode.php
Original file line number Diff line number Diff line change
Expand Up @@ -158,17 +158,17 @@ public function get_choice_list(): choicelist {
$choice->add_option(
NOGROUPS,
get_string('groupsnone', 'group'),
$this->get_option_data(null, 'cmNoGroups', $this->mod->id)
$this->get_option_data(null, 'cmNoGroups', 'cm_nogroups')
);
$choice->add_option(
SEPARATEGROUPS,
get_string('groupsseparate', 'group'),
$this->get_option_data('groupsseparate', 'cmSeparateGroups', $this->mod->id)
$this->get_option_data('groupsseparate', 'cmSeparateGroups', 'cm_separategroups')
);
$choice->add_option(
VISIBLEGROUPS,
get_string('groupsvisible', 'group'),
$this->get_option_data('groupsvisible', 'cmVisibleGroups', $this->mod->id)
$this->get_option_data('groupsvisible', 'cmVisibleGroups', 'cm_visiblegroups')
);
$choice->set_selected_value($this->mod->effectivegroupmode);
return $choice;
Expand All @@ -177,18 +177,26 @@ public function get_choice_list(): choicelist {
/**
* Get the data for the option.
* @param string|null $name the name of the option
* @param string $action the state action of the option
* @param int $id the id of the module
* @param string $mutation the mutation name
* @param string $stateaction the state action name
* @return array
*/
private function get_option_data(?string $name, string $action, int $id): array {
private function get_option_data(?string $name, string $mutation, string $stateaction): array {
$format = $this->format;
$nonajaxurl = $format->get_update_url(
action: $stateaction,
ids: [$this->mod->id],
returnurl: $format->get_view_url($format->get_sectionnum(), ['navigation' => true]),
);

return [
'description' => ($name) ? get_string("groupmode_{$name}_help", 'group') : null,
// The dropdown icons are decorative, so we don't need to provide alt text.
'icon' => $this->get_action_icon($action),
'icon' => $this->get_action_icon($mutation),
'url' => $nonajaxurl,
'extras' => [
'data-id' => $id,
'data-action' => $action,
'data-id' => $this->mod->id,
'data-action' => $mutation,
]
];
}
Expand Down
Loading

0 comments on commit ff03d4f

Please sign in to comment.