You are here

function organigrams_get_tree in Organigrams 7

Create a hierarchical representation of an organigram.

Parameters

int $oid: An organigrams ID.

int $parent: An organigrams item ID under which to generate the tree. If 0, generate the tree for the entire organigrams.

mixed $max_depth: The number of levels of the tree to return. Leave NULL to return all levels.

bool $load_entities: If TRUE, a full entity load will occur on the organigrams item objects. Otherwise they are partial objects queried directly from the {organigrams_item_data} table to save execution time and memory consumption when listing large numbers of organigrams items. Defaults to FALSE.

Return value

array An array of all organigrams item objects in the tree. Each organigrams item object is extended to have "depth" attribute in addition to its normal ones. Results are statically cached. organigrams item objects will be partial or complete depending on the $load_entities parameter.

5 calls to organigrams_get_tree()
organigrams_compose_organigrams in ./organigrams.module
Generate an renderable item list array for the specified organigram.
organigrams_form_export in ./organigrams.admin.inc
Admin menu callback to export all items from an organigram.
organigrams_form_overview_organigrams_items in ./organigrams_item.admin.inc
Generates a form overview of all organigrams items.
organigrams_import_items in ./organigrams.module
Import organigram items in an existing organigram.
organigrams_item_get_suitable_parents_options in ./organigrams.module
Generate a list of suitable parents for the given organigrams item.
1 string reference to 'organigrams_get_tree'
organigrams_items_static_reset in ./organigrams.module
Clear all static cache variables for organigrams items.

File

./organigrams.module, line 1321
Defines the organigrams functions and entity types.

Code

function organigrams_get_tree($oid, $parent = 0, $max_depth = NULL, $load_entities = FALSE) {

  // Retrieve the static cache.
  $children =& drupal_static(__FUNCTION__, array());
  $parents =& drupal_static(__FUNCTION__ . ':parents', array());
  $organigrams_items =& drupal_static(__FUNCTION__ . ':organigrams_items', array());

  // Check if the oid is cached.
  if (!isset($children[$oid])) {

    // Initialize the arrays for the given oid.
    $children[$oid] = array();
    $parents[$oid] = array();
    $organigrams_items[$oid] = array();

    // Construct hierarchy query.
    $query = db_select('organigrams_item_data', 'oid');
    $result = $query
      ->addTag('translatable')
      ->addTag('organigrams_item_access')
      ->fields('oid')
      ->condition('oid.oid', $oid)
      ->orderBy('oid.weight')
      ->orderBy('oid.name')
      ->execute();

    // Iterate through the result set.
    foreach ($result as $organigrams_item) {

      // If no array is initialized then initialize.
      if (($organigrams_item_children =& $children[$oid][$organigrams_item->parent]) === NULL) {
        $organigrams_item_children = array();
      }

      // If not initialized then initialize.
      if (($organigrams_item_parents =& $parents[$oid][$organigrams_item->iid]) === NULL) {
        $organigrams_item_parents = array();
      }

      // Add the hierarchy.
      $organigrams_item_children[] = $organigrams_item->iid;
      $organigrams_item_parents[] = $organigrams_item->parent;
      $organigrams_items[$oid][$organigrams_item->iid] = $organigrams_item;
    }
  }

  // Load full entities, if necessary. The entity controller statically caches
  // the results.
  if ($load_entities) {
    $organigrams_item_entities = organigrams_item_load_multiple(array_keys($organigrams_items[$oid]));
  }

  // Determine the max depth.
  $max_depth = isset($max_depth) ? $max_depth : count($children[$oid]);

  // Initialize the tree.
  $tree = array();

  // Keeps track of the parents we have to process, the last entry is used for
  // the next processing step.
  $process_parents = array(
    $parent,
  );

  // Loop over the parents.
  while (count($process_parents)) {

    // Pop a parent from the parents list.
    $parent = array_pop($process_parents);

    // The number of parents determines the current depth.
    $depth = count($process_parents);

    // Check if the current depth is not passed the max depth.
    if ($max_depth > $depth && !empty($children[$oid][$parent])) {
      $has_children = FALSE;
      $child = current($children[$oid][$parent]);
      do {
        if (empty($child)) {
          break;
        }

        // Retrieve the organigrams item. This can be a queried entity or a
        // fully loaded entity depending on the load_entities value.
        $organigrams_item = $organigrams_items[$oid][$child];
        if ($load_entities && isset($organigrams_item_entities[$child])) {
          $organigrams_item = $organigrams_item_entities[$child];
        }

        // Add the depth as a property.
        $organigrams_item->depth = $depth;

        // Add the organigrams item to the tree.
        $tree[] = $organigrams_item;

        // Check if the organigrams item has children.
        if (!empty($children[$oid][$organigrams_item->iid])) {

          // Indicate that new children were found.
          $has_children = TRUE;

          // We have to continue with this parent later.
          $process_parents[] = $parent;

          // Use the current organigrams item as parent for the next iteration.
          $process_parents[] = $organigrams_item->iid;

          // Reset pointers for child lists.
          reset($children[$oid][$organigrams_item->iid]);

          // Move pointer so that we get the current organigrams item the next
          // time.
          next($children[$oid][$parent]);
          break;
        }
      } while ($child = next($children[$oid][$parent]));

      // Check if the current iteration resulted in new children.
      if (!$has_children) {

        // We processed all terms in this hierarchy-level, reset pointer
        // so that this function works the next time it gets called.
        reset($children[$oid][$parent]);
      }
    }
  }

  // Return the constructed tree.
  return $tree;
}