如何以通用方式处理过滤器的会话存储,避免“实体必须被管理”

问题描述 投票:0回答:1

当我们尝试setFilters() /

getFilters()
时,我们都面临过这个问题:“
实体必须被管理

那么如何以通用方式处理过滤器的会话存储,以避免

merging
detaching
re-hydrating
手动实体?

请参阅下面的答案。

php symfony doctrine-orm
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%)案例)

© www.soinside.com 2019 - 2024. All rights reserved.