Skip to content

Commit 82960df

Browse files
committed
Improve CSS memoization
1 parent 5a3b634 commit 82960df

File tree

1 file changed

+44
-39
lines changed

1 file changed

+44
-39
lines changed

src/CssInlinerPlugin.php

Lines changed: 44 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,25 @@ class CssInlinerPlugin implements \Swift_Events_SendListener
99
/**
1010
* @var CssToInlineStyles
1111
*/
12-
private $converter;
12+
protected $converter;
1313

1414
/**
15-
* @var string
15+
* @var string[]
1616
*/
17-
protected $css;
17+
protected $cssCache;
18+
19+
/**
20+
* @var array
21+
*/
22+
protected $options;
1823

1924
/**
2025
* @param array $options options defined in the configuration file.
2126
*/
2227
public function __construct(array $options)
2328
{
2429
$this->converter = new CssToInlineStyles();
25-
$this->loadOptions($options);
30+
$this->options = $options;
2631
}
2732

2833
/**
@@ -36,14 +41,16 @@ public function beforeSendPerformed(\Swift_Events_SendEvent $evt)
3641
|| ($message->getContentType() === 'multipart/alternative' && $message->getBody())
3742
|| ($message->getContentType() === 'multipart/mixed' && $message->getBody())
3843
) {
39-
$body = $this->loadCssFilesFromLinks($message->getBody());
40-
$message->setBody($this->converter->convert($body, $this->css));
44+
[$body, $cssResources] = $this->messageSieve($message->getBody());
45+
$css = $this->fetchCss($cssResources);
46+
$message->setBody($this->converter->convert($body, $css));
4147
}
4248

4349
foreach ($message->getChildren() as $part) {
4450
if (strpos($part->getContentType(), 'text/html') === 0) {
45-
$body = $this->loadCssFilesFromLinks($part->getBody());
46-
$part->setBody($this->converter->convert($body, $this->css));
51+
[$body, $cssResources] = $this->messageSieve($part->getBody());
52+
$css = $this->fetchCss($cssResources);
53+
$part->setBody($this->converter->convert($body, $css));
4754
}
4855
}
4956
}
@@ -58,37 +65,37 @@ public function sendPerformed(\Swift_Events_SendEvent $evt)
5865
// Do Nothing
5966
}
6067

61-
/**
62-
* Load the options
63-
* @param array $options Options array
64-
*/
65-
public function loadOptions($options)
68+
protected function fetchCss(array $cssResources): string
6669
{
67-
if (isset($options['css-files']) && count($options['css-files']) > 0) {
68-
$this->css = '';
69-
foreach ($options['css-files'] as $fileUrl) {
70-
// Fix relative protocols on hrefs. Assume https.
71-
if (substr($fileUrl, 0, 2) === '//') {
72-
$fileUrl = 'https:' . $fileUrl;
73-
}
74-
75-
$this->css .= file_get_contents($fileUrl);
70+
$output = '';
71+
foreach ($cssResources as $cssResource) {
72+
if (isset($this->cssCache[$cssResource])) {
73+
$output .= $this->cssCache[$cssResource];
74+
continue;
75+
}
76+
$filename = $cssResource;
77+
78+
// Fix relative protocols on hrefs. Assume https.
79+
if (substr($filename, 0, 2) === '//') {
80+
$filename = 'https:' . $filename;
7681
}
82+
83+
$content = file_get_contents($filename);
84+
$this->cssCache[$cssResource] = $content;
85+
$output .= $this->cssCache[$cssResource];
7786
}
87+
88+
return $output;
7889
}
7990

80-
/**
81-
* Find CSS stylesheet links and load them
82-
*
83-
* Loads the body of the message and passes
84-
* any link stylesheets to $this->css
85-
* Removes any link elements
86-
*
87-
* @return string $message The message
88-
*/
89-
public function loadCssFilesFromLinks($message)
91+
protected function messageSieve(string $message): array
9092
{
91-
$options['css-files'] = [];
93+
$cssResources = [];
94+
95+
// Initialize with config defaults, if any
96+
if (isset($this->options['css-files'])) {
97+
$cssResources = $this->options['css-files'];
98+
}
9299

93100
$dom = new \DOMDocument();
94101
// set error level
@@ -103,7 +110,7 @@ public function loadCssFilesFromLinks($message)
103110
/** @var \DOMElement $link */
104111
foreach ($link_tags as $link) {
105112
if ($link->getAttribute('rel') === 'stylesheet') {
106-
$options['css-files'][] = $link->getAttribute('href');
113+
array_push($cssResources, $link->getAttribute('href'));
107114
}
108115
}
109116

@@ -115,12 +122,10 @@ public function loadCssFilesFromLinks($message)
115122
}
116123
}
117124

118-
if (count($options['css-files'])) {
119-
$this->loadOptions($options);
120-
121-
return $dom->saveHTML();
125+
if (count($cssResources)) {
126+
return [$dom->saveHTML(), $cssResources];
122127
}
123128

124-
return $message;
129+
return [$message, []];
125130
}
126131
}

0 commit comments

Comments
 (0)