Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Magento 2 Dependency Injection, Interceptors, and You - php[world] 2015

Magento 2 Dependency Injection, Interceptors, and You - php[world] 2015

Magento 2 introduces dependency injection and interceptors, two approaches to creating a more flexible, extendable architecture. These concepts are new to many PHP developers, but they are critical to understanding and taking advantage of the power and flexibility of Magento 2. Let's take a high-level look at these concepts, and then dive into some real examples of how to utilize these techniques in your development work with Magento 2.

Joshua Warren

November 18, 2015

More Decks by Joshua Warren

Other Decks in Programming



  2. JoshuaWarren.com #phpworld

  3. JoshuaWarren.com Magento 2 officially released yesterday! #phpworld

  4. JoshuaWarren.com 100 slides in ~45 minutes lots of code focus

    on the concepts, download the slides later #phpworld

  6. JoshuaWarren.com My Experience PHP Developer Since 1999 Founded Creatuity in

    2008 Focused on the Magento platform #phpworld
  7. JoshuaWarren.com early adopter of both Magento 1 and Magento 2

  8. JoshuaWarren.com Frequent Magento presenter #phpworld

  9. JoshuaWarren.com Led the Creatuity team in building 3 Magento 2

    extensions (more on the way!) #phpworld
  10. JoshuaWarren.com Already migrating a few merchants from Magento 1 to

    Magento 2 #phpworld
  11. JoshuaWarren.com Wrote Writing the book on Magento 2 #phpworld

  12. JoshuaWarren.com Not a Magento employee, but working closely with the

    development, documentation & product teams on Magento 2 #phpworld
  13. JoshuaWarren.com A quick note for any Magento 1 developers in

    the audience… #phpworld
  14. JoshuaWarren.com #phpworld

  15. JoshuaWarren.com …for PHP developers new to Magento. #phpworld

  16. JoshuaWarren.com PHP developers are learning Magento 2 faster than many

    Magento 1 developers. #phpworld
  17. JoshuaWarren.com Approach Magento 2 with a desire to learn and

    understand the underlying patterns. #phpworld
  18. JoshuaWarren.com Don’t approach Magento 2 with the thought “how do

    I make my Magento 1 code work here” #phpworld
  19. JoshuaWarren.com #phpworld

  20. JoshuaWarren.com Shoshin is a Zen concept meaning “beginner’s mind” #phpworld

  21. JoshuaWarren.com An attitude of openness, eagerness and lack of preconceptions.

  22. JoshuaWarren.com No matter your level of Magento 1 experience, approach

    Magento 2 with a beginner’s mind #phpworld
  23. JoshuaWarren.com With that mind, let’s dive into Magento 2… #phpworld

  24. MAGENTO 2 github.com/magento/magento2

  25. JoshuaWarren.com Technologies #phpworld

  26. JoshuaWarren.com #phpworld Composer composer create-project magento/product-community-edition -- stability="beta" <installation directory

  27. JoshuaWarren.com Each Magento 2 module is a separate Composer package

  28. JoshuaWarren.com PSR-0 thru PSR-4 #phpworld

  29. JoshuaWarren.com Testing built in from the start. phpunit, selenium, JMeter,

    Jasmine #phpworld
  30. JoshuaWarren.com HTML5, CSS3, LESS CSS Preprocessor, JQuery, RequireJS #phpworld

  31. JoshuaWarren.com Components from Zend Framework 1, Zend Framework 2, Symfony

  32. JoshuaWarren.com Technical Architecture #phpworld

  33. JoshuaWarren.com Presentation Layer, Service Layer, Domain Layer, Persistence Layer #phpworld

  34. JoshuaWarren.com #phpworld

  35. JoshuaWarren.com Presentation Layer - views, literally and figuratively #phpworld

  36. JoshuaWarren.com Service Layer - an intermediary between the presentation and

    model layers #phpworld
  37. JoshuaWarren.com Service layer provides a stable, backwards-compatible interface and forms

    the foundation for dependency injection. #phpworld
  38. JoshuaWarren.com Domain layer - business logic, including models. Contains the

    implementation of service contracts. #phpworld
  39. JoshuaWarren.com Persistence Layer - resource models that perform CRUD operations

    on database tables. #phpworld
  40. JoshuaWarren.com Some models use a single table, others continue to

    use the Entity-Attribute-Value design pattern used in Magento 1. #phpworld
  41. JoshuaWarren.com Design Patterns #phpworld

  42. JoshuaWarren.com Loose Coupling #phpworld

  43. JoshuaWarren.com Dependency Injection #phpworld

  44. JoshuaWarren.com Service Contracts #phpworld

  45. JoshuaWarren.com Interceptors #phpworld

  46. JoshuaWarren.com Semantic Versioning #phpworld

  47. JoshuaWarren.com Start your Magento 2 journey learning the basics of

    these design patterns #phpworld
  48. JoshuaWarren.com We are going to take a closer look at

    two patterns today: dependency injection and interceptors #phpworld
  49. DEPENDENCY INJECTION Sorry - no cool photo here, because I

    don’t like needles…
  50. JoshuaWarren.com DI is exactly what it sounds like - injecting

    dependencies into the objects that need them. #phpworld
  51. JoshuaWarren.com It sounds complicated, but it’s not. #phpworld

  52. JoshuaWarren.com Hollywood Principle: “Don’t call us, we’ll call you” #phpworld

  53. JoshuaWarren.com With DI, instead of building an object in your

    class, it’s passed in via your constructor. #phpworld
  54. JoshuaWarren.com DI is designed to reduce dependencies and promote loose

    coupling #phpworld
  55. JoshuaWarren.com DI makes unit testing much easier #phpworld

  56. JoshuaWarren.com DI allows for mocking - replacing things like the

    MySQL adapter with a mock object during testing #phpworld
  57. JoshuaWarren.com Magento 2 uses the Constructor Injection pattern of DI

  58. JoshuaWarren.com This replaces the usage of the Mage class from

    Magento 1. #phpworld
  59. JoshuaWarren.com DI in Magento 2 is Automatic Dependency Injection #phpworld

  60. JoshuaWarren.com Objects do not need to locate the object or

    value in which it depends - it’s automatic. #phpworld
  61. JoshuaWarren.com Magento’s object manager uses PHP’s reflection features to automatically

    instantiate needed objects #phpworld
  62. JoshuaWarren.com DI in Magento 2 is handled via XML files

  63. JoshuaWarren.com #phpworld di.xml <config xmlns:xsi=“[…]” xsi:noNamespaceSchemaLocation=“[…]”>
 <virtualType name="Magento\SamplePaymentProvider\Block\Form\Payinstore" type="Magento\Payment\Block\Form" shared="false">

 <argument name="data" xsi:type="array">
 <item name="template" xsi:type=“string"> Magento_SamplePaymentProvider::form/payinstore.phtml </item>
  64. JoshuaWarren.com I highly recommend Alan Storm’s article “Magento 2’s Automatic

    Dependency Injection” #phpworld
  65. JoshuaWarren.com #phpworld Without Dependency Injection public function getFormattedPrice($sku)

    = new DBHandler;
 $row = $db->query('SELECT price FROM products WHERE sku = ?', $sku);
 $formatter = new PriceFormatter;
 return $formatter->asDollars($row['price']);
  66. JoshuaWarren.com #phpworld With Dependency Injection public function getFormattedPrice($sku, $db, $formatter)

 $row = $db->query('SELECT price FROM products WHERE sku = ?', $sku);
 return $formatter->asDollars($row['price']);
  67. JoshuaWarren.com DI simplifies testing, maintenance and readability #phpworld

  68. JoshuaWarren.com DI.XML is also where plugins following our next pattern

    to discuss are declared. #phpworld

  70. JoshuaWarren.com Plugin system based on the interceptor pattern #phpworld

  71. JoshuaWarren.com Calls to almost any module can be intercepted and

    altered #phpworld
  72. JoshuaWarren.com Vast improvement over the rewrite pattern in Magento 1

    - no more rewrite conflicts #phpworld
  73. JoshuaWarren.com #phpworld di.xml <config>
 <type name="{ObservedType}">
 <plugin name="{pluginName}" type="{PluginClassName}" sortOrder="1"

  74. JoshuaWarren.com Sort order defines order if multiple plugins intercept the

    same item #phpworld
  75. JoshuaWarren.com Possible to intercept before, after and around a function

  76. JoshuaWarren.com #phpworld ‘Before’ Interceptor class Plugin
 public function beforeSetName(\Magento\Catalog\Model\Product

    $subject, $name)
 return array('(' . $name . ')');
  77. JoshuaWarren.com #phpworld ‘After’ Interceptor class Plugin
 public function afterGetName(\Magento\Catalog\Model\Product

    $subject, $result)
 return '|' . $result . '|';
  78. JoshuaWarren.com #phpworld ‘Around’ Interceptor class Plugin
 public function aroundSave(\Magento\Catalog\Model\Product

    $subject, \Closure $proceed)
 $returnValue = $proceed();
 if ($returnValue) {
 return $returnValue;
  79. JoshuaWarren.com Check out the magento 2 sample modules repo for

    a module that demonstrates interception #phpworld
  80. JoshuaWarren.com #phpworld DI.xml <type name="Magento\SampleInterception\Model\Intercepted\ChildBefore">
 <plugin name="Magento_SampleInterception::demoPluginBefore" type="Magento\SampleInterception\Plugin\PluginBefore" />

    <type name="Magento\SampleInterception\Model\Intercepted\ChildAfter">
 <plugin name="Magento_SampleInterception::demoPluginAfter" type="Magento\SampleInterception\Plugin\PluginAfter" />
 <type name="Magento\SampleInterception\Model\Intercepted\ChildAround">
 <plugin name="Magento_SampleInterception::demoPluginAround" type="Magento\SampleInterception\Plugin\PluginAround" />
 <type name="Magento\SampleInterception\Model\Intercepted\ChildInherit">
 <plugin name="Magento_SampleInterception::demoPluginInheritance" type="Magento\SampleInterception\Plugin\ParentPlugin" />

  81. JoshuaWarren.com #phpworld Plugin/PluginBefore.php public function beforeBaseMethodUppercase(ChildBefore $subject, $interceptedInput)

    ["(before) $interceptedInput (/before)"];
  82. JoshuaWarren.com #phpworld Plugin/PluginAfter.php public function afterBaseMethodUppercase(ChildAfter $subject, $interceptedOutput)

    "(after) $interceptedOutput (/after)";
  83. JoshuaWarren.com #phpworld Plugin/PluginAround.php public function aroundBaseMethodUppercase(ChildAround $subject, \Closure $proceed, $interceptedInput)

 $argument = "(around: before base method) $interceptedInput (/around: before base method)";
 $result = $proceed($argument);
 return "(around: after base method) $result (/around: after base method)";
  84. JoshuaWarren.com Interceptors are a replacement for rewrites #phpworld

  85. JoshuaWarren.com Interceptors supplement, but not replace, events and observers #phpworld

  86. JoshuaWarren.com Sort order conflicts #phpworld

  87. JoshuaWarren.com Please don’t define a sort order of 1 unless

    you really need it #phpworld
  88. JoshuaWarren.com We’re all waiting to see what happens with sort

    order conflicts in real world usage #phpworld
  89. JoshuaWarren.com Ideally, the largest extension authors will coordinate their sort

    order for common conflicts #phpworld
  90. JoshuaWarren.com If not, when installing extensions, developers will need to

    modify their sort order to resolve conflicts. #phpworld
  91. LEARNING MORE Don’t end up like this guy ->

  92. JoshuaWarren.com devdocs.magento.com - ‘How Do I?’ magento.stackexchange.com/questions/tagged/ magento2 https://github.com/magento/magento2-samples #phpworld

  93. JoshuaWarren.com Read through the sample modules. #phpworld

  94. JoshuaWarren.com The sample modules don’t currently work (see issue #42)

  95. JoshuaWarren.com In order to run the sample modules, you will

    have to add a registration.php file. #phpworld
  96. JoshuaWarren.com Otherwise, they’re still a great resource to see dependency

    injection and interceptors in action. #phpworld
  97. Dev Docs Team Team of hard-working technical writers (not developers)

    Writing documentation for a system that has yet to be used ‘in the wild’ Very eager for feedback and input - they don’t know what documentation you need Very open to pull requests of documentation or just open an issue on Github with feedback + requests JoshuaWarren.com #phpworld
  98. Dev Docs Team JoshuaWarren.com #phpworld

  99. JoshuaWarren.com Magento U Courses Fundamentals of Magento 2 Development Front-end

    Course #phpworld
  100. JoshuaWarren.com AlanStorm.com AlanKent.me CoderOnCode.com github.com/creatuity/LearningMagento2 #phpworld

  101. JoshuaWarren.com Upcoming events: Magento Imagine - April 2016 #phpworld

  102. JoshuaWarren.com As a freelancer… Learning Magento 2 Set aside time

    in your week to learn the design patterns Magento 2 uses Work through the sample code the Magento 2 team has provided Begin experimenting with developing with Magento 2 Do not try to learn ‘on the job’ - be careful accepting M2 work before you’re ready #phpworld
  103. JoshuaWarren.com As an in-house developer for a merchant… Learning Magento

    2 Determine when your business is likely to migrate to Magento 2 First 2-4 weeks of your Magento 2 migration schedule should be learning Magento 2 Learn the patterns before you start! #phpworld
  104. JoshuaWarren.com As an agency or industry partner… Learning Magento 2

    Create a tiger team of developers focused on Magento 2 Allow those developers time in the day to learn Magento 2 Those developers should implement your first Magento 2 projects That team then helps the rest of your team through the learning curve #phpworld
  105. JoshuaWarren.com When do I need to be Magento 2 ready?

    Learning Magento 2 Magento 2 will be released late enough in the year that most merchants won’t begin using it immediately. Merchants will also wait until their mission-critical extensions are available on Magento 2. Start learning it now - but don’t panic! #phpworld
  106. JoshuaWarren.com Programming With Magento 2 coming to amazon.com & phparch.com

  107. Keep in Touch! @JoshuaSWarren JoshuaWarren.com Mage2DevBook.com joind.in/14790

  108. JoshuaWarren.com #phpworld