Skip to content

Instantly share code, notes, and snippets.

@lukaskleinschmidt
Created June 14, 2024 10:32
Show Gist options
  • Save lukaskleinschmidt/8a25bcd1eb0523f8f8b4a51e6aae408f to your computer and use it in GitHub Desktop.
Save lukaskleinschmidt/8a25bcd1eb0523f8f8b4a51e6aae408f to your computer and use it in GitHub Desktop.
Kirby 4 fetch models from the uuid cache
<?php
use Kirby\Cache\FileCache;
use Kirby\Uuid\Identifiable;
use Kirby\Uuid\Uuid;
class UuidModels
{
/**
* Create a new instance.
*/
public function __construct(
protected string $type,
protected FileCache $cache,
) {}
/**
* Create a new instance for the given uuid type.
*/
public static function for(string $type): static
{
return new static($type, kirby()->cache('uuid'));
}
/**
* Get a uuid from a directory and filename.
*/
protected function uuid(string $dirname, string $filename): string
{
return $this->type . '://' . basename($dirname . $filename, '.cache');
}
/**
* Get a model from the uuid cache.
*
* @return Identifiable|null
*/
protected function model(string $uuid): Identifiable|null
{
return Uuid::for($uuid)->model();
}
/**
* Yield entries from a directory.
*
* @return Generator|string
*/
protected function yield(string $path): Generator
{
$handle = opendir($path);
try {
while (false !== ($entry = readdir($handle))) {
yield $entry;
}
} finally {
closedir($handle);
}
}
/**
* Get entries from the uuid cache.
*
* @return Generator|array<\Kirby\Uuid\Identifiable>
*/
public function entries(): Generator
{
$root = $this->cache->root() . '/' . $this->type;
foreach ($this->yield($root) as $dirname) {
if (in_array($dirname, ['.', '..'])) {
continue;
}
$path = $root . '/' . $dirname;
if (is_dir($path) === false) {
continue;
}
foreach ($this->yield($path) as $filename) {
$file = $path . '/' . $filename;
if (is_file($file) === false) {
continue;
}
try {
$uuid = $this->uuid($dirname, $filename);
$model = $this->model($uuid);
if (is_null($model) === false) {
yield $model;
}
} finally {}
}
}
}
/**
* Take a number of entries from the uuid cache.
*
* @return array<\Kirby\Uuid\Identifiable>
*/
public function take(int $limit, Closure $callback = null): array
{
$entries = [];
foreach ($this->entries() as $entry) {
if ($callback && ! $callback($entry)) {
continue;
}
$entries[] = $entry;
if ($limit > 0 && count($entries) >= $limit) {
break;
}
}
return $entries;
}
/**
* Get files from the uuid cache.
*
* @return array<\Kirby\Cms\File>
*/
public static function files(Closure $callback = null, int $limit = null): array
{
return static::for('file')->take($limit ?? 0, $callback);
}
/**
* Get pages from the uuid cache.
*
* @return array<\Kirby\Cms\Page>
*/
public static function pages(Closure $callback = null, int $limit = null): array
{
return static::for('page')->take($limit ?? 0, $callback);
}
/**
* Get users from the uuid cache.
*
* @return array<\Kirby\Cms\User>
*/
public static function users(Closure $callback = null, int $limit = null): array
{
return static::for('user')->take($limit ?? 0, $callback);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment