Magento 2 module development
An introduction
Joke Puts - @jokeputs
PHP developer at PHPro
What is Magento?
Lets get that question out of the way
A commerce platform
Not just a framework
composer create-project symfony/framework-standard-edition
composer create-project magento/project-community-edition
It’s open source!
The community edition that is
https://github.com/magento/magento2
What's underneath the hood?
Well… a bit of everything
What’s this “module” thing?
An extension, a plugin, … a set of files that makes a feature
What can I do with it?
§Create a composer package
§Create customizations for your commerce platform
§Sell them on the Magento Marketplace
Edition 1-9 extensions
10-30
extensions
31-50
extensions
50+ extensions
Community 10% 53% 26% 11%
Enterprise 9% 32% 27% 32%
Setting it up
Not even a “Hello world”
Adding a customization to your installation?
Start in the app/code directory
Creating a reusable feature?
Create a composer package
§etc/module.xml
§registration.php
§composer.json
https://github.com/jokeputs/mage2-module-setup
registration.php
<?php
MagentoFrameworkComponentComponentRegistrar:
:register(
MagentoFrameworkComponentComponentRegistr
ar::MODULE,
'Vendor_Module',
__DIR__
);
etc/module.xml
<?xml version="1.0" ?>
<config>
<module
name="Vendor_Module"
setup_version="1.0.0" />
</config>
composer.json
{
"name": "vendor/module",
"type": "magento2-module",
"version": "1.0.0",
"require": {
"php": "~7.0.0|~7.1.0",
"magento/framework": "100.1.*"
},
But wait... there’s more!
Or at least there should be
Make this guy your friend!
https://github.com/phpro/grumphp
grumphp.yml
phpcs:
standard: "ruleset.xml"
show_warnings: false
ignore_patterns:
- "vendor"
- "Test/Unit"
triggered_by: [php]
grumphp.yml
triggered_by: [php]
phpunit:
metadata:
priority: 100
grumphp.yml
git_blacklist:
keywords:
- "die("
- "var_dump("
- "exit;"
- "console.log("
triggered_by: [php,js]
Letting Magento know what’s up
Registering your module
bin/magento setup:upgrade
Lets go a little deeper
We only dipped our toe in the water
Model-View-Control pattern
§ Block
§ Controller
§ Model
§ Setup
§ etc
§ frontend
§ routes.xml
§ adminhtml
§ routes.xml
§ view
§ frontend
§ adminhtml
… But it doesn’t do what I want
Change the “core”
Adapting the core
§Dependency injection
§Observers
§Plugins
Dependency injection
§DI via constructor
§Api: interfaces for a module
§etc/di.xml, etc/frontend/di.xml, etc/adminhtml/di.xml
§Class preferences
§Constructor arguments
DI: Class preferences
<preference
for="MagentoCustomerApiAddressRepositoryInter
face"
type="MagentoCustomerModelResourceModelAddre
ssRepository" />
DI: Constructor arguments
<type name="MagentoCustomerModelVisitor">
<arguments>
<argument name="ignoredUserAgents" xsi:type="array">
<item name="google1" xsi:type="string">Googlebot/1.0
(googlebot@googlebot.com http://googlebot.com/)</item>
<item name="google2" xsi:type="string">Mozilla/5.0
(compatible; Googlebot/2.1; +http://www.google.com/bot.html)</item>
<item name="google3" xsi:type="string">Googlebot/2.1
(+http://www.googlebot.com/bot.html)</item>
</argument>
</arguments>
</type>
Events
<event
name="admin_system_config_changed_section_catalo
g">
<observer
name="catalog_update_price_attribute"
instance="MagentoCatalogObserverSwitchPriceAt
tributeScopeOnConfigChange" />
</event>
Plugins
• Modifies behavior of a public method of a class
• Before method
• Runs before the method
• Receives the arguments of the method
• After method
• Runs after completion of the method
• Receives the output of the method
• Around method
• Runs both before and after the method
• Receives the arguments of the method
• Receives a callable, which will give the output of the method
di.xml
<type
name="MagentoEavModelEntityAttributeBackend
AbstractBackend">
<plugin name="attributeValidation"
type="MagentoCatalogPluginModelAttributeBac
kendAttributeValidation"/>
</type>
AttributeValidation.php
public function aroundValidate(AbstractBackend
$subject, Closure $proceed, DataObject $entity)
{
$isAllowedType =
!empty(array_filter(array_map(function
($allowedEntity) use ($entity) {
return $entity instanceof $allowedEntity;
}, $this->allowedEntityTypes)));
...
return $proceed($entity);
}
The one tip…
You know, the one to rule them all
Look at the core
Know it and understand it
Can’t get enough?
I got just the thing for you
Thank you!
https://joind.in/talk/8a633

Introduction to Magento 2 module development - PHP Antwerp Meetup 2017