config = $config;
$this->dispatcher = $dispatcher;
}
/**
* Add image placeholders to image src
*
* @param string $content Content to be processed
* @return string
*/
public function replaceSrcImageWithSrcPlaceholders(string $content): string
{
if ($this->isNotTheFrontEnd()) {
return $content;
}
if ($this->hasAlreadyLazyLoadedIn($content)) {
return $content;
}
/**
* This is a pretty simple regex, but it works
*
* @var string
*/
return \preg_replace_callback(
'#
]+?)src=[\'"]?([^\'"\s>]+)[\'"]?([^>]*)>#',
fn(array $matches) => $this->replaceAttributes($matches),
$content
);
}
/**
* @param array $matches
* @return string
*/
private function replaceAttributes(array $matches)
{
/**
* Replace srcset, sizes and src attributes
*/
$content = \str_replace(
['srcset', 'sizes'],
['data-lazy-srcset', 'data-sizes'],
\sprintf(
'
',
$matches[1],
$this->getImagePlaceholder(),
$matches[2],
$matches[3]
)
);
return $this->appendNoscript($matches, $content);
}
/**
* @param array $matches
* @param string $content
* @return string
*/
private function appendNoscript(array $matches, string $content): string
{
$content .= \sprintf(
'',
$matches[ 1 ],
$matches[ 2 ],
$matches[ 3 ]
);
return $content;
}
/**
* @return string
*/
private function getImagePlaceholder()
{
return $this->dispatcher->filter(
static::PLACEHOLDER_FILTER_EVENT_NAME,
$this->config->get('lazyload-custom-placeholder', static::DEFAULT_PLACEHOLDER)
);
}
/**
* @param string $content
* @return bool
*/
private function hasAlreadyLazyLoadedIn(string $content): bool
{
return false !== \strpos($content, 'data-lazy-src');
}
/**
* @return bool
*/
private function isNotTheFrontEnd(): bool
{
return \is_feed() || \is_preview();
}
}