2

Doctrineのドキュメントに従って、Symfony 2.1プロジェクトでManyToMany自己参照アソシエーションを実行しようとしています:http://docs.doctrine-project.org/en/latest/reference/association-mapping.html#many-to-多対多-自己参照

私のユースケースは、CMSに取り組んでおり、関連するコンテンツアイテムを持つ機能を追加していることです。例:このコンテンツXはYとZに関連していると言うサイドバーをWebサイトに置くことができます。同様に、コンテンツYが表示されるページでは、コンテンツアイテムXに関連していると表示されます。

私のテストでは、これを使用してコンテンツアイテム間に新しい関係を追加すると、現在のコンテンツアイテムでtoArray()が実行され、次に関連するコンテンツアイテムでtoArray()が実行されるため、PHPの最大ネストレベルである100に達するため失敗します。

多対多の自己参照ドクトリンの関連付けについて、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

これに対する修正は、toArrayメソッドを使用する代わりにJMSSerializerBundleを使用してエンティティをJSONにエンコードし、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 に答える