* @link http://getkirby.com * @copyright Bastian Allgeier */ class Content { /** * The raw data array * * @var array */ protected $data = []; /** * Cached field objects * Once a field is being fetched * it is added to this array for * later reuse * * @var array */ protected $fields = []; /** * A potential parent object. * Not necessarily needed. Especially * for testing, but field methods might * need it. * * @var Page|File|User|Site */ protected $parent; /** * Magic getter for content fields * * @param string $name * @param array $arguments * @return Field */ public function __call(string $name, array $arguments = []): Field { return $this->get($name); } /** * Creates a new Content object * * @param array $data * @param object $parent */ public function __construct($data = [], $parent = null) { $this->data = $data; $this->parent = $parent; } /** * Same as `self::data()` to improve * var_dump output * * @see self::data() * @return array */ public function __debuginfo(): array { return $this->toArray(); } /** * Returns the raw data array * * @return array */ public function data(): array { return $this->data; } /** * Returns all registered field objects * * @return array */ public function fields(): array { foreach ($this->data as $key => $value) { $this->get($key); } return $this->fields; } /** * Returns either a single field object * or all registered fields * * @param string $key * @return Field|array */ public function get(string $key = null) { if ($key === null) { return $this->fields(); } $key = strtolower($key); if (isset($this->fields[$key])) { return $this->fields[$key]; } // fetch the value no matter the case $data = $this->data(); $value = $data[$key] ?? array_change_key_case($data)[$key] ?? null; return $this->fields[$key] = new Field($this->parent, $key, $value); } /** * Checks if a content field is set * * @param string $key * @return boolean */ public function has(string $key): bool { $key = strtolower($key); $data = array_change_key_case($this->data); return isset($data[$key]) === true; } /** * Returns all field keys * * @return array */ public function keys(): array { return array_keys($this->data()); } /** * Returns a clone of the content object * without the fields, specified by the * passed key(s) * * @param string ...$keys * @return self */ public function not(...$keys): self { $copy = clone $this; $copy->fields = null; foreach ($keys as $key) { unset($copy->data[$key]); } return $copy; } /** * Returns the parent * Site, Page, File or User object * * @return Site|Page|File|User */ public function parent() { return $this->parent; } /** * Set the parent model * * @param Model $parent * @return self */ public function setParent(Model $parent): self { $this->parent = $parent; return $this; } /** * Returns the raw data array * * @see self::data() * @return array */ public function toArray(): array { return $this->data(); } /** * Updates the content and returns * a cloned object * * @param array $content * @param bool $overwrite * @return self */ public function update(array $content = null, bool $overwrite = false): self { $this->data = $overwrite === true ? (array)$content : array_merge($this->data, (array)$content); return $this; } }