0

I have a tree of Employee objects (they are in a tree-like hierarchy, with everyone having one leader, and all leaders having more employees). All the Employees have a integer parameter called units.

/** * @ORM\Entity * @ORM\Table(name="employees") */ class Employee { /** * @ORM\Id * @ORM\Column(strategy="AUTO") */ protected $id; /** * @ORM\OneToMany(targetEntity="Employee", mappedBy="leader") */ protected $employees; /** * @ORM\ManyToOne(targetEntity("Employee", inversedBy="employees") */ protected $leader; } 

I need to get all the employees, who have at most N units, where N is defined in config.yml. At first, I was trying to push $configContainer into $GLOBALS, and use it in ArrayCollection::filter()'s Closure. Now I found a method, so I can use variables in the Closure:

public function getBestEmployees(&$configContainer) { return $this->getAllEmployees()->filter( function bestEmployees($employee) use ($configContainer) { return ($employee->getUnits() >= $configContainer->getParameter('best_unit_count')); } ); } 

Now I wonder if there is any other way to access the configuration parameters from an Entity, or do I really have to pass the whole configContainer as a reference? Or am I doing it totally wrong?

1 Answer 1

4

You shouldn't be accessing the service container at all inside entities. The value itself should be passed instead

public function getBestEmployees($bestUnitCount) { return $this->getAllEmployees()->filter(function ($employee) use ($bestUnitCount) { return $employee->getUnits()->count() >= $bestUnitCount; }); } 

Of course, we haven't actually solved the problem yet: the parameter still needs to be fetched from the container somewhere. If this method gets invoked mostly in controller actions, I wouldn't bother doing any extra work to make things cleaner and would pass the container parameter straight in the controller action.

However, should there be a need to get the best employees in a Twig template, for example, it would be nice if it wouldn't be necessary to pass the parameter. One possibility would be using a setter method and passing the parameter down beforehand to each and every entity that gets retrieved from the database. You could do this either in repositories or entitiy managers. The most advanced solution would be to listen to the postLoad event and pass the parameter in an event listener.

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

2 Comments

You may also have an EmployeeManager service which gets injected the parameter and proxies or decorates the method call.
EntityManager service is actually the most clean solution. Injecting in controller action is not much better than injecting directly into entity.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.