Skip to content

Commit

Permalink
Improve CSS memoization (#125)
Browse files Browse the repository at this point in the history
* Improve CSS memoization

* Improve CSS memoization
  • Loading branch information
fedeisas authored Sep 12, 2020
1 parent 8585f8d commit c1eb406
Showing 1 changed file with 54 additions and 40 deletions.
94 changes: 54 additions & 40 deletions src/CssInlinerPlugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,25 @@ class CssInlinerPlugin implements \Swift_Events_SendListener
/**
* @var CssToInlineStyles
*/
private $converter;
protected $converter;

/**
* @var string
* @var string[]
*/
protected $css;
protected $cssCache;

/**
* @var array
*/
protected $options;

/**
* @param array $options options defined in the configuration file.
*/
public function __construct(array $options)
{
$this->converter = new CssToInlineStyles();
$this->loadOptions($options);
$this->options = $options;
}

/**
Expand All @@ -36,14 +41,16 @@ public function beforeSendPerformed(\Swift_Events_SendEvent $evt)
|| ($message->getContentType() === 'multipart/alternative' && $message->getBody())
|| ($message->getContentType() === 'multipart/mixed' && $message->getBody())
) {
$body = $this->loadCssFilesFromLinks($message->getBody());
$message->setBody($this->converter->convert($body, $this->css));
[$body, $cssResources] = $this->messageSieve($message->getBody());
$css = $this->concatCss($cssResources);
$message->setBody($this->converter->convert($body, $css));
}

foreach ($message->getChildren() as $part) {
if (strpos($part->getContentType(), 'text/html') === 0) {
$body = $this->loadCssFilesFromLinks($part->getBody());
$part->setBody($this->converter->convert($body, $this->css));
[$body, $cssResources] = $this->messageSieve($part->getBody());
$css = $this->concatCss($cssResources);
$part->setBody($this->converter->convert($body, $css));
}
}
}
Expand All @@ -58,37 +65,46 @@ public function sendPerformed(\Swift_Events_SendEvent $evt)
// Do Nothing
}

/**
* Load the options
* @param array $options Options array
*/
public function loadOptions($options)
protected function concatCss(array $cssResources): string
{
if (isset($options['css-files']) && count($options['css-files']) > 0) {
$this->css = '';
foreach ($options['css-files'] as $fileUrl) {
// Fix relative protocols on hrefs. Assume https.
if (substr($fileUrl, 0, 2) === '//') {
$fileUrl = 'https:' . $fileUrl;
}

$this->css .= file_get_contents($fileUrl);
}
$output = '';
foreach ($cssResources as $cssResource) {
$output.= $this->fetchCss($cssResource);
}

return $output;
}

/**
* Find CSS stylesheet links and load them
*
* Loads the body of the message and passes
* any link stylesheets to $this->css
* Removes any link elements
*
* @return string $message The message
*/
public function loadCssFilesFromLinks($message)
protected function fetchCss(string $filename): string
{
if (isset($this->cssCache[$filename])) {
return $this->cssCache[$filename];
}

$fixedFilename = $filename;
// Fix relative protocols on hrefs. Assume https.
if (substr($filename, 0, 2) === '//') {
$fixedFilename = 'https:' . $filename;
}

$content = file_get_contents($fixedFilename);
if (! $content) {
return '';
}

$this->cssCache[$filename] = $content;

return $content;
}

protected function messageSieve(string $message): array
{
$options['css-files'] = [];
$cssResources = [];

// Initialize with config defaults, if any
if (isset($this->options['css-files'])) {
$cssResources = $this->options['css-files'];
}

$dom = new \DOMDocument();
// set error level
Expand All @@ -103,7 +119,7 @@ public function loadCssFilesFromLinks($message)
/** @var \DOMElement $link */
foreach ($link_tags as $link) {
if ($link->getAttribute('rel') === 'stylesheet') {
$options['css-files'][] = $link->getAttribute('href');
array_push($cssResources, $link->getAttribute('href'));
}
}

Expand All @@ -115,12 +131,10 @@ public function loadCssFilesFromLinks($message)
}
}

if (count($options['css-files'])) {
$this->loadOptions($options);

return $dom->saveHTML();
if (count($cssResources)) {
return [$dom->saveHTML(), $cssResources];
}

return $message;
return [$message, []];
}
}

0 comments on commit c1eb406

Please sign in to comment.