我正在尝试为Drupal 8中未发布的节点返回404页面而不是403响应。
我测试了 内核响应订户,但是发现我使用的代码只会将状态代码从403更改为404,而实际上不显示404页面。因此,也许有人可以向我展示如何在其中生成404页面Response对象?
这是我正在使用的代码:
class ResponseSubscriber implements EventSubscriberInterface {
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents() {
return [KernelEvents::RESPONSE => [['alterResponse']]];
}
/**
* Change status code to 404 from 403 if page is an unpublished node.
*
* @param FilterResponseEvent $event
* The route building event.
*/
public function alterResponse(FilterResponseEvent $event) {
if ($event->getResponse()->getStatusCode() == 403) {
/** @var \Symfony\Component\HttpFoundation\Request $request */
$request = $event->getRequest();
$node = $request->attributes->get('node');
if ($node instanceof Node && !$node->isPublished()) {
$response = $event->getResponse();
// This changes the code, but doesn't return a 404 page.
$response->setStatusCode(404);
$event->setResponse($response);
}
}
}
}
我最终诉诸于完全删除此响应订户,并像这样使用hook_node_access:
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Drupal\Core\Access\AccessResult;
function unpublished_404_node_access(\Drupal\node\NodeInterface $node, $op, \Drupal\Core\Session\AccountInterface $account) {
if ($op == 'view' && !$node->isPublished()) {
if (\Drupal::moduleHandler()->moduleExists('workbench_moderation') && $account->hasPermission('view any unpublished content')) {
return AccessResult::neutral();
}
elseif (\Drupal::routeMatch()->getRouteName() == 'entity.node.canonical' && \Drupal::routeMatch()->getRawParameter('node') == $node->id()) {
throw new NotFoundHttpException();
return AccessResult::neutral();
}
}
return AccessResult::neutral();
}
这似乎与该站点上有关Drupal 7的几个答案是一致的。但是我想看看是否有人通过KernelEvent订阅者而不是hook_node_access拥有更好的方法。似乎我想做的是测试节点是否返回403,然后生成带有404页面和404状态代码的新响应。我不确定该怎么做。