You are here

function nodereference_widget in Content Construction Kit (CCK) 5

Same name and namespace in other branches
  1. 6.3 modules/nodereference/nodereference.module \nodereference_widget()
  2. 6 modules/nodereference/nodereference.module \nodereference_widget()
  3. 6.2 modules/nodereference/nodereference.module \nodereference_widget()

Implementation of hook_widget().

File

./nodereference.module, line 228
Defines a field type for referencing one node from another.

Code

function nodereference_widget($op, &$node, $field, &$items) {
  if ($field['widget']['type'] == 'nodereference_select') {
    switch ($op) {
      case 'prepare form values':
        $items_transposed = content_transpose_array_rows_cols($items);
        $items['default nids'] = $items_transposed['nid'];
        break;
      case 'form':
        $form = array();
        $options = _nodereference_potential_references($field, TRUE);
        foreach ($options as $key => $value) {
          $options[$key] = _nodereference_item($field, $value, FALSE);
        }
        if (!$field['required']) {
          $options = array(
            0 => t('<none>'),
          ) + $options;
        }
        $form[$field['field_name']] = array(
          '#tree' => TRUE,
        );
        $form[$field['field_name']]['nids'] = array(
          '#type' => 'select',
          '#title' => t($field['widget']['label']),
          '#default_value' => $items['default nids'],
          '#multiple' => $field['multiple'],
          '#size' => $field['multiple'] ? min(count($options), 6) : 0,
          '#options' => $options,
          '#required' => $field['required'],
          '#description' => content_filter_xss(t($field['widget']['description'])),
        );
        return $form;
      case 'process form values':
        if ($field['multiple']) {

          // if nothing selected, make it 'none'
          if (empty($items['nids'])) {
            $items['nids'] = array(
              0 => '0',
            );
          }
          elseif (count($items['nids']) > 1) {
            unset($items['nids'][0]);
          }
          $items = array_values(content_transpose_array_rows_cols(array(
            'nid' => $items['nids'],
          )));
        }
        else {
          $items[0]['nid'] = $items['nids'];
        }

        // Remove the widget's data representation so it isn't saved.
        unset($items['nids']);
        foreach ($items as $delta => $item) {
          $items[$delta]['error_field'] = $field['field_name'] . '][nids';
        }
    }
  }
  else {
    switch ($op) {
      case 'prepare form values':
        foreach ($items as $delta => $item) {
          if (!empty($items[$delta]['nid'])) {
            $items[$delta]['default node_name'] = db_result(db_query(db_rewrite_sql('SELECT n.title FROM {node} n WHERE n.nid = %d'), $items[$delta]['nid']));
            $items[$delta]['default node_name'] .= ' [nid:' . $items[$delta]['nid'] . ']';
          }
        }
        break;
      case 'form':
        $form = array();
        $form[$field['field_name']] = array(
          '#tree' => TRUE,
        );
        if ($field['multiple']) {
          $form[$field['field_name']]['#type'] = 'fieldset';
          $form[$field['field_name']]['#description'] = content_filter_xss(t($field['widget']['description']));
          $delta = 0;
          foreach ($items as $item) {
            if ($item['nid']) {
              $form[$field['field_name']][$delta]['node_name'] = array(
                '#type' => 'textfield',
                '#title' => $delta == 0 ? t($field['widget']['label']) : '',
                '#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) {
            $form[$field['field_name']][$delta]['node_name'] = array(
              '#type' => 'textfield',
              '#title' => $delta == 0 ? t($field['widget']['label']) : '',
              '#autocomplete_path' => 'nodereference/autocomplete/' . $field['field_name'],
              '#default_value' => '',
              '#required' => $delta == 0 ? $field['required'] : FALSE,
            );
          }
        }
        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' => $items[0]['default node_name'],
            '#required' => $field['required'],
            '#description' => content_filter_xss(t($field['widget']['description'])),
          );
        }
        return $form;
      case 'validate':
        foreach ($items as $delta => $item) {
          $error_field = $field['field_name'] . '][' . $delta . '][node_name';
          if (!empty($item['node_name'])) {
            preg_match('/^(?:\\s*|(.*) )?\\[\\s*nid\\s*:\\s*(\\d+)\\s*\\]$/', $item['node_name'], $matches);
            if (!empty($matches)) {

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

              // no explicit nid
              $nids = _nodereference_potential_references($field, FALSE, $item['node_name'], TRUE);
              if (empty($nids)) {
                form_set_error($error_field, t('%name: Found no valid post with that title.', array(
                  '%name' => t($field['widget']['label']),
                )));
              }
              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 = array_shift(array_keys($nids));
              }
            }
          }
        }
        return;
      case 'process form values':
        foreach ($items as $delta => $item) {
          $nid = 0;
          if (!empty($item['node_name'])) {
            preg_match('/^(?:\\s*|(.*) )?\\[\\s*nid\\s*:\\s*(\\d+)\\s*\\]$/', $item['node_name'], $matches);
            if (!empty($matches)) {

              // explicit nid
              $nid = $matches[2];
            }
            else {

              // no explicit nid
              // 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...
              $nids = _nodereference_potential_references($field, FALSE, $item['node_name'], TRUE);
              $nid = !empty($nids) ? array_shift(array_keys($nids)) : 0;
            }
          }

          // Remove the widget's data representation so it isn't saved.
          unset($items[$delta]['node_name']);
          if (!empty($nid)) {
            $items[$delta]['nid'] = $nid;
            $items[$delta]['error_field'] = $field['field_name'] . '][' . $delta . '][node_name';
          }
          elseif ($delta > 0) {

            // Don't save empty fields when they're not the first value (keep '0' otherwise)
            unset($items[$delta]);
          }
        }
        break;
    }
  }
}