我们都遇到过这个问题:“必须管理实体”当我们试图setFilters()
/getFilters()
那么如何以通用方式处理过滤器的会话存储,以避免merging
和detaching
/或re-hydrating
手动实体?
请参阅下面的答案。
我们都遇到过这个问题:“必须管理实体”当我们试图setFilters()
/getFilters()
那么如何以通用方式处理过滤器的会话存储,以避免merging
和detaching
/或re-hydrating
手动实体?
请参阅下面的答案。
好吧,工作中的一些同事(@benji07)写了这个:
/**
* 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;
}
它适用于基本实体和多值选择
PS:不要忘记为ArrayCollection
免责声明,我们不知道这是否是一种好的做法,并且我们知道至少有一个限制:您必须确保您尝试在会话中保存的对象具有id
(99.9% 的情况)