Skip to content

Commit

Permalink
[Asset] Optimized WebP Support detection (document & client) - relate…
Browse files Browse the repository at this point in the history
…d to #4557
  • Loading branch information
brusch committed Aug 7, 2019
1 parent 7729b92 commit 3aafee8
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 30 deletions.
28 changes: 27 additions & 1 deletion lib/Document/DocumentStack.php
Expand Up @@ -26,12 +26,18 @@ class DocumentStack
*/
private $documents = [];

/**
* @var string
*/
private $hash = '';

/**
* @param Document $document
*/
public function push(Document $document)
{
$this->documents[] = $document;
$this->regenerateHash();
}

/**
Expand All @@ -43,7 +49,10 @@ public function pop()
return;
}

return array_pop($this->documents);
$returnValue = array_pop($this->documents);
$this->regenerateHash();

return $returnValue;
}

/**
Expand Down Expand Up @@ -81,4 +90,21 @@ public function findOneBy(callable $function)

return null;
}

/**
* @return string
*/
public function getHash() : string {
return $this->hash;
}

/**
*
*/
private function regenerateHash() : void {
$this->hash = '';
foreach($this->documents as $document) {
$this->hash .= $document->getId() . "_";
}
}
}
99 changes: 70 additions & 29 deletions lib/Tool/Frontend.php
Expand Up @@ -14,6 +14,8 @@

namespace Pimcore\Tool;

use Pimcore\Document\DocumentStack;
use Pimcore\Http\RequestHelper;
use Pimcore\Model\Document;
use Pimcore\Model\Site;

Expand Down Expand Up @@ -150,48 +152,87 @@ public static function hasWebpSupport()
{
$config = \Pimcore::getContainer()->getParameter('pimcore.config')['assets']['image']['thumbnails']['webp_auto_support'];
if ($config) {
try {
$requestHelper = \Pimcore::getContainer()->get('Pimcore\Http\RequestHelper');
$documentStack = \Pimcore::getContainer()->get('Pimcore\Document\DocumentStack');
if(self::hasClientWebpSupport() && self::hasDocumentWebpSupport()) {
return true;
}
}

// if a parent is from one of the below types, no WebP images should be rendered
// e.g. when an email is sent from within a document, the email shouldn't contain WebP images, even when the
// triggering client (browser) has WebP support, because the email client (e.g. Outlook) might not support WebP
$hasUnsupportedTypeInStack = $documentStack->findOneBy(function ($doc) {
if (in_array($doc->getType(), ['email', 'newsletter', 'printpage', 'printcontainer'])) {
return true;
}
return false;
}

return false;
});

if ($hasUnsupportedTypeInStack) {
return false;
protected static $clientWebpSupport = null;

/**
* @return bool
*/
protected static function hasClientWebpSupport() : bool {

if(self::$clientWebpSupport === null) {
self::$clientWebpSupport = self::determineClientWebpSupport();
}

return self::$clientWebpSupport;
}

/**
* @return bool
*/
private static function determineClientWebpSupport() : bool {
try {
$requestHelper = \Pimcore::getContainer()->get(RequestHelper::class);
if ($requestHelper->hasMasterRequest()) {
$contentTypes = $requestHelper->getMasterRequest()->getAcceptableContentTypes();
if (in_array('image/webp', $contentTypes)) {
return true;
}

if ($requestHelper->hasMasterRequest()) {
$contentTypes = $requestHelper->getMasterRequest()->getAcceptableContentTypes();
if (in_array('image/webp', $contentTypes)) {
// not nice to do a browser detection but for now the easiest way to get around the topic described in #4345
$userAgent = strtolower($requestHelper->getMasterRequest()->headers->get('User-Agent'));
if (preg_match('@(firefox|edge)/([\d]+)@', $userAgent, $matches)) {
if ($matches[1] == 'firefox' && intval($matches[2]) >= 65) {
return true;
}

// not nice to do a browser detection but for now the easiest way to get around the topic described in #4345
$userAgent = strtolower($requestHelper->getMasterRequest()->headers->get('User-Agent'));
if (preg_match('@(firefox|edge)/([\d]+)@', $userAgent, $matches)) {
if ($matches[1] == 'firefox' && intval($matches[2]) >= 65) {
return true;
}

if ($matches[1] == 'edge' && intval($matches[2]) >= 18) {
return true;
}
if ($matches[1] == 'edge' && intval($matches[2]) >= 18) {
return true;
}
}
} catch (\Exception $e) {
// nothing to do
}
} catch (\Exception $e) {
// nothing to do
}

return false;
}

protected static $documentWebpSupport = [];

/**
* @return bool
*/
protected static function hasDocumentWebpSupport() : bool {

try {
$documentStack = \Pimcore::getContainer()->get(DocumentStack::class);
$hash = $documentStack->getHash();

if (!isset(self::$documentWebpSupport[$hash])) {
// if a parent is from one of the below types, no WebP images should be rendered
// e.g. when an email is sent from within a document, the email shouldn't contain WebP images, even when the
// triggering client (browser) has WebP support, because the email client (e.g. Outlook) might not support WebP
self::$documentWebpSupport[$hash] = !(bool)$documentStack->findOneBy(function (Document $doc) {
if (in_array($doc->getType(), ['email', 'newsletter', 'printpage', 'printcontainer'])) {
return true;
}

return false;
});
}

return self::$documentWebpSupport[$hash];
} catch (\Exception $e) {
return false;
}
}
}

0 comments on commit 3aafee8

Please sign in to comment.