Add X13 WebP module for image conversion to next-generation formats
- Implemented the main module class with essential properties and methods. - Added translation support for various user interface strings. - Created XML configuration file for module versioning. - Ensured compatibility with different PHP versions and PrestaShop versions.
This commit is contained in:
10
modules/x13webp/vendor/rosell-dk/webp-convert/src/Serve/Exceptions/ServeFailedException.php
vendored
Normal file
10
modules/x13webp/vendor/rosell-dk/webp-convert/src/Serve/Exceptions/ServeFailedException.php
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace WebPConvert\Serve\Exceptions;
|
||||
|
||||
use WebPConvert\Exceptions\WebPConvertException;
|
||||
|
||||
class ServeFailedException extends WebPConvertException
|
||||
{
|
||||
public $description = 'Failed serving';
|
||||
}
|
||||
51
modules/x13webp/vendor/rosell-dk/webp-convert/src/Serve/Header.php
vendored
Normal file
51
modules/x13webp/vendor/rosell-dk/webp-convert/src/Serve/Header.php
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
namespace WebPConvert\Serve;
|
||||
|
||||
/**
|
||||
* Add / Set HTTP header.
|
||||
*
|
||||
* This class does nothing more than adding two convenience functions for calling the "header" function.
|
||||
*
|
||||
* @package WebPConvert
|
||||
* @author Bjørn Rosell <it@rosell.dk>
|
||||
* @since Class available since Release 2.0.0
|
||||
*/
|
||||
class Header
|
||||
{
|
||||
/**
|
||||
* Convenience function for adding header (append).
|
||||
*
|
||||
* @param string $header The header to add.
|
||||
* @return void
|
||||
*/
|
||||
public static function addHeader($header)
|
||||
{
|
||||
header($header, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience function for replacing header.
|
||||
*
|
||||
* @param string $header The header to set.
|
||||
* @return void
|
||||
*/
|
||||
public static function setHeader($header)
|
||||
{
|
||||
header($header, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add log header and optionally send it to a logger as well.
|
||||
*
|
||||
* @param string $msg Message to add to "X-WebP-Convert-Log" header
|
||||
* @param \WebPConvert\Loggers\BaseLogger $logger (optional)
|
||||
* @return void
|
||||
*/
|
||||
public static function addLogHeader($msg, $logger = null)
|
||||
{
|
||||
self::addHeader('X-WebP-Convert-Log: ' . $msg);
|
||||
if (!is_null($logger)) {
|
||||
$logger->logLn($msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
54
modules/x13webp/vendor/rosell-dk/webp-convert/src/Serve/Report.php
vendored
Normal file
54
modules/x13webp/vendor/rosell-dk/webp-convert/src/Serve/Report.php
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
namespace WebPConvert\Serve;
|
||||
|
||||
use WebPConvert\Helpers\InputValidator;
|
||||
use WebPConvert\Loggers\EchoLogger;
|
||||
use WebPConvert\WebPConvert;
|
||||
|
||||
/**
|
||||
* Class for generating a HTML report of converting an image.
|
||||
*
|
||||
* @package WebPConvert
|
||||
* @author Bjørn Rosell <it@rosell.dk>
|
||||
* @since Class available since Release 2.0.0
|
||||
*/
|
||||
class Report
|
||||
{
|
||||
public static function convertAndReport($source, $destination, $options)
|
||||
{
|
||||
InputValidator::checkSourceAndDestination($source, $destination);
|
||||
?>
|
||||
<html>
|
||||
<head>
|
||||
<style>td {vertical-align: top} table {color: #666}</style>
|
||||
<script>
|
||||
function showOptions(elToHide) {
|
||||
document.getElementById('options').style.display='block';
|
||||
elToHide.style.display='none';
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<table>
|
||||
<tr><td><i>source:</i></td><td><?php echo htmlentities($source) ?></td></tr>
|
||||
<tr><td><i>destination:</i></td><td><?php echo htmlentities($destination) ?><td></tr>
|
||||
</table>
|
||||
<br>
|
||||
<?php
|
||||
try {
|
||||
$echoLogger = new EchoLogger();
|
||||
$options['log-call-arguments'] = true;
|
||||
WebPConvert::convert($source, $destination, $options['convert'], $echoLogger);
|
||||
} catch (\Exception $e) {
|
||||
$msg = $e->getMessage();
|
||||
echo '<b>' . $msg . '</b>';
|
||||
|
||||
//echo '<p>Rethrowing exception for your convenience</p>';
|
||||
//throw ($e);
|
||||
}
|
||||
?>
|
||||
</body>
|
||||
</html>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
216
modules/x13webp/vendor/rosell-dk/webp-convert/src/Serve/ServeConvertedWebP.php
vendored
Normal file
216
modules/x13webp/vendor/rosell-dk/webp-convert/src/Serve/ServeConvertedWebP.php
vendored
Normal file
@@ -0,0 +1,216 @@
|
||||
<?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 <it@rosell.dk>
|
||||
* @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']);
|
||||
}
|
||||
}
|
||||
160
modules/x13webp/vendor/rosell-dk/webp-convert/src/Serve/ServeConvertedWebPWithErrorHandling.php
vendored
Normal file
160
modules/x13webp/vendor/rosell-dk/webp-convert/src/Serve/ServeConvertedWebPWithErrorHandling.php
vendored
Normal file
@@ -0,0 +1,160 @@
|
||||
<?php
|
||||
namespace WebPConvert\Serve;
|
||||
|
||||
use WebPConvert\Helpers\InputValidator;
|
||||
use WebPConvert\Options\Options;
|
||||
use WebPConvert\Options\StringOption;
|
||||
use WebPConvert\Serve\Header;
|
||||
use WebPConvert\Serve\Report;
|
||||
use WebPConvert\Serve\ServeConvertedWeb;
|
||||
use WebPConvert\Serve\Exceptions\ServeFailedException;
|
||||
use WebPConvert\Exceptions\WebPConvertException;
|
||||
|
||||
/**
|
||||
* Serve a converted webp image and handle errors.
|
||||
*
|
||||
* @package WebPConvert
|
||||
* @author Bjørn Rosell <it@rosell.dk>
|
||||
* @since Class available since Release 2.0.0
|
||||
*/
|
||||
class ServeConvertedWebPWithErrorHandling
|
||||
{
|
||||
|
||||
/**
|
||||
* 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 StringOption('fail', 'original', ['original', '404', 'throw', 'report']),
|
||||
new StringOption('fail-when-fail-fails', 'throw', ['original', '404', 'throw', 'report'])
|
||||
);
|
||||
foreach ($options as $optionId => $optionValue) {
|
||||
$options2->setOrCreateOption($optionId, $optionValue);
|
||||
}
|
||||
$options2->check();
|
||||
return $options2->getOptions();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add headers for preventing caching.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private static function addHeadersPreventingCaching()
|
||||
{
|
||||
Header::setHeader("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
|
||||
Header::addHeader("Cache-Control: post-check=0, pre-check=0");
|
||||
Header::setHeader("Pragma: no-cache");
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform fail action.
|
||||
*
|
||||
* @param string $fail Action to perform (original | 404 | report)
|
||||
* @param string $failIfFailFails Action to perform if $fail action fails
|
||||
* @param string $source path to source file
|
||||
* @param string $destination path to destination
|
||||
* @param array $options (optional) options for serving/converting
|
||||
* @param \Exception $e exception that was thrown when trying to serve
|
||||
* @param string $serveClass (optional) Full class name to a class that has a serveOriginal() method
|
||||
* @return void
|
||||
*/
|
||||
public static function performFailAction($fail, $failIfFailFails, $source, $destination, $options, $e, $serveClass)
|
||||
{
|
||||
self::addHeadersPreventingCaching();
|
||||
|
||||
Header::addLogHeader('Performing fail action: ' . $fail);
|
||||
|
||||
switch ($fail) {
|
||||
case 'original':
|
||||
try {
|
||||
//ServeConvertedWebP::serveOriginal($source, $options);
|
||||
call_user_func($serveClass . '::serveOriginal', $source, $options);
|
||||
} catch (\Exception $e) {
|
||||
self::performFailAction($failIfFailFails, '404', $source, $destination, $options, $e, $serveClass);
|
||||
}
|
||||
break;
|
||||
|
||||
case '404':
|
||||
$protocol = isset($_SERVER["SERVER_PROTOCOL"]) ? $_SERVER["SERVER_PROTOCOL"] : 'HTTP/1.0';
|
||||
Header::setHeader($protocol . " 404 Not Found");
|
||||
break;
|
||||
|
||||
case 'report':
|
||||
$options['show-report'] = true;
|
||||
Report::convertAndReport($source, $destination, $options);
|
||||
break;
|
||||
|
||||
case 'throw':
|
||||
throw $e;
|
||||
//break; commented out as phpstan complains. But do something else complain now?
|
||||
|
||||
case 'report-as-image':
|
||||
// TODO: Implement or discard ?
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Serve webp image and handle errors as specified in the 'fail' option.
|
||||
*
|
||||
* This method basically wraps ServeConvertedWebP:serve in order to provide exception handling.
|
||||
* The error handling is set with the 'fail' option and can be either '404', 'original' or 'report'.
|
||||
* If set to '404', errors results in 404 Not Found headers being issued. If set to 'original', an
|
||||
* error results in the original being served.
|
||||
* Look up the ServeConvertedWebP:serve method to learn more.
|
||||
*
|
||||
* @param string $source path to source file
|
||||
* @param string $destination path to destination
|
||||
* @param array $options (optional) options for serving/converting
|
||||
* Supported options:
|
||||
* - 'fail' => (string) Action to take on failure (404 | original | report | throw).
|
||||
* "404" or "throw" is recommended for development and "original" is recommended for production.
|
||||
* Default: 'original'.
|
||||
* - 'fail-when-fail-fails' => (string) Action to take if fail action also fails. Default: '404'.
|
||||
* - All options supported by WebPConvert::convert()
|
||||
* - All options supported by ServeFile::serve()
|
||||
* - All options supported by DecideWhatToServe::decide)
|
||||
* @param \WebPConvert\Loggers\BaseLogger $serveLogger (optional)
|
||||
* @param \WebPConvert\Loggers\BaseLogger $convertLogger (optional)
|
||||
* @param string $serveClass (optional) Full class name to a class that has a serve() method and a
|
||||
* serveOriginal() method
|
||||
* @return void
|
||||
*/
|
||||
public static function serve(
|
||||
$source,
|
||||
$destination,
|
||||
$options = [],
|
||||
$serveLogger = null,
|
||||
$convertLogger = null,
|
||||
$serveClass = '\\WebPConvert\\Serve\\ServeConvertedWebP'
|
||||
) {
|
||||
|
||||
$options = self::processOptions($options);
|
||||
try {
|
||||
InputValidator::checkSourceAndDestination($source, $destination);
|
||||
//ServeConvertedWebP::serve($source, $destination, $options, $serveLogger);
|
||||
call_user_func($serveClass . '::serve', $source, $destination, $options, $serveLogger, $convertLogger);
|
||||
} catch (\Exception $e) {
|
||||
if ($e instanceof \WebPConvert\Exceptions\WebPConvertException) {
|
||||
Header::addLogHeader($e->getShortMessage(), $serveLogger);
|
||||
}
|
||||
|
||||
self::performFailAction(
|
||||
$options['fail'],
|
||||
$options['fail-when-fail-fails'],
|
||||
$source,
|
||||
$destination,
|
||||
$options,
|
||||
$e,
|
||||
$serveClass
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
133
modules/x13webp/vendor/rosell-dk/webp-convert/src/Serve/ServeFile.php
vendored
Normal file
133
modules/x13webp/vendor/rosell-dk/webp-convert/src/Serve/ServeFile.php
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
<?php
|
||||
namespace WebPConvert\Serve;
|
||||
|
||||
//use WebPConvert\Serve\Report;
|
||||
use WebPConvert\Helpers\InputValidator;
|
||||
use WebPConvert\Options\ArrayOption;
|
||||
use WebPConvert\Options\BooleanOption;
|
||||
use WebPConvert\Options\Options;
|
||||
use WebPConvert\Options\StringOption;
|
||||
use WebPConvert\Serve\Header;
|
||||
use WebPConvert\Serve\Exceptions\ServeFailedException;
|
||||
|
||||
/**
|
||||
* Serve a file (send to standard output)
|
||||
*
|
||||
* @package WebPConvert
|
||||
* @author Bjørn Rosell <it@rosell.dk>
|
||||
* @since Class available since Release 2.0.0
|
||||
*/
|
||||
class ServeFile
|
||||
{
|
||||
|
||||
/**
|
||||
* 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 ArrayOption('headers', []),
|
||||
new StringOption('cache-control-header', 'public, max-age=31536000')
|
||||
);
|
||||
foreach ($options as $optionId => $optionValue) {
|
||||
$options2->setOrCreateOption($optionId, $optionValue);
|
||||
}
|
||||
$options2->check();
|
||||
$options = $options2->getOptions();
|
||||
|
||||
// headers option
|
||||
// --------------
|
||||
|
||||
$headerOptions = new Options();
|
||||
$headerOptions->addOptions(
|
||||
new BooleanOption('cache-control', false),
|
||||
new BooleanOption('content-length', true),
|
||||
new BooleanOption('content-type', true),
|
||||
new BooleanOption('expires', false),
|
||||
new BooleanOption('last-modified', true),
|
||||
new BooleanOption('vary-accept', false)
|
||||
);
|
||||
foreach ($options['headers'] as $optionId => $optionValue) {
|
||||
$headerOptions->setOrCreateOption($optionId, $optionValue);
|
||||
}
|
||||
$options['headers'] = $headerOptions->getOptions();
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serve existing file.
|
||||
*
|
||||
* @param string $filename File to serve (absolute path)
|
||||
* @param string $contentType Content-type (used to set header).
|
||||
* Only used when the "set-content-type-header" option is set.
|
||||
* Set to ie "image/jpeg" for serving jpeg file.
|
||||
* @param array $options Array of named options (optional).
|
||||
* Supported options:
|
||||
* 'add-vary-accept-header' => (boolean) Whether to add *Vary: Accept* header or not. Default: true.
|
||||
* 'set-content-type-header' => (boolean) Whether to set *Content-Type* header or not. Default: true.
|
||||
* 'set-last-modified-header' => (boolean) Whether to set *Last-Modified* header or not. Default: true.
|
||||
* 'set-cache-control-header' => (boolean) Whether to set *Cache-Control* header or not. Default: true.
|
||||
* 'cache-control-header' => string Cache control header. Default: "public, max-age=86400"
|
||||
*
|
||||
* @throws ServeFailedException if serving failed
|
||||
* @return void
|
||||
*/
|
||||
public static function serve($filename, $contentType, $options = [])
|
||||
{
|
||||
// Check mimetype - this also checks that path is secure and file exists
|
||||
InputValidator::checkMimeType($filename, [
|
||||
'image/jpeg',
|
||||
'image/png',
|
||||
'image/webp',
|
||||
'image/gif'
|
||||
]);
|
||||
|
||||
/*
|
||||
if (!file_exists($filename)) {
|
||||
Header::addHeader('X-WebP-Convert-Error: Could not read file');
|
||||
throw new ServeFailedException('Could not read file');
|
||||
}*/
|
||||
|
||||
$options = self::processOptions($options);
|
||||
|
||||
if ($options['headers']['last-modified']) {
|
||||
Header::setHeader("Last-Modified: " . gmdate("D, d M Y H:i:s", @filemtime($filename)) . " GMT");
|
||||
}
|
||||
|
||||
if ($options['headers']['content-type']) {
|
||||
Header::setHeader('Content-Type: ' . $contentType);
|
||||
}
|
||||
|
||||
if ($options['headers']['vary-accept']) {
|
||||
Header::addHeader('Vary: Accept');
|
||||
}
|
||||
|
||||
if (!empty($options['cache-control-header'])) {
|
||||
if ($options['headers']['cache-control']) {
|
||||
Header::setHeader('Cache-Control: ' . $options['cache-control-header']);
|
||||
}
|
||||
if ($options['headers']['expires']) {
|
||||
// Add exprires header too (#126)
|
||||
// Check string for something like this: max-age:86400
|
||||
if (preg_match('#max-age\\s*=\\s*(\\d*)#', $options['cache-control-header'], $matches)) {
|
||||
$seconds = $matches[1];
|
||||
Header::setHeader('Expires: ' . gmdate('D, d M Y H:i:s \G\M\T', time() + intval($seconds)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($options['headers']['content-length']) {
|
||||
Header::setHeader('Content-Length: ' . filesize($filename));
|
||||
}
|
||||
|
||||
if (@readfile($filename) === false) {
|
||||
Header::addHeader('X-WebP-Convert-Error: Could not read file');
|
||||
throw new ServeFailedException('Could not read file');
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user