You could use a Doctrine postLoad
listener to generate a hash and set a hashId
property in your class. Then you could call expose the property in the serializer but set the serialized_name
as id
(or you could just leave it at hash_id
).
Due to the hashing taking place int the postLoad
you would need to refresh your object if you have just created it using $manager->refresh($entity)
for it take effect.
AppBundle\Doctrine\Listener\HashIdListener
class HashIdListsner
{
private $hashIdService;
public function postLoad(LifecycleEventArgs $args)
{
$entity = $args->getEntity();
$reflectionClass = new \ReflectionClass($entity);
// Only hash the id if the class has a "hashId" property
if (!$reflectionClass->hasProperty('hashId')) {
return;
}
// Hash the id
$hashId = $this->hashIdService->encode($entity->getId());
// Set the property through reflection so no need for a setter
// that could be used incorrectly in future
$property = $reflectionClass->getProperty('hashId');
$property->setAccessible(true);
$property->setValue($entity, $hashId);
}
}
services.yml
services:
app.doctrine_listsner.hash_id:
class: AppBundle\Doctrine\Listener\HashIdListener
arguments:
# assuming your are using cayetanosoriano/hashids-bundle
- "@hashids"
tags:
- { name: doctrine.event_listener, event: postLoad }
AppBundle\Resources\config\serializer\Entity.User.yml
AppBundle\Entity\User:
exclusion_policy: ALL
properties:
# ...
hashId:
expose: true
serialized_name: id
# ...