Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
MANIPULATING MAGENTO
Make it do what you want
PHP developer at
Joke Puts - @jokeputs
Goal
Bug free and future proof
customizations
How
Keep the interactions with
the core to a minimum
Topics
• Preferences
• Plugins
• Observers
• Cases
PREFERENCE
Replacing behavior through dependency injection
Dependency injection
“Dependency injection is the concept of the
external environment injecting dependencies for
an object...
Dependency injection
• Constructor injection
• Object manager
MagentoQuoteModelQuoteAddressValidator
public function __construct(
AddressRepositoryInterface $addressRepository,
Custome...
Interfaces
• API directory
• Service contract
• (Relatively) stable across upgrades
MagentoFrameworkObjectManagerObjectManager
public function create(
$type, array
$arguments = []
) {
$type = ltrim($type, '...
di.xml
<preference
for="MagentoCustomerApiDataCustomerInterface"
type="MagentoCustomerModelDataCustomer" />
module.xml
<module name="Namespace_Module"
setup_version="1.0.0">
<sequence>
<module name="Magento_Customer"/>
</sequence>...
<module name="PHPro_AModule"
setup_version="1.0.0">
<sequence>
<module name="Magento_Customer"/>
</sequence>
</module>
<mo...
PLUGINS
Adding and modifying behavior before, after and around
Plugin
“A plugin is a class that modifies the behavior of
public class functions by running code before,
after or around t...
di.xml
<type
name="MagentoCatalogModelResourceModelCategory">
<plugin name="category_delete_plugin"
type="MagentoCatalogUr...
Before
• Runs before the method
• Modifies the arguments of the method
• Returns null to indicate that the arguments
haven...
Before
public function beforeSetName(
Product $subject,
$name
) {
// Do something
}
After
• Runs after the method
• Modifies the output of the method
• Should have a return value
After
public function afterGetName(
Product $subject,
$result
) {
// Do something
return $result;
}
Around
• Runs both before and after the method
• Modifies the entire method
• Access to arguments and output
• Receives a ...
Around
public function aroundUpdateData(
Address $subject,
callable $proceed,
AddressInterface $address
) {
// Do somethin...
Not calling the callable
✖Other around plugins (sort order)
✖Other after plugins (sort order)
✖Original method
Call order prior original
1. Sort order from low to high
2. Order of the uasort() array
3. Before plugins
4. Around plugin...
Call order post original
1. Sort order from high to low*
2. Reversed order of the uasort() array
3. Around plugins (after ...
PHPro/AModule/etc/di.xml à after plugin
<type
name="MagentoStoreModelAddressRenderer">
<plugin name="renderer_a"
type="PHP...
OBSERVERS
Modifying data and running new behavior
Observers
“Observers are executed whenever the event
they are configured to watch is dispatched by
the event manager.”
MagentoCustomerModelSession
public function
setCustomerAsLoggedIn($customer)
{
$this->setCustomer($customer);
$this->_even...
events.xml
<event name="customer_login">
<observer name="wishlist"
instance="MagentoWishlistObserverCusto
merLogin" />
</e...
MagentoWishlistObserverCustomerLogin
class CustomerLogin implements
ObserverInterface
{
public function execute(
Observer ...
Events
• Find events in the core
• Look at the passed data
• $observer->getEvent()->get{key}()
Model events
• {event_prefix}_load_before
• {event_prefix}_load_after
• {event_prefix}_save_before
• {event_prefix}_save_a...
Model events
• Extend
MagentoFrameworkModelAbstractModel
• Set $_eventPrefix
• Set $_eventObject
Collection events
• {event_prefix}_load_before
• {event_prefix}_load_after
Collection events
• Extend
MagentoFrameworkModelResourceModel
DbCollectionAbstractCollection
• Set $_eventPrefix
• Set $_e...
Controller events
• controller_action_predispatch_{route_name}
• controller_action_predispatch_{full_action_name}
• contro...
Controller events
• Extend
MagentoFrameworkAppActionAction
Dispatch order
1. Observers in the global area
a. Module sequence order
b. Order in events.xml
2. Observers in adminhtml o...
PHPro/AModule/etc/adminhtml/events.xml
<event name="sales_order_save_after">
<observer name="phpro_a_order_save"
instance=...
RECAP
What should I use?
Preferences
Replace behavior
Preferences
• (+) Replace entire class or interface
implementation
• (-) Only one preference can be active
• (-) Replace e...
Plugins
Add and modify behavior
Plugins
• (+) Manipulate behavior before, after and
around one method
• (+) Access to arguments and output
• (+) Multiple ...
Observers
Modify passed data and start new behavior
Observers
• (+) Multiple observers for one event can be
active
• (-) Event has to exist
• (-) Only access to the passed da...
CASES
Enough with the theory…
Case #1
Modify the JSON response from
an external module
Case #2
Call an external service when an order
reaches the state “complete”
Case #3
Add a button to the main action bar
on the order view in the admin panel
Case #4
Customers are not stored in Magento and
should be accessed using an external service
Case #5
Change the store address
template in an e-mail template
Questions?
https://joind.in/talk/e48fa
Manipulating Magento - Meet Magento Belgium 2017
Manipulating Magento - Meet Magento Belgium 2017
Upcoming SlideShare
Loading in …5
×

Manipulating Magento - Meet Magento Belgium 2017

575 views

Published on

A talk I gave at Meet Magento Belgium 2017: https://be.meet-magento.com/presentation/manipulating-magento-make-want/

How can you make Magento do what you want? In Magento 2 there are a lot of ways to add customizations. What are your options? Can you do a rewrite like in Magento 1? Should you use an event to add that business-critical logic when your invoice reaches state paid? Or is a plugin a better option? Maybe it’s the only option. What’s the deal with dependency injection and why do I need interfaces? In this talk we’re going to explore all the possibilities.

Published in: Technology
  • Be the first to comment

Manipulating Magento - Meet Magento Belgium 2017

  1. 1. MANIPULATING MAGENTO Make it do what you want PHP developer at Joke Puts - @jokeputs
  2. 2. Goal Bug free and future proof customizations
  3. 3. How Keep the interactions with the core to a minimum
  4. 4. Topics • Preferences • Plugins • Observers • Cases
  5. 5. PREFERENCE Replacing behavior through dependency injection
  6. 6. Dependency injection “Dependency injection is the concept of the external environment injecting dependencies for an object instead of that object manually creating them internally.”
  7. 7. Dependency injection • Constructor injection • Object manager
  8. 8. MagentoQuoteModelQuoteAddressValidator public function __construct( AddressRepositoryInterface $addressRepository, CustomerRepositoryInterface $customerRepository, Session $customerSession ) { $this->addressRepository = $addressRepository; $this->customerRepository = $customerRepository; $this->customerSession = $customerSession; }
  9. 9. Interfaces • API directory • Service contract • (Relatively) stable across upgrades
  10. 10. MagentoFrameworkObjectManagerObjectManager public function create( $type, array $arguments = [] ) { $type = ltrim($type, ''); return $this->_factory->create( $this->_config->getPreference($type), $arguments ); }
  11. 11. di.xml <preference for="MagentoCustomerApiDataCustomerInterface" type="MagentoCustomerModelDataCustomer" />
  12. 12. module.xml <module name="Namespace_Module" setup_version="1.0.0"> <sequence> <module name="Magento_Customer"/> </sequence> </module>
  13. 13. <module name="PHPro_AModule" setup_version="1.0.0"> <sequence> <module name="Magento_Customer"/> </sequence> </module> <module name="PHPro_ZModule" setup_version="1.0.0"> <sequence> <module name="Magento_Customer"/> </sequence> </module>
  14. 14. PLUGINS Adding and modifying behavior before, after and around
  15. 15. Plugin “A plugin is a class that modifies the behavior of public class functions by running code before, after or around that function call.”
  16. 16. di.xml <type name="MagentoCatalogModelResourceModelCategory"> <plugin name="category_delete_plugin" type="MagentoCatalogUrlRewriteModelCategoryPl uginCategoryRemove"/> </type>
  17. 17. Before • Runs before the method • Modifies the arguments of the method • Returns null to indicate that the arguments haven’t changed
  18. 18. Before public function beforeSetName( Product $subject, $name ) { // Do something }
  19. 19. After • Runs after the method • Modifies the output of the method • Should have a return value
  20. 20. After public function afterGetName( Product $subject, $result ) { // Do something return $result; }
  21. 21. Around • Runs both before and after the method • Modifies the entire method • Access to arguments and output • Receives a callable
  22. 22. Around public function aroundUpdateData( Address $subject, callable $proceed, AddressInterface $address ) { // Do something $result = $proceed($address); // Do something return $result; }
  23. 23. Not calling the callable ✖Other around plugins (sort order) ✖Other after plugins (sort order) ✖Original method
  24. 24. Call order prior original 1. Sort order from low to high 2. Order of the uasort() array 3. Before plugins 4. Around plugins (before calling the callable)
  25. 25. Call order post original 1. Sort order from high to low* 2. Reversed order of the uasort() array 3. Around plugins (after calling the callable) 4. After plugins * Only if an around plugin exists
  26. 26. PHPro/AModule/etc/di.xml à after plugin <type name="MagentoStoreModelAddressRenderer"> <plugin name="renderer_a" type="PHProAModulePluginRenderer" sortOrder="10"/> </type> PHPro/ZModule/etc/di.xml à after plugin <type name="MagentoStoreModelAddressRenderer"> <plugin name="renderer_z" type="PHProZModulePluginRenderer" sortOrder="20"/> </type>
  27. 27. OBSERVERS Modifying data and running new behavior
  28. 28. Observers “Observers are executed whenever the event they are configured to watch is dispatched by the event manager.”
  29. 29. MagentoCustomerModelSession public function setCustomerAsLoggedIn($customer) { $this->setCustomer($customer); $this->_eventManager->dispatch( 'customer_login', ['customer' => $customer] );
  30. 30. events.xml <event name="customer_login"> <observer name="wishlist" instance="MagentoWishlistObserverCusto merLogin" /> </event>
  31. 31. MagentoWishlistObserverCustomerLogin class CustomerLogin implements ObserverInterface { public function execute( Observer $observer ) { $this->wishlistData->calculate(); } }
  32. 32. Events • Find events in the core • Look at the passed data • $observer->getEvent()->get{key}()
  33. 33. Model events • {event_prefix}_load_before • {event_prefix}_load_after • {event_prefix}_save_before • {event_prefix}_save_after • {event_prefix}_delete_before • {event_prefix}_delete_after • {event_prefix}_save_commit_after • {event_prefix}_delete_commit_after • {event_prefix}_clear
  34. 34. Model events • Extend MagentoFrameworkModelAbstractModel • Set $_eventPrefix • Set $_eventObject
  35. 35. Collection events • {event_prefix}_load_before • {event_prefix}_load_after
  36. 36. Collection events • Extend MagentoFrameworkModelResourceModel DbCollectionAbstractCollection • Set $_eventPrefix • Set $_eventObject
  37. 37. Controller events • controller_action_predispatch_{route_name} • controller_action_predispatch_{full_action_name} • controller_action_postdispatch_{full_action_name} • controller_action_postdispatch_{route_name}
  38. 38. Controller events • Extend MagentoFrameworkAppActionAction
  39. 39. Dispatch order 1. Observers in the global area a. Module sequence order b. Order in events.xml 2. Observers in adminhtml or frontend area a. Module sequence order b. Order in events.xml
  40. 40. PHPro/AModule/etc/adminhtml/events.xml <event name="sales_order_save_after"> <observer name="phpro_a_order_save" instance="PHProAModuleObserverAfterOrderSa ve" /> </event> PHPro/ZModule/etc/events.xml <event name="sales_order_save_after"> <observer name="phpro_z_order_save" instance="PHProZModuleObserverAfterOrderSa ve" /> </event>
  41. 41. RECAP What should I use?
  42. 42. Preferences Replace behavior
  43. 43. Preferences • (+) Replace entire class or interface implementation • (-) Only one preference can be active • (-) Replace entire class to replace one line of code
  44. 44. Plugins Add and modify behavior
  45. 45. Plugins • (+) Manipulate behavior before, after and around one method • (+) Access to arguments and output • (+) Multiple plugins for one method • (-) Only public methods
  46. 46. Observers Modify passed data and start new behavior
  47. 47. Observers • (+) Multiple observers for one event can be active • (-) Event has to exist • (-) Only access to the passed data
  48. 48. CASES Enough with the theory…
  49. 49. Case #1 Modify the JSON response from an external module
  50. 50. Case #2 Call an external service when an order reaches the state “complete”
  51. 51. Case #3 Add a button to the main action bar on the order view in the admin panel
  52. 52. Case #4 Customers are not stored in Magento and should be accessed using an external service
  53. 53. Case #5 Change the store address template in an e-mail template
  54. 54. Questions? https://joind.in/talk/e48fa

×