context_redirect_reaction.inc in Context Redirect 7
Same filename and directory in other branches
Context redirect reaction plugin for Context API.
File
context_redirect_reaction.incView source
<?php
/**
* @file
* Context redirect reaction plugin for Context API.
*/
class context_redirect_reaction extends context_reaction {
/**
* Implements options_form().
*/
public function options_form($context) {
$values = $this
->fetch_from_context($context);
$form['#tree'] = TRUE;
$form['redirect_path'] = array(
'#title' => t('Redirect URL or path'),
'#type' => 'textfield',
'#default_value' => isset($values['redirect_path']) ? $values['redirect_path'] : '',
'#description' => t('Provide a valid internal URL (ie. node/1) or path (ie. company/about-us) or an external URL (ie. http://drupal.org). You may also use @front to redirect to the front page.', array(
'@front' => '<front>',
)),
);
$form['enable_message'] = array(
'#title' => t('Display redirect message'),
'#type' => 'checkbox',
'#default_value' => isset($values['enable_message']) ? $values['enable_message'] : 0,
'#description' => t('When enabled, this will display a message to the user saying they were redirected.'),
);
$form['redirect_message'] = array(
'#title' => t('Redirect message'),
'#type' => 'textfield',
'#default_value' => isset($values['redirect_message']) ? $values['redirect_message'] : '',
'#description' => t('The message displayed to the user after they are redirected.'),
'#states' => array(
'visible' => array(
':input[name="reactions[plugins][context_redirect][enable_message]"]' => array(
'checked' => TRUE,
),
),
),
);
$form['qsa'] = array(
'#title' => t('Attach query string'),
'#type' => 'checkbox',
'#default_value' => isset($values['qsa']) ? $values['qsa'] : 0,
'#description' => t('When enabled, append the original query string (GET values) to redirected URL.'),
);
$form['redirect_type'] = array(
'#title' => t('Redirect type'),
'#type' => 'select',
'#default_value' => isset($values['redirect_type']) ? $values['redirect_type'] : 302,
'#description' => t('The type of redirect to issue. You can !link.', array(
'!link' => l('review HTTP redirect codes here', 'http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3'),
)),
'#options' => array(
301 => '301: Moved Permanently',
302 => '302: Found',
303 => '303: See Other',
307 => '307: Temporary Redirect',
),
);
$form['admin_key'] = array(
'#title' => t('Admin Key'),
'#type' => 'textfield',
'#default_value' => isset($values['admin_key']) ? $values['admin_key'] : '',
'#field_prefix' => url('', array(
'query' => array(
'admin_key' => '',
),
'absolute' => TRUE,
)),
'#description' => t('You can optionally provide an "admin key" which you can enter as a get variable in the page url to prevent the redirect triggering (eg. ?admin_key=no-redirect-please your admin key would be "no-redirect-please"). Leave blank to disable this.'),
);
return $form;
}
/**
* Implements execute().
*/
public function execute() {
$contexts = $this
->get_contexts();
// Check if we need to react to current Contexts.
foreach ($contexts as $context) {
if (!empty($context->reactions[$this->plugin])) {
if ($url = $context->reactions[$this->plugin]['redirect_path']) {
// Do nothing if this reaction is an invalid redirection.
if ($this
->context_redirect_validate_redirect($url, $context)) {
// Display a message if required.
if ($context->reactions[$this->plugin]['enable_message'] && !(url_is_external($url) && !context_redirect_external_url_is_local($url))) {
drupal_set_message(t('@message', array(
'@message' => check_plain($context->reactions[$this->plugin]['redirect_message']),
)));
}
// Start building an $options array for drupal_goto().
$options = array();
// Preserve the current query parameters if required.
if ($context->reactions[$this->plugin]['qsa']) {
$options['query'] = drupal_get_query_parameters();
}
// Log a watchdog notice.
watchdog('context_redirect', 'User was redirected with the @context context, from @from to @destination.', array(
'@context' => $context->name,
'@from' => current_path(),
'@destination' => $url,
), WATCHDOG_NOTICE, l("Configure {$context->name} context", "admin/structure/context/list/{$context->name}"));
// If the url is "external" according to url_is_external()
// && the url is a domain defined by the Domain Access module
// && the current url is not a registered path on this domain
// then the 'destination' is set to the current internal path,
// leading to an infinite redirect from drupal_goto().
// @see http://drupal.org/node/1883796
if (url_is_external($url) && isset($_GET['destination'])) {
unset($_GET['destination']);
}
// Perform the redirection.
$http_response_code = isset($context->reactions[$this->plugin]['redirect_type']) ? $context->reactions[$this->plugin]['redirect_type'] : 302;
drupal_goto($url, $options, $http_response_code);
}
}
}
}
}
/**
* Validate the redirection.
*
* Depending on the current page, the destination url and the context's
* configuration we may not want to allow this redirection.
*
* @param string $url
* The candidate destination url to be validated.
* @param object $context
* The context object provided by Context API.
*
* @return boolean
* TRUE if the redirect should be allowed, FALSE otherwise.
*/
public function context_redirect_validate_redirect($url, $context) {
$valid_redirect = TRUE;
$current_path = request_path();
// If the url is not a valid path do nothing.
if (!drupal_valid_path($url, FALSE)) {
$valid_redirect = FALSE;
}
// Resolve aliases and/or relative paths to absolute system urls if possible
// and attempt to detect obvious redirect loops.
$normalized_url = url_is_external($url) ? rtrim($url, '/') . '/' : url(drupal_get_normal_path($url), array(
'absolute' => TRUE,
));
$normalized_current_path = url(drupal_get_normal_path($current_path), array(
'absolute' => TRUE,
));
if ($normalized_url == $normalized_current_path) {
$valid_redirect = FALSE;
}
// Don't perform redirections on the context configuration screens.
if (strpos($current_path, 'admin/structure/context') === 0) {
$valid_redirect = FALSE;
}
// Admin key override.
if ($admin_key = $context->reactions['context_redirect']['admin_key']) {
if (isset($_GET['admin_key']) && $_GET['admin_key'] == $admin_key) {
$valid_redirect = FALSE;
}
}
// Allow other modules to invalidate the redirect.
drupal_alter('context_redirect_validate_redirect', $valid_redirect, $context);
return $valid_redirect;
}
}
Classes
Name | Description |
---|---|
context_redirect_reaction | @file Context redirect reaction plugin for Context API. |