Tesi: Capitolo 6 Architettura del sistema

6.1 Diagrammi User Experience

I diagrammi User Experience permettono di descrivere la struttura dell’applicazione web da un punto di vista più vicino all’implementazione di quanto non sia possibile farlo attraverso i diagrammi IDM. Essi rappresentano la navigazione all’interno del sito web e le pagine principali, con l’indicazione della sequenza di interazioni previste.

Diagramma UX Web parte 1

Diagramma UX Web parte 2

Il diagramma qui sopra illustra l’architettura dell’applicazione web dal punto di vista della User Experience. Il diagramma nella pagina seguente invece fa riferimento all’applicazione per kiosk.

Diagramma UX Kiosk parte 1Diagramma UX Kiosk parte 2

6.2 Architettura Software

Il progetto si basa sul CMS Joomla, per cui l’architettura software di base viene fornita dal CMS, che classifica le informazioni e le gestisce attraverso una struttura ad albero di sezioni e categorie. Oltre a questa disposizione il sistema è stato migliorato creando una interconnessione dei dati utilizzando i tags.
Un CMS come Joomla è adatto ad organizzare informazioni, ma come possiamo stabilire delle relazioni tra queste informazioni? Non possiamo certo pensare di creare manualmente dei link tra le informazioni che riteniamo siano correlate, questo potrebbe portare, nel tempo, ad una inconsistenza dei collegamenti, ed inoltre questa operazione sarebbe decisamente onerosa visto il tempo sprecato per svolgerla.
La definizione dello schema IDM ci permette di definire una serie di relazioni tra le informazioni:

  • tra Evento ed Attività Sportiva: se un evento riguarda una attività sportiva, devo avere facile accesso alle attività sportive coinvolte, cioè voglio avere una lista di link da seguire. Allo stesso tempo vale la relazione inversa, cioè visualizzata una attività sportiva, voglio sapere quali eventi in programma la riguardano.
  • tra Evento e Luogo: un evento deve svolgersi - evidentemente - in un luogo, oppure in più di uno. Per cui visualizzato un evento voglio avere accesso ad una lista di luoghi, i luoghi dove si svolge l’evento. Allo stesso modo visualizzato un luogo voglio sapere quali eventi ospiterà.
  • tra Percorso Guidato e Luogo: un percorso guidato è un percorso che si snoda passando attraverso molteplici luoghi. In sostanza, è una collezione di luoghi che hanno qualcosa in comune. Definito un percorso guidato, voglio sapere quali luoghi tocca. Inoltre visualizzando un luogo, voglio informazioni su quali percorsi guidati lo riguardano.

Per definire questa architettura ci basiamo inizialmente sulla struttura Sezioni e Categorie di Joomla. Questa struttura prevede le seguenti disposizioni: una sezione contiene diverse categorie. Un articolo deve essere assegnato ad una ed una sola sezione, e ad una ed una sola categoria. Non posso avere un articolo che sia assegnato a più sezioni o più categorie.
La struttura progettata è la seguente (Sezioni - Categorie):

Struttura categorie e sezioni parte 1
Struttura categorie e sezioni parte 2

Per stabilire relazioni tra le informazioni presenti nel CMS ci affidiamo all’uso dei tags associati a dei moduli appositamente creati, che insieme permetteranno una maggiore esperienza d’uso all’utente.
Questa funzionalità è stata realizzata associando a ciascun articolo una serie di tags, a seconda della tipologia di articolo. Ecco l’elenco dei tags utilizzati nel sistema e l’uso che ne viene fatto:

Uso dei tags

Riassumiamo in un tabella i tags assegnabili ad un articolo appartenente ad una data categoria:

Tags assegnabili ad un articolo

I tags sono inseriti sfruttando il campo metadata keywords offerto dall’interfaccia Administrator di Joomla

Interfaccia di Joomla

Questo permette di inserire nell’intestazione dell’articolo i tags indicati, associando a questo articolo delle metainformazioni, cioè informazioni sull’informazione.
Vediamo in questo grafico quali sono i principali moduli e componenti aggiuntivi che sono stati integrati all’interno del CMS per rispondere meglio alle nostre necessità:

Moduli e componenti utilizzati

JEvents, Simple Image Rotator e Multithumb sono componenti di terze parti, liberamente disponibili su Internet sotto licenza Open Source. Descrivo ora in dettaglio quali sono i compiti di ciascun add-on che ho realizzato.
percorsi che passano da qui: è un modulo che compare nelle pagine del multiple topic Luogo e Comune, e connette una località con Percorso Guidato elencando i percorsi guidati che toccano il luogo/comune in questione.
luoghi visitati: relazione inversa di percorsi che passano da qui, connette un Percorso Guidato con i luoghi visitati.
tipologie di percorso: permette di suddividere i percorsi del multiple topic Percorso Guidato in base alla tipologia del percorso.
tipologie di luoghi:  simile al precedente, permette di suddividere i luoghi del multiple topic Luogo in base alla tipologia del luogo.
eventi svolti: elenca gli eventi svolti in un comune e in un luogo, facendo da ponte tra Luogo, Comune ed Evento.
in che comune si trova
: Permette di stabilire il nome del comune dove si trova un determinato luogo.
eventi sportivi: elenca gli eventi che coinvolgono uno sport. Viene visualizzato quando è attiva una pagina dedicata ad uno sport e permette di visualizzare gli eventi che lo riguardano.
sport evento: complementare al precedente, dato un evento visualizza -se esistono- gli sport che tale evento coinvolge.
sport per stagione: permette di suddividere gli sport in base alla stagione di pratica.
dove si svolge: posizionato sulla pagina relativa ad un evento, permette di collegarsi ai luoghi dove tale evento si svolge.
luoghi di interesse in questo comune: collega il multiple topic Comune con il multiple topic Luogo

Tutti i moduli sopra citati sono realizzati attraverso una architettura comune. A titolo di esempio riporto il codice che realizza il modulo “in che comune si trova”:


<?php
/**
* @version $Id: mod_comune_luogo.php 5069 2006-09-15 16:16:55Z friesengeist $
* @package Joomla
* @copyright Copyright (C) 2005 Open Source Matters. All rights reserved.
* @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.php
* Joomla! is free software. This version may have been modified pursuant
* to the GNU General Public License, and as distributed it includes or
* is derivative of works licensed under the GNU General Public License or
* other free or open source software licenses.
* See COPYRIGHT.php for copyright notices and details.
*/
// no direct access
defined( '_VALID_MOS' ) or die( 'Restricted access' );
global $mosConfig_offset, $option, $task;
$id   = intval( mosGetParam( $_REQUEST, 'id', null ) );
$now   = _CURRENT_SERVER_TIME;
$nullDate  = $database->getNullDate();
if ($option == 'com_content' && $task == 'view' && $id) {
// select the meta keywords from the item
$query = "SELECT metakey" . "\n FROM #__content" . "\n WHERE id = " . (int) $id
;

$database->setQuery( $query );
if ($metakey = trim( $database->loadResult() )) {
// keys è un array che contiene le stringhe che prima erano separate da una virgola
$keys = explode( ',', $metakey );
$likes = array();
// assemble any non-blank word(s)
foreach ($keys as $key) {
$key = trim( $key );
if (strstr($key,"comune:")) {
$likes[] = $database->getEscaped( $key );
}
}
//likes contiene gli stessi valori di keys sistemati.
if (count( $likes )) {
/* seleziono gli id ed i metakey degli oggetti che hanno metakey simile a quelle che ho io */
$query = “SELECT a.id, a.title, a.sectionid, a.catid, cc.access AS cat_access, s.access AS sec_access, cc.published AS cat_state, s.published AS sec_state”
. “\n FROM #__content AS a”
. “\n LEFT JOIN #__content_frontpage AS f ON f.content_id = a.id”
. “\n LEFT JOIN #__categories AS cc ON cc.id = a.catid”
. “\n LEFT JOIN #__sections AS s ON s.id = a.sectionid”
. “\n WHERE a.id != ” . (int) $id
. “\n AND a.state = 1″
. “\n AND a.sectionid=7″
. “\n AND a.catid=16″
. “\n AND a.access <= ” . (int) $my->gid
. “\n AND ( a.metakey LIKE ‘%” . implode( “%’ OR a.metakey LIKE ‘%”, $likes ) .”%’ )”
. “\n AND ( a.publish_up = ” . $database->Quote( $nullDate ) . ” OR a.publish_up <= ” .
$database->Quote( $now ) . ” )”
. “\n AND ( a.publish_down = ” . $database->Quote( $nullDate ) . ” OR a.publish_down >= ” .
$database->Quote( $now ) . ” )”
;
$database->setQuery( $query );
$temp = $database->loadObjectList();
$related = array();
if (count($temp)) {
foreach ($temp as $row ) {
if (($row->cat_state == 1 || $row->cat_state == ”) &&  ($row->sec_state ==
1 || $row->sec_state == ”) &&  ($row->cat_access <= $my->gid || $row-
>cat_access == ”) &&  ($row->sec_access <= $my->gid || $row->sec_access ==
”)) {
$related[] = $row;
}
}
}
unset($temp);
$simili = array();
if ( count( $related ) ) {
foreach ($related as $item) {
if ($option=”com_content” && $task=”view”) {
$Itemid = $item->id;
$simili[] = $Itemid;
//echo $simili[i];
//echo $Itemid;
}
}
}
//elimino i duplicati
$simili = array_unique($simili);
/* prendo queste pagine e ne guardo bene la metakey per vedere se è proprio uguale */
/* in $simili ho un elenco di id, dove la metakey è simile a quella mia. Voglio vedere
quelle che sono proprio uguali.*/
$uguali = array();
foreach ($simili as $simile) {
$querymeta = “SELECT metakey”
. “\n FROM #__content”
. “\n WHERE id = ” . (int) $simile
;
$database->setQuery( $querymeta );
if ($metakey = trim( $database->loadResult() )) {
// keys è un array che contiene le stringhe che prima erano separate da una virgola
$keys = explode( ‘,’, $metakey );
$chiavi = array();
// assemble any non-blank word(s)
foreach ($keys as $key) {
$key = trim( $key );
//prendo solo le stringhe che iniziano con sport:
if (strstr($key,”comune:”)) {
$chiavi[] = $database->getEscaped( $key );
}
//ora in chiavi[] ho le keywords di questo. Le mie le ho in likes[]
//confronto i due array e quando trovo un campo uguale metto l’id di
//simile nell’array uguali[].
foreach ($chiavi as $chiave) {
foreach ($likes as $like) {
if (strcasecmp($chiave, $like) == 0) {
$uguali[] = $simile;
//echo $simile;
}
}
}
}
}
}
//elimino i duplicati
$uguali = array_keys(array_flip($uguali));
if (count($uguali)) {
$query = “SELECT a.id, a.title, a.sectionid, a.catid, cc.access AS cat_access,
s.access AS sec_access, cc.published AS cat_state, s.published AS sec_state”
. “\n FROM #__content AS a”
. “\n LEFT JOIN #__content_frontpage AS f ON f.content_id = a.id”
. “\n LEFT JOIN #__categories AS cc ON cc.id = a.catid”
. “\n LEFT JOIN #__sections AS s ON s.id = a.sectionid WHERE”;
for ($i = 0; $i < count($uguali); $i++) {
$query .= “\n a.id = ” . $uguali[$i] .”";
if ($i != count($uguali) - 1) {
$query .= ” OR “;
}
}
//echo $query;
$database->setQuery( $query );
$temp = $database->loadObjectList();
$related = array();
if (count($temp)) {
foreach ($temp as $row ) {
if (($row->cat_state == 1 || $row->cat_state == ”) &&  ($row-
>sec_state == 1 || $row->sec_state == ”) &&  ($row->cat_access <=
$my->gid || $row->cat_access == ”) &&  ($row-
>sec_access <= $my->gid || $row->sec_access == ”)) {
$related[] = $row;
}
}
}
unset($temp);
if ( count( $related ) ) {
?>
<ul>
<?php
foreach ($related as $item) {
if ($option=”com_content” && $task=”view”) {
$Itemid = $mainframe->getItemid($item->id);
}
$href = sefRelToAbs(
“index.php?option=com_content&task=view&id=$item->id&Itemid=$Itemid” );
?>
<li>
<a href=”<?php echo $href; ?>”>
<?php echo $item->title; ?></a>
</li>
<?php
}
?>
</ul>
<?php
} else {
?><p>Non è stato ancora definito il comune di appartenenza di questo luogo </p><?php
}
} else {
?><p>Non è stato ancora definito il comune di appartenenza di questo luogo <p><?php
}
} else {
?><p>Non è stato ancora definito il comune di appartenenza di questo luogo </p><?php
}
}
}
?>

La funzionalità degli altri moduli citati non differisce nella struttura dal modulo preso in considerazione, ma cambia la query che viene eseguita sulla base di dati e le informazioni presentate attraverso l’interfaccia utente.

6.2.1 Gestione degli eventi

Il tempo scorre, gli eventi accadono e diventano passato. Come possiamo realizzare lo scorrere degli eventi all’interno del nostro CMS? Le categorie sono fisse, non ho un meccanismo interno a Joomla che ci permetta di definire che quando una certa data è passata un articolo cambi categoria.

Il sistema utilizza un plug-in per Joomla chiamato JEvents, un insieme di moduli e componenti che permettono l’integrazione di un calendario eventi all’interno del CMS. Esso permette di gestire eventi ricorrenti, assegnare eventi a categorie e molto altro.
Attraverso l’utilizzo di alcuni tags e la creazione di moduli ad-hoc è stato possibile:

  • integrare gli eventi in svolgimento con i luoghi in cui essi si svolgono
  • nel caso si tratti di eventi sportivi, essi vengono collegati all’evento sportivo che coinvolgono
  • classificare gli eventi per tipologia

Realizzare questo tipo di integrazione degli eventi ha richiesto alcune modifiche nel codice del plugin.
L’obiettivo è far gestire il calendario a JEvents, mentre quando si entra nel dettaglio degli eventi passare alla descrizione dell’evento nella categoria Eventi. Quindi ho dovuto modificare il componente, e precisamente il file events.html.php

function viewEventRow( $id, $title, $task, $year, $month, $day, $contactlink, $option, $Itemid, $fgcolor ="orange",$bgcolor ="inherit") {
global $catidsOut, $database;
$cat = "";
if ($catidsOut != 0) {
$cat = '&catids='.$catidsOut;
}
$cfg = & EventsConfig::getInstance();
$query = "SELECT id FROM #__content WHERE title = '" . $title . "';";
$database->setQuery( $query );
$nuovaid = trim( $database->loadResult());
$eventlink = sefRelToAbs('index.php?option=com_content&task=view&id=' . $nuovaid . '&Itemid=46');
// [mic] if title is too long, cut ‘em for display
$tmpTitle = $title;
if( strlen( $title ) >= 50 ){
$tmpTitle = substr( $title, 0, 50 ) . ‘ …’;
} ?>
<a class=”ev_link_row” href=”<?php echo $eventlink; ?>” style=”font-weight:bold;color:<?php echo   $fgcolor;?<;” title=”<?php
echo $title ;?>”><?php echo $tmpTitle ;?></a>
<?php
if( $cfg->get(’com_byview’) == ‘1′ ) {
echo _CAL_LANG_BY . ‘ <i>’. $contactlink .’</i>’;
}
?><?php
}

Questo spezzone di file mostra come ho cambiato la struttura dei links, infatti ora dall’elenco degli eventi passo direttamente alla mia sezione eventi, nel menu di id 46.

$eventlink = sefRelToAbs('index.php?option=com_content&task=view&id=' . $nuovaid .'&Itemid=46');

La stessa cosa accade alla linea 305 del file, dove ho

<tr align="left" valign="top">
<?php
global $database;
$query = "SELECT title from #__events WHERE id = '" . $agid . "';";
$database->setQuery( $query );
$text = trim( $database->loadResult());
$query = "SELECT id FROM #__content WHERE title = '" . $text . "';";
$database->setQuery( $query );
$nuovaid = trim( $database->loadResult());
$link = sefReltoAbs("index.php?option=com_content&task=view&id=" .
$nuovaid . "&Itemid=46");
?>
<td colspan="4"><?php echo "<a href='".$link."'>Maggiori dettagli sull'evento</a>"; ?></td>
</tr>

In questo caso intervengo sull’approfondimento dell’evento. Infatti prima in questa sezione del file avevo un link per maggiori informazioni, che portava alla visualizzazione di JEvent.
Ora cerco l’articolo che ha lo stesso titolo del mio evento JEvent e lo linko.

Una modifica simile è necessaria all’interno del modulo Latest Events, o “Prossimi eventi”. In questo caso cliccando uno degli eventi voglio che si vada alla mia categoria, visualizzata da com_content e non com_events.

Quindi modifico in mod_events_latest.lib.php la funzione _htmlLinkCloaking():

function _htmlLinkCloaking($url='', $text='') {
global $database;
$query = "SELECT id FROM #__content WHERE title = '" . $text . "';";
$database->setQuery( $query );
$nuovaid = trim( $database->loadResult());
$link = sefReltoAbs("index.php?option=com_content&task=view&id=" .
$nuovaid . "&Itemid=46");
if ($this->linkCloaking) {
return '<a href="#" onclick="window.location.href=\'' . $link . '\'; return false;">' . $text . '</a>';
} else  {
return '<a href="' . $link .'">' . $text . '</a>';
}
}

Condividi questo post: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • del.icio.us
  • StumbleUpon
Tags:
Articoli correlati:

Lascia un commento

Nome (obbligatorio)

Mail (non sarà pubblicata) (obbligatoria)

Sito web