O slideshow foi denunciado.
Utilizamos seu perfil e dados de atividades no LinkedIn para personalizar e exibir anúncios mais relevantes. Altere suas preferências de anúncios quando desejar.

Magento 2 - An Intro to a Modern PHP-Based System - Northeast PHP 2015

4.965 visualizações

Publicada em

Over 200,000 companies use the Magento 1 platform to power their eCommerce needs. So when they set out to build a major new version, the Magento team had significant pressure to deliver a modern, well-designed PHP-based system. Pulling in some of the best of the PHP world through tools like Composer, phpunit and more, I believe they met that goal. In this talk, we’ll take a look at the design and architecture of Magento 2, including it’s use of dependency injections, interceptors and service contracts to provide numerous ways for developers to extend and customize the system.

Presented at Northeast PHP 2015

Publicada em: Tecnologia
  • Nice presentation of Magento 2. I have found many features Magento 1. x & Magento 2 extensions that will be useful for us. In that's are Advanced Newsletter Popup, Advanced Category Slider, Most Viewed & Sold Product Count, Size Chart, Our Services – Extension for Magento® 2 that I like the most. https://goo.gl/tRX8UD
       Responder 
    Tem certeza que deseja  Sim  Não
    Insira sua mensagem aqui

Magento 2 - An Intro to a Modern PHP-Based System - Northeast PHP 2015

  1. 1. PRESENTED BY JOSHUA WARREN PRESENTED AT NORTHEAST PHP 2015 Magento 2 AN INTRODUCTION TO A MODERN PHP- BASED SYSTEM
  2. 2. MY EXPERIENCE
  3. 3. JoshuaWarren.com My Experience PHP Developer Since 1999 Founded Creatuity in 2008 Focused on the Magento platform Magento 2 contributor #NEPHP
  4. 4. JoshuaWarren.com early adopter of both Magento 1 and Magento 2 #NEPHP
  5. 5. JoshuaWarren.com Frequent Magento presenter #NEPHP
  6. 6. JoshuaWarren.com Active member of the #RealMagento community #NEPHP
  7. 7. JoshuaWarren.com Involved in feedback and design discussions throughout the Magento 2 Developer Beta #NEPHP
  8. 8. JoshuaWarren.com Wrote Writing the book on Magento 2 #NEPHP
  9. 9. A BRIEF HISTORY OF MAGENTO Photo courtesy of @YoavKutner
  10. 10. JoshuaWarren.com Magento 1 development began in 2007 by Varien, a PHP development agency. #NEPHP
  11. 11. JoshuaWarren.com In 2007, osCommerce was state of the art. #NEPHP
  12. 12. JoshuaWarren.com Cloud-based eCommerce systems didn’t exist. #NEPHP
  13. 13. JoshuaWarren.com PHP 5.2 was cutting-edge. #NEPHP
  14. 14. JoshuaWarren.com Composer didn’t exist, and Zend Framework 1 was still in early beta. #NEPHP
  15. 15. JoshuaWarren.com Magento 1 was built to resolve the pain points of osCommerce. #NEPHP
  16. 16. JoshuaWarren.com Designed to be more flexible and to provide standardized ways to customize the platform. #NEPHP
  17. 17. JoshuaWarren.com By 2010, Magento had been downloaded 1.5 million times. #NEPHP
  18. 18. JoshuaWarren.com Attracted by Magento’s free, open- source approach, hundreds of thousands of sites were launched using Magento 1. #NEPHP
  19. 19. JoshuaWarren.com There’s just one problem… #NEPHP
  20. 20. JoshuaWarren.com Ecommerce development is hard. #NEPHP
  21. 21. JoshuaWarren.com Lightly documented ecommerce development is even harder. #NEPHP
  22. 22. JoshuaWarren.com Varien, now known as Magento Inc, is acquired by eBay in 2011. #NEPHP
  23. 23. JoshuaWarren.com Work begins on Magento 2 almost immediately. #NEPHP
  24. 24. JoshuaWarren.com Now the most widely-used eCommerce platform, powering over 250,000 sites, expectations are high for the Magento 2 team. #NEPHP
  25. 25. JoshuaWarren.com Fewer than 30 commits are made to Magento 2 in 2012. #NEPHP
  26. 26. JoshuaWarren.com Internal priorities continue to shift, and finally at the end of 2014, Magento 2 development is made public on Github. #NEPHP
  27. 27. JoshuaWarren.com Magento commits to a release schedule for Magento 2, and announces the acceptance of pull requests. #NEPHP
  28. 28. JoshuaWarren.com devdocs.magento.com launches with significant documentation of Magento 2. #NEPHP
  29. 29. JoshuaWarren.com Developer Beta is released in December 2014; Merchant Beta in July 2015 #NEPHP
  30. 30. JoshuaWarren.com Production-ready release (‘general availability’) scheduled for Q4 2015 #NEPHP
  31. 31. MAGENTO 2 github.com/magento/magento2
  32. 32. JoshuaWarren.com Feature parity with Magento 1 + UI/UX Improvements + focus on resolving technical debt #NEPHP
  33. 33. JoshuaWarren.com Technologies #NEPHP
  34. 34. JoshuaWarren.com #NEPHP Composer composer create-project magento/product-community-edition --stability="beta" <installation directory name>
  35. 35. JoshuaWarren.com Each Magento 2 module is a separate Composer package #NEPHP
  36. 36. JoshuaWarren.com PSR-0 thru PSR-4 #NEPHP
  37. 37. JoshuaWarren.com Testing built in from the start. phpunit, selenium, JMeter, Jasmine #NEPHP
  38. 38. JoshuaWarren.com magento2/dev/tests/ #NEPHP
  39. 39. JoshuaWarren.com HTML5, CSS3, LESS CSS Preprocessor, JQuery, RequireJS #NEPHP
  40. 40. JoshuaWarren.com Components from Zend Framework 1, Zend Framework 2, Symfony #NEPHP
  41. 41. JoshuaWarren.com Technical Architecture #NEPHP
  42. 42. JoshuaWarren.com Presentation Layer, Service Layer, Domain Layer, Persistence Layer #NEPHP
  43. 43. JoshuaWarren.com #NEPHP
  44. 44. JoshuaWarren.com Presentation Layer - views, literally and figuratively #NEPHP
  45. 45. JoshuaWarren.com Service Layer - an intermediary between the presentation and model layers #NEPHP
  46. 46. JoshuaWarren.com Service layer provides a stable, backwards-compatible interface and forms the foundation for dependency injection. #NEPHP
  47. 47. JoshuaWarren.com Domain layer - business logic, including models. Contains the implementation of service contracts. #NEPHP
  48. 48. JoshuaWarren.com Persistence Layer - resource models that perform CRUD operations on database tables. #NEPHP
  49. 49. JoshuaWarren.com Some models use a single table, others continue to use the Entity-Attribute-Value design pattern used in Magento 1. #NEPHP
  50. 50. JoshuaWarren.com Design Patterns #NEPHP
  51. 51. JoshuaWarren.com Loose Coupling #NEPHP
  52. 52. JoshuaWarren.com Dependency Injection #NEPHP
  53. 53. JoshuaWarren.com Service Contracts #NEPHP
  54. 54. JoshuaWarren.com Interceptors #NEPHP
  55. 55. JoshuaWarren.com Semantic Versioning #NEPHP
  56. 56. DEPENDENCY INJECTION Sorry - no cool photo here, because I don’t like needles…
  57. 57. JoshuaWarren.com DI is exactly what it sounds like - injecting dependencies into the objects that need them. #NEPHP
  58. 58. JoshuaWarren.com DI is designed to reduce dependencies and promote loose coupling #NEPHP
  59. 59. JoshuaWarren.com DI makes unit testing much easier #NEPHP
  60. 60. JoshuaWarren.com Magento 2 uses the Constructor Injection pattern of DI #NEPHP
  61. 61. JoshuaWarren.com DI in Magento 2 is handled via XML files #NEPHP
  62. 62. JoshuaWarren.com #NEPHP di.xml <config xmlns:xsi=“[…]” xsi:noNamespaceSchemaLocation=“[…]”>
 <virtualType name="MagentoSamplePaymentProviderBlockFormPayinstore" type="MagentoPaymentBlockForm" shared="false"> <arguments>
 <argument name="data" xsi:type="array">
 <item name="template" xsi:type=“string"> Magento_SamplePaymentProvider::form/payinstore.phtml </item>
 </argument>
 </arguments>
 </virtualType>
 </config>
  63. 63. INTERCEPTORS
  64. 64. JoshuaWarren.com Plugin system based on the interceptor pattern #NEPHP
  65. 65. JoshuaWarren.com Calls to almost any module can be intercepted and altered #NEPHP
  66. 66. JoshuaWarren.com Vast improvement over the rewrite pattern in Magento 1 - no more rewrite conflicts #NEPHP
  67. 67. JoshuaWarren.com #NEPHP di.xml <config>
 <type name="{ObservedType}">
 <plugin name="{pluginName}" type="{PluginClassName}" sortOrder="1" disabled="false"/>
 </type>
 </config>
  68. 68. JoshuaWarren.com Sort order defines order if multiple plugins intercept the same item #NEPHP
  69. 69. JoshuaWarren.com Possible to intercept before, after and around a function #NEPHP
  70. 70. JoshuaWarren.com #NEPHP ‘Before’ Interceptor class Plugin
 {
 public function beforeSetName(MagentoCatalogModelProduct $subject, $name)
 {
 return array('(' . $name . ')');
 }
 }
  71. 71. JoshuaWarren.com #NEPHP ‘After’ Interceptor class Plugin
 {
 public function afterGetName(MagentoCatalogModelProduct $subject, $result)
 {
 return '|' . $result . '|';
 }
 }
  72. 72. JoshuaWarren.com #NEPHP ‘Around’ Interceptor class Plugin
 {
 public function aroundSave(MagentoCatalogModelProduct $subject, Closure $proceed)
 {
 $this->doSomethingBeforeProductIsSaved();
 $returnValue = $proceed();
 if ($returnValue) {
 $this->postProductToFacebook();
 }
 return $returnValue;
 }
 }
  73. 73. SERVICE CONTRACTS Credit to Allan MacGregor for the Soylent Green joke.
  74. 74. JoshuaWarren.com Set of interfaces to define the public API of a module #NEPHP
  75. 75. JoshuaWarren.com This API is the interface provided to other modules to access its implementation #NEPHP
  76. 76. JoshuaWarren.com Designed to hide business logic behind a stable interface #NEPHP
  77. 77. JoshuaWarren.com Service contracts + semantic versioning = minor releases will not break existing code #NEPHP
  78. 78. JoshuaWarren.com @deprecated = will be removed with the next major version release #NEPHP
  79. 79. JoshuaWarren.com #NEPHP CustomerRepositoryInterface.php 
 namespace MagentoCustomerApi;
 /**
 * Customer CRUD interface.
 */
 interface CustomerRepositoryInterface
 {
 /**
 * Create customer.
 *
 * @api
 * @param MagentoCustomerApiDataCustomerInterface $customer
 * @param string $passwordHash
 * @return MagentoCustomerApiDataCustomerInterface
 * @throws MagentoFrameworkExceptionInputException If bad input is provided
 * @throws MagentoFrameworkExceptionStateInputMismatchException If the provided email is already used
 * @throws MagentoFrameworkExceptionLocalizedException
 */
 public function save(MagentoCustomerApiDataCustomerInterface $customer, $passwordHash = null);
  80. 80. JoshuaWarren.com #NEPHP CustomerRepositoryInterface.php /**
 * Retrieve customer.
 *
 * @api
 * @param string $email
 * @param int|null $websiteId
 * @return MagentoCustomerApiDataCustomerInterface
 * @throws MagentoFrameworkExceptionNoSuchEntityException If customer with the specified email does not exist.
 * @throws MagentoFrameworkExceptionLocalizedException
 */
 public function get($email, $websiteId = null);
 /**
 * Retrieve customer.
 *
 * @api
 * @param int $customerId
 * @return MagentoCustomerApiDataCustomerInterface
 * @throws MagentoFrameworkExceptionNoSuchEntityException If customer with the specified ID does not exist.
 * @throws MagentoFrameworkExceptionLocalizedException
 */
 public function getById($customerId);

  81. 81. JoshuaWarren.com Service Contracts include Data Interfaces and Service Interfaces #NEPHP
  82. 82. JoshuaWarren.com Data Interfaces return information about data entities #NEPHP
  83. 83. JoshuaWarren.com Service Interfaces handle business logic #NEPHP
  84. 84. JoshuaWarren.com Three types of service interfaces in Magento 2 (so far) #NEPHP
  85. 85. JoshuaWarren.com Repository Interfaces provide access to persistent data entities #NEPHP
  86. 86. JoshuaWarren.com CustomerRepositoryInterface, AddressRepositoryInterface, etc. #NEPHP
  87. 87. JoshuaWarren.com Repository interfaces contain the CRUD operations #NEPHP
  88. 88. JoshuaWarren.com Management interfaces contain management functions not related to repositories #NEPHP
  89. 89. JoshuaWarren.com Validators, createAccount, changePassword, etc #NEPHP
  90. 90. JoshuaWarren.com Metadata interfaces provide meta information - primarily about custom attributes #NEPHP
  91. 91. EXTENDING MAGENTO 2
  92. 92. JoshuaWarren.com Create your basic module file structure #NEPHP
  93. 93. JoshuaWarren.com #NEPHP App/Code/<Vendor>/<Module>/ composer.json etc/module.xml Test/Unit/<tests go here>
  94. 94. JoshuaWarren.com #NEPHP Composer.json { "name": "joshuaswarren/sample-module-minimal", "description": "A minimal sample Magento 2 module", "type": "magento2-module", "version": "1.0.0", "license": [ "OSL-3.0", "AFL-3.0" ], "require": { "php": "~5.5.0|~5.6.0", "magento/magento-composer-installer": "*" }, "extra": { "map": [ [ "*", "joshuaswarren/SampleMinimal" ] ] } }
  95. 95. JoshuaWarren.com #NEPHP etc/module.xml <config> <module name=“Joshuaswarren_SampleMinimal" setup_version="2.0.0"> </module> </config>
  96. 96. JoshuaWarren.com Optional config files in etc: acl.xml config.xml di.xml webapi.xml #NEPHP
  97. 97. JoshuaWarren.com acl.xml defines new items for Magento’s ACL system #NEPHP
  98. 98. JoshuaWarren.com Config.xml adds new configuration options #NEPHP
  99. 99. JoshuaWarren.com Webapi.xml defines items to expose via the REST or SOAP APIs #NEPHP
  100. 100. JoshuaWarren.com Optional subdirectories in etc: adminhtml frontend webapi_rest webapi_soap #NEPHP
  101. 101. JoshuaWarren.com Items in the main etc directory apply globally to your extension #NEPHP
  102. 102. JoshuaWarren.com Items in the 4 subdirectories apply only to that area - i.e., adminhtml only applies to the Magento backend #NEPHP
  103. 103. JoshuaWarren.com Optional subdirectories: API Block Controller Helper Model #NEPHP
  104. 104. JoshuaWarren.com Optional subdirectories: Plugin Setup Ui i18n view #NEPHP
  105. 105. JoshuaWarren.com API contains any new service contracts your extension adds #NEPHP
  106. 106. JoshuaWarren.com Block contains any new template blocks your extension adds #NEPHP
  107. 107. JoshuaWarren.com Controller contains your extension’s controllers #NEPHP
  108. 108. JoshuaWarren.com Helper contains any helper functions that your extension needs #NEPHP
  109. 109. JoshuaWarren.com Model contains your extension’s models #NEPHP
  110. 110. JoshuaWarren.com Plugin contains any interceptors your extension defines #NEPHP
  111. 111. JoshuaWarren.com Setup contains your database migrations using Magento’s setup script system #NEPHP
  112. 112. JoshuaWarren.com UI is for Magento 2’s new Magento UI library #NEPHP
  113. 113. JoshuaWarren.com I18n contains internationalization files - CSV files defining the translations for your strings #NEPHP
  114. 114. JoshuaWarren.com View contains the views for your extension #NEPHP
  115. 115. JoshuaWarren.com If your extension doesn’t need one of these items, just omit that folder #NEPHP
  116. 116. JoshuaWarren.com Sample: custom shipping method to allow for in-store pickup from several locations #NEPHP
  117. 117. JoshuaWarren.com #NEPHP Block/System/Config/Form/Field/Locations.php namespace MagentoSampleShippingProviderBlockSystemConfigFormField;
 use MagentoConfigBlockSystemConfigFormFieldFieldArrayAbstractFieldArray;
 /**
 * Backend system config array field renderer
 */
 class Locations extends AbstractFieldArray
 {
 /**
 * Initialise columns for 'Store Locations'
 *
 * @return void
 */
 protected function _construct()
 {
 $this->addColumn('title',
 ['label' => __('Title'), 'class' => 'validate-no-empty validate-alphanum-with-spaces']);
 $this->addColumn('street',
 ['label' => __('Street Address'), 'class' => 'validate-no-empty validate-alphanum-with-spaces']);
 $this->addColumn('phone',
 ['label' => __('Phone Number'), 'class' => 'validate-no-empty validate-no-empty validate-phoneStrict']);
 $this->addColumn('message',
 ['label' => __('Message'), 'class' => 'validate-no-empty']);
 $this->_addAfter = false;
 parent::_construct();
 }
 }
  118. 118. JoshuaWarren.com #NEPHP Model/Type/Plugin/Onepage.php [1/2] namespace MagentoSampleShippingProviderModelTypePlugin;
 use MagentoCheckoutModelTypeOnepage as CheckoutOnePage;
 use MagentoSampleShippingProviderModelCarrier;
 /**
 * Change Shipping Address to selected Store location address
 */
 class Onepage
 {
 /**
 * @var Carrier
 */
 private $carrier;
 /**
 * @param Carrier $carrier
 */
 public function __construct(Carrier $carrier)
 {
 $this->carrier = $carrier;
 }

  119. 119. JoshuaWarren.com #NEPHP Model/Type/Plugin/Onepage.php [2/2] /**
 * Replace shipping address with pickup location address
 * @param CheckoutOnePage $subject
 * @param array $result
 * @return $this
 */
 public function afterSaveShippingMethod(CheckoutOnePage $subject, array $result)
 {
 if ($result) {
 return $result;
 }
 $quote = $subject->getQuote();
 $shippingAddress = $quote->getShippingAddress();
 $shippingMethod = $shippingAddress->getShippingMethod();
 /**
 * In-Store pickup selected
 * Update Shipping Address
 */
 if (strpos($shippingMethod, $this->carrier->getCarrierCode()) !== false) {
 $locationAddress = $this->carrier->getLocationInfo($shippingMethod);
 $shippingAddress->setCountryId($locationAddress['country_id']);
 $shippingAddress->setRegionId($locationAddress['region_id']);
 $shippingAddress->setPostcode($locationAddress['postcode']);
 $shippingAddress->setCity($locationAddress['city']);
 $shippingAddress->setStreet($locationAddress['street']);
 $shippingAddress->setTelephone($locationAddress['phone']);
 }
 return $result;
 }
 }
  120. 120. JoshuaWarren.com #NEPHP Model/Carrier.php namespace MagentoSampleShippingProviderModel;
 use PsrLogLoggerInterface;
 use MagentoFrameworkAppConfigScopeConfigInterface;
 use MagentoStoreModelScopeInterface;
 use MagentoShippingModelCarrierAbstractCarrier;
 use MagentoShippingModelCarrierCarrierInterface;
 use MagentoShippingModelConfig;
 use MagentoShippingModelRateResultFactory;
 use MagentoQuoteModelQuoteAddressRateResultMethodFactory;
 use MagentoQuoteModelQuoteAddressRateResultErrorFactory;
 /**
 * In-Store Pickup shipping model
 */
 class Carrier extends AbstractCarrier implements CarrierInterface
 {
 /**
 * @var string
 */
 protected $_code = 'storepickup';
 /**
 * @var bool
 */
 protected $_isFixed = true; … see https://github.com/magento/magento2-samples/blob/master/sample-module-shipping-provider/Model/Carrier.php 

  121. 121. JoshuaWarren.com In model/carrier.php we implement all of the functions a shipping carrier must have in Magento 2 #NEPHP
  122. 122. JoshuaWarren.com GetAllowedMethods CollectRates GetLocationInfo BuildRateForLocation GetLocations GetShippingOrigin #NEPHP
  123. 123. JoshuaWarren.com #NEPHP Etc/Adminhtml/System.xml <system>
 <section id="carriers">
 <group id="storepickup" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
 <label>In-Store Pickup</label>
 <field id="active" translate="label" type="select" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="1">
 <label>Enabled</label>
 <source_model>MagentoConfigModelConfigSourceYesno</source_model>
 <comment>
 <![CDATA[<strong style="color:red">Warning</strong>: Shipping Origin should be configured to use this method.]]>
 </comment>
 </field>
 <field id="title" translate="label" type="text" sortOrder="2" showInDefault="1" showInWebsite="1" showInStore="1">
 <label>Title</label>
 </field>
 […]
  124. 124. JoshuaWarren.com #NEPHP Etc/Frontend/di.xml <config xmlns:xsi=“[…]” xsi:noNamespaceSchemaLocation=“[…]”>
 <type name="MagentoSampleShippingProviderModelTypePluginOnepage"/>
 <type name="MagentoCheckoutModelTypeOnepage">
 <plugin name="change_shipping_address" type="MagentoSampleShippingProviderModelTypePluginOnepage"/>
 </type>
 </config>
  125. 125. JoshuaWarren.com #NEPHP Etc/Config.xml <config xmlns:xsi=“[…]” xsi:noNamespaceSchemaLocation=“[…]”>
 <default>
 <carriers>
 <storepickup>
 <active>1</active>
 <model>MagentoSampleShippingProviderModelCarrier</model>
 <title>In-Store Pickup</title>
 <specificerrmsg>This shipping method is not available.</specificerrmsg>
 </storepickup>
 </carriers>
 </default>
 </config>
  126. 126. JoshuaWarren.com #NEPHP Etc/Module.xml <config xmlns:xsi=“[…]” xsi:noNamespaceSchemaLocation=“[…]”>
 <module name="Magento_SampleShippingProvider" setup_version="2.0.0">
 </module>
 </config>
  127. 127. JoshuaWarren.com #NEPHP Composer.json { "name": "magento/sample-module-shipping-provider", "description": "Demonstrate Shipping Provider", "type": "magento2-module", "version": "1.0.0", "license": [ "OSL-3.0", "AFL-3.0" ], "require": { "php": "~5.5.0|~5.6.0", "magento/magento-composer-installer": "*", "magento/framework": "~0.74", "magento/module-store": "~0.74", "magento/module-shipping": "~0.74", "magento/module-quote": "~0.74", "magento/module-checkout": "~0.74" }, "extra": { "map": [ [ "*", "Magento/SampleShippingProvider" ] ] } }
  128. 128. JoshuaWarren.com We now have a complete, functioning in-store-pickup shipping extension for Magento 2 #NEPHP
  129. 129. JoshuaWarren.com Take a look at the Test/Unit directory on Github for tests for this extension #NEPHP
  130. 130. JoshuaWarren.com Magento 2 unit testing includes mocking, fixtures, etc. - everything you need for TDD #NEPHP
  131. 131. LEARNING MORE Don’t end up like this guy ->
  132. 132. JoshuaWarren.com devdocs.magento.com magento.stackexchange.com/questions/tagged/magento2 #NEPHP
  133. 133. JoshuaWarren.com AlanStorm.com AlanKent.me CoderOnCode.com #NEPHP
  134. 134. JoshuaWarren.com Upcoming events: Meet Magento New York, ZendCon, php[world] #NEPHP
  135. 135. JoshuaWarren.com Programming With Magento 2 coming to amazon.com & phparch.com #NEPHP
  136. 136. Keep in Touch! joind.in/14737 @JoshuaSWarren JoshuaWarren.com Mage2DevBook.com
  137. 137. JoshuaWarren.com #NEPHP

×