Files
lichterei-web/kirby/src/Uuid/ModelUuid.php
Bastian Allgeier de62b5f553 Upgrade to 3.8.1.1
2022-10-25 11:51:57 +02:00

138 lines
3.3 KiB
PHP

<?php
namespace Kirby\Uuid;
use Kirby\Cms\App;
use Kirby\Cms\Collection;
/**
* Base for UUIDs for models where id string
* is stored in the content, such as pages and files
* @since 3.8.0
*
* @package Kirby Uuid
* @author Nico Hoffmann <nico@getkirby.com>
* @link https://getkirby.com
* @copyright Bastian Allgeier
* @license https://getkirby.com/license
*/
abstract class ModelUuid extends Uuid
{
/**
* @var \Kirby\Cms\ModelWithContent|null
*/
public Identifiable|null $model;
public function __construct(
string|null $uuid = null,
Identifiable|null $model = null,
Collection|null $context = null
) {
parent::__construct($uuid, $model, $context);
// ensure that ID gets generated right away if
// not yet stored any in content file
$this->id();
}
/**
* Looks up UUID in local and global index
* and returns the identifiable model object
*/
protected function findByIndex(): Identifiable|null
{
foreach ($this->indexes() as $model) {
if (static::retrieveId($model) === $this->id()) {
return $model;
}
}
return null;
}
/**
* Returns the UUID's id string; if not set yet,
* creates a new unique ID and writes it to content file
*/
public function id(): string
{
if ($id = $this->uri->host()) {
return $id;
}
// generate a new ID (to be saved in the content file)
$id = static::generate();
// store the new UUID
$this->storeId($id);
// update the Uri object
$this->uri->host($id);
return $id;
}
/**
* Retrieves the ID string (UUID without scheme) for the model
* from the content file, if it is already stored there
*
* @param \Kirby\Cms\ModelWithContent $model
*/
public static function retrieveId(Identifiable $model): string|null
{
return $model->content('default')->get('uuid')->value();
}
/**
* Stores the UUID for the model and makes sure
* to update the content file and content object cache
*/
protected function storeId(string $id): void
{
// get the content array from the page
$data = $this->model->content('default')->toArray();
// check for an empty content array
// and read content from file again,
// just to be sure we don't lose content
if (empty($data) === true) {
usleep(1000);
$data = $this->model->readContent('default');
}
// add the UUID to the content array
if (empty($data['uuid']) === true) {
$data['uuid'] = $id;
}
// overwrite the content in memory for the current request
if ($this->model->kirby()->multilang() === true) {
// update the default translation instead of the content object
// (the default content object is always freshly loaded from the
// default translation afterwards, so updating the default
// content object would not have any effect)
$this->model->translation('default')->update($data);
} else {
$this->model->content('default')->update($data);
}
// overwrite the content in the file;
// use the most basic write method to avoid object cloning
$this->model->writeContent($data, 'default');
}
/**
* Returns permalink url
*/
public function url(): string
{
// make sure UUID is cached because the permalink
// route only looks up UUIDs from cache
if ($this->isCached() === false) {
$this->populate();
}
return App::instance()->url() . '/@/' . static::TYPE . '/' . $this->id();
}
}