0

If I visit example.route.one and certain conditions are fulfilled I want to redirect it to example.route.two OR else access should be allowed. How Can I achieve this? I tried writing the redirection in the custom controller routeOne but this method does not work properly for non-admin users, the issue being if I click/visit example.route it automatically redirects me to example.route.two

Menu Yml file - example.links.menu.yml

example.route:
  title: 'Route Example'
  route_name: example.route
  parent: system.admin
  description: 'Contains Route Example'
  weight: -99

example.route.one:
  title: 'Route One'
  route_name: example.route.one
  description: 'Route one example'
  parent: example.route
  weight: 1

example.route.two:
  title: 'Route Two'
  route_name: example.route.two
  description: 'Route two example'
  parent: example.route
  weight: 2

Routing File - exmaple.routing.yml

example.route:
  path: '/admin/route'
  defaults:
    _controller: '\Drupal\system\Controller\SystemController::systemAdminMenuBlockPage'
    _title: 'Route Example'
  requirements:
    _access: 'TRUE'

example.route.one:
  path: '/admin/route/one'
  defaults:
    _title: 'Route one'
    _controller: '\Drupal\example\Controller\ExampleController::contentOne'
  requirements:
    _custom_access: '\Drupal\example\Controller\ExampleController::routeOne'
  options:
    _admin_route: TRUE
    
example.route.two:
  path: '/admin/route/two'
  defaults:
    _title: 'Route two'
    _controller: '\Drupal\example\Controller\ExampleController::contentTwo'
  requirements:
    _custom_access: '\Drupal\example\Controller\ExampleController::routeTwo'
  options:
    _admin_route: TRUE

Controller for custom access - ExampleController.php

<?php

namespace Drupal\example\Controller;

use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Access\AccessResult;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Drupal\Core\Url;

/**
 * Defines a route controller .
 */
class ExampleController extends ControllerBase {

  /**
   * {@inheritdoc}
   */
  public function routeOne() {
    if (TRUE) {
      $response = new RedirectResponse(Url::fromRoute('example.route.two')->setAbsolute()->toString());
      $response->send();
      return AccessResult::forbidden();
    }
    else {
      return AccessResult::allowed();
    }
  }

  /**
   * {@inheritdoc}
   */
  public function routeTwo() {
    return AccessResult::allowed();
  }

  /**
   * {@inheritdoc}
   */
  public function contentOne() {
    return [
      '#type' => 'markup',
      '#markup' => $this->t("hello route one"),
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function contentTwo() {
    return [
      '#type' => 'markup',
      '#markup' => $this->t("hello route two"),
    ];
  }

}
0

1 Answer 1

0

The issue if you click/visit example.route it automatically redirects to example.route.two is caused by the access method not only called when you visit example.route.one, but also on other pages with links pointing to example.route.one, for example in a menu.

So use access methods only for calculating access results. If this then results in a 403 you can catch it in an event subscriber and set a redirect response instead of the default 403 message.

See Dynamically change the "access denied page" title and body.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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