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);
}
-
}