2

I feel silly asking this question but I can't find a clear answer anywhere.

I have a token entity which has, among other things, a creation_time.

I have a parameter in parameters.yml called token_lifespan.

For a token, if creation_time < (time() - token_lifespan) then it has expired.

The problem is I can't find a nice way to pass the token_lifespan parameter to the entity. I know I could do something like:

$token->hasExpired($this->getParameter('token_lifespan')) 

But that feels really icky. I've been looking at making a service, and dependency injection, as a way to pass the token lifespan to the token when it is created, but I can't work out what I'm doing.

I'm making my tokens with $token = new MyToken(); and I'm getting my tokens from doctrine like so:

$this->getDoctrine() ->getRepository('MyBundle:MyToken') ->find($token_id); 

Do I need to make my repository a service? Something like:

mytoken_repository: class: MyBundle\Entity\MyToken factory_service: 'doctrine.orm.default_entity_manager' factory_method: 'getRepository' calls: - [setLifespan, ['%token_lifespan%']] 

And what exactly does this mean? Do I still create tokens the same way, with new MyToken()? and just make a setLifespan method in the MyToken class to store the lifespan?

Finally, can I still get tokens back from Doctrine with $this->getDoctrine()...? and what if I need to use the token_lifespan parameter in my repository class?

Sorry there's about a million questions in there. I feel like the dependency injection part of the Symfony docs assumes I know a lot more about the framework than I currently do.

2 Answers 2

1

Let's focus on this:

I've been looking at making a service, and dependency injection, as a way to pass the token lifespan to the token when it is created, but I can't work out what I'm doing.

I will strongly recommend you using Event Listener, prePersist in particular. Why? Simply, if you pass your lifespan to the event listener, and there you calculate your expiration date, you can set that date to your entity and use it later, when needed. Quote from Doctrine documentation about prePersist events:

prePersist - The prePersist event occurs for a given entity before the respective EntityManager persist operation for that entity is executed. It should be noted that this event is only triggered on initial persist of an entity (i.e. it does not trigger on future updates).

So, what do you need to do? Register the listener class first:

token.listener: class: MyBundle\EventListener\TokenListener arguments: - %token_lifespan% tags: - { name: doctrine.event_listener, event: prePersist } 

With this, you can easily pass your token_lifespan as a constructor to your class.

Then, you need to create the class itself:

namespace MyBundle\EventListener; use Doctrine\ORM\Event\LifecycleEventArgs; use MyBundle\Entity\Token; class TokenListener { /** * @var int **/ private $token_lifespan = null; public function __construct($tokenLifespan) { $this->token_lifespan = $tokenLifespan; } public function postPersist(LifecycleEventArgs $args) { $entity = $args->getEntity(); $entityManager = $args->getEntityManager(); // Do your magic here, only if our class is of type Token if ($entity instanceof Token) { // Calculate your expiration date here using $this->token_lifespan // and once you're done, set the result to the entity $entity->setExpirationDate(....); } } } 

I can explain why creating Repository as a service would not work for you, if you like. But anyway, give this a try.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the info and especially the sample code! I'd rather not save an expiration time to the database as it means a config change won't be reflected in the expiration times of existing tokens. I think I'll probably end up going with Marcel's answer. I do find it silly how hard it seems to be to pass config values around in Symfony though.
0

You should get the logic out of the entity and make a service with it. An entity should not have any dependencies.

You configure the service to have %token_lifespan% as an argument and make a method like this:

/** * @return boolean */ function isExpired(Token $token) { //your logic here, add dependencies to constructor and "arguments:" in service configuration } 

I hope this gets you started.

5 Comments

Also, I fully agree, it technically does not answer his question :)
Well, his question consists of multiple question so I took the liberty to write an answer that might help him answer all of them himself :P
So, in terms of best practices, I should put all my entity business logic in services, leaving entities as just models of database information? Having just written that, it sounds very logical!
Yes, that's how I do it.
It may not strictly answer my original question, but it answers the higher level question, which is arguably better. I ended up doing this so I've accepted this answer.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.