Index: node.admin.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/node/node.admin.inc,v retrieving revision 1.60 diff -u -r1.60 node.admin.inc --- modules/node/node.admin.inc 30 Jul 2009 19:24:21 -0000 1.60 +++ modules/node/node.admin.inc 16 Aug 2009 19:55:32 -0000 @@ -397,7 +397,9 @@ // Build the sortable table header. $header = array(); - $header[] = theme('table_select_header_cell'); + if (user_access('administer nodes') && user_access('bypass node access')) { + $header[] = theme('table_select_header_cell'); + } $header[] = array('data' => t('Title'), 'field' => 'n.title'); $header[] = array('data' => t('Type'), 'field' => 'n.type'); $header[] = array('data' => t('Author'), 'field' => 'u.name'); @@ -414,14 +416,23 @@ ); $query = db_select('node', 'n')->extend('PagerDefault')->extend('TableSort'); - $query->join('users', 'u', 'n.uid = u.uid'); node_build_filter_query($query); - - $result = $query - ->fields('n') - ->fields('u', array('name')) + // If the user is able to view their own unpublished nodes, allow them + // to see these in addition to published nodes. Check that they actually + // have some unpublished nodes to view before adding the condition. + if (!user_access('administer nodes') && !user_access('bypass node access') && user_access('view own unpublished content') && $own_unpublished = db_select('node', 'n')->fields('n',array('nid'))->condition('uid', $GLOBALS['user']->uid)->condition(db_and()->condition('status', 0))->execute()->fetchCol()) { + $query->condition(db_or()->condition('n.status', 1)->condition('n.nid', $own_unpublished, 'IN')); + } + // If not, restrict the query to published nodes unless the user can + // bypass node access permission. + elseif (!user_access('administer nodes') && !user_access('bypass node access')) { + $query->condition('n.status', 1); + } + $nids = $query + ->fields('n',array('nid')) ->limit(50) - ->execute(); + ->execute()->fetchCol(); + $nodes = node_load_multiple($nids); // Build the 'Update options' form. $form['options'] = array( @@ -429,6 +440,7 @@ '#title' => t('Update options'), '#prefix' => '
', '#suffix' => '
', + '#access' => user_access('administer nodes') && user_access('bypass node access'), ); $options = array(); foreach (module_invoke_all('node_operations') as $operation => $array) { @@ -447,9 +459,9 @@ $languages = language_list(); $destination = drupal_get_destination(); - $nodes = array(); - foreach ($result as $node) { - $nodes[$node->nid] = ''; + $nids = array(); + foreach ($nodes as $node) { + $nids[$node->nid] = ''; $options = empty($node->language) ? array() : array('language' => $languages[$node->language]); $form['title'][$node->nid] = array('#markup' => l($node->title, 'node/' . $node->nid, $options) . ' ' . theme('mark', node_mark($node->nid, $node->changed))); $form['name'][$node->nid] = array('#markup' => check_plain(node_type_get_name($node))); @@ -459,11 +471,29 @@ if ($multilanguage) { $form['language'][$node->nid] = array('#markup' => empty($node->language) ? t('Language neutral') : t($languages[$node->language]->name)); } - $form['operations'][$node->nid] = array('#markup' => l(t('edit'), 'node/' . $node->nid . '/edit', array('query' => $destination))); + // Build a list of all the accessible operations for the current node. + $operations = array(); + $operations_markup = ''; + if(node_access('update', $node)) { + $operations[] = l(t('edit'),'node/' . $node->nid . '/edit',array('query' => $destination)); + } + if(node_access('delete', $node)) { + $operations[] = l(t('delete'),'node/' . $node->nid . '/delete',array('query' => $destination)); + } + if(!empty($operations)) { + if(count($operations) > 1) { + // Render an unordered list of operations links. + $form['operations'][$node->nid] = array('#markup' => theme('item_list',$operations)); + } else { + // Render the first and only operation as a link. + $form['operations'][$node->nid] = array('#markup' => $operations[0]); + } + } } $form['nodes'] = array( '#type' => 'checkboxes', - '#options' => $nodes, + '#options' => $nids, + '#access' => user_access('administer nodes') && user_access('bypass node access'), ); $form['pager'] = array('#markup' => theme('pager', NULL)); $form['#theme'] = 'node_admin_nodes'; @@ -529,7 +559,9 @@ $rows = array(); foreach (element_children($form['title']) as $key) { $row = array(); - $row[] = drupal_render($form['nodes'][$key]); + if (user_access('administer nodes') && user_access('bypass node access')) { + $row[] = drupal_render($form['nodes'][$key]); + } $row[] = drupal_render($form['title'][$key]); $row[] = drupal_render($form['name'][$key]); $row[] = drupal_render($form['username'][$key]); @@ -599,4 +631,4 @@ function node_modules_installed($modules) { // Clear node type cache for node permissions. node_type_clear(); -} \ No newline at end of file +} Index: node.module =================================================================== RCS file: /cvs/drupal/drupal/modules/node/node.module,v retrieving revision 1.1099 diff -u -r1.1099 node.module --- modules/node/node.module 14 Aug 2009 13:53:01 -0000 1.1099 +++ modules/node/node.module 16 Aug 2009 16:12:39 -0000 @@ -1285,6 +1285,10 @@ 'title' => t('Bypass node access'), 'description' => t('View, edit and delete all site content. Users with this permission will bypass any content-related access control. %warning', array('%warning' => t('Warning: Give to trusted roles only; this permission has security implications.'))), ), + 'access content overview' => array( + 'title' => t('Access content overview'), + 'description' => t('Access the content overview page.'), + ), 'view revisions' => array( 'title' => t('View revisions'), 'description' => t('View content revisions.'), @@ -1645,7 +1649,7 @@ 'title' => 'Content', 'page callback' => 'drupal_get_form', 'page arguments' => array('node_admin_content'), - 'access arguments' => array('administer nodes'), + 'access callback' => 'node_admin_page_access', 'weight' => -10, ); $items['admin/content/node'] = array( @@ -3150,3 +3154,10 @@ ); return $requirements; } + +/** + * Checks whether the current user has access to the content list page. + */ +function node_admin_page_access() { +return user_access('administer nodes') || user_access('access content overview'); +} Index: node.test =================================================================== RCS file: /cvs/drupal/drupal/modules/node/node.test,v retrieving revision 1.38 diff -u -r1.38 node.test --- modules/node/node.test 28 Jul 2009 19:18:06 -0000 1.38 +++ modules/node/node.test 16 Aug 2009 20:23:07 -0000 @@ -362,6 +362,49 @@ } } +/** + * Test the functionality of the administer content page. + */ +class ContentAdminTestCase extends DrupalWebTestCase { + public static function getInfo() { + return array( + 'name' => t('Content administration overview'), + 'description' => t('Create users and content to test the content admin pages functionality.'), + 'group' => t('Node'), + ); + } + + function setUp() { + parent::setUp(); + $this->admin_user = $this->drupalCreateUser(array('access administration pages', 'administer nodes', 'bypass node access')); + $this->base_user = $this->drupalCreateUser(array('access content overview')); + } + + /** + * Ensure that both administrative users and basic content editors have + * access to the appropriate functionality on the node administration page. + */ + function testContentAdminPages() { + $this->drupalLogin($this->admin_user); + + // Ensure the admin user can edit and delete any content. + $created_node = $this->drupalCreateNode(array('type' => 'page')); + $this->drupalGet('admin/content/node'); + $this->assertResponse(200); + $this->assertText('edit', t('Admin user has edit link.')); + $this->assertText('delete', t('Admin user has delete link.')); + $this->drupalLogout(); + + // Ensure users don't see operation links for content they don't have rights to edit. + $this->drupalLogin($this->base_user); + $this->drupalGet('admin/content/node'); + $this->assertResponse(200); + $this->assertText($created_node->title, t('Edit links disabled without edit permissions.')); + $this->assertNoText('edit', t('Edit links do not show up for users without rights.')); + $this->assertNoText('delete', t('Delete links do not show up for users without rights.')); + } +} + class SummaryLengthTestCase extends DrupalWebTestCase { public static function getInfo() { return array(