Index: modules/nodereference/nodereference.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/cck/modules/nodereference/Attic/nodereference.module,v retrieving revision 1.138.2.59 diff -u -p -r1.138.2.59 nodereference.module --- modules/nodereference/nodereference.module 19 Jul 2009 13:03:56 -0000 1.138.2.59 +++ modules/nodereference/nodereference.module 17 Aug 2009 02:53:56 -0000 @@ -52,6 +52,16 @@ function nodereference_theme() { } /** + * Implementation of hook_views_api(). + */ +function nodereference_views_api() { + return array( + 'api' => 2, + 'path' => drupal_get_path('module', 'nodereference') . '/views', + ); +} + +/** * Implementaion of hook_ctools_plugin_directory(). */ function nodereference_ctools_plugin_directory($module, $plugin) { @@ -173,6 +183,30 @@ function nodereference_field_settings($o 'label' => t($field['widget']['label']), 'content_field_name' => $field['field_name'], ); + + // Add a reverse relationship to get information about referring items. + $field_types = _content_field_types(); + $types = array(); + foreach (content_types() as $type) { + if (isset($type['fields'][$field['field_name']])) { + $types[] = $type['name']; + } + } + $label_truncated = truncate_utf8(t($field['widget']['label']), 10, TRUE); + $data[$table_alias]['vid'] = array( + 'group' => t('Content'), + 'title' => t('@label (!name) - reverse reference', array('@label' => t($field['widget']['label']), '!name' => $field['field_name'])), + 'title short' => t('@label-truncated reverse reference', array('@label-truncated' => $label_truncated)), + 'help' => t($field_types[$field['type']]['label']) .' ('. t('reverse reference') .') - '. t('Appears in: @types', array('@types' => implode(', ', $types))), + 'relationship' => array( + 'base' => 'node', + 'base field' => 'vid', + 'left_field' => 'nid', + 'field' => $db_info['columns']['nid']['column'], + 'handler' => 'nodereference_handler_relationship_reverse', + 'label' => t('@label reverse reference', array('@label' => t($field['widget']['label']))), + ), + ); return $data; } } Index: modules/nodereference/views/nodereference.views.inc =================================================================== RCS file: modules/nodereference/views/nodereference.views.inc diff -N modules/nodereference/views/nodereference.views.inc --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ modules/nodereference/views/nodereference.views.inc 17 Aug 2009 02:10:01 -0000 @@ -0,0 +1,23 @@ + array( + 'path' => drupal_get_path('module', 'nodereference') . '/views/handlers', + ), + 'handlers' => array( + 'nodereference_handler_relationship_reverse' => array( + 'parent' => 'views_handler_relationship', + ), + ), + ); +} Index: modules/nodereference/views/handlers/nodereference_handler_relationship_reverse.inc =================================================================== RCS file: modules/nodereference/views/handlers/nodereference_handler_relationship_reverse.inc diff -N modules/nodereference/views/handlers/nodereference_handler_relationship_reverse.inc --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ modules/nodereference/views/handlers/nodereference_handler_relationship_reverse.inc 18 Aug 2009 20:04:12 -0000 @@ -0,0 +1,128 @@ +table_alias)) { + if (!method_exists($this->query, 'ensure_table')) { vpr_trace(); exit; } + + // Since nested joins are not directly supported by Views, we are going + // to do here part of the job performed by views_query::ensure_table(). + + if (empty($this->relationship)) { + $this->relationship = $this->query->base_table; + } + + if ($this->relationship == $this->query->base_table && !empty($this->query->tables[$this->relationship][$this->table])) { + $this->table_alias = $this->query->tables[$relationship][$this->table]['alias']; + } + elseif (!array_key_exists($this->relationship, $this->query->relationships)) { + $this->table_alias = FALSE; + } + elseif ($this->table == $this->query->relationships[$this->relationship]['base']) { + $this->table_alias = $this->relationship; + } + else { + // Build the main join based on the views data cache. + $main_join = $this->query->get_join_data($this->table, $this->query->relationships[$this->relationship]['base']); + + // We want to alter the join so that it uses the field value instead of + // the vid. + $main_join_definition = $main_join->definition; + $main_join_definition['left_field'] = $this->definition['left_field']; + $main_join_definition['field'] = $this->definition['field']; + if (!empty($this->options['required'])) { + $main_join_definition['type'] = 'INNER'; + } + // Build a new join object with our new definition. + $main_join = new nodereference_nested_join(); + $main_join->definition = $main_join_definition; + $main_join->construct(); + $main_join->adjusted = TRUE; + $this->table_alias = $this->query->ensure_table($this->table, $this->relationship, $main_join); + + // Let's build the nested join. + $nested_join_definition = $this->definition; + $nested_join_definition['table'] = $this->definition['base']; + $nested_join_definition['left_field'] = $nested_join_definition['field'] = $nested_join_definition['base field']; + $nested_join_definition['left_table'] = $this->table_alias; + $nested_join_definition['type'] = 'INNER'; + + $nested_join = new nodereference_nested_join(); + $nested_join->definition = $nested_join_definition; + $nested_join->construct(); + $nested_join->adjusted = TRUE; + $nested_alias = $nested_join_definition['table'] .'_'. $this->table; + + $this->alias = $this->query->add_relationship($nested_alias, $nested_join, $this->definition['base'], $this->relationship); + + $main_join->_set_nested_join($nested_join, $this->alias); + } + } + return $this->table_alias; + } + + function query() { + $this->ensure_my_table(); + } +} + +class nodereference_nested_join extends views_join { + var $nested_join; + var $nested_alias; + + function _set_nested_join($nested_join, $nested_alias) { + $this->nested_join = $nested_join; + $this->nested_alias = $nested_alias; + } + + function join($table, &$query, $build_main_join = FALSE) { + if (!isset($this->nested_join)) { + if ($build_main_join) { + return parent::join($table, $query); + } + return ''; + } + $output = parent::join($table, $query); + $nested_join = $this->nested_join->join($query->table_queue[$this->nested_alias], $query, TRUE); + $output = preg_replace('`JOIN ({[_a-z0-9]+} [_a-z0-9]+) ON`', "JOIN (\n\\1\n{$nested_join}\n) ON", $output); + return $output; + } +}