I work with Redis loaded as a service to inject followers to a entity. So i've a entity like User that has a method like getFollowers. I don't want to mix service with entities, so I make a listener that subscribe to postLoad events in Doctrine.
The question is how call the service only when I call the getFollowers method.
My code...
EventListener:
public function postLoad(LifecycleEventArgs $eventArgs)
{
$redisService = get the service loaded with DIC in constructor.
if ($eventArgs->getEntity() instanceof User) {
$user = $eventArgs->getEntity();
$user->setFollowers($redisService->getFollowers($user));
}
}
User entity:
public function setFollowers(Array $followers) {
$this->followers = $followers
}
My problem is that on every load of class user, the RedisService is called and loaded, and I'd like to call the service ONLY on $user->getFollowers
Finally I get the answer...
In my listener postLoad I assign a closure to property of object:
$socialGraph = $this->socialGraph;
$getFollowers = function() use ($socialGraph, $user) {
return $socialGraph->getFollowers($user->getId());
};
$user->setFans($getFollowers);
Now, in my object it's possible to call a method into a property with:
public function getFans()
{
return call_user_func($this->fans);
// another way
return $this->fans->__invoke();
}
Wrap it as singleton. Something like that?
if (is_callable($this->_lazyLoad)) {
$this->_lazyLoad = $this->_lazyLoad($this);
}
return $this->_lazyLoad;