Skip to content

Commit

Permalink
♻️ objId resolve with multilang
Browse files Browse the repository at this point in the history
  • Loading branch information
bnomei committed Jul 1, 2024
1 parent 3aacf31 commit 9a514d0
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 9 deletions.
38 changes: 34 additions & 4 deletions classes/Khulan.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,53 @@

class Khulan
{
public static function index(): array
public static function index(int $iterations = 2): array
{
$count = 0;
$hash = [];

// reading a field like the title will make sure
// that the page is loaded and cached
/** @var Page $page */
foreach (site()->index(true) as $page) {
$hash[] = $page->title()->value();
if ($page->hasKhulan() !== true) {
continue;
}
if (kirby()->multilang()) {
foreach (kirby()->languages() as $language) {
$content = $page->content($language->code())->toArray();
$hash[] = $content['title'];
$page->writeKhulan($content, $language->code());
}
} else {
$hash[] = $page->title()->value();
$page->writeKhulan($page->content()->toArray());
}
$count++;
}
// TODO: files, users

return [
$meta = [
'count' => $count,
'hash' => hash('xxh3', implode('|', $hash)),
];

// call twice by default to make it possible to resolve relations
if ($iterations > 1) {
$iterations--;
$meta = self::index($iterations);
}

// add indexes for better performance
if ($iterations === 1) {
khulan()->createIndex(['id' => 1]);
khulan()->createIndex(['uuid' => 1]);
khulan()->createIndex(['language' => 1]);
khulan()->createIndex(['template' => 1]);
khulan()->createIndex(['modelType' => 1]);
}

return $meta;
}

public static function flush(): bool
Expand Down Expand Up @@ -92,7 +122,7 @@ public static function documentToModel($document = null): Page|File|User|Site|nu
return kirby()->site();
} elseif ($document['modelType'] === 'page') {
$document = iterator_to_array($document);
$id = A::get($document, 'uuid', A::get($document, 'id'));
$id = A::get($document, 'id', A::get($document, 'uuid'));

return kirby()->page($id);
}
Expand Down
59 changes: 54 additions & 5 deletions classes/ModelWithKhulan.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public function hasKhulan(): bool
return true;
}

public function setBoostWillBeDeleted(bool $value): void
public function setKhulanCacheWillBeDeleted(bool $value): void
{
$this->khulanCacheWillBeDeleted = $value;
}
Expand Down Expand Up @@ -101,7 +101,7 @@ public function writeKhulan(?array $data = null, ?string $languageCode = null):
'language' => $languageCode,
'modelType' => $modelType,
];
$data = $this->encodeKhulan($data) + $meta;
$data = $this->encodeKhulan($data, $languageCode) + $meta;

// _id is not allowed as data key
if (array_key_exists('_id', $data)) {
Expand Down Expand Up @@ -131,7 +131,7 @@ public function deleteKhulan(): bool
return true;
}

$this->setBoostWillBeDeleted(true);
$this->setKhulanCacheWillBeDeleted(true);

// using many and by id to delete all language versions
// as well as the version without a language code
Expand All @@ -155,7 +155,7 @@ public function delete(bool $force = false): bool
return $success;
}

public function encodeKhulan(array $data): array
public function encodeKhulan(array $data, ?string $languageCode = null): array
{
// foreach each key value pairs
$copy = $data;
Expand All @@ -175,7 +175,56 @@ public function encodeKhulan(array $data): array

// if it is a valid yaml string, convert it to an array
if (in_array(
$type, ['pages', 'files', 'users', 'object', 'structure']
$type, ['pages', 'files', 'users']
)) {
try {
$v = Yaml::decode($value);
if (is_array($v)) {
$copy[$key.'[]'] = $v;
$copy[$key.'{}'] = [];
// resolve each and set objectid
foreach ($v as $vv) {
$modelType = null;
if (Str::startsWith($vv, 'page://')) {
$modelType = 'page';
} elseif (Str::startsWith($vv, 'file://')) {
$modelType = 'file';
} elseif (Str::startsWith($vv, 'user://')) {
$modelType = 'user';
} elseif (Str::startsWith($vv, 'site://')) {
$modelType = 'site';
}
if (! $modelType) {
continue;
}
$vv = str_replace($modelType.'://', '', $vv);
$query = [
'$or' => [
['id' => $vv],
['uuid' => $vv],
],
];
if (kirby()->multilang() && $languageCode) {
$query = [
'$and' => [
$query,
['language' => $languageCode],
],
];
}
$document = khulan()->findOne($query);
if ($document) {
$copy[$key.'{}'][] = $document['_id'];
}
}
}
} catch (\Exception $e) {
// do nothing
}
}
// if it is a valid yaml string, convert it to an array
if (in_array(
$type, ['object', 'structure']
)) {
try {
$v = Yaml::decode($value);
Expand Down
5 changes: 5 additions & 0 deletions index.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ function khulan(string|array|null $search = null): mixed
],
'hooks' => [
'system.loadPlugins:after' => function () {
if (option('bnomei.mongodb.khulan.read') &&
option('bnomei.mongodb.khulan.write') &&
khulan()->countDocuments() === 0) {
Khulan::index();
}
if (option('bnomei.mongodb.khulan.patch-files-class')) {
$filesClass = kirby()->roots()->kirby().'/src/Cms/Files.php';
if (F::exists($filesClass) && F::isWritable($filesClass)) {
Expand Down
23 changes: 23 additions & 0 deletions tests/MongodbTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,21 @@
expect($value)->toBe('value');
});

it('will not use the cache in debug mode', function () {
Mongodb::$singleton = null;

$mongodb = Mongodb::singleton([
'debug' => true,
]);

expect($mongodb->option('debug'))->toBeTrue();

$mongodb->set('test', 'value');
expect($mongodb->get('test'))->toBeNull();

Mongodb::$singleton = null;
});

it('can use the cache with expiration', function () {
$mongodb = mongo();
$mongodb->set('test', 'value', 1);
Expand All @@ -76,6 +91,14 @@
expect($value)->toBe('value');
});

it('can use a closure in the cache', function () {
$mongodb = mongo();
$mongodb->getOrSet('swatch', fn () => date('B'));
$value = $mongodb->get('swatch');

expect($value)->toBeNumeric();
});

it('can find a page by id and uuid', function () {
Khulan::index();

Expand Down
2 changes: 2 additions & 0 deletions tests/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,7 @@
const KIRBY_HELPER_DUMP = false;
const KIRBY_HELPER_E = false;

// require __DIR__.'/patch.php';

require __DIR__.'/../vendor/autoload.php';
echo (new Kirby())->render();

0 comments on commit 9a514d0

Please sign in to comment.