LaravelPHP

Laravel 5.8 release: 10 new features to try

The latest version of Laravel, version 5.8, has recently been released. This version has many exciting new features and it is a continuous improvement of previous versions of Laravel. These features include:

  • Automatic policy resolution
  • Carbon 2.0 support
  • Has-one-through Eloquent relationships
  • Token guard token hashing
  • Cache TTL
  • Scheduler timezone configuration
  • Artisan::call improvements
  • Artisan serve improvements
  • Mock testing helper methods
  • Higher order orWhere Eloquent method

And many more. In this article, I will discuss some of these new features in greater depth.

1. Automatic policy resolution

Policies are one of two primary ways Laravel handles user authorization. They are classes that organize authorization logic around a particular model or resource. In the previous version of Laravel, policies needed to be registered in the AuthServiceProvider as follows:

<?php

namespace AppProviders;

use AppPost;
use AppPoliciesTransactionPolicy;
use IlluminateSupportFacadesGate;
use IlluminateFoundationSupportProvidersAuthServiceProvider as ServiceProvider;

class AuthServiceProvider extends ServiceProvider
{
    /**
     * The policy mappings for the application.
     *
     * @var array
     */
    protected $policies = [
        Transaction::class => TransactionPolicy::class,
    ];

    /**
     * Register any application authentication / authorization services.
     *
     * @return void
     */
    public function boot()
    {
        $this->registerPolicies();

        //
    }
}

In this case, the policy we are registering is a policy called TransactionPolicy, which we are entering into the $policies array.

However, starting in Laravel 5.8 you do not need to manually register a model’s authorization policy. Laravel can auto-discover policies as long as the model and policy follow standard Laravel naming conventions and the policy directory is in its default location.

If you have models or policies in locations different from the default Laravel structure, you can register a custom callback using the Gate::guessPolicyNamesUsing method. Typically, this method should be called from the boot method of your application’s AuthServiceProvider like this:

use IlluminateSupportFacadesGate;

Gate::guessPolicyNamesUsing(function ($modelClass) {
    // return policy class name...
});

2. Carbon 2.0 support

Carbon is a package that extends PHP’s own DateTime class and makes working with dates and time very easy. Laravel 5.8 provides support for the 2.0 release of Carbon. Among the new features of Carbon 2.0 is the CarbonImmutable class and a new Date facade. Let’s see how this works.

Enter the following in the routesweb.php file of a Laravel 5.8 installation:

use CarbonCarbon;

Route::get('carbon', function () {
    $date = Carbon::now();
    dump($date);
    $date->addDays(3);
    dump($date);
});

Here we are creating a route carbon which would save the current date in a $date variable and then display it. It then adds three (3) days to the current date and also displays it. If you visit the /carbon route we have just created, you would see something like:

What is happening here is that we are changing our object. This may be what you desire, but in many cases, this is not what we want, as dates are usually protected properties. We should actually be able to create a new date and not modify an existing date. For example say we are storing a date of birth in one of the columns of our database, this is not information that is going to change, however, we may create a copy for it and do some modifications to that copy. This is where the CarbonImmutable class comes in. To use this feature, go to your AppServiceProvider and enter the following:

// ...other includes
use IlluminateSupportDateFactory;
use CarbonCarbonImmutable;

class AppServiceProvider extends ServiceProvider
{
  public function register()
    {
        DateFactory::use(CarbonImmutable::class);
    }
}

Then update the routesweb.php file to use the new Date facade and create a copy of the date which we can change:

use IlluminateSupportFacadesDate;

Route::get('carbon', function () {
    $date = Date::now();
    dump($date);
    $newDate = $date->copy()->addDays(7);
    dump($newDate);
});

Refresh your browser and you should see this:

3. HasOneThrough eloquent relationship

Laravel 5.8 introduces a new eloquent relationship: HasOneThrough. Though this is new in Laravel, it exists in other frameworks like Rails. Say we have three models: a Supplier model an Account model and an AccountHistory model. A supplier has an account and an account has one account history.

Previously to get a supplier’s account history, you will have to find the supplier then write something like: $supplier->account->accountHistory. Now you may use a hasOneThrough relationship to skip this step, accessing a supplier’s account history straight away like this: $history = $supplier->accountHistory through the account model:

public function accountHistory()
{
    return $this->hasOneThrough(AccountHistory::class, Account::class);
}

4. Token guard token hashing

A little known fact about Laravel API authentication is that you don’t always have to use Laravel Passport. There is a simpler token guard which provides basic API authentication and in Laravel 5.8 it now supports storing tokens as SHA-256 hashes. This provides greater security over storing plain-text tokens.

5. Cache TTL

In previous versions of Laravel, caching was set in minutes. This has changed in version 5.8, to seconds for more precise and granular setting for expiration time when storing items and provide compliance with the PSR-16 caching library standard. So in any reference to cache in your application remember to update to seconds:

// Laravel 5.7 - Store item for 5 minutes...
Cache::put('foo', 'bar', 10);

// Laravel 5.8 - Store item for 5 seconds...
Cache::put('foo', 'bar', 10);

6. Scheduler timezone configuration

In Laravel you can define your timezone for a scheduled task using the timezone method like this:

$schedule->command('run')
         ->daily()
         ->at('15:00')
         ->timezone('America/Chicago');

In previous releases, you have to repeat this for every scheduled task and this can quickly become cumbersome if you have many of them. In Laravel 5.8 you can just define a method called scheduledTimezone in your app/Console/kernel.php file and return your default timezone. This will be attached to every scheduler you have:

 /**
 * Get the timezone that should be used by default for scheduled events.
 *
 * @return DateTimeZone|string|null
 */
protected function scheduleTimezone()
{
    return 'America/Chicago';
}

7. Artisan call improvements

Laravel allows you to make Artisan commands from your code using the Artisan::call method. In previous versions of Laravel, if you need to pass some options to the command you typically do this:

use IlluminateSupportFacadesArtisan;

Artisan::call('migrate:install', ['database' => 'foo']);

Now in 5.8, instead of passing the options as an array, you can pass it in one single string like this:

Artisan::call('migrate:install --database=foo');

8. Artisan serve improvements

A way to quickly serve your Laravel application is by running the command php artisan serve. In previous versions of Laravel this command will run your application in a default port of 8000 and if you attempt to serve another application with the same command, this would fail. Now in version 5.8 the serve command will scan for available ports up to port 8009 so you can serve multiple applications at once.

9. Mock testing helper methods

This is another improvement to make your test code cleaner and readable. Say we want to mock a transaction service and have it return some dummy transaction data. In previous versions of Laravel we would write something like this:

public function testBasicTest()
{       
  $service = Mockery::mock(TransactionService::class, function ($mock) {
        $mock->shouldReceive('find')->once()->with()->andReturn(['id' => 1, 'name' => 'foo']);
  });

  $this->instance(TransactionService::class, $service)
}

In Laravel 5.8 this can be shortened to:

public function testBasicTest()
{
  $this->mock(TransactionService::class, function($mock){
    $mock->shouldReceive('find')->once()->with(1)->andReturn(['id' => 1, 'name' => 'foo'])
  });
}

This takes care of calling Mockery and binding it into the container. Notice we don’t have to call $this->instance

10. Higher order orWhere eloquent method

Previously if we wanted to combine scoped query with or , we typically would define a closure like this:

// scopeActive and scopeEmailVerified methods defined on the User model...
$users = AppUser::emailVerified()->orWhere(function (Builder $query) {
  $query->active();
})->get();

Laravel 5.8 introduces a “higher order” orWhere method, so you don’t need to write the above closure anymore. Instead, you can write this:

$users = AppUser::emailVerified()->orWhere->active()->get();

Conclusion

This new version of Laravel comes loaded with many exciting features and we have gone through some of the most notable improvements in the framework. For details on how to upgrade your existing Laravel application to version 5.8, see the upgrade guide. What are your thoughts on Laravel 5.8? Let me know in the comments section!

Related Articles

Leave a Reply

Your email address will not be published. Required fields are marked *

Check Also
Close
Back to top button