9. Store Configuration
• In admin application: Stores->Configuration
• Values stored in Database
• Configured in system.xml
• Default values in config.xml
17. Dependency Injection
Dependencies are not located within object but are provided to that object by environment
namespace MagentoFrameworkEvent;
class Manager implements ManagerInterface
{
public function __construct(
Invoker $invoker,
Config $eventConfig,
$prefix = ''
) {
$this->_invoker = $invoker;
$this->_eventConfig = $eventConfig;
$this->_prefix = $prefix;
}
// some other code
}
18. Unit Tests
class ManagerTest extends PHPUnit_Framework_TestCase
{
protected function setUp()
{
$this->_invoker = $this->getMock('MagentoFrameworkEventInvoker');
$this->_eventConfigMock = $this->getMock('MagentoFrameworkEventConfig');
$this->_eventManager = new MagentoFrameworkEventManager(
$this->_invoker,
$this->_eventConfigMock
);
}
}
19. 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.
22. 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
23. 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
25. 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?
26. 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?
27. 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”
28. 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
30. 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
Client
getData()
32. 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
33. 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
34. 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
35. 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
36. 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
37. 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
anager
Services
38. Use Service Contracts
Define dependency on service interface in the constructor
class CreateCustomer extends MagentoCustomerControllerAccount
{
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);
…
}
}
39. 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="MagentoCustomerApiAccountManagementInterface"
type="SomeVendorNewExtensionModelAccountManagement" />
<preference for="MagentoCustomerApiDataRegionInterface"
type="SomeVendorNewExtensionModelDataRegion" />
40. 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;
}
41.
42. 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
43. Generated Extension Attributes
<extension_attributes for="MagentoCatalogApiDataProductInterface">
<attribute
code="bundle_product_options"
type="MagentoBundleApiDataOptionInterface[]" />
</extension_attributes>
interface ProductExtensionInterface extends MagentoFrameworkApiExtensionAttributesInterface
{
/**
* @return MagentoBundleApiDataOptionInterface[]
*/
public function getBundleProductOptions();
/**
* @param MagentoBundleApiDataOptionInterface[] $bundleProductOptions
* @return $this
*/
public function setBundleProductOptions($bundleProductOptions);
...
}
44. 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
Here I will provide a general overview of how 3rd party developers can interact with Magento code. There are 2 general ways to do this: customize Magento behavior and build your own behavior using Magento APIs.
In this first part I will focus on customizing Magento behavior and in second part I will describe how 3rd party developers can build their extensions using Magento APIs.
Let’s see example of extension. Here we have Magento application that stores data in database and represents it in UI. And
Service is stateless by design: it does not rely on the result of the previous invocations of the service methods. It allows to use services in distributed environment. Separation of the Contracts on Service and Data Interfaces outlines stateless design of the service: input data is constructed, then it is passed to the service method. Besides, it makes it easy to map the service interface to corresponding operations on rest and soap
----- Meeting Notes (4/7/15 16:01) -----
Fix Useful links
Combine summary
New slide for references