You are here

function finder_load_objects in Finder 6

Same name and namespace in other branches
  1. 7 finder.module \finder_load_objects()

Load objects from the database.

This is intended as a reverse 'drupal_write_record' based on the code from node_load_multiple() in Drupal 7. It can be used to read records from any table assuming they are keyed by a serial field named {table}_id. Also supports serialized fields.

Parameters

$load: The name of the table, and thus the type of object to load.

$ids: An array of IDs, if selecting by ID.

$conditions: An array of conditions on the table in the form 'field' => $value.

$reset: Whether to reset the internal cache for this type of $load object.

Return value

An array of loaded objects indexed by ID.

2 calls to finder_load_objects()
finder_element_load_multiple in ./finder.module
Load finder element objects from the database.
finder_load_multiple in ./finder.module
Load finder objects from the database.

File

./finder.module, line 277
The finder module.

Code

function finder_load_objects($load, $ids = NULL, $conditions = array(), $reset = FALSE) {
  static $object_cache = array();
  if ($reset) {
    $object_cache[$load] = array();
  }
  if (!isset($object_cache[$load])) {
    $object_cache[$load] = array();
  }
  $objects = array();
  $id_key = $load . '_id';

  // Create a new variable which is either a prepared version of the $ids
  // array for later comparison with the finder cache, or FALSE if no $ids were
  // passed. The $ids array is reduced as items are loaded from cache, and we
  // need to know if it's empty for this reason to avoid querying the database
  // when all requested objects are loaded from cache.
  $passed_ids = !empty($ids) ? array_flip($ids) : FALSE;

  // Load any available objects from the internal cache.
  if ($object_cache[$load]) {
    if (!empty($ids)) {
      $objects += array_intersect_key($object_cache[$load], $passed_ids);

      // If any objects were loaded, remove them from the $ids still to load.
      $ids = array_keys(array_diff_key($passed_ids, $objects));
    }
    elseif ($conditions) {
      $objects = $object_cache[$load];
    }
  }

  // Exclude any objects loaded from cache if they don't match $conditions.
  // This ensures the same behavior whether loading from memory or database.
  if (!empty($conditions)) {
    foreach ($objects as $object) {
      $object_values = (array) $object;
      if (array_diff_assoc($conditions, $object_values)) {
        unset($objects[$object->{$id_key}]);
      }
    }
  }

  // Load objects from the database. This is the case if there are
  // any $ids left to load, if $conditions was passed without $ids,
  // or if $ids and $conditions were intentionally left blank.
  if (!empty($ids) || $conditions && !$passed_ids || $ids === NULL && $conditions === array()) {
    $query = array();

    // build query
    $query['from'] = '{' . $load . '}';
    if (!empty($ids)) {
      $query['wheres'][] = $id_key . ' IN (' . db_placeholders($ids) . ')';
      $query['arguments'] = isset($query['arguments']) && is_array($query['arguments']) ? $query['arguments'] + $ids : $ids;
    }
    if (!empty($conditions)) {
      $object_schema = drupal_get_schema($load);
      if (!empty($object_schema)) {
        foreach ($conditions as $field => $value) {
          $type = $object_schema['fields'][$field]['type'];
          $query['wheres'][] = $field . " = " . db_type_placeholder($type);
          $query['arguments'][] = $value;
        }
      }
    }
    if ($load == 'finder_element') {
      $query['orders'][] = 'weight';
    }
    $queried_objects = finder_query($query);
  }

  // Pass all objects loaded from the database through the finder type specific
  // callbacks and hook_finderapi(), then add them to the internal cache.
  if (!empty($queried_objects)) {
    foreach ($queried_objects as $q_key => $q_object) {

      // unserialize settings
      if (isset($q_object->settings)) {
        $queried_objects[$q_key]->settings = (array) unserialize($q_object->settings);
      }

      // add elements if object is a finder.
      // this code is here in lieu of a hook_finderapi ($op='finder_load') implementation.
      if ($load == 'finder') {
        $queried_objects[$q_key]->elements = finder_element_load_multiple(array(), array(
          $id_key => $q_object->{$id_key},
        ));
        if (!empty($queried_objects[$q_key]->elements)) {
          foreach ($queried_objects[$q_key]->elements as $position => $element) {
            $queried_objects[$q_key]->elements_index[$element->finder_element_id] = $position;
          }
        }
        finder_load_base_handler($queried_objects[$q_key]);
        finder_load_element_handler($queried_objects[$q_key]);
        finder_load_links($queried_objects[$q_key]);
      }

      // invoke finderapi so modules can make changes
      finder_invoke_finderapi($queried_objects[$q_key], $load . '_load');
    }
    $objects += $queried_objects;

    // Add objects to the cache.

    //$object_cache[$load] += $queried_objects;
    foreach ($queried_objects as $queried_object) {
      $object_cache[$load][$queried_object->{$id_key}] = $queried_object;
    }
  }

  // Ensure that the returned array is ordered the same as the original $ids
  // array if this was passed in and remove any invalid ids.
  if ($passed_ids) {

    // Remove any invalid ids from the array.
    $passed_ids = array_intersect_key($passed_ids, $objects);
    foreach ($objects as $object) {
      $passed_ids[$object->{$id_key}] = $object;
    }
    $objects = $passed_ids;
  }
  return $objects;
}