1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* @link https://github.com/vuongxuongminh/laravel-mobile-first |
4
|
|
|
* |
5
|
|
|
* @copyright (c) Vuong Xuong Minh |
6
|
|
|
* @license [MIT](https://opensource.org/licenses/MIT) |
7
|
|
|
*/ |
8
|
|
|
|
9
|
|
|
namespace VXM\MobileFirst; |
10
|
|
|
|
11
|
|
|
use Closure; |
12
|
|
|
use Illuminate\Support\Arr; |
13
|
|
|
use Jenssegers\Agent\Agent; |
14
|
|
|
use Illuminate\Support\Facades\Redirect; |
15
|
|
|
|
16
|
|
|
/** |
17
|
|
|
* @author Vuong Minh <[email protected]> |
18
|
|
|
* @since 1.0.0 |
19
|
|
|
*/ |
20
|
|
|
class MobileRedirect |
21
|
|
|
{ |
22
|
|
|
/** |
23
|
|
|
* Mobile base url. |
24
|
|
|
* |
25
|
|
|
* @var string |
26
|
|
|
*/ |
27
|
|
|
protected $baseUrl; |
28
|
|
|
|
29
|
|
|
/** |
30
|
|
|
* Keep url path when redirect to `baseUrl`. |
31
|
|
|
* |
32
|
|
|
* @var bool |
33
|
|
|
*/ |
34
|
|
|
protected $keepPath; |
35
|
|
|
|
36
|
|
|
/** |
37
|
|
|
* Methods should redirect. |
38
|
|
|
* |
39
|
|
|
* @var array |
40
|
|
|
*/ |
41
|
|
|
protected $methods; |
42
|
|
|
|
43
|
|
|
/** |
44
|
|
|
* Redirect status code. |
45
|
|
|
* |
46
|
|
|
* @var int |
47
|
|
|
*/ |
48
|
|
|
protected $statusCode; |
49
|
|
|
|
50
|
|
|
/** |
51
|
|
|
* Create new MobileRedirect instance. |
52
|
|
|
* |
53
|
|
|
* @param string $baseUrl |
54
|
|
|
* @param bool $keepPath |
55
|
|
|
* @param int $statusCode |
56
|
|
|
*/ |
57
|
|
|
public function __construct(string $baseUrl, bool $keepPath, int $statusCode, array $methods) |
58
|
|
|
{ |
59
|
|
|
$this->baseUrl = $baseUrl; |
60
|
|
|
$this->methods = $methods; |
61
|
|
|
$this->keepPath = $keepPath; |
62
|
|
|
$this->statusCode = $statusCode; |
63
|
|
|
} |
64
|
|
|
|
65
|
|
|
/** |
66
|
|
|
* Redirect to mobile site if end-user not using desktop device. |
67
|
|
|
* |
68
|
|
|
* @param \Illuminate\Http\Request $request |
69
|
|
|
* @param \Closure $next |
70
|
|
|
* @return mixed |
71
|
|
|
*/ |
72
|
|
|
public function handle($request, Closure $next) |
73
|
|
|
{ |
74
|
|
|
if ($this->shouldRedirect($request)) { |
75
|
|
|
return Redirect::to($this->getUrlFor($request), $this->statusCode); |
76
|
|
|
} |
77
|
|
|
|
78
|
|
|
return $next($request); |
79
|
|
|
} |
80
|
|
|
|
81
|
|
|
/** |
82
|
|
|
* Return should redirect or not by request given. |
83
|
|
|
* |
84
|
|
|
* @param \Illuminate\Http\Request $request |
85
|
|
|
* @return bool |
86
|
|
|
*/ |
87
|
|
|
protected function shouldRedirect($request): bool |
88
|
|
|
{ |
89
|
|
|
$agent = new Agent($request->server()); |
|
|
|
|
90
|
|
|
|
91
|
|
|
return ! $agent->isDesktop() && in_array($request->getMethod(), $this->methods); |
92
|
|
|
} |
93
|
|
|
|
94
|
|
|
/** |
95
|
|
|
* Get url for request. |
96
|
|
|
* |
97
|
|
|
* @param \Illuminate\Http\Request $request |
98
|
|
|
* @return string |
99
|
|
|
*/ |
100
|
|
|
protected function getUrlFor($request): string |
101
|
|
|
{ |
102
|
|
|
$url = $this->baseUrl; |
103
|
|
|
|
104
|
|
|
if ($this->keepPath) { |
105
|
|
|
$url = rtrim($url).$request->getPathInfo(); |
106
|
|
|
|
107
|
|
|
if ($query = Arr::query($request->query())) { |
|
|
|
|
108
|
|
|
$url .= '?'.$query; |
109
|
|
|
} |
110
|
|
|
} |
111
|
|
|
|
112
|
|
|
return $url; |
113
|
|
|
} |
114
|
|
|
} |
115
|
|
|
|
This check looks at variables that are passed out again to other methods.
If the outgoing method call has stricter type requirements than the method itself, an issue is raised.
An additional type check may prevent trouble.