index-shop/kirby/src/Content/Field.php
isUnknown a3620a1f5f
Some checks are pending
Deploy / Deploy to Production (push) Waiting to run
first commit
2025-12-10 15:12:06 +01:00

212 lines
4 KiB
PHP

<?php
namespace Kirby\Content;
use Closure;
use Kirby\Cms\ModelWithContent;
use Stringable;
/**
* Every field in a Kirby content text file
* is being converted into such a Field object.
*
* Field methods can be registered for those Field
* objects, which can then be used to transform or
* convert the field value. This enables our
* daisy-chaining API for templates and other components
*
* ```php
* // Page field example with lowercase conversion
* $page->myField()->lower();
* ```
*
* @package Kirby Content
* @author Bastian Allgeier <bastian@getkirby.com>
* @link https://getkirby.com
* @copyright Bastian Allgeier
* @license https://getkirby.com/license
*/
class Field implements Stringable
{
/**
* Field method aliases
*/
public static array $aliases = [];
/**
* Registered field methods
*/
public static array $methods = [];
/**
* Creates a new field object
*
* @param \Kirby\Cms\ModelWithContent|null $parent Parent object if available. This will be the page, site, user or file to which the content belongs
* @param string $key The field name
*/
public function __construct(
protected ModelWithContent|null $parent,
protected string $key,
public mixed $value
) {
}
/**
* Magic caller for field methods
*/
public function __call(string $method, array $arguments = []): mixed
{
$method = strtolower($method);
if (isset(static::$methods[$method]) === true) {
return (static::$methods[$method])(clone $this, ...$arguments);
}
if (isset(static::$aliases[$method]) === true) {
$method = strtolower(static::$aliases[$method]);
if (isset(static::$methods[$method]) === true) {
return (static::$methods[$method])(clone $this, ...$arguments);
}
}
return $this;
}
/**
* Simplifies the var_dump result
* @codeCoverageIgnore
*
* @see self::toArray()
*/
public function __debugInfo(): array
{
return $this->toArray();
}
/**
* Makes it possible to simply echo
* or stringify the entire object
*
* @see self::toString()
*/
public function __toString(): string
{
return $this->toString();
}
/**
* Checks if the field exists in the content data array
*/
public function exists(): bool
{
return $this->parent->content()->has($this->key);
}
/**
* Checks if the field content is empty
*/
public function isEmpty(): bool
{
$value = $this->value;
if (is_string($value) === true) {
$value = trim($value);
}
return
$value === null ||
$value === '' ||
$value === [] ||
$value === '[]';
}
/**
* Checks if the field content is not empty
*/
public function isNotEmpty(): bool
{
return $this->isEmpty() === false;
}
/**
* Returns the name of the field
*/
public function key(): string
{
return $this->key;
}
/**
* @see self::parent()
*/
public function model(): ModelWithContent|null
{
return $this->parent;
}
/**
* Provides a fallback if the field value is empty
*
* @return $this|static
*/
public function or(mixed $fallback = null): static
{
if ($this->isNotEmpty() === true) {
return $this;
}
if ($fallback instanceof self) {
return $fallback;
}
$field = clone $this;
$field->value = $fallback;
return $field;
}
/**
* Returns the parent object of the field
*/
public function parent(): ModelWithContent|null
{
return $this->parent;
}
/**
* Converts the Field object to an array
*/
public function toArray(): array
{
return [$this->key => $this->value];
}
/**
* Returns the field value as string
*/
public function toString(): string
{
return (string)$this->value;
}
/**
* Returns the field content. If a new value is passed,
* the modified field will be returned. Otherwise it
* will return the field value.
*/
public function value(string|Closure|null $value = null): mixed
{
if ($value === null) {
return $this->value;
}
if ($value instanceof Closure) {
$value = $value->call($this, $this->value);
}
$clone = clone $this;
$clone->value = (string)$value;
return $clone;
}
}