You are here

noderefcreate.module in Node Reference Create 6

Same filename and directory in other branches
  1. 7 noderefcreate.module

File

noderefcreate.module
View source
<?php

function noderefcreate_widget_info() {
  return array(
    'noderefcreate_autocomplete' => array(
      'label' => t('Autocomplete text field with create'),
      'field types' => array(
        'nodereference',
      ),
      'multiple values' => CONTENT_HANDLE_CORE,
      'callbacks' => array(
        'default value' => CONTENT_CALLBACK_DEFAULT,
      ),
    ),
  );
}
function noderefcreate_widget_settings($op, $widget) {
  switch ($op) {
    case 'form':
      $form = array();
      $match = isset($widget['autocomplete_match']) ? $widget['autocomplete_match'] : 'contains';
      if ($widget['type'] == 'noderefcreate_autocomplete') {
        $form['autocomplete_match'] = array(
          '#type' => 'select',
          '#title' => t('Autocomplete matching'),
          '#default_value' => $match,
          '#options' => array(
            'starts_with' => t('Starts with'),
            'contains' => t('Contains'),
          ),
          '#description' => t('Select the method used to collect autocomplete suggestions. Note that <em>Contains</em> can cause performance issues on sites with thousands of nodes.'),
        );
      }
      else {
        $form['autocomplete_match'] = array(
          '#type' => 'hidden',
          '#value' => $match,
        );
      }
      return $form;
    case 'save':
      return array(
        'autocomplete_match',
      );
  }
}
function noderefcreate_widget(&$form, &$form_state, $field, $items, $delta = 0) {
  switch ($field['widget']['type']) {
    case 'noderefcreate_autocomplete':
      $element = array(
        '#type' => 'nodereference_autocomplete',
        '#default_value' => isset($items[$delta]) ? $items[$delta] : NULL,
        '#value_callback' => 'nodereference_autocomplete_value',
        '#process' => array(
          'noderefcreate_autocomplete_process',
        ),
      );
      break;
  }
  return $element;
}
function noderefcreate_autocomplete_process($element, $edit, $form_state, $form) {

  // The nodereference autocomplete widget doesn't need to create its own
  // element, it can wrap around the text_textfield element and add an autocomplete
  // path and some extra processing to it.
  // Add a validation step where the value can be unwrapped.
  $field_key = $element['#columns'][0];
  $element[$field_key] = array(
    '#type' => 'text_textfield',
    '#default_value' => isset($element['#value']) ? $element['#value'] : '',
    '#autocomplete_path' => 'nodereference/autocomplete/' . $element['#field_name'],
    // The following values were set by the content module and need
    // to be passed down to the nested element.
    '#title' => $element['#title'],
    '#required' => $element['#required'],
    '#description' => $element['#description'],
    '#field_name' => $element['#field_name'],
    '#type_name' => $element['#type_name'],
    '#delta' => $element['#delta'],
    '#columns' => $element['#columns'],
  );
  if (empty($element[$field_key]['#element_validate'])) {
    $element[$field_key]['#element_validate'] = array();
  }
  array_unshift($element[$field_key]['#element_validate'], 'noderefcreate_autocomplete_validate');

  // Used so that hook_field('validate') knows where to flag an error.
  $element['_error_element'] = array(
    '#type' => 'value',
    // Wrapping the element around a text_textfield element creates a
    // nested element, so the final id will look like 'field-name-0-nid-nid'.
    '#value' => implode('][', array_merge($element['#parents'], array(
      $field_key,
      $field_key,
    ))),
  );
  return $element;
}
function noderefcreate_autocomplete_validate($element, &$form_state) {
  $field_name = $element['#field_name'];
  $type_name = $element['#type_name'];
  $field = content_fields($field_name, $type_name);
  $field_key = $element['#columns'][0];
  $delta = $element['#delta'];
  $value = $element['#value'][$field_key];
  $nid = NULL;
  if (strlen(trim($value)) > 0) {
    preg_match('/^(?:\\s*|(.*) )?\\[\\s*nid\\s*:\\s*(\\d+)\\s*\\]$/', $value, $matches);
    if (!empty($matches)) {

      // Explicit [nid:n].
      list(, $title, $nid) = $matches;
      if (!empty($title) && ($n = node_load($nid)) && $title != $n->title) {
        form_error($element[$field_key], t('%name: title mismatch. Please check your selection.', array(
          '%name' => t($field['widget']['label']),
        )));
      }
    }
    else {

      // No explicit nid.
      $reference = _nodereference_potential_references($field, $value, 'equals', NULL, 1);
      if (empty($reference)) {
        $newnode = NULL;
        if (is_array($field['referenceable_types'])) {
          foreach (array_filter($field['referenceable_types']) as $related_type) {
            $newnode->type = $related_type;
          }
        }
        global $user;
        $newnode->uid = $user->uid;
        $newnode->title = $value;
        if (module_exists('i18n')) {
          $newnode->language = i18n_get_lang();
        }
        else {
          $newnode->language = language_default();
        }
        if (module_exists('comment')) {
          $newnode->comment = variable_get("comment_{$newnode->type}", COMMENT_NODE_READ_WRITE);
        }
        node_save($newnode);
        $nid = $newnode->nid;
      }
      else {

        // TODO:
        // the best thing would be to present the user with an additional form,
        // allowing the user to choose between valid candidates with the same title
        // ATM, we pick the first matching candidate...
        $nid = key($reference);
      }
    }
  }
  else {
    if (strlen($value) > 0) {

      // if we got here then the user filled the name with spaces
      form_error($element, t('%name: title is empty. Please check your input.', array(
        '%name' => $instance['label'],
      )));
    }
  }
  form_set_value($element, $nid, $form_state);
}