¡Laravel 5.3 ya está disponible! y es un buen momento para actualizar nuestros proyectos desarrollados en este framework. ¿La razón? esta versión llega con muchas mejoras y nuevas características con respecto a Laravel 5.2 que estamos seguros estás ansioso por usar. Además que Laravel 5.2 al ser es una versión no LTS, tiene sólo actualizaciones de errores por 6 meses y de seguridad por 1 año.

Laravel 5.3 viene con muchas mejoras y sobretodo con nuevos features como un nuevo sistema de notificaciones, integración de OAuth2 por medio de Laravel Passport, sistema de búsqueda de full-text en modelos de Eloquent a través de Laravel Scout, soporte de Webpack en Laravel Elixir, Laravel Mailable, separación explicita de las rutas web y API, helpers para subir archivos fácilmente, entre muchas otras que podrás empezar a usar luego de realizar los pasos descritos en adelante. Esta es una actualización sencilla que no debe tomarte más de 1 hora o 2, sin embargo la duración también depende de la complejidad de tu proyecto:

Requerimientos

  • Para usar Laravel 5.3 se requiere tener PHP 5.6.4 o superior.  HHVM ya no será oficialmente soportada pues no contiene las mismas características que PHP 5.6 en adelante.
  • Una aplicación en Laravel 5.2, en caso de no serlo, tienes primero que actualizar a la versión 5.2.

Paso 1. Actualiza las dependencias

Actualiza el archivo composer.json de tu aplicación:

"require": {
    "laravel/framework": "5.3.*",
},

También debes revisar que todas las otras dependencias o paquetes que utiliza la aplicación sean compatibles con Laravel 5.3 y actualizar en caso que lo requiera.

Paso 2. Elimina las características obsoletas

Cada una de las características que fueron marcadas como obsoletas en Laravel 5.2 para está versión han sido eliminadas. Puedes revisar el listado completo y sustituir por lo recomendado, en caso de que tu aplicación aún siga usando alguna.

Paso 3. Instala el sistema de notificaciones

Laravel 5.3 incluye un nuevo sistema de notificaciones basado en driver. Por tanto deberías registrar el service provider en el array providers del archivo de configuración config/app.php de tu aplicación, de esta manera:

'providers' => [
    //
    Illuminate\Notifications\NotificationServiceProvider::class,
]

Además, agregar el facade al array aliases:

'aliases' => [
     //
    'Notification' => Illuminate\Support\Facades\Notification::class, 
]

Por último, puedes usar el trait Illuminate\Notifications\Notifiable en el modelo User o cualquier otro modelo que desee recibir notificaciones.

Paso 4. Revisa la autenticación

Paso 4.1 Agrega el nuevo Scaffolding

Los dos controladores de autenticación usados hasta Laravel 5.2 ubicados en el directorio App\Http\Controllers\Auth: AuthControllerPasswordController han sido separados en cuatro controladores más pequeños:

  • ForgotPasswordController
  • LoginController
  • RegisterController
  • ResetPasswordController

Para actualizar tu aplicación puedes sustituir los dos controladores con los cuatro nuevos, copiándolos directamente desde el repositorio GitHub de Laravel.

Adicionalmente, tienes que asegurarte de llamar el método Route::auth() en el archivo routes.php para que se registren las rutas apropiadas a los nuevos controladores de autenticación.

Si en tu aplicación no tienes implementada alguna personalización en los viejos controladores estos son los únicos cambios que deberías realizar, pero si por el contrario has hecho alguna modificación, entonces necesitarás volver a agregar las personalizaciones ahora en los nuevos controladores. Para ello tienes que revisar cada trait de los controladores para determinar cuáles métodos serán sobreescritos en el controlador adecuado. De igual forma, si has copiado las rutas del método Route::auth() a tu archivo routes.php debes sustituir los llamados a los métodos de los controladores nuevos.

Paso 4.2 Configuración para el correo para la recuperación de contraseña

Los correos para la recuperación de contraseña ahora usan el nuevo sistema de notificaciones de Laravel. Por tanto, deberías tenerlo configurado como se explicó arriba. Además, si te gustaría personalizar la notificación enviada cuando se envía el enlace para resetear la contraseña, deberías sobreescribir el método sendPasswordResetNotification del trait Illuminate\Auth\Passwords\CanResetPassword.

El modelo User debe obligatoriamente implementar el nuevo trait Illuminate\Notifications\Notifiable para que el correo con el enlace para la recuperación de la contraseña sea entregado. De esta manera:

<?php

namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    use Notifiable;
}

Paso 4.3 Cambia a ruta de tipo POST para /logout

Ahora el método Route::auth() registra una ruta tipo POST para /logout en vez una ruta tipo GET. Esto previene que otras aplicaciones web puedan cerrar la sesión de un usuario de tu aplicación. Para actualizar, debe o bien convertir la solicitud de cierre de sesión para usar la ruta POST:

Route::post('/logout', 'Auth\LoginController@logout');

o registrar tu propia ruta tipo GET:

Route::get('/logout', 'Auth\LoginController@logout');

Paso 5. Reajusta la Autorización

Paso 5.1. Revisa las llamadas a métodos de Políticas de acceso con nombres de clase

Algunos métodos de política sólo reciben el usuario autenticado actualmente y no una instancia del modelo que autorizan. Esta situación es más común al autorizar acciones create. Por ejemplo, en la creación de un blog, es posible que desees comprobar si un usuario está autorizado para crear un post.

Al definir los métodos de política de acceso que no recibirán una instancia de modelo, como el método create, el nombre de la clase ya no se pasa como segundo argumento del método, sino que solo esperará la instancia del usuario autenticado. Por ejemplo,

public function create(User $user)
{
    //
}

5.2. Elimina el Trait AuthorizesResources

El trait AuthorizesResources ha sido unido con el trait AuthorizesRequests.  Por tanto, debes eliminar el trait AuthorizesResources del archivo app/Http/Controllers/Controller.php.

6. Agrega los cambios en middleware

6.1. Cambia el namespace del middleware can

Para el middleware can que se encuentra listado en la propiedad $routeMiddleware del archivo /app/Http/Kernel.php debes actualizar el namespace a:

'can' => \Illuminate\Auth\Middleware\Authorize::class,

6.2. Revisa que incluyes la nueva excepción de autenticación para can

El middleware can ahora lanzará una instancia de Illuminate\Auth\AuthenticationException si el usuario no está autenticado. Si estuvieras capturando manualmente un tipo de excepción diferente, deberías actualizar tu aplicación para capturar esta excepción. Sin embargo, en la mayoría de los casos este cambio no afectará tu aplicación.

6.3 Agrega el nuevo middleware Binding Substitution

Ahora el Route Model Binding se realiza a través de un middleware. Por tanto, todas las aplicaciones deberían agregarlo al grupo de middleware web en el archivo app/Http/Kernel.php. De esta manera:

\Illuminate\Routing\Middleware\SubstituteBindings::class,

Adicionalmente, debes registrarlo en los middleware de rutas a través de la propiedad $routeMiddleware del mismo archivo app/Http/Kernel.php, así

'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,

Una vez registrado deberías agregarlo al grupo de middleware api:

'api' => [
        'throttle:60,1',
        'bindings',
    ],

7. Revisa las rutas y sus llamados

7.1 Verifica los parámetros de las rutas tipo Resource

En las anteriores versiones de Laravel, los parámetros de una ruta registrados usando Route::resource no estaban en singular, lo que podía provocar algunos comportamientos inesperados cuando se usaba Route Model Binding (inyectar la instancia del modelo directamente en la ruta en vez de su ID), por ejemplo:

Route::resource('photos', 'PhotosController');

La ruta sería definida de esta manera:

/photos/{photos}

Ahora en Laravel 5.3, por defecto, todos los parámetros de rutas de tipo resource son en singular, es decir que al llamar el mismo ejemplo anterior se tendría:

/photos/{photo}

En caso de querer mantener el comportamiento anterior en vez de la «singularización» automática puedes agregar el siguiente llamado al método singularResourceParameters en la clase AppServiceProvider del directorio app/Providers:

use Illuminate\Support\Facades\Route;

Route::singularResourceParameters(false);

7.2 Comprueba que los nombres de rutas tipo Resource funcionan

Los prefijos de rutas ya no afectan los nombre asignados a las rutas cuando se está usando Route::resource dado que este comportamiento anula todo el propósito de nombres de rutas.

Si estás usando Route::resource dentro de Route::group que tiene asignado la opción prefix, entonces deberías verificar que todos los llamados con el helper route ya no tengan el prefijo añadido en el nombre de la ruta.

Por ejemplo,  para:

Route::group(['prefix' => 'admin'], function () {
    Route::resource('posts', 'PostController');
});

El nombre de ruta para admin/posts en Laravel 5.3 será posts.index y no admin.posts.index

En caso de que este cambio provoque que dos rutas tengan el mismo nombre puedes usar la opción names en el Route::resource para cambiar el nombre de las rutas.

Route::resource('posts', 'PostController', ['names' => [
    'create' => 'post.build'
]]);

8. Ajusta las Colecciones

El método where ahora realiza una comparación flexible o loose por defecto, en vez de una comparación estricta. Si deseas realizar una comparación estricta, puedes usar el método whereStrict.

Además, el método where ya no acepta el tercer parámetro que indicaba «rigurosidad» sino que se debería llamar explicítamente el método where o el método whereStrict dependiendo de las necesidades de la aplicación.

Hay también algunos cambios en los métodos first, last y contains para las colección que se verá más adelante.

9. Cambios en Database

9.1 Colecciones

Las consultas realizadas con el constructor de consultas (Query Builder) ahora devolverán una instancia de Illuminate\Support\Collection en vez de un array plano. De esta manera se tiene una mejor consistencia entre los resultados retornados de Query Builder y Eloquent.

Si no quieres migrar los resultados del constructor de consultas a instancias de Collection, puedes encadenar el método all en cada uno de los llamados al método get de query Builder. Así, se devolverá como resultado a un array de PHP plano, permitiendo la compatibilidad con las versiones anteriores:

$users = DB::table('users')->get()->all();

9.2 Cambio en el método de Eloquent save

El método save del ORM Eloquent ahora devuelve false si el modelo no ha sido cambiado desde la última vez que se ha guardado o recuperado.

10. Realiza el cambio en el orden de los argumentos para algunos métodos

Para los métodos where de la clase Illuminate\Support\Arr, contains de Illuminate\Database\Eloquent\Collection además de first y last presentes en ambas clases, cuando son llamados usando un Closure, ahora pasan el parámetro «value» como el primer argumento del Closure dado, en vez de $key. Por ejemplo,

$array = [100, 200, 300];

Arr::first($array, function ($value, $key) {
     return $value >= 150;
});
// devuelve 200

Esto debido a que en la mayoría de los casos sólo se está interesado en el $value por tanto se ha cambiado el orden. Si estás usando algunos de estos métodos de esta manera en tu proyecto debes hacer una búsqueda en toda la aplicación para verificar que $value sea pasado como el primer argumento del Closure.

11. Cambios en la validación

11.1 Nueva excepción

Cuando una validación de un form request falla, Laravel 5.3 lanzará una instancia de Illuminate\Validation\ValidationException en vez de una instancia de HttpException. Si estás capturando manualmente la instancia HttpException lanzada por un form request, deberías sustituir para que ahora capture ValidationException.

11.2 Nueva regla nullable

Cuando estés validando arrays, booleans, integers, numerics, and strings, null ya no será considerado un valor válido a menos que se asigne la regla nullable:

Validate::make($request->all(), [
    'string' => 'nullable|max:5',
]);

12. Actualiza los Service Providers

Elimina los argumentos del método boot en las clases EventServiceProvider y RouteServiceProvider presentes en el directorio app/providers. Cualquier llamada a los argumentos dados se pueden usar en su lugar el equivalente facade. Por ejemplo, en vez de llamar al argumento $dispatcher se usa el facade Event y para el argumento $router se sustituye con la facade Router. Asegúrate de importar la clase de las facade usadas en la clase del service provider.

13. Ejecuta composer update

Finalmente, le indicamos a Composer que actualice nuestro proyecto:

composer update

Otros cambios

Si tu proyecto es complejo puede que necesites revisar otras actualizaciones que se deben realizar:

  • El comando de Artisan make:console ha sido renombrado a make:command
  • En las Queue hay varios cambios como: en la configuración se debe renombrar todas las opciones expire por retry_after, los Closure ya no están soportados, las colecciones en Queue ahora están serializadas, entre otros cambios que debes revisar en la documentación oficial.
  • En Eloquent la clase JoinClause ha sido reescrita para unificar su sintaxis con query builder. También la propiedad $bindings fue eliminada para ahora usar el método addBinding.
  • Ahora es más fácil personalizar la paginación pues solo es necesario usar una simple plantilla de Blade donde puedes modificar el HTML. Para ello debes exportar al directorio resources/views/vendor/pagination la plantilla predefinida default.blade.php usando el comando vendor:publish
    php artisan vendor:publish --tag=laravel-pagination
  • Mcrypt encrypter ha sido eliminado en favor de la implementación basada en OpenSSL.
  • Laravel 5.3 viene con mejoras significativas en el Broadcasting de eventos, para usarlas debes agregar el nuevo service provider BroadcastServiceProvider al directorio app/Providers copiándolo desde el repositorio de GitHub para luego registrarlo en el archivo config/app.php en el array providers.
  • Cambio en la Directivas de Blade personalizadas usando el método directive que pasa una $expression al callback ya no se tomaran en cuenta los parentesis más externos. Revisa la documentación para que tus directivas personalizadas funcionen correctamente.

Hay algunos otros cambios sobre Cache, Cashier, Exceptions, etc. que puedes revisar directamente en la guía de actualización de Laravel (en inglés).

¿Qúe hay de nuevo en Laravel 5.3?

En Styde.Net trabajamos para traerte tutoriales y lecciones de muchas de las nuevas características de Laravel en nuestro Curso de novedades en Laravel 5.3. ¡No te lo pierdas!

Material relacionado

Únete a nuestra comunidad en Discord y comparte con los usuarios y autores de Styde, 100% gratis.

Únete hoy

Regístrate hoy en Styde y obtén acceso a todo nuestro contenido.