2

我正在尝试按照 Doctrine 文档在我的 Symfony 2.1 项目中执行多对多自引用关联:http: //docs.doctrine-project.org/en/latest/reference/association-mapping.html#many-to-多自引用

我的用例是我正在开发一个 CMS,并且我正在添加拥有相关内容项的能力。例如:我可以在网站上有一个侧边栏,它会说这段内容 X 与 Y 和 Z 相关。类似地,在出现内容 Y 的页面上,它说它与内容项 X 相关。

在我的测试中,使用它在内容项之间添加新关系失败了,因为它达到了 PHP 的最大嵌套级别 100,因为它在当前内容项上运行 toArray(),然后在相关内容项上再次运行,依此类推。

我在 SO 上看到了许多关于多对多自引用学说关联的类似问题,但没有一个具有足够完整的代码来了解其他人是如何管理这个问题的。有人可以帮忙吗?

我的内容实体:

/**
 * @ORM\MappedSuperclass
 * @ORM\Table(name="content")
 * @ORM\Entity(repositoryClass="CMS\Bundle\Common\ContentBundle\Entity\ContentRepository")
 * @ORM\InheritanceType("JOINED")
 */
abstract class content implements ContentInterface
{
    /**
     * @var int $id
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string $title
     *
     * @ORM\Column(name="title", type="string", length=255)
     * @Assert\NotBlank()
     */
    private $title;

    // Other class properties

    /**
     * @var array
     *
     * @ORM\ManyToMany(targetEntity="Content", cascade={"persist"})
     * @ORM\JoinTable(name="content_relation",
     *      joinColumns={@ORM\JoinColumn(name="relation_id", referencedColumnName="id")},
     *      inverseJoinColumns={
     *          @ORM\JoinColumn(name="related_content_id", referencedColumnName="id")
     *      })
     **/
    private $related;

    public function __construct() 
    {
        $this->related = new ArrayCollection();
    }

    // Other getters & setters for class properties

    /**
     * @return array
     */
    public function getRelated()
    {
    return $this->related;
    }

    /**
     * @param Content $relation
     */
    public function addRelation(Content $relation)
    {
        $this->related->add($relation);
        $this->related->add($this);
    }

    /**
    * @return array
    */
    public function toArray()
    {
        $related = array();
        foreach($this->getRelated() as $relatedItem) {
        $related[] = $relatedItem->toArray();
    }

    return array(
        'type' => static::getType(),
        'id' => $this->id,
        'title' => $this->title,
        ....
        'related' => $related
    );
}

在用于管理相关内容数据的 RelationsController 中,我像这样使用它:

/**
 * Creates a new relation to a content item
 * 
 * @Route("{_locale}/content/{id}/related", name="relation_add")
 * @Method("POST")
 */
public function addAction(Request $request, $id)
{
    // Validation and error checking
    // $entity is loaded by the repository manager doing a find on the passed $id
    $entity->addRelation($relation);

    $em = $this->getEntityManager();
    $em->persist($entity);
    $em->persist($relation);
    $em->flush();

    $response = $relation->toArray();

    return new JsonResponse($response, 201);
}
4

1 回答 1

1

对此的解决方法是使用JMSSerializerBundle将实体编码为 JSON,而不是使用 toArray 方法并将 addRelation 函数更改为:

/**
 * @param Content $relation
 */
public function addRelation(Content $relation)
{
    $this->related[] = $relation;

    if (! $relation->getRelated()->contains($this)) {
        $relation->addRelation($this);
    }
}
于 2012-10-05T13:11:35.810 回答