diff --git a/CHANGELOG.md b/CHANGELOG.md index 77e9fb04..502411f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,16 @@ +# v1.0.15 +## 06/16/2021 + +1. [](#improved) + * Better checks against missing Flex Type inside tasks + * Better authorization checks, falls back to directory level authorization checks if objects do not support authorization +1. [](#bugfix) + * Fixed missing handling of child_type in Flex Pages [getgrav/grav-plugin-admin#2087](https://github.com/getgrav/grav-plugin-admin/issues/2087) + * Added support for multiple `Exports` in a dropdown + * Admin is no longer a dependency of Flex Objects [#130](https://github.com/trilbymedia/grav-plugin-flex-objects/issues/130) + * Fixed authorization checks during page creation for users who have limited access to some pages [getgrav/grav#3382](https://github.com/getgrav/grav/issues/3382) + * Fixed permission check when moving a page [getgrav/grav#3382](https://github.com/getgrav/grav/issues/3382) + # v1.0.14 ## 06/07/2021 diff --git a/admin/templates/flex-objects/types/default/buttons/export.html.twig b/admin/templates/flex-objects/types/default/buttons/export.html.twig index f6667973..0f8382b2 100644 --- a/admin/templates/flex-objects/types/default/buttons/export.html.twig +++ b/admin/templates/flex-objects/types/default/buttons/export.html.twig @@ -1,3 +1,21 @@ - +{% if export.options %} +
+ + +
+ +{% else %} + {{ export.title ?? (export.formatter.class ? 'PLUGIN_ADMIN.EXPORT'|tu : 'PLUGIN_FLEX_OBJECTS.CSV'|tu) }} +{% endif %} \ No newline at end of file diff --git a/admin/templates/flex-objects/types/pages/edit.html.twig b/admin/templates/flex-objects/types/pages/edit.html.twig index 72074aaf..baf5c872 100644 --- a/admin/templates/flex-objects/types/pages/edit.html.twig +++ b/admin/templates/flex-objects/types/pages/edit.html.twig @@ -192,7 +192,7 @@ {% if object.exists %} {% set modal_data = data({ route: '/' ~ object.key, - name: object.header.child_type ?? null + name: object.header.child_type ?? object.blueprint.child_type ?? 'default' }) %}
diff --git a/blueprints.yaml b/blueprints.yaml index ddd1a155..1fc0054e 100644 --- a/blueprints.yaml +++ b/blueprints.yaml @@ -1,7 +1,7 @@ name: Flex Objects slug: flex-objects type: plugin -version: 1.0.14 +version: 1.0.15 description: Flex Objects plugin allows you to manage Flex Objects in Grav Admin. icon: list-alt author: @@ -15,7 +15,6 @@ license: MIT dependencies: - { name: grav, version: '>=1.7.10' } - - { name: admin, version: '>=1.7.13' } - { name: form, version: '>=5.0.2' } form: diff --git a/classes/Admin/AdminController.php b/classes/Admin/AdminController.php index 512b8cd5..03a2e2ea 100644 --- a/classes/Admin/AdminController.php +++ b/classes/Admin/AdminController.php @@ -123,11 +123,14 @@ class AdminController */ public function taskDefault(): bool { - $object = $this->getObject(); $type = $this->target; - $key = $this->id; - $directory = $this->getDirectory($type); + if (!$directory) { + throw new RuntimeException('Not Found', 404); + } + + $object = $this->getObject(); + $key = $this->id; if ($object && $object->exists()) { $event = new Event( @@ -171,11 +174,14 @@ public function taskDefault(): bool */ public function actionDefault(): bool { - $object = $this->getObject(); $type = $this->target; - $key = $this->id; - $directory = $this->getDirectory($type); + if (!$directory) { + throw new RuntimeException('Not Found', 404); + } + + $object = $this->getObject(); + $key = $this->id; if ($object && $object->exists()) { $event = new Event( @@ -218,11 +224,19 @@ public function actionDefault(): bool */ public function actionList(): void { + $directory = $this->getDirectory(); + if (!$directory) { + throw new RuntimeException('Not Found', 404); + } + + // Check authorization. + if (!$directory->isAuthorized('list', 'admin', $this->user)) { + throw new RuntimeException($this->admin::translate('PLUGIN_ADMIN.INSUFFICIENT_PERMISSIONS_FOR_TASK') . ' list.', 403); + } + /** @var Uri $uri */ $uri = $this->grav['uri']; if ($uri->extension() === 'json') { - $directory = $this->getDirectory(); - $options = [ 'collection' => $this->getCollection(), 'url' => $uri->path(), @@ -260,10 +274,17 @@ public function actionExport(): void { $collection = $this->getCollection(); if (!$collection) { - throw new RuntimeException('Internal Error', 500); + throw new RuntimeException('Not Found', 404); } - if (is_callable([$collection, 'isAuthorized']) && !$collection->isAuthorized('list', 'admin', $this->user)) { - throw new RuntimeException($this->admin::translate('PLUGIN_ADMIN.INSUFFICIENT_PERMISSIONS_FOR_TASK') . ' list.', 403); + + // Check authorization. + $directory = $collection->getFlexDirectory(); + $authorized = is_callable([$collection, 'isAuthorized']) + ? $collection->isAuthorized('read', 'admin', $this->user) + : $directory->isAuthorized('read', 'admin', $this->user); + + if (!$authorized) { + throw new RuntimeException($this->admin::translate('PLUGIN_ADMIN.INSUFFICIENT_PERMISSIONS_FOR_TASK') . ' read.', 403); } $config = $collection->getFlexDirectory()->getConfig('admin.views.export') ?? $collection->getFlexDirectory()->getConfig('admin.export') ?? false; @@ -271,6 +292,15 @@ public function actionExport(): void throw new RuntimeException($this->admin::translate('Not Found'), 404); } + $queryParams = $this->getRequest()->getQueryParams(); + $type = $queryParams['type'] ?? null; + if ($type) { + $config = $config['options'][$type] ?? null; + if (!$config) { + throw new RuntimeException($this->admin::translate('Not Found'), 404); + } + } + $defaultFormatter = CsvFormatter::class; $class = trim($config['formatter']['class'] ?? $defaultFormatter, '\\'); $method = $config['method'] ?? ($class === $defaultFormatter ? 'csvSerialize' : 'jsonSerialize'); @@ -282,7 +312,7 @@ public function actionExport(): void $filename = ($config['filename'] ?? 'export') . $formatter->getDefaultFileExtension(); if (method_exists($collection, $method)) { - $list = $collection->{$method}(); + $list = $type ? $collection->{$method}($type) : $collection->{$method}(); } else { $list = []; @@ -322,12 +352,20 @@ public function actionExport(): void */ public function taskDelete() { + $directory = $this->getDirectory(); + if (!$directory) { + throw new RuntimeException('Not Found', 404); + } + $object = null; try { $object = $this->getObject(); - if ($object && $object->exists()) { - if ($object instanceof FlexAuthorizeInterface && !$object->isAuthorized('delete', 'admin', $this->user)) { + $authorized = $object instanceof FlexAuthorizeInterface + ? $object->isAuthorized('delete', 'admin', $this->user) + : $directory->isAuthorized('delete', 'admin', $this->user); + + if (!$authorized) { throw new RuntimeException($this->admin::translate('PLUGIN_ADMIN.INSUFFICIENT_PERMISSIONS_FOR_TASK') . ' delete.', 403); } @@ -368,11 +406,7 @@ public function taskSaveNewFolder(): void throw new RuntimeException('Not Found', 404); } - if ($directory instanceof FlexAuthorizeInterface && !$directory->isAuthorized('create', 'admin', $this->user)) { - throw new RuntimeException($this->admin::translate('PLUGIN_ADMIN.INSUFFICIENT_PERMISSIONS_FOR_TASK') . ' save.', 403); - } - - $collection = $directory->getCollection(); + $collection = $directory->getIndex(); if (!($collection instanceof PageCollection || $collection instanceof PageIndex)) { throw new RuntimeException('Task saveNewFolder works only for pages', 400); } @@ -391,6 +425,10 @@ public function taskSaveNewFolder(): void throw new RuntimeException('Creating folder failed, bad parent route', 400); } + if (!$parent->isAuthorized('create', 'admin', $this->user)) { + throw new RuntimeException($this->admin::translate('PLUGIN_ADMIN.INSUFFICIENT_PERMISSIONS_FOR_TASK') . ' create.', 403); + } + $path = $parent->getFlexDirectory()->getStorageFolder($parent->getStorageKey()); if (!$path) { throw new RuntimeException('Creating folder failed, bad parent storage path', 400); @@ -439,13 +477,20 @@ public function taskContinue(): void throw new RuntimeException('Not Found', 404); } + $collection = $directory->getIndex(); + if (!($collection instanceof PageCollection || $collection instanceof PageIndex)) { + throw new RuntimeException('Task continue works only for pages', 400); + } + $this->data['route'] = '/' . trim($this->data['route'] ?? '', '/'); $route = trim($this->data['route'], '/'); - $object = $this->getObject($route); - $authorized = $object && $object->isAuthorized('create', 'admin', $this->user); + $parent = $route ? $directory->getObject($route) : $collection->getRoot(); + $authorized = $parent instanceof FlexAuthorizeInterface + ? $parent->isAuthorized('create', 'admin', $this->user) + : $directory->isAuthorized('create', 'admin', $this->user); - if (!$authorized && !$directory->isAuthorized('create', 'admin', $this->user)) { + if (!$authorized) { $this->setRedirect($this->referrerRoute->toString(true)); throw new RuntimeException($this->admin::translate('PLUGIN_ADMIN.INSUFFICIENT_PERMISSIONS_FOR_TASK') . ' add.', 403); @@ -468,7 +513,11 @@ public function taskContinue(): void throw new RuntimeException('Creating page failed: bad folder name', 400); } - if (isset($this->data['name']) && strpos($this->data['name'], 'modular/') === 0) { + if (!isset($this->data['name'])) { + // Get default child type. + $this->data['name'] = $parent->header()->child_type ?? $parent->getBlueprint()->child_type ?? 'default'; + } + if (strpos($this->data['name'], 'modular/') === 0) { $this->data['header']['body_classes'] = 'modular'; $folder = '_' . $folder; } @@ -488,8 +537,6 @@ public function taskContinue(): void // Empty string on visible means auto. if ($auto || $visible) { - /** @var PageObject $parent */ - $parent = $route ? $directory->getObject($route) : $directory->getIndex()->getRoot(); $children = $parent ? $parent->children()->visible() : []; $max = $auto ? 0 : 1; foreach ($children as $child) { @@ -539,14 +586,23 @@ public function taskContinue(): void protected function taskCopy(): bool { try { + $directory = $this->getDirectory(); + if (!$directory) { + throw new RuntimeException('Not Found', 404); + } + $object = $this->getObject(); - if (!$object || !$object->exists()) { + if (!$object || !$object->exists() || !is_callable([$object, 'createCopy'])) { throw new RuntimeException('Not Found', 404); } // Pages are a special case. $parent = $object instanceof PageInterface ? $object->parent() : $object; - if (null === $parent || ($parent instanceof FlexAuthorizeInterface && !$parent->isAuthorized('create', 'admin', $this->user))) { + $authorized = $parent instanceof FlexAuthorizeInterface + ? $parent->isAuthorized('create', 'admin', $this->user) + : $directory->isAuthorized('create', 'admin', $this->user); + + if (!$authorized || !$parent) { throw new RuntimeException($this->admin::translate('PLUGIN_ADMIN.INSUFFICIENT_PERMISSIONS_FOR_TASK') . ' copy.', 403); } @@ -732,6 +788,11 @@ public function taskSaveas(): bool */ public function taskSave(): bool { + $directory = $this->getDirectory(); + if (!$directory) { + throw new RuntimeException('Not Found', 404); + } + $key = $this->id; try { @@ -740,17 +801,15 @@ public function taskSave(): bool throw new RuntimeException('Not Found', 404); } - if ($object->exists()) { - if (!$object->isAuthorized('update', 'admin', $this->user)) { - throw new RuntimeException($this->admin::translate('PLUGIN_ADMIN.INSUFFICIENT_PERMISSIONS_FOR_TASK') . ' save.', - 403); - } - } else { - if (!$object->isAuthorized('create', 'admin', $this->user)) { - throw new RuntimeException($this->admin::translate('PLUGIN_ADMIN.INSUFFICIENT_PERMISSIONS_FOR_TASK') . ' save.', + $authorized = $object instanceof FlexAuthorizeInterface + ? $object->isAuthorized('save', 'admin', $this->user) + : $directory->isAuthorized($object->exists() ? 'update' : 'create', 'admin', $this->user); + + if (!$authorized) { + throw new RuntimeException($this->admin::translate('PLUGIN_ADMIN.INSUFFICIENT_PERMISSIONS_FOR_TASK') . ' save.', 403); - } } + $grav = Grav::instance(); /** @var ServerRequestInterface $request */ @@ -775,6 +834,10 @@ public function taskSave(): bool unset($data['frontmatter']); } + if (is_callable([$object, 'check'])) { + $object->check($this->user); + } + $object->save(); }; @@ -887,8 +950,12 @@ public function taskSave(): bool */ public function taskConfigure(): bool { + $directory = $this->getDirectory(); + if (!$directory) { + throw new RuntimeException('Not Found', 404); + } + try { - $directory = $this->getDirectory(); $config = $directory->getConfig('admin.views.configure.authorize') ?? $directory->getConfig('admin.configure.authorize') ?? 'admin.super'; if (!$this->user->authorize($config)) { throw new RuntimeException($this->admin::translate('PLUGIN_ADMIN.INSUFFICIENT_PERMISSIONS_FOR_TASK') . ' configure.', 403); @@ -940,6 +1007,11 @@ public function taskConfigure(): bool */ public function taskMediaList(): bool { + $directory = $this->getDirectory(); + if (!$directory) { + throw new RuntimeException('Not Found', 404); + } + try { $response = $this->forwardMediaTask('action', 'media.list'); @@ -956,6 +1028,11 @@ public function taskMediaList(): bool */ public function taskMediaUpload(): bool { + $directory = $this->getDirectory(); + if (!$directory) { + throw new RuntimeException('Not Found', 404); + } + try { $response = $this->forwardMediaTask('task', 'media.upload'); @@ -972,6 +1049,11 @@ public function taskMediaUpload(): bool */ public function taskMediaDelete(): bool { + $directory = $this->getDirectory(); + if (!$directory) { + throw new RuntimeException('Not Found', 404); + } + try { $response = $this->forwardMediaTask('task', 'media.delete'); @@ -996,6 +1078,11 @@ public function taskListmedia(): bool */ public function taskAddmedia(): bool { + $directory = $this->getDirectory(); + if (!$directory) { + throw new RuntimeException('Not Found', 404); + } + try { $response = $this->forwardMediaTask('task', 'media.copy'); @@ -1012,6 +1099,11 @@ public function taskAddmedia(): bool */ public function taskDelmedia(): bool { + $directory = $this->getDirectory(); + if (!$directory) { + throw new RuntimeException('Not Found', 404); + } + try { $response = $this->forwardMediaTask('task', 'media.remove'); @@ -1047,6 +1139,11 @@ public function taskRemoveMedia($filename = null): bool */ public function taskGetFilesInFolder(): bool { + $directory = $this->getDirectory(); + if (!$directory) { + throw new RuntimeException('Not Found', 404); + } + try { $response = $this->forwardMediaTask('action', 'media.picker'); diff --git a/composer.json b/composer.json index 4ab34017..6e7dc536 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,5 @@ { - "name": "grav-plugin-flex-objects", + "name": "getgrav/grav-plugin-flex-objects", "type": "grav-plugin", "description": "Flex Objects plugin for Grav CMS", "keywords": ["flex-objects"], diff --git a/composer.lock b/composer.lock index 18806e18..6f140725 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "5ca8fed3d2b79e0be2e6b0c80f8f62eb", + "content-hash": "8cd40668f2f51e9d1c7bceed7be5d27d", "packages": [], "packages-dev": [], "aliases": [], @@ -20,5 +20,6 @@ "platform-dev": [], "platform-overrides": { "php": "7.3.6" - } + }, + "plugin-api-version": "2.0.0" } diff --git a/vendor/composer/ClassLoader.php b/vendor/composer/ClassLoader.php index dc02dfb1..1a58957d 100644 --- a/vendor/composer/ClassLoader.php +++ b/vendor/composer/ClassLoader.php @@ -37,8 +37,8 @@ * * @author Fabien Potencier * @author Jordi Boggiano - * @see http://www.php-fig.org/psr/psr-0/ - * @see http://www.php-fig.org/psr/psr-4/ + * @see https://www.php-fig.org/psr/psr-0/ + * @see https://www.php-fig.org/psr/psr-4/ */ class ClassLoader { @@ -60,7 +60,7 @@ class ClassLoader public function getPrefixes() { if (!empty($this->prefixesPsr0)) { - return call_user_func_array('array_merge', $this->prefixesPsr0); + return call_user_func_array('array_merge', array_values($this->prefixesPsr0)); } return array(); @@ -279,7 +279,7 @@ public function isClassMapAuthoritative() */ public function setApcuPrefix($apcuPrefix) { - $this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null; + $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null; } /** @@ -377,7 +377,7 @@ private function findFileWithExtension($class, $ext) $subPath = $class; while (false !== $lastPos = strrpos($subPath, '\\')) { $subPath = substr($subPath, 0, $lastPos); - $search = $subPath.'\\'; + $search = $subPath . '\\'; if (isset($this->prefixDirsPsr4[$search])) { $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); foreach ($this->prefixDirsPsr4[$search] as $dir) { diff --git a/vendor/composer/InstalledVersions.php b/vendor/composer/InstalledVersions.php new file mode 100644 index 00000000..772fd5aa --- /dev/null +++ b/vendor/composer/InstalledVersions.php @@ -0,0 +1,219 @@ + + array ( + 'pretty_version' => 'dev-develop', + 'version' => 'dev-develop', + 'aliases' => + array ( + ), + 'reference' => '7bfde54d9213f68039891d2076bbab21009bde7c', + 'name' => 'getgrav/grav-plugin-flex-objects', + ), + 'versions' => + array ( + 'getgrav/grav-plugin-flex-objects' => + array ( + 'pretty_version' => 'dev-develop', + 'version' => 'dev-develop', + 'aliases' => + array ( + ), + 'reference' => '7bfde54d9213f68039891d2076bbab21009bde7c', + ), + ), +); + + + + + + + +public static function getInstalledPackages() +{ +return array_keys(self::$installed['versions']); +} + + + + + + + + + +public static function isInstalled($packageName) +{ +return isset(self::$installed['versions'][$packageName]); +} + + + + + + + + + + + + + + +public static function satisfies(VersionParser $parser, $packageName, $constraint) +{ +$constraint = $parser->parseConstraints($constraint); +$provided = $parser->parseConstraints(self::getVersionRanges($packageName)); + +return $provided->matches($constraint); +} + + + + + + + + + + +public static function getVersionRanges($packageName) +{ +if (!isset(self::$installed['versions'][$packageName])) { +throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); +} + +$ranges = array(); +if (isset(self::$installed['versions'][$packageName]['pretty_version'])) { +$ranges[] = self::$installed['versions'][$packageName]['pretty_version']; +} +if (array_key_exists('aliases', self::$installed['versions'][$packageName])) { +$ranges = array_merge($ranges, self::$installed['versions'][$packageName]['aliases']); +} +if (array_key_exists('replaced', self::$installed['versions'][$packageName])) { +$ranges = array_merge($ranges, self::$installed['versions'][$packageName]['replaced']); +} +if (array_key_exists('provided', self::$installed['versions'][$packageName])) { +$ranges = array_merge($ranges, self::$installed['versions'][$packageName]['provided']); +} + +return implode(' || ', $ranges); +} + + + + + +public static function getVersion($packageName) +{ +if (!isset(self::$installed['versions'][$packageName])) { +throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); +} + +if (!isset(self::$installed['versions'][$packageName]['version'])) { +return null; +} + +return self::$installed['versions'][$packageName]['version']; +} + + + + + +public static function getPrettyVersion($packageName) +{ +if (!isset(self::$installed['versions'][$packageName])) { +throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); +} + +if (!isset(self::$installed['versions'][$packageName]['pretty_version'])) { +return null; +} + +return self::$installed['versions'][$packageName]['pretty_version']; +} + + + + + +public static function getReference($packageName) +{ +if (!isset(self::$installed['versions'][$packageName])) { +throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); +} + +if (!isset(self::$installed['versions'][$packageName]['reference'])) { +return null; +} + +return self::$installed['versions'][$packageName]['reference']; +} + + + + + +public static function getRootPackage() +{ +return self::$installed['root']; +} + + + + + + + +public static function getRawData() +{ +return self::$installed; +} + + + + + + + + + + + + + + + + + + + +public static function reload($data) +{ +self::$installed = $data; +} +} diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index 4b84ea7d..f56375b4 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -6,5 +6,6 @@ $baseDir = dirname($vendorDir); return array( + 'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php', 'Grav\\Plugin\\FlexObjectsPlugin' => $baseDir . '/flex-objects.php', ); diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php index 5eb09d8a..f757e35f 100644 --- a/vendor/composer/autoload_real.php +++ b/vendor/composer/autoload_real.php @@ -13,19 +13,24 @@ public static function loadClassLoader($class) } } + /** + * @return \Composer\Autoload\ClassLoader + */ public static function getLoader() { if (null !== self::$loader) { return self::$loader; } + require __DIR__ . '/platform_check.php'; + spl_autoload_register(array('ComposerAutoloaderInit69fc28174abe912f71ebf710ee161e8f', 'loadClassLoader'), true, true); self::$loader = $loader = new \Composer\Autoload\ClassLoader(); spl_autoload_unregister(array('ComposerAutoloaderInit69fc28174abe912f71ebf710ee161e8f', 'loadClassLoader')); $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); if ($useStaticLoader) { - require_once __DIR__ . '/autoload_static.php'; + require __DIR__ . '/autoload_static.php'; call_user_func(\Composer\Autoload\ComposerStaticInit69fc28174abe912f71ebf710ee161e8f::getInitializer($loader)); } else { diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index 461a7c33..ba974625 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -21,6 +21,7 @@ class ComposerStaticInit69fc28174abe912f71ebf710ee161e8f ); public static $classMap = array ( + 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php', 'Grav\\Plugin\\FlexObjectsPlugin' => __DIR__ . '/../..' . '/flex-objects.php', ); diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index fe51488c..f20a6c47 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -1 +1,5 @@ -[] +{ + "packages": [], + "dev": false, + "dev-package-names": [] +} diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php new file mode 100644 index 00000000..d7e80a80 --- /dev/null +++ b/vendor/composer/installed.php @@ -0,0 +1,24 @@ + + array ( + 'pretty_version' => 'dev-develop', + 'version' => 'dev-develop', + 'aliases' => + array ( + ), + 'reference' => '7bfde54d9213f68039891d2076bbab21009bde7c', + 'name' => 'getgrav/grav-plugin-flex-objects', + ), + 'versions' => + array ( + 'getgrav/grav-plugin-flex-objects' => + array ( + 'pretty_version' => 'dev-develop', + 'version' => 'dev-develop', + 'aliases' => + array ( + ), + 'reference' => '7bfde54d9213f68039891d2076bbab21009bde7c', + ), + ), +); diff --git a/vendor/composer/platform_check.php b/vendor/composer/platform_check.php new file mode 100644 index 00000000..01091250 --- /dev/null +++ b/vendor/composer/platform_check.php @@ -0,0 +1,26 @@ += 70306)) { + $issues[] = 'Your Composer dependencies require a PHP version ">= 7.3.6". You are running ' . PHP_VERSION . '.'; +} + +if ($issues) { + if (!headers_sent()) { + header('HTTP/1.1 500 Internal Server Error'); + } + if (!ini_get('display_errors')) { + if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') { + fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL); + } elseif (!headers_sent()) { + echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL; + } + } + trigger_error( + 'Composer detected issues in your platform: ' . implode(' ', $issues), + E_USER_ERROR + ); +}