nid) { case 322: // Mailing list subscription $extra = drupal_get_form('lists_subscribe_form'); break; case 13355: // Site maintainers $extra = drupalorg_handbook_site_maintainers(); break; case 109372: // Handbook maintainers $extra = drupalorg_handbook_maintainers(); break; case 263594: // Revision maintainers $extra = drupalorg_handbook_revision_maintainers(); break; case 23192: // Recent updates $extra = drupalorg_handbook_display_recent_updates(); break; } $node->content['body']['#value'] .= $extra; if (drupalorg_crosssite_section() === 'documentation' && isset($node->book['bid'])) { // Prepend the handbook meta data to book bodies. $node->content['body']['#value'] = drupalorg_handbook_meta_data($node) . $node->content['body']['#value']; } } elseif (($op == 'update' || $op == 'insert') && !empty($node->book) && !empty($node->book['bid'])) { // Remove all cached versions of recently updated data (home & node 23192). cache_clear_all('drupalorg_handbook_recent_updates_', 'cache', TRUE); } } /** * Implementation of hook_form_alter(). */ function drupalorg_handbook_form_alter(&$form, $form_state, $form_id) { // Force a revision log entry when editing existing book nodes. if ($form_id == 'book_node_form' && isset($form['revision_information']['log']) && arg(1) != 'add') { $form['revision_information']['log']['#required'] = TRUE; $form['revision_information']['#collapsed'] = FALSE; } } /** * Gather information for the top of handbook pages. * * @param $node * The node object. * @return * The HTML code for the book meta information. */ function drupalorg_handbook_meta_data($node) { $info = array(); if (count($node->taxonomy)) { $vocabularies = taxonomy_get_vocabularies(); // Group the terms by vid. $taxonomy = array(); foreach ($node->taxonomy as $term_id => $term) { if (isset($vocabularies[$term->vid])) { $term->rendered = TRUE; if ($term_id !== 125) { // No known problems is uninteresting $taxonomy[$term->vid][] = $term; } } } foreach ($vocabularies as $vocabulary) { if (isset($taxonomy[$vocabulary->vid])) { $links = array(); foreach ($taxonomy[$vocabulary->vid] as $term) { $options = array(); if ($vocabulary->vid === '31') { // Page status $options['attributes'] = array('class' => 'alert'); } $links[] = l($term->name, taxonomy_term_path($term), $options); } $info[check_plain($vocabulary->name)] = implode(', ', $links); } } } $modified = format_date($node->changed, 'custom', 'F j, Y'); return theme('drupalorg_handbook_meta_data', $info, $modified); } /** * List usernames with site maintainer role. */ function drupalorg_handbook_site_maintainers() { $output = 'If you have been around for a while, and you want to help maintain Drupal.org and are willing to accept the added responsibilities that come with it, sign up on the Infrastructure team list.'; $output .= '
    '; $result = db_query("SELECT DISTINCT(u.uid), u.name FROM {users} u INNER JOIN {users_roles} r ON u.uid = r.uid WHERE r.rid = 3 OR r.rid = 4 OR r.rid = 9 ORDER BY u.name "); // 3 = site maintainer, 4 = administrator while ($account = db_fetch_object($result)) { $output .= "
  1. ". theme('username', $account) ."
  2. "; } $output .= '
'; return $output; } /** * List usernames with handbook maintainer role. */ function drupalorg_handbook_maintainers() { $output = '

If you are interested in helping maintain/update/correct the documentation on Drupal.org, read up on the many ways to get involved.

'; $output .= '

Note: Many of our site maintainers also participate on the documentation team and are not listed here. Due to their broader responsibilities on drupal.org, site maintainers are listed separately.

'; $output .= '
    '; $result = db_query("SELECT DISTINCT(u.uid), u.name FROM {users} u INNER JOIN {users_roles} r ON u.uid = r.uid WHERE r.rid = 5 OR r.rid = 9 ORDER BY u.name "); // 3 = site maintainer, 4 = administrator 5 = document maintainer while ($account = db_fetch_object($result)) { $output .= "
  1. ". theme('username', $account) ."
  2. "; } $output .= '
'; return $output; } /** * Collect and cache revision maintainers (those who made revisions to books). */ function drupalorg_handbook_revision_maintainers() { if ($cache = cache_get('node_263594')) { return $cache->data; } $result = db_query("SELECT u.uid, u.name, COUNT(nr.vid) AS pages FROM {node} n INNER JOIN {node_revisions} nr ON n.nid = nr.nid INNER JOIN {users} u ON u.uid = n.uid WHERE n.type = 'book' AND n.status = 1 AND n.moderate = 0 GROUP BY u.name ORDER BY pages DESC"); $list = array(); while ($contributor = db_fetch_object($result)) { $list[] = theme('username', $contributor) ." (". format_plural($contributor->pages, "@count revision", "@count revisions") .")"; } $output = theme('item_list', $list); cache_set('node_263594', $output, 'cache', 300); return $output; } /** * API function to get recent update information for the documentation pages. */ function drupalorg_handbook_get_recent_updates($limit = 50) { return db_query_range(db_rewrite_sql("SELECT n.nid, n.title, n.changed, r.log, u.uid, u.name FROM {node} n INNER JOIN {book} b ON n.nid = b.nid INNER JOIN {node_revisions} r ON n.vid = r.vid INNER JOIN {users} u ON u.uid = r.uid WHERE n.status = 1 ORDER BY n.changed DESC"), 0, $limit); } /** * List most recent updates to book pages for moderation reasons. */ function drupalorg_handbook_display_recent_updates() { global $user; // Represents the number of results to retrieve. Also utilized for cache field name. $count = 50; $key = 'drupalorg_handbook_recent_updates_' . $count . ':' . ($user->uid === 0 ? 'anon' : 'auth'); if ($cache = cache_get($key)) { $output = $cache->data; } else { $result = drupalorg_handbook_get_recent_updates($count); while ($page = db_fetch_object($result)) { $row = array( l($page->title, "node/$page->nid") .' '. theme('mark', node_mark($page->nid, $page->changed)) . ($page->log ? "
". check_plain($page->log) : ''), theme('username', $page), t('%time ago', array('%time' => format_interval(time() - $page->changed))), ); if (user_access('view revisions')) { $row[] = l(t('Diff'), "node/$page->nid/revisions/view/latest"); } $rows[] = $row; } $header = array('Page', 'Edited', 'Updated'); if (user_access('view revisions')) { $header[] = 'Diff'; } $output = theme('table', $header, $rows); cache_set($key, $output); } return $output; } /** * License and quick links blocks for docs. */ function drupalorg_handbook_block($op = 'list', $delta = 0, $edit = array()) { switch ($op) { case 'list': return array( 'license' => array( 'info' => t('Handbook License'), 'cache' => BLOCK_CACHE_PER_PAGE, ), 'info' => array( 'info' => t('Documentation home info'), 'cache' => BLOCK_CACHE_PER_PAGE, ), ); case 'view': switch($delta) { case 'license': if (drupalorg_crosssite_section() === 'documentation') { return array( 'content' => t('Drupal’s online documentation is © 2000-!year by the individual contributors and can be used in accordance with the Creative Commons License, Attribution-ShareAlike 2.0. PHP code is distributed under the GNU General Public License.', array('!year' => date('Y'), '@ccl_url' => url('node/14307'), '@gpl_url' => url('http://www.gnu.org/licenses/old-licenses/gpl-2.0.html'))), ); } break; case 'info': return array( 'subject' => t('Help Us Maintain Documentation'), 'content' => '

' . t('The Drupal.org online documentation is written by the Drupal community in co-operation with the Documentation Team. When you are logged in, you can:', array('@docteam_url' => url('node/24572'))) . '

' . '

' . t('Edit most Documentation pages by clicking “Edit” at the top of the page.') . '

' . '

' . t('Add new pages by using the “add a child page” link at the bottom of the page.') . '

' . '

' . t('Use the Documentation issue queue to propose major changes and report problems.', array('@issues-url' => url('project/issues/documentation'))) . '

' ); break; } } } /** * Check whether the current node is a block module. * * Based on Drupal 6 code from book_block(). */ function drupalorg_handbook_block_is_visible() { return ($node = menu_get_object()) && !empty($node->book['bid']); } /** * Implementation of hook_theme(). */ function drupalorg_handbook_theme($existing, $type, $theme, $path) { return array( 'drupalorg_handbook_meta_data' => array( 'arguments' => array( 'info' => NULL, 'modified' => NULL, ), 'template' => 'handbook-meta-data', ), ); } /** * Implementation of template_preprocess_drupalorg_home(). * * @todo * Add caching. */ function drupalorg_handbook_preprocess_drupalorg_home(&$vars) { // Represents the number of results to retrieve. Also utilized for cache field name. $count = 5; if ($cache = cache_get('drupalorg_handbook_recent_updates_' . $count)) { $recent_updates = $cache->data; } else { $result = drupalorg_handbook_get_recent_updates($count); $recent_updates = ''; while ($node = db_fetch_object($result)) { // Fake the created time for the theme function, so we can easily theme it. $node->created = $node->changed; $recent_updates .= '
'. l($node->title, 'node/'. $node->nid) .'

'. theme('node_submitted', $node) .'

'; } $recent_updates .= '

' . l(t('More updates…'), 'handbook/updates') .'

'; cache_set('drupalorg_handbook_recent_updates_' . $count, $recent_updates); } // We have no place to link this to in a nice way. // $fresh_news .= '

'. l(t('More documentation updates...'), '...') .'

'; $vars['tab_content_docs'] = $recent_updates; }