Università degli Studi di Padova Facoltà di Scienze MM.FF.NN. Dipartimento di Matematica pura e applicata Corso di Laurea Triennale in Informatica Refactoring del software gestionale web-based Infostudenti Relatore: Ch.mo Professor Paolo Baldan Laureando: Nicola Beghin, matr. 561540 A.A. 2009/2010 Indice 1 Introduzione 7 1.1 Obiettivi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 1.2 Problematiche . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 2 Analisi dei requisiti 2.1 11 Requisiti di prodotto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 2.1.1 Segreteria . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 2.1.2 Secondo livello . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 2.1.3 Terzo livello . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 2.1.4 Direttore . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 2.1.5 Docenti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 2.1.6 Studenti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 2.1.7 Utenti esterni . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 2.1.8 Amministratore . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 2.1.9 Funzionalità condivise tra gli utenti autenticati . . . . . . . . . . . . . 14 2.2 Requisiti di processo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 2.3 Consuntivo finale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 3 Specifica tecnica 3.1 17 Architettura MVC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 3.1.1 Layer MVC implementati in CakePHP . . . . . . . . . . . . . . . . . . 20 3.2 Web application (client-server) . . . . . . . . . . . . . . . . . . . . . . . . . . 22 3.3 AJAX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 3 INDICE INDICE 3.4 ORM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 3.5 Infostudenti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 3.5.1 Piani di studio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 3.5.2 Piani di studio consigliati . . . . . . . . . . . . . . . . . . . . . . . . . 29 3.5.3 Esami . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 3.5.4 Creazione nuovi utenti . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 3.5.5 Crediti insegnamenti . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 3.5.6 Crediti riga di piano di studi tipo C . . . . . . . . . . . . . . . . . . . 33 3.5.7 Crediti riga di piano di studi tipo D . . . . . . . . . . . . . . . . . . . 34 4 Definizione di prodotto 4.1 4.2 37 Database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 4.1.1 Modellazione concettuale . . . . . . . . . . . . . . . . . . . . . . . . . 37 4.1.2 Specifiche di modellazione relazionale 4.1.3 Convenzioni di database del framework CakePHP . . . . . . . . . . . . . . . . . . 37 . . . . . . . . . . . 42 Classi Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 4.2.1 Application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 4.2.2 Check . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 4.2.3 Classroom 4.2.4 Course 4.2.5 CoursesTeaching . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 4.2.6 Exam . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 4.2.7 Examstatus 4.2.8 Genre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 4.2.9 Grant . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 4.2.10 Instrument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 4.2.11 Log . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 4.2.12 Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 4.2.13 Plan . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 4.2.14 Planstatus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 4.2.15 Preiscription . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 4 INDICE INDICE 4.2.16 Presence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 4.2.17 Qualification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 4.2.18 Requirement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 4.2.19 Role . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 4.2.20 Student . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 4.2.21 Studentstatus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 4.2.22 Tax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 4.2.23 Teacher . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 4.2.24 Teaching . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 4.2.25 Teachingstatus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 4.2.26 TipoCPlan . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 4.2.27 TipoCType . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 4.2.28 TipoDElement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 4.2.29 TipoDPlan . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 4.2.30 TipoDType . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 4.2.31 TipoDTypology 4.2.32 Tipology . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 4.2.33 User . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 4.2.34 Years . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57 4.2.35 Classi Behavior . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57 4.3 Classi Controller . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 4.3.1 4.4 Classi Component . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 Classi View . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 4.4.1 Helper . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 5 Strumenti utilizzati 5.1 63 PHP Framework . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 5.1.1 Caratteristiche valutate per la scelta . . . . . . . . . . . . . . . . . . . 64 5.1.2 CakePHP (v. 1.2.5) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66 5.1.3 Zend Framework (v. 1.9.6) . . . . . . . . . . . . . . . . . . . . . . . . 67 5.1.4 CodeIgniter (v. 1.7.2) . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 5 INDICE INDICE 5.1.5 5.2 5.3 5.4 5.5 5.6 Ulteriori framework . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 Database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 5.2.1 Transazioni . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 5.2.2 ACID . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 5.2.3 Database abstraction layer 5.2.4 Comparazione motori di storage MySQL . . . . . . . . . . . . . . . . . 71 5.2.5 Migrazione dati . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73 . . . . . . . . . . . . . . . . . . . . . . . . 71 Javascript framework . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 5.3.1 Benefici derivanti dall’utilizzo di un framework Javascript . . . . . . . 74 5.3.2 jQuery (v. 1.3.2) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 5.3.3 Prototype (v. 1.6.1) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 5.3.4 Comparazione performance . . . . . . . . . . . . . . . . . . . . . . . . 76 Scambio dati asincrono . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78 5.4.1 AJAX ed XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78 5.4.2 AJAJ: AJAX e JSON . . . . . . . . . . . . . . . . . . . . . . . . . . . 78 5.4.3 AJAH: AJAX ed HTML . . . . . . . . . . . . . . . . . . . . . . . . . . 79 CSS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80 5.5.1 Blueprint CSS framework (v. 0.9.1) . . . . . . . . . . . . . . . . . . . 80 5.5.2 Stampa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 5.5.3 Validazione W3C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 Librerie di esportazione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 5.6.1 TCPDF (v. 4.8.16) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 5.6.2 RTF (v. 0.3.0) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 5.7 Piattaforma di sviluppo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82 5.8 Versionamento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82 5.8.1 5.9 Subversion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82 Verifica e validazione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83 5.9.1 Unit testing (analisi dinamica) . . . . . . . . . . . . . . . . . . . . . . 83 5.10 Documentazione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84 6 Conclusioni 85 6 Capitolo 1 Introduzione 1.1 Obiettivi Lo studente avrà il compito di effettuare il refactoring1 completo di Infostudenti, il software gestionale web-based attualmente in uso al Conservatorio di Musica di Vicenza. Le funzionalità del software dovranno ricalcare quelle attualmente esistenti ed essere integrate con nuove ed eventuali a seconda di quanto emerso dai colloqui con il personale del Conservatorio. Infostudenti La prima incarnazione di Infostudenti nasce nel 1995, qualche anno dopo l’approvazione della legge di riforma dei Conservatori, che allineò le istituzioni statali di musica al modello europeo alla stessa maniera di quanto già avvenuto per le università. Ciò ha significato uno stravolgimento dell’usuale percorso di studi, che è stato suddiviso nell’ormai famoso 3+2, ossia un primo triennio (laurea di I livello) ed un secondo biennio al termine del quale si consegue una laurea specialistica. La prima stesura del software è nata principalmente come ausilio alla compilazione dei piani di studio dei bienni e trienni, il cui laborioso processo di approvazione (cfr. 3.5.1 nella pagina 27) ha reso necessario una qualche via di automatizzazione e controllo dei parametri . A tale principale attività sono poi andate aggiunte tutta una serie di funzioni ausiliari quali la gestione di corsi, insegnamenti, docenti 1 Code refactoring is the process of changing a computer program’s internal structure without modifying its external functional behavior or existing functionality, in order to improve internal quality attributes of the software. Reasons include to improve code readability, to simplify code structure, to change code to adhere to a given programming paradigm, to improve maintainability, to improve performance, or to improve extensibility. [1] 7 1.2. PROBLEMATICHE CAPITOLO 1. INTRODUZIONE e studenti. Nelle ultime fasi è stata implementata la gestione degli esami con relativi appelli e voti, potendo così arrivare alla stampa dell’intera carriera scolastica di ciascuno studente. Si rimanda all’analisi dei requisiti (cfr. 2 nella pagina 11) per una più dettagliata panoramica delle funzionalità di Infostudenti. 1.2 Problematiche Si riporta una panoramica delle principali problematiche affrontate e le soluzioni adottate per risolverle. Per l’approfondimento di ciascuna soluzione si faccia riferimento alle successive sezioni. Manutenzione ed ampliamento L’intero sistema è stato progettato senza l’ausilio di alcuna specifica o ben definita architettura software, così che qualsiasi attività di manutenzione si è dimostrata essere estremamente complicata e prona ad errori (umani e non). Per il medesimo motivo qualsiasi ulteriore ampliamento è difficile da pianificare sia in termini di fattibilità tecnica che di performance ed impatto sulle altre componenti. Molte funzioni sono poi duplicate o frammentate, senza alcuna logica di razionalizzazione del codice. L’utilizzo di un framework rigidamente strutturato secondo una ben definita architettura software ha permesso di standardizzare il codice ed organizzarlo secondo una struttura più razionale. Controlli di consistenza ed integrità Il software in uso è frutto di svariate modifiche architetturali e funzionali avvenute negli anni conseguenti al primo rilascio. Non avendo mai implementato alcun sistema di mantenimento della consistenza ed integrità dei dati (nè a livello codice nè a livello database) dopo 4 anni d’uso ci si è trovati di fronte ad un database con un alto grado di inconsistenza dei dati. L’estensivo utilizzo di chiavi esterne con opportune clausole trigger, l’utilizzo delle transazioni SQL, un’attenta tipizzazione dei campi di database e l’implementazione di un meccanismo di ulteriore controllo d’integrità, garantito dal framework stesso, ha permesso di ovviare ai problemi fin qui riportati. Sicurezza e permessi Non è mai stata posta grande rilevanza alla sicurezza del software, essa intesa sia dal punto di vista della confidenzialità che dell’integrità dei dati. Non esisten8 CAPITOLO 1. INTRODUZIONE do alcuna ACL 2 1.2. PROBLEMATICHE i permessi dei vari ruoli in gioco sono stati gestiti con bassa granularità; non sono inoltre mai state adottate tecniche di data sanitization, ossia di pulizia e controllo dei parametri per evitare vulnerabilità ad attacchi esterni (es. XSS3 ) o fughe di informazione. L’utilizzo di un framework particolarmente attento a tali problematiche, in grado di occuparsene tramite un rigido controllo dei tipi e la sanitizzazione di tutti i dati in entrata e in uscita, ha permesso di ottenere un buon livello di sicurezza; la possibilità poi di delegare sempre al framework l’intero processo di autenticazione (cfr. 4.3.1 nella pagina 59) ha consentito di avvalersi di una procedura di login particolarmente solida e valida. Scarsa usabilità L’impossibilità di strutturare razionalmente il software, frutto di continue modifiche negli anni, ha reso impossibile porre particolare attenzione all’usabilità del software, che prevede logiche di funzionamento controintuitive o contorte o funzionalità frammentate in sezioni diverse o inadeguate. L’utilizzo di un layout tabellare ha poi impedito di svincolare i contenuti dalla visualizzazione, impedendo di procedere con un eventuale restyling grafico/strutturale. Grazie all’estensivo uso di Javascript e tecnologie di caricamento asincrono si è ovviato alla macchinosità di molte azioni, che ora possono essere portate a termine in una maniera più simile alle tradizionali applicazioni desktop-based; si è poi proceduto con una generale rivisitazione delle funzionalità di ciascuna sezione, semplificando alcune procedure e minimizzando il numero di quelle restanti tramite una generale integrazione di funzioni simili o doppiate. Dal punto di vista del layout si è abbandonato lo schema tabellare in favore di uno completamente tableless e basato su CSS, ricorrendo alle tabelle nei soli punti in cui tale uso fosse semanticamente corretto o assolutamente necessario. L’utilizzo di framework sia dal lato CSS che Javascript ha poi appianato le incompatibilità tra browser e piattaforme differenti, garantendo così una base di partenza coerente ed omogenea dal punto di vista della compatibilità cross-browser. 2 With respect to a computer file system, an access control list (ACL) is a list of permissions attached to an object. An ACL specifies which users–or system processes–are granted access to objects, as well as what operations are allowed to be performed on given objects. [3] 3 Cross-site scripting (XSS) is a type of computer security vulnerability typically found in web applications which enable malicious attackers to inject client-side script into web pages viewed by other users. An exploited cross-site scripting vulnerability can be used by attackers to bypass access controls such as the same origin policy. Cross-site scripting carried out on websites were roughly 80% of all documented security vulnerabilities as of 2007 [2] 9 1.2. PROBLEMATICHE CAPITOLO 1. INTRODUZIONE Performance Lo scarso utilizzo di Javascript e l’assoluta esclusione delle tecnologie di caricamento asincrono (cfr. 5.4 nella pagina 78), unito alla scarsa razionalizzazione di molte sezioni, ha portato alla creazione di un software lento e poco reattivo, rendendone frustante l’utilizzo per l’utente finale. Tramite l’utilizzo di tecniche di manipolazione dinamica del DOM4 della pagine e il caricamento asincroni di dati si è ottenuto un miglioramento della velocità percepita dagli utenti del sistema; aggiungendo a ciò una particolare attenzione nella stesura del codice PHP e nell’invocazione delle query di database si è riusciti ad ottenere un buon incremento di velocità ed efficienza. Documentazione A causa dello sviluppo disordinato il software non è corredato da alcun tipo di documentazione, nè cartacea nè a livello codice. Durante lo sviluppo si è quindi proceduto con una parallela attività di documentazione del codice e successivamente mediante phpDocumentor (cfr. 5.10 nella pagina 84) si è generata la documentazione finale per ciascuna classe. E’ stata generata anche una basilare documentazione per l’utente finale, corredata da immagini esemplificative. 4 The Document Object Model (DOM) is a cross-platform and language-independent convention for representing and interacting with objects in HTML, XHTML and XML documents. [48] 10 Capitolo 2 Analisi dei requisiti Trattandosi di un lavoro di refactoring l’analisi dei requisiti si è dimostrata certamente più semplice poichè si è potuto lavorare su aspetti di più alto livello e comunque su una base di requisiti ben consolidati. Si è quindi proceduto con la formalizzazione delle funzionalità attualmente implementate nella vecchia versione del software, ponendo particolare attenzione alle funzionalità che in passato hanno portato ai maggiori problemi, e le si è integrate con quanto emerso dai colloqui con il personale del Conservatorio. 2.1 Requisiti di prodotto Si procede con la formalizzazione delle funzionalità, suddividendole per area di competenza degli enti a cui afferiscono (cfr. 3.5.1 nella pagina 27). Viene mantenuta la legenda utilizzata per il progetto di Ingegneria del Software (o: obbligatorio, d : desiderabile, z : opzionale). 11 2.1. REQUISITI DI PRODOTTO 2.1.1 CAPITOLO 2. ANALISI DEI REQUISITI Segreteria Tipologia o o o Requisito pregresso: inserimento voti ed assegnazione esami appelli: approvazione, visualizzazione e storico preiscrizioni: gestione ed approvazione (formalizzazione in utenti del sistema) certificazioni studenti: esenzioni, borse di studio, contratti 150 ore, stato carriere, tasse anagrafiche studenti/docenti: aggiunta, rimozione, modifica d o Tabella 2.1: Segreteria: tabella dei requisiti 2.1.2 Secondo livello Le funzioni di secondo livello sono svolte dai direttori di ciascun corso o da speciali docenti nominati allo scopo. Loro compito principale è l’assegnazione di eventuali debiti e la prima scrematura dei piani di studio ricevuti da parte degli studenti. Tipologia o Requisito assegnazione e modifica debiti nei piani di studio Tabella 2.2: Secondo livello: tabella dei requisiti 2.1.3 Terzo livello Il terzo livello è rappresentanto dai responsabili della didattica, incaricati dell’ultima fase di approvazione necessaria per la conferma dei piani di studi; è anche l’unica entità capace di riaprire le pratiche riguardanti i piani di studio confermati. In quanto supervisori finali dell’uniformità e correttezza della formulazione dei piani possono procedere con qualsiasi modifica degli stessi. Tipologia o o o o z Requisito conferma e modifica piani di studio rientro: possibilità di riapertura pratiche dei piani di studio riconoscimento crediti ed autorizzazioni alla frequentazione di insegnamenti in altri istituti: inserimento, modifica, cancellazione laboratori, crediti pregressi, altre attività: inserimento, modifica, cancellazione statistiche studenti-corsi-insegnamenti Tabella 2.3: Terzo livello: tabella dei requisiti 12 CAPITOLO 2. ANALISI DEI REQUISITI 2.1.4 2.1. REQUISITI DI PRODOTTO Direttore Il direttore ha responsabilità di supervisione sull’operato dell’intero Conservatorio. Ha quindi bisogno di statistiche incrociate per rilevare eventuali anomalie e prendere decisioni per porre rimedio ad eventuali discrepanze. Tipologia z Requisito statistiche studenti-docenti-insegnamenti Tabella 2.4: Direttore: tabella dei requisiti 2.1.5 Docenti I docenti devono poter gestire la propria classe ed i dati inerenti le proprie docenze. Tipologia o d o Requisito appelli: richiesta approvazione da parte della segreteria, modifica gestione voti e frequenza delle classi di competenza dati docenza: inserimento e modifica (es. programmi degli insegnamenti svolti) Tabella 2.5: Docenti: tabella dei requisiti 2.1.6 Studenti Nel corso di una definita finestra temporale gli studenti possono procedere alla compilazione della prima stesura del proprio piano di studi, che inizierà poi il percorso di approvazione (cfr. 3.5.1 nella pagina 27). Tipologia o d Requisito piani di studi: visualizzazione e modifica limitata iscrizione agli appelli d’esame Tabella 2.6: Studenti: tabella dei requisiti 2.1.7 Utenti esterni Anche gli utenti esterni (ossia coloro che non hanno le credenziali per accedere al sistema) possono usufruire di una parte di Infostudenti, poichè alcune sezioni informative sono pubbliche. 13 2.2. REQUISITI DI PROCESSO Tipologia o o CAPITOLO 2. ANALISI DEI REQUISITI Requisito lista e dettagli insegnamenti, docenti e programmi preiscrizione al prossimo A.A. Tabella 2.7: Utenti esterni: tabella dei requisiti 2.1.8 Amministratore L’amministratore si occupa degli aspetti più tecnici della gestione di Infostudenti. Tipologia o o o o o o o o o o d Requisito anni accademici: aggiunta, modifica parametri insegnamenti: aggiunta, modifica, cancellazioneo insegnamenti assegnabili come debiti: aggiunta, modifica, cancellazione docenze: aggiunta, modifica, cancellazione corsi: aggiunta, modifica, cancellazione piani di studio consigliati: aggiunta, modifica, cancellazione aule: aggiunta, modifica, cancellazione strumenti: aggiunta, modifica, cancellazione utenti: aggiunta, modifica, cancellazione, cambio permessi testi descrittivi: aggiunta, modifica, cancellazione gestione storico delle azioni compiute da tutti gli utenti del sistema Tabella 2.8: Amministratore: tabella dei requisiti 2.1.9 Funzionalità condivise tra gli utenti autenticati Esistono alcune funzionalità che devono essere accessibili a tutti gli utenti autenticati in Infostudenti. Tipologia o d o d Requisito modifica profilo (specifico per tipologia di utente) ricerca studenti e docenti visualizzazione lista insegnamenti con relative docenze visualizzazione calendario appelli Tabella 2.9: Requisiti comuni a tutti gli utenti autenticati in Infostudenti 2.2 Requisiti di processo • web-application basata su framework PHP MVC object-oriented • consistenza, integrità e confidenzialità dei dati 14 CAPITOLO 2. ANALISI DEI REQUISITI 2.3. CONSUNTIVO FINALE • estensivo uso di caricamento asincrono (AJAX) per – velocizzazione di operazioni precedentemente implementate in modo sincrono – alleggerimento complessivo delle pagine (caricamento di componenti solo su richiesta) • manutenibilità ed estensibilità • parametrizzazione dei valori • layout adatto per permetterne la stampa di qualsiasi pagina del software 2.3 Consuntivo finale Tutti i requisiti obbligatori e desiderabili sono stati soddisfatti mentre quelli opzionali verranno eventualmente sviluppati con un lavoro extra-stage. 15 2.3. CONSUNTIVO FINALE CAPITOLO 2. ANALISI DEI REQUISITI 16 Capitolo 3 Specifica tecnica 3.1 Architettura MVC Come da requisiti funzionali si è riprogettato l’intero sistema in ottica MVC: Why use MVC? Because it is a tried and true software design pattern that turns an application into a maintainable, modular, rapidly developed package. Crafting application tasks into separate models, views, and controllers makes your application very light on its feet. New features are easily added, and new faces on old features are a snap. The modular and separate design also allows developers and designers to work simultaneously, including the ability to rapidly prototype. Separation also allows developers to make changes in one part of the application without affecting others. [6] Il recente fiorire di un gran numero di framework PHP ha visto emergere un’architettura software sulle altre: la relativa semplicità di MVC e la possibilità di contare sui framework più noti e stabili ha quindi praticamente obbligato l’adozione di tale architettura, che comunque possiede le caratteristiche richieste dai requisiti di processo rilevati per il refactoring del sistema. Layer MVC In una tipica architettura MVC esistono 3 layer intercomunicanti: • Model: contiene i dati e la business logic dell’applicazione 17 3.1. ARCHITETTURA MVC CAPITOLO 3. SPECIFICA TECNICA Figura 3.1: Architettura MVC • Controller: gestisce gli eventi generati dalla View tramite l’invocazione delle apposite funzionalità del Model • View: si occupa della visualizzazione dei risultati e dell’interazione con l’utente Esempio di richiesta MVC Si espone la logica sottostante ad una richiesta esaudita da una sistema basato su architettura MVC 1. l’utente interagisce con l’interfaccia utente (per esempio, clicca su un’icona) e genera eventi 2. il controller gestisce l’evento generato tramite notifica del model 3. il model esegue l’azione richiesta e risponde direttamente alla view (in alcune implementazioni la risposta passa tramite il controller, che in questo caso funziona da puro dispatcher) 18 CAPITOLO 3. SPECIFICA TECNICA 3.1. ARCHITETTURA MVC Figura 3.2: Architettura MVC implementata in CakePHP Ciclo completo MVC CakePHP Si espone la logica sottostante ad una richiesta portata a termine tramite il framework CakePHP su architettura MVC 1. il client richiede una pagina 2. il dispatcher si occupa del parsing della richiesta tramite distinzione di controller, action e parametri. Possono essere eventualmente seguite Routes (“percorsi”) differenti anche non aderenti allo standard /controller/action/parameters. 3. il controller compie l’azione richiesta e raccoglie i dati necessari per la visualizzazione dei risultati, eventualmente tramite l’uso delle sue estensioni, definite Component. Può richiedere l’ausilio di uno o più Model, che a loro volta possono fare uso di specifiche estensioni (Behavior). I dati ricevuti dal Model possono poi essere ulteriormente elaborati dal Controller. 4. i dati vengono inviati alla View, che può fare uso di particolari classi Helper di suppporto o di file (Element) la cui inclusione può aiutare a non ripetere codice necessario in più parti del sistema 5. la View viene visualizzata dall’utente, con la quale può interagire e far ricominciare il ciclo MVC 19 3.1. ARCHITETTURA MVC CAPITOLO 3. SPECIFICA TECNICA Scelte MVC Si è adottata la tecnica “fat model skinny controller”[5] che consiste nel mantenere nel Model gran parte della business logic in maniera da ottenere controller snelli e veloci, atti al solo dispatching delle richieste loro pervenute. 3.1.1 Layer MVC implementati in CakePHP Si procede con una panoramica dei layer MVC con particolare accezione all’implementazione fornita dal framework CakePHP. Model I Model rappresentano il cuore dell’applicazione: in essi viene infatti racchiusa buona o intera parte della business logic. Il framework fornisce alcuni metodi di base per caricamento, aggiornamento, salvataggio e ricerca dei dati, poi manipolabili prima di essere ritornati al Controller. I Model rappresentano l’astrazione necessaria per l’accesso al data layer, che non necessariamente è dato dal classico database relazionale (CakePHP ad esempio supporta un’ampia gamma di sorgenti quali file CSV o server LDAP1 ). Behavior Behaviors work as ways to add common functionality between models. For example, if you store user data in a tree structure, you can specify your User model as behaving like a tree, and gain free functionality for removing, adding, and shifting nodes in your underlying tree structure. [20] I behavior rappresentano l’equivalente dei Component per i Controller: si occupano di funzionalità aggiuntive dei modelli, funzionalità che può essere utile avere comuni per tutti i modelli o che semplicemente risulta opportuno separare per motivi architetturali od organizzativi. Alcuni metodi standard offerti dai behavior sono beforeSave(), afterSave(), beforeDelete(), afterDelete(), beforeFind(): come intuibile rappresentano una sorta di parallelo con i trigger2 implementati in molti RDBMS. La possibilità di automatizzare tali azioni sotto determinate condizioni permette di ridurre al minimo la possibilità di errori 1 The Lightweight Directory Access Protocol, or LDAP, is an application protocol for querying and modifying directory services running over TCP/IP [7] 2 A database trigger is procedural code that is automatically executed in response to certain events on a particular table or view in a database. The trigger is mostly used for keeping the integrity of the information on the database. [8] 20 CAPITOLO 3. SPECIFICA TECNICA 3.1. ARCHITETTURA MVC umani derivanti dalla dimenticanza di azioni obbligatorie all’atto del salvataggio di nuovi record o il compimento di sequenze di azioni particolarmente delicate. Proprio nei behavior è possibile ricercare una buona parte del peso della community CakePHP, poichè vengono rilasciati settimanalmente nuove classi progettate ad hoc per specifici ambiti applicativi. Un esempio di behavior al momento non implementato nel sistema ma di cui si può prevedere un’inclusione nelle prossime release è il cosiddetto SoftDeletableBehavior: tale classe si occupa di gestire la SoftDeletion ossia la rimozione logica e non fisica dei record di database, tramite l’utilizzo di un apposito flag booleano deleted. Controller I controller CakePHP fungono da tramite tra View e Model. In alcuni casi possono procedere ad una ulteriore modellazione dei dati ricevuti da e per i due layer. Component A Component is a class that aids in controller logic. If you have some logic you want to share between controllers (or applications), a component is usually a good fit. [. . . ] Rather than writing a controller method in a single controller that performs this logic, you can package the logic so it can be shared. [19] Le classi Component permettono di estendere la logica presente nei controller, ma considerato il modello “fat model skinny controller”[5] adottato per l’intero sistema non si è ritenuto opportuno procedere con la progettazione di alcun Component. E’ però bene sottolineare come si sia invece fatto ampio uso di Component offerti nativamente dal framework CakePHP (cfr. 4.3.1 nella pagina 58). View Il View layer si occupa della visualizzazione dei dati all’utente finale e del ritorno al controller degli eventuali input ricevuti dall’utilizzatore. Dato che ciascuna View non rappresenta altro che una delle possibili rappresentazioni per una serie di dati ricevuti dal Model, è stato possibile implementare differenti visualizzazioni per medesime azioni; un esempio è dato dalla visualizzazione del piani di studio confermati: tramite la richiesta /students/plan/14 viene richiesta la visualizzazione XHTML di default, mentre tramite la richiesta /students/plan/14.pdf o /students/plan/14.rtf vengono richieste le cor21 3.2. WEB APPLICATION (CLIENT-SERVER) CAPITOLO 3. SPECIFICA TECNICA rispondenti viste PDF o RTF, rispettivamente per la stampa di certificati da parte degli studenti o la modifica da parte della segreteria. Helper A Helper is a class that aids in view logic. Much like a component used among controllers, helpers allow presentational logic to be accessed and shared between views. [...] Most applications have pieces of view code that are used repeatedly. CakePHP facilitates view code reuse with layouts and elements. [21] Le classi Helper rappresentano il parallelo dei Behavior rispetto ai Model: sono cioè delle estensioni delle classi View, delle quali raccolgono i metodi comuni. Un esempio di helper presente di default in CakePHP è l’HTMLHelper (cfr. 4.4.1 nella pagina 60), una classe atta all’output di elementi HTML opportunamente formattati. 3.2 Web application (client-server) In software engineering, a web application or webapp is an application that is accessed via a web browser over a network such as the Internet or an intranet. The term may also mean a computer software application that is hosted in a browsercontrolled environment (e.g. a Java applet) or coded in a browser-supported language (such as JavaScript, possibly combined with a browser-rendered markup language like HTML) and reliant on a common web browser to render the application executable. Web applications are popular due to the ubiquity of web browsers, and the convenience of using a web browser as a client, sometimes called a thin client. The ability to update and maintain web applications without distributing and installing software on potentially thousands of client computers is a key reason for their popularity, as is the inherent support for cross-platform compatibility. [57] Viene illustrato il funzionamento della transazione utente - web-application. 1. l’utente effettua una richiesta tramite il proprio browser al web-server su cui risiede l’applicazione web 22 CAPITOLO 3. SPECIFICA TECNICA 3.3. AJAX Figura 3.3: Funzionamento web-application (modello client-server) 2. il server web gestisce la richiesta, in questo caso redirigendola alla web-application (nel caso di Infostudenti redirige la richiesta al processore PHP) 3. la web-application genera la risposta alla richiesta dell’utente, eventualmente richiedendo a sua volta l’ausilio del database server per il reperimento dei dati necessari 4. il web-server accoglie la risposta generata dalla web-application e si fa carico di recapitarla all’utente 3.3 AJAX Dall’analisi dei requisiti è emersa la necessità di velocizzare e razionalizzare l’interfaccia utente di Infostudenti. Per tale motivo si è ricorso a metodologie di caricamento asincrono. AJAX (Asynchronous JavaScript And XML) is a group of interrelated web development techniques used on the client-side to create interactive web applications. With Ajax, web applications can retrieve data from the server asynchronously in the background without interfering with the display and behavior of the existing page. The use of Ajax techniques has led to an increase in interactive or dynamic interfaces on web pages. Data is usually retrieved using the XMLHttpRequest object. [51] 23 3.3. AJAX CAPITOLO 3. SPECIFICA TECNICA Figura 3.4: Diagramma di funzionamento tecnologia AJAX Si esplicita un esempio di interazione asincrona per la velocizzazione delle pagine del sistema. 1. L’utente finale richiede al server la pagina necessaria per l’inserimento di nuovi elementi nel proprio piano studi 2. il server risponde in modo sincrono inviando la pagina richiesta, che viene visualizzata sul browser dell’utente 3. l’utente clicca sull’icona dell’elemento che vuole inserire: tramite Javascript viene inviata (in background e senza alcuna cognizione da parte dell’utente) una richiesta asincrona al server, che risponde con il solo form necessario per l’inserimento dell’elemento richiesto. Tale form viene “iniettato” nel codice della pagina così che possa essere immediatamente utilizzato dall’utente Tale tecnologia non rappresenta una novità in senso stretto nel mondo del web, dato che altro non è che un utilizzo particolarmente specifico di tecnologie pre-esistenti. In questi ultimi anni si è però assistito ad un fiorire di librerie capaci di semplificare, standardizzare e portare a pienezza tale incrocio di tecnologie. Nel caso specifico di Infostudenti si è fatto uso di jQuery (cfr. 5.3.2 nella pagina 75), un framework Javascript capace di gestire tutti gli aspetti di basso livello delle transazioni asincrone, permettendo così allo sviluppatore di concentrarsi su aspetti più specifici per il successo dell’applicativo. 24 CAPITOLO 3. SPECIFICA TECNICA 3.4. ORM Tipologia Pagina base (senza form) Form Richiesta AJAX Peso (in kb) 30 3 1 Tabella 3.1: Peso (in kb) delle componenti di una ipotetica transazione web Tipologia Pagina base (senza form) Richiesta pagina con form Pagina base con form Totale Peso (in kb) 30 1 33 64 Tabella 3.2: Dati trasferiti in una ipotetica transazione che non faccia uso di AJAX Tipologia Pagina base (senza form) Richiesta AJAX Form Totale Peso (in kb) 30 1 3 34 Tabella 3.3: Dati trasferiti in una ipotetica transazione che faccia uso di AJAX Performance Tramite il caricamento asincrono si risparmia sul caricamento di una pagina completa, poichè si riesce a caricare solo la porzione necessaria all’aggiornamento della stessa. Considerati i valori medi di una transazione (cfr. tabelle in pagina) è facile calcolare come tra una pagina senza AJAX ed una con AJAX vi sia un risparmio di trasferimento dati corrispondente ad un’intera pagina. Tale risparmio si riflette in primis in termini di migliore esperienza utente, non costringendo l’utilizzatore ad attendere inutilmente il caricamento dell’intera pagina ma soltanto la frazione di secondo necessaria per trasferire l’unico frammento aggiornato; in secondo luogo si assiste ad un alleggerimento del carico del server, non costretto a soddisfare una potenziale richiesta aggiuntiva. 3.4 ORM Object-relational mapping (ORM, O/RM, and O/R mapping): in computer software is a programming technique for converting data between incompatible type systems in relational databases and object-oriented programming lan25 3.5. INFOSTUDENTI CAPITOLO 3. SPECIFICA TECNICA guages. This creates, in effect, a "virtual object database" that can be used from within the programming language. [25] Figura 3.5: Diagramma di funzionamento di un generico Object Relational Mapping Grazie all’utilizzo di tale tecnologia si è potuto ottenere un livello di astrazione e controllo del database, il cui accesso è quindi disciplinato tramite apposite chiamate di libreria del framework. Tale scelta ha permesso di slegare il software dal database sottostante ma soprattutto semplificare e alleggerire il codice sorgente (“the fewer the lines of code in a program, the fewer the errors contained within them”). L’inevitabile overhead aggiunto da questo nuovo layer di astrazione è stato giudicato trascurabile se bilanciato con l’estremo controllo degli accessi al database e la pulizia del codice ottenuta tramite il suo utilizzo. La specifica implementazione ORM adottata (Active Record, cfr. 5.1.2 nella pagina 66) viene discussa nella successiva Definizione di prodotto. 3.5 Infostudenti Si procede con la specifica del funzionamento delle sezioni di Infostudenti che sono risultate non banali o che hanno causato i maggiori problemi durante il refactoring. 26 CAPITOLO 3. SPECIFICA TECNICA 3.5.1 3.5. INFOSTUDENTI Piani di studio Figura 3.6: Diagramma di stato dei piani di studio Si esplicita il ciclo di approvazione a cui è soggetto un piano di studi: 1. lo studente esterno fa richiesta di preiscrizione tramite l’apposito form online 2. la segreteria può decidere di approvare o rigettare la richiesta. In caso positivo 27 3.5. INFOSTUDENTI CAPITOLO 3. SPECIFICA TECNICA (a) lo studente viene registrato nel sistema e gli vengono assegnate delle credenziali di accesso (b) allo studente viene assegnato un basilare piano di studi comprensivo dei soli insegnamenti obbligatori per il corso scelto oppure il piano di studi consigliato (cfr. 3.5.2 nella pagina successiva) precedentemente compilato dal personale del conservatorio 3. lo studente può accedere al sistema e procedere con la compilazione del proprio piano di studi 4. una volta completata la compilazione del proprio piano di studi lo studente può confermare il proprio piano, che passa al secondo livello 5. il secondo livello può modificare il piano inserendo o modificando nuovi debiti; se lo approva il piano passa al terzo livello. In caso di rifiuto il piano torna allo studente 6. il terzo livello può modificare il piano in qualsiasi sua parte e infine approvarlo: il piano viene così confermato e approvato definitivamente. Può anche rifiutare il piano e farlo tornare al secondo livello 7. il terzo livello può riaprire la pratica di specifici piani di studio confermati per poterli modificare a proprio piacimento 28 CAPITOLO 3. SPECIFICA TECNICA 3.5.2 3.5. INFOSTUDENTI Piani di studio consigliati Figura 3.7: Diagramma di stato per un piano di studi consigliato Si esplicita il ciclo di richiesta per un piano di studi consigliato per un ipotetico corso X: 1. il piano di studi consigliato esiste: il personale del conservatorio può modificarlo come qualsiasi altro piano di studi 2. il piano di studi consigliato non esiste: viene creato uno studente con relativo utente fittizio, al cui piano di studi vengono preliminarmente assegnati gli insegnamenti obbligatori per il corso X 29 3.5. INFOSTUDENTI 3.5.3 CAPITOLO 3. SPECIFICA TECNICA Esami Figura 3.8: Diagramma di stato degli esami Si esplicita il ciclo di approvazione a cui è soggetto un esame: 1. il docente fa richiesta dell’appello compilando l’apposito form 2. la segreteria considera la richiesta ed eventualmente modifica i dati dell’esame 3. la segreteria può confermare l’appello, al quale da quel momento possono cominciare ad iscriversi gli studenti, oppure rifiutare e farlo tornare al docente per ulteriori modifiche 30 CAPITOLO 3. SPECIFICA TECNICA 3.5.4 3.5. INFOSTUDENTI Creazione nuovi utenti Figura 3.9: Diagramma di stato per la creazione di nuovi utenti Si esplicita il procedimento tramite cui vengono creati nuovi utenti: 1. indipendentemente dal tipo di utente richiesto viene creato un utente completo di username e password (necessarie per poter accedere al sistema) 2. in caso di richiesta di creazione di nuovo studente: creazione studente associato all’utente di cui sopra ed assegnazione insegnamenti obbligatori o piano di studi consigliato, a discrezione della segreteria 3. in caso di richiesta di creazione di nuovo docente: creazione docente assegnato all’utente di cui sopra ed assegnazione dei ruoli permessi 4. in caso di richiesta di creazione di altro personale (diverso da studente e docente): assegnazione all’utente di cui sopra dei soli ruoli permessi 31 3.5. INFOSTUDENTI 3.5.5 CAPITOLO 3. SPECIFICA TECNICA Crediti insegnamenti Si espone la logica sottostante alla determinazione dei crediti attribuili a ciascun insegnamento. Figura 3.10: Diagramma di stato per i crediti di un insegnamento Si esplicita il procedimento tramite cui vengono determinati i crediti di un insegnamento: 1. la riga di piano di studi cui appartiene l’insegnamento ha una docenza assegnata: i crediti sono già stati assegnati 2. la riga di piano di studi cui appartiene l’insegnamento non ha alcuna docenza assegnata: viene determinata la tipologia espressa nella riga di piano di studi e ricercati i crediti predefiniti per tale insegnamento e tipologia. Se esistono vengono ritornati al chiamante. 32 CAPITOLO 3. SPECIFICA TECNICA 3.5.6 3.5. INFOSTUDENTI Crediti riga di piano di studi tipo C Si espone la logica sottostante alla determinazione dei crediti attribuili a riconoscimenti di crediti o autorizzazioni di insegnamenti svolti in altri istituti. Figura 3.11: Diagramma di stato per i crediti di una riga di piano di studi tipo C 33 3.5. INFOSTUDENTI CAPITOLO 3. SPECIFICA TECNICA Si esplicita il processo tramite cui vengono determinati i crediti di una riga di piano studi tipo C: 1. la riga è contrassegnata come svolta: vengono ritornati i crediti già salvati 2. la riga è contrassegnata come da svolgere: vengono calcolati i crediti a partire dalla durata e dal genere salvati nella riga in oggetto (a) genere “pratico”: i crediti sono ottenuti dal rapporto tra la durata (in ore) e l’apposito coefficiente annuale “ore di pratica per credito”. Se tale numero di crediti è superiore al numero massimo di crediti assegnabili per singolo insegnamento pratico allora viene ritornato tale numero massimo, altrimenti il rapporto precedentemente calcolato (b) genere “teorico”: i crediti sono ottenuti dal rapporto tra la durata (in ore) e l’apposito coefficiente annuale “ore di teoria per credito”. Se tale numero di crediti è superiore al numero massimo di crediti assegnabili per singolo insegnamento teorico allora viene ritornato tale numero massimo, altrimenti il rapporto precedentemente calcolato (c) genere “laboratorio”: i crediti sono ottenuti dal rapporto tra la durata (in ore) e l’apposito coefficiente annuale “ore di laboratorio per credito”. Se tale numero di crediti è superiore al numero massimo di crediti assegnabili per singolo laboratorio allora viene ritornato tale numero massimo, altrimenti il rapporto precedentemente calcolato 3.5.7 Crediti riga di piano di studi tipo D Si espone la logica sottostante alla determinazione dei crediti attribuili a laboratori, attività formative pregresse o altre attività fin qui non contemplate. 34 CAPITOLO 3. SPECIFICA TECNICA 3.5. INFOSTUDENTI Figura 3.12: Diagramma di stato per i crediti di una riga di piano di studi tipo D Si esplicita il procedimento tramite cui vengono determinati i crediti di una riga di piano studi tipo D: 1. la riga è contrassegnata come da svolgere: vengono ritornati durata e crediti preventivati nella stessa riga 2. la riga è contrassegnata come svolta: viene effettuata la somma della durata e dei crediti degli elementi tipo D associati (crediti definitivi) 35 3.5. INFOSTUDENTI CAPITOLO 3. SPECIFICA TECNICA 36 Capitolo 4 Definizione di prodotto Si procede con una descrizione dettagliata dei componenti del sistema Infostudenti. 4.1 Database 4.1.1 Modellazione concettuale Il modello concettuale riportato nella pagina seguente contempla le classi principali del sistema Infostudenti. Per evidenti motivi grafici non è stato possibile inserire le proprietà di ciascuna classe, comunque incluse nei successivi schemi di modellazione relazionale. 4.1.2 Specifiche di modellazione relazionale Vengono discusse le scelte effettuate in fase di rimodellazione del database sottostante al sistema Infostudenti. Chiavi esterne Per garantire la consistenza dei dati si è fatto uso di chiavi esterne1 ogniqualvolta ne fosse possibile l’uso. E’ stato inoltre minimizzato il numero di chiavi esterne settabili a NULL, in maniera da obbligare ad un rigoroso controllo preventivo dei dati inseriti. Piani di studio temporanei Nella precedente versione del database la distinzione tra piani di studio temporanei (ossia in stato di modifica) e piani di studio confermati era ottenuta 1 In the context of relational databases, a foreign key is a referential constraint between two tables. [35] 37 4.1. DATABASE CAPITOLO 4. DEFINIZIONE DI PRODOTTO Figura 4.1: Modellazione concettuale del database 38 CAPITOLO 4. DEFINIZIONE DI PRODOTTO 39 Figura 4.2: Modello precedente 4.1. DATABASE 4.1. DATABASE CAPITOLO 4. DEFINIZIONE DI PRODOTTO tramite l’utilizzo di tabelle con i medesimi campi ma nomi differenti (es. piano_studi e piano_studi_temp). Tale scelta progettuale ha portato negli anni alla duplicazione o inutile complicazione di funzioni (dovendo operare su differenti tabelle) ma soprattutto ad un gran numero di errori di inconsistenza (dovendo ogni volta far riferimento ad una delle varie versioni di tabelle disponibili). Si è quindi scelto di unificare tali tabelle temporanee e definitive per mezzo di un campo booleano (tinyint(1)) “temp” che andasse a svolgere il ruolo di discriminatore. Un esempio pratico di semplificazione è dato dalle varie funzioni di assegnazione docenza, voto ed esame, che è stato possibile riprogettare con un unico parametro d’ingresso, ossia l’identificatore della riga interessata (senza quindi dover più fare riferimento alla tabella di riferimento). Piani di studio extra Analogamente a quanto fatto per le righe temporanee si è deciso di dotare le tabelle dei piani di studio di un ulteriore campo booleano “extra”, necessario per la distinzione tra righe di piano di studi il cui insegnamento non è previsto dal proprio corso di studi. Parametrizzazione dei valori Si è cercato di affidare al database quanti più parametri possibile in maniera da svincolarli dal codice (parametri hard-coded ). Un esempio pratico è dato dagli stati possibili per un esame e per un piano di studi, ora interamente gestiti tramite chiavi esterne. Campi booleani In varie tabelle vengono utilizzati campi come “maschio/femmina”, “sì/no” al posto di più pratici e standard campi booleani. Grazie a tale standardizzazione si è potuto semplificare il codice di gestione ed ottimizzare la tipizzazione del database. Rimozione campi inutilizzati Tramite un controllo campo per campo si è proceduto con la rimozione dei campi inutilizzati o inutilmente ridondanti. Tipizzazione dei dati Tutti i campi di database sono stati rivisti per garantirne una più corretta tipizzazione. Grazie alla stretta relazione del framework CakePHP con il sottostante modello database si è ottenuta così una più rigida validazione dei dati: il framework è infatti in grado di rilevare dinamicamente il tipo dei campi di database e agire di conseguenza, sia in fase di validazione dei dati che in fase di inserimento di nuovi record. 40 CAPITOLO 4. DEFINIZIONE DI PRODOTTO 4.1. DATABASE Figura 4.3: Stralcio di codice SQL commentato Chiavi ed indici In un’ottica di conseguimento delle migliori performance si è valutato l’uso di indici sui campi maggiormente utilizzati o che comunque fossero utilizzati come chiavi esterne. Alla stessa maniera si è predisposto l’uso di chiavi UNIQUE nei campi in cui si sia ritenuto necessario ottenere univocità, comunque garantita anche a livello di codice sorgente tramite appositi metodi e controlli forniti dal framework. Rimozione campi ENUM Il fatto che il framework CakePHP presenti alcuni problemi nella gestione dei campi ENUM, unito alla scarsa versatilità e sicurezza di tale soluzione (la modifica delle opzioni di un ENUM è possibile soltanto mediante l’alterazione della struttura stessa della tabella interessata) ha portato alla sostituzione di tali campi con più pratiche chiavi esterne verso tabelle create ad-hoc. In tale maniera è stato possibile irrobustire il sistema e predisporre le basi per eventuali ampliamenti futuri. Standardizzazione dei nomi dei campi Dopo una preventivo adeguamento dei campi di database secondo le convenzioni del framework scelto (cfr. 4.1.3 nella pagina successiva) si è deciso di procedere con una standardizzazione generale dei nomi dei campi utilizzati in tabelle diverse, così da ridurre i casi di ambiguità di significato ed interpretazione. In contemporanea ci si è avvalsi della funzionalità di commentazione offerta da MySQL per commentare ciascun campo. 41 4.1. DATABASE 4.1.3 CAPITOLO 4. DEFINIZIONE DI PRODOTTO Convenzioni di database del framework CakePHP Il framework scelto permette di mantenere nomi arbitrari per le tabelle di database ma incoraggia l’adozione di specifiche convenzioni per ottenere una maggiore standardizzazione dei progetti e velocizzare il lavoro di sviluppo. Si è deciso di aderire a tale convenzioni come da regole sotto elencate: • tutte le tabelle utilizzate dal framework devono possedere una singola chiave primaria per identificare univocamente ciascuna riga • i nomi delle classi dei Model sono singolari e camel-cased2 es. Course • i nomi delle tabelle corrispondono ai rispettivi Model con il nome pluralizzato e senza spazi (sostituiti da underscore _) es. courses • le relazioni hasMany, belongsTo or hasOne sono definite tramite il nome singolare della tabella relazionata seguita dal suffisso _id es. nel modello Plan (tabella plans) si fa riferimento al modello Course (tabella courses) tramite il campo course_id • le relazioni molti a molti (dal framework definite HABTM, da Has-A-and-Belongs-To-Many) sono definite da una tabella intermedia definita dai nomi dei due modelli interessati, pluralizzati e separati da underscore es. modello User può avere molti Role tramite la tabella roles_users • in caso una tabella possieda un campo title o name tale campo verrà utilizzato di default come campo di visualizzazione es. campo name nel modello Teaching: ogniqualvolta venga richiesta la generazione di una selectbox del modello verrà utilizzato il campo name come campo di visualizzazione e il campo id come campo valore • in caso una tabella possieda un campo created (tipo DATE) o modified (tipo DATE) il framework ne provvederà automaticamente alla gestione, rispettivamente all’atto della creazione o della modifica del modello relazionato 2 CamelCase or medial capitals is the practice of writing compound words or phrases in which the elements are joined without spaces, with each element’s initial letter capitalized within the compound, and the first letter can be upper or lower case — as in LaBelle, BackColor, MacGyver, or iPod. The name comes from the uppercase "bumps" in the middle of the compound word, suggestive of the humps of a camel [9] 42 CAPITOLO 4. DEFINIZIONE DI PRODOTTO 4.1. DATABASE Figura 4.4: Modello relazione finale (completo di proprietà) 43 4.1. DATABASE CAPITOLO 4. DEFINIZIONE DI PRODOTTO Figura 4.5: Modello relazionale finale (solo chiavi primarie ed esterne) 44 CAPITOLO 4. DEFINIZIONE DI PRODOTTO 4.2. CLASSI MODEL Figura 4.6: Gerarchia classe Model ed Helper 4.2 Classi Model Le classi Model rappresentano il cuore dell’intero sistema poichè si è adottata la tecnica “fat model skinny controller”[5]. Ciascun modello estende AppModel che a sua volta estende Model, così che tutti i modelli si trovano ad ereditare i seguenti campi: • array validate: contiene le regole di validazione per ciascun campo del modello. CakePHP fornisce un set di regole comuni come email, numeric, minLength, boolean, date, notEmpty, url, estendibili tramite overloading, oppure è possibile crearne di nuove ad-hoc • array hasOne, hasMany, belongsTo, hasAndBelongsToMany: attributi rappresentanti le relazioni tra i modelli es. Student->hasMany(array(’Student’ => array(’foreign_key’ => ’course_id’))) 45 4.2. CLASSI MODEL CAPITOLO 4. DEFINIZIONE DI PRODOTTO • bool useTable: settato a false in caso il modello non si appoggi ad una tabella di database • string primaryKey: di default settato a id, rappresenta la chiave primaria della tabella di un modello es. nella tabella years si è deciso di utilizzare il campo anno come chiave primaria, motivo per cui nella classe Year si sia definito definito this->primaryKey=’anno’ • array _schema: contiene lo schema della tabella di database del modello, comprensiva di tipi e relazioni Alla stessa maniera tutti i modelli si trovano ad ereditare alcuni metodi di utilità, di cui viene qui esposta una panoramica dei più utilizzati durante il refactoring di Infostudenti: • public bool save(array data, boolean validate=true, array fieldList=array()): permette di aggiornare i dati del modello sul quale è invocato o crearni di nuovi, a seconda della presenza o meno dell’indice data[’Model’][’id’] (dove data rappresenta l’array associativo contenente i dati passati al modello). Il parametro opzionale validate è necessario invece per disabilitare al bisogno la validazione dei campi, validazione che viene automaticamente effettuata dal framework ogni volta venga richiesto un salvataggio di dati. L’ultimo parametro opzionale fieldList rappresenta una lista dei campi interessati, in maniera che si possano decidere a priori i campi che verranno aggiornati (questo perchè altrimenti il framework cerca di salvare tutti i campi presenti nell’array data). • public bool saveAll(array data, array options=array()): il metodo in oggetto si occupa del salvataggio dei dati del modello su cui è invocato e contemporaneamente dei dati relazionati (es. i dati di un modello associato con una relazione hasMany). Se invocato su un database supportante le transazioni riesce a garantire l’atomicità del salvataggio. Si è rivelato fondamentale in moltissime parti del sistema proprio per la sua capacità di salvataggio di diversi tipi di dati correlati, semplificando enormemente la base di codice e garantendo l’integrità della base dati. 46 CAPITOLO 4. DEFINIZIONE DI PRODOTTO 4.2. CLASSI MODEL • public bool updateAll(array fields, array conditions): trasposizione della funzione SQL UPDATE, permette l’aggiornamento di più campi sottostanti alle condizioni passate come parametro (in forma di array associativo) • public bool saveField(string fieldName, string fieldValue, validate=false): metodo ausiliario che permette di salvare un singolo campo di un determinato modello es. $this->Student->saveField(’studentstatus’, 2) • public bool delete(int id, boolean cascade = true): permette di eliminare un record del modello sul quale è invocato; tramite il parametro booleano cascade (di default impostato a true) il framework si occupa di eliminare anche i dati relazionati la cui eliminazione è stata pianificata in fase di progettazione del sistema (in sostanza è un parallelo della clausola ON DELETE CASCADE ottenuta con le chiavi esterne di MySQL). Si noti che gran parte di tali clausole ON sono state impostate a RESTRICT così da obbligare la gestione esplicita dei dati relazionati. • public array view(int id): metodo non ereditato da Model ma definito in gran parte dei modelli per il reperimento del dettaglio dei dati di un singolo record. In caso tale metodo non sia stato definito viene utilizzato il metodo public array read(array fields, int id). Per i modelli particolarmente pesanti si è però evitato tale approcio di default poichè read() legge tutti i dati relazionati, operazione che può risultare particolarmente onerosa in caso di modelli con un gran numero di chiavi esterne. Si procede ora con una panoramica dei modelli definiti per il sistema Infostudenti. 4.2.1 Application Il modello gestisce le iscrizioni degli studenti agli esami e le relative presenze/assenze agli appelli. 4.2.2 Check Il modello gestisce i controlli eseguiti dalla segreteria su ciascuno studente: esenzioni, borse di studio, contratti 150 ore. 47 4.2. CLASSI MODEL 4.2.3 CAPITOLO 4. DEFINIZIONE DI PRODOTTO Classroom Il modello gestisce le aule d’esame. 4.2.4 Course Il modello gestisce i corsi d’insegnamento. Si procede con una panoramica dei metodi specifici. • array public lista(array conditions): ritorna la lista dei corsi completa degli studenti associati e aderenti alle condizioni passate. Metodo utilizzato in tutte le sezioni del software in cui sia necessaria la selezione di studenti a partire dal corso di appartenenza • int piano_consigliato(int course_id): controlla l’esistenza ed in caso negativo procede con la creazione di un piano di studi consigliato per il corso passato. Ritorna l’ID dello studente fittizio associato al piano di studi consigliato (cfr. 3.5.2 nella pagina 29) • bool insegnamento_obbligatorio(int course_id, int teaching_id, int anno_frequenza): controlla se l’insegnamento passato sia obbligatorio per il corso e anno passati come parametri 4.2.5 CoursesTeaching Il modello gestisce le relazioni corso-insegnamento, ossia gli insegnamenti relativi a ciascun corso e le loro caratteristiche (tipologia, obbligatorietà). 4.2.6 Exam Il modello gestisce gli esami. Si procede con una panoramica dei metodi specifici. • public array lista_esami_per_docenza(int qualification_id): ritorna un array associativo contenente la lista degli esami disponibili per una data docenza • public bool confirm(int exam_id): ritorna un booleano rappresentante l’esito della conferma di un esame 48 CAPITOLO 4. DEFINIZIONE DI PRODOTTO 4.2. CLASSI MODEL • public array esami_per_studente(int student_id): ritorna un array associativo contenente gli esami cui può iscriversi uno studente 4.2.7 Examstatus Il modello gestisce gli stati possibili per un singolo esame es. confermato dalla segreteria, rifiutato. 4.2.8 Genre Il modello gestisce i generi associabili ad un piano di studi di tipo C es. pratico, teorico. 4.2.9 Grant Il modello gestisce le relazioni utente-ruolo, ossia i permessi di ciascun utente. 4.2.10 Instrument Il modello gestisce gli strumenti musicali associabili a ciascuno studente. 4.2.11 Log Il modello gestisce lo storico delle azioni effettuate nel sistema, in maniera da poter mantenere una traccia di chi ha fatto cosa. • public bool log_user(int user_id, int planstatus_id, string note=null): salva una riga di storico per l’utente passato, dove planstatus_id rappresenta l’identificatore dello stato del piano di cui viene richiesto il salvataggio • public bool log_student(int student_id, int planstatus_id, string note=null): salva una riga di storico per lo studente passato. Fa uso del metodo log_user per il completamento della richiesta 4.2.12 Page Il modello gestisce i testi introduttivi o di ausilio a particolari sezioni del software es. norme ministeriali per il secondo livello. 49 4.2. CLASSI MODEL 4.2.13 CAPITOLO 4. DEFINIZIONE DI PRODOTTO Plan Il modello gestisce le righe di piani di studio che rappresentano insegnamenti e debiti. Si procede con una panoramica dei metodi specifici. • public array get(int plan_id): ritorna l’array associativo contenente la riga di piano di studi identificata dall’ID passato. Si occupa di reperire anche tutti i dati relazionati. Viene utilizzata soprattutto via AJAX. • private void popola_docenti(array &plan): popola la riga di piano di studi passata per riferimento con i docenti aventi docenze per l’insegnamento rappresentato nella riga • private void popola_crediti(array &plan): popola i crediti della riga di piano di studi passata per riferimento (cfr. 3.5.5 nella pagina 32) • private void popola_docenza(array &plan): popola la riga di piano di studi passata per riferimento con le docenze assegnate al docente ed insegnamento scelto • private void popola_lista_voti(array &plan): popola la lista dei voti assegnabili alla riga di piano di studi passata per riferimento es. assolto/idoneo/voto numerico • private void popola_lista_esami(array &plan): popola la lista degli esami assegnabili alla docenza della riga di piano di studi passata per riferimento • private int crediti(array &plan): ritorna il numero di crediti per la riga di piano di studi passata per riferimento (cfr. 3.5.5 nella pagina 32) 4.2.14 Planstatus Il modello gestisce gli stati possibili per un piano di studi es. confermato, rientro. 4.2.15 Preiscription Il modello gestisce le richieste di iscrizione da parte di utenti esterni al sistema, poi eventualmente confermate e formalizzate dalla segreteria. 50 CAPITOLO 4. DEFINIZIONE DI PRODOTTO 4.2.16 4.2. CLASSI MODEL Presence Il modello gestisce i possibili tipi di presenza dei singoli studenti iscritti a ciascun esame es. studente presente, studente assente. 4.2.17 Qualification Il modello gestisce le docenze, ossia le relazioni docente-insegnamento-anno accademico es. Mario Rossi insegna Pianoforte nell’A.A. 2008/2009. Si procede con una panoramica dei metodi specifici.. • public int esiste_docenza_per_docente(int teacher_id, int teaching_id, int aa): ritorna l’identificatore della docenza avente docente, insegnamento ed anno accademico passato. In caso tale docenza non esista viene ritornato 0. • public array docenze_per_docente(int teacher_id, int teaching_id=0, int aa=0): ritorna un array associativo contenente la lista delle docenze per il docente, insegnamento ed anno accademico passato. Si noti che il solo parametro obbligatorio è dato dall’ID docente, in maniera da poter combinare i vari parametri non obbligatori e poter riutilizzare la medesima funzione per ricerche più o meno mirate. 4.2.18 Requirement Il modello gestisce le propedeuticità degli insegnamenti, ossia gli insegnamenti obbligatori per poter accedere a specifici insegnamenti es. Arte scenica I è propedeutico per Arte scenica II. 4.2.19 Role Il metodo gestisce i ruoli assumibili da ciascun utente es. segreteria, III livello. Si noti che un utente non studente può avere da un minimo di un ruolo fino ad un massimo di tutti i ruoli (cfr. 3.5.4 nella pagina 31). 51 4.2. CLASSI MODEL 4.2.20 CAPITOLO 4. DEFINIZIONE DI PRODOTTO Student Il modello gestisce gli studenti registrati nel sistema. Si procede con una panoramica dei metodi specifici. • private array get_contain_conditions(bool temp=0): ritorna l’array associativo opportunamente formattato contenente le condizioni per il Behavior Containable, necessario per il reperimento di tutti i dati relazionati ad un piano di studi. Il parametro booleano temp è necessario per la discriminazione tra piani di studio in modifica e definitivi • private void crediti_stats(array &plan): popola le statistiche dei crediti per il piano di studi completo passato per riferimento • private void durata_piano(array &plan): determina la durata del piano di studi passato per riferimento • private void plan_stats(array &plan): popola le statistiche del piano di studi passato per riferimento. Fa uso di funzioni ausiliari come crediti_stats(student) • private current_teachings(int student_id, int temp=0, int extra=0): ritorna un array contenente gli insegnamenti già contenuti nel piano di studi di uno studente. Si notino i parametri non obbligatori temp ed extra, rispettivamente per la selezione di piani di studio temporanei o extra. E’ utilizzata principalmente tramite chiamate AJAX • public array plan(int student_id): ritorna un array associativo contenente l’intero piano di studi confermato dello studente passato • public array temp_plan(int student_id): ritorna un array associativo contenente l’intero piano di studi non confermato dello studente passato • private bool check_matricola(string matricola): funzione ausiliaria invocata all’atto della creazione di nuovi studenti. Controlla l’univocità della matricola passata (comunque garantita a basso livello dalla chiave UNIQUE posta sull’analogo campo di database) 52 CAPITOLO 4. DEFINIZIONE DI PRODOTTO 4.2. CLASSI MODEL • private bool check_piano(int student id, array params): funzione ausiliaria per le procedure di rientro, effettua un controllo di coerenza del database. Ritorna true se non esistono righe di piano di studi aderenti alle condizioni passate come secondo parametro • private bool finalizza_piano(int student_id): funzione ausiliaria per le procedure di avanzamento piano. Si occupa della conferma di un piano di studi temporaneo. • public bool plan_confirm(int student_id): fa avanzare un piano di studi es. da secondo livello a terzo livello. In caso il piano sia in rientro o terzo livello provvede alla conferma tramite la funzione finalizza_piano. • private int planstatus(int student_id): funzione ausiliaria che ritorna l’ID dello stato del piano di studi dello studente passato • private bool rientro(int student_id): fa rientrare il piano di studi di uno studente confermato. Ritorna true in caso il rientro vada a buon fine o la pratica sia già stata riaperta. • private bool inserisci_insegnamenti_obbligatori(int student_id): inserisce nel piano di studi temporaneo dello studente passato gli insegnamenti obbligatori per il corso di studi scelto • private int get_course_id(int student_id): ritorna l’ID corso dello studente passato • public bool inizializza_studente(int student_id, int course_id=0, bool copia_def=true): si occupa dell’inizializzazione del piano di studi dello studente passato; in caso course_id sia diverso da zero assegna il piano di studi consigliato, altrimenti i soli insegnamenti obbligatori previsti. Il parametro copia_def definisce se debba essere creata una copia definitiva delle righe temporanee create (uno studente deve sempre avere un piano di studi confermato parallelo a quello in stato di modifica). • private bool assegna_piano_consigliato(int student_id, int course_id): assegna allo studente passato il piano di studi consigliato per il corso passato 53 4.2. CLASSI MODEL CAPITOLO 4. DEFINIZIONE DI PRODOTTO • private bool assegna_docenze_docente_scelto(int student_id, int teacher_id): assegna al piano di studi dello studente le docenze disponibili per il docente passato come parametro • public array crediti_per_tipologia(int student_id, bool check=false): ritorna un array contenente i crediti di uno studente suddivisi per anno e tipologia. In caso il parametro check sia positivo l’array viene integrato con i controlli sui crediti massimi e minimi attribuili per ciascuna tipologia ed anno • private bool set_planstatus(int student_id, int planstatus_id): setta il nuovo stato del piano di studi dello studente passato occupandosi contemporaneamente delle operazioni di compilazione dello storico 4.2.21 Studentstatus Il modello gestisce gli stati possibili per uno studente es. laureato, ritirato. 4.2.22 Tax Il modello gestisce le tasse pagate dagli studenti. 4.2.23 Teacher Il modello gestisce i docenti inseriti nel sistema. Si procede con una panoramica dei metodi specifici. • public array listing(): ritorna un array associativo della lista docenti nella forma {’teacher-id’ => ’cognome nome’} • public array classe(int qualification_id): tenente gli studenti interessati dalla docenza passata 4.2.24 Teaching Il modello gestisce gli insegnamenti inseriti nel sistema. 54 ritorna un array associativo con- CAPITOLO 4. DEFINIZIONE DI PRODOTTO 4.2.25 4.2. CLASSI MODEL Teachingstatus Il modello gestisce gli stati possibili per ciascun insegnamento es. ordinario, debito. 4.2.26 TipoCPlan Il modello gestisce le righe di piani di studio rappresentanti riconoscimenti di crediti o autorizzazioni di insegnamenti svolti in altri istituti. Si procede con una panoramica dei metodi specifici. • public array get(int tipo_c_plan_id): ritorna l’array associativo contenente la riga di piano di studi identificata dall’ID passato. Si occupa di reperire anche tutti i dati relazionati. Viene utilizzata principalmentre via AJAX • public int crediti(array &plan): ritorna il numero di crediti assegnati alla riga di piano di studi passata per riferimento (cfr. 3.5.6 nella pagina 33) 4.2.27 TipoCType Il modello gestisce i tipi di piani di studio di tipo C es. riconoscimento, autorizzazione. 4.2.28 TipoDElement Il modello gestisce gli elementi associati ad alcuni piani di studio di tipo D. 4.2.29 TipoDPlan Il modello gestisce le righe di piani di studio rappresentanti laboratori, crediti per attività formative pregresse o altre attività. Si procede con una panoramica dei metodi specifici. • public array get(int tipo_d_plan_id): ritorna l’array associativo contenente la riga di piano di studi identificata dall’ID passato. Si occupa di reperire anche tutti i dati relazionati. Viene utilizzata principalmente via AJAX • private array durata_e_crediti_effettivi(array plan): effettua i necessari calcoli per la stima della durata e dei crediti effettivi associati ad una riga di piano di studi avente elementi di tipo D associati 55 4.2. CLASSI MODEL CAPITOLO 4. DEFINIZIONE DI PRODOTTO • public int crediti(array &plan): ritorna il numero di crediti assegnati alla riga di piano di studi passata per riferimento (cfr. 3.5.7 nella pagina 34) 4.2.30 TipoDType Il modello gestisce i tipi di piani di studio di tipo D es. laboratorio a progetto, crediti per attività formative pregresse. 4.2.31 TipoDTypology Il modello gestisce le tipologie di piani di studio di tipo D es. stage, tirocinio. 4.2.32 Tipology Il modello gestisce le tipologie associabili a ciascun insegnamento: • tipologia A: di base (la cui presenza è possibile in tutti i piani di studi) • tipologia B: caratterizzanti (specifici per il corso di studi intrapreso) • tipologia C: affini (affini al corso di studi intrapreso) • tipologia D: altro fin qui non contemplato 4.2.33 User Il modello gestisce gli utenti del sistema indipendentemente dai ruoli assunti. Si procede con una panoramica dei metodi specifici. • public string generate_unique_username(string seed=null): genera un nuovo username univoco, eventualmente usando il seed opzionale passato come parametro • private bool check_unique_username(string username): funzione ausiliaria all’atto della creazione di nuovi utenti. Controlla l’univocità del nome utente passato (comunque garantito a basso livello dalla chiave UNIQUE posta come vincolo sull’analogo campo di database) 56 CAPITOLO 4. DEFINIZIONE DI PRODOTTO 4.2. CLASSI MODEL Figura 4.7: Array Containable per il reperimento dei dati relativi ad un piano di studi 4.2.34 Years Il modello gestisce gli anni accademici inseriti nel sistema ed i relativi parametri. Si procede con una panoramica dei metodi specifici. • public bool check_periodo_compilazione_piano_studi(): controlla che la data corrente sia compresa nella finestra temporale in cui gli studenti possono procedere alla compilazione del proprio piano di studi 4.2.35 Classi Behavior ContainableBehavior This model behavior allows you to filter and limit model find operations. Using Containable will help you cut down on needless wear and tear on your database, increasing the speed and overall performance of your application. The class will also help you search and filter your data for your users in a clean and consistent way. [58] Il behavior Containable ha rappresentato un punto fondamentale nelle modalità di sviluppo: potendo contare sul reperimento dei dati relazionati tramite la dichiarazione di semplici array associativi, si è eliminato non meno del 30% del codice del precedente sistema, incrementando al contempo affidabilità e performance complessive. Si noti come il codice SQL generato tramite Containable non rappresenti sempre la soluzione ottimale in 57 4.3. CLASSI CONTROLLER CAPITOLO 4. DEFINIZIONE DI PRODOTTO termini di prestazioni assolute, poichè durante la sua progettazione sono state intraprese specifiche scelte architetturali per poterne garantire il funzionamento nella più ampia varietà di contesti, a volte però a discapito delle prestazioni; non a caso uno dei punti principali della roadmap di CakePHP è dato dall’ottimizzazione di tale behavior. Per quanto riguarda il caso specifico di Infostudenti l’overhead rilevato è stato giudicato trascurabile e nessun metodo ha richiesto l’utilizzo di query SQL manuali. DateConverterBehavior Tramite questo behavior si è gestita la conversione delle date in formato italiano dalle View ai Model, poichè il database necessita di date in formato standard yyyy-mm-dd hh:ii:ss FixCalculatedFieldsBehavior Tramite questo behavior si è gestita la riformattazione di alcuni array generati dal framework CakePHP: normalmente infatti i campi generati tramite funzioni SQL quali MAX(), MIN(), AVG() vengono inserite su indice 0 invece che nell’array associativo del modello di riferimento. Tramite questo behavior si è potuto ovviare a tale particolarità e velocizzare il parsing dei risultati. 4.3 Classi Controller Come da accordi con il relatore non vengono discusse le classi Controller poichè strettamente mappate sulle funzionalità implementate nei Model, verso le quali funzionano da meri dispatcher da e per il View layer, come previsto dalla logica “fat model skinny controller”[5]. 4.3.1 Classi Component Si procede con una panoramica delle classi Component utilizzate per il refactoring del sistema Infostudenti. RequestHandler The Request Handler component is used in CakePHP to obtain additional information about the HTTP requests that are made to your applications. You can use it to inform your controllers about Ajax as well as gain additional insight into content types that the client accepts and automatically changes to the 58 CAPITOLO 4. DEFINIZIONE DI PRODOTTO 4.3. CLASSI CONTROLLER Figura 4.8: Organizzazione delle view basata sui tipi di richiesta ricevuti appropriate layout when file extensions are enabled. [...] When used in conjunction with Router::parseExtensions() RequestHandler will automatically switch the layout and view files to those that match the requested type. [59] Grazie all’utilizzo di tale componente, capace di distinguere le richieste automaticamente in base alla loro modalità di trasmissione ed alla loro estensione (es. trasmissione asincrona AJAX oppure estensione .pdf), è stato possibile mantenere un’organizzazione rigorosa del codice e distinguere con facilità le modalità di risposta necessarie. Un esempio è dato dalle modalità di richiesta del piano di studi di un medesimo studente: /students/plan/14 risponde alla normale visualizzazione XHTML, /students/view/14.rtf all’emissione di certificati in formato RTF e /students/view/14.pdf all’emissione di certificati in formato PDF, tutte richieste riconducibili allo stesso metodo del controller public array plan(int id) ma a View differenti, come previsto dall’architettura MVC. AuthComponent La presenza di un componente nativo per l’autenticazione e la gestione degli utenti ha rappresentato sicuramente un motivo di forte preferenza verso CakePHP. Grazie a tale componente è stato infatti possibile delegare al framework l’intera procedura di autenticazione degli utenti ed ottenere nel contempo un processo di login solido e quanto più sicuro possibile, potendo contare sui controlli di un’intera community di sviluppatori. SessionComponent L’utilizzo di uno specifico componente per la manipolazione delle sessioni3 HTTP ha permesso di delegare al framework gran parte delle problematiche relative 3 In computer science, in particular networking, a session is a semi-permanent interactive information interchange, also known as a dialogue, a conversation or a meeting, between two or more communicating devices, or between a computer and user [...]. A session is set up or established at a certain point in time, and torn down at a later point in time. [...] A session is typically, but not always, stateful, meaning that at 59 4.4. CLASSI VIEW CAPITOLO 4. DEFINIZIONE DI PRODOTTO alla sicurezza delle stesse, oltre a garantire l’indipendenza dall’implementazione, potendo contare su tre differenti tipi di mantenimento dei dati di sessione (file, cache, database). Nel caso di Infostudenti si è optato per le sessioni file-based, ritenute essere il miglior compromesso tra prestazioni, facilità di implementazione e sicurezza dei dati. 4.4 Classi View Per ciascuna action pubblica di ciascun controller è predisposto un file nella directory /app/view/:controller/:action. In caso vi sia stata la richiesta di gestire differenti tipi di dato per una medesima action si sono predisposte le directory /app/view/:controller/:extension/:action. 4.4.1 Helper HTMLHelper Di tale helper, nativo di CakePHP, si sono utilizzati prevalentemente due soli metodi, preferendo affidarsi a codice HTML customizzato per qualsiasi altra necessità. • public string link(string title, array url=null, array htmlAttributes=null, string confirmMessage=null, bool escapeTitle=true): ritorna il codice HTML di un link puntante verso l’URL interno o esterno passato come parametro url, di cui viene preventivamente effettuato il parsing dalla classe statistica Router • public string image(string path, array htmlAttributes=array()): ritorna il codice HTML dell’immagine passata come parametro. Fa riferimento alla directory /app/webroot/img FormHelper La classe FormHelper si occupa delle generazione di elementi di input nel corretto formato HTML. Se vengono rispettate particolari convenzioni nelle modalità di trasferimento dati dal controller alla view è capace di popolare automaticamente gli elementi di input, oltre che selezionare il corretto elemento HTML da utilizzare. Il metodo principale, public string input(string fieldName, array options=array()), è infatti capace di rilevare automaticamente la presenza di eventuali dati provenienti dal controller e utilizzare il corretto markup HTML per la visualizzazione. Se ad esempio viene richiamato least one of the communicating parts needs to save information about the session history in order to be able to communicate, as opposed to stateless communication, where the communication consists of independent requests with responses. [22] 60 CAPITOLO 4. DEFINIZIONE DI PRODOTTO 4.4. CLASSI VIEW Figura 4.9: Esempio di utilizzo della classe FormHelper $form->input(’course’) ed esiste un array associativo contenente la lista di corsi, l’helper si occuperà di stampare una selectbox popolata con gli opportuni valori e chiavi. JavascriptHelper ed AjaxHelper Il framework permette di autogenerare anche codice Javascript ma si è deciso di non avvalersi di tali funzionalità, preferendo mantenere l’intera base di codice Javascript in file separati e denominati da estensione .js. Ciò ha permesso di mantenere il codice HTML estremamente pulito e leggibile e nel contempo ha consentito di separare quanto più possibile markup e logica di business. TimeHelper L’helper ha permesso di convertire le date e gli orari ottenuti dal database in opportuno formato italiano. InfostudentiGenericHelper Questo helper, sviluppato ad hoc per il sistema Infostudenti, ha permesso di centralizzare le funzionalità di visualizzazione necessarie per più view. Elenchiamo i metodi che compongono la classe. • public string fullname(array user): ritorna cognome e nome di un utente. Viene utilizzato in qualsiasi parte del software in cui un utente debba essere esplicitato • public void voto(array &plan): stampa e formatta stilisticamente la tipologia di voto corretta per la riga di piano di studi passata per riferimento • public void esame(array &plan): stampa e formatta stilisticamente data e link dell’esame correlato alla riga di piano di studi passata per riferimento • private string esplicita_numero(int numero): funzione ausiliaria per l’esplicitazione in lettere di un dato intero passato 61 4.4. CLASSI VIEW CAPITOLO 4. DEFINIZIONE DI PRODOTTO • public string menu(array links, array htmlAttributes=array()): ritorna un menù dinamico basato su CSS a partire dall’array di link passati. Si occupa anche dell’evidenziazione della voce di menù correntemente attiva • public string link_piano_studi(array &student): ritorna un link opportunamente formattato e diretto al piano di studi di uno studente passato per riferimento. Tale link può variare a seconda dello stato del piano di studi dello studente InfostudentiPlanHelper Si occupa della specifica formattazione di array concernenti i piani di studio degli studenti. • public array certificato(&student): ritorna una versione opportunamente formattata del piano di studi passato. E’ necessario per la standardizzazione degli array passati alle view di espostazione in PDF ed RTF (cfr. 5.6 nella pagina 81), che necessitano di una minima parte dei dati visualizzati in quelle XHTML. 62 Capitolo 5 Strumenti utilizzati 5.1 PHP Framework A software framework, in computer programming, is an abstraction in which common code providing generic functionality can be selectively overridden or specialized by user code providing specific functionality. Frameworks are a special case of software libraries in that they are reusable abstractions of code wrapped in a well-defined API, yet they contain some key distinguishing features that separate them from normal libraries. [37] I framework permettono di concentrare la propria attenzione sugli aspetti di più alto livello o più specifici per il successo dell’applicativo piuttosto che su tutti gli aspetti di basso livello che solitamente si ripetono di progetto in progetto. I framework offrono infatti un layer di librerie, funzionalità e componenti riutilizzabili sui quali è possibile basare altri software, che vanno quindi a poggiare su una base di codice solitamente ben testato, frutto di soluzioni standardizzate, mantenute ed aggiornate nel tempo, sia dal punto di vista funzionale che della sicurezza. Un buon numero di framework obbliga poi all’utilizzo di convenzioni architetturali e progettuali nei confronti del software in sviluppo, aiutando ad incrementarne il grado di qualità o comunque di facilitarne la standardizzazione e le conseguenti possibilità di manutenzione ed ampliamento. E’ doveroso comunque sottolineare come l’utilizzo di framework e in generale di librerie di terze parti porti inevitabilmente ad un ampliamento della base di codice, parte della 63 5.1. PHP FRAMEWORK CAPITOLO 5. STRUMENTI UTILIZZATI quale sarebbe stato possibile evitare poichè non utile ai fini del progetto specifico. Non è poi da sottovalutare la più o meno ripida curva d’apprendimento che deve essere valutata e bilanciata con gli eventuali benefici apportati dal framework per il successo e la qualità del progetto finale. Alcuni sviluppatori lamentano anche la rigidità dei framework, che a volte rende complicate azioni che di base non lo sarebbero. Inoltre in caso di problemi o di necessità di debug è più difficile risalire alle cause, considerando la mole di righe di codice di cui solitamente consta un framework di medie dimensioni. 5.1.1 Caratteristiche valutate per la scelta Si procede con una lista delle caratteristiche valutate per la scelta del framework. Architettura Come da requisiti non funzionali il framework deve implementare una solida architettura MVC, in maniera da poterne sfruttare tutti i vantaggi (cfr. 3.1). Autenticazione Il framework deve obbligatoriamente possedere un modulo di autenticazione, in maniera da poter delegare questo sensibile aspetto del sistema. ORM L’accesso al database deve avvenire tramite apposite chiamate di libreria funzionanti da wrapper e non direttamente tramite query scritte a mano, poco flessibili e passibili di un gran numero di errori di sintassi. Tale layer di astrazione sul database layer deve poter consentire di utilizzare tecniche di caching in caso vengano trattate query particolarmente onerose. AJAX L’utilizzo di AJAX e in generale di metodi di caricamento asincrono deve essere favorito e semplificato. Data validation and sanitization Il framework deve occuparsi delle fasi di validazione dei tipi di dati e della sanitizzazione di quelli problematici che potrebbero dare adito a problemi di sicurezza es. XSS (cfr. 1.2). Object-oriented Il framework deve essere orientato agli oggetti per garantire solidi paradigmi di progettazione quali incapsulamento, ereditarietà e polimorfismo, capaci di assicurare 64 CAPITOLO 5. STRUMENTI UTILIZZATI 5.1. PHP FRAMEWORK sicurezza dei dati e flessibilità di sviluppo e facilitare la manutenzione e l’ampliamento del sistema. Scaffolding, CRUD code generation Scaffolding is a meta-programming method of building database-backed software applications. It is a technique supported by some model-view-controller fra- meworks, in which the programmer may write a specification that describes how the application database may be used. The compiler uses this specification to generate code that the application can use to create, read, update and delete database entries, effectively treating the template as a "scaffold" on which to build a more powerful application. [39] La possibilità di auto-generazione delle parti di codice CRUD 1 permette di ottenere un prototipo funzionante in brevissimo tempo: dopo un’attenta modellazione database in CakePHP è infatti sufficiente invocare da console il comando bake per ottenere rapidamente il codice di base di modelli, controller e view su cui poter cominciare a lavorare. Tale automatismo permette di evitare molti banali errori umani e minimizzare il tempo necessario per la stesura delle sezioni di codice ripetitivo. Apprendimento Considerate le tempistiche del progetto è stato necessario valutare anche la difficoltà insita in ciascun framework e le relative curve d’apprendimento; in tale compito sono stati di estremo aiuto articoli e recensioni reperibili in rete oltre naturalmente alla documentazione ufficiale accompagnante ogni framework. Qualità della documentazione Considerando che i framework PHP sono in massima parte progetti relativamente giovani (nell’ordine dei 3-4 anni) è necessario valutare la presenza e la qualità di documentazione a supporto delle librerie e componenti fornite. Community di supporto Considerata la natura in continuo sviluppo della stragrande maggioranza dei framework considerati è bene valutare l’attività e la qualità delle community 1 Create, read, update and delete (CRUD) are the four basic functions of persistent storage. Sometimes CRUD is expanded with the words retrieve instead of read or destroy instead of delete. It is also sometimes used to describe user interface conventions that facilitate viewing, searching, and changing information; often using computer-based forms and reports. [38] 65 5.1. PHP FRAMEWORK CAPITOLO 5. STRUMENTI UTILIZZATI Figura 5.1: Google Trends: comparazione framework PHP al 26.11.2009 orbitanti attorno a ciascun framework, in maniera da poter valutare lo stato di salute dei progetti ed avere supporto in caso di eventuali problemi non risolvibili autonomamente. 5.1.2 CakePHP (v. 1.2.5) CakePHP è il framework scelto per il sistema Infostudenti. Si procede quindi con una panoramica delle caratteristiche peculiari che hanno portato a preferirlo nei confronti dei concorrenti. Ruby on Rails Il framework CakePHP è stato progettato riprendendo molti aspetti del più famoso Ruby on Rails [41] per il linguaggio Ruby. Tale framework ha ispirato una buona parte dei framework PHP oggi esistenti, rappresentando un punto di svolta nel mondo dello sviluppo web. Purtroppo presunti problemi di performance [42] e scalabilità [43] del linguaggio Ruby hanno ridotto la sua capacità di adozione: ciononostante ha avuto il grande pregio di avere aperto e favorito la strada a framework scritti in altri linguaggi ma con le medesime caratteristiche e funzionalità. Da Ruby on Rails CakePHP riprende i paradigmi • DRY ("Don’t Repeat Yourself ”): le definizioni devono essere poste una volta soltanto • "Convention Over Configuration": lo sviluppatore deve aver bisogno di mettere mano alla configurazione soltanto per ciò che differisce dalle convenzioni Active Record Pattern 66 CAPITOLO 5. STRUMENTI UTILIZZATI 5.1. PHP FRAMEWORK In software engineering, the Active Record Pattern is a design pattern found in software that stores its data in relational databases. It was named by Martin Fowler in his book “Patterns of Enterprise Application Architecture” [45]. The interface to such an object would include functions such as Insert, Update, and Delete, plus properties that correspond more-or-less directly to the columns in the underlying database table. [. . . ] Active record is an approach to accessing data in a database. A database table or view is wrapped into a class; thus an object instance is tied to a single row in the table. [44] CakePHP implementa ed estende il pattern ORM tramite una parziale l’implementazione di Active Record Pattern nei propri Model. L’accesso al database o ad una generica base dati viene quindi regolarizzato da apposite chiamate di libreria fornite dal framework, che permettono di mantenere l’indipendenza dal data layer sottostante. Debug Il framework integra un buon tool di debug che permette la visualizzazione dello stack corrente e delle query generate dall’ORM. Tramite un apposito plugin2 è poi possibile ottenere statistiche e profiling3 del codice in maniera da poter ottimizzare il sistema e rilevare eventuali colli di bottiglia. Motivi di scelta Il framework soddisfa la totalità dei requisiti posti in origine: architettura MVC, autenticazione tramite il component AuthComponent, ORM, validazione e sanitizzazione dei dati, oltre ad implementare e ampliare lo scaffolding classico tramite ulteriori utility di supporto (cfr. 5.1.1 nella pagina 65) allo sviluppatore per azioni ripetitive o meccaniche; rappresenta infine un buon compromesso tra potenza espressiva e difficoltà d’apprendimento, gode di grande popolarità e la documentazione è di buona qualità. 5.1.3 Zend Framework (v. 1.9.6) Tra i framework qui elencati Zend Framework rappresenta sicuramente quello che più si avvicina ad un mero insieme di librerie più che ad una piattaforma di sviluppo: con questo non 2 CakePHP Debug Kit, http://thechaw.com/debug_kit software engineering, program profiling, software profiling or simply profiling, a form of dynamic program analysis (as opposed to static code analysis), is the investigation of a program’s behavior using information gathered as the program executes. The usual purpose of this analysis is to determine which sections of a program to optimize - to increase its overall speed, decrease its memory requirement or sometimes both. [24] 3 In 67 5.1. PHP FRAMEWORK CAPITOLO 5. STRUMENTI UTILIZZATI si voglia intendere che non sia un vero framework ma solamente che tale scelta progettuale ha contribuito a renderne l’uso più difficoltoso, dato che Zend Framework è configurabile in ogni sua forma proprio per permettere l’uso di singoli componenti. Al contrario degli altri framework offre infatti librerie per un gran numero di attività e architetture comuni, senza però obbligarne l’uso di una o tutte le parti (al contrario ad esempio di CakePHP che, a meno di particolari work-around, impone una scelta “o tutto o niente”). Da una parte la possibilità estrema di configurazione rappresenta sicuramente un grande vantaggio, dall’altro rende però più difficoltoso l’apprendimento e la ricerca di esempi o documentazione per compiti specifici. Resta poi il fatto che la scelta di un framework è dettata in parte anche dalle preferenze dello sviluppatore e dalle tempistiche di sviluppo: nel caso di Infostudenti si è deciso di favorire un framework con convenzioni ben definite alle quali aderire, in maniera da sfruttare al massimo il tempo disponibile per lo sviluppo. 5.1.4 CodeIgniter (v. 1.7.2) La caratteristica principale di CodeIgniter è data dalla velocità di esecuzione e dall’estrema leggerezza (low footprint). Lo stesso creatore di PHP, Rasmus Lerdorf, noto avversatore dei framework, lo preferisce “because it is faster, lighter and the least like a framework” [46]. CodeIgniter non è stato però scelto per la mancanza di caratteristiche indispensabili quali scaffolding, ORM ed autenticazione. 5.1.5 Ulteriori framework Con tale breve panoramica non si ha certo la pretesa di esaurire l’ampio panorama dei framework PHP ma semplicemente illustrarne i protagonisti. Esistono infatti altri framework minori che sulla carta promettono quanto o più di CakePHP ma non se ne è considerato l’utilizzo principalmente per motivi di giovinezza o possibilità di discontinuazione di supporto a medio/lungo periodo. Si ritiene comunque che per poter giudicare in pienezza strumenti complessi quali i framework sia necessario avere sviluppato almeno un progetto con ciascuno di essi. 68 CAPITOLO 5. STRUMENTI UTILIZZATI 5.2. DATABASE Figura 5.2: Comparazione framework PHP al 26.11.2009 [23] 5.2 Database Si procede con una breve dissertazione sui motori di storage offerti dal RDBMS4 MySQL e dei motivi che hanno portato alla scelta di InnoDB. 5.2.1 Transazioni Come illustrato nel diagramma riportato le transazioni rappresentano una peculiarità di alcuni database capaci di atomicizzare più azioni, in senso più pratico più query consecutive. Ciò significa che l’esito di una sequenza di operazioni è dato dall’esito di ciascuna delle operazioni contemplate: in caso anche solo una di queste dovesse concludersi con insuccesso si deve tornare allo stato consistente precedente all’inizio della transazione per evitare l’insorgere di qualsiasi tipo di inconsistenze. 4 A relational database management system (RDBMS) is a database management system (DBMS) that is based on the relational model as introduced by E. F. Codd. Most popular commercial and open source databases currently in use are based on the relational model. [40] 69 5.2. DATABASE CAPITOLO 5. STRUMENTI UTILIZZATI Figura 5.3: Il diagramma di una transazione In caso venga rilevato un qualsiasi errore tra le azioni il cui svolgimento è richiesto essere atomico, invocando il rollback è possibile portare il database alla situazione antecedente, evitando così possibili situazioni di inconsistenza dei dati. Se invece la sequenza di azioni si conclude senza aver riscontrato problemi è possibile effettuare il commit, ossia la conferma della transazione e il conseguente definitivo salvataggio del nuovo stato della base dati. 5.2.2 ACID Per i motivi riportati di consistenza ed integrità dei dati è stato necessario selezionare uno storage engine ACID-compliant, ossia un motore le cui le transazioni (e i meccanismi che le implementano) soddisfino queste 4 proprietà[36]: • Atomicità: la transazione è indivisibile nella sua esecuzione e la sua esecuzione deve essere o totale o nulla, non sono ammesse esecuzioni parziali • Coerenza: quando inizia una transazione il database si trova in uno stato coerente e quando la transazione termina il database deve essere in uno stato coerente, ovvero non deve violare eventuali vincoli di integrità, quindi non devono verificarsi contraddizioni (inconsistency) tra i dati archiviati nel DB • Isolamento: ogni transazione deve essere eseguita in modo isolato e indipendente dalle altre transazioni, l’eventuale fallimento di una transazione non deve interferire con le altre transazioni in esecuzione 70 CAPITOLO 5. STRUMENTI UTILIZZATI 5.2. DATABASE Figura 5.4: Comparazione performance storage engine MySQL • Durabilità: detta anche persistenza, si riferisce al fatto che una volta che una transazione abbia richiesto un commit, i cambiamenti apportati non dovranno essere più persi. Per evitare che nel lasso di tempo fra il momento in cui la base di dati si impegna a scrivere le modifiche e quello in cui li scrive effettivamente si verifichino perdite di dati dovuti a malfunzionamenti, vengono tenuti dei registri di log dove sono annotate tutte le operazioni sulla base dati 5.2.3 Database abstraction layer CakePHP garantisce l’astrazione dallo specifico database layer, supportando un vasto gamma di database commerciali e non: MySQL, PostgreSQL, Firebird DB2, Microsoft SQL Server, Oracle e SQLite [47]. Resta però da considerare come sia necessario un database con motore ACID-compliant per permettere a CakePHP di gestire correttamente le transazioni. MySQL rappresenta il database d’elezione per CakePHP, motivo che, oltre alla precedente esperienza universitaria acquisita durante il corso di Basi di Dati, ha portato al restringimento della valutazione dei motori di storage offerti dal solo MySQL. 5.2.4 Comparazione motori di storage MySQL InnoDB InnoDB is a transaction-safe (ACID compliant) storage engine for MySQL that has commit, rollback, and crash-recovery capabilities to protect user data. In71 5.2. DATABASE CAPITOLO 5. STRUMENTI UTILIZZATI noDB row-level locking (without escalation to coarser granularity locks) and Oracle-style consistent nonlocking reads increase multi-user concurrency and performance. [...] To maintain data integrity, InnoDB also supports FOREIGN KEY referential-integrity constraints. [15] Grazie alle sue peculiarità InnoDB ha rappresentato la scelta ideale per le necessità di consistenza dell’intero software: chiavi esterne e transazioni hanno infatti rappresentato un requisito obbligatorio per la scelta dello storage engine. CakePHP lo supporta specificatamente tramite alcuni metodi nevralgici (cfr. 4.2), capaci di utilizzare le transazioni per salvare set di dati in modo atomico. L’integrità referenziale è mantenuta tramite le seguenti possibili clausole, specificate all’atto della creazione o modifica di una tabella di database, rispettivamente per la modifica (ON UPDATE) o la rimozione (ON DELETE) di valori: • RESTRICT: impedisce la rimozione di valori dalla tabella madre se viene rilevata una qualsiasi relazione esistente con un’altra tabella per il valore per cui si è richiesta la rimozione • CASCADE: aggiorna i valori nella tabella figlia partendo dal valore della tabella madre • SET NULL: imposta a NULL i valori relazionati nelle tabelle figlie Sempre in un’ottica di integrità dei dati InnoDB è in grado di ovviare a possibili crash in tempi estremamente più brevi rispetto a MyISAM, che deve preventivamente procedere con una scansione completa della tabella interessata, al contrario di InnoDB che può basare il recovery su specifici log capaci di delimitare la zona interessata dal danno. La recente acquisizione di Innobase (2005), la compagnia finlandese a capo dello sviluppo di InnoDB, da parte di Oracle, storica concorrente di MySQL sul mercato enterprise, ha gettato qualche ombra sul futuro dello storage engine: Oracle stessa ha però prontamente annunciato che “intends to continue developing the InnoDB technology and expand our commitment to open source software”[17], quindi non si è ritenuto rischioso procedere con lo sviluppo di Infostudenti sulla base di InnoDB. Si ricorda inoltre che in caso di qualsiasi problema grazie all’object relational mapper è possibile cambiare data layer in modo trasparente al soprastante sistema software. 72 CAPITOLO 5. STRUMENTI UTILIZZATI 5.2. DATABASE MyISAM MyISAM is the default storage engine. It is based on the older ISAM code but has many useful extensions. [...] All numeric key values are stored with the high byte first to allow better index compression. [...] [14] MyISAM rappresenta il motore di storage di default di MySQL e viene utilizzato nel database della precedente versione del software. A suo vantaggio ha l’estrema velocità, l’esigua richiesta di risorse di sistema e una capacità di compressione dei dati maggiore rispetto ad InnoDB, al contrario del quale però non supporta chiavi esterne e transazioni, motivo principe che ha portato a scartarlo per l’uso in Infostudenti. Falcon Falcon combines the world’s most popular open source database with a modern transactional engine designed especially for high-traffic, online, transactional applications and systems storing information such as pictures and scanned documents. Falcon in MySQL Server 6.0 is a next-generation engine designed to make optimal use of modern large-memory multi-CPU/multi-core hardware. It is fully ACID, MVCC-compliant 5 , and supports online parameters, tablespaces, automatic file extension/space reclamation, and distributed transactions. [30] Falcon sulla carta rappresenta un passo oltre InnoDB, purtroppo si è dovuto scartarlo preliminarmente per motivi di gioventù (verrà ufficialmente rilasciato solo con la prossima versione di MySQL). In aggiunta il framework scelto non lo supporta ufficialmente. 5.2.5 Migrazione dati Per la migrazione dei dati dal vecchio al nuovo sistema si è creata una classe PHP atta allo scopo. Tale classe permette di migrare i dati secondo i nomi dei nuovi campi adottati, provvede alla conversione dei campi booleani ed è capace di effettuare il merge dei dati di più tabelle, eventualmente tramite l’utilizzo di appositi flag booleani (cfr. 4.1.2). Si faccia riferimento al file utils/DB/SchemaMigrator.class.php per maggiori informazioni. 5 Multiversion concurrency control (abbreviated MCC or MVCC), in the database field of computer science, is a concurrency control method commonly used by database management systems to provide concurrent access to the database. MVCC provides each user connected to the database with a "snapshot" of the database for that person to work with. Any changes made will not be seen by other users of the database until the transaction has been committed. 73 5.3. JAVASCRIPT FRAMEWORK CAPITOLO 5. STRUMENTI UTILIZZATI Ci si è poi avvalsi di una apposita procedura SQL [26] per il rilevamento delle violazioni delle chiavi esterne che sono state evidenziate dopo il passaggio ad InnoDB. Tramite il suo ausilio si è poi proceduto con la bonifica di quelle correggibili e la rimozione di quelle non risolvibili. 5.3 Javascript framework Parallelamente al framework PHP si è scelto di uilizzare un framework Javascript per standardizzare lo sviluppo del codice client-side. La scelta del framework Javascript è stata particolarmente rilevante considerato il requisito di velocizzazione espresso dal committente, non ottenibile in altra maniera che con il caricamento asincrono di parti di pagina e l’utilizzo estensivo di tecniche di manipolazione dinamica del DOM. 5.3.1 Benefici derivanti dall’utilizzo di un framework Javascript Si elencano una serie di vantaggi ottenibili dall’adozione di un framework Javascript. DOM elements selectors, traversal and manipulation Grazie a sintassi modellate in parallelo a quella dei CSS, i framework Javascript permettono un accesso più semplice, rapido e preciso agli elementi del DOM, che possono poi essere manipolati tramite specifiche funzioni ausiliarie solitamente fornite dai framework Compatibilità cross-browser I framework si occupano di gestire e risolvere le incongruenze tra browser differenti, offrendo allo sviluppatore una base consistente e comune; in questa maniera è possibile concentrarsi sugli aspetti di business logic dell’applicazione e non sui workaround necessari per ovviare alle inconsistenze tra browser e piattaforme differenti. Parsing Gran parte dei framework si occupano del parsing automatico di vari formati di file: in tale maniera è possibile ad esempio delegare il compito del parsing di file JSON ricevuti via AJAX ed ottenere in ritorno degli oggetti Javascript preventivamente popolati con i dati ricevuti. 74 CAPITOLO 5. STRUMENTI UTILIZZATI 5.3. JAVASCRIPT FRAMEWORK Effetti grafici In questi ultimi anni grazie al progressivo miglioramento delle capacità dei motori Javascript si è potuto assistere ad una riduzione degli effetti grafici e di animazione sviluppati con tecnologia Flash per assistere ad un boom degli effetti basati su Javascript, effetti che, al contrario di quelli basati su Flash, solitamente permettono di mantenere un alto grado di accessibilità: tramite il loro uso è infatti possibile far degradare correttamente una pagina HTML in caso di assenza delle tecnologie necessarie per il loro funzionamento, mantenendo nel contempo l’accessibilità dei contenuti. Gran parte dei framework Javascript integrano la possibilità di applicare effetti d’animazione agli elementi HTML. 5.3.2 jQuery (v. 1.3.2) La libreria JQuery [31] rappresenta un buon compresso tra facilità d’uso, quantità e qualità di documentazione e performance di utilizzo. Tale libreria viene utilizzata da colossi quali Google, Dell, Digg, NBC, CBS, Mozilla, Technorati ed è integrata in progetti open-source di grande fama e spessore quali Wordpress e Drupal. E’ inoltre sostenuta da una fiorente comunità di supporto, rappresentando al giorno d’oggi la libreria d’elezione del web 2.06 . E’ stata scelta per l’utilizzo in Infostudenti. jQuery UI La scelta di utilizzo di Jquery è stata favorita anche dall’esistenza di una sua libreria di appoggio denominata jQuery UI, specializzata nell’implementazione in puro Javascript di RIA7 . jQuery UI provides abstractions for low-level interaction and animation, advanced effects and high-level, themeable widgets, built on top of the jQuery JavaScript Library, that you can use to build highly interactive web applications. [55] La libreria ha ormai raggiunto un buono stato di maturità ed è mantenuta ed aggiornata in contemporanea con jQuery. Permette di ottenere effetti solitamente ottenibili soltanto 6 The term "Web 2.0" is commonly associated with web applications that facilitate interactive information sharing, interoperability, [...] and collaboration on the World Wide Web. Examples of Web 2.0 include webbased communities, hosted services, web applications, social-networking sites, [...]. A Web 2.0 site allows its users to interact with other users or to change website content, in contrast to non-interactive websites where users are limited to the passive viewing of information that is provided to them. [49] The term is closely associated with Tim O’Reilly because of the O’Reilly Media Web 2.0 conference in 2004 [50] 7 Rich Internet applications (RIAs) are web applications that have most of the characteristics of desktop applications, typically delivered either by way of a standards based web browser, via a browser plug-in, or independently via sandboxes or virtual machines. Examples of RIA frameworks include Ajax, Curl, GWT, Adobe Flash/Adobe Flex/AIR, Java/JavaFX, Mozilla’s XUL and Microsoft Silverlight. [56] 75 5.3. JAVASCRIPT FRAMEWORK CAPITOLO 5. STRUMENTI UTILIZZATI Figura 5.5: Esempio di utilizzo di jQuery UI per il datepicker di Infostudenti in ambito desktop, quali drag-and-drop, finestre di dialogo modali, barre di scorrimento, calendari inline, tab. 5.3.3 Prototype (v. 1.6.1) Nonostante la buona documentazione la libreria è stata scartata per motivi di performance (cfr. 5.3.4), inoltre non integra effetti grafici (motivo per cui si appoggia ad ulteriori librerie esterne quali script.aculo.us8 o mootools9 ). 5.3.4 Comparazione performance La scelta tra jQuery e Prototype è stata fatta in favore del primo per evidenti motivi di performance anche su browser datati o non standard quali Internet Explorer 6 e 7 [32]. 8 http://script.aculo.us/ 9 http://mootools.net/ 76 CAPITOLO 5. STRUMENTI UTILIZZATI 5.3. JAVASCRIPT FRAMEWORK Figura 5.6: Esempio di utilizzo di jQuery UI per una finestra di dialogo modale Figura 5.7: Comparazione performance framework Javascript 77 5.4. SCAMBIO DATI ASINCRONO CAPITOLO 5. STRUMENTI UTILIZZATI Figura 5.8: Esempio di file in formato JSON 5.4 Scambio dati asincrono 5.4.1 AJAX ed XML Come definito in 3.3 la X del termine AJAX corrisponde ad XML, poichè XML rappresenta il formato utilizzato in origine per lo scambio asincrono. Avendo ormai raggiunto la sua maturità, molti sviluppatori stanno però mettendo in discussione XML come formato di scambio in favore di formati terzi più leggeri o semplicemente con caratteristiche più specifiche per particolari ambiti applicativi. Nel caso di Infostudenti si è ritenuto opportuno utilizzare altri formati di scambio, per motivi di leggerezza e conseguentemente velocità di reazione dell’interfaccia. 5.4.2 AJAJ: AJAX e JSON JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write. It is easy for machines to parse and generate. It is based on a subset of the JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999. JSON is a text format that is completely language independent but uses conventions that are familiar to programmers of the C-family of languages, including C, C++, C#, Java, JavaScript, Perl, Python, and many others. These properties make JSON an ideal data-interchange language. [33] 78 CAPITOLO 5. STRUMENTI UTILIZZATI 5.4. SCAMBIO DATI ASINCRONO Vengono elencati alcuni dei motivi che hanno spinto alla preferenza di JSON nei confronti di XML [34]. Comparazione JSON - XML • semplicità: JSON è sintatticamente più semplice e meno pesante (“less verbose”) di XML, portendo vantare una grammatica ridotta e mappando i propri tipi direttamente verso i tipi standard previsti dai più comuni linguaggi di programmazione • estensibilità: JSON non è estensibile e non ha la pretesa di esserlo, dato che non è un linguaggio di markup • interoperabilità: JSON ha il medesimo potenziale di interoperabilità di XML • apertura agli standard e alla modifica: JSON è aperto almeno quanto XML, forse anche di più non essendo al centro di tentativi di standardizzazione • parsing: il parsing di JSON può avvenire più rapidamente grazie alla sua caratteristica di possedere una grammatica più piccola e semplice • internazionalizzazione: entrambi i formati supportano Unicode10 • formato di scambio comune: JSON è migliore per lo scambio di dati e tipi usati nei linguaggi di programmazione, mente XML è più adatto per lo scambio di documenti (“use the right tool for the right job”) Adozione nel sistema Per i motivi sopra riportati si è deciso di adottare JSON come formato utilizzato in gran parte degli scambi asincroni. Sia il framework PHP che quello Javascript supportano nativamente tale formato. 5.4.3 AJAH: AJAX ed HTML L’utilizzo di XML e JSON come formati di scambio dati implica il parsing client-side dei dati ricevuti dal server: se infatti viene ricevuto un array di elementi è necessario procedere al 10 Unicode is a computing industry standard allowing computers to represent and manipulate text expressed in most of the world’s writing systems consistently. Developed in tandem with the Universal Character Set standard and published in book form as The Unicode Standard, the latest version of Unicode consists of a repertoire of more than 107,000 characters covering 90 scripts, [...] and bidirectional display order (for the correct display of text containing both right-to-left scripts, such as Arabic or Hebrew, and left-to-right scripts). [53] 79 5.5. CSS CAPITOLO 5. STRUMENTI UTILIZZATI parsing di tale array in maniera da creare una apposito elemento HTML che possa poi essere inserito nel DOM, con conseguente onero prestazionale a carico del client. Per ovviare a tale problema, in casi in cui non sia praticabile o estremamente dispendioso il parsing dei dati ricevuti dal server si è deciso di utilizzare direttamente l’HTML come formato di scambio. Il server quindi risponde asincronamente con frammenti di codice HTML che verranno iniettati nel DOM una volta ricevuti. Tale modalità di caricamento asincrono è più pesante dal punto di vista della quantità di dati scambiati ma ha semplificato enormemente il codice di gestione client-side; è importante dire poi che in alcune situazioni non è stato possibile procedere in altra maniera poichè effettuare il parsing dei dati ricevuti dal server avrebbe significato effettuare una duplicazione del codice PHP in linguaggio Javascript, in disaccordo con il principio DRY (cfr. 5.1.2 nella pagina 66). 5.5 CSS Trattandosi di un progetto web-based si è posta particolare rilevanza all’aspetto grafico, così che l’uso di CSS è risultato la scelta naturale. In particolar modo è risultato opportuno abbandonare il layout basato su tabelle per approdare ad una pagina totalmente tableless, proprietà che ha poi anche facilitato la stampa di qualsiasi pagina del sistema, grazie all’utilizzo di appositi fogli di stile preimpostati per la stampa. Per motivi di performance e di separazione dei contenuti l’intero codice CSS è stato inserito in appositi file esterni, evitando l’utilizzo di CSS inline e di gran parte del codice HTML che non avesse valenza semantica. 5.5.1 Blueprint CSS framework (v. 0.9.1) Si è deciso di utilizzare un framework CSS per eliminare quanto più possibile le discrepanze di visualizzazione tra browser. I framework CSS altro non sono che fogli di stile di base particolarmente attenti ai workaround necessari per ottenere consistenza grafica tra browser differenti. Grazie a Blueprint11 si è inoltre potuto contare su una griglia basata su CSS così da facilitare il lavoro di restyling grafico, che comunque non rientra nelle competenze del refactoring ma che potrà essere affidato ad apposito studio grafico esterno. 11 http://www.blueprintcss.org/ 80 CAPITOLO 5. STRUMENTI UTILIZZATI 5.5.2 5.6. LIBRERIE DI ESPORTAZIONE Stampa L’utilizzo esclusivo di CSS per il layout ha permesso di evitare la creazione di viste progettate appositamente per la stampa: è stato infatti sufficiente creare un foglio di stile specifico e abilitato in sola fase di stampa. 5.5.3 Validazione W3C Più dell’80% del codice HTML generato ha passato la validazione online W3C (http:// validator.w3.org/). 5.6 Librerie di esportazione La necessità di creazione di certificati ufficiali documentanti i piani di studio degli studenti ha imposto l’utilizzo di apposite librerie di esportazione. Per il momento sono state implementate le sole esportazioni in PDF ed RTF ma si è predisposto un metodo dell’helper InfostudentiGenericHelper (public array certificato(&student)) 4.4.1 nella pagina 61 per facilitare implementazione di ulteriori librerie. 5.6.1 TCPDF (v. 4.8.16) Ci si è avvalsi della libreria TCPDF12 per via del suo continuo aggiornamento e del pieno supporto di Unicode (cfr. 10 nella pagina 79). Da alcuni test preventivi si è rivelata essere anche estremamente veloce rispetto alle concorrenti FPDF13 ed R&OS 14 . Per le sue buone capacità di conversione da HTML a PDF è inclusa in alcuni rilevanti progetti web quali Drupal, Joomla e phpMyAdmin. 5.6.2 RTF (v. 0.3.0) La necessità di esportazione in un formato modificabile con programmi di largo consumo ha imposto l’utilizzo del formato .doc di Microsoft Word: si è però ritenuto opportuno non legarsi a formati proprietari ed utilizzare il formato RTF, letto e modificato senza alcun problema dalla quasi totalità dei sistemi operativi odierni[52]. 12 http://www.tcpdf.org/ 13 http://www.fpdf.org/ 14 http://www.ros.co.nz/pdf/ 81 5.7. PIATTAFORMA DI SVILUPPO La libreria PhpRtf 15 CAPITOLO 5. STRUMENTI UTILIZZATI rappresenta lo standard de facto per la generazione di file RTF da linguaggio PHP, non esistendo veri e propri concorrenti degni di nota. La libreria è comunque ben documentata e completamente object-oriented, non ha dato particolari problemi e si è rivelata estremamente veloce nella generazione dei documenti, anche più della controparte PDF (probabilmente per la struttura interna del formato RTF, sintatticamente più semplice di quella PDF). 5.7 Piattaforma di sviluppo L’intero progetto è stato sviluppato su sistema operativo Mac OS X 10.6.1, server web Apache 2.2.13, processore PHP 5.3.0 e browser Mozilla Firefox 3.5.3. L’utilizzo di tale browser ha permesso l’utilizzo dell’estensione Firebug16 (v. 1.4.5), capace di effettuare profiling e debug del codice Javascript, monitorare le richieste di rete (anche asincrone), favorire le attività di manipolazione del DOM e in generare semplificare le attività correlate allo sviluppo di applicazioni web. 5.8 Versionamento Si è fatto uso di un sistema di controllo versione per il mantenimento degli avanzamenti del codice e la collaborazione tra lo studente e il referente esterno. 5.8.1 Subversion Scartando a priori il vecchio CVS si è utilizzato un repository Subversion17 interfacciato tramite Trac18 , un’interfaccia web-based di gestione dell’intero repository. Ciò ha permesso anche lo scambio di ticket tra il referente esterno e lo studente. 15 http://www.phprtf.com/ 16 http://getfirebug.com/ 17 hosting offerto da svnrepository.com 18 http://trac.edgewall.org/ 82 CAPITOLO 5. STRUMENTI UTILIZZATI 5.9. VERIFICA E VALIDAZIONE Figura 5.9: Esempio di unit testing mediante l’uso della struttura offerta da CakePHP 5.9 Verifica e validazione Il lavoro di verifica accerta che l’esecuzione delle attività di processo non abbia introdotto errori, mentre quello di validazione accerta che il prodotto realizzato dai processi eseguiti corrisponda alle attese. Per tali scopi ci si è avvalsi dei tool di unit testing offerti dal framework CakePHP, che hanno permesso di predisporre più agevolmente gli opportuni test black-box. 5.9.1 Unit testing (analisi dinamica) Il framework CakePHP fornisce i tool necessari per i test di unità del sistema tramite la libreria SimpleTest19 , di cui lo studente ha precedente esperienza per il progetto di Ingegneria del Software. Lo stesso codice del framework è testabile accedendo all’URL /test.php, dalla cui interfaccia è possibile avviare i test sui singoli componenti del framework. Modelli e controller Oltre alla possibilità di effettuare unit testing sul codice del framework, CakePHP offre una suite di testing che facilita il lavoro dello sviluppatore tramite alcuni accorgimenti. Il principale di questi è dato dalle fixtures, dati di esempio utilizzabili per poter effettuare test senza problemi di manipolazione o interferenza con quelli di produzione. 19 http://www.simpletest.org/ 83 5.10. DOCUMENTAZIONE 5.10 CAPITOLO 5. STRUMENTI UTILIZZATI Documentazione Per la documentazione inline del codice ci si è avvalsi del tool phpDocumentor20 . Tramite tale strumento si è ereditato da una parte uno stile di commentazione standardizzato e ben definito (PHPDoc21 ), dall’altra è stato possibile generare documentazione in formato HTML per ciascuna delle classi del sistema, rendendone più agevole la consultazione. 20 http://www.phpdoc.org/ 21 http://en.wikipedia.org/wiki/PHPDoc 84 Capitolo 6 Conclusioni Scostamento dalla pianificazione delle attività Rispetto a quanto pianificato in fase di accettazione del progetto di stage vi è stato un leggero scostamento dovuto al minor tempo richiesto per la messa in opera dei tool di sviluppo, tempo che è stato quindi possibile investire per la creazione dello script di migrazione dei dati (utile per lavorare con una copia dei dati reali provenienti dal precedente sistema) e l’anticipo di parte del lavoro previsto per la settimana successiva. Durante le fasi finali si sono dovuti sacrificare alcuni giorni di verifica e validazione per destinarli alla revisione della documentazione del codice, aspetto sul quale il committente ha desiderato porre particolare attenzione in vista della scadenza dello stage. Analisi critica del prodotto Ritengo di essere abbastanza soddisfatto del prodotto, anche se alcune scelte implementative non hanno potuto avere luogo causa la ristrettezza dei tempi: ad esempio considero non ottimale l’implementazione dell’ACL, che a mio parere dovrebbe essere maggiormente raffinata. Per i medesimi motivi di tempo non si è potuto procedere con un profiling accurato del software, così da rilevare eventuali colli di bottiglia o procedere con basilari tecniche di ottimizzazione delle performance. Valutazione strumenti utilizzati Il framework CakePHP ha rappresentato un punto di svolta nelle mie abitudini di programmazione, riuscendo ad automatizzare molti compiti ripetitivi e proni ad errori, ma soprattutto permettendomi di concentrare l’attenzione sulla 85 CAPITOLO 6. CONCLUSIONI logica di business e di conseguenza aumentare la mia produttività. Alla conclusione dello stage mi sento di padroneggiare buona parte del framework ma ritengo sia necessario del tempo ulteriore per poterlo conoscere nei dettagli; in particolare vorrei approfondirne lo studio di alcune parti del codice in maniera da poter aiutare nello sviluppo. Utilizzo del prodotto Il committente stima di poter utilizzare il prodotto nel secondo trimestre dell’anno 2010. Analisi critica del lavoro di stage Il lavoro di stage ha accresciuto la mia padronanza di utilizzo di molte delle odierne tecnologie riguardanti il web, oltre che fornirmi una visione di massima di come possa funzionare un software complesso quale Infostudenti. Il supporto da parte del tutor esterno, Ing. Stefano Gualtieri, è stato estremamente professionale e non ha fatto pesare le mie lacune riguardanti alcuni argomenti più specifici: a lui vanno i miei ringraziamenti per avermi permesso di lavorare su un progetto così ambizioso. 86 Bibliografia [1] http://en.wikipedia.org/wiki/Code_refactoring [2] http://en.wikipedia.org/wiki/Cross-site_scripting [3] http://en.wikipedia.org/wiki/Access_control_list [4] Golding David, Beginning CakePHP, Apress 2008 [5] Chan Kai - Omokore John - Miller Richard K., Practical CakePHP Projects, Apress 2008 [6] http://book.cakephp.org/view/12/Benefits [7] http://en.wikipedia.org/wiki/Lightweight_Directory_Access_Protocol [8] http://en.wikipedia.org/wiki/Database_trigger [9] http://en.wikipedia.org/wiki/CamelCase [10] Matt Curry, Advanced CakePHP Tips, 2009 (http://www.pseudocoder.com/ free-cakephp-book) [11] http://www.mysqlperformanceblog.com/2009/01/12/should-you-move-from-myisam-to-innodb/ [12] http://www.mysqlperformanceblog.com/2007/01/08/innodb-vs-myisam-vs-falcon% 20-benchmarks-part-1/ [13] http://dev.mysql.com/doc/refman/5.0/en/storage-engines.html [14] http://dev.mysql.com/doc/refman/5.0/en/myisam-storage-engine.html [15] http://dev.mysql.com/doc/refman/5.0/en/innodb.html 87 BIBLIOGRAFIA BIBLIOGRAFIA [16] http://book.cakephp.org/view/12/Benefits [17] http://www.oracle.com/innodb/index.html [18] http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller [19] http://book.cakephp.org/view/15/Controller-Extensions-Components [20] http://book.cakephp.org/view/17/Model-Extensions-Behaviors [21] http://book.cakephp.org/view/16/View-Extensions-Helpers [22] http://en.wikipedia.org/wiki/Session_%28computer_science%29 [23] http://www.phpframeworks.com/ [24] http://en.wikipedia.org/wiki/Profiling_%28computer_programming%29 [25] http://en.wikipedia.org/wiki/Object-relational_mapping [26] http://forge.mysql.com/tools/tool.php?id=11 [27] http://en.wikipedia.org/wiki/Multiversion_concurrency_control [28] http://www.mysqlperformanceblog.com/2007/10/12/myisam-scalability-and-innodb-% 20falcon-benchmarks/ [29] http://en.wikipedia.org/wiki/Rollback_%28data_management%29 [30] http://www.mysql.com/news-and-events/on-demand-webinars/display-od-86. html [31] http://docs.jquery.com/Main_Page [32] http://blog.creonfx.com/javascript/mootools-vs-jquery-vs-prototype-vs-yui-% 20vs-dojo-comparison-revised [33] http://www.json.org/ [34] http://json.org/xml.html [35] http://en.wikipedia.org/wiki/Foreign_key 88 BIBLIOGRAFIA BIBLIOGRAFIA [36] http://it.wikipedia.org/wiki/ACID [37] http://en.wikipedia.org/wiki/Software_framework [38] http://en.wikipedia.org/wiki/Create,_read,_update_and_delete [39] http://en.wikipedia.org/wiki/Scaffold_%28programming%29 [40] http://en.wikipedia.org/wiki/Relational_database_management_system [41] http://rubyonrails.org/ [42] http://shootout.alioth.debian.org/u32q/benchmark.php?test=all&lang= php&lang2=yarv&box=1#mandelbrot [43] http://www.techcrunch.com/2008/05/01/twitter-said-to-be-abandoning-ruby-on-rails/ [44] http://en.wikipedia.org/wiki/Active_record_pattern [45] http://books.google.com/books?id=FyWZt5DdvFkC&lpg=PA1&dq=Patterns%20of% 20Enterprise%20Application%20Architecture%20by%20Martin%20Fowler&pg= PT187#v=onepage&q=active%20record&f=false [46] http://www.sitepoint.com/blogs/2008/08/29/rasmus-lerdorf-php-frameworks-think-again/ [47] http://book.cakephp.org/view/28/Requirements [48] http://en.wikipedia.org/wiki/Document_Object_Model [49] http://lindipendente.splinder.com/post/15354690/World+2.0 [50] http://oreilly.com/web2/archive/what-is-web-20.html [51] http://en.wikipedia.org/wiki/Ajax_%28programming%29 [52] http://en.wikipedia.org/wiki/Rich_Text_Format [53] http://en.wikipedia.org/wiki/Unicode [54] http://en.wikipedia.org/wiki/Database_trigger [55] http://jqueryui.com/ 89 BIBLIOGRAFIA BIBLIOGRAFIA [56] http://en.wikipedia.org/wiki/Rich_Internet_application [57] http://en.wikipedia.org/wiki/Web_application [58] http://book.cakephp.org/view/474/Containable [59] http://book.cakephp.org/view/174/Request-Handling 90 Elenco delle figure 3.1 Architettura MVC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 3.2 Architettura MVC implementata in CakePHP 3.3 Funzionamento web-application (modello client-server) . . . . . . . . . . . . . 23 3.4 Diagramma di funzionamento tecnologia AJAX . . . . . . . . . . . . . . . . . 24 3.5 Diagramma di funzionamento di un generico Object Relational Mapping . . . 26 3.6 Diagramma di stato dei piani di studio . . . . . . . . . . . . . . . . . . . . . . 27 3.7 Diagramma di stato per un piano di studi consigliato . . . . . . . . . . . . . . 29 3.8 Diagramma di stato degli esami . . . . . . . . . . . . . . . . . . . . . . . . . . 30 3.9 Diagramma di stato per la creazione di nuovi utenti . . . . . . . . . . . . . . 31 . . . . . . . . . . . . . . . . . 19 3.10 Diagramma di stato per i crediti di un insegnamento . . . . . . . . . . . . . . 32 3.11 Diagramma di stato per i crediti di una riga di piano di studi tipo C . . . . . 33 3.12 Diagramma di stato per i crediti di una riga di piano di studi tipo D . . . . . 35 4.1 Modellazione concettuale del database . . . . . . . . . . . . . . . . . . . . . . 38 4.2 Modello precedente . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 4.3 Stralcio di codice SQL commentato . . . . . . . . . . . . . . . . . . . . . . . . 41 4.4 Modello relazione finale (completo di proprietà) . . . . . . . . . . . . . . . . . 43 4.5 Modello relazionale finale (solo chiavi primarie ed esterne) . . . . . . . . . . . 44 4.6 Gerarchia classe Model ed Helper . . . . . . . . . . . . . . . . . . . . . . . . . 45 4.7 Array Containable per il reperimento dei dati relativi ad un piano di studi . . 57 4.8 Organizzazione delle view basata sui tipi di richiesta ricevuti . . . . . . . . . 59 4.9 Esempio di utilizzo della classe FormHelper . . . . . . . . . . . . . . . . . . . 61 91 ELENCO DELLE FIGURE ELENCO DELLE FIGURE 5.1 Google Trends: comparazione framework PHP al 26.11.2009 . . . . . . . . . . 66 5.2 Comparazione framework PHP al 26.11.2009 [23] . . . . . . . . . . . . . . . . 69 5.3 Il diagramma di una transazione . . . . . . . . . . . . . . . . . . . . . . . . . 70 5.4 Comparazione performance storage engine MySQL . . . . . . . . . . . . . . . 71 5.5 Esempio di utilizzo di jQuery UI per il datepicker di Infostudenti . . . . . . . 76 5.6 Esempio di utilizzo di jQuery UI per una finestra di dialogo modale . . . . . . 77 5.7 Comparazione performance framework Javascript . . . . . . . . . . . . . . . . 77 5.8 Esempio di file in formato JSON . . . . . . . . . . . . . . . . . . . . . . . . . 78 5.9 Esempio di unit testing mediante l’uso della struttura offerta da CakePHP . . 83 92