Ray Lee | 李宗叡
Learn or Die
Published in
2 min readJun 10, 2024

--

# Introduce the Exceptions Facade

11.4 新增 Exception facade 以及各種 assert method

<?php
use Illuminate\Support\Facades\Exceptions;

test('example', function () {
Exceptions::fake();

$this->post('/generate-report', [
'throw' => 'true',
])->assertStatus(503); // Service Unavailable

Exceptions::assertReported(ServiceUnavailableException::class);

// or
Exceptions::assertReported(function (ServiceUnavailableException $exception) {
return $exception->getMessage() === 'Service is currently unavailable';
});
});

# Livewire-style Directives

11.4 新增 directives

<?php
{{-- Before --}}

<x-fetch wire:poll />

{{-- Generates this HTML --}}

<div ... wire:poll="wire:poll" />

{{-- After --}}
<x-fetch wire:poll />

<div ... wire:poll />

# Reversible Forms in Prompts

11.4 可以在 form 中使用之前的 response

之前的

<?php
use function Laravel\Prompts\form;

$responses = form()
->text('What is your name?', required: true)
->password('What is your password?', validate: ['password' => 'min:8'])
->confirm('Do you accept the terms?')
->submit();

新增功能,line 4 所使用的 data 來自於 line 2 & line 3

<?php
$responses = form()
->text('What is your name?', name: 'name')
->add(fn () => select('What is your favourite language?', ['PHP', 'JS']), name: 'language')
->add(fn ($responses) => note("Your name is {$responses['name']} and your language is {$responses['language']}"))
->submit();

# Add Support for Enums on mapInto Collection Method

11.4 可以直接將 collection mapInto Enum

<?php
public function store(Request $request)
{
$request->validate([
'features' => ['array'],
'features.*' => [new Enum(Feature::class)],
]);

$features = $request
->collect('features')
->mapInto(Feature::class);

if ($features->contains(Feature::DarkMode)) {
// ...
}
}

# An afterQuery() Hook

11.4 新增 afterQuery() hook,可以在 query 執行完畢後,對 model 做操作

比方說情境如下:

  • 如果有登入,就撈出該 user 的 favorite products,如果沒登入,就撈出所有的 products
  • 有登入時,product 要有一個 attribute is_favorite 需為 true
  • 無登入時,需為 false

以前為 11.4 之前的 implementation

<?php
// Before

public function scopeWithIsFavoriteOf($query, ?User $user = null) : void
{
if ($user === null) {
return $query;
}

$query->addSelect([
// 'is_favorite' => some query ...
]);
}

$products = Product::withIsFavoriteOf(auth()->user())->get();

if (auth()->user() === null) {
$products->each->setAttribute('is_favorite', false);
}

11.4 之後的

<?php
// After

public function scopeWithIsFavoriteOf($query, ?User $user = null) : void
{
if ($user === null) {
$query->afterQuery(fn ($products) => $products->each->setAttribute('is_favorite', false));

return;
}

$query->addSelect([
// 'is_favorite' => some query ...
]);
}

Product::withIsFavoriteOf(auth()->user())->get();

更多細節,可參考 contributor’s description

# 參考來源

--

--

Ray Lee | 李宗叡
Learn or Die

It's Ray. I do both backend and frontend, but more focus on backend. I like coding, and would like to see the whole picture of a product.