1. Flow: viaggio nel futuro con un
caso realizzato
Tarcisio Fedrizzi
16-17 Novembre 2012
Bologna
2. Federazione provinciale Scuole
materne di Trento
✗ Associazione di 135 scuole materne
✗ 21 circoli
✗ Quasi 1500 maestre
17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 2/37
3. Outline
✗ Presentazione ✗ Fluid Standalone
✗ Il progetto ✗ Considerazioni su
Flow
✗ Dominio
✗ Tecnologie
✗ Conclusioni
✗ POSIT.MethodLogger ✗ Domande
✗ Annotazioni
✗ AOP
17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 3/37
4. Presentazione
✗ Progettazione e
sviluppo applicazioni
ad-hoc
✗ Primo progetto
basato su
✗ Libero professionista
TYPO3.Flow messo in
dal 2005
produzione
✗ Socio di POSIT dal
2009
17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 4/37
5. 210ore: tecnologie 1/2
✗ Server: TYPO3.Flow
✗ Client:
✗ Insegnanti: ExtJS 4
(è stato
necessario rendere
l'interfaccia
più fedele possibile
a quella del client
windows usato
in precedenza)
17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 5/37
6. 210ore: tecnologie 2/2
✗ Gestori:
TYPO3.Fluid +
JQuery DataTable
✗ Amministratori:
TYPO3.Expose
oppure
TYPO3.Fluid
(ancora in
fase di sviluppo)
17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 6/37
7. Il modulo POSIT.MethodLogger
✗ Estratto dal progetto 210ore
✗ Permette di loggare chiamate a qualsiasi
metodo
✗ È possibile accedere ai parametri della
chiamata
✗ Permette di vedere alcuni aspetti del
framework Flow in azione
17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 7/37
8. Annotazioni 1/2
Elementi che permettono di “appiccicare” dei
dati descrittivi (metadati) a classi, metodi e
interfacce
✗ In alcuni linguaggi (es. Java) sono un costrutto
che fa parte del linguaggio
✗ In altri, tra cui PHP, non sono ancora
disponibili nativamente e vengono quindi
specificate nei commenti.
17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 8/37
9. Annotazioni 2/2
✗ Flow ne fa un uso piuttosto consistente. Ad
esempio:
...
use TYPO3FlowAnnotations as Flow;
...
/**
* @FlowEntity
*/
class MethodLog {
...
nelle definizioni delle Entità.
17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 9/37
10. Definizione Annotazioni
✗ Semplice classe che ...
* @Annotation
* @Target("METHOD")
contiene i parametri */
final class LogMethod {
passati dove /**
* @var string
l'annotazione è */
public $message;
specificata; ...
...
✗ I parametri sono class PostController {
/**
passati al costruttore * @POSITLogMethod(
* message="Creato post.")
dell'annotazione in un */
public function createAction(
unico array. ...
17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 10/37
11. AOP 1/2
Ideata da Gregor Kiczales e altri di Xerox
PARC
✗ Permette di mantenere una netta separazione
tra logica di business e funzionalità non
specifiche dell'applicazione
✗ Queste funzionalità vengono aggiunte con un
sistema che si basa su tre concetti
17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 11/37
12. AOP 2/2
✗ I concetti sono i seguenti:
✗ Advice: definisce la funzionalità che dev'essere
aggiunta (Logging, controlli di accesso, ecc);
✗ Pointcut: permette di specificare in quali punti la
funzionalità dev'essere eseguita (prima di
chiamare un metodo, quando viene lanciata
un'eccezione, ecc);
✗ Join point: descrive il contesto presente nel
punto in cui è stata sospesa l'esecuzione.
17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 12/37
13. AOP in Flow: Aspect
✗ L'aspetto in Flow è una classe annotata con
@FlowAspect.
✗ La classe deve inoltre definire un Advice o un Pointcut
per essere un aspetto considerato valido.
...
/**
* @FlowAspect
*/
class LogMethodAspect {
/**
* @FlowAround(
* "POSITMethodLoggerAspectLogMethodAspect->methodsAnnotatedWithLogMethod")
*/
public function runMethodLogging(TYPO3FlowAopJoinPointInterface $joinPoint){
...
17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 13/37
14. AOP in Flow: Pointcut
✗ Flow offre diversi designatori di pointcut:
method, class, ecc...
✗ Essi permettono di selezionare i metodi ai
quali dev'essere applicato un advice
...
/**
* @FlowPointcut(
* "methodAnnotatedWith(
* POSITMethodLoggerAnnotationsLogMethod)")
*/
public function methodsAnnotatedWithLogMethod() {}
...
17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 14/37
15. AOP in Flow: Advice
✗ L'advice è il metodo che viene eseguito quando vengono
chiamati i metodi selezionati con il pointcut;
✗ Esso viene eseguito secondo le indicazioni
dall'annotazione che decora il metodo;
...
/**
* @FlowAround(
* "POSITMethodLoggerAspectLogMethodAspect->methodsAnnotatedWithLogMethod")
*/
public function runMethodLogging(TYPO3FlowAopJoinPointInterface $joinPoint){
$logMethod = $this->getLogMethodAnnotation($joinPoint);
$this->logMessage($joinPoint, $logMethod);
return $joinPoint->getAdviceChain()->proceed($joinPoint);
}
...
17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 15/37
16. AOP in Flow: Join point
✗ Il join point permette di accedere al contesto e alla descrizione del
metodo al quale è applicato l'advice;
✗ tramite il join point è possibile conoscere il nome del metodo, i
parametri che sono stati passati, ecc
...
$i = 0;
$className = $joinPoint->getClassName();
$methodName = $joinPoint->getMethodName();
$methodArguments = $joinPoint->getMethodArguments();
print("$className->$methodName(");
foreach ($methodArguments as $argumentName => $argumentValue) {
if ($i++ > 0) { print(", "); }
print("$argumentName = $argumentValue");
}
print(");n");
...
17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 16/37
17. Fluid standalone 1/2
✗ È possibile utilizzare il motore di templating anche in
maniera standalone
✗ Questo ci permette di riutilizzare la sintassi di fluid
anche in contesti differenti rispetto a quello delle pagine
web
private function renderViewText(TYPO3FlowAopJoinPointInterface $joinPoint
$text) {
$textView = new TYPO3FluidViewStandaloneView();
$textView->initializeObject();
$textView->setTemplateSource($text);
foreach ($joinPoint->getMethodArguments() as $name => $value) {
$textView->assign($name, $value);
}
return $textView->render();
}
17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 17/37
18. Fluid standalone 2/2
✗ L'utilizzo del metodo definito nella slide
precedente ci permette quindi di accedere ai
parametri del metodo loggato all'interno del
messaggio di log
...
/**
* @POSITLogMethod(message="{newPost.author} ha creato il nuovo
* post intitolato {newPost.title}.")
*/
public function createAction(
TYPO3BlogDomainModelPost $newPost) {
...
17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 18/37
19. Considerazioni su Flow 1/9
✗ Dal punto di vista tecnologico offre molte possibilità
(AOP, annotazioni, slot e segnali)
✗ c'è tutto quello che (e anche di più) può servire per lo
sviluppo web
✗ È in generale semplice aggiungere e/o modificare le
funzionalità offerte dal framework
✗ Si tratta in genere di ereditare da una classe e di
implementare un'interfaccia definendo pochi metodi
(molte volte è sufficiente uno)
17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 19/37
20. Considerazioni su Flow 2/9
✗ Il sistema di controllo degli accessi è molto
flessibile
✗ Permette di specificare anche condizioni
complesse modificando soltanto i file di
configurazione
✗ Il sistema di mapping dei parametri della
richiesta sui parametri del metodo dell'azione
chiamata nel controller permette di
mantenere la logica di business molto pulita
17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 20/37
21. Considerazioni su Flow 3/9
✗ Configurabilità da file
✗ Semplice aggiungere la configurazione anche
per i propri moduli
✗ L'interfaccia a linea di comando
✗ Semplice aggiungere comandi per i propri
moduli
17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 21/37
22. Considerazioni su Flow 4/9
✗ Problema maggiore riguarda l'usabilità:
✗ Punti fondamentali per lo sviluppo
di un progetto reale non sono
documentati. Ad esempio:
✗ Logging e debugging
✗ Deployment e amministrazione
✗ L'applicazione di esempio TYPO3.Blog copre alcune
casistiche ma non offre un esempio esaustivo
✗ Gli esempi che ci sono nella documentazione sono utili
ma anche in questo caso non esaustivi
17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 22/37
23. Considerazioni su Flow 5/9
✗ In molti casi è difficile capire dov'è o a quale
elemento si riferisce un errore
✗ Non c'è menzione a qualche cosa che mi possa
aiutare a trovare il soggetto dell'errore
17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 23/37
24. Considerazioni su Flow 6/9
✗ E lo stacktrace dell'eccezione scritto su file non
offre maggiori informazioni
Uncaught exception #1222268609 in line 146 of
Data/Temporary/Development/Cache/Code/FLOW3_Object_Classes/TYPO3_FLOW3_Security_Authorization_AccessDecisionVoterManager. Php:
Access denied (1 denied, 0 granted, 0 abstained)
22 TYPO3FLOW3SecurityAuthorizationAccessDecisionVoterManager_Original::decideOnJoinPoint(TYPO3FLOW3AopJoinPoint)
21 TYPO3FLOW3SecurityAuthorizationAccessDecisionVoterManager::decideOnJoinPoint(TYPO3FLOW3AopJoinPoint)
20 call_user_func_array(array, array)
19 TYPO3FLOW3SecurityAuthorizationAccessDecisionVoterManager::FLOW3_Aop_Proxy_invokeJoinPoint(TYPO3FLOW3AopJoinPoint)
18 TYPO3FLOW3SecurityAuthorizationAccessDecisionVoterManager::decideOnJoinPoint(TYPO3FLOW3AopJoinPoint)
17 TYPO3FLOW3SecurityAuthorizationInterceptorPolicyEnforcement_Original::invoke()
16 TYPO3FLOW3SecurityAspectPolicyEnforcementAspect_Original::enforcePolicy(TYPO3FLOW3AopJoinPoint)
15 TYPO3FLOW3AopAdviceAroundAdvice::invoke(TYPO3FLOW3AopJoinPoint)
14 TYPO3FLOW3AopAdviceAdviceChain::proceed(TYPO3FLOW3AopJoinPoint)
13 POSITDuecentodieciOreControllerDomainAccountingAnnualEstimateController::initializeAction()
12 TYPO3FLOW3MvcControllerActionController_Original::processRequest(TYPO3FLOW3MvcActionRequest, TYPO3FLOW3HttpResponse)
11 TYPO3FLOW3MvcDispatcher_Original::dispatch(TYPO3FLOW3MvcActionRequest, TYPO3FLOW3HttpResponse)
10 TYPO3FLOW3MvcDispatcher::dispatch(TYPO3FLOW3MvcActionRequest, TYPO3FLOW3HttpResponse)
9 call_user_func_array(array, array)
8 TYPO3FLOW3MvcDispatcher::FLOW3_Aop_Proxy_invokeJoinPoint(TYPO3FLOW3AopJoinPoint)
7 TYPO3FLOW3AopAdviceAdviceChain::proceed(TYPO3FLOW3AopJoinPoint)
6 TYPO3FLOW3SecurityAspectRequestDispatchingAspect_Original::blockIllegalRequestsAndForwardToAuthenticationEntryPoints(
TYPO3FLOW3AopJoinPoin t)
5 TYPO3FLOW3AopAdviceAroundAdvice::invoke(TYPO3FLOW3AopJoinPoint)
4 TYPO3FLOW3AopAdviceAdviceChain::proceed(TYPO3FLOW3AopJoinPoint)
3 TYPO3FLOW3MvcDispatcher::dispatch(TYPO3FLOW3MvcActionRequest, TYPO3FLOW3HttpResponse)
2 TYPO3FLOW3HttpRequestHandler::handleRequest()
1 TYPO3FLOW3CoreBootstrap::run()
17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 24/37
25. Considerazioni su Flow 7/9
✗ Spesso errori nel progetto (per esempio derivanti
da elaborazione del codice del progetto da parte
del framework, configurazioni errate all'interno
del progetto) producono stacktrace e messaggi in
cui non appare niente che riguarda il progetto.
Questo rende quindi molto difficile e pesante
comprendere qual'è il problema.
17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 25/37
26. Considerazioni su Flow 8/9
✗ Assenza di utility per rendere lo sviluppo più
comodo e rapido
✗ Mi sarei aspettato di trovare nella distribuzione
base:
✗ Un'interfaccia web per il debugging (area che posso
consultare per leggere i log, profiling, ecc)
✗ Vedi Debug.Toolbar (debug), Plumber (profiling)
✗ Un'interfaccia grafica per una gestione di base degli
oggetti definiti nel progetto
✗ Vedi TYPO3.Expose
17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 26/37
27. Considerazioni su Flow 9/9
✗ Un interfaccia CRUD che mi permetta di gestire gli oggetti nel
database senza dover scrivere sempre lo stesso codice.
✗ L'usabilità è troppe volte posta come un
elemento a bassa priorità. È invece molto
importante dato che la sua carenza:
✗ costituisce una barriera per l'adozione da parte di
nuovi utenti
✗ rende frustranti operazioni che dovrebbero
essere semplici
17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 27/37
28. Conclusione
✗ TYPO3.Flow è un framework completo che offre tutti gli strumenti per creare le più
disparate applicazioni web
✗ Offre una base ricca e solida su cui costruire i propri progetti
✗ Ancora molto dev'essere fatto sul fronte dell'usabilità perché:
✗ non tutti se la sentono di mettere il naso nel codice del framework per fare il debug della
propria applicazione
✗ un framework che si pone come obiettivo di ...“far tornare la gioia di sviluppare.”...
dovrebbe rendere veloci e semplici quelle operazioni noiose e ripetitive che fanno parte di
ogni progetto
✗ Per evitare che il progetto rimanga nel limbo è necessario cominciare ad utilizzare,
e quindi testare, il framework in ambienti reali. Soltanto così è possibile verificare
quali aspetti vanno migliorati, capire cosa sarebbe comodo avere e, riportandolo
agli sviluppatori oppure contribuendo noi stessi, migliorare il framework fino a
renderlo lo strumento più adatto alle nostre esigenze.
17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 28/37
29. Grazie per l'attenzione
✗ Il codice dell'esempio mostrato nella presentazione è
disponibile all'url:
✗ https://github.com/posit-it/POSIT.MethodLogger
✗ L'esempio gira su Flow 2.0 (ex FLOW3 1.2)
✗ Altri pacchetti menzionati nella presentazione:
✗ Plumber:
✗ https://github.com/sandstorm/Plumber
✗ Debug.Toolbar:
✗ https://github.com/mneuhaus/Debug.Toolbar/
✗ TYPO3.Expose:
✗ http://git.typo3.org/FLOW3/Packages/TYPO3.Expose.git
17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 29/37
30. Persistenza
✗ In Flow la persistenza dei dati è gestita
tramite un livello di astrazione
✗ Flow si basa sulla programmazione orientata
agli oggetti. Questo implica che in flow la
“base dati” è costituita dalla definizione di una
serie di oggetti collegati tra loro.
✗ Dietro le quinte il framework si occupa di
mappare gli oggetti da e verso il database
17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 30/37
31. Persistenza: Doctrine
✗ Flow supporta diversi metodi di persistenza
tuttavia quello maggiormente integrato è
Doctrine.
✗ Doctrine (la versione 2 è quella integrata in
FLOW) è un Object Relational Mapping
Software. Questo genera, a partire dalla
descrizione dei dati e dalle azioni che noi
facciamo sui dati stessi, le query che
aggiornano i dati nel database.
17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 31/37
32. Persistenza: entità
✗ Per poter mappare gli oggetti su database è
necessario decorare gli oggetti con alcune
annotazioni. Queste permettono all'ORM di
raccogliere le informazioni necessarie a generare lo
schema.
...
* @FlowEntity
*/
class MethodLog {
...
/**
* L'indirizzo del client che ha causato l'invocazione del metodo loggato.
* @var string
* @ORMColumn(length=15, nullable=true)
*/
protected $ip;
...
17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 32/37
33. Gestione degli oggetti
✗ In Flow il cliclo di vita degli oggetti è gestito
automaticamente dal framework
✗ La gestione degli oggetti viene quindi affidata
ad una classe chiamata ObjectManager
✗ Ad ogni classe è associato quello che è
definito scope. Questo determina il modo in
cui viene gestito il ciclo di vita dell'oggetto
17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 33/37
34. Gestione degli oggetti
✗ Gli scope offerti dal framework sono:
✗ Singleton: il gestore degli oggetti crea un'unica istanza
dell'oggetto. Ogni volta che viene richiesto l'oggetto viene
ritornata la stessa istanza.
✗ Session: il ciclo di vita dell'oggetto corrisponde alla
sessione di un utente. L'oggetto che ha questo tipo di
scope è quindi specifico per ogni sessione.
✗ Prototype: ogni volta che si richiede un oggetto con
questo tipo di scope ne viene ritornata una nuova istanza
17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 34/37
35. Dependency injection
✗ La gestione centralizzata degli oggetti permette di
eliminare la gestione delle dipendenze tra gli oggetti.
✗ È possibile richiedere un oggetto in varie maniere. La più
semplice consiste nella specifica di due annotazioni nel
commento della variabile che ospiterà l'oggetto.
...
/**
* Il repository delle operazioni fatte dagli utenti.
*
* @FlowInject
* @var POSITMethodLoggerDomainRepositoryMethodLogRepository
*/
protected $methodLogRepository;
...
17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 35/37
36. Configurazione 1/2
...
✗ Flow mette a disposizione /**
tramite la dependency * L'array che contiene le
* impostazioni specificate per
injection un meccanismo * il package.
* @var array
semplice per l'accesso a */
impostazioni di protected $settings;
...
configurazioni specifiche /**
* @param array $settings
del modulo. * @return void
*/
public function
injectSettings(array $settings) {
$this->settings = $settings;
}
...
17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 36/37
37. Configurazione 2/2
...
✗ Una volta iniettato private function isEnabled() {
l'array delle return
array_key_exists('enable',
impostazioni sarà $this->settings) &&
$this->settings['enable'];
possibile accedere }
...
all'albero di
...
configurazione che è POSIT
MethodLogger
denominato come il enable: true
namespace del ...
modulo
17 Novembre 2012 Tarcisio Fedrizzi - T3Camp Bologna 37/37