1907 1760 1361 1980 1115 1517 1766 1047 1757 1021 1923 1915 1506 1108 1671 1814 1173 1964 1668 1527 1173 1681 1419 1627 1700 1912 1198 1778 1238 1965 1348 1242 1907 1571 1070 1965 1129 1237 1065 1620 1945 1529 1787 1643 1463 1158 1111 1121 1547 1132 1173 1012 1793 1841 1412 1094 1935 1337 1121 1862 1469 1700 1269 1089 1225 1808 1255 1366 1252 1150 1276 1547 1256 1221 1313 1561 1451 1413 1667 1660 1003 1713 1135 1834 1944 1280 1759 1139 1011 1302 1991 1137 1002 1942 1799 1285 1198 1336 1154 Blade, Requests, Routing, and Validation: New features since the Laravel 8.0 release in September 2020 (1/2) | PHPnews.io

PHPnews.io

Blade, Requests, Routing, and Validation: New features since the Laravel 8.0 release in September 2020 (1/2)

Written by Pascal Baljet Media - Blog / Original link on Dec. 3, 2021

Following last week's blog post about Jobs and Queues, here's an overview of new features and improvements when it comes to Blade, Requests, Routing and Validation.

I got most code examples and explanations from the PRs and official documentation.

Requests and Routing

v8.17.0 Added dd() and dump() to the request object (#35384)

Quickly inspect the request input.

public function index(Request $request)
{
    // before:
    dd($request->all());

    // after:
    $request->dd();

    $request->dd(['name', 'age']);

    $request->dd('name', 'age');
}

v8.26.0 Added Route::missing() (#36035)

Typically, a 404 HTTP response will be generated if an implicitly bound resource model is not found. With the missing method you may change this behavior:

Route::get('/locations/{location:slug}', [LocationsController::class, 'show'])
    ->name('locations.view')
    ->missing(fn($request) => Redirect::route('locations.index', null, 301));

v8.55.0 Added Support withTrashed on routes (#38348)

This allows you to specify a single route that allows soft deleted models when resolving implicit model bindings:

Route::post('/user/{user}', function (ImplicitBindingModel $user) {
    return $user;
})->middleware(['web'])->withTrashed();

v8.56.0 Added fullUrlWithoutQuery method to Request (#38482)

Get the full URL for the request without the given query string parameters.

// When the current URL is 
// https://example.com/?color=red&shape=square&size=small

request()->fullUrlWithoutQuery('color');
// https://example.com/?shape=square&size=small

request()->fullUrlWithoutQuery(['color', 'size']);
// https://example.com/?shape=square

Blade Templates

v8.19.0 Added Illuminate\View\ComponentAttributeBag::has() (#35562)

Allows to determine if a given attribute is present on a component.

@if ($attributes->has('class'))
    <div>Class Attribute Present</div>
@endif

v8.27.0 Conditionally merge classes into a Blade Component attribute bag (#36131)

Inspired by Vue's :class syntax, this PR adds a class() method to the ComponentAttributeBag class. It merges the given classes into the attribute bag.

<div {{ $attributes->class(['p-4', 'bg-red' => $hasError]) }}>

As of v8.51, you can use the class directive as well:

<div @class(['p-4', 'bg-red' => $hasError])>

v8.45.0 Adds class handling for Blade echo statements (#37478)

This PR adds a new Blade::stringable() method that allows the user to add intercepting closures for any class. The returned value will be outputted in Blade.

// AppServiceProvider
Blade::stringable(Money::class, fn($object) => $object->formatTo('en_GB'));
Blade::stringable(Carbon::class, fn($object) => $object->format('d/m/Y')));
<dl>
    <dt>Total</dt>
    <dd>{{ $product->total }}</dd> <!-- This is a money object, but will be outputted as an en_GB formatted string -->
    <dt>Created at</dt>
    <dd>{{ $product->created_at }}</dd> <!-- This is a Carbon object, but will be outputted as English date format -->
</dl>

v8.64.0 Added @aware blade directive (#39100)

You may use the @aware directive to access data from a parent component inside a child component. For example, imagine a parent <x-menu> and child <x-menu.item>:

<x-menu color="purple">
    <x-menu.item>...</x-menu.item>
    <x-menu.item>...</x-menu.item>
</x-menu>

By using the @aware directive, you can make the color prop available inside as well:

<!-- /resources/views/components/menu/item.blade.php -->
@aware(['color' => 'gray'])

<li {{ $attributes->merge(['class' => 'text-'.$color.'-800']) }}>
    {{ $slot }}
</li>

Validation

v8.32.0 Added prohibited_if and prohibited_unless validation rules (#36516)

The field under validation must be empty or not present if the anotherfield field is equal to any value.

Validator::validate([
    'is_deceased' => false,
    'date_of_death' => '2021-01-01'
], [
    'date_of_death' => 'prohibited_unless:is_deceased,true'
]);

v8.34.0 Added prohibited validation rule (#36667)

The field under validation must be empty or not present.

Validator::validate([
    'name' => 'hello-world',
    'key' => 'random-key',
], [
    'name' => 'required|max:255',
    'key' => 'prohibited',
]);

v8.39.0 Added password validation rule (#36960)

To ensure that passwords have an adequate level of complexity, you may use Laravel's Password rule object:

Validator::validate([
    'password' => '123123',
], [
    'password' => ['required', 'confirmed', Password::min(8)
        ->mixedCase()
        ->letters()
        ->numbers()
        ->symbols()
        ->uncompromised(),
    ],
]);

v8.47.0 Copy password rule to current_password (#37650)

To prevent communication problems with the new Password rule object, the password rule was renamed to current_password with the intention of removing it in Laravel 9.

v8.52.0 Added Unique::withoutTrashed() (#38124)

This PR adds a helper method to the unique validation rule for working with models which can be soft deleted.

// Before
Rule::unique('users')->whereNull('deleted_at');

// After
Rule::unique('users')->withoutTrashed();

v8.54.0 Added withoutTrashed on Exists rule (#38314)

In addition to the unique rule in the example above, you may also use the withoutTrashed method on the exists rule.

// Before
Rule::exists('users')->whereNull('deleted_at');

// After
Rule::exists('users')->withoutTrashed();

v8.53.0 Added accepted_if validation rule (#38210)

In addition to the accepted rule, you can now use this rule if another field under validation is equal to a specified value.

Validator::validate([
    'newsletter_subscription' => '1',
    'newsletter_terms' => '0',
], [
    'newsletter_subscription' => 'required|boolean',
    'newsletter_terms' => 'accepted_if:newsletter_subscription,1',
]);

v8.57.0 Added exclude validation rule (#38537)

The field under validation will be excluded from the request data returned by the validate and validated methods. There are exclude_if, exclude_unless, and exclude_without rules as well.

Validator::validate([
    'role' => 'guest',
    'email' => 'guest@company.com',
], [
    'role' => ['required', 'in:user,guest'],
    'email' => ['required_if:role,user', 'exclude_unless:role:user', 'email'],
]);

v8.58.0 Added prohibits validation (#38612)

If the field under validation is present, no fields in anotherfield can be present, even if empty.

Validator::validate([
    'email' => 'example@example.com',
    'emails' => ['example@example.com', 'other.example@example.com']
], [
    'email' => 'prohibits:emails'
]);

v8.55.0 Added Conditional rules (#38361)

You may use Rule::when() to create a new conditional rule set.

Validator::validate([
    'password' => '123456',
], [
    'password' => ['required', 'string', Rule::when(true, ['min:5', 'confirmed'])],
]);

v8.55.0 Added Validated subsets (#38366)

You may now retrieve a portion of the validated input data:

$validator->safe()->only(['name', 'email']);
$validator->safe()->except([...]);

This works on Form Requests as well:

$formRequest->safe()->only([...]);
$formRequest->safe()->except([...]);

pascalbaljetmedia

« Symfony Demo 2.0 Introduces Support for Symfony 6.0 - New features and improvement in Laravel Jobs and Queues since the original v8.0 release »