Question

I'm trying to use the plugin around method to override the execute method of \Magento\Checkout\Controller\Onepage\Success.php. I'm trying to create a module that allows you to view the checkout onepage success template by giving in an order id through the backend so the template can be viewed without having to place a new order to view additional customizations to this template. What I have so far is:

app/code/Vendor/Module/etc/di.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="\Magento\Checkout\Controller\Onepage\Success">
    <plugin name="Vendor_Plugin_Pluginname" type="\Vendor\Module\Plugin\Pluginname" sortOrder="1" />
</type>

app/code/Vendor/Module/Plugin/Pluginname.php

<?php

namespace Vendor\Module\Plugin;

use Vendor\Module\Helper\Data;

class Pluginname
{

    /**
     * Variable.
     *
     * @var Data
     */
    public $helper;

    /**
     * Construct.
     *
     * @param Data $helper helper.
     */
    public function __construct(
        Data $helper
    ) {
        $this->helper = $helper;
    }

    /**
     * Order success action.
     *
     * @return \Magento\Framework\Controller\ResultInterface
     */
    public function aroundExecute(\Magento\Checkout\Controller\Onepage $subject, $result)
    {
       $session = $subject->getOnepage()->getCheckout();
       if (!$subject->_objectManager->get('Magento\Checkout\Model\Session\SuccessValidator')->isValid() && !$this->cspHelper->viewerAccess()) {
           return $subject->resultRedirectFactory->create()->setPath('checkout/cart');
       }
       $session->clearQuote();
       //@todo: Refactor it to match CQRS
       $resultPage = $subject->resultPageFactory->create();
       $subject->_eventManager->dispatch(
           'checkout_onepage_controller_success_action',
           ['order_ids' => [$session->getLastOrderId()]]
       );
       return $resultPage;
   }
}

The first issue I ran into is that I wanted to extend \Magento\Checkout\Controller\Onepage as this contains all the methods to get the actual checkout data. But when extending this in the plugin for \Magento\Checkout\Controller\Onepage\Success it comes with the following error.

Fatal error: Class Vendor\Module\Plugin\Pluginname contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (Magento\Framework\App\ActionInterface::execute) in \app\code\Vendor\Module\Plugin\Pluginname.php on line 59

After adding an empty execute method (feels weird as I override it with aroundExecute in the same file) the following error is given:

Fatal error: Call to a member function get() on null in \vendor\magento\module-checkout\Controller\Onepage.php on line 261

It seems it's missing some data as it reports null. It's the first time I'm working with the plugin functionality of Magento2 as I'm more a frontend developer. I hope someone can shed some light on this.

[EDIT] I mixed up Preference and Plugin. I edit the code of app/code/Vendor/Module/Plugin/Pluginname.php above to be compatible with plugin but now run into the fact that one of the calls is trying to access a protected property. As discussed below this results in not being able to use the Plugin way at all as it wont allow to override protected properties. The solution is to use the Preferences way to override a class.

Was it helpful?

Solution

You've mixed up two concepts here: preferences and plugins.

Preferences are basically rewrites on the class level. In case you define a preference for your controller your preference class will have to extend the original class and you can modify whatever method you want

Declaring preferences is different than declaring plugins you can find details here: http://alanstorm.com/magento_2_object_manager_preferences

Plugins is way different it lets you modify the behavior of a method so it is modifications on the class level. You can see in the official documentation that it has some limitations but it's a powerful feature: http://devdocs.magento.com/guides/v2.0/extension-dev-guide/plugins.html

In your case your di.xml declares a plugin. Plugin classes do not extend the class they're observing though.

You said you extended the controller to get access to the methods. So for the before, around and after methods the first argument is an object that provides access to all the public methods of the observed class.

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top