--- untitled +++ (clipboard) @@ -11,7 +11,7 @@ function nodereference_url_theme() { return array( 'nodereference_url' => array( - 'arguments' => array('element' => NULL), + 'render element' => 'element', ), ); } @@ -31,26 +31,35 @@ /** * Implements hook_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( + 'fallback' => 'select', + 'node_link' => array(), + 'edit_fallback' => 0, ), + 'behaviors' => array( + 'multiple values' => FIELD_BEHAVIOR_DEFAULT, + 'default value' => FIELD_BEHAVIOR_DEFAULT, + ), ), ); } /** - * Implements hook_link(). + * Implements hook_node_view(). */ -function nodereference_url_link($type, $object, $teaser = FALSE) { - if ($type == 'node') { - return nodereference_url_build_all_links($object, $teaser); - } +function nodereference_url_node_view($node, $view_mode, $langcode) { + $links = nodereference_url_build_all_links($node, $view_mode); + $node->content['links']['nodereference_url'] = array( + '#theme' => 'links__node__nodereference', + '#links' => $links, + '#attributes' => array('class' => array('links', 'inline')), + ); } /** @@ -63,15 +72,16 @@ * @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) { + $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 (isset($link_settings[$view_mode])) { + $link = nodereference_url_build_link($node, $instance, $view_mode); + if ($link) { $links[$target_type .'_'. $field_name] = $link; } } @@ -98,28 +108,28 @@ * @return * An array containing properties to build a single link. */ -function nodereference_url_build_link($node, $field, $teaser = FALSE) { - $view_mode = $teaser ? 'teaser' : 'full'; +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); + 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); } // Otherwise restrict by node type. else { - $referenceable = !empty($field['referenceable_types'][$node->type]); + $field_info = field_info_field($field['field_name']); + $referenceable = !empty($field_info['settings']['referenceable_types'][$node->type]); } - if ($referenceable && node_access('create', $field['type_name'])) { - $link_settings = $field['widget']['node_link']; + if ($referenceable && node_access('create', $field['bundle'])) { + $link_settings = $field['widget']['settings']['node_link']; if (!empty($link_settings[$view_mode])) { // Get the first "preferred" path for creating Node Reference links. $link_urls = variable_get('nodereference_url_paths', array('node/add/%type/%nid')); // Basic wildcard replacement: %type and %nid. $link_url = $link_urls[0]; - $link_url = str_replace('%type', str_replace('_', '-', $field['type_name']), $link_url); + $link_url = str_replace('%type', str_replace('_', '-', $field['bundle']), $link_url); $link_url = str_replace('%nid', $node->nid, $link_url); $link = array( @@ -134,21 +144,20 @@ $link['query'] = drupal_get_destination(); } elseif ($link_settings['destination'] == 'node') { - $link['query'] = 'destination='. urlencode(drupal_get_path_alias('node/'. $node->nid)); + $link['query'] = array('destination' => drupal_get_path_alias('node/'. $node->nid)); } } if (module_exists('og')) { // First try to get context based on the current page URL. - $group_node = og_get_group_context(); + $group_entity = og_get_context_by_url(); // Otherwise try getting the context based on the node being referenced. - if (!$group_node) { - $group_node = og_determine_context_get_group($node); + if (!$group_entity) { + $group_entity = og_context(); } - if ($group_node) { - $link['query'] = isset($link['query']) ? $link['query'] . '&' : ''; - $link['query'] .= 'gids[]=' . $group_node->nid; + if ($group_entity) { + $link['query']['gids'] = $group_entity->gid; } } } @@ -190,21 +199,7 @@ } /** - * Helper function to retrieve all instances of a field. - */ -function _nodereference_url_field_instances($field_name) { - $info = _content_type_info(); - $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]; - } - } - return $instances; -} - -/** - * Implements FAPI hook_elements(). + * Implements of hook_elements_info(). * * Any FAPI callbacks needed for individual widgets can be declared here, * and the element will be passed to those callbacks for processing. @@ -215,31 +210,26 @@ * Autocomplete_path is not used by text_widget but other widgets can use it * (see nodereference and userreference). */ -function nodereference_url_elements() { +function nodereference_url_element_info() { return array( 'nodereference_url' => array( '#input' => TRUE, '#columns' => array('nid'), '#delta' => 0, '#process' => array('_nodereference_url_process'), + '#theme' => 'nodereference_url', + '#theme_wrappers' => array('form_element'), ), ); } /** - * Implements hook_widget_settings(). + * Implements hook_field_widget_settings_form(). */ -function nodereference_url_widget_settings($op, $widget) { - switch ($op) { - case 'form': - return node_reference_url_field_widget_settings_form($widget); - case 'save': - return array('node_link', 'fallback', 'edit_fallback'); - } -} - -function nodereference_url_field_widget_settings_form($widget) { - $settings = $widget; +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') { @@ -256,13 +246,13 @@ '#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'), - '#weight' => -3, + '#weight' => -11, ); $form['edit_fallback'] = array( '#type' => 'checkbox', '#title' => t('Use fallback behavior when editing content'), '#default_value' => isset($settings['edit_fallback']) ? $settings['edit_fallback'] : FALSE, - '#weight' => -2, + '#weight' => -10, ); $form['node_link'] = array( @@ -310,10 +300,17 @@ } /** + * Implements hook_field_widget_error(). + */ +function nodereference_url_field_widget_error($element, $error, $form, &$form_state) { + form_error($element['nid'], $error['message']); +} + +/** * Element validation function to ensure invalid options are not selected. */ function nodereference_url_fallback_validate($element, &$form_state) { - if ($form_state['values']['required'] && $form_state['values']['fallback'] == 'leave_blank') { + if ($form_state['values']['instance']['required'] && $form_state['values']['instance']['widget']['settings']['fallback'] == 'leave_blank') { form_error($element, t('The fallback behavior cannot be left blank if this field is also required.')); } } @@ -331,22 +328,21 @@ /** * Element validation function that makes title required when creating a link. */ -function nodereference_url_node_link_validate($element, &$form_state) { - $link_settings = $form_state['values']['node_link']; +function nodereference_url_node_link_validate($element, &$form_state, $form) { + $link_settings = $form_state['values']['instance']['widget']['settings']['node_link']; if (($link_settings['teaser'] || $link_settings['full']) && empty($link_settings['title'])) { form_error($element['title'], t('A link title must be specified if creating links on referenceable content.')); } } /** - * Implements hook_widget(). + * Implements hook_field_widget_form(). */ -function nodereference_url_widget(&$form, &$form_state, $field, $items, $delta = 0) { - $element = array('#tree' => TRUE); +function nodereference_url_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) { $field_name = $field['field_name']; $field_name_url = preg_replace('/^field_/', '', $field_name); $referenced_nid = NULL; - $fallback = $field['widget']['fallback']; + $fallback = $instance['widget']['settings']['fallback']; // Check for an existing NID. if (isset($items[$delta]['nid']) && is_numeric($items[$delta]['nid'])) { @@ -363,14 +359,14 @@ // Check that the NID is a valid reference. if (!empty($referenced_nid)) { - $reference = _nodereference_potential_references($field, '', 'equals', array($referenced_nid), 1); + $reference = _node_reference_potential_references($field, '', 'equals', array($referenced_nid), 1); if (empty($reference)) { $referenced_nid = NULL; } } // If no NID is available or editing this field, use the fallback behavior. - if (empty($referenced_nid) || (!empty($field['widget']['edit_fallback']) && !empty($items))) { + if (empty($referenced_nid) || (!empty($instance['widget']['settings']['edit_fallback']) && !empty($items))) { // 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 (in_array($fallback, array('page_not_found', 'leave_blank')) && nodereference_url_get_nid($field_name) === FALSE) { @@ -380,33 +376,34 @@ // 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 ($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'); + if ($fallback == 'page_not_found') { + drupal_set_message(t('To create a new @type, a referenced piece of content must be specified in the link you followed.', array('@type' => $field['bundles']['node'][0])), 'error'); drupal_not_found(); exit(); } // Fallback to select list. elseif ($fallback == 'select') { - $element = array( - '#type' => 'nodereference_select', - '#default_value' => $items, - '#after_build' => array('_nodereference_url_process_select'), + $element += array( + '#type' => 'select', + '#default_value' => isset($items[$delta]['nid']) ? $items[$delta]['nid'] : NULL, + '#options' => array('' => t('- None -')) + node_reference_options_list($field), ); } // Fallback to autocomplete. elseif ($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'), + $element += array( + '#type' => 'textfield', + '#default_value' => isset($items[$delta]['nid']) ? $items[$delta]['nid'] : NULL, + '#autocomplete_path' => 'node_reference/autocomplete/' . $instance['entity_type'] . '/' . $field['field_name'], + '#value_callback' => 'node_reference_autocomplete_value', + '#element_validate' => array('node_reference_autocomplete_validate'), ); } } if (isset($referenced_nid) && (empty($element['#type']))) { - $element[$delta]['nid'] = array( - '#title' => $field['widget']['label'], + $element['nid'] = array( + '#title' => $instance['label'], '#type' => 'nodereference_url', '#field_name' => $field_name, '#default_value' => $referenced_nid, @@ -422,7 +419,7 @@ * Build the form element. When creating a form using FAPI #process, * note that $element['#value'] is already set. */ -function _nodereference_url_process($element, $edit, $form_state, $form) { +function _nodereference_url_process($element, $form_state, $form) { if (isset($element['#value']) && is_numeric($element['#value']) && ($node = node_load($element['#value']))) { $element['#display_title'] = $node->title; } @@ -440,22 +437,6 @@ } /** - * An #after_build function used to add an empty value to the list of options. - * - * Normally CCK would do this in optionwidgets_options(), but since the widget - * type "nodereference_url" isn't known by it, we have to add it manually. - */ -function _nodereference_url_process_select($element, $form_state) { - if (isset($element['nid']['nid']['#options'])) { - $field = content_fields($element['#field_name'], $element['#type_name']); - $field['widget']['type'] = 'optionwidgets_select'; - $element['nid']['nid']['#options'] = array('' => theme('optionwidgets_none', $field)) + $element['nid']['nid']['#options']; - } - - return $element; -} - -/** * Check the current URL and pull the referenced node from it. */ function nodereference_url_get_nid($field_name) { @@ -504,6 +485,7 @@ * $element['#field_name'] contains the field name. * $element['#delta] is the position of this element in the group. */ -function theme_nodereference_url($element) { - return theme('form_element', $element, $element['#display_title']); +function theme_nodereference_url($variables) { + $element = $variables['element']; + return $element['#display_title']; }