30
Magento 2 - hands on Andra lungu @iamspringerin

Magento 2 - hands on MeetMagento Romania 2016

Embed Size (px)

Citation preview

Page 1: Magento 2 -  hands on MeetMagento Romania 2016

Magento 2 - hands on

Andra lungu @iamspringerin

Page 2: Magento 2 -  hands on MeetMagento Romania 2016

Dependency InjectionPlugins

Service Contracts

Composer

ProxiesFactories

Ui Components

knockout&Require

Andra lungu @iamspringerin

http://tinyurl.com/m2mmro-links

Extension Attributes

Page 3: Magento 2 -  hands on MeetMagento Romania 2016

The clients asks: I want to know when a user wants the invoice and in this case we need the company name

Add a checkbox, during the shipping step to be checked in case the user wants the invoice and in

that case the company field becomes required

Page 4: Magento 2 -  hands on MeetMagento Romania 2016

Add a checkbox, during the shipping step to be checked in case the user wants the invoice and in that case the company field becomes visible and required.

Easy task, right?

Estimation on magento 1 vs Magento 2

Andra lungu @iamspringerin

Page 5: Magento 2 -  hands on MeetMagento Romania 2016

Before we get started

Requirements :● composer create-project

--repository-url=https://repo.magento.com/ magento/project-community-edition <installation directory name>

● bin/magento setup:install● bin/magento deploy:mode:set developer● bin/magento cache:disable

Page 6: Magento 2 -  hands on MeetMagento Romania 2016

Where to get started: let’s Create our magento 2 modulehttp://tinyurl.com/m2mmro-start

bitbull-team/meetmagentoro/registration.php<?php

\Magento\Framework\Component\ComponentRegistrar::register( \Magento\Framework\Component\ComponentRegistrar::MODULE, 'Bitbull_MeetMagentoRo', __DIR__);

Magento components, including modules, themes, and language packages, must be registered in the Magento system through the Magento ComponentRegistrar class

Page 7: Magento 2 -  hands on MeetMagento Romania 2016

Where to get started: let’s Create our magento 2 module

bitbull-team/meetmagentoro/composer.json

"name": "bitbull-team/meetmagentoro", "description": "sample magento 2 module starter", "require": { "php": "~5.5.0|~5.6.0|~7.0.0", "magento/magento-composer-installer": "*" },……………………... "autoload": { "files": [ "registration.php" ], "psr-4": { "Bitbull\\MeetMagentoRo\\": "" } }

http://tinyurl.com/m2mmro-start

Page 8: Magento 2 -  hands on MeetMagento Romania 2016

Where to get started: let’s Create our magento 2 modulehttp://tinyurl.com/m2mmro-start

bitbull-team/meetmagentoro/etc/module.xml

<?xml version="1.0"?><config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> <module name="Bitbull_MeetMagentoRo" setup_version="0.1.0"> </module></config>

Page 9: Magento 2 -  hands on MeetMagento Romania 2016

SETUP SCRIPTS

Setup/InstallSchemaSetup/UpgradeSchemaSetup/InstallDataSetup/UpgradeDataSetup/Recurring - Magento_Indexer module checks for new defined indexers and adds them to indexer_state table.Setup/Uninstall

Page 10: Magento 2 -  hands on MeetMagento Romania 2016

SETUP SCRIPTS

bitbull-team/meetmagentoro/Setup/InstallSchema.php

namespace Bitbull\MeetMagentoRo\Setup;

use Magento\Framework\Setup\InstallSchemaInterface;use Magento\Framework\Setup\ModuleContextInterface;use Magento\Framework\Setup\SchemaSetupInterface;

/** * Class InstallSchema * @package Bitbull\MeetMagentoRo\Setup */class InstallSchema implements InstallSchemaInterface{

Page 11: Magento 2 -  hands on MeetMagento Romania 2016

SETUP SCRIPTSbitbull-team/meetmagentoro/Setup/InstallSchema.phppublic function install(SchemaSetupInterface $setup, ModuleContextInterface $context) { $installer = $setup; $installer->startSetup();

$installer->getConnection()->addColumn( $installer->getTable('sales_order'), 'invoice_checkbox', [ 'type' => \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT, 'nullable' => false, 'default' => '0', 'comment' => 'Request invoice' ] );

$setup->endSetup(); }

Page 12: Magento 2 -  hands on MeetMagento Romania 2016

SETUP SCRIPTS

magento/module-catalog/Setup/UpgradeData.php

public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface $context){ $setup->startSetup(); if ($context->getVersion() && version_compare($context->getVersion(), '2.0.1') < 0)

<module name="Magento_Catalog" setup_version="2.0.7">

magento/module-catalog/etc/module.xml

Page 13: Magento 2 -  hands on MeetMagento Romania 2016

SETUP SCRIPTSbin/magento module:enable Bitbull_MeetMagentoRobin/magento setup:upgrade

Expected result:- In the db, inside setup_module ( old core_resource)

# module, schema_version, data_version Bitbull_MeetMagentoRo, 0.1.0, 0.1.0

- Listed in config.php- Listed with bin/magento module:status- And our new column inside sales_order

Page 14: Magento 2 -  hands on MeetMagento Romania 2016

SHow it on the frontend: the easy part?

http://tinyurl.com/m2mmro-coxml

<argument name="jsLayout" xsi:type="array"> <item name="components" xsi:type="array"> <item name="checkout" xsi:type="array"> <item name="children" xsi:type="array"> <item name=" steps" xsi:type="array"> <item name="children" xsi:type="array"> <item name=" shipping-step" xsi:type="array"> <item name="children" xsi:type="array"> <item name=" shippingAddress" xsi:type="array"> <item name="children" xsi:type="array"> <item name=" shipping-address-fieldset" xsi:type="array"> <item name="children" xsi:type="array"> <item name=" invoice-checkbox" xsi:type="array">

bitbull-team/meetmagentoro/view/frontend/layout/checkout_index_index.xml

Page 15: Magento 2 -  hands on MeetMagento Romania 2016

SHow it on the frontend

<item name="invoice-checkbox" xsi:type="array"> <item name="component" xsi:type="string">Magento_Ui/js/form/element/boolean</item> <item name="config" xsi:type="array"> <item name="customScope" xsi:type="string">shippingAddress.custom_attributes</item> <item name="template" xsi:type="string">ui/form/field</item> <item name="elementTmpl" xsi:type="string">Bitbull_MeetMagentoRo/form/element/invoice-check</item> </item> <item name="provider" xsi:type="string">checkoutProvider</item> <item name="dataScope" xsi:type="string">shippingAddress.custom_attributes.invoice-checkbox</item> <item name="description" xsi:type="string">Request Invoice</item> <item name="sortOrder" xsi:type="string">121</item></item><item name="company" xsi:type="array"> <item name="component" xsi:type="string">Bitbull_MeetMagentoRo/js/invoice-input</item> <item name="sortOrder" xsi:type="string">122</item></item>

Page 16: Magento 2 -  hands on MeetMagento Romania 2016

SHow it on the frontend

bitbull-team/meetmagentoro/view/frontend/web/template/form/element/invoice-check.html

<item name="elementTmpl" xsi:type="string">Bitbull_MeetMagentoRo/form/element/invoice-check</item>

<div class="field choice"> <input type="checkbox" class="checkbox" data-bind="checked: value, attr: { id: uid, disabled: disabled, name: inputName }, hasFocus: focused">

<label data-bind="checked: value, attr: { for: uid }"> <span data-bind="text: description"></span> </label></div>

Page 17: Magento 2 -  hands on MeetMagento Romania 2016

SHow it on the frontend

bitbull-team/meetmagentoro/view/frontend/web/js/invoice-input.js

<item name="component" xsi:type="string">Bitbull_MeetMagentoRo/js/invoice-input</item>

define([ 'underscore', 'Magento_Ui/js/form/element/abstract', 'jquery'], function (_, Abstract, $) { "use strict"; return Abstract.extend({ defaults: { visible: false, required: false, listens: { '${ $.provider }:${ $.customScope ? $.customScope + "." : ""}custom_attributes.invoice-checkbox': 'setVisible'

Page 18: Magento 2 -  hands on MeetMagento Romania 2016

SHow it on the frontend

bitbull-team/meetmagentoro/view/frontend/web/js/invoice-input.js

<item name="component" xsi:type="string">Bitbull_MeetMagentoRo/js/invoice-input</item>

setVisible: function () { var visible = this.source.shippingAddress.custom_attributes['invoice-checkbox']; if (visible) { this.validation['required-entry'] = true; } else { this.error(false); this.validation = _.omit(this.validation, 'required-entry'); } this.visible(visible); this.required(visible); return this; }

<item name="dataScope" xsi:type="string">shippingAddress.custom_attributes.invoice-checkbox</item>

Page 19: Magento 2 -  hands on MeetMagento Romania 2016

Send it to the backendbitbull-team/meetmagentoro/view/frontend/requirejs-config.js

var config = {

config:{ mixins: { 'Magento_Checkout/js/action/set-shipping-information': { 'Bitbull_MeetMagentoRo/js/action/set-shipping-information-mixin': true } } }, map: { '*': { 'Bitbull_MeetMagentoRo/js/invoice-input': 'Bitbull_MeetMagentoRo/js/invoice-input' } }}

http://tinyurl.com/m2mmro-requirejs

Page 20: Magento 2 -  hands on MeetMagento Romania 2016

Send it to the backendbitbull-team/meetmagentoro/view/frontend/web/js/action/set-shipping-information-mixin.js

define([ 'jquery', 'mage/utils/wrapper', 'Magento_Checkout/js/model/quote'], function ($, wrapper, quote) { 'use strict'; return function (setShippingInformationAction) {

return wrapper.wrap(setShippingInformationAction, function (originalAction) { var shippingAddress = quote.shippingAddress(); if (shippingAddress['extension_attributes'] === undefined) { shippingAddress['extension_attributes'] = {}; } shippingAddress['extension_attributes']['invoice_checkbox'] = shippingAddress.customAttributes['invoice_checkbox']; // original action Magento_Checkout/js/action/set-shipping-information return originalAction();

Page 21: Magento 2 -  hands on MeetMagento Romania 2016

One step back: module.xmlIf you know that your component’s logic depends on something in another component then you should add it to require in composer.json and <sequence> in module.xml

<module name="Bitbull_MeetMagentoRo" setup_version="0.1.0"> <sequence> <module name="Magento_Checkout"/> <module name="Magento_Ui"/> </sequence> </module>

"require": { "php": "~5.5.0|~5.6.0|~7.0.0", "magento/magento-composer-installer": "*", "magento/module-ui": "100.1.*", "magento/framework": "100.1.*", "magento/module-checkout": "100.1.*" },

Page 22: Magento 2 -  hands on MeetMagento Romania 2016

One step back: module.xml

If you change the component load order using <sequence>, you must regenerate the component list in config.php; otherwise,

the load order does not take effect.

bin/magento module:disable Bitbull_MeetMagentoRobin/magento module:enable Bitbull_MeetMagentoRo

Page 23: Magento 2 -  hands on MeetMagento Romania 2016

What we’ve got so far

I am a truly believer in Murphy's law so ...let’s see it in action

Page 24: Magento 2 -  hands on MeetMagento Romania 2016

Save it inside the order

<?xml version="1.0" encoding="UTF-8"?><config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd"> <event name=" sales_model_service_quote_submit_before"> <observer name="save-checkbox-invoice-order" instance="Bitbull\MeetMagentoRo\Observer\SaveCheckboxInvoiceToOrderObserver"/> </event></config>

bitbull-team/meetmagentoro/etc/events.xml

Page 25: Magento 2 -  hands on MeetMagento Romania 2016

Save it inside the order

/** * @param EventObserver $observer * @return $this */ public function execute(EventObserver $observer) { /** @var \Magento\Sales\Api\Data\OrderInterface $order */ $order = $observer->getOrder(); /** @var \Magento\Quote\Model\Quote $quote */ $quote = $observer->getQuote(); $invoiceCheckbox = $quote->getShippingAddress()->getExtensionAttributes()->getInvoiceCheckbox(); $order->setInvoiceCheckbox($invoiceCheckbox); return $this; }

bitbull-team/meetmagentoro/Observer/SaveCheckboxInvoiceToOrderObserver.php

Page 26: Magento 2 -  hands on MeetMagento Romania 2016

Sorry but is not the end ….

<?xml version="1.0"?><config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <type name="Magento\Sales\Api\OrderRepositoryInterface"> <plugin name="add-invoice-check" type="Bitbull\MeetMagentoRo\Plugin\Sales\Api\OrderRepositoryInterfacePlugin"/> </type></config>

bitbull-team/meetmagentoro/etc/di.xml

Page 27: Magento 2 -  hands on MeetMagento Romania 2016

Sorry but is not the end ….

/** * * @param \Magento\Sales\Api\OrderRepositoryInterface $subject * @param \Magento\Sales\Api\Data\OrderSearchResultInterface $result * @return \Magento\Sales\Api\Data\OrderSearchResultInterface */ public function afterGetList( \Magento\Sales\Api\OrderRepositoryInterface $subject, \Magento\Sales\Api\Data\OrderSearchResultInterface $result ) { foreach ($result->getItems() as $order) { $this->getInvoiceCheckExtensionAttribute($order); } return $result; }

bitbull-team/meetmagentoro/Plugin/Sales/Api/OrderRepositoryInterfacePlugin.php

Page 28: Magento 2 -  hands on MeetMagento Romania 2016

Sorry but is not the end ….

/** * @param \Magento\Sales\Api\Data\OrderInterface $order * @return \Magento\Sales\Api\Data\OrderInterface */ private function getInvoiceCheckExtensionAttribute($order) { /** @var \Magento\Sales\Api\Data\OrderExtensionInterface $extensionAttributes */ $extensionAttributes = $order->getExtensionAttributes();

if ($extensionAttributes && $extensionAttributes->getInvoiceCheckbox()) { return $order; }

if (null === $extensionAttributes) { $extensionAttributes = $this->orderExtensionFactory->create(); }

$extensionAttributes->setInvoiceCheckbox($order->getInvoiceCheckbox()); $order->setExtensionAttributes($extensionAttributes);

return $order; }

bitbull-team/meetmagentoro/Plugin/Sales/Api/OrderRepositoryInterfacePlugin.php

Page 29: Magento 2 -  hands on MeetMagento Romania 2016

THE END

Questions ?

Thank you

Page 30: Magento 2 -  hands on MeetMagento Romania 2016