Issue #460408 by marthinal, dww, David_Rothstein, gpk, joelpittet, markie, aerozeppelin, byronveale, Cottser, david_garcia, acbramley, jojonaloha, nerdcore, gnindl, dotton, girishmuraly, umar-ahmad, joseph.olstad, Webrotta, btopro, wizonesolutions, andrewmacpherson, Bojhan, catch: Cannot administer menu item/link if it points to an unpublished node
parent
021554e94d
commit
f4515a59ea
|
@ -1500,13 +1500,25 @@ function menu_tree_check_access(&$tree, $node_links = array()) {
|
|||
$nids = array_keys($node_links);
|
||||
$select = db_select('node', 'n');
|
||||
$select->addField('n', 'nid');
|
||||
$select->condition('n.status', 1);
|
||||
// When a menu administrator who we know has permission to see unpublished
|
||||
// nodes is administering the menu, included the unpublished nodes in the
|
||||
// tree, with a special flag so that the Menu module can label them.
|
||||
// Otherwise, exclude these nodes from the tree.
|
||||
if (!empty($GLOBALS['menu_admin']) && user_access('bypass node access')) {
|
||||
$select->addField('n', 'status');
|
||||
}
|
||||
else {
|
||||
$select->condition('n.status', 1);
|
||||
}
|
||||
$select->condition('n.nid', $nids, 'IN');
|
||||
$select->addTag('node_access');
|
||||
$nids = $select->execute()->fetchCol();
|
||||
foreach ($nids as $nid) {
|
||||
foreach ($node_links[$nid] as $mlid => $link) {
|
||||
$node_links[$nid][$mlid]['access'] = TRUE;
|
||||
$node_objects = $select->execute()->fetchAll();
|
||||
foreach ($node_objects as $node_object) {
|
||||
foreach ($node_links[$node_object->nid] as $mlid => $link) {
|
||||
$node_links[$node_object->nid][$mlid]['access'] = TRUE;
|
||||
if (isset($node_object->status)) {
|
||||
$node_links[$node_object->nid][$mlid]['node_unpublished'] = !$node_object->status;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -100,12 +100,7 @@ function _menu_overview_tree_form($tree) {
|
|||
$form[$mlid]['#item'] = $item;
|
||||
$form[$mlid]['#attributes'] = $item['hidden'] ? array('class' => array('menu-disabled')) : array('class' => array('menu-enabled'));
|
||||
$form[$mlid]['title']['#markup'] = l($item['title'], $item['href'], $item['localized_options']);
|
||||
if ($item['hidden']) {
|
||||
$form[$mlid]['title']['#markup'] .= ' (' . t('disabled') . ')';
|
||||
}
|
||||
elseif ($item['link_path'] == 'user' && $item['module'] == 'system') {
|
||||
$form[$mlid]['title']['#markup'] .= ' (' . t('logged in users only') . ')';
|
||||
}
|
||||
menu_add_link_labels($form[$mlid]['title']['#markup'], $item);
|
||||
|
||||
$form[$mlid]['hidden'] = array(
|
||||
'#type' => 'checkbox',
|
||||
|
|
|
@ -401,6 +401,9 @@ function menu_parent_options_js() {
|
|||
* Helper function to get the items of the given menu.
|
||||
*/
|
||||
function _menu_get_options($menus, $available_menus, $item) {
|
||||
global $menu_admin;
|
||||
$menu_admin = TRUE;
|
||||
|
||||
// If the item has children, there is an added limit to the depth of valid parents.
|
||||
if (isset($item['parent_depth_limit'])) {
|
||||
$limit = $item['parent_depth_limit'];
|
||||
|
@ -417,6 +420,8 @@ function _menu_get_options($menus, $available_menus, $item) {
|
|||
_menu_parents_recurse($tree, $menu_name, '--', $options, $item['mlid'], $limit);
|
||||
}
|
||||
}
|
||||
|
||||
$menu_admin = FALSE;
|
||||
return $options;
|
||||
}
|
||||
|
||||
|
@ -431,9 +436,7 @@ function _menu_parents_recurse($tree, $menu_name, $indent, &$options, $exclude,
|
|||
}
|
||||
if ($data['link']['mlid'] != $exclude && $data['link']['hidden'] >= 0) {
|
||||
$title = $indent . ' ' . truncate_utf8($data['link']['title'], 30, TRUE, FALSE);
|
||||
if ($data['link']['hidden']) {
|
||||
$title .= ' (' . t('disabled') . ')';
|
||||
}
|
||||
menu_add_link_labels($title, $data['link']);
|
||||
$options[$menu_name . ':' . $data['link']['mlid']] = $title;
|
||||
if ($data['below']) {
|
||||
_menu_parents_recurse($data['below'], $menu_name, $indent . '--', $options, $exclude, $depth_limit);
|
||||
|
@ -442,6 +445,27 @@ function _menu_parents_recurse($tree, $menu_name, $indent, &$options, $exclude,
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds labels to the title of a hidden, unpublished or logged-in menu link.
|
||||
*
|
||||
* @param string $title
|
||||
* The title of the menu link. This will be modified as necessary to add the
|
||||
* appropriate label in parentheses at the end.
|
||||
* @param array $item
|
||||
* An array representing the menu link item.
|
||||
*/
|
||||
function menu_add_link_labels(&$title, $item) {
|
||||
if ($item['hidden']) {
|
||||
$title .= ' (' . t('disabled') . ')';
|
||||
}
|
||||
elseif (!empty($item['node_unpublished'])) {
|
||||
$title .= ' (' . t('unpublished') . ')';
|
||||
}
|
||||
elseif ($item['link_path'] == 'user' && $item['module'] == 'system') {
|
||||
$title .= ' (' . t('logged in users only') . ')';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset a system-defined menu link.
|
||||
*/
|
||||
|
|
|
@ -604,6 +604,50 @@ class MenuTestCase extends DrupalWebTestCase {
|
|||
$this->assertText(t('Menus'), 'Add menu node was displayed');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that menu admin lists can include menu items for unpublished nodes.
|
||||
*/
|
||||
function testUnpublishedNodeMenuItem() {
|
||||
// Log in as an administrator who can view unpublished nodes.
|
||||
$menu_and_node_admin_user = $this->drupalCreateUser(array(
|
||||
'bypass node access',
|
||||
'administer menu',
|
||||
));
|
||||
$this->drupalLogin($menu_and_node_admin_user);
|
||||
|
||||
// Create an unpublished node with a menu link.
|
||||
$title = $this->randomName();
|
||||
$node = $this->drupalCreateNode(array(
|
||||
'type' => 'article',
|
||||
'title' => $title,
|
||||
'status' => NODE_NOT_PUBLISHED,
|
||||
));
|
||||
$edit = array(
|
||||
'link_path' => 'node/' . $node->nid,
|
||||
'link_title' => $title,
|
||||
'description' => '',
|
||||
'enabled' => TRUE,
|
||||
'expanded' => TRUE,
|
||||
'parent' => 'navigation:0',
|
||||
'weight' => '0',
|
||||
);
|
||||
$this->drupalPost('admin/structure/menu/manage/navigation/add', $edit, t('Save'));
|
||||
|
||||
// Verify that the administrator can see the menu link (with a label
|
||||
// indicating that it is unpublished) on the menu management page.
|
||||
$this->drupalGet('admin/structure/menu/manage/navigation');
|
||||
$this->assertText($title . ' (unpublished)', 'Menu link to unpublished node is visible to users with "bypass node access" permission.');
|
||||
|
||||
// Verify that a user who cannot view unpublished nodes does not see the
|
||||
// menu link on the menu management page.
|
||||
$menu_admin_user = $this->drupalCreateUser(array('administer menu'));
|
||||
$this->drupalLogin($menu_admin_user);
|
||||
$this->drupalGet('admin/structure/menu/manage/navigation');
|
||||
$this->assertResponse(200);
|
||||
$this->assertNoText($title, 'Menu link to unpublished node is not visible to users without the "bypass node access" permission.');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -758,4 +802,5 @@ class MenuNodeTestCase extends DrupalWebTestCase {
|
|||
$options = $this->xpath('//select[@id=:id]//option[@value=:option]', array(':id' => $id, ':option' => $option));
|
||||
return $this->assertTrue(isset($selects[0]) && !isset($options[0]), $message ? $message : t('Option @option for field @id does not exist.', array('@option' => $option, '@id' => $id)), t('Browser'));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue