mirror of
https://github.com/moodle/moodle.git
synced 2025-04-21 00:12:56 +02:00
Merge branch 'MDL-82349-main-v03' of https://github.com/ferranrecio/moodle
This commit is contained in:
commit
155c4bd1e8
10
.upgradenotes/MDL-82349-2024111211161866.yml
Normal file
10
.upgradenotes/MDL-82349-2024111211161866.yml
Normal file
@ -0,0 +1,10 @@
|
||||
issueNumber: MDL-82349
|
||||
notes:
|
||||
core_courseformat:
|
||||
- message: >-
|
||||
A new core_courseformat\base::get_generic_section_name method is
|
||||
created to know how a specific format name the sections.
|
||||
This method is also used by plugins to know how to name the sections
|
||||
instead of using using a direct get_string on "sectionnamer" that
|
||||
may not exists.
|
||||
type: improved
|
@ -21,8 +21,7 @@
|
||||
* @copyright 1999 onwards Martin Dougiamas (http://dougiamas.com)
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
class block_site_main_menu extends block_list {
|
||||
class block_site_main_menu extends block_base {
|
||||
function init() {
|
||||
$this->title = get_string('pluginname', 'block_site_main_menu');
|
||||
}
|
||||
@ -32,224 +31,37 @@ class block_site_main_menu extends block_list {
|
||||
}
|
||||
|
||||
function get_content() {
|
||||
global $USER, $CFG, $DB, $OUTPUT;
|
||||
|
||||
if ($this->content !== NULL) {
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
$this->content = new stdClass();
|
||||
$this->content->items = array();
|
||||
$this->content->icons = array();
|
||||
$this->content->text = '';
|
||||
$this->content->footer = '';
|
||||
|
||||
if (empty($this->instance)) {
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
require_once($CFG->dirroot . '/course/lib.php');
|
||||
|
||||
$course = get_site();
|
||||
$format = course_get_format($course);
|
||||
$courserenderer = $format->get_renderer($this->page);
|
||||
|
||||
$context = context_course::instance($course->id);
|
||||
$isediting = $this->page->user_is_editing() && has_capability('moodle/course:manageactivities', $context);
|
||||
|
||||
// Output classes.
|
||||
$cmnameclass = $format->get_output_classname('content\\cm\\cmname');
|
||||
$controlmenuclass = $format->get_output_classname('content\\cm\\controlmenu');
|
||||
|
||||
$badgeattributes = [
|
||||
'class' => 'badge rounded-pill bg-warning text-dark mt-2',
|
||||
'data-region' => 'visibility'
|
||||
];
|
||||
|
||||
// Extra fast view mode.
|
||||
if (!$isediting) {
|
||||
$modinfo = get_fast_modinfo($course);
|
||||
if (!empty($modinfo->sections[0])) {
|
||||
foreach($modinfo->sections[0] as $cmid) {
|
||||
$cm = $modinfo->cms[$cmid];
|
||||
if (!$cm->uservisible || !$cm->is_visible_on_course_page()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($cm->indent > 0) {
|
||||
$indent = '<div class="mod-indent mod-indent-'.$cm->indent.'"></div>';
|
||||
} else {
|
||||
$indent = '';
|
||||
}
|
||||
|
||||
$badges = '';
|
||||
if (!$cm->visible) {
|
||||
$badges = html_writer::tag(
|
||||
'span',
|
||||
get_string('hiddenfromstudents'),
|
||||
$badgeattributes
|
||||
);
|
||||
}
|
||||
|
||||
if ($cm->is_stealth()) {
|
||||
$badges = html_writer::tag(
|
||||
'span',
|
||||
get_string('hiddenoncoursepage'),
|
||||
$badgeattributes
|
||||
);
|
||||
}
|
||||
|
||||
if (!$cm->url) {
|
||||
$activitybasis = html_writer::div(
|
||||
$indent . $cm->get_formatted_content(['overflowdiv' => true, 'noclean' => true]),
|
||||
'activity-basis d-flex align-items-center');
|
||||
$content = html_writer::div(
|
||||
$activitybasis . $badges,
|
||||
'contentwithoutlink activity-item activity',
|
||||
['data-activityname' => $cm->name]
|
||||
);
|
||||
} else {
|
||||
$cmname = new $cmnameclass($format, $cm->get_section_info(), $cm);
|
||||
$activitybasis = html_writer::div(
|
||||
$indent . $courserenderer->render($cmname),
|
||||
'activity-basis d-flex align-items-center');
|
||||
$content = html_writer::div(
|
||||
$activitybasis . $badges,
|
||||
'activity-item activity',
|
||||
['data-activityname' => $cm->name]
|
||||
);
|
||||
}
|
||||
|
||||
$this->content->items[] = html_writer::div($content, 'main-menu-content section');
|
||||
}
|
||||
}
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
// Slow & hacky editing mode.
|
||||
$ismoving = ismoving($course->id);
|
||||
course_create_sections_if_missing($course, 0);
|
||||
$modinfo = get_fast_modinfo($course);
|
||||
$format = course_get_format($course);
|
||||
$modinfo = $format->get_modinfo();
|
||||
$section = $modinfo->get_section_info(0);
|
||||
|
||||
if ($ismoving) {
|
||||
$strmovefull = strip_tags(get_string('movefull', '', "'$USER->activitycopyname'"));
|
||||
$strcancel= get_string('cancel');
|
||||
} else {
|
||||
$strmove = get_string('move');
|
||||
}
|
||||
$courserenderer = $format->get_renderer($this->page);
|
||||
|
||||
if ($ismoving) {
|
||||
$this->content->icons[] = $OUTPUT->pix_icon('t/move', get_string('move'));
|
||||
$this->content->items[] = $USER->activitycopyname.' (<a href="'.$CFG->wwwroot.'/course/mod.php?cancelcopy=true&sesskey='.sesskey().'">'.$strcancel.'</a>)';
|
||||
}
|
||||
$output = new block_site_main_menu\output\mainsection($format, $section);
|
||||
|
||||
if (!empty($modinfo->sections[0])) {
|
||||
foreach ($modinfo->sections[0] as $modnumber) {
|
||||
$mod = $modinfo->cms[$modnumber];
|
||||
if (!$mod->uservisible || !$mod->is_visible_on_course_page()) {
|
||||
continue;
|
||||
}
|
||||
if (!$ismoving) {
|
||||
$this->content->text = $courserenderer->render($output);
|
||||
|
||||
$controlmenu = new $controlmenuclass(
|
||||
$format,
|
||||
$mod->get_section_info(),
|
||||
$mod
|
||||
);
|
||||
|
||||
$menu = $controlmenu->get_action_menu($OUTPUT);
|
||||
|
||||
$moveaction = html_writer::link(
|
||||
new moodle_url('/course/mod.php', ['sesskey' => sesskey(), 'copy' => $mod->id]),
|
||||
$OUTPUT->pix_icon('i/dragdrop', $strmove),
|
||||
['class' => 'editing_move_activity']
|
||||
);
|
||||
|
||||
$editbuttons = html_writer::tag(
|
||||
'div',
|
||||
$courserenderer->render($controlmenu),
|
||||
['class' => 'buttons activity-actions ms-auto']
|
||||
);
|
||||
} else {
|
||||
$editbuttons = '';
|
||||
$moveaction = '';
|
||||
}
|
||||
|
||||
if ($mod->visible || has_capability('moodle/course:viewhiddenactivities', $mod->context)) {
|
||||
if ($ismoving) {
|
||||
if ($mod->id == $USER->activitycopy) {
|
||||
continue;
|
||||
}
|
||||
$movingurl = new moodle_url('/course/mod.php', array('moveto' => $mod->id, 'sesskey' => sesskey()));
|
||||
$this->content->items[] = html_writer::link($movingurl, '', array('title' => $strmovefull,
|
||||
'class' => 'movehere'));
|
||||
$this->content->icons[] = '';
|
||||
}
|
||||
|
||||
if ($mod->indent > 0) {
|
||||
$indent = '<div class="mod-indent mod-indent-'.$mod->indent.'"></div>';
|
||||
} else {
|
||||
$indent = '';
|
||||
}
|
||||
|
||||
$badges = '';
|
||||
if (!$mod->visible) {
|
||||
$badges = html_writer::tag(
|
||||
'span',
|
||||
get_string('hiddenfromstudents'),
|
||||
$badgeattributes
|
||||
);
|
||||
}
|
||||
|
||||
if ($mod->is_stealth()) {
|
||||
$badges = html_writer::tag(
|
||||
'span',
|
||||
get_string('hiddenoncoursepage'),
|
||||
$badgeattributes
|
||||
);
|
||||
}
|
||||
|
||||
if (!$mod->url) {
|
||||
$activitybasis = html_writer::div(
|
||||
$moveaction .
|
||||
$indent .
|
||||
$mod->get_formatted_content(['overflowdiv' => true, 'noclean' => true]) .
|
||||
$editbuttons,
|
||||
'activity-basis d-flex align-items-center');
|
||||
$content = html_writer::div(
|
||||
$activitybasis . $badges,
|
||||
'contentwithoutlink activity-item activity',
|
||||
['data-activityname' => $mod->name]
|
||||
);
|
||||
} else {
|
||||
$cmname = new $cmnameclass($format, $mod->get_section_info(), $mod);
|
||||
$activitybasis = html_writer::div(
|
||||
$moveaction .
|
||||
$indent .
|
||||
$courserenderer->render($cmname) .
|
||||
$editbuttons,
|
||||
'activity-basis d-flex align-items-center');
|
||||
$content = html_writer::div(
|
||||
$activitybasis . $badges,
|
||||
'activity-item activity',
|
||||
['data-activityname' => $mod->name]
|
||||
);
|
||||
}
|
||||
$this->content->items[] = html_writer::div($content, 'main-menu-content');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($ismoving) {
|
||||
$movingurl = new moodle_url('/course/mod.php', array('movetosection' => $section->id, 'sesskey' => sesskey()));
|
||||
$this->content->items[] = html_writer::link($movingurl, '', array('title' => $strmovefull, 'class' => 'movehere'));
|
||||
$this->content->icons[] = '';
|
||||
}
|
||||
|
||||
if ($this->page->course->id === SITEID) {
|
||||
$this->content->footer = $courserenderer->course_section_add_cm_control($course,
|
||||
0, null, array('inblock' => true));
|
||||
}
|
||||
$this->content->footer = $courserenderer->course_section_add_cm_control(
|
||||
course: $course,
|
||||
section: 0,
|
||||
sectionreturn: null,
|
||||
displayoptions: ['inblock' => true],
|
||||
);
|
||||
return $this->content;
|
||||
}
|
||||
}
|
||||
|
72
blocks/site_main_menu/classes/output/mainsection.php
Normal file
72
blocks/site_main_menu/classes/output/mainsection.php
Normal file
@ -0,0 +1,72 @@
|
||||
<?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/>.
|
||||
|
||||
namespace block_site_main_menu\output;
|
||||
|
||||
use core_courseformat\base as courseformat;
|
||||
use renderable;
|
||||
use section_info;
|
||||
use templatable;
|
||||
|
||||
/**
|
||||
* Class mainsection
|
||||
*
|
||||
* @package block_site_main_menu
|
||||
* @copyright 2024 Ferran Recio <ferran@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class mainsection implements renderable, templatable {
|
||||
|
||||
/**
|
||||
* The class constructor.
|
||||
*
|
||||
* @param courseformat $format the course format instance
|
||||
* @param section_info $section the section to render
|
||||
*/
|
||||
public function __construct(
|
||||
/** @var courseformat $format the course format instance. */
|
||||
protected courseformat $format,
|
||||
/** @var section_info $section the section to render. */
|
||||
protected section_info $section,
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Export for template.
|
||||
*
|
||||
* @param \renderer_base $output
|
||||
* @return array
|
||||
*/
|
||||
public function export_for_template(\renderer_base $output) {
|
||||
$format = $this->format;
|
||||
$course = $format->get_course();
|
||||
$section = $this->section;
|
||||
|
||||
$sectionoutputclass = $format->get_output_classname('content\\section\\cmlist');
|
||||
$sectionoutput = new $sectionoutputclass($format, $section);
|
||||
|
||||
$cmlist = $output->render($sectionoutput);
|
||||
|
||||
return [
|
||||
'siteid' => $course->id,
|
||||
'cmlist' => $cmlist,
|
||||
'sectionid' => $section->id,
|
||||
'sectionname' => $format->get_section_name($section),
|
||||
'sectionnum' => $section->sectionnum,
|
||||
'editing' => $format->show_editor(),
|
||||
];
|
||||
}
|
||||
}
|
@ -1,26 +1,34 @@
|
||||
.block_site_main_menu li {
|
||||
clear: both;
|
||||
/* Imitate mobile grid for activity card. */
|
||||
.block_site_main_menu .activity-item .activity-grid {
|
||||
grid-template-columns: min-content 1fr min-content min-content min-content;
|
||||
grid-template-rows: 1fr repeat(4, min-content);
|
||||
grid-template-areas:
|
||||
"icon name actions"
|
||||
"visibility visibility visibility"
|
||||
"dates dates dates"
|
||||
"completion completion completion"
|
||||
"altcontent altcontent altcontent"
|
||||
"afterlink afterlink afterlink"
|
||||
"availability availability availability";
|
||||
}
|
||||
|
||||
.block_site_main_menu.block .content > .unlist > li > .column {
|
||||
/* Made specific to win over .block.list_block .unlist > li > .column. */
|
||||
width: 100%;
|
||||
display: table;
|
||||
margin-bottom: 0.5rem;
|
||||
.block_site_main_menu .activity-item .activity-grid.noname-grid {
|
||||
grid-template-columns: 1fr min-content;
|
||||
grid-template-areas:
|
||||
"actions"
|
||||
"visibility"
|
||||
"altcontent"
|
||||
"groupmode"
|
||||
"afterlink"
|
||||
"completion"
|
||||
"availability";
|
||||
}
|
||||
|
||||
.block_site_main_menu li .buttons a img {
|
||||
vertical-align: text-bottom;
|
||||
.block_site_main_menu .activity-item .activity-grid.noname-grid .activity-actions {
|
||||
justify-self: end;
|
||||
}
|
||||
|
||||
.block_site_main_menu .footer {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.block_site_main_menu .section_add_menus noscript div {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.block_site_main_menu .instancename {
|
||||
word-break: break-all;
|
||||
/* Hide extra edit elements in block space. */
|
||||
.block_site_main_menu .activity-groupmode-info {
|
||||
display: none;
|
||||
}
|
||||
|
85
blocks/site_main_menu/templates/mainsection.mustache
Normal file
85
blocks/site_main_menu/templates/mainsection.mustache
Normal file
@ -0,0 +1,85 @@
|
||||
{{!
|
||||
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/>.
|
||||
}}
|
||||
{{!
|
||||
@template block_site_main_menu/mainsection
|
||||
|
||||
This mustache emulates a course single section structure inside a block.
|
||||
|
||||
It requires to include several divs to emulate the structure of a course format.
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"cmlist": "Sample",
|
||||
"siteid": 1,
|
||||
"sectionid": 1,
|
||||
"sectionname": "Sample",
|
||||
"sectionnum": 1,
|
||||
"editing": true
|
||||
}
|
||||
}}
|
||||
<div
|
||||
id="block_site_main_menu_section"
|
||||
class="course-content"
|
||||
>
|
||||
{{! The section list is used by the content module to init the sections.}}
|
||||
<div
|
||||
data-for="course_sectionlist"
|
||||
>
|
||||
{{! The section need some bottom padding and margin for the dropzone.
|
||||
Otherwise the activities will cover the area. }}
|
||||
<div
|
||||
class="mainsection section pb-3"
|
||||
data-for="section"
|
||||
data-sectionid="{{sectionid}}"
|
||||
data-id="{{sectionid}}"
|
||||
data-number="{{sectionnum}}"
|
||||
data-sectionname="{{sectionname}}"
|
||||
>
|
||||
{{#editing}}
|
||||
{{! The section header is used as a dropzone when the section is empty.}}
|
||||
<div
|
||||
class="section-header"
|
||||
data-for="section_title"
|
||||
data-id="{{sectionid}}"
|
||||
data-number="{{sectionnum}}"
|
||||
> </div>
|
||||
{{/editing}}
|
||||
{{{cmlist}}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{#js}}
|
||||
{{! The block should be fast to load, we only load the editor when needed.}}
|
||||
{{#editing}}
|
||||
require(
|
||||
[
|
||||
'core_courseformat/local/content',
|
||||
'core_courseformat/courseeditor'
|
||||
],
|
||||
function(
|
||||
Component,
|
||||
Courseeditor
|
||||
) {
|
||||
{{! The block could be included static in other courses so we use Courseeditor.getCourseEditor. }}
|
||||
new Component({
|
||||
element: document.getElementById('block_site_main_menu_section'),
|
||||
reactive: Courseeditor.getCourseEditor({{siteid}}),
|
||||
});
|
||||
}
|
||||
);
|
||||
{{/editing}}
|
||||
{{/js}}
|
@ -27,10 +27,6 @@
|
||||
|
||||
require_once(__DIR__ . '/../../../../lib/behat/behat_base.php');
|
||||
|
||||
use Behat\Mink\Exception\ExpectationException as ExpectationException,
|
||||
Behat\Mink\Exception\DriverException as DriverException,
|
||||
Behat\Mink\Exception\ElementNotFoundException as ElementNotFoundException;
|
||||
|
||||
/**
|
||||
* Behat steps definitions for block site main menu
|
||||
*
|
||||
@ -40,121 +36,6 @@ use Behat\Mink\Exception\ExpectationException as ExpectationException,
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class behat_block_site_main_menu extends behat_base {
|
||||
|
||||
/**
|
||||
* Returns the DOM node of the activity in the site menu block
|
||||
*
|
||||
* @throws ElementNotFoundException Thrown by behat_base::find
|
||||
* @param string $activityname The activity name
|
||||
* @return NodeElement
|
||||
*/
|
||||
protected function get_site_menu_activity_node($activityname) {
|
||||
$activityname = behat_context_helper::escape($activityname);
|
||||
$xpath = "//*[contains(concat(' ',normalize-space(@class),' '),' block_site_main_menu ')]//li[contains(., $activityname)]";
|
||||
|
||||
return $this->find('xpath', $xpath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the specified activity's action menu contains an item.
|
||||
*
|
||||
* @Then /^"(?P<activity_name_string>(?:[^"]|\\")*)" activity in site main menu block should have "(?P<icon_name_string>(?:[^"]|\\")*)" editing icon$/
|
||||
* @param string $activityname
|
||||
* @param string $iconname
|
||||
*/
|
||||
public function activity_in_site_main_menu_block_should_have_editing_icon($activityname, $iconname) {
|
||||
$activitynode = $this->get_site_menu_activity_node($activityname);
|
||||
|
||||
$notfoundexception = new ExpectationException('"' . $activityname . '" doesn\'t have a "' .
|
||||
$iconname . '" editing icon', $this->getSession());
|
||||
$this->find('named_partial', array('link', $iconname), $notfoundexception, $activitynode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the specified activity's action menu contains an item.
|
||||
*
|
||||
* @Then /^"(?P<activity_name_string>(?:[^"]|\\")*)" activity in site main menu block should not have "(?P<icon_name_string>(?:[^"]|\\")*)" editing icon$/
|
||||
* @param string $activityname
|
||||
* @param string $iconname
|
||||
*/
|
||||
public function activity_in_site_main_menu_block_should_not_have_editing_icon($activityname, $iconname) {
|
||||
$activitynode = $this->get_site_menu_activity_node($activityname);
|
||||
|
||||
try {
|
||||
$this->find('named_partial', array('link', $iconname), false, $activitynode);
|
||||
throw new ExpectationException('"' . $activityname . '" has a "' . $iconname .
|
||||
'" editing icon when it should not', $this->getSession());
|
||||
} catch (ElementNotFoundException $e) {
|
||||
// This is good, the menu item should not be there.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clicks on the specified element of the activity. You should be in the course page with editing mode turned on.
|
||||
*
|
||||
* @Given /^I click on "(?P<element_string>(?:[^"]|\\")*)" "(?P<selector_string>(?:[^"]|\\")*)" in the "(?P<activity_name_string>(?:[^"]|\\")*)" activity in site main menu block$/
|
||||
* @param string $element
|
||||
* @param string $selectortype
|
||||
* @param string $activityname
|
||||
*/
|
||||
public function i_click_on_in_the_activity_in_site_main_menu_block($element, $selectortype, $activityname) {
|
||||
$element = $this->get_site_menu_activity_element($element, $selectortype, $activityname);
|
||||
$element->click();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clicks on the specified element inside the activity container.
|
||||
*
|
||||
* @throws ElementNotFoundException
|
||||
* @param string $element
|
||||
* @param string $selectortype
|
||||
* @param string $activityname
|
||||
* @return NodeElement
|
||||
*/
|
||||
protected function get_site_menu_activity_element($element, $selectortype, $activityname) {
|
||||
$activitynode = $this->get_site_menu_activity_node($activityname);
|
||||
|
||||
$exception = new ElementNotFoundException($this->getSession(), "'{$element}' '{$selectortype}' in '{$activityname}'");
|
||||
return $this->find($selectortype, $element, $exception, $activitynode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the specified activity is hidden.
|
||||
*
|
||||
* @Then /^"(?P<activity_name_string>(?:[^"]|\\")*)" activity in site main menu block should be hidden$/
|
||||
* @param string $activityname
|
||||
*/
|
||||
public function activity_in_site_main_menu_block_should_be_hidden($activityname) {
|
||||
$activitynode = $this->get_site_menu_activity_node($activityname);
|
||||
$exception = new ExpectationException('"' . $activityname . '" is not hidden', $this->getSession());
|
||||
$this->find('named_partial', array('badge', get_string('hiddenfromstudents')), $exception, $activitynode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the specified activity is hidden.
|
||||
*
|
||||
* @Then /^"(?P<activity_name_string>(?:[^"]|\\")*)" activity in site main menu block should be available but hidden from course page$/
|
||||
* @param string $activityname
|
||||
*/
|
||||
public function activity_in_site_main_menu_block_should_be_available_but_hidden_from_course_page($activityname) {
|
||||
$activitynode = $this->get_site_menu_activity_node($activityname);
|
||||
$exception = new ExpectationException('"' . $activityname . '" is not hidden but available', $this->getSession());
|
||||
$this->find('named_partial', array('badge', get_string('hiddenoncoursepage')), $exception, $activitynode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens an activity actions menu if it is not already opened.
|
||||
*
|
||||
* @Given /^I open "(?P<activity_name_string>(?:[^"]|\\")*)" actions menu in site main menu block$/
|
||||
* @throws DriverException The step is not available when Javascript is disabled
|
||||
* @param string $activityname
|
||||
*/
|
||||
public function i_open_actions_menu_in_site_main_menu_block($activityname) {
|
||||
$activityname = behat_context_helper::escape($activityname);
|
||||
$xpath = "//*[contains(concat(' ',normalize-space(@class),' '),' block_site_main_menu ')]//li[contains(., $activityname)]";
|
||||
$this->execute('behat_action_menu::i_open_the_action_menu_in', [$xpath, 'xpath_element']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of partial named selectors.
|
||||
*
|
||||
|
@ -0,0 +1,194 @@
|
||||
<?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/>.
|
||||
|
||||
// NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php.
|
||||
|
||||
require_once(__DIR__ . '/../../../../lib/behat/behat_deprecated_base.php');
|
||||
|
||||
use Behat\Mink\Element\NodeElement;
|
||||
use Behat\Mink\Exception\ExpectationException as ExpectationException;
|
||||
use Behat\Mink\Exception\DriverException as DriverException;
|
||||
use Behat\Mink\Exception\ElementNotFoundException as ElementNotFoundException;
|
||||
|
||||
/**
|
||||
* Behat steps in plugin block_site_main_menu
|
||||
*
|
||||
* @package block_site_main_menu
|
||||
* @category test
|
||||
* @copyright 2024 Ferran Recio <ferran@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class behat_block_site_main_menu_deprecated extends behat_deprecated_base {
|
||||
|
||||
/**
|
||||
* Returns the DOM node of the activity in the site menu block
|
||||
*
|
||||
* @todo MDL-78077 This will be deleted in Moodle 6.0.
|
||||
* @throws ElementNotFoundException Thrown by behat_base::find
|
||||
* @param string $activityname The activity name
|
||||
* @return NodeElement
|
||||
*/
|
||||
protected function get_site_menu_activity_node($activityname) {
|
||||
$activityname = behat_context_helper::escape($activityname);
|
||||
$xpath = "//*[contains(concat(' ',normalize-space(@class),' '),' block_site_main_menu ')]//li[contains(., $activityname)]";
|
||||
|
||||
return $this->find('xpath', $xpath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clicks on the specified element of the activity. You should be in the course page with editing mode turned on.
|
||||
*
|
||||
* @todo MDL-78077 This will be deleted in Moodle 6.0.
|
||||
* @deprecated since 5.0
|
||||
*
|
||||
* @Given /^I click on "(?P<element_string>(?:[^"]|\\")*)" "(?P<selector_string>(?:[^"]|\\")*)" in the "(?P<activity_name_string>(?:[^"]|\\")*)" activity in site main menu block$/
|
||||
* @param string $element
|
||||
* @param string $selectortype
|
||||
* @param string $activityname
|
||||
*/
|
||||
public function i_click_on_in_the_activity_in_site_main_menu_block($element, $selectortype, $activityname) {
|
||||
$this->deprecated_message([
|
||||
'behat_block_site_main_menu::i_click_on_in_the_activity_in_site_main_menu_block is deprecated',
|
||||
'Use: I open ACTIVITYNAME actions menu & I choose OPTIONTEXT in the open action menu',
|
||||
]);
|
||||
$element = $this->get_site_menu_activity_element($element, $selectortype, $activityname);
|
||||
$element->click();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clicks on the specified element inside the activity container.
|
||||
*
|
||||
* @todo MDL-78077 This will be deleted in Moodle 6.0.
|
||||
* @throws ElementNotFoundException
|
||||
* @param string $element
|
||||
* @param string $selectortype
|
||||
* @param string $activityname
|
||||
* @return NodeElement
|
||||
*/
|
||||
protected function get_site_menu_activity_element($element, $selectortype, $activityname) {
|
||||
$activitynode = $this->get_site_menu_activity_node($activityname);
|
||||
|
||||
$exception = new ElementNotFoundException($this->getSession(), "'{$element}' '{$selectortype}' in '{$activityname}'");
|
||||
return $this->find($selectortype, $element, $exception, $activitynode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the specified activity's action menu contains an item.
|
||||
*
|
||||
* @todo MDL-78077 This will be deleted in Moodle 6.0.
|
||||
* @deprecated since 5.0
|
||||
*
|
||||
* @Then /^"(?P<activity_name_string>(?:[^"]|\\")*)" activity in site main menu block should have "(?P<icon_name_string>(?:[^"]|\\")*)" editing icon$/
|
||||
* @param string $activityname
|
||||
* @param string $iconname
|
||||
*/
|
||||
public function activity_in_site_main_menu_block_should_have_editing_icon($activityname, $iconname) {
|
||||
$this->deprecated_message([
|
||||
'behat_block_site_main_menu::activity_in_site_main_menu_block_should_have_editing_icon is deprecated',
|
||||
'Use: I should see WHATEVER in the ACTIVITYNAME "activity"',
|
||||
]);
|
||||
|
||||
$activitynode = $this->get_site_menu_activity_node($activityname);
|
||||
|
||||
$notfoundexception = new ExpectationException('"' . $activityname . '" doesn\'t have a "' .
|
||||
$iconname . '" editing icon', $this->getSession());
|
||||
$this->find('named_partial', ['link', $iconname], $notfoundexception, $activitynode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the specified activity's action menu contains an item.
|
||||
*
|
||||
* @todo MDL-78077 This will be deleted in Moodle 6.0.
|
||||
* @deprecated since 5.0
|
||||
*
|
||||
* @Then /^"(?P<activity_name_string>(?:[^"]|\\")*)" activity in site main menu block should not have "(?P<icon_name_string>(?:[^"]|\\")*)" editing icon$/
|
||||
* @param string $activityname
|
||||
* @param string $iconname
|
||||
*/
|
||||
public function activity_in_site_main_menu_block_should_not_have_editing_icon($activityname, $iconname) {
|
||||
$this->deprecated_message([
|
||||
'behat_block_site_main_menu::activity_in_site_main_menu_block_should_not_have_editing_icon is deprecated',
|
||||
'Use: I should not see WHATEVER in the ACTIVITYNAME "activity"',
|
||||
]);
|
||||
$activitynode = $this->get_site_menu_activity_node($activityname);
|
||||
|
||||
try {
|
||||
$this->find('named_partial', array('link', $iconname), false, $activitynode);
|
||||
throw new ExpectationException('"' . $activityname . '" has a "' . $iconname .
|
||||
'" editing icon when it should not', $this->getSession());
|
||||
} catch (ElementNotFoundException $e) {
|
||||
// This is good, the menu item should not be there.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the specified activity is hidden.
|
||||
*
|
||||
* @todo MDL-78077 This will be deleted in Moodle 6.0.
|
||||
* @deprecated since 5.0
|
||||
*
|
||||
* @Then /^"(?P<activity_name_string>(?:[^"]|\\")*)" activity in site main menu block should be hidden$/
|
||||
* @param string $activityname
|
||||
*/
|
||||
public function activity_in_site_main_menu_block_should_be_hidden($activityname) {
|
||||
$this->deprecated_message([
|
||||
'behat_block_site_main_menu::activity_in_site_main_menu_block_should_be_hidden is deprecated',
|
||||
'Use: I should see "Hidden from students" in the "ACTIVITYNAME" "core_courseformat > Activity visibility"',
|
||||
]);
|
||||
$activitynode = $this->get_site_menu_activity_node($activityname);
|
||||
$exception = new ExpectationException('"' . $activityname . '" is not hidden', $this->getSession());
|
||||
$this->find('named_partial', ['badge', get_string('hiddenfromstudents')], $exception, $activitynode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that the specified activity is hidden.
|
||||
*
|
||||
* @todo MDL-78077 This will be deleted in Moodle 6.0.
|
||||
* @deprecated since 5.0
|
||||
*
|
||||
* @Then /^"(?P<activity_name_string>(?:[^"]|\\")*)" activity in site main menu block should be available but hidden from course page$/
|
||||
* @param string $activityname
|
||||
*/
|
||||
public function activity_in_site_main_menu_block_should_be_available_but_hidden_from_course_page($activityname) {
|
||||
$this->deprecated_message([
|
||||
'behat_block_site_main_menu::activity_in_site_main_menu_block_should_be_available_but_hidden_from_course_page is deprecated',
|
||||
'Use: I should see "Available but not shown on course page" in the "ACTIVITYNAME" "core_courseformat > Activity visibility"',
|
||||
]);
|
||||
$activitynode = $this->get_site_menu_activity_node($activityname);
|
||||
$exception = new ExpectationException('"' . $activityname . '" is not hidden but available', $this->getSession());
|
||||
$this->find('named_partial', ['badge', get_string('hiddenoncoursepage')], $exception, $activitynode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens an activity actions menu if it is not already opened.
|
||||
*
|
||||
* @todo MDL-78077 This will be deleted in Moodle 6.0.
|
||||
* @deprecated since 5.0
|
||||
*
|
||||
* @Given /^I open "(?P<activity_name_string>(?:[^"]|\\")*)" actions menu in site main menu block$/
|
||||
* @throws DriverException The step is not available when Javascript is disabled
|
||||
* @param string $activityname
|
||||
*/
|
||||
public function i_open_actions_menu_in_site_main_menu_block($activityname) {
|
||||
$this->deprecated_message([
|
||||
'behat_block_site_main_menu::i_open_actions_menu_in_site_main_menu_block is deprecated',
|
||||
'Use: I open "ACTIVITYNAME" actions menu',
|
||||
]);
|
||||
$activityname = behat_context_helper::escape($activityname);
|
||||
$xpath = "//*[contains(concat(' ',normalize-space(@class),' '),' block_site_main_menu ')]//li[contains(., $activityname)]";
|
||||
$this->execute('behat_action_menu::i_open_the_action_menu_in', [$xpath, 'xpath_element']);
|
||||
}
|
||||
}
|
@ -17,7 +17,7 @@ Feature: Edit activities in main menu block
|
||||
And I log in as "admin"
|
||||
And I am on site homepage
|
||||
And I turn editing mode on
|
||||
When I set the field "Edit title" in the "My forum name" "block_site_main_menu > Activity" to "New forum name"
|
||||
When I set the field "Edit title" in the "My forum name" "activity" to "New forum name"
|
||||
Then I should not see "My forum name"
|
||||
And I should see "New forum name"
|
||||
And I follow "New forum name"
|
||||
@ -38,20 +38,132 @@ Feature: Edit activities in main menu block
|
||||
And I log in as "admin"
|
||||
And I am on site homepage
|
||||
And I turn editing mode on
|
||||
When I open "My forum name" actions menu in site main menu block
|
||||
When I open "My forum name" actions menu
|
||||
And I choose "Availability > Make available but don't show on course page" in the open action menu
|
||||
Then I should see "Available but not shown on course page" in the "My forum name" "core_courseformat > Activity visibility"
|
||||
# Make sure that "Availability" dropdown in the edit menu has three options.
|
||||
And I open "My forum name" actions menu in site main menu block
|
||||
And I click on "Edit settings" "link" in the "My forum name" activity in site main menu block
|
||||
And I open "My forum name" actions menu
|
||||
And I choose "Edit settings" in the open action menu
|
||||
And I expand all fieldsets
|
||||
And the "Availability" select box should contain "Show on course page"
|
||||
And the "Availability" select box should contain "Hide on course page"
|
||||
And the field "Availability" matches value "Make available but don't show on course page"
|
||||
And I press "Save and return to course"
|
||||
And "My forum name" activity in site main menu block should be available but hidden from course page
|
||||
And I should see "Available but not shown on course page" in the "My forum name" "core_courseformat > Activity visibility"
|
||||
And I turn editing mode off
|
||||
And "My forum name" activity in site main menu block should be available but hidden from course page
|
||||
And I should see "Available but not shown on course page" in the "My forum name" "core_courseformat > Activity visibility"
|
||||
And I log out
|
||||
And I should not see "My forum name" in the "Main menu" "block"
|
||||
And I should see "Visible forum" in the "Main menu" "block"
|
||||
|
||||
@javascript
|
||||
Scenario: The move activity modal allow to move from the main menu block to the main content
|
||||
Given the following "activity" exists:
|
||||
| activity | forum |
|
||||
| course | Acceptance test site |
|
||||
| name | My forum name |
|
||||
| idnumber | forum |
|
||||
And the following "blocks" exist:
|
||||
| blockname | contextlevel | reference | pagetypepattern | defaultregion |
|
||||
| site_main_menu | System | 1 | site-index | side-pre |
|
||||
And I log in as "admin"
|
||||
And I am on site homepage
|
||||
And I turn editing mode on
|
||||
And I should see "My forum name" in the "block_site_main_menu_section" "region"
|
||||
And I should not see "My forum name" in the "region-main" "region"
|
||||
When I open "My forum name" actions menu
|
||||
And I click on "Move" "link" in the "My forum name" activity
|
||||
And I should see "My forum name" in the "Move activity" "dialogue"
|
||||
And I should see "Block" in the "Move activity" "dialogue"
|
||||
And I should see "Site" in the "Move activity" "dialogue"
|
||||
And I click on "Site" "link" in the "Move activity" "dialogue"
|
||||
Then I should see "My forum name" in the "region-main" "region"
|
||||
And I should not see "My forum name" in the "block_site_main_menu_section" "region"
|
||||
|
||||
@javascript
|
||||
Scenario: The move activity modal allow to move from the main content to the main menu block
|
||||
Given the following "activity" exists:
|
||||
| activity | forum |
|
||||
| course | Acceptance test site |
|
||||
| name | My forum name |
|
||||
| idnumber | forum |
|
||||
| section | 1 |
|
||||
And the following "blocks" exist:
|
||||
| blockname | contextlevel | reference | pagetypepattern | defaultregion |
|
||||
| site_main_menu | System | 1 | site-index | side-pre |
|
||||
And I log in as "admin"
|
||||
And I am on site homepage
|
||||
And I turn editing mode on
|
||||
And I should not see "My forum name" in the "block_site_main_menu_section" "region"
|
||||
And I should see "My forum name" in the "region-main" "region"
|
||||
When I open "My forum name" actions menu
|
||||
And I click on "Move" "link" in the "My forum name" activity
|
||||
And I should see "My forum name" in the "Move activity" "dialogue"
|
||||
And I should see "Block" in the "Move activity" "dialogue"
|
||||
And I should see "Site" in the "Move activity" "dialogue"
|
||||
And I click on "Block" "link" in the "Move activity" "dialogue"
|
||||
Then I should not see "My forum name" in the "region-main" "region"
|
||||
And I should see "My forum name" in the "block_site_main_menu_section" "region"
|
||||
|
||||
@javascript
|
||||
Scenario: Admin can delete an activity in the main menu block
|
||||
Given the following "activity" exists:
|
||||
| activity | forum |
|
||||
| course | Acceptance test site |
|
||||
| name | My forum name |
|
||||
| idnumber | forum |
|
||||
And the following "blocks" exist:
|
||||
| blockname | contextlevel | reference | pagetypepattern | defaultregion |
|
||||
| site_main_menu | System | 1 | site-index | side-pre |
|
||||
And I log in as "admin"
|
||||
And I am on site homepage
|
||||
And I turn editing mode on
|
||||
And I should see "My forum name" in the "block_site_main_menu_section" "region"
|
||||
When I open "My forum name" actions menu
|
||||
And I choose "Delete" in the open action menu
|
||||
And I click on "Delete" "button" in the "Delete activity?" "dialogue"
|
||||
Then I should not see "My forum name" in the "block_site_main_menu_section" "region"
|
||||
|
||||
@javascript
|
||||
Scenario: Admin can duplicate an activity in the main menu block
|
||||
Given the following "activity" exists:
|
||||
| activity | forum |
|
||||
| course | Acceptance test site |
|
||||
| name | My forum name |
|
||||
| idnumber | forum |
|
||||
And the following "blocks" exist:
|
||||
| blockname | contextlevel | reference | pagetypepattern | defaultregion |
|
||||
| site_main_menu | System | 1 | site-index | side-pre |
|
||||
And I log in as "admin"
|
||||
And I am on site homepage
|
||||
And I turn editing mode on
|
||||
And I should see "My forum name" in the "block_site_main_menu_section" "region"
|
||||
When I open "My forum name" actions menu
|
||||
And I choose "Duplicate" in the open action menu
|
||||
Then I should see "My forum name (copy)" in the "block_site_main_menu_section" "region"
|
||||
|
||||
@javascript
|
||||
Scenario: Admin can move right and left an activity in the main menu block
|
||||
Given the following "activity" exists:
|
||||
| activity | forum |
|
||||
| course | Acceptance test site |
|
||||
| name | My forum name |
|
||||
| idnumber | forum |
|
||||
And the following "blocks" exist:
|
||||
| blockname | contextlevel | reference | pagetypepattern | defaultregion |
|
||||
| site_main_menu | System | 1 | site-index | side-pre |
|
||||
And I log in as "admin"
|
||||
And I am on site homepage
|
||||
And I turn editing mode on
|
||||
And I should see "My forum name" in the "block_site_main_menu_section" "region"
|
||||
When I open "My forum name" actions menu
|
||||
And "Move right" "link" should be visible
|
||||
And "Move left" "link" should not be visible
|
||||
And I choose "Move right" in the open action menu
|
||||
Then I open "My forum name" actions menu
|
||||
And "Move right" "link" should not be visible
|
||||
And "Move left" "link" should be visible
|
||||
And I choose "Move left" in the open action menu
|
||||
And I open "My forum name" actions menu
|
||||
And "Move right" "link" should be visible
|
||||
And "Move left" "link" should not be visible
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -13,6 +13,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import Config from 'core/config';
|
||||
import {getString} from 'core/str';
|
||||
import {Reactive} from 'core/reactive';
|
||||
import notification from 'core/notification';
|
||||
@ -218,6 +219,16 @@ export default class extends Reactive {
|
||||
* @returns {Object} the current course state
|
||||
*/
|
||||
async getServerCourseState() {
|
||||
// Only logged users can get the course state. Filtering here will prevent unnecessary
|
||||
// calls to the server and login page redirects. Especially for home activities with
|
||||
// guest access.
|
||||
if (Config.userId == 0) {
|
||||
return {
|
||||
course: {},
|
||||
section: [],
|
||||
cm: [],
|
||||
};
|
||||
}
|
||||
const courseState = await ajax.call([{
|
||||
methodname: 'core_courseformat_get_state',
|
||||
args: {
|
||||
|
@ -565,6 +565,18 @@ abstract class base {
|
||||
return self::get_section_name($section);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the generic name for sections in this course format.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_generic_section_name() {
|
||||
if (get_string_manager()->string_exists('sectionname', 'format_' . $this->format)) {
|
||||
return get_string('sectionname', 'format_' . $this->format);
|
||||
}
|
||||
return get_string('section');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name for the highlighted section.
|
||||
*
|
||||
|
@ -60,8 +60,8 @@ class bulkedittoggler implements named_templatable, renderable {
|
||||
];
|
||||
|
||||
if ($section) {
|
||||
$data->sectionname = get_string('sectionname', "format_$course->format");
|
||||
$data->sectiontitle = get_section_name($course, $section);
|
||||
$data->sectionname = $format->get_generic_section_name();
|
||||
$data->sectiontitle = $format->get_section_name($section);
|
||||
}
|
||||
|
||||
return $data;
|
||||
|
@ -89,6 +89,7 @@ class frontpagesection implements named_templatable, renderable {
|
||||
}
|
||||
|
||||
$data = (object)[
|
||||
'editing' => $format->show_editor(),
|
||||
'sections' => [$sectionoutput->export_for_template($output)],
|
||||
];
|
||||
|
||||
|
@ -51,16 +51,19 @@ class format_site extends course_format {
|
||||
* Returns the display name of the given section that the course prefers.
|
||||
*
|
||||
* @param int|stdClass $section Section object from database or just field section.section
|
||||
* @return Display name that the course format prefers, e.g. "Topic 2"
|
||||
* @return string Display name that the course format prefers, e.g. "Topic 2"
|
||||
*/
|
||||
function get_section_name($section) {
|
||||
$section = $this->get_section($section);
|
||||
if ((string)$section->name !== '') {
|
||||
// Return the name the user set.
|
||||
return format_string($section->name, true, array('context' => context_course::instance($this->courseid)));
|
||||
} else {
|
||||
return get_string('site');
|
||||
}
|
||||
// The section zero is located in a block.
|
||||
if ($section->sectionnum == 0) {
|
||||
return get_string('block');
|
||||
}
|
||||
return get_string('site');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -85,6 +88,26 @@ class format_site extends course_format {
|
||||
return blocks_get_default_site_course_blocks();
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public function supports_ajax() {
|
||||
// All home page is rendered in the backend, we only need an ajax editor components in edit mode.
|
||||
// This will also prevent redirectng to the login page when a guest tries to access the site,
|
||||
// and will make the home page loading faster.
|
||||
$ajaxsupport = new stdClass();
|
||||
$ajaxsupport->capable = $this->show_editor();
|
||||
return $ajaxsupport;
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public function supports_components() {
|
||||
return true;
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public function uses_sections() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Definitions of the additional options that site uses
|
||||
*
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"editing": true,
|
||||
"sections": [
|
||||
"<li>This is the section content</li>"
|
||||
],
|
||||
@ -28,7 +29,7 @@
|
||||
"settingsurl": "#"
|
||||
}
|
||||
}}
|
||||
<div class="course-content">
|
||||
<div class="course-content" id="courseformat-frontpage-main-topic">
|
||||
{{#showsettings}}
|
||||
<div class="mb-2">
|
||||
<a href="{{{settingsurl}}}" title="{{#str}} edit {{/str}}" aria-label="{{#str}} edit {{/str}}">
|
||||
@ -37,10 +38,18 @@
|
||||
</div>
|
||||
{{/showsettings}}
|
||||
<div class="sitetopic">
|
||||
<ul class="topics frontpage">
|
||||
<ul class="topics frontpage" data-for="course_sectionlist">
|
||||
{{#sections}}
|
||||
{{> core_courseformat/local/content/section }}
|
||||
{{/sections}}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
{{#js}}
|
||||
{{! The home page should be as fast as possible, we only load the editor when needed.}}
|
||||
{{#editing}}
|
||||
require(['core_courseformat/local/content'], function(component) {
|
||||
component.init('courseformat-frontpage-main-topic', {});
|
||||
});
|
||||
{{/editing}}
|
||||
{{/js}}
|
||||
|
@ -997,6 +997,31 @@ class base_test extends advanced_testcase {
|
||||
$this->assertFalse($format->is_section_visible($modinfostudent->get_section_info(2)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for the get_generic_section_name method.
|
||||
*
|
||||
* @covers ::get_generic_section_name
|
||||
*/
|
||||
public function test_get_generic_section_name(): void {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$generator = $this->getDataGenerator();
|
||||
$course1 = $generator->create_course(['format' => 'topics']);
|
||||
$course2 = $generator->create_course(['format' => 'theunittest']);
|
||||
|
||||
$format = course_get_format($course1);
|
||||
$this->assertEquals(
|
||||
get_string('sectionname', 'format_topics'),
|
||||
$format->get_generic_section_name()
|
||||
);
|
||||
|
||||
$format = course_get_format($course2);
|
||||
$this->assertEquals(
|
||||
get_string('section'),
|
||||
$format->get_generic_section_name()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test can_sections_be_removed_from_navigation().
|
||||
*
|
||||
|
@ -2867,7 +2867,7 @@ function include_course_editor(course_format $format) {
|
||||
|
||||
$course = $format->get_course();
|
||||
|
||||
if ($SITE->id === $course->id) {
|
||||
if (!$format->supports_ajax()?->capable) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -99,7 +99,8 @@ $table = new html_table();
|
||||
$table->attributes['class'] = 'generaltable mod_index';
|
||||
|
||||
if ($usesections) {
|
||||
$strsectionname = get_string('sectionname', 'format_'.$course->format);
|
||||
|
||||
$strsectionname = course_get_format($course)->get_generic_section_name();
|
||||
$table->head = array ($strsectionname, $strname, $strintro);
|
||||
$table->align = array ('center', 'left', 'left');
|
||||
} else {
|
||||
|
@ -148,8 +148,8 @@ $editingtitle = '';
|
||||
if ($PAGE->user_is_editing()) {
|
||||
$editingtitle = 'editing';
|
||||
}
|
||||
$sectionname = get_string('sectionname', "format_$course->format");
|
||||
$sectiontitle = get_section_name($course, $section);
|
||||
$sectionname = $format->get_generic_section_name();
|
||||
$sectiontitle = $format->get_section_name($section);
|
||||
$PAGE->set_title(
|
||||
get_string(
|
||||
'coursesectiontitle' . $editingtitle,
|
||||
|
@ -42,3 +42,75 @@ Feature: Site home activities section
|
||||
And I should see "New section description" in the "region-main" "region"
|
||||
Then I turn editing mode off
|
||||
And I should see "New section description" in the "region-main" "region"
|
||||
|
||||
@javascript
|
||||
Scenario: Admin can change the activity visibility in the frontpage
|
||||
Given the following config values are set as admin:
|
||||
| allowstealth | 1 |
|
||||
And the following "activities" exist:
|
||||
| activity | course | section | name | intro | idnumber |
|
||||
| assign | Acceptance test site | 1 | Frontpage assignment | Assignment description | assign0 |
|
||||
When I log in as "admin"
|
||||
And I am on site homepage
|
||||
And I turn editing mode on
|
||||
And I should see "Frontpage assignment" in the "region-main" "region"
|
||||
Then I open "Frontpage assignment" actions menu
|
||||
And I choose "Availability > Make available but don't show on course page" in the open action menu
|
||||
And I should see "Available but not shown on course page" in the "Frontpage assignment" "core_courseformat > Activity visibility"
|
||||
And I open "Frontpage assignment" actions menu
|
||||
And I choose "Availability > Show on course page" in the open action menu
|
||||
And I should not see "Available but not shown on course page" in the "Frontpage assignment" "activity"
|
||||
And I should not see "Hidden from students" in the "Frontpage assignment" "activity"
|
||||
And I open "Frontpage assignment" actions menu
|
||||
And I choose "Availability > Hide on course page" in the open action menu
|
||||
And I should not see "Available but not shown on course page" in the "Frontpage assignment" "activity"
|
||||
And I should see "Hidden from students" in the "Frontpage assignment" "core_courseformat > Activity visibility"
|
||||
|
||||
@javascript
|
||||
Scenario: Admin can delete an activity in the frontpage
|
||||
Given the following "activities" exist:
|
||||
| activity | course | section | name | intro | idnumber |
|
||||
| assign | Acceptance test site | 1 | Frontpage assignment | Assignment description | assign0 |
|
||||
When I log in as "admin"
|
||||
And I am on site homepage
|
||||
And I turn editing mode on
|
||||
And I should see "Frontpage assignment" in the "region-main" "region"
|
||||
Then I open "Frontpage assignment" actions menu
|
||||
And I choose "Delete" in the open action menu
|
||||
And I click on "Delete" "button" in the "Delete activity?" "dialogue"
|
||||
And I should not see "Frontpage assignment" in the "region-main" "region"
|
||||
|
||||
@javascript
|
||||
Scenario: Admin can duplicate an activity in the frontpage
|
||||
Given the following "activities" exist:
|
||||
| activity | course | section | name | intro | idnumber |
|
||||
| assign | Acceptance test site | 1 | Frontpage assignment | Assignment description | assign0 |
|
||||
When I log in as "admin"
|
||||
And I am on site homepage
|
||||
And I turn editing mode on
|
||||
And I should see "Frontpage assignment" in the "region-main" "region"
|
||||
Then I open "Frontpage assignment" actions menu
|
||||
And I choose "Duplicate" in the open action menu
|
||||
And I should see "Frontpage assignment (copy)" in the "region-main" "region"
|
||||
|
||||
@javascript
|
||||
Scenario: Admin can move an activity lefts and right in the frontpage
|
||||
Given the following "activities" exist:
|
||||
| activity | course | section | name | intro | idnumber |
|
||||
| assign | Acceptance test site | 1 | Frontpage assignment | Assignment description | assign0 |
|
||||
| assign | Acceptance test site | 1 | Frontpage assignment | Assignment description | assign1 |
|
||||
And I log in as "admin"
|
||||
And I am on site homepage
|
||||
And I turn editing mode on
|
||||
And I should see "Frontpage assignment" in the "region-main" "region"
|
||||
When I open "Frontpage assignment" actions menu
|
||||
And "Move right" "link" should be visible
|
||||
And "Move left" "link" should not be visible
|
||||
And I choose "Move right" in the open action menu
|
||||
Then I open "Frontpage assignment" actions menu
|
||||
And "Move right" "link" should not be visible
|
||||
And "Move left" "link" should be visible
|
||||
And I choose "Move left" in the open action menu
|
||||
And I open "Frontpage assignment" actions menu
|
||||
And "Move right" "link" should be visible
|
||||
And "Move left" "link" should not be visible
|
||||
|
@ -284,8 +284,8 @@ if ($PAGE->user_is_editing()) {
|
||||
|
||||
// If viewing a section, make the title more specific.
|
||||
if ($section && $section > 0 && course_format_uses_sections($course->format)) {
|
||||
$sectionname = get_string('sectionname', "format_$course->format");
|
||||
$sectiontitle = get_section_name($course, $section);
|
||||
$sectionname = $format->get_generic_section_name();
|
||||
$sectiontitle = $format->get_section_name($section);
|
||||
$PAGE->set_title(
|
||||
get_string(
|
||||
'coursesectiontitle' . $editingtitle,
|
||||
|
14
index.php
14
index.php
@ -109,6 +109,14 @@ $PAGE->set_title(get_string('home'));
|
||||
$PAGE->set_heading($SITE->fullname);
|
||||
$PAGE->set_secondary_active_tab('coursehome');
|
||||
|
||||
$siteformatoptions = course_get_format($SITE)->get_format_options();
|
||||
$modinfo = get_fast_modinfo($SITE);
|
||||
$modnamesused = $modinfo->get_used_module_names();
|
||||
|
||||
// The home page can have acitvities in the block aside. We should
|
||||
// initialize the course editor before the page structure is rendered.
|
||||
include_course_ajax($SITE, $modnamesused);
|
||||
|
||||
$courserenderer = $PAGE->get_renderer('core', 'course');
|
||||
|
||||
if ($hassiteconfig) {
|
||||
@ -119,10 +127,6 @@ if ($hassiteconfig) {
|
||||
|
||||
echo $OUTPUT->header();
|
||||
|
||||
$siteformatoptions = course_get_format($SITE)->get_format_options();
|
||||
$modinfo = get_fast_modinfo($SITE);
|
||||
$modnamesused = $modinfo->get_used_module_names();
|
||||
|
||||
// Print Section or custom info.
|
||||
if (!empty($CFG->customfrontpageinclude)) {
|
||||
// Pre-fill some variables that custom front page might use.
|
||||
@ -135,8 +139,6 @@ if (!empty($CFG->customfrontpageinclude)) {
|
||||
} else if ($siteformatoptions['numsections'] > 0) {
|
||||
echo $courserenderer->frontpage_section1();
|
||||
}
|
||||
// Include course AJAX.
|
||||
include_course_ajax($SITE, $modnamesused);
|
||||
|
||||
echo $courserenderer->frontpage();
|
||||
|
||||
|
@ -3280,7 +3280,7 @@ class assign {
|
||||
$modinfo = get_fast_modinfo($course);
|
||||
|
||||
if ($usesections) {
|
||||
$strsectionname = get_string('sectionname', 'format_'.$course->format);
|
||||
$strsectionname = course_get_format($course)->get_generic_section_name();
|
||||
$sections = $modinfo->get_section_info_all();
|
||||
}
|
||||
$courseindexsummary = new assign_course_index_summary($usesections, $strsectionname);
|
||||
|
@ -61,7 +61,7 @@ class index implements renderable {
|
||||
$table = new html_table();
|
||||
|
||||
if (course_format_uses_sections($this->course->format)) {
|
||||
$sectionheading = get_string('sectionname', "format_{$this->course->format}");
|
||||
$sectionheading = course_get_format($this->course)->get_generic_section_name();
|
||||
} else {
|
||||
$sectionheading = '';
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ $table = new html_table();
|
||||
$table->attributes['class'] = 'generaltable mod_index';
|
||||
|
||||
if ($usesections) {
|
||||
$strsectionname = get_string('sectionname', 'format_'.$course->format);
|
||||
$strsectionname = course_get_format($course)->get_generic_section_name();
|
||||
$table->head = array ($strsectionname, $strname, $strintro);
|
||||
$table->align = array ('center', 'left', 'left');
|
||||
} else {
|
||||
|
@ -62,7 +62,7 @@ $strname = get_string('name');
|
||||
$table = new html_table();
|
||||
|
||||
if ($usesections) {
|
||||
$strsectionname = get_string('sectionname', 'format_'.$course->format);
|
||||
$strsectionname = course_get_format($course)->get_generic_section_name();
|
||||
$table->head = array ($strsectionname, $strname);
|
||||
$table->align = array ('center', 'left');
|
||||
} else {
|
||||
@ -103,4 +103,3 @@ echo html_writer::table($table);
|
||||
// Finish the page.
|
||||
|
||||
echo $OUTPUT->footer();
|
||||
|
||||
|
@ -51,7 +51,7 @@
|
||||
$table = new html_table();
|
||||
|
||||
if ($usesections) {
|
||||
$strsectionname = get_string('sectionname', 'format_'.$course->format);
|
||||
$strsectionname = course_get_format($course)->get_generic_section_name();
|
||||
$table->head = array ($strsectionname, get_string("question"), get_string("answer"));
|
||||
$table->align = array ("center", "left", "left");
|
||||
} else {
|
||||
@ -103,5 +103,3 @@
|
||||
echo html_writer::table($table);
|
||||
|
||||
echo $OUTPUT->footer();
|
||||
|
||||
|
||||
|
@ -75,7 +75,7 @@ $strnumnotapproved = get_string('numnotapproved', 'data');
|
||||
$table = new html_table();
|
||||
|
||||
if ($usesections) {
|
||||
$strsectionname = get_string('sectionname', 'format_'.$course->format);
|
||||
$strsectionname = course_get_format($course)->get_generic_section_name();
|
||||
$table->head = array ($strsectionname, $strname, $strdescription, $strentries, $strnumnotapproved);
|
||||
$table->align = array ('center', 'center', 'center', 'center', 'center');
|
||||
} else {
|
||||
@ -149,4 +149,3 @@ foreach ($datas as $data) {
|
||||
echo "<br />";
|
||||
echo html_writer::tag('div', html_writer::table($table), array('class'=>'no-overflow'));
|
||||
echo $OUTPUT->footer();
|
||||
|
||||
|
@ -77,7 +77,7 @@ $strresponses = get_string('responses', 'feedback');
|
||||
$table = new html_table();
|
||||
|
||||
if ($usesections) {
|
||||
$strsectionname = get_string('sectionname', 'format_'.$course->format);
|
||||
$strsectionname = course_get_format($course)->get_generic_section_name();
|
||||
if (has_capability('mod/feedback:viewreports', $context)) {
|
||||
$table->head = array ($strsectionname, $strname, $strresponses);
|
||||
$table->align = array ("center", "left", 'center');
|
||||
|
@ -66,7 +66,7 @@ $table = new html_table();
|
||||
$table->attributes['class'] = 'generaltable mod_index';
|
||||
|
||||
if ($usesections) {
|
||||
$strsectionname = get_string('sectionname', 'format_'.$course->format);
|
||||
$strsectionname = course_get_format($course)->get_generic_section_name();
|
||||
$table->head = array ($strsectionname, $strname, $strintro);
|
||||
$table->align = array ('center', 'left', 'left');
|
||||
} else {
|
||||
|
@ -349,7 +349,7 @@ if ($show_rss = (($showsubscriptioncolumns || $course->id == SITEID) &&
|
||||
// Now let's process the learning forums.
|
||||
if ($course->id != SITEID) { // Only real courses have learning forums
|
||||
// 'format_.'$course->format only applicable when not SITEID (format_site is not a format)
|
||||
$strsectionname = get_string('sectionname', 'format_'.$course->format);
|
||||
$strsectionname = course_get_format($course)->get_generic_section_name();
|
||||
// Add extra field for section number, at the front
|
||||
array_unshift($learningtable->head, $strsectionname);
|
||||
array_unshift($learningtable->align, 'center');
|
||||
|
@ -58,7 +58,7 @@ $strentries = get_string("entries", "glossary");
|
||||
$table = new html_table();
|
||||
|
||||
if ($usesections) {
|
||||
$strsectionname = get_string('sectionname', 'format_'.$course->format);
|
||||
$strsectionname = course_get_format($course)->get_generic_section_name();
|
||||
$table->head = array ($strsectionname, $strname, $strentries);
|
||||
$table->align = array ('center', 'left', 'center');
|
||||
} else {
|
||||
@ -139,4 +139,3 @@ echo html_writer::table($table);
|
||||
/// Finish the page
|
||||
|
||||
echo $OUTPUT->footer();
|
||||
|
||||
|
@ -61,7 +61,7 @@ $table = new html_table();
|
||||
$table->attributes['class'] = 'generaltable mod_index';
|
||||
|
||||
if ($usesections) {
|
||||
$strsectionname = get_string('sectionname', 'format_'.$course->format);
|
||||
$strsectionname = course_get_format($course)->get_generic_section_name();
|
||||
$table->head = array ($strsectionname, $strname, $strintro);
|
||||
$table->align = array ('center', 'left', 'left');
|
||||
} else {
|
||||
|
@ -78,7 +78,7 @@ $strnodeadline = get_string("nodeadline", "lesson");
|
||||
$table = new html_table();
|
||||
|
||||
if ($usesections) {
|
||||
$strsectionname = get_string('sectionname', 'format_'.$course->format);
|
||||
$strsectionname = course_get_format($course)->get_generic_section_name();
|
||||
$table->head = array ($strsectionname, $strname, $strgrade, $strdeadline);
|
||||
$table->align = array ("center", "left", "center", "center");
|
||||
} else {
|
||||
|
@ -87,7 +87,7 @@ $table = new html_table();
|
||||
$table->attributes['class'] = 'generaltable mod_index';
|
||||
|
||||
if ($usesections) {
|
||||
$strsectionname = get_string('sectionname', 'format_'.$course->format);
|
||||
$strsectionname = course_get_format($course)->get_generic_section_name();
|
||||
$table->head = array ($strsectionname, $strname);
|
||||
$table->align = array ("center", "left");
|
||||
} else {
|
||||
|
@ -60,7 +60,7 @@ $table = new html_table();
|
||||
$table->attributes['class'] = 'generaltable mod_index';
|
||||
|
||||
if ($usesections) {
|
||||
$strsectionname = get_string('sectionname', 'format_'.$course->format);
|
||||
$strsectionname = course_get_format($course)->get_generic_section_name();
|
||||
$table->head = array ($strsectionname, $strname, $strintro);
|
||||
$table->align = array ('center', 'left', 'left');
|
||||
} else {
|
||||
|
@ -74,7 +74,7 @@ array_push($headings, get_string('quizcloses', 'quiz'));
|
||||
array_push($align, 'left');
|
||||
|
||||
if (course_format_uses_sections($course->format)) {
|
||||
array_unshift($headings, get_string('sectionname', 'format_'.$course->format));
|
||||
array_unshift($headings, course_get_format($course)->get_generic_section_name());
|
||||
} else {
|
||||
array_unshift($headings, '');
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ $event->trigger();
|
||||
|
||||
$strresource = get_string('modulename', 'resource');
|
||||
$strresources = get_string('modulenameplural', 'resource');
|
||||
$strsectionname = get_string('sectionname', 'format_'.$course->format);
|
||||
$strsectionname = course_get_format($course)->get_generic_section_name();
|
||||
$strname = get_string('name');
|
||||
$strintro = get_string('moduleintro');
|
||||
$strlastmodified = get_string('lastmodified');
|
||||
|
@ -65,7 +65,7 @@ if (! $scorms = get_all_instances_in_course("scorm", $course)) {
|
||||
$table = new html_table();
|
||||
|
||||
if ($usesections) {
|
||||
$strsectionname = get_string('sectionname', 'format_'.$course->format);
|
||||
$strsectionname = course_get_format($course)->get_generic_section_name();
|
||||
$table->head = array ($strsectionname, $strname, $strsummary, $strreport);
|
||||
$table->align = array ("center", "left", "left", "left");
|
||||
} else {
|
||||
@ -116,4 +116,4 @@ echo html_writer::empty_tag('br');
|
||||
|
||||
echo html_writer::table($table);
|
||||
|
||||
echo $OUTPUT->footer();
|
||||
echo $OUTPUT->footer();
|
||||
|
@ -44,7 +44,7 @@
|
||||
$table = new html_table();
|
||||
|
||||
if ($usesections) {
|
||||
$strsectionname = get_string('sectionname', 'format_'.$course->format);
|
||||
$strsectionname = course_get_format($course)->get_generic_section_name();
|
||||
$table->head = array ($strsectionname, $strname, $strstatus);
|
||||
} else {
|
||||
$table->head = array ($strname, $strstatus);
|
||||
@ -89,5 +89,3 @@
|
||||
echo "<br />";
|
||||
echo html_writer::table($table);
|
||||
echo $OUTPUT->footer();
|
||||
|
||||
|
||||
|
@ -65,7 +65,7 @@ $table = new html_table();
|
||||
$table->attributes['class'] = 'generaltable mod_index';
|
||||
|
||||
if ($usesections) {
|
||||
$strsectionname = get_string('sectionname', 'format_'.$course->format);
|
||||
$strsectionname = course_get_format($course)->get_generic_section_name();
|
||||
$table->head = array ($strsectionname, $strname, $strintro);
|
||||
$table->align = array ('center', 'left', 'left');
|
||||
} else {
|
||||
|
@ -75,7 +75,7 @@ $strname = get_string("name");
|
||||
$table = new html_table();
|
||||
|
||||
if ($usesections) {
|
||||
$strsectionname = get_string('sectionname', 'format_' . $course->format);
|
||||
$strsectionname = course_get_format($course)->get_generic_section_name();
|
||||
$table->head = array($strsectionname, $strname);
|
||||
} else {
|
||||
$table->head = array($strname);
|
||||
|
@ -63,7 +63,7 @@ $strname = get_string('name');
|
||||
$table = new html_table();
|
||||
|
||||
if ($usesections) {
|
||||
$strsectionname = get_string('sectionname', 'format_'.$course->format);
|
||||
$strsectionname = course_get_format($course)->get_generic_section_name();
|
||||
$table->head = array ($strsectionname, $strname);
|
||||
$table->align = array ('center', 'left');
|
||||
} else {
|
||||
|
Loading…
x
Reference in New Issue
Block a user