PRESENTED BY
JOSHUA
WARREN
PRESENTED AT
PHPWORLD
2015
Magento 2
DEPENDENCY
INJECTION,
INTERCEPTORS
AND YOU
JoshuaWarren.com #phpworld
JoshuaWarren.com
Magento 2 officially released
yesterday!
#phpworld
JoshuaWarren.com
100 slides in ~45 minutes
lots of code
focus on the concepts,
download the slides later
#phpworld
MY
EXPERIENCE
JoshuaWarren.com
My Experience
PHP Developer Since 1999
Founded Creatuity in 2008
Focused on the Magento platform
#phpworld
JoshuaWarren.com
early adopter of both
Magento 1 and Magento 2
#phpworld
JoshuaWarren.com
Frequent Magento presenter
#phpworld
JoshuaWarren.com
Led the Creatuity team in
building 3 Magento 2
extensions (more on the way!)
#phpworld
JoshuaWarren.com
Already migrating a few
merchants from Magento 1 to
Magento 2
#phpworld
JoshuaWarren.com
Wrote Writing the book on
Magento 2
#phpworld
JoshuaWarren.com
Not a Magento employee, but
working closely with the
development, documentation &
product teams on Magento 2
#phpworld
JoshuaWarren.com
A quick note for any Magento 1
developers in the audience…
#phpworld
JoshuaWarren.com #phpworld
JoshuaWarren.com
…for PHP developers new to
Magento.
#phpworld
JoshuaWarren.com
PHP developers are learning
Magento 2 faster than many
Magento 1 developers.
#phpworld
JoshuaWarren.com
Approach Magento 2 with a
desire to learn and understand
the underlying patterns.
#phpworld
JoshuaWarren.com
Don’t approach Magento 2 with
the thought “how do I make my
Magento 1 code work here”
#phpworld
JoshuaWarren.com #phpworld
JoshuaWarren.com
Shoshin is a Zen concept
meaning “beginner’s mind”
#phpworld
JoshuaWarren.com
An attitude of openness, eagerness
and lack of preconceptions.
#phpworld
JoshuaWarren.com
No matter your level of Magento 1
experience, approach Magento 2
with a beginner’s mind
#phpworld
JoshuaWarren.com
With that mind, let’s dive into
Magento 2…
#phpworld
MAGENTO 2
github.com/magento/magento2
JoshuaWarren.com
Technologies
#phpworld
JoshuaWarren.com #phpworld
Composer
composer create-project magento/product-community-edition --
stability="beta" <installation directory name>
JoshuaWarren.com
Each Magento 2 module is a
separate Composer package
#phpworld
JoshuaWarren.com
PSR-0 thru PSR-4
#phpworld
JoshuaWarren.com
Testing built in from the start.
phpunit, selenium, JMeter,
Jasmine
#phpworld
JoshuaWarren.com
HTML5, CSS3, LESS CSS
Preprocessor, JQuery,
RequireJS
#phpworld
JoshuaWarren.com
Components from Zend
Framework 1, Zend Framework
2, Symfony
#phpworld
JoshuaWarren.com
Technical Architecture
#phpworld
JoshuaWarren.com
Presentation Layer, Service
Layer, Domain Layer,
Persistence Layer
#phpworld
JoshuaWarren.com #phpworld
JoshuaWarren.com
Presentation Layer - views,
literally and figuratively
#phpworld
JoshuaWarren.com
Service Layer - an
intermediary between the
presentation and model layers
#phpworld
JoshuaWarren.com
Service layer provides a stable,
backwards-compatible
interface and forms the
foundation for dependency
injection.
#phpworld
JoshuaWarren.com
Domain layer - business logic,
including models. Contains
the implementation of service
contracts.
#phpworld
JoshuaWarren.com
Persistence Layer - resource
models that perform CRUD
operations on database tables.
#phpworld
JoshuaWarren.com
Some models use a single table,
others continue to use the
Entity-Attribute-Value design
pattern used in Magento 1.
#phpworld
JoshuaWarren.com
Design Patterns
#phpworld
JoshuaWarren.com
Loose Coupling
#phpworld
JoshuaWarren.com
Dependency Injection
#phpworld
JoshuaWarren.com
Service Contracts
#phpworld
JoshuaWarren.com
Interceptors
#phpworld
JoshuaWarren.com
Semantic Versioning
#phpworld
JoshuaWarren.com
Start your Magento 2 journey
learning the basics of these
design patterns
#phpworld
JoshuaWarren.com
We are going to take a closer
look at two patterns today:
dependency injection and
interceptors
#phpworld
DEPENDENCY
INJECTION
Sorry - no cool photo here, because I don’t like needles…
JoshuaWarren.com
DI is exactly what it sounds like -
injecting dependencies into the
objects that need them.
#phpworld
JoshuaWarren.com
It sounds complicated, but it’s not.
#phpworld
JoshuaWarren.com
Hollywood Principle: “Don’t call
us, we’ll call you”
#phpworld
JoshuaWarren.com
With DI, instead of building an
object in your class, it’s passed in
via your constructor.
#phpworld
JoshuaWarren.com
DI is designed to reduce
dependencies and promote loose
coupling
#phpworld
JoshuaWarren.com
DI makes unit testing much easier
#phpworld
JoshuaWarren.com
DI allows for mocking - replacing
things like the MySQL adapter
with a mock object during testing
#phpworld
JoshuaWarren.com
Magento 2 uses the Constructor
Injection pattern of DI
#phpworld
JoshuaWarren.com
This replaces the usage of the
Mage class from Magento 1.
#phpworld
JoshuaWarren.com
DI in Magento 2 is Automatic
Dependency Injection
#phpworld
JoshuaWarren.com
Objects do not need to locate the
object or value in which it
depends - it’s automatic.
#phpworld
JoshuaWarren.com
Magento’s object manager uses
PHP’s reflection features to
automatically instantiate needed
objects
#phpworld
JoshuaWarren.com
DI in Magento 2 is handled via XML
files
#phpworld
JoshuaWarren.com #phpworld
di.xml
<config xmlns:xsi=“[…]” xsi:noNamespaceSchemaLocation=“[…]”>

<virtualType name="MagentoSamplePaymentProviderBlockFormPayinstore"
type="MagentoPaymentBlockForm" shared="false">
<arguments>

<argument name="data" xsi:type="array">

<item name="template" xsi:type=“string">
Magento_SamplePaymentProvider::form/payinstore.phtml
</item>

</argument>

</arguments>

</virtualType>

</config>
JoshuaWarren.com
I highly recommend Alan Storm’s
article “Magento 2’s Automatic
Dependency Injection”
#phpworld
JoshuaWarren.com #phpworld
Without Dependency Injection
public function getFormattedPrice($sku)

{

$db = new DBHandler;

$row = $db->query('SELECT price FROM products WHERE sku = ?', $sku);

$formatter = new PriceFormatter;

return $formatter->asDollars($row['price']);

}
JoshuaWarren.com #phpworld
With Dependency Injection
public function getFormattedPrice($sku, $db, $formatter)

{

$row = $db->query('SELECT price FROM products WHERE sku = ?', $sku);

return $formatter->asDollars($row['price']);

}
JoshuaWarren.com
DI simplifies testing,
maintenance and readability
#phpworld
JoshuaWarren.com
DI.XML is also where plugins
following our next pattern to
discuss are declared.
#phpworld
INTERCEPTORS
JoshuaWarren.com
Plugin system based on the
interceptor pattern
#phpworld
JoshuaWarren.com
Calls to almost any module
can be intercepted and
altered
#phpworld
JoshuaWarren.com
Vast improvement over the
rewrite pattern in Magento 1 -
no more rewrite conflicts
#phpworld
JoshuaWarren.com #phpworld
di.xml
<config>

<type name="{ObservedType}">

<plugin name="{pluginName}" type="{PluginClassName}" sortOrder="1" disabled="false"/>

</type>

</config>
JoshuaWarren.com
Sort order defines order if
multiple plugins intercept the
same item
#phpworld
JoshuaWarren.com
Possible to intercept before,
after and around a function
#phpworld
JoshuaWarren.com #phpworld
‘Before’ Interceptor
class Plugin

{

public function beforeSetName(MagentoCatalogModelProduct $subject,
$name)

{

return array('(' . $name . ')');

}

}
JoshuaWarren.com #phpworld
‘After’ Interceptor
class Plugin

{

public function afterGetName(MagentoCatalogModelProduct $subject, $result)

{

return '|' . $result . '|';

}

}
JoshuaWarren.com #phpworld
‘Around’ Interceptor
class Plugin

{

public function aroundSave(MagentoCatalogModelProduct $subject, Closure $proceed)

{

$this->doSomethingBeforeProductIsSaved();

$returnValue = $proceed();

if ($returnValue) {

$this->postProductToFacebook();

}

return $returnValue;

}

}
JoshuaWarren.com
Check out the magento 2
sample modules repo for a
module that demonstrates
interception
#phpworld
JoshuaWarren.com #phpworld
DI.xml
<type name="MagentoSampleInterceptionModelInterceptedChildBefore">

<plugin name="Magento_SampleInterception::demoPluginBefore"
type="MagentoSampleInterceptionPluginPluginBefore" />

</type>

<type name="MagentoSampleInterceptionModelInterceptedChildAfter">

<plugin name="Magento_SampleInterception::demoPluginAfter"
type="MagentoSampleInterceptionPluginPluginAfter" />

</type>

<type name="MagentoSampleInterceptionModelInterceptedChildAround">

<plugin name="Magento_SampleInterception::demoPluginAround"
type="MagentoSampleInterceptionPluginPluginAround" />

</type>

<type name="MagentoSampleInterceptionModelInterceptedChildInherit">

<plugin name="Magento_SampleInterception::demoPluginInheritance"
type="MagentoSampleInterceptionPluginParentPlugin" />

</type>

JoshuaWarren.com #phpworld
Plugin/PluginBefore.php
public function beforeBaseMethodUppercase(ChildBefore $subject, $interceptedInput)

{

return ["(before) $interceptedInput (/before)"];

}
JoshuaWarren.com #phpworld
Plugin/PluginAfter.php
public function afterBaseMethodUppercase(ChildAfter $subject, $interceptedOutput)

{

return "(after) $interceptedOutput (/after)";

}
JoshuaWarren.com #phpworld
Plugin/PluginAround.php
public function aroundBaseMethodUppercase(ChildAround $subject, Closure $proceed,
$interceptedInput)

{

$argument = "(around: before base method) $interceptedInput (/around: before base method)";

$result = $proceed($argument);

return "(around: after base method) $result (/around: after base method)";

}
JoshuaWarren.com
Interceptors are a
replacement for rewrites
#phpworld
JoshuaWarren.com
Interceptors supplement, but
not replace, events and
observers
#phpworld
JoshuaWarren.com
Sort order conflicts
#phpworld
JoshuaWarren.com
Please don’t define a sort
order of 1 unless you really
need it
#phpworld
JoshuaWarren.com
We’re all waiting to see what
happens with sort order
conflicts in real world usage
#phpworld
JoshuaWarren.com
Ideally, the largest extension
authors will coordinate their
sort order for common
conflicts
#phpworld
JoshuaWarren.com
If not, when installing
extensions, developers will
need to modify their sort
order to resolve conflicts.
#phpworld
LEARNING
MORE
Don’t end up like this guy ->
JoshuaWarren.com
devdocs.magento.com - ‘How Do I?’
magento.stackexchange.com/questions/tagged/
magento2
https://github.com/magento/magento2-samples
#phpworld
JoshuaWarren.com
Read through the sample modules.
#phpworld
JoshuaWarren.com
The sample modules don’t currently
work (see issue #42)
#phpworld
JoshuaWarren.com
In order to run the sample modules,
you will have to add a
registration.php file.
#phpworld
JoshuaWarren.com
Otherwise, they’re still a great
resource to see dependency injection
and interceptors in action.
#phpworld
Dev Docs Team
Team of hard-working technical writers (not developers)
Writing documentation for a system that has yet to be used ‘in the
wild’
Very eager for feedback and input - they don’t know what
documentation you need
Very open to pull requests of documentation or just open an issue
on Github with feedback + requests
JoshuaWarren.com #phpworld
Dev Docs Team
JoshuaWarren.com #phpworld
JoshuaWarren.com
Magento U Courses
Fundamentals of Magento 2 Development
Front-end Course
#phpworld
JoshuaWarren.com
AlanStorm.com
AlanKent.me
CoderOnCode.com
github.com/creatuity/LearningMagento2
#phpworld
JoshuaWarren.com
Upcoming events:
Magento Imagine - April 2016
#phpworld
JoshuaWarren.com
As a freelancer…
Learning Magento 2
Set aside time in your week to learn the design patterns Magento 2 uses
Work through the sample code the Magento 2 team has provided
Begin experimenting with developing with Magento 2
Do not try to learn ‘on the job’ - be careful accepting M2 work before you’re
ready
#phpworld
JoshuaWarren.com
As an in-house developer for a merchant…
Learning Magento 2
Determine when your business is likely to migrate to Magento 2
First 2-4 weeks of your Magento 2 migration schedule should be learning Magento 2
Learn the patterns before you start!
#phpworld
JoshuaWarren.com
As an agency or industry partner…
Learning Magento 2
Create a tiger team of developers focused on Magento 2
Allow those developers time in the day to learn Magento 2
Those developers should implement your first Magento 2 projects
That team then helps the rest of your team through the learning curve
#phpworld
JoshuaWarren.com
When do I need to be Magento 2 ready?
Learning Magento 2
Magento 2 will be released late enough in the year that most merchants
won’t begin using it immediately.
Merchants will also wait until their mission-critical extensions are
available on Magento 2.
Start learning it now - but don’t panic!
#phpworld
JoshuaWarren.com
Programming With Magento 2 coming
to amazon.com & phparch.com
#phpworld
Keep in
Touch!
@JoshuaSWarren
JoshuaWarren.com
Mage2DevBook.com
joind.in/14790
JoshuaWarren.com #phpworld

Magento 2 Dependency Injection, Interceptors, and You - php[world] 2015