1
0
mirror of https://github.com/flextype/flextype.git synced 2025-08-10 15:14:20 +02:00

Merge branch '564-new-media-service' into dev

This commit is contained in:
Awilum
2021-08-07 11:16:15 +03:00
37 changed files with 914 additions and 1168 deletions

View File

@@ -27,7 +27,7 @@
"flextype-components/i18n" : "1.3.0",
"atomastic/session": "^2.0.0",
"atomastic/filesystem": "^2.0.0",
"atomastic/filesystem": "^2.1.0",
"atomastic/arrays": "^3.0.5",
"atomastic/registry": "^3.0.1",
"atomastic/strings": "^3.0.2",
@@ -58,7 +58,8 @@
"php-di/slim-bridge": "^3.1.1",
"middlewares/whoops": "^2.0",
"nette/neon": "^3.2",
"league/commonmark": "^2.0"
"league/commonmark": "^2.0",
"siriusphp/upload": "^3.0"
},
"suggest": {
"ext-zend-opcache": "Recommended for better performance",

View File

@@ -1,5 +1,5 @@
parameters:
level: 3
level: 0
reportUnmatchedIgnoredErrors: false
paths:
- src

View File

@@ -9,49 +9,53 @@ declare(strict_types=1);
use Atomastic\Arrays\Arrays;
if (registry()->get('flextype.settings.storage.content.fields.content.fetch.enabled')) {
emitter()->addListener('onContentFetchSingleHasResult', static function (): void {
if (content()->registry()->has('fetch.data.content.fetch')) {
// Get fetch.
$original = content()->registry()->get('fetch');
$data = [];
switch (registry()->get('flextype.settings.storage.content.fields.content.fetch.result')) {
case 'toArray':
$resultTo = 'toArray';
break;
emitter()->addListener('onContentFetchSingleHasResult', static function (): void {
case 'toObject':
default:
$resultTo = 'copy';
break;
}
if (! registry()->get('flextype.settings.entries.content.fields.content.fetch.enabled')) {
return;
}
// Modify fetch.
foreach (content()->registry()->get('fetch.data.content.fetch') as $field => $body) {
if (content()->registry()->has('fetch.data.content.fetch')) {
// Get fetch.
$original = content()->registry()->get('fetch');
$data = [];
if (isset($body['options']['method']) &&
strpos($body['options']['method'], 'fetch') !== false &&
is_callable([content(), $body['options']['method']])) {
$fetchFromCallbackMethod = $body['options']['method'];
} else {
$fetchFromCallbackMethod = 'fetch';
}
switch (registry()->get('flextype.settings.entries.content.fields.content.fetch.result')) {
case 'toArray':
$resultTo = 'toArray';
break;
$result = isset($body['result']) && in_array($body['result'], ['toArray', 'toObject']) ? $body['result'] : $resultTo;
case 'toObject':
default:
$resultTo = 'copy';
break;
}
$data[$field] = content()->{$fetchFromCallbackMethod}($body['id'],
isset($body['options']) ?
$body['options'] :
[]);
// Modify fetch.
foreach (content()->registry()->get('fetch.data.content.fetch') as $field => $body) {
$data[$field] = ($data[$field] instanceof Arrays) ? $data[$field]->{$result}() : $data[$field];
}
if (isset($body['options']['method']) &&
strpos($body['options']['method'], 'fetch') !== false &&
is_callable([content(), $body['options']['method']])) {
$fetchFromCallbackMethod = $body['options']['method'];
} else {
$fetchFromCallbackMethod = 'fetch';
}
// Save fetch.
content()->registry()->set('fetch.id', $original['id']);
content()->registry()->set('fetch.options', $original['options']);
content()->registry()->set('fetch.data', arrays($original['data'])->merge($data)->toArray());
}
});
}
$result = isset($body['result']) && in_array($body['result'], ['toArray', 'toObject']) ? $body['result'] : $resultTo;
$data[$field] = content()->{$fetchFromCallbackMethod}($body['id'],
isset($body['options']) ?
$body['options'] :
[]);
$data[$field] = ($data[$field] instanceof Arrays) ? $data[$field]->{$result}() : $data[$field];
}
// Save fetch.
content()->registry()->set('fetch.id', $original['id']);
content()->registry()->set('fetch.options', $original['options']);
content()->registry()->set('fetch.data', arrays($original['data'])->merge($data)->toArray());
}
});

View File

@@ -7,23 +7,28 @@ declare(strict_types=1);
* Founded by Sergey Romanenko and maintained by Flextype Community.
*/
emitter()->addListener('onContentFetchSingleHasResult', static function (): void {
if (registry()->get('flextype.settings.storage.content.fields.created_at.enabled')) {
emitter()->addListener('onContentFetchSingleHasResult', static function (): void {
if (content()->registry()->get('fetch.data.created_at') === null) {
content()->registry()->set('fetch.data.created_at', (int) filesystem()->file(content()->getFileLocation(content()->registry()->get('fetch.id')))->lastModified());
} else {
content()->registry()->set('fetch.data.created_at', (int) strtotime((string) content()->registry()->get('fetch.data.created_at')));
}
});
if (! registry()->get('flextype.settings.entries.content.fields.created_at.enabled')) {
return;
}
emitter()->addListener('onContentCreate', static function (): void {
if (content()->registry()->get('create.data.created_at') !== null) {
return;
}
if (content()->registry()->get('fetch.data.created_at') === null) {
content()->registry()->set('fetch.data.created_at', (int) filesystem()->file(content()->getFileLocation(content()->registry()->get('fetch.id')))->lastModified());
} else {
content()->registry()->set('fetch.data.created_at', (int) strtotime((string) content()->registry()->get('fetch.data.created_at')));
}
});
content()->registry()->set('create.data.created_at', date(registry()->get('flextype.settings.date_format'), time()));
});
}
emitter()->addListener('onContentCreate', static function (): void {
if (registry()->get('flextype.settings.entries.content.fields.created_at.enabled')) {
return;
}
if (content()->registry()->get('create.data.created_at') !== null) {
return;
}
content()->registry()->set('create.data.created_at', date(registry()->get('flextype.settings.date_format'), time()));
});

View File

@@ -7,12 +7,16 @@ declare(strict_types=1);
* Founded by Sergey Romanenko and maintained by Flextype Community.
*/
if (registry()->get('flextype.settings.storage.content.fields.created_by.enabled')) {
emitter()->addListener('onContentCreate', static function (): void {
if (content()->registry()->get('create.data.created_by') !== null) {
return;
}
emitter()->addListener('onContentCreate', static function (): void {
if (! registry()->get('flextype.settings.entries.content.fields.created_by.enabled')) {
return;
}
if (content()->registry()->get('create.data.created_by') !== null) {
return;
}
content()->registry()->set('create.data.created_by', '');
});
content()->registry()->set('create.data.created_by', '');
});
}

View File

@@ -7,15 +7,15 @@ declare(strict_types=1);
* Founded by Sergey Romanenko and maintained by Flextype Community.
*/
if (registry()->get('flextype.settings.storage.content.fields.id.enabled')) {
emitter()->addListener('onContentFetchSingleHasResult', static function (): void {
emitter()->addListener('onContentFetchSingleHasResult', static function (): void {
if (content()->registry()->get('fetch.data.id') !== null) {
return;
}
if (! registry()->get('flextype.settings.entries.content.fields.id.enabled')) {
return;
}
content()->registry()->set('fetch.data.id', (string) strings(content()->registry()->get('fetch.id'))->trimSlashes());
});
}
if (content()->registry()->get('fetch.data.id') !== null) {
return;
}
content()->registry()->set('fetch.data.id', strings(content()->registry()->get('fetch.id'))->trimSlashes()->toString());
});

View File

@@ -9,100 +9,53 @@ declare(strict_types=1);
use Atomastic\Arrays\Arrays;
if (registry()->get('flextype.settings.storage.content.fields.media.files.fetch.enabled')) {
emitter()->addListener('onContentFetchSingleHasResult', static function (): void {
if (content()->registry()->has('fetch.data.media.files.fetch')) {
// Get fetch.
$original = content()->registry()->get('fetch');
$data = [];
emitter()->addListener('onContentFetchSingleHasResult', static function (): void {
if (! registry()->get('flextype.settings.entries.content.fields.media.enabled')) {
return;
}
switch (registry()->get('flextype.settings.storage.content.fields.media.files.fetch.result')) {
case 'toArray':
$resultTo = 'toArray';
break;
if (content()->registry()->has('fetch.data.media.fetch')) {
// Get fetch.
$original = content()->registry()->get('fetch');
$data = [];
case 'toObject':
default:
$resultTo = 'copy';
break;
}
switch (registry()->get('flextype.settings.entries.content.fields.media.files.fetch.result')) {
case 'toArray':
$resultTo = 'toArray';
break;
// Modify fetch.
foreach (content()->registry()->get('fetch.data.media.files.fetch') as $field => $body) {
case 'toObject':
default:
$resultTo = 'copy';
break;
}
if (isset($body['options']['method']) &&
strpos($body['options']['method'], 'fetch') !== false &&
is_callable([flextype('media')->files(), $body['options']['method']])) {
$fetchFromCallbackMethod = $body['options']['method'];
} else {
$fetchFromCallbackMethod = 'fetch';
}
// Modify fetch.
foreach (content()->registry()->get('fetch.data.media.files.fetch') as $field => $body) {
if (isset($body['options']['method']) &&
strpos($body['options']['method'], 'fetch') !== false &&
is_callable([flextype('media')->files(), $body['options']['method']])) {
$fetchFromCallbackMethod = $body['options']['method'];
} else {
$fetchFromCallbackMethod = 'fetch';
}
$result = isset($body['result']) && in_array($body['result'], ['toArray', 'toObject']) ? $body['result'] : $resultTo;
$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] = flextype('media')->files()->{$fetchFromCallbackMethod}($body['id'],
isset($body['options']) ?
$body['options'] :
[]);
$data[$field] = ($data[$field] instanceof Arrays) ? $data[$field]->{$result}() : $data[$field];
}
$data[$field] = ($data[$field] instanceof Arrays) ? $data[$field]->{$result}() : $data[$field];
}
// Save fetch.
content()->registry()->set('fetch.id', $original['id']);
content()->registry()->set('fetch.options', $original['options']);
content()->registry()->set('fetch.data', arrays($original['data'])->merge($data)->toArray());
}
});
}
if (registry()->get('flextype.settings.storage.content.fields.media.folders.fetch.enabled')) {
emitter()->addListener('onContentFetchSingleHasResult', static function (): void {
if (content()->registry()->has('fetch.data.media.folders.fetch')) {
// Get fetch.
$original = content()->registry()->get('fetch');
$data = [];
switch (registry()->get('flextype.settings.storage.content.fields.media.folders.fetch.result')) {
case 'toArray':
$resultTo = 'toArray';
break;
case 'toObject':
default:
$resultTo = 'copy';
break;
}
// Modify fetch.
foreach (content()->registry()->get('fetch.data.media.folders.fetch') as $field => $body) {
if (isset($body['options']['method']) &&
strpos($body['options']['method'], 'fetch') !== false &&
is_callable([flextype('media')->folders(), $body['options']['method']])) {
$fetchFromCallbackMethod = $body['options']['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.
content()->registry()->set('fetch.id', $original['id']);
content()->registry()->set('fetch.options', $original['options']);
content()->registry()->set('fetch.data', arrays($original['data'])->merge($data)->toArray());
}
});
}
// Save fetch.
content()->registry()->set('fetch.id', $original['id']);
content()->registry()->set('fetch.options', $original['options']);
content()->registry()->set('fetch.data', arrays($original['data'])->merge($data)->toArray());
}
});

View File

@@ -7,12 +7,15 @@ declare(strict_types=1);
* Founded by Sergey Romanenko and maintained by Flextype Community.
*/
if (registry()->get('flextype.settings.storage.content.fields.modified_at.enabled')) {
emitter()->addListener('onContentFetchSingleHasResult', static function (): void {
if (content()->registry()->get('fetch.data.modified_at') !== null) {
return;
}
emitter()->addListener('onContentFetchSingleHasResult', static function (): void {
if (! registry()->get('flextype.settings.entries.content.fields.modified_at.enabled')) {
return;
}
if (content()->registry()->get('fetch.data.modified_at') !== null) {
return;
}
content()->registry()->set('fetch.data.modified_at', (int) filesystem()->file(content()->getFileLocation(content()->registry()->get('fetch.id')))->lastModified());
});
}
content()->registry()->set('fetch.data.modified_at', (int) filesystem()->file(content()->getFileLocation(content()->registry()->get('fetch.id')))->lastModified());
});

View File

@@ -7,37 +7,39 @@ declare(strict_types=1);
* Founded by Sergey Romanenko and maintained by Flextype Community.
*/
if (registry()->get('flextype.settings.storage.content.fields.parsers.enabled')) {
emitter()->addListener('onContentFetchSingleHasResult', static function (): void {
emitter()->addListener('onContentFetchSingleHasResult', static function (): void {
if (! registry()->get('flextype.settings.entries.content.fields.parsers.enabled')) {
return;
}
if (content()->registry()->get('fetch.data.cache.enabled') == null) {
$cache = false;
} else {
$cache = (bool) content()->registry()->get('fetch.data.cache.enabled');
}
if (content()->registry()->get('fetch.data.parsers') != null) {
if (content()->registry()->get('fetch.data.cache.enabled') == null) {
$cache = false;
} else {
$cache = (bool) content()->registry()->get('fetch.data.cache.enabled');
}
if (content()->registry()->get('fetch.data.parsers') != null) {
foreach (content()->registry()->get('fetch.data.parsers') as $parserName => $parserData) {
if (in_array($parserName, ['shortcodes', 'markdown'])) {
if (content()->registry()->get('fetch.data.parsers.'.$parserName.'.enabled') === true) {
if (content()->registry()->get('fetch.data.parsers.'.$parserName.'.fields') != null) {
if (is_array(content()->registry()->get('fetch.data.parsers.'.$parserName.'.fields'))) {
foreach (content()->registry()->get('fetch.data.parsers.'.$parserName.'.fields') as $field) {
if (! in_array($field, registry()->get('flextype.settings.storage.content.fields'))) {
if ($parserName == 'markdown') {
if (arrays(content()->registry()->get('fetch.data'))->has($field)) {
content()->registry()->set('fetch.data.'.$field,
parsers()->markdown()->parse(content()->registry()->get('fetch.data.'.$field), $cache));
}
foreach (content()->registry()->get('fetch.data.parsers') as $parserName => $parserData) {
if (in_array($parserName, ['shortcodes', 'markdown'])) {
if (content()->registry()->get('fetch.data.parsers.'.$parserName.'.enabled') === true) {
if (content()->registry()->get('fetch.data.parsers.'.$parserName.'.fields') != null) {
if (is_array(content()->registry()->get('fetch.data.parsers.'.$parserName.'.fields'))) {
foreach (content()->registry()->get('fetch.data.parsers.'.$parserName.'.fields') as $field) {
if (! in_array($field, registry()->get('flextype.settings.entries.content.fields'))) {
if ($parserName == 'markdown') {
if (arrays(content()->registry()->get('fetch.data'))->has($field)) {
content()->registry()->set('fetch.data.'.$field,
parsers()->markdown()->parse(content()->registry()->get('fetch.data.'.$field), $cache));
}
if ($parserName == 'shortcodes') {
if (arrays(content()->registry()->get('fetch.data'))->has($field)) {
content()->registry()->set('fetch.data.'.$field,
parsers()->shortcodes()->parse(content()->registry()->get('fetch.data.'.$field), $cache));
}
}
if ($parserName == 'shortcodes') {
if (arrays(content()->registry()->get('fetch.data'))->has($field)) {
content()->registry()->set('fetch.data.'.$field,
parsers()->shortcodes()->parse(content()->registry()->get('fetch.data.'.$field), $cache));
}
}
}
@@ -47,5 +49,5 @@ if (registry()->get('flextype.settings.storage.content.fields.parsers.enabled'))
}
}
}
});
}
}
});

View File

@@ -7,20 +7,28 @@ declare(strict_types=1);
* Founded by Sergey Romanenko and maintained by Flextype Community.
*/
if (registry()->get('flextype.settings.storage.content.fields.published_at.enabled')) {
emitter()->addListener('onContentFetchSingleHasResult', static function (): void {
if (content()->registry()->get('fetch.data.published_at') === null) {
content()->registry()->set('fetch.data.published_at', (int) filesystem()->file(content()->getFileLocation(content()->registry()->get('fetch.id')))->lastModified());
} else {
content()->registry()->set('fetch.data.published_at', (int) strtotime((string) content()->registry()->get('fetch.data.published_at')));
}
});
emitter()->addListener('onContentFetchSingleHasResult', static function (): void {
emitter()->addListener('onContentCreate', static function (): void {
if (content()->registry()->get('create.data.published_at') !== null) {
return;
}
if (! registry()->get('flextype.settings.entries.content.fields.published_at.enabled')) {
return;
}
content()->registry()->set('create.data.published_at', date(registry()->get('flextype.settings.date_format'), time()));
});
}
if (content()->registry()->get('fetch.data.published_at') === null) {
content()->registry()->set('fetch.data.published_at', (int) filesystem()->file(content()->getFileLocation(content()->registry()->get('fetch.id')))->lastModified());
} else {
content()->registry()->set('fetch.data.published_at', (int) strtotime((string) content()->registry()->get('fetch.data.published_at')));
}
});
emitter()->addListener('onContentCreate', static function (): void {
if (! registry()->get('flextype.settings.entries.content.fields.published_at.enabled')) {
return;
}
if (content()->registry()->get('create.data.published_at') !== null) {
return;
}
content()->registry()->set('create.data.published_at', date(registry()->get('flextype.settings.date_format'), time()));
});

View File

@@ -7,12 +7,15 @@ declare(strict_types=1);
* Founded by Sergey Romanenko and maintained by Flextype Community.
*/
if (registry()->get('flextype.settings.storage.content.fields.published_by.enabled')) {
emitter()->addListener('onContentCreate', static function (): void {
if (content()->registry()->get('create.data.published_by') !== null) {
return;
}
emitter()->addListener('onContentCreate', static function (): void {
if (! registry()->get('flextype.settings.entries.content.fields.published_by.enabled')) {
return;
}
content()->registry()->set('create.data.published_by', '');
});
}
if (content()->registry()->get('create.data.published_by') !== null) {
return;
}
content()->registry()->set('create.data.published_by', '');
});

View File

@@ -7,25 +7,28 @@ declare(strict_types=1);
* Founded by Sergey Romanenko and maintained by Flextype Community.
*/
if (registry()->get('flextype.settings.storage.content.fields.registry.get.enabled')) {
emitter()->addListener('onContentFetchSingleHasResult', static function (): void {
if (content()->registry()->has('fetch.data.registry.get')) {
// Get fetch.
$original = content()->registry()->get('fetch');
emitter()->addListener('onContentFetchSingleHasResult', static function (): void {
$data = [];
if (! registry()->get('flextype.settings.entries.content.fields.registry.enabled')) {
return;
}
// Modify fetch.
foreach (content()->registry()->get('fetch.data.registry.get') as $field => $body) {
$data = arrays($data)->merge(arrays($data)->set($field, registry()->get($body['key'],
isset($body['default']) ?
$body['default'] :
[]))->toArray())->toArray();
if (content()->registry()->has('fetch.data.registry.get')) {
// Get fetch.
$original = content()->registry()->get('fetch');
}
$data = [];
// Modify fetch.
foreach (content()->registry()->get('fetch.data.registry.get') as $field => $body) {
$data = arrays($data)->merge(arrays($data)->set($field, registry()->get($body['key'],
isset($body['default']) ?
$body['default'] :
[]))->toArray())->toArray();
// Save fetch.
content()->registry()->set('fetch.data', arrays($original['data'])->merge($data)->toArray());
}
});
}
// Save fetch.
content()->registry()->set('fetch.data', arrays($original['data'])->merge($data)->toArray());
}
});

View File

@@ -7,21 +7,29 @@ declare(strict_types=1);
* Founded by Sergey Romanenko and maintained by Flextype Community.
*/
emitter()->addListener('onContentFetchSingleHasResult', static function (): void {
if (registry()->get('flextype.settings.entries.content.fields.routable.enabled')) {
return;
}
if (registry()->get('flextype.settings.storage.content.fields.routable.enabled')) {
emitter()->addListener('onContentFetchSingleHasResult', static function (): void {
if (content()->registry()->get('fetch.data.routable') === null) {
content()->registry()->set('fetch.data.routable', true);
} else {
content()->registry()->set('fetch.data.routable', (bool) content()->registry()->get('fetch.data.routable'));
}
});
if (content()->registry()->get('fetch.data.routable') === null) {
content()->registry()->set('fetch.data.routable', true);
} else {
content()->registry()->set('fetch.data.routable', (bool) content()->registry()->get('fetch.data.routable'));
}
emitter()->addListener('onContentCreate', static function (): void {
if (content()->registry()->get('create.data.routable') === null) {
content()->registry()->set('create.data.routable', true);
} else {
content()->registry()->set('create.data.routable', (bool) content()->registry()->get('create.data.routable'));
}
});
}
});
emitter()->addListener('onContentCreate', static function (): void {
if (! registry()->get('flextype.settings.entries.content.fields.routable.enabled')) {
return;
}
if (content()->registry()->get('create.data.routable') === null) {
content()->registry()->set('create.data.routable', true);
} else {
content()->registry()->set('create.data.routable', (bool) content()->registry()->get('create.data.routable'));
}
});

View File

@@ -7,14 +7,16 @@ declare(strict_types=1);
* Founded by Sergey Romanenko and maintained by Flextype Community.
*/
emitter()->addListener('onContentFetchSingleHasResult', static function (): void {
if (registry()->get('flextype.settings.storage.content.fields.slug.enabled')) {
emitter()->addListener('onContentFetchSingleHasResult', static function (): void {
if (content()->registry()->get('fetch.data.slug') !== null) {
return;
}
if (! registry()->get('flextype.settings.entries.content.fields.slug.enabled')) {
return;
}
$parts = explode('/', ltrim(rtrim(content()->registry()->get('fetch.id'), '/'), '/'));
content()->registry()->set('fetch.data.slug', (string) end($parts));
});
}
if (content()->registry()->get('fetch.data.slug') !== null) {
return;
}
$parts = explode('/', ltrim(rtrim(content()->registry()->get('fetch.id'), '/'), '/'));
content()->registry()->set('fetch.data.slug', (string) end($parts));
});

View File

@@ -9,12 +9,15 @@ declare(strict_types=1);
use Ramsey\Uuid\Uuid;
if (registry()->get('flextype.settings.storage.content.fields.uuid.enabled')) {
emitter()->addListener('onContentCreate', static function (): void {
if (content()->registry()->get('create.data.uuid') !== null) {
return;
}
emitter()->addListener('onContentCreate', static function (): void {
content()->registry()->set('create.data.uuid', Uuid::uuid4()->toString());
});
}
if (! registry()->get('flextype.settings.entries.content.fields.uuid.enabled')) {
return;
}
if (content()->registry()->get('create.data.uuid') !== null) {
return;
}
content()->registry()->set('create.data.uuid', Uuid::uuid4()->toString());
});

View File

@@ -7,26 +7,40 @@ declare(strict_types=1);
* Founded by Sergey Romanenko and maintained by Flextype Community.
*/
if (registry()->get('flextype.settings.storage.content.fields.visibility.enabled')) {
emitter()->addListener('onContentFetchSingleHasResult', static function (): void {
$visibility = [
'draft' => 'draft',
'hidden' => 'hidden',
'visible' => 'visible',
];
emitter()->addListener('onContentFetchSingleHasResult', static function () use ($visibility): void {
if (content()->registry()->get('fetch.data.visibility') !== null && in_array(content()->registry()->get('fetch.data.visibility'), $visibility)) {
content()->registry()->set('fetch.data.visibility', (string) $visibility[content()->registry()->get('fetch.data.visibility')]);
} else {
content()->registry()->set('fetch.data.visibility', (string) $visibility['visible']);
}
});
if (! registry()->get('flextype.settings.entries.content.fields.visibility.enabled')) {
return;
}
emitter()->addListener('onContentCreate', static function () use ($visibility): void {
if (content()->registry()->get('create.data.visibility') !== null && in_array(content()->registry()->get('create.data.visibility'), $visibility)) {
content()->registry()->set('create.data.visibility', (string) $visibility[content()->registry()->get('create.data.visibility')]);
} else {
content()->registry()->set('create.data.visibility', (string) $visibility['visible']);
}
});
}
if (content()->registry()->get('fetch.data.visibility') !== null && in_array(content()->registry()->get('fetch.data.visibility'), $visibility)) {
content()->registry()->set('fetch.data.visibility', (string) $visibility[content()->registry()->get('fetch.data.visibility')]);
} else {
content()->registry()->set('fetch.data.visibility', (string) $visibility['visible']);
}
});
emitter()->addListener('onContentCreate', static function (): void {
$visibility = [
'draft' => 'draft',
'hidden' => 'hidden',
'visible' => 'visible',
];
if (! registry()->get('flextype.settings.entries.content.fields.visibility.enabled')) {
return;
}
if (content()->registry()->get('create.data.visibility') !== null && in_array(content()->registry()->get('create.data.visibility'), $visibility)) {
content()->registry()->set('create.data.visibility', (string) $visibility[content()->registry()->get('create.data.visibility')]);
} else {
content()->registry()->set('create.data.visibility', (string) $visibility['visible']);
}
});

View File

@@ -75,7 +75,7 @@ app()->get('/api/content', function (Request $request, Response $response) use (
}
// override content.fetch.result
registry()->set('flextype.settings.storage.content.fields.content.fetch.result', 'toArray');
registry()->set('flextype.settings.entries.content.fields.content.fetch.result', 'toArray');
if (isset($method) &&
strpos($method, 'fetch') !== false &&

View File

@@ -75,6 +75,14 @@ class Entries
}
foreach ($this->options['fields'] as $field) {
if (! isset($field['enabled'])) {
continue;
}
if (! $field['enabled']) {
continue;
}
if (! isset($field['path'])) {
continue;
}

View File

@@ -0,0 +1,34 @@
<?php
declare(strict_types=1);
/**
* Flextype (https://flextype.org)
* Founded by Sergey Romanenko and maintained by Flextype Community.
*/
emitter()->addListener('onMediaFetchSingleHasResult', static function (): void {
if (! registry()->get('flextype.settings.entries.media.fields.created_at.enabled')) {
return;
}
if (media()->registry()->get('fetch.data.created_at') === null) {
media()->registry()->set('fetch.data.created_at', (int) filesystem()->file(media()->getFileLocation(media()->registry()->get('fetch.id')))->lastModified());
} else {
media()->registry()->set('fetch.data.created_at', (int) strtotime((string) media()->registry()->get('fetch.data.created_at')));
}
});
emitter()->addListener('onMediaCreate', static function (): void {
if (! registry()->get('flextype.settings.entries.media.fields.created_at.enabled')) {
return;
}
if (media()->registry()->get('create.data.created_at') !== null) {
return;
}
media()->registry()->set('create.data.created_at', date(registry()->get('flextype.settings.date_format'), time()));
});

View File

@@ -0,0 +1,21 @@
<?php
declare(strict_types=1);
/**
* Flextype (https://flextype.org)
* Founded by Sergey Romanenko and maintained by Flextype Community.
*/
emitter()->addListener('onMediaCreate', static function (): void {
if (! registry()->get('flextype.settings.entries.media.fields.created_by.enabled')) {
return;
}
if (media()->registry()->get('create.data.created_by') !== null) {
return;
}
media()->registry()->set('create.data.created_by', '');
});

View File

@@ -0,0 +1,21 @@
<?php
declare(strict_types=1);
/**
* Flextype (https://flextype.org)
* Founded by Sergey Romanenko and maintained by Flextype Community.
*/
emitter()->addListener('onMediaFetchSingleHasResult', static function (): void {
if (! registry()->get('flextype.settings.entries.media.fields.id.enabled')) {
return;
}
if (media()->registry()->get('fetch.data.id') !== null) {
return;
}
media()->registry()->set('fetch.data.id', (string) strings(media()->registry()->get('fetch.id'))->trimSlashes());
});

View File

@@ -0,0 +1,21 @@
<?php
declare(strict_types=1);
/**
* Flextype (https://flextype.org)
* Founded by Sergey Romanenko and maintained by Flextype Community.
*/
emitter()->addListener('onMediaFetchSingleHasResult', static function (): void {
if (! registry()->get('flextype.settings.entries.media.fields.modified_at.enabled')) {
return;
}
if (content()->registry()->get('fetch.data.modified_at') !== null) {
return;
}
content()->registry()->set('fetch.data.modified_at', (int) filesystem()->file(content()->getFileLocation(content()->registry()->get('fetch.id')))->lastModified());
});

View File

@@ -0,0 +1,23 @@
<?php
declare(strict_types=1);
/**
* Flextype (https://flextype.org)
* Founded by Sergey Romanenko and maintained by Flextype Community.
*/
use Ramsey\Uuid\Uuid;
emitter()->addListener('onMediaCreate', static function (): void {
if (! registry()->get('flextype.settings.entries.media.fields.uuid.enabled')) {
return;
}
if (media()->registry()->get('create.data.uuid') !== null) {
return;
}
media()->registry()->set('create.data.uuid', Uuid::uuid4()->toString());
});

View File

@@ -10,24 +10,127 @@ declare(strict_types=1);
namespace Flextype\Media;
use Atomastic\Macroable\Macroable;
use Flextype\Entries;
use Sirius\Upload\Handler as UploadHandler;
use Throwable;
class Media
use function emitter;
use function filesystem;
use function getimagesize;
use function image;
use function is_array;
use function is_string;
use function media;
use function registry;
use function strings;
class Media extends Entries
{
use Macroable;
/**
* Create a Media Files instance.
* Constructor.
*
* @param array $options Media options.
*
* @access public
*/
public function files(): MediaFiles
public function __construct(array $options = [])
{
return new MediaFiles();
parent::__construct($options);
emitter()->addListener('onMediaCreate', static function (): void {
if (! media()->registry()->has('create.data.file')) {
return;
}
$file = media()->registry()->get('create.data.file');
if (is_array($file)) {
$id = media()->registry()->get('create.id');
$url = registry()->get('flextype.settings.url');
$media = media()->upload($file, $id);
if ($media->name) {
media()->registry()->set('create.data.file', strings($url . '/project' . registry()->get('flextype.settings.media.upload.directory') . '/' . $id . '/media.' . filesystem()->file($media->name)->extension())->reduceSlashes()->toString());
} else {
media()->registry()->set('create.data.file', '');
}
} else {
media()->registry()->set('create.data.file', $file);
}
});
emitter()->addListener('onMediaCopy', static function (): void {
$currentPath = PATH['project'] . registry()->get('flextype.settings.media.upload.directory') . media()->registry()->get('copy.id');
$newPath = PATH['project'] . registry()->get('flextype.settings.media.upload.directory') . media()->registry()->get('copy.newID');
filesystem()->directory($currentPath)->copy($newPath);
});
emitter()->addListener('onMediaMove', static function (): void {
$currentPath = PATH['project'] . registry()->get('flextype.settings.media.upload.directory') . media()->registry()->get('move.id');
$newPath = PATH['project'] . registry()->get('flextype.settings.media.upload.directory') . media()->registry()->get('move.newID');
filesystem()->directory($currentPath)->move($newPath);
});
emitter()->addListener('onMediaDelete', static function (): void {
$currentPath = PATH['project'] . registry()->get('flextype.settings.media.upload.directory') . media()->registry()->get('delete.id');
filesystem()->directory($currentPath)->delete();
});
}
/**
* Create a Media Files instance.
* Upload media file.
*
* @param array $file Raw file data (multipart/form-data).
* @param string $folder The folder you're targetting.
*
* @access public
*/
public function folders(): MediaFolders
public function upload(array $file, string $folder)
{
return new MediaFolders();
$settings = registry()->get('flextype.settings.media.upload');
$uploadFolder = PATH['project'] . '/uploads/media/' . $folder . '/';
filesystem()->directory($uploadFolder)->ensureExists(0755, true);
$uploadHandler = new UploadHandler($uploadFolder);
$uploadHandler->setOverwrite($settings['overwrite']);
$uploadHandler->setAutoconfirm($settings['autoconfirm']);
$uploadHandler->setPrefix($settings['prefix']);
// Set up the validation rules
$uploadHandler->addRule('extension', ['allowed' => $settings['validation']['allowed_file_extensions']], 'Should be a valid image');
$uploadHandler->addRule('size', ['max' => $settings['validation']['max_file_size']], 'Should have less than {max}');
$uploadHandler->addRule('imagewidth', 'min=' . $settings['validation']['image']['width']['min'] . '&max=' . $settings['validation']['image']['width']['max']);
$uploadHandler->addRule('imageheight', 'min=' . $settings['validation']['image']['height']['min'] . '&max=' . $settings['validation']['image']['width']['max']);
if (isset($settings['validation']['image']['ratio'])) {
$uploadHandler->addRule('imageratio', 'ratio=' . $settings['validation']['image']['ratio']['size'] . '&error_margin=' . $settings['validation']['image']['ratio']['error_margin']);
}
$result = $uploadHandler->process($_FILES['file']);
if (! $result->isValid()) {
return $result->getMessages();
}
try {
$result->confirm();
$mediaFile = $uploadFolder . '/media.' . filesystem()->file($result->name)->extension();
filesystem()->file($uploadFolder . '/' . $result->name)->move($mediaFile);
if (getimagesize($mediaFile)) {
image($mediaFile, $settings['process']['image']);
}
} catch (Throwable $e) {
$result->clear();
throw $e;
}
return $result;
}
}

View File

@@ -1,415 +0,0 @@
<?php
declare(strict_types=1);
/**
* Flextype (https://flextype.org)
* Founded by Sergey Romanenko and maintained by Flextype Community.
*/
namespace Flextype\Media;
use Atomastic\Arrays\Arrays;
use Atomastic\Macroable\Macroable;
use ErrorException;
use Intervention\Image\ImageManagerStatic as Image;
use RuntimeException;
use Slim\Http\Environment;
use Slim\Http\Uri;
use function arrays;
use function basename;
use function chmod;
use function exif_read_data;
use function explode;
use function filesystem;
use function filter;
use function flextype;
use function getimagesize;
use function in_array;
use function is_dir;
use function is_uploaded_file;
use function is_writable;
use function ltrim;
use function mime_content_type;
use function move_uploaded_file;
use function pathinfo;
use function realpath;
use function str_replace;
use function strings;
use function strpos;
use function strrpos;
use function strstr;
use function strtolower;
use function substr;
use function time;
use const DIRECTORY_SEPARATOR;
use const PATHINFO_EXTENSION;
use const UPLOAD_ERR_INI_SIZE;
use const UPLOAD_ERR_OK;
class MediaFiles
{
use Macroable;
/**
* Create a Media Files Meta instance.
*/
public function meta(): MediaFilesMeta
{
return new MediaFilesMeta();
}
/**
* Upload media file
*
* @param array $file Raw file data (multipart/form-data).
* @param string $folder The folder you're targetting.
*
* @access public
*/
public function upload(array $file, string $folder)
{
$uploadFolder = PATH['project'] . '/media/' . $folder . '/';
$uploadMetadataFolder = PATH['project'] . '/media/.meta/' . $folder . '/';
if (! filesystem()->directory($uploadFolder)->exists()) {
filesystem()->directory($uploadFolder)->create(0755, true);
}
if (! filesystem()->directory($uploadMetadataFolder)->exists()) {
filesystem()->directory($uploadMetadataFolder)->create(0755, true);
}
$acceptFileTypes = registry()->get('flextype.settings.media.accept_file_types');
$maxFileSize = registry()->get('flextype.settings.media.max_file_size');
$safeNames = registry()->get('flextype.settings.media.safe_names');
$maxImageWidth = registry()->get('flextype.settings.media.images.max_image_width');
$maxImageHeight = registry()->get('flextype.settings.media.images.max_image_height');
$exact = false;
$chmod = 0644;
$filename = null;
$exifData = [];
// Tests if a successful upload has been made.
if (
isset($file['error'])
and isset($file['tmp_name'])
and $file['error'] === UPLOAD_ERR_OK
and is_uploaded_file($file['tmp_name'])
) {
// Tests if upload data is valid, even if no file was uploaded.
if (
isset($file['error'])
and isset($file['name'])
and isset($file['type'])
and isset($file['tmp_name'])
and isset($file['size'])
) {
// Test if an uploaded file is an allowed file type, by extension.
if (strpos($acceptFileTypes, strtolower(pathinfo($file['name'], PATHINFO_EXTENSION))) !== false) {
// Validation rule to test if an uploaded file is allowed by file size.
if (
($file['error'] !== UPLOAD_ERR_INI_SIZE)
and ($file['error'] === UPLOAD_ERR_OK)
and ($file['size'] <= $maxFileSize)
) {
// Validation rule to test if an upload is an image and, optionally, is the correct size.
if (in_array(mime_content_type($file['tmp_name']), ['image/jpeg', 'image/jpg', 'image/png', 'image/gif'])) {
if ($this->validateImage($file, $maxImageWidth, $maxImageHeight, $exact) === false) {
return false;
}
}
if (! isset($file['tmp_name']) or ! is_uploaded_file($file['tmp_name'])) {
// Ignore corrupted uploads
return false;
}
if ($filename === null) {
// Use the default filename
$filename = $file['name'];
}
if ($safeNames === true) {
// Remove spaces from the filename
$filename = flextype('slugify')->slugify(pathinfo($filename)['filename']) . '.' . pathinfo($filename)['extension'];
}
if (! is_dir($uploadFolder) or ! is_writable(realpath($uploadFolder))) {
throw new RuntimeException("Directory {$uploadFolder} must be writable");
}
// Make the filename into a complete path
$filename = realpath($uploadFolder) . DIRECTORY_SEPARATOR . $filename;
if (move_uploaded_file($file['tmp_name'], $filename)) {
// Set permissions on filename
chmod($filename, $chmod);
if (in_array(mime_content_type($filename), ['image/jpeg', 'image/jpg', 'image/png', 'image/gif'])) {
// open an image file
$img = Image::make($filename);
// now you are able to resize the instance
if (registry()->get('flextype.settings.media.images.image_width') > 0 && registry()->get('flextype.settings.media.images.image_height') > 0) {
$img->resize(registry()->get('flextype.settings.media.images.image_width'), registry()->get('flextype.settings.media.images.image_height'), static function ($constraint): void {
$constraint->aspectRatio();
$constraint->upsize();
});
} elseif (registry()->get('flextype.settings.media.images.image_width') > 0) {
$img->resize(registry()->get('flextype.settings.media.images.image_width'), null, static function ($constraint): void {
$constraint->aspectRatio();
$constraint->upsize();
});
} elseif (registry()->get('flextype.settings.media.images.image_height') > 0) {
$img->resize(null, registry()->get('flextype.settings.media.images.image_height'), static function ($constraint): void {
$constraint->aspectRatio();
$constraint->upsize();
});
}
// finally we save the image as a new file
$img->save($filename, registry()->get('flextype.settings.media.images.image_quality'));
// destroy
$img->destroy();
$exifData = [];
try {
$headers = @exif_read_data($filename);
if ($headers !== false) {
foreach ($headers['COMPUTED'] as $header => $value) {
$exifData[$header] = $value;
}
}
} catch (RuntimeException $e) {
// catch... @todo
}
}
$metadata = [
'title' => substr(basename($filename), 0, strrpos(basename($filename), '.')),
'description' => '',
'type' => mime_content_type($filename),
'filesize' => filesystem()->file($filename)->size(),
'uploaded_on' => time(),
'exif' => $exifData,
];
filesystem()
->file($uploadMetadataFolder . basename($filename) . '.yaml')
->put(serializers()->yaml()->encode($metadata));
// Return new file path
return $filename;
}
}
}
}
}
return false;
}
/**
* Fetch.
*
* @param string $id The path to file.
* @param array $options Options array.
*
* @return Arrays Returns instance of The Arrays class.
*
* @access public
*/
public function fetch(string $id, array $options = []): Arrays
{
// Run event: onEntriesFetch
emitter()->emit('onMediaFilesFetch');
if (
isset($options['collection']) &&
strings($options['collection'])->isTrue()
) {
$result = [];
foreach (filesystem()->find()->files()->depth(0)->in(flextype('media')->folders()->meta()->getDirectoryMetaLocation($id)) as $file) {
$basename = $file->getBasename('.' . $file->getExtension());
$result[$basename] = serializers()->yaml()->decode(filesystem()->file($file->getPathname())->get());
$result[$basename]['filename'] = pathinfo(str_replace('/.meta', '', flextype('media')->files()->meta()->getFileMetaLocation($basename)))['filename'];
$result[$basename]['basename'] = explode('.', basename(flextype('media')->files()->meta()->getFileMetaLocation($basename)))[0];
$result[$basename]['extension'] = ltrim(strstr($basename, '.'), '.');
$result[$basename]['dirname'] = pathinfo(str_replace('/.meta', '', $file->getPathname()))['dirname'];
$result[$basename]['url'] = 'project/media/' . $id . '/' . $basename;
if (registry()->has('flextype.settings.url') && registry()->get('flextype.settings.url') !== '') {
$fullUrl = registry()->get('flextype.settings.url');
} else {
$fullUrl = Uri::createFromEnvironment(new Environment($_SERVER))->getBaseUrl();
}
$result[$basename]['path'] = $id;
$result[$basename]['full_url'] = $fullUrl . '/project/media/' . $id . '/' . $basename;
}
$result = filter($result, $options);
return arrays($result);
}
$result = [];
if (filesystem()->file(flextype('media')->files()->meta()->getFileMetaLocation($id))->exists()) {
$result = serializers()->yaml()->decode(filesystem()->file(flextype('media')->files()->meta()->getFileMetaLocation($id))->get());
$result['filename'] = pathinfo(str_replace('/.meta', '', flextype('media')->files()->meta()->getFileMetaLocation($id)))['filename'];
$result['basename'] = explode('.', basename(flextype('media')->files()->meta()->getFileMetaLocation($id)))[0];
$result['extension'] = ltrim(strstr($id, '.'), '.');
$result['dirname'] = pathinfo(str_replace('/.meta', '', flextype('media')->files()->meta()->getFileMetaLocation($id)))['dirname'];
$result['url'] = 'project/media/' . $id;
$result['path'] = $id;
if (registry()->has('flextype.settings.url') && registry()->get('flextype.settings.url') !== '') {
$fullUrl = registry()->get('flextype.settings.url');
} else {
$fullUrl = Uri::createFromEnvironment(new Environment($_SERVER))->getBaseUrl();
}
$result['full_url'] = $fullUrl . '/project/media/' . $id;
}
$result = filter($result, $options);
return arrays($result);
}
/**
* Move file
*
* @param string $id Unique identifier of the file.
* @param string $newID New Unique identifier of the file.
*
* @return bool True on success, false on failure.
*
* @access public
*/
public function move(string $id, string $newID): bool
{
if (! filesystem()->file($this->getFileLocation($newID))->exists() && ! filesystem()->file(flextype('media')->files()->meta()->getFileMetaLocation($newID))->exists()) {
return filesystem()->file($this->getFileLocation($id))->move($this->getFileLocation($newID)) &&
filesystem()->file(flextype('media')->files()->meta()->getFileMetaLocation($id))->move(flextype('media')->files()->meta()->getFileMetaLocation($newID));
}
return false;
}
/**
* Delete file
*
* @param string $id Unique identifier of the file.
*
* @return bool True on success, false on failure.
*
* @access public
*/
public function delete(string $id): bool
{
return filesystem()->file($this->getFileLocation($id))->delete() &&
filesystem()->file(flextype('media')->files()->meta()->getFileMetaLocation($id))->delete();
}
/**
* Check whether a file exists.
*
* @param string $id Unique identifier of the file.
*
* @return bool True on success, false on failure.
*
* @access public
*/
public function has(string $id): bool
{
return filesystem()->file($this->getFileLocation($id))->exists() &&
filesystem()->file(flextype('media')->files()->meta()->getFileMetaLocation($id))->exists();
}
/**
* Copy file
*
* @param string $id Unique identifier of the file.
* @param string $newID New Unique identifier of the file.
*
* @return bool True on success, false on failure.
*
* @access public
*/
public function copy(string $id, string $newID): bool
{
if (! filesystem()->file($this->getFileLocation($newID))->exists() && ! filesystem()->file(flextype('media')->files()->meta()->getFileMetaLocation($newID))->exists()) {
filesystem()->file($this->getFileLocation($id))->copy($this->getFileLocation($newID));
filesystem()->file(flextype('media')->files()->meta()->getFileMetaLocation($id))->copy(flextype('media')->files()->meta()->getFileMetaLocation($newID));
return filesystem()->file($this->getFileLocation($newID))->exists() &&
filesystem()->file(flextype('media')->files()->meta()->getFileMetaLocation($newID))->exists();
}
return false;
}
/**
* Get file location
*
* @param string $id Unique identifier of the file.
*
* @return string entry file location
*
* @access public
*/
public function getFileLocation(string $id): string
{
return PATH['project'] . '/media/' . $id;
}
/**
* Validate Image
*/
protected function validateImage($file, $maxImageWidth, $maxImageHeight, $exact)
{
try {
// Get the width and height from the uploaded image
[$width, $height] = getimagesize($file['tmp_name']);
} catch (ErrorException $e) {
// Ignore read errors
}
if (empty($width) or empty($height)) {
// Cannot get image size, cannot validate
return false;
}
if (! $maxImageWidth) {
// No limit, use the image width
$maxImageWidth = $width;
}
if (! $maxImageHeight) {
// No limit, use the image height
$maxImageHeight = $height;
}
if ($exact) {
// Check if dimensions match exactly
return $width === $maxImageWidth and $height === $maxImageHeight;
}
// Check if size is within maximum dimensions
return $width <= $maxImageWidth and $height <= $maxImageHeight;
}
}

View File

@@ -1,106 +0,0 @@
<?php
declare(strict_types=1);
/**
* Flextype (https://flextype.org)
* Founded by Sergey Romanenko and maintained by Flextype Community.
*/
namespace Flextype\Media;
use Atomastic\Macroable\Macroable;
use function arrays;
use function filesystem;
use function flextype;
class MediaFilesMeta
{
use Macroable;
/**
* Update file meta information
*
* @param string $id Unique identifier of the file.
* @param string $field Field name
* @param string $value Field value
*
* @return bool True on success, false on failure.
*
* @access public
*/
public function update(string $id, string $field, string $value): bool
{
$fileData = serializers()->yaml()->decode(filesystem()->file($this->getFileMetaLocation($id))->get());
if (arrays($fileData)->has($field)) {
$fileData = arrays($fileData)->set($field, $value);
return (bool) filesystem()->file($this->getFileMetaLocation($id))->put(serializers()->yaml()->encode($fileData->toArray()));
}
return false;
}
/**
* Add file meta information
*
* @param string $id Unique identifier of the file.
* @param string $field Field name
* @param string $value Field value
*
* @return bool True on success, false on failure.
*
* @access public
*/
public function add(string $id, string $field, string $value): bool
{
$fileData = serializers()->yaml()->decode(filesystem()->file($this->getFileMetaLocation($id))->get());
if (! arrays($fileData)->has($field)) {
$fileData = arrays($fileData)->set($field, $value);
return (bool) filesystem()->file($this->getFileMetaLocation($id))->put(serializers()->yaml()->encode($fileData->toArray()));
}
return false;
}
/**
* Delete file meta information
*
* @param string $id Unique identifier of the file.
* @param string $field Field name
*
* @return bool True on success, false on failure.
*
* @access public
*/
public function delete(string $id, string $field): bool
{
$fileData = serializers()->yaml()->decode(filesystem()->file($this->getFileMetaLocation($id))->get());
if (arrays($fileData)->has($field)) {
$fileData = arrays($fileData)->delete($field);
return (bool) filesystem()->file($this->getFileMetaLocation($id))->put(serializers()->yaml()->encode($fileData->toArray()));
}
return false;
}
/**
* Get file meta location
*
* @param string $id Unique identifier of the file.
*
* @return string entry file location
*
* @access public
*/
public function getFileMetaLocation(string $id): string
{
return PATH['project'] . '/media/.meta/' . $id . '.yaml';
}
}

View File

@@ -1,215 +0,0 @@
<?php
declare(strict_types=1);
/**
* Flextype (https://flextype.org)
* Founded by Sergey Romanenko and maintained by Flextype Community.
*/
namespace Flextype\Media;
use Atomastic\Arrays\Arrays;
use Atomastic\Macroable\Macroable;
use Slim\Http\Environment;
use Slim\Http\Uri;
use function arrays;
use function filesystem;
use function filter;
use function flextype;
use function str_replace;
use function strings;
class MediaFolders
{
use Macroable;
/**
* Create a Media Folders Meta instance.
*/
public function meta(): MediaFoldersMeta
{
return new MediaFoldersMeta();
}
/**
* Fetch.
*
* @param string $id The path to folder.
* @param array $options Options array.
*
* @return Arrays Returns instance of The Arrays class.
*
* @access public
*/
public function fetch(string $id, array $options = []): Arrays
{
// Run event: onEntriesFetch
emitter()->emit('onMediaFoldersFetch');
// Single fetch helper
$single = static function ($id, $options) {
$result = [];
if (filesystem()->directory(flextype('media')->folders()->meta()->getDirectoryMetaLocation($id))->exists()) {
$id = trim($id, '/');
$result['basename'] = basename($id);
$result['dirname'] = dirname($id);
$result['path'] = $id;
$result['full_path'] = str_replace('/.meta', '', flextype('media')->folders()->meta()->getDirectoryMetaLocation($id));
$result['url'] = 'project/media/' . $id;
if (registry()->has('flextype.settings.url') && registry()->get('flextype.settings.url') !== '') {
$fullUrl = registry()->get('flextype.settings.url');
} else {
$fullUrl = Uri::createFromEnvironment(new Environment($_SERVER))->getBaseUrl();
}
$result['full_url'] = $fullUrl . '/project/media/' . $id;
}
$result = filter($result, $options);
return arrays($result);
};
if (
isset($options['collection']) &&
strings($options['collection'])->isTrue()
) {
$result = [];
foreach (filesystem()->find()->directories()->depth(0)->in(flextype('media')->folders()->meta()->getDirectoryMetaLocation($id)) as $folder) {
$result[$folder->getFilename()] = $single($id . '/' . $folder->getFilename(), [])->toArray();
}
$result = filter($result, $options);
return arrays($result);
}
return $single($id, $options);
}
/**
* Create folder
*
* @param string $id Unique identifier of the folder.
*
* @return bool True on success, false on failure.
*
* @access public
*/
public function create(string $id): bool
{
if (
! filesystem()->directory($this->getDirectoryLocation($id))->exists() &&
! filesystem()->directory(flextype('media')->folders()->meta()->getDirectoryMetaLocation($id))->exists()
) {
return filesystem()->directory($this->getDirectoryLocation($id))->create(0755, true) &&
filesystem()->directory(flextype('media')->folders()->meta()->getDirectoryMetaLocation($id))->create(0755, true);
}
return false;
}
/**
* Move folder
*
* @param string $id Unique identifier of the folder.
* @param string $newID New Unique identifier of the folder.
*
* @return bool True on success, false on failure.
*
* @access public
*/
public function move(string $id, string $newID): bool
{
if (
(filesystem()->directory($this->getDirectoryLocation($newID))->exists() === false &&
filesystem()->directory(flextype('media')->folders()->meta()->getDirectoryMetaLocation($newID))->exists() === false)
) {
return filesystem()->directory($this->getDirectoryLocation($id))->move($this->getDirectoryLocation($newID)) &&
filesystem()->directory(flextype('media')->folders()->meta()->getDirectoryMetaLocation($id))->move(flextype('media')->folders()->meta()->getDirectoryMetaLocation($newID));
}
return false;
}
/**
* Copy folder
*
* @param string $id Unique identifier of the folder.
* @param string $newID New Unique identifier of the folder.
*
* @return bool True on success, false on failure.
*
* @access public
*/
public function copy(string $id, string $newID): bool
{
if (
(filesystem()->directory($this->getDirectoryLocation($newID))->exists() === false &&
filesystem()->directory(flextype('media')->folders()->meta()->getDirectoryMetaLocation($newID))->exists() === false)
) {
filesystem()
->directory($this->getDirectoryLocation($id))
->copy($this->getDirectoryLocation($newID));
filesystem()
->directory(flextype('media')->folders()->meta()->getDirectoryMetaLocation($id))
->copy(flextype('media')->folders()->meta()->getDirectoryMetaLocation($newID));
return filesystem()->directory($this->getDirectoryLocation($newID))->exists() &&
filesystem()->directory(flextype('media')->folders()->meta()->getDirectoryMetaLocation($newID))->exists();
}
return false;
}
/**
* Delete folder
*
* @param string $id Unique identifier of the file.
*
* @return bool True on success, false on failure.
*
* @access public
*/
public function delete(string $id): bool
{
return filesystem()->directory($this->getDirectoryLocation($id))->delete() &&
filesystem()->directory(flextype('media')->folders()->meta()->getDirectoryMetaLocation($id))->delete();
}
/**
* Check whether a folder exists.
*
* @param string $id Unique identifier of the folder.
*
* @return bool True on success, false on failure.
*
* @access public
*/
public function has(string $id): bool
{
return filesystem()->directory($this->getDirectoryLocation($id))->exists() &&
filesystem()->directory(flextype('media')->folders()->meta()->getDirectoryMetaLocation($id))->exists();
}
/**
* Get files directory location
*
* @param string $id Unique identifier of the folder.
*
* @return string entry directory location
*
* @access public
*/
public function getDirectoryLocation(string $id): string
{
return PATH['project'] . '/media/' . $id;
}
}

View File

@@ -1,31 +0,0 @@
<?php
declare(strict_types=1);
/**
* Flextype (https://flextype.org)
* Founded by Sergey Romanenko and maintained by Flextype Community.
*/
namespace Flextype\Media;
use Atomastic\Macroable\Macroable;
class MediaFoldersMeta
{
use Macroable;
/**
* Get files directory meta location
*
* @param string $id Unique identifier of the folder.
*
* @return string entry directory location
*
* @access public
*/
public function getDirectoryMetaLocation(string $id): string
{
return PATH['project'] . '/media/.meta/' . $id;
}
}

View File

@@ -87,12 +87,15 @@ final class Shortcodes
}
foreach ($shortcodes as $shortcode) {
if (! isset($shortcode['path'])) {
if (! isset($shortcode['enabled'])) {
continue;
}
if (! $shortcode['enabled']) {
continue;
}
if (! file_exists(ROOT_DIR . $shortcode['path'])) {
continue;
}

View File

@@ -12,8 +12,12 @@ namespace Flextype\Parsers\Shortcodes;
use Thunder\Shortcode\Shortcode\ShortcodeInterface;
// Shortcode: [content_fetch id="content-id" field="field-name" default="default-value"]
if (registry()->get('flextype.settings.parsers.shortcodes.shortcodes.content.enabled')) {
parsers()->shortcodes()->addHandler('content_fetch', static function (ShortcodeInterface $s) {
return arrays(content()->fetch($s->getParameter('id')))->get($s->getParameter('field'), $s->getParameter('default'));
});
}
parsers()->shortcodes()->addHandler('content_fetch', static function (ShortcodeInterface $s) {
if (! registry()->get('flextype.settings.parsers.shortcodes.shortcodes.content.enabled')) {
return '';
}
return arrays(content()->fetch($s->getParameter('id')))->get($s->getParameter('field'), $s->getParameter('default'));
});

View File

@@ -12,8 +12,12 @@ namespace Flextype\Parsers\Shortcodes;
use Thunder\Shortcode\Shortcode\ShortcodeInterface;
// Shortcode: [media_files_fetch id="media-id" field="field-name" default="default-value"]
if (registry()->get('flextype.settings.parsers.shortcodes.shortcodes.media.enabled')) {
parsers()->shortcodes()->addHandler('media_files_fetch', static function (ShortcodeInterface $s) {
return arrays(flextype('media')->files()->fetch($s->getParameter('id')))->get($s->getParameter('field'), $s->getParameter('default'));
});
}
parsers()->shortcodes()->addHandler('media_files_fetch', static function (ShortcodeInterface $s) {
if (! registry()->get('flextype.settings.parsers.shortcodes.shortcodes.media.enabled')) {
return '';
}
return arrays(flextype('media')->files()->fetch($s->getParameter('id')))->get($s->getParameter('field'), $s->getParameter('default'));
});

View File

@@ -14,10 +14,9 @@ use Thunder\Shortcode\Events;
use Thunder\Shortcode\Shortcode\ShortcodeInterface;
// Shortcode: [raw]
if (registry()->get('flextype.settings.parsers.shortcodes.shortcodes.raw.enabled')) {
parsers()->shortcodes()->addHandler('raw', static function (ShortcodeInterface $s) {
return $s->getContent();
});
parsers()->shortcodes()->addHandler('raw', static function (ShortcodeInterface $s) {
return $s->getContent();
});
parsers()->shortcodes()->addEventHandler(Events::FILTER_SHORTCODES, new FilterRawEventHandler(['raw']));
parsers()->shortcodes()->addEventHandler(Events::FILTER_SHORTCODES, new FilterRawEventHandler(['raw']));
}

View File

@@ -12,8 +12,11 @@ namespace Flextype\Parsers\Shortcodes;
use Thunder\Shortcode\Shortcode\ShortcodeInterface;
// Shortcode: [registry_get name="item-name" default="default-value"]
if (registry()->get('flextype.settings.parsers.shortcodes.shortcodes.registry.enabled')) {
parsers()->shortcodes()->addHandler('registry_get', static function (ShortcodeInterface $s) {
return registry()->get($s->getParameter('name'), $s->getParameter('default'));
});
}
parsers()->shortcodes()->addHandler('registry_get', static function (ShortcodeInterface $s) {
if (! registry()->get('flextype.settings.parsers.shortcodes.shortcodes.registry.enabled')) {
return '';
}
return registry()->get($s->getParameter('name'), $s->getParameter('default'));
});

View File

@@ -13,12 +13,15 @@ use Slim\Http\Environment;
use Slim\Http\Uri;
// Shortcode: [url]
if (registry()->get('flextype.settings.parsers.shortcodes.shortcodes.url.enabled')) {
parsers()->shortcodes()->addHandler('url', static function () {
if (registry()->has('flextype.settings.url') && registry()->get('flextype.settings.url') !== '') {
return registry()->get('flextype.settings.url');
}
parsers()->shortcodes()->addHandler('url', static function () {
if (!registry()->get('flextype.settings.parsers.shortcodes.shortcodes.url.enabled')) {
return '';
}
return app()->getBasePath();
});
}
if (registry()->has('flextype.settings.url') && registry()->get('flextype.settings.url') !== '') {
return registry()->get('flextype.settings.url');
}
return app()->getBasePath();
});

View File

@@ -14,6 +14,7 @@ use Atomastic\Session\Session;
use Cocur\Slugify\Slugify;
use DateTimeZone;
use Flextype\Content\Content;
use Flextype\Media\Media;
use Flextype\Handlers\HttpErrorHandler;
use Flextype\Handlers\ShutdownHandler;
use Flextype\Parsers\Parsers;
@@ -409,6 +410,9 @@ container()->set('images', function () {
// Add Content Service
container()->set('content', new Content(registry()->get('flextype.settings.entries.content')));
// Add Media Service
container()->set('media', new Media(registry()->get('flextype.settings.entries.media')));
// Add Plugins Service
container()->set('plugins', new Plugins());

View File

@@ -8,8 +8,8 @@ declare(strict_types=1);
*/
use Flextype\Flextype;
use Symfony\Component\Finder\Finder as Finder;
use Intervention\Image\ImageManagerStatic as Image;
use Symfony\Component\Finder\Finder;
if (! function_exists('flextype')) {
/**
@@ -25,7 +25,8 @@ if (! function_exists('app')) {
/**
* Get Flextype App.
*/
function app() {
function app()
{
return flextype()->app();
}
}
@@ -34,7 +35,8 @@ if (! function_exists('container')) {
/**
* Get Flextype Container.
*/
function container() {
function container()
{
return flextype()->container();
}
}
@@ -43,7 +45,8 @@ if (! function_exists('emitter')) {
/**
* Get Flextype Emitter Service.
*/
function emitter() {
function emitter()
{
return flextype()->container()->get('emitter');
}
}
@@ -52,7 +55,8 @@ if (! function_exists('cache')) {
/**
* Get Flextype Cache Service.
*/
function cache() {
function cache()
{
return flextype()->container()->get('cache');
}
}
@@ -61,16 +65,28 @@ if (! function_exists('content')) {
/**
* Get Flextype Content Service.
*/
function content() {
function content()
{
return flextype()->container()->get('content');
}
}
if (! function_exists('media')) {
/**
* Get Flextype Media Service.
*/
function media()
{
return flextype()->container()->get('media');
}
}
if (! function_exists('parsers')) {
/**
* Get Flextype Parsers Service.
*/
function parsers() {
function parsers()
{
return flextype()->container()->get('parsers');
}
}
@@ -79,7 +95,8 @@ if (! function_exists('serializers')) {
/**
* Get Flextype Serializers Service.
*/
function serializers() {
function serializers()
{
return flextype()->container()->get('serializers');
}
}
@@ -88,7 +105,8 @@ if (! function_exists('logger')) {
/**
* Get Flextype Logger Service.
*/
function logger() {
function logger()
{
return flextype()->container()->get('logger');
}
}
@@ -97,7 +115,8 @@ if (! function_exists('session')) {
/**
* Get Flextype Session Service.
*/
function session() {
function session()
{
return flextype()->container()->get('session');
}
}
@@ -106,7 +125,8 @@ if (! function_exists('csrf')) {
/**
* Get Flextype CSRF Service.
*/
function csrf() {
function csrf()
{
return flextype()->container()->get('csrf');
}
}
@@ -115,7 +135,8 @@ if (! function_exists('plugins')) {
/**
* Get Flextype Plugins Service.
*/
function plugins() {
function plugins()
{
return flextype()->container()->get('plugins');
}
}
@@ -127,28 +148,28 @@ if (! function_exists('find')) {
* @param string $path Path.
* @param array $options Options array.
* @param string $searchIn Search in 'files' or 'directories'. Default is 'files'.
*
* @return Finder
*
* @return Finder Finder instance.
*/
function find(string $path = '', array $options = [], string $searchIn = 'files'): Finder
{
$find = filesystem()->find()->in($path);
function find(string $path = '', array $options = [], string $searchIn = 'files'): Finder
{
$find = filesystem()->find()->in($path);
isset($options['depth']) and $find->depth($options['depth']) or $find->depth(1);
isset($options['date']) and $find->date($options['date']);
isset($options['size']) and $find->size($options['size']);
isset($options['exclude']) and $find->exclude($options['exclude']);
isset($options['contains']) and $find->contains($options['contains']);
isset($options['not_contains']) and $find->notContains($options['not_contains']);
isset($options['filter']) and $find->filter($options['filter']);
isset($options['sort']) and $find->sort($options['sort']);
isset($options['path']) and $find->path($options['path']);
isset($options['sort_by']) && $options['sort_by'] === 'atime' and $find->sortByAccessedTime();
isset($options['sort_by']) && $options['sort_by'] === 'mtime' and $find->sortByModifiedTime();
isset($options['sort_by']) && $options['sort_by'] === 'ctime' and $find->sortByChangedTime();
isset($options['depth']) and $find->depth($options['depth']) or $find->depth(1);
isset($options['date']) and $find->date($options['date']);
isset($options['size']) and $find->size($options['size']);
isset($options['exclude']) and $find->exclude($options['exclude']);
isset($options['contains']) and $find->contains($options['contains']);
isset($options['not_contains']) and $find->notContains($options['not_contains']);
isset($options['filter']) and $find->filter($options['filter']);
isset($options['sort']) and $find->sort($options['sort']);
isset($options['path']) and $find->path($options['path']);
isset($options['sort_by']) && $options['sort_by'] === 'atime' and $find->sortByAccessedTime();
isset($options['sort_by']) && $options['sort_by'] === 'mtime' and $find->sortByModifiedTime();
isset($options['sort_by']) && $options['sort_by'] === 'ctime' and $find->sortByChangedTime();
return $searchIn === 'directories' ? $find->directories() : $find->files();
}
return $searchIn === 'directories' ? $find->directories() : $find->files();
}
}
if (! function_exists('filter')) {
@@ -233,3 +254,183 @@ if (! function_exists('filter')) {
return $result;
}
}
if (! function_exists('image')) {
/**
* Create a new image instance.
*
* @param string $file Image file.
* @param array $options Options array.
*
* @return Image|void
*/
function image(string $file, array $options = [])
{
$image = Image::make($file);
if (count($options) === 0) {
return $image;
}
if (isset($options['driver'])) {
if (in_array($options['driver'], ['imagick', 'gd'])) {
Image::configure(['driver' => $options['driver']]);
}
}
if (isset($options['blur'])) {
$image->blur($options['blur']);
}
if (isset($options['brightness'])) {
$image->brightness($options['brightness']);
}
if (
isset($options['colorize']) &&
isset($options['colorize']['red']) &&
isset($options['colorize']['green']) &&
isset($options['colorize']['blue'])
) {
$image->colorize(
$options['colorize']['red'],
$options['colorize']['green'],
$options['colorize']['blue']
);
}
if (isset($options['contrast'])) {
$image->contrast($options['contrast']);
}
if (isset($options['flip'])) {
$image->flip($options['flip']);
}
if (isset($options['gamma'])) {
$image->gamma($options['gamma']);
}
if (isset($options['rotate'])) {
$image->rotate($options['rotate']);
}
if (isset($options['pixelate'])) {
$image->pixelate($options['pixelate']);
}
if (isset($options['heighten'])) {
$image->heighten($options['heighten']['height'],
function ($constraint) use ($options) {
if (isset($options['heighten']['constraint']) &&
is_array($options['heighten']['constraint'])) {
foreach ($options['heighten']['constraint'] as $method) {
if (in_array($method, ['upsize'])) {
$constraint->{$method}();
}
}
}
});
}
if (isset($options['widen'])) {
$image->heighten($options['widen']['width'],
function ($constraint) use ($options) {
if (isset($options['widen']['constraint']) &&
is_array($options['widen']['constraint'])) {
foreach ($options['widen']['constraint'] as $method) {
if (in_array($method, ['upsize'])) {
$constraint->{$method}();
}
}
}
});
}
if (isset($options['fit']) &&
isset($options['fit']['width'])) {
$image->fit($options['fit']['width'],
$options['fit']['height'] ?? null,
function ($constraint) use ($options) {
if (isset($options['fit']['constraint']) &&
is_array($options['fit']['constraint'])) {
foreach ($options['fit']['constraint'] as $method) {
if (in_array($method, ['upsize'])) {
$constraint->{$method}();
}
}
}
},
$options['fit']['position'] ?? 'center');
}
if (isset($options['crop']) &&
isset($options['crop']['width']) &&
isset($options['crop']['height'])) {
$image->crop($options['crop']['width'],
$options['crop']['height'],
$options['crop']['x'] ?? null,
$options['crop']['y'] ?? null);
}
if (isset($options['invert']) &&
$options['invert'] == true) {
$image->invert();
}
if (isset($options['sharpen'])) {
$image->sharpen($options['sharpen']);
}
if (isset($options['resize'])) {
$image->resize($options['resize']['width'] ?? null,
$options['resize']['height'] ?? null,
function ($constraint) use ($options) {
if (isset($options['resize']['constraint']) &&
is_array($options['resize']['constraint'])) {
foreach ($options['resize']['constraint'] as $method) {
if (in_array($method, ['aspectRatio', 'upsize'])) {
$constraint->{$method}();
}
}
}
});
}
$image->save($file, $options['quality'] ?? 70);
$image->destroy();
}
}
if (! function_exists('imageCanvas')) {
/**
* Create a new image canvas instance.
*
* @param int $width Canvas width.
* @param int $height Canvas height.
* @param mixed $background Canvas background.
*
* @return Image Image canvas instance.
*/
function imageCanvas(int $width, int $height, $background = null): Image
{
return Image::canvas($width, $height, $background);
}
}
if (! function_exists('imageCache')) {
/**
* Create a new cached image instance.
*
* @param Closure $callback A closure containing the operations on an image, defining the cached image.
* @param int $lifetime The lifetime in minutes of the image callback in the cache.
* @param bool $returnObj Decide if you want the method to return an Intervention Image instance or (by default) the image stream.
*
* @return mixed Intervention Image instance as return value or just receive the image stream.
*/
function imageCache(Closure $callback, int $lifetime = 5, bool $returnObj = false)
{
return Image::cache($callback, $lifetime, $returnObj);
}
}

View File

@@ -55,6 +55,27 @@ errors:
# Entries
entries:
media:
directory: media
filename: media
extension: yaml
serializer: yaml
fields:
modified_at:
enabled: true
path: "/src/flextype/Media/Fields/ModifiedAtField.php"
created_at:
enabled: true
path: "/src/flextype/Media/Fields/CreatedAtField.php"
created_by:
enabled: true
path: "/src/flextype/Media/Fields/CreatedByField.php"
uuid:
enabled: true
path: "/src/flextype/Media/Fields/UuidField.php"
id:
enabled: true
path: "/src/flextype/Media/Fields/IdField.php"
content:
directory: content
filename: content
@@ -62,56 +83,51 @@ entries:
serializer: yaml
fields:
media:
files:
fetch:
enabled: true
result: toObject
folders:
fetch:
enabled: true
result: toObject
enabled: true
path: "/src/flextype/Content/Fields/MediaField.php"
fetch:
result: toObject
registry:
enabled: true
path: "/src/flextype/Content/Fields/RegistryField.php"
get:
enabled: true
content:
enabled: true
path: "/src/flextype/Content/Fields/ContentField.php"
fetch:
enabled: true
result: toObject
slug:
enabled: true
path: "/src/flextype/Content/Fields/SlugField.php"
enabled: true
published_at:
enabled: true
path: "/src/flextype/Content/Fields/PublishedAtField.php"
enabled: true
published_by:
enabled: true
path: "/src/flextype/Content/Fields/PublishedByField.php"
enabled: true
modified_at:
enabled: true
path: "/src/flextype/Content/Fields/ModifiedAtField.php"
enabled: true
created_at:
enabled: true
path: "/src/flextype/Content/Fields/CreatedAtField.php"
enabled: true
created_by:
enabled: true
path: "/src/flextype/Content/Fields/CreatedByField.php"
enabled: true
routable:
enabled: true
path: "/src/flextype/Content/Fields/RoutableField.php"
enabled: true
parsers:
enabled: true
path: "/src/flextype/Content/Fields/ParsersField.php"
enabled: true
visibility:
enabled: true
path: "/src/flextype/Content/Fields/VisibilityField.php"
enabled: true
uuid:
enabled: true
path: "/src/flextype/Content/Fields/UuidField.php"
enabled: true
id:
path: "/src/flextype/Content/Fields/IdField.php"
enabled: true
path: "/src/flextype/Content/Fields/IdField.php"
# Cache
#
@@ -156,7 +172,7 @@ entries:
# - drivers.files.cache_slams_timeout: This option defines the cache slams timeout in seconds.
cache:
enabled: true
enabled: false
router: routes
auto_reload:
storage: false
@@ -454,20 +470,20 @@ parsers:
cache: true
shortcodes:
media:
enabled: true
path: "/src/flextype/Parsers/Shortcodes/MediaShortcode.php"
enabled: true
content:
enabled: true
path: "/src/flextype/Parsers/Shortcodes/ContentShortcode.php"
enabled: true
raw:
enabled: true
path: "/src/flextype/Parsers/Shortcodes/RawShortcode.php"
enabled: true
registry:
enabled: true
path: "/src/flextype/Parsers/Shortcodes/RegistryShortcode.php"
enabled: true
url:
path: "/src/flextype/Parsers/Shortcodes/UrlShortcode.php"
enabled: true
path: "/src/flextype/Parsers/Shortcodes/UrlShortcode.php"
# CORS
#
@@ -508,19 +524,51 @@ cors:
# Media
#
# - max_file_size: Set the maximum upload size. Note, this can never exceed the settings for
# `post_max_size` and `upload_max_filesize` in `php.ini`.
# - upload.directory: Uploads directory
#
# - upload.overwrite: Overwrite existing files.
#
# - upload.autoconfirm: Auto-confirm uploads.
#
# - upload.prefix: Prefixing uploads.
#
# - upload.validation.allowed_file_extensions: Allowed file extensions.
#
# - upload.validation.max_file_size: Maximum file size.
#
# - upload.validation.image.width.max: Image maxiumum width.
#
# - upload.validation.image.width.min: Image minimum width.
#
# - upload.validation.image.height.max: Image maxiumum height.
#
# - upload.validation.image.height.min: Image minimum height.
#
# - upload.validation.image.ratio.size: The option can be a number (eg: 1.3) or a ratio-like string (eg: 4:3, 16:9).
#
# - upload.validation.image.ratio.error_margin: The option error_margin specifies how much the image is allowed to
# deviate from the target ratio. Default value is 0.
#
# - upload.process.image.quality:
media:
accept_file_types: 'gif, jpg, jpeg, png, ico, zip, tgz, txt, md, doc, docx, pdf, epub, xls, xlsx, ppt, pptx, mp3, ogg, wav, m4a, mp4, m4v, ogv, wmv, avi, webm, svg'
max_file_size: 8000000
safe_names: true
images:
driver: gd
image_width: 1600
image_height: 0
image_quality: 70
max_image_width: null
max_image_height: null
upload:
directory: '/uploads/media'
overwrite: true
autoconfirm: false
prefix: ''
validation:
allowed_file_extensions: ['gif', 'jpg', 'jpeg', 'png', 'ico', 'webm', 'svg']
max_file_size: '24M'
image:
width:
max: 4920
min: 100
height:
max: 3264
min: 100
process:
image:
quality: 70
# Session
#