added email subscriptions

This commit is contained in:
2024-09-27 22:16:29 +10:00
parent db018e9120
commit b10b6b712e
10 changed files with 203 additions and 5 deletions

View File

@@ -0,0 +1,44 @@
<?php
namespace App\Http\Controllers;
use App\Models\EmailSubscriptions;
use App\Models\SentEmail;
use Illuminate\Http\Request;
class UnsubscribeController extends Controller
{
/**
* Display a listing of the resource.
*/
public function destroy($email)
{
$emailModel = SentEmail::where('id', $email)->first();
if (!$emailModel) {
// Email not found, redirect to home page with a message
return redirect()->route('index')->with([
'message' => 'The unsubscribe link is invalid or has expired.',
'message-title' => 'Invalid Unsubscribe Link',
'message-type' => 'warning'
]);
}
// Existing unsubscribe logic
$subscriptions = EmailSubscriptions::where('email', $emailModel->recipient)->get();
if ($subscriptions->isEmpty()) {
session()->flash('message', 'You are already unsubscribed.');
session()->flash('message-title', 'Already Unsubscribed');
session()->flash('message-type', 'info');
} else {
EmailSubscriptions::where('email', $emailModel->recipient)->delete();
session()->flash('message', 'You have been successfully unsubscribed.');
session()->flash('message-title', 'Unsubscribed');
session()->flash('message-type', 'success');
}
return redirect()->route('index');
}
}

View File

@@ -2,6 +2,7 @@
namespace App\Jobs;
use App\Models\SentEmail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
@@ -48,6 +49,18 @@ class SendEmail implements ShouldQueue
*/
public function handle(): void
{
// Record sent email
$sentEmail = SentEmail::create([
'recipient' => $this->to,
'mailable_class' => get_class($this->mailable)
]);
// Add unsubscribe link if mailable supports it
if (method_exists($this->mailable, 'withUnsubscribeLink')) {
$unsubscribeLink = route('unsubscribe', ['email' => $sentEmail->id]);
$this->mailable->withUnsubscribeLink($unsubscribeLink);
}
Mail::to($this->to)->send($this->mailable);
}
}

View File

@@ -0,0 +1,58 @@
<?php
namespace App\Mail;
use App\Models\Workshop;
use App\Traits\HasUnsubscribeLink;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Carbon;
class UpcomingWorkshops extends Mailable
{
use Queueable, SerializesModels, HasUnsubscribeLink;
public $subject;
public $email;
public $workshops;
public function __construct($email, $subject = 'Upcoming Workshops 🌟')
{
$this->subject = $subject;
$this->email = $email;
$this->workshops = $this->getUpcomingWorkshops();
}
private function getUpcomingWorkshops()
{
$startDate = Carbon::now()->addDays(3);
$endDate = Carbon::now()->addDays(42);
return Workshop::select('workshops.*', 'locations.name as location_name')
->join('locations', 'workshops.location_id', '=', 'locations.id')
->whereIn('workshops.status', ['open','scheduled'])
->whereBetween('workshops.starts_at', [$startDate, $endDate])
->where('locations.name', 'not like', '%private%')
->orderBy('locations.name')
->orderBy('workshops.starts_at')
->get();
}
public function build()
{
// Bail if there are no upcoming workshops
if ($this->workshops->isEmpty()) {
return false;
}
return $this
->subject($this->subject)
->markdown('emails.upcoming-workshops')
->with([
'email' => $this->email,
'workshops' => $this->workshops,
'unsubscribeLink' => $this->unsubscribeLink
]);
}
}

View File

@@ -7,8 +7,6 @@ use Illuminate\Database\Eloquent\Model;
class EmailSubscriptions extends Model
{
use HasFactory;
/**
* The attributes that are mass assignable.
*

View File

@@ -0,0 +1,14 @@
<?php
namespace App\Traits;
trait HasUnsubscribeLink
{
protected $unsubscribeLink;
public function withUnsubscribeLink($link)
{
$this->unsubscribeLink = $link;
return $this;
}
}

View File

@@ -6,6 +6,8 @@ use Illuminate\Support\Str;
trait Slug
{
protected $appendsSlug = ['slug'];
/**
* Boot function from Laravel.
*
@@ -20,6 +22,16 @@ trait Slug
});
}
/**
* Initialize the trait.
*
* @return void
*/
public function initializeSlug(): void
{
$this->appends = array_merge($this->appends ?? [], $this->appendsSlug);
}
/**
* Get the value indicating whether the IDs are incrementing.
*
@@ -47,7 +59,7 @@ trait Slug
*/
public function getRouteKey()
{
return $this->slug();
return $this->slug;
}
/**
@@ -68,7 +80,7 @@ trait Slug
*
* @return string
*/
public function slug()
public function getSlugAttribute()
{
return Str::slug($this->title) . '-' . $this->id;
}