Date post: | 08-Jan-2017 |
Category: |
Software |
Upload: | igor-minyaylo |
View: | 64 times |
Download: | 1 times |
Applying Code Customizations to
Magento 2
Who am I?
Igor Miniailo
Interactions with Magento2 Code
Extension
UI Model
UI
ModelService
Contracts
Service Contracts
Vendor
Customization
UI Model
Model
Service Contracts
Vendor
Customization Points
Customization points
Admin Configuration
Low Level Linking
High-level configuration (DSLs)events.xml
routes.xml
routes.xml webapi.xml
acl.xml
di.xml
Object B Object C Object A
Object B
config.xml
Store Configuration
Store Configuration
• In admin application: Stores->Configuration• Values stored in Database• Configured in system.xml• Default values in config.xml
High Level Configuration
Routing
High-level Configuration
Event Manager
events.xml
routes.xml
Application subsystems
AreaApplication
EntryPoint
Cron App
Web App
WebAPI
Admin
FrontendMedia App
Low Level linking
1. Composability2. Modularity
Composability
Composability
Split your code to lots of small chunks and then compose them to
build your application
Dependency InjectionDependencies are not located within object but are provided to that object by environment
namespace Magento\Framework\Event;class Manager implements ManagerInterface{
public function __construct(Invoker $invoker,Config $eventConfig,$prefix = '') {$this->_invoker = $invoker;$this->_eventConfig = $eventConfig;$this->_prefix = $prefix;}// some other code
}
Unit Tests
class ManagerTest extends \PHPUnit_Framework_TestCase{ protected function setUp() { $this->_invoker = $this->getMock('Magento\Framework\Event\Invoker'); $this->_eventConfigMock = $this->getMock('Magento\Framework\Event\Config'); $this->_eventManager = new \Magento\Framework\Event\Manager(
$this->_invoker,$this->_eventConfigMock
); }}
SOLID
1. Single responsibility – Lots of small objects
2. Open Closed - Each object has multiple extension points
3. Liskov Substitution – Polymorphism for composability
4. Interface Segregation – Granularity
5. Dependency Inversion – Decoupling. In particular, any caller of an interface depends only on the interface, even if a separate module implements it.
Modularity
SOLId
Module BModule A
Implementation
Module B
Module A Implementation
Interface
Module C
Implementation
Module AB
Module AC
Impl
Impl
Coupled
Decoupled
Modules Definition
Modules serve as named containers for domain object classes that are highly cohesive with one another.The goal should be low coupling between the classes that are in different Modules
Simple rules for Module design
• Ensuring that Modules are largely independent of others has the same benefit as loosely coupled classes. This will make it easier to maintain and refactor code inside the module.
• Do strive for acyclic dependencies on Modules where coupling is necessary. Just unidirection
Service Contracts
And Compatible Customizations
Extensions Compatibility Challenges
Interfaces may be changed in a new version Extensions may depend on optional modules which is turned off Extensions may depend on undocumented behavior
How to ensure that two extensions will be compatible in a new version?
Challenges for Developer
How to understand what functionality of the extension is stable and what is not?
How to implement extension in the way that it will keep backward compatibility but can evolve?
Stable APIs
Backward Compatible: Classes or Interfaces are not removed Methods of the classes keeps signature between versions Interfaces neither changes existing methods nor add new ones
Explicit Interfaces No generic data types as “mixed”, “object” or “array”
Few ways to make promises in Magento 2
Semantic Versioning of the modules makes dependencies between modules explicit
{ "name": "magento/module-catalog-inventory", "require": { "magento/module-customer": "0.74.0-beta2" }, "type": "magento2-module"}
/** * @api */interface AuthorizationInterface{ /** * Check current user permission on resource and privilege * * @param string $resource * @param string $privilege * @return boolean */ public function isAllowed($resource, $privilege = null);}
@api annotation identifies subset of the methods with the stable APIs
Enforced by tools and static tests
http://alankent.me/2015/10/02/magento-2-version-numbering-update/
MAGENTO 2 VERSION NUMBERING
Magento 1.x Domain Level API
Model is an entry point to the Module Interface implicitly defined via the
database schema No single place for the business rules
They can be in: Controllers Models Helpers Templates
Model
Resource Model
ClientgetData()
Repositories
Service Contracts
Models
Resource Models/Entity
Manager
Web API clients
M2 Module
Blocks TemplatesControllers
Other M2 Modules
Services
Data Objects
Service Contracts
Domain Level API
Single way to define API for the business feature Defines strong interface Single place to implement business rules All interactions with the module are safe to
go through the contracts: same behavior guaranteed
Repositories
Service Contracts
Models
Resource Models/Entity
Manager
M2 Module
Blocks TemplatesControllers
Services
Data Objects
Service Contracts Interfaces
Service Contracts
Service Interfaces Data Interface
Data interfaces Defines data structures, used as input and
output types of the business operations Examples: Customer, Product, Region,
Currency, etc.
Service interfaces Defines business operations Examples: load, delete, save, change
password, etc.
They are just PHP Interfaces
More on Data Interfaces
Has just setters and getters to describe a data
Reusable across different Service interfaces
Encapsulates all the data needed to process service request
Can be Serialized Annotations are used to extract the data
More on Service Interfaces
Defines public operations supported by the module
Methods are independent and stateless. Invocation of one method should not
affect the result of another
Methods combined in interface by cohesion principle
Annotated with types information
Classes Implementing Data Interfaces
It can be Model (NOT Recommended): All the setters and getters should be
declared explicitly No magic methods
It can be Any PHP class: Implements data interface and any
other methods It can be Data Object:
Implements just methods from the data interface
Models
Data Objects
Data Interfaces
Implementation of Service Interfaces
Resource Models (legacy, not recommended): Used for persistence operations Implements load/save/delete
methods and accept Data Interface as an input
Entity Manager: Used for persistence operations ORM implementation
Services: Implements operations and business
rules around them
Service Interfaces
Resource Models/EntityM
anagerServices
Use Service Contracts
Define dependency on service interface in the constructorclass CreateCustomer extends \Magento\Customer\Controller\Account{ public function __construct( AccountManagementInterface $accountManagement ) { $this->accountManagement = $accountManagement; }
public function execute() { $customer = $this->getRequest()->getParam('customer'); $password = $this->getRequest()->getParam('password'); $redirectUrl = $this->getRequest()->getParam('redirect_url'); $customer = $this->accountManagement ->createAccount($customer, $password, $redirectUrl); … }}
Re-Implement Service Contracts
Define a preference in DI: it will point on a new implementation All the constructors will be injected with a new implementation
<preference for="Magento\Customer\Api\AccountManagementInterface" type="SomeVendor\NewExtension\Model\AccountManagement" />
<preference for="Magento\Customer\Api\Data\RegionInterface" type="SomeVendor\NewExtension\Model\Data\Region" />
Customize Service Contracts
Plugins is a way to add new behavior each time Service Interface implementation is invoked
/** * Plugin after create customer that updates any newsletter subscription that may have existed. * * @param CustomerRepositoryInterface $subject * @param CustomerInterface $customer * @return CustomerInterface */public function afterSave(CustomerRepositoryInterface $subject, CustomerInterface $customer){ $this->subscriberFactory->create()->updateSubscription($customer->getId()); return $customer;}
Extend Data Interfaces
Extension Attributes is a way to Extend Data Interfaces from third-party module
Added via xml configuration, generated as an object
Review fields
Catalog Inventory fields
Rating and Reviews Module Catalog
Inventory Module
Product Data Interface
Product fields
Generated Extension Attributes
<extension_attributes for="Magento\Catalog\Api\Data\ProductInterface"> <attribute code="bundle_product_options" type="Magento\Bundle\Api\Data\OptionInterface[]" /></extension_attributes>
interface ProductExtensionInterface extends \Magento\Framework\Api\ExtensionAttributesInterface{ /** * @return \Magento\Bundle\Api\Data\OptionInterface[] */ public function getBundleProductOptions();
/** * @param \Magento\Bundle\Api\Data\OptionInterface[] $bundleProductOptions * @return $this */ public function setBundleProductOptions($bundleProductOptions);...}
Summary
Magento 2.x gives stronger promises on public APIs
Service Contracts are the way to define API for the Business features Service Contracts should be the single entry point to functionality of the
module Customizable via dependency injection, plugins and extension attributes
Customizations become available for all the clients of Service Contracts