2/7/2013 - Welcome to Bugianens'...

109
2/7/2013 1 LE NOVITÀ DI JOOMLA!™ 2.5 Sistema ACL (Access Control List, dalla 1.6) Livelli di categorie definite dall’utente JForm e JTableNested e JDatabaseQuery PHP ≥ 5.2 e MySQL ≥ 5.0.4, più altri DB Formato .ini per i file di linguaggio One-click update Miglioramenti alla struttura MVC Miglioramenti al sistema di ricerca

Transcript of 2/7/2013 - Welcome to Bugianens'...

Page 1: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

1

LE NOVITÀ DI JOOMLA!™ 2.5

Sistema ACL (Access Control List, dalla 1.6)

Livelli di categorie definite dall’utente

JForm e JTableNested e JDatabaseQuery

PHP ≥ 5.2 e MySQL ≥ 5.0.4, più altri DB

Formato .ini per i file di linguaggio

One-click update

Miglioramenti alla struttura MVC

Miglioramenti al sistema di ricerca

Page 2: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

2

RIFERIMENTI

http://developer.joomla.org

http://docs.joomla.org/Developers

Page 3: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

3

L’ECOSISTEMA JOOMLA!™

Browser richiede URL

•XHTML generato

•Fogli di stile CSS

•AJAX per i contenuti dinamici

Web server gestisce richiesta

•Tipicamente Apache o Microsoft IIS

•Linguaggio di programmazione PHP

Contenuti dinamici su database

•MySQL come base di dati relazionale

COME ESTENDERE JOOMLA!™

•Hook per intercettare flusso standard

•"Side" content

•Contenuto centrale della pagina

•Modifica visualizzazione contenuti

•Evitare modifiche dirette al codice

•Bassa manutenibilità

Code hack Layout

overrides

Plugin e moduli

Components

Page 4: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

4

Nuovo articolo

Validazione standard

Plugin: metodo

onBeforeSave

Salvataggio su database

Plugin: metodo

onAfterSave Fine

Permettono di intercettare il flusso standard del codice

Sistema ad eventi e trigger

Esempio

• Esaminare ogni nuovo articolo ed assegnare appropriati metadati (keyword)

ESTENDERE JOOMLA!™ CON I PLUGIN INTERNAZIONALIZZAZIONE

Testi dell'interfaccia disaccoppiati dal codice e inseriti in file speciali .ini

• Approccio consigliato per sviluppatori di terze parti

Esempio

• in administrator/templates/bluestork/login.php ed altri: echo JText::_( 'COM_LOGIN_JOOMLA_ADMINISTRATOR_LOGIN' );

• la traduzione si trova in administrator/language/en-GB/en-GB.com_login.ini

Page 5: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

5

ESTENDERE JOOMLA!™ CON I TEMPLATE

La generazione dei contenuti è separata dalla loro presentazione

Non ci occuperemo dello sviluppo dei template ma solo della struttura dei folder per gli override e per il posizionamento dei moduli

Page 6: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

6

REQUISITI DI JOOMLA!™

Web Server

• DocumentRoot di Apache (httpd.conf)

• XAMPP per Windows e Mac OS X

Istruzioni aggiornate

• Aggiornati per ogni nuova versione

Permessi

• Sviluppo ≠ Produzione

• Impostare al minimo set di permessi richiesto

SCEGLIERE GLI STRUMENTI DI SVILUPPO

IDE

•Rileva errori di sintassi

•Autocompletamento del codice

•Visualizzazione di metodi e campi

•Comparazione di versioni

•Ricerca e sostituzioni semplificate

•Debugger

•Revision control system

Editor

•Semplicità d'uso

Page 7: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

7

ECLIPSE

Installare PDT e verificarne le caratteristiche

• Syntax highlighting (e perspective con manuale)

• Autocompletamento del codice

• Autocompletamento dei metodi

• Esempio $this-> Ctrl+Space

• Outline

• Ricerca delle classi correlate

ALTRI EDITOR

IDE (a pagamento)

• NetBeans

• ZendStudio http://www.zend.com

• Aptana Studio http://www.aptana.com

• Komodo IDE

Editor di testo

• Notepad++

• Vi, Sed e Awk direttamente su un server Linux

Page 8: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

8

PANORAMICA DELLA STRUTTURA

Frontend vs Backend

•Applicazioni separate che condividono librerie

•La cartella /administrator

Il file index.html

•<!DOCTYPE html><title></title>

•Per nascondere l’elenco dei file nella directory

Page 9: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

9

PANORAMICA DEL FRONTEND

•File temporanei per il riutilizzo (consigliato in produzione) Cache

•Applicazioni a linea di comando (Unità 13) CLI

•Generano il contenuto principale della pagina (iniziano con com_) Components

•Contiene gli asset pubblici, divisi in sottocartelle Images

•Librerie specifiche per la sessione di frontend Includes

•Miniapplicazione separata per l’installazione dell’applicazione Installation

•File specifici ed override di lingua Language

•Librerie esterne (phpmailer, phputf8, simplepie) ed interne (core di Joomla) Libraries

•Eventi registrati se abilitato Logs

•CSS, JavaScript e immagini per alcuni componenti, moduli ed editor Media

•Generano i contenuti laterali (iniziano con mod_) Modules

•Mini attività e modificatori di contenuto Plugins

•Template grafici Templates

•File temporanei Tmp

PANORAMICA DEL BACKEND (/ADMINISTRATOR)

•Contenuti dinamici temporanei Cache

•Componenti amministrativi (iniziano con com_) Components

•helpsites.xml per i collegamenti remoti o locali Help

•Librerie per la gestione delle sessioni amministrative Includes

•Traduzioni dell’area amministrativa Language

•Lista dei file e URL per gli aggiornamenti Manifests

•Contenuti laterali per l’area amministrativa Modules

•Bluestork (default) e Hator (alta accessibilità) Templates

Page 10: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

10

FILE TOP-LEVEL

•Contiene le impostazioni essenziali del sito (database e path) configuration.php

•Abilita mod_rewrite (.htaccess): rimuove index.php e aggiunge controlli htaccess.txt

•Punto di attacco per tutti i contenuti del sito index.php

•Copia di administrator/manifests/files/joomla.xml joomla.xml

•Licenza Joomla (GPLv2) LICENSE.txt

•Informazioni generali su Joomla README.txt

•Istruisce bot ed webcrawler ad ignorare le sottocartelle robots.txt

•Analogo di .htaccess per Microsoft IIS web.config.txt

LA JOOMLA!™ PLATFORM

Struttura di base per il CMS Joomla

File libraries/loader.php

• Classe JLoader

• Funzione jexit(): wrapper per la funzione exit()

• Funzione jimport(): scorciatoia per JLoader::import() per il caricamento dei file in stile Java o C#

Librerie esterne

• phpmailer: per l’invio di email via PHP

• phputf8: gestione avanzata delle stringhe UTF-8

• simplepie: gestione di file XML, come i feed RSS e Atom

Page 11: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

11

PANORAMICA DELLA JOOMLA!™ PLATFORM (/LIBRARIES/JOOMLA)

Libreria Descrizione

factory.php classe statica JFactory per il caricamento degli

oggetti

methods.php alcune helper classes per l’interazione con URL e testo

access funzionalità per il controllo degli accessi (ACL)

application funzionalità per le estensioni e per la main application

base classi astratte di basso livello per design pattern e strutture dati

PANORAMICA DELLA JOOMLA!™ PLATFORM (/LIBRARIES/JOOMLA)

Libreria Descrizione

cache gestione dei diversi meccanismi di caching

client connessione a server come FTP o LDAP

database connessione diretta alle basi di dati

document costruzione e la modifica delle

risposte al browser

environment interazione con request (GET, POST, COOKIE) e response

Page 12: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

12

PANORAMICA DELLA JOOMLA!™ PLATFORM (/LIBRARIES/JOOMLA)

Libreria Descrizione

error gestione degli errori

event gestione degli eventi (listen e azioni)

filesystem interazione con il filesystem

filter validazione e filtering dei valori di input e di output

form costruzione, modifica e processamento dei form web

PANORAMICA DELLA JOOMLA!™ PLATFORM (/LIBRARIES/JOOMLA)

Libreria Descrizione

github interazione con il version control system repository

html helper methods per generare HTML, caricare CSS e JavaScript

http interazione con differenti tipi di richieste HTTP

image operazioni sulle immagini

installer installazione ed aggiornamento delle estensioni

language traduzione delle stringhe

Page 13: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

13

PANORAMICA DELLA JOOMLA!™ PLATFORM (/LIBRARIES/JOOMLA)

Libreria Descrizione

log implementazione delle funzionalità di log

mail metodi per l’invio di messaggi di posta elettronica

plugin metodi correlati al sistema di plugin

registry interazione con object data (ad

es INI, JSON, XML)

session creazione, modifica e conservazione delle sessioni

PANORAMICA DELLA JOOMLA!™ PLATFORM (/LIBRARIES/JOOMLA)

Libreria Descrizione

string operazioni sulle stringhe

updater supporto all’auto-aggiornamento delle estensioni

user manipolazione ed interazione con gli oggetti utente

utilities classi e metodi non riconducibili ad altri gruppi

Page 14: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

14

PROGRAMMAZIONE WEB VS PROGRAMMAZIONE "CLASSICA"

Gestione dello stato del programma

•Protocollo HTTP stateless

•Gestione delle variabili di sessione

•Contenuti su database

Validazione dei comandi

•Esposizione degli accessi

•Validazione delle richieste (URL + contenuto dei form)

ANATOMIA DI UN CICLO DI ESECUZIONE JOOMLA!™

Caricamento di index.php

Controllo dell'execution environment

Definizione delle posizioni dei file

Caricamento del framework

Avviamento o continuazione della sessione

Routing dell'URL

Esecuzione del componente

Renderizzazione della pagina

Output della pagina

Page 15: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

15

ESECUZIONE (A)

index.php

• Punto di aggancio predefinito

• Riscrittura degli URL se mod_rewrite abilitato

Controllo dell'execution environment

• define('_JEXEC', 1);

Definizione delle costanti

• includes/defines.php

• Override possibile in /defines.php

ESECUZIONE (B)

Caricamento di includes/framework.php

• Carica la JFactory e il JLoader

• Verifica l'esistenza di configuration.php

Avvia o continua la sessione

• $app = JFactory::getApplication('site');

• JSite estende JApplication e recupera la sessione

• $app->initialise();

• Definisce la lingua e l'editor per l'utente

Page 16: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

16

Routing dell'URL

($app->route();) • Classe che traduce tra

URL e array di comandi

• parse(): da JURI ad

array; build(): inversa

JSite route()

•public function route() {

•parent::route();

•$Itemid = JRequest::getInt('Itemid');

•$this->authorise($Itemid);

• }

JApplication route()

•public function route() {

•$uri = clone JURI::getInstance();

•$router = $this->getRouter();

•$result = $router->parse($uri);

•JRequest::set($result, 'get', false);

•JPluginHelper::importPlugin('system');

•$this->triggerEvent('onAfterRoute');

• }

ESECUZIONE (C) ESECUZIONE (D) – COMPONENTE $APP->DISPATCH() DI JSITE IN INDEX.PHP

Ottiene il componente dalla JRequest

Crea un $document = JFactory::getDocument()

• Contenuti da inviare al browser

• Non è costruito sequenzialmente

• Supporta diversi tipi: html, feed

Carica il componente

• $contents = JComponentHelper::renderComponent($component);

Carica questa parte nel documento

• $document->setBuffer($contents, 'component');

Page 17: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

17

ESECUZIONE (E) – METODO RENDERCOMPONENT()

libraries/joomla/application/component/helper.php

Carica il template e la lingua

Salva il nome in $app->scope (utile per i plugin)

Valida il nome, verifica i path, verifica se abilitato

Esegue il componente!

$contents = self::executeComponent($path);

Metodo statico della classe

•Verifica se generare una toolbar

•return $contents;

protected static function executeComponent($path)

• ob_start();

• require_once $path;

• $contents = ob_get_contents();

• ob_end_clean();

• return $contents();

Attiva l'output buffering

Carica il componente • Tutto è delegato al

componente

• Può seguire qualunque

workflow (non solo MVC)

Salva l'output e pulisce

il buffer

ESECUZIONE (F) – EXECUTECOMPONENT()

Page 18: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

18

ESECUZIONE (G) – RENDERING $APP->RENDER()

Carica il documento (tipo JDocumentHTML, da libraries/joomla/document/html/html.php)

Carica i dati utente

$document->parse($params);

• Carica il template e ne fa il parsing

• return $this->_fetchTemplate($params)->_parseTemplate();

Rendering della response

• JResponse::setBody($document->render($caching, $params));

ESECUZIONE (H) – JDOCUMENTHTML _PARSETEMPLATE()

Prepara un array associativo in $this->_template_tags (oggetto $document)

Contiene

• type: tipo del tag, tra head, modules, messages, debug e component

• name: nome dell'elemento specificato in jdoc:include

• attribs: attributi specifici del tag

Page 19: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

19

ESECUZIONE (I) – RENDERING DEL TEMPLATE

$data = $this->_renderTemplate();

Cicla su tutti i tag

• Il componente è già disponibile in $contents

• I moduli vengono eseguiti ed aggiunti solo se assegnati ad una posizione esistente nel template

render() della parent class JDocument

• Imposta la data ed il content type

ESECUZIONE (J) – OUTPUT DELLA PAGINA

echo $app; chiama il metodo __toString() di JApplication (parenti di JSite)

• $compress = $this->getCfg('gzip', false);

• return JResponse::toString($compress);

• Inserisce il corpo della pagina in $data

• Controlla se comprimere la pagina

• Controlla il caching ed imposta l'header di conseguenza

• Invia l'header

• Invia $data contenente l'intera pagina

Page 20: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

20

Carica index.php

Definisce posizione file

Carica Joomla Framework

Crea o carica sessione

Route URL

Esegue componente

Renderizza pagina

Invia pagina al browser

Durante tutto il processo vengono sollevati trigger per eventuali plugin

I metodi di alto livello sono relativamente pochi

Suddivisione in numerosi sotto task per compiti specifici

RIASSUNTO DEL WORKFLOW NAMING CONVENTIONS

Semplificano la comprensione del sistema

• com_miocomponente/miocomponente.php

Oggetti globali

• Oggetti disponibili in qualunque punto dell'esecuzione

• Design pattern "singleton" e "factory"

• JFactory::getApplication restituisce la JApplication esistente o la crea alla prima esecuzione

Page 21: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

21

GLI OGGETTI GLOBALI DI JOOMLA!™

Oggetto Descrizione Codice

JApplication, JSite e JApplication

Oggetto applicazione e sue declinazioni

$app = JFactory::getApplication();

JRegistry Valori di configuration.php

$config = JFactory::getConfig();

JSession Sessione corrente $session = JFactory::getSession();

JLanguage Contenuti linguistici $language = JFactory::getLanguage();

GLI OGGETTI GLOBALI DI JOOMLA!™

Oggetto Descrizione Codice

JDocument, JDocumentHTML, JDocumentFEED,

JDocumentJSON

Documento corrente

$document = JFactory::getDocument();

JUser Utente corrente $user =

JFactory::getUser();

JAccess Accessi correnti (per il controllo dei permessi)

$access = JFactory::getACL();

JDatabase Per l'esecuzione delle query

$dbo = JFactory::getDbo();

Page 22: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

22

GLI OGGETTI GLOBALI DI JOOMLA!™

Oggetto Descrizione Codice

JMail Per l'invio delle mail

$mail = JFactory::getMailer();

JXMLElement Elemento XML $xml = JFactory::getXML($pathToXml);

JEditor Editor $editor = JFactory::getEditor();

JURI URI $uri = JFactory::getUri();

JDate Date/time (non singleton)

$date = JFactory::getDate();

Page 23: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

23

CONCETTI BASE SUI TEMPLATE

Disaccoppiamento della business logic dalla presentation

Consente modifiche sostanziali al rendering degli elementi via override

css

•Fogli di stile (CSS)

fonts

•Set di caratteri particolari

html

•modules.php: "module chrome", ovvero wrapper per il markup HTML dei moduli

•com_contact e com_content per gli override

images

•Assett grafici

javascript

•Effetti specifici del template

language

•Traduzioni delle stringhe stampate

component.php

•Template per la stampa o l'invio email

error.php

•Template per le pagine di errore (URL invalidi)

favicon.ico

•Icona nella barra degli URL

index.php

•Template principale

•Posiziona i moduli, i componenti ed i messaggi

template_preview.png e _thumbnail.png

•Anteprime del template

templateDetails.xml

•Metadati del template: file, folder e parametri

FOLDER E FILE DEI TEMPLATE (BEEZ_20)

Page 24: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

24

INDEX.PHP DI UN TEMPLATE (ATOMIC)

Istanza $app = JFactory::getApplication()

Tipo di documento <!DOCTYPE html...

HTML tag head meta e title personalizzabili <jdoc:include type="head" />

Contenuto centrale

• <jdoc:include type="component" />

Contenuti laterali

• <jdoc:include type="modules" name="atomic-search"

style="none" />

• name: posizionamento dei moduli

• style: "Module Chrome" (decorazione dei moduli)

PARAMETRI DI TEMPLATE

Extensions > Template Manager > Beez2

Definiti in templates/beez_20/templateDetails.xml

• Ogni <fieldset> è uno "slider"

• Ogni <field> è un parametro definito da attributi

Page 25: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

25

ATTRIBUTI DI UN ELEMENTO <FIELD>

Attributo Descrizione

name Nome per identificare il parametro ed il suo valore

class Classe CSS per la visualizzazione; ad es. la class validate-numeric attiva codice JavaScript per "validare" l'input numerico

type Tipo di dato. Per convenzione se type=text la classe è JFormFieldText dal file libraries/joomla/form/fields/text.php Per il tipo list si aggiungono elementi <option> per descrivere le

opzioni possibili

default Valore predefinito visualizzato nel form

label Etichetta, normalmente traducibile da language/en-GB/en-GB.tpl_beez_20.ini (nell'esempio)

description Descrizione del campo, tradotta come sopra

filter Filtro da applicare, chiama il metodo clean() di JFilterInput da libraries/joomla/filter/filterinput.php con il tipo specificato

SALVATAGGIO PARAMETRI

I fields di tipo "params" (parametri) sono salvati in forma JSON

• Funzioni PHP json_encode e json_decode

I parametri di template sono nella tabella #__templates_styles nella colonna params

Page 26: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

26

DECORATORI DI MODULO (MODULE CHROME)

Definito da <jdoc:include type="modules" ... style="container" />

Cerca funzione modChrome_container in

• Standard templates/system/html/modules.php

• Custom templates/atomic/html/modules.php

FUNZIONE DECORATOR

function modChrome_container ( $module, &$params, &$attribs )

• $module contiene il modulo; $module->content l'HTML da visualizzare

• $params è un JRegistry con i parametri

• $attribs è un array dei valori di jdoc:include

Page 27: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

27

COPIARE UN TEMPLATE

Per lavorare su una versione custom

Copiare la cartella in una nuova

Modificare templateDetails.xml

Rinominare i file di linguaggio

Discover e install

• Extension Manager > Discover

• Funzionalità per installare estensioni copiate localmente

Effettuare le personalizzazioni

TEMPLATE LAYOUT OVERRIDE (MODULO LATEST ARTICLES)

Content > Article Manager > Latest News

Contiene la macro {loadmodule articles_latest,Latest News}

Extensions > Module Manager > Latest News

Trovare il layout originale

• modules/mod_articles_latest/tmpl/default.php

Creare l'override

• templates/<nome>/html/mod_articles_latest/

Page 28: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

28

LAYOUT OVERRIDE I

<h1>Il mio primo override</h1>

<ul class="latestnews<?php echo $moduleclass_sfx; ?>">

<?php foreach ($list as $item) : ?>

• <li><a href="<?php echo $item->link; ?>">

• <?php echo $item->title; ?></a></li>

• <?php var_dump($item); ?>

• <?php echo substr($item->introtext, 0, 50) . '...'; ?>

<?php endforeach; ?>

</ul>

LAYOUT OVERRIDE I: DESCRIZIONE

Inserimento di HTML statico

Controllo delle disponibilità dell'oggetto $item con var_dump

Inserimento dei primi 50 caratteri del testo introduttivo

• Contiene l'articolo fino al primo "Read More" (se esistente)

Page 29: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

29

LAYOUT OVERRIDE II

<ul class="latestnews<?php echo $moduleclass_sfx; ?>">

<?php foreach ($list as $item) : ?>

• <li><a href="<?php echo $item->link; ?>">

• <?php echo $item->title; ?></a></li>

• <p>

• <?php echo substr(strip_tags($item->introtext), 0, 50) . '...'; ?>

• </p>

<?php endforeach; ?>

</ul>

LAYOUT OVERRIDE II: DESCRIZIONE

Elimina i tag HTML presenti nell'articolo

• <img> o <div> causano eventuali problemi di visualizzazione

Funzione-in-funzione substr(strip_tags(...))

Aggiunta tag <p> per racchiudere la stringa

Page 30: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

30

LAYOUT OVERRIDE III

<?php JLoader::register('JHtmlString', JPATH_LIBRARIES . '/joomla/html/html/string.php'); ?>

<ul class="latestnews<?php echo $moduleclass_sfx; ?>">

<?php foreach ($list as $item) : ?>

• <li><a href="<?php echo $item->link; ?>">

• <?php echo $item->title; ?></a></li>

• <p>

• <?php echo JHtmlString::truncate(strip_tags($item->introtext), 53); ?>

• </p>

<?php endforeach; ?>

</ul>

Step operativi 1. Includere la libreria

con JLoader::register • Nome della classe

• Posizione del file

2. Usare la funzione JHtmlString::truncate() • Stringa da tagliare

• Numero di caratteri, comprensivo di '...'

Obiettivo: troncare il testo alla fine di parola

Uso delle funzioni di Joomla

• http://developer.joomla.org/code.html > API

• http://api.joomla.org HTML > Classes > JHtmlString

LAYOUT OVERRIDE III: DESCRIZIONE

Page 31: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

31

LAYOUT OVERRIDE IV

<ul class="latestnews<?php echo $moduleclass_sfx; ?>">

<?php foreach ($list as $item) : ?>

• <li><a href="<?php echo $item->link; ?>">

• <?php echo $item->title; ?></a></li>

• <p>

• <?php echo JHtml::_('string.truncate', strip_tags($item->introtext), 53); ?>

• </p>

<?php endforeach; ?>

</ul>

LAYOUT OVERRIDE IV: DESCRIZIONE

Semplificazione del codice: JHtml::_()

• Argomento string.truncate

• Segmento classe, diventa JHtmlString

• Segmento funzione

• Altri arogmenti passati alla funzione risultante

• La classe è caricata automaticamente

Page 32: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

32

TEMPLATE LAYOUT OVERRIDE (COMPONENTE USER REGISTRATION)

Obiettivo: aggiungere un disclaimer alla procedura di registrazione utente

Originale in components/com_users/views/registration/tmpl

• default.php contiene il form di registrazione

• complete.php la pagina di registrazione completata

Copiare in templates/<nome>/html/com_users/registration

Verificare in Home > Create an Account

Limitazioni • Testo hardcoded • La spunta non è richiesta per

procedere • Il dato non viene salvato

<fieldset> • <legend>Termini di

servizio</legend> • <p><input type="checkbox" />

Consento al trattamento... </p>

</fieldset>

<button type="submit" class="validate"> <?php echo JText::_('JREGISTER'); ?> </button>

LAYOUT OVERRIDE IN AZIONE

Page 33: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

33

Copia "hard-

coded" al template

Layout flessibili

• Diversi da default.php

Rinominare default.php

in <mionome>.php

Selezionare il layout in Advanced Options

• In Module Manager

• Nei Settings globali

LAYOUT ALTERNATIVI CREAZIONE DI UN NUOVO DECORATOR

Creare una nuova funzione modChrome nel modules.php del template

Usare il nuovo stile in una dichiarazione <jdoc:include> per una

specifica posizione

Assegnare un modulo a quella posizione

Raffinare la configurazione con attributi dinamici

Page 34: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

34

1. CREARE LA FUNZIONE MODCHROME

Copiare la funzione modChrome_table da templates/system/html/modules.php in templates/<nome>/html/modules.php

Rinominare in modChrome_<nome>FramedTable

• Nome del template inserito come "namespacing" per evitare

collisioni

Aggiungere un border="5" al tag <table>

2. USARE LO STILE IN UN <JDOC:INCLUDE>

Modificare templates/<nome>/index.php

Aggiungere la posizione 7A sotto la 7

• <jdoc:include type="modules" name="position-7A" style="<nome>FramedTable" />

Page 35: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

35

3. ASSEGNARE UN MODULO ALLA NUOVA POSIZIONE

Module Manager

• Selezionare la posizione a mano

• Per averlo in lista dovremmo modificare templateDetails.xml

• Menu Assignment > On All Pages

4. RAFFINARE LA CONFIGURAZIONE CON GLI ATTRIBUTI

Modificare border="<?php echo $attribs['border'] ?>" nella modChrome

Aggiungere border="2" nel <jdoc:include>

Verificare errore (Notice) se border non specificato nel <jdoc:include>

• Global Configuration > Server > Error Reporting > Maximum

Modificare border="<?php echo (isset($attribs['border'])) ? (int) $attribs['border'] : '0'; ?>"

Page 36: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

36

COS'È UN PLUGIN

Un semplice programma PHP che viene eseguito in uno o più punti predefiniti del

ciclo di esecuzione di Joomla

•L'esecuzione di un plugin è scatenata da un evento

•Plugin semplici (salvare un dato in un database) o complessi (convertire tutti gli URL in un formato diverso)

Page 37: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

37

COME FUNZIONANO I PLUGIN

Inclusione nello script

•JPluginHelper::importPlugin()

•Nessun codice viene eseguito in questo momento

Trigger di un evento

•$dispatcher->trigger()

•Ogni evento ha un nome (ad es. onBeforeInitialize o onContentBeforeSave)

Esecuzione dei metodi

•La procedura cerca tra i plugin abilitati e caricati dei metodi che si riferiscono al nome dell'evento

NAMING CONVENTIONS

Folder plugins/<plugin type>/<plugin name>

•Codice in <plugin name>.php

•Metadati in <plugin name>.xml

Nome della classe

•"plg" + <plugin type> + <plugin file name>

Page 38: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

38

TIPOLOGIE DI PLUGIN

•onUserAuthenticate al tentativo di login di un utente Authentication

•onInit, onDisplay e onCheckAnswer per validare l'input dell'utente Captcha

•Eventi sollevati alla visualizzazione o modifica di contenuti Content

•Implementati come plugin, esulano dalla trattazione Editors

•Pulsanti per attività sull'editor, evento onDisplay Editors-XTD

•Eventi sollevati per installazione/modifica di Estensioni Extension

•onContentSearchAreas (aree di ricerca) e onContentSearch (esegue) Search

•Indicizzano i contenuti Smart Search (Finder)

•Eventi sollevati nel ciclo di esecuzione (onAfterInitialise) System

•Eventi sollevati alla modifica dei profili o al login/logout User

PANORAMICA DEI CORE PLUGIN – SYSTEM: SEF (SEARC-ENGINE-FRIENDLY URL)

JPluginHelper::importPlugin('system'); carica

$this->triggerEvent('onAfterRender'); esegue

• $dispatcher = JDispatcher::getInstance();

• return $dispatcher->trigger($event, $args); chiama il metodo $event per tutti i plugin di tipo system

Page 39: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

39

defined('_JEXEC') or die;

class plgSystemSef extends JPlugin {

• /** • * Converting the site URL to

fit to the HTTP request • */ • public function

onAfterRender() { • ...

Legge documento HTML

Controlla se è sul frontend e l'opzione globale è attiva

• if ($app->getName() != 'site' || $app->getCfg('sef') == '0'

Converte i collegamenti

Rende gli URL assoluti

PLUGIN SEF IN ESECUZIONE PANORAMICA DEI CORE PLUGIN – AUTHENTICATION: JOOMLA

Valida username e password in authenticate() di JAuthentication

• $plugins = JPluginHelper::getPlugin('authentication');

• foreach ($plugins as plugin) {

• $plugin->onUserAuthenticate($credentials, $options, $response);

• }

Page 40: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

40

AUTENTICAZIONE JOOMLA IN ESECUZIONE – PARTE 1

•$credentials contiene username e password

•&$response (by reference) contiene la risposta

function onUserAuthenticate($credentials,

$options, &$response)

• Indica il plugin usato per validare l'utente $response->type = 'Joomla';

•Non consente password vuote e restituisce un errore if (empty($credentials['password'])) ...

• Istanzia una query sul database $db = JFactory::getDbo();

$query = $db->getQuery(true);

•Seleziona i campi dalla tabella

•Usa il prefisso #__ sostituito con quello reale $query->select('id, password');

$query->from('#__users');

•Definisce la condizione

•Valida il campo inserito con $db->Quote $query->where('username=' . $db->Quote($credentials['username']));

AUTENTICAZIONE JOOMLA IN ESECUZIONE – PARTE 2

•Prepara la query ed esegue $db->setQuery($query);

$result = $db->loadObject();

•Se la query non restituisce un valore, utente non esistente

•$response->error_message = JText::_('JGLOBAL_AUTH_NO_USER); if ($result)

•Password composta da <hash>:<salt>

$parts = explode(':', $result->password);

$crypt = $parts[0];

$salt = @$parts[1];

•Esegue la funzione di hashing one-way (md5) sulla password inviata $credentials['password'] con il $salt

$testcrypt = JUserHelper::getCryptedPassword(...);

•Carica profilo utente JUser::getInstance($result->id); o password errata

•restituisce $response passata by reference

if ($crypt == $testcrypt)

Page 41: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

41

PANORAMICA DEI CORE PLUGIN – CONTENT: JOOMLA (PLGCONTENTJOOMLA)

onContentAfterSave

• invia mail di notifica

onContentBeforeDelete

• impedisce di eliminare categorie con item referenziati

• Chiamato dalla delete() di JModelAdmin $result = $dispatcher->trigger($this->event_before_delete, array($context, $table));

"INTEGRITÀ REFERENZIALE" DELLE CATEGORIE IN ESECUZIONE

•Opera solo sulle categorie if ($context !=

'com_categories.category')

•Abilitato nelle opzioni JRegistry

•Parametri definiti nel file XML correlato if(!$this->params-

>def('check_categories', 1)

•Ricava l'estensione

•Plugin lavora solo su estensioni core $extension =

JRequest::getString('extension');

•Conta elementi in tabella (=estensione) $count = $this-

>_countItemsInCategory($table, $data->get('id'));

• Impedisce l'eliminazione della categoria

•Esistono elementi correlati if ($count > 0)

• Impedisce l'eliminazione di una categoria padre (non foglia) if (!$data->isLeaf())

Page 42: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

42

"INTEGRITÀ REFERENZIALE" DELLE CATEGORIE - FAQ

Codice nel plugin = flessibilità

• Può essere disabilitato

• Disabilitabile selettivamente

• Può essere rimpiazzato o esteso

• Modello di sviluppo per altri

Codice hardcoded nelle categorie

• Nessuna operazione attiva

• Restituisce solo un booleano

CREARE UN PLUGIN: DEFINIZIONE E PRIMI CONTROLLI

onBeforeCompileHead

• Prima del rendering degli header HTML

In fetchHead() di JDocumentRendererHtml

• Obiettivo: aggiungere un elemento <meta>

• <meta name="revised" content="Joomlahost, 17/01/2013" />

• Verificare il contenuto di $document prima del trigger

Inserire var_dump($document->getHeadData());

Array associativo di meta tag

Page 43: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

43

CREARE UN PLUGIN: CODE FLOW

Leggere parametri

•meta tag custom

Leggere header esistenti

Modificare header

•Aggiungere elemento

Restituire header

modificati

•setHeaderData()

CREARE UN PLUGIN: STEP OPERATIVI

Creare folder plugins/system/mymeta

Copiare da plugins/system/p3p e rinominare

Modificare mymeta.xml

Codice in mymeta.php

Installare plugin: Extensions Manager » Discover » Install

Inserire valore parametro

Verificare funzionamento

Page 44: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

44

CREARE UN PLUGIN: MYMETA.XML

<fields name="params">

<fieldset name="basic">

<field name="revised" type="text" description="Contenuto del metatag revised" label="Revised content" default="" size="50" />

</fieldset>

</fields>

CREARE UN PLUGIN: MYMETA.PHP

<?php

defined('_JEXEC') or die;

jimport('joomla.plugin.plugin');

class plgSystemMeta extends JPlugin {

function onBeforeCompileHead() {

if ($this->params->get('revised')) {

$document = JFactory::getDocument();

$headData = $document->getHeadData();

$headData['metaTags']['standard']['revised'] = $this->params->get('revised');

$document->setHeadData($headData);

}

}

}

Page 45: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

45

CREARE UN PACKAGE DEL PLUGIN

.zip o .tar.gz dell'intera struttura (senza la trailing directory)

• cd <directory del plugin>

• zip –r plg-<plugin type>-<plugin name>.zip *

• tar cfvz plg-<plugin type>-<plugin name>.tar.gz *

PLUGIN BEST PRACTICES

Ordine di esecuzione in Plugin Manager

•Tipicamente l'ordine non è importante

Usare la naming convention

Eventi differenti hanno signature differenti

•Folder tests/plugins

•http://docs.joomla.org /Plugin/Events

Cercare l'evento migliore

•Non aggiungerne altri

Page 46: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

46

COS'È UN MODULO, AFFINITÀ E DIFFERENZE DA UN COMPOENTE

Piccolo, semplice e "leggero" frammento di

contenuto

• Informazioni e strumenti laterali al componente principale

•Spesso dipende da un componente (ad es gli articoli popolari)

•Spesso aiuta la navigazione dell'utente (menu e form di ricerca)

Non dipende dall'URL: integrato nel workflow built-

in

•Tutti i moduli che sono assegnati (a) al menu item (b) ad una posizione visualizzata nel template

Page 47: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

47

Visualizza gli ultimi n

utenti registrati

Parametri • Limitare utenti visualizzati

• Visualizzare link al profilo

• Visualizzare informazioni

di contatto

Nome del file Descrizione

tmp1/default.php Layout del

modulo (stampa

output su browser)

helper.php Metodi per la

raccolta dei dati

mod_users_latest.php Entry point di

esecuzione

mod_users_latest.xml Metadati per

installazione e

parametri

(formato XML)

PANORAMICA DI UN MODULO CORE – LATEST USERS

PANORAMICA "LATEST USERS" – METADATI

Tipo dell'estensione: modulo

Elenco dei file e delle cartelle

File per la localizzazione linguistica

Copiati nel folder core

•Descrizione dei parametri di configurazione in <fieldset>

3 "basic" e 5 "advanced"

Page 48: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

48

Carica la classe helper

•require_once dirname(__FILE__).'/helper.php';

Chiama metodi helper (per ottenere dati)

•$name = moduserslatestHelper::getUsers($params);

Include file di layout (renderizza i contenuti)

•require JModuleHelper::getLayoutPath('mod_users_latest', $params->get('layout', 'default'));

Dov'è definita la variabile $params?

•Modulo incluso da renderModule() di JModuleHelper

•$params = new JRegistry;

•$params->loadJSON($module->params);

•[...]

•$content = '';

•ob_start();

•require $path; //il codice è inserito ed eseguito as-is, ereditando lo scope

•$module->content = ob_get_contents().$content;

PANORAMICA "LATEST USERS" – CODICE PRINCIPALE (MOD_USERS_LATEST.PHP)

PANORAMICA "LATEST USERS" – RENDERING DEL CONTENUTO

•Classe custom per fine-tuning di CSS $moduleclass_sfx =

htmlspecialchars($params->get('moduleclass_sfx'));

•Eredita lo scope e le variabili (attenzione alle modifiche accidentali)

require JModuleHelper::getLayoutPath(

•Se layout di default modules/mod_users_latest/tmp1/default.php

'mod_users_latest',

•Layout alternativi per i moduli (selezionabili in Module Manager)

$params->get('layout', 'default')

•Il codice è incluso "as-is", ereditando lo scope dallo script chiamante

);

Page 49: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

49

PANORAMICA "LATEST USERS" – CLASSE DI APPOGGIO (HELPER)

•Metodo statico (di classe, non di oggetto) static function getUsers($params)

{

•Query costruita ad oggetti da JDatabaseQuery (platform agnostic)

$query->select('a.id, ...');

$query->order('a.registerDate DESC');

•Definizione tabella (prefix agnostic)

•Selezione per gruppi con $query->leftJoin(...) $query->from('#__users AS a');

•Carica query come stringa: __toString() di JDatabaseQuery

•Condizione LIMIT come shownumber

$db->setQuery($query, 0, $params->get('shownumber'));

•Esegue la query

•Restituisce array di oggetti

$result = $db->loadObjectList();

return (array) $result;

PANORAMICA "LATEST USERS" – LAYOUT PREDEFINITO (TMP1/DEFAULT.PHP)

•Sintassi alternativa PHP per il mixing con HTML <?php if (!empty($names)) : ?>

•Per aggiungere una classe occorre prependere uno spazio

<ul class="latestusers<?php echo $moduleclass_sfx ?>" >

•$names = moduserslatestHelper::getUsers($params); in mod_users_latest.php

<?php foreach ($names as $name) : ?>

•Visualizzazione utenti come lista <li>

<?php echo $name->username; ?> </li>

•Chiusura dei tag PHP e HTML <?php endforeach; ?>

</ul> <?php endif; ?>

Page 50: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

50

SVILUPPO DI UN NUOVO MODULO

Visualizza articoli per autore

•Lista di articoli scritti dallo stesso autore

•Parametri per

•Quanti articoli mostrare

• In che ordine

Lista file mod_<tag>_articles_author

• language/en-GB/

•en-GB.<name>.ini

•en-GB.<name>.sys.ini

• tmpl

•default.php

•helper.php

•<name>.php

•<name>.xml

NUOVO MODULO – METADATI XML

<extension type="module" version="2.5.0" client="site" method="upgrade">

• Modulo area pubblica

<description>MOD_<TAG>_ARTICLES_AUTHOR_DESCRIPTION</description>

• Traduzione dal file .sys.ini

Page 51: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

51

NUOVO MODULO – METADATI XML – PARAMETRI: FIELDSET "BASIC"

<field name="count" type="text" default="5" label="..." description="..."></field>

• Campo tipo testo per il numero di articoli visualizzati, validazione debole

• Macro definite nel linguaggio

<field name="article_ordering" type="list" validate="options" default="a.title"....> <option value="a.title">...</option>

• Campo a scelta multipla, validazione forte tra le opzioni

• Macro lunghe (includono nome modulo) per evitare collisioni

NUOVO MODULO – METADATI XML – PARAMETRI: FIELDSET "ADVANCED"

Copiare mod_articles_archive.xml o altri moduli di front page

• Layout: nome del layout alternativo opzionale

• Module Class Suffix: suffisso classe CSS

• Caching: abilitare la cache

• Cache Time: numero di secondi in cache

• Cachemode: valore di tipo "hidden"; nascosto solo a livello UI =

scarsa validazione

Page 52: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

52

NUOVO MODULO – FILE PRINCIPALE

•JLoader::register('mod<Tag>ArticlesAuthorHelper', dirname(__FILE__).'/helper.php');

•Analogo a require_once ma con autoloading, ovvero jimport(...)

Caricare classe helper

•$list = mod<Tag>ArticlesAuthorHelper::getList($params); Carica articoli

•if (isset($list[0]))

•Analogo a count($list) ma più veloce Se esistono articoli

•$moduleclass_sfx = htmlspecialchars($params->get('moduleclass_sfx')); Carica suffisso CSS

•require JModuleHelper::getLayoutPath('mod_<tag>_articles_author', $params->get('layout', 'default'));

Include il rendering

NUOVO MODULO – CLASSE DI APPOGGIO (I)

•JLoader::register('ContentHelperRoute', JPATH_SITE.'/components/com_content/helpers/route.php');

Registra metodo di appoggio esterno

•Non si istanziano oggetti di questa classe

•abstract class mod<Tag>ArticlesAuthorHelper { Dichiara classe astratta

•public static function getList(&$params) { Dichiara funzione statica

•Per evitare log di livello NOTICE

•$items = array(); Inizializza variabile

•$option = JRequest::getCmd('option'); $view = JRequest::getCmd('view');

•if ($option == 'com_content' && $view == 'article') {

Visualizza articoli correlati solo se in pagina articolo

Page 53: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

53

NUOVO MODULO – CLASSE DI APPOGGIO (II)

•$db = JFactory::getDbo(); $app = JFactory::getApplication(); $user = JFactory::getUser(); Inizializza oggetti usati

•$id = JRequest::getInt('id'); Recupera id articolo

•$levels = implode(',', $user->getAuthorisedViewLevels()); Recupera i permessi

utente

•$date = JFactory::getDate();

•$now = $date->toSql(); $nullDate = $db->getNullDate(); Date di pubblicazione

•$query = $db->getQuery(true);

•$query->select('id, created_by, created_by_alias'); $query->from('#__content');

Recupera autore articolo

•$query->where('id = ' (int) $id);

•$db->setQuery($query); $currentArticle = $db->loadObject(); Conoscendo id articolo

(METODI COMUNI PER RESTITUIRE RISULTATI DI QUERY)

loadObject()

•Restituisce la prima riga della query come oggetto, ogni colonna è un campo

• Utile quando l'output è una singola tupla

loadObjectList()

• Restituisce un array di tutte le righe come oggetti

loadResult()

• Restituisce la prima colonna della prima riga

• Altri metodi in JDatabase (libraries/joomla/database/database.php)

Page 54: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

54

Pulizia query

Tutti i campi articolo e alcuni di categoria

Per eventuali layout override

Alias per overlap dei nomi

•Join delle tabelle

•Pubblicato

•Permessi per accedere

•Date di pubblicazione

In OR, default è AND

•Controllo sull'autore (per esercizio)

$q->clear();

$q->select('a.*');

$q->select('c.access AS cat_access, c.published AS cat_state, c.alias AS cat_alias');

$q->from('#__content AS a');

$q->leftJoin('#__categories AS c ON c.id = a.catid');

$q->where('a.state = 1');

$q->where('c.published = 1');

$q->where('a.access IN ('.$levels.')');

$q->where('c.access IN ('.$levels.')');

$q->where('(a.publish_up = '.$db->Quote($nullDate).' OR a.publish_up <= '.$db->Quote($now).')');

$q->where('(a.publish_down = '.$db->Quote($nullDate).' OR a.publish_down >= '.$db->Quote($now).')');

NUOVO MODULO – CLASSE DI APPOGGIO (III)

Escludere l'articolo corrente

Ricerca per lingua (specifica o generica = *)

Ordinamento e limiti secondo parametri

Creazione dei link per ogni item

"slug": id:alias (es. 23:mio-articolo)

ContentHelperRoute::getArticleRoute crea il link ottimizzato

JRoute::_() lo rende SEF

$q->where('a.id !=' . (int) $currentArticle->id);

if ($app->getLanguageFilter()) {

//Determina la lingua corretta se abilitata

}

$q->order( /*Ordinamento in base a parametri */)

$db->setQuery($q, 0, $params->get('count', 5));

$items = $db->loadObjectList();

$item->link = JRoute::_(ContentHelperRoute::getArticleRoute($item->slug, $item->catslug));

NUOVO MODULO – CLASSE DI APPOGGIO (IV)

Page 55: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

55

NUOVO MODULO – LAYOUT DEFAULT.PHP

•Classe di stile aggiuntiva

•<ul class="<tag><?php echo $moduleclass_sfx; ?>"> Lista non numerata

•<?php foreach ($list as $item) : ?> Ciclo su tutti gli

elementi

•<li><a href="<?php echo $item->link; ?>"> <?php echo $item->title ?></a></li>

Visualizza link e titolo

•<?php endforeach; ?> Fine del ciclo

•$list = mod<Tag>ArticlesAuthorHelper::getList($params);

•Variabile ancora in scope dopo il "require" Fine della lista

NUOVO MODULO – FILE DI LINGUAGGIO

Formato MACRO="Traduzione"

File .sys.ini: usato in Extension Manager o Module Manager

File .ini: usato in tutta l'estensione

Page 56: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

56

VALIDAZIONE DEI PARAMETRI IN JFORM – CONTROLLO DEI VALORI NELL'HELPER

<field name="count" type="text"> consente di inserire qualunque valore via form

Validato successivamente nell'helper

• $count = ( $count <= 0 || $count > 10 ) ? 5 : $count;

Svantaggi

• Non viene segnalato all'utente che il valore è errato

• Il valore errato viene comunque salvato

VALIDAZIONE DEI PARAMETRI IN JFORM – TIPO DI DATO

<field name="count" type="integer" first="1" last="10" step="1">

Svantaggi

• Range limitato all'utente (variabile con step)

• Non impedisce all'hacker di forzare un valore con Firebug

Page 57: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

57

VALIDAZIONE DEI PARAMETRI IN JFORM – FILTRO DI TIPO IN JFORM

<field name="count" type="text" filter="integer">

Sicuro (validato prima dell'inserimento, non può essere manipolato dal browser)

I filtri standard sono in JFilterInput e JForm

• integer, float, double, boolean

• word, cmd, base64, string, html, array, path, username

• rules, unset, raw, int_array, safehtml, server_utc, user_utc (novità in JForm)

VALIDAZIONE DEI PARAMETRI IN JFORM – REGOLA CUSTOM JFORMRULE

Aggiunta del path delle regole

• <fieldset name="basic" addrulepath="modules/ilmiomodulo">

Funzione di validazione (cerca un file .php con lo stesso nome)

• <field name="count" type="text" filter="integer" validate="countinteger">

Page 58: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

58

JFORM REGOLA CUSTOM – PRIMA SCREMATURA

• jimport('joomla.form.formrule'); Importa libreria

standard

•class JFormRuleCountInteger extends JFormRule { Definizione classe

•public function test ( & $element, $value, $group = null, & $input = null, & $form = null) {

Funzione di validazione test()

•return ((int) $value > 0 && (int) $value <= 30); Operatore di validazione

•} Chiusura funzione

•} Chiusura classe

JFORM REGOLA CUSTOM - PERFEZIONAMENTI

R E N D E R E P A R A M E T R I C I I L I M I T I H A R D C O D E D

Specificare

parametri nel

<field>

Richiamarli nel

metodo con

$element-

>getAttribute()

M E S S A G G I D I E R R O R E I N V A L I D A Z I O N E

if ( $result === false) {

$result = new JException(

JText::sprintf(MACRO MESSAGGIO DI ERRORE)

)

}

return $result;

Page 59: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

59

HANDS ON REGOLE DI VALIDAZIONE

Leggere ed analizzare la validazione delle opzioni implementata da validate=options

libraries/joomla/form/rules/options.php

PACKAGING DEL MODULO

Aggiornare i metadati XML con l'elenco di tutti i file

Creare un archivio (.zip e/o .tar.gz) con tutti i file contenuti nella directory modules/ilmiomodulo

Per convenzione mod_<tag>_<nome modulo>_1.0.0.zip

Page 60: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

60

RIASSUMENDO

Il modulo si integra nell'installazione di Joomla

Supporta il multilingua

Supporta layout alternativi e template layout

Consente all'utente di controllare il comportamento con alcuni parametri

Il codice è protetto da eventuali attacchi (SQL injection)

Può essere installato/disinstallato

Ulteriori consigli

• Non restituire errori: un modulo non è il contenuto principale del sito! Piuttosto loggare ed avvisare l'utente a posteriori

• Mantenere snelli e veloci i moduli (sono solo una piccola parte del contenuto della pagina)

Page 61: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

61

2 elementi costitutivi

Menu di navigazione

Contenuti visualizzati

2 aree di lavoro

Frontend e backend

CRUD Create Read Update Delete

I componenti sono unici

Sono l'elemento fondante di un sito Joomla

Gestiscono i contenuti ed i menu

Gestiscono il setup nel backend

Gestiscono tutti i task CRUD

Sono usati (oltre che per visualizzare) per gestire i form ed i metodi POST

COS'È UN COMPONENTE MVC DESIGN PATTERN

Page 62: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

62

STRUTTURA DI UN COMPONENTE BACKEND (WEBLINKS) (A)

MVC File Descrizione

Controllers /weblink.php Controller per un singolo weblink

Controllers /weblinks.php Controller per le liste

Helpers /weblinks.php Funzioni di aiuto in C e V

Models /fields/ordering.php

JFormField custom per l'ordinamento

Models /forms/weblink.xml XML JForm per aggiungere/modificare

Models /weblink.php Model per un singolo weblink

Models /weblinks.php Model per le liste

STRUTTURA DI UN COMPONENTE BACKEND (WEBLINKS) (B)

SQL /install.mysql.utf8.sql

SQL /uninstall.mysql.utf8.sql

Tables /weblink.php

Views /weblink/tmpl/edit_metadata.php Layout predefinito per i metadati

Views /weblink/tmpl/edit_params.php Layout predefinito per le opzioni

Views /weblink/tmpl/edit.php Layout per modificare un weblink

Views /view.html.php HTML output per un singolo weblink

Page 63: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

63

STRUTTURA DI UN COMPONENTE BACKEND (WEBLINKS) (C)

MVC File Descrizione

Views /weblinks/tmpl/default.php Layout predefinito per il Manager

Views /weblinks/view.html.php HTML output per il Manager

access.xml config.xml weblinks.xml

Metadati per ACL, configurazioni ed installazione

[Controller] controller.php Classe controller primaria

[Controller] weblinks.php Entry point del componente

STRUTTURA DI WEBLINKS – INSTALLAZIONE

Lista delle tabelle da creare/droppare in installazione/disinstallazione

Per le estensioni core installation/sql/mysql/joomla.sql contiene le

stesse indicazioni

Molte estensioni core possono comunque essere disinstallate

Page 64: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

64

STRUTTURA DI WEBLINKS – MENU DI BACKEND I menu in backend sono gestiti in modo diverso da quelli del

frontend

Definiti in weblinks.xml ed inseriti nella tabella #__menus in

installazione

STRUTTURA DI WEBLINKS – OPZIONI DEL COMPONENTE (PARAMETRI) Più complesse di quelle di moduli e plugin

Opzioni globali (icona Options nella toolbar)

• Gestite dal componente com_config

• Definite da config.xml e access.xml

Page 65: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

65

STRUTTURA DI WEBLINKS – CLASSI DI APPOGGIO I metodi di appoggio non rientrano nell'organizzazione Model-

View-Controller

Possono essere usate in diversi punti (tipicamente View e

Controller)

• addSubmenu() aggiunge i sottomenu in Weblinks Manager

(gestiti separatamente da weblinks.xml)

• getActions() determina le azioni consentite e mostrate in toolbar

• Ciò non protegge da hacking che modifica la PHP $_REQUEST

direttamente: occorre sempre validare i permessi nel controller prima di eseguire qualunque task!

STRUTTURA DI WEBLINKS – ENTRY POINT

administrator/com_weblinks/weblinks.php

• Controllo permessi per l'action core.manage

• jimport ('joomla.application.component.controller');

• $controller = JController::getInstance('Weblinks');

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

• $controller->redirect();

Page 66: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

66

IL CONTROLLER IN AZIONE – ESEMPIO 1

Utente seleziona menu Componenti > Weblinks

URL administrator

/index.php?option=com_weblinks

Task - (predefinito display)

Controller WeblinksController (controller.php)

Controller

method

display()

Controller

redirect

-

IL CONTROLLER IN AZIONE – ESEMPIO 2A

Utente clicca su un elemento per modificarlo: verifica dei permessi

URL administrator/index.php?option=com_weblinks&task=weblink.edit&id=7

Task weblink.edit (split controller.task)

Controller WeblinksControllerWeblink (controllers/weblink.php)

Controller method

JControllerForm->edit() (metodo della classe padre, non esiste nel controller: verifica permessi e salva id in sessione)

Controller redirect

index.php?option=com_weblinks&view=weblink&layout=edit&id=7 (reale form di modifica del contenuto)

Page 67: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

67

IL CONTROLLER IN AZIONE – ESEMPIO 2B

Utente clicca su un elemento per modificarlo: modifica del contenuto

URL administrator/index.php?option=com_weblinks&view=weblink&layout=edit&id=7

Task - (predefinito display)

Controller WeblinksController (controller.php)

Controller method

WeblinksController->display() La view ed il layout sono definiti per la modifica L'id specificato viene verificato contro quello in

sessione per prevenire hijacking

Controller redirect

-

IL CONTROLLER IN AZIONE – ESEMPIO 3 Utente clicca su Salva&Chiudi nel form di modifica

URL administrator/index.php?option=com_weblinks&layout=edit&id

=7

Task weblink.save (non in URL ma in

onclick="javascript:Joomla.submitbutton('weblink.save')")

Controller WeblinksControllerWeblink (controllers/weblink.php)

Controller

method

JControllerForm->save()

L'id specificato viene verificato contro quello in sessione per

prevenire hijacking

I permessi vengono verificati

I dati vengono validati via ->validate() del modello

I dati vengono salvati via ->save() del modello

Controller

redirect

index.php?option=com_weblinks&view=weblinks (può differire

a seconda di Salva&Nuovo o Salva)

Page 68: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

68

IL CONTROLLER IN AZIONE – ESEMPIO 4A Utente cestina alcuni weblinks

URL administrator/index.php?option=com_weblinks&view=weblinks

Task weblink.trash (da javascript onclick)

Controller WeblinksControllerWeblinks (controllers/weblinks.php)

Controller method

JControllerAdmin->publish() Il task trash viene mappato in publish dall'array $taskmap • Nel costruttore di JController – parent di JControllerAdmin – vengono

prima registrati i metodi pubblici ispezionati via reflection (checkin, display, publish, reorder, saveorder)

• Nel costruttore viene registrato il default come display

($this->registerDefaultTask) • Nel costruttore vengono mappate le alternative

($this->registerTask('trash', 'publish') e altri)

Controller redirect

administrator/index.php?option=com_weblinks&view=weblinks

IL CONTROLLER IN AZIONE – ESEMPIO 4B

Dal controller al model

• Siamo nel metodo publish() di WeblinksControllerWeblinks, implementato nel parent JControllerAdmin

• Verifiche sul token utente

• $this->getTask() settato dalla execute($task) di JController per decidere il valore da modificare

• $this->getModel() è l'unico metodo implementato realmente in WeblinksControllerWeblinks

• public function getModel ( $name = 'Weblink', $prefix =

'WeblinksModel', ...) {

• $model = parent::getModel($name, $prefix, ...);

Page 69: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

69

IL CONTROLLER IN AZIONE – ESEMPIO 4C

Dopo aver ottenuto il model corretto (WeblinksModelWeblink) in JControllerAdmin

$model->publish($cid, $value) effettua la modifica

Il controller imposta il messaggio da restituire

Il controller imposta il redirect

• $this->setRedirect( JRoute:: ...)

RIASSUNTO DI METODI, TASK E CLASSI NEI CONTROLLER DI WEBLINKS WeblinksController (controller.php)

• Contiene solo display(): è l'unico metodo che visualizza qualcosa a schermo

WeblinksControllerWeblinks < JControllerAdmin < JController gestisce le schermate "plurali"

• Implementa solo getModel()

WeblinksControllerWeblink < JControllerForm < JController gestisce le schermate "singolari"

• Implementa due metodi privati

• Mappa apply, save2new e save2copy a save

Page 70: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

70

Entry point del componente MVC

Decidere il controller per il task

Eseguire il task dal controller

Eseguire, se necessario, un redirect

Regole di inferimento del nome del controller (componente + parte del task)

Se il task è diverso da display • Svolge operazioni • Reindirizza ad un display

I task sono mappati su metodi del controller

• Realmente implementati • Definiti con registerTask()

WORKFLOW DEL CONTROLLER IL MODEL IN AZIONE "SINGOLARE" O "PLURALE"

A seconda del controller

Esplicito "cast" a singolare nel caso del controller plurale, altrimenti automatico in getModel() di JControllerForm

Page 71: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

71

Controller Model

add() controlla permessi e redirige a edit

-

edit() verifica permessi + lock e redirige

getTable() checkout() getError()

cancel() redirige al manager checkin()

publish() checkin() delete()

reorder() save() saveorder()

chiamate corrispondenti in WeblinksModelWeblink < JModelAdmin < JModelForm <

Jmodel

IL METODO PUBLISH() – PRIMA PARTE

Dal controller if (!$model->publish(...)) raise warning

Nel model function publish(&$pks, $value = 1) //$pks chiamato by reference

• $dispatcher = JDispatcher::getInstance(); // per i trigger di eventi

• $user = JFactory::getUser();

• $table = $this->getTable();

• $pks = (array) $pks; // modifica array o singolo item

• JPluginHelper::importPlugin('content'); //trigger plugin di tipo content onContentChangeState

Page 72: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

72

IL METODO PUBLISH() – SECONDA PARTE

foreach ($pks as $i => $pk)

• $table->reset(); // reset colonne a valori default

• if ($table->load($pk)) // carica l'item

• if (!$this->canEditState($table)) // verifica permesso

• unset($pks[$i]) // l'item viene rimosso dalla lista, restituita (by reference) al controller, che invierà il messaggio corretto sul numero di item effettivamente modificati

• raiseWarning su permessi e return false

IL METODO PUBLISH() – TERZA PARTE

Verifica del permesso di modifica protected function canEditState($record) // metodo protetto

• $user = JFactory::getUser();

• if (!empty($record->catid)) // i weblinks hanno sempre una categoria

• return $user->authorise( 'core.edit.state', 'com_weblinks.category.' . (int) $record->catid); // permessi definiti nell'access.xml

• else

• return parent::canEditState($record);

Page 73: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

73

IL METODO PUBLISH() – QUARTA PARTE

if ( !$table->publish(...) ) // Questo statement chiama la funzione di $table che opera realmente sul db

• $this->setError($table->getError());

$result = $dispatcher->trigger(...) // trigger per i plugin onContentChangeState

• if (in_array(false, $result, true))

• $this->setError($table->getError()); // lo sviluppo di plugin customizzati può intervenire sul workflow della pubblicazione

(ed altri)

$this->cleanCache(); // pulisce la cache in modo da visualizzare informazioni aggiornate

IL METODO SAVE() DI JMODELFORM

$form = $model->getForm($data, false);

• // ottiene un'istanza di oggetto JForm

$validData = $model->validate($form, $data);

• I dati vengono validati secondo il metodo definito in JModelForm

• $data = $form->filter($data); // i dati vengono filtrati per eliminare dati non corretti – nessuna notifica

• $return = $form->validate($data); // i dati vengono validati in

base al contesto – tipicamente notifica all'utente per reinserire dati corretti (una data in un campo data, etc.)

Page 74: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

74

GENERICO COMPORTAMENTO DEI METODI DEL MODEL

Azioni preliminari

del controller

Chiama il model

•Metodo del model con lo stesso nome

Riceve messaggio

•Fallimento o successo

Restituisce true o false

APPROFONDIMENTO SULL'ACCESSO AL DB

L'accesso al db dal model avviene attraverso la classe table (WeblinksTableWeblink)

• load(): ereditata da JTable, carica una riga ed associa le colonne del db ai rispettivi campi dell'istanza di JTable

• bind(): ha come input un array associativo o oggetto e carica ciascun elemento in un campo di JTable; gestisce anche da serializzare (JSON, ad es.)

• check(): controlla dati non validi o senza senso; non implementato dal parent JTable

• store(): aggiorna dati esistenti ed il modified_by, oppure crea nuovi dati e il created_by; verifica duplicati di categoria ed alias

Page 75: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

75

LE VIEW ED IL METODO DISPLAY()

Una view viene mostrata quando non ci sono task o quando il task è display

WeblinksController (controller.php) implementa il metodo

display() di 2 viste

• Vista Weblinks (default): lista dei links

• Vista Weblink: per aggiungere/modificare un singolo elemento

Page 76: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

76

LA VISTA WEBLINKS

public function display(...)

• // vista e layout predefiniti, campo id vuoto

• // controlla se si trova in una vista "weblink" con layout "edit"

• parent::display();

• return $this; // method chaining (verificare con l'entry point del modulo, rende possibile $oggetto->metodo1()->metodo2())

IL METODO DISPLAY() DI JCONTROLLER

Definisce un $document di tipo JDocumentHTML

Definisce la vista "weblinks", il layout "default" e la view class "WeblinksViewWeblinks"

Ottiene il $model "WeblinksModelWeblink"

Ottiene la $conf da JFactory::getConfig()

Verifica che la pagina sia in cache ed eventualmente la carica

Altrimenti esegue il metodo display() della vista (in views/weblinks/view.html.php)

Page 77: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

77

IL METODO DISPLAY() DI WEBLINKS VIEW WEBLINKS

$this->state = $this->get('State') e analoghi

• Ottiene il model e cerca un metodo getState()

• Spesso ereditati da JModel e JModelList

// Check for errors

$this->addToolbar();

• Aggiunge icone New, Edit, Publish, ... gestite da mod_toolbar

(renderizzato più tardi nel ciclo)

parent::display($tpl);

• Chiama JView (libraries/joomla/application/component/view.php)

IL METODO DISPLAY() DI JVIEW

$result = $this->loadTemplate($tpl);

• Il template viene incluso in questo metodo con include $this->_template;

• Template predefinito in views/weblinks/tmpl/default.php

• Ad esempio con template Hathor, invece di Bluestork, override in administrator/templates/hathor/html/com_weblinks/weblinks/default.php

if (JError::isError($result)) return $result;

echo $result;

• Output inviato all'output buffer avviato con ob_start()

Page 78: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

78

IL LAYOUT PREDEFINITO: LE SEZIONI VISUALIZZATE A SCHERMO

Filtro titoli Filtri di

selezione a tendina

Box per il check-all

Titoli colonne ordinabili

Elementi Weblink effettivi

Controlli paginazione

LAYOUT: PREPARAZIONE

Include il path administrator/com_weblinks/helpers/html

• Per classi e metodi JHtml specifici richiamabili con JHtml::_(...)

• Creare una classe JHtml<Componente> nella cartella, richiamato con JHtml::_('componente.metodo', 'argomenti')

Imposta variabili usate successivamente

• Il template è nello scope di WeblinksViewWeblinks, $this si riferisce a questa

Apre il form con action=URL corrente e method=POST

Page 79: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

79

LAYOUT SEZIONE A: FILTRO TITOLI

Analizzare il contenuto di <div class="filter-search fltflt">...</div>

LAYOUT SEZIONE B: LE SELECT LIST DI FILTRAGGIO

Inserisce 4 filtri per stato di pubblicazione, categoria, accesso e linguaggio

Usa JHtml::_('select.options') che chiama il metodo JHtmlSelect::options() con 5 argomenti

• Array di valori, proveniente dal risultato di JHtmlGrid::publishedOptions()

• Nome della variabile, settato a "value"

• Nome dell'opzione, settato a "text"

• Valore selezionato, proveniente da $this->state->get('filter_state')

• Booleano se tradurre i testi e le label

Verificare l'output HTML risultante

Le altre select list sono costruite in modo analogo

Page 80: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

80

LAYOUT SEZIONE C: LA CASELLA CHECK-ALL

<input type="checkbox" name="checkall-toggle" value="" onclick="Joomla.checkAll(this)" />

Chiama media/system/js/core.js

Loop su tutte le check box e seleziona/deseleziona

LAYOUT SEZIONE D: COLONNE ORDINABILI

Esempio di ordinamento del titolo, effettuato con JHtml::_('grid.sort', ...

• Titolo: "JGLOBAL_TITLE"

• Campo di ordinamento: "a.title" nella tabella #__weblinks

• Direzione di ordinamento: $listDirn (impostato nella fase preliminare)

• Ordinamento selezionato: $listOrder (come sopra)

Le altre colonne in modo analogo

Page 81: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

81

LAYOUT SEZIONE E: TABELLA DEGLI ITEM

Inserita tra tag <tbody>, un elemento per riga <tr>, un campo per colonna <td>

• Select box generata da JHtmlGrid::id()

• Per esercizio analizzare la cella del titolo

• Codice per visualizzare l'icona di checkin/checkout

• Aggiunge l'URL cliccabile solo se si hanno i permessi

• I testi sono inseriti con ->escape() per prevenire codice malizioso

• Per esercizio analizzare la cella di ordinamento

LAYOUT SEZIONE F: CONTROLLI DI PAGINAZIONE

<tfoot>... $this->pagination->getListFooter();

L'oggetto pagination proviene dal metodo getPagination() del model

• A sua volta è un'istanza di JPagination (non approfondita in questa sede)

La maggior parte del codice presentato in questa vista è riutilizzabile/riutilizzato in gran parte di altre estensioni

Page 82: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

82

IL METODO DISPLAY() DI WEBLINKSVIEWWEBLINK

Classe usata per aggiunta o modifica di un singolo item (views/weblink/view.html.php)

$this->state chiama $model->getState() come nella vista

precedente

$this->item chiama ->getItem() di JModelAdmin

• Carica l'item se esistente e crea oggetto JRegistry per i parametri

$this->form chiama ->getForm() di JForm

IL WORKFLOW DI GETFORM()

WeblinksModelWeblink getForm()

JModelForm loadForm()

WeblinkModelWeblink loadFormData()

JModelForm loadForm()

JModelForm preprocessForm()

JModelForm loadForm()

JForm bind()

Page 83: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

83

WEBLINKSMODELWEBLINK GETFORM()

$form = $this->loadForm(...)

• Parametri: $name, $source ed array di opzioni

JMODELFORM LOADFORM()

$form = JForm::getInstance(...) • In blocco try/catch per sollevare eccezioni • Controlla che $data sia una stringa contenente l'XML o un file XML:

in questo caso $data = 'weblink' • Caricato con loadFile() di JForm dal file

models/forms/weblinks.xml

$data = $this->loadFormData() • Carica i dati dalla sessione (ad es. per un form parzialmente

completato , con getUserState()) o dai valori di un item esistente o di default per un item nuovo (con getItem)

$this->preprocessForm($form, $data) • Trigger evento onContentPrepareForm per i plugin che possono

modificare sia $form che $data

$form->bind($data) • Match ed associazione tra i form fields ed i dati

Page 84: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

84

RENDERIZZAZIONE DEL JFORM (IN VIEWS/WEBLINK/TMPL/EDIT.PHP)

Tipicamente ogni campo nella forma

• $this->form->getLabel() per stampare la label

• $this->form->getInput() fa il rendering dell'elemento del form opportuno

L'area laterale è costruita da

• JHtml::_('sliders.start', ...) e JHtml::_('sliders.panel' ...)

L'area dei parametri è renderizzata da

• $this->loadTemplate('params') chiama ./edit_params.php

• Qua viene usato un ciclo foreach su tutto il fieldset nested presente nell'XML: questa tecnica viene usata per presentare i parametri di moduli, plugin, template e linguaggi

Page 85: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

85

IL COMPONENTE WEBLINKS DI FRONTEND

Focus solo sulle similitudini e differenze dal backend

Simile struttura di cartelle e pattern MVC

• No dati di installazione (solo nel backend)

• No gestore table (solo nel backend)

STRUTTURA DEL FRONTEND MVC File Descrizione

Controllers/ /weblink.php Controller per la schermata singola entry

Helpers/ /{category,icon,route}.php Funzioni di appoggio

Models/ *.php Model

Models/ /forms/weblink.xml JForm XML

Views/ /categories/view.html.php Vista per menu categorie

Views/ /categories/tmpl/* Layout per menu categorie; XML per opzioni menu

Views/ /category/view.{html,feed}.php Vista per singola categoria

Views/ /category/tmpl/* Layout per singola categoria; XML per opzioni menu

Views/ /form/view.html.php Vista per creare menu item

Views/ /form/tmpl/* Layout per il form; XML per opzioni menu

router.php Router del componente

[Controller] controller.php Predefinito per task display

[Controller] weblinks.php Entry point del componente

Page 86: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

86

STRUTTURA GENERALE

Entry point identico a quello del backend

• JController::getInstance('Weblinks')->execute( JRequest::getCmd('task'))->redirect();

3 viste, ciascuna estende JView, ha layout caricati da loadTemplate(), ed ha model

• Categorie: visualizza tutte le categorie

• Categoria: visualizza i weblink in una categoria

• Hanno solo funzione display, sono gestite da

WeblinksController (controller.php)

• Form: visualizza il form per inviare un weblink

• Gestita da WeblinksControllerWeblink, task add/edit/save

PECULIARITÀ DEL COMPONENTE WEBLINKS

Il model per il form WeblinksModelForm eredita WeblinksModelWeblink di backend (per usare il metodo save())

La WeblinksModelWeblink di frontend serve a gestire i task prima di redirigere un elemento weblink alla sua destinazione remota (non ha un template/layout proprio)

• Il controller lancia il task go()

• Il model di frontend verifica i permessi, la pubblicazione ed incrementa l'hit counter

Page 87: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

87

UNA DIFFERENZA IMPORTANTE TRA BACKEND E FRONTEND: I MENU ITEM

In backend i menu sono predefiniti ed immodificabili

administrator/components/com_weblinks/weblinks.xml

• In frontend i menu sono modificabili tra 3 tipi

Lista categorie: views/categories/tmpl/default.xml

Lista link in categoria: views/category/tmpl/default.xml

Invia un link: views/form/tmpl/edit.xml

I MENU ITEM IN FRONTEND: VIEWS/CATEGORY/TMPL/DEFAULT.XML

Field "id" nella lista "request"

• Inserito nell'URL come <name> = <value> (id=5) e disponibile nella $_REQUEST

I field nella lista "params"

• Salvati in #__menus come gli altri, ma serializzati da JRegistry in JSON

I field standard (Link type options, Page display options, Metadata options)

• administrator/components/com_menus/models/forms/item_component.xml

• Validi per quasi tutti i tipi di menu item (eccetto External URL, Menu item alias e Text separator)

Page 88: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

88

IL ROUTING DI FRONTEND

Router: classe che traduce URL in array di comandi (parse()) e viceversa (build())

Ragioni del SEF URL

• In admin non interessano nè motori di ricerca nè leggibilità

• Inizialmente motori non abili a parsare query string ma solo URL statici

• Ora fanno l'indexing anche di URL con query string

• Più che SEF possiamo parlare di "human-friendly"

Obiettivo: una stessa pagina

raggiungibile da catene di link diversi

Soluzione: fornire lo stesso URL da

qualunque posizione

Nella definizione del

router di Weblinks, una

vista di singola

categoria è preferibile

ad una vista generica

In altre parole, un link più

specifico ha sempre la

precedenza

IL METODO "BEST FIT"

Page 89: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

89

LA VISTA "NEWS FEED" DEL FRONTEND

Peculiare del frontend, genera contenuti per i news reader

Metodo _prepareDocument() chiamato da display() di views/category/view.html.php

• Genera link con format=feed e type=rss/atom

Vista generata da JDocumentHTMLFeed

• Chiama views/category/view.feed.php

• Genera dei JFeedItem e li aggiunge al JDocumentFeed via addItem()

Page 90: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

90

SOMMARIO

Concetti di base dei RDBMS

• Focus su MySQL, ma concetti generali applicabili a tutti gli engine

Query SQL

Istanza di JDatabaseQuery per costruire le query in Joomla

Database

•Joomla configuration.php

Table

•Collezione di record

Row (tuple)

•Un set di dati

Column (field, attribute)

•Un dato specifico

L'idea di base dei RDBMS:

consentire accesso ed

interazione ai dati dal

punto di vista logico

(con un linguaggio

specifico – SQL)

indipendentemente

dalla loro archiviazione

fisica

PANORAMICA SUI DATABASE

Page 91: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

91

TIPOLOGIE DI STATEMENT

D D L ( D A T A D E F I N I T I O N )

I dati sono strutturati, devono essere definiti in anticipo

• Creazione delle tabelle

• Definizione dei tipi di

dati nelle colonne

• Gestione dei permessi

di accesso

D M L ( D A T A M A N I P U L A T I O N )

Comandi per l'interrogazione del DB e la manipolazione dei dati

• SELECT

• INSERT / REPLACE

• UPDATE

• DELETE

STATEMENT DDL

Tipicamente solo negli script di installazione

• La struttura dei dati deve essere definita prima di essere usata

Specifici per il motore

• Sintassi simile ma non identica

Installazione del core

• installation/sql/mysql/joomla.sql

Page 92: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

92

CREATE TABLE

CREATE TABLE <tabella> ( <lista di colonne>, <lista di indici> ) <character set>

• <tabella>: #__banner_clients

• Carattere ` per racchiudere parole riservate (circa 200 in MySQL)

• <colonna>: <nome> <tipo> <attributi>

• `id` INTEGER NOT NULL AUTO_INCREMENT

• <indice>: INDEX <idx_nome> ( <colonne> )

• INDEX `idx_own_prefix` ( `own_prefix`)

• <character set>: DEFAULT CHARSET=utf8

INDICI E CHIAVI

C H I A V I

Chiave primaria identifica univocamente un record nella tabella

Usata per riferimenti su tabelle esterne (foreign key)

Singolo dato definito da • NOT NULL • AUTO_INCREMENT

Chiave definita da • PRIMARY KEY (`id`)

I N D I C I

Letture + veloci, scritture + lente

Importanti per grandi tabelle

Utili sugli elementi per cui si selezione, raggruppa o odina

Con UNIQUE utili per evitare set di dati duplicati

Per convenzione idx_<nome>

Page 93: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

93

TIPI DI DATI

• Intero signed o unsigned, n indica solo le cifre in display INT/INTEGER(n)

•0-255, per riferimenti a liste limitate, cast a (int) facilitato TINYINT

•Testo di lunghezza max definita (2^16 / 3 char) VARCHAR(n)

•Testo di lunghezza fissa, raramente usato CHAR(n)

•YYYY-MM-DD HH:MM:SS DATETIME

•Testo max 2^16 caratteri, per keyword e JSON TEXT

•Testo max ~16MB, per articoli e descrizioni MEDIUMTEXT

•Valore decimale di n cifre e p precisione DECIMAL(n,p)

•23 e 53 cifre significative FLOAT e DOUBLE

ATTRIBUTI DELLE COLONNE

NOT NULL

•True, false e null sono 3 valori diversi

AUTO_INCREMENT

• Insieme a INTEGER, definisce un campo che si autoincrementa

DEFAULT

•Definisce un valore predefinito se non specificato

•Utile insieme a NOT NULL

UNSIGNED

• INTEGER o TINYINT solo positivi

Page 94: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

94

ALTER E DROP TABLE

ALTER TABLE <table>

• CHANGE <colonna> <colonna> <tipo> <attributi>

• Non cancella dati esistenti finchè sono contenibili nel nuovo tipo

• ADD COLUMN <colonna> <tipo> <attributi> BEFORE/AFTER <colonna>

DROP TABLE <tabella>

• Cancella la tabella (compreso il suo schema) e tutti i dati

STATEMENT DML

Strumenti di interrogazione e manipolazione dei dati

• SELECT

• UNION

• UPDATE

• INSERT

• DELETE

Page 95: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

95

QUERY DI SELEZIONE (SELECT)

SELECT <lista colonne e espressioni>

FROM <tabella primaria>

JOIN <lista di condizioni di join con altre tabelle>

WHERE <condizioni di selezione>

GROUP BY <raggruppamento>

HAVING <condizioni di selezione sul raggruppamento>

ORDER BY <condizioni di ordinamento>

LIMIT <offset e conteggio record>;

SELECT QUERY NEL DETTAGLIO

•SELECT a.* FROM jos_content AS a

•Alias per semplificare la scrittura Lista delle colonne

•FROM jos_content AS a Tabella primaria

•INNER JOIN jos_categories AS c ON a.catid = c.id

•Differenza tra INNER e LEFT Unione di dati

•WHERE a.state = 1 AND c.title = 'Plugins'

•Condizioni con AND/OR e NOT, LIKE per le stringhe Condizione di selezione

•ORDER BY a.created_by_alias ASC Ordinamento

•LIMIT 5,10 (= 10 record a partire dal quinto) Limitazioni

•Raggruppamento su un attributo; sono selezionabili solo campi raggruppati o espressioni calcolate: MIN(), MAX(), AVG(), SUM(), COUNT() e COUNT(DISTINCT) Aggregati

Page 96: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

96

•UPDATE jos_content UPDATE

<tabella>

•SET created_by_alias = 'Myself', created = '2013-01-01 12:00:00'

SET <lista colonne=valori>

•WHERE created_by_alias = 'Joomla'

WHERE <condizioni>;

•DELETE FROM jos_content_frontpage

DELETE FROM <tabella>

•WHERE contend_id = 35 WHERE

<condizioni>;

• INSERT INTO jos_content_frontpage

INSERT INTO <tabella>

• (content_id, ordering)

•Lista delle colonne con valori, le altre avranno default)

(<colonne>, ...)

•VALUES (8,2), (35,4);

•Più righe contemporaneamente

•Usa NULL per colonne AUTO_INCREMENT

VALUES (<valori>,

...);

QUERY DI AGGIORNAMENTO, INSERIMENTO E CANCELLAZIONE

Entity – Relationship

Minimizzazione delle

informazioni

Esempio basato su DB

per una scuola • Studenti

• Insegnanti

• Classi

3 tipologie di tabelle • Reference: rappresentano

le informazioni statiche di un'entità

• Mapping: per la

mappatura n-m

• History: per la

conservazione dei dati

(log, storici acquisti)

DISEGNO DELLA STRUTTURA DELLE TABELLE (SCHEMA)

Page 97: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

97

REFERENCE E MAPPING TABLE

R E F E R E N C E

Studenti: informazioni statiche (nome, indirizzo, età, ...)

Insegnanti: informazioni statiche

Classi: nome, descrizione, dipartimento, date

Dipartimenti: nome e descrizione

Ciascuna riga di ogni tabella rappresenta un'entità concreta

M A P P I N G

Per le relazioni molti a molti

• Ad esempio ogni studente partecipa a più classi; ogni classe ha più studenti • student_class_map con

student_id e class_id

• Esercizi: selezionare gli studenti di una classe e le classi di uno studente

HISTORY TABLE

Dati "dinamici", riguardano eventi o transazioni

Ad esempio storico delle classi completate da uno studente

• student_class_history (history_id, student_id, class_id, semester, date_completed, class_grade, comments)

Page 98: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

98

LAVORARE CON IL DATABASE IN JOOMLA!™

JTable gestisce la maggior parte dei task di insert, update e delete

• Non quelli per le tabelle di mapping

JDatabaseQuery crea lo statement SQL

• JDatabaseQueryMySQLi implementa il driver specifico

• $query = JFactory::getDbo()->getQuery(true)

• NO $query = new JDatabaseQuery()

JDatabase lo esegue e restituisce i risultati

SQL JDatabaseQuery

Lista di colonne select()

FROM from()

INNER JOIN innerJoin()

LEFT JOIN leftJoin()

WHERE where()

ORDER BY order()

GROUP BY group()

LIMIT Implementato in JDatabase

setQuery($query, $start,

$offset)

La costruzione può

essere fatta in qualunque ordine

__toString() riordina

lo statement SQL

Method chaining • $query->select()-

>from()

COSTRUIRE SELECT CON JDATABASEQUERY

Page 99: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

99

PROTEZIONE DELLE QUERY

Tutte le variabili provenienti da sorgenti esterne devono essere controllate

Cast di valori interi: (int) $catid

Escape dei caratteri speciali via quoting del testo: $db->quote() dell'oggetto

JDatabase

COSTRUIRE INSERT CON JDATABASEQUERY

Alternativa con set()

Ogni valore inserito singolarmente

$q->set('chiave= ' . $valore)

Alternativa con columns() e values()

Valori inseriti in gruppo

Lista delle colonne $q->columns( 'colonne,...' )

Lista dei valori $q->values( 'valori,...')

Page 100: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

100

COSTRUIRE UPDATE E DELETE CON JDATABASEQUERY

Metodi analoghi a quelli precedenti

UPDATE

• update()->set()->where()

DELETE

• delete()->from()->where()

ESECUZIONE DELLE QUERY DI MANIPOLAZIONE Modificano il DB ma non restituiscono dati

• Passare la query all'oggetto DB con setQuery()

• Eseguire la query con query()

• Verificare errori ed eventualmente processarli

• $db->getErrorNum() e $db->getErrorMsg() hanno informazioni sul'errore su database

Esempio

• $db->setQuery($query);

• if ($db->query()) {

• return true;

• else

• $this->setError(JText::_('MACRO_ERRORE')); return false;

Page 101: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

101

ESECUZIONE DELLE QUERY DI INTERROGAZIONE Restituiscono dati ma non modificano il DB

• Passare la query all'oggetto DB con setQuery()

• Usare uno dei metodi di caricamento dei dati

• Verificare errori ed eventualmente processarli

Esempio

• $db->setQuery($query, $limitstart, $limit);

• $data = $db->loadObjects();

• if ($db->getErrorNum()) {

• $this->setError(JText::_('MACRO_ERRORE')); return false;

• else

• return $data;

JDatabase Return Descrizione

loadObject() Oggetto Prima riga

loadObjectList() Array di oggetti Tutte le righe

loadResult() Mixed Prima colonna della prima riga

loadColumn() Array Array di una colonna

loadAssoc() Array associativo

Prima riga

loadAssocList() Array di array associativi

Tutte le righe

loadRow() Array con indici Prima riga come array

loadRowList() Array di array Tutte le righe

Esempio 1 • $dbo->loadObjectList(); • foreach ($d as $row) • $title = $row->get('title'); • $id = $row->get('id'); • ...

Esempio 2 • $dbo->loadAssocList(); • foreac ($d as $row) • $title = $row['title']; • $id = $row['id'];

RESTITUIRE I DATI DI UNA QUERY DI INTERROGAZIONE

Page 102: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

102

STRUTTURA DEI FILE

PHP è un linguaggio interpretato

• Il codice sorgente viene letto ad ogni esecuzione

Tipicamente estensione .php

• Il codice è racchiuso tra tag <?php ... ?>

• Tag di chiusura omesso in file solo php

PHP ed HTML nello stesso file possibile

• Soprattutto nei template

Gli spazi (spazi, tabulazioni, ritorni carrello) sono ignorati,

aumentano leggibilità

Page 103: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

103

Carattere Utilizzo

/* */ // Commenti lunghi e inline

; Terminatore di ogni statement

{ } Blocchi di codice

( ) Metodi di funzione; condizioni logiche; valori di array; espressioni; cast

$ Prefisso di ogni variabile

-> Chiamata di metodo di oggetto

:: Chiamata di metodo statico

[ ] Valori di array

=> Key/value in array associativi

' e " Delimitatori di stringa

Carattere Utilizzo

, Separatore di argomenti

. Concatenatore di stringa

= Operatore di assegnazione

= > < e simili Operatori logici

! || e && Connettivi logici

? : Operatore ternario

\ Carattere di escape

+ - * / Operatori matematici

& Nella signature di un metodo indica che il parametro sarà passato by-reference

CARATTERI IMPORTANTI OPERATORI DI FREQUENTE UTILIZZO

Dichiarazione di variabili ed operazioni

• $a = 'valore'; $a .= 'suffisso';

• $x = 1; $x += 1;

Operatore di cast per forzare il tipo

• $c = (string) $b; $c = (int) $d;

Operatori logici per la verifica delle condizioni

• ($a == $b) oppure ($a === $b)

• Equivalenza vs Identità

• ($a == $b && $c != $d)

• Lazy evaluation e differenze tra && e and

Page 104: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

104

STATEMENT CONDIZIONALI

if: codice classico

• if ( condizione ) {

• // esegui se condizione è true

• } else {

• // esegui se condizione è false

• }

Varianti di if

• Condizione con assegnamento

• if ( $link = $db -> loadResult() )

• Esegue metodo, assegna alla variabile, valuta che non sia null

• Sostituzione con operatore ternario

• $a = ( $b == $c ) ? $d : $e

switch: codice classico

• switch ($a) {

• case 'abc':

• // esegui se $a=='abc'

• break;

• default:

• // esegui se nessuno dei precedenti

• break;

• }

STATEMENT DI CICLO

foreach ( $array as $key => $value ) { ... }

• $key non obbligatorio

for ( $i = 0; $i < $max; $i++ ) { ... }

while ( $a != $b ) { ... }

• continue; // Salta il resto dell'iterazione per questo ciclo: da evitare

Page 105: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

105

SINTASSI ALTERNATIVA

Utile in caso di codice mixed con HTML

<?php if ( $a == $b ) : ?>

• codice misto PHP + HTML

• <p>This is a <?php echo 'test'; ?></p>

<?php endif; ?>

<?php foreach ( $groups as $group ) : ?>

• <p><?php echo $group; ?></p>

<?php endforeach; ?>

VARIABILI

Scalare

• Prefisso $var

• Case sensitive

• Non dichiarare ma inizializzare

• Scope del blocco in cui sono usate

• Un file incluso equivale al file stesso

• Costanti con define()

Array

• $simple = array( 'valore1', 'valore2');

• echo $simple[0];

• $assoc = array( 'name' => 'Me', 'age' => 12);

• echo $assoc['age'];

Stringa

• Variabile contenente caratteri

• Funzioni builtin di PHP oppure metodi statici di JString (libraries/ joomla/utilities/ string.php)

Page 106: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

106

FUNZIONI E METODI

function <nome> ( <argomenti> ) {

• // codice della funzione

Linguaggio procedurale: funzioni

OOP: classi, istanze di classe e metodi

Scope degli argomenti: locale alla funzione, anche se dovessero avere lo stesso nome

• Per passare i valori by reference, aggiungere & nella signature

• NON si può fare call-time pass-by-reference

FILE ED INCLUSIONE

T I P I D I F I L E C O M U N I

Dichiarazioni di classi

•class <nome> { <campi>; <metodi>; }

•Codice eseguito solo quando chiamato (oggetti istanziati o metodi statici)

Dichiarazioni di funzioni

•Non possono essere inclusi con jimport

•Esempi templates/system/html/modules.php o components/com_content/router.php

Script semplici

•Esempio index.php

•Eseguiti immediatamente

I N C L U S I O N E D I F I L E

include • Errore se contiene classe o funzione

già dichiarata

include_once

require • Come include ma il file deve

esistere

require_once

JLoader::register() • Metodo consigliato per le classi

jimport() • Shortcut se classe e nome seguono

la convenzione

Page 107: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

107

CONCETTI BASE DI PROGRAMMAZIONE AD OGGETTI

Classe

• Definisce un tipo di entità

• Possiede attributi e metodi

• Ha un metodo __construct() per definire la creazione di un oggetto

Oggetto

• Istanziazione concreta di una classe

• JFactory::get<Name>(): per gli oggetti globali (singleton)

• ::getInstance(<params): per oggetti che implementano il metodo (es. JTable::getInstance('Client', 'BannersTable'))

• new <Class>(): oggetti con istanze multiple, passa gli argomenti al costruttore

EREDITARIETÀ ED OVERRIDING

class JDocumentHTML extends JDocument

• Una classe più specifica eredita le proprietà da una classe più generica

Method overriding

• La classe figlia può ridefinire i metodi implementati dalla classe padre (con stessa signature)

• Chiama il metodo padre con parent::<metodo>

• Modificatori di metodo

• Public: può essere usato da tutti

• Protected: usato da se stessa o sottoclassi

• Private: usato da se stessa

Page 108: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

108

METODI STATICI, $THIS, SELF E PARENT

Metodo statico: di classe, non di oggetto

• Definizione: public static function <funzione>(...)

• Chiamata: <classe>::<funzione>(...)

$this si riferisce all'oggetto corrente

• $model = $this->getModel();

self chiama un componente statico della stessa classe

• $identities = self::getGroupsByUser($userId);

• return self::$_buffer;

parent chiama metodo o campo di una classe padre

• parent::display();

DEBUGGING SEMPLICE

Visualizzare le variabili definite

• var_dump(get_defined_vars()); die;

Visualizzare lo stack trace

• var_dump(debug_backtrace()); die;

Page 109: 2/7/2013 - Welcome to Bugianens' Maccaja...personalpages.to.infn.it/~nebiolo/Documents/CorsoAvanzato2x.pdf · Il file index.html •

2/7/2013

109

TECNICHE COMUNI NEL CODICE DI JOOMLA!™

Connettivo logico || invece di if

• Statement A || statement B

• Esegue B solo se A restituisce false (lazy evaluation)

Concatenazione di metodi (method chaining)

• if (!JFactory::getUser()->authorise('core.admin'))

PHP "magic" methods

• __construct() e __call()

Espressioni regolari

• (bool) preg_match(<needle>, <haystack>);

• (string) preg_replace(<needle>, <subst>, <haystack>);

SCONTO HOSTING JOOMLA!™

Per i partecipanti al corso Joomlahost.it regala un coupon di sconto del valore di 20€ valido per l’acquisto di un cloud hosting Joomla! SMALL

Codice coupon : CORSOROMA3256

Visita www.joomlahost.it e acquista il tuo hosting completamente dedicato a Joomla!™