You are here

function field_redirection_field_formatter_view in Field Redirection 7.2

Same name and namespace in other branches
  1. 7 field_redirection.module \field_redirection_field_formatter_view()

Implements hook_field_formatter_view().

If we have a node reference and we can redirect to it lets do it!

File

./field_redirection.module, line 216
Provides a field formatter to redirect to another path.

Code

function field_redirection_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {

  // Shortcuts to make the rest of the code simpler.
  $settings = $display['settings'];
  $codes = field_redirection_http_codes();

  // Optionally control the list of pages this works on.
  if (!empty($settings['page_restrictions']) && !empty($settings['pages'])) {

    // 1 = Redirect only on these pages, 2 = Redirect on all other pages.
    // Remove '1' from this value so it can be XOR'd later on.
    $page_restrictions = $settings['page_restrictions'] - 1;

    // Do raw token replacements.
    $pages = token_replace($settings['pages'], array(
      $entity_type => $entity,
    ), array(
      'clear' => 1,
      'sanitize' => 0,
    ));

    // Normalise all paths to lower case.
    $pages = drupal_strtolower($pages);
    $path_alias = drupal_strtolower(drupal_get_path_alias($_GET['q']));
    $page_match = drupal_match_path($path_alias, $pages);
    if ($path_alias != $_GET['q']) {
      $page_match = $page_match || drupal_match_path($_GET['q'], $pages);
    }

    // Stop processing if the page restrictions have matched.
    if (!($page_restrictions xor $page_match)) {
      return;
    }
  }

  // Don't execute if running via the CLI, e.g. Drush.
  if (constant('PHP_SAPI') == 'cli') {
    return;
  }
  elseif (strpos($_SERVER['PHP_SELF'], 'cron.php') !== FALSE) {
    return;
  }
  elseif ($_GET['q'] == 'admin/reports/status/run-cron') {
    return;
  }
  elseif (defined('MAINTENANCE_MODE') || variable_get('maintenance_mode', 0)) {
    return;
  }

  // Make some of the rest of the code simpler.
  $item = !empty($items[0]) ? $items[0] : array();
  $response_code = 301;
  if (!empty($settings['code']) && isset($codes[$settings['code']])) {
    $response_code = $settings['code'];
  }

  // Work out the destination path to redirect to. Each field type is handled
  // slightly differently, so identify that here.
  $path = '';
  $options = array();
  if (!empty($field['type'])) {
    switch ($field['type']) {

      // Entity reference field from the EntityReference module.
      case 'entityreference':
        if (!empty($item['target_id'])) {
          $referenced_entities = entity_load($field['settings']['target_type'], array(
            $item['target_id'],
          ));
          if (!empty($referenced_entities)) {
            $referenced_entity = reset($referenced_entities);
            if (!empty($referenced_entity)) {
              $uri = entity_uri($field['settings']['target_type'], $referenced_entity);
              if (!empty($uri['path'])) {
                $path = drupal_get_path_alias($uri['path']);
              }
            }
          }
        }
        break;

      // Fields from the core Image and File modules.
      case 'file':
      case 'image':
        if (!empty($item['uri'])) {
          $path = file_create_url($item['uri']);
        }
        break;

      // Link field from the Link module.
      case 'link_field':
        if (!empty($item['url'])) {

          // The path is the URL field itself.
          $path = $item['url'];

          // Cover for cases when a query string was provided.
          if (!empty($item['query'])) {
            $options['query'] = $item['query'];
          }

          // Optional fragment.
          if (!empty($item['fragment'])) {
            $options['fragment'] = $item['fragment'];
          }

          // Special handling for the front page.
          if ($path == '<front>') {
            $path = '<front>';
          }
        }
        break;

      // Node reference field from the node_reference module, part of the
      // References module.
      case 'node_reference':
      case 'node_reference_autocomplete':
        if (!empty($item['nid'])) {

          // Wrap the internal system path with its alias.
          $path = drupal_get_path_alias('node/' . $item['nid']);
        }
        break;

      // Term reference field from the core Taxonomy module.
      case 'taxonomy_term_reference':
      case 'taxonomy_term_reference_autocomplete':
        if (!empty($item['tid'])) {

          // Wrap the internal system path with its alias.
          $path = drupal_get_path_alias('taxonomy/term/' . $item['tid']);
        }
        break;

      // URL field from the URL module.
      case 'url':
        if (!empty($item['path'])) {
          $path = $item['path'];
          $options = $item['options'];
        }
        break;

      // User reference field from the user_reference module, part of the
      // References module.
      case 'user_reference':
      case 'user_reference_autocomplete':
        if (!empty($item['uid'])) {

          // Wrap the internal system path with its alias.
          $path = drupal_get_path_alias('user/' . $item['uid']);
        }
        break;
    }
  }

  // Don't redirect if the destination is the current page.
  if (!empty($path)) {

    // Simplest case.
    if ($_GET['q'] == $path) {
      $path = '';
    }
    else {
      $current_path = current_path();
      if ($path == $current_path || $path == url($current_path, array(
        'absolute' => TRUE,
      ))) {
        $path = '';
      }
      elseif ($path == '<front>' && drupal_is_front_page()) {
        $path = '';
      }
    }
  }

  // Only proceed if a path was identified.
  if (!empty($path)) {

    // Use default language to not prepend language prefix if path is absolute
    // without hostname.
    if ($path[0] == '/') {
      $path = substr($path, 1);
      $options['language'] = language_default();
    }

    // If the user has permission to bypass the page redirection, return a
    // message explaining where they would have been redirected to.
    if (user_access('bypass redirection')) {

      // "Listen very carefully, I shall say this only once." - 'Allo, 'Allo.
      $message = t('This page is set to redirect to <a href="!path">another URL</a>, but you have permission to see the page and not be automatically redirected.', array(
        '!path' => url($path, $options),
      ));
      if (empty($_SESSION['messages']['warning']) || !in_array($message, $_SESSION['messages']['warning'])) {
        drupal_set_message($message, 'warning');
      }
      $elements = array();
      $elements[] = array(
        '#theme' => 'link',
        '#text' => t('Redirected location'),
        '#path' => $path,
        '#options' => array(
          'attributes' => array(),
          'html' => FALSE,
        ),
      );
      return $elements;
    }
    else {

      // If caching this page, add 'Cache-Control' header before redirecting.
      $caching_enabled = variable_get('cache', 0);
      $page_cacheable = drupal_page_is_cacheable();
      $no_session_cookie = !isset($_COOKIE[session_name()]);
      if ($caching_enabled && $page_cacheable && $no_session_cookie) {

        // @see drupal_serve_page_from_cache().
        // If the client sent a session cookie, a cached copy will only be
        // served to that one particular client due to Vary: Cookie. Thus, do
        // not set max-age > 0, allowing the page to be cached by external
        // proxies, when a session cookie is present unless the Vary header has
        // been replaced or unset in hook_boot().
        $max_age = !isset($_COOKIE[session_name()]) || isset($hook_boot_headers['vary']) ? variable_get('page_cache_maximum_age', 0) : 0;
        drupal_add_http_header('Cache-Control', 'public, max-age=' . $max_age);
      }
      drupal_goto($path, $options, $response_code);
    }
  }
  elseif (!user_access('bypass redirection') && $display['settings']['404_if_empty']) {
    drupal_not_found();
  }
}