themsaid

Hi! I'm Mohamed Said. I work at @laravelphp on weekdays and practise freediving on weekends. Find me as themsaid @twitter and @github.

Back to home

What's new in laravel 5.2.23

By the time of writing this post, laravel has 911 contributors on GitHub, some of them are actively adding awesome stuff to the framework on a daily basis. This is a wrap up for the new stuff in laravel 5.2.23.

in_array validation rule

Array validation in laravel is just awesome, I myself replaced a lot of code in some of the current projects with just a few lines for validation. In 5.2.23 a new rule is added to help with validating that a value of a key exists in another related key:

Validator::make(
    [
        'devices' => [['user_id' => 1], ['user_id' => 2]],
        'users' => [['id' => 1, ['id' => 2]]]
    ],
    ['devices.*.user_id' => 'in_array:users.*.id']
);

This rule will make sure all user_id values exists in the users array.

Arr::first() & Arr::last() now have the callback optional

Previously the callback was required as a second argument for these methods, now it is optional:

$array = [100, 200, 300];

// (NEW) This will return 100
Arr::first($array); /** same for **/ array_first($array);

// (NEW) This will return 300
Arr::last($array); /** same for **/ array_last($array);

// (You still can) do this and return 200
Arr::first($array, function ($key, $value) {
    return $value >= 150;
});

Specifying more than one middleware at a time

When adding controller middlewares, you're now able to register multiple middlewares in the same statement.

$this->middleware(['auth', 'subscribed'], ['only' => ['getCandy']]);

New Blade directives @php, @endphp, and @unset

The @php directive will allow you to write PHP statements with style:

@php($count = 1)

@php(++ $count)
@php
    $now = new DateTime();

    $environment = isset($env) ? $env : "testing";
@endphp

@unset is just a wrapper for unset().

@unset($count)

Ability to override core blade directives

Prior to 5.2.23 it was not possible to extend Blade and override a core directive, now your extension will overwrite any core blade directive.

Ability to escape blade directives

Now you can escape compilation for a blade directive by prepending a @, just like what we used to do to escape compiling echos:

// output: <?php continue; ?>
@continue

// output: @continue
@@continue

You may also use the new @verbatim directive to prevent Blade from compiling multiple statements:

@verbatim
    @if {{ $var }} @endif
@endverbatim

New mail driver for SparkPost

New monthlyOn() method for scheduling commands

$schedule->call(function () {
    DB::table('shopping_list')->delete();
})->monthlyOn(4, '12:00');

New isLocale() method

// Instead of this
if (app()->getLocale() == 'en')

// You can do that
if (app()->isLocale('en'))

Querying MySQL 5.7 & Postegres json fields fluently with the query builder

With the release of MySQL 5.7, a new column type JSON was introduced , in laravel 5.2.23 you're able to query values from a json field as fluent as usual:

Let's say you have a users table with a name column of type JSON, the column has the following value:

{"en":"name","ar":"nom"}

You can query the json values using the following syntax:

User::where('name->en', 'name')->get();

// You may dive deep in the JSON string using the `->` operator.
User::where('contacts->phone->home', 1234);

The same syntax works with Postgres as well, the column->key->key->... format will be converted to a valid JSON path before sending to the database driver.

Notes for MySQL

The output of these queries will be a JSON string ("name" and not name), so you'll need to use json_decode() before display.

To use this syntax make sure your JSON keys are valid ECMAScript identifier names.

seeElement() and dontSeeElement() test helpers

While you have this element:

<image width="100" height="50">

You may run the following tests and get a success:

$this->seeElement('image', ['width' => 100, 'height' => 50]);

$this->dontSeeElement('image', ['class' => 'video']);

+ hidden gem #1

Did you know you can already do this?

User::whereNameAndEmail('jon', 'jon@theWall.com')->first();

User::whereNameAndEmailOrPhone('jon', 'jon@theWall.com', '123321')->first();

DB::table('users')->whereEmailOrUsername('mail@mail.com', 'themsaid')->first();

+ hidden gem #2

// Instead of this:
if(!$item){
    abort(404);
}

// You can do that:
abort_unless($item);

// You may also have something like this:
abort_if($item->is_hidden);