'. t('Beanstalk is a Subversion hosting service offering webhooks.', array('@beanstalk' => 'http://beanstalkapp.com/')) .'

'; case 'admin/settings/beanstalk': $output = '

'. t('Configure the various options of Beanstalk/Drupal integration. Beanstalk repository webhook integration will have to be configured to post messages to specific target urls (see overview).', array('!url' => url('admin/settings/beanstalk/repositories'))) .'

'; $output .= '

'. t('As an option, comments that match #123 can be linked to corresponding nodes (node/123) and Beanstalk users can be linked to Drupal users.') .'

'; $output .= '

'. t('Additionally, you can choose to review all commit messages before publishing and configure commit messages as group posts (requires organic groups) or to be automatically tagged (requires taxonomy).') .'

'; return $output; case 'admin/settings/beanstalk/repositories': return '

'. t('These are your Beanstalk webhooks: URLs commit messages can be posted to.') .'

'; } } /** * Implementation of hook_init() */ function beanstalk_init() { drupal_add_css(drupal_get_path('module', 'beanstalk') .'/beanstalk.css'); } /** * Implementation of hook_menu(). */ function beanstalk_menu() { /* beanstalk main settings */ $items['admin/settings/beanstalk'] = array( 'file' => 'beanstalk.inc', 'access arguments' => array('administer beanstalk'), 'page callback' => 'drupal_get_form', 'page arguments' => array('beanstalk_settings'), 'description' => 'Configure the various Beanstalk options with these settings.', 'title' => 'Beanstalk', 'type' => MENU_NORMAL_ITEM, ); $items['admin/settings/beanstalk/settings'] = array( 'file' => 'beanstalk.inc', 'access arguments' => array('administer beanstalk'), 'page callback' => 'drupal_get_form', 'page arguments' => array('beanstalk_settings'), 'title' => 'Settings', 'weight' => -10, 'type' => MENU_DEFAULT_LOCAL_TASK, ); $items['admin/settings/beanstalk/repositories'] = array( 'file' => 'beanstalk.inc', 'access arguments' => array('administer beanstalk'), 'page callback' => 'beanstalk_repository_overview', 'title' => 'Repositories', 'weight' => 0, 'type' => MENU_LOCAL_TASK, ); $items['admin/settings/beanstalk/repositories/list'] = array( 'file' => 'beanstalk.inc', 'access arguments' => array('administer beanstalk'), 'page callback' => 'beanstalk_repository_overview', 'title' => 'Overview', 'weight' => 0, 'type' => MENU_DEFAULT_LOCAL_TASK, ); $items['admin/settings/beanstalk/repositories/add'] = array( 'file' => 'beanstalk.inc', 'access arguments' => array('administer beanstalk'), 'page callback' => 'drupal_get_form', 'page arguments' => array('beanstalk_repository_edit'), 'title' => 'Add repository', 'weight' => 10, 'type' => MENU_LOCAL_TASK, ); $items['admin/settings/beanstalk/repositories/edit/%'] = array( 'file' => 'beanstalk.inc', 'access arguments' => array('administer beanstalk'), 'page callback' => 'drupal_get_form', 'page arguments' => array('beanstalk_repository_edit', 5), 'title' => 'Edit Repository', 'type' => MENU_CALLBACK, ); $items['admin/settings/beanstalk/repositories/delete/%'] = array( 'file' => 'beanstalk.inc', 'access arguments' => array('administer beanstalk'), 'page callback' => 'beanstalk_repository_delete', 'page arguments' => array(5), 'title' => 'Delete Repository', 'type' => MENU_CALLBACK, ); return $items; } /** * Implementation of hook_node_info(). */ function beanstalk_node_info() { return array( 'beanstalk_commit' => array( 'name' => t('Commit'), 'module' => 'beanstalk', 'description' => t("This is a Beanstalk commit message."), 'has_title' => TRUE, 'title_label' => t('Commit Title'), 'has_body' => TRUE, 'body_label' => t('Commit Message'), ), ); } /** * Implementation of hook_access(). */ function beanstalk_access($op, $node, $account) { if ($op == 'create') { if (user_access('create beanstalk commit message', $account)) { return TRUE; } } if ($op == 'delete') { if (user_access('delete any commit message', $account) || (user_access('delete own commit messages', $account) && ($node->uid == $account->uid))) { return TRUE; } } if ($op == 'update') { if (user_access('edit any commit message', $account) || (user_access('edit own commit messages', $account) && ($node->uid == $account->uid))) { return TRUE; } } if ($op == 'view') { if (user_access('view beanstalk commit message', $account)) { return TRUE; } } } /** * Implementation of hook_perm(). */ function beanstalk_perm() { return array( 'administer beanstalk', 'create beanstalk commit message', 'delete any commit message', 'delete own commit messages', 'edit any commit message', 'edit own commit messages', 'view beanstalk commit message', ); } /** * Implementation of hook_form(). */ function beanstalk_form(&$node) { $type = node_get_types('type', $node); if ($type->has_title) { $form['title'] = array( '#type' => 'textfield', '#title' => check_plain($type->title_label), '#required' => TRUE, '#default_value' => $node->title, '#weight' => -5, ); } if ($type->has_body) { $form['body_field'] = node_body_field($node, $type->body_label, $type->min_word_count); } return $form; } /** * Implementation of hook_validate(). */ function beanstalk_validate(&$node) { if ($node->revision) { if (!is_numeric($node->revision)) { form_set_error('revision', t('The revision must be a number.')); } } else { // Let an empty field mean "zero." $node->revision = 0; } } /** * Implementation of hook_insert(). */ function beanstalk_insert($node) { db_query("INSERT INTO {beanstalk_node_commit} (vid, nid, revision, time, changed_files, changed_dirs, changeset_url, author, author_full_name, author_email) VALUES (%d, %d, %d, %d, '%s', '%s', '%s', '%s', '%s', '%s')", $node->vid, $node->nid, $node->revision, $node->time, $node->changed_files, $node->changed_dirs, $node->changeset_url, $node->author, $node->author_full_name, $node->author_email); } /** * Implementation of hook_update(). */ function beanstalk_update($node) { if ($node->revision) { beanstalk_insert($node); } else { db_query("UPDATE {beanstalk_node_commit} SET revision = %d, time = %d, changeset_url = '%s', author = '%s', author_full_name = '%s', author_email = '%s' WHERE vid = %d", $node->revision, $node->time, $node->changeset_url, $node->author, $node->author_full_name, $node->author_email); } } /** * Implementation of hook_nodeapi(). */ function beanstalk_nodeapi(&$node, $op, $teaser, $page) { switch ($op) { case 'delete revision': db_query('DELETE FROM {beanstalk_node_commit} WHERE vid = %d', $node->vid); break; } } /** * Implementation of hook_delete(). */ function beanstalk_delete($node) { db_query('DELETE FROM {beanstalk_node_commit} WHERE nid = %d', $node->nid); db_query('DELETE FROM {beanstalk_reference} WHERE nid = %d', $node->nid); } /** * Implementation of hook_load(). */ function beanstalk_load($node) { $additions = db_fetch_object(db_query('SELECT revision, time, changed_files, changed_dirs, changeset_url, author, author_full_name, author_email FROM {beanstalk_node_commit} WHERE vid = %d', $node->vid)); foreach (array('changed_files', 'changed_dirs') as $field) { $additions->{$field} = unserialize($additions->{$field}); } return $additions; } /** * Implementation of hook_view(). */ function beanstalk_view($node, $teaser = FALSE, $page = FALSE) { if (variable_get('beanstalk_author', 1) == 1) { module_load_include('inc', 'beanstalk'); $node->body = _beanstalk_link_nodes($node->body); } $node = node_prepare($node, $teaser); if (!$teaser) { $node->content['beanstalk_commit'] = array( '#value' => theme('beanstalk_commit', $node), '#weight' => 1, ); } return $node; } /** * Implementation of hook_views_api(). */ function beanstalk_views_api() { return array('api' => 2.0); } /** * Implementation of hook_date_api_fields. */ function beanstalk_date_api_fields($field) { if ($field == 'beanstalk_repository.time') { return array( 'sql_type' => DATE_UNIX, 'tz_handling' => 'site', ); } } /** * Implementation of hook_block(). */ function beanstalk_block($op = 'list', $delta = 0, $edit = array()) { switch ($op) { case 'list': $blocks[0] = array( 'info' => t('Beanstalk: Related nodes'), 'cache' => BLOCK_NO_CACHE, ); $blocks[1] = array( 'info' => t('Beanstalk: Related commits'), 'cache' => BLOCK_NO_CACHE, ); return $blocks; case 'configure': return array(); case 'save': return; case 'view': default: switch ($delta) { case 0: $block['subject'] = t('Related nodes'); $block['content'] = _beanstalk_related_nodes(0); break; case 1: $block['subject'] = t('Related commits'); $block['content'] = _beanstalk_related_nodes(1); break; } return $block; } } /** * Block content generation function. */ function _beanstalk_related_nodes($block) { $rows = array(); if (arg(0) == 'node') { $node = node_load(arg(1)); switch ($block) { case 0: $sql = "SELECT * FROM {beanstalk_reference} WHERE commit_nid = %d ORDER BY commit_nid DESC"; $result = db_query($sql, $node->nid); $header = array(t('ID'), t(Title)); while ($r = db_fetch_object($result)) { $n = node_load($r->node_nid); $rows[] = array('#'. $n->nid, l($n->title, 'node/'. $n->nid)); } break; case 1: $sql = "SELECT * FROM {beanstalk_reference} WHERE node_nid = %d ORDER BY commit_nid DESC"; $result = db_query($sql, $node->nid); $header = array(t('Revision'), t('Timestamp')); while ($r = db_fetch_object($result)) { $n = node_load($r->commit_nid); $rows[] = array('Rev. '. $n->nid, l(format_date($n->time, 'small'), 'node/'. $n->nid)); } break; } if (!empty($rows)) { return theme('table', $header, $rows); } } return; } /** * Implementation of hook_theme(). */ function beanstalk_theme() { return array( 'beanstalk_commit' => array( 'arguments' => array('node'), ), 'beanstalk_changes' => array( 'arguments' => array('changes'), ), ); } /** * Custom theme function to format commit info table. */ function theme_beanstalk_commit($node) { $headers = array( array( 'data' => t('Commit Data'), 'colspan' => 2 ), ); $rows = array(); if ($node->uid && variable_get('beanstalk_author', 1) == 1) { $object = user_load(array('uid' => $node->uid)); $user = l($object->name, 'user/'. $object->uid) .' ('. check_plain($node->author) .')'; } else { $user = check_plain($node->author); } $changeset_url = check_plain($node->changeset_url); $rows[] = array(t('Revision'), check_plain($node->revision)); $rows[] = array(t('Time'), format_date($node->time)); $rows[] = array(t('Author'), $user); $rows[] = array(t('Changed files'), theme('beanstalk_changes', $node->changed_files)); $rows[] = array(t('Changed folders'), theme('beanstalk_changes', $node->changed_dirs)); $rows[] = array(t('Changeset'), l($changeset_url, $changeset_url)); return "
\n". theme('table', $headers, $rows); } /** * Custom theme function to build list of changes. */ function theme_beanstalk_changes($changes = array()) { $output = ''. t('None') .''; if (is_array($changes) && !empty($changes)) { $output = ''; } return $output; }