1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Spatie\Pjax\Middleware; |
4
|
|
|
|
5
|
|
|
use Closure; |
6
|
|
|
use Illuminate\Http\Request; |
7
|
|
|
use Illuminate\Http\Response; |
8
|
|
|
use Symfony\Component\DomCrawler\Crawler; |
9
|
|
|
|
10
|
|
|
class FilterIfPjax |
11
|
|
|
{ |
12
|
|
|
/** |
13
|
|
|
* The DomCrawler instance. |
14
|
|
|
* |
15
|
|
|
* @var \Symfony\Component\DomCrawler\Crawler |
16
|
|
|
*/ |
17
|
|
|
protected $crawler; |
18
|
|
|
|
19
|
|
|
/** |
20
|
|
|
* Handle an incoming request. |
21
|
|
|
* |
22
|
|
|
* @param \Illuminate\Http\Request $request |
23
|
|
|
* @param \Closure $next |
24
|
|
|
* |
25
|
|
|
* @return mixed |
26
|
|
|
*/ |
27
|
|
|
public function handle(Request $request, Closure $next) |
28
|
|
|
{ |
29
|
|
|
$response = $next($request); |
30
|
|
|
|
31
|
|
|
if (!$request->pjax() || $response->isRedirection()) { |
32
|
|
|
return $response; |
33
|
|
|
} |
34
|
|
|
|
35
|
|
|
$this->filterResponse($response, $request->header('X-PJAX-Container')) |
|
|
|
|
36
|
|
|
->setUriHeader($response, $request) |
37
|
|
|
->setVersionHeader($response, $request); |
38
|
|
|
|
39
|
|
|
return $response; |
40
|
|
|
} |
41
|
|
|
|
42
|
|
|
/** |
43
|
|
|
* @param \Illuminate\Http\Response $response |
44
|
|
|
* @param string $container |
45
|
|
|
* |
46
|
|
|
* @return $this |
47
|
|
|
*/ |
48
|
|
|
protected function filterResponse(Response $response, $container) |
49
|
|
|
{ |
50
|
|
|
$crawler = $this->getCrawler($response); |
51
|
|
|
|
52
|
|
|
$response->setContent( |
53
|
|
|
$this->makeTitle($crawler). |
54
|
|
|
$this->fetchContainer($crawler, $container) |
55
|
|
|
); |
56
|
|
|
|
57
|
|
|
return $this; |
58
|
|
|
} |
59
|
|
|
|
60
|
|
|
/** |
61
|
|
|
* @param \Symfony\Component\DomCrawler\Crawler $crawler |
62
|
|
|
* |
63
|
|
|
* @return null|string |
64
|
|
|
*/ |
65
|
|
|
protected function makeTitle(Crawler $crawler) |
66
|
|
|
{ |
67
|
|
|
$pageTitle = $crawler->filter('head > title'); |
68
|
|
|
|
69
|
|
|
if (!$pageTitle->count()) { |
70
|
|
|
return; |
71
|
|
|
} |
72
|
|
|
|
73
|
|
|
return "<title>{$pageTitle->html()}</title>"; |
74
|
|
|
} |
75
|
|
|
|
76
|
|
|
/** |
77
|
|
|
* @param \Symfony\Component\DomCrawler\Crawler $crawler |
78
|
|
|
* @param string $container |
79
|
|
|
* |
80
|
|
|
* @return string |
81
|
|
|
*/ |
82
|
|
|
protected function fetchContainer(Crawler $crawler, $container) |
83
|
|
|
{ |
84
|
|
|
$content = $crawler->filter($container); |
85
|
|
|
|
86
|
|
|
if (!$content->count()) { |
87
|
|
|
abort(422); |
88
|
|
|
} |
89
|
|
|
|
90
|
|
|
return $content->html(); |
91
|
|
|
} |
92
|
|
|
|
93
|
|
|
/** |
94
|
|
|
* @param \Illuminate\Http\Response $response |
95
|
|
|
* @param \Illuminate\Http\Request $request |
96
|
|
|
* |
97
|
|
|
* @return $this |
98
|
|
|
*/ |
99
|
|
|
protected function setUriHeader(Response $response, Request $request) |
100
|
|
|
{ |
101
|
|
|
$response->header('X-PJAX-URL', $request->getRequestUri()); |
102
|
|
|
|
103
|
|
|
return $this; |
104
|
|
|
} |
105
|
|
|
|
106
|
|
|
/** |
107
|
|
|
* @param \Illuminate\Http\Response $response |
108
|
|
|
* @param \Illuminate\Http\Request $request |
109
|
|
|
* |
110
|
|
|
* @return $this |
111
|
|
|
*/ |
112
|
|
|
protected function setVersionHeader(Response $response, Request $request) |
|
|
|
|
113
|
|
|
{ |
114
|
|
|
$crawler = $this->getCrawler($this->createReponseWithLowerCaseContent($response)); |
115
|
|
|
$node = $crawler->filter('head > meta[http-equiv="x-pjax-version"]'); |
116
|
|
|
|
117
|
|
|
if ($node->count()) { |
118
|
|
|
$response->header('x-pjax-version', $node->attr('content')); |
119
|
|
|
} |
120
|
|
|
|
121
|
|
|
return $this; |
122
|
|
|
} |
123
|
|
|
|
124
|
|
|
/** |
125
|
|
|
* Get the DomCrawler instance. |
126
|
|
|
* |
127
|
|
|
* @param \Illuminate\Http\Response $response |
128
|
|
|
* |
129
|
|
|
* @return \Symfony\Component\DomCrawler\Crawler |
130
|
|
|
*/ |
131
|
|
|
protected function getCrawler(Response $response) |
132
|
|
|
{ |
133
|
|
|
if ($this->crawler) { |
134
|
|
|
return $this->crawler; |
135
|
|
|
} |
136
|
|
|
|
137
|
|
|
return $this->crawler = new Crawler($response->getContent()); |
138
|
|
|
} |
139
|
|
|
|
140
|
|
|
/** |
141
|
|
|
* Make the content of the given response lowercase. |
142
|
|
|
* |
143
|
|
|
* @param \Illuminate\Http\Response $response |
144
|
|
|
* |
145
|
|
|
* @return \Illuminate\Http\Response |
146
|
|
|
*/ |
147
|
|
|
protected function createReponseWithLowerCaseContent(Response $response) |
148
|
|
|
{ |
149
|
|
|
$lowercaseContent = strtolower($response->getContent()); |
150
|
|
|
|
151
|
|
|
return Response::create($lowercaseContent); |
152
|
|
|
} |
153
|
|
|
} |
154
|
|
|
|
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.