1

I know this question has been asked before a couple of times here:

Magento 2 : Redirect From Homepage to Login if not Logged

Magento 2 - Redirect user to a specific page if not logged in

However i cant seem to get it to work and am a bit confused about how this works with my specific controller. So far I have created an event.xml:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
 <event name="controller_action_predispatch">
        <observer name="check_login_persistent" instance="Vendor\Module\Observer\CheckLoginPersistentObserver" />
 </event>
 </config>

This then references the observer:

<?php  
namespace Vendor\Module\Observer;

class CheckLoginPersistentObserver implements \Magento\Framework\Event\ObserverInterface
{
/**
 * @var \Magento\Framework\App\Response\RedirectInterface
 */
protected $redirect;

/**
 * Customer session
 *
 * @var \Magento\Customer\Model\Session
 */
protected $_customerSession;

public function __construct(
    \Magento\Customer\Model\Session $customerSession,
    \Magento\Framework\App\Response\RedirectInterface $redirect

) {

    $this->_customerSession = $customerSession;
    $this->redirect = $redirect;

}

public function execute(\Magento\Framework\Event\Observer $observer)
{
    echo "This is an event";
    $actionName = $observer->getEvent()->getRequest()->getFullActionName();
    $controller = $observer->getControllerAction();

    $openActions = array(
        'create',
        'createpost',
        'login',
        'loginpost',
        'logoutsuccess',
        'forgotpassword',
        'forgotpasswordpost',
        'resetpassword',
        'resetpasswordpost',
        'confirm',
        'confirmation'
    );
    if ($controller == 'account' && in_array($actionName, $openActions)) {
        return $this; //if in allowed actions do nothing.
    }
    if(!$this->_customerSession->isLoggedIn()) {
        $this->redirect->redirect($controller->getResponse(), 'customer/account/login');
    }

}
}

Then im not sure how to make this work in my specific case for my controller. I have looked a bit at events and added the below code to my controller so the event is fired:

$this->_eventManager->dispatch('controller_action_predispatch');

However this has ended up showing an error:

PHP Fatal error: Uncaught Error: Call to a member function getRequest() on null in /var/www/magento2/public_html/vendor/magento/module-customer/Model/Visitor.php

0
protected $_url; 
public function __construct(
        \Magento\Framework\App\Action\Context $context,
        \Magento\Framework\UrlInterface $url
    )
    {
        parent::__construct($context);
        $this->_url = $url;

    }

public function execute()
    {

......
.....
.....
$redirectUrl= $this->_url->getUrl('customer/account/login');
        $this->_responseFactory->create()->setRedirect($redirectUrl)->sendResponse();

}

This is working for me.

0

try this

 /**
     * @var \Magento\Framework\App\ResponseInterface
     */
    protected $_response;

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

    public function __construct
    (
        \Magento\Framework\UrlInterface $url,
        \Magento\Store\Model\StoreManagerInterface $storeManagerInterface,
        \Magento\Framework\App\ResponseInterface $response 
    ){
        $this->_storeManager = $storeManagerInterface;
        $this->_response = $response; 
    }



    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $storeObj = $this->_storeManager->getStore(1);
        $BaseURL = $storeObj->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_WEB);
        $url = $BaseURL . 'customer/account/login';
        $this->_response->setRedirect($url)->sendResponse();

    }
0

Your error :

PHP Fatal error: Uncaught Error: Call to a member function getRequest() on null in

This lets me to believe that the event does not come with the request attached in it's data array.

Not all observer events have the request attached. You need to check if it is. I suggest setting a breakpoint with xdebug and checking what you have available, that is if the event is not thrown by you, if it is, just add the request in the data array (2nd argument) of the ->dispatch method.

$this->_eventManager->dispatch(
    'controller_action_predispatch',
    [ 'request' => $this->getRequest() ] //if request is available...
);

If it's not thrown by you and you need it in your observer just inject the RequestInterface in the observer and you'll get the current request.

<?php
class MyObserver implements ObserverInterface
{
        const VALID_ACTION = 'full_action_name';

    /**
    * @var \Magento\Framework\App\RequestInterface
    */
    private $request;

    /**
    * MyObserver constructor.
    *
    * @param \Magento\Framework\App\RequestInterface $request
    */
    public function __construct(
        RequestInterface $request
    ) {
        $this->request = $request;
    }

    /**
    * @param Observer $observer
    *
    * @return void
    */
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        if ($this->request->getFullActionName() === self::VALID_ACTION ) {
            //Do something here... 
        }
    }
}

Note that full action name is the module_controller_action not just the action name as you have them in your array, so it will not match. You just need to get the action name to have them match.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.