AmpOptimizerSubscriber::isEnabled()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 3
rs 10
ccs 2
cts 2
cp 1
cc 1
nc 1
nop 0
crap 1
1
<?php
2
3
namespace Hola\AmpToolboxBundle\EventSubscriber;
4
5
use AmpProject\Optimizer\ErrorCollection;
6
use AmpProject\Optimizer\TransformationEngine;
7
use Psr\Log\LoggerInterface;
8
use Sunra\PhpSimple\HtmlDomParser;
9
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
10
use Symfony\Component\HttpFoundation\Request;
11
use Symfony\Component\HttpFoundation\Response;
12
use Symfony\Component\HttpKernel\Event\ResponseEvent;
13
use Symfony\Component\HttpKernel\KernelEvents;
14
15
/**
16
 * Listen response event and optimize html
17
 * Class AmpOptimizerSubscriber
18
 * @package Hola\AmpToolboxBundle\EventSubscriber
19
 */
20
class AmpOptimizerSubscriber implements EventSubscriberInterface
21
{
22
23
    /**
24
     * @var LoggerInterface
25
     */
26
    private $logger;
27
28
    /**
29
     * @var TransformationEngine
30
     */
31
    private $transformationEngine;
32
33
    /**
34
     * @var array
35
     */
36
    private $config;
37
38
    /**
39
     * @var ErrorCollection
40
     */
41
    private $errorCollection;
42
43
    /**
44
     * AmpOptimizerSubscriber constructor.
45
     * @param LoggerInterface $logger
46
     * @param TransformationEngine $transformationEngine
47
     * @param $config
48
     */
49 7
    public function __construct(LoggerInterface $logger, TransformationEngine $transformationEngine, $config)
50
    {
51 7
        $this->config = $config;
52 7
        $this->logger = $logger;
53 7
        $this->transformationEngine = $transformationEngine;
54 7
        $this->errorCollection = new ErrorCollection();
55 7
    }
56
57
    /**
58
     * @return array|array[]
59
     */
60 1
    public static function getSubscribedEvents()
61
    {
62
        return [
63 1
            KernelEvents::RESPONSE => ['onKernelResponse', -10],
64
        ];
65
    }
66
67
    /**
68
     * @param ResponseEvent $event
69
     * @return void
70
     */
71 6
    public function onKernelResponse(ResponseEvent $event): void
72
    {
73 6
        if (!array_key_exists('transform_enabled', $this->config) ||
74 6
            false === $this->config['transform_enabled']) {
75 2
            return;
76
        }
77
78 4
        if (!$event->isMasterRequest()) {
0 ignored issues
show
Deprecated Code introduced by
The function Symfony\Component\HttpKe...vent::isMasterRequest() has been deprecated: since symfony/http-kernel 5.3, use isMainRequest() instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

78
        if (!/** @scrutinizer ignore-deprecated */ $event->isMasterRequest()) {

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
79 1
            return;
80
        }
81
82 3
        if (!$this->isAmpHtml($event->getResponse(), $event->getRequest())) {
83 1
            return;
84
        }
85
86 2
        $optimizedHtml = $this->transformationEngine->optimizeHtml(
87 2
            $event->getResponse()->getContent(),
88 2
            $this->errorCollection
89
        );
90
91 2
        $this->handleErrors();
92
93 2
        $event->getResponse()->setContent($optimizedHtml);
94 2
    }
95
96
    /**
97
     * @param Response $response
98
     * @param Request $request
99
     * @return bool
100
     */
101 3
    private function isAmpHtml(Response $response, Request $request): bool
102
    {
103 3
        $pathInfo = pathInfo($request->getUri());
104 3
        if (isset($pathInfo['extension']) && $pathInfo['extension'] !== 'html') {
105 1
            return false;
106
        }
107
108 3
        $contentType = $response->headers->get('Content-type');
109 3
        if (strpos($contentType, 'text/html') === false) {
110 1
            return false;
111
        }
112
113 3
        $content = $response->getContent();
114 3
        $dom = HtmlDomParser::str_get_html($content);
115
116 3
        if ($dom === false) {
0 ignored issues
show
introduced by
The condition $dom === false is always false.
Loading history...
117 1
            $this->logger->error('Content can not be parsed by HtmlDomParser');
118 1
            return false;
119
        }
120
121 3
        $htmlElement = $dom->find('html', 0);
122 3
        if (null === $htmlElement) {
123 1
            return false;
124
        }
125
126 3
        $htmlElementAttrs = $htmlElement->getAllAttributes();
127 3
        if (empty(array_intersect(['⚡', 'amp'], array_keys($htmlElementAttrs)))) {
128 1
            return false;
129
        }
130
131 2
        return true;
132
    }
133
134 2
    private function handleErrors(): void
135
    {
136 2
        if ($this->errorCollection->count() > 0) {
137 1
            foreach ($this->errorCollection as $error) {
138 1
                $this->logger->error(sprintf(
139 1
                    "AMP-Optimizer Error code: %s\nError Message: %s\n",
140 1
                    $error->getCode(),
141 1
                    $error->getMessage()
142
                ));
143
            }
144
        }
145 2
    }
146
147
    /**
148
     * @param bool $enabled
149
     */
150 2
    public function setEnabled(bool $enabled): void
151
    {
152 2
        $this->config['transform_enabled'] = $enabled;
153 2
    }
154
155
    /**
156
     * @return bool
157
     */
158 1
    public function isEnabled(): bool
159
    {
160 1
        return $this->config['transform_enabled'];
161
    }
162
}