TransWikia.com

Magento 2 - Error trying Redirect to login page for controller if not logged in

Magento Asked on November 15, 2021

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="VendorModuleObserverCheckLoginPersistentObserver" />
 </event>
 </config>

This then references the observer:

<?php  
namespace VendorModuleObserver;

class CheckLoginPersistentObserver implements MagentoFrameworkEventObserverInterface
{
/**
 * @var MagentoFrameworkAppResponseRedirectInterface
 */
protected $redirect;

/**
 * Customer session
 *
 * @var MagentoCustomerModelSession
 */
protected $_customerSession;

public function __construct(
    MagentoCustomerModelSession $customerSession,
    MagentoFrameworkAppResponseRedirectInterface $redirect

) {

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

}

public function execute(MagentoFrameworkEventObserver $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

4 Answers

Code below worked for me.

<?php
namespace BACertificateControllerCustAccount;
 
use MagentoCustomerModelSession;
use MagentoFrameworkControllerResultRedirectFactory;
use MagentoFrameworkViewResultPageFactory;

class Index implements MagentoFrameworkAppActionInterface
{
    /**
     * @var MagentoFrameworkViewResultPageFactory
     */
    protected $resultPageFactory;
    /**
     * @var MagentoFrameworkControllerResultRedirectFactory
     */
    protected $resultRedirect;
    /**
     * @var MagentoCustomerModelSession
     */
    protected $customerSession;

    /**
     * @param MagentoFrameworkControllerResultRedirectFactory $resultRedirect
     * @param MagentoFrameworkViewResultPageFactory $resultPageFactory
     * @param MagentoCustomerModelSession $customerSession
     */
    public function __construct(
        RedirectFactory $resultRedirect,
        PageFactory $resultPageFactory,
        Session $customerSession
    ) {
        $this->resultRedirect = $resultRedirect;
        $this->resultPageFactory = $resultPageFactory;
        $this->customerSession = $customerSession;
    }
    /**
     * Default customer account page
     *
     * @return void
     */
    public function execute()
    {
        if (!$this->customerSession->isLoggedIn()) {
            /** @var MagentoFrameworkControllerResultRedirect $resultRedirect */
            $resultRedirect = $this->resultRedirect->create();
            $resultRedirect->setPath('customer/account/login');
            return $resultRedirect;
        } else {
            return $this->resultPageFactory->create();
        }
    }
}

Answered by Liz Eipe C on November 15, 2021

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 MagentoFrameworkAppRequestInterface
    */
    private $request;

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

    /**
    * @param Observer $observer
    *
    * @return void
    */
    public function execute(MagentoFrameworkEventObserver $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.

Answered by drew7721 on November 15, 2021

try this

 /**
     * @var MagentoFrameworkAppResponseInterface
     */
    protected $_response;

    /**
     * @var MagentoStoreModelStoreManagerInterface
     */
    protected $_storeManager;

    public function __construct
    (
        MagentoFrameworkUrlInterface $url,
        MagentoStoreModelStoreManagerInterface $storeManagerInterface,
        MagentoFrameworkAppResponseInterface $response 
    ){
        $this->_storeManager = $storeManagerInterface;
        $this->_response = $response; 
    }



    public function execute(MagentoFrameworkEventObserver $observer)
    {
        $storeObj = $this->_storeManager->getStore(1);
        $BaseURL = $storeObj->getBaseUrl(MagentoFrameworkUrlInterface::URL_TYPE_WEB);
        $url = $BaseURL . 'customer/account/login';
        $this->_response->setRedirect($url)->sendResponse();

    }

Answered by Bojjaiah on November 15, 2021

protected $_url; 
public function __construct(
        MagentoFrameworkAppActionContext $context,
        MagentoFrameworkUrlInterface $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.

Answered by Saurabh Dwivedi on November 15, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP