1

I am looking a way to restrict access to specific CMS page, allowing only logged in customers with a special customer group to see it. EDIT: I have this function, but observer isn't working properly it is redirecting in loops.

public function execute(Observer $observer)
{

    if(!$this->_session->isLoggedIn() && !$this->_helper->isB2DCustomer($this->_session->getCustomer()))
    {
        $request = $this->_objectManager->get('Magento\Framework\App\Request\Http');
        //get instance for URL interface
        /** @var \Magento\Framework\UrlInterface $urlInterface */
        $urlInterface = $this->_objectManager->get('Magento\Framework\UrlInterface');
        // URL to redirect to
        $url = $urlInterface->getUrl('/');
        if(strpos($request->getOriginalPathInfo(), '/b2d') == 0)
        {
            # redirect to root page
            $observer->getControllerAction()
                ->getResponse()
                ->setRedirect($url);
        }
    }
}
kilis
  • 489
  • 2
  • 6
  • 21

2 Answers2

3

You can write an around plugin for the method \Magento\Cms\Helper\Page::prepareResultPage().
You receive the page id as a parameter.
From the page id you can get the identifier and if that identifier (or id) should be restricted just redirect to the login page.

Marius
  • 197,939
  • 53
  • 422
  • 830
0

With Object Manager:

$obm = \Magento\Framework\App\ObjectManager::getInstance();
$redirect = $obm->get('\Magento\Framework\App\Response\Http');
$context = $obm->get('Magento\Framework\App\Http\Context');
$cmsPage = $obm->get('\Magento\Cms\Model\Page');

$pageIdentifier = $cmsPage->getIdentifier(); // CMS Page Identifier

$isLoggedIn = $context->getValue(\Magento\Customer\Model\Context::CONTEXT_AUTH);

if($pageIdentifier == 'cms-page-identifier' && !$isLoggedIn)
{
   $redirect->setRedirect('customer/account/login/');
}

With dependency injection:

protected $_responseHttp;
protected $_httpContext;
protected $_page;

public function __construct(
    \Magento\Framework\App\Response\Http $responseHttp,
    \Magento\Framework\App\Http\Context $httpContext,
    \Magento\Cms\Model\Page $page
) {
    $this->_responseHttp = $responseHttp;
    $this->_httpContext = $httpContext;
    $this->_page = $page
}

public function execute(Observer $observer)
{
    $pageIdentifier = $this->_page->getIdentifier(); // CMS Page Identifier

    $isLoggedIn = $this->_httpContext->getValue(\Magento\Customer\Model\Context::CONTEXT_AUTH);

    if($pageIdentifier == 'cms-page-identifier' && !$isLoggedIn)
    {
       $redirect->setRedirect('customer/account/login/');
    }
}

Note: Don't use Object Manager instance directly check this for more details: Link

Prince Patel
  • 22,708
  • 10
  • 97
  • 119
  • Direct use of ObjectManager is a bad practice, for details take a look at https://magento.stackexchange.com/questions/117098/magento-2-to-use-or-not-to-use-the-objectmanager-directly. Adding logic inside a template in another bad practice. – Lorenzo Jan 31 '19 at 08:42
  • 1
    @Lorenzo Thanks for pointing it out. I updated my answer. – Prince Patel Jan 31 '19 at 09:07