Upload
andra-elena-lungu
View
623
Download
0
Embed Size (px)
Citation preview
Magento 2 - hands on
Andra lungu @iamspringerin
Dependency InjectionPlugins
Service Contracts
Composer
ProxiesFactories
Ui Components
knockout&Require
Andra lungu @iamspringerin
http://tinyurl.com/m2mmro-links
Extension Attributes
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
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
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
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
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
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>
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
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{
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(); }
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
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
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
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>
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>
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'
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>
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
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();
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.*" },
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
What we’ve got so far
I am a truly believer in Murphy's law so ...let’s see it in action
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
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
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
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
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
THE END
Questions ?
Thank you