|
3 | 3 | namespace Statikbe\FilamentFlexibleContentBlockPages\Listeners; |
4 | 4 |
|
5 | 5 | use Illuminate\Http\Response; |
| 6 | +use Illuminate\Support\Facades\DB; |
6 | 7 | use Statikbe\FilamentFlexibleContentBlockPages\Models\Page; |
7 | 8 | use Statikbe\FilamentFlexibleContentBlockPages\Models\Redirect; |
8 | 9 | use Statikbe\FilamentFlexibleContentBlocks\Events\SlugChanged; |
@@ -33,16 +34,41 @@ public function handle(SlugChanged $event): void |
33 | 34 | $oldUrlPath = parse_url($oldUrl, PHP_URL_PATH); |
34 | 35 | $newUrlPath = parse_url($newUrl, PHP_URL_PATH); |
35 | 36 |
|
36 | | - $redirectExists = Redirect::where('old_url', $oldUrlPath) |
37 | | - ->where('new_url', $newUrlPath) |
38 | | - ->exists(); |
| 37 | + try { |
| 38 | + DB::beginTransaction(); |
39 | 39 |
|
40 | | - if (! $redirectExists) { |
41 | | - $redirect = new Redirect; |
42 | | - $redirect->old_url = $oldUrlPath; |
43 | | - $redirect->new_url = $newUrlPath; |
44 | | - $redirect->status_code = Response::HTTP_MOVED_PERMANENTLY; |
45 | | - $redirect->save(); |
| 40 | + // clean up old redirects & avoid circular references: |
| 41 | + // Rule 1: Delete records where $newUrlPath matches existing old_url. |
| 42 | + // This means that the starting point of the redirect, has been recreated. |
| 43 | + Redirect::where('old_url', $newUrlPath)->delete(); |
| 44 | + |
| 45 | + // Rule 2: Update records where $oldUrlPath matches existing new_url. |
| 46 | + // This means that old slug, was already the destination of an existing redirect, so to avoid |
| 47 | + // hopping multiple redirects, we update the existing redirect to the new slug. |
| 48 | + Redirect::where('new_url', $oldUrlPath)->update(['new_url' => $newUrlPath]); |
| 49 | + |
| 50 | + // Rule 3: Delete self-redirects |
| 51 | + // Maybe we have created cases were the source and destination is the same. |
| 52 | + Redirect::whereColumn('old_url', 'new_url')->delete(); |
| 53 | + |
| 54 | + // Rule 4: Add a new redirect if it doesn't exist yet |
| 55 | + $redirectExists = Redirect::where('old_url', $oldUrlPath) |
| 56 | + ->where('new_url', $newUrlPath) |
| 57 | + ->exists(); |
| 58 | + |
| 59 | + if (!$redirectExists) { |
| 60 | + $redirect = new Redirect; |
| 61 | + $redirect->old_url = $oldUrlPath; |
| 62 | + $redirect->new_url = $newUrlPath; |
| 63 | + $redirect->status_code = Response::HTTP_MOVED_PERMANENTLY; |
| 64 | + $redirect->save(); |
| 65 | + } |
| 66 | + |
| 67 | + DB::commit(); |
| 68 | + } |
| 69 | + catch (\Exception $e) { |
| 70 | + report($e); |
| 71 | + DB::rollBack(); |
46 | 72 | } |
47 | 73 | } |
48 | 74 | } |
|
0 commit comments