You are here

r4032login.module in Redirect 403 to User Login 2.x

Redirect denied pages to the user login form.

File

r4032login.module
View source
<?php

/**
 * @file
 * Redirect denied pages to the user login form.
 */
use Drupal\Component\Utility\UrlHelper;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
use Drupal\user\Entity\User;

/**
 * Implements hook_form_FORM_ID_alter().
 *
 * Alters the System module's site information settings form to add additional
 * r4032login settings.
 *
 * @see r4032login_form_system_site_information_settings_form_submit()
 */
function r4032login_form_system_site_information_settings_alter(&$form, FormStateInterface $form_state, $form_id) {
  $config = \Drupal::configFactory()
    ->getEditable('r4032login.settings');
  $form['error_page']['r4032login'] = [
    '#type' => 'details',
    '#title' => t('Redirect 403 to User Login'),
    '#description' => t('Redirect anonymous users from 403 Access Denied pages to the /user/login page.'),
    '#open' => TRUE,
  ];
  $form['error_page']['r4032login']['r4032login_redirect_to_destination'] = [
    '#type' => 'checkbox',
    '#weight' => 4,
    '#title' => t('Redirect user to the page they tried to access after login'),
    '#default_value' => $config
      ->get('redirect_to_destination'),
  ];
  $form['error_page']['r4032login']['r4032login_display_denied_message'] = [
    '#type' => 'checkbox',
    '#weight' => 5,
    '#title' => t('Display access denied message on login page'),
    '#description' => t('Displays an access denied message on the user login page.'),
    '#default_value' => $config
      ->get('display_denied_message'),
  ];
  $form['error_page']['r4032login']['r4032login_access_denied_message'] = [
    '#type' => 'textarea',
    '#rows' => 1,
    '#weight' => 6,
    '#title' => t("User login 'access denied' message"),
    '#description' => t('The message text displayed to users who are denied access to the page.'),
    '#default_value' => $config
      ->get('access_denied_message'),
    '#states' => [
      'invisible' => [
        'input[name="r4032login_display_denied_message"]' => [
          'checked' => FALSE,
        ],
      ],
    ],
  ];
  $form['error_page']['r4032login']['r4032login_access_denied_message_type'] = [
    '#type' => 'select',
    '#title' => t("User login 'access denied' message type"),
    '#description' => t('The message type displayed to users who are denied access to the page.'),
    '#default_value' => $config
      ->get('access_denied_message_type'),
    '#options' => [
      'error' => t('Error'),
      'warning' => t('Warning'),
      'status' => t('Status'),
    ],
    '#weight' => 7,
    '#states' => [
      'invisible' => [
        'input[name="r4032login_display_denied_message"]' => [
          'checked' => FALSE,
        ],
      ],
    ],
  ];
  $form['error_page']['r4032login']['r4032login_redirect_authenticated_users_to'] = [
    '#type' => 'textfield',
    '#weight' => 8,
    '#title' => t("Redirect authenticated users to"),
    '#description' => t('If an authenticated user tries to access a page they can not, redirect them to the given page. Use &lt;front&gt; for the front page, leave blank for a default access denied page.'),
    '#default_value' => $config
      ->get('redirect_authenticated_users_to'),
  ];
  $form['error_page']['r4032login']['r4032login_user_login_path'] = [
    '#type' => 'textfield',
    '#weight' => 9,
    '#title' => t("Path to user login form"),
    '#description' => t('The path to the user login form. Include the leading slash, i.e.: /user/login.'),
    '#default_value' => $config
      ->get('user_login_path'),
  ];
  $form['error_page']['r4032login']['r4032login_default_redirect_code'] = [
    '#type' => 'select',
    '#weight' => 10,
    '#title' => t("HTTP redirect code"),
    '#description' => t('The redirect code to send by default. 301 and 302 responses may be cached by browsers and proxies, so 307 is normally the correct choice.'),
    '#options' => [
      '307' => t('307 Temporary Redirect'),
      '302' => t('302 Found'),
      '301' => t('301 Moved Permanently'),
    ],
    '#default_value' => $config
      ->get('default_redirect_code'),
  ];
  $form['error_page']['r4032login']['r4032login_destination_parameter_override'] = [
    '#type' => 'textfield',
    '#weight' => 11,
    '#title' => t("Destination parameter override"),
    '#description' => t("The parameter to use when setting the return destination once login has succeeded. By default Drupal uses 'destination', but overriding this may be necessary if using an external login system such as CAS, Shibboleth or OAuth."),
    '#default_value' => $config
      ->get('destination_parameter_override'),
  ];
  $form['error_page']['r4032login']['matching_paths'] = [
    '#type' => 'details',
    '#title' => t('Skip redirect for matching pages'),
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
    '#weight' => 12,
  ];
  $form['error_page']['r4032login']['matching_paths']['r4032login_match_noredirect_pages'] = [
    '#type' => 'textarea',
    '#title' => '<span class="element-invisible">' . t('Only the listed pages') . '</span>',
    '#default_value' => $config
      ->get('match_noredirect_pages'),
    '#description' => t('Instead of redirecting, the user will get an access defined response and see the standard login form. This may be useful when the response code is important - such as for removing outdated content from search engines.') . ' ' . t("Specify pages by using their paths. Enter one path per line. The '*' character is a wildcard. Example paths are %blog for the blog page and %blog-wildcard for every personal blog. %front is the front page.", [
      '%blog' => '/blog',
      '%blog-wildcard' => '/blog/*',
      '%front' => '<front>',
    ]),
  ];
  $form['#validate'][] = 'r4032login_form_system_site_information_settings_validate';
  $form['#submit'][] = 'r4032login_form_system_site_information_settings_form_submit';
}

/**
 * Form validation handler for system_site_information_settings().
 *
 * @see r4032login_form_system_site_information_settings_alter()
 */
function r4032login_form_system_site_information_settings_validate($form, FormStateInterface $form_state) {
  $path_validator = \Drupal::pathValidator();
  if (!$form_state
    ->isValueEmpty('r4032login_redirect_authenticated_users_to') && !$path_validator
    ->isValid($form_state
    ->getValue('r4032login_redirect_authenticated_users_to'))) {
    $form_state
      ->setErrorByName('r4032login_redirect_authenticated_users_to', t("The redirect authenticated users path '%path' is either invalid or you do not have access to it.", [
      '%path' => $form_state
        ->getValue('r4032login_redirect_authenticated_users_to'),
    ]));
  }
  if (!$form_state
    ->isValueEmpty('r4032login_user_login_path')) {
    $r4032loginUserLoginPath = $form_state
      ->getValue('r4032login_user_login_path');

    // If Rename Admin Paths is present, replace its path by "user"
    // for validation so we can validate the path as usual.
    $moduleHandler = \Drupal::service('module_handler');
    if ($moduleHandler
      ->moduleExists('rename_admin_paths') && ($configFactory = \Drupal::service('config.factory')) && ($renameAdminPathsSettings = $configFactory
      ->get('rename_admin_paths.settings')
      ->getRawData()) && !empty($renameAdminPathsSettings['user_path']) && !empty($renameAdminPathsSettings['user_path_value'])) {
      $r4032loginUserLoginPath = str_replace($renameAdminPathsSettings['user_path_value'], 'user', $r4032loginUserLoginPath);
    }

    // Check the path validity
    // and whether the anonymous user can access the entered path.
    if (!UrlHelper::isExternal($r4032loginUserLoginPath) && (!$path_validator
      ->getUrlIfValidWithoutAccessCheck($r4032loginUserLoginPath) || !($url = Url::fromUserInput($r4032loginUserLoginPath)) || !$url
      ->access(User::getAnonymousUser()))) {
      $form_state
        ->setErrorByName('r4032login_user_login_path', t("The user login form path '%path' is either invalid or a logged out user does not have access to it.", [
        '%path' => $form_state
          ->getValue('r4032login_user_login_path'),
      ]));
    }
  }
}

/**
 * Form submission handler for system_site_information_settings().
 *
 * @see r4032login_form_system_site_information_settings_alter()
 */
function r4032login_form_system_site_information_settings_form_submit($form, FormStateInterface $form_state) {
  \Drupal::configFactory()
    ->getEditable('r4032login.settings')
    ->set('redirect_to_destination', $form_state
    ->getValue('r4032login_redirect_to_destination'))
    ->set('display_denied_message', $form_state
    ->getValue('r4032login_display_denied_message'))
    ->set('access_denied_message', $form_state
    ->getValue('r4032login_access_denied_message'))
    ->set('access_denied_message_type', $form_state
    ->getValue('r4032login_access_denied_message_type'))
    ->set('redirect_authenticated_users_to', $form_state
    ->getValue('r4032login_redirect_authenticated_users_to'))
    ->set('user_login_path', $form_state
    ->getValue('r4032login_user_login_path'))
    ->set('default_redirect_code', $form_state
    ->getValue('r4032login_default_redirect_code'))
    ->set('destination_parameter_override', $form_state
    ->getValue('r4032login_destination_parameter_override'))
    ->set('match_noredirect_pages', $form_state
    ->getValue('r4032login_match_noredirect_pages'))
    ->save();
}

/**
 * Implements hook_theme().
 */
function r4032login_theme() {
  return [
    'r4032login_denied' => [
      'variables' => [],
    ],
  ];
}

/**
 * Implements hook_config_translation_info_alter().
 */
function r4032login_config_translation_info_alter(&$info) {
  $info['system.site_information_settings']['names'][] = 'r4032login.settings';
}

Functions