Update Composer packages
This commit is contained in:
parent
0320235f6c
commit
a8b68fb61b
378 changed files with 28466 additions and 28852 deletions
|
@ -23,15 +23,11 @@ class Asset
|
|||
|
||||
/**
|
||||
* Relative file path
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $path;
|
||||
protected string|null $path = null;
|
||||
|
||||
/**
|
||||
* Creates a new Asset object for the given path.
|
||||
*
|
||||
* @param string $path
|
||||
*/
|
||||
public function __construct(string $path)
|
||||
{
|
||||
|
@ -44,8 +40,6 @@ class Asset
|
|||
|
||||
/**
|
||||
* Returns a unique id for the asset
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function id(): string
|
||||
{
|
||||
|
@ -54,8 +48,6 @@ class Asset
|
|||
|
||||
/**
|
||||
* Create a unique media hash
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function mediaHash(): string
|
||||
{
|
||||
|
@ -64,8 +56,6 @@ class Asset
|
|||
|
||||
/**
|
||||
* Returns the relative path starting at the media folder
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function mediaPath(): string
|
||||
{
|
||||
|
@ -74,8 +64,6 @@ class Asset
|
|||
|
||||
/**
|
||||
* Returns the absolute path to the file in the public media folder
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function mediaRoot(): string
|
||||
{
|
||||
|
@ -84,8 +72,6 @@ class Asset
|
|||
|
||||
/**
|
||||
* Returns the absolute Url to the file in the public media folder
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function mediaUrl(): string
|
||||
{
|
||||
|
@ -95,8 +81,6 @@ class Asset
|
|||
/**
|
||||
* Returns the path of the file from the web root,
|
||||
* excluding the filename
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function path(): string
|
||||
{
|
||||
|
@ -106,10 +90,9 @@ class Asset
|
|||
/**
|
||||
* Setter for the path
|
||||
*
|
||||
* @param string $path
|
||||
* @return $this
|
||||
*/
|
||||
protected function setPath(string $path)
|
||||
protected function setPath(string $path): static
|
||||
{
|
||||
$this->path = $path === '.' ? '' : $path;
|
||||
return $this;
|
||||
|
|
|
@ -4,6 +4,7 @@ namespace Kirby\Filesystem;
|
|||
|
||||
use Exception;
|
||||
use Kirby\Cms\App;
|
||||
use Kirby\Cms\Helpers;
|
||||
use Kirby\Cms\Page;
|
||||
use Kirby\Toolkit\Str;
|
||||
use Throwable;
|
||||
|
@ -30,10 +31,8 @@ class Dir
|
|||
{
|
||||
/**
|
||||
* Ignore when scanning directories
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $ignore = [
|
||||
public static array $ignore = [
|
||||
'.',
|
||||
'..',
|
||||
'.DS_Store',
|
||||
|
@ -45,19 +44,17 @@ class Dir
|
|||
'@eaDir'
|
||||
];
|
||||
|
||||
public static $numSeparator = '_';
|
||||
public static string $numSeparator = '_';
|
||||
|
||||
/**
|
||||
* Copy the directory to a new destination
|
||||
*
|
||||
* @param string $dir
|
||||
* @param string $target
|
||||
* @param bool $recursive
|
||||
* @param array $ignore
|
||||
* @return bool
|
||||
*/
|
||||
public static function copy(string $dir, string $target, bool $recursive = true, array $ignore = []): bool
|
||||
{
|
||||
public static function copy(
|
||||
string $dir,
|
||||
string $target,
|
||||
bool $recursive = true,
|
||||
array $ignore = []
|
||||
): bool {
|
||||
if (is_dir($dir) === false) {
|
||||
throw new Exception('The directory "' . $dir . '" does not exist');
|
||||
}
|
||||
|
@ -91,15 +88,14 @@ class Dir
|
|||
|
||||
/**
|
||||
* Get all subdirectories
|
||||
*
|
||||
* @param string $dir
|
||||
* @param array $ignore
|
||||
* @param bool $absolute
|
||||
* @return array
|
||||
*/
|
||||
public static function dirs(string $dir, array $ignore = null, bool $absolute = false): array
|
||||
{
|
||||
$result = array_values(array_filter(static::read($dir, $ignore, true), 'is_dir'));
|
||||
public static function dirs(
|
||||
string $dir,
|
||||
array|null $ignore = null,
|
||||
bool $absolute = false
|
||||
): array {
|
||||
$scan = static::read($dir, $ignore, true);
|
||||
$result = array_values(array_filter($scan, 'is_dir'));
|
||||
|
||||
if ($absolute !== true) {
|
||||
$result = array_map('basename', $result);
|
||||
|
@ -110,9 +106,6 @@ class Dir
|
|||
|
||||
/**
|
||||
* Checks if the directory exists on disk
|
||||
*
|
||||
* @param string $dir
|
||||
* @return bool
|
||||
*/
|
||||
public static function exists(string $dir): bool
|
||||
{
|
||||
|
@ -121,15 +114,14 @@ class Dir
|
|||
|
||||
/**
|
||||
* Get all files
|
||||
*
|
||||
* @param string $dir
|
||||
* @param array $ignore
|
||||
* @param bool $absolute
|
||||
* @return array
|
||||
*/
|
||||
public static function files(string $dir, array $ignore = null, bool $absolute = false): array
|
||||
{
|
||||
$result = array_values(array_filter(static::read($dir, $ignore, true), 'is_file'));
|
||||
public static function files(
|
||||
string $dir,
|
||||
array|null $ignore = null,
|
||||
bool $absolute = false
|
||||
): array {
|
||||
$scan = static::read($dir, $ignore, true);
|
||||
$result = array_values(array_filter($scan, 'is_file'));
|
||||
|
||||
if ($absolute !== true) {
|
||||
$result = array_map('basename', $result);
|
||||
|
@ -140,15 +132,13 @@ class Dir
|
|||
|
||||
/**
|
||||
* Read the directory and all subdirectories
|
||||
*
|
||||
* @param string $dir
|
||||
* @param bool $recursive
|
||||
* @param array $ignore
|
||||
* @param string $path
|
||||
* @return array
|
||||
*/
|
||||
public static function index(string $dir, bool $recursive = false, array $ignore = null, string $path = null)
|
||||
{
|
||||
public static function index(
|
||||
string $dir,
|
||||
bool $recursive = false,
|
||||
array|null $ignore = null,
|
||||
string $path = null
|
||||
): array {
|
||||
$result = [];
|
||||
$dir = realpath($dir);
|
||||
$items = static::read($dir);
|
||||
|
@ -168,9 +158,6 @@ class Dir
|
|||
|
||||
/**
|
||||
* Checks if the folder has any contents
|
||||
*
|
||||
* @param string $dir
|
||||
* @return bool
|
||||
*/
|
||||
public static function isEmpty(string $dir): bool
|
||||
{
|
||||
|
@ -179,9 +166,6 @@ class Dir
|
|||
|
||||
/**
|
||||
* Checks if the directory is readable
|
||||
*
|
||||
* @param string $dir
|
||||
* @return bool
|
||||
*/
|
||||
public static function isReadable(string $dir): bool
|
||||
{
|
||||
|
@ -190,9 +174,6 @@ class Dir
|
|||
|
||||
/**
|
||||
* Checks if the directory is writable
|
||||
*
|
||||
* @param string $dir
|
||||
* @return bool
|
||||
*/
|
||||
public static function isWritable(string $dir): bool
|
||||
{
|
||||
|
@ -209,15 +190,13 @@ class Dir
|
|||
* Don't use outside the Cms context.
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @param string $dir
|
||||
* @param string $contentExtension
|
||||
* @param array|null $contentIgnore
|
||||
* @param bool $multilang
|
||||
* @return array
|
||||
*/
|
||||
public static function inventory(string $dir, string $contentExtension = 'txt', array $contentIgnore = null, bool $multilang = false): array
|
||||
{
|
||||
public static function inventory(
|
||||
string $dir,
|
||||
string $contentExtension = 'txt',
|
||||
array|null $contentIgnore = null,
|
||||
bool $multilang = false
|
||||
): array {
|
||||
$dir = realpath($dir);
|
||||
|
||||
$inventory = [
|
||||
|
@ -304,10 +283,6 @@ class Dir
|
|||
* Take all content files,
|
||||
* remove those who are meta files and
|
||||
* detect the main content file
|
||||
*
|
||||
* @param array $inventory
|
||||
* @param array $content
|
||||
* @return array
|
||||
*/
|
||||
protected static function inventoryContent(array $inventory, array $content): array
|
||||
{
|
||||
|
@ -333,16 +308,17 @@ class Dir
|
|||
/**
|
||||
* Go through all inventory children
|
||||
* and inject a model for each
|
||||
*
|
||||
* @param array $inventory
|
||||
* @param string $contentExtension
|
||||
* @param bool $multilang
|
||||
* @return array
|
||||
*/
|
||||
protected static function inventoryModels(array $inventory, string $contentExtension, bool $multilang = false): array
|
||||
{
|
||||
protected static function inventoryModels(
|
||||
array $inventory,
|
||||
string $contentExtension,
|
||||
bool $multilang = false
|
||||
): array {
|
||||
// inject models
|
||||
if (empty($inventory['children']) === false && empty(Page::$models) === false) {
|
||||
if (
|
||||
empty($inventory['children']) === false &&
|
||||
empty(Page::$models) === false
|
||||
) {
|
||||
if ($multilang === true) {
|
||||
$contentExtension = App::instance()->defaultLanguage()->code() . '.' . $contentExtension;
|
||||
}
|
||||
|
@ -362,10 +338,6 @@ class Dir
|
|||
|
||||
/**
|
||||
* Create a (symbolic) link to a directory
|
||||
*
|
||||
* @param string $source
|
||||
* @param string $link
|
||||
* @return bool
|
||||
*/
|
||||
public static function link(string $source, string $link): bool
|
||||
{
|
||||
|
@ -381,7 +353,7 @@ class Dir
|
|||
|
||||
try {
|
||||
return symlink($source, $link) === true;
|
||||
} catch (Throwable $e) {
|
||||
} catch (Throwable) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -420,7 +392,13 @@ class Dir
|
|||
throw new Exception(sprintf('The directory "%s" cannot be created', $dir));
|
||||
}
|
||||
|
||||
return mkdir($dir);
|
||||
return Helpers::handleErrors(
|
||||
fn (): bool => mkdir($dir),
|
||||
// if the dir was already created (race condition),
|
||||
fn (int $errno, string $errstr): bool => Str::endsWith($errstr, 'File exists'),
|
||||
// consider it a success
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -428,11 +406,8 @@ class Dir
|
|||
* subfolders have been modified for the last time.
|
||||
*
|
||||
* @param string $dir The path of the directory
|
||||
* @param string $format
|
||||
* @param string $handler
|
||||
* @return int|string
|
||||
*/
|
||||
public static function modified(string $dir, string $format = null, string $handler = 'date')
|
||||
public static function modified(string $dir, string $format = null, string $handler = 'date'): int|string
|
||||
{
|
||||
$modified = filemtime($dir);
|
||||
$items = static::read($dir);
|
||||
|
@ -478,13 +453,14 @@ class Dir
|
|||
* Returns a nicely formatted size of all the contents of the folder
|
||||
*
|
||||
* @param string $dir The path of the directory
|
||||
* @param string|null|false $locale Locale for number formatting,
|
||||
* @param string|false|null $locale Locale for number formatting,
|
||||
* `null` for the current locale,
|
||||
* `false` to disable number formatting
|
||||
* @return mixed
|
||||
*/
|
||||
public static function niceSize(string $dir, $locale = null)
|
||||
{
|
||||
public static function niceSize(
|
||||
string $dir,
|
||||
string|false|null $locale = null
|
||||
): string {
|
||||
return F::niceSize(static::size($dir), $locale);
|
||||
}
|
||||
|
||||
|
@ -497,8 +473,11 @@ class Dir
|
|||
* @param bool $absolute If true, the full path for each item will be returned
|
||||
* @return array An array of filenames
|
||||
*/
|
||||
public static function read(string $dir, array $ignore = null, bool $absolute = false): array
|
||||
{
|
||||
public static function read(
|
||||
string $dir,
|
||||
array|null $ignore = null,
|
||||
bool $absolute = false
|
||||
): array {
|
||||
if (is_dir($dir) === false) {
|
||||
return [];
|
||||
}
|
||||
|
@ -520,9 +499,6 @@ class Dir
|
|||
|
||||
/**
|
||||
* Removes a folder including all containing files and folders
|
||||
*
|
||||
* @param string $dir
|
||||
* @return bool
|
||||
*/
|
||||
public static function remove(string $dir): bool
|
||||
{
|
||||
|
@ -558,9 +534,8 @@ class Dir
|
|||
*
|
||||
* @param string $dir The path of the directory
|
||||
* @param bool $recursive Include all subfolders and their files
|
||||
* @return mixed
|
||||
*/
|
||||
public static function size(string $dir, bool $recursive = true)
|
||||
public static function size(string $dir, bool $recursive = true): int|false
|
||||
{
|
||||
if (is_dir($dir) === false) {
|
||||
return false;
|
||||
|
@ -582,10 +557,6 @@ class Dir
|
|||
/**
|
||||
* Checks if the directory or any subdirectory has been
|
||||
* modified after the given timestamp
|
||||
*
|
||||
* @param string $dir
|
||||
* @param int $time
|
||||
* @return bool
|
||||
*/
|
||||
public static function wasModifiedAfter(string $dir, int $time): bool
|
||||
{
|
||||
|
|
|
@ -3,7 +3,9 @@
|
|||
namespace Kirby\Filesystem;
|
||||
|
||||
use Exception;
|
||||
use IntlDateFormatter;
|
||||
use Kirby\Cms\Helpers;
|
||||
use Kirby\Http\Response;
|
||||
use Kirby\Toolkit\I18n;
|
||||
use Kirby\Toolkit\Str;
|
||||
use Throwable;
|
||||
|
@ -23,10 +25,7 @@ use ZipArchive;
|
|||
*/
|
||||
class F
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public static $types = [
|
||||
public static array $types = [
|
||||
'archive' => [
|
||||
'gz',
|
||||
'gzip',
|
||||
|
@ -111,17 +110,23 @@ class F
|
|||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public static $units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
|
||||
public static array $units = [
|
||||
'B',
|
||||
'KB',
|
||||
'MB',
|
||||
'GB',
|
||||
'TB',
|
||||
'PB',
|
||||
'EB',
|
||||
'ZB',
|
||||
'YB'
|
||||
];
|
||||
|
||||
/**
|
||||
* Appends new content to an existing file
|
||||
*
|
||||
* @param string $file The path for the file
|
||||
* @param mixed $content Either a string or an array. Arrays will be converted to JSON.
|
||||
* @return bool
|
||||
*/
|
||||
public static function append(string $file, $content): bool
|
||||
{
|
||||
|
@ -132,7 +137,6 @@ class F
|
|||
* Returns the file content as base64 encoded string
|
||||
*
|
||||
* @param string $file The path for the file
|
||||
* @return string
|
||||
*/
|
||||
public static function base64(string $file): string
|
||||
{
|
||||
|
@ -141,11 +145,6 @@ class F
|
|||
|
||||
/**
|
||||
* Copy a file to a new location.
|
||||
*
|
||||
* @param string $source
|
||||
* @param string $target
|
||||
* @param bool $force
|
||||
* @return bool
|
||||
*/
|
||||
public static function copy(string $source, string $target, bool $force = false): bool
|
||||
{
|
||||
|
@ -174,7 +173,6 @@ class F
|
|||
* </code>
|
||||
*
|
||||
* @param string $file The path
|
||||
* @return string
|
||||
*/
|
||||
public static function dirname(string $file): string
|
||||
{
|
||||
|
@ -183,17 +181,13 @@ class F
|
|||
|
||||
/**
|
||||
* Checks if the file exists on disk
|
||||
*
|
||||
* @param string $file
|
||||
* @param string $in
|
||||
* @return bool
|
||||
*/
|
||||
public static function exists(string $file, string $in = null): bool
|
||||
public static function exists(string $file, string|null $in = null): bool
|
||||
{
|
||||
try {
|
||||
static::realpath($file, $in);
|
||||
return true;
|
||||
} catch (Exception $e) {
|
||||
} catch (Exception) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -201,12 +195,13 @@ class F
|
|||
/**
|
||||
* Gets the extension of a file
|
||||
*
|
||||
* @param string $file The filename or path
|
||||
* @param string $extension Set an optional extension to overwrite the current one
|
||||
* @return string
|
||||
* @param string|null $file The filename or path
|
||||
* @param string|null $extension Set an optional extension to overwrite the current one
|
||||
*/
|
||||
public static function extension(string $file = null, string $extension = null): string
|
||||
{
|
||||
public static function extension(
|
||||
string|null $file = null,
|
||||
string|null $extension = null
|
||||
): string {
|
||||
// overwrite the current extension
|
||||
if ($extension !== null) {
|
||||
return static::name($file) . '.' . $extension;
|
||||
|
@ -218,22 +213,16 @@ class F
|
|||
|
||||
/**
|
||||
* Converts a file extension to a mime type
|
||||
*
|
||||
* @param string $extension
|
||||
* @return string|false
|
||||
*/
|
||||
public static function extensionToMime(string $extension)
|
||||
public static function extensionToMime(string $extension): string|null
|
||||
{
|
||||
return Mime::fromExtension($extension);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the file type for a passed extension
|
||||
*
|
||||
* @param string $extension
|
||||
* @return string|false
|
||||
*/
|
||||
public static function extensionToType(string $extension)
|
||||
public static function extensionToType(string $extension): string|false
|
||||
{
|
||||
foreach (static::$types as $type => $extensions) {
|
||||
if (in_array($extension, $extensions) === true) {
|
||||
|
@ -246,11 +235,8 @@ class F
|
|||
|
||||
/**
|
||||
* Returns all extensions for a certain file type
|
||||
*
|
||||
* @param string $type
|
||||
* @return array
|
||||
*/
|
||||
public static function extensions(string $type = null)
|
||||
public static function extensions(string|null $type = null): array
|
||||
{
|
||||
if ($type === null) {
|
||||
return array_keys(Mime::types());
|
||||
|
@ -270,7 +256,6 @@ class F
|
|||
* </code>
|
||||
*
|
||||
* @param string $name The path
|
||||
* @return string
|
||||
*/
|
||||
public static function filename(string $name): string
|
||||
{
|
||||
|
@ -281,15 +266,17 @@ class F
|
|||
* Invalidate opcode cache for file.
|
||||
*
|
||||
* @param string $file The path of the file
|
||||
* @return bool
|
||||
*/
|
||||
public static function invalidateOpcodeCache(string $file): bool
|
||||
{
|
||||
if (function_exists('opcache_invalidate') && strlen(ini_get('opcache.restrict_api')) === 0) {
|
||||
if (
|
||||
function_exists('opcache_invalidate') &&
|
||||
strlen(ini_get('opcache.restrict_api')) === 0
|
||||
) {
|
||||
return opcache_invalidate($file, true);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -297,7 +284,6 @@ class F
|
|||
*
|
||||
* @param string $file Full path to the file
|
||||
* @param string $value An extension or mime type
|
||||
* @return bool
|
||||
*/
|
||||
public static function is(string $file, string $value): bool
|
||||
{
|
||||
|
@ -316,9 +302,6 @@ class F
|
|||
|
||||
/**
|
||||
* Checks if the file is readable
|
||||
*
|
||||
* @param string $file
|
||||
* @return bool
|
||||
*/
|
||||
public static function isReadable(string $file): bool
|
||||
{
|
||||
|
@ -327,9 +310,6 @@ class F
|
|||
|
||||
/**
|
||||
* Checks if the file is writable
|
||||
*
|
||||
* @param string $file
|
||||
* @return bool
|
||||
*/
|
||||
public static function isWritable(string $file): bool
|
||||
{
|
||||
|
@ -342,11 +322,6 @@ class F
|
|||
|
||||
/**
|
||||
* Create a (symbolic) link to a file
|
||||
*
|
||||
* @param string $source
|
||||
* @param string $link
|
||||
* @param string $method
|
||||
* @return bool
|
||||
*/
|
||||
public static function link(string $source, string $link, string $method = 'link'): bool
|
||||
{
|
||||
|
@ -362,7 +337,7 @@ class F
|
|||
|
||||
try {
|
||||
return $method($source, $link) === true;
|
||||
} catch (Throwable $e) {
|
||||
} catch (Throwable) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -371,13 +346,14 @@ class F
|
|||
* Loads a file and returns the result or `false` if the
|
||||
* file to load does not exist
|
||||
*
|
||||
* @param string $file
|
||||
* @param mixed $fallback
|
||||
* @param array $data Optional array of variables to extract in the variable scope
|
||||
* @return mixed
|
||||
*/
|
||||
public static function load(string $file, $fallback = null, array $data = [])
|
||||
{
|
||||
public static function load(
|
||||
string $file,
|
||||
mixed $fallback = null,
|
||||
array $data = [],
|
||||
bool $allowOutput = true
|
||||
) {
|
||||
if (is_file($file) === false) {
|
||||
return $fallback;
|
||||
}
|
||||
|
@ -385,9 +361,21 @@ class F
|
|||
// we use the loadIsolated() method here to prevent the included
|
||||
// file from overwriting our $fallback in this variable scope; see
|
||||
// https://www.php.net/manual/en/function.include.php#example-124
|
||||
$result = static::loadIsolated($file, $data);
|
||||
$callback = fn () => static::loadIsolated($file, $data);
|
||||
|
||||
if ($fallback !== null && gettype($result) !== gettype($fallback)) {
|
||||
// if the loaded file should not produce any output,
|
||||
// call the loaidIsolated method from the Response class
|
||||
// which checks for unintended ouput and throws an error if detected
|
||||
if ($allowOutput === false) {
|
||||
$result = Response::guardAgainstOutput($callback);
|
||||
} else {
|
||||
$result = $callback();
|
||||
}
|
||||
|
||||
if (
|
||||
$fallback !== null &&
|
||||
gettype($result) !== gettype($fallback)
|
||||
) {
|
||||
return $fallback;
|
||||
}
|
||||
|
||||
|
@ -397,37 +385,35 @@ class F
|
|||
/**
|
||||
* A super simple class autoloader
|
||||
* @since 3.7.0
|
||||
*
|
||||
* @param array $classmap
|
||||
* @param string|null $base
|
||||
* @return void
|
||||
*/
|
||||
public static function loadClasses(array $classmap, ?string $base = null): void
|
||||
{
|
||||
public static function loadClasses(
|
||||
array $classmap,
|
||||
string|null $base = null
|
||||
): void {
|
||||
// convert all classnames to lowercase
|
||||
$classmap = array_change_key_case($classmap);
|
||||
|
||||
spl_autoload_register(function ($class) use ($classmap, $base) {
|
||||
$class = strtolower($class);
|
||||
spl_autoload_register(
|
||||
fn ($class) => Response::guardAgainstOutput(function () use ($class, $classmap, $base) {
|
||||
$class = strtolower($class);
|
||||
|
||||
if (!isset($classmap[$class])) {
|
||||
return false;
|
||||
}
|
||||
if (isset($classmap[$class]) === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($base) {
|
||||
include $base . '/' . $classmap[$class];
|
||||
} else {
|
||||
include $classmap[$class];
|
||||
}
|
||||
});
|
||||
if ($base) {
|
||||
include $base . '/' . $classmap[$class];
|
||||
} else {
|
||||
include $classmap[$class];
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a file with as little as possible in the variable scope
|
||||
*
|
||||
* @param string $file
|
||||
* @param array $data Optional array of variables to extract in the variable scope
|
||||
* @return mixed
|
||||
*/
|
||||
protected static function loadIsolated(string $file, array $data = [])
|
||||
{
|
||||
|
@ -440,50 +426,48 @@ class F
|
|||
}
|
||||
|
||||
/**
|
||||
* Loads a file using `include_once()` and returns whether loading was successful
|
||||
*
|
||||
* @param string $file
|
||||
* @return bool
|
||||
* Loads a file using `include_once()` and
|
||||
* returns whether loading was successful
|
||||
*/
|
||||
public static function loadOnce(string $file): bool
|
||||
{
|
||||
public static function loadOnce(
|
||||
string $file,
|
||||
bool $allowOutput = true
|
||||
): bool {
|
||||
if (is_file($file) === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
include_once $file;
|
||||
$callback = fn () => include_once $file;
|
||||
|
||||
if ($allowOutput === false) {
|
||||
Response::guardAgainstOutput($callback);
|
||||
} else {
|
||||
$callback();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the mime type of a file
|
||||
*
|
||||
* @param string $file
|
||||
* @return string|false
|
||||
*/
|
||||
public static function mime(string $file)
|
||||
public static function mime(string $file): string|null
|
||||
{
|
||||
return Mime::type($file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a mime type to a file extension
|
||||
*
|
||||
* @param string $mime
|
||||
* @return string|false
|
||||
*/
|
||||
public static function mimeToExtension(string $mime = null)
|
||||
public static function mimeToExtension(string|null $mime = null): string|false
|
||||
{
|
||||
return Mime::toExtension($mime);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type for a given mime
|
||||
*
|
||||
* @param string $mime
|
||||
* @return string|false
|
||||
*/
|
||||
public static function mimeToType(string $mime)
|
||||
public static function mimeToType(string $mime): string|false
|
||||
{
|
||||
return static::extensionToType(Mime::toExtension($mime));
|
||||
}
|
||||
|
@ -491,13 +475,13 @@ class F
|
|||
/**
|
||||
* Get the file's last modification time.
|
||||
*
|
||||
* @param string $file
|
||||
* @param string|\IntlDateFormatter|null $format
|
||||
* @param string $handler date, intl or strftime
|
||||
* @return mixed
|
||||
*/
|
||||
public static function modified(string $file, $format = null, string $handler = 'date')
|
||||
{
|
||||
public static function modified(
|
||||
string $file,
|
||||
string|IntlDateFormatter|null $format = null,
|
||||
string $handler = 'date'
|
||||
): string|int|false {
|
||||
if (file_exists($file) !== true) {
|
||||
return false;
|
||||
}
|
||||
|
@ -513,7 +497,6 @@ class F
|
|||
* @param string $oldRoot The current path for the file
|
||||
* @param string $newRoot The path to the new location
|
||||
* @param bool $force Force move if the target file exists
|
||||
* @return bool
|
||||
*/
|
||||
public static function move(string $oldRoot, string $newRoot, bool $force = false): bool
|
||||
{
|
||||
|
@ -543,7 +526,6 @@ class F
|
|||
* Extracts the name from a file path or filename without extension
|
||||
*
|
||||
* @param string $name The path or filename
|
||||
* @return string
|
||||
*/
|
||||
public static function name(string $name): string
|
||||
{
|
||||
|
@ -553,14 +535,15 @@ class F
|
|||
/**
|
||||
* Converts an integer size into a human readable format
|
||||
*
|
||||
* @param mixed $size The file size, a file path or array of paths
|
||||
* @param string|null|false $locale Locale for number formatting,
|
||||
* @param int|string|array $size The file size, a file path or array of paths
|
||||
* @param string|false|null $locale Locale for number formatting,
|
||||
* `null` for the current locale,
|
||||
* `false` to disable number formatting
|
||||
* @return string
|
||||
*/
|
||||
public static function niceSize($size, $locale = null): string
|
||||
{
|
||||
public static function niceSize(
|
||||
int|string|array $size,
|
||||
string|false|null $locale = null
|
||||
): string {
|
||||
// file mode
|
||||
if (is_string($size) === true || is_array($size) === true) {
|
||||
$size = static::size($size);
|
||||
|
@ -590,31 +573,27 @@ class F
|
|||
* contents of a remote HTTP or HTTPS URL
|
||||
*
|
||||
* @param string $file The path for the file or an absolute URL
|
||||
* @return string|false
|
||||
*/
|
||||
public static function read(string $file)
|
||||
public static function read(string $file): string|false
|
||||
{
|
||||
if (
|
||||
is_file($file) !== true &&
|
||||
is_readable($file) !== true &&
|
||||
Str::startsWith($file, 'https://') !== true &&
|
||||
Str::startsWith($file, 'http://') !== true
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return @file_get_contents($file);
|
||||
return file_get_contents($file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the name of the file without
|
||||
* touching the extension
|
||||
*
|
||||
* @param string $file
|
||||
* @param string $newName
|
||||
* @param bool $overwrite Force overwrite existing files
|
||||
* @return string|false
|
||||
*/
|
||||
public static function rename(string $file, string $newName, bool $overwrite = false)
|
||||
public static function rename(string $file, string $newName, bool $overwrite = false): string|false
|
||||
{
|
||||
// create the new name
|
||||
$name = static::safeName(basename($newName));
|
||||
|
@ -636,12 +615,8 @@ class F
|
|||
|
||||
/**
|
||||
* Returns the absolute path to the file if the file can be found.
|
||||
*
|
||||
* @param string $file
|
||||
* @param string $in
|
||||
* @return string|null
|
||||
*/
|
||||
public static function realpath(string $file, string $in = null)
|
||||
public static function realpath(string $file, string|null $in = null): string
|
||||
{
|
||||
$realpath = realpath($file);
|
||||
|
||||
|
@ -669,12 +644,8 @@ class F
|
|||
* starting after $in
|
||||
*
|
||||
* @SuppressWarnings(PHPMD.CountInLoopExpression)
|
||||
*
|
||||
* @param string $file
|
||||
* @param string $in
|
||||
* @return string
|
||||
*/
|
||||
public static function relativepath(string $file, string $in = null): string
|
||||
public static function relativepath(string $file, string|null $in = null): string
|
||||
{
|
||||
if (empty($in) === true) {
|
||||
return basename($file);
|
||||
|
@ -715,7 +686,6 @@ class F
|
|||
* </code>
|
||||
*
|
||||
* @param string $file The path for the file
|
||||
* @return bool
|
||||
*/
|
||||
public static function remove(string $file): bool
|
||||
{
|
||||
|
@ -746,7 +716,6 @@ class F
|
|||
* </code>
|
||||
*
|
||||
* @param string $string The file name
|
||||
* @return string
|
||||
*/
|
||||
public static function safeName(string $string): string
|
||||
{
|
||||
|
@ -761,10 +730,6 @@ class F
|
|||
/**
|
||||
* Tries to find similar or the same file by
|
||||
* building a glob based on the path
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $pattern
|
||||
* @return array
|
||||
*/
|
||||
public static function similar(string $path, string $pattern = '*'): array
|
||||
{
|
||||
|
@ -779,9 +744,8 @@ class F
|
|||
* Returns the size of a file or an array of files.
|
||||
*
|
||||
* @param string|array $file file path or array of paths
|
||||
* @return int
|
||||
*/
|
||||
public static function size($file): int
|
||||
public static function size(string|array $file): int
|
||||
{
|
||||
if (is_array($file) === true) {
|
||||
return array_reduce(
|
||||
|
@ -793,7 +757,7 @@ class F
|
|||
|
||||
try {
|
||||
return filesize($file);
|
||||
} catch (Throwable $e) {
|
||||
} catch (Throwable) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -802,9 +766,8 @@ class F
|
|||
* Categorize the file
|
||||
*
|
||||
* @param string $file Either the file path or extension
|
||||
* @return string|null
|
||||
*/
|
||||
public static function type(string $file)
|
||||
public static function type(string $file): string|null
|
||||
{
|
||||
$length = strlen($file);
|
||||
|
||||
|
@ -837,11 +800,8 @@ class F
|
|||
/**
|
||||
* Returns all extensions of a given file type
|
||||
* or `null` if the file type is unknown
|
||||
*
|
||||
* @param string $type
|
||||
* @return array|null
|
||||
*/
|
||||
public static function typeToExtensions(string $type): ?array
|
||||
public static function typeToExtensions(string $type): array|null
|
||||
{
|
||||
return static::$types[$type] ?? null;
|
||||
}
|
||||
|
@ -854,28 +814,15 @@ class F
|
|||
{
|
||||
return Helpers::handleErrors(
|
||||
fn (): bool => unlink($file),
|
||||
function (&$override, int $errno, string $errstr): bool {
|
||||
// if the file or link was already deleted (race condition),
|
||||
// consider it a success
|
||||
if (Str::endsWith($errstr, 'No such file or directory') === true) {
|
||||
$override = true;
|
||||
|
||||
// drop the warning
|
||||
return true;
|
||||
}
|
||||
|
||||
// handle every other warning normally
|
||||
return false;
|
||||
}
|
||||
// if the file or link was already deleted (race condition),
|
||||
fn (int $errno, string $errstr): bool => Str::endsWith($errstr, 'No such file or directory'),
|
||||
// consider it a success
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unzips a zip file
|
||||
*
|
||||
* @param string $file
|
||||
* @param string $to
|
||||
* @return bool
|
||||
*/
|
||||
public static function unzip(string $file, string $to): bool
|
||||
{
|
||||
|
@ -898,9 +845,8 @@ class F
|
|||
* Returns the file as data uri
|
||||
*
|
||||
* @param string $file The path for the file
|
||||
* @return string|false
|
||||
*/
|
||||
public static function uri(string $file)
|
||||
public static function uri(string $file): string|false
|
||||
{
|
||||
if ($mime = static::mime($file)) {
|
||||
return 'data:' . $mime . ';base64,' . static::base64($file);
|
||||
|
@ -915,7 +861,6 @@ class F
|
|||
* @param string $file The path for the new file
|
||||
* @param mixed $content Either a string, an object or an array. Arrays and objects will be serialized.
|
||||
* @param bool $append true: append the content to an existing file if available. false: overwrite.
|
||||
* @return bool
|
||||
*/
|
||||
public static function write(string $file, $content, bool $append = false): bool
|
||||
{
|
||||
|
|
|
@ -2,8 +2,10 @@
|
|||
|
||||
namespace Kirby\Filesystem;
|
||||
|
||||
use IntlDateFormatter;
|
||||
use Kirby\Cms\App;
|
||||
use Kirby\Exception\Exception;
|
||||
use Kirby\Exception\InvalidArgumentException;
|
||||
use Kirby\Http\Response;
|
||||
use Kirby\Sane\Sane;
|
||||
use Kirby\Toolkit\Escape;
|
||||
|
@ -28,25 +30,25 @@ class File
|
|||
use Properties;
|
||||
|
||||
/**
|
||||
* Absolute file path
|
||||
*
|
||||
* @var string
|
||||
* Parent file model
|
||||
* The model object must use the `\Kirby\Filesystem\IsFile` trait
|
||||
*/
|
||||
protected $root;
|
||||
protected object|null $model = null;
|
||||
|
||||
/**
|
||||
* Absolute file path
|
||||
*/
|
||||
protected string|null $root = null;
|
||||
|
||||
/**
|
||||
* Absolute file URL
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
protected $url;
|
||||
protected string|null $url = null;
|
||||
|
||||
/**
|
||||
* Validation rules to be used for `::match()`
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $validations = [
|
||||
public static array $validations = [
|
||||
'maxsize' => ['size', 'max'],
|
||||
'minsize' => ['size', 'min']
|
||||
];
|
||||
|
@ -57,8 +59,10 @@ class File
|
|||
* @param array|string|null $props Properties or deprecated `$root` string
|
||||
* @param string|null $url Deprecated argument, use `$props['url']` instead
|
||||
*/
|
||||
public function __construct($props = null, string $url = null)
|
||||
{
|
||||
public function __construct(
|
||||
array|string|null $props = null,
|
||||
string|null $url = null
|
||||
) {
|
||||
// Legacy support for old constructor of
|
||||
// the `Kirby\Image\Image` class
|
||||
// @todo 4.0.0 remove
|
||||
|
@ -74,8 +78,6 @@ class File
|
|||
|
||||
/**
|
||||
* Improved `var_dump` output
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function __debugInfo(): array
|
||||
{
|
||||
|
@ -84,8 +86,6 @@ class File
|
|||
|
||||
/**
|
||||
* Returns the URL for the file object
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString(): string
|
||||
{
|
||||
|
@ -94,8 +94,6 @@ class File
|
|||
|
||||
/**
|
||||
* Returns the file content as base64 encoded string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function base64(): string
|
||||
{
|
||||
|
@ -104,15 +102,11 @@ class File
|
|||
|
||||
/**
|
||||
* Copy a file to a new location.
|
||||
*
|
||||
* @param string $target
|
||||
* @param bool $force
|
||||
* @return static
|
||||
*/
|
||||
public function copy(string $target, bool $force = false)
|
||||
public function copy(string $target, bool $force = false): static
|
||||
{
|
||||
if (F::copy($this->root, $target, $force) !== true) {
|
||||
throw new Exception('The file "' . $this->root . '" could not be copied');
|
||||
if (F::copy($this->root(), $target, $force) !== true) {
|
||||
throw new Exception('The file "' . $this->root() . '" could not be copied');
|
||||
}
|
||||
|
||||
return new static($target);
|
||||
|
@ -122,7 +116,6 @@ class File
|
|||
* Returns the file as data uri
|
||||
*
|
||||
* @param bool $base64 Whether the data should be base64 encoded or not
|
||||
* @return string
|
||||
*/
|
||||
public function dataUri(bool $base64 = true): string
|
||||
{
|
||||
|
@ -135,77 +128,64 @@ class File
|
|||
|
||||
/**
|
||||
* Deletes the file
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function delete(): bool
|
||||
{
|
||||
if (F::remove($this->root) !== true) {
|
||||
throw new Exception('The file "' . $this->root . '" could not be deleted');
|
||||
if (F::remove($this->root()) !== true) {
|
||||
throw new Exception('The file "' . $this->root() . '" could not be deleted');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Automatically sends all needed headers for the file to be downloaded
|
||||
* and echos the file's content
|
||||
* Automatically sends all needed headers
|
||||
* for the file to be downloaded and
|
||||
* echos the file's content
|
||||
*
|
||||
* @param string|null $filename Optional filename for the download
|
||||
* @return string
|
||||
*/
|
||||
public function download($filename = null): string
|
||||
public function download(string|null $filename = null): string
|
||||
{
|
||||
return Response::download($this->root, $filename ?? $this->filename());
|
||||
return Response::download($this->root(), $filename ?? $this->filename());
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the file actually exists
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function exists(): bool
|
||||
{
|
||||
return file_exists($this->root) === true;
|
||||
return file_exists($this->root()) === true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current lowercase extension (without .)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function extension(): string
|
||||
{
|
||||
return F::extension($this->root);
|
||||
return F::extension($this->root());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the filename
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function filename(): string
|
||||
{
|
||||
return basename($this->root);
|
||||
return basename($this->root());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a md5 hash of the root
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function hash(): string
|
||||
{
|
||||
return md5($this->root);
|
||||
return md5($this->root());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends an appropriate header for the asset
|
||||
*
|
||||
* @param bool $send
|
||||
* @return \Kirby\Http\Response|void
|
||||
*/
|
||||
public function header(bool $send = true)
|
||||
public function header(bool $send = true): Response|null
|
||||
{
|
||||
$response = new Response('', $this->mime());
|
||||
|
||||
|
@ -214,13 +194,11 @@ class File
|
|||
}
|
||||
|
||||
$response->send();
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the file to html
|
||||
*
|
||||
* @param array $attr
|
||||
* @return string
|
||||
*/
|
||||
public function html(array $attr = []): string
|
||||
{
|
||||
|
@ -231,27 +209,22 @@ class File
|
|||
* Checks if a file is of a certain type
|
||||
*
|
||||
* @param string $value An extension or mime type
|
||||
* @return bool
|
||||
*/
|
||||
public function is(string $value): bool
|
||||
{
|
||||
return F::is($this->root, $value);
|
||||
return F::is($this->root(), $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the file is readable
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isReadable(): bool
|
||||
{
|
||||
return is_readable($this->root) === true;
|
||||
return is_readable($this->root()) === true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the file is a resizable image
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isResizable(): bool
|
||||
{
|
||||
|
@ -261,8 +234,6 @@ class File
|
|||
/**
|
||||
* Checks if a preview can be displayed for the file
|
||||
* in the panel or in the frontend
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isViewable(): bool
|
||||
{
|
||||
|
@ -271,20 +242,16 @@ class File
|
|||
|
||||
/**
|
||||
* Checks if the file is writable
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isWritable(): bool
|
||||
{
|
||||
return F::isWritable($this->root);
|
||||
return F::isWritable($this->root());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the app instance if it exists
|
||||
*
|
||||
* @return \Kirby\Cms\App|null
|
||||
*/
|
||||
public function kirby()
|
||||
public function kirby(): App|null
|
||||
{
|
||||
return App::instance(null, true);
|
||||
}
|
||||
|
@ -293,8 +260,6 @@ class File
|
|||
* Runs a set of validations on the file object
|
||||
* (mainly for images).
|
||||
*
|
||||
* @param array $rules
|
||||
* @return bool
|
||||
* @throws \Kirby\Exception\Exception
|
||||
*/
|
||||
public function match(array $rules): bool
|
||||
|
@ -361,27 +326,33 @@ class File
|
|||
|
||||
/**
|
||||
* Detects the mime type of the file
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function mime()
|
||||
public function mime(): string|null
|
||||
{
|
||||
return Mime::type($this->root);
|
||||
return Mime::type($this->root());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the parent file model, which uses this instance as proxied file asset
|
||||
*/
|
||||
public function model(): object|null
|
||||
{
|
||||
return $this->model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the file's last modification time
|
||||
*
|
||||
* @param string|\IntlDateFormatter|null $format
|
||||
* @param string|null $handler date, intl or strftime
|
||||
* @return mixed
|
||||
*/
|
||||
public function modified($format = null, ?string $handler = null)
|
||||
{
|
||||
public function modified(
|
||||
string|IntlDateFormatter|null $format = null,
|
||||
string|null $handler = null
|
||||
): string|int|false {
|
||||
$kirby = $this->kirby();
|
||||
|
||||
return F::modified(
|
||||
$this->root,
|
||||
$this->root(),
|
||||
$format,
|
||||
$handler ?? ($kirby ? $kirby->option('date.handler', 'date') : 'date')
|
||||
);
|
||||
|
@ -390,14 +361,12 @@ class File
|
|||
/**
|
||||
* Move the file to a new location
|
||||
*
|
||||
* @param string $newRoot
|
||||
* @param bool $overwrite Force overwriting any existing files
|
||||
* @return static
|
||||
*/
|
||||
public function move(string $newRoot, bool $overwrite = false)
|
||||
public function move(string $newRoot, bool $overwrite = false): static
|
||||
{
|
||||
if (F::move($this->root, $newRoot, $overwrite) !== true) {
|
||||
throw new Exception('The file: "' . $this->root . '" could not be moved to: "' . $newRoot . '"');
|
||||
if (F::move($this->root(), $newRoot, $overwrite) !== true) {
|
||||
throw new Exception('The file: "' . $this->root() . '" could not be moved to: "' . $newRoot . '"');
|
||||
}
|
||||
|
||||
return new static($newRoot);
|
||||
|
@ -406,62 +375,53 @@ class File
|
|||
/**
|
||||
* Getter for the name of the file
|
||||
* without the extension
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function name(): string
|
||||
{
|
||||
return pathinfo($this->root, PATHINFO_FILENAME);
|
||||
return pathinfo($this->root(), PATHINFO_FILENAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the file size in a
|
||||
* human-readable format
|
||||
*
|
||||
* @param string|null|false $locale Locale for number formatting,
|
||||
* @param string|false|null $locale Locale for number formatting,
|
||||
* `null` for the current locale,
|
||||
* `false` to disable number formatting
|
||||
* @return string
|
||||
*/
|
||||
public function niceSize($locale = null): string
|
||||
public function niceSize(string|false|null $locale = null): string
|
||||
{
|
||||
return F::niceSize($this->root, $locale);
|
||||
return F::niceSize($this->root(), $locale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the file content and returns it.
|
||||
*
|
||||
* @return string|false
|
||||
*/
|
||||
public function read()
|
||||
public function read(): string|false
|
||||
{
|
||||
return F::read($this->root);
|
||||
return F::read($this->root());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the absolute path to the file
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function realpath(): string
|
||||
{
|
||||
return realpath($this->root);
|
||||
return realpath($this->root());
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the name of the file without
|
||||
* touching the extension
|
||||
*
|
||||
* @param string $newName
|
||||
* @param bool $overwrite Force overwrite existing files
|
||||
* @return static
|
||||
*/
|
||||
public function rename(string $newName, bool $overwrite = false)
|
||||
public function rename(string $newName, bool $overwrite = false): static
|
||||
{
|
||||
$newRoot = F::rename($this->root, $newName, $overwrite);
|
||||
$newRoot = F::rename($this->root(), $newName, $overwrite);
|
||||
|
||||
if ($newRoot === false) {
|
||||
throw new Exception('The file: "' . $this->root . '" could not be renamed to: "' . $newName . '"');
|
||||
throw new Exception('The file: "' . $this->root() . '" could not be renamed to: "' . $newName . '"');
|
||||
}
|
||||
|
||||
return new static($newRoot);
|
||||
|
@ -469,21 +429,35 @@ class File
|
|||
|
||||
/**
|
||||
* Returns the given file path
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function root(): ?string
|
||||
public function root(): string|null
|
||||
{
|
||||
return $this->root;
|
||||
return $this->root ??= $this->model?->root();
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the parent file model, which uses this instance as proxied file asset
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @throws \Kirby\Exception\InvalidArgumentException When the model does not use the `Kirby\Filesystem\IsFile` trait
|
||||
*/
|
||||
protected function setModel(object|null $model = null): static
|
||||
{
|
||||
if ($model !== null && method_exists($model, 'hasIsFileTrait') !== true) {
|
||||
throw new InvalidArgumentException('The model object must use the "Kirby\Filesystem\IsFile" trait');
|
||||
}
|
||||
|
||||
$this->model = $model;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for the root
|
||||
*
|
||||
* @param string|null $root
|
||||
* @return $this
|
||||
*/
|
||||
protected function setRoot(?string $root = null)
|
||||
protected function setRoot(string|null $root = null): static
|
||||
{
|
||||
$this->root = $root;
|
||||
return $this;
|
||||
|
@ -492,10 +466,9 @@ class File
|
|||
/**
|
||||
* Setter for the file url
|
||||
*
|
||||
* @param string|null $url
|
||||
* @return $this
|
||||
*/
|
||||
protected function setUrl(?string $url = null)
|
||||
protected function setUrl(string|null $url = null): static
|
||||
{
|
||||
$this->url = $url;
|
||||
return $this;
|
||||
|
@ -503,12 +476,13 @@ class File
|
|||
|
||||
/**
|
||||
* Returns the absolute url for the file
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function url(): ?string
|
||||
public function url(): string|null
|
||||
{
|
||||
return $this->url;
|
||||
// lazily determine the URL from the model object
|
||||
// only if it's needed to avoid breaking custom file::url
|
||||
// components that rely on `$cmsFile->asset()` methods
|
||||
return $this->url ??= $this->model?->url();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -519,14 +493,13 @@ class File
|
|||
* @param string|bool $typeLazy Explicit sane handler type string,
|
||||
* `true` for lazy autodetection or
|
||||
* `false` for normal autodetection
|
||||
* @return void
|
||||
*
|
||||
* @throws \Kirby\Exception\InvalidArgumentException If the file didn't pass validation
|
||||
* @throws \Kirby\Exception\LogicException If more than one handler applies
|
||||
* @throws \Kirby\Exception\NotFoundException If the handler was not found
|
||||
* @throws \Kirby\Exception\Exception On other errors
|
||||
*/
|
||||
public function sanitizeContents($typeLazy = false): void
|
||||
public function sanitizeContents(string|bool $typeLazy = false): void
|
||||
{
|
||||
Sane::sanitizeFile($this->root(), $typeLazy);
|
||||
}
|
||||
|
@ -534,29 +507,23 @@ class File
|
|||
/**
|
||||
* Returns the sha1 hash of the file
|
||||
* @since 3.6.0
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function sha1(): string
|
||||
{
|
||||
return sha1_file($this->root);
|
||||
return sha1_file($this->root());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the raw size of the file
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function size(): int
|
||||
{
|
||||
return F::size($this->root);
|
||||
return F::size($this->root());
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the media object to a
|
||||
* plain PHP array
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
|
@ -582,8 +549,6 @@ class File
|
|||
/**
|
||||
* Converts the entire file array into
|
||||
* a json string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function toJson(): string
|
||||
{
|
||||
|
@ -592,12 +557,10 @@ class File
|
|||
|
||||
/**
|
||||
* Returns the file type.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function type(): ?string
|
||||
public function type(): string|null
|
||||
{
|
||||
return F::type($this->root);
|
||||
return F::type($this->root());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -606,27 +569,23 @@ class File
|
|||
* @param string|bool $typeLazy Explicit sane handler type string,
|
||||
* `true` for lazy autodetection or
|
||||
* `false` for normal autodetection
|
||||
* @return void
|
||||
*
|
||||
* @throws \Kirby\Exception\InvalidArgumentException If the file didn't pass validation
|
||||
* @throws \Kirby\Exception\NotFoundException If the handler was not found
|
||||
* @throws \Kirby\Exception\Exception On other errors
|
||||
*/
|
||||
public function validateContents($typeLazy = false): void
|
||||
public function validateContents(string|bool $typeLazy = false): void
|
||||
{
|
||||
Sane::validateFile($this->root(), $typeLazy);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes content to the file
|
||||
*
|
||||
* @param string $content
|
||||
* @return bool
|
||||
*/
|
||||
public function write($content): bool
|
||||
public function write(string $content): bool
|
||||
{
|
||||
if (F::write($this->root, $content) !== true) {
|
||||
throw new Exception('The file "' . $this->root . '" could not be written');
|
||||
if (F::write($this->root(), $content) !== true) {
|
||||
throw new Exception('The file "' . $this->root() . '" could not be written');
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
@ -30,45 +30,31 @@ class Filename
|
|||
{
|
||||
/**
|
||||
* List of all applicable attributes
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $attributes;
|
||||
protected array $attributes;
|
||||
|
||||
/**
|
||||
* The sanitized file extension
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $extension;
|
||||
protected string $extension;
|
||||
|
||||
/**
|
||||
* The source original filename
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $filename;
|
||||
protected string $filename;
|
||||
|
||||
/**
|
||||
* The sanitized file name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $name;
|
||||
protected string $name;
|
||||
|
||||
/**
|
||||
* The template for the final name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $template;
|
||||
protected string $template;
|
||||
|
||||
/**
|
||||
* Creates a new Filename object
|
||||
*
|
||||
* @param string $filename
|
||||
* @param string $template
|
||||
* @param array $attributes
|
||||
*/
|
||||
public function __construct(string $filename, string $template, array $attributes = [])
|
||||
{
|
||||
|
@ -84,8 +70,6 @@ class Filename
|
|||
|
||||
/**
|
||||
* Converts the entire object to a string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString(): string
|
||||
{
|
||||
|
@ -96,8 +80,6 @@ class Filename
|
|||
* Converts all processed attributes
|
||||
* to an array. The array keys are already
|
||||
* the shortened versions for the filename
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function attributesToArray(): array
|
||||
{
|
||||
|
@ -123,9 +105,8 @@ class Filename
|
|||
* new filename
|
||||
*
|
||||
* @param string|null $prefix The prefix will be used in the filename creation
|
||||
* @return string
|
||||
*/
|
||||
public function attributesToString(string $prefix = null): string
|
||||
public function attributesToString(string|null $prefix = null): string
|
||||
{
|
||||
$array = $this->attributesToArray();
|
||||
$result = [];
|
||||
|
@ -135,16 +116,11 @@ class Filename
|
|||
$value = '';
|
||||
}
|
||||
|
||||
switch ($key) {
|
||||
case 'dimensions':
|
||||
$result[] = $value;
|
||||
break;
|
||||
case 'crop':
|
||||
$result[] = ($value === 'center') ? 'crop' : $key . '-' . $value;
|
||||
break;
|
||||
default:
|
||||
$result[] = $key . $value;
|
||||
}
|
||||
$result[] = match ($key) {
|
||||
'dimensions' => $value,
|
||||
'crop' => ($value === 'center') ? 'crop' : $key . '-' . $value,
|
||||
default => $key . $value
|
||||
};
|
||||
}
|
||||
|
||||
$result = array_filter($result);
|
||||
|
@ -159,10 +135,8 @@ class Filename
|
|||
|
||||
/**
|
||||
* Normalizes the blur option value
|
||||
*
|
||||
* @return false|int
|
||||
*/
|
||||
public function blur()
|
||||
public function blur(): int|false
|
||||
{
|
||||
$value = $this->attributes['blur'] ?? false;
|
||||
|
||||
|
@ -175,10 +149,8 @@ class Filename
|
|||
|
||||
/**
|
||||
* Normalizes the crop option value
|
||||
*
|
||||
* @return false|string
|
||||
*/
|
||||
public function crop()
|
||||
public function crop(): string|false
|
||||
{
|
||||
// get the crop value
|
||||
$crop = $this->attributes['crop'] ?? false;
|
||||
|
@ -194,10 +166,8 @@ class Filename
|
|||
* Returns a normalized array
|
||||
* with width and height values
|
||||
* if available
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function dimensions()
|
||||
public function dimensions(): array
|
||||
{
|
||||
if (empty($this->attributes['width']) === true && empty($this->attributes['height']) === true) {
|
||||
return [];
|
||||
|
@ -211,8 +181,6 @@ class Filename
|
|||
|
||||
/**
|
||||
* Returns the sanitized extension
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function extension(): string
|
||||
{
|
||||
|
@ -225,8 +193,6 @@ class Filename
|
|||
* the option. You can use `grayscale`,
|
||||
* `greyscale` or simply `bw`. The function
|
||||
* will always return `grayscale`
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function grayscale(): bool
|
||||
{
|
||||
|
@ -239,8 +205,6 @@ class Filename
|
|||
|
||||
/**
|
||||
* Returns the filename without extension
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function name(): string
|
||||
{
|
||||
|
@ -249,10 +213,8 @@ class Filename
|
|||
|
||||
/**
|
||||
* Normalizes the quality option value
|
||||
*
|
||||
* @return false|int
|
||||
*/
|
||||
public function quality()
|
||||
public function quality(): int|false
|
||||
{
|
||||
$value = $this->attributes['quality'] ?? false;
|
||||
|
||||
|
@ -268,9 +230,6 @@ class Filename
|
|||
* The extension will be converted
|
||||
* to lowercase and `jpeg` will be
|
||||
* replaced with `jpg`
|
||||
*
|
||||
* @param string $extension
|
||||
* @return string
|
||||
*/
|
||||
protected function sanitizeExtension(string $extension): string
|
||||
{
|
||||
|
@ -282,9 +241,6 @@ class Filename
|
|||
/**
|
||||
* Sanitizes the name with Kirby's
|
||||
* Str::slug function
|
||||
*
|
||||
* @param string $name
|
||||
* @return string
|
||||
*/
|
||||
protected function sanitizeName(string $name): string
|
||||
{
|
||||
|
@ -293,8 +249,6 @@ class Filename
|
|||
|
||||
/**
|
||||
* Returns the converted filename as string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function toString(): string
|
||||
{
|
||||
|
|
|
@ -26,29 +26,21 @@ trait IsFile
|
|||
|
||||
/**
|
||||
* File asset object
|
||||
*
|
||||
* @var \Kirby\Filesystem\File
|
||||
*/
|
||||
protected $asset;
|
||||
protected File|null $asset = null;
|
||||
|
||||
/**
|
||||
* Absolute file path
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
protected $root;
|
||||
protected string|null $root = null;
|
||||
|
||||
/**
|
||||
* Absolute file URL
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
protected $url;
|
||||
protected string|null $url = null;
|
||||
|
||||
/**
|
||||
* Constructor sets all file properties
|
||||
*
|
||||
* @param array $props
|
||||
*/
|
||||
public function __construct(array $props)
|
||||
{
|
||||
|
@ -58,9 +50,6 @@ trait IsFile
|
|||
/**
|
||||
* Magic caller for asset methods
|
||||
*
|
||||
* @param string $method
|
||||
* @param array $arguments
|
||||
* @return mixed
|
||||
* @throws \Kirby\Exception\BadMethodCallException
|
||||
*/
|
||||
public function __call(string $method, array $arguments = [])
|
||||
|
@ -80,8 +69,6 @@ trait IsFile
|
|||
|
||||
/**
|
||||
* Converts the asset to a string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString(): string
|
||||
{
|
||||
|
@ -90,33 +77,29 @@ trait IsFile
|
|||
|
||||
/**
|
||||
* Returns the file asset object
|
||||
*
|
||||
* @param array|string|null $props
|
||||
* @return \Kirby\Filesystem\File
|
||||
*/
|
||||
public function asset($props = null)
|
||||
public function asset(array|string|null $props = null): File
|
||||
{
|
||||
if ($this->asset !== null) {
|
||||
return $this->asset;
|
||||
}
|
||||
|
||||
$props = $props ?? [
|
||||
'root' => $this->root(),
|
||||
'url' => $this->url()
|
||||
];
|
||||
$props ??= [];
|
||||
|
||||
switch ($this->type()) {
|
||||
case 'image':
|
||||
return $this->asset = new Image($props);
|
||||
default:
|
||||
return $this->asset = new File($props);
|
||||
if (is_string($props) === true) {
|
||||
$props = ['root' => $props];
|
||||
}
|
||||
|
||||
$props['model'] ??= $this;
|
||||
|
||||
return $this->asset = match ($this->type()) {
|
||||
'image' => new Image($props),
|
||||
default => new File($props)
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the file exists on disk
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function exists(): bool
|
||||
{
|
||||
|
@ -126,23 +109,29 @@ trait IsFile
|
|||
return file_exists($this->root()) === true;
|
||||
}
|
||||
|
||||
/**
|
||||
* To check the existence of the IsFile trait
|
||||
*
|
||||
* @todo Switch to class constant in traits when min PHP version 8.2 required
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
protected function hasIsFileTrait(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the app instance
|
||||
*
|
||||
* @return \Kirby\Cms\App
|
||||
*/
|
||||
public function kirby()
|
||||
public function kirby(): App
|
||||
{
|
||||
return App::instance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the given file path
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function root(): ?string
|
||||
public function root(): string|null
|
||||
{
|
||||
return $this->root;
|
||||
}
|
||||
|
@ -150,10 +139,9 @@ trait IsFile
|
|||
/**
|
||||
* Setter for the root
|
||||
*
|
||||
* @param string|null $root
|
||||
* @return $this
|
||||
*/
|
||||
protected function setRoot(?string $root = null)
|
||||
protected function setRoot(string|null $root = null): static
|
||||
{
|
||||
$this->root = $root;
|
||||
return $this;
|
||||
|
@ -162,10 +150,9 @@ trait IsFile
|
|||
/**
|
||||
* Setter for the file url
|
||||
*
|
||||
* @param string|null $url
|
||||
* @return $this
|
||||
*/
|
||||
protected function setUrl(?string $url = null)
|
||||
protected function setUrl(string|null $url = null): static
|
||||
{
|
||||
$this->url = $url;
|
||||
return $this;
|
||||
|
@ -173,10 +160,8 @@ trait IsFile
|
|||
|
||||
/**
|
||||
* Returns the file type
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function type(): ?string
|
||||
public function type(): string|null
|
||||
{
|
||||
// Important to include this in the trait
|
||||
// to avoid infinite loops when trying
|
||||
|
@ -186,10 +171,8 @@ trait IsFile
|
|||
|
||||
/**
|
||||
* Returns the absolute url for the file
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function url(): ?string
|
||||
public function url(): string|null
|
||||
{
|
||||
return $this->url;
|
||||
}
|
||||
|
|
|
@ -170,7 +170,7 @@ class Mime
|
|||
* @param string $extension
|
||||
* @return string|null
|
||||
*/
|
||||
public static function fromExtension(string $extension): ?string
|
||||
public static function fromExtension(string $extension): string|null
|
||||
{
|
||||
$mime = static::$types[$extension] ?? null;
|
||||
return is_array($mime) === true ? array_shift($mime) : $mime;
|
||||
|
@ -312,12 +312,8 @@ class Mime
|
|||
|
||||
/**
|
||||
* Returns the MIME type of a file
|
||||
*
|
||||
* @param string $file
|
||||
* @param string $extension
|
||||
* @return string|false
|
||||
*/
|
||||
public static function type(string $file, string $extension = null)
|
||||
public static function type(string $file, string|null $extension = null): string|null
|
||||
{
|
||||
// use the standard finfo extension
|
||||
$mime = static::fromFileInfo($file);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue