「標準のRouteを無効化したい。」って時ありますよね。
え、あんまりしっくりこないですか?
例えばNode。標準で「/node/{node}」ってルートが登録されていると思います。
データとしての登録はしたい。でも、ページは生成したくない。
そんなシチュエーションです。
今回は Routeを 「変更 / 無効化」 する方法について紹介しようと思います。
実装手順
今回は3ファイル作成するのみ!!
コード量少ないです。
ささっと説明しますのでお付き合いいただけると幸いです。
1. モジュールのセットアップ
DrupalのRoutingには専用のイベントがあるのでそこをサブスクライブするのが一般的な手法です。
1-1. モジュールの作成
モジュールを作成します。
web/modules/app/
├── README.md
└── app.info.yml
└── src
└ Routing
└ RouteSubscriber.php
1-2. Serviceの登録
app.services.yml
ファイルに、「app.route_subscribe」サービスを登録します。
app.route_subscribe
class: "\\Drupal\\app\\Routing\\RouteSubscriber"
tags:
- { name: "event_subscriber" }
RouteSubscriberBase
を拡張して、RouteのSubscribeするServiceファイルを生成します。
class RouteSubscriber extends RouteSubscriberBase {
protected function alterRoutes(RouteCollection $collection) {
// ここにRouteへの処理を書く.
}
}
2. Routeの無効化(削除)
class RouteSubscriber extends RouteSubscriberBase {
protected function alterRoutes(RouteCollection $collection) {
$collection->remove('entity.node.canonical');
}
}
なんとこれだけ。簡単ですよね。
/node/{node} にアクセスしても、404が返されます。
3. Routeの変更
3-1. 自前のControllerを適用させたい。
class RouteSubscriber extends RouteSubscriberBase {
protected function alterRoutes(RouteCollection $collection) {
if ($route = $collection->get('entity.node.canonical')) {
$route->setDefault('_controller', '\\Drupal\\app\\Controller\\AppArticle');
$route->setOption('parameters', [
'node' => [
'type' => 'entity:node',
],
]);
}
}
}
RouteのParameterにEntityをセットすることで、別途ロードすることなくNodeオブジェクトを取得することができます。
3-2. ページのタイトルを変更したい。
class RouteSubscriber extends RouteSubscriberBase {
protected function alterRoutes(RouteCollection $collection) {
if ($route = $collection->get('entity.node.canonical')) {
$route->setTitle('_title', 'Qiita - @umekikazuya');
}
}
}
まとめ
いかがでしょうか?
セキュアなシステムを作る上で、「公開すべきじゃないルート」「運用上必要ないルート等」、気になる箇所いろいろあると思います。
Routingへの介入、といってもできることいろいろあります。
カスタマイズして、Controllerに飛ばすことでなんでもできますよね。
- リダイレクトコントローラーに飛ばす。
- ファイルをダウンロードさせる。
- アクセスでバッジ起動する。
発想次第でいろんなことができるかな、と思います。