diff --git a/classes/Khulan.php b/classes/Khulan.php index f280d3c..416bbe0 100644 --- a/classes/Khulan.php +++ b/classes/Khulan.php @@ -10,6 +10,8 @@ use Kirby\Cms\Site; use Kirby\Cms\User; use Kirby\Cms\Users; +use Kirby\Data\Data; +use Kirby\Filesystem\F; use Kirby\Toolkit\A; class Khulan @@ -39,7 +41,7 @@ public static function index(int $iterations = 2): array $count++; } - /** @var File $file */ + /** @var User $user */ foreach (kirby()->users() as $user) { if ($user->hasKhulan() !== true) { continue; @@ -57,6 +59,28 @@ public static function index(int $iterations = 2): array $count++; } + /** @var File $file */ + foreach (site()->index(true)->files() as $file) { + if ($file->hasKhulan() !== true) { + continue; + } + if (kirby()->multilang()) { + foreach (kirby()->languages() as $language) { + $contentFile = $file->root().'.'.$language->code().'.txt'; + if (! F::exists($contentFile)) { + continue; + } + $hash[] = $file->id().$language->code(); + $file->writeKhulan(Data::read($contentFile), $language->code()); + } + } else { + $contentFile = $file->root().'.txt'; + $hash[] = $file->id(); + $file->writeKhulan(Data::read($contentFile)); + } + $count++; + } + $meta = [ 'count' => $count, 'hash' => hash('xxh3', implode('|', $hash)), @@ -75,6 +99,7 @@ public static function index(int $iterations = 2): array khulan()->createIndex(['language' => 1]); khulan()->createIndex(['template' => 1]); khulan()->createIndex(['modelType' => 1]); + khulan()->createIndex(['status' => 1]); } return $meta; diff --git a/classes/KhulanFile.php b/classes/KhulanFile.php index 713a6ca..b15efcd 100644 --- a/classes/KhulanFile.php +++ b/classes/KhulanFile.php @@ -6,5 +6,5 @@ class KhulanFile extends \Kirby\Cms\File { - // use ModelWithKhulan; // TODO: breaks stuff + use ModelWithKhulan; } diff --git a/classes/ModelWithKhulan.php b/classes/ModelWithKhulan.php index 4b4769c..6ef4d59 100644 --- a/classes/ModelWithKhulan.php +++ b/classes/ModelWithKhulan.php @@ -6,11 +6,13 @@ use DateTime; use Exception; +use Kirby\Cms\Blueprint; use Kirby\Cms\File; use Kirby\Cms\Page; use Kirby\Cms\Site; use Kirby\Cms\User; use Kirby\Data\Yaml; +use Kirby\Filesystem\F; use Kirby\Toolkit\A; use Kirby\Toolkit\Str; use MongoDB\BSON\ObjectId; @@ -22,6 +24,10 @@ trait ModelWithKhulan public function hasKhulan(): bool { + if ($this instanceof File) { + return $this->parent()->hasKhulan() === true; + } + return true; } @@ -107,24 +113,33 @@ public function writeKhulan(?array $data = null, ?string $languageCode = null): $modelType = 'file'; } - $slug = explode('/', $this->id()); $meta = [ 'id' => $this->id() ?? null, 'modified' => $modified, 'modified{}' => new UTCDateTime($modified * 1000), - 'slug' => $this->id() ? array_pop($slug) : null, 'class' => $this::class, 'language' => $languageCode, 'modelType' => $modelType, ]; if ($this instanceof Page) { + $slug = explode('/', $this->id()); + $meta['num'] = $this->num() ? (int) $this->num() : null; + $meta['slug'] = $this->id() ? array_pop($slug) : null; $meta['template'] = $this->intendedTemplate()->name(); + $meta['status'] = $this->status(); } elseif ($this instanceof File) { + // can not use $file->content() since it would trigger a loop + $meta['sort'] = A::get($data, 'sort') ? (int) A::get($data, 'sort') : null; $meta['filename'] = $this->filename(); + $meta['template'] = A::get($data, 'template'); + $meta['mimeType'] = F::mime($this->root()); + $meta['parent{}'] = new ObjectId($this->parent()->keyKhulan($languageCode)); } elseif ($this instanceof User) { $meta['email'] = $this->email(); + $meta['name'] = $this->name()->isNotEmpty() ? $this->name()->value() : null; + $meta['role'] = $this->role()->name(); } - $data = $this->encodeKhulan($data, $languageCode) + $meta; + $data = array_merge($this->encodeKhulan($data, $languageCode), $meta); // _id is not allowed as data key if (array_key_exists('_id', $data)) { @@ -180,11 +195,28 @@ public function delete(bool $force = false): bool public function encodeKhulan(array $data, ?string $languageCode = null): array { + $blueprint = null; + if ($this instanceof Page) { + $blueprint = $this->blueprint()->fields(); + } elseif ($this instanceof File) { + // $blueprint = $this->blueprint(); + // does not work as that would trigger a loop reading the content + // but it can be read manually + $blueprint = Blueprint::find('files/'.A::get($data, 'template', 'default')); + $blueprint = A::get($blueprint, 'fields'); + } + if (! $blueprint) { + return $data; + } // foreach each key value pairs $copy = $data; foreach ($data as $key => $value) { + $field = A::get($blueprint, $key); + if (! $field) { + continue; + } if (is_string($value)) { - $type = A::get($this->blueprint()->field($key), 'type'); + $type = A::get($field, 'type'); // if it is a comma separated list unroll it to an array. validate if it is with a regex but allow for spaces chars after the comma @@ -299,14 +331,26 @@ public function decodeKhulan(?array $data = []): array $meta = [ 'id', 'modified', - 'slug', - 'template', + 'modified{}', 'class', 'language', 'modelType', - 'filename', - 'email', ]; + if ($this instanceof Page) { + $meta[] = 'num'; + $meta[] = 'slug'; + $meta[] = 'status'; + $meta[] = 'template'; + } elseif ($this instanceof File) { + $meta[] = 'sort'; + $meta[] = 'filename'; + $meta[] = 'mimeType'; + $meta[] = 'template'; + } elseif ($this instanceof User) { + $meta[] = 'email'; + $meta[] = 'name'; + $meta[] = 'role'; + } foreach ($meta as $key) { if (array_key_exists($key, $copy)) { unset($copy[$key]); diff --git a/composer.json b/composer.json index 5bc73cd..0c34c22 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "bnomei/kirby-mongodb", "type": "kirby-plugin", - "version": "1.2.0", + "version": "1.3.0", "description": "Khulan is a cache driver and content cache with NoSQL interface for Kirby using MongoDB", "license": "MIT", "authors": [ diff --git a/composer.lock b/composer.lock index d41a776..d586171 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "77679a7a33c8ced433f565409a9bc711", + "content-hash": "60f302973165849b692a80d75e7c8546", "packages": [ { "name": "getkirby/composer-installer", diff --git a/index.php b/index.php index e729880..921d269 100644 --- a/index.php +++ b/index.php @@ -72,7 +72,7 @@ function khulan(string|array|null $search = null): mixed 'khulan' => [ // cache for models 'read' => false, // mongodb is most likely slower than file system for the pages 'write' => true, - 'patch-files-class' => false, // monkey patch files class + 'patch-files-class' => true, // monkey patch files class ], ], 'cacheTypes' => [ diff --git a/tests/MongodbTest.php b/tests/MongodbTest.php index e6ec454..b00ec92 100644 --- a/tests/MongodbTest.php +++ b/tests/MongodbTest.php @@ -138,7 +138,7 @@ 'tags[,]' => ['$in' => ['Punk']], ]); - expect($pages->count())->toBe(1); + expect($pages->count())->toBe(2); }); it('can find all pages that have another page linked', function () { @@ -185,6 +185,14 @@ ->and($user->email())->toBe($email); }); +it('can find a file', function () { + Khulan::index(); + + $file = khulan('betterharder/image.jpg'); + expect($file)->toBeInstanceOf(\Kirby\Cms\File::class) + ->and($file->filename())->toBe('image.jpg'); +}); + it('can run the benchmark', function () { mongo()->benchmark(); })->skip(); diff --git a/tests/content/1_home/image.jpg.en.txt b/tests/content/1_home/image.jpg.en.txt deleted file mode 100644 index e69de29..0000000 diff --git a/tests/content/2_betterharder/default.en.txt b/tests/content/2_betterharder/default.en.txt index 81bc426..e7a4e16 100644 --- a/tests/content/2_betterharder/default.en.txt +++ b/tests/content/2_betterharder/default.en.txt @@ -2,7 +2,7 @@ Title: Better Harder ---- -Text: ssxxsss +Text: ssxxssss ---- @@ -18,7 +18,7 @@ Tags: Daft, Punk ---- -Category: +Category: books ---- @@ -26,4 +26,8 @@ Related: - page://fasterstronger ---- +Grass: - file://CVPNHRGDjnSWKsAz + +---- + Uuid: betterharder \ No newline at end of file diff --git a/tests/content/1_home/image.jpg b/tests/content/2_betterharder/example2.png similarity index 100% rename from tests/content/1_home/image.jpg rename to tests/content/2_betterharder/example2.png diff --git a/tests/content/2_betterharder/example2.png.en.txt b/tests/content/2_betterharder/example2.png.en.txt new file mode 100644 index 0000000..4f9b016 --- /dev/null +++ b/tests/content/2_betterharder/example2.png.en.txt @@ -0,0 +1,9 @@ +Uuid: CVPNHRGDjnSWKsAz + +---- + +Template: grass + +---- + +Sort: 1 \ No newline at end of file diff --git a/tests/content/2_betterharder/image.jpg b/tests/content/2_betterharder/image.jpg new file mode 100644 index 0000000..63fd18f Binary files /dev/null and b/tests/content/2_betterharder/image.jpg differ diff --git a/tests/content/2_betterharder/image.jpg.de.txt b/tests/content/2_betterharder/image.jpg.de.txt new file mode 100644 index 0000000..a6d4fc9 --- /dev/null +++ b/tests/content/2_betterharder/image.jpg.de.txt @@ -0,0 +1 @@ +Textinfile: image DE diff --git a/tests/content/2_betterharder/image.jpg.en.txt b/tests/content/2_betterharder/image.jpg.en.txt new file mode 100644 index 0000000..eabbbfc --- /dev/null +++ b/tests/content/2_betterharder/image.jpg.en.txt @@ -0,0 +1,9 @@ +Textinfile: image ENs + +---- + +Uuid: 0MAa7eq7xsWRqK2u + +---- + +Sort: 2 \ No newline at end of file diff --git a/tests/site/blueprints/files/default.yml b/tests/site/blueprints/files/default.yml new file mode 100644 index 0000000..a9a1209 --- /dev/null +++ b/tests/site/blueprints/files/default.yml @@ -0,0 +1,3 @@ +fields: + textinfile: + type: text diff --git a/tests/site/blueprints/files/grass.yml b/tests/site/blueprints/files/grass.yml new file mode 100644 index 0000000..b0b6e19 --- /dev/null +++ b/tests/site/blueprints/files/grass.yml @@ -0,0 +1,3 @@ +fields: + green: + type: text diff --git a/tests/site/blueprints/tabs/default.yml b/tests/site/blueprints/tabs/default.yml index 5c1fb6c..84a99df 100644 --- a/tests/site/blueprints/tabs/default.yml +++ b/tests/site/blueprints/tabs/default.yml @@ -22,7 +22,14 @@ sections: movies: Movies related: type: pages + grass: + type: files + uploads: + template: grass + info: "{{ file.template }}" pages: type: pages + info: "{{ page.template }}" files: type: files + info: "{{ file.template }}" diff --git a/tests/site/blueprints/users/admin.yml b/tests/site/blueprints/users/admin.yml new file mode 100644 index 0000000..46102b7 --- /dev/null +++ b/tests/site/blueprints/users/admin.yml @@ -0,0 +1,3 @@ +fields: + birthday: + type: date diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php index 7c89a88..885a111 100644 --- a/vendor/composer/installed.php +++ b/vendor/composer/installed.php @@ -1,8 +1,8 @@ array( 'name' => 'bnomei/kirby-mongodb', - 'pretty_version' => '1.2.0', - 'version' => '1.2.0.0', + 'pretty_version' => '1.3.0', + 'version' => '1.3.0.0', 'reference' => null, 'type' => 'kirby-plugin', 'install_path' => __DIR__ . '/../../', @@ -11,8 +11,8 @@ ), 'versions' => array( 'bnomei/kirby-mongodb' => array( - 'pretty_version' => '1.2.0', - 'version' => '1.2.0.0', + 'pretty_version' => '1.3.0', + 'version' => '1.3.0.0', 'reference' => null, 'type' => 'kirby-plugin', 'install_path' => __DIR__ . '/../../',