diff --git a/composer.lock b/composer.lock index 0d4bad7ee..26e721b4b 100644 --- a/composer.lock +++ b/composer.lock @@ -1844,12 +1844,12 @@ "source": { "type": "git", "url": "https://github.com/rockettheme/toolbox.git", - "reference": "3e6e698423d86415a329b284fa251a588b1494ac" + "reference": "125d72f87f772806aeafc3ddc136fc42662857a0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/rockettheme/toolbox/zipball/3e6e698423d86415a329b284fa251a588b1494ac", - "reference": "3e6e698423d86415a329b284fa251a588b1494ac", + "url": "https://api.github.com/repos/rockettheme/toolbox/zipball/125d72f87f772806aeafc3ddc136fc42662857a0", + "reference": "125d72f87f772806aeafc3ddc136fc42662857a0", "shasum": "" }, "archive": { @@ -1907,7 +1907,7 @@ "source": "https://github.com/rockettheme/toolbox/tree/develop", "issues": "https://github.com/rockettheme/toolbox/issues" }, - "time": "2020-01-23T20:26:01+00:00" + "time": "2020-02-03T08:53:52+00:00" }, { "name": "seld/cli-prompt", @@ -1959,16 +1959,16 @@ }, { "name": "symfony/console", - "version": "v4.4.3", + "version": "v4.4.4", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "e9ee09d087e2c88eaf6e5fc0f5c574f64d100e4f" + "reference": "f512001679f37e6a042b51897ed24a2f05eba656" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/e9ee09d087e2c88eaf6e5fc0f5c574f64d100e4f", - "reference": "e9ee09d087e2c88eaf6e5fc0f5c574f64d100e4f", + "url": "https://api.github.com/repos/symfony/console/zipball/f512001679f37e6a042b51897ed24a2f05eba656", + "reference": "f512001679f37e6a042b51897ed24a2f05eba656", "shasum": "" }, "require": { @@ -2031,7 +2031,7 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2020-01-10T21:54:01+00:00" + "time": "2020-01-25T12:44:29+00:00" }, { "name": "symfony/contracts", @@ -2112,7 +2112,7 @@ }, { "name": "symfony/event-dispatcher", - "version": "v4.4.3", + "version": "v4.4.4", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", @@ -2471,7 +2471,7 @@ }, { "name": "symfony/process", - "version": "v4.4.3", + "version": "v4.4.4", "source": { "type": "git", "url": "https://github.com/symfony/process.git", @@ -2520,16 +2520,16 @@ }, { "name": "symfony/var-dumper", - "version": "v4.4.3", + "version": "v4.4.4", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "7cfa470bc3b1887a7b2a47c0a702a84ad614fa92" + "reference": "46b53fd714568af343953c039ff47b67ce8af8d6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/7cfa470bc3b1887a7b2a47c0a702a84ad614fa92", - "reference": "7cfa470bc3b1887a7b2a47c0a702a84ad614fa92", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/46b53fd714568af343953c039ff47b67ce8af8d6", + "reference": "46b53fd714568af343953c039ff47b67ce8af8d6", "shasum": "" }, "require": { @@ -2592,11 +2592,11 @@ "debug", "dump" ], - "time": "2020-01-04T13:00:46+00:00" + "time": "2020-01-25T12:44:29+00:00" }, { "name": "symfony/yaml", - "version": "v4.4.3", + "version": "v4.4.4", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", @@ -5449,7 +5449,7 @@ }, { "name": "symfony/browser-kit", - "version": "v4.4.3", + "version": "v4.4.4", "source": { "type": "git", "url": "https://github.com/symfony/browser-kit.git", @@ -5508,7 +5508,7 @@ }, { "name": "symfony/css-selector", - "version": "v4.4.3", + "version": "v4.4.4", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", @@ -5561,7 +5561,7 @@ }, { "name": "symfony/dom-crawler", - "version": "v4.4.3", + "version": "v4.4.4", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", @@ -5622,7 +5622,7 @@ }, { "name": "symfony/finder", - "version": "v4.4.3", + "version": "v4.4.4", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", diff --git a/system/src/Grav/Common/Flex/Pages/PageIndex.php b/system/src/Grav/Common/Flex/Pages/PageIndex.php index f6118a2ae..31e94875e 100644 --- a/system/src/Grav/Common/Flex/Pages/PageIndex.php +++ b/system/src/Grav/Common/Flex/Pages/PageIndex.php @@ -145,7 +145,7 @@ class PageIndex extends FlexPageIndex /** @var PageObject $root */ $root = $this->getFlexDirectory()->createObject($row, '/', false); $root->name('root.md'); - $root->root = true; + $root->root(true); $this->_root = $root; } diff --git a/system/src/Grav/Common/Flex/Users/UserObject.php b/system/src/Grav/Common/Flex/Users/UserObject.php index b63f19f17..651ebd6a3 100644 --- a/system/src/Grav/Common/Flex/Users/UserObject.php +++ b/system/src/Grav/Common/Flex/Users/UserObject.php @@ -487,6 +487,9 @@ class UserObject extends FlexObject implements UserInterface, MediaManipulationI return $this->_storage; } + /** + * @return bool + */ public function isValid(): bool { return $this->getProperty('state') !== null; diff --git a/system/src/Grav/Common/Page/Pages.php b/system/src/Grav/Common/Page/Pages.php index be30150e5..25d8f64ca 100644 --- a/system/src/Grav/Common/Page/Pages.php +++ b/system/src/Grav/Common/Page/Pages.php @@ -15,6 +15,8 @@ use Grav\Common\Data\Blueprint; use Grav\Common\Data\Blueprints; use Grav\Common\Debugger; use Grav\Common\Filesystem\Folder; +use Grav\Common\Flex\Pages\PageCollection; +use Grav\Common\Flex\Pages\PageIndex; use Grav\Common\Grav; use Grav\Common\Language\Language; use Grav\Common\Page\Interfaces\PageCollectionInterface; @@ -1351,6 +1353,7 @@ class Pages $config = $this->grav['config']; // TODO: right now we are just emulating normal pages, it is inefficient and bad... but works! + /** @var PageCollection|PageIndex $collection */ $collection = $directory->getIndex(null, 'storage_key'); $cache = $directory->getCache('index'); diff --git a/system/src/Grav/Common/Processors/InitializeProcessor.php b/system/src/Grav/Common/Processors/InitializeProcessor.php index bf6b20629..2ec0f4960 100644 --- a/system/src/Grav/Common/Processors/InitializeProcessor.php +++ b/system/src/Grav/Common/Processors/InitializeProcessor.php @@ -13,11 +13,11 @@ use Grav\Common\Config\Config; use Grav\Common\Debugger; use Grav\Common\Page\Pages; use Grav\Common\Plugins; +use Grav\Common\Session; use Grav\Common\Uri; use Grav\Common\Utils; use Grav\Framework\Psr7\Response; use Grav\Framework\Session\Exceptions\SessionException; -use Grav\Framework\Session\SessionInterface; use Monolog\Formatter\LineFormatter; use Monolog\Handler\SyslogHandler; use Psr\Http\Message\ResponseInterface; @@ -211,7 +211,7 @@ class InitializeProcessor extends ProcessorBase // TODO: remove in 2.0. $this->container['accounts']; - /** @var SessionInterface $session */ + /** @var Session $session */ $session = $this->container['session']; try { diff --git a/system/src/Grav/Common/User/DataUser/User.php b/system/src/Grav/Common/User/DataUser/User.php index 7b403ad56..ecd24400c 100644 --- a/system/src/Grav/Common/User/DataUser/User.php +++ b/system/src/Grav/Common/User/DataUser/User.php @@ -80,6 +80,9 @@ class User extends Data implements UserInterface return $value; } + /** + * @return bool + */ public function isValid(): bool { return $this->items !== null; diff --git a/system/src/Grav/Framework/Acl/Access.php b/system/src/Grav/Framework/Acl/Access.php index 6232652c2..7a8681528 100644 --- a/system/src/Grav/Framework/Acl/Access.php +++ b/system/src/Grav/Framework/Acl/Access.php @@ -62,7 +62,12 @@ class Access implements \JsonSerializable, \IteratorAggregate, \Countable $inherited = array_diff_key($parent->getAllActions(), $acl); $this->inherited += $parent->inherited + array_fill_keys(array_keys($inherited), $name ?? $parent->getName()); - $this->acl = array_replace($acl, $inherited); + $acl = array_replace($acl, $inherited); + if (null === $acl) { + throw new \RuntimeException('Internal error'); + } + + $this->acl = $acl; } /** diff --git a/system/src/Grav/Framework/Acl/Action.php b/system/src/Grav/Framework/Acl/Action.php index 9edfe6ad7..8b35afe27 100644 --- a/system/src/Grav/Framework/Acl/Action.php +++ b/system/src/Grav/Framework/Acl/Action.php @@ -91,7 +91,8 @@ class Action implements \IteratorAggregate, \Countable public function getScope(): string { - if (($pos = strpos($this->name, '.')) > 0) { + $pos = strpos($this->name, '.'); + if ($pos > 0) { return substr($this->name, 0, $pos); } diff --git a/system/src/Grav/Framework/Acl/Permissions.php b/system/src/Grav/Framework/Acl/Permissions.php index b927b4eef..19874c1eb 100644 --- a/system/src/Grav/Framework/Acl/Permissions.php +++ b/system/src/Grav/Framework/Acl/Permissions.php @@ -16,6 +16,8 @@ class Permissions implements \ArrayAccess, \Countable, \IteratorAggregate /** @var Action[] */ protected $actions = []; /** @var array */ + protected $nested = []; + /** @var array */ protected $types = []; /** @@ -125,7 +127,12 @@ class Permissions implements \ArrayAccess, \Countable, \IteratorAggregate */ public function addTypes(array $types): void { - $this->types = array_replace($this->types, $types); + $types = array_replace($this->types, $types); + if (null === $types) { + throw new \RuntimeException('Internal error'); + } + + $this->types = $types; } /** diff --git a/system/src/Grav/Framework/Acl/PermissionsReader.php b/system/src/Grav/Framework/Acl/PermissionsReader.php index c031e3f8b..d3bdb3b00 100644 --- a/system/src/Grav/Framework/Acl/PermissionsReader.php +++ b/system/src/Grav/Framework/Acl/PermissionsReader.php @@ -21,6 +21,7 @@ class PermissionsReader */ public static function fromYaml(string $filename): array { + /** @var array $content */ $content = CompiledYamlFile::instance($filename)->content(); $actions = $content['actions'] ?? []; $types = $content['types'] ?? []; @@ -101,7 +102,7 @@ class PermissionsReader } unset($val); } - $dependencies = json_decode(json_encode($dependencies), true); + $dependencies = json_decode(json_encode($dependencies, JSON_THROW_ON_ERROR), true); foreach (static::getDependencies($dependencies) as $type) { $defaults = $types[$type] ?? null; @@ -158,6 +159,9 @@ class PermissionsReader $scopes[] = $action; $action = array_replace_recursive(...$scopes); + if (null === $action) { + throw new \RuntimeException('Internal error'); + } $newType = $defaults['type'] ?? null; if ($newType && $newType !== $type) { diff --git a/system/src/Grav/Framework/Flex/Flex.php b/system/src/Grav/Framework/Flex/Flex.php index 5ddb513ee..a966c65f0 100644 --- a/system/src/Grav/Framework/Flex/Flex.php +++ b/system/src/Grav/Framework/Flex/Flex.php @@ -61,6 +61,9 @@ class Flex implements FlexInterface public function addDirectoryType(string $type, string $blueprint, array $config = []) { $config = array_replace_recursive(['enabled' => true], $this->config ?? [], $config); + if ($config === null) { + throw new \RuntimeException('Internal error'); + } $this->types[$type] = new FlexDirectory($type, $blueprint, $config); diff --git a/system/src/Grav/Framework/Flex/FlexDirectory.php b/system/src/Grav/Framework/Flex/FlexDirectory.php index 78c70292f..067a5b8af 100644 --- a/system/src/Grav/Framework/Flex/FlexDirectory.php +++ b/system/src/Grav/Framework/Flex/FlexDirectory.php @@ -202,6 +202,7 @@ class FlexDirectory implements FlexAuthorizeInterface /** @var UniformResourceLocator $locator */ $locator = $grav['locator']; + /** @var string $filename Filename is always string */ $filename = $locator->findResource($this->getDirectoryConfigUri($name), true, true); $file = YamlFile::instance($filename); @@ -224,6 +225,9 @@ class FlexDirectory implements FlexAuthorizeInterface /** @var UniformResourceLocator $locator */ $locator = $grav['locator']; $filename = $locator->findResource($this->getDirectoryConfigUri($name), true); + if ($filename === false) { + return []; + } $file = YamlFile::instance($filename); diff --git a/system/src/Grav/Framework/Flex/FlexDirectoryForm.php b/system/src/Grav/Framework/Flex/FlexDirectoryForm.php index 00c5db582..4cd721ec2 100644 --- a/system/src/Grav/Framework/Flex/FlexDirectoryForm.php +++ b/system/src/Grav/Framework/Flex/FlexDirectoryForm.php @@ -43,7 +43,7 @@ class FlexDirectoryForm implements FlexDirectoryFormInterface, \JsonSerializable /** @var array|null */ private $form; - /** @var FlexDirectory|null */ + /** @var FlexDirectory */ private $directory; /** @var string */ @@ -116,7 +116,11 @@ class FlexDirectoryForm implements FlexDirectoryFormInterface, \JsonSerializable $data = $flash->getData(); $includeOriginal = (bool)($this->getBlueprint()->form()['images']['original'] ?? null); - $this->directory = $flash->getDirectory(); + $directory = $flash->getDirectory(); + if (null === $directory) { + throw new \RuntimeException('Flash has no directory'); + } + $this->directory = $directory; $this->data = $data ? new Data($data, $this->getBlueprint()) : null; $this->files = $flash->getFilesByFields($includeOriginal); } @@ -191,6 +195,10 @@ class FlexDirectoryForm implements FlexDirectoryFormInterface, \JsonSerializable */ public function getData() { + if (null === $this->data) { + $this->data = new Data([], $this->getBlueprint()); + } + return $this->data; } @@ -262,7 +270,7 @@ class FlexDirectoryForm implements FlexDirectoryFormInterface, \JsonSerializable } /** - * @return FlexObjectInterface + * @return FlexDirectory */ public function getDirectory(): FlexDirectory { @@ -277,9 +285,6 @@ class FlexDirectoryForm implements FlexDirectoryFormInterface, \JsonSerializable if (null === $this->blueprint) { try { $blueprint = $this->getDirectory()->getDirectoryBlueprint(); - if (!$blueprint) { - throw new \RuntimeException('Blueprint not found'); - } if ($this->form) { // We have field overrides available. $blueprint->extend(['form' => $this->form], true); diff --git a/system/src/Grav/Framework/Flex/FlexForm.php b/system/src/Grav/Framework/Flex/FlexForm.php index 86c9e101b..c9a875297 100644 --- a/system/src/Grav/Framework/Flex/FlexForm.php +++ b/system/src/Grav/Framework/Flex/FlexForm.php @@ -140,7 +140,11 @@ class FlexForm implements FlexObjectFormInterface, \JsonSerializable } $includeOriginal = (bool)($this->getBlueprint()->form()['images']['original'] ?? null); - $this->object = $flash->getObject(); + $object = $flash->getObject(); + if (null === $object) { + throw new \RuntimeException('Flash has no object'); + } + $this->object = $object; $this->data = $data; $this->files = $flash->getFilesByFields($includeOriginal); } diff --git a/system/src/Grav/Framework/Flex/FlexFormFlash.php b/system/src/Grav/Framework/Flex/FlexFormFlash.php index 9943a285c..dcbdae80c 100644 --- a/system/src/Grav/Framework/Flex/FlexFormFlash.php +++ b/system/src/Grav/Framework/Flex/FlexFormFlash.php @@ -20,7 +20,7 @@ class FlexFormFlash extends FormFlash /** @var FlexObjectInterface|null */ protected $object; - /** @var Flex */ + /** @var FlexInterface */ static protected $flex; public static function setFlex(FlexInterface $flex): void diff --git a/system/src/Grav/Framework/Flex/FlexObject.php b/system/src/Grav/Framework/Flex/FlexObject.php index 30731e524..608a15780 100644 --- a/system/src/Grav/Framework/Flex/FlexObject.php +++ b/system/src/Grav/Framework/Flex/FlexObject.php @@ -863,7 +863,7 @@ class FlexObject implements FlexObjectInterface, FlexAuthorizeInterface $grav = Grav::instance(); /** @var Flex|null $flex */ $flex = $grav['flex']; - $directory = $flex->getDirectory($type); + $directory = $flex ? $flex->getDirectory($type) : null; if (!$directory) { throw new \InvalidArgumentException("Cannot unserialize Flex type '{$type}': Directory not found"); } diff --git a/system/src/Grav/Framework/Flex/Pages/FlexPageObject.php b/system/src/Grav/Framework/Flex/Pages/FlexPageObject.php index d0c5b0a2d..ed937bb2a 100644 --- a/system/src/Grav/Framework/Flex/Pages/FlexPageObject.php +++ b/system/src/Grav/Framework/Flex/Pages/FlexPageObject.php @@ -173,7 +173,7 @@ class FlexPageObject extends FlexObject implements PageInterface, MediaManipulat case 'route': return $this->hasKey() ? '/' . $this->getKey() : null; case 'header.permissions.groups': - return json_decode(json_encode($this->getPermissions()), true); + return json_decode(json_encode($this->getPermissions(), JSON_THROW_ON_ERROR), true); } return parent::getFormValue($name, $default, $separator); diff --git a/system/src/Grav/Framework/Flex/Pages/Traits/PageRoutableTrait.php b/system/src/Grav/Framework/Flex/Pages/Traits/PageRoutableTrait.php index bfcaa7453..ee5f9d78d 100644 --- a/system/src/Grav/Framework/Flex/Pages/Traits/PageRoutableTrait.php +++ b/system/src/Grav/Framework/Flex/Pages/Traits/PageRoutableTrait.php @@ -529,10 +529,15 @@ trait PageRoutableTrait /** * Returns whether or not this page is the root node of the pages tree. * + * @param bool|null $var * @return bool True if it is the root */ - public function root(): bool + public function root($var = null): bool { + if (null !== $var) { + $this->root = (bool)$var; + } + return $this->root === true || $this->getKey() === '/'; } diff --git a/system/src/Grav/Framework/Flex/Storage/FolderStorage.php b/system/src/Grav/Framework/Flex/Storage/FolderStorage.php index c90d15ce1..c41d7da6b 100644 --- a/system/src/Grav/Framework/Flex/Storage/FolderStorage.php +++ b/system/src/Grav/Framework/Flex/Storage/FolderStorage.php @@ -404,6 +404,7 @@ class FolderStorage extends AbstractFilesystemStorage */ protected function deleteFile(File $file) { + $filename = $file->filename(); try { $data = $file->content(); if ($file->exists()) { @@ -412,11 +413,11 @@ class FolderStorage extends AbstractFilesystemStorage /** @var UniformResourceLocator $locator */ $locator = Grav::instance()['locator']; - if ($locator->isStream($file->filename())) { - $locator->clearCache($file->filename()); + if ($locator->isStream($filename)) { + $locator->clearCache($filename); } } catch (\RuntimeException $e) { - throw new \RuntimeException(sprintf('Flex deleteFile(%s): %s', $file->filename(), $e->getMessage())); + throw new \RuntimeException(sprintf('Flex deleteFile(%s): %s', $filename, $e->getMessage())); } return $data; diff --git a/system/src/Grav/Framework/Form/Traits/FormTrait.php b/system/src/Grav/Framework/Form/Traits/FormTrait.php index 2d264b667..9fbf8e28b 100644 --- a/system/src/Grav/Framework/Form/Traits/FormTrait.php +++ b/system/src/Grav/Framework/Form/Traits/FormTrait.php @@ -218,26 +218,41 @@ trait FormTrait return $this; } + /** + * @return bool + */ public function isValid(): bool { return $this->status === 'success'; } + /** + * @return string|null + */ public function getError(): ?string { return !$this->isValid() ? $this->message : null; } + /** + * @return array + */ public function getErrors(): array { return !$this->isValid() ? $this->messages : []; } + /** + * @return bool + */ public function isSubmitted(): bool { return $this->submitted; } + /** + * @return bool + */ public function validate(): bool { if (!$this->isValid()) { @@ -309,16 +324,25 @@ trait FormTrait $this->flash = null; } + /** + * @return array + */ public function getFields(): array { return $this->getBlueprint()->fields(); } + /** + * @return array + */ public function getButtons(): array { return $this->getBlueprint()->get('form/buttons') ?? []; } + /** + * @return array + */ public function getTasks(): array { return $this->getBlueprint()->get('form/tasks') ?? []; diff --git a/system/src/Grav/Framework/Route/RouteFactory.php b/system/src/Grav/Framework/Route/RouteFactory.php index 228048e5c..08f695abc 100644 --- a/system/src/Grav/Framework/Route/RouteFactory.php +++ b/system/src/Grav/Framework/Route/RouteFactory.php @@ -90,7 +90,7 @@ class RouteFactory } /** - * @param $root + * @param string $root */ public static function setRoot($root): void { diff --git a/system/src/Grav/Framework/Session/Session.php b/system/src/Grav/Framework/Session/Session.php index 26e0c6847..88cb44ce8 100644 --- a/system/src/Grav/Framework/Session/Session.php +++ b/system/src/Grav/Framework/Session/Session.php @@ -206,7 +206,7 @@ class Session implements SessionInterface $this->onSessionStart(); $user = $this->__get('user'); - if ($user && (!$user instanceof UserInterface || !$user->isValid())) { + if ($user && (!$user instanceof UserInterface || (method_exists($user, 'isValid') && !$user->isValid()))) { $this->invalidate(); throw new SessionException('Invalid User object, session destroyed.', 500); diff --git a/tests/phpstan/phpstan.neon b/tests/phpstan/phpstan.neon index 9e8dcb36a..9f3d21c5b 100644 --- a/tests/phpstan/phpstan.neon +++ b/tests/phpstan/phpstan.neon @@ -28,11 +28,15 @@ parameters: # TODO: Errors that needs some more thinking (bad design?) - '#Access to an undefined property RocketTheme\\Toolbox\\Event\\Event::#' + - '#Instantiation of deprecated class RocketTheme\\Toolbox\\Event\\Event#' + - '#extends deprecated class RocketTheme\\Toolbox\\Event\\Event#' + - '#implements deprecated interface RocketTheme\\Toolbox\\Event\\EventSubscriberInterface#' - '#Access to an undefined property Grav\\Common\\Data\\Blueprint::#' - '#Access to an undefined property Grav\\Common\\Media\\Interfaces\\MediaObjectInterface::#' - message: '#Cannot call method path\(\) on string#' path: 'system/src/Grav/Common/Page/Media.php' + - '"FlexCollectionInterface::filterBy\(\) invoked with 2 parameters"' # TODO: system.twig.umask_fix will not work with Twig 2 anymore -