Index: ReferencedByFilter.module =================================================================== --- ReferencedByFilter.module (revision 6) +++ ReferencedByFilter.module (working copy) @@ -25,6 +25,16 @@ 'help' => t('This argument allows views to query the nodes referenced by a certain node reference field. In the options field specify the referencing field.'), ), + 'referencedbyfilter_selector' => array( + 'name' => t('Node Reference: Field selector'), + 'handler' => t('referencedbyfilter_arg_selector'), + 'help' => t('This argument allows views to query the nodes referenced by a certain node reference field. Use in conjunction with the "Node Reference: views on selected node reference" argument.'), + ), + 'referencedbyfilter_any' => array( + 'name' => t('Node Reference: views on selected node reference'), + 'handler' => t('referencedbyfilter_arg_any'), + 'help' => t('This argument allows views to query the nodes referenced by the node reference field given by the selector field.'), + ), ); return $arguments; } @@ -80,4 +90,90 @@ } } return $existing_reference_fields ; -} \ No newline at end of file +} + +/** + * Handler for the selector: does nothing. + */ +function referencedbyfilter_arg_selector($op, &$query, $argtype, $arg = NULL) { + // do nothing. + // This argument is used by referencedbyfilter_arg_any. +} + +/** + * Handler for the "any field" argument. + * Uses field set by the selector argument. + * Eg, if your content type has a field "myfield", then to get all the noderef nodes in that field, + * feed the view the args /myfield/NID + * + * This allows reuse of views. + */ +function referencedbyfilter_arg_any($op, &$query, $argtype, $arg = NULL) { + if ($op == 'filter') { + + $nid = (int)$arg; + if (is_int($nid)) { + $selector_argument = _views_get_argument('referencedbyfilter_selector'); + // Get field name from the selector argument. Clean user input! + $referencing_field = check_plain($selector_argument['value']); + $node_reference_table = 'content_'. $referencing_field; + + // platform3 joachim: + // fixing bug where nodes that had no row for their noderef field produced all results, + // because a node_load here (WHY????) checked the field in the $node object. + /* + $node = node_load($nid); + if (!empty($node->$referencing_field)) { + */ + $joininfo = array( + 'type' => 'LEFT', + 'left' => array( + 'table' => 'node', + 'field' => 'nid', + ), + 'right' => array( + // Join to the referenced field. + 'field' => $referencing_field .'_nid', + ), + ); + $query->add_table($node_reference_table, FALSE, 1, $joininfo); + $query->add_field($referencing_field .'_nid', $node_reference_table); + $query->add_where($node_reference_table. '.nid = %d', $nid); + $vid=db_result(db_query("SELECT vid FROM {node} WHERE nid = %d", $nid)); + $query->add_where($node_reference_table .'.vid = %d', $vid); + } + } +} + + +/** + * Helper function: retrieve the argument data from the current view, given the argument name. + * Eg: one argument needs to get data from a helper argument. We know what name it has + * but not what position. + * + * @return + * A full argument array from the view object, with a value item added so no further + * poking at the views object is necessary. + * Eg: + vid (String, 2 characters ) 21 + type (String, 27 characters ) referencedbyfilter_selector + argdefault (String, 1 characters ) 2 + title (String, 0 characters ) + options (String, 0 characters ) + position (String, 1 characters ) 0 + wildcard (String, 0 characters ) + wildcard_substitution (String, 0 characters ) + id (String, 27 characters ) referencedbyfilter_selector + value userinput + */ +function _views_get_argument($argument_name) { + $view = $GLOBALS['current_view']; + + foreach ($view->argument as $position => $argument) { + if ($argument['type'] == $argument_name) { + $argument['value'] = $view->args[$argument['position']]; + + return $argument; + } + } +}