From 0c5692d47f13347effd227b678133f1c469090c6 Mon Sep 17 00:00:00 2001 From: Awilum Date: Wed, 25 Aug 2021 16:44:24 +0300 Subject: [PATCH 01/51] feat(composer): add atomastic view --- composer.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index da9048e5..67a60654 100755 --- a/composer.json +++ b/composer.json @@ -33,6 +33,7 @@ "atomastic/strings": "^3.0.2", "atomastic/macroable": "^2.0.0", "atomastic/csrf": "^1.0.1", + "atomastic/view": "dev-dev", "slim/slim": "^4.8.1", @@ -57,7 +58,7 @@ "php-di/php-di": "^6.3.4", "php-di/slim-bridge": "^3.1.1", "middlewares/whoops": "^2.0", - "nette/neon": "^3.2", + "nette/neon": "^3.2", "league/commonmark": "^2.0", "siriusphp/upload": "^3.0" }, From 689bc66858cb1b42efc21279e594ae44a74b7618 Mon Sep 17 00:00:00 2001 From: Awilum Date: Wed, 25 Aug 2021 16:44:53 +0300 Subject: [PATCH 02/51] feat(tests): update phpunit xml file --- phpunit.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/phpunit.xml b/phpunit.xml index 69a03bf1..01174ffa 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -11,7 +11,6 @@ - ./app ./src From 15a21c28706c1cf29dbca9774ee348d945bce4d2 Mon Sep 17 00:00:00 2001 From: Awilum Date: Wed, 25 Aug 2021 16:45:15 +0300 Subject: [PATCH 03/51] feat(tests): add macos os --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 0e962caa..cc008c50 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -6,7 +6,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [ubuntu-latest] + os: [ubuntu-latest, macos-latest] php: ['7.4', '8.0'] dependency-version: [prefer-stable] From c8576f7a3c9fc36f97e15d03bf23e6dbaeb7e837 Mon Sep 17 00:00:00 2001 From: Awilum Date: Thu, 26 Aug 2021 09:58:34 +0300 Subject: [PATCH 04/51] feat(middlewares): updates for CSRF middleware --- .../core/Middlewares/CsrfMiddleware.php | 32 +++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/src/flextype/core/Middlewares/CsrfMiddleware.php b/src/flextype/core/Middlewares/CsrfMiddleware.php index c4825cd7..2ac78f1c 100644 --- a/src/flextype/core/Middlewares/CsrfMiddleware.php +++ b/src/flextype/core/Middlewares/CsrfMiddleware.php @@ -9,8 +9,9 @@ declare(strict_types=1); namespace Flextype\Middlewares; -use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ServerRequestInterface as Request; +use Psr\Http\Server\RequestHandlerInterface as RequestHandler; +use Slim\Psr7\Response; class CsrfMiddleware { @@ -21,7 +22,7 @@ class CsrfMiddleware * @param Response $response PSR7 response * @param callable $next Next middleware */ - public function __invoke(Request $request, Response $response, callable $next) : Response + /*public function __invoke(Request $request, Response $response, callable $next) : Response { $data = $request->getParsedBody(); @@ -35,6 +36,33 @@ class CsrfMiddleware $response = $next($request, $response); } + return $response; + }*/ + + + /** + * Example middleware invokable class + * + * @param ServerRequest $request PSR-7 request + * @param RequestHandler $handler PSR-15 request handler + * + * @return Response + */ + public function __invoke(Request $request, RequestHandler $handler): Response + { + $response = $handler->handle($request); + $data = $request->getParsedBody(); + + if (isset($data[csrf()->getTokenName()])) { + if (csrf()->isValid($data[csrf()->getTokenName()])) { + return $response; + } else { + $response = new Response(); + $response->getBody()->write('This looks like a cross-site request forgery!'); + return $response; + } + } + return $response; } } From d4138a4aee4fe607ff0dd28e4b0a191f423c21d2 Mon Sep 17 00:00:00 2001 From: Awilum Date: Sun, 29 Aug 2021 20:50:56 +0300 Subject: [PATCH 05/51] feat(helpers): decouple and refactor all helpers --- src/flextype/helpers/arrays.php | 86 +++++ src/flextype/helpers/finder.php | 36 ++ src/flextype/helpers/helpers.php | 560 +----------------------------- src/flextype/helpers/image.php | 185 ++++++++++ src/flextype/helpers/services.php | 163 +++++++++ src/flextype/helpers/tokens.php | 46 +++ src/flextype/helpers/upload.php | 63 ++++ 7 files changed, 585 insertions(+), 554 deletions(-) create mode 100644 src/flextype/helpers/arrays.php create mode 100644 src/flextype/helpers/finder.php create mode 100644 src/flextype/helpers/image.php create mode 100644 src/flextype/helpers/services.php create mode 100644 src/flextype/helpers/tokens.php create mode 100644 src/flextype/helpers/upload.php diff --git a/src/flextype/helpers/arrays.php b/src/flextype/helpers/arrays.php new file mode 100644 index 00000000..3b8df304 --- /dev/null +++ b/src/flextype/helpers/arrays.php @@ -0,0 +1,86 @@ +only($options['only']); + } + + if (isset($options['except'])) { + $collection->except($options['except']); + } + + if (isset($options['where'])) { + if (is_array($options['where'])) { + foreach ($options['where'] as $key => $value) { + if ( + ! isset($value['key']) || + ! isset($value['operator']) || + ! isset($value['value']) + ) { + continue; + } + + $collection->where($value['key'], $value['operator'], $value['value']); + } + } + } + + if (isset($options['group_by'])) { + $collection->groupBy($options['group_by']); + } + + if (isset($options['sort_by'])) { + if (isset($options['sort_by']['key']) && isset($options['sort_by']['direction'])) { + $collection->sortBy($options['sort_by']['key'], $options['sort_by']['direction']); + } + } + + if (isset($options['offset'])) { + $collection->offset(isset($options['offset']) ? (int) $options['offset'] : 0); + } + + if (isset($options['limit'])) { + $collection->limit(isset($options['limit']) ? (int) $options['limit'] : 0); + } + + switch ($options['return']) { + case 'first': + $result = $collection->first(); + break; + case 'last': + $result = $collection->last(); + break; + case 'next': + $result = $collection->next(); + break; + case 'random': + $result = $collection->random(isset($options['random']) ? (int) $options['random'] : null); + break; + case 'shuffle': + $result = $collection->shuffle()->toArray(); + break; + case 'all': + default: + $result = $collection->all(); + break; + } + + return $result; + } +} \ No newline at end of file diff --git a/src/flextype/helpers/finder.php b/src/flextype/helpers/finder.php new file mode 100644 index 00000000..c2d7d500 --- /dev/null +++ b/src/flextype/helpers/finder.php @@ -0,0 +1,36 @@ +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(); + + return $searchIn === 'directories' ? $find->directories() : $find->files(); + } +} \ No newline at end of file diff --git a/src/flextype/helpers/helpers.php b/src/flextype/helpers/helpers.php index 068eef87..4afb26b7 100644 --- a/src/flextype/helpers/helpers.php +++ b/src/flextype/helpers/helpers.php @@ -2,557 +2,9 @@ declare(strict_types=1); -/** - * Flextype (https://flextype.org) - * Founded by Sergey Romanenko and maintained by Flextype Community. - */ - -use Flextype\Flextype; -use Intervention\Image\ImageManagerStatic as Image; -use Symfony\Component\Finder\Finder; -use Sirius\Upload\Handler as UploadHandler; -use Sirius\Upload\Result\File as UploadResultFile; - -if (! function_exists('flextype')) { - /** - * Get the available Flextype instance. - */ - function flextype($container = null) - { - return Flextype::getInstance($container); - } -} - -if (! function_exists('app')) { - /** - * Get Flextype App. - */ - function app() - { - return flextype()->app(); - } -} - -if (! function_exists('container')) { - /** - * Get Flextype Container. - */ - function container() - { - return flextype()->container(); - } -} - -if (! function_exists('emitter')) { - /** - * Get Flextype Emitter Service. - */ - function emitter() - { - return flextype()->container()->get('emitter'); - } -} - -if (! function_exists('cache')) { - /** - * Get Flextype Cache Service. - */ - function cache() - { - return flextype()->container()->get('cache'); - } -} - -if (! function_exists('entries')) { - /** - * Get Flextype Entries Service. - */ - function entries() - { - return flextype()->container()->get('entries'); - } -} - -if (! function_exists('parsers')) { - /** - * Get Flextype Parsers Service. - */ - function parsers() - { - return flextype()->container()->get('parsers'); - } -} - -if (! function_exists('serializers')) { - /** - * Get Flextype Serializers Service. - */ - function serializers() - { - return flextype()->container()->get('serializers'); - } -} - -if (! function_exists('logger')) { - /** - * Get Flextype Logger Service. - */ - function logger() - { - return flextype()->container()->get('logger'); - } -} - -if (! function_exists('session')) { - /** - * Get Flextype Session Service. - */ - function session() - { - return flextype()->container()->get('session'); - } -} - -if (! function_exists('registry')) { - /** - * Get Flextype Registry Service. - */ - function registry() - { - return flextype()->container()->get('registry'); - } -} - -if (! function_exists('csrf')) { - /** - * Get Flextype CSRF Service. - */ - function csrf() - { - return flextype()->container()->get('csrf'); - } -} - -if (! function_exists('slugify')) { - /** - * Get Flextype Slugify Service. - */ - function slugify() - { - return flextype()->container()->get('slugify'); - } -} - -if (! function_exists('plugins')) { - /** - * Get Flextype Plugins Service. - */ - function plugins() - { - return flextype()->container()->get('plugins'); - } -} - -if (! function_exists('find')) { - /** - * Create a Finder instance with predefined filter params or without them. - * - * @param string $path Path. - * @param array $options Options array. - * @param string $searchIn Search in 'files' or 'directories'. Default is 'files'. - * - * @return Finder Finder instance. - */ - 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(); - - return $searchIn === 'directories' ? $find->directories() : $find->files(); - } -} - -if (! function_exists('filterCollection')) { - /** - * Filter collection. - * - * @param mixed $items Items. - * @param array $options Options array. - * - * @return array - */ - function filterCollection($items = [], array $options = []): array - { - $collection = arrays($items); - - ! isset($options['return']) and $options['return'] = 'all'; - - if (isset($options['only'])) { - $collection->only($options['only']); - } - - if (isset($options['except'])) { - $collection->except($options['except']); - } - - if (isset($options['where'])) { - if (is_array($options['where'])) { - foreach ($options['where'] as $key => $value) { - if ( - ! isset($value['key']) || - ! isset($value['operator']) || - ! isset($value['value']) - ) { - continue; - } - - $collection->where($value['key'], $value['operator'], $value['value']); - } - } - } - - if (isset($options['group_by'])) { - $collection->groupBy($options['group_by']); - } - - if (isset($options['sort_by'])) { - if (isset($options['sort_by']['key']) && isset($options['sort_by']['direction'])) { - $collection->sortBy($options['sort_by']['key'], $options['sort_by']['direction']); - } - } - - if (isset($options['offset'])) { - $collection->offset(isset($options['offset']) ? (int) $options['offset'] : 0); - } - - if (isset($options['limit'])) { - $collection->limit(isset($options['limit']) ? (int) $options['limit'] : 0); - } - - switch ($options['return']) { - case 'first': - $result = $collection->first(); - break; - case 'last': - $result = $collection->last(); - break; - case 'next': - $result = $collection->next(); - break; - case 'random': - $result = $collection->random(isset($options['random']) ? (int) $options['random'] : null); - break; - case 'shuffle': - $result = $collection->shuffle()->toArray(); - break; - case 'all': - default: - $result = $collection->all(); - break; - } - - return $result; - } -} - -if (! function_exists('images')) { - /** - * Get Flextype Images Service. - */ - function images() - { - return flextype()->container()->get('images'); - } -} - -if (! function_exists('imageFile')) { - /** - * Create a new image instance. - * - * @param string $file Image file. - * @param array $options Options array. - * - * @return Image|void - */ - function imageFile(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); - } -} - -if (! function_exists('upload')) { - /** - * Upload file. - * - * @param array $file Raw file data (multipart/form-data). - * @param string $folder The folder you're targetting. - * - * @return UploadResultFile Result file. - */ - function upload(array $file, string $folder): UploadResultFile - { - $settings = registry()->get('flextype.settings.upload'); - - $uploadFolder = strings(PATH['project'] . '/' . $settings['directory'] . '/' . $folder . '/')->reduceSlashes()->toString(); - - filesystem()->directory($uploadFolder)->ensureExists(0755, true); - - $uploadHandler = new UploadHandler($uploadFolder); - $uploadHandler->setOverwrite($settings['overwrite']); - $uploadHandler->setAutoconfirm($settings['autoconfirm']); - $uploadHandler->setPrefix($settings['prefix']); - - // Set 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(); - - // If upload file is image, do image file processing - if (isset($result->name)) { - if (getimagesize($mediaFile)) { - imageFile($mediaFile, $settings['process']['image']); - } - } - } catch (Throwable $e) { - $result->clear(); - - throw $e; - } - - return $result; - } -} - -if (! function_exists('token')) { - /** - * Token. - * - * @param int $length Token string length. - * - * @return strings Token string. - */ - function token(int $length = 16): string - { - return bin2hex(random_bytes($length)); - } -} - -if (! function_exists('tokenHash')) { - /** - * Token hash. - * - * @param int $length Token string length. - * - * @return string Token string. - */ - function tokenHash(int $length = 16): string - { - return password_hash(token($length), PASSWORD_BCRYPT); - } -} - -if (! function_exists('tokenHashValidate')) { - /** - * Token hash validate. - * - * @param string $token Token string length. - * @param string $tokenHashed Token string length. - * - * @return bool Token string. - */ - function tokenHashValidate(string $token, string $tokenHashed): bool - { - return password_verify($token, $tokenHashed); - } -} +require_once ROOT_DIR . '/src/flextype/helpers/services.php'; +require_once ROOT_DIR . '/src/flextype/helpers/arrays.php'; +require_once ROOT_DIR . '/src/flextype/helpers/finder.php'; +require_once ROOT_DIR . '/src/flextype/helpers/image.php'; +require_once ROOT_DIR . '/src/flextype/helpers/upload.php'; +require_once ROOT_DIR . '/src/flextype/helpers/tokens.php'; \ No newline at end of file diff --git a/src/flextype/helpers/image.php b/src/flextype/helpers/image.php new file mode 100644 index 00000000..2189666c --- /dev/null +++ b/src/flextype/helpers/image.php @@ -0,0 +1,185 @@ + $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); + } +} \ No newline at end of file diff --git a/src/flextype/helpers/services.php b/src/flextype/helpers/services.php new file mode 100644 index 00000000..35ab5a2f --- /dev/null +++ b/src/flextype/helpers/services.php @@ -0,0 +1,163 @@ +app(); + } +} + +if (! function_exists('container')) { + /** + * Get Flextype Container. + */ + function container() + { + return flextype()->container(); + } +} + +if (! function_exists('emitter')) { + /** + * Get Flextype Emitter Service. + */ + function emitter() + { + return flextype()->container()->get('emitter'); + } +} + +if (! function_exists('cache')) { + /** + * Get Flextype Cache Service. + */ + function cache() + { + return flextype()->container()->get('cache'); + } +} + +if (! function_exists('entries')) { + /** + * Get Flextype Entries Service. + */ + function entries() + { + return flextype()->container()->get('entries'); + } +} + +if (! function_exists('parsers')) { + /** + * Get Flextype Parsers Service. + */ + function parsers() + { + return flextype()->container()->get('parsers'); + } +} + +if (! function_exists('serializers')) { + /** + * Get Flextype Serializers Service. + */ + function serializers() + { + return flextype()->container()->get('serializers'); + } +} + +if (! function_exists('logger')) { + /** + * Get Flextype Logger Service. + */ + function logger() + { + return flextype()->container()->get('logger'); + } +} + +if (! function_exists('session')) { + /** + * Get Flextype Session Service. + */ + function session() + { + return flextype()->container()->get('session'); + } +} + +if (! function_exists('registry')) { + /** + * Get Flextype Registry Service. + */ + function registry() + { + return flextype()->container()->get('registry'); + } +} + +if (! function_exists('csrf')) { + /** + * Get Flextype CSRF Service. + */ + function csrf() + { + return flextype()->container()->get('csrf'); + } +} + +if (! function_exists('slugify')) { + /** + * Get Flextype Slugify Service. + */ + function slugify() + { + return flextype()->container()->get('slugify'); + } +} + +if (! function_exists('plugins')) { + /** + * Get Flextype Plugins Service. + */ + function plugins() + { + return flextype()->container()->get('plugins'); + } +} + +if (! function_exists('router')) { + /** + * Get Flextype Router Service. + */ + function router() + { + return flextype()->container()->get('router'); + } +} + +if (! function_exists('images')) { + /** + * Get Flextype Images Service. + */ + function images() + { + return flextype()->container()->get('images'); + } +} \ No newline at end of file diff --git a/src/flextype/helpers/tokens.php b/src/flextype/helpers/tokens.php new file mode 100644 index 00000000..66eaab5e --- /dev/null +++ b/src/flextype/helpers/tokens.php @@ -0,0 +1,46 @@ +get('flextype.settings.upload'); + + $uploadFolder = strings(PATH['project'] . '/' . $settings['directory'] . '/' . $folder . '/')->reduceSlashes()->toString(); + + filesystem()->directory($uploadFolder)->ensureExists(0755, true); + + $uploadHandler = new UploadHandler($uploadFolder); + $uploadHandler->setOverwrite($settings['overwrite']); + $uploadHandler->setAutoconfirm($settings['autoconfirm']); + $uploadHandler->setPrefix($settings['prefix']); + + // Set 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(); + + // If upload file is image, do image file processing + if (isset($result->name)) { + if (getimagesize($mediaFile)) { + imageFile($mediaFile, $settings['process']['image']); + } + } + } catch (Throwable $e) { + $result->clear(); + + throw $e; + } + + return $result; + } +} \ No newline at end of file From b6e1866dcc89ccadb0d7b628508696d736816b59 Mon Sep 17 00:00:00 2001 From: Awilum Date: Sun, 29 Aug 2021 20:54:05 +0300 Subject: [PATCH 06/51] feat(helpers): fix services helpers --- src/flextype/helpers/services.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/flextype/helpers/services.php b/src/flextype/helpers/services.php index 35ab5a2f..5ad1e825 100644 --- a/src/flextype/helpers/services.php +++ b/src/flextype/helpers/services.php @@ -2,6 +2,8 @@ declare(strict_types=1); +use Flextype\Flextype; + if (! function_exists('flextype')) { /** * Get the available Flextype instance. From 84cfcc395763c71f22d96222fc6dfd432695768d Mon Sep 17 00:00:00 2001 From: Awilum Date: Mon, 30 Aug 2021 09:58:28 +0300 Subject: [PATCH 07/51] feat(macros): decouple and refactor all macros --- src/flextype/macros/arrays.php | 43 ++++++++++++++++++++++++++++++++ src/flextype/macros/macros.php | 45 +--------------------------------- 2 files changed, 44 insertions(+), 44 deletions(-) create mode 100644 src/flextype/macros/arrays.php diff --git a/src/flextype/macros/arrays.php b/src/flextype/macros/arrays.php new file mode 100644 index 00000000..b4dff6d0 --- /dev/null +++ b/src/flextype/macros/arrays.php @@ -0,0 +1,43 @@ +toArray() as $key => $value) { + $result[$key] = arrays($value)->only($keys)->toArray(); + } + + return arrays($result); + }); +} + +if (! Arrays::hasMacro('exceptFromCollection')) { + /** + * Return slice of an array except given keys. + * + * @param array $keys List of keys to except. + * + * @return Arrays Returns instance of The Arrays class. + */ + Arrays::macro('exceptFromCollection', function (array $keys) { + $result = []; + + foreach ($this->toArray() as $key => $value) { + $result[$key] = arrays($value)->except($keys)->toArray(); + } + + return arrays($result); + }); +} diff --git a/src/flextype/macros/macros.php b/src/flextype/macros/macros.php index 498f2297..dd1a51db 100644 --- a/src/flextype/macros/macros.php +++ b/src/flextype/macros/macros.php @@ -2,47 +2,4 @@ declare(strict_types=1); -/** - * Flextype (https://flextype.org) - * Founded by Sergey Romanenko and maintained by Flextype Community. - */ - -use Atomastic\Arrays\Arrays; - -if (! Arrays::hasMacro('onlyFromCollection')) { - /** - * Return slice of an array with just a given keys. - * - * @param array $keys List of keys to return. - * - * @return Arrays Returns instance of The Arrays class. - */ - Arrays::macro('onlyFromCollection', function (array $keys) { - $result = []; - - foreach ($this->toArray() as $key => $value) { - $result[$key] = arrays($value)->only($keys)->toArray(); - } - - return arrays($result); - }); -} - -if (! Arrays::hasMacro('exceptFromCollection')) { - /** - * Return slice of an array except given keys. - * - * @param array $keys List of keys to except. - * - * @return Arrays Returns instance of The Arrays class. - */ - Arrays::macro('exceptFromCollection', function (array $keys) { - $result = []; - - foreach ($this->toArray() as $key => $value) { - $result[$key] = arrays($value)->except($keys)->toArray(); - } - - return arrays($result); - }); -} +require_once ROOT_DIR . '/src/flextype/macros/arrays.php'; \ No newline at end of file From f1d6f4c0d470df8dbb42ab3f2fe1ef6d7f6d5f7d Mon Sep 17 00:00:00 2001 From: Awilum Date: Mon, 30 Aug 2021 11:08:12 +0300 Subject: [PATCH 08/51] feat(helpers): remove router service --- src/flextype/helpers/services.php | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/flextype/helpers/services.php b/src/flextype/helpers/services.php index 5ad1e825..3b3cd7e8 100644 --- a/src/flextype/helpers/services.php +++ b/src/flextype/helpers/services.php @@ -144,16 +144,6 @@ if (! function_exists('plugins')) { } } -if (! function_exists('router')) { - /** - * Get Flextype Router Service. - */ - function router() - { - return flextype()->container()->get('router'); - } -} - if (! function_exists('images')) { /** * Get Flextype Images Service. From 3b3161658a5bd4421cda5d8eb4a1dc5c30494bad Mon Sep 17 00:00:00 2001 From: Awilum Date: Mon, 30 Aug 2021 11:08:43 +0300 Subject: [PATCH 09/51] feat(helpers): add urls helpers --- src/flextype/helpers/helpers.php | 3 +- src/flextype/helpers/urls.php | 128 +++++++++++++++++++++++++++++++ 2 files changed, 130 insertions(+), 1 deletion(-) create mode 100644 src/flextype/helpers/urls.php diff --git a/src/flextype/helpers/helpers.php b/src/flextype/helpers/helpers.php index 4afb26b7..956852ed 100644 --- a/src/flextype/helpers/helpers.php +++ b/src/flextype/helpers/helpers.php @@ -7,4 +7,5 @@ require_once ROOT_DIR . '/src/flextype/helpers/arrays.php'; require_once ROOT_DIR . '/src/flextype/helpers/finder.php'; require_once ROOT_DIR . '/src/flextype/helpers/image.php'; require_once ROOT_DIR . '/src/flextype/helpers/upload.php'; -require_once ROOT_DIR . '/src/flextype/helpers/tokens.php'; \ No newline at end of file +require_once ROOT_DIR . '/src/flextype/helpers/tokens.php'; +require_once ROOT_DIR . '/src/flextype/helpers/urls.php'; \ No newline at end of file diff --git a/src/flextype/helpers/urls.php b/src/flextype/helpers/urls.php new file mode 100644 index 00000000..febd1b6b --- /dev/null +++ b/src/flextype/helpers/urls.php @@ -0,0 +1,128 @@ + $data Route placeholders. + * @param array $queryParams Query parameters. + * + * @return string Url for a named route. + */ + function urlFor(string $routeName, array $data = [], array $queryParams = []): string + { + return app()->getRouteCollector()->getRouteParser()->urlFor($routeName, $data, $queryParams); + } +} + +if (! function_exists('fullUrlFor')) { + /** + * Get the full url for a named route. + * + * @param ServerRequestInterface $request Servert request interface. + * @param string $routeName Route name. + * @param array $data Route placeholders. + * @param array $queryParams Query parameters. + * + * @return string Full url for a named route. + */ + function fullUrlFor(ServerRequestInterface $request, string $routeName, array $data = [], array $queryParams = []): string + { + return app()->getRouteCollector()->getRouteParser()->fullUrlFor($request->getUri(), $routeName, $data, $queryParams); + } +} + +if (! function_exists('isCurrentUrl')) { + /** + * Determine is current url equal to route name. + * + * @param ServerRequestInterface $request Servert request interface. + * @param string $routeName Route name. + * @param array $data Route placeholders. + * + * @return bool + */ + function isCurrentUrl(ServerRequestInterface $request, string $routeName, array $data = []): bool + { + $currentUrl = getBasePath() . $request->getUri()->getPath(); + $result = app()->getRouteCollector()->getRouteParser()->urlFor($routeName, $data); + + return $result === $currentUrl; + } +} + +if (! function_exists('getCurrentUrl')) { + /** + * Get current path on given Uri. + * + * @param ServerRequestInterface $request Servert request interface. + * @param bool $withQueryString Get query string for current path. + * + * @return string + */ + function getCurrentUrl(ServerRequestInterface $request, bool $withQueryString = false): string + { + $currentUrl = getBasePath() . $request->getUri()->getPath(); + $query = $request->getUri()->getQuery(); + + if ($withQueryString && !empty($query)) { + $currentUrl .= '?'.$query; + } + + return $currentUrl; + } +} + +if (! function_exists('getBasePath')) { + /** + * Get the base path + * + * @return string Base Path. + */ + function getBasePath(): string + { + return app()->getBasePath(); + } +} + +if (! function_exists('setBasePath')) { + /** + * Set the base path + * + * @param string $basePath Base path. + * + * @return void + */ + function setBasePath(string $basePath) + { + app()->setBasePath($basePath); + } +} + +if (! function_exists('redirect')) { + /** + * Redirect + * + * @param string $routeName Route name + * @param array $data Route placeholders + * @param array $queryParams Query parameters + * + * @return Response + */ + function redirect(string $routeName, array $data = [], array $queryParams = []): Response + { + $response = new Response(); + $response->withHeader('Location', urlFor($routeName, $data, $queryParams)); + + return $response; + } +} \ No newline at end of file From 96beeb3b325db677e42ec277164c639b42de6070 Mon Sep 17 00:00:00 2001 From: Awilum Date: Mon, 30 Aug 2021 11:38:57 +0300 Subject: [PATCH 10/51] feat(helpers): fix paths for helpers --- src/flextype/helpers/helpers.php | 14 +++++++------- src/flextype/helpers/urls.php | 1 - 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/flextype/helpers/helpers.php b/src/flextype/helpers/helpers.php index 956852ed..441cf71b 100644 --- a/src/flextype/helpers/helpers.php +++ b/src/flextype/helpers/helpers.php @@ -2,10 +2,10 @@ declare(strict_types=1); -require_once ROOT_DIR . '/src/flextype/helpers/services.php'; -require_once ROOT_DIR . '/src/flextype/helpers/arrays.php'; -require_once ROOT_DIR . '/src/flextype/helpers/finder.php'; -require_once ROOT_DIR . '/src/flextype/helpers/image.php'; -require_once ROOT_DIR . '/src/flextype/helpers/upload.php'; -require_once ROOT_DIR . '/src/flextype/helpers/tokens.php'; -require_once ROOT_DIR . '/src/flextype/helpers/urls.php'; \ No newline at end of file +require_once __DIR__ . '/services.php'; +require_once __DIR__ . '/arrays.php'; +require_once __DIR__ . '/finder.php'; +require_once __DIR__ . '/image.php'; +require_once __DIR__ . '/upload.php'; +require_once __DIR__ . '/tokens.php'; +require_once __DIR__ . '/urls.php'; \ No newline at end of file diff --git a/src/flextype/helpers/urls.php b/src/flextype/helpers/urls.php index febd1b6b..670d90a8 100644 --- a/src/flextype/helpers/urls.php +++ b/src/flextype/helpers/urls.php @@ -2,7 +2,6 @@ declare(strict_types=1); - use Slim\Interfaces\RouteParserInterface; use Psr\Http\Message\UriInterface; use Psr\Http\Message\ServerRequestInterface as Request; From 319c65768d1e61397bc87dc3eca58823a25b5c72 Mon Sep 17 00:00:00 2001 From: Awilum Date: Mon, 30 Aug 2021 11:39:22 +0300 Subject: [PATCH 11/51] feat(macros): fix paths for macros --- src/flextype/macros/macros.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/flextype/macros/macros.php b/src/flextype/macros/macros.php index dd1a51db..a9c66666 100644 --- a/src/flextype/macros/macros.php +++ b/src/flextype/macros/macros.php @@ -2,4 +2,4 @@ declare(strict_types=1); -require_once ROOT_DIR . '/src/flextype/macros/arrays.php'; \ No newline at end of file +require_once __DIR__ . '/arrays.php'; \ No newline at end of file From d3443a14b79709048e4ea9ba3ab29fbb92cbbbd7 Mon Sep 17 00:00:00 2001 From: Awilum Date: Mon, 30 Aug 2021 11:39:32 +0300 Subject: [PATCH 12/51] feat(middlewares): updates for CSRF middleware --- src/flextype/core/Middlewares/CsrfMiddleware.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/flextype/core/Middlewares/CsrfMiddleware.php b/src/flextype/core/Middlewares/CsrfMiddleware.php index 2ac78f1c..94d15e54 100644 --- a/src/flextype/core/Middlewares/CsrfMiddleware.php +++ b/src/flextype/core/Middlewares/CsrfMiddleware.php @@ -41,7 +41,7 @@ class CsrfMiddleware /** - * Example middleware invokable class + * Invoke * * @param ServerRequest $request PSR-7 request * @param RequestHandler $handler PSR-15 request handler From 7a2c71a7dbc1fd021c750f0cac01a4788e3c6952 Mon Sep 17 00:00:00 2001 From: Awilum Date: Mon, 30 Aug 2021 11:40:49 +0300 Subject: [PATCH 13/51] feat(flextype): update flextype bootstrap code --- src/flextype/flextype.php | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/flextype/flextype.php b/src/flextype/flextype.php index b77a8724..3cb0c35d 100644 --- a/src/flextype/flextype.php +++ b/src/flextype/flextype.php @@ -162,7 +162,7 @@ if (filesystem()->file($preflightFlextypePath . '/' . $cacheID . '.php')->exists registry()->set('flextype', $flextypeData); // Set Flextype base path -app()->setBasePath(registry()->get('flextype.settings.url')); +setBasePath(registry()->get('flextype.settings.url')); // Add Routing Middleware app()->add(new RoutingMiddleware(app()->getRouteResolver(), app()->getRouteCollector()->getRouteParser())); @@ -410,9 +410,6 @@ container()->set('images', static function () { // Add Entries Service container()->set('entries', new Entries(registry()->get('flextype.settings.entries'))); -// Add Plugins Service -container()->set('plugins', new Plugins()); - // Set session options before you start the session // Standard PHP session configuration options // https://secure.php.net/manual/en/session.configuration.php @@ -434,8 +431,8 @@ if (in_array(registry()->get('flextype.settings.timezone'), DateTimeZone::listId date_default_timezone_set(registry()->get('flextype.settings.timezone')); } -// Init Plugins -plugins()->init(); +// Add Plugins Service +container()->set('plugins', new Plugins()); // Api Endpoints require_once ROOT_DIR . '/src/flextype/routes/endpoints/utils.php'; From d14bac223f0617b630297a4d84f575cb6e3e95a0 Mon Sep 17 00:00:00 2001 From: Awilum Date: Mon, 30 Aug 2021 11:41:25 +0300 Subject: [PATCH 14/51] feat(plugins): simple updates for plugins api --- src/flextype/core/Plugins.php | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/flextype/core/Plugins.php b/src/flextype/core/Plugins.php index 5e929cfb..9cee310a 100755 --- a/src/flextype/core/Plugins.php +++ b/src/flextype/core/Plugins.php @@ -44,6 +44,7 @@ class Plugins public function __construct() { $this->locales = serializers()->yaml()->decode(filesystem()->file(ROOT_DIR . '/src/flextype/locales.yaml')->get()); + $this->init(); } /** @@ -61,9 +62,9 @@ class Plugins /** * Init Plugins * - * @access public + * @access protected */ - public function init(): void + protected function init(): void { // Set empty plugins item registry()->set('plugins', []); @@ -74,7 +75,7 @@ class Plugins // Get plugins list $pluginsList = $this->getPluginsList(); - $pluginsList = arrays($pluginsList)->only(['box'])->toArray(); + // $pluginsList = arrays($pluginsList)->only(['twig', 'blueprints'])->toArray(); // Get plugins Cache ID $pluginsCacheID = $this->getPluginsCacheID($pluginsList); @@ -185,8 +186,6 @@ class Plugins $this->includeEnabledPlugins(); - - emitter()->emit('onPluginsInitialized'); } @@ -393,7 +392,7 @@ class Plugins continue; } - include_once PATH['project'] . '/plugins/' . $pluginName . '/plugin.php'; + require_once PATH['project'] . '/plugins/' . $pluginName . '/plugin.php'; } } } From d4d57d4b62bdf641baad8cee6fb7775706ea7137 Mon Sep 17 00:00:00 2001 From: Awilum Date: Wed, 1 Sep 2021 08:07:11 +0300 Subject: [PATCH 15/51] feat(helpers): update `redirect` urls helpers --- src/flextype/helpers/urls.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/flextype/helpers/urls.php b/src/flextype/helpers/urls.php index 670d90a8..a0c62512 100644 --- a/src/flextype/helpers/urls.php +++ b/src/flextype/helpers/urls.php @@ -120,7 +120,7 @@ if (! function_exists('redirect')) { function redirect(string $routeName, array $data = [], array $queryParams = []): Response { $response = new Response(); - $response->withHeader('Location', urlFor($routeName, $data, $queryParams)); + $response = $response->withHeader('Location', urlFor($routeName, $data, $queryParams)); return $response; } From a2ca98fd993c2623205073124004b9654503fc80 Mon Sep 17 00:00:00 2001 From: Awilum Date: Wed, 1 Sep 2021 19:40:42 +0300 Subject: [PATCH 16/51] feat(images): update and improve settings for Images service --- src/flextype/flextype.php | 8 ++++---- src/flextype/settings.yaml | 20 ++++++++++++++++++++ 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/flextype/flextype.php b/src/flextype/flextype.php index 3cb0c35d..133d057a 100644 --- a/src/flextype/flextype.php +++ b/src/flextype/flextype.php @@ -344,24 +344,24 @@ parsers()->shortcodes()->initShortcodes(); // Add Serializers Service container()->set('serializers', new Serializers()); -// Add Image Service +// Add Images Service container()->set('images', static function () { // Get image settings $imagesSettings = ['driver' => registry()->get('flextype.settings.images.driver')]; // Set source filesystem $source = new Flysystem( - new Local(PATH['project'] . '/uploads/') + new Local(PATH['project'] . registry()->get('flextype.settings.images.directory')), ); // Set cache filesystem $cache = new Flysystem( - new Local(PATH['tmp'] . '/glide') + new Local(PATH['tmp'] . registry()->get('flextype.settings.images.cache.directory')) ); // Set watermarks filesystem $watermarks = new Flysystem( - new Local(PATH['project'] . '/watermarks') + new Local(PATH['project'] . registry()->get('flextype.settings.images.watermarks.directory')) ); // Set image manager diff --git a/src/flextype/settings.yaml b/src/flextype/settings.yaml index 443b904e..bc03a664 100644 --- a/src/flextype/settings.yaml +++ b/src/flextype/settings.yaml @@ -654,6 +654,26 @@ upload: image: quality: 70 +# Images +# +# - driver: Images driver (gd, imagick) +# +# - directory: Images directory. +# +# - watermarks.directory: Watermarks directory. +# +# - cache.enabled: Set to true to enable images caching. +# +# - cache.directory: Images cache directory. +images: + driver: gd + directory: '/uploads' + watermarks: + directory: '/watermarks' + cache: + directory: '/images' + + # Session # # Set session options before you start the session From 1fd93a4839581851fe8133e045379c190eadc5d4 Mon Sep 17 00:00:00 2001 From: Awilum Date: Wed, 1 Sep 2021 19:45:45 +0300 Subject: [PATCH 17/51] feat(images): add presets functionality for Images service --- src/flextype/flextype.php | 4 ++++ src/flextype/settings.yaml | 3 +++ 2 files changed, 7 insertions(+) diff --git a/src/flextype/flextype.php b/src/flextype/flextype.php index 133d057a..a1ec26fa 100644 --- a/src/flextype/flextype.php +++ b/src/flextype/flextype.php @@ -395,6 +395,10 @@ container()->set('images', static function () { 'api' => $api, ]); + // Set presets + $server->setPresets(registry()->get('flextype.settings.images.presets')); + + // Set Glide response factory $server->setResponseFactory( new PsrResponseFactory( new Response(), diff --git a/src/flextype/settings.yaml b/src/flextype/settings.yaml index bc03a664..7de7d79d 100644 --- a/src/flextype/settings.yaml +++ b/src/flextype/settings.yaml @@ -665,6 +665,8 @@ upload: # - cache.enabled: Set to true to enable images caching. # # - cache.directory: Images cache directory. +# +# - presets: Group of presets for images processing. images: driver: gd directory: '/uploads' @@ -672,6 +674,7 @@ images: directory: '/watermarks' cache: directory: '/images' + presets: [] # Session From 1ed5afff7dc52070b4bc64bb7ea52ab89a66c550 Mon Sep 17 00:00:00 2001 From: Awilum Date: Wed, 1 Sep 2021 19:47:15 +0300 Subject: [PATCH 18/51] feat(images): update settings --- src/flextype/settings.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/src/flextype/settings.yaml b/src/flextype/settings.yaml index 7de7d79d..79fdaa1a 100644 --- a/src/flextype/settings.yaml +++ b/src/flextype/settings.yaml @@ -676,7 +676,6 @@ images: directory: '/images' presets: [] - # Session # # Set session options before you start the session From 451b81779e7679240ffc759aa5dac1add5abd586 Mon Sep 17 00:00:00 2001 From: Awilum Date: Wed, 1 Sep 2021 19:55:09 +0300 Subject: [PATCH 19/51] feat(settings): update settings --- src/flextype/settings.yaml | 88 ++++++++++++++++++++++---------------- 1 file changed, 50 insertions(+), 38 deletions(-) diff --git a/src/flextype/settings.yaml b/src/flextype/settings.yaml index 79fdaa1a..dc969bb3 100644 --- a/src/flextype/settings.yaml +++ b/src/flextype/settings.yaml @@ -519,19 +519,31 @@ serializers: # Parsers # -# markdown.cache: Cache result data or no. Default is true. -# markdown.commonmark.renderer.block_separator: String to use for separating renderer block elements. -# markdown.commonmark.renderer.inner_separator: String to use for separating inner block contents. -# markdown.commonmark.renderer.soft_break: String to use for rendering soft breaks. -# markdown.commonmark.commonmark.enable_em: Disable parsing by setting to false; enable with true (default: true) -# markdown.commonmark.commonmark.enable_strong: Disable parsing by setting to false; enable with true (default: true) -# markdown.commonmark.commonmark.use_asterisk: Disable parsing of * for emphasis by setting to false; enable with true (default: true) -# markdown.commonmark.commonmark.use_underscore: Disable parsing of _ for emphasis by setting to false; enable with true (default: true) -# markdown.commonmark.commonmark.unordered_list_markers: Array of characters that can be used to indicate a bulleted list. -# markdown.commonmark.html_input: `strip` all HTML (equivalent to 'safe' => true). `allow` all HTML input as-is (default value; equivalent to `‘safe’ => false) `escape` Escape all HTML. -# markdown.commonmark.allow_unsafe_links: Remove risky link and image URLs by setting this to false (default: true). -# markdown.commonmark.max_nesting_level: The maximum nesting level for blocks (default: PHP_INT_MAX). Setting this to a positive integer can help protect against long parse times and/or segfaults if blocks are too deeply-nested. -# markdown.commonmark.slug_normalizer.max_length: Limits the size of generated slugs (defaults to 255 characters) +# - markdown.cache: Cache result data or no. Default is true. +# +# - markdown.commonmark.renderer.block_separator: String to use for separating renderer block elements. +# +# - markdown.commonmark.renderer.inner_separator: String to use for separating inner block contents. +# +# - markdown.commonmark.renderer.soft_break: String to use for rendering soft breaks. +# +# - markdown.commonmark.commonmark.enable_em: Disable parsing by setting to false; enable with true (default: true) +# +# - markdown.commonmark.commonmark.enable_strong: Disable parsing by setting to false; enable with true (default: true) +# +# - markdown.commonmark.commonmark.use_asterisk: Disable parsing of * for emphasis by setting to false; enable with true (default: true) +# +# - markdown.commonmark.commonmark.use_underscore: Disable parsing of _ for emphasis by setting to false; enable with true (default: true) +# +# - markdown.commonmark.commonmark.unordered_list_markers: Array of characters that can be used to indicate a bulleted list. +# +# - markdown.commonmark.html_input: `strip` all HTML (equivalent to 'safe' => true). `allow` all HTML input as-is (default value; equivalent to `‘safe’ => false) `escape` Escape all HTML. +# +# - markdown.commonmark.allow_unsafe_links: Remove risky link and image URLs by setting this to false (default: true). +# +# - markdown.commonmark.max_nesting_level: The maximum nesting level for blocks (default: PHP_INT_MAX). Setting this to a positive integer can help protect against long parse times and/or segfaults if blocks are too deeply-nested. +# +# - markdown.commonmark.slug_normalizer.max_length: Limits the size of generated slugs (defaults to 255 characters) parsers: markdown: cache: true @@ -576,24 +588,24 @@ parsers: # This is important for third party web apps using Flextype, as without CORS, a JavaScript app hosted on example.com # couldn't access our APIs because they're hosted on another.com which is a different domain. # -# - enabled: Set to true to enable cors +# - enabled: Set to true to enable cors # -# - origin: The Access-Control-Allow-Origin response header indicates whether -# the response can be shared with requesting code from the given origin. -# read more: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin +# - origin: The Access-Control-Allow-Origin response header indicates whether +# the response can be shared with requesting code from the given origin. +# read more: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin # -# - headers: The Access-Control-Allow-Headers response header is used in response -# to a preflight request which includes the Access-Control-Request-Headers -# to indicate which HTTP headers can be used during the actual request. -# read more: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers +# - headers: The Access-Control-Allow-Headers response header is used in response +# to a preflight request which includes the Access-Control-Request-Headers +# to indicate which HTTP headers can be used during the actual request. +# read more: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers # -# - methods: The Access-Control-Allow-Methods response header specifies the method -# or methods allowed when accessing the resource in response to a preflight request. -# read more: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Methods +# - methods: The Access-Control-Allow-Methods response header specifies the method +# or methods allowed when accessing the resource in response to a preflight request. +# read more: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Methods # -# - expose: The Access-Control-Expose-Headers response header indicates which headers -# can be exposed as part of the response by listing their names. -# read more: https://developer.mozilla.org/ru/docs/Web/HTTP/Headers/Access-Control-Expose-Headers +# - expose: The Access-Control-Expose-Headers response header indicates which headers +# can be exposed as part of the response by listing their names. +# read more: https://developer.mozilla.org/ru/docs/Web/HTTP/Headers/Access-Control-Expose-Headers # # - credentials: The Access-Control-Allow-Credentials response header tells browsers whether # to expose the response to frontend JavaScript code when the request's credentials @@ -609,27 +621,27 @@ cors: # Upload # -# - directory: Uploads directory +# - directory: Uploads directory # -# - overwrite: Overwrite existing files. +# - overwrite: Overwrite existing files. # -# - autoconfirm: Auto-confirm uploads. +# - autoconfirm: Auto-confirm uploads. # -# - prefix: Prefixing uploads. +# - prefix: Prefixing uploads. # -# - validation.allowed_file_extensions: Allowed file extensions. +# - validation.allowed_file_extensions: Allowed file extensions. # -# - validation.max_file_size: Maximum file size. +# - validation.max_file_size: Maximum file size. # -# - validation.image.width.max: Image maxiumum width. +# - validation.image.width.max: Image maxiumum width. # -# - validation.image.width.min: Image minimum width. +# - validation.image.width.min: Image minimum width. # -# - validation.image.height.max: Image maxiumum height. +# - validation.image.height.max: Image maxiumum height. # -# - validation.image.height.min: Image minimum height. +# - validation.image.height.min: Image minimum height. # -# - validation.image.ratio.size: The option can be a number (eg: 1.3) or a ratio-like string (eg: 4:3, 16:9). +# - validation.image.ratio.size: The option can be a number (eg: 1.3) or a ratio-like string (eg: 4:3, 16:9). # # - 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. From 3643831430cbff067ccf4463cf3cbc281fe38bb2 Mon Sep 17 00:00:00 2001 From: Awilum Date: Wed, 1 Sep 2021 20:11:39 +0300 Subject: [PATCH 20/51] feat(entries): add ability to set directory for Entries service --- src/flextype/core/Entries/Entries.php | 6 +++--- src/flextype/settings.yaml | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/flextype/core/Entries/Entries.php b/src/flextype/core/Entries/Entries.php index 74f5be94..81a352d5 100755 --- a/src/flextype/core/Entries/Entries.php +++ b/src/flextype/core/Entries/Entries.php @@ -304,7 +304,7 @@ class Entries $currentEntryID = strings($currenEntry->getPath()) ->replace('\\', '/') - ->replace(PATH['project'] . '/entries/', '') + ->replace(PATH['project'] . $this->options['directory'] . '/', '') ->trim('/') ->toString(); @@ -561,7 +561,7 @@ class Entries // Set collection options $this->registry()->set('collection.options', $this->getCollectionOptions($id)); - return PATH['project'] . '/entries/' . $id . '/' . $this->registry()->get('collection.options.filename') . '.' . $this->registry()->get('collection.options.extension'); + return PATH['project'] . $this->options['directory'] . '/' . $id . '/' . $this->registry()->get('collection.options.filename') . '.' . $this->registry()->get('collection.options.extension'); } /** @@ -575,7 +575,7 @@ class Entries */ public function getDirectoryLocation(string $id): string { - return PATH['project'] . '/entries/' . $id; + return PATH['project'] . $this->options['directory'] . '/' . $id; } /** diff --git a/src/flextype/settings.yaml b/src/flextype/settings.yaml index dc969bb3..a1654cde 100644 --- a/src/flextype/settings.yaml +++ b/src/flextype/settings.yaml @@ -55,6 +55,7 @@ errors: # Entries entries: + directory: '/entries' collections: default: filename: entry From 4514b8946eb9264f144aaf6fa5fea77c02139af2 Mon Sep 17 00:00:00 2001 From: Awilum Date: Wed, 1 Sep 2021 20:59:55 +0300 Subject: [PATCH 21/51] feat(images): add ability to set max images size for Images service --- src/flextype/flextype.php | 5 ++++- src/flextype/settings.yaml | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/flextype/flextype.php b/src/flextype/flextype.php index a1ec26fa..f575e964 100644 --- a/src/flextype/flextype.php +++ b/src/flextype/flextype.php @@ -367,11 +367,14 @@ container()->set('images', static function () { // Set image manager $imageManager = new ImageManager($imagesSettings); + // Set max image size + $maxImageSize = registry()->get('flextype.settings.images.max_image_size.width') * registry()->get('flextype.settings.images.max_image_size.height'); + // Set manipulators $manipulators = [ new Orientation(), new Crop(), - new Size(), + new Size($maxImageSize), new Brightness(), new Contrast(), new Gamma(), diff --git a/src/flextype/settings.yaml b/src/flextype/settings.yaml index a1654cde..c3bd3659 100644 --- a/src/flextype/settings.yaml +++ b/src/flextype/settings.yaml @@ -683,6 +683,9 @@ upload: images: driver: gd directory: '/uploads' + max_image_size: + width: 2000 + height: 2000 watermarks: directory: '/watermarks' cache: From 310f2f6c3de0a6d72ee0c87d1eb71eb0df1864e5 Mon Sep 17 00:00:00 2001 From: Awilum Date: Thu, 2 Sep 2021 10:31:52 +0300 Subject: [PATCH 22/51] feat(endpoints): use directory setting for Images service --- src/flextype/core/Endpoints/Images.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/flextype/core/Endpoints/Images.php b/src/flextype/core/Endpoints/Images.php index b9f0820f..4db1b701 100644 --- a/src/flextype/core/Endpoints/Images.php +++ b/src/flextype/core/Endpoints/Images.php @@ -41,7 +41,7 @@ class Images extends Api } // Check is file exists - if (! filesystem()->file(PATH['project'] . '/uploads/' . $path)->exists()) { + if (! filesystem()->file(flextype()->registry()->get('flextype.settings.images.directory') . $path)->exists()) { return $this->getApiResponse($response, $this->getStatusCodeMessage(404), 404); } From 26cfd57ac8c0eab1eac1962d464c2814d0452906 Mon Sep 17 00:00:00 2001 From: Awilum Date: Thu, 2 Sep 2021 10:34:10 +0300 Subject: [PATCH 23/51] feat(endpoints): use directory setting for Images service --- src/flextype/core/Endpoints/Images.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/flextype/core/Endpoints/Images.php b/src/flextype/core/Endpoints/Images.php index 4db1b701..63f80ce6 100644 --- a/src/flextype/core/Endpoints/Images.php +++ b/src/flextype/core/Endpoints/Images.php @@ -41,7 +41,7 @@ class Images extends Api } // Check is file exists - if (! filesystem()->file(flextype()->registry()->get('flextype.settings.images.directory') . $path)->exists()) { + if (! filesystem()->file(flextype()->registry()->get('flextype.settings.images.directory') . '/' . $path)->exists()) { return $this->getApiResponse($response, $this->getStatusCodeMessage(404), 404); } From f3ccaeb5d0d02648f055920ed21d1b8adfbdac87 Mon Sep 17 00:00:00 2001 From: Awilum Date: Thu, 2 Sep 2021 20:06:16 +0300 Subject: [PATCH 24/51] feat(images): update settings for Images service --- src/flextype/flextype.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/flextype/flextype.php b/src/flextype/flextype.php index f575e964..65c273c3 100644 --- a/src/flextype/flextype.php +++ b/src/flextype/flextype.php @@ -346,8 +346,9 @@ container()->set('serializers', new Serializers()); // Add Images Service container()->set('images', static function () { - // Get image settings - $imagesSettings = ['driver' => registry()->get('flextype.settings.images.driver')]; + + // Get image settings driver + $imagesSettingsDriver = ['driver' => registry()->get('flextype.settings.images.driver')]; // Set source filesystem $source = new Flysystem( @@ -365,7 +366,7 @@ container()->set('images', static function () { ); // Set image manager - $imageManager = new ImageManager($imagesSettings); + $imageManager = new ImageManager($imagesSettingsDriver); // Set max image size $maxImageSize = registry()->get('flextype.settings.images.max_image_size.width') * registry()->get('flextype.settings.images.max_image_size.height'); From ddacb495c4e24018a7f5ed95ab4d1f1c881ccc8d Mon Sep 17 00:00:00 2001 From: Awilum Date: Fri, 3 Sep 2021 11:01:04 +0300 Subject: [PATCH 25/51] feat(media): remove media class --- src/flextype/core/Media.php | 135 ------------------------------------ 1 file changed, 135 deletions(-) delete mode 100644 src/flextype/core/Media.php diff --git a/src/flextype/core/Media.php b/src/flextype/core/Media.php deleted file mode 100644 index 30daccc4..00000000 --- a/src/flextype/core/Media.php +++ /dev/null @@ -1,135 +0,0 @@ -directory(PATH['project'] . registry()->get('flextype.settings.upload.directory') . '/media') - ->ensureExists(0755, true); - - container()->get('emitter')->addListener('onEntriesCreate', static function (): void { - entries()->registy()->get('collections'); - }); - } - - /** - * Create media entry. - * - * @param string $id Unique identifier of the media entry. - * @param array $data Data to create for the media entry. - * - * @return bool True on success, false on failure. - * - * @access public - */ - public function create(string $id, array $data = []): bool - { - $data['resource'] = $data['resource'] ?? ''; - - if (is_array($data['resource'])) { - - $media = upload($data['resource'], $id); - - if ($media->name) { - - //$mediaFile = $uploadFolder . '/media.' . filesystem()->file($media->name)->extension(); - //filesystem()->file($uploadFolder . '/' . $media->name)->move($mediaFile); - - - $data['resource'] = strings($id . '/media.' . filesystem()->file($media->name)->extension())->reduceSlashes()->toString(); - } else { - $data['resource'] = ''; - } - } - } - - /** - * Move media entry. - * - * @param string $id Unique identifier of the media entry. - * @param string $newID New Unique identifier of the media entry. - * - * @return bool True on success, false on failure. - * - * @access public - */ - public function move(string $id, string $newID): bool - { - $mediaResourceDirectoryCurrentLocation = PATH['project'] . registry()->get('flextype.settings.media.upload.directory') . '/' . $id; - $mediaResourceDirectoryNewLocation = PATH['project'] . registry()->get('flextype.settings.media.upload.directory') . '/' . $newID; - - if (filesystem()->directory($mediaResourceDirectoryCurrentLocation)->exists()) { - filesystem()->directory($mediaResourceDirectoryCurrentLocation)->move($mediaResourceDirectoryNewLocation); - } - } - - /** - * Copy media entry. - * - * @param string $id Unique identifier of the media entry. - * @param string $newID New Unique identifier of the media entry. - * - * @return bool|null True on success, false on failure. - * - * @access public - */ - public function copy(string $id, string $newID): bool - { - $mediaResourceDirectoryCurrentLocation = PATH['project'] . registry()->get('flextype.settings.media.upload.directory') . '/' . $id; - $mediaResourceDirectoryNewLocation = PATH['project'] . registry()->get('flextype.settings.media.upload.directory') . '/' . $newID; - - if (filesystem()->directory($mediaResourceDirectoryCurrentLocation)->exists()) { - filesystem()->directory($mediaResourceDirectoryCurrentLocation)->copy($mediaResourceDirectoryNewLocation); - } - } - - /** - * Delete media entry. - * - * @param string $id Unique identifier of the media entry. - * - * @return bool True on success, false on failure. - * - * @access public - */ - public function delete(string $id): bool - { - $mediaResourceDirectoryCurrentLocation = PATH['project'] . registry()->get('flextype.settings.media.upload.directory') . '/' . $id; - - if (filesystem()->directory($mediaResourceDirectoryCurrentLocation)->exists()) { - filesystem()->directory($mediaResourceDirectoryCurrentLocation)->delete(); - } - } -} From 55be04bfa57058780263968d34373dddf9822429 Mon Sep 17 00:00:00 2001 From: Awilum Date: Fri, 3 Sep 2021 11:01:48 +0300 Subject: [PATCH 26/51] feat(endpoints): update endpoints for Images service --- src/flextype/core/Endpoints/Images.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/flextype/core/Endpoints/Images.php b/src/flextype/core/Endpoints/Images.php index 63f80ce6..9a1e7cf1 100644 --- a/src/flextype/core/Endpoints/Images.php +++ b/src/flextype/core/Endpoints/Images.php @@ -40,12 +40,12 @@ class Images extends Api return $this->getApiResponse($response, $this->getStatusCodeMessage($result['http_status_code']), $result['http_status_code']); } - // Check is file exists + // Determine if the image file exists if (! filesystem()->file(flextype()->registry()->get('flextype.settings.images.directory') . '/' . $path)->exists()) { return $this->getApiResponse($response, $this->getStatusCodeMessage(404), 404); } // Return image response - return container()->get('images')->getImageResponse($path, $request->getQueryParams()); + return images()->getImageResponse($path, $request->getQueryParams()); } } From 89da2476880beaf1ff3605f43192ba6d00ecf3d1 Mon Sep 17 00:00:00 2001 From: Awilum Date: Fri, 3 Sep 2021 12:29:31 +0300 Subject: [PATCH 27/51] fix(helpers): fix upload function image processing --- src/flextype/helpers/upload.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/flextype/helpers/upload.php b/src/flextype/helpers/upload.php index 125455c4..4a1e88d4 100644 --- a/src/flextype/helpers/upload.php +++ b/src/flextype/helpers/upload.php @@ -45,9 +45,12 @@ if (! function_exists('upload')) { try { $result->confirm(); - + // If upload file is image, do image file processing - if (isset($result->name)) { + if ($result->name) { + + $mediaFile = $uploadFolder . '/' . $result->name; + if (getimagesize($mediaFile)) { imageFile($mediaFile, $settings['process']['image']); } From 9d8fd988105295e654fd2abad32cf8cacc16f8f5 Mon Sep 17 00:00:00 2001 From: Awilum Date: Fri, 3 Sep 2021 12:32:45 +0300 Subject: [PATCH 28/51] feat(helpers): typo updates for `imageFile` function helper --- src/flextype/helpers/image.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/flextype/helpers/image.php b/src/flextype/helpers/image.php index 2189666c..65369dea 100644 --- a/src/flextype/helpers/image.php +++ b/src/flextype/helpers/image.php @@ -6,7 +6,7 @@ use Intervention\Image\ImageManagerStatic as Image; if (! function_exists('imageFile')) { /** - * Create a new image instance. + * Create a new image instance for image file. * * @param string $file Image file. * @param array $options Options array. From 21ed275a51306db620739d9432289eca6a1367bf Mon Sep 17 00:00:00 2001 From: Awilum Date: Fri, 3 Sep 2021 13:22:16 +0300 Subject: [PATCH 29/51] feat(settings): improve settings definition for Images API --- src/flextype/flextype.php | 12 +++---- src/flextype/settings.yaml | 73 +++++++++++++++++++++++++------------- 2 files changed, 54 insertions(+), 31 deletions(-) diff --git a/src/flextype/flextype.php b/src/flextype/flextype.php index 65c273c3..ae2a2e13 100644 --- a/src/flextype/flextype.php +++ b/src/flextype/flextype.php @@ -348,28 +348,28 @@ container()->set('serializers', new Serializers()); container()->set('images', static function () { // Get image settings driver - $imagesSettingsDriver = ['driver' => registry()->get('flextype.settings.images.driver')]; + $imagesSettingsDriver = ['driver' => registry()->get('flextype.settings.api.images.driver')]; // Set source filesystem $source = new Flysystem( - new Local(PATH['project'] . registry()->get('flextype.settings.images.directory')), + new Local(PATH['project'] . registry()->get('flextype.settings.api.images.directory')), ); // Set cache filesystem $cache = new Flysystem( - new Local(PATH['tmp'] . registry()->get('flextype.settings.images.cache.directory')) + new Local(PATH['tmp'] . registry()->get('flextype.settings.api.images.cache.directory')) ); // Set watermarks filesystem $watermarks = new Flysystem( - new Local(PATH['project'] . registry()->get('flextype.settings.images.watermarks.directory')) + new Local(PATH['project'] . registry()->get('flextype.settings.api.images.watermarks.directory')) ); // Set image manager $imageManager = new ImageManager($imagesSettingsDriver); // Set max image size - $maxImageSize = registry()->get('flextype.settings.images.max_image_size.width') * registry()->get('flextype.settings.images.max_image_size.height'); + $maxImageSize = registry()->get('flextype.settings.api.images.max_image_size.width') * registry()->get('flextype.settings.api.images.max_image_size.height'); // Set manipulators $manipulators = [ @@ -400,7 +400,7 @@ container()->set('images', static function () { ]); // Set presets - $server->setPresets(registry()->get('flextype.settings.images.presets')); + $server->setPresets(registry()->get('flextype.settings.api.images.presets')); // Set Glide response factory $server->setResponseFactory( diff --git a/src/flextype/settings.yaml b/src/flextype/settings.yaml index c3bd3659..7da27c9b 100644 --- a/src/flextype/settings.yaml +++ b/src/flextype/settings.yaml @@ -666,31 +666,6 @@ upload: process: image: quality: 70 - -# Images -# -# - driver: Images driver (gd, imagick) -# -# - directory: Images directory. -# -# - watermarks.directory: Watermarks directory. -# -# - cache.enabled: Set to true to enable images caching. -# -# - cache.directory: Images cache directory. -# -# - presets: Group of presets for images processing. -images: - driver: gd - directory: '/uploads' - max_image_size: - width: 2000 - height: 2000 - watermarks: - directory: '/watermarks' - cache: - directory: '/images' - presets: [] # Session # @@ -698,15 +673,63 @@ images: # Standard PHP session configuration options # https://secure.php.net/manual/en/session.configuration.php session: + + # Session name name: Flextype # Flextype Rest APIs api: + + # Entries API entries: + + # Set to true to enable Entries API enabled: true + + # Registry API registry: + + # Set to true to enable Registry API enabled: true + + # Images API images: + + # Set to true to enable Images API enabled: true + + # Images driver (gd, imagick) + driver: gd + + # Images directory. + directory: '/uploads' + + # Images max size + max_image_size: + + # Image max width + width: 2000 + + # Image max height + height: 2000 + + # Images watermarks + watermarks: + + # Images watermarks directory + directory: '/watermarks' + + # Images cache + cache: + + # Images cache directory + directory: '/images' + + # Group of presets for images processing. + presets: [] + + # Utils API utils: + + # Set to true to enable Utils API enabled: true \ No newline at end of file From e1b18bca81014766291f1fdcd2ab6269e9d938c8 Mon Sep 17 00:00:00 2001 From: Awilum Date: Fri, 3 Sep 2021 13:36:15 +0300 Subject: [PATCH 30/51] feat(entries): typo doc updates --- src/flextype/core/Entries/Entries.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/flextype/core/Entries/Entries.php b/src/flextype/core/Entries/Entries.php index 81a352d5..885dfbb9 100755 --- a/src/flextype/core/Entries/Entries.php +++ b/src/flextype/core/Entries/Entries.php @@ -36,6 +36,8 @@ class Entries * Local entries registry used for storing current requested * entries data and allow to change them on fly. * + * @var Arrays + * * @access private */ private Arrays $registry; @@ -52,6 +54,7 @@ class Entries * actions - Array of actions for entries collection. * * @var array + * * @access private */ private array $options = []; From 3f5c9419a950a5296551e5b905291fd59f0fdf93 Mon Sep 17 00:00:00 2001 From: Awilum Date: Fri, 3 Sep 2021 13:48:57 +0300 Subject: [PATCH 31/51] feat(helpers): typo doc updates --- src/flextype/helpers/urls.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/flextype/helpers/urls.php b/src/flextype/helpers/urls.php index a0c62512..31a53195 100644 --- a/src/flextype/helpers/urls.php +++ b/src/flextype/helpers/urls.php @@ -83,7 +83,7 @@ if (! function_exists('getCurrentUrl')) { if (! function_exists('getBasePath')) { /** - * Get the base path + * Get the base path. * * @return string Base Path. */ @@ -95,7 +95,7 @@ if (! function_exists('getBasePath')) { if (! function_exists('setBasePath')) { /** - * Set the base path + * Set the base path. * * @param string $basePath Base path. * @@ -109,7 +109,7 @@ if (! function_exists('setBasePath')) { if (! function_exists('redirect')) { /** - * Redirect + * Redirect. * * @param string $routeName Route name * @param array $data Route placeholders From 907c990e56cfbe14f355b166cf03512d40716bf3 Mon Sep 17 00:00:00 2001 From: Awilum Date: Fri, 3 Sep 2021 13:49:12 +0300 Subject: [PATCH 32/51] update CHANGELOG.md --- CHANGELOG.md | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 86ab04f2..58d4d811 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,10 @@ * **entries**: Added new method `getOptions`. +* **entries**: Added new method `setOptions`. + +* **entries**: Added new method `setRegistry`. + * **entries**: Added ability to override logic for built-in custom fields. Example: @@ -214,7 +218,7 @@ * **helpers**: Added helper function `cache` to get Flextype Cache Service. -* **helpers**: Added helper function `content` to get Flextype Content Service. +* **helpers**: Added helper function `entries` to get Flextype Entries Service. * **helpers**: Added helper function `media` to get Flextype Media Service. @@ -230,11 +234,29 @@ * **helpers**: Added helper function `plugins` to get Flextype Plugins Service. -* **helpers**: Added helper function `image` to create a new image instance. +* **helpers**: Added helper function `imageFile` to create a new image instance for image file. * **helpers**: Added helper function `imageCanvas` to create a new image canvas instance. -* **helpers**: Added helper function `imageCache` to create a new cached image instance. +* **helpers**: Added helper function `token` to generate unique token. + +* **helpers**: Added helper function `tokenHash` to generate unique token hash. + +* **helpers**: Added helper function `tokenHashValidate` to validate token hash. + +* **helpers**: Added helper function `urlFor` to get url for a named route. + +* **helpers**: Added helper function `fullUrlFor` to get full url for a named route. + +* **helpers**: Added helper function `isCurrentUrl` to determine is current url equal to route name. + +* **helpers**: Added helper function `getCurrentUrl` to get current path on given Uri. + +* **helpers**: Added helper function `getBasePath` to get base path. + +* **helpers**: Added helper function `setBasePath` to set base path. + +* **helpers**: Added helper function `redirect` to create redirect. * **macros**: All core macros are located in the `/src/flextype/macros.php`. From 6c12a121183caf4f955fc8a7b13f2b5b7cacda29 Mon Sep 17 00:00:00 2001 From: Awilum Date: Fri, 3 Sep 2021 14:24:44 +0300 Subject: [PATCH 33/51] update CHANGELOG.md --- CHANGELOG.md | 136 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 119 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 58d4d811..d1b8d3d6 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,21 +3,23 @@ ### Features -* **core**: Core updated from Slim 3 to Slim4! +* **core**: Core updated from Slim 3 to Slim 4! See: [Upgrade Guide](https://www.slimframework.com/docs/v4/start/upgrade.html) * **core**: PHP-DI added instead of Pimple DI. + See: [Usage Guide](https://php-di.org/doc/frameworks/slim.html) + * **entries**: Added ability to create completely customizable high level collections for entries. - Example: https://github.com/flextype/flextype/issues/563#issuecomment-893507342 + Example: https://github.com/flextype/flextype/issues/563 -* **entries**: Added new method `getOptions`. +* **entries**: Added new method `getOptions` to get entries options. -* **entries**: Added new method `setOptions`. +* **entries**: Added new method `setOptions` to set entries options. -* **entries**: Added new method `setRegistry`. +* **entries**: Added new method `setRegistry` to set entries registry. * **entries**: Added ability to override logic for built-in custom fields. @@ -62,6 +64,46 @@ * **images** League Glide updated to Glide 2. +* **images** added ablity to define League Glide settings. + + ```yaml + api: + images: + + # Set to true to enable Images API + enabled: true + + # Images driver (gd, imagick) + driver: gd + + # Images directory. + directory: '/uploads' + + # Images max size + max_image_size: + + # Image max width + width: 2000 + + # Image max height + height: 2000 + + # Images watermarks + watermarks: + + # Images watermarks directory + directory: '/watermarks' + + # Images cache + cache: + + # Images cache directory + directory: '/images' + + # Group of presets for images processing. + presets: [] + ``` + * **csrf**: Added Atomastic CSRF protection for Cross Site Request Forgery protection by comparing provided token with session token to ensure request validity. * **serializers**: Added new serializer `Neon`. @@ -258,6 +300,67 @@ * **helpers**: Added helper function `redirect` to create redirect. +* **helpers**: Added helper function `upload` to upload files and process uloaded images. + +* **uploder**: Added Sirius Uploader for file upload. + + ```yaml + # Upload + upload: + + # Uploads directory + directory: '/uploads' + + # Overwrite existing files. + overwrite: true + + # Auto-confirm uploads. + autoconfirm: false + + # Prefixing uploads. + prefix: '' + + # Validation options + validation: + + # Allowed file extensions. + allowed_file_extensions: ['gif', 'jpg', 'jpeg', 'png', 'ico', 'webm', 'svg'] + + # Maximum file size. + max_file_size: '24M' + + # Image validation options + image: + + # Image maxiumum and minimum width + width: + max: 4920 + min: 100 + + # Image maxiumum and minimum height + height: + max: 3264 + min: 100 + + # Image ratio + #ratio: + # The option can be a number (eg: 1.3) or a ratio-like string (eg: 4:3, 16:9). + # size: 1.3 + + # The option error_margin specifies how much the image is allowed to + # deviate from the target ratio. Default value is 0. + # error_margin: 0 + + # Process uploaded files + process: + + # Images process settings + image: + + # Image quality + quality: 70 + ``` + * **macros**: All core macros are located in the `/src/flextype/macros.php`. * **macros**: Added `onlyFromCollection` and `exceptFromCollection` macros for Arrays ([#553](https://github.com/flextype/flextype/issues/553)) @@ -278,14 +381,13 @@ * **core** Use new helpers functions to access Flextype Services. - * use `content()` instead of `flextype('entries')` + * use `entries()` instead of `flextype('entries')` * use `session()` instead of `flextype('session')` * use `cache()` instead of `flextype('cache')` * use `app()` instead of `flextype()` * use `container()` instead of `flextype('container_name_here')` * use `parsers()` instead of `flextype('parsers')` * use `serializers()` instead of `flextype('serializers')` - * use `media()` instead of `flextype('media')` * use `plugins()` instead of `flextype('plugins')` * use `emitter()` instead of `flextype('emitter')` * use `logger()` instead of `flextype('logger')` @@ -295,26 +397,26 @@ * **core**: Use helper function `container` to access Flextype Application container instead of old helper function `flextype()` with container name argument. - * use `container()->get('content')` instead of `flextype('entries')` - * use `container()->set('content', new Content())` instead of `flextype()['content'] = new Content()` + * use `container()->get('entries')` instead of `flextype('entries')` + * use `container()->set('content', new Entries())` instead of `flextype()['entries'] = new Entries()` * **entries**: Don't use Entries API directly. Instead, you should use API's based on Entries API. e.g. built-in Content API, Media API, or create your own by extending Entries API. * **entries**: Project entries moved from `/project/entries/` to `/project/entries/content/`. -* **content**: Content API for content manipulations instead of base Entries API. +* **content**: Entries API for content manipulations instead of base Entries API. - * use `content()->fetch()` instead of `flextype('entries')->fetch()` - * use `content()->create()` instead of `flextype('entries')->create()` - * use `content()->delete()` instead of `flextype('entries')->delete()` + * use `entries()->fetch()` instead of `flextype('entries')->fetch()` + * use `entries()->create()` instead of `flextype('entries')->create()` + * use `entries()->delete()` instead of `flextype('entries')->delete()` etc... * **content**: Changes for content(prev. entries) memory storage. - * use `content()->registry()->get()` instead of `flextype('entries')->storage()->get()` - * use `content()->registry()->set()` instead of `flextype('entries')->storage()->set()` - * use `content()->registry()->has()` instead of `flextype('entries')->storage()->has()` - * use `content()->registry()->delete()` instead of `flextype('entries')->storage()->delete()` + * use `entries()->registry()->get()` instead of `flextype('entries')->storage()->get()` + * use `entries()->registry()->set()` instead of `flextype('entries')->storage()->set()` + * use `entries()->registry()->has()` instead of `flextype('entries')->storage()->has()` + * use `entries()->registry()->delete()` instead of `flextype('entries')->storage()->delete()` note: all method from Atomastic Arrays are available for Arrays Storage Object manipulations docs: https://github.com/atomastic/arrays From 28570412caf7f954632899cf3c6187872d0fc711 Mon Sep 17 00:00:00 2001 From: Awilum Date: Fri, 3 Sep 2021 14:41:12 +0300 Subject: [PATCH 34/51] update CHANGELOG.md --- CHANGELOG.md | 46 ++++++++++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d1b8d3d6..a72bc441 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,8 @@ Example: https://github.com/flextype/flextype/issues/563 +* **entries**: Added ability to set custom actions for each entries collections. + * **entries**: Added new method `getOptions` to get entries options. * **entries**: Added new method `setOptions` to set entries options. @@ -58,9 +60,22 @@ ... ``` -* **media**: Added new Media API based on core Entries API. +* **endpoints** All Rest API Endpoints codebase were rewritten from scratch. -* **content**: Added new Content API based on core Entries API. +* **endpoints** New Rest API Endpoint `/api/utils/cache/clear`. + + ``` + Clear cache + + endpoint: POST /api/utils/cache/clear + + Body: + token - [REQUIRED] - Valid public token. + access_token - [REQUIRED] - Valid access token. + + Returns: + Returns an empty body with HTTP status 204 + ``` * **images** League Glide updated to Glide 2. @@ -166,7 +181,7 @@ allowed: ['yaml', 'json', 'neon'] ``` -* **parsers**: Markdown parser [Commonmark updated to v2](https://commonmark.thephpleague.com/2.0/upgrading/). +* **parsers**: Markdown parser [Commonmark updated to v2](https://commonmark.thephpleague.com/2.0/upgrading/) * **parsers**: Added ability to set global settings for all parsers. @@ -379,7 +394,7 @@ ### BREAKING CHANGES -* **core** Use new helpers functions to access Flextype Services. +* **helpers** Use new helpers functions to access Flextype Services. * use `entries()` instead of `flextype('entries')` * use `session()` instead of `flextype('session')` @@ -393,25 +408,18 @@ * use `logger()` instead of `flextype('logger')` * use `registry()` instead of `flextype('registry')` -* **core**: Use helper function `app` to access Flextype Application instance instead of old helper function `flextype()`. +* **helpers**: Use helper function `app` to access Flextype Application instance instead of old helper function `flextype()`. -* **core**: Use helper function `container` to access Flextype Application container instead of old helper function `flextype()` with container name argument. +* **helpers**: Use helper function `container` to access Flextype Application container instead of old helper function `flextype()` with container name argument. * use `container()->get('entries')` instead of `flextype('entries')` * use `container()->set('content', new Entries())` instead of `flextype()['entries'] = new Entries()` -* **entries**: Don't use Entries API directly. Instead, you should use API's based on Entries API. e.g. built-in Content API, Media API, or create your own by extending Entries API. +* **helpers**: Use helper function `filterCollection` instead of old `filter`. -* **entries**: Project entries moved from `/project/entries/` to `/project/entries/content/`. +* **tokens**: Project tokens moved from `/project/tokens/` to `/project/entries/tokens/`. -* **content**: Entries API for content manipulations instead of base Entries API. - - * use `entries()->fetch()` instead of `flextype('entries')->fetch()` - * use `entries()->create()` instead of `flextype('entries')->create()` - * use `entries()->delete()` instead of `flextype('entries')->delete()` - etc... - -* **content**: Changes for content(prev. entries) memory storage. +* **entries**: Changes for etnries memory storage. * use `entries()->registry()->get()` instead of `flextype('entries')->storage()->get()` * use `entries()->registry()->set()` instead of `flextype('entries')->storage()->set()` @@ -421,6 +429,12 @@ note: all method from Atomastic Arrays are available for Arrays Storage Object manipulations docs: https://github.com/atomastic/arrays +### Refactoring + +* **core**: general code refactoring and improvements. + +* **tests**: All unit tests were rewritten. + # [0.9.16](https://github.com/flextype/flextype/compare/v0.9.15...v0.9.16) (2021-01-14) From d6371d668f9b6d1501d379af71aaaf2ec65427f4 Mon Sep 17 00:00:00 2001 From: Awilum Date: Fri, 3 Sep 2021 14:43:21 +0300 Subject: [PATCH 35/51] update CHANGELOG.md --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a72bc441..ad000734 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -265,7 +265,7 @@ * **cache**: Added new cache driver `Phparray` to storage cache data in raw php arrays files. -* **helpers**: All core helpers are located in the `/src/flextype/helpers.php`. +* **helpers**: All core helpers are located in the `/src/flextype/helpers/`. * **helpers**: Added helper function `app` to get Flextype Application instance. @@ -376,7 +376,7 @@ quality: 70 ``` -* **macros**: All core macros are located in the `/src/flextype/macros.php`. +* **macros**: All core macros are located in the `/src/flextype/macros/`. * **macros**: Added `onlyFromCollection` and `exceptFromCollection` macros for Arrays ([#553](https://github.com/flextype/flextype/issues/553)) From 702cee94f7d2aba1da1a869976e2bc3c7b6282be Mon Sep 17 00:00:00 2001 From: Awilum Date: Fri, 3 Sep 2021 19:45:24 +0300 Subject: [PATCH 36/51] feat(settings): update settings --- src/flextype/settings.yaml | 183 ++++++++++++++++++++----------------- 1 file changed, 99 insertions(+), 84 deletions(-) diff --git a/src/flextype/settings.yaml b/src/flextype/settings.yaml index 7da27c9b..92f81a49 100644 --- a/src/flextype/settings.yaml +++ b/src/flextype/settings.yaml @@ -23,18 +23,18 @@ url: '/flextype' # Valid date format # -# - date_format: Valid date format -# -# - date_display_format: Valid date format to display -# # Date format variants: # -# d-m-Y H:i" - 02-02-2020 09:41 -# Y-m-d H:i" - 2020-02-02 09:41 -# m/d/Y h:i a - 02/02/2020 09:41 pm -# H:i d-m-Y - 09:41 02-02-2020 -# h:i a m/d/Y - 09:41 pm 02/02/2020 +# d-m-Y H:i" - 02-02-2020 09:41 +# Y-m-d H:i" - 2020-02-02 09:41 +# m/d/Y h:i a - 02/02/2020 09:41 pm +# H:i d-m-Y - 09:41 02-02-2020 +# h:i a m/d/Y - 09:41 pm 02/02/2020 + +# Valid date format date_format: 'd-m-Y H:i' + +# Valid date format to display date_display_format: 'd-m-Y H:i' # Display errors @@ -48,9 +48,9 @@ date_display_format: 'd-m-Y H:i' # - Detailed error messages for login failures could leak information to attackers # # In a production environment, always log errors to your PHP error logs. -# -# - display: Display errors or not. errors: + + # Set true to display errors. display: true # Entries @@ -420,35 +420,37 @@ determine_route_before_app_middleware: false output_buffering: append # Slugify -# -# - separator: By default Slugify will use dashes as separators. -# If you want to use a different default separator, -# you can set the separator option. -# -# - lowercase: By default Slugify will convert the slug to lowercase. -# If you want to preserve the case of the string you can set the -# lowercase option to false. -# -# - trim: By default Slugify will remove leading and trailing separators before -# returning the slug. If you do not want the slug to be trimmed you can -# set the trim option to false. -# -# - regexp: You can also change the regular expression that is used to replace -# characters with the separator. -# -# - lowercase_after_regexp: Lowercasing is done before using the regular expression. -# If you want to keep the lowercasing behavior but your -# regular expression needs to match uppercase letters, -# you can set the lowercase_after_regexp option to true. -# -# - strip_tags: Adds in an option to go through strip_tags() in case the string contains HTML etc. slugify: + + # Set true to enable slugify. enabled: true + + # By default Slugify will use dashes as separators. + # If you want to use a different default separator, + # you can set the separator option. separator: "-" + + # By default Slugify will convert the slug to lowercase. + # If you want to preserve the case of the string you can set the + # lowercase option to false. lowercase: true + + # By default Slugify will remove leading and trailing separators before + # returning the slug. If you do not want the slug to be trimmed you can + # set the trim option to false. trim: true + + # You can also change the regular expression that is used to replace + # characters with the separator. regexp: "/[^A-Za-z0-9]+/" + + # Lowercasing is done before using the regular expression. + # If you want to keep the lowercasing behavior but your + # regular expression needs to match uppercase letters, + # you can set the lowercase_after_regexp option to true. lowercase_after_regexp: false + + # Adds in an option to go through strip_tags() in case the string contains HTML etc. strip_tags: false # Serializers @@ -588,83 +590,96 @@ parsers: # CORS (Cross-origin resource sharing) allows JavaScript web apps to make HTTP requests to other domains. # This is important for third party web apps using Flextype, as without CORS, a JavaScript app hosted on example.com # couldn't access our APIs because they're hosted on another.com which is a different domain. -# -# - enabled: Set to true to enable cors -# -# - origin: The Access-Control-Allow-Origin response header indicates whether -# the response can be shared with requesting code from the given origin. -# read more: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin -# -# - headers: The Access-Control-Allow-Headers response header is used in response -# to a preflight request which includes the Access-Control-Request-Headers -# to indicate which HTTP headers can be used during the actual request. -# read more: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers -# -# - methods: The Access-Control-Allow-Methods response header specifies the method -# or methods allowed when accessing the resource in response to a preflight request. -# read more: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Methods -# -# - expose: The Access-Control-Expose-Headers response header indicates which headers -# can be exposed as part of the response by listing their names. -# read more: https://developer.mozilla.org/ru/docs/Web/HTTP/Headers/Access-Control-Expose-Headers -# -# - credentials: The Access-Control-Allow-Credentials response header tells browsers whether -# to expose the response to frontend JavaScript code when the request's credentials -# mode (Request.credentials) is include. -# read more: https://developer.mozilla.org/ru/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials cors: + + # Set to true to enable cors enabled: true + + # The Access-Control-Allow-Origin response header indicates whether + # the response can be shared with requesting code from the given origin. + # + # read more: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin origin: "*" + + # The Access-Control-Allow-Headers response header is used in response + # to a preflight request which includes the Access-Control-Request-Headers + # to indicate which HTTP headers can be used during the actual request. + # + # read more: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers headers: ["X-Requested-With", "Content-Type", "Accept", "Origin", "Authorization"] + + # The Access-Control-Allow-Methods response header specifies the method + # or methods allowed when accessing the resource in response to a preflight request. + # + # read more: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Methods methods: [GET, POST, PUT, DELETE, PATCH, OPTIONS] + + # The Access-Control-Expose-Headers response header indicates which headers + # can be exposed as part of the response by listing their names. + # + # read more: https://developer.mozilla.org/ru/docs/Web/HTTP/Headers/Access-Control-Expose-Headers expose: [] + + # The Access-Control-Allow-Credentials response header tells browsers whether + # to expose the response to frontend JavaScript code when the request's credentials + # mode (Request.credentials) is include. + # + # read more: https://developer.mozilla.org/ru/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials credentials: false # Upload -# -# - directory: Uploads directory -# -# - overwrite: Overwrite existing files. -# -# - autoconfirm: Auto-confirm uploads. -# -# - prefix: Prefixing uploads. -# -# - validation.allowed_file_extensions: Allowed file extensions. -# -# - validation.max_file_size: Maximum file size. -# -# - validation.image.width.max: Image maxiumum width. -# -# - validation.image.width.min: Image minimum width. -# -# - validation.image.height.max: Image maxiumum height. -# -# - validation.image.height.min: Image minimum height. -# -# - validation.image.ratio.size: The option can be a number (eg: 1.3) or a ratio-like string (eg: 4:3, 16:9). -# -# - 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. -# -# - process.image.quality: upload: + + # Uploads directory directory: '/uploads' + + # Overwrite existing files. overwrite: true + + # Auto-confirm uploads. autoconfirm: false + + # Prefixing uploads. prefix: '' + + # Validation options validation: + + # Allowed file extensions. allowed_file_extensions: ['gif', 'jpg', 'jpeg', 'png', 'ico', 'webm', 'svg'] + + # Maximum file size. max_file_size: '24M' + + # Image validation options image: + + # Image maxiumum and minimum width width: max: 4920 min: 100 + + # Image maxiumum and minimum height height: max: 3264 min: 100 + + # Image ratio + #ratio: + # The option can be a number (eg: 1.3) or a ratio-like string (eg: 4:3, 16:9). + # size: 1.3 + + # The option error_margin specifies how much the image is allowed to + # deviate from the target ratio. Default value is 0. + # error_margin: 0 + + # Process uploaded files process: + + # Images process settings image: + + # Image quality quality: 70 # Session From 50f1b44dbc75fe6eff5610319e248696cb82cf36 Mon Sep 17 00:00:00 2001 From: Awilum Date: Fri, 3 Sep 2021 20:05:17 +0300 Subject: [PATCH 37/51] feat(composer): update dependencies --- composer.json | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 67a60654..56abadb4 100755 --- a/composer.json +++ b/composer.json @@ -33,7 +33,6 @@ "atomastic/strings": "^3.0.2", "atomastic/macroable": "^2.0.0", "atomastic/csrf": "^1.0.1", - "atomastic/view": "dev-dev", "slim/slim": "^4.8.1", @@ -47,9 +46,9 @@ "respect/validation": "^2.2.3", "monolog/monolog": "^2.3.2", "cocur/slugify": "^4.0.0", - "ramsey/uuid": "^4.1.1", + "ramsey/uuid": "^4.2.1", "symfony/yaml": "^5.3.6", - "symfony/finder": "^5.3.4", + "symfony/finder": "^5.3.7", "thunderer/shortcode": "^0.7.4", From 578ddbe830ec452c18dea038c8db132c93f4a4ea Mon Sep 17 00:00:00 2001 From: Awilum Date: Fri, 3 Sep 2021 22:27:21 +0300 Subject: [PATCH 38/51] feat(core): add new code base for Whoops Error handling with updated settings --- composer.json | 7 +- .../core/Middlewares/WhoopsMiddleware.php | 50 +++++++ src/flextype/core/WhoopsGuard.php | 141 ++++++++++++++++++ src/flextype/flextype.php | 38 +++-- src/flextype/settings.yaml | 24 ++- 5 files changed, 220 insertions(+), 40 deletions(-) create mode 100644 src/flextype/core/Middlewares/WhoopsMiddleware.php create mode 100644 src/flextype/core/WhoopsGuard.php diff --git a/composer.json b/composer.json index 56abadb4..c80efba8 100755 --- a/composer.json +++ b/composer.json @@ -36,8 +36,6 @@ "slim/slim": "^4.8.1", - "filp/whoops": "^2.14", - "league/event": "^2.2.0", "league/glide": "^2.0.0", @@ -56,10 +54,11 @@ "slim/psr7": "^1.4", "php-di/php-di": "^6.3.4", "php-di/slim-bridge": "^3.1.1", - "middlewares/whoops": "^2.0", "nette/neon": "^3.2", "league/commonmark": "^2.0", - "siriusphp/upload": "^3.0" + "siriusphp/upload": "^3.0", + + "filp/whoops": "^2.14" }, "suggest": { "ext-zend-opcache": "Recommended for better performance", diff --git a/src/flextype/core/Middlewares/WhoopsMiddleware.php b/src/flextype/core/Middlewares/WhoopsMiddleware.php new file mode 100644 index 00000000..b07492b6 --- /dev/null +++ b/src/flextype/core/Middlewares/WhoopsMiddleware.php @@ -0,0 +1,50 @@ +settings = $settings; + $this->handlers = $handlers; + } + + /** + * Handle the requests + * + * @param ServerRequestInterface $request + * @param RequestHandlerInterface $handler + * @return ResponseInterface + */ + public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface { + $whoopsGuard = new WhoopsGuard($this->settings); + $whoopsGuard->setRequest($request); + $whoopsGuard->setHandlers($this->handlers); + $whoopsGuard->install(); + + return $handler->handle($request); + } + +} \ No newline at end of file diff --git a/src/flextype/core/WhoopsGuard.php b/src/flextype/core/WhoopsGuard.php new file mode 100644 index 00000000..92033dde --- /dev/null +++ b/src/flextype/core/WhoopsGuard.php @@ -0,0 +1,141 @@ +settings = array_merge([ + 'enable' => true, + 'editor' => '', + 'title' => '', + ], $settings); + } + + /** + * Set the server request object + * + * @param ServerRequestInterface $request + * @return void + */ + public function setRequest(ServerRequestInterface $request): void { + $this->request = $request; + } + + /** + * Set the custom handlers for whoops + * + * @param array $handlers + * @return void + */ + public function setHandlers(array $handlers): void { + $this->handlers = $handlers; + } + + /** + * Install the whoops guard object + * + * @return WhoopsRun|null + */ + public function install(): ?WhoopsRun { + if ($this->settings['enable'] === false) { + return null; + } + + // Enable PrettyPageHandler with editor options + $prettyPageHandler = new PrettyPageHandler(); + + if (empty($this->settings['editor']) === false) { + $prettyPageHandler->setEditor($this->settings['editor']); + } + + if (empty($this->settings['title']) === false) { + $prettyPageHandler->setPageTitle($this->settings['title']); + } + + // Add more information to the PrettyPageHandler + $contentCharset = ''; + if ( + method_exists($this->request, 'getContentCharset') === true && + $this->request->getContentCharset() !== null + ) { + $contentCharset = $this->request->getContentCharset(); + } + + $prettyPageHandler->addDataTable('Flextype', [ + 'Version' => Flextype::VERSION, + 'Accept Charset' => $this->request->getHeader('ACCEPT_CHARSET') ?: '', + 'Content Charset' => $contentCharset, + 'HTTP Method' => $this->request->getMethod(), + 'Path' => $this->request->getUri()->getPath(), + 'Query String' => $this->request->getUri()->getQuery() ?: '', + 'Base URL' => (string) $this->request->getUri(), + 'Scheme' => $this->request->getUri()->getScheme(), + 'Port' => $this->request->getUri()->getPort(), + 'Host' => $this->request->getUri()->getHost(), + ]); + + // Set Whoops to default exception handler + $whoops = new \Whoops\Run; + + switch ($this->settings['handler']) { + case 'json': + $whoops->pushHandler(new JsonResponseHandler()); + break; + + case 'xml': + $whoops->pushHandler(new XmlResponseHandler()); + break; + + case 'plain': + $whoops->pushHandler(new PlainTextHandler()); + break; + + case 'pretty': + default: + $whoops->pushHandler($prettyPageHandler); + break; + } + + // Enable JsonResponseHandler when request is AJAX + if (Misc::isAjaxRequest() === true){ + $whoops->pushHandler(new JsonResponseHandler()); + } + + // Add each custom handler to whoops handler stack + if (empty($this->handlers) === false) { + foreach($this->handlers as $handler) { + $whoops->pushHandler($handler); + } + } + + $whoops->register(); + + return $whoops; + } + +} \ No newline at end of file diff --git a/src/flextype/flextype.php b/src/flextype/flextype.php index ae2a2e13..e343d07d 100644 --- a/src/flextype/flextype.php +++ b/src/flextype/flextype.php @@ -16,7 +16,6 @@ use DateTimeZone; use Flextype\Entries\Entries; use Flextype\Handlers\HttpErrorHandler; use Flextype\Handlers\ShutdownHandler; -use Flextype\Media\Media; use Flextype\Parsers\Parsers; use Flextype\Serializers\Serializers; use Flextype\Tokens\Tokens; @@ -57,6 +56,7 @@ use Slim\Psr7\Factory\StreamFactory; use Slim\Psr7\Response; use Slim\Psr7\Stream; use Symfony\Component\Yaml\Yaml as SymfonyYaml; +use Flextype\Middlewares\WhoopsMiddleware; use function app; use function array_replace_recursive; @@ -87,11 +87,11 @@ use function sys_get_temp_dir; use function trim; use function var_export; -// Init Flextype Instance -// Creates $app Application and $container Container objects +// Init Flextype Instance. +// Creates $app Application and $container Container objects. flextype(); -// Add Registry Service +// Add Registry Service. container()->set('registry', registry()); // Init Flextype config (manifest and settings) @@ -108,7 +108,7 @@ $f1 = file_exists($flextypeManifestFilePath) ? filemtime($flextypeManifestFilePa $f2 = file_exists($defaultFlextypeSettingsFilePath) ? filemtime($defaultFlextypeSettingsFilePath) : ''; $f3 = file_exists($customFlextypeSettingsFilePath) ? filemtime($customFlextypeSettingsFilePath) : ''; -// Create Unique Cache ID +// Create Unique Cache ID. $cacheID = md5($flextypeManifestFilePath . $defaultFlextypeSettingsFilePath . $customFlextypeSettingsFilePath . $f1 . $f2 . $f3); if (filesystem()->file($preflightFlextypePath . '/' . $cacheID . '.php')->exists()) { @@ -194,15 +194,6 @@ if (registry()->get('flextype.settings.cache.routes')) { app()->getRouteCollector()->setCacheFile(PATH['tmp'] . '/routes/routes.php'); } -$callableResolver = app()->getCallableResolver(); -$responseFactory = app()->getResponseFactory(); -$serverRequestCreator = ServerRequestCreatorFactory::create(); -$request = $serverRequestCreator->createServerRequestFromGlobals(); - -$errorHandler = new HttpErrorHandler($callableResolver, $responseFactory); -$shutdownHandler = new ShutdownHandler($request, $errorHandler, registry()->get('flextype.settings.errors.display')); -register_shutdown_function($shutdownHandler); - // Add Session Service container()->set('session', new Session()); @@ -216,8 +207,8 @@ container()->set('emitter', new Emitter()); container()->set('slugify', new Slugify([ 'separator' => registry()->get('flextype.settings.slugify.separator'), 'lowercase' => registry()->get('flextype.settings.slugify.lowercase'), - 'trim' => registry()->get('flextype.settings.slugify.trim'), - 'regexp' => registry()->get('flextype.settings.slugify.regexp'), + 'trim' => registry()->get('flextype.settings.slugify.trim'), + 'regexp' => registry()->get('flextype.settings.slugify.regexp'), 'lowercase_after_regexp' => registry()->get('flextype.settings.slugify.lowercase_after_regexp'), 'strip_tags' => registry()->get('flextype.settings.slugify.strip_tags'), ])); @@ -395,8 +386,8 @@ container()->set('images', static function () { // Setup Glide server $server = ServerFactory::create([ 'source' => $source, - 'cache' => $cache, - 'api' => $api, + 'cache' => $cache, + 'api' => $api, ]); // Set presets @@ -482,11 +473,16 @@ if (registry()->get('flextype.settings.cors.enabled')) { // Add Routing Middleware app()->addRoutingMiddleware(); -// Add Error Handling Middleware -app()->addErrorMiddleware(registry()->get('flextype.settings.errors.display'), false, false)->setDefaultErrorHandler($errorHandler); - // Run high priority event: onFlextypeBeforeRun before Flextype Application starts. emitter()->emit('onFlextypeBeforeRun'); +// Add Whoops Error Handling Middleware +app()->add(new WhoopsMiddleware([ + 'enable' => registry()->get('flextype.settings.errors.display'), + 'editor' => registry()->get('flextype.settings.errors.editor'), + 'title' => registry()->get('flextype.settings.errors.page_title'), + 'handler' => registry()->get('flextype.settings.errors.handler'), +])); + // Run Flextype Application app()->run(); diff --git a/src/flextype/settings.yaml b/src/flextype/settings.yaml index 92f81a49..2da8e8b1 100644 --- a/src/flextype/settings.yaml +++ b/src/flextype/settings.yaml @@ -53,6 +53,15 @@ errors: # Set true to display errors. display: true + # Editor (emacs, idea, macvim, phpstorm, sublime, textmate, xdebug, vscode, atom, espresso) + editor: atom + + # Error page title + page_title: Error! + + # Handler (pretty, plain, json, xml) + handler: pretty + # Entries entries: directory: '/entries' @@ -379,22 +388,8 @@ cache: zenddisk: {} zendshm: {} -# Whoops -# -# Error handler framework for PHP. -# -# - editor: emacs, idea, macvim, phpstorm, sublime, textmate, xdebug, vscode, atom, espresso -# -# - page_title: page title -whoops: - editor: atom - page_title: Error! - # Slim # -# - display_error_details: When true, additional information about exceptions are -# displayed by the default error handler. -# # - add_content_length_header: When true, Slim will add a Content-Length header to # the response. If you are using a runtime analytics tool, # such as New Relic, then this should be disabled. @@ -413,7 +408,6 @@ whoops: # If 'append' or 'prepend', then any echo or print statements # are captured and are either appended or prepended to the Response # returned from the route callable. -display_error_details: true add_content_length_header: true router_cache_file: false determine_route_before_app_middleware: false From cb376e793a3d222c1a75cf47fdf57e23afce5070 Mon Sep 17 00:00:00 2001 From: Awilum Date: Fri, 3 Sep 2021 22:36:47 +0300 Subject: [PATCH 39/51] feat(core): add new code base for Whoops Error handling with updated settings --- .../core/Middlewares/WhoopsMiddleware.php | 9 +- src/flextype/core/WhoopsGuard.php | 86 ++++++++++--------- 2 files changed, 51 insertions(+), 44 deletions(-) diff --git a/src/flextype/core/Middlewares/WhoopsMiddleware.php b/src/flextype/core/Middlewares/WhoopsMiddleware.php index b07492b6..d69db7a9 100644 --- a/src/flextype/core/Middlewares/WhoopsMiddleware.php +++ b/src/flextype/core/Middlewares/WhoopsMiddleware.php @@ -15,7 +15,8 @@ use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ResponseInterface; use Flextype\WhoopsGuard; -class WhoopsMiddleware implements MiddlewareInterface { +class WhoopsMiddleware implements MiddlewareInterface +{ protected $settings = []; protected $handlers = []; @@ -26,7 +27,8 @@ class WhoopsMiddleware implements MiddlewareInterface { * @param array $settings * @param array $handlers */ - public function __construct(array $settings = [], array $handlers = []) { + public function __construct(array $settings = [], array $handlers = []) + { $this->settings = $settings; $this->handlers = $handlers; } @@ -38,7 +40,8 @@ class WhoopsMiddleware implements MiddlewareInterface { * @param RequestHandlerInterface $handler * @return ResponseInterface */ - public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface { + public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface + { $whoopsGuard = new WhoopsGuard($this->settings); $whoopsGuard->setRequest($request); $whoopsGuard->setHandlers($this->handlers); diff --git a/src/flextype/core/WhoopsGuard.php b/src/flextype/core/WhoopsGuard.php index 92033dde..1c293654 100644 --- a/src/flextype/core/WhoopsGuard.php +++ b/src/flextype/core/WhoopsGuard.php @@ -17,7 +17,8 @@ use Whoops\Handler\PlainTextHandler; use Whoops\Handler\JsonResponseHandler; use Whoops\Handler\XmlResponseHandler; -class WhoopsGuard { +class WhoopsGuard +{ protected $settings = []; protected $request = null; @@ -28,11 +29,13 @@ class WhoopsGuard { * * @param array $settings */ - public function __construct(array $settings = []) { + public function __construct(array $settings = []) + { $this->settings = array_merge([ 'enable' => true, - 'editor' => '', - 'title' => '', + 'editor' => 'vscode', + 'title' => 'Error!', + 'hadler' => 'plain' ], $settings); } @@ -42,7 +45,8 @@ class WhoopsGuard { * @param ServerRequestInterface $request * @return void */ - public function setRequest(ServerRequestInterface $request): void { + public function setRequest(ServerRequestInterface $request): void + { $this->request = $request; } @@ -52,7 +56,8 @@ class WhoopsGuard { * @param array $handlers * @return void */ - public function setHandlers(array $handlers): void { + public function setHandlers(array $handlers): void + { $this->handlers = $handlers; } @@ -61,44 +66,12 @@ class WhoopsGuard { * * @return WhoopsRun|null */ - public function install(): ?WhoopsRun { + public function install(): ?WhoopsRun + { if ($this->settings['enable'] === false) { return null; } - // Enable PrettyPageHandler with editor options - $prettyPageHandler = new PrettyPageHandler(); - - if (empty($this->settings['editor']) === false) { - $prettyPageHandler->setEditor($this->settings['editor']); - } - - if (empty($this->settings['title']) === false) { - $prettyPageHandler->setPageTitle($this->settings['title']); - } - - // Add more information to the PrettyPageHandler - $contentCharset = ''; - if ( - method_exists($this->request, 'getContentCharset') === true && - $this->request->getContentCharset() !== null - ) { - $contentCharset = $this->request->getContentCharset(); - } - - $prettyPageHandler->addDataTable('Flextype', [ - 'Version' => Flextype::VERSION, - 'Accept Charset' => $this->request->getHeader('ACCEPT_CHARSET') ?: '', - 'Content Charset' => $contentCharset, - 'HTTP Method' => $this->request->getMethod(), - 'Path' => $this->request->getUri()->getPath(), - 'Query String' => $this->request->getUri()->getQuery() ?: '', - 'Base URL' => (string) $this->request->getUri(), - 'Scheme' => $this->request->getUri()->getScheme(), - 'Port' => $this->request->getUri()->getPort(), - 'Host' => $this->request->getUri()->getHost(), - ]); - // Set Whoops to default exception handler $whoops = new \Whoops\Run; @@ -117,6 +90,38 @@ class WhoopsGuard { case 'pretty': default: + $prettyPageHandler = new PrettyPageHandler(); + + if (empty($this->settings['editor']) === false) { + $prettyPageHandler->setEditor($this->settings['editor']); + } + + if (empty($this->settings['title']) === false) { + $prettyPageHandler->setPageTitle($this->settings['title']); + } + + // Add more information to the PrettyPageHandler + $contentCharset = ''; + if ( + method_exists($this->request, 'getContentCharset') === true && + $this->request->getContentCharset() !== null + ) { + $contentCharset = $this->request->getContentCharset(); + } + + $prettyPageHandler->addDataTable('Flextype', [ + 'Version' => Flextype::VERSION, + 'Accept Charset' => $this->request->getHeader('ACCEPT_CHARSET') ?: '', + 'Content Charset' => $contentCharset, + 'HTTP Method' => $this->request->getMethod(), + 'Path' => $this->request->getUri()->getPath(), + 'Query String' => $this->request->getUri()->getQuery() ?: '', + 'Base URL' => (string) $this->request->getUri(), + 'Scheme' => $this->request->getUri()->getScheme(), + 'Port' => $this->request->getUri()->getPort(), + 'Host' => $this->request->getUri()->getHost(), + ]); + $whoops->pushHandler($prettyPageHandler); break; } @@ -137,5 +142,4 @@ class WhoopsGuard { return $whoops; } - } \ No newline at end of file From b667d755865e49cd81876a4cf53cf0160b992116 Mon Sep 17 00:00:00 2001 From: Awilum Date: Sat, 4 Sep 2021 14:07:41 +0300 Subject: [PATCH 40/51] feat(core): new `base_path` option instead of old `url` to define app base path. --- src/flextype/flextype.php | 4 ++-- src/flextype/settings.yaml | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/flextype/flextype.php b/src/flextype/flextype.php index e343d07d..c657c633 100644 --- a/src/flextype/flextype.php +++ b/src/flextype/flextype.php @@ -161,8 +161,8 @@ if (filesystem()->file($preflightFlextypePath . '/' . $cacheID . '.php')->exists // Store flextype merged data in the flextype registry. registry()->set('flextype', $flextypeData); -// Set Flextype base path -setBasePath(registry()->get('flextype.settings.url')); +// Set Flextype Aplication base path +setBasePath(registry()->get('flextype.settings.base_path')); // Add Routing Middleware app()->add(new RoutingMiddleware(app()->getRouteResolver(), app()->getRouteCollector()->getRouteParser())); diff --git a/src/flextype/settings.yaml b/src/flextype/settings.yaml index 2da8e8b1..4287c93d 100644 --- a/src/flextype/settings.yaml +++ b/src/flextype/settings.yaml @@ -16,10 +16,10 @@ charset: UTF-8 # Available locales to use: src/flextype/config/locales.yaml locale: en_US -# Application URL +# Application Base Path # -# Define custom application url -url: '/flextype' +# Define application base path +base_path: '/flextype' # Valid date format # From ca0324ab676bca9914f83239d63008442c2427d6 Mon Sep 17 00:00:00 2001 From: Awilum Date: Sat, 4 Sep 2021 19:21:57 +0300 Subject: [PATCH 41/51] feat(settings): add new settings option `base_url` --- src/flextype/settings.yaml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/flextype/settings.yaml b/src/flextype/settings.yaml index 4287c93d..de43cc05 100644 --- a/src/flextype/settings.yaml +++ b/src/flextype/settings.yaml @@ -16,9 +16,14 @@ charset: UTF-8 # Available locales to use: src/flextype/config/locales.yaml locale: en_US +# Application Base url +# +# Define application base url +base_url: '' + # Application Base Path # -# Define application base path +# Define application base path if application located in subdirectory base_path: '/flextype' # Valid date format From c7f20711f755f622a8ea1fa4fdb0b5936f25651e Mon Sep 17 00:00:00 2001 From: Awilum Date: Sat, 4 Sep 2021 19:22:34 +0300 Subject: [PATCH 42/51] feat(helpers): add new helper function `getAbsoluteUrl` and ``getBaseUrl --- src/flextype/helpers/urls.php | 85 +++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/src/flextype/helpers/urls.php b/src/flextype/helpers/urls.php index 31a53195..60bdcef4 100644 --- a/src/flextype/helpers/urls.php +++ b/src/flextype/helpers/urls.php @@ -107,6 +107,91 @@ if (! function_exists('setBasePath')) { } } +if (! function_exists('getBaseUrl')) { + /** + * Get the application base url. + * + * @return string Application base url. + */ + function getBaseUrl(): string + { + $baseUrl = registry()->get('flextype.settings.base_url') ?? ''; + $basePath = registry()->get('flextype.settings.base_path') ?? ''; + + if ($baseUrl != '') { + return $baseUrl . $basePath; + } + + $getAuth = static function (): string { + $result = ''; + if ($user = $_SERVER['PHP_AUTH_USER'] ?? '') { + $result .= $user; + + if ($password = $_SERVER['PHP_AUTH_PW'] ?? '') { + $result .= ':' . $password; + } + + $result .= '@'; + } + + return $result; + }; + + $isHttps = static function (): bool { + if (array_key_exists('HTTPS', $_SERVER)) { + return !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off'; + } + + return false; + }; + + $url = ''; + + $isHttps = $isHttps(); + + $url .= $getAuth(); + + $serverData = arrays($_SERVER); + + $host = (string) $serverData->get('HTTP_HOST'); + $port = (int) $serverData->get('SERVER_PORT'); + $url .= str_replace(':' . $port, '', $host); + + if ($isHttps && $port !== 443) { + $url .= $port ? ":{$port}" : ''; + } elseif (!$isHttps && $port !== 80) { + $url .= $port ? ":{$port}" : ''; + } + + if ($url) { + if ($isHttps) { + $url = 'https://' . $url; + } else { + $url = 'http://' . $url; + } + } + + $url .= $basePath; + + return $url; + } +} + +if (! function_exists('getAbsoluteUrl')) { + /** + * Get the application absolute url. + * + * @return string Application absolute url. + */ + function getAbsoluteUrl(): string + { + $url = getBaseUrl(); + $url .= $_SERVER['REQUEST_URI']; + + return $url; + } +} + if (! function_exists('redirect')) { /** * Redirect. From a27f69a667594b9be4311bad5617b55e98aacdad Mon Sep 17 00:00:00 2001 From: Awilum Date: Sun, 5 Sep 2021 18:09:28 +0300 Subject: [PATCH 43/51] feat(entries): use options directory for `getCacheID` method --- src/flextype/core/Entries/Entries.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/flextype/core/Entries/Entries.php b/src/flextype/core/Entries/Entries.php index 885dfbb9..e46445d0 100755 --- a/src/flextype/core/Entries/Entries.php +++ b/src/flextype/core/Entries/Entries.php @@ -599,10 +599,10 @@ class Entries $entryFile = $this->getFileLocation($id); if (filesystem()->file($entryFile)->exists()) { - return strings('entry' . $entryFile . (filesystem()->file($entryFile)->lastModified() ?: ''))->hash()->toString(); + return strings($this->options['directory'] . $entryFile . (filesystem()->file($entryFile)->lastModified() ?: ''))->hash()->toString(); } - return strings('entry' . $entryFile)->hash()->toString(); + return strings($this->options['directory'] . $entryFile)->hash()->toString(); } /** From 6e871cedfc0753bf58e901e148bd8b996e3ff23e Mon Sep 17 00:00:00 2001 From: Awilum Date: Wed, 8 Sep 2021 17:07:13 +0300 Subject: [PATCH 44/51] feat(images): remove Glide and images resize on demand to avoid image resize attack on production. #574 --- composer.json | 2 +- src/flextype/core/Endpoints/Images.php | 51 -------------- src/flextype/flextype.php | 88 ------------------------ src/flextype/helpers/services.php | 10 --- src/flextype/routes/endpoints/images.php | 30 -------- 5 files changed, 1 insertion(+), 180 deletions(-) delete mode 100644 src/flextype/core/Endpoints/Images.php delete mode 100644 src/flextype/routes/endpoints/images.php diff --git a/composer.json b/composer.json index c80efba8..7ec73d86 100755 --- a/composer.json +++ b/composer.json @@ -37,7 +37,7 @@ "slim/slim": "^4.8.1", "league/event": "^2.2.0", - "league/glide": "^2.0.0", + "intervention/image": "^2.6.1", "phpfastcache/phpfastcache": "^8.0.6", diff --git a/src/flextype/core/Endpoints/Images.php b/src/flextype/core/Endpoints/Images.php deleted file mode 100644 index 9a1e7cf1..00000000 --- a/src/flextype/core/Endpoints/Images.php +++ /dev/null @@ -1,51 +0,0 @@ -validateApiRequest([ - 'request' => $request, - 'api' => 'images', - 'params' => ['token'], - ])) > 0 - ) { - return $this->getApiResponse($response, $this->getStatusCodeMessage($result['http_status_code']), $result['http_status_code']); - } - - // Determine if the image file exists - if (! filesystem()->file(flextype()->registry()->get('flextype.settings.images.directory') . '/' . $path)->exists()) { - return $this->getApiResponse($response, $this->getStatusCodeMessage(404), 404); - } - - // Return image response - return images()->getImageResponse($path, $request->getQueryParams()); - } -} diff --git a/src/flextype/flextype.php b/src/flextype/flextype.php index c657c633..59b6c99f 100644 --- a/src/flextype/flextype.php +++ b/src/flextype/flextype.php @@ -23,23 +23,6 @@ use Intervention\Image\ImageManager; use League\Event\Emitter; use League\Flysystem\Filesystem as Flysystem; use League\Flysystem\Local\LocalFilesystemAdapter as Local; -use League\Glide\Api\Api; -use League\Glide\Manipulators\Background; -use League\Glide\Manipulators\Blur; -use League\Glide\Manipulators\Border; -use League\Glide\Manipulators\Brightness; -use League\Glide\Manipulators\Contrast; -use League\Glide\Manipulators\Crop; -use League\Glide\Manipulators\Encode; -use League\Glide\Manipulators\Filter; -use League\Glide\Manipulators\Gamma; -use League\Glide\Manipulators\Orientation; -use League\Glide\Manipulators\Pixelate; -use League\Glide\Manipulators\Sharpen; -use League\Glide\Manipulators\Size; -use League\Glide\Manipulators\Watermark; -use League\Glide\Responses\PsrResponseFactory; -use League\Glide\ServerFactory; use Monolog\Handler\StreamHandler; use Monolog\Logger; use Phpfastcache\Drivers\Apcu\Config; @@ -335,77 +318,6 @@ parsers()->shortcodes()->initShortcodes(); // Add Serializers Service container()->set('serializers', new Serializers()); -// Add Images Service -container()->set('images', static function () { - - // Get image settings driver - $imagesSettingsDriver = ['driver' => registry()->get('flextype.settings.api.images.driver')]; - - // Set source filesystem - $source = new Flysystem( - new Local(PATH['project'] . registry()->get('flextype.settings.api.images.directory')), - ); - - // Set cache filesystem - $cache = new Flysystem( - new Local(PATH['tmp'] . registry()->get('flextype.settings.api.images.cache.directory')) - ); - - // Set watermarks filesystem - $watermarks = new Flysystem( - new Local(PATH['project'] . registry()->get('flextype.settings.api.images.watermarks.directory')) - ); - - // Set image manager - $imageManager = new ImageManager($imagesSettingsDriver); - - // Set max image size - $maxImageSize = registry()->get('flextype.settings.api.images.max_image_size.width') * registry()->get('flextype.settings.api.images.max_image_size.height'); - - // Set manipulators - $manipulators = [ - new Orientation(), - new Crop(), - new Size($maxImageSize), - new Brightness(), - new Contrast(), - new Gamma(), - new Sharpen(), - new Filter(), - new Blur(), - new Pixelate(), - new Watermark($watermarks), - new Background(), - new Border(), - new Encode(), - ]; - - // Set API - $api = new Api($imageManager, $manipulators); - - // Setup Glide server - $server = ServerFactory::create([ - 'source' => $source, - 'cache' => $cache, - 'api' => $api, - ]); - - // Set presets - $server->setPresets(registry()->get('flextype.settings.api.images.presets')); - - // Set Glide response factory - $server->setResponseFactory( - new PsrResponseFactory( - new Response(), - static function ($stream) { - return new Stream($stream); - } - ) - ); - - return $server; -}); - // Add Entries Service container()->set('entries', new Entries(registry()->get('flextype.settings.entries'))); diff --git a/src/flextype/helpers/services.php b/src/flextype/helpers/services.php index 3b3cd7e8..e55fb77d 100644 --- a/src/flextype/helpers/services.php +++ b/src/flextype/helpers/services.php @@ -142,14 +142,4 @@ if (! function_exists('plugins')) { { return flextype()->container()->get('plugins'); } -} - -if (! function_exists('images')) { - /** - * Get Flextype Images Service. - */ - function images() - { - return flextype()->container()->get('images'); - } } \ No newline at end of file diff --git a/src/flextype/routes/endpoints/images.php b/src/flextype/routes/endpoints/images.php deleted file mode 100644 index d17323c3..00000000 --- a/src/flextype/routes/endpoints/images.php +++ /dev/null @@ -1,30 +0,0 @@ -get('/api/images/{path:.+}', [Images::class, 'fetch']); From fb3c97160fac440e46aa909fa018caa8286aefb5 Mon Sep 17 00:00:00 2001 From: Awilum Date: Wed, 8 Sep 2021 20:23:56 +0300 Subject: [PATCH 45/51] feat(images): remove Glide and images resize on demand to avoid image resize attack on production. #574 --- src/flextype/settings.yaml | 36 ------------------------------------ 1 file changed, 36 deletions(-) diff --git a/src/flextype/settings.yaml b/src/flextype/settings.yaml index de43cc05..7e3c3fbe 100644 --- a/src/flextype/settings.yaml +++ b/src/flextype/settings.yaml @@ -706,42 +706,6 @@ api: # Set to true to enable Registry API enabled: true - # Images API - images: - - # Set to true to enable Images API - enabled: true - - # Images driver (gd, imagick) - driver: gd - - # Images directory. - directory: '/uploads' - - # Images max size - max_image_size: - - # Image max width - width: 2000 - - # Image max height - height: 2000 - - # Images watermarks - watermarks: - - # Images watermarks directory - directory: '/watermarks' - - # Images cache - cache: - - # Images cache directory - directory: '/images' - - # Group of presets for images processing. - presets: [] - # Utils API utils: From 679d7d0a751b1a642a2afa3c1153f92455c74c20 Mon Sep 17 00:00:00 2001 From: Awilum Date: Wed, 8 Sep 2021 21:17:17 +0300 Subject: [PATCH 46/51] feat(images): remove Glide and images resize on demand to avoid image resize attack on production. #574 --- src/flextype/flextype.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/flextype/flextype.php b/src/flextype/flextype.php index 59b6c99f..3911a923 100644 --- a/src/flextype/flextype.php +++ b/src/flextype/flextype.php @@ -347,7 +347,6 @@ container()->set('plugins', new Plugins()); // Api Endpoints require_once ROOT_DIR . '/src/flextype/routes/endpoints/utils.php'; -require_once ROOT_DIR . '/src/flextype/routes/endpoints/images.php'; require_once ROOT_DIR . '/src/flextype/routes/endpoints/entries.php'; require_once ROOT_DIR . '/src/flextype/routes/endpoints/registry.php'; From 29cf0fdf0f17b06662b81ea8c9639fd03fd160a4 Mon Sep 17 00:00:00 2001 From: Awilum Date: Thu, 9 Sep 2021 19:56:24 +0300 Subject: [PATCH 47/51] feat(endpoints): typo update --- src/flextype/routes/endpoints/entries.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/flextype/routes/endpoints/entries.php b/src/flextype/routes/endpoints/entries.php index a03922a2..d67b3798 100644 --- a/src/flextype/routes/endpoints/entries.php +++ b/src/flextype/routes/endpoints/entries.php @@ -35,8 +35,7 @@ app()->get('/api/entries', [Entries::class, 'fetch']); * * Body: * id - [REQUIRED] - Unique identifier of the entry. - * token - - * [REQUIRED] - Valid public token. + * token - [REQUIRED] - Valid public token. * access_token - [REQUIRED] - Valid access token. * data - [REQUIRED] - Data to store for the entry. * From bbdc40d4b1a4973712719a6c1722dbc151603cc9 Mon Sep 17 00:00:00 2001 From: Awilum Date: Fri, 10 Sep 2021 10:47:10 +0300 Subject: [PATCH 48/51] feat(core): remove default handlers and rename `WhoopsGuard` to `Whoops` --- .../core/Handlers/HttpErrorHandler.php | 76 ----------------- .../core/Handlers/ShutdownHandler.php | 83 ------------------- .../core/Middlewares/WhoopsMiddleware.php | 4 +- .../core/{WhoopsGuard.php => Whoops.php} | 2 +- 4 files changed, 3 insertions(+), 162 deletions(-) delete mode 100644 src/flextype/core/Handlers/HttpErrorHandler.php delete mode 100644 src/flextype/core/Handlers/ShutdownHandler.php rename src/flextype/core/{WhoopsGuard.php => Whoops.php} (99%) diff --git a/src/flextype/core/Handlers/HttpErrorHandler.php b/src/flextype/core/Handlers/HttpErrorHandler.php deleted file mode 100644 index cb6da13f..00000000 --- a/src/flextype/core/Handlers/HttpErrorHandler.php +++ /dev/null @@ -1,76 +0,0 @@ -exception; - $statusCode = 500; - $type = self::SERVER_ERROR; - $description = 'An internal error has occurred while processing your request.'; - - if ($exception instanceof HttpException) { - $statusCode = $exception->getCode(); - $description = $exception->getMessage(); - - if ($exception instanceof HttpNotFoundException) { - $type = self::RESOURCE_NOT_FOUND; - } elseif ($exception instanceof HttpMethodNotAllowedException) { - $type = self::NOT_ALLOWED; - } elseif ($exception instanceof HttpUnauthorizedException) { - $type = self::UNAUTHENTICATED; - } elseif ($exception instanceof HttpForbiddenException) { - $type = self::UNAUTHENTICATED; - } elseif ($exception instanceof HttpBadRequestException) { - $type = self::BAD_REQUEST; - } elseif ($exception instanceof HttpNotImplementedException) { - $type = self::NOT_IMPLEMENTED; - } - } - - if ( - !($exception instanceof HttpException) - && ($exception instanceof Exception || $exception instanceof Throwable) - && $this->displayErrorDetails - ) { - $description = $exception->getMessage(); - } - - $error = [ - 'statusCode' => $statusCode, - 'error' => [ - 'type' => $type, - 'description' => $description, - ], - ]; - - $payload = json_encode($error, JSON_PRETTY_PRINT); - - $response = $this->responseFactory->createResponse($statusCode); - $response->getBody()->write($payload); - - return $response; - } -} \ No newline at end of file diff --git a/src/flextype/core/Handlers/ShutdownHandler.php b/src/flextype/core/Handlers/ShutdownHandler.php deleted file mode 100644 index 3bdceb3d..00000000 --- a/src/flextype/core/Handlers/ShutdownHandler.php +++ /dev/null @@ -1,83 +0,0 @@ -request = $request; - $this->errorHandler = $errorHandler; - $this->displayErrorDetails = $displayErrorDetails; - } - - public function __invoke() - { - $error = error_get_last(); - if ($error) { - $errorFile = $error['file']; - $errorLine = $error['line']; - $errorMessage = $error['message']; - $errorType = $error['type']; - $message = 'An error while processing your request. Please try again later.'; - - if ($this->displayErrorDetails) { - switch ($errorType) { - case E_USER_ERROR: - $message = "FATAL ERROR: {$errorMessage}. "; - $message .= " on line {$errorLine} in file {$errorFile}."; - break; - - case E_USER_WARNING: - $message = "WARNING: {$errorMessage}"; - break; - - case E_USER_NOTICE: - $message = "NOTICE: {$errorMessage}"; - break; - - default: - $message = "ERROR: {$errorMessage}"; - $message .= " on line {$errorLine} in file {$errorFile}."; - break; - } - } - - $exception = new HttpInternalServerErrorException($this->request, $message); - $response = $this->errorHandler->__invoke($this->request, $exception, $this->displayErrorDetails, false, false); - - if (ob_get_length()) { - ob_clean(); - } - - $responseEmitter = new ResponseEmitter(); - $responseEmitter->emit($response); - } - } -} \ No newline at end of file diff --git a/src/flextype/core/Middlewares/WhoopsMiddleware.php b/src/flextype/core/Middlewares/WhoopsMiddleware.php index d69db7a9..913d879b 100644 --- a/src/flextype/core/Middlewares/WhoopsMiddleware.php +++ b/src/flextype/core/Middlewares/WhoopsMiddleware.php @@ -13,7 +13,7 @@ use Psr\Http\Server\MiddlewareInterface; use Psr\Http\Server\RequestHandlerInterface; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ResponseInterface; -use Flextype\WhoopsGuard; +use Flextype\Whoops; class WhoopsMiddleware implements MiddlewareInterface { @@ -42,7 +42,7 @@ class WhoopsMiddleware implements MiddlewareInterface */ public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface { - $whoopsGuard = new WhoopsGuard($this->settings); + $whoopsGuard = new Whoops($this->settings); $whoopsGuard->setRequest($request); $whoopsGuard->setHandlers($this->handlers); $whoopsGuard->install(); diff --git a/src/flextype/core/WhoopsGuard.php b/src/flextype/core/Whoops.php similarity index 99% rename from src/flextype/core/WhoopsGuard.php rename to src/flextype/core/Whoops.php index 1c293654..fd24bdf0 100644 --- a/src/flextype/core/WhoopsGuard.php +++ b/src/flextype/core/Whoops.php @@ -17,7 +17,7 @@ use Whoops\Handler\PlainTextHandler; use Whoops\Handler\JsonResponseHandler; use Whoops\Handler\XmlResponseHandler; -class WhoopsGuard +class Whoops { protected $settings = []; From ec9f0beab952f30182dd491f00670d6056c6b74e Mon Sep 17 00:00:00 2001 From: Awilum Date: Fri, 10 Sep 2021 10:49:11 +0300 Subject: [PATCH 49/51] feat(media): remove media functionality for now, possible we should use imagekit instead --- .../core/Entries/Actions/Media/CopyAction.php | 25 -------- .../Entries/Actions/Media/CreateAction.php | 38 ------------ .../Entries/Actions/Media/DeleteAction.php | 23 ------- .../core/Entries/Actions/Media/MoveAction.php | 25 -------- .../Parsers/Shortcodes/MediaShortcode.php | 26 -------- src/flextype/settings.yaml | 60 +------------------ 6 files changed, 1 insertion(+), 196 deletions(-) delete mode 100644 src/flextype/core/Entries/Actions/Media/CopyAction.php delete mode 100644 src/flextype/core/Entries/Actions/Media/CreateAction.php delete mode 100644 src/flextype/core/Entries/Actions/Media/DeleteAction.php delete mode 100644 src/flextype/core/Entries/Actions/Media/MoveAction.php delete mode 100644 src/flextype/core/Parsers/Shortcodes/MediaShortcode.php diff --git a/src/flextype/core/Entries/Actions/Media/CopyAction.php b/src/flextype/core/Entries/Actions/Media/CopyAction.php deleted file mode 100644 index b9dd3fae..00000000 --- a/src/flextype/core/Entries/Actions/Media/CopyAction.php +++ /dev/null @@ -1,25 +0,0 @@ -addListener('onEntriesMove', static function (): void { - - if (! entries()->registry()->get('collection.options.actions.copy.enabled')) { - return; - } - - $id = entries()->registry()->get('copy.id'); - $newID = entries()->registry()->get('copy.newID'); - - $mediaResourceDirectoryCurrentLocation = PATH['project'] . registry()->get('flextype.settings.media.upload.directory') . '/' . $id; - $mediaResourceDirectoryNewLocation = PATH['project'] . registry()->get('flextype.settings.media.upload.directory') . '/' . $newID; - - if (filesystem()->directory($mediaResourceDirectoryCurrentLocation)->exists()) { - filesystem()->directory($mediaResourceDirectoryCurrentLocation)->copy($mediaResourceDirectoryNewLocation); - } -}); \ No newline at end of file diff --git a/src/flextype/core/Entries/Actions/Media/CreateAction.php b/src/flextype/core/Entries/Actions/Media/CreateAction.php deleted file mode 100644 index 23fcc19e..00000000 --- a/src/flextype/core/Entries/Actions/Media/CreateAction.php +++ /dev/null @@ -1,38 +0,0 @@ -addListener('onEntriesCreate', static function (): void { - - if (! entries()->registry()->get('collection.options.actions.create.enabled')) { - return; - } - - $id = entries()->registry()->get('create.id'); - $data = entries()->registry()->get('create.data'); - - $data['resource'] = $data['resource'] ?? ''; - - if (is_array($data['resource'])) { - - $media = upload($data['resource'], $id); - - if ($media->name) { - - $uploadDirectory = strings(PATH['project'] . '/' . registry()->get('flextype.settings.upload.directory') . '/' . $id)->reduceSlashes()->toString(); - $mediaFile = $uploadDirectory . '/media.' . filesystem()->file($media->name)->extension(); - filesystem()->file($uploadDirectory . '/' . $media->name)->move($mediaFile); - - $data['resource'] = strings($id . '/media.' . filesystem()->file($media->name)->extension())->reduceSlashes()->toString(); - } else { - $data['resource'] = ''; - } - } - - entries()->registry()->set('create.data', array_merge(entries()->registry()->get('create.data'), $data)); -}); \ No newline at end of file diff --git a/src/flextype/core/Entries/Actions/Media/DeleteAction.php b/src/flextype/core/Entries/Actions/Media/DeleteAction.php deleted file mode 100644 index 032545a7..00000000 --- a/src/flextype/core/Entries/Actions/Media/DeleteAction.php +++ /dev/null @@ -1,23 +0,0 @@ -addListener('onEntriesMove', static function (): void { - - if (! entries()->registry()->get('collection.options.actions.delete.enabled')) { - return; - } - - $id = entries()->registry()->get('move.id'); - - $mediaResourceDirectoryCurrentLocation = PATH['project'] . registry()->get('flextype.settings.media.upload.directory') . '/' . $id; - - if (filesystem()->directory($mediaResourceDirectoryCurrentLocation)->exists()) { - filesystem()->directory($mediaResourceDirectoryCurrentLocation)->delete(); - } -}); \ No newline at end of file diff --git a/src/flextype/core/Entries/Actions/Media/MoveAction.php b/src/flextype/core/Entries/Actions/Media/MoveAction.php deleted file mode 100644 index 9a17ec44..00000000 --- a/src/flextype/core/Entries/Actions/Media/MoveAction.php +++ /dev/null @@ -1,25 +0,0 @@ -addListener('onEntriesMove', static function (): void { - - if (! entries()->registry()->get('collection.options.actions.move.enabled')) { - return; - } - - $id = entries()->registry()->get('move.id'); - $newID = entries()->registry()->get('move.newID'); - - $mediaResourceDirectoryCurrentLocation = PATH['project'] . registry()->get('flextype.settings.media.upload.directory') . '/' . $id; - $mediaResourceDirectoryNewLocation = PATH['project'] . registry()->get('flextype.settings.media.upload.directory') . '/' . $newID; - - if (filesystem()->directory($mediaResourceDirectoryCurrentLocation)->exists()) { - filesystem()->directory($mediaResourceDirectoryCurrentLocation)->move($mediaResourceDirectoryNewLocation); - } -}); \ No newline at end of file diff --git a/src/flextype/core/Parsers/Shortcodes/MediaShortcode.php b/src/flextype/core/Parsers/Shortcodes/MediaShortcode.php deleted file mode 100644 index ec306ac8..00000000 --- a/src/flextype/core/Parsers/Shortcodes/MediaShortcode.php +++ /dev/null @@ -1,26 +0,0 @@ -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')); -}); diff --git a/src/flextype/settings.yaml b/src/flextype/settings.yaml index 7e3c3fbe..1810fd60 100644 --- a/src/flextype/settings.yaml +++ b/src/flextype/settings.yaml @@ -168,61 +168,6 @@ entries: state: enabled: true path: "/src/flextype/core/Entries/Fields/Tokens/Items/StateField.php" - media: - pattern: media - filename: media - extension: yaml - serializer: yaml - fields: - modified_at: - enabled: true - path: "/src/flextype/core/Entries/Fields/Default/ModifiedAtField.php" - created_at: - enabled: true - path: "/src/flextype/core/Entries/Fields/Default/CreatedAtField.php" - created_by: - enabled: true - path: "/src/flextype/core/Entries/Fields/Default/CreatedByField.php" - uuid: - enabled: true - path: "/src/flextype/core/Entries/Fields/Default/UuidField.php" - id: - enabled: true - path: "/src/flextype/core/Entries/Fields/Default/IdField.php" - media_item: - pattern: media/(.*) - filename: media - extension: yaml - serializer: yaml - actions: - create: - enabled: true - path: "/src/flextype/core/Entries/Actions/Media/CreateAction.php" - move: - enabled: true - path: "/src/flextype/core/Entries/Actions/Media/MoveAction.php" - copy: - enabled: true - path: "/src/flextype/core/Entries/Actions/Media/CopyAction.php" - delete: - enabled: true - path: "/src/flextype/core/Entries/Actions/Media/DeleteAction.php" - fields: - modified_at: - enabled: true - path: "/src/flextype/core/Entries/Fields/Default/ModifiedAtField.php" - created_at: - enabled: true - path: "/src/flextype/core/Entries/Fields/Default/CreatedAtField.php" - created_by: - enabled: true - path: "/src/flextype/core/Entries/Fields/Default/CreatedByField.php" - uuid: - enabled: true - path: "/src/flextype/core/Entries/Fields/Default/UuidField.php" - id: - enabled: true - path: "/src/flextype/core/Entries/Fields/Default/IdField.php" # Cache @@ -494,7 +439,7 @@ serializers: native: true flags: 0 encode: - inline: 5 + inline: 10 indent: 2 flags: 0 frontmatter: @@ -568,9 +513,6 @@ parsers: shortcodes: cache: true shortcodes: - media: - enabled: true - path: "/src/flextype/core/Parsers/Shortcodes/MediaShortcode.php" entries: enabled: true path: "/src/flextype/core/Parsers/Shortcodes/EntriesShortcode.php" From 1121fa0a4cb91d5d0f0d0ec6f6c5fbb42213acbd Mon Sep 17 00:00:00 2001 From: Awilum Date: Sat, 11 Sep 2021 11:11:02 +0300 Subject: [PATCH 50/51] feat(actions): add Actions API and add AcationsHelper #549 --- src/flextype/core/Actions.php | 63 +++++++++++++++++++++++++++++++ src/flextype/flextype.php | 3 ++ src/flextype/helpers/services.php | 10 +++++ 3 files changed, 76 insertions(+) create mode 100644 src/flextype/core/Actions.php diff --git a/src/flextype/core/Actions.php b/src/flextype/core/Actions.php new file mode 100644 index 00000000..fd2c0140 --- /dev/null +++ b/src/flextype/core/Actions.php @@ -0,0 +1,63 @@ +set('registry', registry()); +// Add Actions Service. +container()->set('actions', Actions::getInstance()); + // Init Flextype config (manifest and settings) $flextypeManifestFilePath = ROOT_DIR . '/src/flextype/flextype.yaml'; $defaultFlextypeSettingsFilePath = ROOT_DIR . '/src/flextype/settings.yaml'; diff --git a/src/flextype/helpers/services.php b/src/flextype/helpers/services.php index e55fb77d..e5454df8 100644 --- a/src/flextype/helpers/services.php +++ b/src/flextype/helpers/services.php @@ -114,6 +114,16 @@ if (! function_exists('registry')) { } } +if (! function_exists('actions')) { + /** + * Get Flextype Actions Service. + */ + function actions() + { + return flextype()->container()->get('actions'); + } +} + if (! function_exists('csrf')) { /** * Get Flextype CSRF Service. From 0bf56410f1475fa888cdb2625adeacb0ea9d0491 Mon Sep 17 00:00:00 2001 From: Awilum Date: Sat, 11 Sep 2021 11:14:04 +0300 Subject: [PATCH 51/51] feat(entries): rename entries actions to entries events --- src/flextype/core/Entries/Entries.php | 28 +++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/flextype/core/Entries/Entries.php b/src/flextype/core/Entries/Entries.php index e46445d0..9dfaf065 100755 --- a/src/flextype/core/Entries/Entries.php +++ b/src/flextype/core/Entries/Entries.php @@ -69,18 +69,18 @@ class Entries { $this->setRegistry($registry); $this->setOptions($options); - $this->loadCollectionsActions(); + $this->loadCollectionsEvents(); $this->loadCollectionsFields(); } /** - * Load Collections Actions + * Load Collections Events * * @access public */ - private function loadCollectionsActions(): void + private function loadCollectionsEvents(): void { - $actions = []; + $events = []; if (! isset($this->options['collections']) || ! is_array($this->options['collections'])) { @@ -90,29 +90,29 @@ class Entries foreach ($this->options['collections'] as $collection) { if ( - ! isset($collection['actions']) || - ! is_array($collection['actions']) || - count($collection['actions']) <= 0 + ! isset($collection['events']) || + ! is_array($collection['events']) || + count($collection['events']) <= 0 ) { continue; } - foreach ($collection['actions'] as $action) { + foreach ($collection['events'] as $event) { - if (! isset($action['path'])) { + if (! isset($event['path'])) { continue; } - $actions[] = ROOT_DIR . $action['path']; + $events[] = ROOT_DIR . $event['path']; } } - $actions = arrays($actions)->unique()->toArray(); + $events = arrays($events)->unique()->toArray(); - foreach ($actions as $action) { - if (filesystem()->file($action)->exists()) { + foreach ($events as $event) { + if (filesystem()->file($event)->exists()) { - include_once $action; + include_once $event; } } }