mirror of
https://github.com/moodle/moodle.git
synced 2025-04-18 23:15:38 +02:00
Merge branch 'MDL-72352-master-v2' of git://github.com/peterRd/moodle
This commit is contained in:
commit
56c55f996a
@ -57,6 +57,7 @@ class secondary extends view {
|
||||
'gradebooksetup' => 2.1,
|
||||
'outcomes' => 2.2,
|
||||
'coursecompletion' => 6,
|
||||
'filtermanagement' => 9,
|
||||
],
|
||||
];
|
||||
$nodes['navigation'] = [
|
||||
@ -197,13 +198,129 @@ class secondary extends view {
|
||||
$this->initialised = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively goes and gets all children nodes.
|
||||
*
|
||||
* @param navigation_node $node The node to get the children of.
|
||||
* @return array The additional child nodes.
|
||||
*/
|
||||
protected function get_additional_child_nodes(navigation_node $node): array {
|
||||
$nodes = [];
|
||||
foreach ($node->children as $child) {
|
||||
if ($child->has_action()) {
|
||||
$nodes[$child->action->out()] = $child->text;
|
||||
}
|
||||
if ($child->has_children()) {
|
||||
$childnodes = $this->get_additional_child_nodes($child);
|
||||
$nodes = array_merge($nodes, $childnodes);
|
||||
}
|
||||
}
|
||||
return $nodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of sections, actions, and text for a url select menu.
|
||||
*
|
||||
* @param navigation_node $node The node to use for a url select menu.
|
||||
* @return array The menu array.
|
||||
*/
|
||||
protected function get_menu_array(navigation_node $node): array {
|
||||
$urldata = [];
|
||||
|
||||
// Check that children have children.
|
||||
$additionalchildren = false;
|
||||
$initialchildren = [];
|
||||
if ($node->has_action()) {
|
||||
$initialchildren[$node->action->out()] = $node->text;
|
||||
}
|
||||
foreach ($node->children as $child) {
|
||||
$additionalnode = [];
|
||||
if ($child->has_action()) {
|
||||
$additionalnode[$child->action->out()] = $child->text;
|
||||
}
|
||||
|
||||
if ($child->has_children()) {
|
||||
$additionalchildren = true;
|
||||
$urldata[][$child->text] = $additionalnode + $this->get_additional_child_nodes($child);
|
||||
} else {
|
||||
$initialchildren += $additionalnode;
|
||||
}
|
||||
}
|
||||
if ($additionalchildren) {
|
||||
$urldata[][$node->text] = $initialchildren;
|
||||
} else {
|
||||
$urldata = $initialchildren;
|
||||
}
|
||||
|
||||
return $urldata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a node with the action being from the first found child node that has an action (Recursive).
|
||||
*
|
||||
* @param navigation_node $node The part of the node tree we are checking.
|
||||
* @param navigation_node $basenode The very first node to be used for the return.
|
||||
* @return navigation_node|null
|
||||
*/
|
||||
protected function get_node_with_first_action(navigation_node $node, navigation_node $basenode): ?navigation_node {
|
||||
$newnode = null;
|
||||
if (!$node->has_children()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Find the first child with an action and update the main node.
|
||||
foreach ($node->children as $child) {
|
||||
if ($child->has_action()) {
|
||||
$newnode = $basenode;
|
||||
$newnode->action = $child->action;
|
||||
return $newnode;
|
||||
}
|
||||
}
|
||||
if (is_null($newnode)) {
|
||||
// Check for children and go again.
|
||||
foreach ($node->children as $child) {
|
||||
if ($child->has_children()) {
|
||||
$newnode = $this->get_node_with_first_action($child, $basenode);
|
||||
|
||||
if (!is_null($newnode)) {
|
||||
return $newnode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Some nodes are containers only with no action. If this container has an action then nothing is done. If it does not have
|
||||
* an action then a search is done through the children looking for the first node that has an action. This action is then given
|
||||
* to the parent node that is initially provided as a parameter.
|
||||
*
|
||||
* @param navigation_node $node The navigation node that we want to ensure has an action tied to it.
|
||||
* @return navigation_node The node intact with an action to use.
|
||||
*/
|
||||
protected function get_first_action_for_node(navigation_node $node): ?navigation_node {
|
||||
// If the node does not have children OR has an action no further processing needed.
|
||||
$newnode = null;
|
||||
if ($node->has_children()) {
|
||||
if (!$node->has_action()) {
|
||||
// We want to find the first child with an action.
|
||||
// We want to check all children on this level before going further down.
|
||||
// Note that new node gets changed here.
|
||||
$newnode = $this->get_node_with_first_action($node, $node);
|
||||
} else {
|
||||
$newnode = $node;
|
||||
}
|
||||
}
|
||||
return $newnode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the course secondary navigation. Since we are sourcing all the info from existing objects that already do
|
||||
* the relevant checks, we don't do it again here.
|
||||
*/
|
||||
protected function load_course_navigation(): void {
|
||||
$course = $this->page->course;
|
||||
|
||||
// Initialise the main navigation and settings nav.
|
||||
// It is important that this is done before we try anything.
|
||||
$settingsnav = $this->page->settingsnav;
|
||||
@ -224,6 +341,74 @@ class secondary extends view {
|
||||
$url = new \moodle_url('/course/admin.php', array('courseid' => $this->page->course->id));
|
||||
$this->add($text, $url, null, null, 'courseadmin', new \pix_icon('t/edit', $text));
|
||||
}
|
||||
|
||||
// Try to get any custom nodes defined by a user which may include containers.
|
||||
$expectedcourseadmin = ['editsettings', 'coursecompletion', 'users', 'coursereports', 'gradebooksetup', 'coursebadges',
|
||||
'backup', 'restore', 'import', 'copy', 'reset', 'questionbank'];
|
||||
foreach ($settingsnav->children as $value) {
|
||||
if ($value->key == 'courseadmin') {
|
||||
foreach ($value->children as $other) {
|
||||
if (array_search($other->key, $expectedcourseadmin) === false) {
|
||||
$othernode = $this->get_first_action_for_node($other);
|
||||
// Get the first node and check whether it's been added already.
|
||||
if ($othernode && !$this->get($othernode->key)) {
|
||||
$this->add_node($othernode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively looks for a match to the current page url.
|
||||
*
|
||||
* @param navigation_node $node The node to look through.
|
||||
* @return navigation_node|null The node that matches this page's url.
|
||||
*/
|
||||
protected function nodes_match_current_url(navigation_node $node): ?navigation_node {
|
||||
$pagenode = $this->page->url;
|
||||
if ($node->has_action()) {
|
||||
// Check this node first.
|
||||
if ($node->action->compare($pagenode)) {
|
||||
return $node;
|
||||
}
|
||||
}
|
||||
if ($node->has_children()) {
|
||||
foreach ($node->children as $child) {
|
||||
$result = $this->nodes_match_current_url($child);
|
||||
if ($result) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a url_select object with overflow navigation nodes.
|
||||
*
|
||||
* @return \url_select|null The overflow menu data.
|
||||
*/
|
||||
public function get_overflow_menu_data(): ?\url_select {
|
||||
$activenode = $this->find_active_node();
|
||||
if ($activenode && $activenode->has_action() && $activenode->has_children() && $activenode->key != 'coursehome') {
|
||||
// This needs to be expanded to does the active node have children and does the page url match any of the children.
|
||||
$menunode = $this->page->settingsnav->find($activenode->key, null);
|
||||
if ($menunode instanceof navigation_node) {
|
||||
// Loop through all children and try and find a match to the current url.
|
||||
$matchednode = $this->nodes_match_current_url($menunode);
|
||||
if (is_null($matchednode)) {
|
||||
return null;
|
||||
}
|
||||
if (!isset($menunode) || !$menunode->has_children()) {
|
||||
return null;
|
||||
}
|
||||
$selectdata = $this->get_menu_array($menunode);
|
||||
return new \url_select($selectdata, $matchednode->action->out(), null);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -342,7 +527,15 @@ class secondary extends view {
|
||||
$leftover = array_diff($existingkeys, $populatedkeys);
|
||||
foreach ($leftover as $key) {
|
||||
if (!in_array($key, $flattenednodes) && $leftovernode = $completenode->get($key)) {
|
||||
$this->add_node($leftovernode);
|
||||
// Check for nodes with children and potentially no action to direct to.
|
||||
if ($leftovernode->has_children()) {
|
||||
$leftovernode = $this->get_first_action_for_node($leftovernode);
|
||||
}
|
||||
|
||||
// Confirm we have a valid object to add.
|
||||
if ($leftovernode) {
|
||||
$this->add_node($leftovernode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4516,7 +4516,8 @@ class settings_navigation extends navigation_node {
|
||||
// Manage filters
|
||||
if ($adminoptions->filters) {
|
||||
$url = new moodle_url('/filter/manage.php', array('contextid'=>$coursecontext->id));
|
||||
$coursenode->add(get_string('filters', 'admin'), $url, self::TYPE_SETTING, null, null, new pix_icon('i/filter', ''));
|
||||
$coursenode->add(get_string('filters', 'admin'), $url, self::TYPE_SETTING,
|
||||
null, 'filtermanagement', new pix_icon('i/filter', ''));
|
||||
}
|
||||
|
||||
// View course reports.
|
||||
|
@ -404,4 +404,415 @@ class secondary_test extends \advanced_testcase {
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursive call to generate a navigation node given an array definition.
|
||||
*
|
||||
* @param array $structure
|
||||
* @param string $parentkey
|
||||
* @return navigation_node
|
||||
*/
|
||||
private function generate_node_tree_construct(array $structure, string $parentkey): navigation_node {
|
||||
$node = navigation_node::create($parentkey, null, navigation_node::TYPE_CUSTOM, '', $parentkey);
|
||||
foreach ($structure as $key => $value) {
|
||||
if (is_array($value)) {
|
||||
$children = $value['children'] ?? $value;
|
||||
$child = $this->generate_node_tree_construct($children, $key);
|
||||
if (isset($value['action'])) {
|
||||
$child->action = new \moodle_url($value['action']);
|
||||
}
|
||||
$node->add_node($child);
|
||||
} else {
|
||||
$node->add($key, $value, navigation_node::TYPE_CUSTOM, '', $key);
|
||||
}
|
||||
}
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the nodes_match_current_url function.
|
||||
*
|
||||
* @param string $selectedurl
|
||||
* @param string $expectednode
|
||||
* @dataProvider test_nodes_match_current_url_provider
|
||||
*/
|
||||
public function test_nodes_match_current_url(string $selectedurl, string $expectednode) {
|
||||
global $PAGE;
|
||||
$structure = [
|
||||
'parentnode1' => [
|
||||
'child1' => '/my',
|
||||
'child2' => [
|
||||
'child2.1' => '/view/course.php',
|
||||
'child2.2' => '/view/admin.php',
|
||||
]
|
||||
]
|
||||
];
|
||||
$node = $this->generate_node_tree_construct($structure, 'primarynode');
|
||||
$node->action = new \moodle_url('/');
|
||||
|
||||
$PAGE->set_url($selectedurl);
|
||||
$secondary = new secondary($PAGE);
|
||||
$method = new ReflectionMethod('core\navigation\views\secondary', 'nodes_match_current_url');
|
||||
$method->setAccessible(true);
|
||||
$response = $method->invoke($secondary, $node);
|
||||
|
||||
$this->assertSame($response->key ?? null, $expectednode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provider for test_nodes_match_current_url
|
||||
*
|
||||
* @return \string[][]
|
||||
*/
|
||||
public function test_nodes_match_current_url_provider(): array {
|
||||
return [
|
||||
"Match url to a node that is a deep nested" => [
|
||||
'/view/course.php',
|
||||
'child2.1',
|
||||
],
|
||||
"Match url to a parent node with children" => [
|
||||
'/', 'primarynode'
|
||||
],
|
||||
"Match url to a child node" => [
|
||||
'/my', 'child1'
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the get_menu_array function
|
||||
*
|
||||
* @param string $selected
|
||||
* @param array $expected
|
||||
* @dataProvider test_get_menu_array_provider
|
||||
*/
|
||||
public function test_get_menu_array(string $selected, array $expected) {
|
||||
global $PAGE;
|
||||
|
||||
// Custom nodes - mimicing nodes added via 3rd party plugins.
|
||||
$structure = [
|
||||
'parentnode1' => [
|
||||
'child1' => '/my',
|
||||
'child2' => [
|
||||
'action' => '/test.php',
|
||||
'children' => [
|
||||
'child2.1' => '/view/course.php?child=2',
|
||||
'child2.2' => '/view/admin.php?child=2',
|
||||
'child2.3' => '/test.php',
|
||||
]
|
||||
],
|
||||
'child3' => [
|
||||
'child3.1' => '/view/course.php?child=3',
|
||||
'child3.2' => '/view/admin.php?child=3',
|
||||
]
|
||||
],
|
||||
'parentnode2' => "/view/module.php"
|
||||
];
|
||||
|
||||
$secondary = new secondary($PAGE);
|
||||
$secondary->add_node($this->generate_node_tree_construct($structure, 'primarynode'));
|
||||
$selectednode = $secondary->find($selected, null);
|
||||
$method = new ReflectionMethod('core\navigation\views\secondary', 'get_menu_array');
|
||||
$method->setAccessible(true);
|
||||
$response = $method->invoke($secondary, $selectednode);
|
||||
|
||||
$this->assertSame($expected, $response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provider for test_get_menu_array
|
||||
*
|
||||
* @return array[]
|
||||
*/
|
||||
public function test_get_menu_array_provider(): array {
|
||||
return [
|
||||
"Fetch information from a node with action and no children" => [
|
||||
'child1',
|
||||
[
|
||||
'https://www.example.com/moodle/my' => 'child1'
|
||||
],
|
||||
],
|
||||
"Fetch information from a node with no action and children" => [
|
||||
'child3',
|
||||
[
|
||||
'https://www.example.com/moodle/view/course.php?child=3' => 'child3.1',
|
||||
'https://www.example.com/moodle/view/admin.php?child=3' => 'child3.2'
|
||||
],
|
||||
],
|
||||
"Fetch information from a node with children" => [
|
||||
'child2',
|
||||
[
|
||||
'https://www.example.com/moodle/test.php' => 'child2',
|
||||
'https://www.example.com/moodle/view/course.php?child=2' => 'child2.1',
|
||||
'https://www.example.com/moodle/view/admin.php?child=2' => 'child2.2'
|
||||
],
|
||||
],
|
||||
"Fetch information from a node with an action and no children" => [
|
||||
'parentnode2',
|
||||
['https://www.example.com/moodle/view/module.php' => 'parentnode2'],
|
||||
],
|
||||
"Fetch information from a node with an action and multiple nested children" => [
|
||||
'parentnode1',
|
||||
[
|
||||
[
|
||||
'child2' => [
|
||||
'https://www.example.com/moodle/test.php' => 'child2',
|
||||
'https://www.example.com/moodle/view/course.php?child=2' => 'child2.1',
|
||||
'https://www.example.com/moodle/view/admin.php?child=2' => 'child2.2',
|
||||
]
|
||||
],
|
||||
[
|
||||
'child3' => [
|
||||
'https://www.example.com/moodle/view/course.php?child=3' => 'child3.1',
|
||||
'https://www.example.com/moodle/view/admin.php?child=3' => 'child3.2'
|
||||
]
|
||||
],
|
||||
[
|
||||
'parentnode1' => [
|
||||
'https://www.example.com/moodle/my' => 'child1'
|
||||
]
|
||||
]
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the get_node_with_first_action function
|
||||
*
|
||||
* @param string $selectedkey
|
||||
* @param string|null $expectedkey
|
||||
* @dataProvider test_get_node_with_first_action_provider
|
||||
*/
|
||||
public function test_get_node_with_first_action(string $selectedkey, ?string $expectedkey) {
|
||||
global $PAGE;
|
||||
$structure = [
|
||||
'parentnode1' => [
|
||||
'child1' => [
|
||||
'child1.1' => null
|
||||
],
|
||||
'child2' => [
|
||||
'child2.1' => [
|
||||
'child2.1.1' => [
|
||||
'action' => '/test.php',
|
||||
'children' => [
|
||||
'child2.1.1.1' => '/view/course.php?child=2',
|
||||
'child2.1.1.2' => '/view/admin.php?child=2',
|
||||
]
|
||||
]
|
||||
]
|
||||
],
|
||||
'child3' => [
|
||||
'child3.1' => '/view/course.php?child=3',
|
||||
'child3.2' => '/view/admin.php?child=3',
|
||||
]
|
||||
],
|
||||
'parentnode2' => "/view/module.php"
|
||||
];
|
||||
|
||||
$nodes = $this->generate_node_tree_construct($structure, 'primarynode');
|
||||
$selectednode = $nodes->find($selectedkey, null);
|
||||
|
||||
$expected = null;
|
||||
// Expected response will be the parent node with the action updated.
|
||||
if ($expectedkey) {
|
||||
$expectedbasenode = clone $selectednode;
|
||||
$actionfromnode = $nodes->find($expectedkey, null);
|
||||
$expectedbasenode->action = $actionfromnode->action;
|
||||
$expected = $expectedbasenode;
|
||||
}
|
||||
|
||||
$secondary = new secondary($PAGE);
|
||||
$method = new ReflectionMethod('core\navigation\views\secondary', 'get_node_with_first_action');
|
||||
$method->setAccessible(true);
|
||||
$response = $method->invoke($secondary, $selectednode, $selectednode);
|
||||
$this->assertEquals($expected, $response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provider for test_get_node_with_first_action
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function test_get_node_with_first_action_provider(): array {
|
||||
return [
|
||||
"Search for action when parent has no action and multiple children with actions" => [
|
||||
"child3",
|
||||
"child3.1",
|
||||
],
|
||||
"Search for action when parent child is deeply nested." => [
|
||||
"child2",
|
||||
"child2.1.1"
|
||||
],
|
||||
"No navigation node returned when node has no children" => [
|
||||
"parentnode2",
|
||||
null
|
||||
],
|
||||
"No navigation node returned when node has children but no actions available." => [
|
||||
"child1",
|
||||
null
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for get_additional_child_nodes
|
||||
*
|
||||
* @param string $selectedkey
|
||||
* @param array $expected
|
||||
* @dataProvider test_get_additional_child_nodes_provider
|
||||
*/
|
||||
public function test_get_additional_child_nodes(string $selectedkey, array $expected) {
|
||||
global $PAGE;
|
||||
$structure = [
|
||||
'parentnode1' => [
|
||||
'child1' => '/my',
|
||||
'child2' => [
|
||||
'action' => '/test.php',
|
||||
'children' => [
|
||||
'child2.1' => '/view/course.php?child=2',
|
||||
'child2.2' => '/view/admin.php?child=2',
|
||||
]
|
||||
],
|
||||
'child3' => [
|
||||
'child3.1' => '/view/course.php?child=3',
|
||||
'child3.2' => '/view/admin.php?child=3',
|
||||
]
|
||||
],
|
||||
'parentnode2' => "/view/module.php"
|
||||
];
|
||||
|
||||
$secondary = new secondary($PAGE);
|
||||
$nodes = $this->generate_node_tree_construct($structure, 'primarynode');
|
||||
$selectednode = $nodes->find($selectedkey, null);
|
||||
$method = new ReflectionMethod('core\navigation\views\secondary', 'get_additional_child_nodes');
|
||||
$method->setAccessible(true);
|
||||
$response = $method->invoke($secondary, $selectednode);
|
||||
|
||||
$this->assertSame($expected, $response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provider for test_get_additional_child_nodes
|
||||
*
|
||||
* @return array[]
|
||||
*/
|
||||
public function test_get_additional_child_nodes_provider(): array {
|
||||
return [
|
||||
"Get nodes with deep nested children" => [
|
||||
"parentnode1",
|
||||
[
|
||||
'https://www.example.com/moodle/my' => 'child1',
|
||||
'https://www.example.com/moodle/test.php' => 'child2',
|
||||
'https://www.example.com/moodle/view/course.php?child=2' => 'child2.1',
|
||||
'https://www.example.com/moodle/view/admin.php?child=2' => 'child2.2',
|
||||
'https://www.example.com/moodle/view/course.php?child=3' => 'child3.1',
|
||||
'https://www.example.com/moodle/view/admin.php?child=3' => 'child3.2',
|
||||
]
|
||||
],
|
||||
"Get children from parent without action " => [
|
||||
"child3",
|
||||
[
|
||||
'https://www.example.com/moodle/view/course.php?child=3' => 'child3.1',
|
||||
'https://www.example.com/moodle/view/admin.php?child=3' => 'child3.2'
|
||||
]
|
||||
],
|
||||
"Get children from parent with action " => [
|
||||
"child2",
|
||||
[
|
||||
'https://www.example.com/moodle/view/course.php?child=2' => 'child2.1',
|
||||
'https://www.example.com/moodle/view/admin.php?child=2' => 'child2.2'
|
||||
]
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the get_overflow_menu_data function
|
||||
*
|
||||
* @param string $selectedurl
|
||||
* @param bool $expectednull
|
||||
* @param bool $emptynode
|
||||
* @dataProvider test_get_overflow_menu_data_provider
|
||||
*/
|
||||
public function test_get_overflow_menu_data(string $selectedurl, bool $expectednull, bool $emptynode = false) {
|
||||
global $PAGE;
|
||||
// Custom nodes - mimicing nodes added via 3rd party plugins.
|
||||
$structure = [
|
||||
'parentnode1' => [
|
||||
'child1' => '/my',
|
||||
'child2' => [
|
||||
'action' => '/test.php',
|
||||
'children' => [
|
||||
'child2.1' => '/view/course.php',
|
||||
'child2.2' => '/view/admin.php',
|
||||
]
|
||||
]
|
||||
],
|
||||
'parentnode2' => "/view/module.php"
|
||||
];
|
||||
$PAGE->set_url($selectedurl);
|
||||
navigation_node::override_active_url(new \moodle_url($selectedurl));
|
||||
$node = $this->generate_node_tree_construct($structure, 'primarynode');
|
||||
$node->action = new \moodle_url('/');
|
||||
|
||||
$secondary = new secondary($PAGE);
|
||||
$secondary->add_node($node);
|
||||
$PAGE->settingsnav->add_node(clone $node);
|
||||
$secondary->add('Course home', '/coursehome.php', navigation_node::TYPE_CUSTOM, '', 'coursehome');
|
||||
$secondary->add('Course settings', '/course/settings.php', navigation_node::TYPE_CUSTOM, '', 'coursesettings');
|
||||
|
||||
// Test for an empty node without children and action.
|
||||
if ($emptynode) {
|
||||
$node = $secondary->add('Course management', null, navigation_node::TYPE_CUSTOM, '', 'course');
|
||||
$node->make_active();
|
||||
} else {
|
||||
// Set the correct node as active.
|
||||
$method = new ReflectionMethod('core\navigation\views\secondary', 'scan_for_active_node');
|
||||
$method->setAccessible(true);
|
||||
$method->invoke($secondary, $secondary);
|
||||
}
|
||||
|
||||
$method = new ReflectionMethod('core\navigation\views\secondary', 'get_overflow_menu_data');
|
||||
$method->setAccessible(true);
|
||||
$response = $method->invoke($secondary);
|
||||
if ($expectednull) {
|
||||
$this->assertNull($response);
|
||||
} else {
|
||||
$this->assertIsObject($response);
|
||||
$this->assertInstanceOf('url_select', $response);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for test_get_overflow_menu_data
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function test_get_overflow_menu_data_provider(): array {
|
||||
return [
|
||||
"Active node is the course home node" => [
|
||||
'/coursehome.php',
|
||||
true
|
||||
],
|
||||
"Active node is one with an action and no children" => [
|
||||
'/view/module.php',
|
||||
false
|
||||
],
|
||||
"Active node is one with an action and children" => [
|
||||
'/',
|
||||
false
|
||||
],
|
||||
"Active node is one without an action and children" => [
|
||||
'/',
|
||||
true,
|
||||
true,
|
||||
],
|
||||
"Active node is one with an action and children but is NOT in settingsnav" => [
|
||||
'/course/settings.php',
|
||||
true
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -71,11 +71,19 @@ $buildregionmainsettings = !$PAGE->include_region_main_settings_in_header_action
|
||||
$regionmainsettingsmenu = $buildregionmainsettings ? $OUTPUT->region_main_settings_menu() : false;
|
||||
|
||||
$secondarynavigation = false;
|
||||
$overflow = false;
|
||||
if (!defined('BEHAT_SITE_RUNNING')) {
|
||||
$buildsecondarynavigation = $PAGE->has_secondary_navigation();
|
||||
if ($buildsecondarynavigation) {
|
||||
$moremenu = new \core\navigation\output\more_menu($PAGE->secondarynav, 'nav-tabs');
|
||||
$secondary = $PAGE->secondarynav;
|
||||
$moremenu = new \core\navigation\output\more_menu($secondary, 'nav-tabs');
|
||||
$secondarynavigation = $moremenu->export_for_template($OUTPUT);
|
||||
|
||||
// Get the pre-content stuff.
|
||||
$overflowdata = $secondary->get_overflow_menu_data();
|
||||
if (!is_null($overflowdata)) {
|
||||
$overflow = $overflowdata->export_for_template($OUTPUT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -100,6 +108,7 @@ $templatecontext = [
|
||||
'usermenu' => $primarymenu['user'],
|
||||
'langmenu' => $primarymenu['lang'],
|
||||
'forceblockdraweropen' => $forceblockdraweropen,
|
||||
'overflow' => $overflow
|
||||
];
|
||||
|
||||
$nav = $PAGE->flatnav;
|
||||
|
@ -129,6 +129,9 @@
|
||||
<div class="region_main_settings_menu_proxy"></div>
|
||||
{{/hasregionmainsettingsmenu}}
|
||||
{{{ output.course_content_header }}}
|
||||
{{#overflow}}
|
||||
{{> core/url_select}}
|
||||
{{/overflow}}
|
||||
{{{ output.main_content }}}
|
||||
{{{ output.activity_navigation }}}
|
||||
{{{ output.course_content_footer }}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user