web-dev-qa-db-ja.com

Cookieに基づいてリダイレクトする場合のWSOD

ユーザーが特定のコンテンツタイプにアクセスするときにCookieを設定するサイトがあります。

function THEME_preprocess_node(&$variables) {
  if (isset($variables['node']) && $variables['node']->getType() == 'MYTYPE') {
    // Store cookie with id of active node.
    user_cookie_save(['THEME_location' => $variables['node']->get('nid')->getString()]);
  }
}

次に、ユーザーが再びトップページにアクセスする場合、上記のCookieから参照されるノードにユーザーをリダイレクトしたいと思います。

function THEME_preprocess(&$variables, $hook) {
  $variables['is_front'] = \Drupal::service('path.matcher')->isFrontPage();

  // Redirect the user to the selected node.
  $cookies = \Drupal::request()->cookies->all();
  if ($variables['is_front'] && isset($cookies['Drupal_visitor_THEME_location'])) {
    $nid = $cookies['Drupal_visitor_THEME_location'];
    $response = new RedirectResponse(\Drupal::url('entity.node.canonical', ['node' => $nid]));
    $response->send();
  }
}

上記は正常に動作しますmostの時間ですが、バックエンドからログアウトしてフロントページにアクセスすると、白い画面しか表示されず、ページが完全に停止します。私はこれが非常に曖昧であることを知っていますが、特定の手順を実行してもこのエラーを再現できないようです。たまにしか起こりません。次にキャッシュをクリアすると、すべてが再び期待どおりに動作するように見えますか?誰かが私がここで間違っていることを見ることができますか?

1
Cyclonecode

結果をキャッシュできない処理を実行するために、theme_preprocessを使用しないでください。最終的なテーマ処理関数またはテンプレートに渡される変数の操作のみを実行してください。

Theme_preprocessでリダイレクトを実行すると、結果が空になり、これがWSODにつながると思います。

代わりに、このページで説明されているように、イベントサブスクライバーを使用することをお勧めします。 https://www.drupal.org/node/2013014

イベントサブスクライバーをmymodule.services.ymlに登録し、そのようにタグ付けします。

services:
  mymodule_event_subscriber:
    class: Drupal\mymodule\EventSubscriber\MymoduleSubscriber
    tags:
      - {name: event_subscriber}

MymoduleSubscriberは、modules/src/EventSubscriber/MymoduleSubscriber.phpのフォルダー構造に配置し、EventSubscriberInterfaceインターフェースを実装し、そのgetSubscribeEvents()で実行するメソッドをポイントする必要があります。

namespace Drupal\mymodule\EventSubscriber;

use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class MymoduleSubscriber implements EventSubscriberInterface {

  public function checkForRedirection(GetResponseEvent $event) {
    if ($event->getRequest()->query->get('redirect-me')) {
      $event->setResponse(new RedirectResponse('http://example.com/'));
    }
  }

  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents() {
    $events[KernelEvents::REQUEST][] = array('checkForRedirection');
    return $events;
  }

}
3