Add X13 WebP module for image conversion to next-generation formats

- Implemented the X13Webp class with core functionalities for converting images to WebP format.
- Added support for different PHP versions and defined constants for versioning.
- Included translation strings for various user interface elements and messages.
- Created XML file for module versioning.
This commit is contained in:
2025-09-12 00:41:29 +02:00
parent fa0f4b590b
commit 9003eede2d
247 changed files with 55597 additions and 1 deletions

View File

@@ -0,0 +1,96 @@
<?php
namespace FileUtil;
use FileUtil\FileExistsUsingExec;
/**
* A fileExist function free of deception
*
* @package FileUtil
* @author Bjørn Rosell <it@rosell.dk>
*/
class FileExists
{
private static $lastWarning;
/**
* A warning handler that registers that a warning has occured and suppresses it.
*
* The function is a callback used with "set_error_handler".
* It is declared public because it needs to be accessible from the point where the warning is triggered.
*
* @param integer $errno
* @param string $errstr
* @param string $errfile
* @param integer $errline
*
* @return void
*/
public static function warningHandler($errno, $errstr, $errfile, $errline)
{
self::$lastWarning = [$errstr, $errno];
// Suppress the warning by returning void
return;
}
/**
* A well behaved replacement for file_exist that throws upon failure rather than emitting a warning.
*
* @throws \Exception Throws an exception in case file_exists emits a warning
* @return boolean True if file exists. False if it doesn't.
*/
public static function fileExists($path)
{
// There is a challenges here:
// We want to suppress warnings, but at the same time we want to know that it happened.
// We achieve this by registering an error handler
set_error_handler(
array('FileUtil\FileExists', "warningHandler"),
E_WARNING | E_USER_WARNING | E_NOTICE | E_USER_NOTICE
);
self::$lastWarning = null;
$found = @file_exists($path);
// restore previous error handler immediately
restore_error_handler();
// If file_exists returns true, we can rely on there being a file there
if ($found) {
return true;
}
// file_exists returned false.
// this result is only trustworthy if no warning was emitted.
if (is_null(self::$lastWarning)) {
return false;
}
list($errstr, $errno) = self::$lastWarning;
throw new \Exception($errstr, $errno);
}
/**
* A fileExist doing the best it can.
*
* @throws \Exception If it cannot be determined if the file exists
* @return boolean|null True if file exists. False if it doesn't.
*/
public static function fileExistsTryHarder($path)
{
try {
$result = self::fileExists($path);
} catch (\Exception $e) {
try {
$result = FileExistsUsingExec::fileExists($path);
} catch (\Exception $e) {
throw new \Exception('Cannot determine if file exists or not');
} catch (\Throwable $e) {
throw new \Exception('Cannot determine if file exists or not');
}
}
return $result;
}
}

View File

@@ -0,0 +1,40 @@
<?php
namespace FileUtil;
use ExecWithFallback\ExecWithFallback;
/**
* A fileExist implementation using exec()
*
* @package FileUtil
* @author Bjørn Rosell <it@rosell.dk>
*/
class FileExistsUsingExec
{
/**
* A fileExist based on an exec call.
*
* @throws \Exception If exec cannot be called
* @return boolean|null True if file exists. False if it doesn't.
*/
public static function fileExists($path)
{
if (!ExecWithFallback::anyAvailable()) {
throw new \Exception(
'cannot determine if file exists using exec() or similar - the function is unavailable'
);
}
// Lets try to find out by executing "ls path/to/cwebp"
ExecWithFallback::exec('ls ' . $path, $output, $returnCode);
if (($returnCode == 0) && (isset($output[0]))) {
return true;
}
// We assume that "ls" command is general available!
// As that failed, we can conclude the file does not exist.
return false;
}
}

View File

@@ -0,0 +1,70 @@
<?php
namespace FileUtil;
use FileUtil\FileExists;
/**
*
*
* @package FileUtil
* @author Bjørn Rosell <it@rosell.dk>
*/
class PathValidator
{
/**
* Check if path looks valid and doesn't contain suspecious patterns.
* The path must meet the following criteria:
*
* - It must be a string
* - No NUL character
* - No control characters between 0-20
* - No phar stream wrapper
* - No php stream wrapper
* - No glob stream wrapper
* - Not empty path
*
* @throws \Exception In case the path doesn't meet all criteria
*/
public static function checkPath($path)
{
if (gettype($path) !== 'string') {
throw new \Exception('File path must be string');
}
if (strpos($path, chr(0)) !== false) {
throw new \Exception('NUL character is not allowed in file path!');
}
if (preg_match('#[\x{0}-\x{1f}]#', $path)) {
// prevents line feed, new line, tab, charater return, tab, ets.
throw new \Exception('Control characters #0-#20 not allowed in file path!');
}
// Prevent phar stream wrappers (security threat)
if (preg_match('#^phar://#', $path)) {
throw new \Exception('phar stream wrappers are not allowed in file path');
}
if (preg_match('#^(php|glob)://#', $path)) {
throw new \Exception('php and glob stream wrappers are not allowed in file path');
}
if (empty($path)) {
throw new \Exception('File path is empty!');
}
}
/**
* Check if path points to a regular file (and doesnt match suspecious patterns).
*
* @throws \Exception In case the path doesn't point to a regular file or matches suspecious patterns
*/
public static function checkFilePathIsRegularFile($path)
{
self::checkPath($path);
if (!FileExists::fileExists($path)) {
throw new \Exception('File does not exist');
}
if (@is_dir($path)) {
throw new \Exception('Expected a regular file, not a dir');
}
}
}