Index: project.module
===================================================================
--- project.module (revision 51)
+++ project.module (working copy)
@@ -423,10 +423,16 @@
*/
function project_init() {
drupal_add_css(drupal_get_path('module', 'project') .'/project.css');
+}
- if (module_exists('views')) {
- module_load_include ('inc', 'project', 'project.views');
- }
+/**
+ * Implementation of hook_views_api().
+ */
+function project_views_api() {
+ return array(
+ 'api' => 2,
+ 'path' => drupal_get_path('module', 'project') .'/views',
+ );
}
/**
@@ -881,4 +887,4 @@
if (!empty($form_state['values']['tags'])) {
form_set_error('tags', t('The %name vocabulary does not support tags.', array('%name' => $form_state['values']['name'])));
}
-}
\ No newline at end of file
+}
Index: views/project_views_handler_argument_term_node_tid_depth_project.inc
===================================================================
--- views/project_views_handler_argument_term_node_tid_depth_project.inc (revision 0)
+++ views/project_views_handler_argument_term_node_tid_depth_project.inc (revision 0)
@@ -0,0 +1,44 @@
+table . '.' . $this->field;
+ $join = $this->get_join();
+
+ if (!empty($this->options['require_value'])) {
+ $join->type = 'INNER';
+ }
+
+ if (empty($this->options['add_table']) || empty($this->view->many_to_one_tables[$field])) {
+ $this->table_alias = $this->query->ensure_table($this->table, $this->relationship, $join);
+ }
+ else {
+ $this->table_alias = $this->helper->summary_join();
+ }
+
+ // Add the field.
+ $this->base_alias = $this->query->add_field($this->table_alias, $this->real_field);
+
+ if (isset($this->argument) && is_numeric($this->argument)) {
+ // Add {term_hierarchy} table
+ $th_alias = $this->query->add_table('term_hierarchy');
+
+ // Limit returned results to terms whose parent is the argument.
+ $this->query->add_where(0, "$th_alias.parent = %d", $this->argument);
+ }
+
+ $this->summary_name_field();
+
+ return $this->summary_basics();
+ }
+
+ //function query() {
+ // $this->query->clear_fields();
+ //}
+}
Index: views/project_views_handler_filter_term_node_project_type_tid.inc
===================================================================
--- views/project_views_handler_filter_term_node_project_type_tid.inc (revision 0)
+++ views/project_views_handler_filter_term_node_project_type_tid.inc (revision 0)
@@ -0,0 +1,210 @@
+ 'select');
+
+ // Make this filter be exposed by default.
+ $options['exposed'] = array('default' => TRUE);
+
+ // Set the default vid to be the project type vid.
+ $vid = _project_get_vid();
+ if (!empty($vid)) {
+ $options['vid'] = array('default' => $vid);
+ }
+ else {
+ $options['vid'] = array('default' => 0);
+ }
+
+ // Allow user to specify which argument in the view this filter
+ // should interact with.
+ $options['associated_argument'] = array('default' => '');
+
+ // Allow user to specify that this filter should only be added
+ // if it has 1 or more options (not including All).
+ $options['remove_if_no_options'] = array('default' => 1);
+ return $options;
+ }
+
+ /**
+ * Provide the basic form which calls through to subforms.
+ * Since we want this filter to always be exposed, we have
+ * to override this function so we can prevent the expose/hide
+ * button from being built.
+ */
+ function options_form(&$form, &$form_state) {
+ $form['op_val_start'] = array('#value' => '
');
+ $this->show_operator_form($form, $form_state);
+ $this->show_value_form($form, $form_state);
+ $form['op_val_end'] = array('#value' => '
');
+ $this->show_expose_form($form, $form_state);
+ }
+
+ function extra_options_form(&$form, &$form_state) {
+ parent::extra_options_form($form, $form_state);
+
+ // Remove the 'Show hierarchy in dropdown' option.
+ unset($form['hierarchy']);
+
+ // Require the widget to be a select box.
+ $form['type']['#options'] = array('select' => t('Dropdown'));
+
+ // Remove 'markup_end' form element so we can first add in some
+ // additional options. We add it back in at the end of this function.
+ unset($form['markup_end']);
+
+ // Option to select which argument to process.
+ $arguments = $this->view->display_handler->get_option('arguments');
+ $argument_options = array();
+ $i = 0;
+ foreach ($arguments as $key => $value) {
+ //$argument_options[$key] = t('Argument !num (@name)', array('!num' => $i, '@name' => $key)); // @TODO: Fix this
+ $argument_options[$i] = t('Argument !num (@name)', array('!num' => $i, '@name' => $key));
+ $i++;
+ }
+ $form['associated_argument'] = array(
+ '#type' => 'select',
+ '#title' => t('Associated argument'),
+ '#description' => t('Select the argument this filter should be associated with. If you later change your argument(s) or their order, you must come back to these options and confirm that the correct argument is still selected.'),
+ '#options' => $argument_options,
+ '#default_value' => $this->options['associated_argument'],
+ );
+
+ // Allow this filter to be un-exposed if it contains no options.
+ $form['remove_if_no_options'] = array(
+ '#type' => 'checkbox',
+ '#title' => t('Remove filter if empty'),
+ '#description' => t('If checked, this filter will be removed from the view if the argument this filter is associated with is a term that has no child terms.'),
+ '#default_value' => !empty($this->options['remove_if_no_options']),
+ '#process' => array('views_process_dependency'),
+ '#dependency' => array('radio:options[type]' => array('select')),
+ );
+
+ $form['markup_end'] = array(
+ '#value' => '',
+ );
+ }
+
+ function value_form(&$form, &$form_state) {
+ parent::value_form($form, $form_state);
+ $vocabulary = taxonomy_vocabulary_load($this->options['vid']);
+ if (!$vocabulary) {
+ $form['markup'] = array(
+ '#prefix' => '',
+ '#suffix' => '
',
+ '#value' => t('An invalid vocabulary is selected. Please change it in the options.'),
+ );
+ return;
+ }
+
+ // At this point, we know that the argument is valid, because it's already
+ // been run through the validation handler. However, the first run through
+ // the validation handler is for the menu system to see if views wants to
+ // handle this partcular path, and after views tells the menu system that it
+ // should handle this path, the $view object is destroyed. So we can't store
+ // the processed argument (eg. the tid) in the $view object from within the
+ // argument handler, because it won't stay there.
+ $associated_argument = $this->options['associated_argument'];
+ $argument = isset($this->view->args[$associated_argument]) ? $this->view->args[$associated_argument] : NULL;
+ if (isset($argument)) {
+ // Build the term object of the term used as the argument. We don't
+ // actually need to join on the term_hierarchy table here, but we'll
+ // store the term object we get from these queries in the $view
+ // object so that when the argument validator function runs again, it can
+ // just use the stored objects instead of re-running it's own queries
+ // again.
+ if (is_numeric($argument)) {
+ $argument_term = db_fetch_object(db_query(db_rewrite_sql("SELECT td.tid, td.vid, td.name, td.description, td.weight, th.parent FROM {term_data} td LEFT JOIN {term_hierarchy} th ON th.tid = td.tid WHERE td.tid = %d", 'td', 'tid'), $argument));
+ }
+ else {
+ $argument_term = db_fetch_object(db_query(db_rewrite_sql("SELECT td.tid, td.vid, td.name, td.description, td.weight, th.parent FROM {term_data} td LEFT JOIN {term_synonym} ts ON ts.tid = td.tid LEFT JOIN {term_hierarchy} th ON th.tid = td.tid WHERE (td.name = '%s' OR ts.name = '%s') AND td.vid = %d", 'td', 'tid'), $argument, $argument, $this->options['vid']));
+ }
+
+ if ($argument_term) {
+ // Store the term object in the $view object for later use by other
+ // handlers.
+ $this->view->project->argument_term_objects[$associated_argument] = $argument_term;
+ }
+ else {
+ // The only way execution would get to this point is if the argument
+ // this filter handler is inspecting is not the argument that has
+ // been validated by the project type validator function.
+ // This function is expected to add something $form['value'], so we just
+ // make it a field of type value.
+ $this->options['exposed'] = FALSE;
+ $form['value'] = array(
+ '#type' => 'value',
+ );
+ $field = $this->field;
+ unset($this->view->filter->$field);
+ return;
+ }
+
+ // Currently this handler only supports using a select box for the project type terms.
+ if ($this->options['type'] == 'select') {
+ $options = array();
+ $result = db_query(db_rewrite_sql("SELECT * FROM {term_data} td INNER JOIN {term_hierarchy} th ON th.tid = td.tid WHERE th.parent = %d ORDER BY weight, name", 'td', 'tid'), $argument_term->tid);
+ while ($term = db_fetch_object($result)) {
+ $options[$term->tid] = $term->name;
+ }
+
+ // If there are no $options, that means that the term used in the argument
+ // has no child terms. If that's the case, we may want remove this
+ // filter from the current view.
+ if (count($options) < 1 && !empty($this->options['remove_if_no_options'])) {
+ $this->options['exposed'] = FALSE;
+ $form['value'] = array(
+ '#type' => 'value',
+ );
+ $field = $this->field;
+ unset($this->view->filter->$field);
+ return;
+ }
+
+ // Since we're overriding, allow the list of options to be reduced.
+ if (!empty($form_state['exposed']) && !empty($this->options['expose']['reduce'])) {
+ $options = $this->reduce_value_options($options);
+ }
+
+ $form['value'] = array(
+ '#type' => 'select',
+ '#title' => t('Select terms from vocabulary @voc', array('@voc' => $vocabulary->name)),
+ '#multiple' => TRUE,
+ '#options' => $options,
+ '#size' => min(9, count($options)),
+ '#default_value' => !empty($this->value) ? $this->value : array(),
+ );
+ }
+
+ if (empty($form_state['exposed'])) {
+ // Retain the helper option
+ $this->helper->options_form($form, $form_state);
+ }
+ return;
+ }
+
+ // Execution will only get to this point if the argument wasn't found. This
+ // can happen when the filter's settings are being edited in the Views UI,
+ // and can also happen if the user selected a value for $argument_position
+ // that is invalid. In either case we have to add something to $form['value'].
+ // In addition, if we're in a view that's being executed, we need to
+ // un-expose this particular filter and also remove it from the view.
+ if (!empty($this->view->args)) {
+ $this->options['exposed'] = FALSE;
+ $field = $this->field;
+ unset($this->view->filter->$field);
+ }
+ $form['value'] = array(
+ '#type' => 'value',
+ );
+ }
+}
Index: views/project_views_plugin_argument_validate_project_type_term.inc
===================================================================
--- views/project_views_plugin_argument_validate_project_type_term.inc (revision 0)
+++ views/project_views_plugin_argument_validate_project_type_term.inc (revision 0)
@@ -0,0 +1,168 @@
+ 'checkboxes',
+ '#prefix' => '',
+ '#suffix' => '
',
+ '#title' => t('Vocabularies'),
+ '#options' => _project_views_plugin_argument_validate_project_vocabulary(),
+ '#default_value' => isset($this->argument->options['validate_argument_project_term_vocabulary']) ? $this->argument->options['validate_argument_project_term_vocabulary'] : array(),
+ '#description' => t('If you wish to validate for specific vocabularies, check them; if none are checked, all arguments will fail validation.'),
+ '#process' => array('expand_checkboxes', 'views_process_dependency'),
+ '#dependency' => array('edit-options-validate-type' => array($this->id)),
+ );
+
+ // Argument type
+ $form['validate_argument_project_term_argument_type'] = array(
+ '#type' => 'select',
+ '#title' => t('Argument type'),
+ '#options' => array(
+ 'tid' => t('Term ID'),
+ 'name' => t('Term name or synonym'),
+ 'convert' => t('Term name/synonym converted to Term ID'),
+ ),
+ '#default_value' => isset($this->argument->options['validate_argument_project_term_argument_type']) ? $this->argument->options['validate_argument_project_term_argument_type'] : 'tid',
+ '#description' => t('Select the form of this argument; if using term name, it is generally more efficient to convert it to a term ID and use Taxonomy: Term ID rather than Taxonomy: Term Name" as an argument.'),
+ '#process' => array('views_process_dependency'),
+ '#dependency' => array('edit-options-validate-type' => array($this->id)),
+ );
+
+ // @TODO: Project term actions fieldset/grouping?
+
+ $project_term_actions = array(
+ 'pass' => t('Pass validation'),
+ 'fail_delete_argument' => t('Fail validation and delete argument'),
+ 'fail' => t('Fail validation'),
+ );
+ // Top level term without children
+ $form['validate_argument_project_term_argument_action_top_without'] = array(
+ '#type' => 'select',
+ '#title' => t('Term is a top level term without children'),
+ '#options' => $project_term_actions,
+ '#default_value' => isset($this->argument->options['validate_argument_project_term_argument_action_top_without']) ? $this->argument->options['validate_argument_project_term_argument_action_top_without'] : 'pass',
+ '#description' => t('Terms that are top level project type terms but which have no child terms will be handled as selected here.'),
+ '#process' => array('views_process_dependency'),
+ '#dependency' => array('edit-options-validate-type' => array($this->id)),
+ );
+
+ // Top level term with children
+ $form['validate_argument_project_term_argument_action_top_with'] = array(
+ '#type' => 'select',
+ '#title' => t('Term is a top level term with children'),
+ '#options' => $project_term_actions,
+ '#default_value' => isset($this->argument->options['validate_argument_project_term_argument_action_top_with']) ? $this->argument->options['validate_argument_project_term_argument_action_top_with'] : 'pass',
+ '#description' => t('Terms that are top level project type terms but which do have child terms will be handled as selected here.'),
+ '#process' => array('views_process_dependency'),
+ '#dependency' => array('edit-options-validate-type' => array($this->id)),
+ );
+
+ // Child term
+ $form['validate_argument_project_term_argument_action_child'] = array(
+ '#type' => 'select',
+ '#title' => t('Term is a child of another term'),
+ '#options' => $project_term_actions,
+ '#default_value' => isset($this->argument->options['validate_argument_project_term_argument_action_child']) ? $this->argument->options['validate_argument_project_term_argument_action_child'] : 'pass',
+ '#description' => t('Terms that are not top level project type terms will be handled as selected here.'),
+ '#process' => array('views_process_dependency'),
+ '#dependency' => array('edit-options-validate-type' => array($this->id)),
+ );
+ }
+
+ function validate_argument($argument) {
+ $vids = isset($this->argument->options['validate_argument_project_term_vocabulary']) ? array_filter($this->argument->options['validate_argument_project_term_vocabulary']) : array();
+ $type = isset($this->argument->options['validate_argument_project_term_argument_type']) ? $this->argument->options['validate_argument_project_term_argument_type'] : 'tid';
+ $action_top_without = isset($this->argument->options['validate_argument_project_term_argument_action_top_without']) ? $this->argument->options['validate_argument_project_term_argument_action_top_without'] : 'pass';
+ $action_top_with = isset($this->argument->options['validate_argument_project_term_argument_action_top_with']) ? $this->argument->options['validate_argument_project_term_argument_action_top_with'] : 'pass';
+ $action_child = isset($this->argument->options['validate_argument_project_term_argument_action_child']) ? $this->argument->options['validate_argument_project_term_argument_action_child'] : 'pass';
+
+ // If no vocabularies were selected in the options form, we can fail right away.
+ if (empty($vids)) {
+ return FALSE;
+ }
+
+ // First we check to determine whether the argument is a term in the project type vocabulary.
+ // If not, we know the argument won't validate, and we can return FALSE. The other added benefit
+ // is that in the switch statement below we ensure that we have the actual term ID of the argument,
+ // which makes the subsequent query easier to write and faster.
+ switch ($type) {
+ case 'tid':
+ if (!is_numeric($argument)) {
+ return FALSE;
+ }
+ $result = db_fetch_object(db_query(db_rewrite_sql("SELECT td.tid, td.vid, td.name, td.description, td.weight, th.parent FROM {term_data} td LEFT JOIN {term_hierarchy} th ON th.tid = td.tid WHERE td.tid = %d", 'td', 'tid'), $argument));
+ if (!$result) {
+ return FALSE;
+ }
+ elseif (empty($vids[$result->vid])) {
+ return FALSE;
+ }
+ break;
+
+ case 'name':
+ case 'convert':
+ $query_args = array($argument, $argument);
+ $query_args = array_merge($query_args, $vids);
+ $result = db_fetch_object(db_query(db_rewrite_sql("SELECT td.tid, td.vid, td.name, td.description, td.weight, th.parent FROM {term_data} td LEFT JOIN {term_synonym} ts ON ts.tid = td.tid LEFT JOIN {term_hierarchy} th ON th.tid = td.tid WHERE (td.name = '%s' OR ts.name = '%s') AND td.vid IN(" . db_placeholders($vids) . ")", 'td', 'tid'), $query_args));
+ if (!$result) {
+ return FALSE;
+ }
+
+ if ($type == 'convert') {
+ $this->argument->argument = $result->tid;
+ }
+ break;
+ }
+
+ if ($result->parent == 0) {
+ // This term is a top level term.
+ // Before we know what to do, we need to determine if this term
+ // has any child terms or not.
+ $has_children = db_result(db_query("SELECT COUNT(*) FROM {term_hierarchy} WHERE parent = %d", $result->tid));
+ if ($has_children) {
+ $action = $action_top_with;
+ }
+ else {
+ $action = $action_top_without;
+ }
+ }
+ else {
+ // This term is a child term.
+ $action = $action_child;
+ }
+
+ switch ($action) {
+ case 'pass':
+ return TRUE;
+ case 'fail_delete_argument':
+ $this->argument->options['validate_fail'] = $this->argument->options['default_action'];
+ return FALSE;
+ case 'fail':
+ return FALSE;
+ }
+ }
+}
+
+/**
+ * Return an array containing the project type vocabulary
+ * formatted to be used in the argument validator options form.
+ */
+function _project_views_plugin_argument_validate_project_vocabulary() {
+ $vid = _project_get_vid();
+ if (!empty($vid)) {
+ $vocabulary = taxonomy_vocabulary_load($vid);
+ }
+
+ $options = array();
+ if (!empty($vocabulary)) {
+ $options[$vocabulary->vid] = $vocabulary->name;
+ }
+ return $options;
+}
Index: views/project_views_plugin_row_project_node_view.inc
===================================================================
--- views/project_views_plugin_row_project_node_view.inc (revision 0)
+++ views/project_views_plugin_row_project_node_view.inc (revision 0)
@@ -0,0 +1,75 @@
+ TRUE);
+ if (module_exists('taxonomy')) {
+ $options['project_term_links'] = array('default' => TRUE);
+ }
+ if (module_exists('project_release')) {
+ $options['project_release_download_table'] = array('default' => TRUE);
+ $options['project_release_download_link'] = array('default' => TRUE);
+ }
+ if (module_exists('project_issue')) {
+ $options['project_issue_issues_link'] = array('default' => TRUE);
+ }
+ return $options;
+ }
+
+ function options_form(&$form, &$form_state) {
+ $form['project_teaser'] = array(
+ '#type' => 'checkbox',
+ '#title' => t('Display only teaser instead of the full node'),
+ '#default_value' => $this->options['project_teaser'],
+ );
+
+ if (module_exists('taxonomy')) {
+ $form['project_term_links'] = array(
+ '#type' => 'checkbox',
+ '#title' => t('Display project type term links'),
+ '#default_value' => $this->options['project_term_links'],
+ );
+ }
+ if (module_exists('project_release')) {
+ $form['project_release_download_table'] = array(
+ '#type' => 'checkbox',
+ '#title' => t('Display the release download table'),
+ '#default_value' => $this->options['project_release_download_table'],
+ );
+ $form['project_release_download_link'] = array(
+ '#type' => 'checkbox',
+ '#title' => t('Display a link to a file download when the version filter is in use'),
+ '#default_value' => $this->options['project_release_download_link'],
+ );
+ }
+ if (module_exists('project_issue')) {
+ $form['project_issue_issues_link'] = array(
+ '#type' => 'checkbox',
+ '#title' => t('Display a link to issues for the project'),
+ '#default_value' => $this->options['project_issue_issues_link'],
+ );
+ }
+ }
+
+ /**
+ * Determine what project type is being viewed and store it
+ * for use later on in the rendering process.
+ *
+ * @param $result
+ * The full array of results from the query.
+ */
+ function pre_render($result) {
+ if (!isset($this->view->project->project_type) && isset($this->view->args[0])) {
+ $this->view->project->project_type = _project_views_get_project_type($this->view->args[0]);
+ }
+ }
+}
+
Index: views/project_views_handler_filter_project_type_vid.inc
===================================================================
--- views/project_views_handler_filter_project_type_vid.inc (revision 0)
+++ views/project_views_handler_filter_project_type_vid.inc (revision 0)
@@ -0,0 +1,141 @@
+include = $options['include'];
+ }
+
+ function construct() {
+ parent::construct();
+ $this->include_title = t('Include terms from');
+ $this->include_options = NULL;
+ }
+
+ function option_definition() {
+ $options = parent::option_definition();
+ $options['include'] = array('default' =>array());
+ return $options;
+ }
+
+ function get_value_options() {
+ if (isset($this->value_options)) {
+ return;
+ }
+
+ $this->value_options = array();
+ $vid = _project_get_vid();
+ if (!empty($vid)) {
+ $vocabulary = taxonomy_vocabulary_load($vid);
+ $this->value_options[$vid] = $vocabulary->name;
+ }
+ }
+
+ function options_form(&$form, &$form_state) {
+ parent::options_form($form, $form_state);
+ $this->show_include_form($form, $form_state);
+ }
+
+ function options_submit(&$form, &$form_state) {
+ parent::options_submit($form, $form_state);
+ $this->include_submit($form, $form_state);
+ }
+
+ /**
+ * Shortcut to display the operator form.
+ */
+ function show_include_form(&$form, &$form_state) {
+ $this->include_form($form, $form_state);
+ }
+
+ /**
+ * Provide only inclusive matching.
+ */
+ function operator_options() {
+ return array(
+ 'in' => t('Is one of'),
+ );
+ }
+
+ /**
+ * Provide only inclusive matching.
+ */
+ function include_options() {
+ return array(
+ 'top_level' => t('Top level'),
+ 'children' => t('Child'),
+ );
+ }
+
+ function include_form(&$form, &$form_state) {
+ $options = $this->include_options();
+
+ $form['include'] = array(
+ '#type' => $this->include_form_type,
+ '#title' => $this->include_title,
+ '#options' => $options,
+ '#default_value' => (array) $this->include,
+ // These are only valid for 'select' type, but do no harm to checkboxes.
+ '#multiple' => TRUE,
+ '#size' => count($this->include_options) > 8 ? 8 : $this->include_options,
+ );
+ }
+
+ function include_submit($form, &$form_state) {
+ $form_state['values']['options']['include'] = array_filter($form_state['values']['options']['include']);
+ }
+
+ function admin_summary() {
+ $summary = parent::admin_summary();
+ $this->include_options = $this->include_options();
+ if (count($this->include) > 0) {
+ $summary .= t('(including');
+ foreach($this->include as $key => $value) {
+ $summary .= ' ' . $this->include_options[$key] . ',';
+ }
+ // Remove the trailing comma.
+ $summary = rtrim($summary, ',');
+ $summary .= t(' terms)');
+ }
+ return $summary;
+ }
+
+ /**
+ * Override $this->query() so we can limit to top level and/or child terms.
+ */
+ function query() {
+ // If neither top level nor child terms should be displayed, then don't modify the query.
+ if (empty($this->include)) {
+ return;
+ }
+
+ // Allow the parent method to set the query.
+ parent::query();
+
+ // If both top level and children terms should be displayed, then we don't need
+ // to limit the query any further.
+ if (isset($this->include['top_level']) && isset($this->include['children'])) {
+ return;
+ }
+
+ if (isset($this->include['top_level'])) {
+ // Include only top level terms by adding node_hierarchy.parent = 0 to WHERE clause.
+ $operator = '=';
+ }
+ else {
+ // Include only children terms by adding node_hierarchy.parent <> 0 to WHERE clause.
+ $operator = '<>';
+ }
+ $term_hierarchy_alias = $this->query->add_table('term_hierarchy');
+ $this->query->add_where($this->options['group'], "$term_hierarchy_alias.parent $operator %d", 0);
+ }
+}
Index: views/project_views_plugin_row_project_fields_view.inc
===================================================================
--- views/project_views_plugin_row_project_fields_view.inc (revision 0)
+++ views/project_views_plugin_row_project_fields_view.inc (revision 0)
@@ -0,0 +1,5 @@
+ array(
+ 'path' => drupal_get_path('module', 'project') .'/includes',
+ ),
+ 'handlers' => array(
+ 'project_views_handler_argument_term_node_tid_depth_project' => array(
+ 'parent' => 'views_handler_argument_term_node_tid',
+ ),
+ 'project_views_handler_field_term_node_project_type_tid' => array(
+ 'parent' => 'views_handler_field_term_node_tid',
+ ),
+ 'project_views_handler_filter_project_sort_method' => array(
+ 'parent' => 'views_handler_filter',
+ ),
+ 'project_views_handler_filter_project_type_vid' => array(
+ 'parent' => 'views_handler_filter_in_operator',
+ ),
+ 'project_views_handler_filter_project_type_vid' => array(
+ 'parent' => 'views_handler_filter_in_operator',
+ ),
+ 'project_views_handler_filter_term_node_project_type_tid' => array(
+ 'parent' => 'views_handler_filter_term_node_tid',
+ ),
+ ),
+ );
+}
+
+/**
+ * Implementation of hook_views_data().
+ *
+ * Exposes all fields to the views system.
+ */
+function project_views_data() {
+ $data = array();
+ // ----------------------------------------------------------------
+ // project_projectss table
+
+ // Define the base group of this table. Fields that don't
+ // have a group defined will go into this field by default.
+ $data['project_projects']['table']['group'] = t('Project');
+
+ $data['project_projects']['table']['join'] = array(
+ 'node' => array(
+ 'left_field' => 'nid',
+ 'field' => 'nid',
+ ),
+ );
+
+ // uri
+ $data['project_projects']['uri'] = array(
+ 'title' => t('Short name'),
+ 'help' => t('The short name (uri) of a project.'),
+ 'field' => array(
+ 'group' => t('Project'),
+ 'handler' => 'views_handler_field_node',
+ 'click sortable' => TRUE,
+ ),
+ 'sort' => array(
+ 'handler' => 'views_handler_sort',
+ ),
+ 'filter' => array(
+ 'handler' => 'views_handler_filter_string',
+ ),
+ 'argument' => array(
+ 'handler' => 'views_handler_argument_string',
+ ),
+ );
+
+ // homepage
+ $data['project_projects']['homepage'] = array(
+ 'title' => t('Homepage'),
+ 'help' => t("The project's homepage."),
+ 'field' => array(
+ 'group' => t('Project'),
+ 'handler' => 'views_handler_field_url',
+ 'click sortable' => TRUE,
+ ),
+ 'sort' => array(
+ 'handler' => 'views_handler_sort',
+ ),
+ 'filter' => array(
+ 'handler' => 'views_handler_filter_string',
+ ),
+ 'argument' => array(
+ 'handler' => 'views_handler_argument_string',
+ ),
+ );
+
+ // changelog
+ $data['project_projects']['changelog'] = array(
+ 'title' => t('Changelog'),
+ 'help' => t("The project's changelog."),
+ 'field' => array(
+ 'group' => t('Project'),
+ 'handler' => 'views_handler_field_url',
+ 'click sortable' => TRUE,
+ ),
+ 'sort' => array(
+ 'handler' => 'views_handler_sort',
+ ),
+ 'filter' => array(
+ 'handler' => 'views_handler_filter_string',
+ ),
+ 'argument' => array(
+ 'handler' => 'views_handler_argument_string',
+ ),
+ );
+
+ // cvs
+ $data['project_projects']['cvs'] = array(
+ 'title' => t('CVS directory'),
+ 'help' => t("The project's cvs directory."),
+ 'field' => array(
+ 'group' => t('Project'),
+ //'handler' => 'views_handler_field_node',
+ 'click sortable' => TRUE,
+ ),
+ 'sort' => array(
+ 'handler' => 'views_handler_sort',
+ ),
+ 'filter' => array(
+ 'handler' => 'views_handler_filter_string',
+ ),
+ 'argument' => array(
+ 'handler' => 'views_handler_argument_string',
+ ),
+ );
+
+ // demo
+ $data['project_projects']['demo'] = array(
+ 'title' => t('Demonstration'),
+ 'help' => t('Link to a demonstration of the project.'),
+ 'field' => array(
+ 'group' => t('Project'),
+ 'handler' => 'views_handler_field_url',
+ 'click sortable' => TRUE,
+ ),
+ 'sort' => array(
+ 'handler' => 'views_handler_sort',
+ ),
+ 'filter' => array(
+ 'handler' => 'views_handler_filter_string',
+ ),
+ 'argument' => array(
+ 'handler' => 'views_handler_argument_string',
+ ),
+ );
+
+ // documentation
+ $data['project_projects']['documentation'] = array(
+ 'title' => t('Documentation'),
+ 'help' => t("The project's documentation."),
+ 'field' => array(
+ 'group' => t('Project'),
+ 'handler' => 'views_handler_field_url',
+ 'click sortable' => TRUE,
+ ),
+ 'sort' => array(
+ 'handler' => 'views_handler_sort',
+ ),
+ 'filter' => array(
+ 'handler' => 'views_handler_filter_string',
+ ),
+ 'argument' => array(
+ 'handler' => 'views_handler_argument_string',
+ ),
+ );
+
+ // screenshots
+ $data['project_projects']['screenshots'] = array(
+ 'title' => t('Screenshots'),
+ 'help' => t("The project's screenshots."),
+ 'field' => array(
+ 'group' => t('Project'),
+ 'handler' => 'views_handler_field_url',
+ 'click sortable' => TRUE,
+ ),
+ 'sort' => array(
+ 'handler' => 'views_handler_sort',
+ ),
+ 'filter' => array(
+ 'handler' => 'views_handler_filter_string',
+ ),
+ 'argument' => array(
+ 'handler' => 'views_handler_argument_string',
+ ),
+ );
+
+ // license
+ $data['project_projects']['license'] = array(
+ 'title' => t('License'),
+ 'help' => t('The license used for the project.'),
+ 'field' => array(
+ 'group' => t('Project'),
+ 'handler' => 'views_handler_field_url',
+ 'click sortable' => TRUE,
+ ),
+ 'sort' => array(
+ 'handler' => 'views_handler_sort',
+ ),
+ 'filter' => array(
+ 'handler' => 'views_handler_filter_string',
+ ),
+ 'argument' => array(
+ 'handler' => 'views_handler_argument_string',
+ ),
+ );
+
+ return $data;
+}
+
+/**
+ * Implementation of hook_views_data_alter().
+ */
+function project_views_data_alter(&$data) {
+ // @TODO: Rewrite the help and title to be more descriptive?
+ $data['term_node']['term_node_tid_depth_project'] = array(
+ 'group' => t('Taxonomy'),
+ 'title' => t('Term ID (summary)'),
+ 'help' => t('This argument produces a summary with the option to exclude top level terms.'),
+ 'real field' => 'tid',
+ 'argument' => array(
+ 'handler' => 'project_views_handler_argument_term_node_tid_depth_project',
+ 'name table' => 'term_data',
+ 'name field' => 'name',
+ 'empty name field' => t('Uncategorized'),
+ 'numeric' => TRUE,
+ ),
+ );
+
+ // Add a Project type vocabulary filter that makes it possible to include
+ // only the top level terms or child terms in the project types vocabulary.
+ $data['term_data']['project_type'] = array(
+ 'title' => t('Project type depth'),
+ 'help' => t('Limit the results to project type terms that are either parents or children, or both.'),
+ 'filter' => array(
+ 'field' => 'vid',
+ 'handler' => 'project_views_handler_filter_project_type_vid',
+ ),
+ );
+
+ // tid field (based on {term_node}.tid field in taxonomy.views.inc).
+ $data['term_node']['project_type_tid'] = array(
+ 'group' => t('Project'),
+ 'title' => t('Project type term'),
+ 'real field' => 'tid',
+ 'field' => array(
+ 'title' => t('Project type terms'),
+ 'help' => t('The project type terms associated with a node.'),
+ 'handler' => 'project_views_handler_field_term_node_project_type_tid',
+ ),
+ 'filter' => array(
+ 'help' => t('Filter by the project type term.'),
+ 'handler' => 'project_views_handler_filter_term_node_project_type_tid',
+ 'hierarchy table' => 'term_hierarchy',
+ 'numeric' => TRUE,
+ ),
+ );
+
+ // Project sorting method filter. This is a bit of a hack until Views
+ // supports exposed sorting.
+ $data['views']['project_sort_method'] = array(
+ 'group' => t('Project'),
+ 'title' => t('Sort method'),
+ 'help' => t('This is a filter that provides a sort method select box that can be exposed to the user.'),
+ 'filter' => array(
+ 'handler' => 'project_views_handler_filter_project_sort_method',
+ ),
+ );
+}
+
+/**
+ * Implementation of hook_views_plugins().
+ */
+function project_views_plugins() {
+ return array(
+ 'module' => 'project',
+ 'style' => array(
+ 'project_list' => array(
+ 'title' => t('Project list'),
+ 'help' => t('Displays a list of project rows with additional project related information.'),
+ 'handler' => 'project_views_plugin_style_project_list',
+ 'theme' => 'project_views_view_project_list',
+ 'uses row plugin' => TRUE,
+ 'uses options' => TRUE,
+ 'uses fields' => TRUE,
+ 'uses grouping' => TRUE,
+ 'type' => 'normal',
+ ),
+ 'collapsible_summary' => array(
+ 'title' => t('Collapsible'),
+ 'help' => t('Displays the summary in a collapsible fieldset'),
+ 'handler' => 'views_plugin_style_summary',
+ 'theme' => 'project_views_view_collapsible_summary',
+ 'type' => 'summary', // only shows up as a summary style
+ 'uses options' => TRUE,
+ ),
+ ),
+ 'row' => array(
+ 'project_node' => array(
+ 'title' => t('Project node'),
+ 'help' => t('Display the project node with download table.'),
+ 'handler' => 'project_views_plugin_row_project_node_view',
+ 'theme' => 'project_views_view_row_project_node',
+ 'base' => array('node'), // only works with 'node' as base.
+ 'uses options' => TRUE,
+ 'type' => 'normal',
+ ),
+ 'project_fields' => array( // Project row style for fields.
+ 'title' => t('Project fields'),
+ 'help' => t('Displays project fields.'),
+ 'handler' => 'project_views_plugin_row_project_fields_view',
+ 'theme' => 'project_views_view_row_project_fields',
+ 'uses fields' => TRUE,
+ 'uses options' => TRUE,
+ 'type' => 'normal',
+ ),
+ ),
+ 'argument validator' => array(
+ 'project_term_top_level' => array(
+ 'title' => t('Project type: Top level term'),
+ 'handler' => 'project_views_plugin_argument_validate_project_term_top_level',
+ ),
+ 'project_type_term' => array(
+ 'title' => t('Project type term'),
+ 'handler' => 'project_views_plugin_argument_validate_project_type_term',
+ ),
+ ),
+ );
+}
+
+/**
+ * Template helper for theme_project_views_view_row_project_node
+ */
+function template_preprocess_project_views_view_row_project_node(&$vars) {
+ $options = $vars['options'];
+ $vars['node'] = ''; // make sure var is defined.
+ $nid = $vars['row']->nid;
+ if (!is_numeric($nid)) {
+ return;
+ }
+
+ $node = node_load($nid);
+ $node->view = $vars['view'];
+
+ if (empty($node)) {
+ return;
+ }
+
+ $id = $vars['id'];
+ $vars['project']->class = ($id % 2) ? 'odd' : 'even';
+
+ // Build the term links for the project.
+ if (module_exists('taxonomy') && !empty($options['project_term_links'])) {
+ if (!empty($vars['view']->project->project_type)) {
+ // Hide the top-level project type term from the links.
+ unset($node->taxonomy[$vars['view']->project->project_type->tid]);
+ }
+ $vars['project']->terms = theme('links', taxonomy_link('taxonomy terms', $node));
+ }
+
+ // Because $vars['id'] is one based but $vars['view']>result-># is zero based, subtract
+ // one from $vars['id'] to get the corresponding index into $vars['view']->result.
+ $result_id = $id - 1;
+
+ $vars['project']->title = l($node->title, "project/$node->uri");
+ $vars['project']->new_date = isset($vars['view']->project->project_new_date[$result_id]) ? $node->changed : FALSE;
+ $vars['project']->changed = t('Last changed: !interval ago', array('!interval' => format_interval(time() - $node->changed, 2)));
+ $vars['project']->body = check_markup($options['project_teaser'] ? $node->teaser : $node->body, $node->format, FALSE);
+ if (!empty($options['project_release_download_table'])) {
+ $vars['project_release']->download_table = $project->download_table = theme('project_release_table_overview', $node, 'recommended', 'all', t('Version'), FALSE);
+ }
+
+ // Link to a downloadable file.
+ if (!empty($options['project_release_download_link'])) {
+// @TODO: Given the potential for confusion with multiple supported versions, I think it might
+// be best to not display a download link at all on the project overview page.
+// if ($node->file_path) {
+// $vars['project_release']->download_link = theme('project_release_download_link', $node->file_path, t('Download'), 'array');
+// }
+ }
+
+ // Link to the project's issue queue.
+ if (!empty($options['project_issue_issues_link'])) {
+ if (isset($node->issues)) {
+ $vars['project_issue']->issues_link = array(
+ 'title' => t('Bugs and feature requests'),
+ 'href' => "project/issues/$node->uri",
+ );
+ }
+ }
+}
+
+/**
+ * Preprocess theme function that is used for the project list style.
+ */
+function template_preprocess_project_views_view_project_list(&$vars) {
+ $view = $vars['view'];
+
+ // Sanitize all of the project type term information before placing
+ // the values into $vars.
+ if (!empty($view->project->project_type)) {
+ $term = $view->project->project_type;
+ $vars['project']['arguments'][0] = array(
+ 'tid' => $term->tid,
+ 'vid' => $term->vid,
+ 'name' => check_plain($term->name),
+ 'description' => filter_xss_admin($term->description),
+ 'weight' => $term->weight,
+ );
+ }
+}
+
+/**
+ * Provides the term object for the project type used
+ * as an argument.
+ *
+ * @param $argument
+ * This should be the value of the argument used to indicate
+ * what project type is being browsed. This will usually be
+ * the first argument. The value can be either the tid or the
+ * name of the term.
+ *
+ * @return
+ * The term object or NULL if none could be found.
+ */
+function _project_views_get_project_type($argument = NULL) {
+ if (module_exists('taxonomy')) {
+ if (is_numeric($argument)) {
+ $term = taxonomy_get_term($argument);
+ }
+ else {
+ $project_vid = _project_get_vid();
+ $term = db_fetch_object(db_query(db_rewrite_sql("SELECT t.tid, t.* FROM {term_data} t INNER JOIN {term_hierarchy} th ON t.tid = th.tid WHERE t.vid = %d AND th.parent = %d AND t.name = '%s'", 't', 'tid'), $project_vid, 0, $argument));
+ }
+ return $term;
+ }
+}
+
+/**
+ * Preprocess theme function that is used for the collapsible summary style.
+ */
+function template_preprocess_project_views_view_collapsible_summary(&$vars) {
+ $view = $vars['view'];
+ $argument = $view->argument[$view->build_info['summary_level']];
+
+ $url_options = array();
+ $terms = array();
+
+ if (!empty($view->exposed_raw_input)) {
+ $url_options['query'] = $view->exposed_raw_input;
+ }
+
+ $children = array();
+
+ foreach ($vars['rows'] as $id => $row) {
+ $name = $argument->summary_name($row);
+ $count = intval($row->{$argument->count_alias});
+ $tid = $row->term_node_tid;
+ $term = taxonomy_get_term($tid);
+ //$url = url($view->get_url($args), $url_options);
+ $url = taxonomy_term_path($term);
+
+ // @TODO: We might not want to print terms with no projects so the user doesn't click on the
+ // term and end up with a 404 error.
+
+ // @TODO: We want to include the description of the term as well.
+
+ $vars['rows'][$id]->link = $name;
+ $vars['rows'][$id]->url = $url;
+ $vars['rows'][$id]->count = $count;
+ $vars['rows'][$id]->term = $term;
+
+ // Prepare terms for sending to theme_project_term_list().
+ $l_options = array('attributes' => array('title' => strip_tags($term->description)), 'absolute' => TRUE);
+ $l_options = array_merge($l_options, $url_options);
+ $children[] = l("$name ($count)", $url, $l_options);
+ }
+
+ // For each row returned, we store the data in two different ways for use
+ // and display by the template.
+ $vars['project_terms'] = array(
+ '#title' => t('Categories'),
+ '#collapsible' => TRUE,
+ '#collapsed' => isset($view->original_args[1]) ? TRUE : FALSE,
+ '#children' => theme('item_list', $children),
+ );
+}
+
+/**
+ * Theme the extra_options form for the project_sort_method filter.
+ */
+function theme_project_views_project_sort_method_options_form($form) {
+ $header = array(
+ array('data' => t('Enabled')),
+ array('data' => t('ID')),
+ array('data' => t('Name')),
+ array('data' => t('Weight')),
+ array('data' => t('Display name')),
+ );
+ $rows = array();
+ foreach (element_children($form) as $key) {
+ $row = array();
+ $row[] = drupal_render($form[$key]['enabled']);
+ $row[] = drupal_render($form[$key]['id']);
+ $row[] = drupal_render($form[$key]['name']);
+ $form[$key]['weight']['#attributes']['class'] = 'weight';
+ $row[] = drupal_render($form[$key]['weight']);
+ $row[] = drupal_render($form[$key]['display_name']);
+
+ $rows[] = array('data' => $row, 'class' => 'draggable');
+ }
+ if (empty($rows)) {
+ $rows[] = array(array('data' => t('No fields available.'), 'colspan' => '2'));
+ }
+
+ drupal_add_tabledrag('exposed-sort-weight', 'order', 'sibling', 'weight');
+ $output = theme('table', $header, $rows, array('id' => 'exposed-sort-weight'));
+ $output .= drupal_render($form);
+ return $output;
+}
+
+/**
+ * Preprocess theme function to print a single project record from a row, using fields.
+ */
+function template_preprocess_project_views_view_row_project_fields(&$vars) {
+ $view = $vars['view'];
+
+ // Loop through the fields for this view.
+ $inline = FALSE;
+ $vars['fields'] = array(); // ensure it's at least an empty array.
+ foreach ($view->field as $id => $field) {
+ if (empty($field->options['exclude'])) {
+ $object = new stdClass();
+
+ $object->content = $view->field[$id]->theme($vars['row']);
+ if (isset($view->field[$id]->field_alias) && isset($vars['row']->{$view->field[$id]->field_alias})) {
+ $object->raw = $vars['row']->{$view->field[$id]->field_alias};
+ }
+ else {
+ $object->raw = NULL; // make sure it exists to reduce NOTICE
+ }
+
+ $object->handler = $view->field[$id];
+ $object->class = views_css_safe($id);
+ $object->label = check_plain($view->field[$id]->label());
+ $vars['fields'][$id] = $object;
+ }
+ }
+
+}
+/**
+ * @}
+ */
Index: views/project_views_handler_filter_project_sort_method.inc
===================================================================
--- views/project_views_handler_filter_project_sort_method.inc (revision 0)
+++ views/project_views_handler_filter_project_sort_method.inc (revision 0)
@@ -0,0 +1,175 @@
+value = $this->options['value'];
+ }
+
+ function has_extra_options() { return TRUE; }
+
+ function get_value_options() { /* don't overwrite the value options */ }
+
+ function option_definition() {
+ $options = parent::option_definition();
+
+ // Make this filter be exposed by default.
+ $options['exposed'] = array('default' => TRUE);
+
+ // Provide a select box for selecting the sort methods to expose to the user.
+ $options['sort_methods'] = array('default' => array());
+
+ // We don't need an operator for this filter.
+ unset($options['operator']);
+ return $options;
+ }
+
+ /**
+ * Provide the basic form which calls through to subforms.
+ *
+ * We override the parent function here because we only want
+ * to show the exposed filter settings form.
+ */
+ function options_form(&$form, &$form_state) {
+ $this->show_expose_form($form, $form_state);
+ }
+
+ /**
+ * Provide a form for setting the sorting method.
+ */
+ function value_form(&$form, &$form_state) {
+ $options = array();
+
+ // Get an array with all sorting methods available for this display.
+ $sorts = $this->view->display_handler->get_option('sorts');
+
+ // Get an array with the sorting methods the admin has enabled to
+ // be options for this filter.
+ $enabled_sort_methods = array();
+ $enabled_sort_weights = array();
+ $sort_methods = $this->options['sort_methods'];
+ foreach ($sort_methods as $id => $value) {
+ if ($value['enabled']) {
+ $enabled_sort_weights[$id] = $value['weight'];
+ }
+ }
+ // Sort the array by weight.
+ asort($enabled_sort_weights);
+ foreach ($enabled_sort_weights as $id => $value) {
+ $enabled_sort_methods[$id] = $sort_methods[$id]['display_name'];
+ }
+
+ $form['value'] = array(
+ '#type' => 'select',
+ '#title' => t('Select the sorting method'),
+ '#multiple' => FALSE,
+ '#options' => $enabled_sort_methods,
+ );
+ }
+
+ /**
+ * Allow the user to select which search criteria
+ * the user should be able to pick from.
+ */
+ function extra_options_form(&$form, &$form_state) {
+ parent::extra_options_form($form, $form_state);
+
+ $sort_method_options = $this->options['sort_methods'];
+ $sorts = $this->view->display_handler->get_option('sorts');
+ $form['sort_methods'] = array(
+ '#prefix' => '' . t('Below you will find a list of all available sort criteria. Enable those criteria you wish to be available for the user to select. You can change the order these sort criteria will be displayed in the dropdown box by changing the weight. Changing the weight on this form will not affect the relative order of the sorts. The value used in the Display name column is the name that will be displayed to the user.'),
+ '#theme' => 'project_views_project_sort_method_options_form',
+ '#suffix' => '
',
+ '#tree' => TRUE,
+ );
+
+ $weights = array();
+ foreach ($sorts as $id=> $value) {
+ $handler = views_get_handler($sorts[$id]['table'], $sorts[$id]['field'], 'sort');
+ $weights[$id] = isset($sort_method_options[$id]['weight']) ? $sort_method_options[$id]['weight'] : 0;
+ $rows[$id]['enabled'] = array(
+ '#type' => 'checkbox',
+ '#default_value' => !empty($sort_method_options[$id]['enabled']) ? TRUE : FALSE,
+ );
+
+ $rows[$id]['id'] = array(
+ '#type' => 'markup',
+ '#value' => $id,
+ );
+
+ $rows[$id]['name'] = array(
+ '#type' => 'markup',
+ '#value' => $handler->ui_name(),
+ );
+
+ $rows[$id]['weight'] = array(
+ '#type' => 'weight',
+ '#delta' => 25,
+ '#default_value' => $weights[$id],
+ );
+
+ $rows[$id]['display_name'] = array(
+ '#type' => 'textfield',
+ '#default_value' => isset($sort_method_options[$id]['display_name']) ? $sort_method_options[$id]['display_name'] : $sort_method_options[$id]['name'],
+ '#size' => 25,
+ );
+ }
+
+ // We have to display the rows in order by weight.
+ asort($weights);
+ foreach ($weights as $id => $row) {
+ $form['sort_methods'][$id] = $rows[$id];
+ }
+
+ // Set up this form to use tabledrag.
+ $form_state['js settings']['tableDrag']['exposed-sort-weight']['weight'][0] = array(
+ 'target' => 'weight',
+ 'source' => NULL,
+ 'relationship' => 'sibling',
+ 'action' => 'order',
+ 'hidden' => TRUE,
+ 'limit' => 0,
+ );
+ }
+
+ /**
+ * Display the filter on the administrative summary
+ */
+ function admin_summary() {
+ if (!empty($this->options['exposed'])) {
+ return t('exposed');
+ }
+ }
+
+ /**
+ * When the user selects a sorting method, remove all other sort criteria
+ * that the user also chould have selected from the view.
+ */
+ function exposed_submit(&$form, &$form_state) {
+ // Determine which sort criteria was selected.
+ $filter_identifier = $this->options['expose']['identifier'];
+ $sort_by = $form_state['values'][$filter_identifier];
+
+ // Remove all other sort criteria that the user could have selected
+ // but didn't from the view.
+ $exposed_sort_methods = $form[$filter_identifier]['#options'];
+ foreach ($exposed_sort_methods as $id => $value) {
+ if ($id != $sort_by) {
+ unset($this->view->sort[$id]);
+ }
+ }
+ }
+
+ /**
+ * Since this handler isn't a "true" filter, we don't want to directly
+ * modify the query here.
+ */
+ function query() { }
+}
Index: views/project_views_plugin_style_project_list.inc
===================================================================
--- views/project_views_plugin_style_project_list.inc (revision 0)
+++ views/project_views_plugin_style_project_list.inc (revision 0)
@@ -0,0 +1,63 @@
+view->args[0])) {
+ $this->view->project->project_type = _project_views_get_project_type($this->view->args[0]);
+ }
+
+ // If the first sort criteria is the changed field (for sorting by date),
+ // then we need to add some information to the results set
+ // so that they can later be grouped by date in the theming functions.
+ // Views doesn't allow us to do this via the UI because views can
+ // only handle grouping if fields, not nodes, are being displayed.
+ if (is_array($this->view->sort) && isset($this->view->sort['changed']) && $this->view->sort['changed']->position == 0) {
+ $field_alias = $this->view->sort['changed']->table_alias . "_" . $this->view->sort['changed']->field;
+ $granularity = $this->view->sort['changed']->options['granularity'];
+ switch ($granularity) {
+ case 'second':
+ $date_format_string = 'YmdHis';
+ break;
+ case 'minute':
+ $date_format_string = 'YmdHi';
+ break;
+ case 'hour':
+ $date_format_string = 'YmdH';
+ break;
+ case 'day':
+ $date_format_string = 'Ymd';
+ break;
+ case 'month':
+ $date_format_string = 'Ym';
+ break;
+ case 'year':
+ $date_format_string = 'Y';
+ break;
+ default:
+ $date_format_string = 'Ymd';
+ }
+
+ $last_date = '';
+ foreach ($this->view->result as $i => $value) {
+ $date = format_date($value->$field_alias, 'custom', $date_format_string);
+ // If this date is a new date, once the granularity selected has been taken
+ // into account, set a special property in the results of the view so that
+ // later on in template_preprocess_project_views_view_row_project_node() we
+ // can flag a row as having a different changed date than the last row
+ // so that the actual date can be displayed as a header from the template.
+ // @TODO: As written, this only works with second granularity.
+ if ($date != $last_date) {
+ $this->view->project->project_new_date[$i] = TRUE;
+ }
+ $last_date = $date;
+ }
+ }
+ parent::pre_render($result);
+ }
+}
Index: views/project.views_default.inc
===================================================================
--- views/project.views_default.inc (revision 0)
+++ views/project.views_default.inc (revision 0)
@@ -0,0 +1,769 @@
+name = 'project_types';
+ $view->description = 'A list of project types with descriptions.';
+ $view->tag = 'project';
+ $view->view_php = '';
+ $view->base_table = 'term_data';
+ $view->is_cacheable = FALSE;
+ $view->api_version = 2;
+ $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */
+ $handler = $view->new_display('default', 'Defaults', 'default');
+ $handler->override_option('fields', array(
+ 'name' => array(
+ 'id' => 'name',
+ 'table' => 'term_data',
+ 'field' => 'name',
+ 'label' => '',
+ 'relationship' => 'none',
+ 'link_to_taxonomy' => 1,
+ ),
+ 'description' => array(
+ 'id' => 'description',
+ 'table' => 'term_data',
+ 'field' => 'description',
+ 'label' => '',
+ 'relationship' => 'none',
+ ),
+ ));
+ $handler->override_option('filters', array(
+ 'project_type' => array(
+ 'operator' => 'in',
+ 'value' => array(
+ '1' => 1,
+ ),
+ 'group' => 0,
+ 'exposed' => FALSE,
+ 'expose' => array(
+ 'operator' => FALSE,
+ 'label' => '',
+ ),
+ 'include' => array(
+ 'top_level' => 'top_level',
+ ),
+ 'id' => 'project_type',
+ 'table' => 'term_data',
+ 'field' => 'project_type',
+ 'relationship' => 'none',
+ ),
+ ));
+ $handler->override_option('access', array(
+ 'type' => 'perm',
+ 'role' => array(),
+ 'perm' => 'browse project listings',
+ ));
+ $handler->override_option('title', 'Project types');
+ $handler->override_option('empty_format', '1');
+ $handler->override_option('items_per_page', 30);
+ $handler->override_option('use_pager', '1');
+ $handler->override_option('distinct', 1);
+ $handler->override_option('style_plugin', 'list');
+ $handler->override_option('style_options', array(
+ 'type' => 'ul',
+ ));
+ $handler->override_option('row_options', array(
+ 'inline' => array(),
+ 'separator' => '',
+ ));
+ $handler = $view->new_display('page', 'Page: Project types', 'page');
+ $handler->override_option('path', 'project');
+ $handler->override_option('menu', array(
+ 'type' => 'normal',
+ 'title' => 'Projects',
+ 'weight' => '0',
+ ));
+ $handler->override_option('tab_options', array(
+ 'type' => 'none',
+ 'title' => '',
+ 'weight' => 0,
+ ));
+ $views[$view->name] = $view;
+
+ $view = new view;
+ $view->name = 'project_overview_2';
+ $view->description = 'A view for browsing projects.';
+ $view->tag = 'project';
+ $view->view_php = '';
+ $view->base_table = 'node';
+ $view->is_cacheable = FALSE;
+ $view->api_version = 2;
+ $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */
+ $handler = $view->new_display('default', 'Defaults', 'default');
+ $handler->override_option('relationships', array(
+ 'project_release_version' => array(
+ 'label' => 'release',
+ 'required' => 0,
+ 'id' => 'project_release_version',
+ 'table' => 'node',
+ 'field' => 'project_release_version',
+ 'relationship' => 'none',
+ ),
+ ));
+ $handler->override_option('fields', array(
+ 'title' => array(
+ 'label' => '',
+ 'link_to_node' => 1,
+ 'exclude' => 0,
+ 'id' => 'title',
+ 'table' => 'node',
+ 'field' => 'title',
+ 'relationship' => 'none',
+ ),
+ 'changed' => array(
+ 'label' => 'Last changed',
+ 'date_format' => 'time ago',
+ 'custom_date_format' => '2',
+ 'exclude' => 0,
+ 'id' => 'changed',
+ 'table' => 'node',
+ 'field' => 'changed',
+ 'relationship' => 'none',
+ ),
+ 'teaser' => array(
+ 'label' => '',
+ 'exclude' => 0,
+ 'id' => 'teaser',
+ 'table' => 'node_revisions',
+ 'field' => 'teaser',
+ 'relationship' => 'none',
+ ),
+ 'download_table' => array(
+ 'label' => '',
+ 'exclude' => 0,
+ 'id' => 'download_table',
+ 'table' => 'node',
+ 'field' => 'download_table',
+ 'release_type' => 'official',
+ 'table_type' => 'supported',
+ 'first_column_title' => 'Version',
+ 'relationship' => 'none',
+ ),
+ 'project_type_tid' => array(
+ 'label' => '',
+ 'type' => 'separator',
+ 'separator' => ' ',
+ 'empty' => '',
+ 'link_to_taxonomy' => 1,
+ 'limit' => 0,
+ 'vids' => array(
+ '1' => 1,
+ ),
+ 'exclude_top_level_terms' => 1,
+ 'exclude' => 0,
+ 'id' => 'project_type_tid',
+ 'table' => 'term_node',
+ 'field' => 'project_type_tid',
+ 'relationship' => 'none',
+ ),
+ ));
+ $handler->override_option('sorts', array(
+ 'sticky' => array(
+ 'order' => 'DESC',
+ 'id' => 'sticky',
+ 'table' => 'node',
+ 'field' => 'sticky',
+ 'relationship' => 'none',
+ ),
+ 'title' => array(
+ 'order' => 'ASC',
+ 'id' => 'title',
+ 'table' => 'node',
+ 'field' => 'title',
+ 'relationship' => 'none',
+ ),
+ 'changed' => array(
+ 'order' => 'DESC',
+ 'granularity' => 'day',
+ 'id' => 'changed',
+ 'table' => 'node',
+ 'field' => 'changed',
+ 'relationship' => 'project_release_version',
+ ),
+ 'title_1' => array(
+ 'order' => 'ASC',
+ 'id' => 'title_1',
+ 'table' => 'node',
+ 'field' => 'title',
+ 'relationship' => 'none',
+ ),
+ ));
+ $handler->override_option('arguments', array(
+ 'tid' => array(
+ 'default_action' => 'not found',
+ 'style_plugin' => 'default_summary',
+ 'style_options' => array(),
+ 'wildcard' => 'all',
+ 'wildcard_substitution' => 'All',
+ 'title' => '%1',
+ 'default_argument_type' => 'fixed',
+ 'default_argument' => '',
+ 'validate_type' => 'project_type_term',
+ 'validate_fail' => 'not found',
+ 'break_phrase' => 0,
+ 'add_table' => 0,
+ 'require_value' => 0,
+ 'reduce_duplicates' => 1,
+ 'set_breadcrumb' => 0,
+ 'id' => 'tid',
+ 'table' => 'term_node',
+ 'field' => 'tid',
+ 'relationship' => 'none',
+ 'default_options_div_prefix' => '',
+ 'default_argument_user' => 0,
+ 'default_argument_fixed' => '',
+ 'default_argument_php' => '',
+ 'validate_argument_node_type' => array(
+ 'project_project' => 0,
+ 'project_release' => 0,
+ 'book' => 0,
+ 'page' => 0,
+ 'story' => 0,
+ ),
+ 'validate_argument_node_access' => 0,
+ 'validate_argument_nid_type' => 'nid',
+ 'validate_argument_vocabulary' => array(
+ '3' => 0,
+ '5' => 0,
+ '2' => 0,
+ '1' => 0,
+ '4' => 0,
+ ),
+ 'validate_argument_type' => 'tid',
+ 'validate_argument_project_term_vocabulary' => array(
+ '1' => 1,
+ ),
+ 'validate_argument_project_term_argument_type' => 'convert',
+ 'validate_argument_project_term_argument_action_top_without' => 'pass',
+ 'validate_argument_project_term_argument_action_top_with' => 'pass',
+ 'validate_argument_project_term_argument_action_child' => 'pass',
+ 'validate_argument_php' => '',
+ 'override' => array(
+ 'button' => 'Override',
+ ),
+ ),
+ ));
+ $handler->override_option('filters', array(
+ 'type' => array(
+ 'operator' => 'in',
+ 'value' => array(
+ 'project_project' => 'project_project',
+ ),
+ 'group' => '0',
+ 'exposed' => FALSE,
+ 'expose' => array(
+ 'operator' => FALSE,
+ 'label' => '',
+ ),
+ 'id' => 'type',
+ 'table' => 'node',
+ 'field' => 'type',
+ 'relationship' => 'none',
+ ),
+ 'status' => array(
+ 'operator' => '=',
+ 'value' => 1,
+ 'group' => '0',
+ 'exposed' => FALSE,
+ 'expose' => array(
+ 'operator' => FALSE,
+ 'label' => '',
+ ),
+ 'id' => 'status',
+ 'table' => 'node',
+ 'field' => 'status',
+ 'relationship' => 'none',
+ ),
+ 'project_release_api_version' => array(
+ 'operator' => 'or',
+ 'value' => array(),
+ 'group' => '0',
+ 'exposed' => TRUE,
+ 'expose' => array(
+ 'use_operator' => 0,
+ 'operator' => 'project_release_api_version_op',
+ 'identifier' => 'api',
+ 'label' => 'API Version',
+ 'optional' => 1,
+ 'single' => 1,
+ 'remember' => 1,
+ 'reduce' => 0,
+ ),
+ 'type' => 'select',
+ 'vid' => '2',
+ 'reduce_duplicates' => TRUE,
+ 'id' => 'project_release_api_version',
+ 'table' => 'term_node',
+ 'field' => 'project_release_api_version',
+ 'hierarchy' => 0,
+ 'relationship' => 'project_release_version',
+ 'override' => array(
+ 'button' => 'Override',
+ ),
+ ),
+ 'keys' => array(
+ 'operator' => 'optional',
+ 'value' => '',
+ 'group' => '0',
+ 'exposed' => TRUE,
+ 'expose' => array(
+ 'use_operator' => 0,
+ 'operator' => 'keys_op',
+ 'identifier' => 'keywords',
+ 'label' => 'Keywords:',
+ 'optional' => 1,
+ 'remember' => 0,
+ ),
+ 'id' => 'keys',
+ 'table' => 'search_index',
+ 'field' => 'keys',
+ 'override' => array(
+ 'button' => 'Override',
+ ),
+ 'relationship' => 'none',
+ ),
+ 'project_type_tid' => array(
+ 'operator' => 'or',
+ 'value' => '',
+ 'group' => '0',
+ 'exposed' => TRUE,
+ 'expose' => array(
+ 'use_operator' => 0,
+ 'operator' => 'project_type_tid_op',
+ 'identifier' => 'type',
+ 'label' => 'Category:',
+ 'optional' => 1,
+ 'single' => 1,
+ 'remember' => 0,
+ 'reduce' => 0,
+ ),
+ 'type' => 'select',
+ 'vid' => '1',
+ 'associated_argument' => '0',
+ 'remove_if_no_options' => 1,
+ 'argument_position' => '0',
+ 'id' => 'project_type_tid',
+ 'table' => 'term_node',
+ 'field' => 'project_type_tid',
+ 'relationship' => 'none',
+ 'reduce_duplicates' => 1,
+ ),
+ 'project_sort_method' => array(
+ 'value' => 'sticky',
+ 'group' => '0',
+ 'exposed' => TRUE,
+ 'expose' => array(
+ 'operator' => '',
+ 'label' => 'Sort by:',
+ 'identifier' => 'sort_by',
+ 'optional' => 0,
+ 'single' => 1,
+ 'remember' => 0,
+ ),
+ 'sort_methods' => array(
+ 'changed' => array(
+ 'enabled' => 1,
+ 'weight' => '-23',
+ 'display_name' => 'Date',
+ ),
+ 'title_1' => array(
+ 'enabled' => 0,
+ 'weight' => '-25',
+ 'display_name' => 'title_1',
+ ),
+ 'sticky' => array(
+ 'enabled' => 0,
+ 'weight' => '-24',
+ 'display_name' => 'sticky',
+ ),
+ 'title' => array(
+ 'enabled' => 1,
+ 'weight' => '-22',
+ 'display_name' => 'Name',
+ ),
+ ),
+ 'id' => 'project_sort_method',
+ 'table' => 'views',
+ 'field' => 'project_sort_method',
+ 'relationship' => 'none',
+ ),
+ ));
+ $handler->override_option('access', array(
+ 'type' => 'perm',
+ 'role' => array(),
+ 'perm' => 'browse project listings',
+ ));
+ $handler->override_option('empty', 'No results were found.');
+ $handler->override_option('empty_format', '1');
+ $handler->override_option('items_per_page', 30);
+ $handler->override_option('use_pager', '1');
+ $handler->override_option('distinct', 1);
+ $handler->override_option('style_plugin', 'project_list');
+ $handler->override_option('row_plugin', 'project_fields');
+ $handler->override_option('row_options', array(
+ 'inline' => array(),
+ 'separator' => '',
+ ));
+ $handler = $view->new_display('page', 'Page', 'page_1');
+ $handler->override_option('path', 'project2/%');
+ $handler->override_option('menu', array(
+ 'type' => 'none',
+ 'title' => 'Yuki',
+ 'weight' => '0',
+ ));
+ $handler->override_option('tab_options', array(
+ 'type' => 'none',
+ 'title' => '',
+ 'weight' => 0,
+ ));
+ $handler = $view->new_display('feed', 'Feed', 'feed_1');
+ $handler->override_option('style_plugin', 'rss');
+ $handler->override_option('style_options', array(
+ 'mission_description' => FALSE,
+ 'description' => '',
+ ));
+ $handler->override_option('row_plugin', 'node_rss');
+ $handler->override_option('row_options', array(
+ 'item_length' => 'default',
+ ));
+ $handler->override_option('path', 'project2/%/feed');
+ $handler->override_option('menu', array(
+ 'type' => 'none',
+ 'title' => '',
+ 'weight' => 0,
+ ));
+ $handler->override_option('tab_options', array(
+ 'type' => 'none',
+ 'title' => '',
+ 'weight' => 0,
+ ));
+ $handler->override_option('displays', array(
+ 'default' => 'default',
+ 'page_1' => 'page_1',
+ ));
+ $handler->override_option('sitename_title', FALSE);
+ $views[$view->name] = $view;
+
+ $view = new view;
+ $view->name = 'project_overview';
+ $view->description = 'A view for browsing projects.';
+ $view->tag = 'project';
+ $view->view_php = '';
+ $view->base_table = 'node';
+ $view->is_cacheable = FALSE;
+ $view->api_version = 2;
+ $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */
+ $handler = $view->new_display('default', 'Defaults', 'default');
+ $handler->override_option('relationships', array(
+ 'project_release_version' => array(
+ 'label' => 'release',
+ 'required' => 0,
+ 'id' => 'project_release_version',
+ 'table' => 'node',
+ 'field' => 'project_release_version',
+ 'relationship' => 'none',
+ ),
+ ));
+ $handler->override_option('sorts', array(
+ 'sticky' => array(
+ 'order' => 'DESC',
+ 'id' => 'sticky',
+ 'table' => 'node',
+ 'field' => 'sticky',
+ 'relationship' => 'none',
+ ),
+ 'title' => array(
+ 'order' => 'ASC',
+ 'id' => 'title',
+ 'table' => 'node',
+ 'field' => 'title',
+ 'relationship' => 'none',
+ ),
+ 'changed' => array(
+ 'order' => 'DESC',
+ 'granularity' => 'day',
+ 'id' => 'changed',
+ 'table' => 'node',
+ 'field' => 'changed',
+ 'relationship' => 'project_release_version',
+ ),
+ 'title_1' => array(
+ 'order' => 'ASC',
+ 'id' => 'title_1',
+ 'table' => 'node',
+ 'field' => 'title',
+ 'relationship' => 'none',
+ ),
+ ));
+ $handler->override_option('arguments', array(
+ 'tid' => array(
+ 'default_action' => 'not found',
+ 'style_plugin' => 'default_summary',
+ 'style_options' => array(),
+ 'wildcard' => 'all',
+ 'wildcard_substitution' => 'All',
+ 'title' => '%1',
+ 'default_argument_type' => 'fixed',
+ 'default_argument' => '',
+ 'validate_type' => 'project_type_term',
+ 'validate_fail' => 'not found',
+ 'break_phrase' => 0,
+ 'add_table' => 0,
+ 'require_value' => 0,
+ 'reduce_duplicates' => 1,
+ 'set_breadcrumb' => 0,
+ 'id' => 'tid',
+ 'table' => 'term_node',
+ 'field' => 'tid',
+ 'relationship' => 'none',
+ 'default_options_div_prefix' => '',
+ 'default_argument_user' => 0,
+ 'default_argument_fixed' => '',
+ 'default_argument_php' => '',
+ 'validate_argument_node_type' => array(
+ 'project_project' => 0,
+ 'project_release' => 0,
+ 'book' => 0,
+ 'page' => 0,
+ 'story' => 0,
+ ),
+ 'validate_argument_node_access' => 0,
+ 'validate_argument_nid_type' => 'nid',
+ 'validate_argument_vocabulary' => array(
+ '3' => 0,
+ '5' => 0,
+ '2' => 0,
+ '1' => 0,
+ '4' => 0,
+ ),
+ 'validate_argument_type' => 'tid',
+ 'validate_argument_project_term_vocabulary' => array(
+ '1' => 1,
+ ),
+ 'validate_argument_project_term_argument_type' => 'convert',
+ 'validate_argument_project_term_argument_action_top_without' => 'pass',
+ 'validate_argument_project_term_argument_action_top_with' => 'pass',
+ 'validate_argument_project_term_argument_action_child' => 'pass',
+ 'validate_argument_php' => '',
+ 'override' => array(
+ 'button' => 'Override',
+ ),
+ ),
+ ));
+ $handler->override_option('filters', array(
+ 'type' => array(
+ 'operator' => 'in',
+ 'value' => array(
+ 'project_project' => 'project_project',
+ ),
+ 'group' => '0',
+ 'exposed' => FALSE,
+ 'expose' => array(
+ 'operator' => FALSE,
+ 'label' => '',
+ ),
+ 'id' => 'type',
+ 'table' => 'node',
+ 'field' => 'type',
+ 'relationship' => 'none',
+ ),
+ 'status' => array(
+ 'operator' => '=',
+ 'value' => 1,
+ 'group' => '0',
+ 'exposed' => FALSE,
+ 'expose' => array(
+ 'operator' => FALSE,
+ 'label' => '',
+ ),
+ 'id' => 'status',
+ 'table' => 'node',
+ 'field' => 'status',
+ 'relationship' => 'none',
+ ),
+ 'project_release_api_version' => array(
+ 'operator' => 'or',
+ 'value' => array(),
+ 'group' => '0',
+ 'exposed' => TRUE,
+ 'expose' => array(
+ 'use_operator' => 0,
+ 'operator' => 'project_release_api_version_op',
+ 'identifier' => 'api',
+ 'label' => 'API Version',
+ 'optional' => 1,
+ 'single' => 1,
+ 'remember' => 1,
+ 'reduce' => 0,
+ ),
+ 'type' => 'select',
+ 'vid' => '2',
+ 'reduce_duplicates' => TRUE,
+ 'id' => 'project_release_api_version',
+ 'table' => 'term_node',
+ 'field' => 'project_release_api_version',
+ 'hierarchy' => 0,
+ 'relationship' => 'project_release_version',
+ 'override' => array(
+ 'button' => 'Override',
+ ),
+ ),
+ 'keys' => array(
+ 'operator' => 'optional',
+ 'value' => '',
+ 'group' => '0',
+ 'exposed' => TRUE,
+ 'expose' => array(
+ 'use_operator' => 0,
+ 'operator' => 'keys_op',
+ 'identifier' => 'keywords',
+ 'label' => 'Keywords:',
+ 'optional' => 1,
+ 'remember' => 0,
+ ),
+ 'id' => 'keys',
+ 'table' => 'search_index',
+ 'field' => 'keys',
+ 'override' => array(
+ 'button' => 'Override',
+ ),
+ 'relationship' => 'none',
+ ),
+ 'project_type_tid' => array(
+ 'operator' => 'or',
+ 'value' => '',
+ 'group' => '0',
+ 'exposed' => TRUE,
+ 'expose' => array(
+ 'use_operator' => 0,
+ 'operator' => 'project_type_tid_op',
+ 'identifier' => 'type',
+ 'label' => 'Category:',
+ 'optional' => 1,
+ 'single' => 1,
+ 'remember' => 0,
+ 'reduce' => 0,
+ ),
+ 'type' => 'select',
+ 'vid' => '1',
+ 'associated_argument' => '0',
+ 'remove_if_no_options' => 1,
+ 'argument_position' => '0',
+ 'id' => 'project_type_tid',
+ 'table' => 'term_node',
+ 'field' => 'project_type_tid',
+ 'relationship' => 'none',
+ 'reduce_duplicates' => 1,
+ ),
+ 'project_sort_method' => array(
+ 'value' => 'sticky',
+ 'group' => '0',
+ 'exposed' => TRUE,
+ 'expose' => array(
+ 'operator' => '',
+ 'label' => 'Sort by:',
+ 'identifier' => 'sort_by',
+ 'optional' => 0,
+ 'single' => 1,
+ 'remember' => 0,
+ ),
+ 'sort_methods' => array(
+ 'changed' => array(
+ 'enabled' => 1,
+ 'weight' => '-23',
+ 'display_name' => 'Date',
+ ),
+ 'title_1' => array(
+ 'enabled' => 0,
+ 'weight' => '-25',
+ 'display_name' => 'title_1',
+ ),
+ 'sticky' => array(
+ 'enabled' => 0,
+ 'weight' => '-24',
+ 'display_name' => 'sticky',
+ ),
+ 'title' => array(
+ 'enabled' => 1,
+ 'weight' => '-22',
+ 'display_name' => 'Name',
+ ),
+ ),
+ 'id' => 'project_sort_method',
+ 'table' => 'views',
+ 'field' => 'project_sort_method',
+ 'relationship' => 'none',
+ ),
+ ));
+ $handler->override_option('access', array(
+ 'type' => 'perm',
+ 'role' => array(),
+ 'perm' => 'browse project listings',
+ ));
+ $handler->override_option('empty', 'No results were found.');
+ $handler->override_option('empty_format', '1');
+ $handler->override_option('items_per_page', 30);
+ $handler->override_option('use_pager', '1');
+ $handler->override_option('distinct', 1);
+ $handler->override_option('style_plugin', 'project_list');
+ $handler->override_option('row_plugin', 'project_node');
+ $handler->override_option('row_options', array(
+ 'project_teaser' => 1,
+ 'project_term_links' => 1,
+ 'project_release_download_table' => 1,
+ 'project_release_download_link' => 1,
+ ));
+ $handler = $view->new_display('page', 'Page', 'page_1');
+ $handler->override_option('path', 'project/%');
+ $handler->override_option('menu', array(
+ 'type' => 'none',
+ 'title' => 'Yuki',
+ 'weight' => '0',
+ ));
+ $handler->override_option('tab_options', array(
+ 'type' => 'none',
+ 'title' => '',
+ 'weight' => 0,
+ ));
+ $handler = $view->new_display('feed', 'Feed', 'feed_1');
+ $handler->override_option('style_plugin', 'rss');
+ $handler->override_option('style_options', array(
+ 'mission_description' => FALSE,
+ 'description' => '',
+ ));
+ $handler->override_option('row_plugin', 'node_rss');
+ $handler->override_option('row_options', array(
+ 'item_length' => 'default',
+ ));
+ $handler->override_option('path', 'project/%/feed');
+ $handler->override_option('menu', array(
+ 'type' => 'none',
+ 'title' => '',
+ 'weight' => 0,
+ ));
+ $handler->override_option('tab_options', array(
+ 'type' => 'none',
+ 'title' => '',
+ 'weight' => 0,
+ ));
+ $handler->override_option('displays', array(
+ 'default' => 'default',
+ 'page_1' => 'page_1',
+ ));
+ $handler->override_option('sitename_title', FALSE);
+ $views[$view->name] = $view;
+
+ return $views;
+}
+
+
Index: views/project_views_handler_field_term_node_project_type_tid.inc
===================================================================
--- views/project_views_handler_field_term_node_project_type_tid.inc (revision 0)
+++ views/project_views_handler_field_term_node_project_type_tid.inc (revision 0)
@@ -0,0 +1,99 @@
+ TRUE);
+
+ return $options;
+ }
+
+ /**
+ * Provide "exclude top level terms" option.
+ */
+ function options_form(&$form, &$form_state) {
+ parent::options_form($form, $form_state);
+
+ $form['exclude_top_level_terms'] = array(
+ '#title' => t('Exclude top level project type terms'),
+ '#type' => 'checkbox',
+ '#default_value' => !empty($this->options['exclude_top_level_terms']),
+ );
+
+ // Override the parent vocabulary selection field so that the project
+ // type vocabulary is always selected.
+ $options = array();
+ $project_type_vid = _project_get_vid();
+ if (!empty($project_type_vid)) {
+ $vocabulary = taxonomy_vocabulary_load($project_type_vid);
+ $options[$vocabulary->vid] = $vocabulary->name;
+
+ unset($form['vids']);
+ $form['vids'] = array(
+ '#prefix' => '',
+ '#type' => 'checkboxes',
+ '#title' => t('Project type vocabulary'),
+ '#options' => $options,
+ '#default_value' => $this->options['vids'],
+ '#process' => array('expand_checkboxes', 'views_process_dependency'),
+ '#dependency' => array('edit-options-limit' => array(TRUE)),
+ );
+ }
+ }
+
+ /**
+ * Add this term to the query
+ */
+ function query() {
+ $this->add_additional_fields();
+ }
+
+// @TODO: Finish this handler.
+ function pre_render($values) {
+ $this->field_alias = $this->aliases['vid'];
+ $vids = array();
+ foreach ($values as $result) {
+ $vids[] = $result->{$this->aliases['vid']};
+ }
+
+ if ($vids) {
+ $voc = '';
+ if (!empty($this->options['limit']) && !empty($this->options['vids'])) {
+ $voc = " AND td.vid IN (" . implode(', ', array_keys(array_filter($this->options['vids']))) . ")";
+ }
+
+ // Exclude top level terms.
+ $top_level_join = '';
+ $top_level_where = '';
+ if (!empty($this->options['exclude_top_level_terms'])) {
+ $top_level_join = " INNER JOIN {term_hierarchy} th ON td.tid = th.tid";
+ $top_level_where = "AND th.parent <> 0";
+ }
+
+ $result = db_query("SELECT tn.vid AS node_vid, td.* FROM {term_data} td INNER JOIN {term_node} tn ON td.tid = tn.tid$top_level_join WHERE tn.vid IN (" . implode(', ', $vids) . ")$voc $top_level_where ORDER BY td.weight, td.name");
+
+ while ($term = db_fetch_object($result)) {
+ if (empty($this->options['link_to_taxonomy'])) {
+ $this->items[$term->node_vid][$term->tid] = check_plain($term->name);
+ }
+ else {
+ $this->items[$term->node_vid][$term->tid] = l($term->name, taxonomy_term_path($term));
+ }
+ }
+ }
+ }
+
+ function admin_summary() {
+ if (!empty($this->options['exclude_top_level_terms'])) {
+ return t('top level terms excluded');
+ }
+ }
+}