Index: nodereference_url.info =================================================================== RCS file: /cvs/drupal/contributions/modules/nodereference_url/nodereference_url.info,v retrieving revision 1.1 diff -u -r1.1 nodereference_url.info --- nodereference_url.info 22 Jan 2009 02:25:29 -0000 1.1 +++ nodereference_url.info 16 Feb 2010 23:05:46 -0000 @@ -1,6 +1,8 @@ ; $Id: nodereference_url.info,v 1.1 2009/01/22 02:25:29 quicksketch Exp $ name = Node Reference URL Widget -description = Adds an additional widget to the CCK Node Reference field that prepopulates a reference by the URL. -dependencies[] = nodereference +description = Adds an additional widget to the Node Reference Field that prepopulates a reference by the URL. package = CCK -core = 6.x \ No newline at end of file +core = 7.x +version = "7.x-1.x-dev" +dependencies[] = node_reference +files[]=nodereference_url.module Index: nodereference_url.module =================================================================== RCS file: /cvs/drupal/contributions/modules/nodereference_url/nodereference_url.module,v retrieving revision 1.19 diff -u -r1.19 nodereference_url.module --- nodereference_url.module 7 Jan 2010 05:15:06 -0000 1.19 +++ nodereference_url.module 16 Feb 2010 23:05:47 -0000 @@ -29,28 +29,201 @@ } /** - * Implementation of hook_widget_info(). + * Implements hook_field_widget_info(). */ -function nodereference_url_widget_info() { +function nodereference_url_field_widget_info() { return array( 'nodereference_url' => array( 'label' => t('Reference from URL'), - 'field types' => array('nodereference'), - 'multiple values' => CONTENT_HANDLE_MODULE, - 'callbacks' => array( - 'default value' => CONTENT_CALLBACK_NONE, - ), + 'description' => t('Node Reference calculated from URL'), + 'field types' => array('node_reference'), + 'settings' => array(), + 'behaviors' => array( + 'multiple values' => FIELD_BEHAVIOR_DEFAULT, + 'defaul value' => FIELD_BEHAVIOR_DEFAULT, + ), ), ); } /** - * Implementation of hook_link(). + * Implements hook_field_widget_info_alter(). */ -function nodereference_url_link($type, $object, $teaser = FALSE) { - if ($type == 'node') { - return nodereference_url_build_all_links($object, $teaser); +function nodereference_url_field_widget_info_alter(&$info) { + $info['options_select']['field types'][] = 'node_reference'; + $info['options_buttons']['field types'][] = 'node_reference'; +} + +/** + * Implementation of hook_widget_settings(). + */ +function nodereference_url_field_widget_settings_form($field, $instance) { + $widget = $instance['widget']; + $defaults = field_info_widget_settings($widget['type']); + $settings = array_merge($defaults, $widget['settings']); + + $form = array(); + if ($widget['type'] == 'nodereference_url') { + $form['fallback'] = array( + '#type' => 'radios', + '#title' => t('Fallback behavior'), + '#options' => array( + 'page_not_found' => t('Display page not found error'), + 'select' => t('Use select list widget'), + 'autocomplete' => t('Use autocomplete widget'), + 'leave_blank' => t('Leave the field blank'), + ), + '#default_value' => isset($settings['fallback']) ? $settings['fallback'] : 'page_not_found', + '#description' => t('If no content is referenced in the URL, determine how the form should be handled.'), + '#required' => TRUE, + '#element_validate' => array('nodereference_url_fallback_validate'), + ); + + $form['node_link'] = array( + '#tree' => TRUE, + '#type' => 'fieldset', + '#title' => t('Referenceable node links'), + '#element_validate' => array('nodereference_url_node_link_validate'), + '#description' => t('These settings will automatically make a link on nodes that can be referenced. Clicking the link will take the user to the new node form and prepopulate the value of this node reference field.'), + ); + $form['node_link']['teaser'] = array( + '#type' => 'checkbox', + '#title' => t('Create link on the teaser view'), + '#default_value' => isset($settings['node_link']['teaser']) ? $settings['node_link']['teaser'] : FALSE, + ); + $form['node_link']['full'] = array( + '#type' => 'checkbox', + '#title' => t('Create link on the full view'), + '#default_value' => isset($settings['node_link']['full']) ? $settings['node_link']['full'] : TRUE, + ); + $form['node_link']['title'] = array( + '#type' => 'textfield', + '#title' => t('Link title'), + '#default_value' => isset($settings['node_link']['title']) ? $settings['node_link']['title'] : '', + '#description' => t('The title is the visible text for the link. This is required if you enable the content links.'), + ); + $form['node_link']['hover_title'] = array( + '#type' => 'textfield', + '#title' => t('Link hover title'), + '#default_value' => isset($settings['node_link']['hover_title']) ? $settings['node_link']['hover_title'] : '', + '#description' => t('Text shown while hovering over the link.'), + ); + $form['node_link']['destination'] = array( + '#type' => 'select', + '#title' => t('Return path'), + '#default_value' => isset($settings['node_link']['destination']) ? $settings['node_link']['destination'] : 'default', + '#options' => array( + 'default' => t('The new node (no redirect)'), + 'node' => t('The referenced node'), + 'source' => t('The previous page'), + ), + '#description' => t('After creating the new node through the link, determine where the user should be redirected.'), + ); } + return $form; +} + + +/** + * Implements hook_field_widget_error(). + */ +function nodereference_url_field_widget_error($element, $error) { + form_error($element['nid'], $error['message']); +} + +/** + * Implementation of hook_field_widget_form(). + * TODO JPH : remove notice & warning + */ +function nodereference_url_field_widget_form(&$form, &$form_state, $field, $items, $delta = 0) { + $element = array('#tree' => TRUE); + $field_name = $field['field_name']; + $field_name_url = preg_replace('/^field_/', '', $field_name); + + // Check for an existing NID or pull it from the URL. + if (isset($items[0]['nid']) && is_numeric($items[0]['nid'])) { + $referenced_nid = $items[0]['nid']; + } + elseif (arg(0) == 'node' && arg(1) == 'add' && isset($_GET[$field_name_url])) { + $referenced_nid = is_numeric($_GET[$field_name_url]) ? $_GET[$field_name_url] : NULL; + } + elseif (arg(0) == 'node' && arg(1) == 'add') { + $referenced_nid = is_numeric(arg(3)) ? arg(3) : NULL; + } + + // + $valid_types = array(); + foreach ($field[$settings][$referenceable_types] as $type => $value) { + if ($value != 0) { + $valid_types[]=$key; + } + } + $referenced_node = node_load($reference_nid); + // Check that the NID is a valid reference. + if (isset($referenced_nid)) { + if (!in_array($node->type,$valid_types)) { + unset($referenced_nid); + } + } + + // If no NID is available, use the fallback behavior. + if (!isset($referenced_nid)) { + // If not on a node/add page (such as editing a node that does not yet have + // a reference), switch to using an autocomplete widget. + if ($field['widget']['fallback'] == 'page_not_found' && arg(0) == 'node' && is_numeric(arg(1))) { + $field['widget']['fallback'] = 'autocomplete'; + } + + // Page not found error. + // Check for the form_build_id to prevent throwing a page not found on + // manual builds. See http://drupal.org/node/397606. + if ($field['widget']['fallback'] == 'page_not_found' && isset($form['form_build_id'])) { + drupal_set_message(t('To create a new @type, a referenced piece of content must be specified in the link you followed.', array('@type' => node_get_types('name', $field['type_name']))), 'error'); + drupal_not_found(); + exit(); + } + // Fallback to select list. + elseif ($field['widget']['fallback'] == 'select') { + $element = array( + '#type' => 'nodereference_select', + '#default_value' => $items, + '#after_build' => array('nodereference_url_process_select'), + ); + } + // Fallback to autocomplete. + elseif ($field['widget']['fallback'] == 'autocomplete') { + $element = array( + '#type' => 'nodereference_autocomplete', + '#default_value' => isset($items[$delta]) ? $items[$delta] : NULL, + '#value_callback' => 'nodereference_autocomplete_value', + '#element_validate' => array('nodereference_url_autocomplete_validate'), + ); + } + // Fallback to an empty field. + else { + $referenced_nid = ''; + } + } + + if (isset($referenced_nid)) { + $element[0]['nid'] = array( + '#title' => $field['widget']['label'], + '#type' => 'nodereference_url', + '#field_name' => $field_name, + '#default_value' => $referenced_nid, + ); + } + + return $element; +} + +function nodereference_url_node_view($node, $view_mode) { + $links = _nodereference_url_build_all_links($node, $view_mode); + $node->content['links']['blog'] = array( + '#theme' => 'links', + '#links' => $links, + '#attributes' => array('class' => array('links', 'inline')), + ); } /** @@ -59,19 +232,21 @@ * @param $node * A fully loaded node object. * @param $teaser - * + * * @return * An array of links for use with theme_links(). */ -function nodereference_url_build_all_links($node, $teaser) { +function _nodereference_url_build_all_links($node, $view_mode) { $links = array(); - $fields = content_fields(); - foreach ($fields as $field_name => $field) { - foreach (_nodereference_url_field_instances($field_name) as $target_type => $instance) { + //check if the type is one of referenced fields. + $fields = field_info_instances('node'); + foreach ($fields as $target_type => $field) { + foreach ($field as $field_name => $instance) { if ($instance['widget']['type'] == 'nodereference_url') { - $link_settings = $instance['widget']['node_link']; - if (($link_settings['teaser'] && $teaser == TRUE) || ($link_settings['full'] && $teaser == FALSE)) { - if ($link = nodereference_url_build_link($node, $instance, $teaser)) { + $link_settings = $instance['widget']['settings']['node_link']; + if ( $link_settings[$view_mode] ) { + $link = _nodereference_url_build_link($node, $instance, $view_mode); + if ($link) { $links[$target_type .'_'. $field_name] = $link; } } @@ -92,45 +267,46 @@ * A fully loaded node object. * @param $field * A CCK field instance. - * @param $teaser - * Optional. The current display mode of the node. Defaults to FALSE. + * @param $view_mode + * The current display mode of the node. * * @return * An array containing properties to build a single link. */ -function nodereference_url_build_link($node, $field, $teaser = FALSE) { +function _nodereference_url_build_link($node, $field, $view_mode) { $link = array(); - // Check if this widget is using a views listing. - if (module_exists('views') && !empty($field['advanced_view']) && $field['advanced_view'] != '--') { - $referenceable = (bool) _nodereference_potential_references_views($field, '', NULL, array($node->nid), 1); - } - // Otherwise restrict by node type. - else { - $referenceable = !empty($field['referenceable_types'][$node->type]); + if (module_exists('views') && isset($field['advanced_view']) && !empty($field['advanced_view']) && $field['advanced_view'] != '--') { + $referenceable = (bool) _node_reference_potential_references($field, '', NULL, array($node->nid), 1); + } else { + // Otherwise, + // Seems referenceables_types are no more present in this case... + // For now, make it true by default. + // TODO JPH : restrict by node type. + // + $referenceable = true; //!empty($field['referenceable_types'][$node->type]); } - if ($referenceable && node_access('create', $field['type_name'])) { - $link_settings = $field['widget']['node_link']; - if ((!empty($link_settings['teaser']) && $teaser == TRUE) || (!empty($link_settings['full']) && $teaser == FALSE)) { + if ($referenceable && node_access('create', $field['bundle'])) { + $link_settings = $field['widget']['settings']['node_link']; + if ( !empty($link_settings[$view_mode]) ) { $link = array( 'title' => t($link_settings['title']), - 'href' => 'node/add/'. str_replace('_', '-', $field['type_name']) .'/'. $node->nid, + 'href' => 'node/add/'. str_replace('_', '-', $field['bundle']) .'/'. $node->nid, ); if (!empty($link_settings['hover_title'])) { $link['attributes']['title'] = t($link_settings['hover_title']); } if (!empty($link_settings['destination'])) { if ($link_settings['destination'] == 'source') { - $link['query'] = drupal_get_destination(); + $link['query'] = array ( 'destination' => drupal_get_destination()); } elseif ($link_settings['destination'] == 'node') { - $link['query'] = 'destination='. urlencode(drupal_get_path_alias('node/'. $node->nid)); + $link['query'] = array ('destination' => urlencode(drupal_get_path_alias('node/'. $node->nid)) ); } } if (module_exists('og') && $group_node = og_determine_context_get_group($node)) { - $link['query'] = isset($link['query']) ? $link['query'] . '&' : ''; - $link['query'] .= 'gids[]=' . $group_node->nid; + $link['query']['gids'] = $group_node->nid; } } } @@ -173,12 +349,14 @@ /** * Helper function to retrieve all instances of a field. */ -function _nodereference_url_field_instances($field_name) { - $info = _content_type_info(); +function _nodereference_url_field_instances($node_type) { + $info = field_info_instances('node'); $instances = array(); - foreach (node_get_types('names') as $node_type => $node_type_name) { - if (isset($info['content types'][$node_type]['fields'][$field_name])) { - $instances[$node_type] = $info['content types'][$node_type]['fields'][$field_name]; + foreach ($info as $node_type => $fields) { + foreach ($fields as $fieldname => $fielddata) { + if ($field_name == $fieldname) { + $instances[$node_type] = $fielddata; + } } } return $instances; @@ -207,76 +385,6 @@ ); } -/** - * Implementation of hook_widget_settings(). - */ -function nodereference_url_widget_settings($op, $widget) { - switch ($op) { - case 'form': - $form = array(); - if ($widget['type'] == 'nodereference_url') { - $form['fallback'] = array( - '#type' => 'radios', - '#title' => t('Fallback behavior'), - '#options' => array( - 'page_not_found' => t('Display page not found error'), - 'select' => t('Use select list widget'), - 'autocomplete' => t('Use autocomplete widget'), - 'leave_blank' => t('Leave the field blank'), - ), - '#default_value' => isset($widget['fallback']) ? $widget['fallback'] : 'page_not_found', - '#description' => t('If no content is referenced in the URL, determine how the form should be handled.'), - '#required' => TRUE, - '#element_validate' => array('nodereference_url_fallback_validate'), - ); - - $form['node_link'] = array( - '#tree' => TRUE, - '#type' => 'fieldset', - '#title' => t('Referenceable node links'), - '#element_validate' => array('nodereference_url_node_link_validate'), - '#description' => t('These settings will automatically make a link on nodes that can be referenced. Clicking the link will take the user to the new node form and prepopulate the value of this node reference field.'), - ); - $form['node_link']['teaser'] = array( - '#type' => 'checkbox', - '#title' => t('Create link on the teaser view'), - '#default_value' => isset($widget['node_link']['teaser']) ? $widget['node_link']['teaser'] : FALSE, - ); - $form['node_link']['full'] = array( - '#type' => 'checkbox', - '#title' => t('Create link on the full view'), - '#default_value' => isset($widget['node_link']['full']) ? $widget['node_link']['full'] : TRUE, - ); - $form['node_link']['title'] = array( - '#type' => 'textfield', - '#title' => t('Link title'), - '#default_value' => isset($widget['node_link']['title']) ? $widget['node_link']['title'] : '', - '#description' => t('The title is the visible text for the link. This is required if you enable the content links.'), - ); - $form['node_link']['hover_title'] = array( - '#type' => 'textfield', - '#title' => t('Link hover title'), - '#default_value' => isset($widget['node_link']['hover_title']) ? $widget['node_link']['hover_title'] : '', - '#description' => t('Text shown while hovering over the link.'), - ); - $form['node_link']['destination'] = array( - '#type' => 'select', - '#title' => t('Return path'), - '#default_value' => isset($widget['node_link']['destination']) ? $widget['node_link']['destination'] : 'default', - '#options' => array( - 'default' => t('The new node (no redirect)'), - 'node' => t('The referenced node'), - 'source' => t('The previous page'), - ), - '#description' => t('After creating the new node through the link, determine where the user should be redirected.'), - ); - } - return $form; - - case 'save': - return array('node_link', 'fallback'); - } -} /** * Element validation function to ensure invalid options are not selected. @@ -293,7 +401,7 @@ * This function doesn't actually validate, it just reformats form_state value * into an array of a suitable format for nodereference module */ -function nodereference_url_autocomplete_validate($element, &$form_state) { +function nodereference_url_autocomplete_validate($element, &$form_state, $form) { form_set_value($element, array($form_state['values'][$element['#field_name']]), $form_state); } @@ -307,83 +415,7 @@ } } -/** - * Implementation of hook_widget(). - */ -function nodereference_url_widget(&$form, &$form_state, $field, $items, $delta = 0) { - $element = array('#tree' => TRUE); - $field_name = $field['field_name']; - $field_name_url = preg_replace('/^field_/', '', $field_name); - // Check for an existing NID or pull it from the URL. - if (isset($items[0]['nid']) && is_numeric($items[0]['nid'])) { - $referenced_nid = $items[0]['nid']; - } - elseif (arg(0) == 'node' && arg(1) == 'add' && isset($_GET[$field_name_url])) { - $referenced_nid = is_numeric($_GET[$field_name_url]) ? $_GET[$field_name_url] : NULL; - } - elseif (arg(0) == 'node' && arg(1) == 'add') { - $referenced_nid = is_numeric(arg(3)) ? arg(3) : NULL; - } - - // Check that the NID is a valid reference. - if (isset($referenced_nid)) { - $valid_options = optionwidgets_options($field); - if (!isset($valid_options[$referenced_nid])) { - unset($referenced_nid); - } - } - - // If no NID is available, use the fallback behavior. - if (!isset($referenced_nid)) { - // If not on a node/add page (such as editing a node that does not yet have - // a reference), switch to using an autocomplete widget. - if ($field['widget']['fallback'] == 'page_not_found' && arg(0) == 'node' && is_numeric(arg(1))) { - $field['widget']['fallback'] = 'autocomplete'; - } - - // Page not found error. - // Check for the form_build_id to prevent throwing a page not found on - // manual builds. See http://drupal.org/node/397606. - if ($field['widget']['fallback'] == 'page_not_found' && isset($form['form_build_id'])) { - drupal_set_message(t('To create a new @type, a referenced piece of content must be specified in the link you followed.', array('@type' => node_get_types('name', $field['type_name']))), 'error'); - drupal_not_found(); - exit(); - } - // Fallback to select list. - elseif ($field['widget']['fallback'] == 'select') { - $element = array( - '#type' => 'nodereference_select', - '#default_value' => $items, - '#after_build' => array('nodereference_url_process_select'), - ); - } - // Fallback to autocomplete. - elseif ($field['widget']['fallback'] == 'autocomplete') { - $element = array( - '#type' => 'nodereference_autocomplete', - '#default_value' => isset($items[$delta]) ? $items[$delta] : NULL, - '#value_callback' => 'nodereference_autocomplete_value', - '#element_validate' => array('nodereference_url_autocomplete_validate'), - ); - } - // Fallback to an empty field. - else { - $referenced_nid = ''; - } - } - - if (isset($referenced_nid)) { - $element[0]['nid'] = array( - '#title' => $field['widget']['label'], - '#type' => 'nodereference_url', - '#field_name' => $field_name, - '#default_value' => $referenced_nid, - ); - } - - return $element; -} /** * Process an individual element. @@ -391,26 +423,21 @@ * Build the form element. When creating a form using FAPI #process, * note that $element['#value'] is already set. * - * The $fields array is in $form['#field_info'][$element['#field_name']]. */ -function nodereference_url_process($element, $edit, $form_state, $form) { - $field_key = $element['#columns'][0]; - $field = $form['#field_info'][$element['#field_name']]; - - if (isset($element['#value']) && is_numeric($element['#value'])) { - $element['#display_title'] = _nodereference_titles($element['#value']); - } - else { - $element['#display_title'] = t('Referenced content not found.'); +function nodereference_url_process($form, $type) { + if ($type == 'field') { + if ( isset($form['field_type']) && $form['field_type'] == 'node_reference') { + $field_key = $form['field_name']; + $element = $form['element']; + $field=$form['object']->$field_key; + if (isset($element['#items'][0]['nid']) && is_numeric($element['#items'][0]['nid'])) { + $element['#title'] = _node_reference_get_node_titles(array($element['#items'][0]['nid'])); + } else { + $element['#title'] = t('Referenced content not found.'); + } + } } - - $element['nid'] = array( - '#type' => 'value', - '#value' => isset($element['#value']) ? $element['#value'] : $element['#value'], - '#parents' => $element['#parents'], - ); - - return $element; + return $form; } /** Index: nodereference_url.install =================================================================== RCS file: nodereference_url.install diff -N nodereference_url.install --- nodereference_url.install 25 Jul 2009 23:40:04 -0000 1.2 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,75 +0,0 @@ - $fields) { - foreach ($fields as $field) { - if ($field['type'] == 'nodereference' && $field['widget']['type'] == 'nodereference_url') { - // Widgets are each updated individually. - if (isset($field['widget']['node_link']['enabled'])) { - $field['widget']['node_link']['teaser'] = TRUE; - $field['widget']['node_link']['full'] = TRUE; - $field['widget']['node_link']['destination'] = 'default'; - unset($field['widget']['node_link']['enabled']); - - content_field_instance_update($field); - $ret[] = array('success' => TRUE, 'query' => t('Updated widget settings for @name.', array('@name' => $field['field_name']))); - } - } - } - } - - content_clear_type_cache(TRUE); - - return $ret; -} -