Drupal 8 核心 bug: Views创建menu tab时无视参数验证

逆流の鱼, 21 三月, 2019

当用views创建page时,定义像'node/%node/foo'这样的路径,然后创建一个menu tab,在context filter里提供当前node页面的id作为默认参数,并开启参数验证:node type必须为article等。

当访问node/123/foo时,如果该node type不是article,会返回404等(根据设置),但menu tab依旧存在。

相关issue链接:

View argument validators are not taken into account in access checks

Views argument validators aren't taken into account on access checks - local task point to 404

暂时未有完美的patch,已推后至计划在drupal8.8.x-dev版本解决。

目前只有通过自定义模块去更替views建立的route配置

这也是通用的类似drupal 7的hook_menu_alter()方法

RouteSubscriber.php

<?php
namespace Drupal\round_robin\Routing;

use Drupal\Core\Routing\RouteSubscriberBase;
use Symfony\Component\Routing\RouteCollection;

/**
 * Listens to the dynamic route events.
 */
class RouteSubscriber extends RouteSubscriberBase {

  /**
   * {@inheritdoc}
   */
  protected function alterRoutes(RouteCollection $collection) {
    // Note that the second parameter of setRequirement() is a string.
    if ($route = $collection->get('view.matches.page_2')) {
      $route->setRequirement('_custom_access', 'Drupal\round_robin\Controller\RoundRobinController::access');
    }
  }

}

round_robin.services.yml

services:
  round_robin.route_subscriber:
    class: Drupal\round_robin\Routing\RouteSubscriber
    tags:
      - { name: event_subscriber }

Drupal\round_robin\Controller\RoundRobinController::access

......

  //verify route access
  public function access() {
    $bundle = false;
    $route = \Drupal::routeMatch();
    $nid = $route->getParameter('node');
    if (is_object($nid)) {
      $node = $nid;
    } else {
      $node = \Drupal\node\Entity\Node::load($nid);
    }
    if ($node instanceof \Drupal\node\NodeInterface) {
      $bundle = $node->bundle();
    }
    return AccessResult::allowedIf($bundle === 'league');
  }

 

 

评论