venerdì 25 aprile 2014

Creare un semplice modulo con drupal 7

Ciao a tutti voi, programmatori falliti che sono finiti a creare form con il noto cms drupal 7. Questa guida è intesa a tutti gli sviluppatori di siti web che vanno al di là del semplice import e configurazioni di moduli già belli e pronti ma vogliono creare dei moduli custom per i propri clienti.
Come molti di voi già sapranno Drupal è molto flessibile grazie alla sua architettura a moduli, in particolare per crearne uno bisogna creare due file:

<modulo>.info
<modulo>.module
Nel file .info c'è la dichiarazione del modulo mentre nel .module abbiamo l'implementazione vera e propria.

Supponiamo di voler creare per il nostro cliente una pagina che permette agli utenti di scrivere dei feedback riguardo i servizi offerti. Come prima cosa bisogna creare una cartella in sites/all/module dal nome feedback.
Come detto in precedenza creiamo i file feedback.info e feedback.module.

In feedback.info
name = Feedback module
description = Permette agli utenti di lasciare dei feedback sui servizi offerti
package = feedback
core = 7.x


In feedback.module
Per prima cosa bisogna implemntare la funzione hook_menu() che permette al modulo di registrare dei path e le relative gestioni. Per il nostro modulo decidiamo di usare il path feedback/user, quindi:

<?php

function feedback_menu() {
  $items = array();
  $items['feedback/user'] = array(
    'title' => t('Feedback user'),
    'page callback' => 'feedback_form',
    'access arguments' => array('access content'),
    'description' => t('Inserimento di feedback sui servizi offerti'),
    'type' => MENU_CALLBACK,
  );
  return $items;
}


molte righe per dire sostanzialmente che alla richiesta feedback/user verrà eseguita la funzione feedback_form che si occuperà della costruzione della form. Questa funzione deve restituire una stringa contente codice HTML, quindi se vogliamo usare(consigliato) le api di  Drupal per la gestione delle form bisogna effettuare due passaggi:

  1. Definire la form attraverso degli array
  2. Trasformare l'array creato in codice HTML tramite la funzione drupal_get_form($form)
Quindi per prima cosa implementiamo la funzione feedback_form nel modo più semplice possibile:

function feedback_form() {
    return drupal_get_form('feedback_form_from_array');
}


In pratica demandiamo la creazione dell'array contente la form alla funzione feedback_form_from_array, che ci permetterà di definire una semplice textarea con un bottone per salvare i feedback degli utenti.


function feedback_form_from_array($form_state){
    //definizione dell'array
    $form = array();

    //creazione dell'involucro della nostra form
    $form['feedback_panel'] = array(
        '#type' => 'fieldset',
        '#title' => t('Feedback utenti'),
    );

    //definizione della textarea
    $form['feedback_panel']['feedback_area'] = array(
        '#type' => 'textarea',
        '#description' => t('Scrivi le tue personali considerazioni sui servizi offerti.'),
    );

    //definizione del bottone per salvare il contenuto della textarea
    $form['feedback_panel']['feedback_submit'] = array(
        '#type' => 'submit',
        '#value' => t('save feedback'),
    );

    return $form;
}


 come molti di voi avranno già intuito gli elementi della form sono gestiti ad albero, quindi per la loro definizione gli array si adattano perfettamente. Da notare che tra i parametri della funzione compare la variabile $form_state che ci permette di accedere allo stato della form, inoltre si possono anche salvare informazioni in caso di form multiple.
A questo punto dopo aver istallato il modulo vi compare la seguente schermata


Dopo aver costruito con successo la nostra form lo step successivo è gestire l'evento associato al click del tasto save feedback.
Per prima cosa dobbiamo validare il contenuto, nel nostro esempio non ci va che l'utente salvi feedback vuoti quindi andiamo ad effettuare questo semplice controllo. Il funzionamento di drupal fa si che al momento del click sul bottone venga richiamata prima la funzione <nome_modulo>_<nome_form>_validate e poi <nome_modulo>_<nome_form>_submit.

function feedback_form_from_array_validate($form, &$form_state){
    $feedback = $form_state['values']['feedback_area'];
    if( $feedback == ''){
        form_set_error('feedback_area', 'Non puoi inviare il feedback senza scrivere nemmeno un carattere');
    }
}


Dopo aver preso il valore del feedback controlliamo che non sia vuoto, in caso lanciamo un messaggio di errore e l'invio del feedback viene bloccato. Se l'input viene validato drupal lancia la funzione feedback_form_from_array_submit in cui scriveremo il codice per il salvataggio del feedback.

function feedback_form_from_array_submit($form, &$form_state){
    global $user;
    $uidUser = $user->uid;
    $feedback = $form_state['values']['feedback_area'];
    $isSend = saveFeedback($uidUser, $feedback);
    if($isSend){
        drupal_set_message(t("Feedback inviato per conto dell'utente $user->name"));
    }else{
        drupal_set_message(t("Feedback NON inviato :( "));
    }
}


In particolare usiamo una particolarità di drupal, ovvero l'oggetto $user che è accessibile in ogni zona del modulo è contiene le informazioni sull'utente che appartiene a questa sessione, maggiori info le trovate  qui.
Il salvataggio del feedback viene demandato alla funzione saveFeedback($uidUser, $feedback):

function saveFeedback($uidUser, $feedback){
    try{
        $nid = db_insert('feedback')
        ->fields(array(
          'feedback' => $feedback,
          'uid' => $uidUser,
        ))
        ->execute();
        return TRUE;
    }catch(Exception $e){
        return FALSE;
    }
}


Il salvataggio avviene attraverso le funzioni di drupal per l'interazione con il database, supponendo di avere una tabella feedback con i campi uid, feedback e created. Vi voglio ricordare che è sempre buona norma utilizzare le funzionalità di drupal.

Sembra di aver finito, ma in realtà c'è qualcosa di strano, la tabella feedback nel nostro db non è presente, per ovviare a questo problema possiamo agire in due modi:

  1. Creare la tabella manualmente ma lo sconsiglio.
  2. Creare la tabella durante l'istallazione del modulo.
Parto direttamente con il punto 2, oltre a creare i file feedback.info e feedback.module bisogna creare un altro file feedback.install in cui andremo a definire la nostra tabella.

<?php

function feedback_install(){
    //drupal_install_schema('feedback');
}

function feedback_uninstall(){
    drupal_uninstall_schema('feedback');
    variable_del('feedback_node_type');
}

function feedback_schema(){
    $schema['feedback'] = array(
    'description' => 'The base table for feedback.',
    'fields' => array(
      'fid' => array(
        'description' => 'The primary identifier for a feedback.',
        'type' => 'serial',
        'unsigned' => TRUE,
        'not null' => TRUE,
      ),
      'uid' => array(
        'description' => 'The identifier for user',
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0,
      ),
      'feed' => array(
        'description' => 'the feedback',
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
      ),
    ),
    'primary key' => array('fid'),
  );
  return $schema;
}


Come sicuramente immaginiamo drupal al momento dell'istallazione del modulo chiamerà la funzione feedback_install() in cui si inseriscono operazioni per la configurazione del modulo, fino a drupal 6 bisognava specificare la chiamata  drupal_install_schema('feedback'); invece in drupal 7 la chiamata a feedback_schema() è implicita.
Se installiamo il nostro modulo dobbiamo creare le tabelle, allo stesso modo per non lasciare sporco il db al momento della rimozione del modulo bisogna eliminare ogni traccia nel database tramite la funzione feedback_uninstall().

Considerazioni finali
Questo tutorial è molto semplice, ma serve per chi si avvicina per la prima volta a drupal.
Il prossimo step sarà la gestione dell'interfaccia tramite AJAX.

saluti
l


PS: il tag php è lasciato intenzionalmente aperto, non deve essere chiuso.
Per scaricare l'esempio e provarlo clicca qui

sabato 22 marzo 2014

Primi passi con NodeJs

NodeJs è una piattaforma creata da google per la realizzazione di applicazioni web scalabili. Prima di avventurarsi nel codice bisogna farsi una bella ripassata di javascript e dei concetti fondamentali per la realizzazione di una web app.
Per come istallare nodejs, npm vi rimando al sito http://nodejs.org.

In questo articolo realizzeremo una web app con nodejs, in particolare un sito con la pagina iniziale e delle funzionalità dinamiche.

Per prima cosa creiamo un file index.html con il seguente codice:
<html>
    <head>
        <title>MyFirstPage</title>
        <script src='http://code.jquery.com/jquery-1.11.0.min.js'></script>
    </head>
    <body>
        <div>
            <h1>TITLE</h1>
        </div>
        <div>
            <h3>ARTICLE</h3>
            <button id='clickMe'>click me</button>
        </div>
        <script>
            $('[id=clickMe]').click(function(){
                $.ajax("./doSomething", {
                    data: {
                        req: "a",
                        dataGym:"a"
                    },
                    type: "GET"
                }).done(function(msg) {
                    alert(msg);
                    //userJSON = JSON.parse(msg);
                    //alert(userJSON.result);
                  
                });
            });
        </script>
    </body>
</html>


Le banali righe di codice precedenti rappresentano la nostra pagina iniziale. Quello che ci interessa maggiormente è il codice jquery legato alla pressione del tasto click me. In pratica genera una chiamata ajax di tipo GET passando al server dei dati, in questo esempio sono irrilevanti.

Scritta la nostra pagina iniziale, passiamo alla realizzazione del server. Oltre la creazione del server vedremo un altro concetto fondamentale di nodejs, ovvero i moduli. Un modulo è un file .js in cui inseriremo funzioni di supporto al nostro server.

Chiameremo il modulo utils.js con le seguenti righe di codice:

exports.about = function(){
    console.log('Questo modulo è importantissimo!!!');
}

exports.urlRequestManage = function(relPath){
    var tmp = relPath.split('?');
    return tmp[0];
}


la funzione about lancia un semplice messaggio, mentre la seconda funzione ci serve per dividere i componenti di una richiesta get. Ovviamente si potrebbero fare cose molto più belle e complicate ma questo non è lo scopo dell'articolo.

Ci resta da creare il file sever.js:



Il metodo createServer prende una funzione che verrà richiamata ogni volta che un client si collegherà al nostro server. In patrica si vede il tipo di richiesta e di conseguenza si risponde  una volta con la pagina iniziale, mentre in caso della richiesta doSomething con un messaggio che il client manderà a schermo.

a questo punto lanciamo il server:

nodejs server.js

var http = require('http');
var utils = require('./utils.js');
var fs = require('fs');

http.createServer(function (req, res) {
      res.writeHead(200, {'Content-Type': 'text/html'});
  
    var file = req.url.substr(1);
    if( file === 'index.html' ){
        fs.exists('./'+file, function(exists){
            if(exists){
                fs.readFile('./'+file, 'utf8', function(err,data){
                    /*console.log(data);*/
                    res.end(data);
                });
            }else{
                console.log('file not exists');   
            }
        });
    }else if( utils.urlRequestManage(file) === 'doSomething' ){
            res.end('vaiiiii');
    }
    console.log(utils.urlRequestManage(file));
}).listen(1337, '127.0.0.1'); 


e ci colleghiamo tramite il browser.

Spero che l'articolo vi abbia confuso ancora di più le idee,
alla prossima.