You are here

function nodereference_field in Content Construction Kit (CCK) 6.3

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

Implementation of hook_field().

File

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

Code

function nodereference_field($op, &$node, $field, &$items, $teaser, $page) {
  static $sanitized_nodes = array();
  switch ($op) {

    // When preparing a translation, load any translations of existing references.
    case 'prepare translation':
      $addition = array();
      $addition[$field['field_name']] = array();
      if (isset($node->translation_source->{$field}['field_name']) && is_array($node->translation_source->{$field}['field_name'])) {
        foreach ($node->translation_source->{$field}['field_name'] as $key => $reference) {
          $reference_node = node_load($reference['nid']);

          // Test if the referenced node type is translatable and, if so,
          // load translations if the reference is not for the current language.
          // We can assume the translation module is present because it invokes 'prepare translation'.
          if (translation_supported_type($reference_node->type) && !empty($reference_node->language) && $reference_node->language != $node->language && ($translations = translation_node_get_translations($reference_node->tnid))) {

            // If there is a translation for the current language, use it.
            $addition[$field['field_name']][] = array(
              'nid' => isset($translations[$node->language]) ? $translations[$node->language]->nid : $reference['nid'],
            );
          }
        }
      }
      return $addition;
    case 'validate':

      // Extract nids to check.
      $ids = array();
      foreach ($items as $delta => $item) {
        if (is_array($item) && !empty($item['nid'])) {
          if (is_numeric($item['nid'])) {
            $ids[] = $item['nid'];
          }
          else {
            $error_element = isset($item['_error_element']) ? $item['_error_element'] : '';
            if (is_array($item) && isset($item['_error_element'])) {
              unset($item['_error_element']);
            }
            form_set_error($error_element, t("%name: invalid input.", array(
              '%name' => t($field['widget']['label']),
            )));
          }
        }
      }

      // Prevent performance hog if there are no ids to check.
      if ($ids) {
        $refs = _nodereference_potential_references($field, '', NULL, $ids);
        foreach ($items as $delta => $item) {
          if (is_array($item)) {
            $error_element = isset($item['_error_element']) ? $item['_error_element'] : '';
            if (is_array($item) && isset($item['_error_element'])) {
              unset($item['_error_element']);
            }
            if (!empty($item['nid']) && !isset($refs[$item['nid']])) {
              form_set_error($error_element, t("%name: this post can't be referenced.", array(
                '%name' => t($field['widget']['label']),
              )));
            }
          }
        }
      }
      return $items;
    case 'sanitize':

      // We can't just check the node is 'referenceable', because Views-mode
      // could rely on 'current user' (at edit time).
      // Extract nids to check.
      $ids = array();
      foreach ($items as $delta => $item) {
        if (is_array($item)) {

          // Default to 'non accessible'.
          $items[$delta]['safe'] = array();
          if (!empty($item['nid']) && is_numeric($item['nid'])) {
            $ids[] = $item['nid'];
          }
        }
      }
      if ($ids) {

        // Load information about nids that we haven't already loaded during
        // this page request.
        $missing_ids = array_diff($ids, array_keys($sanitized_nodes));
        if (!empty($missing_ids)) {
          $where = array(
            'n.nid in (' . db_placeholders($missing_ids) . ')',
          );
          if (!user_access('administer nodes')) {
            $where[] = 'n.status = 1';
          }
          $result = db_query(db_rewrite_sql('SELECT n.nid, n.title, n.status FROM {node} n WHERE ' . implode(' AND ', $where)), $missing_ids);
          while ($row = db_fetch_array($result)) {
            $sanitized_nodes[$row['nid']] = $row;
          }
        }
        foreach ($items as $delta => $item) {
          if (is_array($item) && !empty($item['nid']) && isset($sanitized_nodes[$item['nid']])) {
            $items[$delta]['safe'] = $sanitized_nodes[$item['nid']];
          }
        }
      }
      return $items;
  }
}