From 508abcd2a832fb52a92f2b2bd839a0386d7efd8b Mon Sep 17 00:00:00 2001 From: Awilum Date: Thu, 26 May 2022 20:44:20 +0300 Subject: [PATCH] feat(shortcodes): add ability to parse nested shortcodes for `entries` --- .../Parsers/Shortcodes/EntriesShortcode.php | 92 +++++++++---------- .../Shortcodes/EntriesShortcodeTest.php | 8 +- 2 files changed, 45 insertions(+), 55 deletions(-) diff --git a/src/flextype/core/Parsers/Shortcodes/EntriesShortcode.php b/src/flextype/core/Parsers/Shortcodes/EntriesShortcode.php index 33a8f3be..d7232396 100644 --- a/src/flextype/core/Parsers/Shortcodes/EntriesShortcode.php +++ b/src/flextype/core/Parsers/Shortcodes/EntriesShortcode.php @@ -30,63 +30,53 @@ parsers()->shortcodes()->addHandler('entries', static function (ShortcodeInterfa return ''; } - $varsDelimeter = ($s->getParameter('varsDelimeter') != null) ? parsers()->shortcodes()->parse($s->getParameter('varsDelimeter')) : ','; $result = ''; + $params = $s->getParameters(); + + if (collection(array_keys($params))->filter(fn ($v) => $v == 'fetch')->count() > 0 && + isset($params['id']) && + registry()->get('flextype.settings.parsers.shortcodes.shortcodes.entries.fetch.enabled') === true) { - foreach($s->getParameters() as $key => $value) { - - if ($key == 'fetch' && registry()->get('flextype.settings.parsers.shortcodes.shortcodes.entries.fetch.enabled') === true) { + $id = parsers()->shortcodes()->parse($params['id']); - $vars = $value !== null ? strings($value)->contains($varsDelimeter) ? explode($varsDelimeter, $value) : [$value] : []; - - // Parse shortcodes for each var. - $vars = array_map(fn($v) => parsers()->shortcodes()->parse(is_string($v) ? $v : ''), $vars); - - // Set options - if (isset($vars[1])) { - parse_str($vars[1], $options); - } else { - $options = []; - } - - // Prepare options - $options = collection($options)->dot()->map(function($value) { - if(strings($value)->isInteger()) { - $value = strings($value)->toInteger(); - } elseif(strings($value)->isFloat()) { - $value = strings($value)->toFloat(); - } elseif(strings($value)->isBoolean()) { - $value = strings($value)->toBoolean(); - } elseif(strings($value)->isNull()) { - $value = strings($value)->toNull(); - } else { - $value = (string) $value; - } - return $value; - })->undot()->toArray(); - - // Backup current entry data - $original = entries()->registry()['methods.fetch']; - - // Fetch entry - $result = entries()->fetch($vars[0], $options); - - // Restore original entry data - entries()->registry()->set('methods.fetch', $original); - - // Convert entry as a json string - $result = $result->toJson(); + // Set options + if (isset($params['options'])) { + parse_str(parsers()->shortcodes()->parse($params['options']), $options); + } else { + $options = []; } - // Get specific field value or return default value. - if ($key == 'field' && $value !== null) { - - $vars = $value !== null ? strings($value)->contains($varsDelimeter) ? explode($varsDelimeter, $value) : [$value] : ['']; - - // Parse shortcodes for each var. - $vars = array_map(fn($v) => parsers()->shortcodes()->parse(is_string($v) ? $v : ''), $vars); + // Prepare options + $options = collection($options)->dot()->map(function($value) { + if(strings($value)->isInteger()) { + $value = strings($value)->toInteger(); + } elseif(strings($value)->isFloat()) { + $value = strings($value)->toFloat(); + } elseif(strings($value)->isBoolean()) { + $value = strings($value)->toBoolean(); + } elseif(strings($value)->isNull()) { + $value = strings($value)->toNull(); + } else { + $value = (string) $value; + } + return $value; + })->undot()->toArray(); - $result = collectionFromJson($result)->get($vars[0], $vars[1] ?? ''); + // Backup current entry data + $original = entries()->registry()['methods.fetch']; + + // Fetch entry + $result = entries()->fetch($id, $options); + + // Restore original entry data + entries()->registry()->set('methods.fetch', $original); + + // Convert entry as a json string + $result = $result->toJson(); + + // Get specific field value + if ($s->getParameter('field') != null) { + $result = collectionFromJson($result)->get(parsers()->shortcodes()->parse($s->getParameter('field')), ($s->getParameter('default') != null) ? parsers()->shortcodes()->parse($s->getParameter('default')) : ''); } } diff --git a/tests/src/flextype/core/Parsers/Shortcodes/EntriesShortcodeTest.php b/tests/src/flextype/core/Parsers/Shortcodes/EntriesShortcodeTest.php index fa20e422..12f8d8ef 100644 --- a/tests/src/flextype/core/Parsers/Shortcodes/EntriesShortcodeTest.php +++ b/tests/src/flextype/core/Parsers/Shortcodes/EntriesShortcodeTest.php @@ -11,7 +11,7 @@ afterEach(function () { }); test('entries shortcode', function () { - $this->assertTrue(entries()->create('blog', ['title' => 'Blog', 'categories' => "@type[array] (entries fetch:'blog,collection=true&filter[sort_by][key]=date&filter[sort_by][direction]=ASC' /)"])); + $this->assertTrue(entries()->create('blog', ['title' => 'Blog', 'categories' => "@type[array] (entries fetch id:'blog' options:'collection=true&filter[sort_by][key]=date&filter[sort_by][direction]=ASC' /)"])); $this->assertTrue(entries()->create('blog/post-1', ['title' => 'Post 1'])); $this->assertTrue(entries()->create('blog/post-2', ['title' => 'Post 2'])); $this->assertTrue(entries()->create('blog/post-3', ['title' => 'Post 3'])); @@ -21,13 +21,13 @@ test('entries shortcode', function () { expect(entries()->fetch('blog')->dot()->count())->toBe(44); - $this->assertTrue(entries()->create('blog-2', ['title' => 'Blog', 'category-cat' => "(entries fetch:'categories/cat' field:'title,Foo' /)"])); + $this->assertTrue(entries()->create('blog-2', ['title' => 'Blog', 'category-cat' => "(entries fetch id:'categories/cat' field:'title' default:'foo' /)"])); expect(entries()->fetch('blog-2')['category-cat'])->toBe('Cat'); - $this->assertTrue(entries()->create('blog-3', ['title' => 'Blog', 'category-cat' => "(entries fetch:'categories/cat' field:'title2,Foo' /)"])); + $this->assertTrue(entries()->create('blog-3', ['title' => 'Blog', 'category-cat' => "(entries fetch id:'categories/cat' field:'title2' default:'Foo' /)"])); expect(entries()->fetch('blog-3')['category-cat'])->toBe('Foo'); - $this->assertTrue(entries()->create('shop', ['vars' => ['id' => 'shop', 'options' => 'collection=true'], 'title' => 'Shop', 'products' => "@type[array] (entries fetch:'(var:id),(var:options)' /)"])); + $this->assertTrue(entries()->create('shop', ['vars' => ['id' => 'shop', 'options' => 'collection=true'], 'title' => 'Shop', 'products' => "@type[array] (entries fetch id:'(var:id)' options:'(var:options)' /)"])); $this->assertTrue(entries()->create('shop/product-1', ['title' => 'Product 1'])); expect(count(entries()->fetch('shop')['products']))->toBe(1); });