How can I exclude certain routes from maintenance mode?
-
28-02-2021 - |
Question
I am trying to make certain routes exempt from maintenance mode by adding the option _maintenance_access to the route and setting it to TRUE.
I think (although I'm not 100%) that this works because in Drupal\Core\Site\MaintenanceMode there is the following method which checks for the _maintenance_access option and returns false if it is present -
public function applies(RouteMatchInterface $route_match) {
if (!$this->state->get('system.maintenance_mode')) {
return FALSE;
}
if ($route = $route_match->getRouteObject()) {
if ($route->getOption('_maintenance_access')) {
return FALSE;
}
}
return TRUE;
}
I have followed this guide on drupal.org on how to alter existing routes
Here is my mymodule.services.yml file
services:
mymodule.route_subscriber:
class: Drupal\mymodule\Routing\MaintenanceModeRouteSubscriber
tags:
- { name: event_subscriber }
Here is my MaintenanceModeRouteSubscriber class
<?php
namespace Drupal\mymodule\Routing;
use Drupal\Core\Routing\RouteSubscriberBase;
use Symfony\Component\Routing\RouteCollection;
class MaintenanceModeRouteSubscriber extends RouteSubscriberBase {
/**
* {@inheritdoc}
*/
protected function alterRoutes(RouteCollection $collection) {
if ($route = $collection->get('entity.node.canonical')) {
$route->addOptions(['_maintenance_access' => TRUE]);
}
}
}
But this is not working as when viewing this route (any node) it is still in maintenance mode.
Solution
You need to override the service directly.
mymodule.services.yml
services:
maintenance_mode: # same ID as declared in core.services.yml
class: Drupal\mymodule\Services\CustomMaintenanceMode # point to your class
arguments: ['@state']
mymodule/src/Services/CustomMaintenaceMode.php
<?php
namespace Drupal\mymodule\Services;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Site\MaintenanceMode;
class CustomMaintenanceMode extends MaintenanceMode {
/**
* {@inheritdoc}
*/
public function exempt(AccountInterface $account) {
$node = \Drupal::routeMatch()->getParameter('node');
if ($node instanceof \Drupal\node\NodeInterface && $node->getType() == 'article') {
return TRUE;
}
else {
return $account->hasPermission('access site in maintenance mode');
}
}
}
Licensed under: CC-BY-SA with attribution
Not affiliated with drupal.stackexchange