0

我们都遇到过这个问题:“必须管理实体”当我们试图setFilters()/getFilters()

那么如何以通用方式处理过滤器的会话存储,以避免mergingdetaching/或re-hydrating手动实体?

请参阅下面的答案。

4

1 回答 1

1

好吧,工作中的一些同事(@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% 的情况)

于 2012-06-12T07:47:27.177 回答