Skip to content

Commit 6a05b71

Browse files
committed
Merge branch '@feature/driver-support'
2 parents dce4177 + be68213 commit 6a05b71

13 files changed

+308
-25
lines changed

README.md

Lines changed: 75 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Laravel package for manage your URL redirects in database to get better SEO results
1+
# Laravel package for manage your URL redirects in database or other sources to get better SEO results
22

33
[![Latest Version on Packagist](https://img.shields.io/packagist/v/sirodiaz/laravel-redirection.svg?style=flat-square)](https://packagist.org/packages/SiroDiaz/laravel-redirection)
44
[![GitHub Tests Action Status](https://img.shields.io/github/workflow/status/SiroDiaz/laravel-redirection/run-tests?label=tests&style=flat-square)](https://github.com/SiroDiaz/laravel-redirection/actions?query=workflow%3Arun-tests+branch%3Amain)
@@ -55,24 +55,89 @@ return [
5555

5656
/*
5757
|--------------------------------------------------------------------------
58-
| Default model used for redirections
58+
| Default Redirect status code (in case of not defined)
59+
|--------------------------------------------------------------------------
60+
|
61+
| Status code used by default to redirect from an old URL to a new mapped
62+
| URL.
63+
|
64+
*/
65+
'default_status_code' => (int)env('REDIRECT_DEFAULT_STATUS', 301),
66+
67+
/*
68+
|--------------------------------------------------------------------------
69+
| Redirect Driver
70+
|--------------------------------------------------------------------------
71+
|
72+
| Here you may specify the default redirect driver that you want to use.
73+
| The "config" driver is used by default when you want to code faster.
74+
| Consider database driver better for admin panel configuration backed by
75+
| a relational DB.
76+
|
77+
*/
78+
'driver' => env('REDIRECT_DRIVER', 'config'),
79+
80+
/*
81+
|--------------------------------------------------------------------------
82+
| Array containing all available drivers and its implementations and source
5983
|--------------------------------------------------------------------------
6084
|
6185
| Concrete implementation for the "redirection model".
62-
| To extend or replace this functionality, change the value below with your full "redirection model" FQN.
86+
| To extend or replace this functionality, change the value below with
87+
| your full "redirection model" FQN.
6388
|
6489
| Your class will have to (first option is recommended):
6590
| - extend the "SiroDiaz\Redirection\Models\Redirection" class
6691
| - or at least implement the "SiroDiaz\Redirection\Contracts\RedirectionModelContract" interface.
6792
|
6893
| Regardless of the concrete implementation below, you can still use it like:
69-
| - app('redirection.model') OR app('\SiroDiaz\Redirection\Models\Redirection\Contracts\RedirectsModelContract')
70-
| - or you could even use your own class as a direct implementation
94+
| - app('redirection.') OR app('\SiroDiaz\Redirection\Contracts\RedirectionModelContract')
95+
| - or you could even use your own class as a direct implementation. For this
96+
| case you must extend from "SiroDiaz\Redirection\Models\Redirection" model class and
97+
| replace in the published config file 'drivers.database.source'.
98+
|
7199
|
72100
*/
73-
'model' => SiroDiaz\Redirection\Models\Redirection::class,
101+
'drivers' => [
102+
'config' => [
103+
'driver' => SiroDiaz\Redirection\Drivers\FileRedirector::class,
104+
'source' => 'redirection.urls',
105+
],
106+
'database' => [
107+
'driver' => SiroDiaz\Redirection\Drivers\DatabaseRedirector::class,
108+
'source' => SiroDiaz\Redirection\Models\Redirection::class,
109+
],
110+
],
111+
112+
/*
113+
|--------------------------------------------------------------------------
114+
| Url list with redirections used for config driver
115+
|--------------------------------------------------------------------------
116+
|
117+
| You can use urls array of two different ways. The simple one uses the
118+
| default redirect status code ('redirection.default_status_code').
119+
| Example:
120+
| 'urls' => [
121+
| '/old/url' => '/new/url',
122+
| '/another/old/url' => '/another/new/url',
123+
| '/url/with?id=123' => '/url/with/123',
124+
| ],
125+
|
126+
| The second way to write redirect urls in your config/redirection.php
127+
| is using associative arrays. You can combine this method with the previous one.
128+
| Look at this example:
129+
| 'urls' => [
130+
| '/old/url' => ['new_url' => '/new/url', 'status_code' => 302],
131+
| '/another/old/url' => '/another/new/url',
132+
| '/url/with?id=123' => ['new_url' => '/url/with/123'],
133+
| ],
134+
|
135+
*/
136+
'urls' => [],
137+
74138
];
75139

140+
76141
```
77142

78143
You can change and extend the default `SiroDiaz\Redirection\Models\Redirection` model class.
@@ -111,7 +176,10 @@ Ey! **don't forget** to append the middleware `SiroDiaz\Redirection\RedirectRequ
111176
],
112177
```
113178

114-
## Testing
179+
## Extending and creating new redirect Drivers
180+
**TODO**
181+
182+
## Testing this package for contribution
115183

116184
```bash
117185
composer test

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "sirodiaz/laravel-redirection",
3-
"description": "Laravel package that allows storing in database urls to redirect for SEO purposes",
3+
"description": "Laravel package that allows storing in database (or other sources) urls to redirect for SEO purposes",
44
"keywords": [
55
"sirodiaz",
66
"laravel",

config/redirection.php

Lines changed: 69 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,84 @@
1818

1919
/*
2020
|--------------------------------------------------------------------------
21-
| Default model used for redirections
21+
| Default Redirect status code (in case of not defined)
22+
|--------------------------------------------------------------------------
23+
|
24+
| Status code used by default to redirect from an old URL to a new mapped
25+
| URL.
26+
|
27+
*/
28+
'default_status_code' => (int)env('REDIRECT_DEFAULT_STATUS', 301),
29+
30+
/*
31+
|--------------------------------------------------------------------------
32+
| Redirect Driver
33+
|--------------------------------------------------------------------------
34+
|
35+
| Here you may specify the default redirect driver that you want to use.
36+
| The "config" driver is used by default when you want to code faster.
37+
| Consider database driver better for admin panel configuration backed by
38+
| a relational DB.
39+
|
40+
*/
41+
'driver' => env('REDIRECT_DRIVER', 'config'),
42+
43+
/*
44+
|--------------------------------------------------------------------------
45+
| Array containing all available drivers and its implementations and source
2246
|--------------------------------------------------------------------------
2347
|
2448
| Concrete implementation for the "redirection model".
25-
| To extend or replace this functionality, change the value below with your full "redirection model" FQN.
49+
| To extend or replace this functionality, change the value below with
50+
| your full "redirection model" FQN.
2651
|
2752
| Your class will have to (first option is recommended):
2853
| - extend the "SiroDiaz\Redirection\Models\Redirection" class
2954
| - or at least implement the "SiroDiaz\Redirection\Contracts\RedirectionModelContract" interface.
3055
|
3156
| Regardless of the concrete implementation below, you can still use it like:
32-
| - app('redirection.model') OR app('\SiroDiaz\Redirection\Models\Redirection\Contracts\RedirectsModelContract')
33-
| - or you could even use your own class as a direct implementation
57+
| - app('redirection.') OR app('\SiroDiaz\Redirection\Contracts\RedirectionModelContract')
58+
| - or you could even use your own class as a direct implementation. For this
59+
| case you must extend from "SiroDiaz\Redirection\Models\Redirection" model class and
60+
| replace in the published config file 'drivers.database.source'.
61+
|
62+
|
63+
*/
64+
'drivers' => [
65+
'config' => [
66+
'driver' => SiroDiaz\Redirection\Drivers\FileRedirector::class,
67+
'source' => 'redirection.urls',
68+
],
69+
'database' => [
70+
'driver' => SiroDiaz\Redirection\Drivers\DatabaseRedirector::class,
71+
'source' => SiroDiaz\Redirection\Models\Redirection::class,
72+
],
73+
],
74+
75+
/*
76+
|--------------------------------------------------------------------------
77+
| Url list with redirections used for config driver
78+
|--------------------------------------------------------------------------
79+
|
80+
| You can use urls array of two different ways. The simple one uses the
81+
| default redirect status code ('redirection.default_status_code').
82+
| Example:
83+
| 'urls' => [
84+
| '/old/url' => '/new/url',
85+
| '/another/old/url' => '/another/new/url',
86+
| '/url/with?id=123' => '/url/with/123',
87+
| ],
88+
|
89+
| The second way to write redirect urls in your config/redirection.php
90+
| is using associative arrays. You can combine this method with the previous one.
91+
| Look at this example:
92+
| 'urls' => [
93+
| '/old/url' => ['new_url' => '/new/url', 'status_code' => 302],
94+
| '/another/old/url' => '/another/new/url',
95+
| '/url/with?id=123' => ['new_url' => '/url/with/123'],
96+
| ],
3497
|
3598
*/
36-
'model' => SiroDiaz\Redirection\Models\Redirection::class,
99+
'urls' => [],
100+
37101
];

src/Contracts/RedirectionModelContract.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,5 +46,5 @@ public function syncOldRedirects(self $model, string $finalUrl): void;
4646
* @param string $path
4747
* @return RedirectionModelContract|null
4848
*/
49-
public static function findValidOrNull(string $path);
49+
public static function findValidOrNull(string $path): ?RedirectionModelContract;
5050
}

src/Contracts/Redirector.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
namespace SiroDiaz\Redirection\Contracts;
4+
5+
use SiroDiaz\Redirection\Redirect;
6+
7+
interface Redirector
8+
{
9+
public function getRedirectFor(string $path): ?Redirect;
10+
}

src/Drivers/DatabaseRedirector.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
namespace SiroDiaz\Redirection\Drivers;
4+
5+
use SiroDiaz\Redirection\Contracts\Redirector;
6+
use SiroDiaz\Redirection\Redirect;
7+
8+
class DatabaseRedirector implements Redirector
9+
{
10+
/** @var string */
11+
protected string $driver;
12+
13+
public function __construct(string $driver = 'database')
14+
{
15+
$this->driver = $driver;
16+
}
17+
18+
public function getRedirectFor(string $path): ?Redirect
19+
{
20+
$model = app()->make(
21+
config("redirection.drivers.{$this->driver}.source"),
22+
[$this->driver],
23+
);
24+
25+
$redirect = $model->findValidOrNull($path);
26+
27+
return $redirect !== null
28+
? new Redirect($redirect->old_url, $redirect->new_url, $redirect->status_code)
29+
: null;
30+
}
31+
}

src/Drivers/FileRedirector.php

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
namespace SiroDiaz\Redirection\Drivers;
4+
5+
use SiroDiaz\Redirection\Contracts\Redirector;
6+
use SiroDiaz\Redirection\Redirect;
7+
8+
class FileRedirector implements Redirector
9+
{
10+
/** @var string */
11+
protected string $driver;
12+
13+
public function __construct(string $driver = 'config')
14+
{
15+
$this->driver = $driver;
16+
}
17+
18+
public function getRedirectFor(string $path): ?Redirect
19+
{
20+
$redirect = config(config("redirection.drivers.{$this->driver}.source"));
21+
22+
if (! array_key_exists($path, $redirect)) {
23+
return null;
24+
}
25+
26+
$redirect = $redirect[$path];
27+
// in case of associative array with redirection status code
28+
if (is_array($redirect)) {
29+
return new Redirect(
30+
$path,
31+
$redirect['new_url'],
32+
$redirect['status_code'] ?? config('redirection.default_status_code')
33+
);
34+
}
35+
36+
return new Redirect(
37+
$path,
38+
$redirect,
39+
config('redirection.default_status_code'),
40+
);
41+
}
42+
}

src/Models/Redirection.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ public function setOldUrlAttribute(string $value): void
9494
* @param string $value
9595
* @returns void
9696
*/
97-
public function setNewUrlAttribute(string $value)
97+
public function setNewUrlAttribute(string $value): void
9898
{
9999
$this->attributes['new_url'] = trim(parse_url($value)['path'], '/');
100100
}

src/Redirect.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
namespace SiroDiaz\Redirection;
4+
5+
class Redirect
6+
{
7+
/** @var string */
8+
public string $oldUrl;
9+
10+
/** @var string */
11+
public string $newUrl;
12+
13+
/** @var int */
14+
public int $statusCode;
15+
16+
public function __construct($oldUrl, $newUrl, $statusCode)
17+
{
18+
$this->oldUrl = $oldUrl;
19+
$this->newUrl = $newUrl;
20+
$this->statusCode = $statusCode;
21+
}
22+
}

src/RedirectRequests.php

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,21 @@ class RedirectRequests
1818
*/
1919
public function handle(Request $request, Closure $next)
2020
{
21-
$redirection = app()->make(config('redirection.model'))->findValidOrNull($request->path());
21+
$driverName = config('redirection.driver');
22+
23+
$redirectorDriverInstance = app()->make(
24+
config("redirection.drivers.{$driverName}.driver"),
25+
[$driverName],
26+
);
27+
$redirection = $redirectorDriverInstance->getRedirectFor($request->path());
2228

2329
if (! $redirection && $request->getQueryString()) {
2430
$path = sprintf('%s?%s', $request->path(), $request->getQueryString());
25-
$redirection = app()->make(config('redirection.model'))->findValidOrNull($path);
31+
$redirection = $redirectorDriverInstance->getRedirectFor($path);
2632
}
2733

28-
if ($redirection && $redirection->exists) {
29-
return redirect($redirection->new_url, $redirection->status_code);
34+
if ($redirection) {
35+
return redirect($redirection->newUrl, $redirection->statusCode);
3036
}
3137

3238
return $next($request);

0 commit comments

Comments
 (0)