SlideShare ist ein Scribd-Unternehmen logo
1 von 48
Downloaden Sie, um offline zu lesen
Hooks and events in
D8
Overview
– Hooks - What, Why, When and How.

– State - Where we are, What about hooks? What about
events?

– Events/Symfony Event Dispatcher - What, Why, When, and
How

– Hooks in D8.
“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.
what has changed
– Procedural to Object Oriented

– Symfony components.

– Modularity, Portability

– Dependency Injection

– Event Subscribers for Hooks

– Unit testing. objects can be mocked, but how do u mock
a global function?

– Developer experience
Hooks
… hooks
– “To extend Drupal, a module need simply implement a
hook. When Drupal wishes to allow intervention from
modules, it determines which modules implement a hook
and calls that hook in all enabled modules that
implement it.”

– Allow interaction with your module (or even core).

– triggered by function naming convention matching on the
hook_name event
Creating hooks
– Calling all modules implementing ‘hook_name':

module_invoke_all(‘name');

– Calling a particular module's 'hook_name' implementation:

module_invoke('module_name', ‘name’);

– returns a list of modules 

module_implements(‘hook_name’);

– drupal_alter('my_data', $data);

module_invoke() D7
/**

* Invokes a hook in a particular module.

*

* All arguments are passed by value. Use drupal_alter() if you need to pass

* arguments by reference.

*

*

* @return

* The return value of the hook implementation.

*/

function module_invoke($module, $hook) {

$args = func_get_args();

// Remove $module and $hook from the arguments.

unset($args[0], $args[1]);

if (module_hook($module, $hook)) {

return call_user_func_array($module . '_' . $hook, $args);

}

}
Issue we faced #1
– Implemented a hook in a module and got “method
already defined” error.

– debugging nightmare

– figured someone had declared a function/hook of one
module in another module.

– because both the modules were already enabled, it
worked just fine.
drupal_alter() D7
function drupal_alter($type, &$data, &$context1 = NULL, &$context2 = NULL, &$context3 =
NULL) {

. . . . .

// Some alter hooks are invoked many times per page request, so statically

// cache the list of functions to call, and on subsequent calls, iterate

// through them quickly.

if (!isset($functions[$cid])) {

$functions[$cid] = array();

$hook = $type . '_alter';

$modules = module_implements($hook);

if (!isset($extra_types)) {

// For the more common case of a single hook, we do not need to call

// function_exists(), since module_implements() returns only modules with

// implementations.

foreach ($modules as $module) {

$functions[$cid][] = $module . '_' . $hook;

}

}
. . . . .
}
order of execution D7
function module_implements($hook, $sort = FALSE, $reset = FALSE) {
. . . . .
if ($hook != 'module_implements_alter') {

// Remember the implementations before hook_module_implements_alter().

$implementations_before = $implementations[$hook];

drupal_alter('module_implements', $implementations[$hook],
$hook);

// Verify implementations that were added or modified.

foreach (array_diff_assoc($implementations[$hook], $implementations_before) as $module =>
$group) {

// If drupal_alter('module_implements') changed or added a $group, the

// respective file needs to be included.

if ($group) {

module_load_include('inc', $module, "$module.$group");

}

// If a new implementation was added, verify that the function exists.

if (!function_exists($module . '_' . $hook)) {

unset($implementations[$hook][$module]);

}

. . . .
}
Issue we faced #2
– we wanted to alter the “node publishing options/menu
settings” on the right block on node/edit form in drupal 8

– did a form_alter inside module, figured what we wanted
to alter wasn't available in the form.

– It was added in form_alter in seven.theme
State
– All the info hooks are gone

– Replaced with annotations, yaml files etc eg
hook_block_info

– hook_init, hook_exit, hook_boot are gone.

– Alter hooks are still there

– Will likely be replaced with Event Listeners
Whats wrong? / Why change?
– D7 - Block hooks

– _info()

– _view()

– _configure()

– _save()

– D8 - Block Plugin

– build()

– blockForm()

– blockSubmit()
Events vs Hooks
– Object oriented.

– Easy to write extensible
code.

– Stopping propagation. 

– Loosely coupled

– Reusability

– Services
– Procedural

– Ambiguity

– No proper control over
hook process flow.

– Tight coupling

– Poor reuse/ duplication
Events
“… an event is an action or an
occurrence recognised by software
that may be handled by software. ”
Events
– 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
Mediator Pattern
– Intent

– 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.
Mediator Pattern
Creating and subscribing to events
What do we need
– Logic

– Dispatch the Event

– Listen to the Event

– Do something.
How do we listen/subscribe to an event
– Implement EventSubscriberInterface in your subscriber
class

– Implement the getSubscribedEvents() method 

– Write the methods that respond to events to extend
functionality

– Declare the Event subscriber as a service. Add to the
services.yml
Event subscriber interface
interface EventSubscriberInterface

{

/**

* Returns an array of event names this subscriber wants to listen to.

*

* * array('eventName' => 'methodName')

* * array('eventName' => array('methodName', $priority))

* * array('eventName' => array(array('methodName1', $priority), array('methodName2')))

*

* @return array The event names to listen to

*/

public static function getSubscribedEvents();

}
event subscriber class
class ConfigFactory implements ConfigFactoryInterface, EventSubscriberInterface {
. . . .
/**

* {@inheritdoc}

*/

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 }
callable to perform action
class AlterResponse implements EventSubscriberInterface {
public function loggingDemo(GetResponseEvent $event) {

// do something.

}



public static function getSubscribedEvents() {

return [

KernelEvents::REQUEST => 'loggingDemo',

];

}
}
order of execution - set priority
class AlterResponse implements EventSubscriberInterface {
public function loggingDemo(GetResponseEvent $event) {

// do something.

}



public static function getSubscribedEvents() {

return [

KernelEvents::REQUEST => [‘loggingDemo’, 10],
KernelEvents::RESPONSE => [
[‘loggingDemoResp’, 10],
[‘somethingElse’, 20],

];

}
}
Listen
– Define a service in your module, tagged with ‘event_subscriber'
– Define a class for your subscriber service that implements
SymfonyComponentEventDispatcherEventSubscriberInterface

– Implement the getSubscribedEvents() method and return a list of the events this
class is subscribed to, and which methods on the class should be called for each one.

– Write the methods that respond to the events; each one receives the event object
provided in the dispatch as its one argument.
How do we Dispatch
– Static Event class

– Extend the Event class

– Dispatch the Event
Static Event Class
namespace SymfonyComponentHttpKernel;



/**

* Contains all events thrown in the HttpKernel component.

*

* @author Bernhard Schussek <bschussek@gmail.com>

*/

final class KernelEvents

{

const REQUEST = 'kernel.request';



const EXCEPTION = 'kernel.exception';

const VIEW = 'kernel.view';

const CONTROLLER = 'kernel.controller';



const RESPONSE = 'kernel.response';



const TERMINATE = 'kernel.terminate';

const FINISH_REQUEST = 'kernel.finish_request';

}
To use each event you can use just
the constant
like: KernelEvents::REQUEST
Event class
class Event

{

private $propagationStopped = false;

private $dispatcher;

private $name;

public function isPropagationStopped() {

return $this->propagationStopped;

}

public function stopPropagation() {

$this->propagationStopped = true;

}

public function getName() {

return $this->name;

}

public function setName($name) {

$this->name = $name;

}

}
“The base Event class provided by the
EventDispatcher 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.”
Extend the generic Event Class
class EventDemo extends Event {



protected $config;





public function __construct(Config $config) {

$this->config = $config;

}



public function getConfig() {

return $this->config;

}



public function setConfig($config) {

$this->config = $config;

}



}
Dispatch your event - with logic
$dispatcher = Drupal::service('event_dispatcher');



$event = new EventDemo($config);



$event = $dispatcher->dispatch(EVENT_NAME, $event);

// Alter the data in the Event class.
// Fetch the data from the event.
Dispatch
– To dispatch an event, call the 

SymfonyComponentEventDispatcherEventDispatchInterface::dispatch()

method on the 'event_dispatcher' service.



– The first argument is the unique event name, which you should normally define as
a constant in a separate static class. 

– The second argument is a 

SymfonyComponentEventDispatcherEvent object;

normally you will need to extend this class, so that your event class can provide
data to the event subscribers.
other event dispatchers and listeners
– Container Aware Event Dispatcher

– Use services within your events

– EventDispatcher Aware Events and Listeners

– dispatch other events from within the event listeners

– 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.
What’s happening in core
– ConfigEvents::DELETE, IMPORT, SAVE, RENAME etc

– EntityTypeEvents::CREATE, UPDATE, DELETE

– FieldStorageDefinitionEvents::CREATE, UPDATE,
DELETE

– ConsoleEvents::COMMAND, EXCEPTION, TERMINATE
What’s happening in core
– KernelEvents::CONTROLLER, EXCEPTION, REQUEST,
RESPONSE, TERMINATE, VIEW

– MigrateEvents:: MAP_DELETE, MAP_SAVE, POST_IMPORT,
POST_ROLLBACK, POST_ROW_DELETE,
POST_ROW_SAVE, 

– RoutingEvents::ALTER, DYNAMIC, FINISHED
Hooks in D8
Hooks in D8
function user_login_finalize(UserInterface $account) {

Drupal::currentUser()->setAccount($account);

Drupal::logger('user')->notice('Session opened for %name.', array('%name' =>
$account->getUsername()));

// Update the user table timestamp noting user has logged in.

// This is also used to invalidate one-time login links.

$account->setLastLoginTime(REQUEST_TIME);

Drupal::entityManager()

->getStorage('user')

->updateLastLoginTimestamp($account);



// Regenerate the session ID to prevent against session fixation attacks.

// This is called before hook_user_login() in case one of those functions

// fails or incorrectly does a redirect which would leave the old session

// in place.

Drupal::service('session')->migrate();

Drupal::service('session')->set('uid', $account->id());

Drupal::moduleHandler()->invokeAll('user_login', array($account));

}
Hooks in D8
/**

* {@inheritdoc}

*/

public function invoke($module, $hook, array $args = array()) {

if (!$this->implementsHook($module, $hook)) {

return;

}

$function = $module . '_' . $hook;

return call_user_func_array($function, $args);

}
Hooks in D8
/**

* {@inheritdoc}

*/

public function invokeAll($hook, array $args = array()) {

$return = array();

$implementations = $this->getImplementations($hook);

foreach ($implementations as $module) {

$function = $module . '_' . $hook;

$result = call_user_func_array($function, $args);

if (isset($result) && is_array($result)) {

$return = NestedArray::mergeDeep($return, $result);

}

elseif (isset($result)) {

$return[] = $result;

}

}



return $return;

}
Hooks in D8 - alter()
/**

* Passes alterable variables to specific hook_TYPE_alter() implementations.

*

* This dispatch function hands off the passed-in variables to type-specific

* hook_TYPE_alter() implementations in modules. It ensures a consistent

* interface for all altering operations.

*

* A maximum of 2 alterable arguments is supported. In case more arguments need

* to be passed and alterable, modules provide additional variables assigned by

* reference in the last $context argument
*/

public function alter($type, &$data, &$context1 = NULL, &$context2 = NULL);
Drupal::moduleHandler->alter($type, $data);
Summary
Summary
– Writing your own module?

– trigger an Event for everything.

– Interact 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
examples
Thank You

Weitere ähnliche Inhalte

Was ist angesagt?

C++ project on police station software
C++ project on police station softwareC++ project on police station software
C++ project on police station softwaredharmenderlodhi021
 
Développement d'un site web jee de e commerce basé sur spring (m.youssfi)
Développement d'un site web jee de e commerce basé sur spring (m.youssfi)Développement d'un site web jee de e commerce basé sur spring (m.youssfi)
Développement d'un site web jee de e commerce basé sur spring (m.youssfi)ENSET, Université Hassan II Casablanca
 
Developing MIPS Exploits to Hack Routers
Developing MIPS Exploits to Hack RoutersDeveloping MIPS Exploits to Hack Routers
Developing MIPS Exploits to Hack RoutersBGA Cyber Security
 
La sécurité sur le web
La sécurité sur le webLa sécurité sur le web
La sécurité sur le webSofteam agency
 
Threat hunting on the wire
Threat hunting on the wireThreat hunting on the wire
Threat hunting on the wireInfoSec Addicts
 
Modern C++ Explained: Move Semantics (Feb 2018)
Modern C++ Explained: Move Semantics (Feb 2018)Modern C++ Explained: Move Semantics (Feb 2018)
Modern C++ Explained: Move Semantics (Feb 2018)Olve Maudal
 
Rapport systéme embarqué busybox
Rapport systéme embarqué busyboxRapport systéme embarqué busybox
Rapport systéme embarqué busyboxAyoub Rouzi
 
Thick Client Penetration Testing.pdf
Thick Client Penetration Testing.pdfThick Client Penetration Testing.pdf
Thick Client Penetration Testing.pdfSouvikRoy114738
 
Securité des applications web
Securité des applications webSecurité des applications web
Securité des applications webMarcel TCHOULEGHEU
 
Sécurité des applications web: attaque et défense
Sécurité des applications web: attaque et défenseSécurité des applications web: attaque et défense
Sécurité des applications web: attaque et défenseAntonio Fontes
 
Windows attacks - AT is the new black
Windows attacks - AT is the new blackWindows attacks - AT is the new black
Windows attacks - AT is the new blackChris Gates
 
Time based CAPTCHA protected SQL injection through SOAP-webservice
Time based CAPTCHA protected SQL injection through SOAP-webserviceTime based CAPTCHA protected SQL injection through SOAP-webservice
Time based CAPTCHA protected SQL injection through SOAP-webserviceFrans Rosén
 
Top 10 Web Security Vulnerabilities (OWASP Top 10)
Top 10 Web Security Vulnerabilities (OWASP Top 10)Top 10 Web Security Vulnerabilities (OWASP Top 10)
Top 10 Web Security Vulnerabilities (OWASP Top 10)Brian Huff
 
1- Les bases de la sécurité informatique.pdf
1- Les bases de la sécurité informatique.pdf1- Les bases de la sécurité informatique.pdf
1- Les bases de la sécurité informatique.pdfbadrboutouja1
 
Cloud computing : Cloud sim
Cloud computing : Cloud sim Cloud computing : Cloud sim
Cloud computing : Cloud sim Khalid EDAIG
 

Was ist angesagt? (20)

C++ project on police station software
C++ project on police station softwareC++ project on police station software
C++ project on police station software
 
Threads
ThreadsThreads
Threads
 
Sécurité des Applications Web avec Json Web Token (JWT)
Sécurité des Applications Web avec Json Web Token (JWT)Sécurité des Applications Web avec Json Web Token (JWT)
Sécurité des Applications Web avec Json Web Token (JWT)
 
Développement d'un site web jee de e commerce basé sur spring (m.youssfi)
Développement d'un site web jee de e commerce basé sur spring (m.youssfi)Développement d'un site web jee de e commerce basé sur spring (m.youssfi)
Développement d'un site web jee de e commerce basé sur spring (m.youssfi)
 
Developing MIPS Exploits to Hack Routers
Developing MIPS Exploits to Hack RoutersDeveloping MIPS Exploits to Hack Routers
Developing MIPS Exploits to Hack Routers
 
Support JEE Servlet Jsp MVC M.Youssfi
Support JEE Servlet Jsp MVC M.YoussfiSupport JEE Servlet Jsp MVC M.Youssfi
Support JEE Servlet Jsp MVC M.Youssfi
 
Support programmation orientée objet c# .net version f8
Support programmation orientée objet c#  .net version f8Support programmation orientée objet c#  .net version f8
Support programmation orientée objet c# .net version f8
 
La sécurité sur le web
La sécurité sur le webLa sécurité sur le web
La sécurité sur le web
 
Threat hunting on the wire
Threat hunting on the wireThreat hunting on the wire
Threat hunting on the wire
 
Modern C++ Explained: Move Semantics (Feb 2018)
Modern C++ Explained: Move Semantics (Feb 2018)Modern C++ Explained: Move Semantics (Feb 2018)
Modern C++ Explained: Move Semantics (Feb 2018)
 
Rapport systéme embarqué busybox
Rapport systéme embarqué busyboxRapport systéme embarqué busybox
Rapport systéme embarqué busybox
 
Thick Client Penetration Testing.pdf
Thick Client Penetration Testing.pdfThick Client Penetration Testing.pdf
Thick Client Penetration Testing.pdf
 
Securité des applications web
Securité des applications webSecurité des applications web
Securité des applications web
 
Sécurité des applications web: attaque et défense
Sécurité des applications web: attaque et défenseSécurité des applications web: attaque et défense
Sécurité des applications web: attaque et défense
 
Windows attacks - AT is the new black
Windows attacks - AT is the new blackWindows attacks - AT is the new black
Windows attacks - AT is the new black
 
Time based CAPTCHA protected SQL injection through SOAP-webservice
Time based CAPTCHA protected SQL injection through SOAP-webserviceTime based CAPTCHA protected SQL injection through SOAP-webservice
Time based CAPTCHA protected SQL injection through SOAP-webservice
 
Red Team P1.pdf
Red Team P1.pdfRed Team P1.pdf
Red Team P1.pdf
 
Top 10 Web Security Vulnerabilities (OWASP Top 10)
Top 10 Web Security Vulnerabilities (OWASP Top 10)Top 10 Web Security Vulnerabilities (OWASP Top 10)
Top 10 Web Security Vulnerabilities (OWASP Top 10)
 
1- Les bases de la sécurité informatique.pdf
1- Les bases de la sécurité informatique.pdf1- Les bases de la sécurité informatique.pdf
1- Les bases de la sécurité informatique.pdf
 
Cloud computing : Cloud sim
Cloud computing : Cloud sim Cloud computing : Cloud sim
Cloud computing : Cloud sim
 

Ähnlich wie Hooks and Events in Drupal 8

The state of hooking into Drupal - DrupalCon Dublin
The state of hooking into Drupal - DrupalCon DublinThe state of hooking into Drupal - DrupalCon Dublin
The state of hooking into Drupal - DrupalCon DublinNida Ismail Shah
 
Osiąganie mądrej architektury z Symfony2
Osiąganie mądrej architektury z Symfony2 Osiąganie mądrej architektury z Symfony2
Osiąganie mądrej architektury z Symfony2 3camp
 
Symfony2 - from the trenches
Symfony2 - from the trenchesSymfony2 - from the trenches
Symfony2 - from the trenchesLukas Smith
 
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rulesSrijan Technologies
 
Interoperable Component Patterns
Interoperable Component PatternsInteroperable Component Patterns
Interoperable Component PatternsMatthew Beale
 
PuppetDB: Sneaking Clojure into Operations
PuppetDB: Sneaking Clojure into OperationsPuppetDB: Sneaking Clojure into Operations
PuppetDB: Sneaking Clojure into Operationsgrim_radical
 
The Naked Bundle - Tryout
The Naked Bundle - TryoutThe Naked Bundle - Tryout
The Naked Bundle - TryoutMatthias Noback
 
Writing Maintainable JavaScript
Writing Maintainable JavaScriptWriting Maintainable JavaScript
Writing Maintainable JavaScriptAndrew Dupont
 
First Steps in Drupal Code Driven Development
First Steps in Drupal Code Driven DevelopmentFirst Steps in Drupal Code Driven Development
First Steps in Drupal Code Driven DevelopmentNuvole
 
Symfony2 from the Trenches
Symfony2 from the TrenchesSymfony2 from the Trenches
Symfony2 from the TrenchesJonathan Wage
 
Introduction to nodejs
Introduction to nodejsIntroduction to nodejs
Introduction to nodejsJames Carr
 
Automation with Ansible and Containers
Automation with Ansible and ContainersAutomation with Ansible and Containers
Automation with Ansible and ContainersRodolfo Carvalho
 
"Angular.js Concepts in Depth" by Aleksandar Simović
"Angular.js Concepts in Depth" by Aleksandar Simović"Angular.js Concepts in Depth" by Aleksandar Simović
"Angular.js Concepts in Depth" by Aleksandar SimovićJS Belgrade
 
Puppet atbazaarvoice
Puppet atbazaarvoicePuppet atbazaarvoice
Puppet atbazaarvoiceDave Barcelo
 
Global objects in Node.pdf
Global objects in Node.pdfGlobal objects in Node.pdf
Global objects in Node.pdfSudhanshiBakre1
 
Introduction to Actor Model and Akka
Introduction to Actor Model and AkkaIntroduction to Actor Model and Akka
Introduction to Actor Model and AkkaYung-Lin Ho
 

Ähnlich wie Hooks and Events in Drupal 8 (20)

The state of hooking into Drupal - DrupalCon Dublin
The state of hooking into Drupal - DrupalCon DublinThe state of hooking into Drupal - DrupalCon Dublin
The state of hooking into Drupal - DrupalCon Dublin
 
Osiąganie mądrej architektury z Symfony2
Osiąganie mądrej architektury z Symfony2 Osiąganie mądrej architektury z Symfony2
Osiąganie mądrej architektury z Symfony2
 
Symfony2 - from the trenches
Symfony2 - from the trenchesSymfony2 - from the trenches
Symfony2 - from the trenches
 
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
 
Interoperable Component Patterns
Interoperable Component PatternsInteroperable Component Patterns
Interoperable Component Patterns
 
PuppetDB: Sneaking Clojure into Operations
PuppetDB: Sneaking Clojure into OperationsPuppetDB: Sneaking Clojure into Operations
PuppetDB: Sneaking Clojure into Operations
 
The Naked Bundle - Tryout
The Naked Bundle - TryoutThe Naked Bundle - Tryout
The Naked Bundle - Tryout
 
Writing Maintainable JavaScript
Writing Maintainable JavaScriptWriting Maintainable JavaScript
Writing Maintainable JavaScript
 
First Steps in Drupal Code Driven Development
First Steps in Drupal Code Driven DevelopmentFirst Steps in Drupal Code Driven Development
First Steps in Drupal Code Driven Development
 
Symfony2 from the Trenches
Symfony2 from the TrenchesSymfony2 from the Trenches
Symfony2 from the Trenches
 
Introduction to nodejs
Introduction to nodejsIntroduction to nodejs
Introduction to nodejs
 
Automation with Ansible and Containers
Automation with Ansible and ContainersAutomation with Ansible and Containers
Automation with Ansible and Containers
 
Django Good Practices
Django Good PracticesDjango Good Practices
Django Good Practices
 
"Angular.js Concepts in Depth" by Aleksandar Simović
"Angular.js Concepts in Depth" by Aleksandar Simović"Angular.js Concepts in Depth" by Aleksandar Simović
"Angular.js Concepts in Depth" by Aleksandar Simović
 
Puppet atbazaarvoice
Puppet atbazaarvoicePuppet atbazaarvoice
Puppet atbazaarvoice
 
Drupal 8 Hooks
Drupal 8 HooksDrupal 8 Hooks
Drupal 8 Hooks
 
Global objects in Node.pdf
Global objects in Node.pdfGlobal objects in Node.pdf
Global objects in Node.pdf
 
Introduction to Actor Model and Akka
Introduction to Actor Model and AkkaIntroduction to Actor Model and Akka
Introduction to Actor Model and Akka
 
6976.ppt
6976.ppt6976.ppt
6976.ppt
 
Node.js essentials
 Node.js essentials Node.js essentials
Node.js essentials
 

Kürzlich hochgeladen

Nanded City ( Call Girls ) Pune 6297143586 Hot Model With Sexy Bhabi Ready ...
Nanded City ( Call Girls ) Pune  6297143586  Hot Model With Sexy Bhabi Ready ...Nanded City ( Call Girls ) Pune  6297143586  Hot Model With Sexy Bhabi Ready ...
Nanded City ( Call Girls ) Pune 6297143586 Hot Model With Sexy Bhabi Ready ...tanu pandey
 
VIP Model Call Girls Hadapsar ( Pune ) Call ON 9905417584 Starting High Prof...
VIP Model Call Girls Hadapsar ( Pune ) Call ON 9905417584 Starting  High Prof...VIP Model Call Girls Hadapsar ( Pune ) Call ON 9905417584 Starting  High Prof...
VIP Model Call Girls Hadapsar ( Pune ) Call ON 9905417584 Starting High Prof...singhpriety023
 
Call Now ☎ 8264348440 !! Call Girls in Shahpur Jat Escort Service Delhi N.C.R.
Call Now ☎ 8264348440 !! Call Girls in Shahpur Jat Escort Service Delhi N.C.R.Call Now ☎ 8264348440 !! Call Girls in Shahpur Jat Escort Service Delhi N.C.R.
Call Now ☎ 8264348440 !! Call Girls in Shahpur Jat Escort Service Delhi N.C.R.soniya singh
 
Best VIP Call Girls Noida Sector 75 Call Me: 8448380779
Best VIP Call Girls Noida Sector 75 Call Me: 8448380779Best VIP Call Girls Noida Sector 75 Call Me: 8448380779
Best VIP Call Girls Noida Sector 75 Call Me: 8448380779Delhi Call girls
 
CALL ON ➥8923113531 🔝Call Girls Lucknow Lucknow best sexual service Online
CALL ON ➥8923113531 🔝Call Girls Lucknow Lucknow best sexual service OnlineCALL ON ➥8923113531 🔝Call Girls Lucknow Lucknow best sexual service Online
CALL ON ➥8923113531 🔝Call Girls Lucknow Lucknow best sexual service Onlineanilsa9823
 
Hot Call Girls |Delhi |Hauz Khas ☎ 9711199171 Book Your One night Stand
Hot Call Girls |Delhi |Hauz Khas ☎ 9711199171 Book Your One night StandHot Call Girls |Delhi |Hauz Khas ☎ 9711199171 Book Your One night Stand
Hot Call Girls |Delhi |Hauz Khas ☎ 9711199171 Book Your One night Standkumarajju5765
 
INDIVIDUAL ASSIGNMENT #3 CBG, PRESENTATION.
INDIVIDUAL ASSIGNMENT #3 CBG, PRESENTATION.INDIVIDUAL ASSIGNMENT #3 CBG, PRESENTATION.
INDIVIDUAL ASSIGNMENT #3 CBG, PRESENTATION.CarlotaBedoya1
 
On Starlink, presented by Geoff Huston at NZNOG 2024
On Starlink, presented by Geoff Huston at NZNOG 2024On Starlink, presented by Geoff Huston at NZNOG 2024
On Starlink, presented by Geoff Huston at NZNOG 2024APNIC
 
✂️ 👅 Independent Andheri Escorts With Room Vashi Call Girls 💃 9004004663
✂️ 👅 Independent Andheri Escorts With Room Vashi Call Girls 💃 9004004663✂️ 👅 Independent Andheri Escorts With Room Vashi Call Girls 💃 9004004663
✂️ 👅 Independent Andheri Escorts With Room Vashi Call Girls 💃 9004004663Call Girls Mumbai
 
GDG Cloud Southlake 32: Kyle Hettinger: Demystifying the Dark Web
GDG Cloud Southlake 32: Kyle Hettinger: Demystifying the Dark WebGDG Cloud Southlake 32: Kyle Hettinger: Demystifying the Dark Web
GDG Cloud Southlake 32: Kyle Hettinger: Demystifying the Dark WebJames Anderson
 
𓀤Call On 7877925207 𓀤 Ahmedguda Call Girls Hot Model With Sexy Bhabi Ready Fo...
𓀤Call On 7877925207 𓀤 Ahmedguda Call Girls Hot Model With Sexy Bhabi Ready Fo...𓀤Call On 7877925207 𓀤 Ahmedguda Call Girls Hot Model With Sexy Bhabi Ready Fo...
𓀤Call On 7877925207 𓀤 Ahmedguda Call Girls Hot Model With Sexy Bhabi Ready Fo...Neha Pandey
 
Delhi Call Girls Rohini 9711199171 ☎✔👌✔ Whatsapp Hard And Sexy Vip Call
Delhi Call Girls Rohini 9711199171 ☎✔👌✔ Whatsapp Hard And Sexy Vip CallDelhi Call Girls Rohini 9711199171 ☎✔👌✔ Whatsapp Hard And Sexy Vip Call
Delhi Call Girls Rohini 9711199171 ☎✔👌✔ Whatsapp Hard And Sexy Vip Callshivangimorya083
 
₹5.5k {Cash Payment}New Friends Colony Call Girls In [Delhi NIHARIKA] 🔝|97111...
₹5.5k {Cash Payment}New Friends Colony Call Girls In [Delhi NIHARIKA] 🔝|97111...₹5.5k {Cash Payment}New Friends Colony Call Girls In [Delhi NIHARIKA] 🔝|97111...
₹5.5k {Cash Payment}New Friends Colony Call Girls In [Delhi NIHARIKA] 🔝|97111...Diya Sharma
 
Call Girls In Model Towh Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Model Towh Delhi 💯Call Us 🔝8264348440🔝Call Girls In Model Towh Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Model Towh Delhi 💯Call Us 🔝8264348440🔝soniya singh
 
Lucknow ❤CALL GIRL 88759*99948 ❤CALL GIRLS IN Lucknow ESCORT SERVICE❤CALL GIRL
Lucknow ❤CALL GIRL 88759*99948 ❤CALL GIRLS IN Lucknow ESCORT SERVICE❤CALL GIRLLucknow ❤CALL GIRL 88759*99948 ❤CALL GIRLS IN Lucknow ESCORT SERVICE❤CALL GIRL
Lucknow ❤CALL GIRL 88759*99948 ❤CALL GIRLS IN Lucknow ESCORT SERVICE❤CALL GIRLimonikaupta
 
Call Now ☎ 8264348440 !! Call Girls in Sarai Rohilla Escort Service Delhi N.C.R.
Call Now ☎ 8264348440 !! Call Girls in Sarai Rohilla Escort Service Delhi N.C.R.Call Now ☎ 8264348440 !! Call Girls in Sarai Rohilla Escort Service Delhi N.C.R.
Call Now ☎ 8264348440 !! Call Girls in Sarai Rohilla Escort Service Delhi N.C.R.soniya singh
 
WhatsApp 📞 8448380779 ✅Call Girls In Mamura Sector 66 ( Noida)
WhatsApp 📞 8448380779 ✅Call Girls In Mamura Sector 66 ( Noida)WhatsApp 📞 8448380779 ✅Call Girls In Mamura Sector 66 ( Noida)
WhatsApp 📞 8448380779 ✅Call Girls In Mamura Sector 66 ( Noida)Delhi Call girls
 

Kürzlich hochgeladen (20)

Nanded City ( Call Girls ) Pune 6297143586 Hot Model With Sexy Bhabi Ready ...
Nanded City ( Call Girls ) Pune  6297143586  Hot Model With Sexy Bhabi Ready ...Nanded City ( Call Girls ) Pune  6297143586  Hot Model With Sexy Bhabi Ready ...
Nanded City ( Call Girls ) Pune 6297143586 Hot Model With Sexy Bhabi Ready ...
 
VIP Model Call Girls Hadapsar ( Pune ) Call ON 9905417584 Starting High Prof...
VIP Model Call Girls Hadapsar ( Pune ) Call ON 9905417584 Starting  High Prof...VIP Model Call Girls Hadapsar ( Pune ) Call ON 9905417584 Starting  High Prof...
VIP Model Call Girls Hadapsar ( Pune ) Call ON 9905417584 Starting High Prof...
 
Rohini Sector 22 Call Girls Delhi 9999965857 @Sabina Saikh No Advance
Rohini Sector 22 Call Girls Delhi 9999965857 @Sabina Saikh No AdvanceRohini Sector 22 Call Girls Delhi 9999965857 @Sabina Saikh No Advance
Rohini Sector 22 Call Girls Delhi 9999965857 @Sabina Saikh No Advance
 
Call Now ☎ 8264348440 !! Call Girls in Shahpur Jat Escort Service Delhi N.C.R.
Call Now ☎ 8264348440 !! Call Girls in Shahpur Jat Escort Service Delhi N.C.R.Call Now ☎ 8264348440 !! Call Girls in Shahpur Jat Escort Service Delhi N.C.R.
Call Now ☎ 8264348440 !! Call Girls in Shahpur Jat Escort Service Delhi N.C.R.
 
Best VIP Call Girls Noida Sector 75 Call Me: 8448380779
Best VIP Call Girls Noida Sector 75 Call Me: 8448380779Best VIP Call Girls Noida Sector 75 Call Me: 8448380779
Best VIP Call Girls Noida Sector 75 Call Me: 8448380779
 
CALL ON ➥8923113531 🔝Call Girls Lucknow Lucknow best sexual service Online
CALL ON ➥8923113531 🔝Call Girls Lucknow Lucknow best sexual service OnlineCALL ON ➥8923113531 🔝Call Girls Lucknow Lucknow best sexual service Online
CALL ON ➥8923113531 🔝Call Girls Lucknow Lucknow best sexual service Online
 
Hot Call Girls |Delhi |Hauz Khas ☎ 9711199171 Book Your One night Stand
Hot Call Girls |Delhi |Hauz Khas ☎ 9711199171 Book Your One night StandHot Call Girls |Delhi |Hauz Khas ☎ 9711199171 Book Your One night Stand
Hot Call Girls |Delhi |Hauz Khas ☎ 9711199171 Book Your One night Stand
 
INDIVIDUAL ASSIGNMENT #3 CBG, PRESENTATION.
INDIVIDUAL ASSIGNMENT #3 CBG, PRESENTATION.INDIVIDUAL ASSIGNMENT #3 CBG, PRESENTATION.
INDIVIDUAL ASSIGNMENT #3 CBG, PRESENTATION.
 
On Starlink, presented by Geoff Huston at NZNOG 2024
On Starlink, presented by Geoff Huston at NZNOG 2024On Starlink, presented by Geoff Huston at NZNOG 2024
On Starlink, presented by Geoff Huston at NZNOG 2024
 
✂️ 👅 Independent Andheri Escorts With Room Vashi Call Girls 💃 9004004663
✂️ 👅 Independent Andheri Escorts With Room Vashi Call Girls 💃 9004004663✂️ 👅 Independent Andheri Escorts With Room Vashi Call Girls 💃 9004004663
✂️ 👅 Independent Andheri Escorts With Room Vashi Call Girls 💃 9004004663
 
GDG Cloud Southlake 32: Kyle Hettinger: Demystifying the Dark Web
GDG Cloud Southlake 32: Kyle Hettinger: Demystifying the Dark WebGDG Cloud Southlake 32: Kyle Hettinger: Demystifying the Dark Web
GDG Cloud Southlake 32: Kyle Hettinger: Demystifying the Dark Web
 
𓀤Call On 7877925207 𓀤 Ahmedguda Call Girls Hot Model With Sexy Bhabi Ready Fo...
𓀤Call On 7877925207 𓀤 Ahmedguda Call Girls Hot Model With Sexy Bhabi Ready Fo...𓀤Call On 7877925207 𓀤 Ahmedguda Call Girls Hot Model With Sexy Bhabi Ready Fo...
𓀤Call On 7877925207 𓀤 Ahmedguda Call Girls Hot Model With Sexy Bhabi Ready Fo...
 
Delhi Call Girls Rohini 9711199171 ☎✔👌✔ Whatsapp Hard And Sexy Vip Call
Delhi Call Girls Rohini 9711199171 ☎✔👌✔ Whatsapp Hard And Sexy Vip CallDelhi Call Girls Rohini 9711199171 ☎✔👌✔ Whatsapp Hard And Sexy Vip Call
Delhi Call Girls Rohini 9711199171 ☎✔👌✔ Whatsapp Hard And Sexy Vip Call
 
₹5.5k {Cash Payment}New Friends Colony Call Girls In [Delhi NIHARIKA] 🔝|97111...
₹5.5k {Cash Payment}New Friends Colony Call Girls In [Delhi NIHARIKA] 🔝|97111...₹5.5k {Cash Payment}New Friends Colony Call Girls In [Delhi NIHARIKA] 🔝|97111...
₹5.5k {Cash Payment}New Friends Colony Call Girls In [Delhi NIHARIKA] 🔝|97111...
 
VVVIP Call Girls In Connaught Place ➡️ Delhi ➡️ 9999965857 🚀 No Advance 24HRS...
VVVIP Call Girls In Connaught Place ➡️ Delhi ➡️ 9999965857 🚀 No Advance 24HRS...VVVIP Call Girls In Connaught Place ➡️ Delhi ➡️ 9999965857 🚀 No Advance 24HRS...
VVVIP Call Girls In Connaught Place ➡️ Delhi ➡️ 9999965857 🚀 No Advance 24HRS...
 
Call Girls In Model Towh Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Model Towh Delhi 💯Call Us 🔝8264348440🔝Call Girls In Model Towh Delhi 💯Call Us 🔝8264348440🔝
Call Girls In Model Towh Delhi 💯Call Us 🔝8264348440🔝
 
Dwarka Sector 26 Call Girls | Delhi | 9999965857 🫦 Vanshika Verma More Our Se...
Dwarka Sector 26 Call Girls | Delhi | 9999965857 🫦 Vanshika Verma More Our Se...Dwarka Sector 26 Call Girls | Delhi | 9999965857 🫦 Vanshika Verma More Our Se...
Dwarka Sector 26 Call Girls | Delhi | 9999965857 🫦 Vanshika Verma More Our Se...
 
Lucknow ❤CALL GIRL 88759*99948 ❤CALL GIRLS IN Lucknow ESCORT SERVICE❤CALL GIRL
Lucknow ❤CALL GIRL 88759*99948 ❤CALL GIRLS IN Lucknow ESCORT SERVICE❤CALL GIRLLucknow ❤CALL GIRL 88759*99948 ❤CALL GIRLS IN Lucknow ESCORT SERVICE❤CALL GIRL
Lucknow ❤CALL GIRL 88759*99948 ❤CALL GIRLS IN Lucknow ESCORT SERVICE❤CALL GIRL
 
Call Now ☎ 8264348440 !! Call Girls in Sarai Rohilla Escort Service Delhi N.C.R.
Call Now ☎ 8264348440 !! Call Girls in Sarai Rohilla Escort Service Delhi N.C.R.Call Now ☎ 8264348440 !! Call Girls in Sarai Rohilla Escort Service Delhi N.C.R.
Call Now ☎ 8264348440 !! Call Girls in Sarai Rohilla Escort Service Delhi N.C.R.
 
WhatsApp 📞 8448380779 ✅Call Girls In Mamura Sector 66 ( Noida)
WhatsApp 📞 8448380779 ✅Call Girls In Mamura Sector 66 ( Noida)WhatsApp 📞 8448380779 ✅Call Girls In Mamura Sector 66 ( Noida)
WhatsApp 📞 8448380779 ✅Call Girls In Mamura Sector 66 ( Noida)
 

Hooks and Events in Drupal 8

  • 2. Overview – Hooks - What, Why, When and How. – State - Where we are, What about hooks? What about events? – Events/Symfony Event Dispatcher - What, Why, When, and How – Hooks in D8.
  • 3. “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.
  • 4. what has changed – Procedural to Object Oriented – Symfony components. – Modularity, Portability – Dependency Injection – Event Subscribers for Hooks – Unit testing. objects can be mocked, but how do u mock a global function? – Developer experience
  • 6. … hooks – “To extend Drupal, a module need simply implement a hook. When Drupal wishes to allow intervention from modules, it determines which modules implement a hook and calls that hook in all enabled modules that implement it.” – Allow interaction with your module (or even core). – triggered by function naming convention matching on the hook_name event
  • 7. Creating hooks – Calling all modules implementing ‘hook_name':
 module_invoke_all(‘name');
 – Calling a particular module's 'hook_name' implementation:
 module_invoke('module_name', ‘name’);
 – returns a list of modules 
 module_implements(‘hook_name’);
 – drupal_alter('my_data', $data);

  • 8. module_invoke() D7 /**
 * Invokes a hook in a particular module.
 *
 * All arguments are passed by value. Use drupal_alter() if you need to pass
 * arguments by reference.
 *
 *
 * @return
 * The return value of the hook implementation.
 */
 function module_invoke($module, $hook) {
 $args = func_get_args();
 // Remove $module and $hook from the arguments.
 unset($args[0], $args[1]);
 if (module_hook($module, $hook)) {
 return call_user_func_array($module . '_' . $hook, $args);
 }
 }
  • 9. Issue we faced #1 – Implemented a hook in a module and got “method already defined” error. – debugging nightmare – figured someone had declared a function/hook of one module in another module. – because both the modules were already enabled, it worked just fine.
  • 10. drupal_alter() D7 function drupal_alter($type, &$data, &$context1 = NULL, &$context2 = NULL, &$context3 = NULL) {
 . . . . .
 // Some alter hooks are invoked many times per page request, so statically
 // cache the list of functions to call, and on subsequent calls, iterate
 // through them quickly.
 if (!isset($functions[$cid])) {
 $functions[$cid] = array();
 $hook = $type . '_alter';
 $modules = module_implements($hook);
 if (!isset($extra_types)) {
 // For the more common case of a single hook, we do not need to call
 // function_exists(), since module_implements() returns only modules with
 // implementations.
 foreach ($modules as $module) {
 $functions[$cid][] = $module . '_' . $hook;
 }
 } . . . . . }
  • 11. order of execution D7 function module_implements($hook, $sort = FALSE, $reset = FALSE) { . . . . . if ($hook != 'module_implements_alter') {
 // Remember the implementations before hook_module_implements_alter().
 $implementations_before = $implementations[$hook];
 drupal_alter('module_implements', $implementations[$hook], $hook);
 // Verify implementations that were added or modified.
 foreach (array_diff_assoc($implementations[$hook], $implementations_before) as $module => $group) {
 // If drupal_alter('module_implements') changed or added a $group, the
 // respective file needs to be included.
 if ($group) {
 module_load_include('inc', $module, "$module.$group");
 }
 // If a new implementation was added, verify that the function exists.
 if (!function_exists($module . '_' . $hook)) {
 unset($implementations[$hook][$module]);
 }
 . . . . }
  • 12. Issue we faced #2 – we wanted to alter the “node publishing options/menu settings” on the right block on node/edit form in drupal 8
 – did a form_alter inside module, figured what we wanted to alter wasn't available in the form. – It was added in form_alter in seven.theme
  • 13. State – All the info hooks are gone – Replaced with annotations, yaml files etc eg hook_block_info – hook_init, hook_exit, hook_boot are gone. – Alter hooks are still there – Will likely be replaced with Event Listeners
  • 14. Whats wrong? / Why change? – D7 - Block hooks – _info() – _view() – _configure() – _save() – D8 - Block Plugin – build() – blockForm() – blockSubmit()
  • 15. Events vs Hooks – Object oriented. – Easy to write extensible code. – Stopping propagation. – Loosely coupled – Reusability – Services – Procedural – Ambiguity – No proper control over hook process flow. – Tight coupling – Poor reuse/ duplication
  • 17. “… an event is an action or an occurrence recognised by software that may be handled by software. ”
  • 18. Events – 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
  • 19. Mediator Pattern – Intent – 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.
  • 22. What do we need – Logic – Dispatch the Event – Listen to the Event – Do something.
  • 23. How do we listen/subscribe to an event – Implement EventSubscriberInterface in your subscriber class – Implement the getSubscribedEvents() method – Write the methods that respond to events to extend functionality – Declare the Event subscriber as a service. Add to the services.yml
  • 24. Event subscriber interface interface EventSubscriberInterface
 {
 /**
 * Returns an array of event names this subscriber wants to listen to.
 *
 * * array('eventName' => 'methodName')
 * * array('eventName' => array('methodName', $priority))
 * * array('eventName' => array(array('methodName1', $priority), array('methodName2')))
 *
 * @return array The event names to listen to
 */
 public static function getSubscribedEvents();
 }
  • 25. event subscriber class class ConfigFactory implements ConfigFactoryInterface, EventSubscriberInterface { . . . . /**
 * {@inheritdoc}
 */
 static function getSubscribedEvents() {
 $events[ConfigEvents::SAVE][] = array('onConfigSave', 255);
 $events[ConfigEvents::DELETE][] = array('onConfigDelete', 255);
 return $events;
 } . . . . }
  • 26. 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 }
  • 27. callable to perform action class AlterResponse implements EventSubscriberInterface { public function loggingDemo(GetResponseEvent $event) {
 // do something.
 }
 
 public static function getSubscribedEvents() {
 return [
 KernelEvents::REQUEST => 'loggingDemo',
 ];
 } }
  • 28. order of execution - set priority class AlterResponse implements EventSubscriberInterface { public function loggingDemo(GetResponseEvent $event) {
 // do something.
 }
 
 public static function getSubscribedEvents() {
 return [
 KernelEvents::REQUEST => [‘loggingDemo’, 10], KernelEvents::RESPONSE => [ [‘loggingDemoResp’, 10], [‘somethingElse’, 20],
 ];
 } }
  • 29. Listen – Define a service in your module, tagged with ‘event_subscriber' – Define a class for your subscriber service that implements SymfonyComponentEventDispatcherEventSubscriberInterface – Implement the getSubscribedEvents() method and return a list of the events this class is subscribed to, and which methods on the class should be called for each one. – Write the methods that respond to the events; each one receives the event object provided in the dispatch as its one argument.
  • 30. How do we Dispatch – Static Event class – Extend the Event class – Dispatch the Event
  • 31. Static Event Class namespace SymfonyComponentHttpKernel;
 
 /**
 * Contains all events thrown in the HttpKernel component.
 *
 * @author Bernhard Schussek <bschussek@gmail.com>
 */
 final class KernelEvents
 {
 const REQUEST = 'kernel.request';
 
 const EXCEPTION = 'kernel.exception';
 const VIEW = 'kernel.view';
 const CONTROLLER = 'kernel.controller';
 
 const RESPONSE = 'kernel.response';
 
 const TERMINATE = 'kernel.terminate';
 const FINISH_REQUEST = 'kernel.finish_request';
 } To use each event you can use just the constant like: KernelEvents::REQUEST
  • 32. Event class class Event
 {
 private $propagationStopped = false;
 private $dispatcher;
 private $name;
 public function isPropagationStopped() {
 return $this->propagationStopped;
 }
 public function stopPropagation() {
 $this->propagationStopped = true;
 }
 public function getName() {
 return $this->name;
 }
 public function setName($name) {
 $this->name = $name;
 }
 }
  • 33. “The base Event class provided by the EventDispatcher 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.”
  • 34. Extend the generic Event Class class EventDemo extends Event {
 
 protected $config;
 
 
 public function __construct(Config $config) {
 $this->config = $config;
 }
 
 public function getConfig() {
 return $this->config;
 }
 
 public function setConfig($config) {
 $this->config = $config;
 }
 
 }
  • 35. Dispatch your event - with logic $dispatcher = Drupal::service('event_dispatcher');
 
 $event = new EventDemo($config);
 
 $event = $dispatcher->dispatch(EVENT_NAME, $event);
 // Alter the data in the Event class. // Fetch the data from the event.
  • 36. Dispatch – To dispatch an event, call the 
 SymfonyComponentEventDispatcherEventDispatchInterface::dispatch()
 method on the 'event_dispatcher' service.
 – The first argument is the unique event name, which you should normally define as a constant in a separate static class. 
 – The second argument is a 
 SymfonyComponentEventDispatcherEvent object;
 normally you will need to extend this class, so that your event class can provide data to the event subscribers.
  • 37. other event dispatchers and listeners – Container Aware Event Dispatcher – Use services within your events – EventDispatcher Aware Events and Listeners – dispatch other events from within the event listeners – 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.
  • 38. What’s happening in core – ConfigEvents::DELETE, IMPORT, SAVE, RENAME etc
 – EntityTypeEvents::CREATE, UPDATE, DELETE
 – FieldStorageDefinitionEvents::CREATE, UPDATE, DELETE
 – ConsoleEvents::COMMAND, EXCEPTION, TERMINATE
  • 39. What’s happening in core – KernelEvents::CONTROLLER, EXCEPTION, REQUEST, RESPONSE, TERMINATE, VIEW
 – MigrateEvents:: MAP_DELETE, MAP_SAVE, POST_IMPORT, POST_ROLLBACK, POST_ROW_DELETE, POST_ROW_SAVE, 
 – RoutingEvents::ALTER, DYNAMIC, FINISHED
  • 41. Hooks in D8 function user_login_finalize(UserInterface $account) {
 Drupal::currentUser()->setAccount($account);
 Drupal::logger('user')->notice('Session opened for %name.', array('%name' => $account->getUsername()));
 // Update the user table timestamp noting user has logged in.
 // This is also used to invalidate one-time login links.
 $account->setLastLoginTime(REQUEST_TIME);
 Drupal::entityManager()
 ->getStorage('user')
 ->updateLastLoginTimestamp($account);
 
 // Regenerate the session ID to prevent against session fixation attacks.
 // This is called before hook_user_login() in case one of those functions
 // fails or incorrectly does a redirect which would leave the old session
 // in place.
 Drupal::service('session')->migrate();
 Drupal::service('session')->set('uid', $account->id());
 Drupal::moduleHandler()->invokeAll('user_login', array($account));
 }
  • 42. Hooks in D8 /**
 * {@inheritdoc}
 */
 public function invoke($module, $hook, array $args = array()) {
 if (!$this->implementsHook($module, $hook)) {
 return;
 }
 $function = $module . '_' . $hook;
 return call_user_func_array($function, $args);
 }
  • 43. Hooks in D8 /**
 * {@inheritdoc}
 */
 public function invokeAll($hook, array $args = array()) {
 $return = array();
 $implementations = $this->getImplementations($hook);
 foreach ($implementations as $module) {
 $function = $module . '_' . $hook;
 $result = call_user_func_array($function, $args);
 if (isset($result) && is_array($result)) {
 $return = NestedArray::mergeDeep($return, $result);
 }
 elseif (isset($result)) {
 $return[] = $result;
 }
 }
 
 return $return;
 }
  • 44. Hooks in D8 - alter() /**
 * Passes alterable variables to specific hook_TYPE_alter() implementations.
 *
 * This dispatch function hands off the passed-in variables to type-specific
 * hook_TYPE_alter() implementations in modules. It ensures a consistent
 * interface for all altering operations.
 *
 * A maximum of 2 alterable arguments is supported. In case more arguments need
 * to be passed and alterable, modules provide additional variables assigned by
 * reference in the last $context argument */
 public function alter($type, &$data, &$context1 = NULL, &$context2 = NULL); Drupal::moduleHandler->alter($type, $data);
  • 46. Summary – Writing your own module? – trigger an Event for everything. – Interact 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