質問

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.

役に立ちましたか?

解決

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

}
ライセンス: CC-BY-SA帰属
所属していません drupal.stackexchange
scroll top