From 2e99d68d4bceb09bb23bd3ccab6cfbf26f6d7027 Mon Sep 17 00:00:00 2001 From: Awilum Date: Sun, 28 Aug 2022 21:20:11 +0300 Subject: [PATCH] feat(helpers): add shortcode `fetch` for `fetch` helper #581 --- .../Parsers/Shortcodes/FetchShortcode.php | 107 ++++++++++++++++++ .../Parsers/Shortcodes/FetchShortcodeTest.php | 51 +++++++++ 2 files changed, 158 insertions(+) create mode 100644 src/flextype/core/Parsers/Shortcodes/FetchShortcode.php create mode 100644 tests/src/flextype/core/Parsers/Shortcodes/FetchShortcodeTest.php diff --git a/src/flextype/core/Parsers/Shortcodes/FetchShortcode.php b/src/flextype/core/Parsers/Shortcodes/FetchShortcode.php new file mode 100644 index 00000000..af878e74 --- /dev/null +++ b/src/flextype/core/Parsers/Shortcodes/FetchShortcode.php @@ -0,0 +1,107 @@ +shortcodes()->addHandler('fetch', static function (ShortcodeInterface $s) { + $params = $s->getParameters(); + + $fetchHelper = function ($params) use ($s) { + + // Get the resource parameter. + $resource = parsers()->shortcodes()->parse($params['resource']); + + // Set options + if (isset($params['options'])) { + parse_str(parsers()->shortcodes()->parse($params['options']), $options); + } else { + $options = []; + } + + // Prepare options + $options = collection($options)->dot()->map(static 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']; + + // Do fetch the data from the resource. + $result = fetch($resource, $options); + + // Restore original entry data + entries()->registry()->set('methods.fetch', $original); + + // Return empty result if result is instance of Response (for e.g. if async = true). + if ($result instanceof Response) { + return ''; + } + + if ($result->count() > 0) { + + $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')) : ''); + } + + return $result; + } + + return ''; + }; + + if (isset($params['resource'])) { + return $fetchHelper($params); + } + + if ($s->getBBCode() !== null) { + $params = ['resource' => $s->getBBCode(), 'options' => isset($params['options']) ? $params['options'] : '']; + return $fetchHelper($params); + } + + return ''; +}); \ No newline at end of file diff --git a/tests/src/flextype/core/Parsers/Shortcodes/FetchShortcodeTest.php b/tests/src/flextype/core/Parsers/Shortcodes/FetchShortcodeTest.php new file mode 100644 index 00000000..913cd0ca --- /dev/null +++ b/tests/src/flextype/core/Parsers/Shortcodes/FetchShortcodeTest.php @@ -0,0 +1,51 @@ +directory(FLEXTYPE_PATH_PROJECT . '/entries')->ensureExists(0755, true); +}); + +afterEach(function () { + filesystem()->directory(FLEXTYPE_PATH_PROJECT . '/entries')->delete(); +}); + +test('fetch shortcode', function () { + + // 1. + $this->assertTrue(entries()->create('data', ['title' => 'Foo', 'category' => 'foo'])); + $this->assertTrue(entries()->create('foo', ['test1' => "(fetch:data field:'title')", + 'test2' => '(fetch:data)', + 'test3' => "(fetch:data field:'foo' default:'FooDefault')"])); + + $foo = entries()->fetch('foo'); + + expect($foo['test1'])->toBe('Foo'); + expect($foo['test2'])->toBeJson(); + expect($foo['test3'])->toBe('FooDefault'); + + // 2. + $this->assertTrue(entries()->create('bar', ['test1' => "(fetch:'(const:FLEXTYPE_ROOT_DIR)/src/flextype/flextype.yaml' field:'name')", + 'test2' => "(fetch:'(const:FLEXTYPE_ROOT_DIR)/src/flextype/flextype.yaml')", + 'test3' => "(fetch:'(const:FLEXTYPE_ROOT_DIR)/src/flextype/flextype.yaml' field:boo default:Boo)"])); + + $bar = entries()->fetch('bar'); + + expect($bar['test1'])->toBe('Flextype'); + expect($bar['test2'])->toBeJson(); + expect($bar['test3'])->toBe('Boo'); + + // 3. @TODO test for fetch data from the urls... +}); + +test('entries shortcode disabled', function () { + registry()->set('flextype.settings.parsers.shortcodes.shortcodes.fetch.enabled', false); + expect(entries()->create('foo', ['test' => ""]))->toBeTrue(); + expect(entries()->fetch('foo')['test'])->toBe(''); + registry()->set('flextype.settings.parsers.shortcodes.shortcodes.fetch.enabled', true); +}); \ No newline at end of file