3

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.

  • Your code works fine for me. Do you see any errors when clearing the cache with drush cr? Try to print debug messages which you then see from the command line like var_dump($route);. – 4k4 Oct 1 at 8:07
  • I'm not sure what is going on (no errors), what happens when you try to view a node when not logged in and when maintenance mode is on? Does it allow you to view it? – hck12685 Oct 1 at 9:18
  • Yes, I can view nodes, other pages return the maintenance message. Did you try to print a debug message from alterRoutes() to see if it is working when clearing the cache? – 4k4 Oct 1 at 9:37
2

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');
    }
  }

}
| improve this answer | |
  • Thank you, would overiding the service directly allow me to, say for instance, allow one node type and disallow another from the maintenance mode access? – hck12685 Sep 30 at 22:36
  • Yes, but I'm babysitting right now, I'll show ya later. – No Sssweat Sep 30 at 22:51
  • @hck12685 after testing this out, turns out you need to override the exempt() method as overriding the applies() method to TRUE didn't do it. – No Sssweat Oct 1 at 3:26
  • Yes I figured that out, thanks. It does seem to be working now as the maintenance mode is gone, but now I am left with a "The requested page could not be found. " message. So some more debugging required. If it is anything related to this question I will post the solution back here. – hck12685 Oct 1 at 9:23
  • Probably due to some contrib/custom module introducing that, because I'm not getting that on a fresh D8 install. – No Sssweat Oct 1 at 9:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.