Il trait Illuminate\Support\Traits\Conditionable aggiunge alla tua classe i metodi when() e unless(). La sua caratteristica principale è permettere di diramare l’elaborazione in base a una condizione mantenendo la method chain.
Il codice sorgente reale si trova in src/Illuminate/Conditionable/Traits/Conditionable.php. È referenziato tramite l’alias Illuminate\Support\Traits\Conditionable.
Molte classi Laravel — QueryBuilder, EloquentBuilder, Mail, Notification — utilizzano questo trait.
Se il primo argomento è vero, viene eseguito il callback passato come secondo argomento. Se è falso, viene eseguito il callback di default (terzo argomento).
Se il valore di ritorno del callback è null, viene restituito $this (l’oggetto che usa il trait). Se il callback non restituisce null, viene restituito quel valore.
// viene restituito $this, quindi la catena continua$query = User::query() ->when($request->has('active'), function ($query) { $query->where('active', true); // restituisce void / null }) ->when($request->filled('name'), function ($query) use ($request) { $query->where('name', 'like', "%{$request->name}%"); }) ->orderBy('created_at', 'desc');
Se il callback restituisce un valore esplicito, quel valore viene propagato al passo successivo della catena. Se non restituisce nulla (null), viene restituito $this.
Chiamandolo con un solo argomento ottieni un proxy che porta con sé quel valore come condizione.
// un solo argomento: passi la condizione e ottieni il proxy$proxy = collect([1, 2, 3])->when($request->has('filter'));// con $proxy->methodName() puoi chiamare methodName() solo se la condizione è vera
when() è utilizzabile anche nella costruzione di email, notifiche e response.
use Illuminate\Mail\Mailable;use Illuminate\Support\Traits\Conditionable;class OrderConfirmation extends Mailable{ public function build(): static { return $this ->subject('Abbiamo ricevuto il tuo ordine') ->view('emails.order.confirmation') ->when($this->order->hasDiscount(), function (Mailable $mail) { $mail->attach(storage_path('discounts/coupon.pdf')); }) ->when(app()->environment('production'), function (Mailable $mail) { $mail->bcc('[email protected]'); }); }}
tap() e when() si assomigliano, ma hanno scopi diversi.
tap()
when()
Scopo
Side effect (log, debug)
Diramazione condizionale
Valore di ritorno
Sempre $this
$this o il valore di ritorno del callback, in base alla condizione
Condizione
Nessuna
Presente
// tap: usato per side effect. Il valore di ritorno è sempre $this$user = User::find($id) ->tap(fn ($user) => Log::info("User {$user->id} loaded"));// when: usato per diramare$user = User::query() ->when($isAdmin, fn ($q) => $q->where('role', 'admin')) ->first();
Se vuoi solo eseguire qualcosa nella catena per debug o side effect, usa tap(). Se vuoi cambiare comportamento in base a una condizione, usa when() / unless().