SlideShare a Scribd company logo
1 of 47
Download to read offline
Events: The Object Oriented
Hook System
Nida Ismail Shah
Developer at
d.o & twitter: @nidaismailshah
Acquia
nidashah.com/blog
Gulmarg, Kashmir
Overview
Kolahoi Peak, Kashmir
Overview
The Symfony Event Dispatcher component.
Installation and usage
Creating and dispatching an event
Subscribing/Listening to events
Events in Drupal 8
Creating Events.
Subscribing to Events
Intent/Purpose
Dal Lake, Kashmir
“ The idea is to be able to run random code at given places in the
engine. This random code should then be able to do whatever needed to
enhance the functionality. The places where code can be executed are
called “hooks” and are defined by a fixed interface.
~ Dries Buytaert.
“ The Event Dispatcher component provides
tools that allow your application components to
communicate with each other by dispatching
events and listening to them.
“ an event is an action or an occurrence
recognised by software that may be handled
by software.
event?
Extensibility
Modularity
Maintainability
Developer Experience
Background Tulian Lake,
Pahalgam, Kashmir
Extensibility
Hooks
Plugins
Mulitple instances
Admin forms
Configuration
Tagged Services
Simple Extensions
Events
Alter something?
React to something?
Symfony Event Dispatcher
Component
Installation and usage
Installing the symfony event
dispatcher component
Text
Text
Use the official Git repository
( )https://github.com/symfony/event-dispatcher
composer require symfony/event-dispatcher
Using version ^3.2 for symfony/event-dispatcher
./composer.json has been created
Loading composer repositories with package information
Updating dependencies (including require-dev)
- Installing symfony/event-dispatcher (v3.2.6)
Loading from cache
symfony/event-dispatcher suggests installing symfony/dependency-injection ()
symfony/event-dispatcher suggests installing symfony/http-kernel ()
Writing lock file
Generating autoload files
Using the symfony event dispatcher
component
1. Event - representing the event or the state of the application.
2. Dispatcher - to notify the subscribers or listeners about the occurrence of the
event.
3. Subscriber/Listener - to extend the application once the event has occurred.
Pub-Sub pattern
The pub sub exemplifies the
proper decoupling of
components of an application.
Publishers publish the messages
into classes without knowledge
of which subscribers would be
interested in the message.
Subscribers express interest in
one or more classes and only
receive messages that are of
interest, without knowledge of
which publishers.
Mediator pattern
Define an object that
encapsulates how a set of
objects interact.
Mediator promotes loose
coupling by keeping objects
from referring to each other
explicitly, and it lets you vary
their interaction independently.
Design an intermediary to
decouple many peers.
Workflow
Workflow
A listener (PHP object) tells a central dispatcher object that it wants to listen to
the 'xyz' event
At some point, Symfony tells the dispatcher object to dispatch the 'xyz' event,
passing with it an Event object that has access to the Object defining the state
of the application at that point.
The dispatcher notifies (i.e. calls a method on) all listeners of the 'xyz' event,
allowing each of them to make modifications to the State object.
Components
The dispatcher object
The Event object
The subscriber/listener
the dispatcher
// create an EventDispatcher instance.

$dispatcher = new EventDispatcher();


// the order is somehow created or retrieved
// contains the state of our application
// or the information we want expose.

$order = new Order();

// ...


// create the OrderPlacedEvent and dispatch it

$event = new OrderPlacedEvent($order);


// dispatch the event.

$dispatcher->dispatch(OrderPlacedEvent::NAME, $event);

// or $dispatcher->dispatch('order.placed', $event);
the event


/**

* The order.placed event is dispatched each time an order is created

* in the system.

*/

class OrderPlacedEvent extends Event {



const NAME = 'order.placed';


protected $order;


public function __construct(Order $order) {

$this->order = $order;

}


public function getOrder() {

return $this->order;

}

}
the base event
/**
* Event is the base class for classes containing event data.
* This class contains no event data. It is used by events that do not pass
* state information to an event handler when an event is raised.
*/
class Event
{
/**
* @var bool Whether no further event listeners should be triggered
*/
private $propagationStopped = false;
/**
* Returns whether further event listeners should be triggered.
*/
public function isPropagationStopped()
{
return $this->propagationStopped;
}
/**
* Stops the propagation of the event to further event listeners.
*/
public function stopPropagation()
{
$this->propagationStopped = true;
}
}
“ The base Event class provided by the Event
Dispatcher component is deliberately sparse to
allow the creation of API specific event objects by
inheritance using OOP. This allows for elegant and
readable code in complex applications.
the subscriber
class StoreSubscriber implements EventSubscriberInterface
 {

public static function getSubscribedEvents()
 {

return array(

KernelEvents::RESPONSE => array(

array('onKernelResponsePre', 10),

array('onKernelResponsePost', -10),

),

OrderPlacedEvent::NAME => 'onStoreOrder',

);

}


public function onKernelResponsePre(FilterResponseEvent $event)
 {
// do something.


}


public function onKernelResponsePost(FilterResponseEvent $event)
 {
// do something.


}




 public function onStoreOrder(OrderPlacedEvent $event)
 {
// do something.


}



}
the listener
class AcmeListener
 {

// ...


public function onFooAction(Event $event)
 {

// ... do something

}

}
// This is very similar to a subscriber class,
// except that the class itself cant tell the dispatcher which events it should listen to.
register listener/subscriber
// create an EventDispatcher instance.

$dispatcher = new EventDispatcher();


$subscriber = new StoreSubscriber();

// Register subscriber

$dispatcher->addSubscriber($subscriber);


// add a listener

$listener = new AcmeListener();

$dispatcher->addListener('acme.foo.action', array($listener, 'onFooAction'));


// create the OrderPlacedEvent and dispatch it

$event = new OrderPlacedEvent($order);


// dispatch the event.

$dispatcher->dispatch(OrderPlacedEvent::NAME, $event);

// or $dispatcher->dispatch(order.placed, $event);
other ways to register
# app/config/services.yml
services:
kernel.listener.your_listener_name:
class: AppBundleEventListenerAcmeExceptionListener
tags:
- { name: kernel.event_listener, event: kernel.exception, method:
onKernelException }
With the use of ContainerAwareEventDispatcher and dependency
injection:
Use the to tag services as event
listeners/subscribers.
Define event subscriber/listener as a service.
Tag them as kernel.event_listener or kernel.event_subscriber.
RegisterListenersPass
subscriber vs listener
Event listeners and Subscribers serve the same purpose and can be used in
an application indistinctly.
Event listeners can be added via service definition and also with
addListener()method.
Event subscribers are added via service definition and by implementing the
getSubscribedEvents() method and also with addSubscriber() method.
Event subscribers are easier to use and reuse.
Event listener is registered specifying the events on which it listens. The
subscriber has a method telling the dispatcher what events it is listening to.
More here: http://nidashah.com/drupal/events-and-listeners.html
more dispatchers
ContainerAwareEventDispatcher
Use services within your events, and subscribers as services
TraceableEventDispatcher
wraps any other event dispatcher and can then be used to determine
which event listeners have been called by the dispatcher
ImmutableEventDispatcher
is a locked or frozen event dispatcher. The dispatcher cannot register
new listeners or subscribers.
ContainerAwareEventDispatcher
The ContainerAwareEventDispatcher is a special Event Dispatcher
implementation which is coupled to the service container that is part of the
DependencyInjection component.
It allows services to be specified as event listeners making the
EventDispatcher extremely powerful.
Services are lazy loaded meaning the services attached as listeners will only
be created if an event is dispatched that requires those listeners.
ContainerAwareEventDispatcher
use SymfonyComponentDependencyInjectionContainerBuilder;
use SymfonyComponentEventDispatcherContainerAwareEventDispatcher;
$container = new ContainerBuilder();
$dispatcher = new ContainerAwareEventDispatcher($container);
// Add the listener and subscriber services
$dispatcher->addListenerService($eventName, array('foo', 'logListener'));
$dispatcher->addSubscriberService(
'kernel.store_subscriber',
'StoreSubscriber'
);
TraceableEventDispatcher
The TraceableEventDispatcher is an event dispatcher that wraps any other
event dispatcher and can then be used to determine which event listeners have
been called by the dispatcher.
// the event dispatcher to debug
$eventDispatcher = ...;
$traceableEventDispatcher = new TraceableEventDispatcher( $eventDispatcher, new Stopwatch()
);
$traceableEventDispatcher->addListener(
'event.the_name',
$eventListener,
$priority
);
// dispatch an event
$traceableEventDispatcher->dispatch('event.the_name', $event);
$calledListeners = $traceableEventDispatcher->getCalledListeners();
$notCalledListeners = $traceableEventDispatcher->getNotCalledListeners();
ImmutableEventDispatcher
The ImmutableEventDispatcher is a locked or frozen event dispatcher. The
dispatcher cannot register new listeners or subscribers.
The ImmutableEventDispatcher takes another event dispatcher with all the
listeners and subscribers. The immutable dispatcher is just a proxy of this
original dispatcher.
Using it
first create a normal dispatcher (EventDispatcher or
ContainerAwareEventDispatcher) and register some listeners or
subscribers
Now, inject that into an ImmutableEventDispatcher
ImmutableEventDispatcher
use SymfonyComponentEventDispatcherEventDispatcher;
use SymfonyComponentEventDispatcherImmutableEventDispatcher;
$dispatcher = new EventDispatcher();
$dispatcher->addListener('foo.action', function ($event) {
// ...
});
// ...
// ...
$immutableDispatcher = new ImmutableEventDispatcher($dispatcher);
Events in Drupal 8
Events are part of the Symfony framework: they allow for different
components of the system to interact and communicate with each
other.
Object oriented way of interaction with core and other modules.
Mediator Pattern
Container Aware dispatcher
Will probably replace hooks in future drupal versions.
Since Drupal is using ContainerAwareEventDispatcher, we always
have the dispatcher object available as a service.
Consequently, Drupal supports the service definition way of adding
event subscribers.
Service definition way of adding event listeners is not supported.
something to note
1. Get the dispatcher object from the service container.
2. Create the event.
3. Dispatch the event.
4. Define a service tagged with event_subscriber in services.yml.
5. Implement the EventSubscriberInterface to write getSubscribedEvents()
method to return what events you want to subscribe to.
Workflow in Drupal
event subscriber class
class ConfigFactory implements ConfigFactoryInterface, EventSubscriberInterface {

static function getSubscribedEvents() {

$events[ConfigEvents::SAVE][] = array('onConfigSave', 255);

$events[ConfigEvents::DELETE][] = array('onConfigDelete', 255);

return $events;

}
}
// services.yml
config.factory:

class: DrupalCoreConfigConfigFactory

tags:

- { name: event_subscriber }

- { name: service_collector, tag: 'config.factory.override', call: addOverride }

arguments: ['@config.storage', '@event_dispatcher', ‘@config.typed']
services:

event_demo.alter_response:

class: Drupalevent_demoEventSubscriberAlterResponse

arguments: [ '@logger.factory' ]

tags:

- { name: event_subscriber }
dispatching the event
$dispatcher = Drupal::service('event_dispatcher');


// or inject as a dependency
$event = new EventDemo($config);


$event = $dispatcher->dispatch(EVENT_NAME, $event);
core registering event subscribers
namespace DrupalCoreDependencyInjectionCompiler;
use SymfonyComponentDependencyInjectionContainerBuilder;
use SymfonyComponentDependencyInjectionCompilerCompilerPassInterface;
/**
* Registers all event subscribers to the event dispatcher.
*/
class RegisterEventSubscribersPass implements CompilerPassInterface {
/**
* {@inheritdoc}
*/
public function process(ContainerBuilder $container) {
if (!$container->hasDefinition('event_dispatcher')) {
return;
}
$definition = $container->getDefinition('event_dispatcher');
$event_subscriber_info = [];
foreach ($container->findTaggedServiceIds('event_subscriber') as $id => $attributes) {
// We must assume that the class value has been correctly filled, even if
// the service is created by a factory.
$class = $container->getDefinition($id)->getClass();
$refClass = new ReflectionClass($class);
$interface = 'SymfonyComponentEventDispatcherEventSubscriberInterface';
if (!$refClass->implementsInterface($interface)) {
throw new InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $id, $interface));
}
// Get all subscribed events.
foreach ($class::getSubscribedEvents() as $event_name => $params) {
if (is_string($params)) {
$priority = 0;
KernelEvents::CONTROLLER, EXCEPTION, REQUEST, RESPONSE,
TERMINATE, VIEW
ConfigEvents::DELETE, IMPORT, SAVE, RENAME ...
EntityTypeEvents::CREATE, UPDATE, DELETE
FieldStorageDefinitionEvents::CREATE, UPDATE, DELETE
ConsoleEvents::COMMAND, EXCEPTION, TERMINATE
MigrateEvents:: MAP_DELETE, MAP_SAVE, POST_IMPORT,
POST_ROLLBACK, POST_ROW_DELETE, POST_ROW_SAVE,
RoutingEvents::ALTER, DYNAMIC, FINISHED
Events in Drupal 8 core
path forward
Writing your own module?
trigger an Event for everything.
Interacting with or alter core?
subscribe to an event (if one is fired).
Hooks … you don't have too many options.
Configuration, Admin forms?
Plugins
Simple Extensions
Tagged services
summary
demo
Questions?
Hazratbal, Kashmir
Join Us for Contribution Sprints
Friday, April 28, 2017
First-Time Sprinter
Workshop
9:00am-12:00pm
Room: 307-308
Mentored Core Sprint
9:00am-12:00pm
Room:301-303
General Sprints
9:00am-6:00pm
Room:309-310
#drupalsprints
WHAT DID
YOU THINK?
Locate this session at the DrupalCon
Baltimore website:
Take the survey!
https://www.surveymonkey.com/r/dr
upalconbaltimore
http://baltimore2017.drupal.org/schedule
THANK YOU!
email: nida@nidashah.com
twitter: @nidaismailshah

More Related Content

What's hot

Design how your objects talk through mocking
Design how your objects talk through mockingDesign how your objects talk through mocking
Design how your objects talk through mockingKonstantin Kudryashov
 
Guard Authentication: Powerful, Beautiful Security
Guard Authentication: Powerful, Beautiful SecurityGuard Authentication: Powerful, Beautiful Security
Guard Authentication: Powerful, Beautiful SecurityRyan Weaver
 
How I started to love design patterns
How I started to love design patternsHow I started to love design patterns
How I started to love design patternsSamuel ROZE
 
Simple Photo Processing and Web Display with Perl
Simple Photo Processing and Web Display with PerlSimple Photo Processing and Web Display with Perl
Simple Photo Processing and Web Display with PerlKent Cowgill
 
Symfony2 - from the trenches
Symfony2 - from the trenchesSymfony2 - from the trenches
Symfony2 - from the trenchesLukas Smith
 
Memory management in Objective C
Memory management in Objective CMemory management in Objective C
Memory management in Objective CNeha Gupta
 
Anton Minashkin Dagger 2 light
Anton Minashkin Dagger 2 lightAnton Minashkin Dagger 2 light
Anton Minashkin Dagger 2 lightMichael Pustovit
 
iOS Memory Management Basics
iOS Memory Management BasicsiOS Memory Management Basics
iOS Memory Management BasicsBilue
 
Data binding в массы! (1.2)
Data binding в массы! (1.2)Data binding в массы! (1.2)
Data binding в массы! (1.2)Yurii Kotov
 
Symfony Messenger (Symfony Live San Francisco)
Symfony Messenger (Symfony Live San Francisco)Symfony Messenger (Symfony Live San Francisco)
Symfony Messenger (Symfony Live San Francisco)Samuel ROZE
 
Cloudstack talk
Cloudstack talkCloudstack talk
Cloudstack talkbodepd
 
MCE^3 - Gregory Kick - Dagger 2
MCE^3 - Gregory Kick - Dagger 2 MCE^3 - Gregory Kick - Dagger 2
MCE^3 - Gregory Kick - Dagger 2 PROIDEA
 

What's hot (20)

Design how your objects talk through mocking
Design how your objects talk through mockingDesign how your objects talk through mocking
Design how your objects talk through mocking
 
Guard Authentication: Powerful, Beautiful Security
Guard Authentication: Powerful, Beautiful SecurityGuard Authentication: Powerful, Beautiful Security
Guard Authentication: Powerful, Beautiful Security
 
Javabean1
Javabean1Javabean1
Javabean1
 
How I started to love design patterns
How I started to love design patternsHow I started to love design patterns
How I started to love design patterns
 
javabeans
javabeansjavabeans
javabeans
 
Drupal 8: Fields reborn
Drupal 8: Fields rebornDrupal 8: Fields reborn
Drupal 8: Fields reborn
 
Simple Photo Processing and Web Display with Perl
Simple Photo Processing and Web Display with PerlSimple Photo Processing and Web Display with Perl
Simple Photo Processing and Web Display with Perl
 
Symfony2 - from the trenches
Symfony2 - from the trenchesSymfony2 - from the trenches
Symfony2 - from the trenches
 
Memory management in Objective C
Memory management in Objective CMemory management in Objective C
Memory management in Objective C
 
Anton Minashkin Dagger 2 light
Anton Minashkin Dagger 2 lightAnton Minashkin Dagger 2 light
Anton Minashkin Dagger 2 light
 
Java beans
Java beansJava beans
Java beans
 
iOS Memory Management Basics
iOS Memory Management BasicsiOS Memory Management Basics
iOS Memory Management Basics
 
Bean Intro
Bean IntroBean Intro
Bean Intro
 
Data binding в массы! (1.2)
Data binding в массы! (1.2)Data binding в массы! (1.2)
Data binding в массы! (1.2)
 
introduction of Java beans
introduction of Java beansintroduction of Java beans
introduction of Java beans
 
iOS Memory Management
iOS Memory ManagementiOS Memory Management
iOS Memory Management
 
Ios - Introduction to memory management
Ios - Introduction to memory managementIos - Introduction to memory management
Ios - Introduction to memory management
 
Symfony Messenger (Symfony Live San Francisco)
Symfony Messenger (Symfony Live San Francisco)Symfony Messenger (Symfony Live San Francisco)
Symfony Messenger (Symfony Live San Francisco)
 
Cloudstack talk
Cloudstack talkCloudstack talk
Cloudstack talk
 
MCE^3 - Gregory Kick - Dagger 2
MCE^3 - Gregory Kick - Dagger 2 MCE^3 - Gregory Kick - Dagger 2
MCE^3 - Gregory Kick - Dagger 2
 

Similar to Events: The Object Oriented Hook System.

PATTERNS06 - The .NET Event Model
PATTERNS06 - The .NET Event ModelPATTERNS06 - The .NET Event Model
PATTERNS06 - The .NET Event ModelMichael Heron
 
D8 dispatcher / subscriber
D8 dispatcher / subscriberD8 dispatcher / subscriber
D8 dispatcher / subscriberjoshirohit100
 
Scala API - Azure Event Hub Integration
Scala API - Azure Event Hub IntegrationScala API - Azure Event Hub Integration
Scala API - Azure Event Hub IntegrationBraja Krishna Das
 
Java gui event
Java gui eventJava gui event
Java gui eventSoftNutx
 
EventBus for Android
EventBus for AndroidEventBus for Android
EventBus for Androidgreenrobot
 
A Deep Dive into Spring Application Events
A Deep Dive into Spring Application EventsA Deep Dive into Spring Application Events
A Deep Dive into Spring Application EventsVMware Tanzu
 
Swiss army knife Spring
Swiss army knife SpringSwiss army knife Spring
Swiss army knife SpringMario Fusco
 
Java Svet - Communication Between Android App Components
Java Svet - Communication Between Android App ComponentsJava Svet - Communication Between Android App Components
Java Svet - Communication Between Android App ComponentsAleksandar Ilić
 
Java Svet - Communication Between Android App Components
Java Svet - Communication Between Android App ComponentsJava Svet - Communication Between Android App Components
Java Svet - Communication Between Android App ComponentsPSTechSerbia
 
Laravel 8 events and listeners with example
Laravel 8 events and listeners with exampleLaravel 8 events and listeners with example
Laravel 8 events and listeners with exampleKaty Slemon
 
Lviv MDDay 2014. Сергій Комлач “Використання accessibility api для доступу до...
Lviv MDDay 2014. Сергій Комлач “Використання accessibility api для доступу до...Lviv MDDay 2014. Сергій Комлач “Використання accessibility api для доступу до...
Lviv MDDay 2014. Сергій Комлач “Використання accessibility api для доступу до...Lviv Startup Club
 
Dependency Injection, Zend Framework and Symfony Container
Dependency Injection, Zend Framework and Symfony ContainerDependency Injection, Zend Framework and Symfony Container
Dependency Injection, Zend Framework and Symfony ContainerDiego Lewin
 
Axon Framework, Exploring CQRS and Event Sourcing Architecture
Axon Framework, Exploring CQRS and Event Sourcing ArchitectureAxon Framework, Exploring CQRS and Event Sourcing Architecture
Axon Framework, Exploring CQRS and Event Sourcing ArchitectureAshutosh Jadhav
 
Explained: Domain events
Explained: Domain eventsExplained: Domain events
Explained: Domain eventsJoão Pires
 
Event and Signal Driven Programming Zendcon 2012
Event and Signal Driven Programming Zendcon 2012Event and Signal Driven Programming Zendcon 2012
Event and Signal Driven Programming Zendcon 2012Elizabeth Smith
 
Unit-3 event handling
Unit-3 event handlingUnit-3 event handling
Unit-3 event handlingAmol Gaikwad
 
Event and signal driven programming
Event and signal driven programmingEvent and signal driven programming
Event and signal driven programmingElizabeth Smith
 
Advance Java Programming(CM5I) Event handling
Advance Java Programming(CM5I) Event handlingAdvance Java Programming(CM5I) Event handling
Advance Java Programming(CM5I) Event handlingPayal Dungarwal
 
Fabric - Realtime stream processing framework
Fabric - Realtime stream processing frameworkFabric - Realtime stream processing framework
Fabric - Realtime stream processing frameworkShashank Gautam
 

Similar to Events: The Object Oriented Hook System. (20)

PATTERNS06 - The .NET Event Model
PATTERNS06 - The .NET Event ModelPATTERNS06 - The .NET Event Model
PATTERNS06 - The .NET Event Model
 
D8 dispatcher / subscriber
D8 dispatcher / subscriberD8 dispatcher / subscriber
D8 dispatcher / subscriber
 
Scala API - Azure Event Hub Integration
Scala API - Azure Event Hub IntegrationScala API - Azure Event Hub Integration
Scala API - Azure Event Hub Integration
 
Java gui event
Java gui eventJava gui event
Java gui event
 
EventBus for Android
EventBus for AndroidEventBus for Android
EventBus for Android
 
A Deep Dive into Spring Application Events
A Deep Dive into Spring Application EventsA Deep Dive into Spring Application Events
A Deep Dive into Spring Application Events
 
Swiss army knife Spring
Swiss army knife SpringSwiss army knife Spring
Swiss army knife Spring
 
Java Svet - Communication Between Android App Components
Java Svet - Communication Between Android App ComponentsJava Svet - Communication Between Android App Components
Java Svet - Communication Between Android App Components
 
Java Svet - Communication Between Android App Components
Java Svet - Communication Between Android App ComponentsJava Svet - Communication Between Android App Components
Java Svet - Communication Between Android App Components
 
Laravel 8 events and listeners with example
Laravel 8 events and listeners with exampleLaravel 8 events and listeners with example
Laravel 8 events and listeners with example
 
Lviv MDDay 2014. Сергій Комлач “Використання accessibility api для доступу до...
Lviv MDDay 2014. Сергій Комлач “Використання accessibility api для доступу до...Lviv MDDay 2014. Сергій Комлач “Використання accessibility api для доступу до...
Lviv MDDay 2014. Сергій Комлач “Використання accessibility api для доступу до...
 
Dependency Injection, Zend Framework and Symfony Container
Dependency Injection, Zend Framework and Symfony ContainerDependency Injection, Zend Framework and Symfony Container
Dependency Injection, Zend Framework and Symfony Container
 
Axon Framework, Exploring CQRS and Event Sourcing Architecture
Axon Framework, Exploring CQRS and Event Sourcing ArchitectureAxon Framework, Exploring CQRS and Event Sourcing Architecture
Axon Framework, Exploring CQRS and Event Sourcing Architecture
 
Explained: Domain events
Explained: Domain eventsExplained: Domain events
Explained: Domain events
 
Event and Signal Driven Programming Zendcon 2012
Event and Signal Driven Programming Zendcon 2012Event and Signal Driven Programming Zendcon 2012
Event and Signal Driven Programming Zendcon 2012
 
Unit-3 event handling
Unit-3 event handlingUnit-3 event handling
Unit-3 event handling
 
pattern v
pattern vpattern v
pattern v
 
Event and signal driven programming
Event and signal driven programmingEvent and signal driven programming
Event and signal driven programming
 
Advance Java Programming(CM5I) Event handling
Advance Java Programming(CM5I) Event handlingAdvance Java Programming(CM5I) Event handling
Advance Java Programming(CM5I) Event handling
 
Fabric - Realtime stream processing framework
Fabric - Realtime stream processing frameworkFabric - Realtime stream processing framework
Fabric - Realtime stream processing framework
 

Recently uploaded

WSO2CON 2024 - Designing Event-Driven Enterprises: Stories of Transformation
WSO2CON 2024 - Designing Event-Driven Enterprises: Stories of TransformationWSO2CON 2024 - Designing Event-Driven Enterprises: Stories of Transformation
WSO2CON 2024 - Designing Event-Driven Enterprises: Stories of TransformationWSO2
 
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...WSO2
 
What Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the SituationWhat Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the SituationJuha-Pekka Tolvanen
 
WSO2CON 2024 - Architecting AI in the Enterprise: APIs and Applications
WSO2CON 2024 - Architecting AI in the Enterprise: APIs and ApplicationsWSO2CON 2024 - Architecting AI in the Enterprise: APIs and Applications
WSO2CON 2024 - Architecting AI in the Enterprise: APIs and ApplicationsWSO2
 
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Bert Jan Schrijver
 
WSO2Con2024 - Software Delivery in Hybrid Environments
WSO2Con2024 - Software Delivery in Hybrid EnvironmentsWSO2Con2024 - Software Delivery in Hybrid Environments
WSO2Con2024 - Software Delivery in Hybrid EnvironmentsWSO2
 
Evolving Data Governance for the Real-time Streaming and AI Era
Evolving Data Governance for the Real-time Streaming and AI EraEvolving Data Governance for the Real-time Streaming and AI Era
Evolving Data Governance for the Real-time Streaming and AI Eraconfluent
 
WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2
 
WSO2Con204 - Hard Rock Presentation - Keynote
WSO2Con204 - Hard Rock Presentation - KeynoteWSO2Con204 - Hard Rock Presentation - Keynote
WSO2Con204 - Hard Rock Presentation - KeynoteWSO2
 
WSO2CON 2024 - Unlocking the Identity: Embracing CIAM 2.0 for a Competitive A...
WSO2CON 2024 - Unlocking the Identity: Embracing CIAM 2.0 for a Competitive A...WSO2CON 2024 - Unlocking the Identity: Embracing CIAM 2.0 for a Competitive A...
WSO2CON 2024 - Unlocking the Identity: Embracing CIAM 2.0 for a Competitive A...WSO2
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024VictoriaMetrics
 
WSO2CON 2024 - How CSI Piemonte Is Apifying the Public Administration
WSO2CON 2024 - How CSI Piemonte Is Apifying the Public AdministrationWSO2CON 2024 - How CSI Piemonte Is Apifying the Public Administration
WSO2CON 2024 - How CSI Piemonte Is Apifying the Public AdministrationWSO2
 
WSO2CON 2024 - Not Just Microservices: Rightsize Your Services!
WSO2CON 2024 - Not Just Microservices: Rightsize Your Services!WSO2CON 2024 - Not Just Microservices: Rightsize Your Services!
WSO2CON 2024 - Not Just Microservices: Rightsize Your Services!WSO2
 
Architecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the pastArchitecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the pastPapp Krisztián
 
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...WSO2
 
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...WSO2
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareJim McKeeth
 
WSO2Con2024 - Organization Management: The Revolution in B2B CIAM
WSO2Con2024 - Organization Management: The Revolution in B2B CIAMWSO2Con2024 - Organization Management: The Revolution in B2B CIAM
WSO2Con2024 - Organization Management: The Revolution in B2B CIAMWSO2
 
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...WSO2
 
Artyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptxArtyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptxAnnaArtyushina1
 

Recently uploaded (20)

WSO2CON 2024 - Designing Event-Driven Enterprises: Stories of Transformation
WSO2CON 2024 - Designing Event-Driven Enterprises: Stories of TransformationWSO2CON 2024 - Designing Event-Driven Enterprises: Stories of Transformation
WSO2CON 2024 - Designing Event-Driven Enterprises: Stories of Transformation
 
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
 
What Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the SituationWhat Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the Situation
 
WSO2CON 2024 - Architecting AI in the Enterprise: APIs and Applications
WSO2CON 2024 - Architecting AI in the Enterprise: APIs and ApplicationsWSO2CON 2024 - Architecting AI in the Enterprise: APIs and Applications
WSO2CON 2024 - Architecting AI in the Enterprise: APIs and Applications
 
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
 
WSO2Con2024 - Software Delivery in Hybrid Environments
WSO2Con2024 - Software Delivery in Hybrid EnvironmentsWSO2Con2024 - Software Delivery in Hybrid Environments
WSO2Con2024 - Software Delivery in Hybrid Environments
 
Evolving Data Governance for the Real-time Streaming and AI Era
Evolving Data Governance for the Real-time Streaming and AI EraEvolving Data Governance for the Real-time Streaming and AI Era
Evolving Data Governance for the Real-time Streaming and AI Era
 
WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?
 
WSO2Con204 - Hard Rock Presentation - Keynote
WSO2Con204 - Hard Rock Presentation - KeynoteWSO2Con204 - Hard Rock Presentation - Keynote
WSO2Con204 - Hard Rock Presentation - Keynote
 
WSO2CON 2024 - Unlocking the Identity: Embracing CIAM 2.0 for a Competitive A...
WSO2CON 2024 - Unlocking the Identity: Embracing CIAM 2.0 for a Competitive A...WSO2CON 2024 - Unlocking the Identity: Embracing CIAM 2.0 for a Competitive A...
WSO2CON 2024 - Unlocking the Identity: Embracing CIAM 2.0 for a Competitive A...
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
 
WSO2CON 2024 - How CSI Piemonte Is Apifying the Public Administration
WSO2CON 2024 - How CSI Piemonte Is Apifying the Public AdministrationWSO2CON 2024 - How CSI Piemonte Is Apifying the Public Administration
WSO2CON 2024 - How CSI Piemonte Is Apifying the Public Administration
 
WSO2CON 2024 - Not Just Microservices: Rightsize Your Services!
WSO2CON 2024 - Not Just Microservices: Rightsize Your Services!WSO2CON 2024 - Not Just Microservices: Rightsize Your Services!
WSO2CON 2024 - Not Just Microservices: Rightsize Your Services!
 
Architecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the pastArchitecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the past
 
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
 
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK Software
 
WSO2Con2024 - Organization Management: The Revolution in B2B CIAM
WSO2Con2024 - Organization Management: The Revolution in B2B CIAMWSO2Con2024 - Organization Management: The Revolution in B2B CIAM
WSO2Con2024 - Organization Management: The Revolution in B2B CIAM
 
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
 
Artyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptxArtyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptx
 

Events: The Object Oriented Hook System.

  • 1. Events: The Object Oriented Hook System
  • 2. Nida Ismail Shah Developer at d.o & twitter: @nidaismailshah Acquia nidashah.com/blog Gulmarg, Kashmir
  • 4. Overview The Symfony Event Dispatcher component. Installation and usage Creating and dispatching an event Subscribing/Listening to events Events in Drupal 8 Creating Events. Subscribing to Events
  • 6. “ The idea is to be able to run random code at given places in the engine. This random code should then be able to do whatever needed to enhance the functionality. The places where code can be executed are called “hooks” and are defined by a fixed interface. ~ Dries Buytaert.
  • 7. “ The Event Dispatcher component provides tools that allow your application components to communicate with each other by dispatching events and listening to them.
  • 8. “ an event is an action or an occurrence recognised by software that may be handled by software. event?
  • 11. Extensibility Hooks Plugins Mulitple instances Admin forms Configuration Tagged Services Simple Extensions Events Alter something? React to something?
  • 13. Installing the symfony event dispatcher component Text Text Use the official Git repository ( )https://github.com/symfony/event-dispatcher composer require symfony/event-dispatcher Using version ^3.2 for symfony/event-dispatcher ./composer.json has been created Loading composer repositories with package information Updating dependencies (including require-dev) - Installing symfony/event-dispatcher (v3.2.6) Loading from cache symfony/event-dispatcher suggests installing symfony/dependency-injection () symfony/event-dispatcher suggests installing symfony/http-kernel () Writing lock file Generating autoload files
  • 14. Using the symfony event dispatcher component 1. Event - representing the event or the state of the application. 2. Dispatcher - to notify the subscribers or listeners about the occurrence of the event. 3. Subscriber/Listener - to extend the application once the event has occurred.
  • 15. Pub-Sub pattern The pub sub exemplifies the proper decoupling of components of an application. Publishers publish the messages into classes without knowledge of which subscribers would be interested in the message. Subscribers express interest in one or more classes and only receive messages that are of interest, without knowledge of which publishers. Mediator pattern Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently. Design an intermediary to decouple many peers.
  • 17. Workflow A listener (PHP object) tells a central dispatcher object that it wants to listen to the 'xyz' event At some point, Symfony tells the dispatcher object to dispatch the 'xyz' event, passing with it an Event object that has access to the Object defining the state of the application at that point. The dispatcher notifies (i.e. calls a method on) all listeners of the 'xyz' event, allowing each of them to make modifications to the State object.
  • 18. Components The dispatcher object The Event object The subscriber/listener
  • 19. the dispatcher // create an EventDispatcher instance.
 $dispatcher = new EventDispatcher();

 // the order is somehow created or retrieved // contains the state of our application // or the information we want expose. 
$order = new Order(); 
// ...

 // create the OrderPlacedEvent and dispatch it
 $event = new OrderPlacedEvent($order);

 // dispatch the event.
 $dispatcher->dispatch(OrderPlacedEvent::NAME, $event);
 // or $dispatcher->dispatch('order.placed', $event);
  • 20. the event 

/**
 * The order.placed event is dispatched each time an order is created
 * in the system. 
*/ 
class OrderPlacedEvent extends Event { 

 const NAME = 'order.placed';

 protected $order;

 public function __construct(Order $order) {
 $this->order = $order;
 }

 public function getOrder() {
 return $this->order;
 } 
}
  • 21. the base event /** * Event is the base class for classes containing event data. * This class contains no event data. It is used by events that do not pass * state information to an event handler when an event is raised. */ class Event { /** * @var bool Whether no further event listeners should be triggered */ private $propagationStopped = false; /** * Returns whether further event listeners should be triggered. */ public function isPropagationStopped() { return $this->propagationStopped; } /** * Stops the propagation of the event to further event listeners. */ public function stopPropagation() { $this->propagationStopped = true; } }
  • 22. “ The base Event class provided by the Event Dispatcher component is deliberately sparse to allow the creation of API specific event objects by inheritance using OOP. This allows for elegant and readable code in complex applications.
  • 23. the subscriber class StoreSubscriber implements EventSubscriberInterface
 {
 public static function getSubscribedEvents()
 {
 return array(
 KernelEvents::RESPONSE => array(
 array('onKernelResponsePre', 10),
 array('onKernelResponsePost', -10),
 ),
 OrderPlacedEvent::NAME => 'onStoreOrder',
 );
 }

 public function onKernelResponsePre(FilterResponseEvent $event)
 { // do something. 
 }

 public function onKernelResponsePost(FilterResponseEvent $event)
 { // do something. 
 }

 

 public function onStoreOrder(OrderPlacedEvent $event)
 { // do something. 
 }

 
}
  • 24. the listener class AcmeListener
 {
 // ...

 public function onFooAction(Event $event)
 {
 // ... do something
 } 
} // This is very similar to a subscriber class, // except that the class itself cant tell the dispatcher which events it should listen to.
  • 25. register listener/subscriber // create an EventDispatcher instance.
 $dispatcher = new EventDispatcher(); 

$subscriber = new StoreSubscriber(); 
// Register subscriber
 $dispatcher->addSubscriber($subscriber);

 // add a listener
 $listener = new AcmeListener();
 $dispatcher->addListener('acme.foo.action', array($listener, 'onFooAction'));

 // create the OrderPlacedEvent and dispatch it
 $event = new OrderPlacedEvent($order);

 // dispatch the event. 
$dispatcher->dispatch(OrderPlacedEvent::NAME, $event); 
// or $dispatcher->dispatch(order.placed, $event);
  • 26. other ways to register # app/config/services.yml services: kernel.listener.your_listener_name: class: AppBundleEventListenerAcmeExceptionListener tags: - { name: kernel.event_listener, event: kernel.exception, method: onKernelException } With the use of ContainerAwareEventDispatcher and dependency injection: Use the to tag services as event listeners/subscribers. Define event subscriber/listener as a service. Tag them as kernel.event_listener or kernel.event_subscriber. RegisterListenersPass
  • 27. subscriber vs listener Event listeners and Subscribers serve the same purpose and can be used in an application indistinctly. Event listeners can be added via service definition and also with addListener()method. Event subscribers are added via service definition and by implementing the getSubscribedEvents() method and also with addSubscriber() method. Event subscribers are easier to use and reuse. Event listener is registered specifying the events on which it listens. The subscriber has a method telling the dispatcher what events it is listening to. More here: http://nidashah.com/drupal/events-and-listeners.html
  • 28. more dispatchers ContainerAwareEventDispatcher Use services within your events, and subscribers as services TraceableEventDispatcher wraps any other event dispatcher and can then be used to determine which event listeners have been called by the dispatcher ImmutableEventDispatcher is a locked or frozen event dispatcher. The dispatcher cannot register new listeners or subscribers.
  • 29. ContainerAwareEventDispatcher The ContainerAwareEventDispatcher is a special Event Dispatcher implementation which is coupled to the service container that is part of the DependencyInjection component. It allows services to be specified as event listeners making the EventDispatcher extremely powerful. Services are lazy loaded meaning the services attached as listeners will only be created if an event is dispatched that requires those listeners.
  • 30. ContainerAwareEventDispatcher use SymfonyComponentDependencyInjectionContainerBuilder; use SymfonyComponentEventDispatcherContainerAwareEventDispatcher; $container = new ContainerBuilder(); $dispatcher = new ContainerAwareEventDispatcher($container); // Add the listener and subscriber services $dispatcher->addListenerService($eventName, array('foo', 'logListener')); $dispatcher->addSubscriberService( 'kernel.store_subscriber', 'StoreSubscriber' );
  • 31. TraceableEventDispatcher The TraceableEventDispatcher is an event dispatcher that wraps any other event dispatcher and can then be used to determine which event listeners have been called by the dispatcher. // the event dispatcher to debug $eventDispatcher = ...; $traceableEventDispatcher = new TraceableEventDispatcher( $eventDispatcher, new Stopwatch() ); $traceableEventDispatcher->addListener( 'event.the_name', $eventListener, $priority ); // dispatch an event $traceableEventDispatcher->dispatch('event.the_name', $event); $calledListeners = $traceableEventDispatcher->getCalledListeners(); $notCalledListeners = $traceableEventDispatcher->getNotCalledListeners();
  • 32. ImmutableEventDispatcher The ImmutableEventDispatcher is a locked or frozen event dispatcher. The dispatcher cannot register new listeners or subscribers. The ImmutableEventDispatcher takes another event dispatcher with all the listeners and subscribers. The immutable dispatcher is just a proxy of this original dispatcher. Using it first create a normal dispatcher (EventDispatcher or ContainerAwareEventDispatcher) and register some listeners or subscribers Now, inject that into an ImmutableEventDispatcher
  • 33. ImmutableEventDispatcher use SymfonyComponentEventDispatcherEventDispatcher; use SymfonyComponentEventDispatcherImmutableEventDispatcher; $dispatcher = new EventDispatcher(); $dispatcher->addListener('foo.action', function ($event) { // ... }); // ... // ... $immutableDispatcher = new ImmutableEventDispatcher($dispatcher);
  • 35. Events are part of the Symfony framework: they allow for different components of the system to interact and communicate with each other. Object oriented way of interaction with core and other modules. Mediator Pattern Container Aware dispatcher Will probably replace hooks in future drupal versions.
  • 36. Since Drupal is using ContainerAwareEventDispatcher, we always have the dispatcher object available as a service. Consequently, Drupal supports the service definition way of adding event subscribers. Service definition way of adding event listeners is not supported. something to note
  • 37. 1. Get the dispatcher object from the service container. 2. Create the event. 3. Dispatch the event. 4. Define a service tagged with event_subscriber in services.yml. 5. Implement the EventSubscriberInterface to write getSubscribedEvents() method to return what events you want to subscribe to. Workflow in Drupal
  • 38. event subscriber class class ConfigFactory implements ConfigFactoryInterface, EventSubscriberInterface { 
static function getSubscribedEvents() {
 $events[ConfigEvents::SAVE][] = array('onConfigSave', 255);
 $events[ConfigEvents::DELETE][] = array('onConfigDelete', 255);
 return $events;
 } } // services.yml config.factory:
 class: DrupalCoreConfigConfigFactory
 tags:
 - { name: event_subscriber }
 - { name: service_collector, tag: 'config.factory.override', call: addOverride }
 arguments: ['@config.storage', '@event_dispatcher', ‘@config.typed'] services:
 event_demo.alter_response:
 class: Drupalevent_demoEventSubscriberAlterResponse
 arguments: [ '@logger.factory' ]
 tags:
 - { name: event_subscriber }
  • 39. dispatching the event $dispatcher = Drupal::service('event_dispatcher');

 // or inject as a dependency $event = new EventDemo($config); 

$event = $dispatcher->dispatch(EVENT_NAME, $event);
  • 40. core registering event subscribers namespace DrupalCoreDependencyInjectionCompiler; use SymfonyComponentDependencyInjectionContainerBuilder; use SymfonyComponentDependencyInjectionCompilerCompilerPassInterface; /** * Registers all event subscribers to the event dispatcher. */ class RegisterEventSubscribersPass implements CompilerPassInterface { /** * {@inheritdoc} */ public function process(ContainerBuilder $container) { if (!$container->hasDefinition('event_dispatcher')) { return; } $definition = $container->getDefinition('event_dispatcher'); $event_subscriber_info = []; foreach ($container->findTaggedServiceIds('event_subscriber') as $id => $attributes) { // We must assume that the class value has been correctly filled, even if // the service is created by a factory. $class = $container->getDefinition($id)->getClass(); $refClass = new ReflectionClass($class); $interface = 'SymfonyComponentEventDispatcherEventSubscriberInterface'; if (!$refClass->implementsInterface($interface)) { throw new InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $id, $interface)); } // Get all subscribed events. foreach ($class::getSubscribedEvents() as $event_name => $params) { if (is_string($params)) { $priority = 0;
  • 41. KernelEvents::CONTROLLER, EXCEPTION, REQUEST, RESPONSE, TERMINATE, VIEW ConfigEvents::DELETE, IMPORT, SAVE, RENAME ... EntityTypeEvents::CREATE, UPDATE, DELETE FieldStorageDefinitionEvents::CREATE, UPDATE, DELETE ConsoleEvents::COMMAND, EXCEPTION, TERMINATE MigrateEvents:: MAP_DELETE, MAP_SAVE, POST_IMPORT, POST_ROLLBACK, POST_ROW_DELETE, POST_ROW_SAVE, RoutingEvents::ALTER, DYNAMIC, FINISHED Events in Drupal 8 core
  • 42. path forward Writing your own module? trigger an Event for everything. Interacting with or alter core? subscribe to an event (if one is fired). Hooks … you don't have too many options. Configuration, Admin forms? Plugins Simple Extensions Tagged services
  • 45. Join Us for Contribution Sprints Friday, April 28, 2017 First-Time Sprinter Workshop 9:00am-12:00pm Room: 307-308 Mentored Core Sprint 9:00am-12:00pm Room:301-303 General Sprints 9:00am-6:00pm Room:309-310 #drupalsprints
  • 46. WHAT DID YOU THINK? Locate this session at the DrupalCon Baltimore website: Take the survey! https://www.surveymonkey.com/r/dr upalconbaltimore http://baltimore2017.drupal.org/schedule