You are here

function query_parameters_to_url_url_inbound_alter in Query Parameters To URL 7

Implements hook_url_inbound_alter().

1 call to query_parameters_to_url_url_inbound_alter()
QueryParametersToURLTestCase::testUrlEncodingAndDecoding in ./query_parameters_to_url.test
Tests url() encoding and decoding, affected by inbound / outbound hooks.
2 string references to 'query_parameters_to_url_url_inbound_alter'
query_parameters_to_url_init in ./query_parameters_to_url.module
Implements hook_init().
query_parameters_to_url_page_cache_object_alter in ./query_parameters_to_url.module
Implements hook_page_cache_object_alter().

File

./query_parameters_to_url.module, line 387
Query Arguments To URL module.

Code

function query_parameters_to_url_url_inbound_alter(&$path, $original_path, $path_language) {
  if (variable_get(QUERY_PARAMETERS_TO_URL_ENABLED, TRUE)) {

    // Don't rewrite URL, if trying to save a menu item with a rewritten URL.
    // URLs with aliases or query parameters cannot be saved as a menu item.
    // By not calling url_inbound_alter when saving the menu item path, we allow
    // the rewritten URL to be saved to the database, which overcomes this
    // limitation. This is a hack, and should not be used if possible.
    // @see https://www.drupal.org/node/118072#comment-9492455
    if (query_parameters_to_url_is_called_from_menu_item_edit()) {
      return;
    }
    $parts = explode('/', $path);
    $url_and_query_delimiter = query_parameters_to_url_url_query_delimiter();

    // Check if this is a path we should rewrite.
    $rewrite = query_parameters_to_url_path_should_be_rewritten($path, array(), $original_path, $path_language);
    if ($rewrite && ($p_key = array_search($url_and_query_delimiter, $parts)) !== FALSE) {
      $last_part_key = count($parts);

      // Extract all the path parts that are actually encoded query parameters.
      $extracted_query_parameters = array();
      for ($i = $p_key + 1; $i < $last_part_key; $i += 2) {
        $query_key = $parts[$i];

        // Validation that there are actually pairs of key-value.
        if (!isset($parts[$i + 1])) {
          continue;
        }
        $query_values = $parts[$i + 1];

        // Decode the query parameters values string.
        $query_parameter_values_array = query_parameters_to_url_decode_query_parameter_values($query_values);
        $extracted_query_parameters[$query_key] = $query_parameter_values_array;
      }
      if (!empty($extracted_query_parameters)) {

        // Save the initial inbound path to be used in the cache cid alter.
        $inbound_path =& drupal_static(__FUNCTION__ . '_inbound_path', '');
        $inbound_path = $path;

        // Remove the encoded query parameters in the path, and set it as the
        // inbound path.
        $path = implode('/', array_slice($parts, 0, $p_key));

        // Make a copy of the path for the request_uri, before the front page
        // check, so that the request URI has the empty string path, to make
        // sure global redirect module doesn't cause endless redirect loops,
        // by constantly comparing the request uri to the 'q' parameter, and
        // always seeing that request uri isn't empty, when it actually expects
        // it to be empty for the front page.
        $request_uri_path = $path;

        // Make sure to prepend the base path to the request URI, in case the
        // Drupal environment is not a virtual host, but rather a sub-folder
        // of the main domain. This also fixes endless redirect loops, when
        // Global Redirect is enabled.
        $base_path = base_path();
        if (!empty($base_path)) {
          $request_uri_path = $base_path . $request_uri_path;
        }

        // If path is empty, make sure to set it to the actual front page path,
        // because otherwise Drupal can't find the proper menu item, and returns
        // page not found.
        if (empty($path)) {
          $path = variable_get('site_frontpage', 'node');
        }

        // Mark that the inbound URL was altered, so that hook_init doesn't do
        // an endless redirect loop.
        $path_altered =& drupal_static(__FUNCTION__, FALSE);
        $path_altered = TRUE;
        if (query_parameters_to_url_rewrite_hooks_enabled()) {

          // Allow altering the final inbound url.
          $context = array(
            'direction' => 'inbound',
            'original_path' => $original_path,
            'path_language' => $path_language,
            'extracted_query_parameters' => &$extracted_query_parameters,
            'request_uri_path' => &$request_uri_path,
            'initial_url_components' => $parts,
          );
          drupal_alter('query_parameters_to_url_rewrite', $path, $context);
        }

        // If there were any query parameters imploded in the URL, put them
        // into $_GET, as if they were originally there.
        $_GET += $extracted_query_parameters;

        // Get a copy of all query parameters except for q.
        $query_parameters_without_q = drupal_get_query_parameters();

        // Build new REQUEST_URI, because certain modules extract the query
        // parameters from inside it, instead of $_GET. One example is Better
        // Exposed filters.
        // So the new REQUEST_URI will contain the new inbound path,
        // concatenated with all the query parameters present.
        // @ignore security_12
        if (isset($_SERVER['REQUEST_URI'])) {
          $query_string = http_build_query($query_parameters_without_q, '');
          $new_request_uri = $request_uri_path . '?' . $query_string;

          // @TODO Is this really a sec hole? If so what can we do about it?
          // @ignore security_12
          $_SERVER['REQUEST_URI'] = $new_request_uri;
          if (isset($_SERVER['QUERY_STRING'])) {
            $_SERVER['QUERY_STRING'] = $query_string;
          }
          if (isset($_SERVER['REDIRECT_QUERY_STRING'])) {
            $_SERVER['REDIRECT_QUERY_STRING'] = $query_string;
          }
        }
      }
    }
  }
}