ݺߣ

ݺߣShare a Scribd company logo
COME SFRUTTARE TUTTE LE POTENZIALITÀ
DI SYMFONY IN DRUPAL 8
LUCA LUSSO
• @lussoluca
• www.linkedin.com/in/lussoluca
• drupal.org/user/138068
• llusso@wellnet.it
Senior Web Developer @Wellnet
#DrupalDaysIT
BENVENUTI
Sviluppatori Drupal7 ?
Sviluppatori Symfony ?
Sviluppatori Drupal8 ?
#DrupalDaysIT
NUOVE API IN DRUPAL8
• Routing
• Configuration management
• Entity
• Plugin
• Views
• Migrate
• Typed Data
• Validation
• …
#DrupalDaysIT
COMPONENTI DI SYMFONY IN DRUPAL8
• Classloader
• Dependency injection
• Event dispatcher
• Http foundation
• Http kernel
• Routing
• Serializer
• Validator
• Yaml
• Twig
#DrupalDaysIT
MODULI CUSTOM
In un modulo custom posso usare:
le nuove API di Drupal8
+
tutte le API messe a disposizione dai
componenti di Symfony
+
#DrupalDaysIT
TALK
In questo talk vedremo un sacco di codice, non
preoccupatevi…
…però partiamo da un caso reale, giusto per non
parlare a vuoto :-)
+
#DrupalDaysIT
PROBLEMA
Identificare il motivo per cui una data pagina è lenta
#DrupalDaysIT
DRUPAL DEVEL
Il modulo Devel ha un logger per query, time e memoria
#DrupalDaysIT
SYMFONY PROFILER
#DrupalDaysIT
SYMFONY PROFILER
E’ presente solo nella Standard Edition di Symfony.
Quindi nel core di Drupal8 non ci sarà…
#DrupalDaysIT
SYMFONY PROFILER
Per poter misurare tutti questi valori il profiler di Symfony è
molto integrato dentro il framework e usa API e concetti
piuttosto specifici
Posso fare una cosa simile per Drupal?
#DrupalDaysIT
WEBPROFILER
Modulo Webprofiler
drupal.org/project/webprofiler
#DrupalDaysIT
WEBPROFILER
Profiler di Symfony per Drupal8!
#DrupalDaysIT
WEBPROFILER
#DrupalDaysIT
WEBPROFILER
#DrupalDaysIT
ATTENZIONE 1
Drupal8 è ancora in versione alpha, gli esempi seguenti
potrebbero non funzionare più!
#DrupalDaysIT
ATTENZIONE 2
Esistono due versioni del modulo webprofiler
!
• 8.x-1.x-alpha11 -> compatibile con la alpha11 del core
• 8.x-dev -> compatibile con l’HEAD corrente del core
#DrupalDaysIT
ESEMPIO
Vedremo come sfruttare questi concetti Symfony in
un modulo Drupal:
!
• Service provider
• Compiler
• Event listener
• Profiler
#DrupalDaysIT
SERVICE PROVIDER
• Symfony utilizza un’architettura a servizi
• I servizi dovrebbero contenere la business logic dell’applicazione,
non i controller!
• Tutti i servizi del core sono definiti nel file core/core.services.yml
• I moduli possono aggiungere nuovi servizi e modificare quelli esistenti
#DrupalDaysIT
SERVIZI DEL CORE
• current_user
• string_translation
• database
• settings
• state
• config.factory
• cache_factory
• form_builder
• http_client
• ~ altri 200 (^(s){2}([a-z_.]*):$ su core.services.yml)
#DrupalDaysIT
SERVIZI
• Implementano una certa funzionalità
• Aumentano la possibilità di riuso del codice
• Rendono un applicazione più testabile
• Possono essere facilmente sostituti
• Vengono caricati solo se servono per gestire una data richiesta
#DrupalDaysIT
SERVIZI
Sono gestiti da un ServiceContainer che in
automatico soddisfa le eventuali dipendenze
attraverso un meccanismo chiamato Dependency
Injection, ossia non è il servizio che carica le proprie
dipendenze da altri servizi ma è il Container che
istanzia le classi necessarie all’atto della creazione
del servizio stesso.
#DrupalDaysIT
SERVIZI
Servizio B (es. Database)
Servizio A (es. Mailer)
Servizio C che dipende da A e B (es. Newsletter)
Se chiedo al Container un’istanza del servizio C,
prima verranno create le istanze dei servizi A e B. Il
container userà poi queste istanze (tipicamente)
come parametri del costruttore di C all’atto della sua
creazione.
#DrupalDaysIT
SERVICE PROVIDER
• Durante il bootstrap Drupal cerca una classe chiamata
nomemoduloServiceProvider e un file nomemodulo.services.yml
all’interno di ciascun modulo attivo
• Il file .yml permette di aggiungere nuovi servizi
• La classe permette di modificare i servizi esistenti o di
aggiungerne di nuovi
• Alla fine del processo di scoperta e modifica dei servizi il
ServiceContainer viene scritto su un file (tipicamente) in sites/
default/files/php (verrà eliminato solo da uno svuotamento
eventuale della cache)
#DrupalDaysIT
WEBPROFILERSERVICEPROVIDER.PHP
#DrupalDaysIT
WEBPROFILER.SERVICES.YML
#DrupalDaysIT
ESEMPIO
• Service provider
• Compiler
• Event listener
• Profiler
#DrupalDaysIT
COMPILER
• Dopo aver aggiunto o alterato i servizi il ServiceContainer viene
“compilato” per ottimizzarlo e per aggiungere ulteriori funzionalità
(parametri e tag)
• Il ServiceContainer passa attraverso una sequenza ordinata di
passi di compilazione. Molti di questi passi sono definiti da
Symfony stesso, alcuni sono nel core di Drupal, i moduli possono
definirne ulteriori
• I passi di compilazione servono per gestire i riferimenti circolari,
rimuovere servizi inutilizzati, trovare servizi con specifici tag, …
#DrupalDaysIT
COMPILER
#DrupalDaysIT
COMPILER PASS
Un passo di compilazione potrebbe ad esempio
cercare tutti i servizi che hanno un certo tag:
ContainerBuilder::findTaggedServiceIds()
#DrupalDaysIT
COMPILER PASS
#DrupalDaysIT
COMPILER PASS
Oppure modificare un servizio esistente, ad
esempio cambiando una delle dipendenze.
Possiamo addirittura modificare completamente
l’implementazione di un servizio (l’importante è che il
nuovo servizio rispetti la stessa interfaccia di quello
sostituito) -> servizi mock per il testing
#DrupalDaysIT
COMPILER PASS
Cambio una dipendenza
Sostituisco un servizio con un altro
#DrupalDaysIT
ESEMPIO
• Service provider
• Compiler
• Event listener
• Profiler
#DrupalDaysIT
EVENT LISTENER
Il componente EventDispatcher di Symfony permette di
definire, sollevare e registrarsi ad eventi:
EventDispatcher::dispatch($eventName, Event $e = null)
EventSubscriberInterface::getSubscribedEvents()
#DrupalDaysIT
EVENT LISTENER
Definisco un servizio all’interno di
nomemodulo.services.yml e gli aggiungo il tag
“event_subscriber”. La classe relativa deve
implementare l’interfaccia EventSubscriberInterface
e definire il metodo getSubscribedEvents(); in
questo metodo registro i listener agli eventi che mi
interessano. Uno dei passi di compilazione si
occuperà di trovare il mio servizio e di registrarlo
all’interno del gestore degli eventi. Se qualcuno
solleva uno degli eventi a cui mi sono registrato
vengo notificato.
#DrupalDaysIT
EVENT LISTENER
#DrupalDaysIT
EVENT LISTENER
#DrupalDaysIT
EVENT LISTENER
• Posso definire i miei eventi e sollevarli in punti precisi
dell’esecuzione di un mio codice
• Sostanzialmente gli eventi potrebbero sostituire il meccanismo
degli hook di Drupal e in effetti posso già usarli all’interno di
moduli custom (probabilmente gli hook spariranno del tutto in
Drupal9, sostituiti dagli eventi)
#DrupalDaysIT
ESEMPIO
• Service provider
• Compiler
• Event listener
• Profiler
#DrupalDaysIT
PROFILER
• Il componente Http kernel contiene un tool per il profiling delle
richieste
• In Symfony Standard Edition il Profiler è definito nel
WebProfilerBundle e usato dal FrameworkBundle (i bundle
sono i moduli di Symfony)
• Usa diversi DataCollectors per memorizzare informazioni su una
specifica richiesta (tempo di esecuzione, memoria, routing, query
al database, …)
• Nell’implementazione di Symfony salva i profili sul filesystem,
usando un token come nome del file
#DrupalDaysIT
PROFILER
L’infrastruttura per la generazione e il salvataggio dei
profili è già tutta nel core di Drupal8, mancherebbero
i pezzi aggiunti dal FrameworkBundle e dal
WebprofilerBundler, però le funzionalità che questi
due bundle usano sono già anch’esse nel core di
Drupal8 (eventi, servizi, tag, …)
#DrupalDaysIT
PROFILER
Ogni singolo collettore di dati è registrato come
servizio e marcato con il tag “data_collector”. La
classe relativa deve estendere la classe
DataCollector e implementare il metodo collect()
#DrupalDaysIT
PROFILER
#DrupalDaysIT
ESEMPIO
• Service provider
• Compiler
• Event listener
• Profiler
#DrupalDaysIT
TOOLS
• PHP 5.4
• GIT
• Drush 7
• PhpStorm EAP (ha il supporto per Drupal8!)
#DrupalDaysIT
APPROFONDIMENTI
La versione 8.x del modulo examples (drupal.org/
project/examples) conterrà a breve molti esempi a
riguardo di questi concetti, potete scaricarne una
preview da qua:
github.com/lussoluca/examples
#DrupalDaysIT
RISORSE
• drupal.org/node/2116747
• drupal.org/node/2133171
• symfony.com/doc/current/components/dependency_injection/index.html
• symfony.com/doc/current/components/event_dispatcher/index.html
• symfony.com/doc/current/cookbook/profiler/index.html
#DrupalDaysIT
CONCLUSIONI
• Drupal8 mette a disposizione innumerevoli nuove API, ma i
componenti di Symfony inclusi nel core ne aggiungono a loro volta
molte altre!
• Molte delle API di Symfony sono esposte da Drupal8 in modo che
i moduli contrib e custom ne possano beneficiare
• I nostri moduli custom possono sfruttare tutte queste potenzialità
per integrarsi sempre di più all’interno del framework
#DrupalDaysIT
CONCLUSIONI
Se vogliamo arrivare pronti all’uscita di Drupal8
potremmo già iniziare a ragionare a “servizi” nei
nostri moduli custom per Drupal7, quello che ci serve
sono un classloader in grado di capire i namespace
di PHP 5.3 e il PSR-0/4 (quello standard di Drupal7
non lo è) e un implementazione di ServiceContainer:
!
• drupal.org/project/xautoload -> PSR-0, PSR-4
• drupal.org/project/pimple_container
Se progettiamo così la business logic della nostra
applicazione, la migrazione di un modulo per
Drupal7 a Drupal8 potrebbe essere meno faticosa
#DrupalDaysIT
Vuoi contribuire a webprofiler? Contattaci!
Abbiamo bisogno di codice, grafica, documentazione, idee
drupal.org/project/webprofiler
#DrupalDaysIT
DOMANDE?
#DrupalDaysIT
GRAZIE ;-)
#DrupalDaysIT
TITOLO DIAPOSITIVA
Corpo della diapositiva

More Related Content

Come sfruttare tutte le potenzialità di Symfony in Drupal 8