FilterIfInstantClick::isInstantClickRequest()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
3
namespace Devmatic\InstantClick\Middleware;
4
5
use Closure;
6
use Illuminate\Http\Request;
7
use Illuminate\Http\Response;
8
use Symfony\Component\DomCrawler\Crawler;
9
10
class FilterIfInstantClick
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 (!$this->isInstantClickRequest($request) || $response->isRedirection()) {
32
            return $response;
33
        }
34
35
        $this->filterResponse($response, $container = 'body')
36
            ->setResponseHeader($response);
37
38
        return $response;
39
    }
40
41
    /**
42
     * @param \Illuminate\Http\Response $response
43
     * @param string                    $container
44
     *
45
     * @return $this
46
     */
47
    protected function filterResponse(Response $response, $container)
48
    {
49
        $crawler = $this->getCrawler($response);
50
51
        $response->setContent(
52
            $this->makeTitle($crawler) .
53
            $this->fetchContainer($crawler, $container)
54
        );
55
56
        return $this;
57
    }
58
59
    /**
60
     * @param \Symfony\Component\DomCrawler\Crawler $crawler
61
     *
62
     * @return null|string
63
     */
64
    protected function makeTitle(Crawler $crawler)
65
    {
66
        $pageTitle = $crawler->filter('head > title');
67
68
        if (!$pageTitle->count()) {
69
            return;
70
        }
71
72
        return "<title>{$pageTitle->html()}</title>";
73
    }
74
75
    /**
76
     * @param \Symfony\Component\DomCrawler\Crawler $crawler
77
     * @param string                                $container
78
     *
79
     * @return string
80
     */
81
    protected function fetchContainer(Crawler $crawler, $container)
82
    {
83
        $content = $crawler->filter($container);
84
85
        if (!$content->count()) {
86
            abort(422);
87
        }
88
89
        return $content->html();
90
    }
91
92
    /**
93
     * Get the DomCrawler instance.
94
     *
95
     * @param \Illuminate\Http\Response $response
96
     *
97
     * @return \Symfony\Component\DomCrawler\Crawler
98
     */
99
    protected function getCrawler(Response $response)
100
    {
101
        if ($this->crawler) {
102
            return $this->crawler;
103
        }
104
105
        return $this->crawler = new Crawler($response->getContent());
106
    }
107
108
109
    /**
110
     * Determine if the request is the result of an InstantClick call.
111
     *
112
     * @return bool
113
     */
114
    public function isInstantClickRequest(Request $request)
115
    {
116
        return $request->headers->get('X-INSTANTCLICK') == true;
117
    }
118
119
    /**
120
     * @param \Illuminate\Http\Response $response
121
     *
122
     * @return $this
123
     * @internal param \Illuminate\Http\Request $request
124
     *
125
     */
126
    protected function setResponseHeader(Response $response)
127
    {
128
        $response->header('X-INSTANTCLICK', "true");
129
130
        return $this;
131
    }
132
133
}
134