Home Blog Pagina 13

Aggiungere la Classe active all'elemento li del menu attualmente attivo.

0

Quante volte ti sei chiesto come fare per aggiungere (usando Boostrap) in automatico la classe active al tag li corrispondente alla pagina che stiamo visitando?

Bene oggi voglio mostrarti uno snippet che potrebbe esserti molto utile.

// Creo una nuova macro tramite l’HTML Builder di Laravel
HTML::macro(‘liLinkROute’, function($name, $title = null, $parameters = array(), $attributes = array()){
// Imposto la variabile $active
$active = (URL::current() == URL::route($name, $parameters)) ? ‘ class=”active”‘:”;
// Ritorno l’HTML modificato
return ‘ <li'.$active.'>’ . HTML::linkRoute($name, $title, $parameters, $attributes) . ‘
</li'.$active.'>

‘;
});

Ti è servito? Ne hai uno migliore?

Dicci la tua!

Effettuare una Query in Laravel… in sei modi diversi!

0

Laravel ti permette di effettuare le query verso il database in tanti modi diversi.

Ho così preparato una lista, in modo tale da farti avere un riferimento più o meno completo di quelle che sono le possibilità.

Supponiamo, innanzitutto, di avere una tabella con i seguenti campi:

Users:

  • id;
  • name;

Posts:

  • id;
  • content;
  • user_id;

Nota: supponiamo anche di aver definito le relazioni nei model Eloquent.

Arriviamo quindi ai metodi. Ecco le varie possibilità:

/* Primo Metodo /
/
Semplicemente utilizzando Eloquent */
$user=User::find(1);
$posts=$user->posts;

/* Secondo Metodo /
/
Eloquent con Eager loading */
$posts=User::with(‘posts’)->find(1);

/* Terzo Metodo /
/
Eloquent con Lazy Eager loading */
$posts=User::find(1)->load(‘posts’);

/* Quarto Metodo /
/
Eloquent con Query Builder */
$posts=User::join(‘posts’,’users.id’,’=’,’posts.user_id’)->where(‘users.id’,1)->get();

/* Quinto Metodo /
/
Query Builder senza Eloquent */
$posts=DB::table(‘users’)->join(‘posts’,’users.id’,’=’,’posts.user_id’)->where(‘users.id’,1)->get();

/* Sesto Metodo /
/
SQL */
$posts=DB::select(‘select * from users join posts on users.id = posts.user_id where users.id = 1’);

Laravel Commander

0

Questa è una traduzione del package laracasts-commander.

Laravel Commander

Prima di procedere con la spiegazione di questo package. Guarda insieme a me questo semplice esempio:

fails())
{
return Redirect::back()->withInput()->withErrors($validator);
}

/**
* Creazione e salvataggio del nuovo utente registrato
*/
$user = new User(Input::all());
$user->save();

/**
* Invio email di notifica all’admin per una nuova iscrizione
*/
Mail::send(‘emails.welcome’, $user->toArray(), function($message) use($user)
{
$message->to(‘admin@example.com’, $user->username)->subject(‘Nuova registrazione!’);
});

/**
* Invio email di notifica al nuovo utente appena registrato
*/
Mail::send(‘emails.welcome’, $user->toArray(), function($message) use($user)
{
$message->to($user->email, $user->username)->subject(‘Benvenuto!’);
});

}

Abbiamo un controller che gestisce l’iscrizioni di nuovi utenti sul nostro sito.
Per prima cosa validiamo i dati inseriti. Se tutto è ok, procediamo al salvataggio.
Inoltre, decidiamo di inviare delle email con messaggi di benvenuto e/o di notifica, rispettivamente all’utente appena iscritto e all’admin.

Noti nulla di strano ? No ? Male! Scherzo.
Se stai realizzando una piccola applicazione questo esempio appena visto è del tutto lecito.
Ma prova ad immaginare se, a queste semplici operazioni, dovessi aggiungerne delle altre.
Cosa potrebbe succedere ? Le linee di codice aumenterebbero, così da renderti difficili futuri aggiornamenti.

Perchè non snellire il codice ? Lo so, l’estate è appena finita quindi non abbiamo più il problema della prova costume. Bando alle ciance.

Con questo package, basato sul pattern DTO (data transfer object, se non hai dimestichezza non ti preoccupare, ti sarà più chiaro a fine articolo) ti insegnerò un modo alternativo per rendere il tuo codice, molto più leggibile e facile da aggiornare. Cominciamo!

Installazione

L’installazione del package avviene tramite composer. Inserisci quindi questa linea all’interno del campo require del file composer.json. Ed infine esegui il comando composer update.

"require": {
"laracasts/commander": "~1.0"
}

Successivamente, aggiorna il file app.php all’interno di app/config ed includi la stringa seguente all’interno dell’array providers:

'providers' =&gt; [
'LaracastsCommanderCommanderServiceProvider'
]

Uso

Il consiglio più importante che posso darti, è di tenere in mente che questo tipo di approccio non è adatto a tutti. Ma cercherò di farti capire la sua importanza all’interno di un contesto come applicazioni su grande scala.
Se stai realizzando una semplice app che segue il pattern CRUD (create, read, update, delete) allora l’utilizzo di questo package probabilmente non ha senso.
Ma lo so che tu sei sempre affamato di conoscenza. Quindi ? Hai ancora voglia di continuare ? Bene, lo sapevo, welcome to the real, in questo caso, commands world. Cominciamo !

Lo scopo

Immagina di realizzare un’applicazione per la pubblicazione di annunci di lavoro.
Ora, ipotizziamo che dopo ogni pubblicazione di un nuovo annuncio, debbano essere eseguite una serie di operazioni. Invio di una mail ad ogni utente iscritto all’annuncio, notifica all’admin dell’avvenuto invio, o ancora invio di una mail di notifica all’impiegato o azienda che ha pubblicato l’annuncio.
Insomma il nostro limite è la nostra immaginazione.
Bene, ora a questo punto, la mole di operazioni da eseguire, tradotte in codice verranno messe all’interno del nostro caro controller…
Scherzo, ovviamente e qui che entrano in gioco i comandi, e ti assicuro che sarà davvero semplice organizzare e mantenere il codice pulito.

Il Controller

Per iniziare, devi iniettare la libreria CommandTrait nel tuo controller di base (BaseController), in maniera tale da non dover ogni volta includerla negli altri Controllers.
CommandTrait, non è nient’altro che un helper di funzionalità e metodi per la gestione del passaggio dei comandi al Command bus.
Vediamo subito un esempio:

execute(PostJobListingCommand::class);

return Redirect::to(‘/’);
}

Ah dimenticato questo package si base sull’ultima versione di PHP ( > 5.4), che introduce il comando “class”. Se dovessi avere problemi, puoi tranquillamente indicare il path della classe come una stringa.
Es.:

$this-&gt;execute('AppCommandsPostJobListingCommand')

La prima cosa che noterai, è la rappresentazione dell’istruzione da eseguire. Un nome di una classe che dà subito l’idea di cosa dovrà fare il comando.

Il comando DTO (Data Transfer Object).

Molto semplice vero ? Abbiamo un comando per rappresentare un istruzione, che viene poi gestita attraverso il command bus.
Ora vediamo come è fatta la classe comando:

title = $title;
$this->description = $description;
}

Quando viene eseguito il metodo execute della libreria CommandTrait, verrà eseguita una mappatura dei dati contenuti in Input::all().

Ora, cosa fa esattamente la classe CommandBus ?
Pensala come ad una sorta di semplice utility, che si comporta da “Traduttore” del comando.
Nell’esempio precedente la classe “PostJobListingCommand”, delegherà alla classe associata la pubblicazione di un nuovo annuncio di lavoro.

Di default, il command bus eseguirà una rapida sostituzione e ricerca, sul nome della classe del comando. In questo modo saprà quale gestore usare all’interno dell’IoC Container.
Ma vediamo anche qui un rapido esempio:

Prendi la classe vista poco fa “PostJobListingCommand”. Seguendo quando detto sopra avrai un gestore per la classe con la seguente denominazione “PostJobListingCommandHandler”.
Oppure se hai un comando per l’archiviazione degli annunci “ArchiveJobCommand” la sua controparte sarà “ArchiveJobCommandHandler”.

Tutto chiaro ? Bene. Tieni in mente però, che se preferisci una nomenclatura differente, si può facilmente sovrascrivere il processo di base. Lo vedrai più avanti nel corso dell’articolo. Non ti lascio per strada tranquillo !

Decorare il Command Bus

Ci possono essere volte in cui hai la necessità di “decorare” un comando. Cioè eseguire un qualche tipo di operazione. Ad esempio la codifica di dati (come la pulizia da tag html per avere una stringa “pulita”), prima di passare la gestione al commandBus.

NB: Innanzitutto per decorare, si intende una classe che aggiunge funzionalità ad un’altra classe. Senza modificare la struttura delle altre classi.

Eccoti un esempio.

Per prima cosa, dobbiamo creare una classe che implementa la classe CommandBus in questo modo:

job = $job;
}

La chiamata all’evento verrà eseguita dal metodo raise di “EventGenerator”, che non farà nient’altro che salvarlo all’interno di un array.

Listener di Eventi

Ora, la classe gestore dell’evento dovrà in qualche modo eseguire tutti gli eventi che verranno salvati. Questo significa che possono esserci un numero qualsiasi di gestori di tali eventi. Chiaro ?

Il nome dell’evento, segue ancora una volta, una semplice convenzione:

  • PercorsoPerEvetiEvento => Percorso.Per.Eventi.Evento

In questo modo il meccanismo di esecuzione degli eventi farà una sostituzione con i punti.
In questo modo se viene lanciata l’esecuzione dell’evento:

  • AppJobsEventsJobWasPublished

Avremo che l’evento in attesa di essere eseguito sarà:

  • App.Jobs.Events.JobWasPublished

Andiamo a registrare un listener di eventi base.
Per esempio, invio di email.
Vediamo subito un esempio:

Event::listen('App.Jobs.Events.JobWasPublished', function($event)
{
var_dump('invia un'email di notifica al creatore dell'annuncio di lavoro.');
});

NB: puoi registrare molteplici ascoltatori per lo stesso evento.
Ma allo stesso modo, puoi anche non aver bisogno di eseguire nessuna operazione correlata quando un lavoro viene pubblicato.

Aggiungiamo un’altro listener di eventi.
In questo esempio abbiamo usato una closure, ma se vuoi, puoi usare approccio più “catch-all”.

Riprendiamo l’esempio visto sopra riguardo l’invio di email.
Per prima cosa creiamo una classe “EmailNotifier” che andrà a gestire determinati eventi della nostra applicazione.

Event::listen('App.*', 'AppListenersEmailNotifier');

Il primo parametro del metodo listen della classe Event, vedila come una espressione regolare che intereccettare dove e quando eseguire determinati eventi.

Ogni volta che si eseguirà un evento che si trova all’interno del namespace App, una volta inviato, la classe EmailNotifier si preoccuperà della sua esecuzione finale. Naturalmente ci possono essere casi in cui non hai il bisogno di rispondere ad ogni evento !
Meglio fare i fatti che parlare vero ? Bene, quello che puoi fare è, essere più specifici sul percorso da seguire.

La classe JobWasPublished cerca un metodo whenJobWasPublished sul nostro listener di eventi.
Se esiste, viene eseguito. In caso contrario, passerà oltre.
Ciò significa che la nostra classe EmailNotifier potrebbe apparire in questo modo:

PostJobListingValidator

E’ sufficiente creare quella classe (PostJobListingValidator), e includere un metodo validate, che riceverà l’oggetto PostJobListingCommand.
In caso di convalida non riuscita, verrà lanciata dal sistema un eccezione – ValidationFailedException.
In questo modo, sia all’interno del controller o in global.php, è possibile gestire in modo appropriato la validazione fallita.

Sovrascrivere i percorsi

Come ti ho detto poco fa, questo package adotta alcune assunzioni riguardo la struttura dei file. Come dimostrato da questo esempio:

  • Percorso/Per/PostJobListingCommand => Percorso/Per/PostJobListingCommandHandler
  • Percorso/Per/PostJobListingCommand => Percorso/Per/PostJobListingValidator

E comunque non ti deve limitare affatto.
Supponiamo di voler creare un comando ad hoc, di traduzioni delle ‘classi gestori’ dei comandi.
Niente di più semplice. Basta creare una classe che estende l’interfaccia LaracastsCommanderCommandTranslator. Questa classe include due metodi:

  • toCommandHandler
  • toValidator

Bene, supponiamo ancora di voler salvare i nostri validatori all’interno di una directory Validators.
In questo modo avrai un organizzazione migliore dei file nella tua app root.
Vediamo come si trasforma il nostro traduttore:

first = $first;
$this->last = $last;
}

Bello vero ? Quindi mi raccomando tieni a mente dell’esistenza di questo comando artisan!

NB: Quando usi questo comando artisan, è consigliato usare lo slash per indicare il path. Se però dovessi usare il backslashes ricorda di metterlo tra doppi apici.

Due Punto Zero.

0

Dove eravamo rimasti?

Più o meno un anno fa, quando siamo partiti, qualcuno ci aveva fatto giustamente notare quanto fosse paradossale aver costruito il sito della Community Italiana di Laravel con WordPress. Dall’esterno, forse, avrei fatto la stessa obiezione anche io.

Non voglio ripetere quello che ho già scritto: si è trattato fondamentalmente di priorità e di tempo disponibile. L’idea era innanzitutto di partire scrivendo del materiale ed è quello che, nell’ultimo anno, abbiamo fatto. Per scrivere del materiale e pubblicarlo la via più breve è usare un CMS, e WordPress ha fatto il suo lavoro più che egregiamente, partendo da zero.

Non solo: una bella sfida è stata anche trovare le persone adatte ed organizzarsi al meglio con le risorse disponibili.

Anche su questo aspetto, comunque, non voglio annoiarvi troppo.

Se oggi sono qui a scrivere questo post, infatti, è perché sono felice di presentare la nuova versione di Laravel-Italia.it. Stavolta fatta interamente a mano, con Laravel. Senza CMS sottostanti o altro.

Dura e pura, creata ad-hoc per lo scopo.

Userò questo post per spiegarvi cosa c’è di nuovo e di come trarne vantaggio al meglio.

Che c’è di nuovo?

Innanzitutto, una nuova struttura grafica. Sicuramente la cosa che balza per prima agli occhi di chi naviga: responsive, più in linea con il tema “istituzionale” di Laravel, fatta a mano usando come base Bootstrap.

L’idea è quella di avere un menu con le cose più importanti sempre a disposizione, in modo tale da passare velocemente da una parte all’altra del sito senza problemi, con un click.

Sono state scelte le voci più significative in questo senso:

  • Nella prima colonna, “Laravel”, verranno inserite delle informazioni basilari sul Framework: la creazione della prima applicazione base ed il collegamento alla sezione “Documentazione” del sito;
  • Nella seconda colonna, “Materiali”, tutto quello che mettiamo a disposizione dell’utente: gli articoli, le serie di articoli ed una pagina di presentazione dei libri attualmente esistenti su Laravel;
  • Nella terza colonna, infine, le funzionalità relative alla community: il Forum ed il Canale IRC, oltre ad una pagina di presentazione del team;

Detto questo, passiamo alla Documentazione, che si presenta stavolta come una sezione a parte del sito. Non sarà più composta da un insieme di articoli in una pagina che funge come indice. La struttura della documentazione avrà una sua area a parte, con un menu laterale più comodo a sinistra di ogni pagina, per passare da un capitolo all’altro con più facilità.

Ovviamente, faremo il possibile per tenerla sempre in linea con l’ultima versione di Laravel. Il nostro prezioso collaboratore Francesco Lettera sarà delegato al compito, occupandosi solo di questo.

Se dovessimo scordarci qualcosa… segnalatecelo!

Un’altra componente fondamentale è l’utente: esatto, parlo esattamente di te. Tramite il link in alto a destra “Registrati” sarà possibile entrare a far parte al volo della community inserendo Nome, Cognome, Email e Password.

“Cosa potrò fare con il mio account?”

  • Commentare gli articoli del sito, partecipando attivamente alla discussione. Inizialmente i tuoi commenti verranno moderati da noi amministratori: vogliamo accertarci che effettivamente il tuo contributo porti del valore aggiunto, o si tratti di qualcosa che può essere utile agli altri, oltre che a te. Una volta approvati quindici commenti, in ogni caso, il tuo utente verrà riconosciuto come “Verificato” e non dovrai più passare per la moderazione.
  • Partecipare al forum, di cui parleremo a breve.
  • Partecipare ad altre iniziative a cui stiamo pensando o, in alcuni casi, già lavorando. La versione che vedi oggi di Laravel-Italia, infatti, è comunque un Work in Progress. Vogliamo implementare nuove funzionalità in futuro, anche basandoci sulla direzione che la community stessa prenderà!

Riprendendo il primo punto, qualche piccola modifica è stata fatta anche nel contesto degli Articoli. Rispetto al passato, infatti, il font scelto, le dimensioni e la line-height sono state rivisti per migliorare la leggibilità generale dei contenuti.

Gli articoli disposti in Serie, inoltre, sono stati organizzati diversamente: in corrispondenza di ogni serie sarà possibile disporre, a lato della pagina, di un menu con i vari “capitoli” di ogni serie, in modo tale da poter leggere tranquillamente una sequenza di articoli senza dover andare avanti ed indietro tra le varie pagine.

Saranno disponibili, inoltre, le pagine di raggruppamento di articoli in base alla Categoria oppure in base all’Autore.

Un’altra novità, probabilmente una delle più interessanti, è l’introduzione del Forum. Era un bel po’ che ce l’avevo in mente e questa è stata l’occasione perfetta per implementarlo. Per interagire sul forum basta creare l’account menzionato in precedenza, senza nessuna ulteriore “personalizzazione”. Il look del forum è volutamente semplice e dritto al punto, quasi minimalista.

Un forum composto da due macro-aree: la prima, generica, in cui presentarsi, parlare del più e del meno con l’aggiunta delle due sezioni “Progetti” e “Lavori”, in cui introdurre i propri progetti creati con Laravel oppure cercare lavoro.

Abbiamo creato anche un canale IRC, su freenode. Quando possibile ci faremo trovare lì 🙂

Per il momento è tutto. Ripeto, però, che queste di cui ho parlato non sono le uniche cose che abbiamo intenzione di implementare.

“Quindi, cosa ci sarà dopo?”

Nelle ultime due settimane ho buttato giù un bel po’ di idee e le sto valutando, una dopo l’altra, in base alle priorità e alle risorse di cui disponiamo.

Stiamo pensando ad un sistema diversificato di accesso e autenticazione, con il supporto di Facebook, Twitter e GitHub.

Poi ci sono le altre idee varie ed eventuali: la prima che mi è venuta in mente (già da un po’ di tempo) è la creazione di un gioco a quiz, capace di far divertire l’utente imparando. Si potrebbe quindi creare anche una “bacheca” dei punteggi e così via.

Un’altra idea è quella di creare un sistema di Smart Snippet. Snippet intelligenti, nel senso che chi li posta deve dare una spiegazione esauriente di quello che il codice riportato effettivamente fa: in caso contrario non verranno accettati.

In ogni caso sono solo due delle idee che abbiamo in mente: le altre le discuteremo presto con voi stessi sul Forum, nella sezione Community.

Concludendo…

… spero vi piaccia quello che abbiamo fatto e che stiamo facendo. Se vi siete appena registrati venite a salutarci sul Forum, nella sezione Presentazioni. Ci farebbe davvero piacere conoscervi un po’ tutti.

Un piccolo ringraziamento conclusivo va inoltre ad un paio di persone che non posso fare a meno di menzionare.

Innanzitutto Christopher Pecoraro, con il quale abbiamo parlato della prima idea di community italiana di Laravel più di un anno fa. E continuiamo a parlare, tra una proposta e l’altra, oltre a confronti sempre interessanti.

Federico Biccheddu, una delle prime persone che ho conosciuto a Roma appena mi sono trasferito, proprio quest’anno, proprio tramite l’idea di Laravel-Italia! Un amico come pochi se ne trovano, che spero di rivedere presto nonostante la lontananza.

Ringrazio quindi il team che ha portato avanti l’impresa in questi mesi, dandomi una mano: Marco, Francesco, Leonardo, Ionut e Luigi.

Un saluto anche alla new entry, Matteo de Prezzo.

Infine, ringrazio voi utenti che giorno dopo giorno crescete sempre di più.

Grazie di cuore e… code happy (and code bright)!

Francesco

Testing dei Model… like a boss! – Parte 2

0

Traduzione seconda parte dell’articolo “Testing Like a Boss in Laravel: Models” su Tuts+

La prima parte di questo articolo tradotto in italiano, invece, la trovate qui.

Il Model “Page”

Il nostro CMS ha bisogno di un model per rappresentare le pagine statiche. Ecco come implementarlo:

‘required’, // Page Title
‘slug’ => ‘required|alpha_dash’, // Slug (url)
‘content’ => ‘required’, // Content (markdown)
‘author_id’ => ‘required|numeric’, // Author id
);

/**
* Array used by FactoryMuff
*/
public static $factory = array(
‘title’ => ‘string’,
‘slug’ => ‘string’,
‘content’ => ‘text’,
‘author_id’ => ‘factory|User’, // Will be the id of an existent User.
);

/**
* Belongs to user
*/
public function author()
{
return $this->belongsTo( ‘User’, ‘author_id’ );
}

/**
* Renders the menu using cache
*
* @return string Html for page links.
*/
public static function renderMenu()
{
$pages = Cache::rememberForever(‘pages_for_menu’, function()
{
return Page::select(array(‘title’,’slug’))->get()->toArray();
});

$result = ”;

foreach( $pages as $page )
{
$result .= HTML::action( ‘PagesController@show’, $page[‘title’], [‘slug’=>$page[‘slug’]] ).’ | ‘;
}

return $result;
}

/**
* Forget cache when saved
*/
public function afterSave( $success )
{
if( $success )
Cache::forget(‘pages_for_menu’);
}

/**
* Forget cache when deleted
*/
public function delete()
{
parent::delete();
Cache::forget(‘pages_for_menu’);
}

}

Il metodo statico renderMenu() _renderizza un numero di link per tutte le pagine esistenti. Questo numero è salvato nella chiave cache ‘_pages_for_menu‘. In questo modo, quando ci saranno chiamate future al metodo _renderMenu() _non ci sarà bisogno di interrogare nuovamente il db.

Il risultato sarà un significativo miglioramento delle performance della nostra applicazione.

Ad ogni modo, se una Page _è salvata o cancellata (i metodi sono _afterSave() _e _delete() _), il valore della cache sarà ripulito, grazie al metodo _renderMenu() _che riflette il nuovo stato del db. Quindi, se cambia il nome della pagina, o se viene cancellata, la chiave _’pages_for_menu’ _sarà ripulita dalla cache (_Cache::forget(‘pages_for_menu’);).

Nota: il metodo afterSave() _è presente nel pacchetto Ardent. Altrimenti, sarebbe opportuno implementare il metodo _save() _per cancellare la cache e richiamarlo attraverso _parent::save()

Test del Model “Page”

All’interno di _app/tests/model/PageTest.php _scriveremo questi test:

assertEquals( $page->author_id, $page->author->id );
}

Ancora una volta, ci troviamo di fronte ad un test “opzionale” per confermare la relazione. Le relazioni di _Illuminate/Database/Eloquent _sono già testate da Laravel stesso: non abbiamo quindi bisogno di scrivere ulteriori test a proposito.

public function test_render_menu()
{
$pages = array();

for ($i=0; $i < 4; $i++) {
$pages[] = FactoryMuff::create(‘Page’);
}

$result = Page::renderMenu();

foreach ($pages as $page)
{
// Check if each page slug(url) is present in the menu rendered.
$this->assertGreaterThan(0, strpos($result, $page->slug));
}

// Check if cache has been written
$this->assertNotNull(Cache::get(‘pages_for_menu’));
}

Questo è il test più importante per il model. Prima di tutto abbiamo creato quattro pagine nel ciclo for. _A seguire la variabile _$result valorizzata dal metodo renderMenu(). Questa variabile dovrebbe contenere una stringa HTML, che a sua volta contiene i link alle pagine esistenti.

Il ciclo _foreach, _invece, controlla se lo slug (url) di ogni pagina è presente nella variabile _$result. _Questo è sufficiente, dal momento in cui l’esatto formato dell’HTML non è rilevante per il nostro test.

Infine, controlliamo se la chiave cache pages_for_menu ha immagazzinato qualcosa. In altre parole, renderMenu() ha fatto il suo dovere? Ha memorizzato qualche valore nella cache?

public function test_clear_cache_after_save()
{
// An test value is saved in cache
Cache::put(‘pages_for_menu’,’avalue’, 5);

// This should clean the value in cache
$page = FactoryMuff::create(‘Page’);

$this->assertNull(Cache::get(‘pages_for_menu’));
}

Qui invece l’obiettivo è verificare, quando salviamo una nuova Page, se viene svuotata la cache in corrispondenza di pages_for_menu. Il metodo FactoryMuff:create(‘Page’) innesca eventualmente il metodo save() e questa dovrebbe essere un’operazione sufficiente per svuotare la chiave ‘pages_for_menu’.

public function test_clear_cache_after_delete()
{
$page = FactoryMuff::create(‘Page’);

// An test value is saved in cache
Cache::put(‘pages_for_menu’,’value’, 5);

// This should clean the value in cache
$page->delete();

$this->assertNull(Cache::get(‘pages_for_menu’));
}

Simile al precedente test, vogliamo sapere se la ‘pages_for_menu’ viene svuotato correttamente dopo la cancellazione di Page.

Ecco il test:

assertEquals( $page->author_id, $page->author->id );
}

public function test_render_menu()
{
$pages = array();

for ($i=0; $i < 4; $i++) {
$pages[] = FactoryMuff::create(‘Page’);
}

$result = Page::renderMenu();

foreach ($pages as $page)
{
// Check if each page slug(url) is present in the menu rendered.
$this->assertGreaterThan(0, strpos($result, $page->slug));
}

// Check if cache has been written
$this->assertNotNull(Cache::get(‘pages_for_menu’));
}

public function test_clear_cache_after_save()
{
// An test value is saved in cache
Cache::put(‘pages_for_menu’,’avalue’, 5);

// This should clean the value in cache
$page = FactoryMuff::create(‘Page’);

$this->assertNull(Cache::get(‘pages_for_menu’));
}

public function test_clear_cache_after_delete()
{
$page = FactoryMuff::create(‘Page’);

// An test value is saved in cache
Cache::put(‘pages_for_menu’,’value’, 5);

// This should clean the value in cache
$page->delete();

$this->assertNull(Cache::get(‘pages_for_menu’));
}
}

Il Model “User”

In relazione con i model precedenti, adesso tocca al model User. Ecco il codice per questo model:

‘string’,
‘email’ => ‘email’,
‘password’ => ‘123123’,
‘password_confirmation’ => ‘123123’,
);

/**
* Has many pages
*/
public function pages()
{
return $this->hasMany( ‘Page’, ‘author_id’ );
}

/**
* Has many posts
*/
public function posts()
{
return $this->hasMany( ‘Post’, ‘author_id’ );
}

}

Questo model non ha test. Siamo salvi.

Possiamo osservare, infatti, che ad eccezione delle relazioni (utili per i test) non ci sono metodi da implementare in questo model. E l’autenticazione?

Vero, ma… l’uso del package Confide fornisce già i test per l’autenticazione.

I test per ZizacoConfideConfideUser li trovate in ConfideUserTest.php.
E’ importante determinare quali siano le responsabilità delle classi prima di scrivere i tuoi test. Testare l’opzione “reset della password” di un model User _è ridondante. Questo perché la responsabilità di questo test è già all’interno di _ZizacoConfideConfideUser, non dentro il model User.

Lo stesso vale per i test di validazione dei dati: è proprio Ardent che gestisce queste responsabilità, non avrebbe senso testare nuovamente questa funzionalità.

In breve: mantieni i tuoi test puliti e organizzati. Verifica la responsabilità di ogni classe, e testa solo ciò che è strettamente legato a quella responsabilità

Conclusioni

L’uso di un db in memoria è sicuramente una best practice per eseguire test rispetto ad un classico database.

Grazie all’aiuto di alcuni package come Ardent, FactoryMuff e Confide, puoi ridurre la quantità di codice nei tuoi model, e mantenere i test puliti e obiettivi.

Testing dei Model… like a boss! – Parte 1

0

Traduzione prima parte dell’articolo “Testing Like a Boss in Laravel: Models” su Tuts+

Se stai studiando il TDD e devi ancora capireperché fare testing èuna best practice, questo non è l’articolo che fa perte. Darò per scontato, infatti, che hai già capito quali sono i vantaggi di un buon testing e mi concentrerò su come scriverli in modo giusto e ben organizzato. Laravel 4 offre degli strumenti migliorati, rispetto alla versione precedente, per il testing delle nostre applicazioni.

Setup

Database in-memory

A meno che tu non eseguaquery dirette al database (raw query), sai che Laravel mantiene un approccio “agnostico” al database. Con un semplice cambiamento di driver puoi far lavorare la tua applicazione con diversi DBMS (MySQL, PostgreSQL, SQLite, e.c.c).

Tra questi, SQLite offre una particolare opzione molto utile: in-memory database.

Tramite questa feature saremo in grado, settando la connessione con l’opzione :memory:, di incrementare le prestazioni dei nostri test, datocheil database non saràpiù presente sul disco rigido ma, appunto, in memoria. Inoltre, il database di produzione/sviluppo non sarà mai popolato con i dati di test poiché la connessione :memory: sarà sempre inizializzata con database vuoto.

In breve: l’in-memory database permette un testing veloce e pulito.

All’interno della directory app/config/testing crea un nuovo file chiamato database.php e modificalo nel seguente modo:

// app/config/testing/database.php

‘sqlite’,

‘connections’ => array(
‘sqlite’ => array(
‘driver’ => ‘sqlite’,
‘database’ => ‘:memory:’,
‘prefix’ => ”
),
)
);

Come puoi notare, il file database.php è all’interno della cartella di configurazione di testing e ciò significa che sarà usato solo quando ci troveremo all’interno dell’ambiente di test (che Laravel imposta automaticamente). Per questo motivo, conun accesso “normale” all’applicazione non vieneutilizzato l’in-memory database.

Prima di eseguire un test

Come abbiamo detto, l’in-memory database è sempre vuoto ad ogni connessione. Per questo è importante eseguire una migration del database prima di ogni test.

Per farlo aggiungi il metodo _setUp()_alla fine della classe openapp/tests/TestCase.php.

/**
* Migrates the database and set the mailer to ‘pretend’.
* This will cause the tests to run quickly.
*
*/
private function prepareForTests()
{
Artisan::call(‘migrate’);
Mail::pretend(true);
}

NOTA: setUp() viene eseguito da PHPUnit prima di ogni test.
Cosa succede? Laclasse Mailer_viene “messa” nello stato di _pretend. In questo modo, durante itest, non vieneinviata nessuna mail. Vieneinvece scrittoun file di log con una riga di “sent” messages che indica che il messaggio è stato inviato.

Viene inoltre effettuata una chiamata a prepareForTests(). Non dimenticare inoltre cheparent::setUp(), è un overwriting del metodo della classe padre.

/**
* Default preparation for each test
*
*/
public function setUp()
{
parent::setUp(); // Don’t forget this!

$this->prepareForTests();
}

A questo punto app/tests/TestCase.php dovrebbe avere un codice simile al seguente. (Ricorda che createApplicationè creato automaticamente da Laravel, non dovrai quindi occupartene).

// app/tests/TestCase.php

prepareForTests();
}

/**
* Creates the application.
*
* @return SymfonyComponentHttpKernelHttpKernelInterface
*/
public function createApplication()
{
$unitTesting = true;

$testEnvironment = ‘testing’;

return require DIR.’/../../start.php’;
}

/**
* Migrates the database and set the mailer to ‘pretend’.
* This will cause the tests to run quickly.
*/
private function prepareForTests()
{
Artisan::call(‘migrate’);
Mail::pretend(true);
}
}

Ora, per scrivere i nostri test, estendiamo semplicemente la classe TestCase. Il database sarà inizializzato e migrato prima di ogni test.

I Test

In questo articolo non seguiremo l’approccio TDD (test driven development). Questo per motivididattici e con l’obiettivo di dimostrare come scrivere buoni test. Affronteremo quindi, prima i model e poi i relativi test.

Lo scenario che descriveremo sarà quello di un semplice blog/CMS, con autenticazione utente, post e pagine statiche (mostrate nel menu).

Il model “Post”

In questa fase è necessario notare il fatto che i model non estenderanno Eloquent ma Ardent. Ardent è un package che facilita le operazioni di validazione dei dati nel salvataggio dei model (vedi la proprietà $rulesproperty).

L’array $factory influenza l’azione del package FactoryMuff per la creazione degli oggetti durante il testing.

Puoi installare Ardentx e FactoryMuff trovandoli nella directoryPackagist o attraverso Composer.
Nel nostro model Post c’è una relazione con il model User: a legarli è il metodo magico author.

Infine, abbiamo un metodo che ritorna la data nel formato “giorno/mese/anno”.

// app/models/Post.php

‘required’, // Post tittle
‘slug’ => ‘required|alpha_dash’, // Post Url
‘content’ => ‘required’, // Post content (Markdown)
‘author_id’ => ‘required|numeric’, // Author id
);

/**
* Array used by FactoryMuff to create Test objects
*/
public static $factory = array(
‘title’ => ‘string’,
‘slug’ => ‘string’,
‘content’ => ‘text’,
‘author_id’ => ‘factory|User’, // Will be the id of an existent User.
);

/**
* Belongs to user
*/
public function author()
{
return $this->belongsTo( ‘User’, ‘author_id’ );
}

/**
* Get formatted post date
*
* @return string
*/
public function postedAt()
{
$date_obj = $this->created_at;

if (is_string($this->created_at))
$date_obj = DateTime::createFromFormat(‘Y-m-d H:i:s’, $date_obj);

return $date_obj->format(‘d/m/Y’);
}
}

Test del model “Post”

Per mantenere il nostro progetto ben organizzato, andiamo a sistemarela classe col model Post all’interno di app/tests/models/PostTest.php. Andiamo ad effettuare i nostri test, un passo alla volta.

// app/tests/models/PostTest.php

assertEquals( $post->author_id, $post->author->id );
}

In pratica stiamo testando la relazione “Post belongsTo User”: tuttavia, lo scopo è principalmente dimostrare il funzionamento di FactoryMuff.

Una volta che l’array $factory della classe Post contiene ‘author_id’ => ‘factory|User’ (come mostra il codice del model sopra) il FactoryMuff istanzierà un nuovo model User con i suoi attributi valorizzati, salverà nel database e ritornerà l’ id author_id nel Post.

Perché ciò sia possibile, il model User dovrà avere tutti i suoi attributi descritti nell’array $factory .

Fai attenzione a come accedi alle relazioni sul model User con $post->author. Ad esempio puoi accedere allo username con $post->author->username, e così per tutti gli altri attributi.

Il package FactoryMuff permette una rapida creazione di istanze di oggetti per il testing rispettando e istanziando le relazioni nececssarie. Nel nostro caso, quando creiamo un Post con FactoryMuff::create(‘Post’), il model User sarà subito disponibile.

public function test_posted_at()
{
// Instantiate, fill with values, save and return
$post = FactoryMuff::create(‘Post’);

// Regular expression that represents d/m/Y pattern
$expected = ‘/d{2}/d{2}/d{4}/’;

// True if preg_match finds the pattern
$matches = ( preg_match($expected, $post->postedAt()) ) ? true : false;

$this->assertTrue( $matches );
}
}

Infine, controlliamo che la stringa ritornata dal metodo postedAt() abbia il corretto formato “giorno/mese/anno”. Per questa verifica, usiamo un’espressione regolare che testa il pattern d{2}/d{2}/d{4} (“2 numeri” + “barra” + “2 numeri” + “barra” + “4 numeri”).

In alternativa possiamo usare il matcher assertRegExp di PHPUnit.

A questo punto, il listato del file app/tests/models/PostTest.php appare simile a:

// app/tests/models/PostTest.php

assertEquals( $post->author_id, $post->author->id );
}

public function test_posted_at()
{
// Instantiate, fill with values, save and return
$post = FactoryMuff::create(‘Post’);

// Regular expression that represents d/m/Y pattern
$expected = ‘/d{2}/d{2}/d{4}/’;

// True if preg_match finds the pattern
$matches = ( preg_match($expected, $post->postedAt()) ) ? true : false;

$this->assertTrue( $matches );
}
}

Nota: Non ho utilizzato il tipo di nomenclatura CamelCase per i metodi. Seppur in opposizione al PSR-1, metodi cometestRelationWithAuthor non mi sembravano leggibili. Sei comunque libero di usare lo stile che più ti piace.

Conclusione

Per ora è tutto: la prossima settimana, nella seconda parte, vedremo insieme come lavorare sul model “Page”.

Spedire email con Laravel 4 e Gmail

0

Traduzione dell’articolo “Sending Emails With Laravel 4 & Gmail” su Tuts+

Spedire email è un aspetto cruciale per qualsiasi applicazione. Di solito, un email è spedita per notificare all’utente che qualcosa è successo nel sito. Per esempio, un aggiornamento o la notifica di nuovi amici. In questo piccolo tutorial vedremo come spedire email con Gmail velocemente, attraverso una semplice applicazione scritta con Laravel. Tale applicazione estenderà un’altra già esistente (che puoi trovare qui).

Cominciamo!

Configurazione del file mail

Prima di spedire email con Laravel 4 è necessario configurare il file _app/config/mail.php. _In questo file imposteremo le seguenti opzioni:

**Opzione** Decrizione
`driver` Il driver per il mailing che vorresti usare. Di default è impostato su SMTP, ma puoi anche cambiarlo nel caso tu voglia usare PHP mail o Sendmail.
`host` Questo è il tuo host SMTP.
`port` La tua porta SMTP.
`from` Questo ti permette di impostare il campo “Da” (mittente) nella tua email, in modo tale che tutte le email saranno spedite dallo stesso indirizzo.
`encryption` Questo è il protocolo di crittografia che sarà usato per spedire le email.
`username` Questa è la tua username SMTP.
`password` Questa è la tua password SMTP.
`sendmail` Questo il percorso di localizzazione Sendmail sul server, quando usi un driver sendmail.
`pretend` Se impostato a _true, _le email saranno tracciate un file di log, piuttosto che inviate come messaggi reali.

Lavorare con Gmail

In questo tutorial useremo Gmail per spedire email. Di conseguenza, tutto quello di cui abbiamo bisogno è avere un account Gmail, con username e password. Editiamo il nostro file _app/config/mail.php _(ho rimosso i commenti per rendere il codice più compatto):

return array(

‘driver’ => ‘smtp’,

‘host’ => ‘smtp.gmail.com’,

‘port’ => 587,

‘from’ => array(‘address’ => ‘authapp@awesomeauthapp. com’, ‘name’ => ‘Awesome Laravel 4 Auth App’),

‘encryption’ => ‘tls’,

‘username’ => ‘your_gmail_username’,

‘password’ => ‘your_gmail_password’,

‘sendmail’ => ‘/usr/sbin/sendmail -bs’,

‘pretend’ => false,

);

Ho lasciato il driver impostato in SMTP.

L’host è impostato su smtp.gmail.com che rappresenta appunto il server SMTP di Gmail. La porta è la 587, il from è un’email fake utile per la nostra applicazione.

L’indice encryption impostato su tls ed infine le credenziali Gmail e l’indice pretend impostato su false .

Spedire email

In questa applicazione manderemo un’email di benvenuto all’utente appena registrato. Per spedire email con Laravel useremo il metodo Mail::send(). Ecco qui un piccolo snippet di esempio:

Mail::send(‘folder.view’, $data, function($message) {
$message->to(‘registered-user@gmail. com’, ‘Jon Doe’)->subject(‘Welcome to the Laravel 4 Auth App!’);
});

Il primo argomento è il file view che vogliamo usare per formattare la nostra email. Il secondo argomento è rappresentato da qualsiasi dato vogliamo trasferire alla view. Il terzo argomento è una closure che accetta come parametro un oggetto $message. Tramite tale oggetto possiamo specificare tutti i dati relativi ad oggetto, destinatari ed altri dati relativi al messaggio.

Piuttosto semplice vero?

Spedire il messaggio dopo la registrazione

Modifichiamo adesso il nostro metodo postCreate() di UsersController in modo tale da inviare la email di benvenuto ad ogni utente che si è appena registrato. Nel nostro metodo postCreate(), nel caso in cui la validazione dei dati dovesse andare a buon fine, inseriremo i nostri dati nel db per poi spedire la nostra email:

if ($validator->passes()) {
$user = new User;
$user->firstname = Input::get(‘firstname’);
$user->lastname = Input::get(‘lastname’);
$user->email = Input::get(‘email’);
$user->password = Hash::make(Input::get(‘password’));
$user->save();

Mail::send(‘users.mails.welcome’, array(‘firstname’=>Input::get(‘firstname’)), function($message){
$message->to(Input::get(‘email’), Input::get(‘firstname’).’ ‘.Input::get(‘lastname’))->subject(‘Welcome to the Laravel 4 Auth App!’);
});

return Redirect::to(‘users/login’)->with(‘message’, ‘Thanks for registering!’);
} else {
return Redirect::to(‘users/register’)->with(‘message’, ‘The following errors occurred’)->withErrors($validator)->withInput();
}

Al metodo Mail::send() daremo in pasto il file view users.mail.welcome. Il secondo argomento è rappresentato dai dati che saranno utilizzati nella view ed in questo caso sarà solo il nome. Poi creiamo la nostra closure per impostare l’email del destinatario. Possiamo anche impostare il nome usando i campi “nome” e “cognome” del form.

Infine, diamo alla closure un generico “oggetto” e il gioco è fatto.

La view del messaggio

Bene: adesso dobbiamo creare una view per l’email di benvenuto. All’interno di app/views/users creiamo una nuova cartella e chiamiamola mails. Al suo interno ci sarà un nuovo file chiamato welcome.blade.php con il seguente codice:

Hello {{ $firstname }}

We’d like to personally welcome you to the Laravel 4 Authentication Application. Thank you for registering!

In questo file view ci sarà un po’ di codice HTML e la variabile $firstname che abbiamo introdotto come dato dal nostro controller.

Non c’è nient’altro da fare.

Facciamo una prova!

Assicuriamoci che il nostro webserver sia attivo con _php artisan serve, _poi andiamo su _http://localhost:8000/users/register, _e creiamo un nuovo utente:

laravel-auth-create-user

…poi controlliamo l’email dell’utente per verificare che sia stata effettivamente spedita:

laravel-auth-emai-sent

Perfetto, la nostra email è stata spedita.

In conclusione

Chiaramente, possiamo personalizzare il messaggio dell’email per dare maggiore appeal all’applicazione. D’altronde quello che abbiamo visto è il modo più semplice per inviare email e, sicuramente, non è il metodo più efficace quando l’applicazione è complessa e l’invio delle email diventa più frequente. In questo caso possiamo utilizzare l’opzione queue per spedire le email in background, senza far attendere i nostri utenti. Questo argomento, però, verrà trattato in un ulteriore articolo.

Ulteriori informazioni su come spedire email con Laravel nella documentazione online.

Installare Laravel su un hosting condiviso

0

Se dopo aver costruito la tua app con Laravel hai l’esigenza di trasferirla su un hosting condiviso, le prossime righe potrebbero interessarti.

E’ frequente ormai l’uso di servizi di cloud hosting in cui coesistono diverse realtà: ad esempio potremmo ritrovarci a far “convivere” un’installazione di WordPress insieme ad una di Drupal e/o di altri CMS/Framework. Come puoi ben immaginare per ogni CMS/ Framework esiste un servizio più o meno ottimizzato nel quale far girare la nostra applicazione: un esempio, ma non l’unico, è Fortrabbit (o Forge) per Laravel.

Tralasciando questo aspetto più commerciale che tecnico, andiamo subito all’argomento: come installare un’applicazione fatta con Laravel all’interno di un hosting condiviso.

Darò per scontato che le caratteristiche di sistema di cui Laravel ha bisogno:
* Versione di PHP >= 5.4
* Estensione MCrypt di PHP

siano rispettate.

Vediamo ora su che tipo di scenario andremo ad operare: prenderò in considerazione una struttura comune che puoi ritrovare all’interno dei vari servizi di hosting. E’ chiaro che devi valutare tutto in maniera critica rapportando questo articolo alla tua situazione particolare.

Tipicamente puoi trovarti di fronte una struttura simile a questa:

config/
logs/
www/
sito1/
sito2/
sito3/

Secondo questa struttura, ogni cartella dentro /www conterrà un’applicazione.

Ognuna di queste viene detta “DocumentRoot” e, in genere, è la cartella a cui il dominio deve puntare per eseguire l’applicazione.

Un esempio per chiarire: quando digito sulla barra degli indirizzi www.sito1.it, il contenuto da eseguire verrà preso all’interno di /www/sito1 e così per gli altri. La DocumentRoot per Laravel è la cartella /public. Questo significa che il dominio deve far riferimento a /public per eseguire l’applicazione.

Nell’hosting condiviso, a volte, non possiamo impostare la cartella /public come DocumentRoot, ma ci troviamo di fronte ad una struttura predefinita (come quella che stiamo considerando) o poco malleabile.

Cosa fare in questi casi?

Ci sono tre possibili diversi approcci al problema. Vediamoli insieme.

Spostare il contenuto della cartella /public nella DocumentRoot

Supponiamo di voler installare la nostra applicazione fatta con Laravel all’interno di /www/sito1.

Considerando la struttura descritta sopra, crea una cartella chiamata /laravelsito1 all’interno della webroot e caricaci dentro tutte le cartelle e i files dell’applicazione: /vendor, /app, /bootstrap e i vari files.

Dovresti avere una situazione simile a questa:

config/
laravelsito1/
app/
bootstrap/
vendor/

logs/
www/
sito1/
sito2/
sito3/

Ora effettua l’upload del contenuto della cartella /public all’interno di /www/sito1.

Quello che otterrai sarà simile a:

config/
laravelsito1/
app/
bootstrap/
vendor/

logs/
www/
sito1/
packages/
.htaccess
index.php

A questo punto è d’obbligo fare un pò di configurazione.

Vai al file bootstrap/paths.php e alla riga:

‘public’ => DIR.’/../public’,

cambia il path in:

‘public’ => DIR.’/../../www/sito1′,

dopodiché apri il file www/sito1/index.php e modifica queste righe:

require DIR.’/../bootstrap/autoload.php’;
$app = require_once DIR.’/../bootstrap/start.php’;

con queste:

require DIR.’/../../laravelsito1/bootstrap/autoload.php’;
$app = require_once DIR.’/../../laravelsito1/bootstrap/start.php’;

Con questa ultima configurazione hai terminato.

Questo metodo è elegante e pulito ed è quello che ti incoraggio a seguire poiché mantiene fuori da potenziali attacchi l’applicazione.

Usare .htaccess con mod_rewrite

Un’altro approccio, più semplice ma meno raccomandato, è quello di dare delle direttive all’interno del file .htaccess. Vediamo come.

Carica l’intera applicazione all’interno della DocumentRoot: considerando il nostro scenario dovrai caricare tutte le cartelle e i files (compresa la cartella /public) all’interno di /www/sito1.

La struttura sarà simile alla seguente:

config/
logs/
www/
sito1/
app/
bootstrap/
public/
packages/
.htaccess
index.php

vendor/

sito2/
sito3/

Ora crea un file .htaccess all’interno di /www/sito1, aprilo con un editor di testo ed inserisci le seguenti righe:

RewriteEngine on
RewriteCond %{REQUEST_URI} !^public
RewriteRule ^(.*)$ public/$1 [L]

Potrai chiederti: cosa ho scritto? Semplice, non hai fatto altro che dirottare tutte le richieste del dominio www.sito1.it all’interno della cartella /www/sito1/public terminando così l’operazione.

Questo metodo è più veloce del precedente ma, senza entrare nello specifico, è sconsigliato per motivi di sicurezza: il core e la cartella pubblica si trovano allo stesso livello e questo può rendere l’applicazione vulnerabile ad attacchi esterni.

Eliminare la cartella /public spostando tutto nella DocumentRoot

Simile al precedente. Fai l’upload di tutto il progetto nella cartella /www/sito1, sposta il contenuto della cartella /public allo stesso livello di /app, /vendor /bootstrap e gli altri file ed elimina la cartella /public.

Dovresti avere una cosa simile a questa:

config/
logs/
www/
sito1/
app/
bootstrap/
public/
packages/
.htaccess
index.php

vendor/

sito2/
sito3/

Ora apri il file bootstrap/paths.php e
modifica questa riga

‘public’ => DIR.’/../public’,

così:

‘public’ => DIR.’/..’,

Infine apri l’index.php e modifica queste linee

require DIR.’/../bootstrap/autoload.php’;
$app = require_once DIR.’/../bootstrap/start.php’;

in questo modo

require DIR.’/bootstrap/autoload.php’;
$app = require_once DIR.’/bootstrap/start.php’;

E’ tutto! Te la sei cavata con poco, tutto sommato.

Analogalmente a quanto detto per il secondo metodo, anche questo mantiene il core dell’applicazione insieme ai file della cartella pubblica e quindi anche questo metodo, sepppur veloce da realizzare non è quello migliore.

Conclusioni

Come hai potuto vedere ci sono diversi modi di installare Laravel su un hosting condiviso.

Gli ultimi due, come già detto, sono più veloci e meno “invasivi” da realizzare ma quello raccomandato per motivi di sicurezza è il primo.

È tutto, alla prossima!

Hangout con Taylor Otwell: Il futuro di Laravel

0

Il 10 Aprile, in un Hangout, Taylor Otwell ed altri sviluppatori hanno discusso del futuro di Laravel.

Si è parlato di modifiche, di miglioramenti e di programmi. Un Hangout importante considerando il cambio di rotta degli ultimi mesi: Laravel ha conquistato un’ottima fetta di mercato e si è fatto sempre più avanti nel mondo dei framework PHP, con successo.

Questo di seguito è il video completo.

Per chi non avesse voglia di vederlo tutto riassumiamo velocemente i punti salienti in questo articolo.

Taylor ha parlato innanzitutto di nuove versioni: “Al momento non è in programma una release 5.0, l’architettura di Laravel attuale e la sua flessibilità permettono (a noi e agli sviluppatori) di scrivere facilmente pacchetti per qualsiasi cosa. A differenza del passato, inoltre, l’aggiornamento dalla versione 4.1 a 4.2 sarà indolore. Le tempistiche di rilascio rimangono quelle previste: ogni sei mesi uscirà una nuova versione. Laravel 4.2 sarà disponibile poco dopo il Laracon di Maggio e poi, seguendo il ritmo, la 4.3, 4.4 e così via. L’obiettivo è far diventare Laravel qualcosa di accessibile a tutti e trovare il perfetto equilibrio: non solo per principianti e al tempo stesso non solo per guru.”

Le prerogative per arrivare ad un ottimo prodotto ci sono tutte: dalla dependency injection senza neanche una riga di configurazione ai vari strumenti di Unit Testing, e così via. Un’ulteriore enfasi è stata posta sulla semplicità d’uso, uno dei punti chiave di Laravel. La complessità di un progetto (queste le parole di Taylor) deve chiaramente essere commisurata alla richiesta. Quello che serve per lavorare c’è già: routing, sessioni, controller, database.

“Vedo molte persone, su IRC, che stanno costruendo cose più complesse. Spero che non vadano verso una complessità eccessiva: non avrebbe molto senso. Personalmente preferisco giocare e sperimentare nuovi modi di costruire applicazioni di volta in volta.”

Un’altra domanda riguarda uno dei package più famosi, Generators, di cui abbiamo parlato ieri.

“Generators farà parte del core oppure rimarrà un package?”

Su questo Taylor esita: di base il suo focus è tutto sul core e grazie a Composer aggiungere un nuovo package richiede un tempo prossimo allo zero.

Una nota dolente sembra riguardare la documentazione: “non c’è nessuno ancora disponibile a scriverla in maniera esaustiva“.

Tra gli altri obiettivi importanti, poi c’è laravel.io, che secondo Shawn McCool dovrebbe diventare un vero e proprio hub di video e informazioni. Oltre un semplice forum, quindi.

Infine un paio di curiosità sulla vita di Taylor.

“Come gestisci la tua vita privata in relazione a Laravel?”

“Ogni mattina mi arrivano circa 200 email: è un po’ difficile gestire tutto. La società dove lavoro, comunque, mi da l’opportunità di lavorare su Laravel ogni venerdì. Riesco inoltre a lavorarci una o due ore al giorno, di sera, fino a mezzanotte. Mentre la mia famiglia dorme. Sabato e domenica sto con la mia famiglia e al massimo tocco il codice un altro po’ domenica notte.”

Generare Sitemap con Laravel

0

Traduzione dell’articolo Generate a sitemap using Laravel

Se stai sviluppando il tuo sito con Laravel probabilmente avrai l’esigenza di posizionarlo su Google e sugli altri motori di ricerca. Una sitemap contribuisce al posizionamento fornendo a Google una “mappa” delle URL per migliorare l’indicizzazione dei contenuti.

Nella sitemap non farai altro che elencare, in modo gerarchico, le URL del tuo sito: ad esempio se il tuo sito è multilingua, la sitemap dovrà contenere tutte le URL per ogni lingua.

Per approfondire il discorso ti consiglio di leggere le seguenti linee guida di Google:

Package

Per creare le tue sitemap ti presento un package molto interessante: laravel-sitemap.

Installazione

Per installare il package apri il file composer.json e aggiungi la seguente istruzione nell’array require:

"roumen/sitemap": "dev-master"

Ora dalla riga di comando lancia il seguente comando:

composer update

Aggiungi al service provider il package:

'RoumenSitemapSitemapServiceProvider',

Pubblica il file di configurazione con il seguente comando artisan. (OPZIONALE)

php artisan config:publish roumen/sitemap

Bene, l’installazione è completata. Ora vediamo come usare il package per generare sitemap.

Generare Sitemap Dinamiche

Una sitemap viene generata dinamicamente ad ogni chiamata dell’URL http://domain.com/sitemap. Ogni volta che viene chiamata questa URL, il package si occuperà di recuperare tutte le URL del sito e ritornare la sitemap in XML o in un altro formato supportato. Per una migliore ottimizzazione del sistema il package permette di effettuare un caching della sitemap per uno specifico periodo di tempo.

Per definire la sitemap dobbiamo indicare una route specifica /sitemap

File:

Directory:

Puoi aggiungere il seguente codice direttamente all’interno di routes.php o in un altro file per una migliore separazione del codice.

Route::get(‘sitemap’, function(){

// crea il nuovo oggetto
$sitemap = App::make(“sitemap”);

// imposta la cache (key (string), la durata è in minuti
$sitemap->setCache(‘laravel.sitemap’, 3600);

// gli elementi vanno in un nested array in questo formato
$translations= array(
array(
‘url’=>’http://domain.com/en/topic’,
‘language’=>’en’
),
array(
‘url’=>’http://domain.com/topic’,
‘language’=>’hr’
)
);

// assumiamo che di default il sito sia croato
$sitemap->add(
‘http://domain.com/topic’, // loc
‘2012-08-25T20:10:00+02:00’, // datetime modified
1.0, // priority from 0.0 to 1.0
‘daily’, // frequency
null, // title
null, // images array() (url|caption)
$translations // translations array() (url|language)
);

return $sitemap->render(‘xml’);
});

E’ tutto! Adatta il codice di sopra al tuo sito includendo tutte le URL e rispettando la stessa sintassi, e avrai la tua sitemap.

Su GitHub puoi trovare diversi esempi che potranno guidarti ulteriormente all’utilizzo del plugin.

Spero che questo articolo ti sia stato utile, ora puoi generare la sitemap per il tuo sito 🙂