Magento2:オブザーバーからカスタムURLにリダイレクト


7

私の要件は、顧客がインドの国のウェブサイトにアクセスした場合、インドのウェブサイトwww.example.com/in/にリダイレクトされることです。それ以外の場合はすべて、デフォルトのWebサイトのみにする必要があります。

geoipPHPライブラリを使用しています。私はフロントエンドイベントcontroller_action_predispatchを使用しましたが、これが私のオブザーバーコードです。

namespace Amit\Geoip\Observer;
require_once 'lib/geoip.inc';
use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\Controller\ResultFactory;
use Magento\Store\Model\StoreManager;

class ControllerActionPredispatch implements  ObserverInterface {

    protected $resultRedirectFactory;

    public function __construct(
        ResultFactory $resultFactory,
        StoreManager $storeManager
    )  {
        $this->resultFactory = $resultFactory;
        $this->storeManager = $storeManager;
    }

    public function execute(\Magento\Framework\Event\Observer $observer) {
        $baseUrl = $this->storeManager->getStore()->getBaseUrl();
        $gi = geoip_open(getcwd()."/app/code/Amit/Geoip/Observer/lib/GeoIP.dat",GEOIP_STANDARD);
        $ip = $_SERVER['REMOTE_ADDR'];

        $country_code = geoip_country_code_by_addr($gi, $ip);

        if((strtoupper($country_code) == "IN")){
            $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
            $resultRedirect->setUrl($baseUrl . '/in/' . $_SERVER['REQUEST_URI']);
        }
    }
}

問題:

  1. オブザーバー機能が実行されており、お客様のIPから国を取得していますが、ウェブサイトwww.example.com/in/*にリダイレクトしていません 。カスタムURLにリダイレクトする適切な方法は何ですか?
  2. イベントcontroller_action_predispatchは、顧客が訪問するすべてのページでオブザーバー関数を呼び出すと思います。顧客がWebサイトに初めてアクセスしたときにのみ実行されるように、どのイベントを使用する必要がありますか?
  3. 可能なオプションの1つにCookieの設定がありますが、モジュールのどこにCookieを設定する必要があるか(イベント?どのイベント?)と、それらをリダイレクトするために従う必要があるプロセスがわかりません。

このコードスニペットは、ストアの速度を低下させます。PHPセッションでcountry_codeをキャッシュします。そして、店がニスを持っているならば、それはまったく働きません。
あいまい

回答:


5

magentoコードを編集せずにこれを行う方法はいくつかあります(たとえば、Webサーバーレベル)。これらのアプローチはより効率的かもしれません。

しかし、magentoを使用したい場合は、$ resultRedirectをに戻す必要がありますApp\Http。オブザーバーは$ resultRedirectを返さないため、によって処理されず\Magento\Framework\App\Http::launch、リダイレクトは発生しません。(その権利である?)だけ店先では、あなたのリダイレクトロジックは、可能な限り早期に起こるようにしたいので、代わりに、観察者のあなたは上の周りに、プラグインを置く必要があり\Magento\Framework\App\FrontControllerInterface::dispatch、それが中に呼び出される最初のメソッドですので、\Magento\Framework\App\Http::launch領域の後に定義されており、リターンResultInterface。そのプラグインから$resultRedirectオブジェクトを返すことができます:

namespace My\Module\App\FrontController;

class Plugin
{
    // Constructor and dependencies here

    public function aroundDispatch(
        FrontControllerInterface $subject,
        callable $proceed,
        RequestInterface $request
    ) {
            $baseUrl = $this->storeManager->getStore()->getBaseUrl();
            $gi = geoip_open(getcwd()."/app/code/Amit/Geoip/Observer/lib/GeoIP.dat",GEOIP_STANDARD);
            $ip = $_SERVER['REMOTE_ADDR'];

            $country_code = geoip_country_code_by_addr($gi, $ip);

            if((strtoupper($country_code) == "IN")){
                $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
                $resultRedirect->setUrl($baseUrl . '/in/' . $_SERVER['REQUEST_URI']);
                return $resultRedirect;
            } else {
                return $proceed($request);
            }
    }
}

最初の顧客だけにそれを行うことに関しては、クッキーの存在チェックは実行可能なオプションのように見えます。


プラグインの概念を使用してモジュールを開発しました。そこで問題が1つあります。indiaベースURLとリクエストされたURIの間に複数回追加されています。リダイレクトURLはのように生成されていexample.com/india/india/india/.../aboutusます。indiabase-urlとrequested-uriの間に何回も追加されているのはなぜ ですか?github.com/amitshree/magento2-website-switcher/blob/master/app/...
amitshree

2

これらは行うためのステップです:

1.リダイレクトは次の方法で実行できます。 $observer->getControllerAction()->getResponse()>setRedirect($redirectUrl);

2.おそらく、最善の解決策は、を使用することです controller_action_predispatch(残念ながら、他のより適切なイベントはありません)。

3.同じオブザーバで、いくつかのCookie(「geoip_country_code」など)を設定して、 controller_action_predispatch.

ただし、この方法を選択する場合は、リダイレクトの前に毎回顧客のCookieを確認する必要があることに注意してください。


ありがとう。私は可能な方法を探していました。実装したり、リファレンスチュートリアル/ドキュメントを持っている場合は、これよりも良い方法があるかどうかをお知らせください。より良い方法があれば、私はそれをやり直す準備ができています。
amitshree

$ observerオブジェクトのsetRedirectリダイレクトにアクセスできない
kevando

0

これが私がしたことです(アクションフラグを設定することを忘れないでください):

/**
 * @var \Magento\Framework\App\Response\RedirectInterface
 */
protected $redirect;

/**
 * @var \Magento\Framework\App\ActionFlag
 */
protected $actionFlag;

public function __construct
(
    \Magento\Framework\App\Response\RedirectInterface $redirect,
    \Magento\Framework\App\ActionFlag $actionFlag
)
{
    $this->redirect = $redirect;
    $this->actionFlag = $actionFlag;
}

public function execute(\Magento\Framework\Event\Observer $observer)
{
     /** @var \Magento\Framework\App\Action\Action $controller */
    $controller = $observer->getControllerAction();

    $this->actionFlag->set('', \Magento\Framework\App\Action\Action::FLAG_NO_DISPATCH, true);
    $this->redirect->redirect($controller->getResponse(), 'my/custom/url');
}

更新:

magento 2.1.5の場合、次のようにします

/**
 * @param Observer $observer
 * @return void
 */
public function execute(\Magento\Framework\Event\Observer $observer)
{
    $event = $observer->getEvent();
    $this->redirect->redirect($event->getResponse(), 'my/custom/url');
}

0

Anton Krilは良い例を書いていますが、$ resultRedirectのタイプは\ Magento \ Framework \ App \ Response \ Httpである必要があります。ここに私のコードの例:

class RedirectPlugin {
protected $subDomainsPrefix = [
    'CA' => '',
    'US' => 'us',
    'UK' => 'uk',
    'EU' => 'eu',
    'AU' => 'au'
];

protected $_responseFactory;

/**
 * @var \Magento\Framework\App\Config\ScopeConfigInterface
 */
protected $_scopeConfig;

/**
 * @var \Magento\Store\Model\StoreManager
 */
protected $_storeManager;

public function __construct(
    \Magento\Store\Model\StoreManager $storeManager,
    \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
    \Magento\Framework\App\Response\HttpFactory $httpFactory
) {
    $this->_storeManager    = $storeManager;
    $this->_scopeConfig     = $scopeConfig;
    $this->_responseFactory = $httpFactory;
}

/**
 * Redirect to subdomain by country code
 *
 * @param \Magento\Framework\App\FrontControllerInterface $subject
 * @param \Closure                                        $proceed
 * @param \Magento\Framework\App\RequestInterface         $request
 *
 * @return mixed
 */
public function aroundDispatch(
    \Magento\Framework\App\FrontControllerInterface $subject,
    \Closure $proceed,
    \Magento\Framework\App\RequestInterface $request
) {
    $baseUrl = $this->_storeManager->getStore()->getBaseUrl();
    if (isset($_SERVER['GEOIP_COUNTRY_CODE']) && isset($this->subDomainsPrefix[$_SERVER['GEOIP_COUNTRY_CODE']])) {
        $prefix      = $this->subDomainsPrefix[$_SERVER['GEOIP_COUNTRY_CODE']];
        $mainBaseUrl = $this->_scopeConfig->getValue('web/unsecure/base_url');
        $parts       = explode('.', str_replace('://', '.', $baseUrl));
        $subDomain   = $parts[1];
        if ($subDomain == $prefix || ($prefix == '' && strrpos($subDomain, 'carnivore') !== false)) {
            return $proceed($request);
        } else {
            $subDomain = str_replace('://', '://' . $prefix . '.', $mainBaseUrl);
            /**
             * @var \Magento\Framework\App\Response\Http $response
             */
            $response  = $this->_responseFactory->create();
            $response->setRedirect($subDomain);

            return $response;
        }
    } else {
        return $proceed($request);
    }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.