> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Invio di email

> Basi dell'invio email con la classe Mailable di Laravel, email Markdown e invio in coda.

## Le funzionalità email di Laravel

Le funzionalità email di Laravel sono costruite su [Symfony Mailer](https://symfony.com/doc/current/mailer.html) e supportano driver come SMTP, Mailgun, Postmark, Resend, Amazon SES, sendmail.

<Info>
  SwiftMailer è stato dismesso. Da Laravel 9 si usa Symfony Mailer.
</Info>

Configura in `config/mail.php`. Nel `.env` scegli il driver.

```ini theme={null}
MAIL_MAILER=smtp
MAIL_HOST=smtp.example.com
MAIL_PORT=587
MAIL_USERNAME=your-username
MAIL_PASSWORD=your-password
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS="hello@example.com"
MAIL_FROM_NAME="${APP_NAME}"
```

## Creare una Mailable

Ogni email inviata è rappresentata da una classe "Mailable".

```shell theme={null}
php artisan make:mail OrderShipped
```

In `app/Mail/`.

## Configurazione della Mailable

Contiene `envelope()`, `content()`, `attachments()`.

```php theme={null}
<?php

namespace App\Mail;

use App\Models\Order;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;

class OrderShipped extends Mailable
{
    use Queueable, SerializesModels;

    public function __construct(
        public Order $order,
    ) {}

    public function envelope(): Envelope
    {
        return new Envelope(
            subject: 'Il tuo ordine è stato spedito',
        );
    }

    public function content(): Content
    {
        return new Content(
            view: 'mail.orders.shipped',
        );
    }

    public function attachments(): array
    {
        return [];
    }
}
```

### Mittente

```php theme={null}
use Illuminate\Mail\Mailables\Address;
use Illuminate\Mail\Mailables\Envelope;

public function envelope(): Envelope
{
    return new Envelope(
        from: new Address('shop@example.com', 'Shop Support'),
        subject: 'Il tuo ordine è stato spedito',
    );
}
```

Mittente globale in `config/mail.php`.

```php theme={null}
'from' => [
    'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'),
    'name' => env('MAIL_FROM_NAME', 'Example'),
],
```

### Corpo del messaggio

`content()` indica una vista Blade. Le proprietà `public` del costruttore sono disponibili nella vista.

```php theme={null}
public function content(): Content
{
    return new Content(
        view: 'mail.orders.shipped',
    );
}
```

Vista Blade (`resources/views/mail/orders/shipped.blade.php`):

```blade theme={null}
<!DOCTYPE html>
<html>
<body>
    <h1>Il tuo ordine è stato spedito</h1>
    <p>Numero ordine: {{ $order->id }}</p>
    <p>Totale: € {{ number_format($order->total) }}</p>
    <p>Grazie per il tuo ordine.</p>
</body>
</html>
```

Puoi passare dati esplicitamente con `with` (proprietà `protected`/`private`).

```php theme={null}
public function __construct(
    protected Order $order,
) {}

public function content(): Content
{
    return new Content(
        view: 'mail.orders.shipped',
        with: [
            'orderId' => $this->order->id,
            'total' => $this->order->total,
        ],
    );
}
```

## Invio

Con la facade `Mail`, usa `to()` e `send()`.

```mermaid theme={null}
flowchart TD
    A["Mail::to()->send(new OrderShipped())"] --> B{"Implementa<br>ShouldQueue?"}
    B -- "No" --> C["Invio sincrono<br>al Mailer"]
    B -- "Sì" --> D["In coda<br>invio in background"]
    D --> C
    C --> E{"Driver MAIL"}
    E --> F["smtp"]
    E --> G["ses / mailgun<br>/ postmark"]
    E --> H["log<br>(sviluppo)"]
```

```php theme={null}
<?php

namespace App\Http\Controllers;

use App\Mail\OrderShipped;
use App\Models\Order;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;

class OrderShipmentController extends Controller
{
    public function store(Request $request): RedirectResponse
    {
        $order = Order::findOrFail($request->order_id);

        Mail::to($request->user())->send(new OrderShipped($order));

        return redirect('/orders');
    }
}
```

CC e BCC:

```php theme={null}
Mail::to($request->user())
    ->cc($ccUsers)
    ->bcc($bccUsers)
    ->send(new OrderShipped($order));
```

Con un mailer specifico:

```php theme={null}
Mail::mailer('postmark')
    ->to($request->user())
    ->send(new OrderShipped($order));
```

## Invio via coda

```php theme={null}
Mail::to($request->user())->queue(new OrderShipped($order));
```

<Warning>
  Con le code serve la configurazione e il worker attivo.
</Warning>

Con delay:

```php theme={null}
Mail::to($request->user())
    ->later(now()->plus(minutes: 10), new OrderShipped($order));
```

Se la Mailable implementa `ShouldQueue`, anche `send()` mette in coda.

```php theme={null}
use Illuminate\Contracts\Queue\ShouldQueue;

class OrderShipped extends Mailable implements ShouldQueue
{
    // ...
}
```

### Connection e coda tramite attribute PHP

Con gli attribute PHP dichiari connection e coda a livello di classe.

```php theme={null}
use Illuminate\Queue\Attributes\Connection;
use Illuminate\Queue\Attributes\Queue;

#[Connection('sqs')]
#[Queue('emails')]
class OrderShipped extends Mailable implements ShouldQueue
{
    // ...
}
```

## Email Markdown

Con il Markdown usi i template Blade responsive di Laravel.

```shell theme={null}
php artisan make:mail OrderShipped --markdown=mail.orders.shipped
```

```php theme={null}
use Illuminate\Mail\Mailables\Content;

public function content(): Content
{
    return new Content(
        markdown: 'mail.orders.shipped',
        with: [
            'url' => route('orders.show', $this->order),
        ],
    );
}
```

Template Markdown:

```blade theme={null}
<x-mail::message>
# Il tuo ordine è stato spedito

Ti informiamo che il tuo ordine è stato spedito.

<x-mail::button :url="$url">
Vedi ordine
</x-mail::button>

Grazie,<br>
{{ config('app.name') }}
</x-mail::message>
```

Componenti disponibili:

| Componente         | Descrizione                                            |
| ------------------ | ------------------------------------------------------ |
| `<x-mail::button>` | Pulsante link (`color`: `primary`, `success`, `error`) |
| `<x-mail::panel>`  | Riquadro evidenziato                                   |
| `<x-mail::table>`  | Tabella in stile Markdown                              |

<Tip>
  Le email Markdown generano automaticamente anche la versione text.
</Tip>

## Anteprima delle email

Restituendo l'istanza Mailable da una route puoi visualizzare l'email nel browser.

```php theme={null}
Route::get('/mailable', function () {
    $order = App\Models\Order::first();
    return new App\Mail\OrderShipped($order);
});
```

## Email in sviluppo locale

Per non inviare email reali in sviluppo, usa [Mailpit](https://github.com/axllent/mailpit).

```ini theme={null}
MAIL_MAILER=smtp
MAIL_HOST=127.0.0.1
MAIL_PORT=1025
```

Laragon e Laravel Herd includono Mailpit di default.

<Info>
  Con il driver `log` le email vengono scritte nel file di log: il modo più semplice per verificarle.
</Info>

```ini theme={null}
MAIL_MAILER=log
```

## Riepilogo

| Obiettivo            | Metodo                            |
| -------------------- | --------------------------------- |
| Creare Mailable      | `php artisan make:mail ClassName` |
| Impostare mittente   | `envelope()` → `from`             |
| Usare template Blade | `content()` → `view`              |
| Usare Markdown       | `content()` → `markdown`          |
| Inviare              | `Mail::to()->send()`              |
| In coda              | `Mail::to()->queue()`             |
| Ritardato            | `Mail::to()->later()`             |


## Related topics

- [Eventi e listener](/it/events.md)
- [Tutorial - Laravel Console Starter](/it/packages/laravel-console-starter/tutorial.md)
- [Contracts (contratti)](/it/contracts.md)
- [Reset della password](/it/passwords.md)
- [Costruire una SPA con Inertia.js](/it/blog/inertia-introduction.md)
