Index: modules/dashboard/dashboard.css =================================================================== RCS file: /cvs/drupal/drupal/modules/dashboard/dashboard.css,v retrieving revision 1.3 diff -u -r1.3 dashboard.css --- modules/dashboard/dashboard.css 21 Nov 2009 17:42:00 -0000 1.3 +++ modules/dashboard/dashboard.css 30 Nov 2009 21:30:51 -0000 @@ -113,3 +113,7 @@ width: 30px; height: 1.6em; } + +#dashboard #block-node-recent div.content { + padding: 0 0 5px 1px; +} Index: profiles/default/default.install =================================================================== RCS file: /cvs/drupal/drupal/profiles/default/default.install,v retrieving revision 1.18 diff -u -r1.18 default.install --- profiles/default/default.install 10 Nov 2009 17:27:54 -0000 1.18 +++ profiles/default/default.install 30 Nov 2009 21:30:51 -0000 @@ -121,6 +121,16 @@ 'cache' => -1, ), array( + 'module' => 'node', + 'delta' => 'recent', + 'theme' => 'seven', + 'status' => 1, + 'weight' => 10, + 'region' => 'dashboard_main', + 'pages' => '', + 'cache' => -1, + ), + array( 'module' => 'user', 'delta' => 'new', 'theme' => 'seven', Index: modules/node/node.module =================================================================== RCS file: /cvs/drupal/drupal/modules/node/node.module,v retrieving revision 1.1170 diff -u -r1.1170 node.module --- modules/node/node.module 29 Nov 2009 10:43:53 -0000 1.1170 +++ modules/node/node.module 30 Nov 2009 21:30:51 -0000 @@ -170,6 +170,12 @@ 'node_admin_overview' => array( 'variables' => array('name' => NULL, 'type' => NULL), ), + 'node_recent_block' => array( + 'variables' => array('nodes' => NULL), + ), + 'node_recent_content' => array( + 'variables' => array('node' => NULL), + ), ); } @@ -1999,6 +2005,9 @@ $blocks['syndicate']['info'] = t('Syndicate'); // Not worth caching. $blocks['syndicate']['cache'] = DRUPAL_NO_CACHE; + + $blocks['recent']['info'] = t('Recent content'); + return $blocks; } @@ -2006,13 +2015,141 @@ * Implement hook_block_view(). */ function node_block_view($delta = '') { - $block['subject'] = t('Syndicate'); - $block['content'] = theme('feed_icon', array('url' => url('rss.xml'), 'title' => t('Syndicate'))); + $block = array(); + switch ($delta) { + case 'syndicate': + $block['subject'] = t('Syndicate'); + $block['content'] = theme('feed_icon', array('url' => url('rss.xml'), 'title' => t('Syndicate'))); + break; + + case 'recent': + if (user_access('access content') && ($nodes = node_get_recent(variable_get('node_recent_block_count', 10)))) { + $block['subject'] = t('Recent content'); + $block['content'] = theme('node_recent_block', array( + 'nodes' => $nodes, + )); + } + break; + } return $block; } /** + * Implements hook_block_configure(). + */ +function node_block_configure($delta = '') { + $form = array(); + if ($delta == 'recent') { + $form['node_recent_block_count'] = array( + '#type' => 'select', + '#title' => t('Number of recent content items to display'), + '#default_value' => variable_get('node_recent_block_count', 10), + '#options' => drupal_map_assoc(array(2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 25, 30)), + ); + } + return $form; +} + +/** + * Implementation of hook_block_save(). + */ +function node_block_save($delta = '', $edit = array()) { + if ($delta == 'recent') { + variable_set('node_recent_block_count', $edit['node_recent_block_count']); + } +} + +/** + * Find the most recent nodes that are available to the current user. + * + * @param $number + * (optional) The maximum number of nodes to find. Defaults to 10. + * + * @return + * An array of partial node objects or an empty array if there are no recent + * nodes visible to the current user. + */ +function node_get_recent($number = 10) { + $query = db_select('node', 'n'); + + if (!user_access('bypass node access')) { + // 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('view own unpublished content') && $own_unpublished = db_query('SELECT nid FROM {node} WHERE uid = :uid AND status = :status', array(':uid' => $GLOBALS['user']->uid, ':status' => NODE_NOT_PUBLISHED))->fetchCol()) { + $query->condition(db_or() + ->condition('n.status', NODE_PUBLISHED) + ->condition('n.nid', $own_unpublished, 'IN') + ); + } + else { + // If not, restrict the query to published nodes. + $query->condition('n.status', NODE_PUBLISHED); + } + } + $nids = $query + ->fields('n', array('nid')) + ->orderBy('changed', 'DESC') + ->range(0, $number) + ->addTag('node_access') + ->execute() + ->fetchCol(); + + $nodes = node_load_multiple($nids); + + return $nodes ? $nodes : array(); +} + +/** + * Returns a formatted list of recent nodes to be displayed in the recent content block. + * + * @return + * The recent content table HTML. + * @ingroup themeable + */ +function theme_node_recent_block($variables) { + $rows = array(); + $output = ''; + + $l_options = array('query' => drupal_get_destination()); + foreach ($variables['nodes'] as $node) { + $row = array(); + $row[] = theme('node_recent_content', array('node' => $node)); + $row[] = node_access('update', $node) ? l(t('edit'), 'node/' . $node->nid . '/edit', $l_options) : ''; + $row[] = node_access('delete', $node) ? l(t('delete'), 'node/' . $node->nid . '/delete', $l_options) : ''; + $rows[] = $row; + } + + if ($rows) { + $output = theme('table', array('rows' => $rows)); + $output .= '