Magento2: Chuyển hướng đến URL tùy chỉnh từ người quan sát


7

Yêu cầu của tôi là nếu một khách hàng truy cập trang web từ quốc gia Ấn Độ, họ nên được chuyển hướng đến trang web Ấn Độ www.example.com/in/ . Trong tất cả các trường hợp khác, nó chỉ là trang web mặc định.

Tôi đang sử dụng geoipthư viện PHP. Tôi đã sử dụng sự kiện frontend controller_action_predispatchvà đây là mã người quan sát của tôi:

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']);
        }
    }
}

Các vấn đề:

  1. Chức năng quan sát viên của tôi đang được thực thi và tôi nhận được quốc gia của khách hàng từ IP của họ nhưng nó không được chuyển hướng đến trang web www.example.com/in/* . Cách thích hợp để chuyển hướng đến url tùy chỉnh của tôi là gì?
  2. Tôi nghĩ rằng sự kiện controller_action_predispatchsẽ gọi chức năng quan sát viên trên mỗi lượt truy cập của khách hàng. Sự kiện nào tôi nên sử dụng để nó sẽ chỉ được thực hiện cho lần đầu tiên khách hàng truy cập trang web?
  3. Tôi thấy một trong các tùy chọn có thể là đặt cookie cho nó nhưng tôi không chắc chắn nên đặt cookie ở đâu trong mô-đun của mình (sự kiện? Sự kiện nào?) Và tôi nên thực hiện quy trình nào để định hướng lại chúng.

Đoạn mã này sẽ làm chậm cửa hàng. Cache quốc gia_code trong phiên PHP. Và nếu cửa hàng có Varnish, nó sẽ không hoạt động.
tối

Câu trả lời:


5

Có nhiều cách tiếp cận làm thế nào bạn có thể làm điều này mà không cần chỉnh sửa mã magento (ví dụ cấp độ máy chủ web). Những cách tiếp cận này có thể hiệu quả hơn.

Nhưng nếu bạn muốn làm điều đó với magento, $ resultRedirect của bạn sẽ được trả về App\Http. Người quan sát của bạn không trả về $ resultRedirect, vì vậy nó không được xử lý bởi \Magento\Framework\App\Http::launchvà chuyển hướng không xảy ra. Vì bạn muốn logic chuyển hướng của mình xảy ra càng sớm càng tốt, nhưng chỉ ở mặt tiền cửa hàng (có đúng không?) Thay vì người quan sát, bạn nên đặt một plugin xung quanh \Magento\Framework\App\FrontControllerInterface::dispatchvì đó là phương thức đầu tiên được gọi \Magento\Framework\App\Http::launchsau khi khu vực được xác định và trả về ResultInterface. Từ plugin đó, bạn sẽ có thể trả về $resultRedirectđối tượng của mình :

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);
            }
    }
}

Đối với việc chỉ làm cho khách hàng đầu tiên, kiểm tra sự hiện diện của cookie trông giống như một lựa chọn khả thi.


Tôi đã phát triển mô-đun bằng cách sử dụng khái niệm plugin. Tôi có một vấn đề ở đó. indiađang được thêm nhiều lần vào giữa url cơ sở và URI được yêu cầu. URL trực tiếp đang được tạo ra một cái gì đó như example.com/india/india/india/.../aboutus. Tại sao lại indiađược thêm nhiều lần vào giữa url cơ sở và url được yêu cầu? github.com/amitshree/magento2-website-switcher/blob/master/app/
mẹo

2

Đây là các bước để làm:

1. Chuyển hướng có thể được thực hiện theo cách sau: $observer->getControllerAction()->getResponse()>setRedirect($redirectUrl);

2. Giải pháp tốt nhất, có lẽ, sẽ là sử dụng controller_action_predispatch(vì không may là không có sự kiện nào khác phù hợp hơn).

3. Trong cùng một người quan sát, bạn cũng có thể thiết lập một số cookie (ví dụ: "Geoip_country_code") sẽ được xử lý bởi controller_action_predispatch.

Nhưng lưu ý rằng trong trường hợp bạn quyết định đi theo cách này, bạn sẽ phải kiểm tra cookie của khách hàng mỗi lần trước khi chuyển hướng.


Cảm ơn. Tôi đã tìm kiếm những cách có thể. Vui lòng cho tôi biết nếu có cách nào tốt hơn cách này nếu bạn đã triển khai hoặc có tài liệu / hướng dẫn tham khảo. Tôi sẵn sàng làm việc lại nếu có những cách tốt hơn.
amitshree

Tôi không có quyền truy cập vào chuyển hướng setRedirect trong đối tượng $ observer của mình
kevando 28/03/2016

0

Đây là những gì tôi đã làm (nhớ đặt cờ hành động):

/**
 * @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');
}

Cập nhật:

Đối với magento 2.1.5, hãy làm như sau

/**
 * @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 đã viết ví dụ hay nhưng $ resultRedirect nên có loại \ Magento \ Framework \ App \ Feedback \ Http. Ví dụ ở đây từ mã của tôi:

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);
    }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.