You are here

corresponding_node_references.module in Corresponding node references 7.4

Same filename and directory in other branches
  1. 6.4 corresponding_node_references.module

Module file providing the "corresponding node reference" module main functions.

File

corresponding_node_references.module
View source
<?php

/**
 * @file
 * Module file providing the "corresponding node reference" module main
 * functions.
 */

/**
 * Implements hook_menu().
 */
function corresponding_node_references_menu() {
  $items = array();
  $items['admin/config/system/corresponding_node_references'] = array(
    'title' => 'Corresponding node references',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'corresponding_node_references_settings_form',
    ),
    'access arguments' => array(
      'administer corresponding node references settings',
    ),
    'file' => 'corresponding_node_references.admin.inc',
    'type' => MENU_NORMAL_ITEM,
  );
  $items['admin/config/system/corresponding_node_references/references'] = array(
    'title' => 'Corresponding node references',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'corresponding_node_references_settings_form',
    ),
    'access arguments' => array(
      'administer corresponding node references settings',
    ),
    'file' => 'corresponding_node_references.admin.inc',
    'type' => MENU_DEFAULT_LOCAL_TASK,
  );
  $items['admin/config/system/corresponding_node_references/update'] = array(
    'title' => 'Update existing nodes',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'corresponding_node_references_update_form',
    ),
    'access arguments' => array(
      'administer corresponding node references settings',
    ),
    'file' => 'corresponding_node_references.admin.inc',
    'type' => MENU_LOCAL_TASK,
  );
  return $items;
}

/**
 * Implements hook_permission().
 */
function corresponding_node_references_permission() {
  return array(
    'administer corresponding node references settings' => array(
      'title' => t('Administer corresponding node reference settings'),
      'description' => t('Administer corresponding node reference settings'),
    ),
  );
}

/**
 * Formats a label.
 */
function corresponding_node_references_format_label($key) {
  $key = explode(' ', $key);
  return t('Field instance:"!field1" on Bundle type:"!type1" <b>Corresponds with</b> Field instance:"!field2" on Bundle type:"!type2"', array(
    '!type1' => $key[0],
    '!field1' => $key[1],
    '!type2' => $key[2],
    '!field2' => $key[3],
  ));
}

/**
 * Implements hook_node_insert().
 */
function corresponding_node_references_node_insert($node) {
  corresponding_node_references_processing_node('insert', $node);
}

/**
 * Implements hook_node_update().
 */
function corresponding_node_references_node_update($node) {
  corresponding_node_references_processing_node('update', $node);
}

/**
 * Implements hook_node_delete().
 */
function corresponding_node_references_node_delete($node) {
  corresponding_node_references_processing_node('delete', $node);
}

/**
 * Load enabled CNR presets.
 */
function corresponding_node_references_preset_load_enabled() {
  ctools_include('export');
  return ctools_export_load_object('corresponding_node_references', 'conditions', array(
    'enabled' => 1,
  ));
}

/**
 * Return CNR preset by key.
 */
function corresponding_node_references_preset_load($key) {
  ctools_include('export');
  return ctools_export_crud_load('corresponding_node_references', $key);
}

/**
 * Return 1 if CNR preset specified by given key is enabled.
 */
function corresponding_node_references_preset_enabled($key) {
  $preset = corresponding_node_references_preset_load($key);
  return empty($preset) ? 0 : $preset->enabled;
}

/**
 * Process a node's corresponding node references.
 *
 * @param $op the operation being performed on the node.
 * @param $node the node object
 * @param $process_unchanged whether or not to process node reference fields
 *        whose values have not changed.
 */
function corresponding_node_references_processing_node($op, $node, $process_unchanged = FALSE) {
  module_load_include('inc', 'corresponding_node_references', 'corresponding_node_references.crud');
  $result = corresponding_node_references_preset_load_enabled();
  while ($row = array_shift($result)) {
    $key = explode('*', $row->node_types_content_fields);
    switch ($node->type) {
      case $key[0]:
        $args = array(
          $node,
          $key[1],
          $key[2],
          $key[3],
          $process_unchanged,
        );
        $function = 'corresponding_node_references_' . $op;
        call_user_func_array($function, $args);
        if ($key[0] != $key[2]) {
          break;
        }

      // Fall through.
      case $key[2]:
        $args = array(
          $node,
          $key[3],
          $key[0],
          $key[1],
          $process_unchanged,
        );
        $function = 'corresponding_node_references_' . $op;
        call_user_func_array($function, $args);
        break;
    }
  }
}

/**
 * Submit a batch job to index the remaining, unindexed content.
 */
function corresponding_node_references_batch_index_remaining($types, $limit) {
  $batch = array(
    'operations' => array(
      array(
        'corresponding_node_references_batch_update_existing_nodes',
        array(
          $types,
          $limit,
        ),
      ),
    ),
    'finished' => 'corresponding_node_references_batch_update_existing_finished',
    'title' => t('Processing'),
    'init_message' => t('Preparing to update corresponding node references for existing nodes...'),
    'progress_message' => t('Processing nodes...'),
    'error_message' => t('Corresponding node references existing node update has encountered an error.'),
  );
  batch_set($batch);
}

/**
 * Batch Operation Callback
 *
 * @see corresponding_node_references_batch_index_remaining()
 */
function corresponding_node_references_batch_update_existing_nodes($types, $limit, &$context) {

  // If we are on our first time through.
  if (!isset($context['sandbox']['progress'])) {
    $context['sandbox']['progress'] = 0;
    $context['sandbox']['current_node'] = 0;
    $context['sandbox']['max'] = db_query("SELECT COUNT(DISTINCT nid) FROM {node} WHERE type IN (:types)", array(
      ':types' => $types,
    ))
      ->fetchField();
  }
  $nids = array();
  $args = $types;
  $args['current_node'] = $context['sandbox']['current_node'];

  // Get node IDs to update.
  $result = db_query_range("SELECT nid FROM {node} WHERE type IN (:types) AND nid > :args ORDER BY nid", 0, $limit, array(
    ':types' => $types,
    ':args' => $args['current_node'],
  ));
  while ($row = $result
    ->fetchObject()) {
    $node = node_load($row->nid);
    corresponding_node_references_processing_node('update', $node, TRUE);

    // Update our progress information.
    $context['sandbox']['progress']++;
    $context['sandbox']['current_node'] = $node->nid;
    $context['message'] = t('Processed @current of @total nodes', array(
      '@current' => $context['sandbox']['progress'],
      '@total' => $context['sandbox']['max'],
    ));
  }

  // Inform the batch engine that we are not finished,
  // and provide an estimation of the completion level we reached.
  if ($context['sandbox']['progress'] != $context['sandbox']['max']) {
    $context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
  }

  // Put the total into the results section when we're finished so we can show
  // it to the admin.
  if ($context['finished']) {
    $context['results']['count'] = $context['sandbox']['progress'];
  }
}

/**
 * Batch 'finished' callback.
 *
 * @see corresponding_node_references_batch_index_remaining()
 */
function corresponding_node_references_batch_update_existing_finished($success, $results, $operations) {
  if ($success) {
    $type = 'status';
    $message = format_plural($results['count'], '1 node processed successfully.', '@count nodes processed successfully.');
  }
  else {
    $type = 'error';

    // An error occurred.
    // $operations contains the operations that remained unprocessed.
    $error_operation = reset($operations);
    $message = 'An error occurred while processing ' . $error_operation[0] . ' with arguments:' . print_r($error_operation[0], TRUE);
  }
  drupal_set_message($message, $type);
}
function corresponding_node_references_ctools_plugin_api($owner, $api) {
  if ($owner == 'corresponding_node_references' && $api == 'default_corresponding_node_references_presets') {
    return array(
      'version' => 1,
    );
  }
}