Commit 27bd89be authored by alexpott's avatar alexpott

Issue #1998228 by ParisLiakos, dawehner: Remove hook_menu_site_status_alter()...

Issue #1998228 by ParisLiakos, dawehner: Remove hook_menu_site_status_alter() in favor of request listeners.
parent f0f2475b
......@@ -2,11 +2,12 @@
/**
* @file
* Definition of Drupal\Core\EventSubscriber\MaintenanceModeSubscriber.
* Contains \Drupal\Core\EventSubscriber\MaintenanceModeSubscriber.
*/
namespace Drupal\Core\EventSubscriber;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
......@@ -18,22 +19,29 @@
class MaintenanceModeSubscriber implements EventSubscriberInterface {
/**
* Response with the maintenance page when the site is offline.
* Determine whether the page is configured to be offline.
*
* @param Symfony\Component\HttpKernel\Event\GetResponseEvent $event
* @param \Symfony\Component\HttpKernel\Event\GetResponseEvent $event
* The Event to process.
*/
public function onKernelRequestMaintenanceModeCheck(GetResponseEvent $event) {
public function onKernelRequestDetermineSiteStatus(GetResponseEvent $event) {
// Check if the site is offline.
$status = _menu_site_is_offline() ? MENU_SITE_OFFLINE : MENU_SITE_ONLINE;
// Allow other modules to change the site status but not the path. The path
// can be changed using a request listener.
$read_only_path = $event->getRequest()->attributes->get('system_path');
drupal_alter('menu_site_status', $status, $read_only_path);
$request = $event->getRequest();
$is_offline = _menu_site_is_offline() ? MENU_SITE_OFFLINE : MENU_SITE_ONLINE;
$request->attributes->set('_maintenance', $is_offline);
}
// Only continue if the site is online.
if ($status != MENU_SITE_ONLINE) {
/**
* Returns the site maintenance page if the site is offline.
*
* @param \Symfony\Component\HttpKernel\Event\GetResponseEvent $event
* The event to process.
*/
public function onKernelRequestMaintenance(GetResponseEvent $event) {
$request = $event->getRequest();
$response = $event->getResponse();
// Continue if the site is online and the response is not a redirection.
if ($request->attributes->get('_maintenance') != MENU_SITE_ONLINE && !($response instanceof RedirectResponse)) {
// Deliver the 503 page.
drupal_maintenance_theme();
drupal_set_title(t('Site under maintenance'));
......@@ -45,13 +53,13 @@ public function onKernelRequestMaintenanceModeCheck(GetResponseEvent $event) {
}
/**
* Registers the methods in this class that should be listeners.
*
* @return array
* An array of event listener definitions.
* {@inheritdoc}
*/
static function getSubscribedEvents() {
$events[KernelEvents::REQUEST][] = array('onKernelRequestMaintenanceModeCheck', 40);
// In order to change the maintenance status an event subscriber with a
// priority between 30 and 40 should be added.
$events[KernelEvents::REQUEST][] = array('onKernelRequestDetermineSiteStatus', 40);
$events[KernelEvents::REQUEST][] = array('onKernelRequestMaintenance', 30);
return $events;
}
}
......@@ -179,9 +179,9 @@ function testThemeCallbackMaintenanceMode() {
}
/**
* Make sure the maintenance mode can be bypassed using hook_menu_site_status_alter().
* Make sure the maintenance mode can be bypassed using an EventSubscriber.
*
* @see hook_menu_site_status_alter().
* @see \Drupal\menu_test\EventSubscriber\MaintenanceModeSubscriber::onKernelRequestMaintenance().
*/
function testMaintenanceModeLoginPaths() {
config('system.maintenance')->set('enabled', 1)->save();
......@@ -190,7 +190,7 @@ function testMaintenanceModeLoginPaths() {
$this->drupalGet('test-page');
$this->assertText($offline_message);
$this->drupalGet('menu_login_callback');
$this->assertText('This is menu_login_callback().', 'Maintenance mode can be bypassed through hook_menu_site_status_alter().');
$this->assertText('This is menu_login_callback().', 'Maintenance mode can be bypassed using an event subscriber.');
config('system.maintenance')->set('enabled', 0)->save();
}
......
......@@ -3497,29 +3497,6 @@ function hook_countries_alter(&$countries) {
$countries['EB'] = 'Elbonia';
}
/**
* Control site status before menu dispatching.
*
* The hook is called after checking whether the site is offline but before
* the current router item is retrieved and executed. If the site is in offline
* mode, $menu_site_status is set to MENU_SITE_OFFLINE.
*
* @param $menu_site_status
* Supported values are MENU_SITE_OFFLINE, MENU_ACCESS_DENIED,
* MENU_NOT_FOUND and MENU_SITE_ONLINE. Any other value than
* MENU_SITE_ONLINE will skip the default menu handling system and be passed
* for delivery directly.
* @param $path
* Contains the system path that is going to be loaded. This is read only,
* use a request listener to change the inbound path.
*/
function hook_menu_site_status_alter(&$menu_site_status, $path) {
// Allow access to my_module/authentication even if site is in offline mode.
if ($menu_site_status == MENU_SITE_OFFLINE && user_is_anonymous() && $path == 'my_module/authentication') {
$menu_site_status = MENU_SITE_ONLINE;
}
}
/**
* Register information about FileTransfer classes provided by a module.
*
......
<?php
/**
* @file
* Contains \Drupal\menu_test\EventSubscriber\MaintenanceModeSubscriber.
*/
namespace Drupal\menu_test\EventSubscriber;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
/**
* Maintenance mode subscriber to set site online on a test.
*/
class MaintenanceModeSubscriber implements EventSubscriberInterface {
/**
* Set the page online if called from a certain path.
*
* @param \Symfony\Component\HttpKernel\Event\GetResponseEvent $event
* The event to process.
*/
public function onKernelRequestMaintenance(GetResponseEvent $event) {
$request = $event->getRequest();
// Allow access to menu_login_callback even if in maintenance mode.
if ($request->attributes->get('_maintenance') == MENU_SITE_OFFLINE && $request->attributes->get('system_path') == 'menu_login_callback') {
$request->attributes->set('_maintenance', MENU_SITE_ONLINE);
}
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents() {
$events[KernelEvents::REQUEST][] = array('onKernelRequestMaintenance', 35);
return $events;
}
}
......@@ -679,16 +679,6 @@ function menu_test_static_variable($value = NULL) {
return $variable;
}
/**
* Implements hook_menu_site_status_alter().
*/
function menu_test_menu_site_status_alter(&$menu_site_status, $path) {
// Allow access to menu_login_callback even if in maintenance mode.
if ($menu_site_status == MENU_SITE_OFFLINE && $path == 'menu_login_callback') {
$menu_site_status = MENU_SITE_ONLINE;
}
}
/**
* Menu callback to be used as a login path.
*/
......
services:
menu_test_maintenance_mode_subscriber:
class: Drupal\menu_test\EventSubscriber\MaintenanceModeSubscriber
tags:
- { name: event_subscriber }
......@@ -11,37 +11,23 @@
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Drupal\Core\Controller\ControllerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
/**
* Controller routines for user routes.
*/
class UserController implements ControllerInterface {
/**
* The module handler service.
*
* @var \Drupal\Core\Extension\ModuleHandlerInterface
*/
protected $moduleHandler;
/**
* Constructs an UserController object.
*
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
* The module handler service.
*/
public function __construct(ModuleHandlerInterface $module_handler) {
$this->moduleHandler = $module_handler;
public function __construct() {
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('module_handler')
);
return new static();
}
/**
......@@ -54,12 +40,7 @@ public static function create(ContainerInterface $container) {
* A redirection to home page.
*/
public function logout(Request $request) {
global $user;
watchdog('user', 'Session closed for %name.', array('%name' => $user->name));
$this->moduleHandler->invokeAll('user_logout', array($user));
// Destroy the current session, and reset $user to the anonymous user.
session_destroy();
user_logout();
// @todo Remove the destination check once drupal.org/node/1668866 is in.
$url = $request->query->get('destination') ?: '<front>';
return new RedirectResponse(url($url, array('absolute' => TRUE)));
......
<?php
/**
* @file
* Contains \Drupal\user\EventSubscriber\MaintenanceModeSubscriber.
*/
namespace Drupal\user\EventSubscriber;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
/**
* Maintenance mode subscriber to logout users.
*/
class MaintenanceModeSubscriber implements EventSubscriberInterface {
/**
* Determine whether the page is configured to be offline.
*
* @param \Symfony\Component\HttpKernel\Event\GetResponseEvent $event
* The event to process.
*/
public function onKernelRequestMaintenance(GetResponseEvent $event) {
$request = $event->getRequest();
$site_status = $request->attributes->get('_maintenance');
$path = $request->attributes->get('system_path');
if ($site_status == MENU_SITE_OFFLINE) {
// If the site is offline, log out unprivileged users.
if (user_is_logged_in() && !user_access('access site in maintenance mode')) {
user_logout();
// Redirect to homepage.
$event->setResponse(new RedirectResponse(url('<front>', array('absolute' => TRUE))));
return;
}
if (user_is_anonymous()) {
switch ($path) {
case 'user':
// Forward anonymous user to login page.
$event->setResponse(new RedirectResponse(url('user/login', array('absolute' => TRUE))));
return;
case 'user/login':
case 'user/password':
// Disable offline mode.
$request->attributes->set('_maintenance', MENU_SITE_ONLINE);
break;
default:
if (strpos($path, 'user/reset/') === 0) {
// Disable offline mode.
$request->attributes->set('_maintenance', MENU_SITE_ONLINE);
}
break;
}
}
}
if (user_is_logged_in()) {
if ($path == 'user/login') {
// If user is logged in, redirect to 'user' instead of giving 403.
$event->setResponse(new RedirectResponse(url('user', array('absolute' => TRUE))));
return;
}
if ($path == 'user/register') {
// Authenticated user should be redirected to user edit page.
$event->setResponse(new RedirectResponse(url('user/' . $GLOBALS['user']->uid . '/edit', array('absolute' => TRUE))));
return;
}
}
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents() {
$events[KernelEvents::REQUEST][] = array('onKernelRequestMaintenance', 35);
return $events;
}
}
......@@ -1050,48 +1050,6 @@ function user_menu() {
return $items;
}
/**
* Implements hook_menu_site_status_alter().
*/
function user_menu_site_status_alter(&$menu_site_status, $path) {
if ($menu_site_status == MENU_SITE_OFFLINE) {
// If the site is offline, log out unprivileged users.
if (user_is_logged_in() && !user_access('access site in maintenance mode')) {
module_load_include('pages.inc', 'user', 'user');
user_logout();
}
if (user_is_anonymous()) {
switch ($path) {
case 'user':
// Forward anonymous user to login page.
drupal_goto('user/login');
case 'user/login':
case 'user/password':
// Disable offline mode.
$menu_site_status = MENU_SITE_ONLINE;
break;
default:
if (strpos($path, 'user/reset/') === 0) {
// Disable offline mode.
$menu_site_status = MENU_SITE_ONLINE;
}
break;
}
}
}
if (user_is_logged_in()) {
if ($path == 'user/login') {
// If user is logged in, redirect to 'user' instead of giving 403.
drupal_goto('user');
}
if ($path == 'user/register') {
// Authenticated user should be redirected to user edit page.
drupal_goto('user/' . $GLOBALS['user']->uid . '/edit');
}
}
}
/**
* Implements hook_menu_link_presave().
*/
......@@ -2675,3 +2633,17 @@ function user_library_info() {
return $libraries;
}
/**
* Logs the current user out.
*/
function user_logout() {
global $user;
watchdog('user', 'Session closed for %name.', array('%name' => $user->name));
Drupal::moduleHandler()->invokeAll('user_logout', array($user));
// Destroy the current session, and reset $user to the anonymous user.
session_destroy();
}
......@@ -169,22 +169,6 @@ function user_pass_reset($form, &$form_state, $uid, $timestamp, $hashed_pass, $a
}
}
/**
* Logs the current user out, and redirects to the home page.
*/
function user_logout() {
global $user;
watchdog('user', 'Session closed for %name.', array('%name' => $user->name));
module_invoke_all('user_logout', $user);
// Destroy the current session, and reset $user to the anonymous user.
session_destroy();
drupal_goto();
}
/**
* Prepares variables for user templates.
*
......
......@@ -21,3 +21,7 @@ services:
user.autocomplete:
class: Drupal\user\UserAutocomplete
arguments: ['@database', '@config.factory']
user_maintenance_mode_subscriber:
class: Drupal\user\EventSubscriber\MaintenanceModeSubscriber
tags:
- { name: event_subscriber }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment