Hot answers tagged

42

Plugins are omnipresent since it is possible to modify/replace the behavior of any public method in the system. Customizations should be done using plugins for public methods/classes marked with @api annotation (stable public API) whenever possible. Such approach guarantees that customization will stay functional after new Magento releases. In addition to ...


38

Plugins are sorted by sort order first, and then by method prefix. Example: for method with 3 plugins (PluginA, PluginB, PluginC) with following methods and sortOrder: PluginA (sortOrder = 10) beforeDispatch() afterDispatch() PluginB (sortOrder = 20) beforeDispatch() aroundDispatch() afterDispatch() PluginC (sortOrder = 30): beforeDispatch() ...


32

Interceptor classes are an implementation of the interceptor design pattern. The interceptors are how how Magento 2's object system implements a plugin system. As a client developer, the theory is you don't need to worry about interceptors -- you ask the object manager for an object of type X, and it returns it to you. The object you asked for may or may ...


24

I'm going to focus on the first part of your question - "how do I learn / where do I get started?" As a former Zend Framework developer, the biggest help to me in developing Magento has been the explosion in online learning that Magento U has brought in the past 2 years. Aside from the formal learning - I learn mostly by doing, and I have been "doing" ...


22

1) You can disable plugin by name. In your case it authorization. <type name="Magento\Sales\Model\ResourceModel\Order\Plugin\Authorization"> <plugin name="authorization" disabled="true" /> </type> <type name="Magento\Sales\Model\ResourceModel\Order\Plugin\Authorization"> <plugin name="vendor_name_authorization" type="...


19

The obvious reason to use a rewrite instead of a plugin is when you need to override a private, protected or final methods. But also consider the following scenarios. 1st scenario (absolute sort order): Rewrites can be useful when you need your code to be run before plugins. I know you can do it by setting the plugin sortOrder, but you cannot be sure your ...


16

From the Magento 2 cookbook: If there are multiple plugins that extend the same original function, they are executed in the following sequence: the before plugin with the lowest sortOrder the around plugin with the lowest sortOrder other before plugins (from the lowest to highest sortOrder) other around plugins (from the lowest to highest ...


14

My 2 cents to brilliant @philwinkle's answer. There are two official PDFs 1) Magento Extension Developer’s Guide 80 pages on how-to create a custom extension from scratch step-by-step. Module "News" is developed from scratch - it will show you module’s files and folders’ structure, config files, controllers, models, blocks. 2) Designer's Guide to ...


13

In your di.xml you can do the following: <type name="\Magento\Catalog\Model\Product"> <plugin name="se_catalog_product_plugin_ample" disabled="true" /> </type> Magento does it out of the box in Magento/Backend/etc/adminhtml/di.xml with the following : <type name="Magento\Framework\App\Action\Action"> <plugin name="...


13

You do this with using a requirejs mixin and the mage/utils/wrapper js module. Heres a demonstration of how the wrapper module functions: var wrapper = require('mage/utils/wrapper'); function multiply(a, b) { return a * b; } var wrapped1 = wrapper.wrap(multiply, function (_super) { var result = _super(); return result + 1; }); var wrapped2 = ...


12

Is that even possible? Yes. How can I pluginize the magic getters/setters in magento 2? In the same way as a other public method. You need to declare plugin in di.xml configuration and add you custom code in plugin. public function before__call(\Magento\Review\Model\Review $review, $method, $args) { if ($method == 'setStatusId') { if (isset(...


11

Use plugins whenever possible, then observers (see the pros and cons of each), this will allow you to avoid conflicts with other extensions (3rd party modules). Preference should be used only if the whole core class/interface implementation should be substituted with custom one. Take into account that only one preference is active at any time (which one, is ...


11

We are working on "@api" annotations to annotate recommended methods that will be more stable across releases. If you worry about upgradability, in additional to what can have a plugin defined, you should also consider what should have a plugin defined. We don't recommend interception of non-@api methods, but sometimes we know that may be the best option. (...


10

Every Class of an Magento Module is intercaptable. As described on the current wiki, it is limited by final methods and classes Not validated, but Classes of libraries (lib directory) are(/should) not allowed to get intercepted. The limitation how the object got created is not true anymore I think, at least if the autoloader is correctly configured. And ...


10

No, plugins on virtual types do not work. Proof of concept code: <?php namespace Training\Example\Model class Type { public function bar() { return __CLASS__; } } Plugin using <type>: <?php namespace Training\Example\Model; class TypePlugin { public function afterBar(Type $subject) { return __CLASS__; ...


10

I think you misread the documentation. Basically the following are plugins limitations: Objects that are instantiated before Magento\Framework\Interception is bootstrapped Final methods Final classes Any class that contains at least one final public method Non-public methods Class methods (such as static methods) __construct Virtual types ...


9

Late answer but you need to change __constructor to __construct and it will work perfectly well. Don't use static ObjectManager if possible. You should always use DI instead.


8

Great answers here so far all around. Regarding Extensions/plugins are very confusing so far to me. Other platforms like WordPress allow you to place a plugin into it's own folder and all it's files will live under that folder. From what I have seen so far, a plugin might be scattered across several folders in Magento, is this correct? The terminology ...


8

Plugins only? Yes. You can write plugins for abstract classes and plugins should always be preferred over preferences if possible. Preferences are useful if you want to replace an implementation. I can't think of a use case to replace the implementation for all models that extend AbstractModel, if that's even logically possible. So what you probably want ...


8

For getting all available list of plugins: Go to vendor/magento/framework/Interception/PluginList/PluginList.php find method merge public function merge(array $config) { // default code echo "<pre>"; print_r($this->_data); die(); } For getting all available list of preferences: vendor/magento/framework/ObjectManager/Config/...


8

Looks like you are using wrong class in your construct for $request. Change your construct to following and it should work: public function __construct( \Magento\Framework\Webapi\Rest\Request $request ) { $this->_request = $request; } After that you can get REST request's parameters in following way: var_dump($this->_request->getParams()...


8

You have an answer here : https://stackoverflow.com/a/29730810/4629261 The difference is, that a [Closure] must be an anonymous function, where [callable] also can be a normal function. You can see/test this with the example below and you will see that you will get an error for the first one: function callFunc1(Closure $closure) { $closure(); } ...


8

After so much investigation and implementation, I found a solution to display custom error message on checkout page. 1) Override a shipping.js file (vendor\magento\module-checkout\view\frontend\web\js\view\shipping.js) into your custom theme (app\design\frontend\Vendor\Theme\Module_Checkout\web\js\view\shipping.js): 2) Add your ajax call into ...


7

In addition to the @philwinkle's answer, I want to reply to your statement regarding overriding classes using the PHP include path priority. Consider that an emergency solution if there is no other way to accomplish what you want. Often you can specify which class to use via a configuration XML setting, or using a class rewrite (also specified in config XML)...


7

You have specified a type of Magento\Firstmodule\Model\Basic but called the class 'Plugin' in your Basic.php file. It needs to be class Basic { }


7

Great question, I asked myself the same thing the other day and here's what I came up with: First, plugins cannot be used for final methods, final classes and classes created without dependency injection I reckon that's a very specific case but that's one case where you can't use plugins Second, you need to keep in mind the definition of a plugin. It is ...


7

You can try like below use Magento\Framework\App\Response\Http as responseHttp; use Magento\Framework\UrlInterface; class Test{ public function __construct( responseHttp $response, UrlInterface $url ) { $this->response = $response; $this->_url = $url; } public function afterExecute(\Magento\...


7

You can do this by observer. SR/StackExchange/etc/frontend/events.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="customer_register_success"> <observer name="sr_customer_account_createPost" instance="SR\...


7

1) PHPStorm with XDebug: PHPStorm is my favorite IDE. It is an advanced IDE for PHP developers. Many developers still use only var_dump and die to debug the system. From my experience, these techniques are not powerful. They possibility will break the application. Magento 2 is a huge system. We should try with XDebug. With XDebug, we can see how the ...


6

You can create before plugin on setTemplate method and overwrite template argument. Create plugin class ProductSwatchPlugin { public function beforeSetTemplate( \Magento\Swatches\Block\Product\Renderer\Configurable $subject, $template ) { return ['You_Module::template.phtml']; } } and declare it in DI.xml <type ...


Only top voted, non community-wiki answers of a minimum length are eligible