From ca4002e4aba7cc2e4adf0699d6d0bb617d04721a Mon Sep 17 00:00:00 2001 From: Mark Carver Date: Mon, 15 Sep 2014 03:08:46 -0500 Subject: Issue #2281551 by Mark Carver, Steven Jones: Create input filter code for linking to git commits --- .../versioncontrol_project_git.module | 91 ++++++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/versioncontrol_project_git/versioncontrol_project_git.module b/versioncontrol_project_git/versioncontrol_project_git.module index 2449714..615a3e4 100644 --- a/versioncontrol_project_git/versioncontrol_project_git.module +++ b/versioncontrol_project_git/versioncontrol_project_git.module @@ -121,3 +121,94 @@ function versioncontrol_project_git_views_api() { 'path' => drupal_get_path('module', 'versioncontrol_project_git') . '/views', ); } + +/** + * Implements hook_filter_info(). + */ +function versioncontrol_project_git_filter_info() { + $filters['versioncontrol_project_git'] = array( + 'title' => t('Versioncontrol project - Git revision'), + 'description' => t('Replaces git revision strings with links to the appropriate commit viewer.'), + 'process callback' => 'versioncontrol_project_git_revision_filter_process', + 'tips callback' => 'versioncontrol_project_git_revision_filter_tips', + ); + return $filters; +} + +/** + * Filter tips callback for the Git revision filter. + */ +function versioncontrol_project_git_revision_filter_tips($filter, $format, $long = FALSE) { + if ($long) { + return t("References to git commits in the form of project_short_name@commit_hash turn into links automatically. You may reference sandboxes by referencing their numeric short name, and you may use any length of commit hash from 8-40. For example: drupal@2569242a, drupal@2569242afd5eec297e7d72065f4e3dd2586d0fd8"); + } + else { + return t('Referenced git commits (ex. drupal@2569242a) turn into links automatically.'); + } +} + +/** + * Filter process callback for the Git revision filter. + */ +function versioncontrol_project_git_revision_filter_process($text, $filter, $format, $langcode, $cache, $cache_id) { + return preg_replace_callback('/([a-z0-9_]{2,})@([a-z0-9]{8,40})/', 'versioncontrol_project_git_revision_process_callback', $text); +} + +/** + * A preg_replace_callback for generating git revision links. + * + * @param array $matches + * The grouped matches from the regex that invoked this callback. This + * callback assumes that $matches[1] is the project machine name and + * $matches[2] is the commit revision. + * + * @return string + * A link to the repository with a specific revision. The link will use the + * shorthand display text of "project_name@revision" where "project_name" is + * the machine name of the project and "revision" is the commit hash limited + * to 8 characters. If this callback could not generate a link successfully, + * the original matched text will be returned. + * + * @see versioncontrol_project_git_revision_filter_process() + */ +function versioncontrol_project_git_revision_process_callback($matches) { + try { + $machine_name = $matches[1]; + $revision = $matches[2]; + + // Get the node ID for the project machine name. + $nid = project_get_nid_from_machinename($machine_name); + if (!$nid) { + throw new Exception('$nid is not a valid project.'); + } + + // Get the repository handler for the node ID. + $repo = versioncontrol_project_repository_load($nid); + if (!($repo instanceof VersioncontrolRepository)) { + throw new Exception('$repo is not an instance of VersioncontrolRepository.'); + } + + // Get the URL handler for the repository. + $url_handler = $repo->getUrlHandler(); + if (!($url_handler instanceof VersioncontrolWebviewerUrlHandlerInterface)) { + throw new Exception('$url_handler is not an instance of VersioncontrolWebviewerUrlHandlerInterface.'); + } + + // Get the URL for the revision. + $url = $url_handler->getCommitViewUrl($revision); + if (empty($url)) { + throw new Exception('There is no URL for the revision.'); + } + + // Generate a link to the revision. + return l($machine_name . '@' . substr($revision, 0, 8), $url, array( + 'attributes' => array( + 'target' => '_blank', + ), + )); + } + catch (Exception $e) { + // Ignore any caught exceptions and let it return the original matched text. + } + return $matches[0]; +} -- 2.0.1