designtopack/public/kirby/src/Cms/Files.php
2025-02-08 11:08:45 +01:00

174 lines
3.9 KiB
PHP

<?php
namespace Kirby\Cms;
use Kirby\Exception\InvalidArgumentException;
use Kirby\Filesystem\F;
use Kirby\Uuid\HasUuids;
/**
* The `$files` object extends the general
* `Collection` class and refers to a
* collection of files, i.e. images, documents
* etc. Files can be filtered, searched,
* converted, modified or evaluated with the
* following methods:
*
* @package Kirby Cms
* @author Bastian Allgeier <bastian@getkirby.com>
* @link https://getkirby.com
* @copyright Bastian Allgeier
* @license https://getkirby.com/license
*/
class Files extends Collection
{
use HasUuids;
/**
* All registered files methods
*/
public static array $methods = [];
/**
* Adds a single file or
* an entire second collection to the
* current collection
*
* @param \Kirby\Cms\Files|\Kirby\Cms\File|string $object
* @return $this
* @throws \Kirby\Exception\InvalidArgumentException When no `File` or `Files` object or an ID of an existing file is passed
*/
public function add($object): static
{
// add a files collection
if ($object instanceof self) {
$this->data = array_merge($this->data, $object->data);
// add a file by id
} elseif (
is_string($object) === true &&
$file = App::instance()->file($object)
) {
$this->__set($file->id(), $file);
// add a file object
} elseif ($object instanceof File) {
$this->__set($object->id(), $object);
// give a useful error message on invalid input;
// silently ignore "empty" values for compatibility with existing setups
} elseif (in_array($object, [null, false, true], true) !== true) {
throw new InvalidArgumentException('You must pass a Files or File object or an ID of an existing file to the Files collection');
}
return $this;
}
/**
* Sort all given files by the
* order in the array
*
* @param array $files List of file ids
* @param int $offset Sorting offset
* @return $this
*/
public function changeSort(array $files, int $offset = 0): static
{
foreach ($files as $filename) {
if ($file = $this->get($filename)) {
$offset++;
$file->changeSort($offset);
}
}
return $this;
}
/**
* Creates a files collection from an array of props
*/
public static function factory(array $files, Page|Site|User $parent): static
{
$collection = new static([], $parent);
foreach ($files as $props) {
$props['collection'] = $collection;
$props['parent'] = $parent;
$file = File::factory($props);
$collection->data[$file->id()] = $file;
}
return $collection;
}
/**
* Finds a file by its filename
* @internal Use `$files->find()` instead
*/
public function findByKey(string $key): File|null
{
if ($file = $this->findByUuid($key, 'file')) {
return $file;
}
return $this->get(ltrim($this->parent?->id() . '/' . $key, '/'));
}
/**
* Returns the file size for all
* files in the collection in a
* human-readable format
* @since 3.6.0
*
* @param string|null|false $locale Locale for number formatting,
* `null` for the current locale,
* `false` to disable number formatting
*/
public function niceSize($locale = null): string
{
return F::niceSize($this->size(), $locale);
}
/**
* Returns the raw size for all
* files in the collection
* @since 3.6.0
*/
public function size(): int
{
return F::size($this->values(fn ($file) => $file->root()));
}
/**
* Returns the collection sorted by
* the sort number and the filename
*/
public function sorted(): static
{
return $this->sort('sort', 'asc', 'filename', 'asc');
}
/**
* Filter all files by the given template
*
* @return $this|static
*/
public function template(string|array|null $template): static
{
if (empty($template) === true) {
return $this;
}
if ($template === 'default') {
$template = ['default', ''];
}
return $this->filter(
'template',
is_array($template) ? 'in' : '==',
$template
);
}
}