You are here

function hansel_get_breadcrumbs in Hansel breadcrumbs 7

Same name and namespace in other branches
  1. 8 hansel.module \hansel_get_breadcrumbs()

Generate breadcrumbs.

Parameters

bool $test: Save test messages.

bool $html: Return the output in plain text rather than HTML.

bool $keep_last_item: Force this function to keep the last item, even when the settings are set to hide it. This is used for the alias token.

array $flags: Breadcrumb actions and switches can act differently upon the given flags.

Return value

mixed Array with breadcrumbs or FALSE (means: leave with restore option).

4 calls to hansel_get_breadcrumbs()
hansel_get_themed_breadcrumbs in ./hansel.module
Get themed breadcrumbs, which content may be overruled by Hansel.
hansel_tokens in ./hansel.module
Implements of hook_tokens().
hansel_ui_test_form in hansel_ui/hansel_ui.test.inc
Menu callback to generate the Hansel test form.
_hansel_activate_menu in ./hansel.module
Set the active menu item to the item corresponding the breadcrumbs.

File

./hansel.module, line 462
Hansel module

Code

function hansel_get_breadcrumbs($test = FALSE, $plaintext = FALSE, $keep_last_item = FALSE, $flags = array()) {
  global $_hansel_flags, $is_https, $user;
  $_hansel_flags = $flags;

  // Check if we can use caching.
  if (!$user->uid && ($cache_lifetime = variable_get('hansel_cache_whole', 0))) {
    $cid = array(
      $test,
      $plaintext,
      $keep_last_item,
      implode(',', $flags),
      $is_https,
      $_SERVER['HTTP_HOST'],
      request_uri(),
    );

    // Let other modules add contextual variables.
    drupal_alter('hansel_cache_parts', $cid);
    $cid = 'hansel:b:' . implode(':', $cid);
    if ($cache = cache_get($cid)) {
      return $cache->data;
    }
  }
  else {
    $cid = NULL;
  }
  $config = hansel_get_config();
  extract($config);
  if (!$start_rid) {
    !$test or _hansel_test_message(t('No rule found with name "start" on the top level'));
    return FALSE;
  }
  $crumb_actions = _hansel_get_action_types();
  $switch_types = _hansel_get_switch_types();

  // Define variable containing rule id's we had used.
  // We need this to prevent infinite loops generated by wrong goto actions.
  $history = array();

  // Define variable containing the newly generated breadcrumbs.
  $breadcrumbs = array();

  // Set the current rule id to the start rule.
  $rid = $start_rid;

  // Walk through the rules until we return or break.
  while (TRUE) {

    // Check for recursion.
    if (in_array($rid, $history)) {
      !$test or _hansel_test_message(t('Got recursion on rule %name', array(
        '%name' => $rules[$rid]->name,
      )));
      return FALSE;
    }
    $history[] = $rid;
    !$test or _hansel_test_message(t('Executing rule %name', array(
      '%name' => $rules[$rid]->name,
    )));

    // Execute crumb action.
    if ($rules[$rid]->crumb_action) {
      !$test or _hansel_test_message(t('Executing crumb action %type', array(
        '%type' => $rules[$rid]->crumb_action,
      )));
      $callback = $crumb_actions[$rules[$rid]->crumb_action]['get crumbs'];
      if (!function_exists($callback)) {
        !$test or _hansel_test_message(t('Callback not found'));
        break;

        // Break while (TRUE) loop
      }
      $crumbs = call_user_func($callback, $rules[$rid]->crumb_action_arguments);
      for ($i = 0; $i < count($crumbs); $i++) {
        if (empty($crumbs[$i]) || is_array($crumbs[$i]) && empty($crumbs[$i]['title'])) {

          // Skip empty breadcrumbs in output.
          continue;
        }
        $breadcrumbs[] = $crumbs[$i];
      }
      !$test or _hansel_test_message(t('Added %count crumb(s)', array(
        '%count' => count($crumbs),
      )));
    }

    // Execute action.
    switch ($rules[$rid]->action) {
      case 'goto':
        if (!isset($rules[$rules[$rid]->destination])) {
          !$test or _hansel_test_message(t('Destination not found, leaving'));
          break 2;

          // Break while (TRUE) loop
        }
        !$test or _hansel_test_message(t('Goto rule %name', array(
          '%name' => $rules[$rules[$rid]->destination]->name,
        )));
        $rid = $rules[$rid]->destination;
        break;
      case 'switch':
        !$test or _hansel_test_message(t('switch on %handler', array(
          '%handler' => $rules[$rid]->handler,
        )));
        $callback = $switch_types[$rules[$rid]->handler]['compare'];
        if (!function_exists($callback)) {
          !$test or _hansel_test_message(t('Callback not found'));
          break 2;

          // Break while (TRUE) loop
        }
        $default_rid = NULL;
        foreach ($rules[$rid]->children as $child_rid) {
          if (call_user_func($callback, $rules[$rid]->arguments, $rules[$child_rid]->name)) {
            !$test or _hansel_test_message(t('Match on rule %name', array(
              '%name' => $rules[$child_rid]->name,
            )));
            $rid = $child_rid;
            break 2;
          }
          else {
            !$test or _hansel_test_message(t('No match on rule %name', array(
              '%name' => $rules[$child_rid]->name,
            )));
            if ($rules[$child_rid]->name == '<default>') {
              $default_rid = $child_rid;
            }
          }
        }
        if ($default_rid) {
          !$test or _hansel_test_message(t('Using default rule'));
          $rid = $default_rid;
        }
        else {
          !$test or _hansel_test_message(t('No default rule found, leaving'));
          break 2;

          // Break while (TRUE) loop
        }
        break;
      case 'leave':
      default:

        // Check if the "restore original breadcrumbs" option is checked.
        if ($rules[$rid]->restore) {
          hansel_breadcrumb_was_restored(TRUE);
          !$test or _hansel_test_message(t('Leave and restore old breadcrumbs'));
          !$cid or cache_set($cid, FALSE);
          return FALSE;
        }
        else {
          !$test or _hansel_test_message(t('Leave'));
          break 2;

          // Break while (TRUE) loop
        }
        break;
    }
  }
  $count = count($breadcrumbs);
  $last_item_number = $count - 1;
  $last_item_link = variable_get('hansel_breadcrumb_last_item_link', TRUE);

  // Convert breadcrumbs array structure into an array with HTML links
  for ($i = 0; $i < $count; ++$i) {

    // Breadcrumbs should be returned in an array by the get crumbs callbacks.
    // Strings are supported for legacy, but are deprecated.
    // Please note that tokens are not supported only on arrays.
    if (is_array($breadcrumbs[$i])) {
      $breadcrumbs[$i]['title'] = hansel_replace_tokens($breadcrumbs[$i]['title'], $breadcrumbs[$i]);
      if ($plaintext) {
        $breadcrumbs[$i] = $breadcrumbs[$i]['title'];
        continue;
      }
      $breadcrumbs[$i]['href'] = hansel_replace_tokens($breadcrumbs[$i]['href'], $breadcrumbs[$i]);
      $breadcrumbs[$i]['title'] = _hansel_trim($breadcrumbs[$i]['title']);
      switch ($breadcrumbs[$i]['href']) {
        case '<none>':
          $breadcrumbs[$i] = check_plain($breadcrumbs[$i]['title']);
          break;
        case '<front>':
          $breadcrumbs[$i] = $last_item_link || $i != $last_item_number ? l($breadcrumbs[$i]['title'], '') : check_plain($breadcrumbs[$i]['title']);
          break;
        default:
          if ($breadcrumbs[$i]['href'] && $breadcrumbs[$i]['href'][0] == '/') {

            // Prefix paths starting with a slash with the full URI.
            if (preg_match('/^(https?...[^\\/]+)/', url('', array(
              'absolute' => TRUE,
            )), $match)) {
              $breadcrumbs[$i]['href'] = $match[1] . $breadcrumbs[$i]['href'];
            }
          }
          $breadcrumbs[$i] = $last_item_link || $i != $last_item_number ? l($breadcrumbs[$i]['title'], $breadcrumbs[$i]['href']) : check_plain($breadcrumbs[$i]['title']);
      }
    }
  }

  // Remove the last item if the "Hide last item" configuration option is set.
  if (variable_get('hansel_breadcrumb_last_item_hide', FALSE) && !$keep_last_item) {
    if ($count) {
      !$test or _hansel_test_message(t('Removing last breadcrumb item (hide last item configuration option is set)'));
      array_pop($breadcrumbs);
      --$count;
    }
  }

  // Trim whole items if a maximum item count is set.
  if ($max_items = variable_get('hansel_max_item_count', 0)) {
    if ($count > $max_items) {
      $trimmed_breadcrumbs = array();
      for ($i = 0; $i < floor($max_items / 2); $i++) {
        $trimmed_breadcrumbs[] = $breadcrumbs[$i];
      }
      if ($replacement = variable_get('hansel_removed_items_replacement', '(...)')) {
        $trimmed_breadcrumbs[] = check_plain($replacement);
      }
      for ($i = $count - ceil($max_items / 2); $i < $count; $i++) {
        $trimmed_breadcrumbs[] = $breadcrumbs[$i];
      }
      $breadcrumbs = $trimmed_breadcrumbs;
    }
  }

  // Store in cache if applicable.
  if ($cid) {
    cache_set($cid, array(
      'breadcrumb' => $breadcrumbs,
    ), 'cache', $cache_lifetime);
  }
  return array(
    'breadcrumb' => $breadcrumbs,
  );
}