IMPORTANT: Per accedir als fitxer de subversion: http://acacha.org/svn (sense password). Poc a poc s'aniran migrant els enllaços. Encara però funciona el subversion de la farga però no se sap fins quan... (usuari: prova i la paraula de pas 123456)

Contingut

Historia

De https://hashnode.com/ama/with-taylor-otwell-cilmj90zh000k6t53il0rdgqp

Before I created Laravel I worked for a large corporation writing .NET and COBOL. I use both .NET WinForms and ASP.NET MVC. I knew I wanted to eventually start my own business and hosting .NET wasn't very simple at the time. I knew PHP was simple to host and I wanted some of the features I had used in .NET MVC in a PHP framework, especially automatic dependency injection via Reflection.

My first PHP open source project was actually a reflection based IoC container I released for CodeIgniter in 2010. AFAIK, this was the first reflection based container in PHP. Then I wrote Laravel after being unable to cleanly extend CodeIgniter to support this kind of dependency injection.

Requeriments

IMPORTANT: Per veure les últimes notes de requeriments consulteu: https://laravel.com/docs/master/installation

IMPORTANT: Aquestes requeriments només són necessàries sinó penseu utilitzar Laravel Homestead. En la majoria de casos lo habitual és utilitzar Laravel Homestead i evidentment ja està el sistema al dia amb els requeriments

Laravel 5:

  • PHP >= 5.4 i les extensions php:
  • Composer instal·la la resta de dependències. Per exemple utilitza Symfony, guzzlehttp...
$ sudo apt-get install php7.0-mbstring php7.0-xml

o

$ sudo apt-get install php7.1-mbstring php7.1-xml

Instal·lació

https://laravel.com/docs/master/installation

Instal·lació en desenvolupament

Un cop instal·lat Composer teniu dos opcions per a crear nous projectes Laravel

Utilitzar l'instal·lador de projectes de Laravel [1]'

$ composer global require "laravel/installer"

I ara podeu crear un nou projecte Laravel amb:

$ laravel new app

Utilitzar composer create-project

$ composer create-project laravel/laravel quickstart --prefer-dist

llum

Podeu utilitzar el paquet acacha/llum per preparar més ràpidament per al desenvolupament les vostres aplicacions Laravel:

$ composer require acacha/llumn
$ laravel new app
$ cd app
$ llum boot

I s'executarà en un servidor http en local la vostra app. Llum us obre el vostra navegador per defecte amb l'aplicació i l'aplicació ja té una base de dades sqlite amb les migracions executades i eines de desenvolupament bàsiques instal·lades com Laravel Debugbar i laravel Ide Helper.

Recursos:

Màquina virtual Homestead

Vegeu Laravel Homestead

Instal·lació en explotació

Instal·lació amb LAMP

NOTA: Laravel amb Homestead està pensat per tal de funcionar amb LEMP és a dir utilitzar Nginx en comptes d'Apache. Podeu però seguint estes passes fer instal·lació amb LAMP si teniu la necessitat de fer-ho així

Requeriments:

Instal·lació de PHP. Podeu utilitzar l'stack LAMP (tot i que si aneu a utilitzar Apache potser no us cal instal·lar cap):

$ sudo tasksel install lamp

Extensions php:

$ sudo apt-get install php5-mcrypt php5-json

Ara instal·leu Laravel amb Composer:

$ composer global require "laravel/installer=~1.1"
Changed current directory to /home/sergi/.composer
./composer.json has been created
Loading composer repositories with package information 
Updating dependencies (including require-dev)
  - Installing symfony/console (v2.6.4)
    Loading from cache

  - Installing guzzlehttp/streams (2.1.0)
    Downloading: 100%         

  - Installing guzzlehttp/guzzle (4.2.3)
    Downloading: 100%         

  - Installing laravel/installer (v1.1.3)
    Downloading: 100%         

symfony/console suggests installing symfony/event-dispatcher ()
symfony/console suggests installing symfony/process ()
symfony/console suggests installing psr/log (For using the console logger)
Writing lock file
Generating autoload files

NOTA: Observeu la opció global! això instal·la globalment Laravel (observeu com se us instal·la al composer de la vostra home, a l'exemple /home/sergi/.composer)

Ja teniu instal·lat laravel a la carpeta:

$ ls -la ~/.composer/vendor/bin
total 8
drwxrwxr-x 2 sergi sergi 4096 feb 18 09:43 .
drwxrwxr-x 7 sergi sergi 4096 feb 18 09:43 ..
lrwxrwxrwx 1 sergi sergi   28 feb 18 09:43 laravel -> ../laravel/installer/laravel

Ara només cal afegir-lo al path. Editeu el fitxer ~/.bashrc

$ editor ~/.bashrc

I afegiu la línia:

export PATH=${PATH}:~/.composer/vendor/bin

Recarregeu la configuració de bash:

$ source ~/.bashrc

I ja podeu executar laravel:

$ laravel
Laravel Installer version 1.1
 
Usage:
[options] command [arguments]
 
Options:
 --help (-h)           Display this help message
 --quiet (-q)          Do not output any message
 --verbose (-v|vv|vvv) Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
 --version (-V)        Display this application version
 --ansi                Force ANSI output
 --no-ansi             Disable ANSI output
 --no-interaction (-n) Do not ask any interactive question
 
Available commands:
 help   Displays help for a command
 list   Lists commands
 new    Create a new Laravel application.

Instal·lació de la versió de development

$ composer create-project laravel/laravel laravel52 dev-develop
$ cd laravel52

Instal·lació de versions antigues

Opció 1:

$ composer create-project laravel/laravel laravel51test v5.1.11

Opció 2 Cal fer una instal·lació manual des del codi font:

$ cd 
$ git clone git@github.com:laravel/laravel.git

Ara podeu obtenir una copia:

$ cp -r laravel laravel51
$ cd laravel51
$ git tag | grep 5.1
v5.1.0
v5.1.1
v5.1.11
v5.1.3
v5.1.4
$ git checkout v5.1.11
$ composer install

Ara ja teniu una carpeta per fer de plantilla. Per crear un nour projecte:

$ mkdir -p ~/Code/Laravel51 && cd ~/Code/Laravel51
$ cp -r ~/laravel51 testlaravel51
$ cp .env.example .env
$ php artisan key:generate
$ php artisan clear-compiled
$ php artisan optimize

Amb Laravel installer (no funciona)

Vegem com podem instal·lar una versió antiga mantenint la versió actual

NOTA: Amb el laravel installer no sembla que funcioni!

$ cd
$ git clone git@github.com:laravel/installer.git laravelinstaller

$ cd laravelinstaller

$ git tag

Cal saber quin tag correspon a quina versió. Per exemple 1.2.2 correspon a l'última versió de Laravel 5.1

$ git checkout v1.2.2
$ composer install
$ sudo chmod +x laravel
$ cd
$ mkdir Code/Laravel51 && cd Code/Laravel51
$ ~/laravelinstaller/laravel new provalaravel51

Upgrade

Conèixer les versions que tenim de Laravel

El primer és saber la versió de l'instal·lador de Laravel amb:

$ laravel

o

$ laravel --version
Laravel Installer version 1.2.1

Recordeu que el instal·lador s'instal·la al sistema com a paquet composer i que el tindreu instal·lat a:

$ which laravel
/home/sergi/.composer/vendor/bin/laravel

I que teniu aquesta versió instal·lada segons lo indicat al fitxer:

$ cat ~/.composer/composer.json 
{
    "require": {
        "laravel/homestead": "~2.0",
        "laravel/installer": "^1.2",
        "phpunit/phpunit": "~4.0",
        "kherge/box": "^2.6"
    },
    "require-dev": {
        "apigen/apigen": "^4.1"
    }
}

Finalment també us pot ser d'utilitat:

$ composer global show laravel/homestead
$ $ composer global show laravel/laravel

URLs interessants

Al packagist podeu trobar els paquets i consultar la informació dels mateixos com per exemples la versió actual:

Instal·lador de Laravel: https://packagist.org/packages/laravel/installer
Homestead: https://packagist.org/packages/laravel/homestead

Compareu amb:

$ homestead --version
Laravel Homestead version 2.1.8
$ laravel --version
Laravel Installer version 1.3.1

Actualitzar

Per actualitzar el instal·lador executeu:

$ composer global update laravel/laravel

Però abans mireu si hi ha un canvi de versió important com de 2 a 3 per exemple comprovant el fitxer:

~/.composer/composer.json

I canviant la línia:

"laravel/homestead": "~2.0",

A si s'escau:

"laravel/homestead": "~3.0",

I torneu a executar:

 $ composer global update laravel/laravel

Un cop actualitzat el instal·lador al crear un nou projecte:

$ laravel new test
Crafting application...
...

Podreu observar que si cal es posarà a actualitzar nous paquets de composer abans de crear el projecte, és a dir l'instal·lador de Laravel s'encarrega de crear un Laravel de la última versió . Entre al projecte i comproveu tot està a la última versió:

 $ cd test
 $ cat composer.json 
{
    "name": "laravel/laravel",
    "description": "The Laravel Framework.",
    "keywords": ["framework", "laravel"],
    "license": "MIT",
    "type": "project",
    "require": {
        "php": ">=5.5.9",
        "laravel/framework": "5.2.*"
    },
    "require-dev": {
        "fzaninotto/faker": "~1.4",
        "mockery/mockery": "0.9.*",
        "phpunit/phpunit": "~4.0",
        "symfony/css-selector": "2.8.*|3.0.*",
        "symfony/dom-crawler": "2.8.*|3.0.*"
    },
    "autoload": {
        "classmap": [
            "database"
        ],
        "psr-4": {
            "App\\": "app/"
        }
    },
    "autoload-dev": {
        "classmap": [
            "tests/TestCase.php"
        ]
    },
    "scripts": {
        "post-root-package-install": [
            "php -r \"copy('.env.example', '.env');\""
        ],
        "post-create-project-cmd": [
            "php artisan key:generate"
        ],
        "post-install-cmd": [
            "php artisan clear-compiled",
            "php artisan optimize"
        ],
        "pre-update-cmd": [
            "php artisan clear-compiled"
        ],
        "post-update-cmd": [
            "php artisan optimize"
        ]
    },
    "config": {
        "preferred-install": "dist"
    }
}

Ara segurament estareu interessats en actualitzar Laravel Homestead. Consulteu l'apartat Actualització de Laravel Homestead

Més complicat és actualitzar el codi d'una aplicació ja existent. Llegiu:

https://laravel.com/docs/master/upgrade

Versions

Laravel 5.2

Torna el scaffolding de auth;

NOTA: La versió que proposa no m'agrada gaire (per exemple el layout té un link a Home que no porta a la home porta a la welcome page/landing page). A més no em queda clar en que quedarà la cosa ja que també està Laravel Spark que de moment no funciona del tot bé per Laravel 5.2 i també té un scaffolding per a auth però una mica més elaborat

$ php artisan make:auth
Created View: /home/sergi/Code/AdminLTE/acacha/laravelesborrar/resources/views/auth/login.blade.php
Created View: /home/sergi/Code/AdminLTE/acacha/laravelesborrar/resources/views/auth/register.blade.php
Created View: /home/sergi/Code/AdminLTE/acacha/laravelesborrar/resources/views/auth/passwords/email.blade.php
Created View: /home/sergi/Code/AdminLTE/acacha/laravelesborrar/resources/views/auth/passwords/reset.blade.php
Created View: /home/sergi/Code/AdminLTE/acacha/laravelesborrar/resources/views/auth/emails/password.blade.php
Created View: /home/sergi/Code/AdminLTE/acacha/laravelesborrar/resources/views/layouts/app.blade.php
Created View: /home/sergi/Code/AdminLTE/acacha/laravelesborrar/resources/views/home.blade.php
Created View: /home/sergi/Code/AdminLTE/acacha/laravelesborrar/resources/views/welcome.blade.php
Installed HomeController. 
Updated Routes File.
Authentication scaffolding generated successfully!

Es poden instal·lar només les vistes amb:

$ php artisan make:auth --views

Com podeu veure es creen una sèrie de vistes per a l'autenticació (login, registre, recuperació de paraula de pas, email recuperació paraula de pas, pàgina de welcome/landing page, home i els layouts) tots a la carpeta resources.

Després podeu veure com s'instal·la un controlador HomeController per a la pàgina home (pàgina principal un cop l'usuari s'ha logat a vegades l'anomenem dashboard també).

Al fitxer:

Illuminate\Auth\Console\MakeAuthCommand
https://github.com/laravel/framework/blob/5.2/src/Illuminate/Auth/Console/MakeAuthCommand.php

podeu veure el codi del que fa la comanda. Podeu observar com el nou fitxer HomeController és un Stub que podeu trobar a la carpeta Illuminate/Auth/Console/stubs/make/controllers/:

https://github.com/laravel/framework/blob/5.2/src/Illuminate/Auth/Console/stubs/make/controllers/HomeController.stub

Finalment s'afegeix al fitxer rutes l'stub:

https://github.com/laravel/framework/blob/5.2/src/Illuminate/Auth/Console/stubs/make/routes.stub

Com podeu veure hi ha un mètode auth a la facade Route. A Illuminate\Routing\Router podeu trobar la Facade i en concret el mètode auth publica les següents rutes:

/**
     * Register the typical authentication routes for an application.
     *
     * @return void
     */
    public function auth()
    {
        // Authentication Routes...
        $this->get('login', 'Auth\AuthController@showLoginForm');
        $this->post('login', 'Auth\AuthController@login');
        $this->get('logout', 'Auth\AuthController@logout');

        // Registration Routes...
        $this->get('register', 'Auth\AuthController@showRegistrationForm');
        $this->post('register', 'Auth\AuthController@register');

        // Password Reset Routes...
        $this->get('password/reset/{token?}', 'Auth\PasswordController@showResetForm');
        $this->post('password/email', 'Auth\PasswordController@sendResetLinkEmail');
        $this->post('password/reset', 'Auth\PasswordController@reset');
    }

Laravel homestead

Consulteu Laravel Homestead

Eines imprescindibles per al desenvolupament aplicacions Laravel

Vegeu i instal·leu: Laravel-ide-helper i també Laravel debug bar. També us pot interessar https://github.com/acacha/llum i https://github.com/acacha/admin-lte

Creació d'un projecte Laravel

Un cop instal·lat la comanda laravel (aka laravel installer) podeu crear un nou projecte Laravel amb:

$ laravel new NOM_DEL_PROJECTE

Per exemple:

$ mkdir ~/laravel_projects && cd ~/laravel_projects
$ laravel new blog

NOTA: Alternativament podeu utilitzar:

$ composer create-project laravel/laravel --prefer-dist

Fonaments de Laravel

Cicle de vida

https://laravel.com/docs/master/lifecycle
http://laravel-recipes.com/recipes/52/understanding-the-request-lifecycle

El Laravel Request Lifecycle fa referència a l'ordre en que s'executa el codi d'una aplicació Laravel cada cop que executem la nostra aplicació web Laravel (normalment mitjançant una petició HTTP o HTTP Request).

IMPORTANT: Observeu que, parlem sovint a mode d'exemple d'una petició HTTP però que aquesta no és sempre la única forma en que es pot executar una "aplicació web" Laravel. Per exemple, sovint també executem la nostra aplicació Laravel des de la línia de comandes utilitzant php artisan. Tot seguit veurem com de fet Laravel té en compte com a mínim dos cores/nuclis/kernels de l'aplicació el Kernel Console i el Kernel HTTP

Aleshores, el primer que cal distingir és quin tipus de petició estem atenent si una petició HTTP o una petició per línia de comandes o CLI (amb la comanda php artisan). Depenent de quin sigui el cas executarà el kernel Console o el kernel HTTP que trobareu explicats als següents apartats. La forma de distingir entre una petició o un altre és molt senzilla:

NOTA: Tant la nostra aplicació via web com la línia de comandes amb php artisan estan lligades al mateix codi, aquesta és la raó per la que us podeu torbar que la comanda php artisan no funcioni quan teniu algun error al vostre codi de l'aplicació Laravel. Heu de veure els dos kernels com part del mateix codi

.

Per tant els dos fitxers principals d'execució de Laravel són

Tots dos sistemes si observeu inicialment fan el mateix:

A partir d'aqui un executa el Kernel HTTP i l'altre el Kernel Console.

Gràfica

NOTA: És una gràfica antiga de Laravel 4 amb qüestions obsoletes com els workbenchs

bootstrap1.jpg

Kernel HTTP

Laravel segueix un paradigma prou habitual en la majoria de frameworks anomenat Front controller ([4]) on tot el codi de la nostra aplicació pel fitxer public/index.php. Recordeu que de fet els únics fitxers que s'exposen públicament i que són directament accessibles des del navegador mitjançant el protocol HTTP són els fitxers de la carpeta public. Per exposar aquest fitxer podem utilitzar qualsevol servidor web amb suport per PHP ja sigui Nginx/Apache o un servidor de desenvolupament local com el servidor per defecte de PHP.

NOTA: Observeu com al design pattern SPA també se segueix un patró en certa manera similar. També observeu que als frameworks Javascript associats al patró de disseny SPA com Angular, Ember,Vue router, etc apareix la necessitat de tenir un sistema de rutes. Vegeu també Web Routing

Que executa realment el fitxer index.php ([5])?:

NOTA: Tot i que és quelcom pot documentat és possible utilitzar molts dels components de Laravel de forma independent al framework Laravel és a dir fora de Laravel en qualsevol aplicació PHP. Vegeu Utilitzant Laravel fora de Laravel i ([6])

Per tant realment el codi amb xixa no es troba al fitxer index.php que realment és un simple script per arrancar la nostra aplicació continguda a l'objecte $app.

El fitxer principal del nucli HTTP el trobareu al fitxer app/Http/Kernel.php ([7]]) que possiblement coneixereu com el fitxer on es configura el Middleware a Laravel i per tant els middleware són específics dels Kernel HTTP.

On es troba la resta de codi? com podeu observar la classe Kernel.php del fitxer app/Http/Kernel.php és filla de la classe:

Illuminate\Foundation\Http\Kernel.php ([8])

En resum aquesta classe per a cada request executa una seria de bootstrappers que podeu veure a:

 protected $bootstrappers = [
        'Illuminate\Foundation\Bootstrap\DetectEnvironment',
        'Illuminate\Foundation\Bootstrap\LoadConfiguration',
        'Illuminate\Foundation\Bootstrap\ConfigureLogging',
        'Illuminate\Foundation\Bootstrap\HandleExceptions',
        'Illuminate\Foundation\Bootstrap\RegisterFacades',
        'Illuminate\Foundation\Bootstrap\RegisterProviders',
        'Illuminate\Foundation\Bootstrap\BootProviders',
    ];

I que bàsicament configuren la gestió dels errors, la detecció de l'entorn (Laravel Environment), el logging ( Laravel Logging, carregar les configuracions però sobretot observeu els tres últims:

'Illuminate\Foundation\Bootstrap\RegisterFacades',
'Illuminate\Foundation\Bootstrap\RegisterProviders',
'Illuminate\Foundation\Bootstrap\BootProviders',

..que són els encarregats de registrar les Facades i els Service Providers.

Observeu la senzillesa del mètode handle que processa una petició HTTP i retorna una resposta HTTP, és a dir del mètode:

/**
     * Handle an incoming HTTP request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function handle($request)
    {
        ...
        return $response;
    }

Simplement rep un objecte Request (HTTP Request) i retorna un objecte Response (HTTP Response). Podeu veure tot el kernel HTTP com una caixa negra que processa tota la nostra aplicació i que simplement s'alimenta de peticions HTPP i retorna respostes HTTP.

Service Providers

NOTA: Per a més detalls sobre els proveidors de servei a Laravel vegeu també Laravel Service Provider

Una de les tasques més importants les les accions de boostrapìng/arrancada que realitza el Kernel és carregar els service providers de la nostra aplicació. Tots els proveïdors de serveis es configuren al fitxer principal de configuració config/app.php al array providers vegeu:

https://github.com/laravel/laravel/blob/master/config/app.php

El que fa Laravel es primer executar tots els mètodes register dels service providers i després executar tots els mètodes boot de tots els service providers. Els proveïdors de serveis són els encarregats de carregar els diferents components propis del framework com bases de dades, cues, validacions, routing, etc.

IMPORTANT: Focus On Service Providers. En conclusió els desenvolupadors d'aplicacions Laravel només ens hem de centrar en els Laravel Service Providers és a dir tot l'explicat fins ara en aquest apartat ajuda a entendre els internals de Laravel però realment mai hauriem de tocar aquest codi i simplement afegim funcionalitat creant proveidors de servei

Per tant és molt important a Laravel comprendre la importància dels proveïdors de servei. Normalment els proveïdors de servei de la vostra aplicació els trobareu a la carpeta app/Providers. Com podeu observar a qualsevol projecte Laravel creat des de zero ja disposeu d'un quants proveïdors de servei per defecte a aquesta carpeta. Si observeu el proveïdor AppServiceProvider està buit i sol ser el lloc adequat per tal de realitzar les activitats de bootstraping pròpies de la vostra aplicació. També és possible però crear altres proveïdors de servei o utilitza proveïdors de serveis de paquets de tercers.

Dispatch Request

Un cop tots els proveidors de serveis i totes les Facades han estat registrades aleshores Laravel procesa la petició HTTP concreta que ha fet arrancar la nostra aplicació web. El component Router (carregat via el service provider RouteServiceProvider) és l'encarregat de mapejar una URL concreta cap al codi que processarà aquella petició (que pot ser un Closure, un mètode d'un controlador, etc. Vegeu Laravel Routing). Recordeu però que també tant prèviament com posteriorment la petició pot ser modificada pels Midlewares

Kernel Console

Estructura de fitxers. Arquitectura

https://laracasts.com/series/whats-new-in-laravel-5/episodes/1

La estructura de fitxers creada és la següent:

$ ls -la blog/
drwxrwxr-x 10 sergi sergi   4096 feb 18 10:01 app
-rw-rw-r--  1 sergi sergi   1635 feb 18 10:01 artisan
drwxrwxr-x  2 sergi sergi   4096 feb 18 10:01 bootstrap
-rw-rw-r--  1 sergi sergi    788 feb 18 10:01 composer.json
-rw-rw-r--  1 sergi sergi 100294 feb 18 10:01 composer.lock
drwxrwxr-x  2 sergi sergi   4096 feb 18 10:01 config
drwxrwxr-x  4 sergi sergi   4096 feb 18 10:01 database
-rw-rw-r--  1 sergi sergi    175 feb 18 10:01 .env.example
-rw-rw-r--  1 sergi sergi     61 feb 18 10:01 .gitattributes
-rw-rw-r--  1 sergi sergi     27 feb 18 10:01 .gitignore
-rw-rw-r--  1 sergi sergi    503 feb 18 10:01 gulpfile.js
-rw-rw-r--  1 sergi sergi     79 feb 18 10:01 package.json
-rw-rw-r--  1 sergi sergi     87 feb 18 10:01 phpspec.yml
-rw-rw-r--  1 sergi sergi    729 feb 18 10:01 phpunit.xml
drwxrwxr-x  3 sergi sergi   4096 feb 18 10:01 public
-rw-rw-r--  1 sergi sergi   1724 feb 18 10:01 readme.md
drwxrwxr-x  5 sergi sergi   4096 feb 18 10:01 resources
-rw-rw-r--  1 sergi sergi    561 feb 18 10:01 server.php
drwxrwxr-x  5 sergi sergi   4096 feb 18 10:01 storage
drwxrwxr-x  2 sergi sergi   4096 feb 18 10:01 tests
drwxrwxr-x 26 sergi sergi   4096 feb 18 10:01 vendor 

Com podeu veure el projecte ja porta suport per a:

  • /vendor: dependències del projecte (composer)
  • /node_modules:
  • .env: Els fitxers acabats amb la extensió .env soc carregats per laravel automàticament per tal de crear variables d'entorn. Estes variables d'entorn estan pensades per contenir dades sensibles com paraules de pas d'accés a bases de dades, tokens o altres... Vegeu el fitxer exemple .env.example
  • Github: fitxer readme.md on mostra la documentació de la pàgina principal del projecte a github

Altres carpetes i fitxers:

  • public: aquesta és la única carpeta que és publica a Internet (Servidor web). Conté el fitxers index.php encarregat d'executar Laravel. També conté assets o fitxers a publicar com css, javascript, favicon, robots.txt, imatges, etc.
  • app: Aquí està la lògica, el codi de l'aplicació. A la versió 5 hi han hagut canvis sent el principal que no hi ha carpeta model i s'aposta per una divisió més especifica amb múltiples carpetes que content el model. Hi podeu trobar les subcarpetes:
  • Http: aquí podeu trobar els controladors HTTP (carpeta Controllers) però també la configuració de routes (routes.php), MiddleWare, Filters i Requests.
  • Commands: conté les comandes de l'aplicació. Les comandes són tasques que s'han d'executar. Important no confondre amb console! De fet les comandes executen lògica de la nostra aplicació que es pot executar des de controladors HTTP (és a dir una comanda seria la part de lògica/model des d'una perspectiva MVC) però també des del CLI (utilitzant Console). Cal destacar que les tasques/jobs que realitzen les nostres comandes s'executen de forma síncrona o que es poden posar en una cua d'execució.
  • Console: Laravel defineix dos formes principals d'interactuar amb la nostra aplicació. La primera és utilitzant el protocol HTTP (vegeu carpeta Http) però també es possible definir comandes per comunicar-se via CLI utilitzant artisan
  • Events: els esdeveniments són tasques que cal executar de forma asíncrona al succeir un esdeveniment (event en anglès).
  • Handlers: tant les comandes (commands) com els esdeveniments (events) utilitzant Handlers per acabar executant la lògica en responsa a la comanda executada o esdeveniment succeït.
  • Exceptions: on guardar les excepcions PHP.
  • Providers:
  • Services:
  • User.php: model d'usuari per a autenticació i sessió.
  • tests: carpeta que conté els fitxers de test de l'aplicació. Utilitza PHPUNIT
  • phpunit.xml: configuració dels tests amb PHPUNIT
  • artisan: artisan és el CLI de laravel
  • config: Carpeta que conté les configuracions de l'aplicació
  • resources:
  • database: carpeta on es porta la gestió de la base de dades utilitzant l'eina migrations de Laravel
  • bootstrap: aquesta carpeta conté el fitxers que utilitza Laravel per arrancar(bootstrap en anglès) el propi Laravel i configurar el Autoload de PHP. Es utilitzat bàsicament pel fitxer index.php de la carpeta public.
  • storage: és una carpeta que serveix de espai temporal per a fitxers aquí es guardes les dades de les sessions, logs, cache, les plantilles de vistes compilades, etc. Aquesta carpeta ha de tenir permisos d'escriptura per al servidor web. També pot ser interessant ignorat aquesta carpeta o els fitxers que conté a git
  • gulpfile.js: Fitxer javascript de Gulp. Gulp és un build system també coneguts com a gestors de tasques (similar al que fan per altres llenguatges com Java Ant o Gradle) però en aquest cas està pensat per javascript. Les tasques més habituals són la gestió dels assets (fitxers CSS i Javascript) és a dir dur a terme tasques com la minificació de javascripts, buscar errors de sintaxi, etc. Consulteu Laravel Elixir que els nom que li han posat a l´us de Gulp dins de Laravel.
  • package.json: és el fitxer que defineix les dependències de node.js, similar a composer però per a a dependències nodejs. S'utilitza per instal·lar laravel Elixir que utilitza node.js.
  • phpspec.yml: fitxer de configuració de phpspec (http://www.phpspec.net/en/latest/)
  • server.php: permet emular mod_rewrite d'Apache sense Apache i és el fitxer que utilitza la comanda php artisan serve


Recursos:

Service Provider

Vegeu Laravel Service Provider

IoC Container

https://laravel.com/docs/master/container

NOTA: Abans de mirar d'entendre el IoC container es recomanable conèixer els conceptes Type-Hinting i autoload especialment autoload amb Composer que és el que utilitzar Laravel. També pot ser molt útil entendre els patrons de disseny SOLID especialment la D Dependency Inversion o DIP i el concepte de DI o Dependency Injection que sovint es confonen

El contenidor inversion of control de Laravel (aka Laravel Service Container o container) és una poderosa eina per gestionar class dependencies (les dependencies entre classes). Dependency injection és el mètode que permet eliminar del codi les dependències entre classes (remove hard-coded class dependencies) de forma que aquestes es poguin resoldre en temps d'execució de forma que sigui molt fàcil modificar les dependències i facilitar també els tests. De fet la injecció de dependències és la forma més prominent de Inversion of Control

El IoC Container aka Laravel Service Container gestiona les dependències utilitzant una tècnica anomenada Dependency Injection o DI que no és més que una forma de fer referència a la injecció de dependències en una classes a través del seu constructor o en alguns casos fins i ott a través dels mètodes (funcionalitat introduïda a Laravel 5).

Vegem un exemple bàsic de Injecció de dependències:

class JeepWrangler
{
    public function __construct(Petrol $fuel)
    {
        $this->fuel = $fuel;
    }
     
    public function refuel($litres)
    {
        return $litres * $this->fuel->getPrice();
    }
}
 
class Petrol
{
    public function getPrice()
    {
        return 130.7;
    }
}
 
$petrol = new Petrol;
$car = new JeepWrangler($petrol);
 
$cost = $car->refuel(60);

Com podeu veure la clsse JeepWrangler depèn de Petrol i gestionem aquesta dependència fent que per a construir la classe JeepWrangler s'hagui de proporcionar un objecte Petrol com a paràmetre del constructor de JeepWrangler. Com podeu veure, la injecció de dependències no és un concepte només de Laravel ni tan sols de PHP, de fet es pot aplicar en general a la programació orientada a objectes. Si us fixeu es tracta de no tenir "new"s dins de classes per tal d'evitar tenir que modificar les classes si canviem les dependències o el que es el mateix evitar que les nostres classes estiguin hard coupled (acoplades). El codi de les classes escrites d'aquesta forma no s'ha de modificar si volem modificar les dependències (nota: sobretot si en comptes de fer referència a objectes concrets fem referència a interficies o classes Abstractes com a dependències seguint el principi DIP). En temps d'execució al instanciar els objectes podem canviar/gestionar les dependències i facilitar el manteniment del codi així com els testos.

Que aporta Laravel doncs? Ens proporciona un objecte principal que és l'objecte App o variable $app que centralitzarà tant la creació d'objectes a partir de les seves classes (instanciar) com la gestió de les dependències a l'hora de crear objectes que depenen d'altres objectes.

El container és accessible des dels Service Providers amb:

$this->app

o també se sol utilitzar la Facade:

App::

Facade definida al fitxer config/app.php:

'aliases' => [

'App' => 'Illuminate\Support\Facades\App',

...

NOTA: També és accesible al fitxer routes o qualsevol altre fitxer inclòs pel fitxer principal index.php (vegeu Laravel Request Lifecycle directamentcom l'objecte $app)

Als següents apartat veurem exemples de com utilitzar el container...

NOTA: Vegeu també per a més info el Patró de disseny Inversion of Control (aka IoC) i (Laracasts video [9])). També els principis SOLID són un interessant prerequisit especialment el principi D: Dependency Inversion

Recursos:

Exemple

Vegem una típica classe Laravel (a l'exemple PurchasePodcast) que depènd d'un altre classe (Mailer) indicant que tenim una comanda que es comprar un podcast que necessita enviar un email cada cop que es compri un podcast:

<?php

namespace App\Jobs;

use App\User;
use Illuminate\Contracts\Mail\Mailer;
use Illuminate\Contracts\Bus\SelfHandling;

class PurchasePodcast implements SelfHandling
{
    /**
     * The mailer implementation.
     */
    protected $mailer;

    /**
     * Create a new instance.
     *
     * @param  Mailer  $mailer
     * @return void
     */
    public function __construct(Mailer $mailer)
    {
        $this->mailer = $mailer;
    }

    /**
     * Purchase a podcast.
     *
     * @return void
     */
    public function handle()
    {
        //
    }
}

Com resol aquesta dependència Laravel. Doncs bé la resposta és que depèn. I no depèn pas del tros de codi de l'exemple sinó de com estigui configurat el container de Laravel. De forma resumida:

  • Si el container de Laravel no sap res sobre la classe Mailer aleshores s'utilitza el sistema de Reflection de PHP i gràcies al Type-hinting busca la classe Mailer (més concretament la classe Illuminate\Contracts\Mail\Mailer ja que hem de tenir en compte el namespace) per crear una instància de la classe sense la nostra intervenció
  • Si el container sap com resoldre aquesta dependència i com construir l'objecte aleshores el container es l'encarregat de crear una instància de l'objecte. Cal tenir en compte que no hi ha magia sinó que es qüestió dels desenvolupadors configurar el container per tal de saber com crear les instàncies de les classes (també anomenats components de la nostra aplicació). Aquesta feina com hem vist en apartat anteriors es realitza als laravel Service Providers i més concretament als mètodes register dels proveïdors de servei Laravel. En els pròxims apartats veurem els detalls de com indicar al container com ha de carregar els components de la nostra app.

NOTA: Si sou observadors veureu que amb Laravel fora dels service providers que és el lloc on es configura el container de Laravel no trobareu gaires operadors new. Això no vol dir que no els pugueu utilitzar però no és una bona pràctica com hem vist a la explicació de injecció de dependències ja que provoca que les classes estiguin acoplades. Amb el ús d'un IoC container la definició de dependències i els detalls de com construim els objectes es mou a la fase de boostrapping és a dir durant la configuració de l'aplicació o més concretament dels Service Providers.

Recursos

Binding

https://laravel.com/api/master/Illuminate/Container/Container.html#method_bind

En aquesta apartat veurem que és un Service Container Binding. Els service container bindings es registren als proveïdors de serveis Laravel (vegeu Laravel Service Providers) concretament al mètode register. El que fem és indicar un String que normalment farà referència a una Interfície (molt sovint anomenats contracts a Laravel) o classe Abstracta i definirem com aquesta aquesta abstracció és converteix en un implementació concreta. Un exemple:

<?php

interface VehicleInterface {}
class Car implements VehicleInterface {}

App::bind('VehicleInterface', 'Car');

class SomeController {
    public __construct(BlahInterface $blah) {
        // $blah is an instance of ConcreteBlah
    }
}

Lo normal serà que tinguem espais de noms quelcom similar a:

<?php
namespace Acacha;

interface VehicleInterface {}
class Car implements VehicleInterface {}

App::bind('Acacha\VehicleInterface', 'Acacha\Car');

class SomeController {
    public __construct(BlahInterface $blah) {
        // $blah is an instance of ConcreteBlah
    }
}

A l'exemple vegeu tot el codi en un sol fitxer per facilitar la comprensió però l'habitual és tenir les clases VehicleInterface i Car als seus propis fitxers (els quals Laravel sabrà trobar via Autoloading i Composer) i tenir la línia amb el App:bind a un Service Provider:

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Acacha\VehicleInterface;
use Acacha\Car;

class VehicleServiceProvider extends ServiceProvider
{
    /**
     * Register bindings in the container.
     *
     * @return void
     */
    public function register()
    {
        $this->app->bind('VehicleInterface', 'Car');
    }
}

I el controlador a la seva propia classes dins la carpeta app/Http/Controllers. MOLT IMPORTANT, aleshores recordeu d'afegir el service provider al fitxer config/app.php al array providers.

IMPORTANT: No passa res si definim un binding referent a una classe concreta però NO ÉS NECESSARI. En aquesta cas Laravel pot directament resoldre l'objecte utilitzar PHP Reflection sempre i quan haguiu fet ús del Type Hinting durant la injecció de dependències. Sinó Laravel mostra la Excepció BindingResolutionException que és la excepció que utilitza Laravel per avisar-nos que no ha pogut resoldre un objecte. Per tant lo normal es definir bindings sobre interfícies és a dir indicar al container de Laravel quina implementació específica utilitzarem d'una interfície

Un altre possibilitat és utilitzar un Closure:

$this->app->bind('VehicleInterface', function ($app) {
    return new Car($app['Petrol']);
});
Singleton

També és un binding però volem que un cop instànciat l'objecte no es torni a instànciar més a és a dir sigui un singleton o objecte compartit.

$this->app->singleton('FooBar', function ($app) {
    return new FooBar($app['SomethingElse']);
});

De fet és equivalent a utilitzar le mètode bind amb el tercer paràmetre a true ([10]):

public function singleton($abstract, $concrete = null)
{
$this->bind($abstract, $concrete, true);
}

Vegeu també el design pattern Singleton

Canviant les instàncies en qualsevol moment

Podeu utilitzar:

 $fooBar = new FooBar(new SomethingElse);
 $this->app->instance('FooBar', $fooBar);

Això és molt útil per a realitzar testos i utilitzar Mocks en comptes de implementacions concretes de les dependències però també es pot utilitzar per canviar un bind per defecte d'un proveidor de serveis.

Resolving (make)

https://laravel.com/docs/master/container#resolving

En qualsevol moment podeu obtenir uns instància d'un objecte a partir del container utilitzant make, per exemple en proveïdors de servei:

$fooBar = $this->app->make('FooBar');

O en forma d'array:

$fooBar = $this->app['FooBar'];

Però també podeu utilitzar la Facade App:

$fooBar = App::make('FooBar');

I al fitxer routes també podeu utilitzar directament $app:

$fooBar = $>app->make('FooBar');

O en forma d'array:

$fooBar = $app['FooBar'];

Finalment però el més important, podeu utilitzar directament simplementt fent ús del Type-Hinting l'objecte a qualsevol controlador, midleware, events, vaja a qualsevol lloc de Laravel. El container de laravel resoldrà la dependència i la injectarà. Un exemple típic utilitzant el design pattern Repository Pattern:


<?php

namespace App\Http\Controllers;

use App\Users\Repository as UserRepository;

class UserController extends Controller
{
    /**
     * The user repository instance.
     */
    protected $users;

    /**
     * Create a new controller instance.
     *
     * @param  UserRepository  $users
     * @return void
     */
    public function __construct(UserRepository $users)
    {
        $this->users = $users;
    }
...

Aliases i Facades

Llegiu abans Laravel IoC Container i Laravel Request Lifecycle. Podeu trobar la informació sobre Facades a Laravel a l'article Laravel Facades

Injecció (mètodes i controladors). Dependency injection

La injecció de dependències o Dependency injection facilita el pas d'objectes a controladors i mètodes dels controladors utilitzant PHP Reflection de forma que no calgui instànciar els objectes i les seves dependències de forma manual en temps de compilació. Vegeu l'apartat Laravel IoC Container, el container de Laravel (objecte app) és el facilitador de la injecció de dependències.

Laravel suporta tant injecció de dependències al constructor com als mètodes (des de la versió 5). Vegem un exemple:

class FooBar {

    public function __construct(Baz $baz)
    {
        $this->baz = $baz;
    }

}

$fooBar = App::make('FooBar');

NOTA: Normalment no fem ús de la Facade App directament ni tampoc de l'objecte equivalent $app, sinó que com veureu a continuació s'utilitza directament la funcionalitat als constructors i mètodes dels controladors

Amb Laravel encara que no registrem específicament una classe al contenidor pot resoldre la classe automàticament injectant automàticament la classe Baz (el que es coneix com injecció de dependències). Això és així perquè amb el type-hinting que hem fet al posar Baz al paràmetre baz del constructor Laravel pot utilitzar PHP Reflection per inspeccionar la classe i crear un nou objecte automàticament.

A la pràctica el més sovint és fer aquest tipus de relació entre classes als controladors de la següent forma:


class OrderController extends BaseController {

    public function __construct(OrderRepository $orders)
    {
        $this->orders = $orders;
    }

    public function getIndex()
    {
        $all = $this->orders->all();

        return View::make('orders', compact('all'));
    }

}

En aquest cas la classe OrderRepository serà injectada automàticament al controlador. Això és ideal per a realitzar testos unitaris Unit testing ja que podem crear un mock OrderRepository al fer els tests unitaris del controlador. Video recomanat:

https://laracasts.com/series/whats-new-in-laravel-5/episodes/2

Recursos

Configuració

Variables d'entorn

Una de les primeres coses que s'han d'aprendre amb Laravel és el concepte de variable d'entorn. Les variables d'entorn es defineixen al fitxer .env. Aquest fitxer inicialment no existeix però ens proporcionen un fitxer d'exemple .env.sample.

Laravel utilitza la llibreria phpdotenv

https://github.com/vlucas/phpdotenv

Recursos:

Controladors

Tot i que Laravel permet posar el codi dels nostres controladors directament al fitxer routes.php utilitzant per exemple Closures el més habitual és organitzar el codi dels controladors en classes anomenades Controller classes. Els controladors agrupen peticions HTTP relacionades entre elles i la seva lògica en una mateixa classe.

Laravel per defecte guarda els controladors (a partir de la versió 5.0) a:

app/Http/Controllers

Resources

Rutes

routes.php

Una ruta té dos parts:

  • URI: o porció de la URL a la que fa referència la ruta
  • Closure o Laravel controller: és el mètode/funció o controlador encarregat de l'execució de la lògica

Per especificar les rutes de Laravel és fa al fitxer routes.php dins la carpeta app/Http i s'utiliza la Facade Route::. Vegem alguns exemples:

Route::get('/', function()
{
    return 'Hello World';
});
Other Basic Routes Route

Route::post('foo/bar', function()
{
    return 'Hello World';
});

Route::put('foo/bar', function()
{
    //
});

Route::delete('foo/bar', function()
{
    //
});

Com podeu veure cada mètode indica el tipus de petició HTTP (verb HTTP) és a dir si és un GET, un POST o altres valors com PUT o DELETE.

Es pot executar el mateix mètode per a múltiples verbs:

Route::match(['get', 'post'], '/', function()
{
    return 'Hello World';
});

o fins i tot per a qualsevol:

Route::any('foo', function()
{
    return 'Hello World';
});

Al codi podeu utilitzar el mètode url per obtenir la URL completa de qualsevol ruta amb:

$url = url('foo');

I podeu utilitzar Artisan per consultar les rutes instal·lades/configurades:

$ php artisan route:list

NOTA: L'anterior comanda en alguns casos depèn de la existència de la base de dades o altre factors de l'entorn i per aquesta raó a vegades només us funcionarà dins de la màquina virtual Homestead

Recursos:


Especificar paràmetres a les rutes

Vegem exemples, un sol paràmetre:

Route::get('user/{id}', function($id)
{
    return 'User '.$id;
});

Podem indicar que un paràmetre és opcional amb?:

Route::get('user/{name?}', function($name = null)
{
    return $name;
});

i especificar si cal un valor per defecte:

Route::get('user/{name?}', function($name = 'John')
{
    return $name;
});

I utilitzar expressions regulars:

Route::get('user/{name}', function($name)
{
    //
})
->where('name', '[A-Za-z]+');

Route::get('user/{id}', function($id)
{
    //
})
->where('id', '[0-9]+');

Named routes. Rutes amb controlladors

Es poden posar noms a les rutes amb as:

Route::get('user/profile', ['as' => 'profile', function()
{
    //
}]);
<pre>

Igual amb controladors:

<pre class="brush:php">
Route::get('user/profile', [
    'as' => 'profile', 'uses' => 'UserController@showProfile'
]);

Ara es pot fer referència a la ruta pel seu nom:

$url = route('profile');
$redirect = redirect()->route('profile');

I es pot obtenir el nom de la ruta actual amb:

$name = Route::currentRouteName();

Resources:

Controladors

Controladors i injecció de dependències

Els controladors a Laravel han de ser classes que heretin la Classe Controller que es troba a la carpeta app/Htpp/Controllers:

...
class UserController extends Controller {
...
}

Cal tenir en compte que és el Laravel service container qui resol els controladors i que per tant suporta injecció de dependències tant indicant les dependències al constructor:


<?php namespace App\Http\Controllers;

use Illuminate\Routing\Controller;
use App\Repositories\UserRepository;

class UserController extends Controller {

    /**
     * The user repository instance.
     */
    protected $users;

    /**
     * Create a new controller instance.
     *
     * @param  UserRepository  $users
     * @return void
     */
    public function __construct(UserRepository $users)
    {
        $this->users = $users;
    }

}

O com injecció als mètodes:


<?php namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Routing\Controller;

class UserController extends Controller {

    /**
     * Store a new user.
     *
     * @param  Request  $request
     * @return Response
     */
    public function store(Request $request)
    {
        $name = $request->input('name');

        //
    }

}

A l'exemple de fet podeu veure la forma típica de passar els paràmetres de Request d'un mètode passant directament la classe Illuminate\Http\Request.

NOTA: També es poden utilitzar Laravel contracts

Controladors bàsics

Exemple de controlador bàsic i configuració de fitxer de rutes:

<?php namespace App\Http\Controllers;

use App\Http\Controllers\Controller;

class UserController extends Controller {

    /**
     * Show the profile for the given user.
     *
     * @param  int  $id
     * @return Response
     */
    public function showProfile($id)
    {
        return view('user.profile', ['user' => User::findOrFail($id)]);
    }

}

Al fitxer routes.php:

 Route::get('user/{id}', 'UserController@showProfile');

Controladors implícits

Controladors de recursos RESTFul

Controler Middleware

Els Middleware es poden definir al fitxer de rutes directament:

Middleware may be specified on controller routes like so:

Route::get('profile', [
    'middleware' => 'auth',
    'uses' => 'UserController@showProfile'
]);

O a la classe controller al constructor:

class UserController extends Controller {

    /**
     * Instantiate a new UserController instance.
     */
    public function __construct()
    {
        $this->middleware('auth');

        $this->middleware('log', ['only' => ['fooAction', 'barAction']]);

        $this->middleware('subscribed', ['except' => ['fooAction', 'barAction']]);
    }
}

Hi ha uns quants Middleware predefinits a Laravel però en podeu també crear de propis. Middlewares per defecte estan a app/Http/Middleware:

  • Authenticate: Abans de mostrar un controlador es comprova que l'usuari estigui autenticat.
  • RedirectIfAuthenticate:
  • VerifiCsfrToken: per als tokens per a vitar atacs CSFR

i són registrats al fitxer app/Http/Kernel.php

<?php namespace LaravelNotificationApp\Http;

use Illuminate\Foundation\Http\Kernel as HttpKernel;

class Kernel extends HttpKernel {

	/**
	 * The application's global HTTP middleware stack.
	 *
	 * @var array
	 */
	protected $middleware = [
		'Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode',
		'Illuminate\Cookie\Middleware\EncryptCookies',
		'Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse',
		'Illuminate\Session\Middleware\StartSession',
		'Illuminate\View\Middleware\ShareErrorsFromSession',
		'LaravelNotificationApp\Http\Middleware\VerifyCsrfToken',
	];

	/**
	 * The application's route middleware.
	 *
	 * @var array
	 */
	protected $routeMiddleware = [
		'auth' => 'LaravelNotificationApp\Http\Middleware\Authenticate',
		'auth.basic' => 'Illuminate\Auth\Middleware\AuthenticateWithBasicAuth',
		'guest' => 'LaravelNotificationApp\Http\Middleware\RedirectIfAuthenticated',
	];

}

Cache

Es pot activar el cache per tal de gestionar les rutes molt més ràpid amb:

$ php artisan route:cache

Un cop executada aquesta comanda ja no s'utilitza el fitxer de rutes sinó una cache. Només podem fer això doncs si al fitxer routes.php tot són controladors i no hi ha closures directament al fitxer. Tingueu en compte que un cop activat el cache els canvis al fitxer routes.php no s'apliquen. Per desactivar la cache:

$ php artisan route:clear

La cache només se sol activar en explotació.

Simulació de mètodes no suportats pels navegadors ((Method Spoofing)

Els formularis HTML no suporten crides HTTP que no siguin GET o POST. S'utilitza la següent tècnica per simular els mètodes identificant-los amb un camp ocult:

<form action="/foo/bar" method="POST">
    <input type="hidden" name="_method" value="PUT">
    <input type="hidden" name="_token" value="<?php echo csrf_token(); ?>">
</form>

Aquesta tècnica és anomenada Method Spoofing. Observeu també l'ús de CSFR Tokens per a evitar atacs CSFR.

Forms & HTML

Simular peticions PUT, PATCH i DELETE

Es pot utilitzar el camp ocult _method i el sistema de routing de Laravel automàticament convertirà el formulari en una petició HTTP del tipus indicat a aquest camp:

<form ...>
<input type="hidden" name="_method" value="DELETE">
</form ...>

o utilitzar el laravel helper method_field():

<form ...>
{{ method_field('DELETE') }}
</form ...>

Cross Site Request Forgery (CSRF) a formularis

Vegeu l'article Cross Site Request Forgery#Laravel

Laravel 4.2

El suport per a la Facade Form ha estat eliminat del framework core de Laravel 5. Podeu trobar la documentació antiga (Laravel 4) a:

http://laravel.com/docs/4.2/html

Que s'hagui eliminat del framework no implica que ja no sigui una sol·lució vàlida i passa simplement a ser opcional. Per afegir el suport podem utilitzar un paquet composer:

"require": {
   "illuminate/html": "~5.0"
}

Vegeu Packagist: https://packagist.org/packages/illuminate/html

El projecte Laravelcollective

http://laravelcollective.com/

s'encarrega de mantenir (corregir errors, millorar, etc) antics parts del framework Laravel que ara ja no són al core. La documentació la podeu trobar a:

http://laravelcollective.com/docs/5.0/html

Per utilitzar aquest paquet amb composer:

"require": {
   "laravelcollective/html": "~5.0"
}

Vegeu el packagist https://packagist.org/packages/laravelcollective/html

Artisan

Laravel ofereix un script/comanda php anomenat artisan i que podeu trobar a l'arrel del vostre projecte:

$ php artisan

Us mostrarà les comandes que suporta.

NOTA: Un altre script PHP que utilitzar Symfony Console

Creació de controladors

S'utilitza la comanda

$ php artisan make:controller

Per exemple:

$ php artisan make:controller ResourceController

Per defecte es crea el típic controlador de recurs amb totes les operacions CRUD i les peticions REST equivalents:

també podeu crear un controlador buit amb:

$ php artisan make:controller MainController --plain

Consulta de rutes

S'utilitza la comanda route:list:

$ php artisan route:list


Cal tenir en compte que cal tenir configurada correctament la base de dades sinó pot donar l'error:

[PDOException]                                                                    
 SQLSTATE[42000] [1044] Access denied for user @'localhost' to database 'forge'

o similar.

Bases de dades. Migracions

Vegeu l'apartat sobre migracions a la Cheatseet Laravel: http://cheats.jesse-obrien.ca/

NOTA: Vegeu també l'article Laravel Database

La comanda principal per executar migracions és migrate:

$ php artisan migrate

Si teniu la base de dades configurada correctament o per exemple si heu configurat Homestead s'haurien d'executar les migracions que es troben a la carpeta:

$ ls -l database/migrations/
total 8
-rw-rw-r-- 1 sergi sergi 586 mar 16 12:29 2014_10_12_000000_create_users_table.php
-rw-rw-r-- 1 sergi sergi 543 mar 16 12:29 2014_10_12_100000_create_password_resets_table.php

és a dir es creen dos taules users i password_resets.

Si no teniu la base de dades configurada us dona l'error:

PDOException]                                                                               
SQLSTATE[28000] [1045] Access denied for user 'homestead'@'localhost' (using password: YES)  

Atenció si us dona l'error:

$ php artisan migrate
**************************************
*     Application In Production!     *
**************************************

Do you really wish to run this command? [y/N]

Això sol ser degut ha no haver executat les primeres comandes/accions que s'han d'executar al crear una nova app Laravel al inici:

http://laravel.com/docs/5.0/configuration

Basicament si creeu un fitxer .env a l'arrel (el podeu crear a partir del fitxer .env.example):

$ cat .env
APP_ENV=local
...

La variable d'entorn APP_ENV serveix per especificar l'entorn. Amb local ja no estareu a explotació

Si realment esteu a explotació i sabeu el que esteu fent es pot forçar una migració amb:

$ php artisan migrate --force

Per a crear fitxers PHP de migració:

$ php artisan make:migration create_users_table

NOTA: Es recomana posar un nom descriptiu encara que pugui semblar "llarg". Vegeu l'article STUPID

Els fitxers de migració es troben a la carpeta database/migrations, observeu que el sistema posa al nom del fitxer un timestamp cosa que permet que el framework sàpiga el ordre en que s'han d'executar les migracions.

Es poden utilitzar les opcions --table i --create:

$ php artisan make:migration add_votes_to_users_table --table=users

o

$ php artisan make:migration create_users_table --create=users

Mode manteniment. Artisan up/down

$ php artisan down 
$ php artisan up

Creació de comandes per artisan

Vegeu Artisan console

Scaffolding

php artisan fresh

IMPORTANT: Eliminat a la versió 5.1 el tema de l'scaffolding d'autenticació i tornat a afegir a la versió 5.2 amb la comanda make:auth però ja no hi ha una comanda com refresh per desmuntar el canvi

La comanda:

$ php artisan fresh
Scaffolding removed! Enjoy your fresh start.

Executada en un projecte Laravel 5 acabat d'instal·lar fa que tota la estructura bàsica (Scaffold) del projecte (Plantilles per defecte tema autorització, base de dades, etc ) s'esborrin per tal de tenir un projecte Laravel 5 from scratch (buit). Si teniu el projecte sota control de git podeu veure els fitxers eliminats:

$ git status
On branch master
Changes not staged for commit:
 (use "git add/rm <file>..." to update what will be committed)
 (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   .idea/workspace.xml
	deleted:    app/Http/Controllers/Auth/AuthController.php
	deleted:    app/Http/Controllers/Auth/PasswordController.php
	deleted:    app/Http/Controllers/HomeController.php
	modified:   app/Http/routes.php
	modified:   app/Providers/AppServiceProvider.php
	deleted:    app/Services/Registrar.php
	deleted:    public/css/app.css
	deleted:    public/fonts/glyphicons-halflings-regular.eot
	deleted:    public/fonts/glyphicons-halflings-regular.svg
	deleted:    public/fonts/glyphicons-halflings-regular.ttf
	deleted:    public/fonts/glyphicons-halflings-regular.woff
	deleted:    public/fonts/glyphicons-halflings-regular.woff2
	modified:   resources/assets/less/app.less
	deleted:    resources/assets/less/bootstrap/alerts.less
	deleted:    resources/assets/less/bootstrap/badges.less
	deleted:    resources/assets/less/bootstrap/bootstrap.less
	deleted:    resources/assets/less/bootstrap/breadcrumbs.less
	deleted:    resources/assets/less/bootstrap/button-groups.less
	deleted:    resources/assets/less/bootstrap/buttons.less
	deleted:    resources/assets/less/bootstrap/carousel.less
	deleted:    resources/assets/less/bootstrap/close.less
	deleted:    resources/assets/less/bootstrap/code.less
	deleted:    resources/assets/less/bootstrap/component-animations.less
	deleted:    resources/assets/less/bootstrap/dropdowns.less
	deleted:    resources/assets/less/bootstrap/forms.less
	deleted:    resources/assets/less/bootstrap/glyphicons.less
	deleted:    resources/assets/less/bootstrap/grid.less
	deleted:    resources/assets/less/bootstrap/input-groups.less
	deleted:    resources/assets/less/bootstrap/jumbotron.less
	deleted:    resources/assets/less/bootstrap/labels.less
	deleted:    resources/assets/less/bootstrap/list-group.less
	deleted:    resources/assets/less/bootstrap/media.less
 	deleted:    resources/assets/less/bootstrap/mixins.less
	deleted:    resources/assets/less/bootstrap/mixins/alerts.less
	deleted:    resources/assets/less/bootstrap/mixins/background-variant.less
	deleted:    resources/assets/less/bootstrap/mixins/border-radius.less
	deleted:    resources/assets/less/bootstrap/mixins/buttons.less
	deleted:    resources/assets/less/bootstrap/mixins/center-block.less
	deleted:    resources/assets/less/bootstrap/mixins/clearfix.less
	deleted:    resources/assets/less/bootstrap/mixins/forms.less
	deleted:    resources/assets/less/bootstrap/mixins/gradients.less
	deleted:    resources/assets/less/bootstrap/mixins/grid-framework.less
	deleted:    resources/assets/less/bootstrap/mixins/grid.less
	deleted:    resources/assets/less/bootstrap/mixins/hide-text.less
	deleted:    resources/assets/less/bootstrap/mixins/image.less
	deleted:    resources/assets/less/bootstrap/mixins/labels.less
	deleted:    resources/assets/less/bootstrap/mixins/list-group.less
	deleted:    resources/assets/less/bootstrap/mixins/nav-divider.less
	deleted:    resources/assets/less/bootstrap/mixins/nav-vertical-align.less
	deleted:    resources/assets/less/bootstrap/mixins/opacity.less
	deleted:    resources/assets/less/bootstrap/mixins/pagination.less
	deleted:    resources/assets/less/bootstrap/mixins/panels.less
	deleted:    resources/assets/less/bootstrap/mixins/progress-bar.less
	deleted:    resources/assets/less/bootstrap/mixins/reset-filter.less
	deleted:    resources/assets/less/bootstrap/mixins/resize.less
	deleted:    resources/assets/less/bootstrap/mixins/responsive-visibility.less
	deleted:    resources/assets/less/bootstrap/mixins/size.less
	deleted:    resources/assets/less/bootstrap/mixins/tab-focus.less
	deleted:    resources/assets/less/bootstrap/mixins/table-row.less
	deleted:    resources/assets/less/bootstrap/mixins/text-emphasis.less
	deleted:    resources/assets/less/bootstrap/mixins/text-overflow.less
	deleted:    resources/assets/less/bootstrap/mixins/vendor-prefixes.less
	deleted:    resources/assets/less/bootstrap/modals.less
	deleted:    resources/assets/less/bootstrap/navbar.less
	deleted:    resources/assets/less/bootstrap/navs.less
	deleted:    resources/assets/less/bootstrap/normalize.less
	deleted:    resources/assets/less/bootstrap/pager.less
	deleted:    resources/assets/less/bootstrap/pagination.less
	deleted:    resources/assets/less/bootstrap/panels.less
	deleted:    resources/assets/less/bootstrap/popovers.less
	deleted:    resources/assets/less/bootstrap/print.less
	deleted:    resources/assets/less/bootstrap/progress-bars.less
	deleted:    resources/assets/less/bootstrap/responsive-embed.less
	deleted:    resources/assets/less/bootstrap/responsive-utilities.less
	deleted:    resources/assets/less/bootstrap/scaffolding.less
	deleted:    resources/assets/less/bootstrap/tables.less
	deleted:    resources/assets/less/bootstrap/theme.less
	deleted:    resources/assets/less/bootstrap/thumbnails.less
	deleted:    resources/assets/less/bootstrap/tooltip.less
	deleted:    resources/assets/less/bootstrap/type.less
	deleted:    resources/assets/less/bootstrap/utilities.less
	deleted:    resources/assets/less/bootstrap/variables.less
	deleted:    resources/assets/less/bootstrap/wells.less
	deleted:    resources/views/app.blade.php
	deleted:    resources/views/auth/login.blade.php
	deleted:    resources/views/auth/password.blade.php
	deleted:    resources/views/auth/register.blade.php
	deleted:    resources/views/auth/reset.blade.php
	deleted:    resources/views/emails/password.blade.php
	deleted:    resources/views/home.blade.php

I també podeu desfer el canvi amb:

$ git reset --hard

Laravel Database

Vegeu Laravel Database i Eloquent

Sistema de plantilles Blade

Vegeu Blade

Laravel email

Vegeu Laravel email

Laravel Elixir

Vegeu Laravel Elixir

Apache

Primer de tot cal tenir en compte si cridareu a una URL utilitzant un Virtual Host ja siqui:

http://lamevaappplaravel.com/

O subdomini

http://applaravel.elmeudomini.com

o amb un Alias:

http://elmeudimini.com/laravelapp

En el cas de l'Alias cal fer un canvi al codi de Laravel, editeu el fitxer public/.htaccess i afegiu RewriteBase:

<IfModule mod_rewrite.c>
    <IfModule mod_negotiation.c>
        Options -MultiViews
    </IfModule>

    RewriteEngine On
    RewriteBase /laraveltest/

    # Redirect Trailing Slashes...
    RewriteRule ^(.*)/$ /$1 [L,R=301]

    # Handle Front Controller...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
</IfModule>

Ara cal instal·lar i activar el mòdul rewrite:

$ sudo a2enmod rewrite
$ sudo service apache2 reload

I ara cal crear una configuració del site:

IMPORTANT:

Apache 2.2:

$ cat /etc/apache2/conf.d/laraveltest.conf 
Alias /laraveltest /home/sergi/provaesborrar/blog/public

<Directory /home/sergi/provaesborrar/blog/public>
       Options Indexes FollowSymLinks
       AllowOverride All
       Order allow,deny
       Allow from all
</Directory>
$ sudo service apache2 reload

Apache 2.4 o superior:

$ cat /etc/apache2/conf-available/laraveltest.conf 
Alias /laraveltest /home/sergi/provaesborrar/blog/public

<Directory /home/sergi/provaesborrar/blog/public>
       Options Indexes FollowSymLinks
       AllowOverride All
       Require all granted
</Directory>
$ sudo a2enconf laraveltest
$ sudo service apache2 reload

Important nota final. Les vistes per defecte de l'autenticació "NO FUNCIONEN" per defecte pq no troben el CSS al utilitzar URL relatives a l'arrel del servidor!

Laravel REST

At this webpage:

http://www.codetutorial.io/laravel-5-angularjs-tutorial/

you willl find a basic tutorial example to create a REST API with Laravel 5 using Controladors RESTFul. Also in the article is explained how to implement a client with AngularJS. You can test the rest API with POSTMAN

Second example:

http://www.codetutorial.io/laravel-5-and-angularjs-tutorial-reloaded-part-1/

Laravel REST tools for building APIs

Laravel JSON

See Laravel JSON

Laravel Authorization

http://laravel.com/docs/5.1/authorization

Recommended package: https://github.com/spatie/laravel-permission

Authorization Libraries

Resources

Laravel Session

Vegeu Laravel Session

Laravel Helpers

Els Laravel Helpers són funcions disponibles a qualsevol lloc de l'aplicació Laravel que ens ajuden a desenvolupar aplicacions Laravel. Podeu trobar la documentació oficial dels helpers a:

http://laravel.com/docs/5.0/helpers

Aquestes funcions estan disponibles a tot el projecte Laravel per que al "composer.json" del paquet "laravel/framework" podeu trobar les següent línies:

...
 "autoload": {
     ...
     "files": [
            "src/Illuminate/Foundation/helpers.php",
            "src/Illuminate/Support/helpers.php"
        ],
        "psr-4": {
            "Illuminate\\": "src/Illuminate/"
        }
    },

Com podeu veure hi ha dos tipus de Helpers:

src/Illuminate/Foundation/helpers.php
src/Illuminate/Support/helpers.php

El primer són helpers que només tenen sentit dins d'una aplicació Laravel i els segons són helpers que realment poden ser utilitzats a qualsevol aplicació PHP.

Laravel packages

Vegeu Laravel Packages

Laravel Debug

Vegeu Laravel debug

Laravel testing

Vegeu Laravel Testing

Laravel Cache

Vegeu Laravel i cache

Laravel Redis

Vegeu Laravel i redis

Laravel commands/jobs

Vegeu Laravel jobs o potser esteu interessats en Artisan Console

Laravel Queues

Vegeu Laravel Queues

Laravel Events

Vegeu Laravel events i Laravel_Broadcasting_Events

Artisan console

Aka Artisan commands no confondre amb les comandes o jobs Laravel. Vegeu Laravel Jobs

Laravel Scheduler

Vegeu Laravel Scheduler

Implicit Model Binding

Implicit Model Binding aka Implicit Route Binding


Exemple:

Route::delete('post/{post}', function (Post $post){
 $post->delete();
})

Recursos:

Laravel Spark

Vegeu Laravel Spark


Laravel Socialite

Vegeu Laravel socialite


Laravel macros

Vegeu Laravel macros

Laravel Passport

Vegeu Laravel Passport

Laravel Cross_Site_Request (CSRF)

Vegeu l'article Cross_Site_Request_Forgery#Laravel

Laravel Cookies

Vegeu Laravel Cookies

Laravel seguretat

Vegeu Laravel Seguretat: Laravel Encryption i Laravel Hash

Utilitzant Laravel fora de Laravel

Vegeu:

http://www.gufran.me

Per exemple:

http://www.gufran.me/post/using-laravel-illuminate-config-package-outside-laravel/

Recursos:

Resol·lució de problemes. Troubleshooting

Use of undefined constant MCRYPT_RIJNDAEL_128 - assumed 'MCRYPT_RIJNDAEL_128'

Cal tenir instal·lat mcrypt i el mòdul de mcrypt per a PHP. A més però a partir d'Ubuntu 13.10 pot ser necessari arreglar un error a mà:

$ sudo apt-get install php5-mcrypt
$ sudo ln -s /etc/php5/conf.d/mcrypt.ini /etc/php5/mods-available
$ sudo php5enmod mcrypt
$ sudo service apache2 restart

Local gulp not found

Si us dona un error tipus:

Local gulp not found in ~/github/laracast-laravel-frontend-series
[13:34:14] Try running: npm install gulp

Es per què Gulp utilitza npm un gestor de paquets similar a composer i el primer que heu de fer com amb qualsevol projecte que depèn de composer es fer un:

$ npm install

Per instal·lar totes les dependències.

PHP Fatal error: Uncaught exception 'UnexpectedValueException' with message 'The stream or file ###.log could not be opened: failed to open stream: Permission denied

A la carpeta storage/logs van els logs de l'aplicació i el servidor web ha de tenir-hi permissos. Per exemple si és Apache:

 $  sudo chown www-data:www-data -R storage/logs

també cal tenir permisos a

$  sudo chown www-data:www-data -R storage/framework

PHP Fatal error: Call to undefined function Illuminate\\Encryption\\mcrypt_get_iv_size() in ###/storage/framework/compiled.php on line 11832

Amb Ubuntu 14.04:

$ sudo apt-get install php5-mcrypt
$ sudo mv /etc/php5/conf.d/mcrypt.ini /etc/php5/mods-available/
$ sudo php5enmod mcrypt
$ sudo service apache2 restart

Recursos:

Exemples

MVC

Diagrama:

http://laravelbook.com/laravel-architecture/#components-of-laravel

Recursos:

Vegeu també

Enllaços externs