From 78a306ddae35783a77bbe60c082511df0b0121ba Mon Sep 17 00:00:00 2001 From: Tac Tacelosky Date: Thu, 10 Nov 2022 09:13:07 -0500 Subject: [PATCH 1/3] Add Symfony 6.2 to matrix (#183) From bb7087f58bc40d9d1b3c319056d33baa1b61d23c Mon Sep 17 00:00:00 2001 From: Tac Tacelosky Date: Thu, 10 Nov 2022 09:13:07 -0500 Subject: [PATCH 2/3] Add Symfony 6.2 to matrix (#183) From f6e4448c11cad30b5a8644adfc7a1d4f97ee412c Mon Sep 17 00:00:00 2001 From: PedroTroller Date: Thu, 25 May 2023 09:43:44 +0200 Subject: [PATCH 3/3] refactor: set phpstan level to max --- .php-cs-fixer.dist.php | 1 + phpstan-baseline.neon | 11 ++ phpstan.neon.dist | 5 +- rector.php | 3 + .../Compiler/DictionaryBuildingPassSpec.php | 15 +- .../Dictionary/CollectionSpec.php | 14 +- .../Dictionary/CombinedSpec.php | 130 +++++------------- .../Dictionary/DictionaryBehavior.php | 66 +++++++++ .../Dictionary/Factory/AggregateSpec.php | 7 +- .../Dictionary/Factory/CombinedSpec.php | 7 +- .../Dictionary/Factory/ExtendedSpec.php | 7 +- .../Dictionary/InvokableSpec.php | 5 +- .../Dictionary/IteratorSpec.php | 52 ++----- .../Dictionary/SimpleSpec.php | 30 +--- .../Faker/Provider/DictionarySpec.php | 5 +- .../Templating/Extension/DictionarySpec.php | 28 ++-- .../Constraints/DictionaryValidatorSpec.php | 12 +- spec/PHPSpec/OneOfMatcher.php | 22 +-- .../DataCollector/DictionaryDataCollector.php | 16 ++- .../Compiler/DictionaryBuildingPass.php | 2 +- .../DictionaryFactoryBuildingPass.php | 2 +- .../Compiler/DictionaryRegistrationPass.php | 2 +- .../Compiler/DictionaryTracePass.php | 2 +- src/Knp/DictionaryBundle/Dictionary.php | 21 ++- .../Dictionary/Collection.php | 24 ++-- .../DictionaryBundle/Dictionary/Combined.php | 13 +- .../DictionaryBundle/Dictionary/Factory.php | 2 +- .../Dictionary/Factory/Combined.php | 26 +++- .../Dictionary/Factory/Extended.php | 5 +- .../Dictionary/Factory/Invokable.php | 20 ++- .../Dictionary/Factory/Iterator.php | 4 +- .../Dictionary/Factory/KeyValue.php | 4 +- .../Dictionary/Factory/Value.php | 4 +- .../Dictionary/Factory/ValueAsKey.php | 11 +- .../DictionaryBundle/Dictionary/Invokable.php | 78 ++++++----- .../DictionaryBundle/Dictionary/Iterator.php | 7 +- .../DictionaryBundle/Dictionary/Simple.php | 24 ++-- .../DictionaryBundle/Dictionary/Traceable.php | 14 +- .../DictionaryBundle/Dictionary/Wrapper.php | 15 +- .../Exception/DictionaryNotFoundException.php | 9 +- .../Faker/Provider/Dictionary.php | 8 +- .../Templating/Extension/Dictionary.php | 10 +- .../Constraints/DictionaryValidator.php | 9 +- .../ValueTransformer/Constant.php | 3 + 44 files changed, 417 insertions(+), 338 deletions(-) create mode 100644 phpstan-baseline.neon create mode 100644 spec/Knp/DictionaryBundle/Dictionary/DictionaryBehavior.php diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index 96e46e57..dbbdfc0e 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -30,6 +30,7 @@ ->enable('ordered_imports') ->enable('ordered_interfaces') ->enable('phpdoc_line_span') + ->enable('PedroTroller/line_break_between_method_arguments', ['max-length' => 80]) ->disable('method_chaining_indentation') ->disable('no_break_comment') ->disable('no_superfluous_phpdoc_tags') diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon new file mode 100644 index 00000000..156e6e74 --- /dev/null +++ b/phpstan-baseline.neon @@ -0,0 +1,11 @@ +parameters: + ignoreErrors: + - + message: "#^Method Knp\\\\DictionaryBundle\\\\Dictionary\\\\Factory\\\\Value\\:\\:create\\(\\) should return Knp\\\\DictionaryBundle\\\\Dictionary\\ but returns Knp\\\\DictionaryBundle\\\\Dictionary\\\\Simple\\\\.$#" + count: 1 + path: src/Knp/DictionaryBundle/Dictionary/Factory/Value.php + + - + message: "#^Parameter \\#1 \\$array of function array_flip expects array\\, array\\ given\\.$#" + count: 1 + path: src/Knp/DictionaryBundle/Form/Type/DictionaryType.php diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 253e9e6c..34bda530 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -1,5 +1,8 @@ +includes: + - phpstan-baseline.neon + parameters: - level: 8 + level: max paths: - src - spec/PHPSpec diff --git a/rector.php b/rector.php index 15405a8b..a6c24568 100644 --- a/rector.php +++ b/rector.php @@ -5,6 +5,7 @@ use Rector\Config\RectorConfig; use Rector\Core\ValueObject\PhpVersion; use Rector\Set\ValueObject\LevelSetList; +use Rector\Set\ValueObject\SetList; return static function (RectorConfig $rectorConfig): void { $rectorConfig @@ -25,6 +26,8 @@ ->sets( [ LevelSetList::UP_TO_PHP_80, + SetList::CODE_QUALITY, + SetList::DEAD_CODE, ] ) ; diff --git a/spec/Knp/DictionaryBundle/DependencyInjection/Compiler/DictionaryBuildingPassSpec.php b/spec/Knp/DictionaryBundle/DependencyInjection/Compiler/DictionaryBuildingPassSpec.php index 87b7f700..b6cc2119 100644 --- a/spec/Knp/DictionaryBundle/DependencyInjection/Compiler/DictionaryBuildingPassSpec.php +++ b/spec/Knp/DictionaryBundle/DependencyInjection/Compiler/DictionaryBuildingPassSpec.php @@ -20,8 +20,9 @@ function it_is_initializable() $this->shouldHaveType(DictionaryBuildingPass::class); } - function it_builds_a_value_as_key_dictionary_from_the_config(ContainerBuilder $container) - { + function it_builds_a_value_as_key_dictionary_from_the_config( + ContainerBuilder $container + ) { $config = [ 'dictionaries' => [ 'dico1' => [ @@ -66,8 +67,9 @@ function it_builds_a_value_as_key_dictionary_from_the_config(ContainerBuilder $c $this->process($container); } - function it_builds_a_value_dictionary_from_the_config(ContainerBuilder $container) - { + function it_builds_a_value_dictionary_from_the_config( + ContainerBuilder $container + ) { $config = [ 'dictionaries' => [ 'dico1' => [ @@ -109,8 +111,9 @@ function it_builds_a_value_dictionary_from_the_config(ContainerBuilder $containe $this->process($container); } - function it_builds_a_key_value_dictionary_from_the_config(ContainerBuilder $container) - { + function it_builds_a_key_value_dictionary_from_the_config( + ContainerBuilder $container + ) { $config = [ 'dictionaries' => [ 'dico1' => [ diff --git a/spec/Knp/DictionaryBundle/Dictionary/CollectionSpec.php b/spec/Knp/DictionaryBundle/Dictionary/CollectionSpec.php index 39240a42..8ec3d753 100644 --- a/spec/Knp/DictionaryBundle/Dictionary/CollectionSpec.php +++ b/spec/Knp/DictionaryBundle/Dictionary/CollectionSpec.php @@ -14,10 +14,10 @@ final class CollectionSpec extends ObjectBehavior { - function let(Dictionary $dictionary, Dictionary $dictionary2) + function let(Dictionary $dictionary1, Dictionary $dictionary2) { - $this->beConstructedWith($dictionary, $dictionary2); - $dictionary->getName()->willReturn('foo'); + $this->beConstructedWith($dictionary1, $dictionary2); + $dictionary1->getName()->willReturn('foo'); $dictionary2->getName()->willReturn('dictionary'); } @@ -49,13 +49,13 @@ function it_should_entry_if_it_exists() function it_counts_entries() { - $this->count()->shouldReturn(2); + $this->shouldHaveCount(2); } - function it_is_a_list_ob_dictionaries($dictionary, $dictionary2) + function it_is_a_list_of_dictionaries($dictionary1, $dictionary2) { - $this->getIterator()->getArrayCopy()->shouldReturn([ - 'foo' => $dictionary, + $this->shouldYieldLike([ + 'foo' => $dictionary1, 'dictionary' => $dictionary2, ]); } diff --git a/spec/Knp/DictionaryBundle/Dictionary/CombinedSpec.php b/spec/Knp/DictionaryBundle/Dictionary/CombinedSpec.php index 0bc622e3..e7f94386 100644 --- a/spec/Knp/DictionaryBundle/Dictionary/CombinedSpec.php +++ b/spec/Knp/DictionaryBundle/Dictionary/CombinedSpec.php @@ -4,20 +4,38 @@ namespace spec\Knp\DictionaryBundle\Dictionary; -use ArrayIterator; use Knp\DictionaryBundle\Dictionary; use Knp\DictionaryBundle\Dictionary\Combined; use PhpSpec\ObjectBehavior; final class CombinedSpec extends ObjectBehavior { - function let(Dictionary $dictionary1, Dictionary $dictionary2, Dictionary $dictionary3) + use DictionaryBehavior; + + function let() { $this->beConstructedWith( 'combined_dictionary', - $dictionary1, - $dictionary2, - $dictionary3 + new Dictionary\Simple( + 'dictionary1', + [ + 'foo' => 1, + 'bar' => 2, + ] + ), + new Dictionary\Simple( + 'dictionary2', + [ + 'bar' => 3, + 'baz' => 4, + ] + ), + new Dictionary\Simple( + 'dictionary3', + [ + 'baz' => 5, + ] + ), ); } @@ -26,103 +44,17 @@ function it_is_initializable() $this->shouldHaveType(Combined::class); } - function it_is_a_dictionary() - { - $this->shouldImplement(Dictionary::class); - } - - function it_access_to_value_like_an_array($dictionary1, $dictionary2, $dictionary3) + protected function getExpectedResult(): array { - $dictionary1->getIterator()->willReturn(new ArrayIterator(['foo1' => 'foo10'])); - - $dictionary2->getIterator()->willReturn(new ArrayIterator(['bar1' => 'bar10'])); - - $dictionary3->getIterator()->willReturn(new ArrayIterator(['baz1' => 'baz10'])); - - $this['foo1']->shouldBe('foo10'); - $this['bar1']->shouldBe('bar10'); - $this['baz1']->shouldBe('baz10'); - } - - function it_getvalues_should_return_dictionaries_values($dictionary1, $dictionary2, $dictionary3) - { - $dictionary1->getIterator()->willReturn(new ArrayIterator([ - 'foo1' => 'foo10', - 'foo2' => 'foo20', - ])); - - $dictionary2->getIterator()->willReturn(new ArrayIterator([ - 'bar1' => 'bar10', - 'bar2' => 'bar20', - ])); - - $dictionary3->getIterator()->willReturn(new ArrayIterator([ - 'foo1' => 'baz10', - 'bar2' => 'baz20', - ])); - - $this->getKeys()->shouldReturn([ - 'foo1', - 'foo2', - 'bar1', - 'bar2', - ]); - $this->getValues()->shouldReturn([ - 'foo1' => 'baz10', - 'foo2' => 'foo20', - 'bar1' => 'bar10', - 'bar2' => 'baz20', - ]); - } - - function it_can_iterate_over_dictionaries($dictionary1, $dictionary2, $dictionary3) - { - $dictionary1->getIterator()->willReturn(new ArrayIterator([ - 'foo1' => 'foo10', - 'foo2' => 'foo20', - ])); - - $dictionary2->getIterator()->willReturn(new ArrayIterator([ - 'bar1' => 'bar10', - 'bar2' => 'bar20', - ])); - - $dictionary3->getIterator()->willReturn(new ArrayIterator([ - 'foo2' => 'baz20', - 'bar2' => 'baz20', - ])); - - $this->shouldIterateLike([ - 'foo1' => 'foo10', - 'foo2' => 'baz20', - 'bar1' => 'bar10', - 'bar2' => 'baz20', - ]); - } - - function it_sums_the_count_of_elements($dictionary1, $dictionary2, $dictionary3) - { - $dictionary1->getIterator()->willReturn(new ArrayIterator([ - 'foo1' => 'foo10', - ])); - - $dictionary2->getIterator()->willReturn(new ArrayIterator([ - 'bar1' => 'bar10', - 'bar2' => 'bar20', - ])); - - $dictionary3->getIterator()->willReturn(new ArrayIterator([ - 'baz1' => 'baz10', - 'baz2' => 'baz20', - 'baz3' => 'baz30', - 'baz4' => 'baz40', - ])); - - $this->count()->shouldReturn(7); + return [ + 'foo' => 1, + 'bar' => 3, + 'baz' => 5, + ]; } - function its_getname_should_return_dictionary_name() + protected function getExpectedName(): string { - $this->getName()->shouldReturn('combined_dictionary'); + return 'combined_dictionary'; } } diff --git a/spec/Knp/DictionaryBundle/Dictionary/DictionaryBehavior.php b/spec/Knp/DictionaryBundle/Dictionary/DictionaryBehavior.php new file mode 100644 index 00000000..b6760e00 --- /dev/null +++ b/spec/Knp/DictionaryBundle/Dictionary/DictionaryBehavior.php @@ -0,0 +1,66 @@ +shouldImplement(Dictionary::class) + ; + } + + public function it_access_to_value_like_an_array(): void + { + foreach ($this->getExpectedResult() as $key => $value) { + $this[$key]->shouldBe($value); + } + } + + public function it_provides_keys(): void + { + $this + ->getKeys() + ->shouldReturn(array_keys($this->getExpectedResult())) + ; + } + + public function it_provides_values(): void + { + $this + ->getValues() + ->shouldReturn(array_values($this->getExpectedResult())) + ; + } + + public function it_provides_combination_of_keys_and_values(): void + { + $this + ->shouldYieldLike($this->getExpectedResult()) + ; + } + + public function it_is_countable(): void + { + $this + ->shouldHaveCount(\count($this->getExpectedResult())) + ; + } + + public function it_has_a_name(): void + { + $this + ->getName() + ->shouldReturn($this->getExpectedName()) + ; + } + + abstract protected function getExpectedResult(): array; + + abstract protected function getExpectedName(): string; +} diff --git a/spec/Knp/DictionaryBundle/Dictionary/Factory/AggregateSpec.php b/spec/Knp/DictionaryBundle/Dictionary/Factory/AggregateSpec.php index f271e44a..1a8e7efb 100644 --- a/spec/Knp/DictionaryBundle/Dictionary/Factory/AggregateSpec.php +++ b/spec/Knp/DictionaryBundle/Dictionary/Factory/AggregateSpec.php @@ -22,8 +22,11 @@ function it_is_a_factory() $this->shouldHaveType(Factory::class); } - function it_supports_if_one_factory_supports(Factory $factory1, Factory $factory2, Factory $factory3) - { + function it_supports_if_one_factory_supports( + Factory $factory1, + Factory $factory2, + Factory $factory3 + ) { $this->addFactory($factory1); $this->addFactory($factory2); diff --git a/spec/Knp/DictionaryBundle/Dictionary/Factory/CombinedSpec.php b/spec/Knp/DictionaryBundle/Dictionary/Factory/CombinedSpec.php index 6641956b..c20be932 100644 --- a/spec/Knp/DictionaryBundle/Dictionary/Factory/CombinedSpec.php +++ b/spec/Knp/DictionaryBundle/Dictionary/Factory/CombinedSpec.php @@ -33,8 +33,11 @@ function it_supports_specific_config() $this->supports(['type' => 'combined'])->shouldReturn(true); } - function it_creates_a_dictionary(Dictionary $dictionary1, Dictionary $dictionary2, Dictionary $dictionary3) - { + function it_creates_a_dictionary( + Dictionary $dictionary1, + Dictionary $dictionary2, + Dictionary $dictionary3 + ) { $dictionary1->getIterator()->willReturn(new ArrayIterator(['foo1' => 'foo10', 'foo2' => 'foo20'])); $dictionary1->getName()->willReturn('dictionary1'); diff --git a/spec/Knp/DictionaryBundle/Dictionary/Factory/ExtendedSpec.php b/spec/Knp/DictionaryBundle/Dictionary/Factory/ExtendedSpec.php index ff6263fd..c62dfc05 100644 --- a/spec/Knp/DictionaryBundle/Dictionary/Factory/ExtendedSpec.php +++ b/spec/Knp/DictionaryBundle/Dictionary/Factory/ExtendedSpec.php @@ -33,8 +33,11 @@ function it_supports_specific_config() $this->supports(['extends' => 'my_dictionary'])->shouldReturn(true); } - function it_creates_a_dictionary($factory, Dictionary $initialDictionary, Dictionary $extendsDictionary) - { + function it_creates_a_dictionary( + $factory, + Dictionary $initialDictionary, + Dictionary $extendsDictionary + ) { $initialDictionary->getName()->willReturn('initial_dictionary'); $initialDictionary->getIterator()->willReturn(new ArrayIterator(['foo1', 'foo2'])); diff --git a/spec/Knp/DictionaryBundle/Dictionary/InvokableSpec.php b/spec/Knp/DictionaryBundle/Dictionary/InvokableSpec.php index 640bba2b..c3834e34 100644 --- a/spec/Knp/DictionaryBundle/Dictionary/InvokableSpec.php +++ b/spec/Knp/DictionaryBundle/Dictionary/InvokableSpec.php @@ -101,8 +101,9 @@ function it_access_to_value_like_an_array() $this['baz']->shouldReturn(2); } - function it_throws_an_exception_if_callable_returns_somthing_else_than_an_array_or_an_array_access($nothing) - { + function it_throws_an_exception_if_callable_returns_somthing_else_than_an_array_or_an_array_access( + $nothing + ) { $this->beConstructedWith('foo', function (): void {}); $this diff --git a/spec/Knp/DictionaryBundle/Dictionary/IteratorSpec.php b/spec/Knp/DictionaryBundle/Dictionary/IteratorSpec.php index 9804485f..a8368307 100644 --- a/spec/Knp/DictionaryBundle/Dictionary/IteratorSpec.php +++ b/spec/Knp/DictionaryBundle/Dictionary/IteratorSpec.php @@ -5,12 +5,14 @@ namespace spec\Knp\DictionaryBundle\Dictionary; use Exception; -use Knp\DictionaryBundle\Dictionary; use Knp\DictionaryBundle\Dictionary\Iterator; use PhpSpec\ObjectBehavior; +use Webmozart\Assert\Assert; final class IteratorSpec extends ObjectBehavior { + use DictionaryBehavior; + /** * @var bool */ @@ -28,11 +30,6 @@ function it_is_initializable() $this->shouldHaveType(Iterator::class); } - function it_is_a_dictionary() - { - $this->shouldImplement(Dictionary::class); - } - function it_supports_some_array_access_functions() { $dictionary = $this->getWrappedObject(); @@ -47,58 +44,39 @@ function it_supports_some_array_access_functions() $this->shouldNotHaveKey('foo'); } - function it_provides_a_set_of_values() - { - $this->getValues()->shouldReturn([ - 'foo' => 0, - 'bar' => 1, - 'baz' => 2, - ]); - } - - function it_provides_a_set_of_keys() - { - $this->getKeys()->shouldReturn([ - 'foo', - 'bar', - 'baz', - ]); - } - function it_is_hydrated_just_once() { - $this->getValues()->shouldReturn([ + Assert::false($this->executed); + + $this->shouldYieldLike([ 'foo' => 0, 'bar' => 1, 'baz' => 2, ]); - $this->getValues()->shouldReturn([ + Assert::true($this->executed); + + $this->shouldYieldLike([ 'foo' => 0, 'bar' => 1, 'baz' => 2, ]); - } - function it_access_to_value_like_an_array() - { - $this['foo']->shouldReturn(0); - $this['bar']->shouldReturn(1); - $this['baz']->shouldReturn(2); + Assert::true($this->executed); } - function it_generates_an_iterator() + protected function getExpectedResult(): array { - $this->shouldIterateLike([ + return [ 'foo' => 0, 'bar' => 1, 'baz' => 2, - ]); + ]; } - function its_getname_should_return_dictionary_name() + protected function getExpectedName(): string { - $this->getName()->shouldReturn('foo'); + return 'foo'; } private function execution(): iterable diff --git a/spec/Knp/DictionaryBundle/Dictionary/SimpleSpec.php b/spec/Knp/DictionaryBundle/Dictionary/SimpleSpec.php index c30fb6a4..c70b0677 100644 --- a/spec/Knp/DictionaryBundle/Dictionary/SimpleSpec.php +++ b/spec/Knp/DictionaryBundle/Dictionary/SimpleSpec.php @@ -4,12 +4,13 @@ namespace spec\Knp\DictionaryBundle\Dictionary; -use Knp\DictionaryBundle\Dictionary; use Knp\DictionaryBundle\Dictionary\Simple; use PhpSpec\ObjectBehavior; final class SimpleSpec extends ObjectBehavior { + use DictionaryBehavior; + function let() { $this->beConstructedWith('foo', [ @@ -24,34 +25,17 @@ function it_is_initializable() $this->shouldHaveType(Simple::class); } - function it_is_a_dictionary() - { - $this->shouldImplement(Dictionary::class); - } - - function it_access_to_value_like_an_array() + protected function getExpectedResult(): array { - $this['foo']->shouldReturn(0); - $this['bar']->shouldReturn(1); - $this['baz']->shouldReturn(2); - } - - function its_getvalues_should_return_dictionary_values() - { - $this->getValues()->shouldReturn([ + return [ 'foo' => 0, 'bar' => 1, 'baz' => 2, - ]); - } - - function its_getname_should_return_dictionary_name() - { - $this->getName()->shouldReturn('foo'); + ]; } - function it_is_countable() + protected function getExpectedName(): string { - $this->count()->shouldReturn(3); + return 'foo'; } } diff --git a/spec/Knp/DictionaryBundle/Faker/Provider/DictionarySpec.php b/spec/Knp/DictionaryBundle/Faker/Provider/DictionarySpec.php index f4f9be5f..01b51781 100644 --- a/spec/Knp/DictionaryBundle/Faker/Provider/DictionarySpec.php +++ b/spec/Knp/DictionaryBundle/Faker/Provider/DictionarySpec.php @@ -38,8 +38,9 @@ function it_can_generates_random_values(Dictionary $dictionary) $this->dictionary('the_dico')->shouldBeOneOf('foo', 'bar', 'baz'); } - function it_can_generates_unique_random_values(Dictionary $dictionary) - { + function it_can_generates_unique_random_values( + Dictionary $dictionary + ) { $dictionary->getName()->willReturn('the_dico'); $dictionary->getKeys()->willReturn(['foo', 'bar', 'baz']); diff --git a/spec/Knp/DictionaryBundle/Templating/Extension/DictionarySpec.php b/spec/Knp/DictionaryBundle/Templating/Extension/DictionarySpec.php index 5c670f90..d7c74593 100644 --- a/spec/Knp/DictionaryBundle/Templating/Extension/DictionarySpec.php +++ b/spec/Knp/DictionaryBundle/Templating/Extension/DictionarySpec.php @@ -12,15 +12,21 @@ final class DictionarySpec extends ObjectBehavior { - function let(Dictionary $dico1, Dictionary $dico2) - { - $dico1->offsetGet('foo')->willReturn('bar'); - $dico1->getName()->willReturn('test'); - - $dico2->offsetGet('foo')->willReturn(false); - $dico2->getName()->willReturn('other'); + private Dictionary $dictionary1; + private Dictionary $dictionary2; - $this->beConstructedWith(new Collection($dico1->getWrappedObject(), $dico2->getWrappedObject())); + function let() + { + $this->dictionary1 = new Dictionary\Simple( + 'test', + ['foo' => 'bar'], + ); + $this->dictionary2 = new Dictionary\Simple( + 'other', + ['foo' => false], + ); + + $this->beConstructedWith(new Collection($this->dictionary1, $this->dictionary2)); } function it_is_initializable() @@ -37,13 +43,13 @@ function it_has_a_filter_and_a_function() $functions[0]->getName()->shouldReturn('dictionary'); } - function it_returns_a_dictionary_by_its_name($dico1, $dico2) + function it_returns_a_dictionary_by_its_name() { $functions = $this->getFunctions(); $callable = current($functions->getWrappedObject())->getCallable(); - Assert::eq($callable('test'), $dico1->getWrappedObject()); - Assert::eq($callable('other'), $dico2->getWrappedObject()); + Assert::eq($callable('test'), $this->dictionary1); + Assert::eq($callable('other'), $this->dictionary2); } function it_returns_a_value_from_a_dictionary() diff --git a/spec/Knp/DictionaryBundle/Validator/Constraints/DictionaryValidatorSpec.php b/spec/Knp/DictionaryBundle/Validator/Constraints/DictionaryValidatorSpec.php index 6fe6fb20..fb49cb91 100644 --- a/spec/Knp/DictionaryBundle/Validator/Constraints/DictionaryValidatorSpec.php +++ b/spec/Knp/DictionaryBundle/Validator/Constraints/DictionaryValidatorSpec.php @@ -16,8 +16,10 @@ final class DictionaryValidatorSpec extends ObjectBehavior { - function let(ExecutionContextInterface $context, Dictionary $dictionary) - { + function let( + ExecutionContextInterface $context, + Dictionary $dictionary + ) { $dictionary->getName()->willReturn('dico'); $dictionary->getKeys()->willReturn(['the_key']); @@ -59,8 +61,10 @@ function it_adds_violation_for_an_unexisting_keys($context) $this->validate('the_unexisting_key', $constraint); } - function it_transforms_keys_in_string_representation($dictionary, $context) - { + function it_transforms_keys_in_string_representation( + $dictionary, + $context + ) { $dictionary->getKeys()->willReturn(['the_key', true, 12, 3.14, 0.0, null]); $constraint = new Constraint(['name' => 'dico']); diff --git a/spec/PHPSpec/OneOfMatcher.php b/spec/PHPSpec/OneOfMatcher.php index d6a7eb68..b641cb4c 100644 --- a/spec/PHPSpec/OneOfMatcher.php +++ b/spec/PHPSpec/OneOfMatcher.php @@ -32,12 +32,15 @@ protected function matches($subject, array $arguments): bool } /** - * @param mixed $subject + * @param string $subject * @param mixed[] $arguments */ - protected function getFailureException(string $name, $subject, array $arguments): FailureException - { - if (1 === \count($arguments) && \is_array(current($arguments))) { + protected function getFailureException( + string $name, + $subject, + array $arguments + ): FailureException { + if ([] !== \count($arguments) && \is_array(current($arguments))) { $arguments = current($arguments); } @@ -51,12 +54,15 @@ protected function getFailureException(string $name, $subject, array $arguments) } /** - * @param mixed $subject + * @param string $subject * @param mixed[] $arguments */ - protected function getNegativeFailureException(string $name, $subject, array $arguments): FailureException - { - if (1 === \count($arguments) && \is_array(current($arguments))) { + protected function getNegativeFailureException( + string $name, + $subject, + array $arguments + ): FailureException { + if ([] !== \count($arguments) && \is_array(current($arguments))) { $arguments = current($arguments); } diff --git a/src/Knp/DictionaryBundle/DataCollector/DictionaryDataCollector.php b/src/Knp/DictionaryBundle/DataCollector/DictionaryDataCollector.php index 148611f8..c487efb3 100644 --- a/src/Knp/DictionaryBundle/DataCollector/DictionaryDataCollector.php +++ b/src/Knp/DictionaryBundle/DataCollector/DictionaryDataCollector.php @@ -10,16 +10,26 @@ use Symfony\Component\HttpKernel\DataCollector\DataCollector; use Throwable; +/** + * @property array> $data + */ final class DictionaryDataCollector extends DataCollector { - public function collect(Request $request, Response $response, Throwable $exception = null): void {} + public function collect( + Request $request, + Response $response, + Throwable $exception = null + ): void {} /** * @param array $keys * @param array $values */ - public function addDictionary(string $name, array $keys, array $values): void - { + public function addDictionary( + string $name, + array $keys, + array $values + ): void { $this->data[$name] = array_map( static fn ($key, $value): array => ['key' => $key, 'value' => $value], $keys, diff --git a/src/Knp/DictionaryBundle/DependencyInjection/Compiler/DictionaryBuildingPass.php b/src/Knp/DictionaryBundle/DependencyInjection/Compiler/DictionaryBuildingPass.php index 5211a83b..ba7ed8a2 100644 --- a/src/Knp/DictionaryBundle/DependencyInjection/Compiler/DictionaryBuildingPass.php +++ b/src/Knp/DictionaryBundle/DependencyInjection/Compiler/DictionaryBuildingPass.php @@ -18,7 +18,7 @@ public function process(ContainerBuilder $container): void { $configuration = $container->getParameter('knp_dictionary.configuration'); - if (false === \is_array($configuration)) { + if (!\is_array($configuration)) { throw new Exception('The configuration "knp_dictionary.dictionaries" should be an array.'); } diff --git a/src/Knp/DictionaryBundle/DependencyInjection/Compiler/DictionaryFactoryBuildingPass.php b/src/Knp/DictionaryBundle/DependencyInjection/Compiler/DictionaryFactoryBuildingPass.php index a39a92b8..8fe01ab3 100644 --- a/src/Knp/DictionaryBundle/DependencyInjection/Compiler/DictionaryFactoryBuildingPass.php +++ b/src/Knp/DictionaryBundle/DependencyInjection/Compiler/DictionaryFactoryBuildingPass.php @@ -18,7 +18,7 @@ final class DictionaryFactoryBuildingPass implements CompilerPassInterface public function process(ContainerBuilder $container): void { - foreach ($container->findTaggedServiceIds(self::TAG_FACTORY) as $id => $tags) { + foreach (array_keys($container->findTaggedServiceIds(self::TAG_FACTORY)) as $id) { $container ->findDefinition(Aggregate::class) ->addMethodCall('addFactory', [new Reference($id)]) diff --git a/src/Knp/DictionaryBundle/DependencyInjection/Compiler/DictionaryRegistrationPass.php b/src/Knp/DictionaryBundle/DependencyInjection/Compiler/DictionaryRegistrationPass.php index 717a2158..e32cdbcf 100644 --- a/src/Knp/DictionaryBundle/DependencyInjection/Compiler/DictionaryRegistrationPass.php +++ b/src/Knp/DictionaryBundle/DependencyInjection/Compiler/DictionaryRegistrationPass.php @@ -18,7 +18,7 @@ final class DictionaryRegistrationPass implements CompilerPassInterface public function process(ContainerBuilder $container): void { - foreach ($container->findTaggedServiceIds(self::TAG_DICTIONARY) as $id => $tags) { + foreach (array_keys($container->findTaggedServiceIds(self::TAG_DICTIONARY)) as $id) { $container ->getDefinition(Collection::class) ->addMethodCall('add', [new Reference($id)]) diff --git a/src/Knp/DictionaryBundle/DependencyInjection/Compiler/DictionaryTracePass.php b/src/Knp/DictionaryBundle/DependencyInjection/Compiler/DictionaryTracePass.php index 71ae06d5..a9a4c946 100644 --- a/src/Knp/DictionaryBundle/DependencyInjection/Compiler/DictionaryTracePass.php +++ b/src/Knp/DictionaryBundle/DependencyInjection/Compiler/DictionaryTracePass.php @@ -19,7 +19,7 @@ public function process(ContainerBuilder $container): void return; } - foreach ($container->findTaggedServiceIds(DictionaryRegistrationPass::TAG_DICTIONARY) as $id => $tags) { + foreach (array_keys($container->findTaggedServiceIds(DictionaryRegistrationPass::TAG_DICTIONARY)) as $id) { $serviceId = sprintf('%s.%s.traceable', $id, md5($id)); $dictionary = new Reference(sprintf('%s.inner', $serviceId)); $traceable = new Definition(Traceable::class, [$dictionary, new Reference(DictionaryDataCollector::class)]); diff --git a/src/Knp/DictionaryBundle/Dictionary.php b/src/Knp/DictionaryBundle/Dictionary.php index d2856280..5444c2d2 100644 --- a/src/Knp/DictionaryBundle/Dictionary.php +++ b/src/Knp/DictionaryBundle/Dictionary.php @@ -9,37 +9,44 @@ use IteratorAggregate; /** - * @template E + * @template TKey of (int|string) + * @template TValue * - * @extends IteratorAggregate - * @extends ArrayAccess + * @extends IteratorAggregate + * @extends ArrayAccess */ interface Dictionary extends ArrayAccess, Countable, IteratorAggregate { /** * @var string + * + * @deprecated */ public const VALUE = 'value'; /** * @var string + * + * @deprecated */ public const VALUE_AS_KEY = 'value_as_key'; /** * @var string + * + * @deprecated */ public const KEY_VALUE = 'key_value'; public function getName(): string; /** - * @return mixed[] + * @return array */ - public function getValues(): array; + public function getKeys(): array; /** - * @return mixed[] + * @return array */ - public function getKeys(): array; + public function getValues(): array; } diff --git a/src/Knp/DictionaryBundle/Dictionary/Collection.php b/src/Knp/DictionaryBundle/Dictionary/Collection.php index 4dcbde74..3f55b437 100644 --- a/src/Knp/DictionaryBundle/Dictionary/Collection.php +++ b/src/Knp/DictionaryBundle/Dictionary/Collection.php @@ -5,7 +5,6 @@ namespace Knp\DictionaryBundle\Dictionary; use ArrayAccess; -use ArrayIterator; use Countable; use IteratorAggregate; use Knp\DictionaryBundle\Dictionary; @@ -14,18 +13,18 @@ use Traversable; /** - * @implements ArrayAccess> - * @implements IteratorAggregate> + * @implements ArrayAccess> + * @implements IteratorAggregate> */ final class Collection implements ArrayAccess, Countable, IteratorAggregate { /** - * @var array> + * @var array> */ private array $dictionaries = []; /** - * @param Dictionary ...$dictionaries + * @param Dictionary ...$dictionaries */ public function __construct(Dictionary ...$dictionaries) { @@ -35,25 +34,24 @@ public function __construct(Dictionary ...$dictionaries) } /** - * @param Dictionary $dictionary + * @param Dictionary $dictionary */ public function add(Dictionary $dictionary): void { $this->dictionaries[$dictionary->getName()] = $dictionary; } - public function offsetExists($offset): bool + public function offsetExists(mixed $offset): bool { return \array_key_exists($offset, $this->dictionaries); } /** - * @return Dictionary - * {@inheritdoc} + * @return Dictionary * * @throws DictionaryNotFoundException */ - public function offsetGet($offset): Dictionary + public function offsetGet(mixed $offset): mixed { if (!$this->offsetExists($offset)) { throw new DictionaryNotFoundException($offset, array_keys($this->dictionaries)); @@ -62,21 +60,21 @@ public function offsetGet($offset): Dictionary return $this->dictionaries[$offset]; } - public function offsetSet($offset, $value): void + public function offsetSet(mixed $offset, mixed $value): void { throw new RuntimeException( 'To add a Dictionary to the Collection, use Knp\DictionaryBundle\Dictionary\Collection::add(Dictionary $dictionary).' ); } - public function offsetUnset($offset): void + public function offsetUnset(mixed $offset): void { throw new RuntimeException('It is not possible to remove a dictionary from the collection.'); } public function getIterator(): Traversable { - return new ArrayIterator($this->dictionaries); + return yield from $this->dictionaries; } public function count(): int diff --git a/src/Knp/DictionaryBundle/Dictionary/Combined.php b/src/Knp/DictionaryBundle/Dictionary/Combined.php index 149c3329..0c6c02a2 100644 --- a/src/Knp/DictionaryBundle/Dictionary/Combined.php +++ b/src/Knp/DictionaryBundle/Dictionary/Combined.php @@ -7,14 +7,15 @@ use Knp\DictionaryBundle\Dictionary; /** - * @template E + * @template TKey of (int|string) + * @template TValue * - * @extends Wrapper + * @extends Wrapper */ final class Combined extends Wrapper { /** - * @param Dictionary ...$dictionaries + * @param Dictionary ...$dictionaries */ public function __construct(string $name, Dictionary ...$dictionaries) { @@ -32,10 +33,10 @@ public function __construct(string $name, Dictionary ...$dictionaries) } /** - * @param E[] $array1 - * @param E[] $array2 + * @param array $array1 + * @param array $array2 * - * @return E[] + * @return array */ private function merge(array $array1, array $array2): array { diff --git a/src/Knp/DictionaryBundle/Dictionary/Factory.php b/src/Knp/DictionaryBundle/Dictionary/Factory.php index bbf96d65..c5ab996a 100644 --- a/src/Knp/DictionaryBundle/Dictionary/Factory.php +++ b/src/Knp/DictionaryBundle/Dictionary/Factory.php @@ -11,7 +11,7 @@ interface Factory /** * @param mixed[] $config * - * @return Dictionary + * @return Dictionary */ public function create(string $name, array $config): Dictionary; diff --git a/src/Knp/DictionaryBundle/Dictionary/Factory/Combined.php b/src/Knp/DictionaryBundle/Dictionary/Factory/Combined.php index 8fe996e9..343338dc 100644 --- a/src/Knp/DictionaryBundle/Dictionary/Factory/Combined.php +++ b/src/Knp/DictionaryBundle/Dictionary/Factory/Combined.php @@ -21,14 +21,28 @@ public function __construct(private Collection $dictionaries) {} public function create(string $name, array $config): Dictionary { if (!isset($config['dictionaries'])) { - throw new InvalidArgumentException(sprintf( - 'Dictionary of type %s must contains a key "dictionaries".', - self::TYPE - )); + throw new InvalidArgumentException( + sprintf( + 'The configuration of the dictionary named "%s" of type "%s" must contain a "dictionary" parameter.', + $name, + self::TYPE + ) + ); + } + + if (!\is_array($config['dictionaries'])) { + throw new InvalidArgumentException( + sprintf( + 'The "dictionaries" configuration parameter of the dictionary named "%s" of type "%s" must contain an array, %s is given.', + $name, + self::TYPE, + \gettype($config['dictionaries']), + ) + ); } $dictionaries = array_map( - fn ($name): Dictionary => $this->dictionaries[$name], + fn (string $name): Dictionary => $this->dictionaries[$name], $config['dictionaries'] ); @@ -37,6 +51,6 @@ public function create(string $name, array $config): Dictionary public function supports(array $config): bool { - return isset($config['type']) ? self::TYPE === $config['type'] : false; + return isset($config['type']) && self::TYPE === $config['type']; } } diff --git a/src/Knp/DictionaryBundle/Dictionary/Factory/Extended.php b/src/Knp/DictionaryBundle/Dictionary/Factory/Extended.php index 70f90875..8bd00c0e 100644 --- a/src/Knp/DictionaryBundle/Dictionary/Factory/Extended.php +++ b/src/Knp/DictionaryBundle/Dictionary/Factory/Extended.php @@ -12,7 +12,10 @@ final class Extended implements Factory { - public function __construct(private Factory $factory, private Collection $dictionaries) {} + public function __construct( + private Factory $factory, + private Collection $dictionaries + ) {} public function create(string $name, array $config): Dictionary { diff --git a/src/Knp/DictionaryBundle/Dictionary/Factory/Invokable.php b/src/Knp/DictionaryBundle/Dictionary/Factory/Invokable.php index b9edfe49..e884eef1 100644 --- a/src/Knp/DictionaryBundle/Dictionary/Factory/Invokable.php +++ b/src/Knp/DictionaryBundle/Dictionary/Factory/Invokable.php @@ -13,9 +13,12 @@ final class Invokable implements Factory { public function __construct(private ContainerInterface $container) {} + public function supports(array $config): bool + { + return 'callable' === $config['type'] ?: false; + } + /** - * {@inheritdoc} - * * @throw InvalidArgumentException if there is some problem with the config. */ public function create(string $name, array $config): Dictionary @@ -27,6 +30,14 @@ public function create(string $name, array $config): Dictionary )); } + if (!\is_string($config['service'])) { + throw new InvalidArgumentException(sprintf( + 'The "service" config key must be a string for the dictionary named "%s"; %s given.', + $name, + \gettype($config['service']), + )); + } + $service = $this->container->get($config['service']); $callable = [$service]; @@ -43,9 +54,4 @@ public function create(string $name, array $config): Dictionary return new Dictionary\Invokable($name, $callable); } - - public function supports(array $config): bool - { - return (isset($config['type'])) ? 'callable' === $config['type'] : false; - } } diff --git a/src/Knp/DictionaryBundle/Dictionary/Factory/Iterator.php b/src/Knp/DictionaryBundle/Dictionary/Factory/Iterator.php index b69964de..7646bb27 100644 --- a/src/Knp/DictionaryBundle/Dictionary/Factory/Iterator.php +++ b/src/Knp/DictionaryBundle/Dictionary/Factory/Iterator.php @@ -17,6 +17,8 @@ public function __construct(private ContainerInterface $container) {} /** * {@inheritdoc} * + * @param array{service?: string} $config + * * @throw InvalidArgumentException if there is some problem with the config. */ public function create(string $name, array $config): Dictionary @@ -42,6 +44,6 @@ public function create(string $name, array $config): Dictionary public function supports(array $config): bool { - return (isset($config['type'])) ? 'iterator' === $config['type'] : false; + return isset($config['type']) && 'iterator' === $config['type']; } } diff --git a/src/Knp/DictionaryBundle/Dictionary/Factory/KeyValue.php b/src/Knp/DictionaryBundle/Dictionary/Factory/KeyValue.php index 9a53a488..c7b5acbc 100644 --- a/src/Knp/DictionaryBundle/Dictionary/Factory/KeyValue.php +++ b/src/Knp/DictionaryBundle/Dictionary/Factory/KeyValue.php @@ -17,6 +17,8 @@ public function __construct(private ValueTransformer $transformer) {} /** * {@inheritdoc} * + * @param array{content?: array} $config + * * @throw InvalidArgumentException if there is some problem with the config. */ public function create(string $name, array $config): Dictionary @@ -42,6 +44,6 @@ public function create(string $name, array $config): Dictionary public function supports(array $config): bool { - return (isset($config['type'])) ? 'key_value' === $config['type'] : false; + return isset($config['type']) && 'key_value' === $config['type']; } } diff --git a/src/Knp/DictionaryBundle/Dictionary/Factory/Value.php b/src/Knp/DictionaryBundle/Dictionary/Factory/Value.php index 8376c0a9..3faf5c1d 100644 --- a/src/Knp/DictionaryBundle/Dictionary/Factory/Value.php +++ b/src/Knp/DictionaryBundle/Dictionary/Factory/Value.php @@ -17,6 +17,8 @@ public function __construct(private ValueTransformer $transformer) {} /** * {@inheritdoc} * + * @param array{content?: array} $config + * * @throw InvalidArgumentException Not able to create a dictionary with the given name */ public function create(string $name, array $config): Dictionary @@ -40,6 +42,6 @@ public function create(string $name, array $config): Dictionary public function supports(array $config): bool { - return (isset($config['type'])) ? 'value' === $config['type'] : false; + return isset($config['type']) && 'value' === $config['type']; } } diff --git a/src/Knp/DictionaryBundle/Dictionary/Factory/ValueAsKey.php b/src/Knp/DictionaryBundle/Dictionary/Factory/ValueAsKey.php index 6c2344f8..8af8ce89 100644 --- a/src/Knp/DictionaryBundle/Dictionary/Factory/ValueAsKey.php +++ b/src/Knp/DictionaryBundle/Dictionary/Factory/ValueAsKey.php @@ -15,8 +15,6 @@ final class ValueAsKey implements Factory public function __construct(private ValueTransformer $transformer) {} /** - * {@inheritdoc} - * * @throw InvalidArgumentException if there is some problem with the config. */ public function create(string $name, array $config): Dictionary @@ -26,7 +24,12 @@ public function create(string $name, array $config): Dictionary } $content = $config['content']; - $values = []; + + if (!is_iterable($content)) { + throw new InvalidArgumentException(sprintf('The key content for dictionary %s must iterable.', $name)); + } + + $values = []; foreach ($content as $value) { $builtValue = $this->transformer->transform($value); @@ -38,6 +41,6 @@ public function create(string $name, array $config): Dictionary public function supports(array $config): bool { - return (isset($config['type'])) ? 'value_as_key' === $config['type'] : false; + return isset($config['type']) && 'value_as_key' === $config['type']; } } diff --git a/src/Knp/DictionaryBundle/Dictionary/Invokable.php b/src/Knp/DictionaryBundle/Dictionary/Invokable.php index b178fddb..1670c245 100644 --- a/src/Knp/DictionaryBundle/Dictionary/Invokable.php +++ b/src/Knp/DictionaryBundle/Dictionary/Invokable.php @@ -4,45 +4,40 @@ namespace Knp\DictionaryBundle\Dictionary; -use ArrayIterator; use InvalidArgumentException; use Knp\DictionaryBundle\Dictionary; -use ReturnTypeWillChange; +use Traversable; /** - * @template E + * @template TKey of (int|string) + * @template TValue * - * @implements Dictionary + * @implements Dictionary */ final class Invokable implements Dictionary { - private bool $invoked = false; - /** - * @var array + * @var Simple */ - private array $values = []; + private Simple $dictionary; /** - * @var callable + * @var callable(): array */ private $callable; /** - * @param mixed[] $callableArgs + * @param mixed[] $callableArgs + * @param callable(): array $callable */ - public function __construct(private string $name, callable $callable, private array $callableArgs = []) - { + public function __construct( + private string $name, + callable $callable, + private array $callableArgs = [] + ) { $this->callable = $callable; } - public function getValues(): array - { - $this->invoke(); - - return $this->values; - } - public function getName(): string { return $this->name; @@ -52,58 +47,66 @@ public function getKeys(): array { $this->invoke(); - return array_keys($this->values); + return $this->dictionary->getKeys(); + } + + public function getValues(): array + { + $this->invoke(); + + return $this->dictionary->getValues(); } - public function offsetExists($offset): bool + public function offsetExists(mixed $offset): bool { $this->invoke(); - return \array_key_exists($offset, $this->values); + return $this->dictionary->offsetExists($offset); } - #[ReturnTypeWillChange] - public function offsetGet($offset) + public function offsetGet(mixed $offset): mixed { $this->invoke(); - return $this->values[$offset]; + return $this->dictionary->offsetGet($offset); } - public function offsetSet($offset, $value): void + /** + * {@inheritdoc} + * + * @param TKey $offset + */ + public function offsetSet(mixed $offset, mixed $value): void { $this->invoke(); - $this->values[$offset] = $value; + $this->dictionary->offsetSet($offset, $value); } - public function offsetUnset($offset): void + public function offsetUnset(mixed $offset): void { $this->invoke(); - unset($this->values[$offset]); + $this->dictionary->offsetUnset($offset); } - /** - * @return ArrayIterator - */ - public function getIterator(): ArrayIterator + public function getIterator(): Traversable { $this->invoke(); - return new ArrayIterator($this->values); + yield from $this->dictionary; } public function count(): int { $this->invoke(); - return \count($this->values); + return $this->dictionary->count(); } private function invoke(): void { - if ($this->invoked) { + if (isset($this->dictionary)) { return; } @@ -115,7 +118,6 @@ private function invoke(): void ); } - $this->values = $values; - $this->invoked = true; + $this->dictionary = new Simple($this->name, $values); } } diff --git a/src/Knp/DictionaryBundle/Dictionary/Iterator.php b/src/Knp/DictionaryBundle/Dictionary/Iterator.php index 3814de04..e5bd5733 100644 --- a/src/Knp/DictionaryBundle/Dictionary/Iterator.php +++ b/src/Knp/DictionaryBundle/Dictionary/Iterator.php @@ -7,14 +7,15 @@ use Traversable; /** - * @template E + * @template TKey of (int|string) + * @template TValue * - * @extends Wrapper + * @extends Wrapper */ final class Iterator extends Wrapper { /** - * @param Traversable $iterator + * @param Traversable $iterator */ public function __construct(string $name, Traversable $iterator) { diff --git a/src/Knp/DictionaryBundle/Dictionary/Simple.php b/src/Knp/DictionaryBundle/Dictionary/Simple.php index e66f9aaa..ddcff741 100644 --- a/src/Knp/DictionaryBundle/Dictionary/Simple.php +++ b/src/Knp/DictionaryBundle/Dictionary/Simple.php @@ -4,18 +4,19 @@ namespace Knp\DictionaryBundle\Dictionary; -use Generator; use Knp\DictionaryBundle\Dictionary; +use Traversable; /** - * @template E + * @template TKey of (int|string) + * @template TValue * - * @implements Dictionary + * @implements Dictionary */ final class Simple implements Dictionary { /** - * @param array $values + * @param array $values */ public function __construct(private string $name, private array $values) {} @@ -24,14 +25,14 @@ public function getName(): string return $this->name; } - public function getValues(): array + public function getKeys(): array { - return $this->values; + return array_keys($this->values); } - public function getKeys(): array + public function getValues(): array { - return array_keys($this->values); + return array_values($this->values); } public function offsetExists(mixed $offset): bool @@ -44,6 +45,11 @@ public function offsetGet(mixed $offset): mixed return $this->values[$offset]; } + /** + * {@inheritdoc} + * + * @param TKey $offset + */ public function offsetSet(mixed $offset, mixed $value): void { $this->values[$offset] = $value; @@ -54,7 +60,7 @@ public function offsetUnset(mixed $offset): void unset($this->values[$offset]); } - public function getIterator(): Generator + public function getIterator(): Traversable { yield from $this->values; } diff --git a/src/Knp/DictionaryBundle/Dictionary/Traceable.php b/src/Knp/DictionaryBundle/Dictionary/Traceable.php index 9994d705..fbf16606 100644 --- a/src/Knp/DictionaryBundle/Dictionary/Traceable.php +++ b/src/Knp/DictionaryBundle/Dictionary/Traceable.php @@ -8,16 +8,20 @@ use Knp\DictionaryBundle\Dictionary; /** - * @template E of mixed + * @template TKey of (int|string) + * @template TValue * - * @implements Dictionary + * @implements Dictionary */ final class Traceable implements Dictionary { /** - * @param Dictionary $dictionary + * @param Dictionary $dictionary */ - public function __construct(private Dictionary $dictionary, private DictionaryDataCollector $collector) {} + public function __construct( + private Dictionary $dictionary, + private DictionaryDataCollector $collector + ) {} public function getName(): string { @@ -67,7 +71,7 @@ public function offsetUnset(mixed $offset): void } /** - * @return Dictionary + * @return Dictionary */ public function getIterator(): Dictionary { diff --git a/src/Knp/DictionaryBundle/Dictionary/Wrapper.php b/src/Knp/DictionaryBundle/Dictionary/Wrapper.php index 095cc83d..64eafde9 100644 --- a/src/Knp/DictionaryBundle/Dictionary/Wrapper.php +++ b/src/Knp/DictionaryBundle/Dictionary/Wrapper.php @@ -5,16 +5,18 @@ namespace Knp\DictionaryBundle\Dictionary; use Knp\DictionaryBundle\Dictionary; +use Traversable; /** - * @template E + * @template TKey of (int|string) + * @template TValue * - * @implements Dictionary + * @implements Dictionary */ abstract class Wrapper implements Dictionary { /** - * @param Dictionary $wrapped + * @param Dictionary $wrapped */ public function __construct(private Dictionary $wrapped) {} @@ -58,11 +60,8 @@ public function count(): int return $this->wrapped->count(); } - /** - * @return Dictionary - */ - public function getIterator(): Dictionary + public function getIterator(): Traversable { - return $this->wrapped; + yield from $this->wrapped; } } diff --git a/src/Knp/DictionaryBundle/Exception/DictionaryNotFoundException.php b/src/Knp/DictionaryBundle/Exception/DictionaryNotFoundException.php index 7d35fc89..d1549327 100644 --- a/src/Knp/DictionaryBundle/Exception/DictionaryNotFoundException.php +++ b/src/Knp/DictionaryBundle/Exception/DictionaryNotFoundException.php @@ -11,11 +11,14 @@ final class DictionaryNotFoundException extends Exception /** * @param string[] $knowns */ - public function __construct(string $dictionaryName, array $knowns = [], Exception $previous = null) - { + public function __construct( + string $dictionaryName, + array $knowns = [], + Exception $previous = null + ) { $message = sprintf('The dictionary "%s" has not been found in the registry.', $dictionaryName); - if (!empty($knowns)) { + if ([] !== $knowns) { $message .= sprintf(' Known dictionaries are: "%s".', implode('", "', $knowns)); } diff --git a/src/Knp/DictionaryBundle/Faker/Provider/Dictionary.php b/src/Knp/DictionaryBundle/Faker/Provider/Dictionary.php index 4c1b9db5..52a872e5 100644 --- a/src/Knp/DictionaryBundle/Faker/Provider/Dictionary.php +++ b/src/Knp/DictionaryBundle/Faker/Provider/Dictionary.php @@ -10,9 +10,11 @@ final class Dictionary extends Base { - public function __construct(private Collection $dictionaries, Generator $generator = null) - { - if (null === $generator) { + public function __construct( + private readonly Collection $dictionaries, + Generator $generator = null + ) { + if (!$generator instanceof Generator) { $generator = new Generator(); $generator->addProvider($this); } diff --git a/src/Knp/DictionaryBundle/Templating/Extension/Dictionary.php b/src/Knp/DictionaryBundle/Templating/Extension/Dictionary.php index 30dd7b82..54fd3f90 100644 --- a/src/Knp/DictionaryBundle/Templating/Extension/Dictionary.php +++ b/src/Knp/DictionaryBundle/Templating/Extension/Dictionary.php @@ -19,7 +19,10 @@ public function __construct(private Collection $dictionaries) {} public function getFunctions() { return [ - new TwigFunction('dictionary', [$this->dictionaries, 'offsetGet']), + new TwigFunction( + 'dictionary', + fn (string $name) => $this->dictionaries[$name], + ), ]; } @@ -29,7 +32,10 @@ public function getFunctions() public function getFilters() { return [ - new TwigFilter('dictionary', fn ($key, string $name) => $this->dictionaries[$name][$key]), + new TwigFilter( + 'dictionary', + fn ($key, string $name) => $this->dictionaries[$name][$key] ?? null, + ), ]; } } diff --git a/src/Knp/DictionaryBundle/Validator/Constraints/DictionaryValidator.php b/src/Knp/DictionaryBundle/Validator/Constraints/DictionaryValidator.php index 7e4513ab..9e38777a 100644 --- a/src/Knp/DictionaryBundle/Validator/Constraints/DictionaryValidator.php +++ b/src/Knp/DictionaryBundle/Validator/Constraints/DictionaryValidator.php @@ -14,7 +14,7 @@ final class DictionaryValidator extends ConstraintValidator public function __construct(private Collection $dictionaries) {} - private function varToString(mixed $var): string + protected function varToString(mixed $var): string { if (null === $var) { return 'null'; @@ -38,11 +38,8 @@ private function varToString(mixed $var): string return $var->__toString(); } - if (settype($var, 'string')) { - /** - * @var string $var - */ - return $var; + if (\is_scalar($var) && '' !== (string) $var) { + return (string) $var; } throw new Exception('Unable to transform var to string.'); diff --git a/src/Knp/DictionaryBundle/ValueTransformer/Constant.php b/src/Knp/DictionaryBundle/ValueTransformer/Constant.php index 7a009738..89a97111 100644 --- a/src/Knp/DictionaryBundle/ValueTransformer/Constant.php +++ b/src/Knp/DictionaryBundle/ValueTransformer/Constant.php @@ -35,6 +35,9 @@ public function supports(mixed $value): bool return \array_key_exists($matches['constant'], $constants); } + /** + * @param string $value + */ public function transform(mixed $value) { if (null === $matches = $this->extract($value)) {