Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
project
drupal
Commits
a42a9d3e
Commit
a42a9d3e
authored
Nov 09, 2007
by
Gábor Hojtsy
Browse files
#178608
by chx: convert menu overview page to a form to overcome any CSRF vulnerabilities
parent
0ff81a7e
Changes
6
Hide whitespace changes
Inline
Side-by-side
includes/menu.inc
View file @
a42a9d3e
...
...
@@ -838,7 +838,6 @@ function menu_tree_page_data($menu_name = 'navigation') {
* Recursive helper function - collect node links.
*/
function
menu_tree_collect_node_links
(
&
$tree
,
&
$node_links
)
{
foreach
(
$tree
as
$key
=>
$v
)
{
if
(
$tree
[
$key
][
'link'
][
'router_path'
]
==
'node/%'
)
{
$nid
=
substr
(
$tree
[
$key
][
'link'
][
'link_path'
],
5
);
...
...
@@ -911,7 +910,6 @@ function _menu_tree_check_access(&$tree) {
* See menu_tree_page_data for a description of the data structure.
*/
function
menu_tree_data
(
$result
=
NULL
,
$parents
=
array
(),
$depth
=
1
)
{
list
(,
$tree
)
=
_menu_tree_data
(
$result
,
$parents
,
$depth
);
return
$tree
;
}
...
...
@@ -930,16 +928,19 @@ function _menu_tree_data($result, $parents, $depth, $previous_element = '') {
// We need to determine if we're on the path to root so we can later build
// the correct active trail and breadcrumb.
$item
[
'in_active_trail'
]
=
in_array
(
$item
[
'mlid'
],
$parents
);
$index
=
$previous_element
?
(
$previous_element
[
'mlid'
])
:
''
;
// The current item is the first in a new submenu.
if
(
$item
[
'depth'
]
>
$depth
)
{
// _menu_tree returns an item and the menu tree structure.
list
(
$item
,
$below
)
=
_menu_tree_data
(
$result
,
$parents
,
$item
[
'depth'
],
$item
);
$tree
[
$index
]
=
array
(
'link'
=>
$previous_element
,
'below'
=>
$below
,
);
if
(
$previous_element
)
{
$tree
[
$previous_element
[
'mlid'
]]
=
array
(
'link'
=>
$previous_element
,
'below'
=>
$below
,
);
}
else
{
$tree
=
$below
;
}
// We need to fall back one level.
if
(
!
isset
(
$item
)
||
$item
[
'depth'
]
<
$depth
)
{
return
array
(
$item
,
$tree
);
...
...
@@ -951,7 +952,7 @@ function _menu_tree_data($result, $parents, $depth, $previous_element = '') {
elseif
(
$item
[
'depth'
]
==
$depth
)
{
if
(
$previous_element
)
{
// Only the first time.
$tree
[
$
index
]
=
array
(
$tree
[
$
previous_element
[
'mlid'
]
]
=
array
(
'link'
=>
$previous_element
,
'below'
=>
FALSE
,
);
...
...
modules/menu/menu.admin.inc
View file @
a42a9d3e
...
...
@@ -21,11 +21,12 @@ function menu_overview_page() {
}
/**
* Shows for one menu the menu items accessible to the current user and relevant operations.
* Form for editing an entire menu tree at once.
*
* Shows for one menu the menu items accessible to the current user and
* relevant operations.
*/
function
menu_overview
(
$menu
)
{
$header
=
array
(
t
(
'Menu item'
),
t
(
'Expanded'
),
array
(
'data'
=>
t
(
'Operations'
),
'colspan'
=>
'3'
));
function
menu_overview_form
(
&
$form_state
,
$menu
)
{
$sql
=
"
SELECT m.load_functions, m.to_arg_functions, m.access_callback, m.access_arguments, m.page_callback, m.page_arguments, m.title, m.title_callback, m.title_arguments, m.type, ml.*
FROM
{
menu_links
}
ml LEFT JOIN
{
menu_router
}
m ON m.path = ml.router_path
...
...
@@ -37,81 +38,120 @@ function menu_overview($menu) {
$node_links
=
array
();
menu_tree_collect_node_links
(
$tree
,
$node_links
);
menu_tree_check_access
(
$tree
,
$node_links
);
$rows
=
_menu_overview_tree
(
$tree
);
$output
=
theme
(
'table'
,
$header
,
$rows
);
$output
.
=
theme
(
'pager'
,
NULL
,
200
,
0
);
return
$output
;
$form
=
_menu_overview_tree_form
(
$tree
);
if
(
element_children
(
$form
))
{
$form
[
'submit'
]
=
array
(
'#type'
=>
'submit'
,
'#value'
=>
t
(
'Save configuration'
),
);
}
else
{
$form
[
'empty_menu'
]
=
array
(
'#value'
=>
t
(
'There are no menu items yet.'
));
}
return
$form
;
}
/**
* Recursive helper function for menu_overview().
* Recursive helper function for menu_overview
_form
().
*/
function
_menu_overview_tree
(
$tree
)
{
static
$
rows
=
array
();
function
_menu_overview_tree
_form
(
$tree
)
{
static
$
form
=
array
(
'#tree'
=>
TRUE
);
foreach
(
$tree
as
$data
)
{
$title
=
''
;
$item
=
$data
[
'link'
];
// Don't show callbacks; these have $item['hidden'] < 0.
if
(
$item
&&
$item
[
'hidden'
]
>=
0
)
{
$title
=
str_repeat
(
' '
,
$item
[
'depth'
]
-
1
)
.
(
$item
[
'depth'
]
>
1
?
'- '
:
''
);
$title
.
=
l
(
$item
[
'title'
],
$item
[
'href'
],
$item
[
'options'
]);
// Populate the operations field.
$mlid
=
$item
[
'mlid'
];
$form
[
$mlid
][
'#item'
]
=
$item
;
$form
[
$mlid
][
'#attributes'
]
=
$item
[
'hidden'
]
?
array
(
'class'
=>
'menu-disabled'
)
:
array
(
'class'
=>
'menu-enabled'
);
$form
[
$mlid
][
'title'
][
'#value'
]
=
l
(
$item
[
'title'
],
$item
[
'href'
],
$item
[
'options'
])
.
(
$item
[
'hidden'
]
?
' ('
.
t
(
'disabled'
)
.
')'
:
''
);
$form
[
$mlid
][
'hidden'
]
=
array
(
'#type'
=>
'checkbox'
,
'#default_value'
=>
!
$item
[
'hidden'
],
);
$form
[
$mlid
][
'expanded'
]
=
array
(
'#type'
=>
'checkbox'
,
'#default_value'
=>
$item
[
'has_children'
]
&&
$item
[
'expanded'
],
);
// Build a list of operations.
$operations
=
array
();
// Set the edit column.
$operations
[]
=
array
(
'data'
=>
l
(
t
(
'edit'
),
'admin/build/menu/item/'
.
$item
[
'mlid'
]
.
'/edit'
));
if
(
$item
[
'hidden'
])
{
$title
.
=
' ('
.
t
(
'disabled'
)
.
')'
;
$class
=
'menu-disabled'
;
$operations
[]
=
array
(
'data'
=>
l
(
t
(
'enable'
),
'admin/build/menu/item/'
.
$item
[
'mlid'
]
.
'/enable'
));
}
else
{
$class
=
'menu-enabled'
;
$operations
[]
=
array
(
'data'
=>
l
(
t
(
'disable'
),
'admin/build/menu/item/'
.
$item
[
'mlid'
]
.
'/disable'
));
}
$operations
[
'edit'
]
=
l
(
t
(
'edit'
),
'admin/build/menu/item/'
.
$item
[
'mlid'
]
.
'/edit'
);
// Only items created by the menu module can be deleted.
if
(
$item
[
'module'
]
==
'menu'
)
{
$operations
[
]
=
array
(
'data'
=
>
l
(
t
(
'delete'
),
'admin/build/menu/item/'
.
$item
[
'mlid'
]
.
'/delete'
)
)
;
$operations
[
'delete'
]
=
l
(
t
(
'delete'
),
'admin/build/menu/item/'
.
$item
[
'mlid'
]
.
'/delete'
);
}
// Set the reset column.
elseif
(
$item
[
'module'
]
==
'system'
&&
$item
[
'customized'
])
{
$operations
[
]
=
array
(
'data'
=
>
l
(
t
(
'reset'
),
'admin/build/menu/item/'
.
$item
[
'mlid'
]
.
'/reset'
)
)
;
$operations
[
'reset'
]
=
l
(
t
(
'reset'
),
'admin/build/menu/item/'
.
$item
[
'mlid'
]
.
'/reset'
);
}
else
{
$operations
[]
=
array
(
'data'
=>
''
);
}
$row
=
array
(
array
(
'data'
=>
$title
,
'class'
=>
$class
),
array
(
'data'
=>
(
$item
[
'has_children'
]
?
((
$item
[
'expanded'
])
?
t
(
'Yes'
)
:
t
(
'No'
))
:
''
),
'class'
=>
$class
),
);
foreach
(
$operations
as
$operation
)
{
$operation
[
'class'
]
=
$class
;
$row
[]
=
$operation
;
$form
[
$mlid
][
'operations'
]
=
array
();
foreach
(
$operations
as
$op
=>
$value
)
{
$form
[
$mlid
][
'operations'
][
$op
]
=
array
(
'#value'
=>
$value
);
}
$rows
[]
=
$row
;
}
if
(
$data
[
'below'
])
{
_menu_overview_tree
(
$data
[
'below'
]);
_menu_overview_tree_form
(
$data
[
'below'
]);
}
}
return
$form
;
}
function
menu_overview_form_submit
(
$form
)
{
foreach
(
element_children
(
$form
)
as
$mlid
)
{
if
(
isset
(
$form
[
$mlid
][
'hidden'
]))
{
$element
=
$form
[
$mlid
];
if
(
$element
[
'hidden'
][
'#value'
]
!=
$element
[
'hidden'
][
'#default_value'
])
{
$element
[
'#item'
][
'hidden'
]
=
!
$element
[
'hidden'
][
'#value'
];
menu_link_save
(
$element
[
'#item'
]);
}
if
(
$element
[
'expanded'
][
'#value'
]
!=
$element
[
'expanded'
][
'#default_value'
])
{
$element
[
'#item'
][
'expanded'
]
=
$element
[
'expanded'
][
'#value'
];
menu_link_save
(
$element
[
'#item'
]);
}
}
}
return
$rows
;
}
/**
* Menu callback; enable/disable a menu link.
*
* @param $hide
* TRUE to not show in the menu tree. FALSE to make the item and its children
* reappear in menu tree.
* @param $item
* The menu item.
* Theme the menu overview form into a table.
*/
function
menu_flip_item
(
$hide
,
$item
)
{
function
theme_menu_overview_form
(
$form
)
{
$header
=
array
(
t
(
'Enabled'
),
t
(
'Expanded'
),
t
(
'Menu item'
),
array
(
'data'
=>
t
(
'Operations'
),
'colspan'
=>
'3'
));
$rows
=
array
();
foreach
(
element_children
(
$form
)
as
$mlid
)
{
if
(
isset
(
$form
[
$mlid
][
'hidden'
]))
{
$element
=
&
$form
[
$mlid
];
// Build a list of operations.
$operations
=
array
();
foreach
(
element_children
(
$element
[
'operations'
])
as
$op
)
{
$operations
[]
=
drupal_render
(
$element
[
'operations'
][
$op
]);
}
while
(
count
(
$operations
)
<
2
)
{
$operations
[]
=
''
;
}
$item
[
'hidden'
]
=
(
bool
)
$hide
;
$item
[
'customized'
]
=
1
;
menu_link_save
(
$item
);
drupal_set_message
(
$hide
?
t
(
'The menu item has been disabled.'
)
:
t
(
'The menu item has been enabled.'
));
drupal_goto
(
'admin/build/menu-customize/'
.
$item
[
'menu_name'
]);
$row
=
array
();
$row
[]
=
array
(
'data'
=>
drupal_render
(
$element
[
'hidden'
]),
'align'
=>
'center'
);
$row
[]
=
array
(
'data'
=>
drupal_render
(
$element
[
'expanded'
]),
'align'
=>
'center'
);
$depth
=
$element
[
'#item'
][
'depth'
];
$indentation
=
str_repeat
(
' '
,
$depth
-
1
)
.
(
$depth
>
1
?
'- '
:
''
);
$row
[]
=
$indentation
.
drupal_render
(
$element
[
'title'
]);
$row
=
array_merge
(
$row
,
$operations
);
$row
=
array_merge
(
array
(
'data'
=>
$row
),
$element
[
'#attributes'
]);
$rows
[]
=
$row
;
}
}
$output
=
''
;
if
(
$rows
)
{
$output
.
=
theme
(
'table'
,
$header
,
$rows
,
array
(
'id'
=>
'menu-overview'
));
$output
.
=
theme
(
'pager'
,
NULL
,
200
,
0
);
}
$output
.
=
drupal_render
(
$form
);
return
$output
;
}
/**
...
...
modules/menu/menu.module
View file @
a42a9d3e
...
...
@@ -80,8 +80,8 @@ function menu_menu() {
);
$items
[
'admin/build/menu-customize/%menu'
]
=
array
(
'title'
=>
'Customize menu'
,
'page callback'
=>
'
menu_overview
'
,
'page arguments'
=>
array
(
3
),
'page callback'
=>
'
drupal_get_form
'
,
'page arguments'
=>
array
(
'menu_overview_form'
,
3
),
'title callback'
=>
'menu_overview_title'
,
'title arguments'
=>
array
(
3
),
'access arguments'
=>
array
(
'administer menu'
),
...
...
@@ -115,20 +115,6 @@ function menu_menu() {
'type'
=>
MENU_CALLBACK
,
'file'
=>
'menu.admin.inc'
,
);
$items
[
'admin/build/menu/item/%menu_link/disable'
]
=
array
(
'title'
=>
'Disable menu item'
,
'page callback'
=>
'menu_flip_item'
,
'page arguments'
=>
array
(
TRUE
,
4
),
'type'
=>
MENU_CALLBACK
,
'file'
=>
'menu.admin.inc'
,
);
$items
[
'admin/build/menu/item/%menu_link/enable'
]
=
array
(
'title'
=>
'Enable menu item'
,
'page callback'
=>
'menu_flip_item'
,
'page arguments'
=>
array
(
FALSE
,
4
),
'type'
=>
MENU_CALLBACK
,
'file'
=>
'menu.admin.inc'
,
);
$items
[
'admin/build/menu/item/%menu_link/edit'
]
=
array
(
'title'
=>
'Edit menu item'
,
'page callback'
=>
'drupal_get_form'
,
...
...
@@ -154,6 +140,18 @@ function menu_menu() {
return
$items
;
}
/**
* Implemenation of hook_theme().
*/
function
menu_theme
()
{
return
array
(
'menu_overview_form'
=>
array
(
'file'
=>
'menu.admin.inc'
,
'arguments'
=>
array
(
'form'
=>
NULL
),
),
);
}
/**
* Implementation of hook_enable()
*
...
...
themes/garland/fix-ie-rtl.css
View file @
a42a9d3e
...
...
@@ -47,7 +47,7 @@ html.js fieldset.collapsed {
margin-bottom
:
1em
;
}
t
d
.menu-disabled
{
t
r
.menu-disabled
{
/* Use filter to emulate CSS3 opacity */
filter
:
alpha
(
opacity
=
50
);
}
...
...
themes/garland/fix-ie.css
View file @
a42a9d3e
...
...
@@ -49,7 +49,7 @@ html.js fieldset.collapsed {
margin-bottom
:
1em
;
}
t
d
.menu-disabled
{
t
r
.menu-disabled
{
/* Use filter to emulate CSS3 opacity */
filter
:
alpha
(
opacity
=
50
);
}
...
...
themes/garland/style.css
View file @
a42a9d3e
...
...
@@ -779,15 +779,15 @@ ul.links li, ul.inline li {
/**
* Menu.module
*/
tr
.menu-disabled
{
opacity
:
0.5
;
}
tr
.odd
td
.menu-disabled
{
background-color
:
#edf5fa
;
}
tr
.even
td
.menu-disabled
{
background-color
:
#fff
;
}
td
.menu-disabled
{
opacity
:
0.5
;
}
/**
* Poll.module
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new 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