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

Magento 2 Workshop - Meet Magento New York 2015 #MM15NY

Joshua Warren
September 22, 2015

Magento 2 Workshop - Meet Magento New York 2015 #MM15NY

Learning the basics of Magento 2 for Magento 1 developers. Periscope recording: https://t.co/zpQp7K3DXO

Joshua Warren

September 22, 2015
Tweet

More Decks by Joshua Warren

Other Decks in Programming

Transcript

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

    2008 Focused on the Magento platform Magento 2 contributor #MM15NY
  2. JoshuaWarren.com The hardest part for a Magento 1 developer learning

    Magento 2 has nothing to do with code… #MM15NY
  3. JoshuaWarren.com Approach Magento 2 with a desire to learn and

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

    I make my Magento 1 code work here” #MM15NY
  5. JoshuaWarren.com A look at the state of the art when

    Magento 1 was built PHP & Ecommerce in 2007 osCommerce is state of the art Cloud-based / SaaS ecommerce doesn’t exist yet PHP 5.2 is cutting-edge Composer doesn’t exist - PHP has no dependency management There’s this new thing called ZF, otherwise it’s Cake or Symfony Testing? You might find a few people using PHPUnit #MM15NY
  6. JoshuaWarren.com The Painful World of osCommerce PHP & Ecommerce in

    2007 Want to add an attribute? Modify your database schema on live. Looking at add new features? Modify core PHP files. Want to upgrade your store? Good luck! #MM15NY
  7. JoshuaWarren.com Modernizing PHP-based Ecommerce in 2007 Magento 1’s Initial Development

    Forces a standardized approach to extensions, database migrations, etc. Introduces patterns previously unseen in PHP (EAV, anyone?) Broke with standard practices at the time in pursuit of something better Developers flock to Magento 1 because of this #MM15NY
  8. JoshuaWarren.com As a community, we built documentation & tools to

    make Magento 1 development easier. #MM15NY
  9. JoshuaWarren.com Ecommerce in 2015 Ecommerce grows by 10%/year every year

    - despite the Great Recession SaaS ecommerce platforms take off Responsive design & mobile commerce are the norm Ecommerce becomes a basic requirement for modern business - B2C & B2B #MM15NY
  10. JoshuaWarren.com PHP in 2015 PHP 5.2 has been unsupported for

    4 years Namespaces, added in PHP 5.3, didn’t exist when Magento 1 was designed Laravel, Symfony & others are bringing advanced design patterns to PHP PHP 7 is right around the corner, including scalar type hints and more #MM15NY
  11. JoshuaWarren.com Some models use a single table, others continue to

    use the Entity-Attribute-Value design pattern used in Magento 1. #MM15NY
  12. JoshuaWarren.com DI is exactly what it sounds like - injecting

    dependencies into the objects that need them. #MM15NY
  13. JoshuaWarren.com #MM15NY di.xml <config xmlns:xsi=“[…]” xsi:noNamespaceSchemaLocation=“[…]”>
 <virtualType name="Magento\SamplePaymentProvider\Block\Form\Payinstore" type="Magento\Payment\Block\Form" 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>
  14. JoshuaWarren.com #MM15NY ‘Around’ Interceptor class Plugin
 {
 public function aroundSave(\Magento\Catalog\Model\Product

    $subject, \Closure $proceed)
 {
 $this->doSomethingBeforeProductIsSaved();
 $returnValue = $proceed();
 if ($returnValue) {
 $this->postProductToFacebook();
 }
 return $returnValue;
 }
 }
  15. JoshuaWarren.com #MM15NY CustomerRepositoryInterface.php 
 namespace Magento\Customer\Api;
 /**
 * Customer CRUD

    interface.
 */
 interface CustomerRepositoryInterface
 {
 /**
 * Create customer.
 *
 * @api
 * @param \Magento\Customer\Api\Data\CustomerInterface $customer
 * @param string $passwordHash
 * @return \Magento\Customer\Api\Data\CustomerInterface
 * @throws \Magento\Framework\Exception\InputException If bad input is provided
 * @throws \Magento\Framework\Exception\State\InputMismatchException If the provided email is already used
 * @throws \Magento\Framework\Exception\LocalizedException
 */
 public function save(\Magento\Customer\Api\Data\CustomerInterface $customer, $passwordHash = null);
  16. JoshuaWarren.com #MM15NY CustomerRepositoryInterface.php /**
 * Retrieve customer.
 *
 * @api


    * @param string $email
 * @param int|null $websiteId
 * @return \Magento\Customer\Api\Data\CustomerInterface
 * @throws \Magento\Framework\Exception\NoSuchEntityException If customer with the specified email does not exist.
 * @throws \Magento\Framework\Exception\LocalizedException
 */
 public function get($email, $websiteId = null);
 /**
 * Retrieve customer.
 *
 * @api
 * @param int $customerId
 * @return \Magento\Customer\Api\Data\CustomerInterface
 * @throws \Magento\Framework\Exception\NoSuchEntityException If customer with the specified ID does not exist.
 * @throws \Magento\Framework\Exception\LocalizedException
 */
 public function getById($customerId);

  17. JoshuaWarren.com #MM15NY 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" ] ] } }
  18. JoshuaWarren.com Items in the 4 subdirectories apply only to that

    area - i.e., adminhtml only applies to the Magento backend #MM15NY
  19. JoshuaWarren.com #MM15NY Block/System/Config/Form/Field/Locations.php namespace Magento\SampleShippingProvider\Block\System\Config\Form\Field;
 use Magento\Config\Block\System\Config\Form\Field\FieldArray\AbstractFieldArray;
 /**
 * 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();
 }
 }
  20. JoshuaWarren.com #MM15NY Model/Type/Plugin/Onepage.php [1/2] namespace Magento\SampleShippingProvider\Model\Type\Plugin;
 use Magento\Checkout\Model\Type\Onepage as CheckoutOnePage;


    use Magento\SampleShippingProvider\Model\Carrier;
 /**
 * 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;
 }

  21. JoshuaWarren.com #MM15NY 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;
 }
 }
  22. JoshuaWarren.com #MM15NY Model/Carrier.php namespace Magento\SampleShippingProvider\Model;
 use Psr\Log\LoggerInterface;
 use Magento\Framework\App\Config\ScopeConfigInterface;
 use

    Magento\Store\Model\ScopeInterface;
 use Magento\Shipping\Model\Carrier\AbstractCarrier;
 use Magento\Shipping\Model\Carrier\CarrierInterface;
 use Magento\Shipping\Model\Config;
 use Magento\Shipping\Model\Rate\ResultFactory;
 use Magento\Quote\Model\Quote\Address\RateResult\MethodFactory;
 use Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory;
 /**
 * 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 

  23. JoshuaWarren.com #MM15NY 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>Magento\Config\Model\Config\Source\Yesno</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>
 […]
  24. JoshuaWarren.com #MM15NY 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" ] ] } }
  25. 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 #MM15NY
  26. JoshuaWarren.com As an in-house developer for a merchant… Learning Magento

    2 Determine when your business is likely to migrate to Magento 2 Start your Magento 2 migration schedule with 2-4 weeks of time dedicated to learning Magento 2 Learn the patterns before you start! #MM15NY
  27. 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 #MM15NY
  28. 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! #MM15NY