diff --git a/CHANGELOG-2.0.md b/CHANGELOG-2.0.md new file mode 100644 index 0000000..9b62694 --- /dev/null +++ b/CHANGELOG-2.0.md @@ -0,0 +1,12 @@ +# CHANGELOG for 2.0.x + +This changelog references the relevant changes done in 2.0 version. + +### 2.0.0(2018-03-26) + +* This new version is only for PHP ⩾7.1. +* Update all dependencies (remove all doctrine dependencies) +* DoctrineParamConverter is not used anymore +* This bundle only converts hashid into an id +* Replace `autowire` with `passthrough`. +This new parameter which allows to continue with the next param converters available. diff --git a/README.md b/README.md index dff37bf..6b522f5 100644 --- a/README.md +++ b/README.md @@ -2,55 +2,58 @@ # HashidsBundle -Integrates [hashids/hashids][1] in a Symfony2 project. +Integrates [hashids/hashids](https://github.com/ivanakimov/hashids.php) in a Symfony project. -## Installation +## Installation using composer -Open a command console, enter your project directory and execute the -following command to download the latest stable version of this bundle: +These commands requires you to have Composer installed globally. +Open a command console, enter your project directory and execute the following +commands to download the latest stable version of this bundle: + +### Using Symfony Flex ``` - composer require roukmoute/hashids-bundle + composer config extra.symfony.allow-contrib true + composer req roukmoute/hashids-bundle ``` -This command requires you to have Composer installed globally. +### Using Symfony 4 Framework -## Enable the Bundle +``` + composer require roukmoute/hashids-bundle +``` -Then, enable the bundle by adding the following line in the ``app/AppKernel.php`` -file of your project: +If this has not been done automatically, enable the bundle by adding the +following line in the `config/bundles.php` file of your project: ```php ['all' => true], +]; ``` -The configuration looks as follows : +## Configuration + +The configuration (`config/packages/roukmoute_hashids.yaml`) looks as follows : ```yaml roukmoute_hashids: # if set, the hashids will differ from everyone else's - salt: "" + salt: "" # if set, will generate minimum length for the id # 0 — meaning hashes will be the shortest possible length - min_hash_length: 0 + min_hash_length: 0 # if set, will use only characters of alphabet string - alphabet: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890" + alphabet: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890" - # if set to true, guess automatically hashid - autowire: false + # if set to true, it will continue with the next available param converters + passthrough: false ``` ## Usage @@ -59,7 +62,7 @@ roukmoute_hashids: $hashids = $this->get('hashids'); ``` -Next it's the same things of [official documentation][2]. +Next it's the same things of [official documentation](http://hashids.org/php/). ## Other Features @@ -75,99 +78,91 @@ $this->get('hashids')->setMinHashLength($minHashLength)->encode(1, 2, 3); $this->get('hashids')->encodeWithCustomHashLength($minHashLength, 1, 2, 3); ``` -Hashids Converter -================= +## Hashids Converter Converter Name: `hashids.converter` -The hashids converter attempts to convert request hashid attributes to a -id for fetch a Doctrine entity. +The hashids converter attempts to convert `hashid`/`id` attribute set in the route into an integer parameter. -For specify to use hashids converter just add `"id" = "hashid"` in -options. +You could use `hashid` or `id` to add : ```php /** * @Route("/users/{hashid}") - * @ParamConverter("user", class="RoukmouteBundle\Entity\User", options={"id" = "hashid"}) */ -public function getAction(User $user) +public function getAction(int $user) { } ``` -You could have several hashids one the same URL. -Just finish your word option with "hashid": +or ```php /** - * @Route("/users/{userHashid}/status/{statusHashid}") - * @ParamConverter("user", class="RoukmouteBundle\Entity\User", options={"id" = "userHashid"}) - * @ParamConverter("status", class="RoukmouteBundle\Entity\Notification", options={"id" = "statusHashid"}) + * @Route("/users/{id}") */ -public function getAction(User $user, Status $status) +public function getAction(int $user) { } ``` -Defining Hashid Automatically (Autowiring) -========================================== - -Autowiring allows to guess hashid with minimal configuration. -It automatically resolves the variable in route. -The ParamConverter component will be able to automatically guess -the hashid when configuration has autowire to true. - -``` -roukmoute_hashids: - autowire: true -``` - -The autowiring subsystem will detect the hashid. - -Base on the example above: +For specific case, just add `"hashid" = "{parameter_name}"` in ParamConverter +options: ```php /** - * @Route("/users/{hashid}") - * @ParamConverter("user", class="RoukmouteBundle\Entity\User", options={"id" = "hashid"}) + * @Route("/users/{slug}") + * + * @ParamConverter("user", class="RoukmouteBundle\Entity\User", options={"hashid" = "user"}) */ -public function getAction(User $user) +public function getAction(int $user) { } ``` -Now you can do simply that: +You could have several hashids one the same URL: ```php /** - * @Route("/users/{hashid}") + * @Route("/users/{user}/status/{status}") + * + * @ParamConverter("user", class="RoukmouteBundle\Entity\User", options={"hashid" = "user"}) + * @ParamConverter("status", class="RoukmouteBundle\Entity\Notification", options={"hashid" = "status"}) */ -public function getAction(User $user) +public function getAction(int $user, int $status) { } ``` -Or can directly use `id` now ! +## Using Passthrough + +`Passthrough` allows to continue with the next available param converters. +So if you would like to retrieve an object instead of an integer, just active +passthrough : + +```yaml +roukmoute_hashids: + passthrough: true +``` + +Base on the example above: ```php /** - * @Route("/users/{id}") + * @Route("/users/{hashid}") */ public function getAction(User $user) { } ``` -As you can see, the autowiring feature reduces the amount of -configuration required to define a hashid. +As you can see, the passthrough feature allows to use `DoctrineParamConverter` +or any another `ParamConverter` you would have created. + +## Twig Extension +### Usage -# Twig Extension -## Usage ```twig {{ path('users.show', {'hashid': user.id | hashids_encode }) }} {{ app.request.query.get('hashid') | hashids_decode }} ``` - -[1]: https://github.com/ivanakimov/hashids.php -[2]: http://hashids.org/php/ diff --git a/Resources/config/services.xml b/Resources/config/services.xml index 9f9e699..a2d71b0 100644 --- a/Resources/config/services.xml +++ b/Resources/config/services.xml @@ -17,8 +17,7 @@ class="Roukmoute\HashidsBundle\ParamConverter\HashidsParamConverter" > - - %hashids.autowire% + %hashids.passthrough% diff --git a/UPGRADE-2.0.md b/UPGRADE-2.0.md new file mode 100644 index 0000000..b3f76ab --- /dev/null +++ b/UPGRADE-2.0.md @@ -0,0 +1,77 @@ +# UPGRADE FROM 1.x to 2.0 + +### Configuration + +* Removed the `autowire` parameter in favor of the `passthrough` parameter. + +Before: + +```yml +roukmoute_hashids: + autowire: false +``` + +After: + +```yml +roukmoute_hashids: + passthrough: false +``` + +### HashidsParamConverter + +* Replace `id` key option with `hashid`. + +Before: + +```php +/** + * @Route("/users/{userHashid}/status/{statusHashid}") + * @ParamConverter("user", class="RoukmouteBundle\Entity\User", options={"id" = "userHashid"}) + * @ParamConverter("status", class="RoukmouteBundle\Entity\Notification", options={"id" = "statusHashid"}) + */ +public function getAction(User $user, Status $status) +{ +} +``` + +After: + +```php +/** + * @Route("/users/{userHashid}/status/{statusHashid}") + * @ParamConverter("user", class="RoukmouteBundle\Entity\User", options={"hashid" = "userHashid"}) + * @ParamConverter("status", class="RoukmouteBundle\Entity\Notification", options={"hashid" = "statusHashid"}) + */ +public function getAction(User $user, Status $status) +{ +} +``` + +* Remove the requirement to have `Hashid` at the end of the value option + +Before: + +```php +/** + * @Route("/users/{userHashid}/status/{statusHashid}") + * @ParamConverter("user", class="RoukmouteBundle\Entity\User", options={"id" = "userHashid"}) + * @ParamConverter("status", class="RoukmouteBundle\Entity\Notification", options={"id" = "statusHashid"}) + */ +public function getAction(User $user, Status $status) +{ +} +``` + +After: + +```php +/** + * @Route("/users/{user}/status/{status}") + * @ParamConverter("user", class="RoukmouteBundle\Entity\User", options={"hashid" = "user"}) + * @ParamConverter("status", class="RoukmouteBundle\Entity\Notification", options={"hashid" = "status"}) + */ +public function getAction(User $user, Status $status) +{ +} +``` diff --git a/composer.json b/composer.json index e735663..8067186 100644 --- a/composer.json +++ b/composer.json @@ -15,22 +15,26 @@ "Roukmoute\\HashidsBundle\\": "src/" } }, + "autoload-dev": { + "psr-4": { + "spec\\Roukmoute\\HashidsBundle\\": "spec/" + } + }, "require": { - "php": ">=5.6", - "doctrine/doctrine-bundle": "^1.8", - "doctrine/orm": "^2.6", - "hashids/hashids": "^2.0", - "sensio/framework-extra-bundle": "^3.0", - "symfony/http-kernel": "~3.3|~4.0" + "php": ">=7.1", + "hashids/hashids": "^3.0", + "sensio/framework-extra-bundle": "^5.1", + "symfony/http-kernel": "^4.0" }, "require-dev": { "bossa/phpspec2-expect": "^3.0", - "phpspec/phpspec": "^4.0", + "phpspec/phpspec": "^4.3", + "roave/security-advisories": "dev-master", "twig/twig": "^2.4" }, "extra": { "branch-alias": { - "dev-master": "1.5-dev" + "dev-master": "2.1-dev" } }, "suggest": { diff --git a/spec/ParamConverter/HashidsParamConverterSpec.php b/spec/ParamConverter/HashidsParamConverterSpec.php index b8746fa..704409e 100644 --- a/spec/ParamConverter/HashidsParamConverterSpec.php +++ b/spec/ParamConverter/HashidsParamConverterSpec.php @@ -15,198 +15,77 @@ class HashidsParamConverterSpec extends ObjectBehavior { - public function it_is_initializable(Hashids $hashids, ManagerRegistry $registry) + public function let() { - $this->beConstructedWith($hashids, $registry, false); - - $this->shouldHaveType(HashidsParamConverter::class); + $this->beConstructedWith(new Hashids(), false); } - public function it_returns_false_when_id_cannot_be_founded( - Hashids $hashids, - ManagerRegistry $registry, - Request $request, - ParamConverter $configuration - ) { - $this->beConstructedWith($hashids, $registry, false); - - $configuration->getOptions()->willReturn([]); + public function it_is_initializable(Hashids $hashids) + { + $this->beConstructedWith($hashids, false); - $this->apply($request, $configuration)->shouldReturn(false); + $this->shouldHaveType(HashidsParamConverter::class); } - public function it_throws_a_LogicException_when_hashid_cannot_be_guessed( - Hashids $hashids, - ManagerRegistry $registry - ) { - $this->beConstructedWith($hashids, $registry, false); + public function it_hashes_when_hashid_is_in_request() + { + $request = new Request([], [], ['hashid' => '9x']); + $configuration = new ParamConverter([]); + $configuration->setName('controllerArgument'); - $request = new Request(); - $request->attributes->set('hashid', 'h45h1d5'); - - $configuration = new ParamConverter( - [ - 'name' => 'user', - 'class' => 'Roukmoute\User', - 'options' => [ - 'id' => 'hashid', - ], - ] - ); - - $this->shouldThrow(new \LogicException('Unable to guess hashid from the request information.')) - ->during( - 'apply', - [$request, $configuration] - ) - ; + $this->apply($request, $configuration)->shouldReturn(true); + expect($request->attributes->get('controllerArgument'))->toBe(42); } - public function it_throws_a_NotFoundHttpException_when_object_cannot_be_resolved( - Hashids $hashids, - ManagerRegistry $registry, - ObjectManager $manager, - ObjectRepository $repository - ) { - $this->beConstructedWith($hashids, $registry, false); - - $class = 'Roukmoute\User'; - $repository->find(1)->willReturn(); - $manager->getRepository($class)->willReturn($repository); - $registry->getManagerForClass($class)->willReturn($manager); - $hash = 'h45h1d5'; - $hashids->decode($hash)->willReturn([1]); + public function it_hashes_when_id_is_in_request() + { + $request = new Request([], [], ['id' => '9x']); + $configuration = new ParamConverter([]); + $configuration->setName('controllerArgument'); - $request = new Request(); - $request->attributes->set('hashid', $hash); - - $configuration = new ParamConverter( - [ - 'name' => 'user', - 'class' => $class, - 'options' => [ - 'id' => 'hashid', - ], - ] - ); - - $this->shouldThrow(new NotFoundHttpException('User "' . $hash . '" not found.')) - ->during( - 'apply', - [$request, $configuration] - ) - ; + $this->apply($request, $configuration)->shouldReturn(true); + expect($request->attributes->get('controllerArgument'))->toBe(42); } - public function it_applies_an_id_without_autowire( - Hashids $hashids, - ManagerRegistry $registry, - ObjectManager $manager, - ObjectRepository $repository - ) { - $this->beConstructedWith($hashids, $registry, false); - - $class = 'Roukmoute\User'; - $repository->find(1)->willReturn(new \stdClass()); - $manager->getRepository($class)->willReturn($repository); - $registry->getManagerForClass($class)->willReturn($manager); - $hashids->decode('h45h1d5')->willReturn([1]); - - $request = new Request(); - $request->attributes->set('hashid', 'h45h1d5'); - - $configuration = new ParamConverter( - [ - 'name' => 'user', - 'class' => $class, - 'options' => [ - 'id' => 'hashid', - ], - ] - ); + public function it_hashes_when_hashid_is_in_ParamConverter_options() + { + $request = new Request([], [], ['slug' => '9x']); + $configuration = new ParamConverter(['options' => ['hashid' => 'slug']]); + $configuration->setName('controllerArgument'); $this->apply($request, $configuration)->shouldReturn(true); + expect($request->attributes->get('controllerArgument'))->toBe(42); } - public function it_applies_an_id_with_autowire( - Hashids $hashids, - ManagerRegistry $registry, - ObjectManager $manager, - ObjectRepository $repository - ) { - $this->beConstructedWith($hashids, $registry, true); - - $class = 'Roukmoute\User'; - $repository->find(1)->willReturn(new \stdClass()); - $manager->getRepository($class)->willReturn($repository); - $registry->getManagerForClass($class)->willReturn($manager); - $hashids->decode('h45h1d5')->willReturn([1]); - - $request = new Request(); - $request->attributes->set('hashid', 'h45h1d5'); - - $configuration = new ParamConverter( - [ - 'name' => 'user', - 'class' => $class, - ] - ); + public function it_does_not_hash_when_there_is_no_hashid() + { + $request = new Request([], [], ['hashid' => 'not_an_hashid']); + $configuration = new ParamConverter([]); + $configuration->setName('controllerArgument'); $this->apply($request, $configuration)->shouldReturn(true); + expect($request->attributes->get('controllerArgument'))->toBe(null); } - public function it_applies_an_hashid_with_autowire( - Hashids $hashids, - ManagerRegistry $registry, - ObjectManager $manager, - ObjectRepository $repository - ) { - $this->beConstructedWith($hashids, $registry, true); - - $class = 'Roukmoute\User'; - $repository->find('h45h1d5')->willReturn(); - $repository->find(1)->willReturn(new \stdClass()); - $manager->getRepository($class)->willReturn($repository); - $registry->getManagerForClass($class)->willReturn($manager); - $hashids->decode('h45h1d5')->willReturn([1]); + public function it_passthrough_when_argument_is_true(Hashids $hashids) + { + $this->beConstructedWith($hashids, true); $request = new Request(); - $request->attributes->set('id', 'h45h1d5'); + $configuration = new ParamConverter([]); + $configuration->setName('controllerArgument'); - $configuration = new ParamConverter( - [ - 'name' => 'user', - 'class' => $class, - ] - ); - - $this->apply($request, $configuration)->shouldReturn(true); + $this->apply($request, $configuration)->shouldReturn(false); } - public function it_throws_a_LogicException_when_object_cannot_be_guessed_with_autowire( - Hashids $hashids, - ManagerRegistry $registry, - ObjectManager $manager, - ObjectRepository $repository, - ClassMetadata $classMetadata - ) { - $this->beConstructedWith($hashids, $registry, true); - - $class = 'Roukmoute\User'; - $manager->getRepository($class)->willReturn($repository); - $manager->getClassMetadata($class)->willReturn($classMetadata); - $registry->getManagerForClass($class)->willReturn($manager); + public function it_does_not_passthrough_when_argument_is_false(Hashids $hashids) + { + $this->beConstructedWith($hashids, false); $request = new Request(); - $request->attributes->set('hashid', 'h45h1d5'); - - $configuration = new ParamConverter( - [ - 'name' => 'user', - 'class' => $class, - ] - ); + $configuration = new ParamConverter([]); + $configuration->setName('controllerArgument'); - $this->shouldThrow(\LogicException::class)->during('apply', [$request, $configuration]); + $this->apply($request, $configuration)->shouldReturn(true); } } diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index fded1b3..09cf752 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -1,12 +1,16 @@ root('roukmoute_hashids'); @@ -26,11 +30,12 @@ public function getConfigTreeBuilder() ->info('if set, will use only characters of alphabet string.') ->defaultValue('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890') ->end() - ->booleanNode('autowire') - ->info('if true, will try to detect the hashids when Doctrine was unable to guess Entity.') + ->booleanNode('passthrough') + ->info('if true, will continue with others param converters.') ->defaultFalse() ->end() - ->end(); + ->end() + ; return $treeBuilder; } diff --git a/src/DependencyInjection/RoukmouteHashidsExtension.php b/src/DependencyInjection/RoukmouteHashidsExtension.php index d1157df..8e42d09 100644 --- a/src/DependencyInjection/RoukmouteHashidsExtension.php +++ b/src/DependencyInjection/RoukmouteHashidsExtension.php @@ -1,4 +1,7 @@ processConfiguration($configuration, $configs); - $loader = new Loader\XmlFileLoader($container, new FileLocator(__DIR__.'/../../Resources/config')); + $loader = new Loader\XmlFileLoader($container, new FileLocator(dirname(__DIR__, 2) . '/Resources/config')); $loader->load('services.xml'); - $container->setParameter('hashids.salt', $config['salt']); - $container->setParameter('hashids.min_hash_length', $config['min_hash_length']); - $container->setParameter('hashids.alphabet', $config['alphabet']); - $container->setParameter('hashids.autowire', $config['autowire']); + foreach (['salt', 'min_hash_length', 'alphabet', 'passthrough'] as $parameter) { + $container->setParameter('hashids.' . $parameter, $config[$parameter]); + } } } diff --git a/src/Hashids.php b/src/Hashids.php index fadda1e..b534100 100644 --- a/src/Hashids.php +++ b/src/Hashids.php @@ -1,75 +1,48 @@ minHashLength = (int) $minHashLength; - - return $this; + $this->minHashLength = $minHashLength; } /** * Encode parameters to generate a hash with custom minimum hash length. * - * @param int $minHashLength The minimum hash length. - * @param array ...$numbers parameters to encode - * - * @return string + * @param array ...$numbers parameters to encode */ - public function encodeWithCustomHashLength($minHashLength, ...$numbers) + public function encodeWithCustomHashLength(int $minHashLength, int ...$numbers): string { - $newHashLength = $this->updateMinHashLength($minHashLength); + $originalHashLength = $this->minHashLength; + $this->setMinHashLength($minHashLength); $hashids = $this->encode($numbers); - $this->restoreMinHashLength($newHashLength); + $this->restoreMinHashLength($originalHashLength); return $hashids; } /** * Decode parameter to generate a decoded hash with custom minimum hash length. - * - * @param int $minHashLength The minimum hash length. - * @param string $hash parameters to encode - * - * @return array */ - public function decodeWithCustomHashLength($minHashLength, $hash) + public function decodeWithCustomHashLength(int $minHashLength, string $hash): array { - $originalHashLength = $this->updateMinHashLength($minHashLength); + $originalHashLength = $this->minHashLength; + $this->setMinHashLength($minHashLength); $hashids = $this->decode($hash); $this->restoreMinHashLength($originalHashLength); return $hashids; } - /** - * @param string $newMinHashLength - * - * @return int - */ - protected function updateMinHashLength($newMinHashLength) - { - $originalMinHashLength = $this->minHashLength; - - $this->minHashLength = (int) $newMinHashLength; - - return $originalMinHashLength; - } - - /** - * @param string $originalMinHashLength - */ - protected function restoreMinHashLength($originalMinHashLength) + protected function restoreMinHashLength(int $originalMinHashLength): void { $this->minHashLength = $originalMinHashLength; } diff --git a/src/ParamConverter/HashidsParamConverter.php b/src/ParamConverter/HashidsParamConverter.php index 27d3273..b5b3d12 100644 --- a/src/ParamConverter/HashidsParamConverter.php +++ b/src/ParamConverter/HashidsParamConverter.php @@ -1,16 +1,15 @@ hashids = $hashids; - $this->autowire = $autowire; + $this->passthrough = $passthrough; } - /** - * {@inheritdoc} - * - * @throws \LogicException When unable to guess how to get a id from the request information - */ - public function apply(Request $request, ParamConverter $configuration) + public function apply(Request $request, ParamConverter $configuration): bool { - $exception = null; + $this->setHashid($request, $configuration); + $this->removeHashidOption($configuration); - if ($this->autowire) { - try { - return parent::apply($request, $configuration); - } catch (\Exception $exception) { - $hashid = $this->hashIdentifier($request, $configuration); - } - } else { - $options = $configuration->getOptions(); + return $this->continueWithNextParamConverters(); + } - if (!isset($options['id']) || mb_strtolower(mb_substr($options['id'], -6)) !== 'hashid') { - return false; - } + public function supports(ParamConverter $configuration): bool + { + return true; + } - $hashid = $request->attributes->get($options['id']); + private function setHashid(Request $request, ParamConverter $configuration): void + { + $hashids = $this->hashids->decode( + $this->getIdentifier( + $request, + array_replace(['hashid' => null], $configuration->getOptions()), + $configuration->getName() + ) + ); + + if ($this->hasHashidDecoded($hashids)) { + $request->attributes->set($configuration->getName(), current($hashids)); } - - return $this->decodeHashid($request, $configuration, $hashid, $exception); } - /** - * @param Request $request - * @param ParamConverter $configuration - * @param $hashid - * @param \Exception|null $exception - * - * @return bool - * @throws \Exception - */ - private function decodeHashid(Request $request, ParamConverter $configuration, $hashid, \Exception $exception = null) + private function getIdentifier(Request $request, $options, string $name): string { - $options = $configuration->getOptions(); - $decodeHashids = $this->hashids->decode($hashid); - - if (!is_array($decodeHashids) - || !isset($decodeHashids[0]) - || false === ($id = $decodeHashids[0]) - || false === is_int($id) - ) { - if ($exception) { - throw $exception; - } - throw new \LogicException('Unable to guess hashid from the request information.'); + if ($options['hashid'] && !is_array($options['hashid'])) { + $name = $options['hashid']; } - $request->attributes->set('id', $id); - unset($options['id']); - - $configuration->setOptions($options); - $configuration->setIsOptional(true); - - parent::apply($request, $configuration); - - $name = $configuration->getName(); + if ($request->attributes->has($name)) { + return (string) $request->attributes->get($name); + } - if (!$request->attributes->get($name)) { - throw new NotFoundHttpException(sprintf('%s "%s" not found.', ucfirst($name), $hashid)); + foreach (['id', 'hashid'] as $item) { + if ($request->attributes->has($item) && !$options['hashid']) { + return (string) $request->attributes->get($item); + } } - return true; + return ''; } - /** - * @param Request $request - * @param ParamConverter $configuration - * - * @return string - */ - private function hashIdentifier(Request $request, ParamConverter $configuration) + private function hasHashidDecoded($hashids): bool { - $name = $configuration->getName(); - $options = $this->getOptions($configuration); + return $hashids && is_iterable($hashids); + } - $hashid = $this->getIdentifier($request, $options, $name); + private function removeHashidOption(ParamConverter $configuration): void + { + $options = $configuration->getOptions(); - if (!$hashid && $request->attributes->has('hashid')) { - $hashid = $request->attributes->get('hashid'); + if (isset($options['hashid'])) { + unset($options['hashid']); + $configuration->setOptions($options); } - - return $hashid; } + private function continueWithNextParamConverters(): bool + { + return !$this->passthrough; + } } diff --git a/src/RoukmouteHashidsBundle.php b/src/RoukmouteHashidsBundle.php index 9c5a467..007beee 100644 --- a/src/RoukmouteHashidsBundle.php +++ b/src/RoukmouteHashidsBundle.php @@ -1,4 +1,7 @@ hashids = $hashids; } - public function getFilters() + public function getFilters(): array { return [ new \Twig_SimpleFilter('hashids_encode', [$this, 'encode']), @@ -24,14 +26,13 @@ public function getFilters() ]; } - public function encode($number) + public function encode($number): string { return $this->hashids->encode($number); } - public function decode($hash) + public function decode($hash): array { return $this->hashids->decode($hash); } - }