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; +}