5

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.

1 Answer 1

5

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.

3
  • You are right, seems I mixed them up. I removed the extends from the plugin and added the object and result parameters for the aroundExecute method (see original post). I edited the $this-> calls to $subject but now I run into the fact that $subject->_objectmanager-> is a protected property and accessing it throws an error. You already mentioned that the object only provides access to the public methods. How to proceed from here, does this mean I cant use the plugin way if I only want to edit the execute method a little and that I need to use the Preference way to rewrite the class?
    – Solide
    Jul 2, 2016 at 10:57
  • @Solide yes you're totally right in your case you'll have to use preferences ;) Jul 2, 2016 at 11:20
  • @RaphaelatDigitalPianism could you help me with magento.stackexchange.com/q/190603/3895
    – Mukesh
    Aug 28, 2017 at 11:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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