diff --git a/src/flextype/Foundation/Entries/Fields/MediaField.php b/src/flextype/Foundation/Entries/Fields/MediaField.php new file mode 100644 index 00000000..e279b9a0 --- /dev/null +++ b/src/flextype/Foundation/Entries/Fields/MediaField.php @@ -0,0 +1,106 @@ +get('flextype.settings.entries.fields.media.files.fetch.enabled')) { + flextype('emitter')->addListener('onEntriesFetchSingleHasResult', static function (): void { + if (flextype('entries')->hasStorage('fetch.data.media.files.fetch')) { + // Get fetch. + $original = flextype('entries')->getStorage('fetch'); + + switch (flextype('registry')->get('flextype.settings.entries.fields.media.files.fetch.result')) { + case 'toArray': + $resultTo = 'toArray'; + break; + + case 'toObject': + default: + $resultTo = 'copy'; + break; + } + + // Modify fetch. + foreach (flextype('entries')->getStorage('fetch.data.media.files.fetch') as $field => $body) { + + if (isset($body['method']) && + strpos($body['method'], 'fetch') !== false && + is_callable([flextype('media_files'), $body['method']])) { + $fetchFromCallbackMethod = $body['method']; + } else { + $fetchFromCallbackMethod = 'fetch'; + } + + + $result = isset($body['result']) && in_array($body['result'], ['toArray', 'toObject']) ? $body['result'] : $resultTo; + + $data[$field] = flextype('media_files')->{$fetchFromCallbackMethod}($body['id'], + isset($body['options']) ? + $body['options'] : + []); + + $data[$field] = ($data[$field] instanceof Arrays) ? $data[$field]->{$result}() : $data[$field]; + } + + // Save fetch. + flextype('entries')->setStorage('fetch.id', $original['id']); + flextype('entries')->setStorage('fetch.options', $original['options']); + flextype('entries')->setStorage('fetch.data', arrays($original['data'])->merge($data)->toArray()); + } + }); +} + + +if (flextype('registry')->get('flextype.settings.entries.fields.media.folders.fetch.enabled')) { + flextype('emitter')->addListener('onEntriesFetchSingleHasResult', static function (): void { + if (flextype('entries')->hasStorage('fetch.data.media.folders.fetch')) { + + // Get fetch. + $original = flextype('entries')->getStorage('fetch'); + + switch (flextype('registry')->get('flextype.settings.entries.fields.media.folders.fetch.result')) { + case 'toArray': + $resultTo = 'toArray'; + break; + + case 'toObject': + default: + $resultTo = 'copy'; + break; + } + + // Modify fetch. + foreach (flextype('entries')->getStorage('fetch.data.media.folders.fetch') as $field => $body) { + + if (isset($body['method']) && + strpos($body['method'], 'fetch') !== false && + is_callable([flextype('media_folders'), $body['method']])) { + $fetchFromCallbackMethod = $body['method']; + } else { + $fetchFromCallbackMethod = 'fetch'; + } + + + $result = isset($body['result']) && in_array($body['result'], ['toArray', 'toObject']) ? $body['result'] : $resultTo; + + $data[$field] = flextype('media_folders')->{$fetchFromCallbackMethod}($body['id'], + isset($body['options']) ? + $body['options'] : + []); + + $data[$field] = ($data[$field] instanceof Arrays) ? $data[$field]->{$result}() : $data[$field]; + } + + // Save fetch. + flextype('entries')->setStorage('fetch.id', $original['id']); + flextype('entries')->setStorage('fetch.options', $original['options']); + flextype('entries')->setStorage('fetch.data', arrays($original['data'])->merge($data)->toArray()); + } + }); +} diff --git a/src/flextype/settings.yaml b/src/flextype/settings.yaml index 0e9c2a48..78328bed 100644 --- a/src/flextype/settings.yaml +++ b/src/flextype/settings.yaml @@ -59,6 +59,15 @@ errors: entries: extension: md fields: + media: + files: + fetch: + enabled: true + result: toObject + folders: + fetch: + enabled: true + result: toObject registry: get: enabled: true diff --git a/tests/Foundation/Entries/Fields/MediaFieldTest.php b/tests/Foundation/Entries/Fields/MediaFieldTest.php new file mode 100644 index 00000000..9f8d4799 --- /dev/null +++ b/tests/Foundation/Entries/Fields/MediaFieldTest.php @@ -0,0 +1,46 @@ +directory(PATH['project'] . '/entries')->create(); + filesystem()->directory(PATH['project'] . '/uploads')->create(0755, true); + filesystem()->directory(PATH['project'] . '/uploads/.meta')->create(0755, true); + filesystem()->directory(PATH['project'] . '/uploads/foo')->create(0755, true); + filesystem()->directory(PATH['project'] . '/uploads/.meta/foo')->create(0755, true); +}); + +afterEach(function (): void { + filesystem()->directory(PATH['project'] . '/uploads/.meta')->delete(); + filesystem()->directory(PATH['project'] . '/uploads')->delete(); + filesystem()->directory(PATH['project'] . '/entries')->delete(); +}); + +test('test media_files field', function () { + + filesystem()->file(PATH['project'] . '/uploads/foo.txt')->put('foo'); + filesystem()->file(PATH['project'] . '/uploads/.meta/foo.txt.yaml')->put(flextype('yaml')->encode(['title' => 'Foo', 'description' => '', 'type' => 'text/plain', 'filesize' => 3, 'uploaded_on' => 1603090370, 'exif' => []])); + filesystem()->file(PATH['project'] . '/uploads/bar.txt')->put('foo'); + filesystem()->file(PATH['project'] . '/uploads/.meta/bar.txt.yaml')->put(flextype('yaml')->encode(['title' => 'Bar', 'description' => '', 'type' => 'text/plain', 'filesize' => 3, 'uploaded_on' => 1603090370, 'exif' => []])); + + flextype('entries')->create('media', flextype('frontmatter')->decode(filesystem()->file(ROOT_DIR . '/tests/Foundation/Entries/Fields/fixtures/entries/media/entry.md')->get())); + + flextype('media_files')::macro('fetchExtraData', function ($id, $options) { + return ['id' => $id, 'options' => $options]; + }); + + flextype('media_folders')::macro('fetchExtraData', function ($id, $options) { + return ['id' => $id, 'options' => $options]; + }); + + $media = flextype('entries')->fetch('media'); + + $this->assertEquals('Media', $media['title']); + $this->assertEquals('foo', $media['macroable_file']['id']); + $this->assertEquals('foo.txt', $media['foo_file']['filename']); + $this->assertEquals(2, $media['collection_of_files']->count()); + + $this->assertEquals('foo', $media['macroable_folder']['id']); + $this->assertEquals(4, $media['foo_folder']->count()); + $this->assertEquals(1, $media['collection_of_folders']->count()); +}); diff --git a/tests/Foundation/Entries/Fields/fixtures/entries/media/entry.md b/tests/Foundation/Entries/Fields/fixtures/entries/media/entry.md new file mode 100644 index 00000000..3295914b --- /dev/null +++ b/tests/Foundation/Entries/Fields/fixtures/entries/media/entry.md @@ -0,0 +1,28 @@ +--- +title: Media +media: + folders: + fetch: + macroable_folder: + id: 'foo' + method: fetchExtraData + options: [] + foo_folder: + id: 'foo' + collection_of_folders: + id: '/' + options: + collection: true + files: + fetch: + macroable_file: + id: 'foo' + method: fetchExtraData + options: [] + foo_file: + id: foo.txt + collection_of_files: + id: '/' + options: + collection: true +---