Documento Allegato
Transcript
Documento Allegato
Dlibs/DSite 1.0 prima bozza di documentazione Autore: LM Revisione: 0.3 Contenuti del documento DLibs....................................................................................................................................................3 Introduzione.....................................................................................................................................3 Struttura delle directory...................................................................................................................3 ActiveDB....................................................................................................................................3 ActiveForm.................................................................................................................................3 DataSource..................................................................................................................................4 Externals......................................................................................................................................4 General........................................................................................................................................4 ActiveDB ........................................................................................................................................5 Convenzioni................................................................................................................................5 Utilizzo di base............................................................................................................................6 I metodi di ricerca.......................................................................................................................7 Metodi get a disposizione.......................................................................................................7 Metodi find a disposizione.....................................................................................................8 Rules............................................................................................................................................8 Rule con parametri......................................................................................................................9 Gli inserimenti/modifiche/cancellazioni...................................................................................10 Le relazioni master/detail..........................................................................................................11 Come uscire dallo schema delle convenzioni...........................................................................11 I callback...................................................................................................................................11 I metodi avanzati.......................................................................................................................11 Dsite....................................................................................................................................................12 Struttura delle directory.................................................................................................................12 cache..........................................................................................................................................12 config........................................................................................................................................12 libs.............................................................................................................................................12 website......................................................................................................................................13 amp.......................................................................................................................................13 controllers.............................................................................................................................13 files.......................................................................................................................................13 js, pics, styles........................................................................................................................13 logs.......................................................................................................................................13 models..................................................................................................................................13 plugin-config........................................................................................................................13 variables................................................................................................................................13 views.....................................................................................................................................13 urlmap.php............................................................................................................................14 index.php..............................................................................................................................14 Il primo test....................................................................................................................................14 Multilingua.....................................................................................................................................16 Variabili di default.........................................................................................................................16 Modelli e templates........................................................................................................................16 Controllers.....................................................................................................................................16 ImageServer...................................................................................................................................16 Urlmap...........................................................................................................................................16 DLibs Introduzione Dlibs è un framework di librerie PHP nato per velocizzare le comuni operazioni svolte durante lo sviluppo di una applicazione o di un sito web. Il framework è scritto in PHP5 ed è incompatibile con PHP4. Tutti gli include utilizzati nelle Dlibs assumono che la root directory delle librerie sia nell'include path. L'include path può essere settato sia nel file php.ini sia runtime, tramite la funzione set_include_path(). Struttura delle directory In tutte le directory di trova una directory "test". La directory test contiene gli unit-test della sezione delle dlibs corrispondente ed è invocabile direttamente da browser. (C'è un index.php che si occupa di lanciare i test) ActiveDB Contiene ActiveDB e le classi derivate. ActiveDB è un'implementazione che si basa (ma non segue al 100%) il pattern ActiveRecord. Lo scopo di ActiveDB è quello di fornire un'astrazione per la base dati, su cui basare le proprie operazioni di ricerca, inserimento, cancellazione e modifica dei record. La classe AcriveDB fornisce quindi un'astrazione relativa ad una tabella del database. Le princilapli classi derivate da ActiveDB sono ActiveQuery, che consente di utilizzare le funzioni ricerca su una query custom, invece che su una tabella, e DContentActiveDB (e MLDcontentActiveDB) che permettono di utilizzare i metodi di ActiveDB su tabelle che abbiano una gestione del Workflow (vedremo in seguito). La classi che finiscono per "DbWrapper" costituiscono i "Drivers" di accesso al Database. Al momento sono disponibili solo MySQLDbWrapper per i database MySQL e ODBCDbWrapper per le fonti dati ODBC (utilizzabile solo in ambiente Windows). Le classi DbWrapper Debbono implementare l'interfaccia AbstractDB per potere essere utilizzate da ActiveDB. Tutte le altre classi sono classi di appoggio, che vedremo nella descrizione dettagliata. ActiveForm ActiveForm è un insieme di classi utilizzato per generare delle form in XHTML. ActiveForm si occupa della generazione dei componenti, dei check di obbligatorietà dei dati, della gestione degli errori e del display dell'XHTML delle form. Non gestisce, in nessun modo, il tag <form> ne il tag <submit>. La parte di gestione che esula dalla generazione del codice XHTML dei componenti e dai check di obbligatorietà dei dati viene lasciata allo sviluppatore. La directory components contiene i singoli componenti della form. Nel modello di ActiveForm ogni singolo componente è rappresentato da una classe che estende la classe base ActiveFormComponent. Ogni singolo componente è responsabile dei propri check di esistenza o consistenza del dato e dell'output del proprio XHTML. La classe DBFormGenerator è un Helper per generare delle istanze di ActiveForm partendo da un oggetto ActiveDB. DataSource Contiene la classe DataSource, deprecata, che verrà presto rimossa dalle Dlibs. Externals Contiene le classi necessarie al funzionamento o al testing delle Dlibs, non sviluppate all'interno del progetto. Al momento solo la classe simpletest, utilizzata per lo unit-testing. La classe simpletest non è necessaria al funzionamento delle Dlibs e può quindi essere eliminata dall'ambiente di produzione. General General contiene una collezione di classi generiche d'appoggio. CalendarManager: permette di costruire cicli su giorni, settimane, mesi, di individuare, dato un giorno, la settimana e il mese corrispondente o il primo o l'ultimo giorno della settimana o del mese corrispondente. Molto utile per la costruzione di calendari. DirWalker: classe statica per listare il contenuto di una directory, filtrando il contenuto per estensione. (La classe DirWalker2 è in fase di ricostruzione o eliminazione, da non usare) DLString: classe utilizzata per trasformare una stringa in una semplificzione utile per gli indici di ricerca. Permette la "romanizzazione" (trasformazione di tutti i caratteri speciali, accentati o simili nell'equivalente "romano"), l'appiattimento delle doppie ( Mazza in Maza ad esempio). La classe utilizza le funzioni di PHP per la manipolazione delle stringhe multibyte. IncludeManager: classe utilizzata per costruire una tabella di file da includere (css, javascript o similari) utilizzati dalle DLibs. Utilizzata praticamente solo da ActiveForm, risulta un po' ostica nei suoi meccanismi. Non è esclusa una persante revisione. Logger: sistema di log dei messaggi. E' costituita da una classe principale e da una serie di Writer. Un writer è una classe che permette di scrivere un messaggio di log su un particolare supporto. Sono disponibili, ad esempio, FileWriter, per scrivere su file, MailWriter, per inviare la riga di log via mail (utile per loggare gli errori importanti) e ActiveDBWriter per salvare su una tabella di database. SimpleObject: è di fatto la classe di base per ActiveDB e per alcune classi di DSite. Il suo compito principale è quello di mappare le sue proprietà su un array associativo e di permettere un completo controllo di getter/setter per tutte le classi che ne derivano. Implementa le interfacce PHP ArrayAccess e Iterator, permettendo così di scorrere le proprietà di un oggetto sia tramite il normale operatore di accesso -> che tramite [proprietà] come se si trattasse di un array, sia tramite un ciclo foreach. Singleton: semplice classe statica che permette di utilizzare il pattern singleton con qualsiasi altra classe. UrlMapper: classe che permette di registrare delle mappe di url nel formato /{variabile1}/test_{variabile2} e di eseguire il match di una stringa (URL) con le mappe registrate, ottenendo in caso di match positivo, la lista di variabili espresse nella mappa (coppie associative chiave=>valore) ImageManager: lo sviluppo di questa classe non è ancora ultimato. Si tratta di un porting nelle dlibs dell'omonimo plugin per DSite. Attualmente non è utilizzabile. Workflow: gestore di workflow, compatibile con i files XML del vecchio sistema DContent (CMS proprietario di DSign). Permette l'utilizzo di un workflow espresso tramite un file XML. Utilizzato da DContentActiveDB, ma abbastanza generico per essere utilizzato anche separatamente. ActiveDB Si può dire che ActiveDB sia di fatto la parte più importante delle Dlibs, o quantomeno la più utilizata. Svolge quasi tutte le operazioni di lettura, scrittura, cancellazioni necessarie per l'utilizzo di un DB in una web-application. Convenzioni Un oggetto ActiveDB rappresenta sempre (o almeno, così dovrebbe essere), una tabella di un Database relazionale. Nelle Dlibs si predilige un approggio "Convention over Configuration" ovvero se non specificato altrimenti il sistema si basa su convenzioni interne, che possono però essere alterate facilmente. In questo modo se si progetta un sistema per funzionare con le Dlibs, seguendo le convenzioni, basteranno pochissime righe di codice per potere utilizzare ActiveDB. Se ci si deve adattare a strutture già esistenti questo non è un problema, sarà necessario però scrivere più codice, per specificare la struttura delle tabelle su cui andremo a lavorare. Le convenzioni usate da ActiveDB sono: 1. Ogni tabella ha sempre una Primary Key 2. La chiave primaria di una tabelle si chiama sempre <NomeTabella>KEY ed è un campo numerico con autoincrement. Quindi se la tabella si chiama "Pagine" la sua chiave primaria sarà "PagineKEY". 3. Le Foreign Key si chiamano <NomeTabellaPadre>FKEY, e sono ovviamente numeriche. Dunque se abbiamo una tabella Immagini collegata in relazione 0-n con la tabella Pagine (Pagine è "0" il master, Immagini è "n" il detail) la chiave primaria di Immagini sarà ImmaginiKEY e la chiave che punta a Pagine sarà PagineFKEY 4. La classe ActiveDB che gestisce una tabella si chiama sempre come la tabella stessa. Utilizzo di base Per potere utilizzare ActiveDB su una tabella è per prima cosa necessario definire la classe che si occupa della gestione della tabella. Bisogna sempre, assolutamente rispettare il rapporto una classe, una tabella. Prendiamo come esempio la tabella Pagine, così strutturata: PagineKEY: Codice: Titolo: Abstract: Corpo: Thumbnail: Ordine: chiave primaria varchar(255) varchar(255) varchr(255) Text varchar(255) tinyint Per definire la classe che la gestisce: class Pagine extends ActiveDB {} A questo punto la classe di gestione della tabella Pagine è pronta. Ora basta istanziarla. Per farlo abbiamo bisogno di collegrci al Database. Lo faremo con un MySQLDbWrapper. // host,dbname, username, password $dbw=new MySQLDbWrapper("localhost","test","username","password"); $pgn=new Pagine($dbw); Ora $pgn rappresenta la tabella pagine. Se per esempio vogliamo stampare i titoli di tutte le pagine contenute nella tabella possiamo fare: foreach($pgn->getAll() as $pagina) print($pagina->Titolo."<br/>"); Come si vede dall'esempio tutti i field della tabella sono stati mappati sulle proprietà corrispondenti dell'oggetto $pagina. Possiamo quindi avere accesso a: $pagina->Titolo, $pagina->Abstract, $pagina->Corpo e così via. Per accedere alla primary key della tabella si può invece usare la scorciatoia $pagina->PrimaryKEY che nel nostro caso di esempio equivale a $pagina->PagineKEY Attenzione: il nome delle proprietà è case sensitive. Continuando a usare la funzione getAll() possiamo ad esempio volere ottenere la stessa lista, ma ordinata er il campo "Ordine". $pgn->getAll(array(OrderBy => "Ordine")); Il primo parametro di getAll è un array associativo di proprietà che permettono di modificare la "select" che viene fatta per estrarre i dati. In particolare per ora possiamo utilizzare "Where" per aggiungere (in and) una clausola where alla select e OrderBy per specificare l'ordinamento. Il metodo getAll restituisce un array di oggetti ActiveDB, che rappresentano il risultato della ricerca. I metodi di ricerca ActiveDB mette a disposizione vari metodi di ricerca, che possiamo dividere in 2 macrocategorie: i metodi "get" e i metodi"find". La differenza tra le due categorie è che i metodi "get" restituiscono sempre un array di oggetti o un singolo oggetto. Se facciamo quindi con un metodo getAll una get di una tabella con 10.000 record ci troveremo con un array di 10.000 oggetti ActiveDB ed un conseguente dispendio di memoria e tempo. I metodi "find" invece preparano la query di ricerca ma lasciano allo sviluppatore l'onere del ciclo per estrarre i dati. Per chiarire la differenza, se seguenti due porzioni di codice ottengono lo stesso risultato: // utilizzando un metodo get $dbw=new MySQLDbWrapper("localhost","test","username","password"); $pgn=new Pagine($dbw); $dat=$pgn->getAll(); // utilizzando un metodo find $dbw=new MySQLDbWrapper("localhost","test","username","password"); $pgn=new Pagine($dbw); $pgn->findAll(); while($dt=$pgn->fetchObject()) $dat[]=$dt; Metodi get a disposizione (il parametro $params è sempre un array associativo che può contenere le chiavi Where e OrderBy) - getAll($params) get di tutti i record che corrispondono ai parametri in $params - getBlock($start, $end, $parameters) get dei record dall'offset $start a $end che corrispondono ai parametri in $params - getPage($pagenum, $pagelen, $params) get dei record della pagina $pagenum che corrispondono ai parametri in $params. il parametro $pagelen esprime la lunghezza, in record, della pagina. Il valore di default è 10. - getHalf($pos, $params) get della metà dell'intero set di record (espressa da $pos. 1= prima metà, 2 = seconda metà) corrispondente ai parametri in $params. - getObject($params) get di un singolo oggetto (il primo in caso di più risultati), risultante dalla ricerca corrispondente ai parametri in $params - getAllBy_{nomecampo}($value) get di tuttii record in cui il campo {nomecampo} è uguale al parametro dato. Prendendo ad esempio la tabella Pagine citata sopra possiamo scrivere $pgn->getAllBy_Codice("home") Questo equivale ai risultati della query Select * From Pagine Where Codice='home' - getAllLike_{nomecampo}($value) Come il metodo precedente, solo che utilizza Like al posto di "=". Scrivendo quindi $pgn->getAllLike_Titolo("News%") si otterrà il risultato della query Select * From Pagine Where Titolo like 'News%' - getBlockBy_{nomecampo}($start,$end,$value) - getPageBy_{nomecampo}($pagenum,$pagelen,$value) - getHalfBy_{nomecampo}($pos,$value) - getObjectBy_{nomecampo}($value) Sono quindi tutti equivalenti dei metodi corrispondenti sopracitati, che però utilizzano il metodo di generazione della where visto per getAllBy_{nomecampo}($value) Metodi find a disposizione I metodi find sono in realtà molto simili, nella loro interfaccia e funzionamento, ai metodi get precedentemente visti. L'unica grande differenza, come già accennato, è che il fetch dei dati viene lasciato allo sviluppatore. I parametri $param sono sostanzialmente identicia quelli dei metodi get findAll($params) Prepara la query per il fetch di tutti i record corrispondenti ai parametri in $params findAllBy_{nomecampo}($value) Prepara la query per il fetch di tutti i record corrispondenti alla clausola “nomecampo='$value'” Rules Per semplificare i modelli dati e rendere il codice più gestibile e manutenibile è stato creato il concetto di “rule”. Una rule è di fatto una regola, tale e quale a quelle specificate tramite i parametri $params visti in precedenza, che può essere associata ad un identificativo e richiamata velocemente in un momento successivo. Per creare una rule si usa il metodo: $adbobject->addRule($rulename,$params); dove $adbobject è un oggetto derivato da ActiveDB, $rulename è l'identificativo univoco della rule e $params è un array associativo di parametri (Where, OrderBy). E' possibile specificare quindi una rule in questo modo: class Pagine extends ActiveDB {} $dbw=new MySQLDbWrapper("localhost","test","username","password"); $pgn=new Pagine($dbw); $pgn->addRule(“homepages”, array(Where => “Codice like 'home_%'”, OrderBy => “Ordine”)); In questo modo abbiamo creato una rule chiamata homepages che corrisponderà alla query: Select * From Pagine Where Codice like 'home_%' Order By Ordine In generale è però prassi apprezzata creare le rule direttamente nel costruttore della classe ActiveDB. Questo rende il codice più leggibile e evita duplicazioni dovute alla distrazione. In questo caso possiamo anche scrivere: class Pagine extends ActiveDB { public function __construct($dbw) { parent::__construct($dbw); $this->addRule(“homepages”, array(Where => “Codice like 'home_%'”, OrderBy => “Ordine”)); } } Così abbiamo ottenuto lo stesso effetto, però la rule sarà disponibile in ogni istanza della classe. Per potere utilizzare le rule appena create possiamo usare appositi metodi get o find: getAll_{rulename}() getObject_{rulename}() getBlock_{rulename}($start, $end) getPage_{rulename}($pagenum, $pagelen) Questi metodi si comportano come i corrispondenti metodi get e find precedentemente citati, ad esclusione del fatto che {rulename} specifica il nome della rule da applicare. Sarà quindi possibile scrivere, dato $pgn un oggetto di tipo Pagine: $homes=$pgn->getAll_homepages(); Rule con parametri Spesso ovviamente una rule non basta in tutte le situazioni. Ad esempio se vogliamo estrarre un set di record la cui data sia compresa tra due estremi. In questo caso saremmo costretti a usare una normale getAll() con un parametro “Where”. In questo caso ci vengono in aiuto le Rule con parametri. Prendiamo la tabella News così definita: NewsKEY: DataNews: Titolo: Abstract: Corpo: Thumbnail: chiave primaria Date varchar(255) varchr(255) Text varchar(255) Definiamo poi il modello per gestirla: class News extends ActiveDB { public function __construct($dbw) { parent::__construct($dbw); $this->addRule(“NewsInIntervallo”, array( Where => } } “DataNews between '%1' and '%2'” )); I placeholder %1 e %2 rappresentano i parametri della funzione get per utilizzare la rule. Questo significa che ora possiamo usare, ad esempio: $nws_lst=$nws->getAll_NewsInIntervallo(“2008-01-01”,”2008-12-31”); dove ovviamente news è un'istanza di una classe vista sopra. In caso di funzioni come getPage_ o getBlock_ che hanno alcuni parametri, i parametri della Rule vanno in coda. Ad esempio: $nws_lst=$nws->getBlock_NewsInIntervallo(1,10,“2008-01-01”,”2008-12-31”); ci restituirà un array delle news dalla 1 alla 10 con DataNews nel 2008. In questo caso non abbiamo specificato l'ordine in cui le news devono essere restituite. Possiamo ovviamente parametrizzare anche il campo ordine, nello stesso modo. Ad esempio potremmo volere le news in ordine ASC o DESC a seconda della lista che presentiamo nel sito. Facciamo una piccola modifica alla nostra classe: class News extends ActiveDB { public function __construct($dbw) { parent::__construct($dbw); $this->addRule(“NewsInIntervallo”, array( Where => “DataNews between '%1' and '%2'”, OrderBy => “DataNews %3” )); } e quindi $nws_lst=$nws->getAll_NewsInIntervallo(“2008-01-01”,”2008-12-31”,”DESC”); Gli inserimenti/modifiche/cancellazioni Appurato come gestire le ricerche con ActiveDB passiamo agli inserimenti, modifiche, cancellazioni. Prendiamo come esempio la classe News vista nel capitolo precendente. Istanziamola con: $dbw=new MySQLDbWrapper("localhost","test","username","password"); $nws=new News($dbw); Ora supponiamo di volere inserire una nuova news nella tabella: $nws->DataNews=”2008-01-01”; $nws->Titolo=”Plug è un mostro”; $nws->Abstract=”Plug e Giovanni di nitrostudio.it sono delle belve”; $nws->Corpo=”Lorem Ipsum etc etc Dolor etc Ipsum etc\n”. ”Lorem Ipsum etc etc Dolor etc Ipsum etc\n”. ”Lorem Ipsum etc etc Dolor etc Ipsum etc\n”; $nes->save(); In questo modo abbiamo eseguito una insert sul database. Al termine del'operazione la proprietà PrimaryKEY dell'oggetto $new viene settata sull'indice appena ottenuto dalla insert. Il metodo save si cura di eseguire l'operazione di insert oppure update a seconda della presenza o meno della PrimaryKEY dell'oggetto. Se un oggetto ha una primary key settata ad un valore il metodo save esegue una update, se la primary key non è settata allora viene eseguita una insert. Se vogliamo cercare un record e modificarlo sarà quindi possibile in questo modo: $nws_nitro=$nws->getObjectBy_ Titolo(“Plug è un mostro”); $nws_nitro->Titolo=”Plug e Giovanni sono delle belve”; $nws_nitro->save(); Questo produrrà una Update che cambia di fatto il titolo della news trovata. In alcuni casi è necessario utilizzare delle funzioni del DB per determinare il valore da inserire, come ad esempio NOW() su mysql per ottenere la data odierna. Anteponendo e postponendo “_” alla proprietà è possibile specificare al posto di un valore generico una funzione. Rivediamo il codice di prima: $nws->_DataNews_=”NOW()”; $nws->Titolo=”Plug è un mostro”; $nws->Abstract=”Plug e Giovanni di nitrostudio.it sono delle belve”; $nws->Corpo=”Lorem Ipsum etc etc Dolor etc Ipsum etc\n”. ”Lorem Ipsum etc etc Dolor etc Ipsum etc\n”. ”Lorem Ipsum etc etc Dolor etc Ipsum etc\n”; Come vedete DataNews è diventato _DataNews_, questo fa si che il valore “NOW()” invece che essere interpretato come stringa venga gestito come funzione (nel nostro caso di mysql). La cancellazione di un record funziona sostanzialmente secondo gli stessi principi. Prima si cerca un record, con effetto quindi di settare la PrimaryKEY, poi si usa il metodo delete(). Prendiamo come esempio la nostra news iniziale: $nws_nitro=$nws->getObjectBy_ Titolo(“Plug è un mostro”); $nws_nitro->delete(); In questo modo avremo cancellato la news sulla belvalità di nitrostudio. Le operazioni di update e delete si basano sempre sulla presenza di un valore nella chiave primaria della tabella. Per questo motivo le tabelle, per potere essere utilizzate con ActiveDB, devono sempre avere una chiave primaria. Le relazioni master/detail Come uscire dallo schema delle convenzioni I callback I metodi avanzati basewhere reset resetfields addfielda helpers Dsite Dsite è un framework di pubblicazione, basato sulle dlibs, che ha come scopo quello di velocizzare lo sviluppo di siti web e applicazioni, incoraggiando il riutilizzo del codice e separando il più possibile la logica dalla presentazione. Dsite implementa la classica architettura MVC, utilizzando come model oggetti ActiveDB, come view templates di smarty ( http://www.smarty.net ) L'architettura di Dsite prevede un sistema di plug-in per potere espandere velocemente, senza bisogno di agire a basso livello, il framework. Struttura delle directory cache Contiene le directory in cui le varie cache di Dsite vengono salvate. In particolare: smarty: contiene i templates compilati e le cache delle view (i templates di smarty) imagecache: contiene le cache dell'imageserver website: contiene le cache delle pagine config Contiene tutti i files con le configurazioni di base per Dsite. Normalmente Dsite è in grado di funzionare, eccetto per quello che riguarda il database, senza necessità di alterare i files di configurazione. La directory di installazione e tutti i path necessari vengono determinati automaticamente. autoload.php: contiene la funzione __autoload che serve a dsite per l'inclusione automatica delle classi. autosetup.php: al momento non utilizzato. cache.php: contiene la configurazione delle cache delle pagine html. Tramite questo file è possibile stabilire quali pagine o blocchi di pagine devono essere cachate, e il loro tempo di expire. database.php: contiene la configurazione dei “wrapper” usati per collegarsi ai database utilizzati da dsite. general.php: contiene la configurazione di tutti i path utilizzati dal framework, tra cui l'include path. E' molto importante che le Dlibs si trovino o nel path di sistema, specificato nel php.ini, o nel path specificato in questo file di configurazione. private.php: file da utilizzare per tutte le configurazioni personalizzate. libs Nella directory libs si trovano tutte le librerie e i plug-in che costituiscono il cuore di Dsite. In generale normalmente non è necessario modificare nessuno dei file presenti in questa Directory. website Questa directory contiene il “sito web” vero e proprio. E' qui che verrà svolta la totalità, o quasi, del lavoro necessario a costruire un sistema basato su Dsite. Le directory principali sono “controllers”, “models” e “views” che contengono le componenti omonime della struttura MVC. Tutte le altre directory sono directory di appoggio o di configurazione. amp Cartella di Anarchy Media Player ( http://an-archos.com/anarchy-media-player/ ), utilizzato molto spesso nei progetti con Dsite. controllers Contiene i controller di Dsite. files Normalmente utilizzata per contenere tutti i files che devono essere pubblicati sul sito. js, pics, styles Directory utilizzate per javascript, fogli di stile e immagini utilizzate dai templates (views) logs Normalmente i due log di base di Dsite, dsite.log e error.log vengono creati in questa directory. Si deve utilizzare questa directory anche per tutti gli altri log “custom”. models Contiene i modelli di Dsite. Per dsite un modello è una classe che estende ActiveDB (o una sua classe derivata). All'interno di models è presente una directory autoload. Tutti i modelli all'interno di essa saranno istanziati in automatica e passati automaticamente a views e controllers, ad ogni richiesta di url. I modelli che si trovano nella radice dovranno invece essere istanziati manualmente. In generale è buona prassi, per questioni di performance, utilizzare l'autoload dei modelli solo dove necessario. plugin-config Come già accennato in precedenza Dsite fa largo uso di plug-in per estendere le funzionalità di base. In questa cartella si trovano tutti i files di appoggio relativi alle configurazioni dei plug-in. Le interfaccie del back-end (Dcontent) e i file di configurazione dell'image server si trovano in questa cartella. variables La directory variables contiene le “variabili” di configurazione del sito e i cataloghi delle label statiche. Tramite i file contenuti in questa cartella è possibile creare parametri di configurazione dipendenti dalla lingua selezionata in Dsite. In particolare catalogs.php descrive le lingue supportate dal sito in questione, la lingua di default e le relative “label” statiche per ciascuna lingua. views In questa directory si trovano le views, ovvero i templates (smarty) che implementano la parte di rappresentazione del modello MVC. urlmap.php Questo file contiene il sistema di associazione url, controller, view utilizzzato da Dsite. Tramite questo file è possibile ad esempio stabilire quale template caricare in base all'url richiesto. index.php Questo è un file ad uso interno. Di fatto è il “gateway” verso il quale vengono indirizzate tutte le richieste. il suo compito è quello di inizializzare Dsite e di istanziare tutte le classi necessarie al corretto funzionamento del framework. In generale non dovrebbe mai essere modificato durante lo sviluppo di una applicazione DSite. Il primo test Tentiamo a questo punto un primo test di Dsite. Per un corretto funzionamento è necessario un ambiente che includa: Apache PHP5 mod_rewrite per apache il primo file che dobbiamo includere nella directory di root di dsite, che non è incluso nell'svn, è il file .htaccess che specifica il mapping delle directory e le necessarie regole di mod_rewrite. Un file di esempio si trova in config/htaccess_model. Il modello da utilizzare è il seguente: Options -Indexes <IfModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteRule index.html website/index.php [L] RewriteRule ^files/(.*)$ website/files/$1 [L] RewriteRule ^pics/(.*)$ website/pics/$1 [L] RewriteRule ^styles/(.*)$ website/styles/$1 [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . website/index.php [L] </IfModule> Il file, in sostanza, non fa altro che reindirizzare rel richieste che non corrispondono ad un file o cartella realmente esistente su website/index.php Il file mostrato qui sopra assume che il sito di test si trovi sulla root del webserver. In caso contrario, se ad esempio avessimo installato Dsite in /dsitetest, per accedervi tramite l'url http://<mydomain>/dsitetest dovremmo cambiare la riga con RewriteBase / RewriteBase /dsitetest/ Fatto questo assicuriamoci che al momento nessuna connessione con il database sia attiva. Aprendo config/database.php assicuriamoci che la riga che inizializza il DBWrapper di base (maindb) sia commentata. define("DB_HOST", define("DB_NAME", define("DB_USER", define("DB_PASS", "localhost"); "DSiteTest"); "root"); ""); //DBManager::addConnection("maindb",new MysqlDBwrapper(DB_HOST,DB_NAME,DB_USER,DB_PASS)); Fatto questo apriamo il file “website/urlmap.php” e facciamo in modo che contenga solo la riga: $website->registerUrl("^testpage$", array(Template => "testpage.html")); Come ultima cosa creiamo un file chiamato website/views/testpage.html <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>DSite testpage!</title> </head> <body> <h1>Ciao Mondo!</h1> </body> </html> ora, andando su http://myserver/testpage potremo vedere la nostra prima pagina. Vediamo in dettaglio le procedure di mapping dell'url, per capire come funziona. La riga $website->registerUrl("^testpage$", array(Template => "testpage.html")); corrisponde alla funzione registerUrl($url_expression, $control_array, $extradata_array) dell'oggetto base di Dsite, dove: $url_expression è una stringa che rappresenta un url che deve essere “matchato” da Dsite. La stringa può contenere i caratteri ^ e $ che rappresentano rispettivamente “inizio” e “fine” come nelle regular expressions, e dei blocchi {nomevariabile} che rappresentano il mapping tra tutto quello contenuto tra le parentesi {} e una variabile “nomevariabile”. Tutte le volte che viene trovata una corrispondenza tra $url_expression e l'url di richiesta verrà fermato il processo di matching e passato il controllo al controller e template specificati. In caso non venga specificato un controller (come nel nostro caso) il controller invocato sarà quello specificato dalla costante BASEC_NAME (config/general.php) Prendiamo per esempio $website->registerUrl("^{section}/news$", array(Template => "testpage.html")); Questo mapping verrà attivato in caso gli url di richiesta siano: http://myserver/products/news http://myserver/events/news http://myserver/team/news ma non nel caso: http://myserver/products/events Inoltre nel caso dei primi tre match positivi la variabile “section” passata automaticamente sia ai templates che al controller, avrà rispettivamente i valori di “products”, “events”, “team”. Per utilizzare una variabile che proviene dall'urlmap.php nei template basta utilizzare la sintassi {$nomevariabile}. Possiamo ad esempio utilizzare: website/urlmap.php $website->registerUrl("^{section}/news$", array(Template => "testpage.html")); website/views/testpage.html <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>DSite testpage!</title> </head> <body> <h1>Sei nelle news della sezione {$section}</h1> </body> </html> Multilingua Variabili di default Modelli e templates Controllers ImageServer Urlmap