diff --git a/css/rocketship.main.css b/css/rocketship.main.css
new file mode 100644
index 0000000..fff986f
--- /dev/null
+++ b/css/rocketship.main.css
@@ -0,0 +1,12 @@
+.node-rocketship-issue .field-type-taxonomy-term-reference {
+ display: inline-block;
+ margin: 0;
+}
+
+.node-rocketship-issue .field-type-taxonomy-term-reference ul {
+ display: inline;
+}
+
+.node-rocketship-issue .field-type-taxonomy-term-reference ul li {
+ float: left;
+}
\ No newline at end of file
diff --git a/plugins/content_types/rocketship_legend.inc b/plugins/content_types/rocketship_legend.inc
new file mode 100644
index 0000000..f19ddbc
--- /dev/null
+++ b/plugins/content_types/rocketship_legend.inc
@@ -0,0 +1,48 @@
+ TRUE,
+ 'title' => t('Rocketship Legend'),
+ 'description' => t('Shows a legend for the Rocketship issue colors.'),
+ 'category' => t('Miscellaneous'),
+ 'edit form' => 'rocketship_legend_form',
+ 'render callback' => 'rocketship_legend_render',
+ 'admin info' => 'rocketship_legend_admin_info',
+);
+
+/**
+ * Info callback for the Rocketship legend panel.
+ */
+function rocketship_legend_admin_info($subtype, $conf, $contexts) {
+ if (!empty($conf)) {
+ $block = new stdClass;
+ $block->title = $conf['override_title'] ? $conf['override_title_text'] : '';
+ $block->content = t('Showing a link to the drupal issue queue.');
+ return $block;
+ }
+}
+
+/**
+ * Configuration form for the Rocketship legend panel.
+ */
+function rocketship_legend_form($form, &$form_state) {
+ return $form;
+}
+
+/**
+ * Renders the Rocketship legend panel.
+ */
+function rocketship_legend_render($subtype, $conf, $panel_args, $context = NULL) {
+ $block = new stdClass();
+
+ $block->title = $conf['override_title'] ? $conf['override_title_text'] : t('Legend');
+ $block->content = '
' . t('Critical issue') . '
';
+ $block->content .= '' . t('Major issue') . '
';
+ $block->content .= '' . t('Current top priority') . '
';
+
+ return $block;
+}
\ No newline at end of file
diff --git a/plugins/content_types/rocketship_link.inc b/plugins/content_types/rocketship_link.inc
new file mode 100644
index 0000000..cbbebbc
--- /dev/null
+++ b/plugins/content_types/rocketship_link.inc
@@ -0,0 +1,57 @@
+ TRUE,
+ 'title' => t('Rocketship Link'),
+ 'description' => t('Shows a link for certain tags to the drupal.org issue queue.'),
+ 'category' => t('Miscellaneous'),
+ 'edit form' => 'rocketship_link_form',
+ 'render callback' => 'rocketship_link_render',
+ 'admin info' => 'rocketship_link_admin_info',
+ 'required context' => new ctools_context_optional(t('Term'), 'entity:taxonomy_term'),
+);
+
+/**
+ * Info callback for the Rocketship link panel.
+ */
+function rocketship_link_admin_info($subtype, $conf, $contexts) {
+ if (!empty($conf)) {
+ $block = new stdClass;
+ $block->title = $conf['override_title'] ? $conf['override_title_text'] : '';
+ $block->content = t('Showing a link to the drupal issue queue.');
+ return $block;
+ }
+}
+
+/**
+ * Configuration form for the Rocketship link panel.
+ */
+function rocketship_link_form($form, &$form_state) {
+ return $form;
+}
+
+/**
+ * Renders the Rocketship link panel.
+ */
+function rocketship_link_render($subtype, $conf, $panel_args, $context = NULL) {
+ $tags = array();
+ if (!empty($context) && !empty($context->data) && is_object($context->data)) {
+ $tags[$context->data->tid] = $context->data->name;
+ }
+ $path = rocketship_get_issue_path($tags);
+
+ $block = new stdClass();
+
+ $block->title = $conf['override_title'] ? $conf['override_title_text'] : '';
+
+ $block->content = t('See all these issues also at !link. This view of issues is automatically cached and might be out of date up to two hours at times.', array(
+ '!link' => l(url($path['path'], $path), $path['path'], $path),
+ ));
+
+ return $block;
+}
diff --git a/plugins/content_types/rocketship_thanks.inc b/plugins/content_types/rocketship_thanks.inc
new file mode 100644
index 0000000..d80f72a
--- /dev/null
+++ b/plugins/content_types/rocketship_thanks.inc
@@ -0,0 +1,91 @@
+ TRUE,
+ 'title' => t('Rocketship Thanks'),
+ 'description' => t('Shows a tag cloud of the contributors.'),
+ 'category' => t('Miscellaneous'),
+ 'edit form' => 'rocketship_thanks_form',
+ 'render callback' => 'rocketship_thanks_render',
+ 'admin info' => 'rocketship_thanks_admin_info',
+);
+
+/**
+ * Info callback for the Rocketship legend panel.
+ */
+function rocketship_thanks_admin_info($subtype, $conf, $contexts) {
+ if (!empty($conf)) {
+ $block = new stdClass;
+ $block->title = $conf['override_title'] ? $conf['override_title_text'] : '';
+ $block->content = t('Tag cloud of the contributors.');
+ return $block;
+ }
+}
+
+/**
+ * Configuration form for the Rocketship legend panel.
+ */
+function rocketship_thanks_form($form, &$form_state) {
+ return $form;
+}
+
+/**
+ * Renders the Rocketship legend panel.
+ */
+function rocketship_thanks_render($subtype, $conf, $panel_args, $context = NULL) {
+ $block = new stdClass();
+
+ $block->title = $conf['override_title'] ? $conf['override_title_text'] : t('Thanks to');
+
+
+ // Include username cloud if the sprint tag is displayed.
+ $participant_stats = variable_get('rocketship_participant_stats', array());
+ if (!empty($participant_stats)) {
+ $lead_users = variable_get('rocketship_lead_user', array('Gábor Hojtsy'));
+ $participant_uids = variable_get('rocketship_participant_uids', array());
+ $participant_recent = variable_get('rocketship_participant_recent', array());
+
+ // Remove lead user and some users to avoid skewing the stats.
+ if (!empty($lead_users) && is_array($lead_users)) {
+ foreach ($lead_users as $lead_user) {
+ unset($participant_stats[$lead_user]);
+ }
+ }
+
+ unset($participant_stats['System Message']);
+ unset($participant_stats['Abandoned Projects']);
+
+ $usercloud = array();
+ $max = max(array_values($participant_stats));
+ $steps = array(1, 2, 3, 5, 7, 10);
+ foreach ($steps as $i => $step) {
+ foreach ($participant_stats as $name => $count) {
+ if (($step == 10) || ($count <= $step * ($max/10))) {
+ $class = 'rocketship-cloud-' . ($i+1);
+ if (in_array($participant_uids[$name], $participant_recent)) {
+ $class .= ' rocketship-cloud-recent';
+ }
+ $usercloud[$name] = '' . check_plain($name) . '';
+ unset($participant_stats[$name]);
+ }
+ }
+ }
+ // Sort by username in a case insensitive fashion.
+ uksort($usercloud, "strnatcasecmp");
+ $notes = array();
+ $notes[] = t('Based on participation in all @tag issues (font size) using a quasi-logarithmic scale and on recent activity (boldness).', array('@tag' => variable_get('rocketship_master_tag', 'D8MI')));
+ if (!empty($lead_users)) {
+ $notes[] = format_plural(count($lead_users), 'Excludes the initiative lead, @lead.', 'Excludes the initiative leads, @lead.', array('@lead' => implode(', ', $lead_users)));
+ }
+
+ $block->content = '' . join(' ', $usercloud) . '
';
+ $block->content .= '' . join(' ', $notes) . '
';
+ }
+
+ return $block;
+}
\ No newline at end of file
diff --git a/plugins/layouts/rocketship/rocketship.css b/plugins/layouts/rocketship/rocketship.css
new file mode 100644
index 0000000..426117b
--- /dev/null
+++ b/plugins/layouts/rocketship/rocketship.css
@@ -0,0 +1,143 @@
+.rocketship .panel-col-top,
+.rocketship .panel-col-middle,
+.rocketship .panel-col-bottom,
+.rocketship .panel-separator {
+ width: 100%;
+ clear: both;
+}
+
+.rocketship .panel-col-top .inside,
+.rocketship .panel-col-middle .inside {
+ margin-bottom: 1em;
+}
+
+.rocketship .panel-col-first {
+ float: left;
+ width: 33%;
+}
+
+.rocketship .panel-col-first .inside {
+ margin: 0 .5em 1em 0;
+}
+
+.rocketship .panel-col {
+ float: left;
+ width: 33%;
+}
+
+.rocketship .panel-col .inside {
+ margin: 0 .5em 1em .5em;
+}
+
+.rocketship .panel-col-last {
+ float: left;
+ width: 33%;
+}
+
+.rocketship .panel-col-last .inside {
+ margin: 0 0 1em .5em;
+}
+
+.rocketship .panel-separator {
+ margin: 0 0 1em 0;
+}
+
+.view-id-issues .views-row {
+ margin-bottom: 1em;
+}
+
+.rocketship-node,
+.panel-pane .view-id-issues .node-rocketship-issue {
+ padding: 0.2em 0.3em 0.2em 0.5em;
+ -moz-box-shadow: 0 0 0.5em rgba(0,0,0,0.4);
+ -webkit-box-shadow: 0 0 0.5em rgba(0,0,0,0.4);
+ border: none;
+ border-left: 0.7em solid #F5F5F5;
+}
+
+.panel-pane .view-id-issues .node-rocketship-issue h2 a {
+ font-weight: bold;
+ font-size: 0.8em;
+}
+
+.rocketship-focus,
+.panel-pane .view-id-issues .node-rocketship-issue-focus {
+ border-left-color: #336699;
+}
+
+.rocketship-major,
+.panel-pane .view-id-issues .node-rocketship-issue-major {
+ border-left-color: #FF9900;
+}
+
+.rocketship-critical,
+.panel-pane .view-id-issues .node-rocketship-issue-critical {
+ border-left-color: #FF0000;
+}
+
+.rocketship-needs-tests,
+.panel-pane .view-id-issues .node-rocketship-issue-needs-tests {
+ font-weight: bold;
+}
+
+.view-id-issues .node-rocketship-issue .field-type-taxonomy-term-reference li {
+ background-color: #F5F5F5;
+ margin: 0.1em 0.3em 0.1em 0;
+ padding: 0.1em 0.3em;
+ display: inline-block;
+ border-radius: 0.2em;
+}
+
+.pane-rocketship-legend {
+ float: right;
+ clear: both;
+}
+.pane-rocketship-legend .pane-title,
+.pane-rocketship-legend .pane-content,
+.pane-rocketship-legend .rocketship-node {
+ display: inline-block;
+ margin-left: 6px;
+}
+.panel-pane .view-id-issues .node-rocketship-issue .field-name-rocketship-assignee {
+ background-color: #F5F5F5;
+ margin: -0.2em -0.3em -0.3em -0.5em;
+ padding: 0.1em 1em;
+ border: none;
+ border-top: 0.1em dotted #DDDDDD;
+ font-size: 0.9em;
+}
+.rocketship-cloud-wrapper {
+ border-top: 0.1em solid #3b3b3b;
+ margin-bottom: 2em;
+ clear: both;
+}
+.rocketship-cloud-wrapper p {
+ font-size: 0.8em;
+ margin-top: 1.3em;
+ font-style: italic;
+}
+.rocketship-cloud {
+ line-height: 1.3em;
+ text-align: justify;
+}
+.rocketship-cloud-1 {
+ font-size: 0.8em;
+}
+.rocketship-cloud-2 {
+ font-size: 1em;
+}
+.rocketship-cloud-3 {
+ font-size: 1.4em;
+}
+.rocketship-cloud-4 {
+ font-size: 1.6em;
+}
+.rocketship-cloud-5 {
+ font-size: 1.8em;
+}
+.rocketship-cloud-6 {
+ font-size: 2em;
+}
+.rocketship-cloud-recent a {
+ font-weight: bold;
+}
diff --git a/plugins/layouts/rocketship/rocketship.inc b/plugins/layouts/rocketship/rocketship.inc
new file mode 100644
index 0000000..412c329
--- /dev/null
+++ b/plugins/layouts/rocketship/rocketship.inc
@@ -0,0 +1,25 @@
+ t('Rocketship'),
+ 'category' => t('Columns: 3'),
+ 'icon' => 'rocketship.png',
+ 'theme' => 'rocketship',
+ 'css' => 'rocketship.css',
+ 'regions' => array(
+ 'top' => t('Top'),
+ 'upper_first' => t('Upper First'),
+ 'upper_middle' => t('Upper Middle'),
+ 'upper_last' => t('Upper Last'),
+ 'middle' => t('Middle'),
+ 'lower_first' => t('Lower First'),
+ 'lower_middle' => t('Lower Middle'),
+ 'lower_last' => t('Lower Last'),
+ 'bottom' => t('Bottom')
+ ),
+);
diff --git a/plugins/layouts/rocketship/rocketship.tpl.php b/plugins/layouts/rocketship/rocketship.tpl.php
new file mode 100644
index 0000000..18b6fc2
--- /dev/null
+++ b/plugins/layouts/rocketship/rocketship.tpl.php
@@ -0,0 +1,64 @@
+
+
diff --git a/rocketship.info b/rocketship.info
index d8933d5..c02d6ec 100644
--- a/rocketship.info
+++ b/rocketship.info
@@ -1,3 +1,17 @@
name = Rocketship
description = Issue augmentation for Drupal initiatives
-core = 7.x
\ No newline at end of file
+core = 7.x
+
+dependencies[] = ctools
+dependencies[] = page_manager
+dependencies[] = panels
+dependencies[] = taxonomy
+dependencies[] = views
+dependencies[] = views_content
+
+
+; Information added by drush on 2013-06-04
+version = "master-dev"
+project = "rocketship"
+datestamp = "1370350776"
+
diff --git a/rocketship.install b/rocketship.install
new file mode 100644
index 0000000..2c9b03e
--- /dev/null
+++ b/rocketship.install
@@ -0,0 +1,180 @@
+ t('Issue tags'),
+ 'rocketship_version_tags' => t('Version tags'),
+ 'rocketship_category_tags' => t('Category tags'),
+ 'rocketship_status_tags' => t('Status tags'),
+ 'rocketship_priority_tags' => t('Priority tags'),
+ 'rocketship_component_tags' => t('Component tags'),
+ );
+ $vocabulary_tags = array(
+ 'rocketship_version_tags' => array(
+ '6.x-dev', '7.x-dev',
+ ),
+ 'rocketship_status_tags' => array('patch (to be ported)', 'fixed', 'closed (duplicate)',
+ 'closed (won\'t fix)', 'closed (works as designed)',
+ 'closed (cannot reproduce)', 'closed (fixed)', 'postponed',
+ 'postponed (maintainer needs more info)', 'active', 'needs work',
+ 'reviewed & tested by the community', 'needs review',
+ ),
+ );
+ foreach ($vocabularies as $machine_name => $label) {
+ $vocabulary = taxonomy_vocabulary_machine_name_load($machine_name);
+ if (!$vocabulary) {
+ $vocabulary = (object)array(
+ 'name' => $label,
+ 'machine_name' => $machine_name,
+ 'description' => '',
+ 'hierarchy' => 0,
+ );
+ taxonomy_vocabulary_save($vocabulary);
+ }
+ variable_set($machine_name . '_vid', $vocabulary->vid);
+ if (isset($vocabulary_tags[$machine_name])) {
+ foreach ($vocabulary_tags[$machine_name] as $tag) {
+ if (!taxonomy_get_term_by_name($tag)) {
+ taxonomy_term_save((object) array(
+ 'vid' => $vocabulary->vid,
+ 'name' => $tag,
+ ));
+ }
+ }
+ }
+ }
+
+ if (!field_info_field('rocketship_assignee')) {
+ field_create_field(array(
+ 'field_name' => 'rocketship_assignee',
+ 'type' => 'text',
+ ));
+ }
+
+ if (!field_info_field('rocketship_priority')) {
+ field_create_field(array(
+ 'field_name' => 'rocketship_priority',
+ 'type' => 'number_integer',
+ ));
+ }
+
+ foreach ($vocabularies as $machine_name => $label) {
+ if (!field_info_field($machine_name)) {
+ field_create_field(array(
+ 'field_name' => $machine_name,
+ 'type' => 'taxonomy_term_reference',
+ 'settings' => array(
+ 'allowed_values' => array(
+ array('vocabulary' => $machine_name, 'parent' => NULL),
+ ),
+ ),
+ 'cardinality' => -1,
+ ));
+ }
+
+ if (!field_info_instance('node', $machine_name, 'rocketship_issue')) {
+ field_create_instance(array(
+ 'label' => $label,
+ 'field_name' => $machine_name,
+ 'entity_type' => 'node',
+ 'bundle' => 'rocketship_issue',
+ 'widget' => array('type' => 'taxonomy_autocomplete'),
+ 'display' => array(
+ 'default' => array(
+ 'label' => 'hidden',
+ 'type' => 'taxonomy_term_reference_plain',
+ 'weight' => 0,
+ ),
+ 'teaser' => array(
+ 'label' => 'hidden',
+ 'type' => 'taxonomy_term_reference_plain',
+ 'weight' => 0,
+ ),
+ ),
+ ));
+ }
+ }
+
+ if (!field_info_instance('node', 'rocketship_assignee', 'rocketship_issue')) {
+ field_create_instance(array(
+ 'label' => 'Assigned to',
+ 'field_name' => 'rocketship_assignee',
+ 'entity_type' => 'node',
+ 'bundle' => 'rocketship_issue',
+ 'widget' => array('type' => 'text_textfield'),
+ 'display' => array(
+ 'default' => array(
+ 'label' => 'inline',
+ 'type' => 'text_default',
+ 'weight' => 1,
+ ),
+ 'teaser' => array(
+ 'label' => 'inline',
+ 'type' => 'text_default',
+ 'weight' => 1,
+ ),
+ ),
+ ));
+ }
+
+ if (!field_info_instance('node', 'rocketship_priority', 'rocketship_issue')) {
+ field_create_instance(array(
+ 'label' => 'Priority',
+ 'field_name' => 'rocketship_priority',
+ 'entity_type' => 'node',
+ 'bundle' => 'rocketship_issue',
+ 'widget' => array(
+ 'type' => 'number',
+ ),
+ 'display' => array(
+ 'default' => array('type' => 'hidden'),
+ 'teaser' => array('type' => 'hidden'),
+ ),
+ ));
+ }
+
+ if (!field_info_instance('node', 'rocketship_issue_tags', 'rocketship_focus')) {
+ field_create_instance(array(
+ 'label' => 'Issue tags',
+ 'field_name' => 'rocketship_issue_tags',
+ 'entity_type' => 'node',
+ 'bundle' => 'rocketship_focus',
+ 'widget' => array('type' => 'taxonomy_autocomplete'),
+ ));
+ }
+}
+
+/**
+ * Implements hook_uninstall().
+ */
+function rocketship_uninstall() {
+ $vocabularies = array(
+ 'rocketship_issue_tags' => t('Issue tags'),
+ 'rocketship_version_tags' => t('Version tags'),
+ 'rocketship_category_tags' => t('Category tags'),
+ 'rocketship_status_tags' => t('Status tags'),
+ 'rocketship_priority_tags' => t('Priority tags'),
+ 'rocketship_component_tags' => t('Component tags'),
+ );
+ foreach ($vocabularies as $machine_name => $label) {
+ field_delete_field($machine_name);
+ $vocabulary = taxonomy_vocabulary_machine_name_load($machine_name);
+ taxonomy_vocabulary_delete($vocabulary->vid);
+ }
+ field_delete_field('rocketship_assignee');
+ field_delete_field('rocketship_priority');
+
+
+}
\ No newline at end of file
diff --git a/rocketship.module b/rocketship.module
index 54d0c2d..fdd3a42 100644
--- a/rocketship.module
+++ b/rocketship.module
@@ -1,22 +1,10 @@
array(
+ 'name' => t('Issue'),
+ 'base' => 'node_content',
+ 'description' => '',
+ 'has_title' => '1',
+ 'title_label' => t('Title'),
+ 'help' => '',
+ ),
+ 'rocketship_focus' => array(
+ 'name' => t('Issue Focus'),
+ 'base' => 'node_content',
+ 'description' => '',
+ 'has_title' => '1',
+ 'title_label' => t('Title'),
+ 'help' => '',
+ ),
+ );
+ return $items;
+}
+
+/**
+ * Implements hook_views_api().
+ */
+function rocketship_views_api() {
+ return array(
+ 'api' => 3,
+ 'path' => drupal_get_path('module', 'rocketship'),
+ );
+}
+
+/**
+ * Implementation of hook_ctools_plugin_api().
+ */
+function rocketship_ctools_plugin_api($module, $api) {
+ if ($module == 'page_manager' && $api == 'pages_default') {
+ return array('version' => 1);
+ }
+}
+
+/**
+ * Implementation of hook_ctools_plugin_directory()
+ */
+function rocketship_ctools_plugin_directory($owner, $plugin_type) {
+ $supported = array('content_types', 'layouts');
+ if (in_array($plugin_type, $supported)) {
+ return 'plugins/' . $plugin_type;
+ }
+}
+
+/**
* Implements hook_cron().
*/
function rocketship_cron() {
@@ -65,14 +107,16 @@ function rocketship_launch_form_submit() {
*/
function rocketship_parse_all() {
// Grab the first page of the listings of issues for this tag.
- $issue_page = 'http://drupal.org/project/issues/search/drupal?issue_tags=' . urlencode(variable_get('rocketship_master_tag', 'D8MI'));
- $page_output = drupal_http_request($issue_page);
+ $tags = array(variable_get('rocketship_master_tag', 'D8MI'));
+ $path = rocketship_get_issue_path($tags);
+ $url = url($path['path'], $path);
+ $page_output = drupal_http_request($url);
if ($page_output->code == 200 && !empty($page_output->data)) {
// Figure out the index number of the last issue list page by scraping.
$last_page_num = 0;
if (preg_match('!href="([^"]+)" title="Go to last page"!', $page_output->data, $last_page)) {
- if (preg_match('!\?page=(\d+)&!', $last_page[1], $last_page_find)) {
+ if (preg_match('!\?page=(\d+)&!', $last_page[1], $last_page_find)) {
$last_page_num = $last_page_find[1];
}
}
@@ -83,7 +127,9 @@ function rocketship_parse_all() {
// If we have more pages, go on to the rest of the pages as well.
if (!empty($last_page_num)) {
for ($page_num = 1; $page_num <= $last_page_num; $page_num++) {
- $page_output = drupal_http_request($issue_page . '&page='. $page_num);
+ $path['query']['page'] = $page_num;
+ $url = url($path['path'], $path);
+ $page_output = drupal_http_request($url);
if ($page_output->code == 200 && !empty($page_output->data)) {
rocketship_parse_issue_page($page_output->data);
}
@@ -123,11 +169,10 @@ function rocketship_stat_add_username($username = NULL, $uid = NULL, $time = NUL
/**
* Data scraper for a drupal.org issue listing page.
*
- * @todo
+ * @todo Drop outdated nodes and unused tags.
* Does not drop outdated nodes (if master tag is removed), only updates old
* ones and create new ones. Also does not drop unused tags.
- * @todo
- * Does not consider multi-page issues. Yeah.
+ * @todo Does not consider multi-page issues. Yeah.
*/
function rocketship_parse_issue_page(&$issue_page_content) {
@@ -146,7 +191,9 @@ function rocketship_parse_issue_page(&$issue_page_content) {
// pattern, where 12345 is the issue nid from drupal.org and "title" is
// the issue title from drupal.org. Since all that stays the same for
// a drupal.org is the issue number, we look for that specifically.
- $nid = db_query("SELECT nid FROM {node} WHERE type = :type AND title LIKE '#" . (int) $match . ":%'", array(':type' => ROCKETSHIP_NODE_TYPE))->fetchField();
+ $nid = db_query("SELECT nid FROM {node} WHERE type = 'rocketship_issue' AND title LIKE :title", array(
+ ':title' => '#' . (int) $match . ':%'
+ ))->fetchField();
if ($nid) {
$node = node_load($nid);
}
@@ -155,7 +202,7 @@ function rocketship_parse_issue_page(&$issue_page_content) {
// and other listings of nodes, taxonomy index data is only stored for
// published nodes, so this is what we can do to get easy results
// quickly.
- $node = (object) array('type' => ROCKETSHIP_NODE_TYPE, 'language' => 'und', 'status' => 1);
+ $node = (object) array('type' => 'rocketship_issue', 'language' => 'und', 'status' => 1);
}
// Grab node title based on drupal.org HTML markup.
@@ -175,57 +222,88 @@ function rocketship_parse_issue_page(&$issue_page_content) {
}
}
- // Assumes a "field_assigned" text field is present on this node type.
- if (preg_match('!Assigned: | (.*) | !', $issue_node->data, $assigned)) {
- $node->field_assigned['und'][0]['value'] = strip_tags($assigned[1]);
+ if (preg_match('!Assigned: | (.*) | !', $issue_node->data, $match)) {
+ $assigned = strip_tags($match[1]);
+ if ($assigned != 'Unassigned') {
+ $node->rocketship_assingee['und'][0]['value'] = $assigned;
+ }
+ else {
+ $node->rocketship_assingee['und'] = array();
+ }
}
// Store all kinds of metadata as plain tags on this node. We can then
// do listings based on the presence of these tags "easily".
$tags = array();
if (preg_match('!Version: | (.*) | !', $issue_node->data, $tag)) {
- $tags[] = $tag[1];
+ $tags['rocketship_version_tags'][] = $tag[1];
}
if (preg_match('!Category: | (.*) | !', $issue_node->data, $tag)) {
- $tags[] = $tag[1];
+ $tags['rocketship_category_tags'][] = $tag[1];
}
if (preg_match('!Priority: | (.*) | !', $issue_node->data, $tag)) {
- $tags[] = $tag[1];
+ $tags['rocketship_priority_tags'][] = $tag[1];
+ }
+ if (preg_match('!Component: | (.*) | !', $issue_node->data, $tag)) {
+ $tags['rocketship_component_tags'][] = $tag[1];
}
if (preg_match('!Status: | (.*) | !', $issue_node->data, $tag)) {
// "Decode" for "reviewed & tested by the community".
- $tags[] = str_replace('&', '&', $tag[1]);
+ $tags['rocketship_status_tags'][] = str_replace('&', '&', $tag[1]);
}
if (preg_match('!Issue tags: | (.*) | !', $issue_node->data, $tag)) {
if (preg_match_all('!>([^<]+)!', $tag[1], $more_tags)) {
foreach ($more_tags[1] as $tag) {
- $tags[] = $tag;
+ $tags['rocketship_issue_tags'][] = $tag;
}
}
}
// Now try and find existing tags with matching names if present or
// create the new tags if needed.
- $node->field_issue_tags['und'] = array();
- foreach($tags as $tag) {
- // This is an ugly pattern but there might be multiple matching
- // terms, so we need to find the one matching in our vocabulary.
- $matching_terms = taxonomy_get_term_by_name($tag);
- if (!empty($matching_terms)) {
- foreach ($matching_terms as $term) {
- if ($term->vid == variable_get('rocketship_tags_vid', 6)) {
- $node->field_issue_tags['und'][] = array('tid' => $term->tid);
+ foreach($tags as $machine_name => $vocabulary_tags) {
+ $node->$machine_name['und'] = array();
+ $vocabulary = taxonomy_vocabulary_machine_name_load($machine_name);
+ foreach ($vocabulary_tags as $tag) {
+ // This is an ugly pattern but there might be multiple matching
+ // terms, so we need to find the one matching in our vocabulary.
+ $matching_terms = taxonomy_get_term_by_name($tag);
+ if (!empty($matching_terms)) {
+ foreach ($matching_terms as $term) {
+ if ($term->vid == $vocabulary->vid) {
+ $node->{$machine_name}['und'][] = array('tid' => $term->tid);
+ }
}
}
+ else {
+ // Not found, so create a new tag and assign.
+ $term = (object) array(
+ 'vid' => $vocabulary->vid,
+ 'name' => $tag,
+ );
+ taxonomy_term_save($term);
+ $node->{$machine_name}['und'][] = array('tid' => $term->tid);
+ }
}
- else {
- // Not found, so create a new tag and assign.
- $term = (object) array(
- 'vid' => variable_get('rocketship_tags_vid', 6),
- 'name' => $tag,
- );
- taxonomy_term_save($term);
- $node->field_issue_tags['und'][] = array('tid' => $term->tid);
+ if ($machine_name == 'rocketship_priority_tags') {
+ $priority = 0;
+ foreach ($vocabulary_tags as $tag) {
+ switch ($tag) {
+ case 'Needs tests':
+ break;
+ case 'major':
+ $priority = min(-5, $priority);
+ break;
+ case 'critical':
+ $priority = min(-7, $priority);
+ break;
+ case 'sprint':
+ $priority = min(-10, $priority);
+ break;
+ }
+ }
+
+ $node->rocketship_priority['und'][0]['value'] = $priority;
}
}
@@ -237,396 +315,71 @@ function rocketship_parse_issue_page(&$issue_page_content) {
}
/**
- * Display controlled for nodes.
+ * Gets the drupal issue search path.
*
- * This assumes nodes where we want to display a list of issues have a
- * "field_issue_tag_display" single value taxonomy term reference field,
- * which designates the tag that we want to dive into (from all the)
- * issues that we gathered. This can be equal to the rocketship_master_tag
- * variable if we want a list of all locally cached issues.
+ * @param array $tags
+ * List of tags to query for
*
- * The primary goal here is to group the issues in sensible groups and
- * display them by their group to help produce a visual overview.
+ * @return array
+ * url() compatible array structure.
*/
-function rocketship_node_view($node, $view_mode, $langcode) {
- if (!empty($node->field_issue_tag_display['und'])) {
-
- // Get more info on the term we are presenting this list for.
- $tid_for_list = $node->field_issue_tag_display['und'][0]['tid'];
- $term_for_list = taxonomy_term_load($tid_for_list);
-
- // Get all the issue nodes that have the tag we need.
- $nids = db_query('SELECT nid FROM {taxonomy_index} WHERE tid = :tid', array(':tid' => $tid_for_list))->fetchAll();
-
- // Look up a cached version for this term if we have it and
- // it is not yet expired (no newer nodes of the issue type
- // available yet).
- if ($cache = cache_get('rocketship:' . $tid_for_list)) {
- $last_issue_update = db_query("SELECT changed FROM {node} WHERE type = :type ORDER BY created DESC", array(':type' => ROCKETSHIP_NODE_TYPE))->fetchField();
- if ($cache->created > $last_issue_update) {
- $node->content['rocketship_issues'] = array(
- '#markup' => $cache->data,
- // Place at the end of the page before book navigation (if present).
- '#weight' => 80,
- );
- return;
- }
- }
-
- // Now come some tricky wrangly of the data. We want to display
- // two 3-column tables. The first one is the primary overview
- // with the second more informal about issues we are not currently
- // focusing on.
- $tables = array(
- 1 => t('Currently in the works for Drupal 8'),
- 2 => t('Other related issues'),
+function rocketship_get_issue_path(array $tags, $operator = 'and') {
+ $path = array();
+ $path['path'] = 'http://drupal.org/project/issues/search/' . variable_get('rocketship_project', 'drupal');
+
+ if (!empty($tags)) {
+ $path['query'] = array(
+ 'issue_tags' => implode(',', $tags),
+ 'issue_tags_op' => $operator,
);
+ }
- // The columns for these two tables are intermingled here to make
- // term matching simpler without complicated conditions. We achieve
- // categorization without complex conditions by prioritizing the
- // placement of issues in categories with their tags.
- $columns = array(
- // Need this first so that we catch the backport patches first and then
- // the rest can sort itself based on simpler tag lookups.
- t('Backport') => array(array('patch (to be ported)', '6.x-dev', '7.x-dev'), 2),
- t('To do') => array(array('active', 'needs work'), 1),
- t('To review') => array(array('needs review'), 1),
- t('To be committed') => array(array('reviewed & tested by the community'), 1),
- t('Postponed') => array(array('postponed', 'postponed (maintainer needs more info)'), 2),
- t('Closed') => array(array('fixed', 'closed (duplicate)', "closed (won't fix)", 'closed (works as designed)', 'closed (cannot reproduce)', 'closed (fixed)'), 2),
- );
+ return $path;
+}
- // Some trickery to replace the term names in the $columns array
- // with term ids for easier lookup later and collect a list of
- // all those term IDs for later matching.
- $status_tids = array();
- foreach ($columns as $name => &$terms) {
- foreach ($terms[0] as &$term_name) {
- if ($matching_terms = taxonomy_get_term_by_name($term_name)) {
- foreach ($matching_terms as $term) {
- if ($term->vid == variable_get('rocketship_tags_vid', 6)) {
- // Replace term name in $columns with term ID (the variable
- // is taken by reference, so we directly modify the arary here).
- $term_name = $term->tid;
- // Collect a complete list of all status tids.
- $status_tids[] = $term->tid;
+/**
+ * Implements hook_preprocess_node().
+ */
+function rocketship_preprocess_node(&$variables) {
+ if ($variables['type'] == 'rocketship_issue' && !$variables['page']) {
+ drupal_add_css(drupal_get_path('module', 'rocketship') . '/css/rocketship.main.css');
+ $drupalorg_nid = preg_replace('!#(\d+):(.*)$!', '\1', $variables['title']);
+ $variables['node_url'] = 'http://drupal.org/node/' . $drupalorg_nid;
+
+ $rocketship_tags = array();
+ $vocabularies = array(
+ 'rocketship_issue_tags' => t('Issue tags'),
+ 'rocketship_version_tags' => t('Version tags'),
+ 'rocketship_category_tags' => t('Category tags'),
+ 'rocketship_status_tags' => t('Status tags'),
+ 'rocketship_priority_tags' => t('Priority tags'),
+ 'rocketship_component_tags' => t('Component tags'),
+ );
+ foreach ($vocabularies as $machine_name => $label) {
+ $rocketship_tags = field_get_items('node', $variables['node'], $machine_name);
+ if ($rocketship_tags) {
+ foreach ($rocketship_tags as $tag_info) {
+ $term = taxonomy_term_load($tag_info['tid']);
+ switch ($term->name) {
+ // Style the needs tests tag specially.
+ // @todo: this has some more potential, think about it.
+ case 'Needs tests':
+ $variables['classes_array'][] = 'node-rocketship-issue-needs-tests';
+ break;
+ // Mark issues with major and critical status.
+ case 'major':
+ $variables['classes_array'][] = 'node-rocketship-issue-major';
+ break;
+ case 'critical':
+ $variables['classes_array'][] = 'node-rocketship-issue-critical';
+ break;
+ // Use the "sprint" tag to mark issues for current focus.
+ case 'sprint':
+ $variables['classes_array'][] = 'node-rocketship-issue-focus';
break;
- }
- }
- }
- else {
- // This might happen if we never had issues with the given status tag,
- // so we don't have the status tag created yet. In this case, we should
- // ignore this tag for now.
- $term_name = 0;
- }
- }
- }
-
- // Now load the nodes we found for the page tag and categorize into
- // the groups defined by terms in $columns.
- $nodes = array();
- foreach($nids as $nid) {
- $issue_node = node_load($nid->nid);
- // Tags on the issue node should be referenced in field_issue_tags[].
- if (!empty($issue_node->field_issue_tags['und'])) {
- foreach ($issue_node->field_issue_tags['und'] as $tag_info) {
- if (in_array($tag_info['tid'], $status_tids)) {
- // If this was a status tid, look at which group it is in,
- // in which case we found where to categorize the node.
- foreach ($columns as $title => $status_map) {
- if (in_array($tag_info['tid'], $status_map[0])) {
- // Save the whole node object categorized under the $columns
- // $title for this column and move two levels up to the next
- // node.
- $nodes[$title][] = $issue_node;
- break 2;
- }
- }
- }
- }
- }
- }
-
- // Now sort the $nodes array into two tables and fill in the table
- // headers and cells appropriately.
- $header_data = array();
- $table_data = array();
- foreach ($columns as $header => $columns_data) {
- // Sort nodes by "priority" defined by current focus as most important and
- // then major and critical being slightly less important and then the rest.
- $cell = array(-10 => '', -7 => '', -5 => '', 0 => '');
- if (!empty($nodes[$header])) {
- foreach ($nodes[$header] as $issue_node) {
- $classes = 'rocketship-node';
- $cell_terms = '';
- $priority = 0;
- foreach ($issue_node->field_issue_tags['und'] as $tag_info) {
- $term = taxonomy_term_load($tag_info['tid']);
- $term_class = 'rocketship-term';
- switch($term->name) {
- // Style the needs tests tag specially.
- // @todo: this has some more potential, think about it.
- case 'Needs tests':
- $term_class .= ' rocketship-needs-tests';
- break;
- // Mark issues with major and critical status.
- case 'major':
- $classes .= ' rocketship-major';
- $priority = min(-5, $priority);
- break;
- case 'critical':
- $classes .= ' rocketship-critical';
- $priority = min(-7, $priority);
- break;
- // Use the "sprint" tag to mark issues for current focus.
- case 'sprint':
- $classes .= ' rocketship-focus';
- $priority = min(-10, $priority);
- break;
- }
- // Remove tags that are "trivial" in this listing. The master tag
- // is always trivial, the tool focuses on 8.x issues, so those
- // not having that tag should be assumed to be 8.x, RTBC and
- // needs review issues are in their respective column, so that is
- // already represented, and the current page tag is presented on
- // the page, so again no need to repeat it on all nodes (it is not
- // a distinguishing factor).
- if (!in_array($term->name, array(variable_get('rocketship_master_tag', 'D8MI'), 'reviewed & tested by the community', 'needs review', '8.x-dev', $term_for_list->name))) {
- // Add up all terms with their respective tags.
- $cell_terms .= ''. check_plain($term->name) .'';
- }
- }
-
- // Add rocketship-normal class for easier styling.
- if ($priority == 0) {
- $classes .= ' rocketship-normal';
- }
-
- // Link to drupal.org node for this issue.
- $drupalorg_nid = preg_replace('!#(\d+):(.*)$!', '\1', $issue_node->title);
- $cell[$priority] .= ''. l($issue_node->title, 'http://drupal.org/node/'. $drupalorg_nid) .'
';
- $cell[$priority] .= $cell_terms;
- if (!empty($issue_node->field_assigned['und'][0]['value']) && $issue_node->field_assigned['und'][0]['value'] != 'Unassigned') {
- $cell[$priority] .= '
' . t('Assigned to @assigned', array('@assigned' => $issue_node->field_assigned['und'][0]['value'])) . "
";
- }
- $cell[$priority] .= '
';
- }
- }
-
- // Store this cell and header in the right table. Each table will only
- // have one cell per column (which might not look nice), but it gets us
- // to the best display results. For purity's sake we might want to
- // rebuild this based on a three column layout, that is what we
- // accomplish with the tables basically.
- $table_data[$columns_data[1]][] = join('', $cell);
- $header_data[$columns_data[1]][] = $header;
- }
-
- // Styling and some usabiltiy improvement JS included inline. This is indeed
- // very ugly but is quickly accessible for development and can be refactored
- // later.
- $output = <<
-STYLE;
-
- // Produce a short legend to be included with each table.
- $legend = 'Legend:
Critical issue
Major issue
Current top priority
';
- foreach($tables as $num => $title) {
- // Lead the table with a legend.
- $output .= $legend . ''. $title .'
';
- // Link to drupal.org issue list for the same issue overview. Reassures
- // users that there is no special data showcased here, they can still
- // access all this on drupal.org.
- $issue_list_url = 'http://drupal.org/project/issues/search/drupal?issue_tags=' . urlencode($term_for_list->name) . ($term_for_list->name == variable_get('rocketship_master_tag', 'D8MI') ? '' : '%2C+' . variable_get('rocketship_master_tag', 'D8MI') . '&issue_tags_op=and');
- $output .= 'See all these issues also at ' .check_plain($issue_list_url) . '. This view of issues is automatically cached and might be out of date up to two hours at times.
';
-
- // Theme the respective "table" with responsive markup.
- $output .= '';
- foreach ($header_data[$num] as $i => $cell) {
- $output .= '
' . $cell . '
';
- if (empty($table_data[$num][$i])) {
- $output .= t('(None)');
- }
- else {
- $output .= $table_data[$num][$i];
- }
- $output .= '';
- }
- $output .= '
';
- // $output .= theme('table', array('header' => $header_data[$num], 'rows' => array($table_data[$num])));
- }
- $output .= '';
-
- // Include username cloud if the sprint tag is displayed.
- $participant_stats = variable_get('rocketship_participant_stats', array());
- if ($term_for_list->name == 'sprint' && !empty($participant_stats)) {
- $lead_user = variable_get('rocketship_lead_user', 'Gábor Hojtsy');
- $participant_uids = variable_get('rocketship_participant_uids', array());
- $participant_recent = variable_get('rocketship_participant_recent', array());
-
- // Remove lead user and some users to avoid skewing the stats.
- if ($lead_user) {
- unset($participant_stats[$lead_user]);
- }
- unset($participant_stats['System Message']);
- unset($participant_stats['Abandoned Projects']);
-
- $usercloud = array();
- $max = max(array_values($participant_stats));
- $steps = array(1, 2, 3, 5, 7, 10);
- foreach ($steps as $i => $step) {
- foreach ($participant_stats as $name => $count) {
- if (($step == 10) || ($count <= $step * ($max/10))) {
- $class = 'rocketship-cloud-' . ($i+1);
- if (in_array($participant_uids[$name], $participant_recent)) {
- $class .= ' rocketship-cloud-recent';
- }
- $usercloud[$name] = '' . check_plain($name) . '';
- unset($participant_stats[$name]);
}
}
}
- // Sort by username in a case insensitive fashion.
- uksort($usercloud, "strnatcasecmp");
- $note = '' . t('Based on participation in all @tag issues (font size) using a quasi-logarithmic scale and on recent activity (boldness).', array('@tag' => variable_get('rocketship_master_tag', 'D8MI')));
- if ($lead_user) {
- $note .= ' ' . t('Excludes the initiative lead, @lead.', array('@lead' => $lead_user));
- }
- $note .= '
';
- $output .= '' . t('Thanks to') . ' #
' . '
' . join(' ', $usercloud) . '
' . $note . '
';
}
-
- // Save the generated page section in the rocketship cache.
- cache_set('rocketship:' . $tid_for_list, $output);
- watchdog('rocketship', 'Rocketship cache miss.');
-
- $node->content['rocketship_issues'] = array(
- '#markup' => $output,
- // Place at the end of the page before book navigation (if present).
- '#weight' => 80,
- );
}
}
diff --git a/rocketship.pages_default.inc b/rocketship.pages_default.inc
new file mode 100644
index 0000000..449c582
--- /dev/null
+++ b/rocketship.pages_default.inc
@@ -0,0 +1,388 @@
+disabled = FALSE; /* Edit this to true to make a default handler disabled initially */
+ $handler->api_version = 1;
+ $handler->name = 'node_view_panel_context';
+ $handler->task = 'node_view';
+ $handler->subtask = '';
+ $handler->handler = 'panel_context';
+ $handler->weight = 0;
+ $handler->conf = array(
+ 'title' => 'Issues',
+ 'no_blocks' => 0,
+ 'pipeline' => 'standard',
+ 'body_classes_to_remove' => '',
+ 'body_classes_to_add' => '',
+ 'css_id' => '',
+ 'css' => '',
+ 'contexts' => array(),
+ 'relationships' => array(
+ 0 => array(
+ 'identifier' => 'Display Tags',
+ 'keyword' => 'tags',
+ 'name' => 'terms_from_node',
+ 'vocabulary' => array(
+ 'rocketship_tags' => 'rocketship_tags',
+ ),
+ 'concatenator' => ',',
+ 'context' => 'argument_entity_id:node_1',
+ 'id' => 1,
+ ),
+ ),
+ 'access' => array(
+ 'plugins' => array(
+ 0 => array(
+ 'name' => 'entity_bundle:node',
+ 'settings' => array(
+ 'type' => array(
+ 'rocketship_focus' => 'rocketship_focus',
+ ),
+ ),
+ 'context' => 'argument_entity_id:node_1',
+ 'not' => FALSE,
+ ),
+ ),
+ 'logic' => 'and',
+ ),
+ );
+ $display = new panels_display();
+ $display->layout = 'rocketship';
+ $display->layout_settings = array();
+ $display->panel_settings = array(
+ 'style_settings' => array(
+ 'default' => NULL,
+ 'middle' => NULL,
+ 'left' => NULL,
+ 'right' => NULL,
+ 'top' => NULL,
+ 'bottom' => NULL,
+ 'upper_first' => NULL,
+ 'upper_middle' => NULL,
+ 'upper_last' => NULL,
+ 'lower_first' => NULL,
+ 'lower_middle' => NULL,
+ 'lower_last' => NULL,
+ ),
+ );
+ $display->cache = array();
+ $display->title = '%node:title';
+ $display->content = array();
+ $display->panels = array();
+ $pane = new stdClass();
+ $pane->pid = 'new-1';
+ $pane->panel = 'bottom';
+ $pane->type = 'rocketship_thanks';
+ $pane->subtype = 'rocketship_thanks';
+ $pane->shown = TRUE;
+ $pane->access = array();
+ $pane->configuration = array(
+ 'override_title' => 0,
+ 'override_title_text' => '',
+ );
+ $pane->cache = array();
+ $pane->style = array(
+ 'settings' => NULL,
+ );
+ $pane->css = array();
+ $pane->extras = array();
+ $pane->position = 0;
+ $pane->locks = array();
+ $display->content['new-1'] = $pane;
+ $display->panels['bottom'][0] = 'new-1';
+ $pane = new stdClass();
+ $pane->pid = 'new-2';
+ $pane->panel = 'lower_first';
+ $pane->type = 'views_panes';
+ $pane->subtype = 'issues-focus';
+ $pane->shown = TRUE;
+ $pane->access = array();
+ $pane->configuration = array(
+ 'exposed' => array(
+ 'rocketship_tags_tid' => 'patch (to be ported), 6.x-dev, 7.x-dev',
+ ),
+ 'context' => array(
+ 0 => 'relationship_terms_from_node_1',
+ ),
+ 'override_title' => 1,
+ 'override_title_text' => 'Backport',
+ );
+ $pane->cache = array();
+ $pane->style = array(
+ 'settings' => NULL,
+ 'style' => 'default',
+ );
+ $pane->css = array();
+ $pane->extras = array();
+ $pane->position = 0;
+ $pane->locks = array();
+ $display->content['new-2'] = $pane;
+ $display->panels['lower_first'][0] = 'new-2';
+ $pane = new stdClass();
+ $pane->pid = 'new-3';
+ $pane->panel = 'lower_last';
+ $pane->type = 'views_panes';
+ $pane->subtype = 'issues-focus';
+ $pane->shown = TRUE;
+ $pane->access = array();
+ $pane->configuration = array(
+ 'exposed' => array(
+ 'rocketship_tags_tid' => 'fixed, closed (duplicate), closed (won\'t fix), closed (works as designed), closed (cannot reproduce), closed (fixed)',
+ ),
+ 'context' => array(
+ 0 => 'relationship_terms_from_node_1',
+ ),
+ 'override_title' => 1,
+ 'override_title_text' => 'Closed',
+ );
+ $pane->cache = array();
+ $pane->style = array(
+ 'settings' => NULL,
+ 'style' => 'default',
+ );
+ $pane->css = array();
+ $pane->extras = array();
+ $pane->position = 0;
+ $pane->locks = array();
+ $display->content['new-3'] = $pane;
+ $display->panels['lower_last'][0] = 'new-3';
+ $pane = new stdClass();
+ $pane->pid = 'new-4';
+ $pane->panel = 'lower_middle';
+ $pane->type = 'views_panes';
+ $pane->subtype = 'issues-focus';
+ $pane->shown = TRUE;
+ $pane->access = array();
+ $pane->configuration = array(
+ 'exposed' => array(
+ 'rocketship_tags_tid' => 'postponed, postponed (maintainer needs more info)',
+ ),
+ 'context' => array(
+ 0 => 'relationship_terms_from_node_1',
+ ),
+ 'override_title' => 1,
+ 'override_title_text' => 'Postponed',
+ );
+ $pane->cache = array();
+ $pane->style = array(
+ 'settings' => NULL,
+ 'style' => 'default',
+ );
+ $pane->css = array();
+ $pane->extras = array();
+ $pane->position = 0;
+ $pane->locks = array();
+ $display->content['new-4'] = $pane;
+ $display->panels['lower_middle'][0] = 'new-4';
+ $pane = new stdClass();
+ $pane->pid = 'new-5';
+ $pane->panel = 'middle';
+ $pane->type = 'rocketship_legend';
+ $pane->subtype = 'rocketship_legend';
+ $pane->shown = TRUE;
+ $pane->access = array();
+ $pane->configuration = array(
+ 'override_title' => 0,
+ 'override_title_text' => '',
+ );
+ $pane->cache = array();
+ $pane->style = array(
+ 'settings' => NULL,
+ );
+ $pane->css = array();
+ $pane->extras = array();
+ $pane->position = 0;
+ $pane->locks = array();
+ $display->content['new-5'] = $pane;
+ $display->panels['middle'][0] = 'new-5';
+ $pane = new stdClass();
+ $pane->pid = 'new-6';
+ $pane->panel = 'middle';
+ $pane->type = 'rocketship_link';
+ $pane->subtype = 'rocketship_link';
+ $pane->shown = TRUE;
+ $pane->access = array();
+ $pane->configuration = array(
+ 'override_title' => 1,
+ 'override_title_text' => 'Other related issues',
+ 'context' => 'empty',
+ );
+ $pane->cache = array();
+ $pane->style = array(
+ 'settings' => NULL,
+ );
+ $pane->css = array();
+ $pane->extras = array();
+ $pane->position = 1;
+ $pane->locks = array();
+ $display->content['new-6'] = $pane;
+ $display->panels['middle'][1] = 'new-6';
+ $pane = new stdClass();
+ $pane->pid = 'new-7';
+ $pane->panel = 'top';
+ $pane->type = 'node_content';
+ $pane->subtype = 'node_content';
+ $pane->shown = TRUE;
+ $pane->access = array();
+ $pane->configuration = array(
+ 'links' => 1,
+ 'no_extras' => 1,
+ 'override_title' => 0,
+ 'override_title_text' => '',
+ 'identifier' => '',
+ 'link' => 0,
+ 'leave_node_title' => 0,
+ 'build_mode' => 'full',
+ 'context' => 'argument_entity_id:node_1',
+ );
+ $pane->cache = array();
+ $pane->style = array(
+ 'settings' => NULL,
+ );
+ $pane->css = array();
+ $pane->extras = array();
+ $pane->position = 0;
+ $pane->locks = array();
+ $display->content['new-7'] = $pane;
+ $display->panels['top'][0] = 'new-7';
+ $pane = new stdClass();
+ $pane->pid = 'new-8';
+ $pane->panel = 'top';
+ $pane->type = 'rocketship_legend';
+ $pane->subtype = 'rocketship_legend';
+ $pane->shown = TRUE;
+ $pane->access = array();
+ $pane->configuration = array(
+ 'override_title' => 0,
+ 'override_title_text' => '',
+ );
+ $pane->cache = array();
+ $pane->style = array(
+ 'settings' => NULL,
+ );
+ $pane->css = array();
+ $pane->extras = array();
+ $pane->position = 1;
+ $pane->locks = array();
+ $display->content['new-8'] = $pane;
+ $display->panels['top'][1] = 'new-8';
+ $pane = new stdClass();
+ $pane->pid = 'new-9';
+ $pane->panel = 'top';
+ $pane->type = 'rocketship_link';
+ $pane->subtype = 'rocketship_link';
+ $pane->shown = TRUE;
+ $pane->access = array();
+ $pane->configuration = array(
+ 'override_title' => 1,
+ 'override_title_text' => 'Currently in the works for Drupal 8',
+ 'context' => 'relationship_terms_from_node_1',
+ );
+ $pane->cache = array();
+ $pane->style = array(
+ 'settings' => NULL,
+ );
+ $pane->css = array();
+ $pane->extras = array();
+ $pane->position = 2;
+ $pane->locks = array();
+ $display->content['new-9'] = $pane;
+ $display->panels['top'][2] = 'new-9';
+ $pane = new stdClass();
+ $pane->pid = 'new-10';
+ $pane->panel = 'upper_first';
+ $pane->type = 'views_panes';
+ $pane->subtype = 'issues-focus';
+ $pane->shown = TRUE;
+ $pane->access = array();
+ $pane->configuration = array(
+ 'exposed' => array(
+ 'rocketship_tags_tid' => 'active, needs work',
+ ),
+ 'context' => array(
+ 0 => 'relationship_terms_from_node_1',
+ ),
+ 'override_title' => 1,
+ 'override_title_text' => 'To do',
+ );
+ $pane->cache = array();
+ $pane->style = array(
+ 'settings' => NULL,
+ 'style' => 'default',
+ );
+ $pane->css = array();
+ $pane->extras = array();
+ $pane->position = 0;
+ $pane->locks = array();
+ $display->content['new-10'] = $pane;
+ $display->panels['upper_first'][0] = 'new-10';
+ $pane = new stdClass();
+ $pane->pid = 'new-11';
+ $pane->panel = 'upper_last';
+ $pane->type = 'views_panes';
+ $pane->subtype = 'issues-focus';
+ $pane->shown = TRUE;
+ $pane->access = array();
+ $pane->configuration = array(
+ 'exposed' => array(
+ 'rocketship_tags_tid' => 'reviewed & tested by the community',
+ ),
+ 'context' => array(
+ 0 => 'relationship_terms_from_node_1',
+ ),
+ 'override_title' => 1,
+ 'override_title_text' => 'To be committed',
+ );
+ $pane->cache = array();
+ $pane->style = array(
+ 'settings' => NULL,
+ 'style' => 'default',
+ );
+ $pane->css = array();
+ $pane->extras = array();
+ $pane->position = 0;
+ $pane->locks = array();
+ $display->content['new-11'] = $pane;
+ $display->panels['upper_last'][0] = 'new-11';
+ $pane = new stdClass();
+ $pane->pid = 'new-12';
+ $pane->panel = 'upper_middle';
+ $pane->type = 'views_panes';
+ $pane->subtype = 'issues-focus';
+ $pane->shown = TRUE;
+ $pane->access = array();
+ $pane->configuration = array(
+ 'exposed' => array(
+ 'rocketship_tags_tid' => 'needs review',
+ ),
+ 'context' => array(
+ 0 => 'relationship_terms_from_node_1',
+ ),
+ 'override_title' => 1,
+ 'override_title_text' => 'To review',
+ );
+ $pane->cache = array();
+ $pane->style = array(
+ 'settings' => NULL,
+ 'style' => 'default',
+ );
+ $pane->css = array();
+ $pane->extras = array();
+ $pane->position = 0;
+ $pane->locks = array();
+ $display->content['new-12'] = $pane;
+ $display->panels['upper_middle'][0] = 'new-12';
+ $display->hide_title = PANELS_TITLE_NONE;
+ $display->title_pane = '0';
+ $handler->conf['display'] = $display;
+
+ $export['node_view_panel_context'] = $handler;
+
+ return $export;
+}
diff --git a/rocketship.views_default.inc b/rocketship.views_default.inc
new file mode 100644
index 0000000..60732bd
--- /dev/null
+++ b/rocketship.views_default.inc
@@ -0,0 +1,184 @@
+name = 'issues';
+ $view->description = '';
+ $view->tag = 'Rocketship';
+ $view->base_table = 'node';
+ $view->human_name = 'Issues';
+ $view->core = 7;
+ $view->api_version = '3.0';
+ $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */
+
+ /* Display: Master */
+ $handler = $view->new_display('default', 'Master', 'default');
+ $handler->display->display_options['use_more_always'] = FALSE;
+ $handler->display->display_options['access']['type'] = 'perm';
+ $handler->display->display_options['cache']['type'] = 'none';
+ $handler->display->display_options['query']['type'] = 'views_query';
+ $handler->display->display_options['exposed_form']['type'] = 'basic';
+ $handler->display->display_options['pager']['type'] = 'none';
+ $handler->display->display_options['pager']['options']['offset'] = '0';
+ $handler->display->display_options['style_plugin'] = 'default';
+ $handler->display->display_options['row_plugin'] = 'node';
+ $handler->display->display_options['row_options']['links'] = FALSE;
+ /* No results behavior: Global: Text area */
+ $handler->display->display_options['empty']['area']['id'] = 'area';
+ $handler->display->display_options['empty']['area']['table'] = 'views';
+ $handler->display->display_options['empty']['area']['field'] = 'area';
+ $handler->display->display_options['empty']['area']['empty'] = TRUE;
+ $handler->display->display_options['empty']['area']['content'] = '(None)';
+ $handler->display->display_options['empty']['area']['format'] = 'plain_text';
+ /* Field: Content: Title */
+ $handler->display->display_options['fields']['title']['id'] = 'title';
+ $handler->display->display_options['fields']['title']['table'] = 'node';
+ $handler->display->display_options['fields']['title']['field'] = 'title';
+ $handler->display->display_options['fields']['title']['label'] = '';
+ $handler->display->display_options['fields']['title']['alter']['word_boundary'] = FALSE;
+ $handler->display->display_options['fields']['title']['alter']['ellipsis'] = FALSE;
+ /* Sort criterion: Content: Priority (rocketship_priority) */
+ $handler->display->display_options['sorts']['rocketship_priority_value']['id'] = 'rocketship_priority_value';
+ $handler->display->display_options['sorts']['rocketship_priority_value']['table'] = 'field_data_rocketship_priority';
+ $handler->display->display_options['sorts']['rocketship_priority_value']['field'] = 'rocketship_priority_value';
+ /* Sort criterion: Content: Updated date */
+ $handler->display->display_options['sorts']['changed']['id'] = 'changed';
+ $handler->display->display_options['sorts']['changed']['table'] = 'node';
+ $handler->display->display_options['sorts']['changed']['field'] = 'changed';
+ $handler->display->display_options['sorts']['changed']['order'] = 'DESC';
+ /* Contextual filter: Content: Issue tags (rocketship_issue_tags) */
+ $handler->display->display_options['arguments']['rocketship_issue_tags_tid']['id'] = 'rocketship_issue_tags_tid';
+ $handler->display->display_options['arguments']['rocketship_issue_tags_tid']['table'] = 'field_data_rocketship_issue_tags';
+ $handler->display->display_options['arguments']['rocketship_issue_tags_tid']['field'] = 'rocketship_issue_tags_tid';
+ $handler->display->display_options['arguments']['rocketship_issue_tags_tid']['default_action'] = 'empty';
+ $handler->display->display_options['arguments']['rocketship_issue_tags_tid']['default_argument_type'] = 'fixed';
+ $handler->display->display_options['arguments']['rocketship_issue_tags_tid']['summary']['number_of_records'] = '0';
+ $handler->display->display_options['arguments']['rocketship_issue_tags_tid']['summary']['format'] = 'default_summary';
+ $handler->display->display_options['arguments']['rocketship_issue_tags_tid']['summary_options']['items_per_page'] = '25';
+ $handler->display->display_options['filter_groups']['operator'] = 'OR';
+ /* Filter criterion: Content: Type */
+ $handler->display->display_options['filters']['type']['id'] = 'type';
+ $handler->display->display_options['filters']['type']['table'] = 'node';
+ $handler->display->display_options['filters']['type']['field'] = 'type';
+ $handler->display->display_options['filters']['type']['value'] = array(
+ 'rocketship_issue' => 'rocketship_issue',
+ );
+ $handler->display->display_options['filters']['type']['group'] = 1;
+ /* Filter criterion: Content: Published */
+ $handler->display->display_options['filters']['status']['id'] = 'status';
+ $handler->display->display_options['filters']['status']['table'] = 'node';
+ $handler->display->display_options['filters']['status']['field'] = 'status';
+ $handler->display->display_options['filters']['status']['value'] = 1;
+ $handler->display->display_options['filters']['status']['group'] = 1;
+ $handler->display->display_options['filters']['status']['expose']['operator'] = FALSE;
+ /* Filter criterion: Content: Category tags (rocketship_category_tags) */
+ $handler->display->display_options['filters']['rocketship_category_tags_tid']['id'] = 'rocketship_category_tags_tid';
+ $handler->display->display_options['filters']['rocketship_category_tags_tid']['table'] = 'field_data_rocketship_category_tags';
+ $handler->display->display_options['filters']['rocketship_category_tags_tid']['field'] = 'rocketship_category_tags_tid';
+ $handler->display->display_options['filters']['rocketship_category_tags_tid']['value'] = '';
+ $handler->display->display_options['filters']['rocketship_category_tags_tid']['exposed'] = TRUE;
+ $handler->display->display_options['filters']['rocketship_category_tags_tid']['expose']['operator_id'] = 'rocketship_category_tags_tid_op';
+ $handler->display->display_options['filters']['rocketship_category_tags_tid']['expose']['label'] = 'Category tags (rocketship_category_tags)';
+ $handler->display->display_options['filters']['rocketship_category_tags_tid']['expose']['operator'] = 'rocketship_category_tags_tid_op';
+ $handler->display->display_options['filters']['rocketship_category_tags_tid']['expose']['identifier'] = 'rocketship_category_tags_tid';
+ $handler->display->display_options['filters']['rocketship_category_tags_tid']['expose']['multiple'] = TRUE;
+ $handler->display->display_options['filters']['rocketship_category_tags_tid']['expose']['remember_roles'] = array(
+ 2 => '2',
+ 1 => 0,
+ );
+ $handler->display->display_options['filters']['rocketship_category_tags_tid']['vocabulary'] = 'rocketship_category_tags';
+ /* Filter criterion: Content: Component tags (rocketship_component_tags) */
+ $handler->display->display_options['filters']['rocketship_component_tags_tid']['id'] = 'rocketship_component_tags_tid';
+ $handler->display->display_options['filters']['rocketship_component_tags_tid']['table'] = 'field_data_rocketship_component_tags';
+ $handler->display->display_options['filters']['rocketship_component_tags_tid']['field'] = 'rocketship_component_tags_tid';
+ $handler->display->display_options['filters']['rocketship_component_tags_tid']['value'] = '';
+ $handler->display->display_options['filters']['rocketship_component_tags_tid']['exposed'] = TRUE;
+ $handler->display->display_options['filters']['rocketship_component_tags_tid']['expose']['operator_id'] = 'rocketship_component_tags_tid_op';
+ $handler->display->display_options['filters']['rocketship_component_tags_tid']['expose']['label'] = 'Component tags (rocketship_component_tags)';
+ $handler->display->display_options['filters']['rocketship_component_tags_tid']['expose']['operator'] = 'rocketship_component_tags_tid_op';
+ $handler->display->display_options['filters']['rocketship_component_tags_tid']['expose']['identifier'] = 'rocketship_component_tags_tid';
+ $handler->display->display_options['filters']['rocketship_component_tags_tid']['expose']['multiple'] = TRUE;
+ $handler->display->display_options['filters']['rocketship_component_tags_tid']['expose']['remember_roles'] = array(
+ 2 => '2',
+ 1 => 0,
+ );
+ $handler->display->display_options['filters']['rocketship_component_tags_tid']['vocabulary'] = 'rocketship_component_tags';
+ /* Filter criterion: Content: Priority tags (rocketship_priority_tags) */
+ $handler->display->display_options['filters']['rocketship_priority_tags_tid']['id'] = 'rocketship_priority_tags_tid';
+ $handler->display->display_options['filters']['rocketship_priority_tags_tid']['table'] = 'field_data_rocketship_priority_tags';
+ $handler->display->display_options['filters']['rocketship_priority_tags_tid']['field'] = 'rocketship_priority_tags_tid';
+ $handler->display->display_options['filters']['rocketship_priority_tags_tid']['value'] = '';
+ $handler->display->display_options['filters']['rocketship_priority_tags_tid']['exposed'] = TRUE;
+ $handler->display->display_options['filters']['rocketship_priority_tags_tid']['expose']['operator_id'] = 'rocketship_priority_tags_tid_op';
+ $handler->display->display_options['filters']['rocketship_priority_tags_tid']['expose']['label'] = 'Priority tags (rocketship_priority_tags)';
+ $handler->display->display_options['filters']['rocketship_priority_tags_tid']['expose']['operator'] = 'rocketship_priority_tags_tid_op';
+ $handler->display->display_options['filters']['rocketship_priority_tags_tid']['expose']['identifier'] = 'rocketship_priority_tags_tid';
+ $handler->display->display_options['filters']['rocketship_priority_tags_tid']['expose']['multiple'] = TRUE;
+ $handler->display->display_options['filters']['rocketship_priority_tags_tid']['expose']['remember_roles'] = array(
+ 2 => '2',
+ 1 => 0,
+ );
+ $handler->display->display_options['filters']['rocketship_priority_tags_tid']['vocabulary'] = 'rocketship_priority_tags';
+ /* Filter criterion: Content: Status tags (rocketship_status_tags) */
+ $handler->display->display_options['filters']['rocketship_status_tags_tid']['id'] = 'rocketship_status_tags_tid';
+ $handler->display->display_options['filters']['rocketship_status_tags_tid']['table'] = 'field_data_rocketship_status_tags';
+ $handler->display->display_options['filters']['rocketship_status_tags_tid']['field'] = 'rocketship_status_tags_tid';
+ $handler->display->display_options['filters']['rocketship_status_tags_tid']['value'] = '';
+ $handler->display->display_options['filters']['rocketship_status_tags_tid']['exposed'] = TRUE;
+ $handler->display->display_options['filters']['rocketship_status_tags_tid']['expose']['operator_id'] = 'rocketship_status_tags_tid_op';
+ $handler->display->display_options['filters']['rocketship_status_tags_tid']['expose']['label'] = 'Status tags (rocketship_status_tags)';
+ $handler->display->display_options['filters']['rocketship_status_tags_tid']['expose']['operator'] = 'rocketship_status_tags_tid_op';
+ $handler->display->display_options['filters']['rocketship_status_tags_tid']['expose']['identifier'] = 'rocketship_status_tags_tid';
+ $handler->display->display_options['filters']['rocketship_status_tags_tid']['expose']['multiple'] = TRUE;
+ $handler->display->display_options['filters']['rocketship_status_tags_tid']['expose']['remember_roles'] = array(
+ 2 => '2',
+ 1 => 0,
+ );
+ $handler->display->display_options['filters']['rocketship_status_tags_tid']['vocabulary'] = 'rocketship_status_tags';
+ /* Filter criterion: Content: Version tags (rocketship_version_tags) */
+ $handler->display->display_options['filters']['rocketship_version_tags_tid']['id'] = 'rocketship_version_tags_tid';
+ $handler->display->display_options['filters']['rocketship_version_tags_tid']['table'] = 'field_data_rocketship_version_tags';
+ $handler->display->display_options['filters']['rocketship_version_tags_tid']['field'] = 'rocketship_version_tags_tid';
+ $handler->display->display_options['filters']['rocketship_version_tags_tid']['value'] = '';
+ $handler->display->display_options['filters']['rocketship_version_tags_tid']['exposed'] = TRUE;
+ $handler->display->display_options['filters']['rocketship_version_tags_tid']['expose']['operator_id'] = 'rocketship_version_tags_tid_op';
+ $handler->display->display_options['filters']['rocketship_version_tags_tid']['expose']['label'] = 'Version tags (rocketship_version_tags)';
+ $handler->display->display_options['filters']['rocketship_version_tags_tid']['expose']['operator'] = 'rocketship_version_tags_tid_op';
+ $handler->display->display_options['filters']['rocketship_version_tags_tid']['expose']['identifier'] = 'rocketship_version_tags_tid';
+ $handler->display->display_options['filters']['rocketship_version_tags_tid']['expose']['multiple'] = TRUE;
+ $handler->display->display_options['filters']['rocketship_version_tags_tid']['expose']['remember_roles'] = array(
+ 2 => '2',
+ 1 => 0,
+ );
+ $handler->display->display_options['filters']['rocketship_version_tags_tid']['vocabulary'] = 'rocketship_version_tags';
+
+ /* Display: Focus */
+ $handler = $view->new_display('panel_pane', 'Focus', 'focus');
+ $handler->display->display_options['pane_title'] = 'Taged Issues';
+ $handler->display->display_options['allow']['use_pager'] = 0;
+ $handler->display->display_options['allow']['items_per_page'] = 0;
+ $handler->display->display_options['allow']['offset'] = 0;
+ $handler->display->display_options['allow']['link_to_view'] = 0;
+ $handler->display->display_options['allow']['more_link'] = 0;
+ $handler->display->display_options['allow']['path_override'] = 0;
+ $handler->display->display_options['allow']['title_override'] = 'title_override';
+ $handler->display->display_options['allow']['exposed_form'] = 'exposed_form';
+ $handler->display->display_options['allow']['fields_override'] = 0;
+ $handler->display->display_options['argument_input'] = array(
+ 'rocketship_issue_tags_tid' => array(
+ 'type' => 'context',
+ 'context' => 'entity:taxonomy_term.tid',
+ 'context_optional' => 0,
+ 'panel' => '0',
+ 'fixed' => '',
+ 'label' => 'Content: Issue tags (rocketship_issue_tags)',
+ ),
+ );
+ $handler->display->display_options['inherit_panels_path'] = '0';
+ $views[$view->name] = $view;
+ return $views;
+}