CHI SONO

{
    "name": "Matteo Mangoni",
    "description": "PHP e Full Stack developer con oltre 11 anni di esperienza nel settore",
    "age": 31,
    "skills": [ "PHP", "Laravel", "Symfony", "Vue.js", "ReactJS", "React Native", "Node.JS" ],
    "company": {
        "name": "EWEBITE SEO & Digital Marketing",
        "url": "https://www.ewebite.it"
    }
}

Ai miei tempi... jQuery era il futuro

Ai miei tempi... WordPress era un astro nascente

Flexible Laravel

come rendere meno traumatica la gestione di un sistema legacy

Il progetto

 

Rinnovare un applicativo senza intaccare i suoi

servizi secondari e il funzionamento della web app esistente.

WEB APP

MOBILE

DESKTOP

Il risultato desiderato

 

WEB APP

MOBILE

DESKTOP

NUOVA WEB APP

Laravel come risorsa.

- Facile da utilizzare

- Ottima documentazione

- Estremamente potente

- Flessibile

Convention over configuration

Paradigma di software design utilizzato (da Laravel, ma anche da Ruby on Rails) per diminuire sensibilmente il numero di scelte delegate direttamente allo sviluppatore, a patto che quest'ultimo decida di sottostare a determinate regole e rispettare un certo numero di convenzioni.

Un esempio pratico...

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Category extends Model
{
    //
}

Questa singola classe, così com'è, rappresenta già di per sé un model completamente funzionante, il quale si interfaccia con il database presupponendo che esista una tabella chiamata "categories", ovvero il nome del model al plurale.

E la flessibilità?

L'utilizzo di tale paradigma non implica necessariamente l'impossibilità di avere un ambiente di sviluppo flessibile e altamente configurabile. Laravel, nello specifico, ci consente di farlo in maniera piuttosto semplice per tutti gli aspetti fondamentali della nostra applicazione.

Il punto di partenza

<?php

// ...

class CreateGroupsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('gruppi_macchine', function (Blueprint $table) {
            $table->increments('id');
            $table->string('nomegruppo');
            $table->timestamps();
        });
    }

    // ...
}
<?php

// ...

class CreateMachineriesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('macchine', function (Blueprint $table) {
            $table->increments('idmacchina');
            $table->unsignedInteger('id_gruppomacchine');
            $table->string('nome_macchina');
            $table->string('codicemacchina');
            $table->string('posizione_macchina');
            $table->timestamps();
        });
    }

    // ...
}

Quando è strettamente necessario, non abbiate paura di andare contro le convenzioni. Fate il possibile per rendere l’ambiente di sviluppo il migliore possibile per il vostro scopo.

Mappare le tabelle con dei model dedicati, creando relazioni volte a semplificare la gestione del contenuto.

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Group extends Model
{
    protected $table = 'gruppi_macchine';

    public function machineries()
    {
        return $this->hasMany('App\Machinery', 'id_gruppomacchine');
    }
}
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Machinery extends Model
{
    protected $table = 'macchine';

    protected $primaryKey = 'idmacchina';

    public function maintenance()
    {
        return $this->hasOne('App\MaintenanceSheet', 'macchina_id', 'idmacchina');
    }
}

Se i campi del database hanno nomi inconsistenti e poveri di rigore logico, provate a creare voi stessi una regola univoca e seguitela sempre.

Tentativo #1: creazione di accessor per rimappare i campi più problematici. Ottima soluzione a livello di tempi di progettazione, ma scartata immediatamente perché poco efficace, troppo verbosa e lunga da implementare in ogni singolo model.

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Machinery extends Model
{
    // ...

    protected $appends = ['name'];

    protected $visible = ['name'];

    /**
     * Get the machinery's name.
     *
     * @return string
     */
    public function getNameAttribute()
    {
        return $this->nome_macchina;
    }
}
// GET /machineries/1

{
    "name": "Macchina #1"
}

È importante isolare le astrazioni e non sovraccaricare di responsabilità i model.

!

Utilizzare le date come istanze di Carbon

{
    "id": 1,
    "macchina_id": 1,
    "id_cadenza": 1,
    "termine_manutenzione": "2018-12-20"
}
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class MaintenanceSheet extends Model
{
    protected $table = 'schedemanutenzione';

    protected $dates = ['termine_manutenzione'];

    protected $casts = ['termine_manutenzione' => 'date:d/m/Y'];

    protected $dateFormat = 'Y-m-d';
}
{
    "id": 1,
    "macchina_id": 1,
    "id_cadenza": 1,
    "termine_manutenzione": "20/12/2018"
}

Astrazione tramite API resources, un modo semplice e veloce per normalizzare i dati ricevuti in output dal database.

<?php

// ...

class MachineryResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        return [
            'id' => $this->idmacchina,
            'name' => $this->nome_macchina,
            'code' => $this->codicemacchina,
            'created_at' => $this->created_at->format('d/m/Y'),
            'updated_at' => $this->updated_at->format('d/m/Y')
        ];
    }
}

Un altro step fondamentale: scrivere test capillari sull'intero backend.

Importantissimo soprattutto in ottica di futuri sviluppi.

E poi siamo finalmente riusciti a sviluppare la nostra applicazione con Vue.JS senza problem... NO.

 

Proprio quando tutto sembrava andare nella direzione giusta, ci siamo trovati davanti un altro ostacolo: aggiungere nuove funzionalità, senza alterare il funzionamento delle applicazioni preesistenti.

Sviluppare un sistema che sospenda la manutenzione ricorrente senza intaccare il planner, che risiede ancora nella vecchia web app

?

Ogni tanto, per portare a casa il risultato bisogna essere creativi, giocare con i tool a nostra disposizione in maniera non convenzionale.

!

Il futuro

Cosa si può fare adesso per migliorare ulteriormente il prodotto finale?

Su cosa abbiamo dovuto sorvolare?

https://joind.in/talk/b91b5

matt.mangoni@gmail.com

LaravelDay 2018 - Flexible Laravel

By Matteo Mangoni

LaravelDay 2018 - Flexible Laravel

  • 908