web-dev-qa-db-ja.com

クエリ文字列に基づいてリダイレクト

レガシーブログを自家製のCMSからDrupal 7に移行しています。URLを新しいエイリアスパターンにリダイレクトする方法に頭を抱える必要があります。

従来のサイトのURLはクエリ文字列/?t=40&an=49187&anc=570&format=xmlを使用し、/blog/i-know-this-is-not-idealなどのエイリアスURLにリダイレクトします。サイトのほとんどのリストページは、クエリパラメーターを使用してページにリンクしていますが、エイリアスURLを使用しているものもあります。 anパラメータは、Node IDのバージョンを参照しているように見えます。これは、移行で解析して保存できます。

このプラットフォームを所有している会社は、ある列にエイリアスを、別の列にクエリ文字列を含むExcelスプレッドシートを送ってくれたので、少なくとも何かありました。

SEOジュースを維持することはこのクライアントにとって重要です。Googleは多くの場合、これらのクエリパラメータを解析しています。

Redirectモジュールはクエリパラメーターのサポートを提供していないように見えるので、このためのカスタムモジュールの作成に向けるべきでしょうか?それともhtaccess書き換えルールを調べる必要がありますか?

3
Aaron Silber

小さなカスタムモジュールは、おそらくオーバーヘッドが最も少ない方法だと思います。移行中にレガシーIDをフィールドに保存し、適切なクエリ文字列が設定されている場合はそこからアクセスできます。

非常に大まかな例...

Drupal 7:

mymodule.module

function mymodule_init() {
    if (!empty($_GET['an'])) {
        $query = new \EntityFieldQuery();
        $result = $query->entityCondition('entity_type', 'node')
            ->fieldCondition('field_old_id', 'value', $_GET['an'])
            ->execute();

        if (!empty($result['node'])) {
            $nids = array_keys($result['node']);
            $nid = reset($nids);
            drupal_goto(url("node/$nid"), [], 301);
        }

    }
}

Drupal 8:

mymodule.services.yml:

services:
  mymodule.redirect_subscriber:
    class: Drupal\mymodule\RedirectSubscriber
    arguments: ['@entity_type.manager', '@path.alias_manager']
    tags:
      - { name: 'event_subscriber' }

src/RedirectSubscriber.php:

namespace Drupal\mymodule;

use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Path\AliasManagerInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class RedirectSubscriber implements EventSubscriberInterface
{

    protected $nodeStorage;

    protected $aliasManager;

    public function __construct(EntityTypeManagerInterface $entity_type_manager, AliasManagerInterface $alias_manager)
    {
        $this->nodeStorage = $entity_type_manager->getStorage('node');
        $this->aliasManager = $alias_manager;
    }

    public function Redirect(GetResponseEvent $event)
    {
        $old_id = $event->getRequest()->get('an');

        if (!empty($old_id)) {
            $ids = $this->nodeStorage->getQuery()
                ->condition('field_old_id', intval($old_id))
                ->execute();

            if (!empty($ids)) {
                $nid = reset($ids);
                $url = $this->aliasManager->getAliasByPath("/node/$nid");
                $event->setResponse(new RedirectResponse($url, 301));
            }
        }
    }

    static function getSubscribedEvents()
    {
        $events[KernelEvents::REQUEST][] = array('Redirect', 20);
        return $events;
    }
}
3
Clive