File "ServeConvertedWebP.php"
Full Path: /var/www/html/wordpress/wp-content/plugins/wp-optimize/vendor/rosell-dk/webp-convert/src/Serve/ServeConvertedWebP.php
File size: 9.07 KB
MIME-type: text/x-php
Charset: utf-8
<?php
namespace WebPConvert\Serve;
use WebPConvert\Convert\Exceptions\ConversionFailedException;
use WebPConvert\Helpers\InputValidator;
use WebPConvert\Helpers\MimeType;
use WebPConvert\Helpers\PathChecker;
use WebPConvert\Serve\Exceptions\ServeFailedException;
use WebPConvert\Serve\Header;
use WebPConvert\Serve\Report;
use WebPConvert\Serve\ServeFile;
use WebPConvert\Options\ArrayOption;
use WebPConvert\Options\BooleanOption;
use WebPConvert\Options\Options;
use WebPConvert\Options\SensitiveArrayOption;
use WebPConvert\Options\Exceptions\InvalidOptionTypeException;
use WebPConvert\Options\Exceptions\InvalidOptionValueException;
use WebPConvert\WebPConvert;
/**
* Serve a converted webp image.
*
* The webp that is served might end up being one of these:
* - a fresh convertion
* - the destionation
* - the original
*
* Exactly which is a decision based upon options, file sizes and file modification dates
* (see the serve method of this class for details)
*
* @package WebPConvert
* @author Bjørn Rosell <[email protected]>
* @since Class available since Release 2.0.0
*/
class ServeConvertedWebP
{
/**
* Process options.
*
* @throws \WebPConvert\Options\Exceptions\InvalidOptionTypeException If the type of an option is invalid
* @throws \WebPConvert\Options\Exceptions\InvalidOptionValueException If the value of an option is invalid
* @param array $options
*/
private static function processOptions($options)
{
$options2 = new Options();
$options2->addOptions(
new BooleanOption('reconvert', false),
new BooleanOption('serve-original', false),
new BooleanOption('show-report', false),
new BooleanOption('suppress-warnings', true),
new BooleanOption('redirect-to-self-instead-of-serving', false),
new ArrayOption('serve-image', []),
new SensitiveArrayOption('convert', [])
);
foreach ($options as $optionId => $optionValue) {
$options2->setOrCreateOption($optionId, $optionValue);
}
$options2->check();
return $options2->getOptions();
}
/**
* Serve original file (source).
*
* @param string $source path to source file
* @param array $serveImageOptions (optional) options for serving an image
* Supported options:
* - All options supported by ServeFile::serve()
* @throws ServeFailedException if source is not an image or mime type cannot be determined
* @return void
*/
public static function serveOriginal($source, $serveImageOptions = [])
{
// PS: We do not use InputValidator::checkSource($source) because we want to be
// a bit more lenient here and allow any image to be served (even though ie webp does not
// qualify for being used as a source when converting)
// Check that the filename is ok (no control chars, streamwrappers), and that the file exists
// and is not a dir
PathChecker::checkSourcePath($source);
$contentType = MimeType::getMimeTypeDetectionResult($source);
if (is_null($contentType)) {
throw new ServeFailedException('Rejecting to serve original (mime type cannot be determined)');
} elseif ($contentType === false) {
throw new ServeFailedException('Rejecting to serve original (it is not an image)');
} else {
ServeFile::serve($source, $contentType, $serveImageOptions);
}
}
/**
* Serve destination file.
*
* TODO: SHould this really be public?
*
* @param string $destination path to destination file
* @param array $serveImageOptions (optional) options for serving (such as which headers to add)
* Supported options:
* - All options supported by ServeFile::serve()
* @return void
*/
public static function serveDestination($destination, $serveImageOptions = [])
{
InputValidator::checkDestination($destination);
ServeFile::serve($destination, 'image/webp', $serveImageOptions);
}
public static function warningHandler()
{
// do nothing! - as we do not return anything, the warning is suppressed
}
/**
* Serve converted webp.
*
* Serve a converted webp. If a file already exists at the destination, that is served (unless it is
* older than the source - in that case a fresh conversion will be made, or the file at the destination
* is larger than the source - in that case the source is served). Some options may alter this logic.
* In case no file exists at the destination, a fresh conversion is made and served.
*
* @param string $source path to source file
* @param string $destination path to destination
* @param array $options (optional) options for serving/converting
* Supported options:
* 'show-report' => (boolean) If true, the decision will always be 'report'
* 'serve-original' => (boolean) If true, the decision will be 'source' (unless above option is set)
* 'reconvert ' => (boolean) If true, the decision will be 'fresh-conversion' (unless one of the
* above options is set)
* - All options supported by WebPConvert::convert()
* - All options supported by ServeFile::serve()
* @param \WebPConvert\Loggers\BaseLogger $serveLogger (optional)
* @param \WebPConvert\Loggers\BaseLogger $convertLogger (optional)
*
* @throws \WebPConvert\Exceptions\WebPConvertException If something went wrong.
* @return void
*/
public static function serve($source, $destination, $options = [], $serveLogger = null, $convertLogger = null)
{
InputValidator::checkSourceAndDestination($source, $destination);
$options = self::processOptions($options);
if ($options['suppress-warnings']) {
set_error_handler(
array('\\WebPConvert\\Serve\\ServeConvertedWebP', "warningHandler"),
E_WARNING | E_USER_WARNING | E_NOTICE | E_USER_NOTICE
);
}
//$options = array_merge(self::$defaultOptions, $options);
// Step 1: Is there a file at the destination? If not, trigger conversion
// However 1: if "show-report" option is set, serve the report instead
// However 2: "reconvert" option should also trigger conversion
if ($options['show-report']) {
Header::addLogHeader('Showing report', $serveLogger);
Report::convertAndReport($source, $destination, $options);
return;
}
if (!@file_exists($destination)) {
Header::addLogHeader('Converting (there were no file at destination)', $serveLogger);
WebPConvert::convert($source, $destination, $options['convert'], $convertLogger);
} elseif ($options['reconvert']) {
Header::addLogHeader('Converting (told to reconvert)', $serveLogger);
WebPConvert::convert($source, $destination, $options['convert'], $convertLogger);
} else {
// Step 2: Is the destination older than the source?
// If yes, trigger conversion (deleting destination is implicit)
$timestampSource = @filemtime($source);
$timestampDestination = @filemtime($destination);
if (($timestampSource !== false) &&
($timestampDestination !== false) &&
($timestampSource > $timestampDestination)) {
Header::addLogHeader('Converting (destination was older than the source)', $serveLogger);
WebPConvert::convert($source, $destination, $options['convert'], $convertLogger);
}
}
// Step 3: Serve the smallest file (destination or source)
// However, first check if 'serve-original' is set
if ($options['serve-original']) {
Header::addLogHeader('Serving original (told to)', $serveLogger);
self::serveOriginal($source, $options['serve-image']);
return;
}
if ($options['redirect-to-self-instead-of-serving']) {
Header::addLogHeader(
'Redirecting to self! ' .
'(hope you got redirection to existing webps set up, otherwise you will get a loop!)',
$serveLogger
);
header('Location: ?fresh', 302);
return;
}
$filesizeDestination = @filesize($destination);
$filesizeSource = @filesize($source);
if (($filesizeSource !== false) &&
($filesizeDestination !== false) &&
($filesizeDestination > $filesizeSource)) {
Header::addLogHeader('Serving original (it is smaller)', $serveLogger);
self::serveOriginal($source, $options['serve-image']);
return;
}
Header::addLogHeader('Serving converted file', $serveLogger);
self::serveDestination($destination, $options['serve-image']);
}
}