Index: nodereference.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/cck/nodereference.module,v retrieving revision 1.28 diff -u -F^f -r1.28 nodereference.module --- nodereference.module 12 Jun 2006 19:36:54 -0000 1.28 +++ nodereference.module 4 Jul 2006 23:15:53 -0000 @@ -23,8 +23,13 @@ function nodereference_menu($may_cache) $items = array(); if ($may_cache) { - $items[] = array('path' => 'nodereference/autocomplete', 'title' => t('node reference autocomplete'), - 'callback' => 'nodereference_autocomplete', 'access' => user_access('access content'), 'type' => MENU_CALLBACK); + $items[] = array( + 'path' => 'nodereference/autocomplete', + 'title' => t('node reference autocomplete'), + 'callback' => 'nodereference_autocomplete', + 'access' => user_access('access content'), + 'type' => MENU_CALLBACK, + ); } return $items; @@ -35,7 +40,8 @@ function nodereference_menu($may_cache) */ function nodereference_field_info() { return array( - 'nodereference' => array('label' => 'Node Reference'), + 'nodereference' => array('label' => t('Node Reference')), + 'nodereferrers' => array('label' => t('Node Referrers')), ); } @@ -43,8 +49,8 @@ function nodereference_field_info() { * Implementation of hook_field_settings(). */ function nodereference_field_settings($op, $field) { - switch ($op) { - case 'form': + switch ($field['type'] .'/'. $op) { + case 'nodereference/form': $form = array(); $form['referenceable_types'] = array( '#type' => 'checkboxes', @@ -55,10 +61,11 @@ function nodereference_field_settings($o ); return $form; - case 'save': + case 'nodereference/save': return array('referenceable_types'); - case 'database columns': + case 'nodereference/database columns': + case 'nodereferrers/database columns': $columns = array( 'nid' => array('type' => 'int', 'not null' => TRUE, 'default' => '0'), ); @@ -70,25 +77,46 @@ function nodereference_field_settings($o * Implementation of hook_field(). */ function nodereference_field($op, &$node, $field, &$node_field, $teaser, $page) { - switch ($op) { - case 'view': + switch ($field['type'] .'/'. $op) { + case 'nodereference/view': foreach ($node_field as $delta => $item) { - $node_field[$delta]['view'] = nodereference_field_view_item($field, $item, $node); + $node_field[$delta]['view'] = nodereference_field_view_item($field, $item); } return theme('field', $node, $field, $node_field, $teaser, $page); + + case 'nodereferrers/view': + // Note: Multiple values are not supported for nodereferrers fields. Would not make any sense. + $node_field[0]['view'] = nodereference_field_view_item($field, $node_field[0]); + return theme('field', $node, $field, $node_field, $teaser, $page); + + case 'nodereferrers/insert': + // Assign the node's nid to the referrers data. This helps retrieving the node's referrers. + $node_field[0]['nid'] = $node->nid; + return; } } /** * Implementation of hook_field_view_item(). */ -function nodereference_field_view_item($field, $node_field_item) { - if (!isset($node_field_item['nid'])) { +function nodereference_field_view_item($field, $item) { + if (!isset($item['nid'])) { return ''; } - $referenced_node = node_load($node_field_item['nid']); - if ($referenced_node) { - return l($referenced_node->title, 'node/'. $referenced_node->nid); + switch($field['type']) { + case 'nodereference': + $referenced_node = node_load($item['nid']); + if ($referenced_node) { + return theme('nodereference', $field, $referenced_node); + } + break; + + case 'nodereferrers': + $referrers = nodereference_get_referrers($item['nid']); // Should/could these be retrieved on hook_field($op='load')? + foreach($referrers as $referrer) { + $output .= theme('nodereference', $field, $referrer); + } + return $output; } } @@ -99,13 +127,17 @@ function nodereference_field_view_item($ function nodereference_widget_info() { return array( 'nodereference_select' => array( - 'label' => 'Select List', + 'label' => t('Select List'), 'field types' => array('nodereference'), ), 'nodereference_autocomplete' => array( - 'label' => 'Autocomplete Text Field', + 'label' => t('Autocomplete Text Field'), 'field types' => array('nodereference'), ), + 'nodereferrers_list' => array( + 'label' => t('Read-Only List'), + 'field types' => array('nodereferrers'), + ), ); } @@ -113,112 +145,117 @@ function nodereference_widget_info() { * Implementation of hook_widget(). */ function nodereference_widget($op, &$node, $field, &$node_field) { - if ($field['widget']['type'] == 'nodereference_select') { - switch ($op) { - case 'prepare form values': - $node_field_transposed = content_transpose_array_rows_cols($node_field); - $node_field['default nids'] = $node_field_transposed['nid']; - break; - - case 'form': - $form = array(); - - $form[$field['field_name']] = array('#tree' => TRUE); - $form[$field['field_name']]['nids'] = array( - '#type' => 'select', - '#title' => t($field['widget']['label']), - '#default_value' => $node_field['default nids'], - '#multiple' => $field['multiple'], - '#options' => _nodereference_potential_references($field), - '#required' => $field['required'], - '#description' => $field['widget']['description'], + switch($field['widget']['type'] .'/'. $op) { + case 'nodereference_select/prepare form values': + $node_field_transposed = content_transpose_array_rows_cols($node_field); + $node_field['default nids'] = $node_field_transposed['nid']; + break; + + case 'nodereference_select/form': + $form = array(); + + $form[$field['field_name']] = array('#tree' => TRUE); + $form[$field['field_name']]['nids'] = array( + '#type' => 'select', + '#title' => t($field['widget']['label']), + '#default_value' => $node_field['default nids'], + '#multiple' => $field['multiple'], + '#options' => _nodereference_potential_references($field), + '#required' => $field['required'], + '#description' => $field['widget']['description'], ); + return $form; - return $form; + case 'nodereference_select/process form values': + if ($field['multiple']) { + $node_field = content_transpose_array_rows_cols(array('nid' => $node_field['nids'])); + } + else { + $node_field[0]['nid'] = $node_field['nids']; + } + // Remove the widget's data representation so it isn't saved. + unset($node_field['nids']); + break; + + case 'nodereference_autocomplete/prepare form values': + foreach ($node_field as $delta => $item) { + $node_field[$delta]['default node_name'] = db_result(db_query(db_rewrite_sql('SELECT n.title FROM {node} n WHERE n.nid = %d'), $node_field[$delta]['nid'])); + } + break; - case 'process form values': - if ($field['multiple']) { - $node_field = content_transpose_array_rows_cols(array('nid' => $node_field['nids'])); - } - else { - $node_field[0]['nid'] = $node_field['nids']; - } - // Remove the widget's data representation so it isn't saved. - unset($node_field['nids']); - } - } - else { - switch ($op) { - case 'prepare form values': - foreach ($node_field as $delta => $item) { - $node_field[$delta]['default node_name'] = db_result(db_query(db_rewrite_sql('SELECT n.title FROM {node} n WHERE n.nid = %d'), $node_field[$delta]['nid'])); - } - break; + case 'nodereference_autocomplete/form': + $form = array(); + $form[$field['field_name']] = array('#tree' => TRUE); - case 'form': - $form = array(); - $form[$field['field_name']] = array('#tree' => TRUE); - - if ($field['multiple']) { - $form[$field['field_name']]['#type'] = 'fieldset'; - $form[$field['field_name']]['#title'] = t($field['widget']['label']); - $form[$field['field_name']]['#description'] = $field['widget']['description']; - $delta = 0; - foreach ($node_field as $item) { - if ($item['nid']) { - $form[$field['field_name']][$delta]['node_name'] = array( - '#type' => 'textfield', - '#title' => '', - '#autocomplete_path' => 'nodereference/autocomplete/'. $field['field_name'], - '#default_value' => $item['default node_name'], - '#required' => ($delta == 0) ? $field['required'] : FALSE, - ); - $delta++; - } - } - foreach (range($delta, $delta + 2) as $delta) { + if ($field['multiple']) { + $form[$field['field_name']]['#type'] = 'fieldset'; + $form[$field['field_name']]['#title'] = t($field['widget']['label']); + $form[$field['field_name']]['#description'] = $field['widget']['description']; + $delta = 0; + foreach ($node_field as $item) { + if ($item['nid']) { $form[$field['field_name']][$delta]['node_name'] = array( '#type' => 'textfield', '#title' => '', '#autocomplete_path' => 'nodereference/autocomplete/'. $field['field_name'], - '#default_value' => '', + '#default_value' => $item['default node_name'], '#required' => ($delta == 0) ? $field['required'] : FALSE, - ); + ); + $delta++; } } - else { - $form[$field['field_name']][0]['node_name'] = array( + foreach (range($delta, $delta + 2) as $delta) { + $form[$field['field_name']][$delta]['node_name'] = array( '#type' => 'textfield', - '#title' => t($field['widget']['label']), + '#title' => '', '#autocomplete_path' => 'nodereference/autocomplete/'. $field['field_name'], - '#default_value' => $node_field[0]['default node_name'], - '#required' => $field['required'], - '#description' => $field['widget']['description'], - ); + '#default_value' => '', + '#required' => ($delta == 0) ? $field['required'] : FALSE, + ); } - return $form; + } + else { + $form[$field['field_name']][0]['node_name'] = array( + '#type' => 'textfield', + '#title' => t($field['widget']['label']), + '#autocomplete_path' => 'nodereference/autocomplete/'. $field['field_name'], + '#default_value' => $node_field[0]['default node_name'], + '#required' => $field['required'], + '#description' => $field['widget']['description'], + ); + } + return $form; - case 'validate': - foreach ($node_field as $delta => $item) { - if ($item['node_name'] && !in_array($item['node_name'], _nodereference_potential_references($field))) { - form_set_error($field['field_name'], t('No post with that title exists.')); - } + case 'nodereference_autocomplete/validate': + foreach ($node_field as $delta => $item) { + if ($item['node_name'] && !in_array($item['node_name'], _nodereference_potential_references($field))) { + form_set_error($field['field_name'], t('No post with that title exists.')); } - return; + } + return; - case 'process form values': - foreach ($node_field as $delta => $item) { - $nid = db_result(db_query(db_rewrite_sql("SELECT n.nid FROM {node} n WHERE n.title = '%s'"), $node_field[$delta]['node_name'])); - // Remove the widget's data representation so it isn't saved. - unset($node_field[$delta]['node_name']); - if ($nid) { - $node_field[$delta]['nid'] = $nid; - } - else { - unset($node_field[$delta]); - } + case 'nodereference_autocomplete/process form values': + foreach ($node_field as $delta => $item) { + $nid = db_result(db_query(db_rewrite_sql("SELECT n.nid FROM {node} n WHERE n.title = '%s'"), $node_field[$delta]['node_name'])); + // Remove the widget's data representation so it isn't saved. + unset($node_field[$delta]['node_name']); + if ($nid) { + $node_field[$delta]['nid'] = $nid; } - } + else { + unset($node_field[$delta]); + } + } + break; + + case 'nodereferrers_list/form': + $form = array(); + $form[$field['field_name']] = array('#tree' => TRUE); + $form[$field['field_name']][0]['nid'] = array( + '#type' => 'hidden', + '#value' => $node->nid, + ); + return $form; } } @@ -261,20 +298,27 @@ function _nodereference_potential_refere return $rows; } -function nodereference_referenced_by_list($nid, $content_type = '') { - if ($content_type) { - $result = db_query("SELECT n.* FROM {node_field_nodereference_data} node_ref INNER JOIN {node} n ON n.vid = node_ref.vid AND n.type = '%s' WHERE node_ref.field_nid = %d ORDER BY delta", $nid, $content_type); - } - else { - $result = db_query("SELECT n.* FROM {node_field_nodereference_data} node_ref INNER JOIN {node} n ON n.vid = node_ref.vid WHERE node_ref.field_nid = %d ORDER BY delta", $nid); - } - +function nodereference_get_referrers($nid, $content_type = '') { + // Retrieve the fields in order to find the field names of all nodereference fields + $fields = content_fields(); $values = array(); - - while ($value = db_fetch_object($result)) { - $values[] = $value; + foreach($fields as $field) { + if ($field['type'] == 'nodereference') { + $db_info = content_database_info($field); + + // Gather the nodereferences that refer to $nid + //TODO: Should probably collect only nids and call node_load(). + if ($content_type) { + $result = db_query("SELECT n.* FROM {" . $db_info['table'] . "} nr INNER JOIN {node} n ON n.vid = nr.vid AND n.type = '%s' AND n.status = 1 WHERE nr." . $db_info['columns']['nid']['column'] . " = %d ORDER BY n.created DESC", $content_type, $nid); + } + else { + $result = db_query("SELECT n.* FROM {" . $db_info['table'] . "} nr INNER JOIN {node} n ON n.vid = nr.vid AND n.status = 1 WHERE nr." . $db_info['columns']['nid']['column'] . " = %d ORDER BY n.created DESC", $nid); + } + while ($value = db_fetch_object($result)) { + $values[$value->nid] = $value; // Note: Using nid as key to avoid duplicate referrers + } + } } - return $values; } @@ -294,4 +338,8 @@ function nodereference_autocomplete($fie print drupal_to_js($matches); exit(); +} + +function theme_nodereference($field, $node) { + return '
'. l($node->title, 'node/'. $node->nid) .'
'; } \ No newline at end of file