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()) { |
|
|
|
|
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) { |
|
|
|
|
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
|
|
|
} |
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.