Reputation: 8855
We've all been confronted to that problem : "Entity must be managed" when we are trying to setFilters()
/ getFilters()
So how to handle the session storage of filters in a generic way, in order to avoid merging
and detaching
or re-hydrating
manually the entities ?
See the answer just below.
Upvotes: 0
Views: 189
Reputation: 8855
Well, some colleague (@benji07) at work have written this :
/**
* Set filters
* @param string $name Name of the key to store filters
* @param array $filters Filters
*/
public function setFilters($name, array $filters = array())
{
foreach ($filters as $key => $value) {
// Transform entities objects into a pair of class/id
if (is_object($value)) {
if ($value instanceof ArrayCollection) {
if (count($value)) {
$filters[$key] = array(
'class' => get_class($value->first()),
'ids' => array()
);
foreach ($value as $v) {
$identifier = $this->getDoctrine()->getEntityManager()->getUnitOfWork()->getEntityIdentifier($v);
$filters[$key]['ids'][] = $identifier['id'];
}
}
}
elseif (!$value instanceof \DateTime) {
$filters[$key] = array(
'class' => get_class($value),
'id' => $this->getDoctrine()->getEntityManager()->getUnitOfWork()->getEntityIdentifier($value)
);
}
}
}
$this->getRequest()->getSession()->set(
$name,
$filters
);
}
/**
* Get Filters
* @param string $name Name of the key to get filters
* @param array $filters Filters
*
* @return array
*/
public function getFilters($name, array $filters = array())
{
$filters = array_merge(
$this->getRequest()->getSession()->get(
$name,
array()
),
$filters
);
foreach ($filters as $key => $value) {
// Get entities from pair of class/id
if (is_array($value) && isset($value['class']) && isset($value['id'])) {
$filters[$key] = $this->getDoctrine()->getEntityManager()->find($value['class'], $value['id']);
} elseif (isset($value['ids'])) {
$data = $this->getDoctrine()->getEntityManager()->getRepository($value['class'])->findBy(array('id' => $value['ids']));
$filters[$key] = new ArrayCollection($data);
}
}
return $filters;
}
It works for basic entities, and multivalued choices
PS: Don't forget to add a use statement for the ArrayCollection
Disclaimer, we don't know if it's a good practice, and we know at least one limitation : you have to be sure that the object you try to save in the session has an id
(it's 99,9% the case)
Upvotes: 1