Skip to content

Commit 4a3873b

Browse files
authored
Test mailable can have attachments at runtime
Unclexo
2 parents db1720e + 8d8962d commit 4a3873b

File tree

11 files changed

+405
-0
lines changed

11 files changed

+405
-0
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
namespace App\Http\Controllers;
4+
5+
use Illuminate\Http\Request;
6+
7+
class OrderController extends Controller
8+
{
9+
//
10+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
namespace App\Http\Controllers;
4+
5+
use App\Mail\PostPublished;
6+
use App\Models\Post;
7+
8+
class PostPublishController extends Controller
9+
{
10+
public function previewMailTemplate(int $id)
11+
{
12+
$post = Post::find($id);
13+
14+
return (new PostPublished($post))->render();
15+
}
16+
}

app/Mail/OrderShipped.php

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?php
2+
3+
namespace App\Mail;
4+
5+
use App\Models\Order;
6+
use Illuminate\Bus\Queueable;
7+
use Illuminate\Contracts\Queue\ShouldQueue;
8+
use Illuminate\Mail\Mailable;
9+
use Illuminate\Mail\Mailables\Attachment;
10+
use Illuminate\Mail\Mailables\Content;
11+
use Illuminate\Mail\Mailables\Envelope;
12+
use Illuminate\Queue\SerializesModels;
13+
14+
class OrderShipped extends Mailable
15+
{
16+
use Queueable, SerializesModels;
17+
18+
public Order $order;
19+
20+
/**
21+
* Create a new message instance.
22+
*
23+
* @return void
24+
*/
25+
public function __construct(Order $order)
26+
{
27+
$this->order = $order;
28+
}
29+
30+
/**
31+
* Get the message content definition.
32+
*
33+
* @return \Illuminate\Mail\Mailables\Content
34+
*/
35+
public function content()
36+
{
37+
return new Content(
38+
markdown: 'emails.orders.shipped',
39+
with: [
40+
'url' => url("/orders/{$this->order->id}"),
41+
],
42+
);
43+
}
44+
45+
/**
46+
* Get the attachments for the message.
47+
*
48+
* @return array
49+
*/
50+
public function attachments()
51+
{
52+
return [
53+
Attachment::fromPath(storage_path('app/public/some.pdf')),
54+
Attachment::fromStorageDisk('public', 'other.pdf'),
55+
];
56+
}
57+
}

app/Mail/PostPublished.php

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<?php
2+
3+
namespace App\Mail;
4+
5+
use App\Models\Post;
6+
use Illuminate\Bus\Queueable;
7+
use Illuminate\Contracts\Queue\ShouldQueue;
8+
use Illuminate\Mail\Mailable;
9+
use Illuminate\Mail\Mailables\Address;
10+
use Illuminate\Mail\Mailables\Content;
11+
use Illuminate\Mail\Mailables\Envelope;
12+
use Illuminate\Queue\SerializesModels;
13+
14+
class PostPublished extends Mailable
15+
{
16+
use Queueable, SerializesModels;
17+
18+
public Post $post;
19+
20+
/**
21+
* Create a new message instance.
22+
*
23+
* @return void
24+
*/
25+
public function __construct(Post $post)
26+
{
27+
$this->post = $post;
28+
}
29+
30+
/**
31+
* Get the message envelope.
32+
*
33+
* @return \Illuminate\Mail\Mailables\Envelope
34+
*/
35+
public function envelope()
36+
{
37+
return new Envelope(
38+
from: new Address('[email protected]', 'Medium Online Publication'),
39+
to: new Address('[email protected]', 'Abu Jobaer'),
40+
bcc: new Address('[email protected]', 'Ria Jobaer'),
41+
replyTo: [
42+
new Address('[email protected]', 'Taylor Otwell'),
43+
],
44+
subject: 'Post Published',
45+
tags: ['architecture', 'design-patterns'],
46+
metadata: [
47+
'post_id' => $this->post->id,
48+
],
49+
);
50+
}
51+
52+
/**
53+
* Get the message content definition.
54+
*
55+
* @return \Illuminate\Mail\Mailables\Content
56+
*/
57+
public function content()
58+
{
59+
return new Content(
60+
markdown: 'emails.posts.published',
61+
with: [
62+
'url' => url("/posts/{$this->post->id}"),
63+
],
64+
);
65+
}
66+
67+
/**
68+
* Get the attachments for the message.
69+
*
70+
* @return array
71+
*/
72+
public function attachments()
73+
{
74+
return [];
75+
}
76+
}

app/Models/Order.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
namespace App\Models;
4+
5+
use Illuminate\Database\Eloquent\Factories\HasFactory;
6+
use Illuminate\Database\Eloquent\Model;
7+
8+
class Order extends Model
9+
{
10+
use HasFactory;
11+
}

database/factories/OrderFactory.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
namespace Database\Factories;
4+
5+
use App\Models\User;
6+
use Illuminate\Database\Eloquent\Factories\Factory;
7+
8+
/**
9+
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Order>
10+
*/
11+
class OrderFactory extends Factory
12+
{
13+
/**
14+
* Define the model's default state.
15+
*
16+
* @return array<string, mixed>
17+
*/
18+
public function definition()
19+
{
20+
return [
21+
'user_id' => User::factory()->create(),
22+
'shipper_id' => $this->faker->numberBetween(1, 10),
23+
'name' => $this->faker->userName,
24+
'price' => $this->faker->numberBetween(100, 10000),
25+
];
26+
}
27+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
use Illuminate\Database\Migrations\Migration;
4+
use Illuminate\Database\Schema\Blueprint;
5+
use Illuminate\Support\Facades\Schema;
6+
7+
return new class extends Migration
8+
{
9+
/**
10+
* Run the migrations.
11+
*
12+
* @return void
13+
*/
14+
public function up()
15+
{
16+
Schema::create('orders', function (Blueprint $table) {
17+
$table->id();
18+
$table->unsignedBigInteger('user_id');
19+
$table->unsignedBigInteger('shipper_id');
20+
$table->string('name');
21+
$table->unsignedDecimal('price');
22+
$table->timestamps();
23+
});
24+
}
25+
26+
/**
27+
* Reverse the migrations.
28+
*
29+
* @return void
30+
*/
31+
public function down()
32+
{
33+
Schema::dropIfExists('orders');
34+
}
35+
};
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<x-mail::message>
2+
# Order Shipped
3+
4+
Your order has been shipped. The order summary:
5+
6+
Order ID: {{ $order->id }}
7+
Name: {{ $order->name }}
8+
Price: {{ $order->price }}
9+
10+
<x-mail::button :url="$url">
11+
View Order
12+
</x-mail::button>
13+
14+
Thanks,<br>
15+
{{ config('app.name') }}
16+
</x-mail::message>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<x-mail::message>
2+
# Post Published
3+
4+
Your post has been published on Medium
5+
6+
<x-mail::button :url="$url">
7+
View Post
8+
</x-mail::button>
9+
10+
Thanks,<br>
11+
{{ config('app.name') }}
12+
</x-mail::message>

routes/web.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
use App\Http\Controllers\HomeController;
44
use App\Http\Controllers\MediaUploaderController;
55
use App\Http\Controllers\PostController;
6+
use App\Http\Controllers\PostPublishController;
67
use Illuminate\Support\Facades\Route;
78

89
/*
@@ -56,4 +57,9 @@
5657

5758
Route::get('/upload/download/{filename}', 'download')->name('upload.download');
5859
});
60+
61+
Route::prefix('mailable')->group(function() {
62+
Route::get('template/{id}', [PostPublishController::class, 'previewMailTemplate'])
63+
->name('mailable.preview');
64+
});
5965
});

0 commit comments

Comments
 (0)