You are here

nodereferrer.module in NodeReferrer 7

Same filename and directory in other branches
  1. 5 nodereferrer.module
  2. 6 nodereferrer.module

Defines a field type for backlinking referencing nodes.

@todo -clear content cache with nodeapi. -query nids for access on load/view..

File

nodereferrer.module
View source
<?php

/**
 * @file
 * Defines a field type for backlinking referencing nodes.
 *
 * @todo
 *    -clear content cache with nodeapi.
 *    -query nids for access on load/view..
 */

/**
 * Implements hook_help().
 */
function nodereferrer_help($path, $arg) {
  switch ($path) {
    case 'admin/modules#description':
      return t('Defines a field type for displaying referrers to a node. <em>Note: Requires node_reference module.</em>');
  }
}

/**
 * Implements hook_field_info().
 */
function nodereferrer_field_info() {
  return array(
    'nodereferrer' => array(
      'label' => t('Node Referrers'),
      'description' => t('This field provides a counter part to node_reference field'),
      'instance_settings' => array(
        'prefix' => '',
        'suffix' => '',
      ),
      // It probably make more sense to have the settings per-field than per-instance.
      'settings' => array(
        'referrer_types' => array(),
        'referrer_fields' => array(),
        'referrer_translations' => 0,
        'referrer_nodes_per_page' => 0,
        'referrer_pager_element' => 0,
        'referrer_order' => 'TITLE_ASC',
      ),
      'default_widget' => 'nodereferrer_list',
      'default_formatter' => 'nodereferrer_default',
      // Support hook_entity_property_info() from contrib "Entity API".
      'property_type' => 'node',
    ),
  );
}

/**
 * Implements hook_field_settings_form().
 */
function nodereferrer_field_settings_form($field, $instance, $has_data) {
  $settings = $field['settings'];
  $form = array();

  // Hide unused options
  $form['required'] = array(
    '#type' => 'hidden',
    '#value' => FALSE,
  );
  $form['multiple'] = array(
    '#type' => 'hidden',
    '#value' => 0,
  );
  $form['referrer_types'] = array(
    '#type' => 'checkboxes',
    '#title' => t('Referring Node Types'),
    '#multiple' => TRUE,
    '#default_value' => $settings['referrer_types'],
    '#options' => node_type_get_names(),
  );
  $options = _nodereferrer_nodereference_field_options();
  $form['referrer_fields'] = array(
    '#type' => 'checkboxes',
    '#title' => t('Referring Fields'),
    '#multiple' => TRUE,
    '#default_value' => $settings['referrer_fields'],
    '#options' => $options,
  );
  if (module_exists('translation')) {
    $form['referrer_translations'] = array(
      '#type' => 'checkbox',
      '#title' => t('Show on translations'),
      '#description' => t('If this is checked, referrers will also show on translations of the referenced node'),
      '#default_value' => $settings['referrer_translations'],
    );
  }
  $form['referrer_nodes_per_page'] = array(
    '#type' => 'textfield',
    '#title' => t('Referrers Per Page'),
    '#description' => t('Referring nodes to display per page. 0 for no paging.'),
    '#default_value' => $settings['referrer_nodes_per_page'],
  );
  $form['referrer_pager_element'] = array(
    '#type' => 'textfield',
    '#title' => t('Pager element'),
    '#description' => t('Use this to avoid clashes if you have several pagers on one page'),
    '#default_value' => $settings['referrer_pager_element'],
  );
  $options = array(
    'CREATED_ASC' => t('Chronological Order'),
    'CREATED_DESC' => t('Reverse Chronological Order'),
    'TITLE_ASC' => t('Title Order'),
    'TITLE_DESC' => t('Reverse Title Order'),
  );
  $form['referrer_order'] = array(
    '#type' => 'select',
    '#title' => t('Refferer Sort Order'),
    '#options' => $options,
    '#default_value' => $settings['referrer_order'],
  );
  return $form;
}

/**
 * Implements hook_field_instance_settings_form().
 */
function nodereferrer_field_instance_settings_form($field, $instance) {
  $settings = $instance['settings'];
  $form['prefix'] = array(
    '#type' => 'textfield',
    '#title' => t('Prefix'),
    '#default_value' => $settings['prefix'],
    '#size' => 60,
    '#description' => t("Define a string that should be prefixed to the value, like '\$ ' or '&euro; '. Leave blank for none. Separate singular and plural values with a pipe ('pound|pounds')."),
  );
  $form['suffix'] = array(
    '#type' => 'textfield',
    '#title' => t('Suffix'),
    '#default_value' => $settings['suffix'],
    '#size' => 60,
    '#description' => t("Define a string that should be suffixed to the value, like ' m', ' kb/s'. Leave blank for none. Separate singular and plural values with a pipe ('pound|pounds')."),
  );
  return $form;
}

/**
 * implements hook_field_load().
 */
function nodereferrer_field_load($entity_type, $entities, $field, $instances, $langcode, &$items, $age) {
  $settings = $field['settings'];

  // Get field settings.
  $types = array_filter($settings['referrer_types']);
  $fields = array_filter($settings['referrer_fields']);
  $order = $settings['referrer_order'];
  $translations = $settings['referrer_translations'];
  foreach ($entities as $id => $entity) {
    if ($instances[$id]['entity_type'] == 'node') {
      $values = nodereferrer_referrers($id, $fields, $types, $translations, $order);
      if (!empty($values)) {
        $items[$id][0] = array(
          'items' => $values,
          'limit' => $settings['referrer_nodes_per_page'],
          'element' => $settings['referrer_pager_element'],
          'pager' => '',
        );
      }
    }
  }

  /*
      foreach ($items[$id] as $delta => $item) {
        // Only process items with a cacheable format, the rest will be handled
        // by formatters if needed.
        if (empty($instances[$id]['settings']['prefix']) || filter_format_allowcache($item['format'])) {
          $items[$id][$delta]['safe_value'] = isset($item['value']) ? _text_sanitize($instances[$id], $langcode, $item, 'value') : '';
          if ($field['type'] == 'text_with_summary') {
            $items[$id][$delta]['safe_summary'] = isset($item['summary']) ? _text_sanitize($instances[$id], $langcode, $item, 'summary') : '';
          }
        }
      }
    }

    $values = nodereferrer_referrers($node->nid, $fields, $types, $translations, $order);
    // Pass referring node objects into CCK content_load() cache. 24/08/2006 sun
    $items = array();
    foreach ($values as $nid => $rnode) {
      $items[] = $rnode;
    }

    if (count($items) == 0) {
      return array($field['field_name'] => array());
    }

    $output = array(
      'items' => $items,
      'limit' => empty($field['referrer_nodes_per_page']) ? 0 : $field['referrer_nodes_per_page'],
      'element' => empty($field['referrer_pager_element']) ? 0 : $field['referrer_pager_element'],
      'pager' => '',
    );

    return array($field['field_name'] => array($output));*/
}

/**
 * Implements of hook_field_settings().
 */
function nodereferrer__field_settings($op, $field) {
  switch ($op) {
    case 'views data':
      $data = content_views_field_views_data($field);
      if (is_array($data)) {
        foreach ($data as $k => $v) {
          $data[$k] = array();
        }
      }
      else {
        $data = array();
      }
      return $data;
    case 'callbacks':
      return array(
        'view' => CONTENT_CALLBACK_CUSTOM,
      );
    case 'form':
      $form = array();

      // Hide unused options
      $form['required'] = array(
        '#type' => 'hidden',
        '#value' => FALSE,
      );
      $form['multiple'] = array(
        '#type' => 'hidden',
        '#value' => 0,
      );
      $form['referrer_types'] = array(
        '#type' => 'checkboxes',
        '#title' => t('Referring Node Types'),
        '#multiple' => TRUE,
        '#default_value' => is_array($field['referrer_types']) ? $field['referrer_types'] : array(),
        '#options' => node_get_types('names'),
      );
      $options = _nodereferrer_nodereference_field_options();
      $form['referrer_fields'] = array(
        '#type' => 'checkboxes',
        '#title' => t('Referring Fields'),
        '#multiple' => TRUE,
        '#default_value' => is_array($field['referrer_fields']) ? $field['referrer_fields'] : array(),
        '#options' => $options,
      );
      if (module_exists('translation')) {
        $form['referrer_translations'] = array(
          '#type' => 'checkbox',
          '#title' => t('Show on translations'),
          '#description' => t('If this is checked, referrers will also show on translations of the referenced node'),
          '#default_value' => is_int($field['referrer_translations']) ? $field['referrer_translations'] : 0,
        );
      }
      $form['referrer_nodes_per_page'] = array(
        '#type' => 'textfield',
        '#title' => t('Referrers Per Page'),
        '#description' => t('Referring nodes to display per page. 0 for no paging.'),
        '#default_value' => !empty($field['referrer_nodes_per_page']) ? $field['referrer_nodes_per_page'] : 0,
      );
      $form['referrer_pager_element'] = array(
        '#type' => 'textfield',
        '#title' => t('Pager element'),
        '#description' => t('Use this to avoid clashes if you have several pagers on one page'),
        '#default_value' => !empty($field['referrer_pager_element']) ? $field['referrer_pager_element'] : 0,
      );
      $form['referrer_order'] = array(
        '#type' => 'select',
        '#title' => t('Refferer Sort Order'),
        '#options' => array(
          'CREATED_ASC' => t('Chronological Order'),
          'CREATED_DESC' => t('Reverse Chronological Order'),
          'TITLE_ASC' => t('Title Order'),
          'TITLE_DESC' => t('Reverse Title Order'),
        ),
        '#default_value' => strlen($field['referrer_order']) ? $field['referrer_order'] : 'TITLE_ASC',
      );
      return $form;
    case 'save':
      $settings = array(
        'referrer_types',
        'referrer_fields',
        'referrer_nodes_per_page',
        'referrer_pager_element',
        'referrer_order',
      );
      if (module_exists('translation')) {
        $settings[] = 'referrer_translations';
      }
      return $settings;
  }
}

/**
 * Implements of hook_field().
 */
function nodereferrer_field_OLD($op, &$node, $field, &$items, $teaser, $page) {
  switch ($op) {
    case 'load':
      $types = isset($field['referrer_types']) ? array_values(array_filter($field['referrer_types'])) : array();
      $fields = isset($field['referrer_fields']) ? array_values(array_filter($field['referrer_fields'])) : array();
      $order = $field['referrer_order'];
      $translations = isset($field['referrer_translations']) ? $field['referrer_translations'] : 0;
      $values = nodereferrer_referrers($node->nid, $fields, $types, $translations, $order);

      // Pass referring node objects into CCK content_load() cache. 24/08/2006 sun
      $items = array();
      foreach ($values as $nid => $rnode) {
        $items[] = $rnode;
      }
      if (count($items) == 0) {
        return array(
          $field['field_name'] => array(),
        );
      }
      $output = array(
        'items' => $items,
        'limit' => empty($field['referrer_nodes_per_page']) ? 0 : $field['referrer_nodes_per_page'],
        'element' => empty($field['referrer_pager_element']) ? 0 : $field['referrer_pager_element'],
        'pager' => '',
      );
      return array(
        $field['field_name'] => array(
          $output,
        ),
      );
    case 'delete':
    case 'update':

      // clear cache on nodes that refer to me.
      $types = array_values(array_filter($field['referrer_types']));
      $fields = array_values(array_filter($field['referrer_fields']));

      // clear any modules referring to me as my title or other data may change.
      // and nodereference doesn't clear the cache yet.
      foreach (nodereferrer_referrers($node->nid, $fields, $types, false) as $delta => $item) {
        $cid = 'content:' . $item['nid'] . ':' . $item['vid'];
        cache_clear_all($cid, 'cache_page');
      }
      return;
  }
}

/**
 * Implements hook_field_formatter_info().
 */
function nodereferrer_field_formatter_info() {
  $ret = array(
    'nodereferrer_default' => array(
      'label' => t('Title (link)'),
      'description' => t('Display the title of the referred node as a link to the node page.'),
      'field types' => array(
        'nodereferrer',
      ),
    ),
    'nodereferrer_plain' => array(
      'label' => t('Title (no link)'),
      'description' => t('Display the title of the referred node as plain text.'),
      'field types' => array(
        'nodereferrer',
      ),
    ),
    'nodereferrer_node' => array(
      'label' => t('Rendered node'),
      'description' => t('Display the referred node in a specific view mode'),
      'field types' => array(
        'nodereferrer',
      ),
      'settings' => array(
        'nodereferrer_view_mode' => 'full',
      ),
    ),
    'nodereferrer_count' => array(
      'label' => t('Node Count'),
      'field types' => array(
        'nodereferrer',
      ),
      'settings' => array(
        'prefix_suffix' => '',
      ),
    ),
  );
  return $ret;
}

/**
 * Implements hook_field_formatter_settings_form().
 */
function nodereferrer_field_formatter_settings_form($field, $instance, $view_mode, $form, &$form_state) {
  $display = $instance['display'][$view_mode];
  $settings = $display['settings'];
  if ($display['type'] === 'nodereferrer_node') {
    $entity_info = entity_get_info('node');
    $modes = $entity_info['view modes'];
    $options = array();
    foreach ($modes as $name => $mode) {
      $options[$name] = $mode['label'];
    }
    $element['nodereferrer_view_mode'] = array(
      '#title' => t('View mode'),
      '#type' => 'select',
      '#options' => $options,
      '#default_value' => $settings['nodereferrer_view_mode'],
    );
  }
  $element['prefix_suffix'] = array(
    '#type' => 'checkbox',
    '#title' => t('Display prefix and suffix.'),
    '#default_value' => $settings['prefix_suffix'],
  );
  return $element;
}

/**
 * Implements hook_field_formatter_settings_summary().
 */
function nodereferrer_field_formatter_settings_summary($field, $instance, $view_mode) {
  $display = $instance['display'][$view_mode];
  $settings = $display['settings'];
  $summary = array();
  if ($display['type'] === 'nodereferrer_node') {
    $entity_info = entity_get_info('node');
    $modes = $entity_info['view modes'];
    $mode = $modes[$settings['nodereferrer_view_mode']]['label'];
    $summary[] = t('View mode: %mode', array(
      '%mode' => $mode,
    ));
  }
  if (!empty($settings['prefix_suffix'])) {
    $summary[] = t('Display with prefix and suffix.');
  }
  else {
    $summary[] = ' ';
  }
  return implode('<br />', $summary);
}

/**
 * Implements of hook_field_formatter_info().
 */
function nodereferrer__field_formatter_info() {
  return array(
    'default' => array(
      'label' => t('Node Title Link (Default)'),
      'field types' => array(
        'nodereferrer',
      ),
      'multiple values' => CONTENT_HANDLE_CORE,
    ),
    'plain' => array(
      'label' => 'Node Title Plain Text',
      'field types' => array(
        'nodereferrer',
      ),
      'multiple values' => CONTENT_HANDLE_CORE,
    ),
    'teaser' => array(
      'label' => 'Node Teaser',
      'field types' => array(
        'nodereferrer',
      ),
      'multiple values' => CONTENT_HANDLE_CORE,
    ),
    'full' => array(
      'label' => 'Node Body',
      'field types' => array(
        'nodereferrer',
      ),
      'multiple values' => CONTENT_HANDLE_CORE,
    ),
    'count' => array(
      'label' => 'Node Count',
      'field types' => array(
        'nodereferrer',
      ),
      'multiple values' => CONTENT_HANDLE_CORE,
    ),
  );
}

/**
 * Implements hook_field_formatter_view().
 */
function nodereferrer_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
  $result = array();
  switch ($display['type']) {
    case 'nodereferrer_default':
    case 'nodereferrer_plain':
      foreach ($items as $delta => $item) {

        // Sometimes the values in $item['items'] is not an array,
        // in situations where there are no referring nodes.
        // array_keys() will throw an error in that situation,
        // so to avoid unnecessary messages in watchdog - we check.
        $nodes = array();
        if (is_array($item['items'])) {
          $nodes = node_load_multiple(array_keys($item['items']));
        }
        $rendered_nodes = array();
        foreach ($nodes as $node) {
          if ($display['type'] == 'nodereferrer_default') {
            $uri = entity_uri('node', $node);
            $rendered_nodes[$node->nid] = l($node->title, $uri['path'], $uri['options']);
          }
          else {
            $rendered_nodes[$node->nid] = check_plain($node->title);
          }

          /*if (!$node->status) {
              $rendered_nodes[$node->nid]['#prefix'] = '<span class="node-unpublished">';
              $rendered_nodes[$node->nid]['#suffix'] = '</span>';
            }*/
        }
        $result[$delta] = array(
          '#theme' => 'item_list',
          '#items' => $rendered_nodes,
        );
      }
      break;
    case 'nodereferrer_node':
      $view_mode = $display['settings']['nodereferrer_view_mode'];
      foreach ($items as $delta => $item) {
        $nodes = node_load_multiple(array_keys($item['items']));
        $result[$delta] = node_view_multiple($nodes, $view_mode);
      }
      break;
    case 'nodereferrer_count':

      // Assemble the render array.
      foreach ($items as $delta => $item) {
        $result[$delta] = array(
          '#markup' => count($item['items']),
          '#prefix' => $instance['settings']['prefix'] . ' ',
          '#suffix' => ' ' . $instance['settings']['suffix'],
        );
      }
  }
  return $result;
}

/**
 * Implementation of hook_theme().
 */
function nodereferrer_theme_OLD() {
  return array(
    'nodereferrer_formatter_default' => array(
      'arguments' => array(
        'info' => NULL,
      ),
    ),
    'nodereferrer_field_default' => array(
      'arguments' => array(
        'element' => NULL,
      ),
    ),
    'nodereferrer_formatter_plain' => array(
      'arguments' => array(
        'element' => NULL,
      ),
    ),
    'nodereferrer_field_plain' => array(
      'arguments' => array(
        'element' => NULL,
      ),
    ),
    'nodereferrer_formatter_teaser' => array(
      'arguments' => array(
        'element' => NULL,
      ),
    ),
    'nodereferrer_field_teaser' => array(
      'arguments' => array(
        'element' => NULL,
      ),
    ),
    'nodereferrer_formatter_full' => array(
      'arguments' => array(
        'element' => NULL,
      ),
    ),
    'nodereferrer_field_full' => array(
      'arguments' => array(
        'element' => NULL,
      ),
    ),
    'nodereferrer_formatter_count' => array(
      'arguments' => array(
        'element' => NULL,
      ),
    ),
  );
}

/**
 * Generic formatter function
 */
function nodereferrer_theme_formatter($formatter, $info) {
  $items = isset($info['#item']['items']) ? $info['#item']['items'] : array();
  $limit = isset($info['#item']['limit']) ? $info['#item']['limit'] : 0;
  $element = isset($info['#item']['element']) ? $info['#item']['element'] : array();
  $pager = '';
  if ($limit) {

    // Fake the values set by pager query...
    global $pager_page_array, $pager_total, $pager_total_items;
    $page = isset($_GET['page']) ? $_GET['page'] : '';

    // Convert comma-separated $page to an array, used by other functions.
    $pager_page_array = explode(',', $page);

    // We calculate the total of pages as ceil(items / limit).
    $pager_total_items[$element] = count($items);
    $pager_total[$element] = ceil($pager_total_items[$element] / $limit);
    $pager_page_array[$element] = max(0, min((int) $pager_page_array[$element], (int) $pager_total[$element] - 1));

    // only display the select elements.
    if (is_array($items)) {
      $items = array_slice($items, $pager_page_array[$element] * $limit, $limit);
    }
    $pager = theme('pager', array(), $limit, $element);
  }
  $themed_items = array();
  foreach ($items as $i) {
    $i['field'] = $info;

    // Add some extra information the themer might like to have
    $themed_items[] = theme('nodereferrer_field_' . $formatter, $i);
  }
  $out = theme('item_list', $themed_items) . $pager;
  return $out;
}

/**
 * Theme functions for 'default' field formatter.
 */
function theme_nodereferrer_formatter_default($info) {
  return nodereferrer_theme_formatter('default', $info);
}
function theme_nodereferrer_field_default($element) {
  return l($element['title'], 'node/' . $element['nid']);
}

/**
 * Theme function for 'plain' field formatter.
 */
function theme_nodereferrer_formatter_plain($info) {
  return nodereferrer_theme_formatter('plain', $info);
}
function theme_nodereferrer_field_plain($element) {
  return strip_tags($element['title']);
}

/**
 * Theme function for 'teaser' field formatter.
 */
function theme_nodereferrer_formatter_teaser($info) {
  return nodereferrer_theme_formatter('teaser', $info);
}
function theme_nodereferrer_field_teaser($element) {
  return node_view(node_load($element['nid']), TRUE);
}

/**
 * Theme function for 'full' field formatter.
 */
function theme_nodereferrer_formatter_full($info) {
  return nodereferrer_theme_formatter('full', $info);
}
function theme_nodereferrer_field_full($element) {
  return node_view(node_load($element['nid']));
}

/**
 * Theme function for 'count' field formatter.
 */
function theme_nodereferrer_formatter_count($info) {
  return count($info['#item']['items']);
}

/**
 * Implementation of hook_field_widget_info().
 */
function nodereferrer_field_widget_info() {
  return array(
    'nodereferrer_list' => array(
      'label' => t('Read-Only List'),
      'field types' => array(
        'nodereferrer',
      ),
      'behaviors' => array(
        'multiple values' => FIELD_BEHAVIOR_CUSTOM,
        'default value' => FIELD_BEHAVIOR_NONE,
      ),
    ),
  );
}

/**
 * Implements hook_field_is_empty().
 */
function nodereferrer_field_is_empty($item, $field) {
  return TRUE;
}

/**
 * Gets an array of referrer nids, by node.type & field.type
 *
 * @param nid
 *     the nid we want to find referres for
 * @param fieldnames
 *     array of fieldnames to be checked for referrers
 * @param nodetypes
 *     array of node types to be checked for referrers
 * @param translations
 *     boolean if true, also return nodes that referrer to translations of the given node
 */
function nodereferrer_referrers($nid, $fieldnames = array(), $nodetypes = array(), $translations = 0, $order = 'DESC') {
  $query = new EntityFieldQuery();
  $query
    ->entityCondition('entity_type', 'node', '=')
    ->propertyCondition('status', NODE_PUBLISHED, '=');
  if ($nodetypes) {
    $query
      ->entityCondition('bundle', $nodetypes, 'IN');
  }

  // Order the query.
  switch ($order) {
    case 'TITLE_ASC':
      $query
        ->propertyOrderBy('title', 'ASC');
      break;
    case 'TITLE_DESC':
      $query
        ->propertyOrderBy('title', 'DESC');
      break;
    case 'ASC':
    case 'CREATED_ASC':
      $query
        ->propertyOrderBy('created', 'ASC');
      break;
    case 'DESC':
    case 'CREATED_DESC':
    default:
      $query
        ->propertyOrderBy('created', 'DESC');
      break;
  }
  $fields = _nodereferrer_nodereference_field_options();
  if (empty($fieldnames)) {
    $fieldnames = array_keys($fields);
  }
  $values = array();
  foreach ($fieldnames as $fieldname) {
    $current_query = clone $query;

    // @todo check for translation.
    $current_query
      ->fieldCondition($fieldname, 'nid', $nid, '=');
    $result = $current_query
      ->execute();
    if (!empty($result['node'])) {
      foreach ($result['node'] as $ref_node) {

        /*if (!empty($nodetypes) && !isset($nodetypes[$ref_node->type])) {
          	continue;
          }*/

        // avoid duplicate referrers by using nid as key
        $values[$ref_node->nid]['nid'] = $ref_node->nid;
        $values[$ref_node->nid]['vid'] = $ref_node->vid;

        //$values[$ref_node->nid]['title'] = $ref_node->title;

        //Store the nodereference fieldnames in the nodereferrer data in the node,

        //so that it can be looked up without needing to load the referring node.
        $values[$ref_node->nid]['referrers'][$fieldname] = $fieldname;
      }
    }
  }
  return $values;

  /*
    if ($nodetypes) {
      $filter_nodetypes = "AND n.type IN ('" . implode("', '", $nodetypes) . "')";
    }
    else {
      $filter_nodetypes = '';
    }
    $fields = content_fields();
    // Set default values of fieldnames.
    if (!count($fieldnames)) {
      $fieldnames = array_keys($fields);
    }
    $values = array();
    foreach ($fieldnames as $fieldname) {
      if ($fields[$fieldname]['type'] == 'nodereference') {
        $db_info = content_database_info($fields[$fieldname]);

        if ($translations) {
          $query = "SELECT       n.nid, n.vid, n.title $select_field
                    FROM         {" . $db_info['table'] . "} nr
                    INNER JOIN   {node} current_node ON current_node.nid = %d
                    INNER JOIN   {node} n ON n.vid = nr.vid AND n.status = 1 " . $filter_nodetypes . "
                    LEFT JOIN    {node} translations ON current_node.tnid > 0 AND translations.tnid = current_node.tnid
                    WHERE        (current_node.tnid = 0 AND nr." . $db_info['columns']['nid']['column'] . " = current_node.nid)
                                 OR
                                 (current_node.tnid > 0 AND nr." . $db_info['columns']['nid']['column'] . " = translations.nid)
                    ORDER BY     " . $order;
        }
        else {
          $query = "SELECT       n.nid, n.vid, n.title $select_field
                    FROM         {" . $db_info['table'] . "} nr
                    INNER JOIN   {node} n ON n.vid = nr.vid AND n.status = 1 " . $filter_nodetypes . "
                    WHERE        nr." . $db_info['columns']['nid']['column'] . " = %d
                    ORDER BY     " . $order;
        }

        $query = db_rewrite_sql($query);
        $result = db_query($query, $nid);

        while ($value = db_fetch_array($result)) {
          // avoid duplicate referrers by using nid as key
          $values[$value['nid']]['nid'] = $value['nid'];
          $values[$value['nid']]['vid'] = $value['vid'];
          $values[$value['nid']]['title'] = $value['title'];
          //Store the nodereference fieldnames in the nodereferrer data in the node,
          //so that it can be looked up without needing to load the referring node.
          $values[$value['nid']]['referrers'][$fieldname] = $fieldname;
        }
      }
    }
    return $values;
  */
}

/**
 * Helper function to create an options list of nodereference fields.
 */
function _nodereferrer_nodereference_field_options() {
  $options = drupal_static(__FUNCTION__, FALSE);
  if ($options === FALSE) {
    $options = array();
    $fields = field_info_fields();
    foreach ($fields as $field_name => $field) {
      if ($field['type'] == 'node_reference') {
        $options[$field_name] = $field['field_name'];
      }
    }
  }
  return $options;
}

/**
 * Implementation of hook_node_prepare().
 */
function nodereferrer_node_prepare($node) {
  _nodereferrer_manage_cache($node);
}

/**
 * Implementation of hook_node_insert().
 */
function nodereferrer_node_insert($node) {
  _nodereferrer_manage_cache($node);
}

/**
 * Implementation of hook_node_update().
 */
function nodereferrer_node_update($node) {
  _nodereferrer_manage_cache($node);
}

/**
 * Implementation of hook_node_delete().
 */
function nodereferrer_node_delete($node) {
  _nodereferrer_manage_cache($node);
}

/**
 * Helper function for Node API Hooks.
 */
function _nodereferrer_manage_cache($node) {

  // Clear content cache to help maintain proper display of nodes.
  $nids = array();
  $type = field_info_instances('node', $node->type);
  if (!empty($type)) {
    foreach ($type as $field => $instance) {
      $fieldinfo = field_info_field($field);
      if ($fieldinfo['type'] == 'node_reference') {
        $node_field = isset($node->{$fieldinfo}['field_name']) ? $node->{$fieldinfo}['field_name'] : array();
        if (isset($node_field['und'])) {
          foreach ($node_field['und'] as $delta => $item) {

            // Add referenced nodes to nids. This will clean up nodereferrer fields
            // when the referencing node is updated.
            $nids[$item['nid']] = $item['nid'];
          }
        }
      }
    }
  }

  // Clear Content cache for nodes that reference the node that is being updated.
  // This will keep nodereference fields up to date when referred nodes are
  // updated. @note this currenlty doesn't work all that well since nodereference
  // doesn't respect publishing states or access control.
  if (isset($node->nid)) {
    $referrers = nodereferrer_referrers($node->nid);
    $referrer_nids = array_keys($referrers);
    $nids = array_merge($nids, $referrer_nids);
  }
  foreach ($nids as $nid) {
    $printnode = node_load($nid);
    $cid = "field:node:{$nid}";

    // define a table to delete from or else this complains
    cache_clear_all($cid, 'cache_field', TRUE);
  }
}

/**
 * Implementation of hook_nodeapi().
 */

/*
function nodereferrer_nodeapi($node, $op) {
  switch ($op) {
    case 'prepare':
    case 'insert':
    case 'update':
    case 'delete':
      // Clear content cache to help maintain proper display of nodes.
      $nids = array();
      $type = content_types($node->type);
      if (!empty($type['fields'])) {
        foreach ($type['fields'] as $field) {
          // Add referenced nodes to nids. This will clean up nodereferrer fields
          // when the referencing node is updated.
          if ($field['type'] == 'nodereference') {
            $node_field = isset($node->$field['field_name']) ? $node->$field['field_name'] : array();
            foreach ($node_field as $delta => $item) {
              $nids[$item['nid']] = $item['nid'];
            }
          }
        }
      }

      // Clear Content cache for nodes that reference the node that is being updated.
      // This will keep nodereference fields up to date when referred nodes are
      // updated. @note this currenlty doesn't work all that well since nodereference
      // doesn't respect publishing states or access control.
      if (isset($node->nid)) {
        $referrers = nodereferrer_referrers($node->nid);
        $referrer_nids = array_keys($referrers);
        $nids = array_merge($nids, $referrer_nids);
      }

      foreach ($nids as $nid) {
        $cid = "content:$nid:";
        // define a table to delete from or else this complains
        cache_clear_all($cid, 'cache_content', TRUE);
      }
  }
}
*/

/**
 * Implements of hook_views_api().
 */
function nodereferrer_views_api() {
  return array(
    'api' => '2.0',
    'path' => drupal_get_path('module', 'nodereferrer') . '/views',
  );
}

Functions

Namesort descending Description
nodereferrer_field_formatter_info Implements hook_field_formatter_info().
nodereferrer_field_formatter_settings_form Implements hook_field_formatter_settings_form().
nodereferrer_field_formatter_settings_summary Implements hook_field_formatter_settings_summary().
nodereferrer_field_formatter_view Implements hook_field_formatter_view().
nodereferrer_field_info Implements hook_field_info().
nodereferrer_field_instance_settings_form Implements hook_field_instance_settings_form().
nodereferrer_field_is_empty Implements hook_field_is_empty().
nodereferrer_field_load implements hook_field_load().
nodereferrer_field_OLD Implements of hook_field().
nodereferrer_field_settings_form Implements hook_field_settings_form().
nodereferrer_field_widget_info Implementation of hook_field_widget_info().
nodereferrer_help Implements hook_help().
nodereferrer_node_delete Implementation of hook_node_delete().
nodereferrer_node_insert Implementation of hook_node_insert().
nodereferrer_node_prepare Implementation of hook_node_prepare().
nodereferrer_node_update Implementation of hook_node_update().
nodereferrer_referrers Gets an array of referrer nids, by node.type & field.type
nodereferrer_theme_formatter Generic formatter function
nodereferrer_theme_OLD Implementation of hook_theme().
nodereferrer_views_api Implements of hook_views_api().
nodereferrer__field_formatter_info Implements of hook_field_formatter_info().
nodereferrer__field_settings Implements of hook_field_settings().
theme_nodereferrer_field_default
theme_nodereferrer_field_full
theme_nodereferrer_field_plain
theme_nodereferrer_field_teaser
theme_nodereferrer_formatter_count Theme function for 'count' field formatter.
theme_nodereferrer_formatter_default Theme functions for 'default' field formatter.
theme_nodereferrer_formatter_full Theme function for 'full' field formatter.
theme_nodereferrer_formatter_plain Theme function for 'plain' field formatter.
theme_nodereferrer_formatter_teaser Theme function for 'teaser' field formatter.
_nodereferrer_manage_cache Helper function for Node API Hooks.
_nodereferrer_nodereference_field_options Helper function to create an options list of nodereference fields.