Sviluppo componenti Joomla

33
1 Introduzione Introduzione Questa guida è allo stesso tempo una sintesi ed un approfondimento di una serie di articoli pubblicati sul mio blog (Sviluppare in Rete ) a partire dalla fine di Agosto 2007 quando la versione 1.5 di Joomla era allo stadio di release candidate. L'incoraggiamento di alcuni lettori mi ha convinto a realizzare una documenta- zione più organica e facilmente consultabile rispetto ad articoli sparsi su un blog. L'impostazione della guida è assolutamente pratica: si creerà un componente di esempio mostrando nel modo più dettagliato possibile il codice dei vari file che ne fanno parte. Il componente è strutturato secondo le linee guida per lo sviluppo dei componenti così come si ricavano dall'esame dell'esempio Hello World presentato nella sezione Developers del sito www.joomla.org. Per l'implementazione di alcune funzionalità che non sono presenti nel tutorial ufficiale (ad esempio la paginazione dei dati nel backend), mi sono ispirato al componente Weblinks incluso nell'installazione base di Joomla. Se riscontrate errori nel codice o nel testo o avete commenti, dubbi o domande potete contattarmi tramite il modulo contatti sul blog o con un messaggio su forum.joomla.org, nome utente gmassi). Se fossero necessarie correzioni o integrazioni, una versione aggiornata della guida e del codice di esempio sarà sempre scaricabile da questo indirizzo http://sviluppare.in.rete.googlepages.com/guida-componenti-joomla1-5 Questo documento è liberamente distribuibile purché rimanga nella sua forma integrale mantenendo i riferimenti all'autore. Spero che questo piccolo contributo alla comunità degli utenti di Joomla possa esservi utile. Massimo Giagnoni ( gmassi ) http://sviluppare-in-rete.blogspot.com/ ©2008 Sviluppare in Rete

description

Developer document

Transcript of Sviluppo componenti Joomla

Page 1: Sviluppo componenti Joomla

1 Introduzione

Introduzione

Questa guida è allo stesso tempo una sintesi ed un approfondimento di una serie di articoli pubblicati sul mio blog (Sviluppare in Rete ) a partire dalla fine di Agosto 2007 quando la versione 1.5 di Joomla era allo stadio di release candidate.

L'incoraggiamento di alcuni lettori mi ha convinto a realizzare una documenta-zione più organica e facilmente consultabile rispetto ad articoli sparsi su un blog.

L'impostazione della guida è assolutamente pratica: si creerà un componente di esempio mostrando nel modo più dettagliato possibile il codice dei vari file che ne fanno parte.

Il componente è strutturato secondo le linee guida per lo sviluppo dei componenti così come si ricavano dall'esame dell'esempio Hello World presentato nella sezione Developers del sito www.joomla.org. Per l'implementazione di alcune funzionalità che non sono presenti nel tutorial ufficiale (ad esempio la paginazione dei dati nel backend), mi sono ispirato al componente Weblinks incluso nell'installazione base di Joomla.

Se riscontrate errori nel codice o nel testo o avete commenti, dubbi o domande potete contattarmi tramite il modulo contatti sul blog o con un messaggio su forum.joomla.org, nome utente gmassi).

Se fossero necessarie correzioni o integrazioni, una versione aggiornata della guida e del codice di esempio sarà sempre scaricabile da questo indirizzo

http://sviluppare.in.rete.googlepages.com/guida-componenti-joomla1-5

Questo documento è liberamente distribuibile purché rimanga nella sua forma integrale mantenendo i riferimenti all'autore.

Spero che questo piccolo contributo alla comunità degli utenti di Joomla possa esservi utile.

Massimo Giagnoni ( gmassi )http://sviluppare-in-rete.blogspot.com/

©2008 Sviluppare in Rete

Page 2: Sviluppo componenti Joomla

Il componente di esempio 2

Il componente di esempio

Immagino avrete visto in qualche portale quelle pagine 'Accadde oggi ...' o simili dove sono riportati fatti del passato accaduti nella data del giorno.

Il componente consentirà di creare una pagina di questo tipo in un sito realizzato con Joomla. L'idea non è originalissima, se ricordo bene esiste un componente del genere per la versione precedente di Joomla, comunque l'importante era avere un esempio semplice anche se non troppo banale.

Nel backend si gestirà un archivio di eventi storici, nel frontend saranno mostrate le descrizioni di fatti passati accaduti nel giorno e mese attuali. Con qualche modifica si potrebbe usare il componente per mostrare la ricetta del giorno, la barzelletta del giorno e così via.

Il pacchetto di installazione è disponibile al seguente indirizzo:

http://sviluppare.in.rete.googlepages.com/guida-componenti-joomla1-5

Il nome del componente è com_pastevents.

Probabilmente è una buona idea procedere all'installazione, creare un link al componente in un menu e fare qualche prova prima di proseguire con la lettura. Sarà più facile seguire la spiegazione avendo i sorgenti a portata di mano.

©2008 Sviluppare in Rete

Page 3: Sviluppo componenti Joomla

3 Struttura di un componente per Joomla 1.5

Struttura di un componente per Joomla 1.5

Paragonata a quella di un componente scritto per una delle versioni precedenti del cms, la struttura di un componente per Joomla 1.5 è molto più modulare. Il team di sviluppo ha infatti adottato una metodologia di programmazione orientata agli oggetti seguendo il design pattern Model-View-Controller.

Ora non è il caso di mettersi a fare troppa teoria. Per limitarsi all'essenziale si può dire che secondo questa impostazione un'applicazione si compone di tre categorie fondamentali di oggetti.

● Model: gestisce la logica applicativa, accede ai dati (di un database, file o altra fonte), compie le necessarie elaborazioni e fornisce il risultato agli altri oggetti.

● View: organizza i dati in un formato adatto alla visualizzazione all'utente.

● Controller: acquisisce le richieste dell'utente e le indirizza agli altri oggetti perché vengano eseguite.

Sviluppare un componente implica la creazione, oltre che di un certo numero di file di servizio, delle classi contenenti le definizioni degli oggetti Model, View e Controller necessari al funzionamento del componente.

È il caso di iniziare a scendere un po' più nel concreto.

©2008 Sviluppare in Rete

Page 4: Sviluppo componenti Joomla

File XML di installazione 4

File XML di installazione

Tutte le informazioni necessarie a Joomla per installare il componente sono contenute in un file xml pastdays.xml.

<?xml version="1.0" encoding="utf-8"?><!DOCTYPE install SYSTEM "http://dev.joomla.org/xml/1.5/component-install.dtd"><install type="component" version="1.5.0">

Queste prime righe devono essere riportate così come sono nel file xml di qualsiasi componente.

<name>PastDays</name> <creationDate>February 2008</creationDate> <author>Massimo Giagnoni</author> <authorUrl>http://sviluppare-in-rete.blogspot.com/</authorUrl> <copyright>Copyright 2008 Massimo Giagnoni</copyright> <license>http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL</license> <version>1.0</version> <description> <![CDATA[Esempio di componente allegato alla <b>Guida allo sviluppo di componenti per Joomla 1.5</b>]]> </description>

Il significato di questi tag dovrebbe essere autoesplicativo: nome del componente, informazioni sull'autore, copyright e versione.

<install> <sql> <file charset="utf8" driver="mysql">install.sql</file> </sql> </install> <uninstall> <sql> <file charset="utf8" driver="mysql">uninstall.sql</file> </sql> </uninstall>

Script SQL per la creazione delle tabelle sul database che vengono eseguiti quando il componente viene installato e disinstallato.

<files folder="site"> <filename>pastdays.php</filename> <filename>controller.php</filename> <filename>views/pastdays/view.html.php</filename> <filename>views/pastdays/tmpl/default.php</filename> <filename>models/pastdays.php</filename> </files>

I file che compongono il frontend del componente. L'attributo folder del tag

©2008 Sviluppare in Rete

Page 5: Sviluppo componenti Joomla

5 File XML di installazione

<files> indica che questi file si trovano in una cartella site all'interno del pacchetto di installazione.

Tutti questi file saranno copiati dalla procedura di installazione in

[...]/components/com_pastdays/

Dove i puntini rappresentano il percorso sul vostro server web fino alla cartella dove avete installato Joomla.

<languages> <language tag="it-IT">languages/site/it-IT.com_pastdays.ini</language> </languages>

File per la localizzazione della parte frontend del componente. Ne vedremo tra poco la struttura.

<administration> <menu>Past Days</menu> <files folder="admin"> <filename>admin.pastdays.php</filename> <filename>controller.php</filename> <filename>controllers/pdevent.php</filename> <filename>tables/pdevent.php</filename> <filename>views/pastdays/view.html.php</filename> <filename>views/pastdays/tmpl/default.php</filename> <filename>views/pdevent/view.html.php</filename> <filename>views/pdevent/tmpl/default.php</filename> <filename>models/pastdays.php</filename> <filename>models/pdevent.php</filename> <filename>helpers/pastdays.php</filename> <filename>install.sql</filename> <filename>uninstall.sql</filename> </files>

File del backend del componente. <menu> imposta il titolo del menu attraverso il quale si accederà all'amministrazione del componente.

Analogamente a quanto abbiamo visto sopra l'attributo folder del tag <files> indica che questi file si trovano in una cartella admin nel pacchetto di installazione.

Saranno copiati in

[...]/administrator/components/com_pastdays/ <languages> <language tag="it-IT">languages/admin/it-IT.com_pastdays.ini</language> </languages>

File per la localizzazione della parte backend del componente.

©2008 Sviluppare in Rete

Page 6: Sviluppo componenti Joomla

File XML di installazione 6

</administration></install>

fine pastdays.xml

©2008 Sviluppare in Rete

Page 7: Sviluppo componenti Joomla

7 Script SQL

Script SQL

Sono eseguiti automaticamente quando il componente viene installato o disinstallato. Nel nostro esempio si tratta di creare e cancellare una singola tabella.

Install.sql

DROP TABLE IF EXISTS `#__pastdays`;

CREATE TABLE `#__pastdays` (`id` INT NOT NULL AUTO_INCREMENT,`year` char(4) NOT NULL,`month` char(2) NOT NULL,`day` char(2) NOT NULL,`description` TEXT NOT NULL,PRIMARY KEY (`id`),KEY `monthday` (`month`,`day`)) DEFAULT CHARSET=utf8;

La sequenza #__ viene automaticamente sostituita con il prefisso per le tabelle del database, jos_ a meno che non se ne sia scelto uno diverso quando si è installato Joomla.

Uninstall.sql

DROP TABLE IF EXISTS `#__pastdays`;

©2008 Sviluppare in Rete

Page 8: Sviluppo componenti Joomla

File per la localizzazione 8

File per la localizzazione

Il componente include due file .ini per la localizzazione rispettivamente della parte frontend e backend del componente. Il nome del file è sempre it-IT.com_pastdays.ini

Il primo è incluso in languages/site, l'altro in languages/admin nel pacchetto di installazione.

it-IT.com_pastdays.ini (frontend)NO EVENTS=Nessun evento

it-IT.com_pastdays.ini (backend)EVENT DATE=Data Evento

EVENT DESCRIPTION=Descrizione Evento

DETAILS=Dettagli

YOU MUST ENTER A DESCRIPTION=Devi inserire una descrizione

YOU MUST ENTER A DAY=Devi inserire un giorno

YOU MUST ENTER A MONTH=Devi inserire un mese

EVENT(S) DELETED=Evento/i cancellato/i

ERROR DELETING ONE OR MORE EVENTS=Errore durante la cancellazione di uno o più eventi

EVENT SAVED=Evento salvato

ERROR SAVING EVENT=Errore durante il salvataggio dell'evento

OPERATION CANCELLED=Operazione annullata

La struttura è semplice: a sinistra del segno = la stringa da tradurre, a destra la traduzione.

Sarà ovviamente necessario creare due file per ogni lingua in cui si vuole localizzare il componente. Se volessimo la localizzazione anche in lingua tedesca dovremmo creare due file

de-DE.com_pastdays.ini

©2008 Sviluppare in Rete

Page 9: Sviluppo componenti Joomla

9 Frontend del componente

Frontend del componente

File principale

Il file contenente il codice a cui viene passato il controllo dal framework quando viene eseguito il componente.

File: pastdays.phpCartella: [...]/components/com_pastdays/<?php// Impedisce l'accesso diretto al filedefined('_JEXEC') or die('Restricted access');

Si tratta di una misura di sicurezza che impedisce l'accesso diretto al file.

Esempio: se tentaste di aprire direttamente il file nel vostro browser inserendo nella barra degli indirizzi qualcosa del tipo

http://www.esempio.it/components/com_pastdays/pastdays.php

otterreste solo il messaggio Restricted access.

E' importante ricordarsi sempre di inserire questa riga come prima istruzione di ogni file che fa parte del componente.

// Richiede la classe Controller principale del componenterequire_once(JPATH_COMPONENT. DS . 'controller.php');

// Richiede una classe specifica se// controller=nome_controller è presente in $_REQUESTif($controller = JRequest::getWord('controller')) { $path = JPATH_COMPONENT . DS . 'controllers' . DS . $controller . '.php'; if(file_exists($path)) { require_once $path; } else { $controller = ''; }}

Vengono inclusi i file con le definizioni delle classi Controller necessarie al componente. Si tratta di una parte standard che potete tranquillamente trasferire nei vostri componenti senza modifiche. La vedremo in dettaglio tra poco.

JPATH_COMPONENT è una costante di sistema che contiene il percorso sul server della cartella dove si trova il frontend del componente.

DS (directory separator) è un'altra costante che contiene il carattere separatore

©2008 Sviluppare in Rete

Page 10: Sviluppo componenti Joomla

Frontend del componente 10

di directory (sarà / su Linux/Unix e \ su Windows). Utilizzando sempre questa costante nei percorsi si favorisce la portabilità del componente sui diversi sistemi.

// Crea un'instanza dell'oggetto Controller$classname = 'PastDaysController'. $controller;$controller = new $classname();

Viene creato l'oggetto Controller come istanza della classe inclusa preceden-temente.

Quando sviluppiamo la parte frontend di un componente dobbiamo sempre definire una classe Controller base , derivata da JController e definita nel file controller.php, situato nella cartella principale del componente.

Il nome della classe Controller base è creato aggiungendo la costante 'Controller' ad un prefisso che di solito è il nome del componente senza il com_ iniziale, quindi, nel nostro caso

PastDaysController

Questo prefisso ha un ruolo importante nella determinazione dei nomi delle classi degli oggetti View e Model, da ora in poi mi riferirò ad esso come [nome_base].

Esaminando la logica del codice sopra riportato, è facile rendersi conto che il file controller.php viene sempre incluso.

Oltre ad una classe Controller base possono esistere anche classi Controller derivate .

Sempre con un occhio al codice si nota che se nella richiesta è passata una variabile controller (cioè se $_REQUEST['controller'] è impostata) se ne legge il valore ( con JRequest::getWord() ) e si include un file con questo nome (ed estensione .php) che si trova nella cartella controllers e contiene la definizione della classe Controller derivata.

Il nome di questa classe ha la forma

[nome_base]+Controller+[nome_controller] (da $_REQUEST['controller'])

È inoltre importante sottolineare che le classi Controller derivate non discendono da JController, ma dalla classe Controller base.

A parte quest'ultima notazione, tutto il resto deriva dalla logica di quelle poche righe di codice contenute nel file principale del componente. Capite quelle e avrete capito tutto!

©2008 Sviluppare in Rete

Page 11: Sviluppo componenti Joomla

11 Frontend del componente

Breve riassunto.

Classe Controller base

Nome: [nome_base]+Controller[nome_base] è di solito il nome del componente senza com_File: [...]/components/[nome_componente]/controller.php

Classi Controller derivate

Nome: [nome_base]+Controller+[nome_controller][nome_controller] preso da $_REQUEST['controller']File: [...]/components/[nome_componente]/controllers/[nome_controller].php

Nel nostro esempio esiste il solo Controller base per il frontend, mentre esistono un Controller base e uno derivato per il backend.

L'oggetto Controller determina quale funzione (task) deve essere eseguita dal componente, di regola elaborando una richiesta dell'utente che interagisce con elementi della pagina web (link, pulsanti). Invoca poi i metodi degli altri oggetti (Model e View) che servono ad eseguire tale funzione.

//Esegue task (ottenuto da $_REQUEST)$controller->execute(JRequest::getVar('task'));

Il metodo execute(), che il nostro oggetto Controller eredita dalla classe base JController, viene invocato e riceve come argomento il valore in $_REQUEST['task'] (se esiste).

getVar() è una funzione di utilità che serve a leggere un valore da $_REQUEST, $_POST, $_GET. Come molte funzioni di questo tipo presenti nel framework di Joomla, è incapsulata in una classe e va quindi chiamata come metodo statico ( Classe::metodo() ).

Incontreremo altri utilizzi di getVar() (o funzioni simili come getWord(), vedi poco sopra nel codice). È importante non accedere direttamente alle variabili superglobali del PHP, ma utilizzare queste funzioni del framework che compiono dietro le quinte una serie di controlli di validazione dell'input molto importanti per la sicurezza dei nostri componenti.

// Esegue un eventuale redirect$controller->redirect();?>

Viene eseguito un eventuale reindirizzamento di pagina se impostato nel Controller con setRedirect().

©2008 Sviluppare in Rete

Page 12: Sviluppo componenti Joomla

Frontend del componente 12

Controller PastDays (base)

Abbiamo visto le istruzioni che creano un oggetto Controller, dobbiamo creare il file contenente la definizione della classe corrispondente.

File: controller.phpCartella: [...]/components/com_pastdays/<?php// Impedisce l'accesso diretto al filedefined('_JEXEC') or die('Restricted access');

// Include la classe base JControllerjimport('joomla.application.component.controller');

class PastDaysController extends JController {

Dopo quanto detto sopra il nome della classe è quello che ci si aspetta per un Controller base.

function display() { parent::display(); }}?>

fine controller.php

Poiché il componente che stiamo creando è molto semplice abbiamo un solo metodo, display(). Di regola in una classe Controller devono essere implementati tanti metodi quanti sono i task che il controller deve elaborare.

Serve un esempio. Mettiamo che un componente venga invocato con questa URL

.../index.php?option=com_nomecomponente&task=register

Ricorderete l'istruzione

$controller->execute(JRequest::getVar('task'));

che abbiamo trovato esaminando il file principale.

Il metodo execute() (implementato in JController e quindi ereditato dalla nostra classe Controller) esegue il metodo che ha lo stesso nome della variabile task ricevuta come argomento, in questo caso register(), a patto che, ovviamente, un metodo con questo nome sia stato definito nella classe.

Però l'indicazione di un task non è obbligatoria. Un componente può essere invocato semplicemente con

.../index.php?option=com_nomecomponente

Quando non è specificato alcun task si assume come task display e viene quindi eseguito il metodo display() del Controller.

©2008 Sviluppare in Rete

Page 13: Sviluppo componenti Joomla

13 Frontend del componente

A voler essere precisi, va detto che in fase di creazione dell'oggetto Controller si potrebbe specificare un metodo diverso da display() da utilizzare in mancanza di uno specifico task, ma sono dettagli che non vedremo nel codice di esempio.

In questo caso il metodo display() chiama semplicemente il metodo omonimo della classe base JController.

View PastDays

Il metodo display() del Controller esegue il metodo omonimo di un altro oggetto, dal Controller stesso preventivamente creato, la View.

Si è accennato all'inizio che la funzione di questo oggetto è determinare il modello di rappresentazione utilizzato per la visualizzazione dei dati richiesti. La View utilizza un oggetto Model per la selezione dei dati, mentre le istruzioni che provvedono alla effettiva generazione del documento da servire al client sono contenute nel Template (o layout) a cui la View passa i dati da visualizzare.

Poiché un componente può utilizzare molteplici View, come determina l'oggetto Controller quale classe deve essere utilizzata per istanziare l'oggetto View ed invocarne il metodo display()?

Se una variabile view è passata nella richiesta (cioè se $_REQUEST['view'] è impostata) questo valore è utilizzato come nome della View.

In caso contrario ($_REQUEST['view'] non impostata) si assume [nome_base] (avevo detto che sarebbe servito ancora!) come nome della View.

Il nome della View serve a reperire il file con la definizione della classe relativa che è

[...]/components/nome_componente/views/[nome_view]/view.html.php

A dire il vero questo non è del tutto esatto: view.html.php è il nome di file che si incontra più frequentemente, ma in un componente potremmo trovare ad esempio un file view.pdf.php. Il tipo di documento che la View genera determina la parte centrale del nome del file. Mi fermo qui senza scendere in ulteriori dettagli. Tutti le View che incontreremo generano documenti html per cui i nomi dei file contenenti la definizione della classe saranno sempre view.html.php.

Il nome della classe definita nel file deve avere questa forma

[nome_base]+View+[nome_view]

Tutto questo lavoro per determinare le classi da utilizzare per la creazione di un oggetto View è svolto dal framework (in particolare dalla classe JController). Ho cercato di semplificare il più possibile dicendo però quello che è necessario per capire quali nomi utilizzare per le classi View e Model dei nostri componenti.

©2008 Sviluppare in Rete

Page 14: Sviluppo componenti Joomla

Frontend del componente 14

Vedremo subito un esempio in concreto.

File: view.html.phpCartella: [...]/components/com_pastdays/views/pastdays/<?php// Impedisce l'accesso diretto al filedefined('_JEXEC') or die( 'Restricted access' );

// Include la classe base JViewjimport('joomla.application.component.view');

class PastDaysViewPastDays extends JView {

Perché questo nome di classe, PastDaysViewPastDays ?

Il primo PastDays è [nome_base] e questo lo abbiamo detto fin dall'inizio. View è una parte costante. Abbiamo anche detto poco fa che quando il nome della View non è contenuto nella richiesta si assume uguale a [nome_base].

Quindi con questo nome di classe definiamo la View predefinita del Controller base PastDaysController. In mancanza dell'indicazione di un diverso nome View ( in, ricordo, $_REQUEST['view'] ) il Controller utilizzerà questa classe per creare l'oggetto View ed invocarne il metodo display().

function display($tpl = null) { // Ottiene da Model i dati da visualizzare $events =& $this->get('Data');

Ottiene i dati da visualizzare. Una spiegazione più dettagliata deve essere rimandata a quando avremo esaminato l'oggetto Model.

// Riferimento per il template $this->assignRef('rows', $events);

Assegna un riferimento rows ai dati da visualizzare. Questo riferimento verrà utilizzato dal Template.

// Visualizza template parent::display($tpl); }}?>

fine view.html.php

Passa il controllo al Template.

Template

Le istruzioni per l'output dei dati sono localizzate nel Template. Ad una View possono essere associati più Template, default è quello predefinito ed è l'unico che incontreremo nel nostro esempio.

©2008 Sviluppare in Rete

Page 15: Sviluppo componenti Joomla

15 Frontend del componente

Un Template si trova sempre in una cartella tmpl all'interno della cartella della relativa View.

File: default.phpCartella: [...]/components/com_pastdays/views/pastdays/tmpl/

Il commento può essere ridotto all'essenziale in quanto si tratta per lo più di semplici istruzioni per l'output del codice html necessario alla creazione della pagina da visualizzare.

<?php // Impedisce l'accesso diretto al filedefined('_JEXEC') or die('Restricted access'); require JPATH_COMPONENT_ADMINISTRATOR . DS . 'helpers' . DS . 'pastdays.php';

Include un file contentente alcune funzioni di supporto necessarie al componente.

?><?php if(count($this->rows) == 0) { echo JText::_('No Events');

Funzione per la localizzazione del componente: la stringa passata come argomento sarà tradotta utilizzando il file .ini corrispondente alla lingua impostata per il sito.

Come abbiamo visto il file it-IT.com_pastadays.ini per il frontend contiene la riga

NO EVENTS=Nessun evento

che sarà utilizzata per la traduzione.

} else { foreach($this->rows as $r) {

$this->rows

è l'insieme degli eventi da visualizzare. Vi si accede con questo identificatore perché nella View abbiamo l'istruzione

$this->assignRef('rows', $events);?><div class="pastdays-date"><?php echo $r->day . ' ' . PastDaysHelper::monthName($r->month) . ' ' . $r->year;?></div><div class="pastdays-descr"><?php echo $r->description; ?></div><?php } // Fine foreach

©2008 Sviluppare in Rete

Page 16: Sviluppo componenti Joomla

Frontend del componente 16

}?>

fine default.php

Model PastDays

Abbiamo lasciato per ultimo Model. Come detto, la sua funzione è quella di contenere la logica applicativa del componente e fornire i suoi servizi ai Controller e alle View.

Un oggetto Model è creato dal Controller che, a seconda del tipo di operazione, ne invoca direttamente i metodi oppure lo assegna ad un oggetto View e in questo caso sarà quest'ultima a servirsene.

Le definizioni delle classi da cui si istanziano gli oggetti Model si trovano in una cartella models. Il nome del file è sempre

[nome_model].php

Il nome della classe ha la forma

[nome_base]+Model+[nome_model]

Ecco quindi la classe per l'oggetto Model del frontend.

File: pastdays.phpCartella: [...]/components/com_pastdays/models/<?php// Impedisce l'accesso diretto al filedefined('_JEXEC') or die();

// Include la classe base JModeljimport('joomla.application.component.model');

class PastDaysModelPastDays extends JModel {

A proposito del nome della classe va tenuto presente che quando il Controller crea un oggetto View crea anche un oggetto Model con lo stesso nome della View e lo assegna alla View.

PastDaysModelPastDays sarà quindi la classe utilizzata per creare l'oggetto Model da assegnare alla View PastDays (classe PastDaysViewPastDays) che abbiamo visto in precedenza.

function &getData() { // Array con mese e giorno di oggi $d = explode('-', date('m-d')); $sql = "SELECT * FROM #__pastdays " . "WHERE month = '{$d[0]}' AND day ='{$d[1]}'"; $this->_db->setQuery($sql);

©2008 Sviluppare in Rete

Page 17: Sviluppo componenti Joomla

17 Frontend del componente

$events = $this->_db->loadObjectList(); return $events; }}?>

fine pastdays.php

L'unico metodo getData() ha la funzione di estrarre dal database la lista degli eventi accaduti nel giorno e mese attuali.

Da notare solo che $this->_db contiene un riferimento all'oggetto database di sistema. Questa proprietà è inizializzata automaticamente dal costruttore della classe base (JModel) in vista del fatto che molte della funzionalità di un oggetto Model necessitano dell'accesso al database.

Resta da dire una cosa importante sui rapporti tra Model e View: quando un oggetto Model possiede un metodo il cui nome inizia con get, la View a cui l'oggetto Model è stato assegnato può leggere il valore di ritorno di quel metodo attraverso un proprio metodo get() che riceve come argomento il nome del metodo di Model meno il get iniziale.

Detto questo possiamo concludere la spiegazione del codice presente nella View PastDays.

$events = $this->get('events');

$events contiene il valore di ritorno del metodo getEvents() dell'oggetto Model, vale a dire un array contenente gli eventi da visualizzare.

©2008 Sviluppare in Rete

Page 18: Sviluppo componenti Joomla

Backend del componente 18

Backend del componente

Il backend di un componente non è strutturato in modo molto diverso dal frontend. Dovremo quindi creare un file principale (entry point) e classi Controller (base e derivate), View e Model.

File principale

File: admin.pastdays.phpCartella: [...]/administrator/components/com_pastdays/<?php// Impedisce l'accesso diretto al filedefined('_JEXEC') or die();

// Richiede la classe Controller principale del componenterequire_once(JPATH_COMPONENT.DS.'controller.php');

// Richiede una classe specifica// (se controller=nome_controller è presente in $_REQUEST)if($controller = JRequest::getWord('controller')) { $path = JPATH_COMPONENT.DS.'controllers'.DS.$controller.'.php'; if(file_exists($path)) { require_once $path; } else { $controller = ''; }}

// Crea un'instanza dell'oggetto Controller$classname = 'PastDaysController'.$controller;$controller = new $classname();

//Esegue task (letto da $_REQUEST)$controller->execute(JRequest::getVar('task'));

// Esegue un eventuale redirect$controller->redirect();?>

fine admin.pastdays.php

Il codice è del tutto identico al file principale del frontend per cui non è necessario alcun commento.

Controller PastDays (base)

File: controller.phpCartella: [...]/administrator/components/com_pastdays/<?php

©2008 Sviluppare in Rete

Page 19: Sviluppo componenti Joomla

19 Backend del componente

// Impedisce l'accesso diretto al filedefined( '_JEXEC' ) or die( 'Restricted access' );

// Include la classe base JControllerjimport('joomla.application.component.controller');

class PastDaysController extends JController { function display() { parent::display(); }}?>

fine controller.php

Anche qui nessuna novità. Ricordo che il metodo display() istanzierà un oggetto View di classe PastDaysViewPastDays e ne invocherà il metodo display().

View PastDays

File: view.html.phpCartella: [...]/administrator/components/com_pastdays/views/pastdays/<?php// Impedisce l'accesso diretto al filedefined('_JEXEC') or die('Restricted access');

// Include la classe base JViewjimport('joomla.application.component.view');

class PastDaysViewPastDays extends JView {

In base a quanto già spiegato per la parte frontend, il nome della classe ci indica che questa è la View predefinita del Controller base del backend PastDaysController.

function display($tpl = null) { // Oggetto per la paginazione dei dati $pagination =& $this->get('Pagination'); // Ottiene i dati da Model $items =& $this->get('Data');

Ormai abbiamo familiarità con questa notazione e dobbiamo aspettarci un oggetto Model con implementati metodi getData() e getPagination(), lo troveremo in seguito.

// Passa i dati al template $this->assignRef('items', $items); $this->assignRef('pagination', $pagination); parent::display($tpl); }}?>

fine view.html.php

©2008 Sviluppare in Rete

Page 20: Sviluppo componenti Joomla

Backend del componente 20

Come al solito vengono predisposti i riferimenti per il Template.

Template

Si occupa dell'output del codice html necessario alla visualizzazione dell'elenco eventi.

File: default.phpCartella: [...]/administrator/components/com_pastdays/views/pastdays/tmpl/<?php// Impedisce l'accesso diretto al file defined('_JEXEC') or die( 'Restricted access' );require JPATH_COMPONENT_ADMINISTRATOR . DS . 'helpers' . DS . 'pastdays.php';// Crea pulsanti standard barra di strumentiJToolBarHelper::title( JText::_('PastDays' ), 'generic.png');JToolBarHelper::deleteList();JToolBarHelper::editListX();JToolBarHelper::addNewX();?>

Queste istruzioni servono a generare il codice html per l'intestazione della pagina e tre pulsanti sulla barra degli strumenti: Cancella, Modifica e Nuovo.

Come abbiamo già visto in precedenza per altre funzioni standard, anche in questo caso si tratta di metodi statici di una classe definita nel framework (JToolbarHelper).

Poiché non abbiamo passato argomenti ad alcuno dei metodi, tutte le impostazioni sono quelle predefinite inclusi i task associati alla pressione dei pulsanti: rispettivamente remove, edit e add.

<form action="index.php" method="post" name="adminForm"><div id="editcell"> <table class="adminlist"> <thead> <tr> <th width="5"> <?php echo JText::_('ID'); ?> </th> <th width="20"> <!-- checkbox per selezionare tutti i record --> <input type="checkbox" name="toggle" value="" onclick="checkAll(<?php echo count($this->items); ?> );" /> </th>

Funzione standard per la casella di selezione (checkbox) che seleziona / deseleziona tutti i record nell'elenco.

<th width="125"> <?php echo JText::_('Event Date'); ?> </th> <th> <?php echo JText::_('Event Description'); ?> </th>

©2008 Sviluppare in Rete

Page 21: Sviluppo componenti Joomla

21 Backend del componente

Intestazioni delle colonne dell'elenco.

</tr> </thead> <tfoot> <tr> <td colspan="4"> <?php echo $this->pagination->getListFooter(); ?> </td> </tr> </tfoot> <tbody>

Inserisce i link per la paginazione dei dati e la lista di selezione con cui l'utente controlla il numero dei record da mostrare in ogni pagina dell'elenco.

<?php $k = 0; $n=count($this->items); for($i=0 ; $i < $n; $i++) {

Ciclo per la lettura dei dati. $this->items contiene l'array delle righe da visualizzare.

$row =& $this->items[$i]; // codice HTML per checkbox $checked = JHTML::_('grid.id', $i, $row->id );

Genera il codice per la casella di selezione del record all'inizio di ciascuna riga.

// Crea link per editare il record $link = JRoute::_('index.php?option=com_pastdays&controller=pdevent&task=edit&cid[]='. $row->id); $d = (int)$row->day.' '.PastDaysHelper::monthName($row->month).' '. $row->year; ?> <tr class="<?php echo "row$k"; ?>"> <td> <?php echo $row->id; ?> </td> <td> <?php echo $checked; ?> </td> <td> <?php echo JHTML::link($link, $d); ?> </td> <td> <?php echo $row->description; ?> </td> </tr> <?php //Per la classe che imposta lo sfondo delle righe a colori alternati $k = 1 - $k; } // Fine for ?>

©2008 Sviluppare in Rete

Page 22: Sviluppo componenti Joomla

Backend del componente 22

</tbody> </table></div><input type="hidden" name="option" value="com_pastdays" /><input type="hidden" name="task" value="" /><input type="hidden" name="boxchecked" value="0" />

Questi campi nascosti devono sempre essere presenti in quanto servono a trasmettere il valore del task e per lo script che gestisce la selezione dei record nell'elenco.

<input type="hidden" name="controller" value="pdevent" />

Il task generato dalla pressione di uno dei pulsanti sarà passato al controller derivato PDEvent che creeremo.

</form>

fine default.php

Model PastDays

File: pastdays.phpCartella: [...]/administrator/components/com_pastdays/models/<?php// Impedisce l'accesso diretto al filedefined('_JEXEC') or die();

// Include la classe base JModeljimport('joomla.application.component.model');

class PastDaysModelPastDays extends JModel {

Il nome della classe ci dice che questa è la classe che sarà utilizzata per creare l'oggetto Model da assegnare alla View PastDays (classe PastDaysViewPastDays vista in precedenza)

var $_data; var $_total = null; var $_pagination = null; function __construct() { parent::__construct();

global $mainframe, $option;

$limit = $mainframe->getUserStateFromRequest('global.list.limit', 'limit',

$mainframe->getCfg('list_limit'), 'int'); $limitstart = $mainframe->getUserStateFromRequest($option.'limitstart', 'limitstart', 0, 'int');

$limitstart = ($limit != 0 ? (floor($limitstart / $limit) * $limit):0); $this->setState('limit', $limit);

©2008 Sviluppare in Rete

Page 23: Sviluppo componenti Joomla

23 Backend del componente

$this->setState('limitstart', $limitstart); } function getTotal() { if (empty($this->_total)) { $query = $this->_buildQuery(); $this->_total = $this->_getListCount($query); } return $this->_total; } function &getPagination() { if (empty($this->_pagination)) { jimport('joomla.html.pagination'); $this->_pagination = new JPagination( $this->getTotal(), $this->getState('limitstart'), $this->getState('limit') ); } return $this->_pagination; }

Il codice nel costruttore e i metodi getTotal() e getPagination() servono per implementare nel nostro componente la funzione standard di paginazione dei dati nell'elenco. Non voglio entrare troppo nei dettagli, si tratta di una parte che può essere trasferita da componente a componente praticamente senza modifiche. Il codice che vedete è tratto dal componente Weblinks fornito con l'installazione base di Joomla.

function _buildQuery() { $query = ' SELECT * ' . ' FROM #__pastdays '; return $query; } function &getData() { // Carica i dati se non esistono già if(empty($this->_data)) { $query = $this->_buildQuery(); $pagination = $this->getPagination(); $this->_data = $this->_getList($query, $pagination->limitstart, $pagination->limit); } return $this->_data; }}?>

fine pastdays.php

Predisposizione ed esecuzione della query per l'estrazione dei record.

_getList() è un metodo privato ereditato da JModel: riceve come argomenti una query sql e i valori di limit e limitstart (per la paginazione dei dati) e ritorna il risultato come array di oggetti.

©2008 Sviluppare in Rete

Page 24: Sviluppo componenti Joomla

Backend del componente 24

Controller PDEvent (derivato)

Ricordo che abbiamo deciso che i task associati ai pulsanti Cancella, Modifica e Nuovo sulla barra degli strumenti nella schermata che mostra l'elenco dei dati siano processati non dal controller base, ma da un controller derivato di nome PDEvent.

Ricordo anche che questi task sono quelli standard per questo tipo di pulsanti: remove, edit, add.

Dobbiamo quindi creare una classe Controller che implementi i relativi metodi.

File: pdevent.phpCartella: [...]/administrator/components/com_pastdays/controllers/<?php// Impedisce l'accesso diretto al filedefined('_JEXEC') or die();

class PastDaysControllerPDEvent extends PastDaysController {

Nella parte frontend esiste solo il Controller base, quindi questa è la prima classe di un Controller derivato che incontriamo.

function __construct() { parent::__construct();

// task add processato da metodo edit() $this->registerTask('add', 'edit'); }

Le operazioni di inserimento è modifica sono simili tra loro per cui è comodo che siano processate da un unico metodo. registerTask() serve a questo scopo: assegna il task passato come primo argomento (add) al metodo il cui nome è passato come secondo argomento (edit). Poiché, per impostazione predefinita, allo stesso metodo edit() è assegnato il task edit, i due task saranno processati dallo stesso metodo del controller.

function edit() { JRequest::setVar('view', 'pdevent'); JRequest::setVar('layout', 'default');

Si passa nella richiesta il nome della view da mostrare. Senza queste istruzioni il Controller mostrerebbe la View predefinita PastDays.

JRequest::setVar('hidemainmenu', 1);

Si disabilita il menu principale durante le operazioni di inserimento e modifica

parent::display(); }

©2008 Sviluppare in Rete

Page 25: Sviluppo componenti Joomla

25 Backend del componente

Si invoca il metodo display() della classe base PastDaysController che crea la View PDEvent e ne invoca il metodo display().

//Cancellazione di un evento function remove() { $model = $this->getModel('pdevent'); if($model->delete()) { $msg = JText::_('Event(s) Deleted'); } else { $msg = JText::_('Error Deleting One or More Events') . ': ' . $model->getError(); }

Questo metodo processa il task remove associato al pulsante Cancella. Non c'è molto da dire: viene invocato il metodo delete() dell'oggetto Model PDEvent (che vedremo) e, a seconda del risultato, viene predisposto un messaggio di conferma o di errore.

//Redirect per rivisualizzare l'elenco degli eventi $this->setRedirect('index.php?option=com_pastdays', $msg); } // Fine remove

Si imposta un reindirizzamento di pagina per ricaricare la pagina con l'elenco dei record dove sarà visualizzato il messaggio impostato precedentemente.

function save() { $model = $this->getModel('pdevent');

if($model->store()) { $msg = JText::_('Event Saved'); } else { $msg = JText::_('Error Saving Event') . ': ' . $model->getError(); }

Anche in questo caso ci si limita a visualizzare l'esito di un'operazione demandata all'oggetto Model

$link = 'index.php?option=com_pastdays'; $this->setRedirect($link, $msg); } // Fine save

Di nuovo un reindirizzamento con impostazione di un messaggio per l'utente.

function cancel() { $msg = JText::_('Operation Cancelled'); $this->setRedirect( 'index.php?option=com_pastdays', $msg ); }}?>

fine pdevent.php

Si ricarica la pagina dell'elenco senza fare altro che visualizzare un messaggio di avviso.

©2008 Sviluppare in Rete

Page 26: Sviluppo componenti Joomla

Backend del componente 26

Questi ultimi due metodi processano i task associati ai pulsanti Salva e Chiudi che si trovano nella barra degli strumenti della pagina che visualizza il modulo per inserire o modificare un evento. Questa pagina è generata dalla View PDEvent (o meglio dal template ad essa associato) che vedremo subito.

View PDEvent

File: view.html.phpCartella: [...]/administrator/components/com_pastdays/views/pdevent/<?php// Impedisce l'accesso diretto al filedefined('_JEXEC') or die( 'Restricted access' );require JPATH_COMPONENT_ADMINISTRATOR . DS . 'helpers' . DS . 'pastdays.php';// Include la classe base JViewjimport('joomla.application.component.view');

class PastDaysViewPDEvent extends Jview { function display($tpl = null) { //Legge i dati dell'evento (da Model) $event =& $this->get('Data'); //Se ID record è zero si tratta di inserimento $isnew = ($event->id < 1); $this->assignRef('isnew', $isnew);

I dati dell'evento da modificare (ID, data e descrizione) sono richiesti all'oggetto Model PDEvent. Se il valore del campo ID è minore o uguale a zero non c'è alcun evento da modificare e quindi si tratta di una operazione di inserimento nuovo evento.

// Crea codice HTML per liste selezione giorni e mesi $months = PastDaysHelper::months(); $mlist = JHTML::_('select.genericlist',$months,'month',null,'value','text',$event->month,false,true); $this->assignRef('mlist', $mlist); $days = PastDaysHelper::days(); $dlist = JHTML::_('select.genericlist',$days,'day',null,'value','text',$event->day,false,true); $this->assignRef('dlist', $dlist); $this->assignRef('event', $event); parent::display($tpl); }}?>

fine view.html.php

Riferimenti alle liste per la selezione di giorno e mese e all'oggetto evento vengono passati al template.

©2008 Sviluppare in Rete

Page 27: Sviluppo componenti Joomla

27 Backend del componente

TemplateFile: default.phpCartella: [...]/administrator/components/com_pastdays/views/pdevent/tmpl/<?php// Impedisce l'accesso diretto al filedefined('_JEXEC') or die( 'Restricted access' );

$text = $this->isnew ? JText::_('New') : JText::_('Edit');JToolBarHelper::title(JText::_('PastDays').': <small>[ ' . $text.' ]</small>');JToolBarHelper::save();if ($this->isnew) { // Nuovo record: etichetta predefinita per il pulsante JToolBarHelper::cancel();} else { // Modifica record: etichetta pulsante rinominata Chiudi JToolBarHelper::cancel('cancel', 'Close');}?>

Si creano i pulsanti Salva e Chiudi. Intestazione pagina ed etichette dei pulsanti sono modificate in base al tipo di operazione (inserimento o modifica).

<script language="javascript" type="text/javascript"> function submitbutton(pressbutton) { var form = document.adminForm; if (pressbutton == 'cancel') { submitform( pressbutton ); return; }

// Validazione campi if (form.description.value == ""){ alert("<?php echo JText::_('You must enter a description', true); ?>"); } else if (form.day.value == ""){ alert("<?php echo JText::_('You must enter a day', true); ?>"); } else if (form.month.value == ""){ alert("<?php echo JText::_('You must enter a month', true); ?>"); } else { submitform( pressbutton ); } }</script>

Javascript per la validazione dei dati immessi nel form.

<form action="index.php" method="post" name="adminForm" id="adminForm"><div class="col100"> <fieldset class="adminform"> <legend><?php echo JText::_('Details'); ?></legend> <table class="admintable"> <tr> <td width="100" align="right" class="key"> <label for="day"> <?php echo JText::_('Event Date'); ?>: </label> </td>

©2008 Sviluppare in Rete

Page 28: Sviluppo componenti Joomla

Backend del componente 28

<td> <?php echo $this->dlist;?> &nbsp;<?php echo $this->mlist;?> &nbsp;<input class="text_area" type="text" name="year" id="year" size="4" maxlength="4" value="<?php echo $this->event->year;?>" /> </td> </tr> <tr> <td width="100" align="right" class="key"> <label for="description"> <?php echo JText::_('Event Description'); ?>: </label> </td> <td> <textarea class="text_area" name="description" id="description" cols="40" rows="10">

<?php echo $this->event->description;?></textarea> </td> </tr> </table> </fieldset></div><div class="clr"></div>

Codice html che genera il form per l'inserimento e la modifica di un evento. Da notare che si accede ai valori dei campi con

$this->event->nome_campo<input type="hidden" name="option" value="com_pastdays" /><input type="hidden" name="id" value="<?php echo $this->event->id; ?>" />

$this->event->id

contiene il valore del campo ID dell'evento da modificare oppure zero in caso di inserimento di nuovo evento.

<input type="hidden" name="task" value="" /><input type="hidden" name="controller" value="pdevent" /></form>

fine default.php

I task generati dai pulsanti Salva e Chiudi saranno gestiti dai metodi save() e cancel() che abbiamo già esaminato nel controller PDEvent .

Table PDEvent

L'oggetto Table è utilizzato da Model per le operazioni di inserimento e modifica dati. La struttura della classe è molto semplice: una proprietà con lo stesso nome utilizzato per ogni campo della tabella dal nostro componente. Può inoltre contenere un metodo per la validazione dei dati inseriti.

File: pdevent.phpCartella: [...]/administrator/components/com_pastdays/tables/

©2008 Sviluppare in Rete

Page 29: Sviluppo componenti Joomla

29 Backend del componente

<?php// Impedisce l'accesso diretto al filedefined('_JEXEC') or die( 'Restricted access' );

class TablePDEvent extends JTable { var $id = null; var $year = null; var $month = null; var $day = null; var $description = null; function TablePDEvent(& $db) { parent::__construct('#__pastdays', 'id', $db); }

Passiamo al costruttore della classe base JTable il nome della tabella nel database e il nome del campo chiave (id).

function check() { $v = (int)$this->day; if($v <= 0 || $v > 31) { $this->setError (JText::_('You must enter a day')); return false; } $v = (int)$this->month; if($v <= 0 || $v > 12) { $this->setError (JText::_('You must enter a month')); return false; } if(trim($this->description) == '') { $this->setError (JText::_('You must enter a description')); return false; } return true; }}?>

fine pdevent.php

Il metodo check() per la validazione dei dati sarà utilizzato dall'oggetto Model come vedremo.

Model PDEvent

File: pdevent.phpCartella: [...]/administrator/components/com_pastdays/models/<?php// Impedisce l'accesso diretto al filedefined('_JEXEC') or die();

// Include la classe base JModeljimport('joomla.application.component.model');

©2008 Sviluppare in Rete

Page 30: Sviluppo componenti Joomla

Backend del componente 30

class PastDaysModelPDEvent extends JModel { function __construct() { parent::__construct();

$array = JRequest::getVar('cid', 0, '', 'array'); $this->setId((int)$array[0]); }

function setId($id) { $this->_id = $id; $this->_data = null; }

Quando viene creata un'istanza dell'oggetto Model il costruttore memorizza il valore del campo ID dell' evento da modificare nella proprietà _id dell'oggetto.

getVar() la conosciamo già, ma fino ad ora l'abbiamo trovata con un solo argomento. In questo caso vengono passati oltre l'identificatore della variabile (cid), un valore di default (0) da ritornare nel caso in cui $_REQUEST['cid'] non sia impostata il che accade quando l'operazione sia di inserimento e non di modifica, un terzo argomento vuoto ad indicare che si sta leggendo il valore da $_REQUEST, un quarto argomento (array) che indica che $_REQUEST['cid'] non contiene un valore singolo, ma un array. $array, quindi, conterrà i valori del campo ID di tutti i record selezionati nell'elenco.

Il tutto può essere più chiaro se si controlla il codice html generato per una casella di selezione nell'elenco degli eventi

<input type="checkbox" id="cb0" name="cid[]" value="X" onclick="isChecked(this.checked);" />

Al posto di X troverete il valore del campo ID del record su quella riga.

function &getData() { // Carica i dati se non esistono già if(empty($this->_data)) { $sql = 'SELECT * FROM #__pastdays ORDER BY year, month, day'. ' WHERE id = '. $this->_id; $this->_db->setQuery($sql); $this->_data = $this->_db->loadObject(); } if(!$this->_data) { $this->_data = new stdClass(); $this->_data->id = 0; $this->_data->year = null; $this->_data->month = null; $this->_data->day = null; $this->_data->description = null; } return $this->_data; }

Estrae dal database il record relativo ad un evento e lo ritorna come oggetto: il

©2008 Sviluppare in Rete

Page 31: Sviluppo componenti Joomla

31 Backend del componente

contenuto di ogni campo del record è assegnato ad una proprietà dell'oggetto.

L'oggetto è anche memorizzato internamente a Model (proprietà _data) così che, in caso di successive chiamate a getData() all'interno della stessa richiesta pagina, si evita di rifare la query più di una volta.

function store() { // Ottiene un riferimento all'oggetto Table PDEvent $row =& $this->getTable(); // Legge i dati da $_POST $data = JRequest::get('post');

// Associa i campi ricevuti da $_POST con Table if(!$row->bind($data)) { $this->setError($row->getError()); return false; }

Non c'è molto da dire. $row contiene un riferimento ad un'istanza di TablePDEvent, il metodo bind() (definito in JTable) inizializza le proprietà di $row con i valori letti da $_POST (mediante la ormai nota funzione getVar()), di modo che se abbiamo $_POST['description'] = descrizione' avremo$row->description = 'descrizione' e così per tutti gli altri campi.

// Validazione record if(!$row->check()) { $this->setError($row->getError()); return false; } // Salvataggio record if(!$row->store()) { $this->setError($row->getError()); return false; } return true; }

Controllo di validazione sui dati mediante il metodo che abbiamo già visto in TablePDEvent e salvataggio del record.

function delete() { // Array valori ID record selezionati $cids = JRequest::getVar('cid', array(0), 'post', 'array');

Ancora recupero di un array con i valori del campo ID di tutti i record selezionati.

// Ottiene un riferimento all'oggetto Table PDEvent $row =& $this->getTable();

if(count($cids)) { foreach($cids as $cid) { // Cancellazione record

©2008 Sviluppare in Rete

Page 32: Sviluppo componenti Joomla

Backend del componente 32

if(!$row->delete($cid)) { $this->setError($row->getError()); return false; } } } return true; } // Fine delete}?>

fine pdevent.php

Solo che, mentre in un'operazione di modifica anche in caso di selezione di record multipli si modifica solo il primo record, la cancellazione può operare su più record. Quindi si compie un ciclo e si cancellano i record uno per uno.

Da notare che delete(), come anche store() poco sopra, non sono stati implementati nella nostra classe TablePDEvent. Vengono quindi ereditati i metodi definiti in JTable.

Classe Helper

Contiene alcune funzioni di utilità per la conversione di date che sono utilizzate sia dal frontend che dal backend del componente.

File: pastdays.phpCartella: [...]/administrator/components/com_pastdays/helpers/<?phpdefined('_JEXEC') or die('Restricted access');

class PastDaysHelper { function monthName($m) { $months = array( '', 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ); return JText::_($months[(int)$m]); } function months() { $m = array(); for($i = 1; $i <= 12; $i++) { $obj = new stdClass();

©2008 Sviluppare in Rete

Page 33: Sviluppo componenti Joomla

33 Backend del componente

$obj->text = PastDaysHelper::monthName($i); $obj->value = sprintf('%02d', $i); $m[] = $obj; } return $m; } function days() { $d = array(); for($i = 1; $i <= 31; $i++) { $obj = new stdClass(); $obj->text = $i; $obj->value = sprintf('%02d', $i); $d[] = $obj; } return $d; } }?>

fine pastdays.php

Conclusioni

Siamo arrivati alla fine. Non tutto può essere chiaro, soprattutto per chi non ha letto nient'altro sull'argomento anche perché la struttura di un componente nativo per Joomla 1.5 è molto più complessa rispetto a quella cui eravamo abituati con le precedenti versioni. I vantaggi ci sono, è forse difficile rendersene conto semplicemente dalla lettura di una guida, ma risultano chiari con la pratica, specie se si sviluppano componenti di una certa complessità.

Quindi se posso dare un suggerimento, a questo punto la cosa migliore da fare è studiarsi attentamente il codice di esempio e magari provare a modificarlo aggiungendo qualche funzione al componente.

Se avete dubbi o domande mi potete contattare tramite il blog o sulla sezione italiana del forum forum.joomla.org

©2008 Sviluppare in Rete