Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
moodle
moodle
Commits
a665ad27
Commit
a665ad27
authored
Sep 30, 2021
by
Eloy Lafuente
Browse files
Merge branch 'MDL-72396-master' of
https://github.com/sharidas/moodle
parents
2384dc7d
3d18e005
Changes
9
Hide whitespace changes
Inline
Side-by-side
admin/search.php
View file @
a665ad27
...
...
@@ -47,6 +47,7 @@ if ($data = data_submitted() and confirm_sesskey() and isset($data->action) and
}
$PAGE
->
has_secondary_navigation_setter
(
false
);
$PAGE
->
set_primary_active_tab
(
'siteadminnode'
);
// and finally, if we get here, then there are matching settings and we have to print a form
// to modify them
...
...
course/index.php
View file @
a665ad27
...
...
@@ -65,6 +65,9 @@ $courserenderer = $PAGE->get_renderer('core', 'course');
$PAGE
->
set_heading
(
$heading
);
$content
=
$courserenderer
->
course_category
(
$categoryid
);
$PAGE
->
set_primary_active_tab
(
'courses'
);
$PAGE
->
set_secondary_active_tab
(
'categorymain'
);
echo
$OUTPUT
->
header
();
echo
$OUTPUT
->
skip_link_target
();
echo
$content
;
...
...
course/management.php
View file @
a665ad27
...
...
@@ -108,6 +108,7 @@ $PAGE->set_pagelayout('admin');
$PAGE
->
set_title
(
$strmanagement
);
$PAGE
->
set_heading
(
$pageheading
);
$PAGE
->
requires
->
js_call_amd
(
'core_course/copy_modal'
,
'init'
,
array
(
$context
->
id
));
$PAGE
->
set_secondary_active_tab
(
'managecategory'
);
// This is a system level page that operates on other contexts.
require_login
();
...
...
lib/classes/navigation/views/primary.php
View file @
a665ad27
...
...
@@ -16,6 +16,8 @@
namespace
core\navigation\views
;
use
navigation_node
;
/**
* Class primary.
*
...
...
@@ -67,7 +69,61 @@ class primary extends view {
}
// Search and set the active node.
$this
->
search_
for
_active_node
();
$this
->
search_
and_set
_active_node
(
$this
);
$this
->
initialised
=
true
;
}
/**
* Searches all children for the matching active node
*
* This method recursively traverse through the node tree to
* find the node to activate/highlight:
* 1. If the user had set primary node key to highlight, it
* tries to match this key with the node(s). Hence it would
* travel all the nodes.
* 2. If no primary key is provided by the dev, then it would
* check for the active node set in the tree.
*
* @param navigation_node $node
* @param array $actionnodes navigation nodes array to set active and inactive.
* @return navigation_node|null
*/
private
function
search_and_set_active_node
(
navigation_node
$node
,
array
&
$actionnodes
=
[]):
?navigation_node
{
global
$PAGE
;
$activekey
=
$PAGE
->
get_primary_activate_tab
();
if
(
$activekey
)
{
if
(
$node
->
key
&&
(
$activekey
===
$node
->
key
))
{
return
$node
;
}
}
else
if
(
$node
->
check_if_active
(
URL_MATCH_BASE
))
{
return
$node
;
}
foreach
(
$node
->
children
as
$child
)
{
$outcome
=
$this
->
search_and_set_active_node
(
$child
,
$actionnodes
);
if
(
$outcome
!==
null
)
{
$outcome
->
make_active
();
$actionnodes
[
'active'
]
=
$outcome
;
if
(
$activekey
===
null
)
{
return
$actionnodes
[
'active'
];
}
}
else
{
// If the child is active then make it inactive.
if
(
$child
->
isactive
)
{
$actionnodes
[
'set_inactive'
][]
=
$child
;
}
}
}
// If we have successfully found an active node then reset any other nodes to inactive.
if
(
isset
(
$actionnodes
[
'set_inactive'
])
&&
isset
(
$actionnodes
[
'active'
]))
{
foreach
(
$actionnodes
[
'set_inactive'
]
as
$inactivenode
)
{
$inactivenode
->
make_inactive
();
}
$actionnodes
[
'set_inactive'
]
=
[];
}
return
(
$actionnodes
[
'active'
]
??
null
);
}
}
lib/classes/navigation/views/view.php
View file @
a665ad27
...
...
@@ -113,31 +113,42 @@ abstract class view extends navigation_node {
* @param int $strictness How stict to be with the scan for the active node.
* @return navigation_node|null
*/
protected
function
active_node_scan
(
navigation_node
$node
,
int
$strictness
=
URL_MATCH_EXACT
):
?navigation_node
{
protected
function
active_node_scan
(
navigation_node
$node
,
int
$strictness
=
URL_MATCH_EXACT
):
?navigation_node
{
if
(
$node
->
check_if_active
(
$strictness
))
{
$result
=
null
;
$activekey
=
$this
->
page
->
get_secondary_active_tab
();
if
(
$activekey
)
{
if
(
$node
->
key
&&
$activekey
===
$node
->
key
)
{
return
$node
;
}
}
else
if
(
$node
->
check_if_active
(
$strictness
))
{
return
$node
;
// No need to continue, exit function.
}
if
(
$node
->
children
->
count
()
>
0
)
{
foreach
(
$node
->
children
as
$child
)
{
if
(
$this
->
active_node_scan
(
$child
,
$strictness
))
{
// If node is one of the new views then set the active node to the child.
if
(
!
$node
instanceof
view
)
{
$node
->
make_active
();
$child
->
make_inactive
();
}
else
{
$child
->
make_active
();
$this
->
activenode
=
$child
;
}
return
$node
;
// We have found the active node, set the parent status, no need to continue.
}
else
{
// Make sure to reset the active state.
foreach
(
$node
->
children
as
$child
)
{
if
(
$this
->
active_node_scan
(
$child
,
$strictness
))
{
// If node is one of the new views then set the active node to the child.
if
(
!
$node
instanceof
view
)
{
$node
->
make_active
();
$child
->
make_inactive
();
$result
=
$node
;
}
else
{
$child
->
make_active
();
$this
->
activenode
=
$child
;
$result
=
$child
;
}
// If the secondary active tab not set then just return the result (fallback).
if
(
$activekey
===
null
)
{
return
$result
;
}
}
else
{
// Make sure to reset the active state.
$child
->
make_inactive
();
}
}
return
null
;
return
$result
;
}
}
lib/pagelib.php
View file @
a665ad27
...
...
@@ -393,6 +393,16 @@ class moodle_page {
*/
protected
$_hassecondarynavigation
=
true
;
/**
* @var string the key of the secondary node to be activated.
*/
protected
$_activekeysecondary
=
null
;
/**
* @var string the key of the primary node to be activated.
*/
protected
$_activenodeprimary
=
null
;
/**
* Force the settings menu to be displayed on this page. This will only force the
* settings menu on an activity / resource page that is being displayed on a theme that
...
...
@@ -2189,4 +2199,40 @@ class moodle_page {
public
function
has_secondary_navigation
()
:
bool
{
return
$this
->
_hassecondarynavigation
;
}
/**
* Set the key of the secondary nav node to be activated.
*
* @param string $navkey the key of the secondary nav node to be activated.
*/
public
function
set_secondary_active_tab
(
string
$navkey
)
:
void
{
$this
->
_activekeysecondary
=
$navkey
;
}
/**
* The key of secondary nav node to activate.
*
* @return string|null get the key of the secondary node to activate.
*/
public
function
get_secondary_active_tab
():
?string
{
return
$this
->
_activekeysecondary
;
}
/**
* Set the key of the primary nav node to be activated.
*
* @param string $navkey
*/
public
function
set_primary_active_tab
(
string
$navkey
):
void
{
$this
->
_activenodeprimary
=
$navkey
;
}
/**
* The key of the primary nav node to activate.
*
* @return string|null get the key of the primary nav node to activate.
*/
public
function
get_primary_activate_tab
():
?string
{
return
$this
->
_activenodeprimary
;
}
}
lib/tests/navigation/views/primary_test.php
View file @
a665ad27
...
...
@@ -16,6 +16,9 @@
namespace
core\navigation\views
;
use
navigation_node
;
use
ReflectionMethod
;
/**
* Class core_primary_testcase
*
...
...
@@ -63,4 +66,107 @@ class primary_test extends \advanced_testcase {
'Testing as a regular user'
=>
[
'user'
,
[
'home'
,
'myhome'
,
'courses'
]]
];
}
/**
* Get the nav tree initialised to test search_and_set_active_node.
*
* @param string|null $seturl The url set for $PAGE.
* @return navigation_node The initialised nav tree.
*/
private
function
get_tree_initilised_to_set_activate
(
?string
$seturl
=
null
):
navigation_node
{
$node
=
new
navigation_node
(
'My test node'
);
$node
->
type
=
navigation_node
::
TYPE_SYSTEM
;
$node
->
add
(
'first child'
,
null
,
navigation_node
::
TYPE_CUSTOM
,
'firstchld'
,
'firstchild'
);
$child2
=
$node
->
add
(
'second child'
,
null
,
navigation_node
::
TYPE_COURSE
,
'secondchld'
,
'secondchild'
);
$child3
=
$node
->
add
(
'third child'
,
null
,
navigation_node
::
TYPE_CONTAINER
,
'thirdchld'
,
'thirdchild'
);
$node
->
add
(
'fourth child'
,
null
,
navigation_node
::
TYPE_ACTIVITY
,
'fourthchld'
,
'fourthchld'
);
$node
->
add
(
'fifth child'
,
'/my'
,
navigation_node
::
TYPE_CATEGORY
,
'fifthchld'
,
'fifthchild'
);
// If seturl is null then set actionurl of child6 to '/'.
if
(
$seturl
===
null
)
{
$child6actionurl
=
new
\
moodle_url
(
'/'
);
}
else
{
// If seturl is provided then set actionurl of child6 to '/foo'.
$child6actionurl
=
new
\
moodle_url
(
'/foo'
);
}
$child6
=
$child2
->
add
(
'sixth child'
,
$child6actionurl
,
navigation_node
::
TYPE_COURSE
,
'sixthchld'
,
'sixthchild'
);
// Activate the sixthchild node.
$child6
->
make_active
();
$child2
->
add
(
'seventh child'
,
null
,
navigation_node
::
TYPE_COURSE
,
'seventhchld'
,
'seventhchild'
);
$child8
=
$child2
->
add
(
'eighth child'
,
null
,
navigation_node
::
TYPE_CUSTOM
,
'eighthchld'
,
'eighthchild'
);
$child8
->
add
(
'nineth child'
,
null
,
navigation_node
::
TYPE_CUSTOM
,
'ninethchld'
,
'ninethchild'
);
$child3
->
add
(
'tenth child'
,
null
,
navigation_node
::
TYPE_CUSTOM
,
'tenthchld'
,
'tenthchild'
);
return
$node
;
}
/**
* Testing search_and_set_active_node.
*
* @param string $expectedkey Expected key of the node, if set.
* @param string|null $key The key of the node to activate.
* @param string|null $seturl Set the url for $PAGE.
* @return void
* @dataProvider test_search_and_set_active_node_provider
*/
public
function
test_search_and_set_active_node
(
string
$expectedkey
,
?string
$key
=
null
,
?string
$seturl
=
null
):
void
{
global
$PAGE
;
if
(
$seturl
!==
null
)
{
navigation_node
::
override_active_url
(
new
\
moodle_url
(
$seturl
));
}
else
{
$PAGE
->
set_url
(
'/'
);
navigation_node
::
override_active_url
(
new
\
moodle_url
(
'/'
));
}
if
(
$key
!==
null
)
{
$PAGE
->
set_primary_active_tab
(
$key
);
}
$node
=
$this
->
get_tree_initilised_to_set_activate
(
$seturl
);
$primary
=
new
primary
(
$PAGE
);
$method
=
new
ReflectionMethod
(
'core\navigation\views\primary'
,
'search_and_set_active_node'
);
$method
->
setAccessible
(
true
);
$result
=
$method
->
invoke
(
$primary
,
$node
);
$sixthchildnode
=
$node
->
find
(
'sixthchild'
,
navigation_node
::
TYPE_COURSE
);
if
(
$expectedkey
!==
''
)
{
$this
->
assertInstanceOf
(
'navigation_node'
,
$result
);
$this
->
assertEquals
(
$result
->
isactive
,
true
);
$this
->
assertEquals
(
$result
->
key
,
$expectedkey
);
// Test the state of sixthchild, based on $expectedkey.
if
(
$expectedkey
!==
'sixthchild'
)
{
$this
->
assertFalse
(
$sixthchildnode
->
isactive
);
}
else
{
$this
->
assertTrue
(
$sixthchildnode
->
isactive
);
}
}
else
{
$this
->
assertNull
(
$result
);
$this
->
assertTrue
(
$sixthchildnode
->
isactive
);
}
}
/**
* Data provider for test_search_and_set_active_node
*
* @return array
*/
public
function
test_search_and_set_active_node_provider
():
array
{
return
[
'Test by activating node which is part of the tree'
=>
[
'tenthchild'
,
'tenthchild'
],
'Do not change the state of any nodes of the tree'
=>
[
'sixthchild'
],
'Test by setting an empty string as node key to activate'
=>
[
'sixthchild'
,
''
],
'Activate a node which does not exist in the tree'
=>
[
''
,
'foobar'
],
'Activate the leaf node of the tree'
=>
[
'ninethchild'
,
'ninethchild'
],
'Test by changing the $PAGE url which is different from action url of child6'
=>
[
''
,
null
,
'/foobar'
],
'Test by having $PAGE url and child6 action url same'
=>
[
'sixthchild'
,
null
,
'/foo'
],
];
}
}
lib/tests/navigation/views/secondary_test.php
View file @
a665ad27
...
...
@@ -86,10 +86,11 @@ class secondary_test extends \advanced_testcase {
* @param string $expectedfirstnode The expected first node
* @param string $header The expected string
* @param string $activenode The expected active node
* @return void
* @dataProvider test_setting_initialise_provider
*/
public
function
test_setting_initialise
(
string
$context
,
string
$expectedfirstnode
,
string
$header
,
string
$activenode
)
{
string
$header
,
string
$activenode
)
:
void
{
global
$PAGE
,
$SITE
;
$this
->
resetAfterTest
();
$this
->
setAdminUser
();
...
...
@@ -140,6 +141,106 @@ class secondary_test extends \advanced_testcase {
];
}
/**
* Get the nav tree initialised to test active_node_scan.
*
* This is to test the secondary nav with navigation_node instance.
*
* @param string|null $seturl The url set for $PAGE.
* @return navigation_node The initialised nav tree.
*/
private
function
get_tree_initilised_to_set_activate
(
?string
$seturl
=
null
):
navigation_node
{
global
$PAGE
;
$node
=
new
secondary
(
$PAGE
);
$node
->
key
=
'mytestnode'
;
$node
->
type
=
navigation_node
::
TYPE_SYSTEM
;
$node
->
add
(
'first child'
,
null
,
navigation_node
::
TYPE_CUSTOM
,
'firstchld'
,
'firstchild'
);
$child2
=
$node
->
add
(
'second child'
,
null
,
navigation_node
::
TYPE_COURSE
,
'secondchld'
,
'secondchild'
);
$child3
=
$node
->
add
(
'third child'
,
null
,
navigation_node
::
TYPE_CONTAINER
,
'thirdchld'
,
'thirdchild'
);
$node
->
add
(
'fourth child'
,
null
,
navigation_node
::
TYPE_ACTIVITY
,
'fourthchld'
,
'fourthchld'
);
$node
->
add
(
'fifth child'
,
'/my'
,
navigation_node
::
TYPE_CATEGORY
,
'fifthchld'
,
'fifthchild'
);
// If seturl is null then set actionurl of child6 to '/'.
if
(
$seturl
===
null
)
{
$child6actionurl
=
new
\
moodle_url
(
'/'
);
}
else
{
// If seturl is provided then set actionurl of child6 to '/foo'.
$child6actionurl
=
new
\
moodle_url
(
'/foo'
);
}
$child6
=
$child2
->
add
(
'sixth child'
,
$child6actionurl
,
navigation_node
::
TYPE_COURSE
,
'sixthchld'
,
'sixthchild'
);
// Activate the sixthchild node.
$child6
->
make_active
();
$child2
->
add
(
'seventh child'
,
null
,
navigation_node
::
TYPE_COURSE
,
'seventhchld'
,
'seventhchild'
);
$child8
=
$child2
->
add
(
'eighth child'
,
null
,
navigation_node
::
TYPE_CUSTOM
,
'eighthchld'
,
'eighthchild'
);
$child8
->
add
(
'nineth child'
,
null
,
navigation_node
::
TYPE_CUSTOM
,
'ninethchld'
,
'ninethchild'
);
$child3
->
add
(
'tenth child'
,
null
,
navigation_node
::
TYPE_CUSTOM
,
'tenthchld'
,
'tenthchild'
);
return
$node
;
}
/**
* Testing active_node_scan on navigation_node instance.
*
* @param string $expectedkey The expected node key.
* @param string|null $key The key set by user using set_secondary_active_tab.
* @param string|null $seturl The url set by user.
* @return void
* @dataProvider test_active_node_scan_provider
*/
public
function
test_active_node_scan
(
string
$expectedkey
,
?string
$key
=
null
,
?string
$seturl
=
null
):
void
{
global
$PAGE
;
if
(
$seturl
!==
null
)
{
navigation_node
::
override_active_url
(
new
\
moodle_url
(
$seturl
));
}
else
{
$PAGE
->
set_url
(
'/'
);
navigation_node
::
override_active_url
(
new
\
moodle_url
(
'/'
));
}
if
(
$key
!==
null
)
{
$PAGE
->
set_secondary_active_tab
(
$key
);
}
$node
=
$this
->
get_tree_initilised_to_set_activate
(
$seturl
);
$secondary
=
new
secondary
(
$PAGE
);
$method
=
new
ReflectionMethod
(
'core\navigation\views\secondary'
,
'active_node_scan'
);
$method
->
setAccessible
(
true
);
$result
=
$method
->
invoke
(
$secondary
,
$node
);
if
(
$expectedkey
!==
''
)
{
$this
->
assertInstanceOf
(
'navigation_node'
,
$result
);
$this
->
assertEquals
(
$expectedkey
,
$result
->
key
);
}
else
{
$this
->
assertNull
(
$result
);
}
}
/**
* Data provider for the active_node_scan_provider
*
* @return array
*/
public
function
test_active_node_scan_provider
():
array
{
return
[
'Test by activating node adjacent to root node'
=>
[
'firstchild'
,
'firstchild'
],
'Activate a grand child node of the root'
=>
[
'thirdchild'
,
'tenthchild'
],
'When child node is activated the parent node is activated and returned'
=>
[
'secondchild'
,
null
],
'Test by setting an empty string as node key to activate'
=>
[
'secondchild'
,
''
],
'Activate a node which does not exist in the tree'
=>
[
''
,
'foobar'
],
'Activate the leaf node of the tree'
=>
[
'secondchild'
,
'ninethchild'
,
null
,
true
],
'Changing the $PAGE url which is different from action url of child6 and not setting active tab manually'
=>
[
''
,
null
,
'/foobar'
],
'Having $PAGE url and child6 action url same and not setting active tab manually'
=>
[
'secondchild'
,
null
,
'/foo'
],
];
}
/**
* Test the force_nodes_into_more_menu method.
*
...
...
my/index.php
View file @
a665ad27
...
...
@@ -90,6 +90,8 @@ $PAGE->set_subpage($currentpage->id);
$PAGE
->
set_title
(
$pagetitle
);
$PAGE
->
set_heading
(
$header
);
$PAGE
->
set_primary_active_tab
(
'myhome'
);
if
(
!
isguestuser
())
{
// Skip default home page for guests
if
(
get_home_page
()
!=
HOMEPAGE_MY
)
{
if
(
optional_param
(
'setdefaulthome'
,
false
,
PARAM_BOOL
))
{
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment