发出持久嵌套嵌套嵌入文档

发布于 2024-11-01 04:35:26 字数 10939 浏览 5 评论 0原文

更新: 非常确定这是一个错误,在 Jira 上提出了一个问题:http://bit.ly/ GPSW9
更新(2011 年 5 月 5 日):根据 jwage 的建议,我已切换到类别和帖子之间的引用关系(而不是嵌入)。

我正在使用最新版本的 Doctrine ODM(来自 Git)。

我有三个级别的文档(两个嵌入式);类别-> EmbedsMany:发布 ->嵌入许多帖子版本。

PostVersion 由 Post 自动处理。当我发布新帖子时,它实际上也在幕后创建了一个新的帖子版本。

我的问题是 Doctrine 与 PostVersions 混淆,如果我检索现有类别并向其添加新帖子,新帖子的 PostVersions 将添加到类别 $posts 集合中的第一个帖子。

一步一步:

  1. 制作新帖子 (Post1) 和类别
  2. 将 Post1 添加到类别
  3. 保留类别、刷新、清除
  4. 检索类别
  5. 制作新帖子 (Post2)
  6. 将 Post2 添加到类别
  7. 刷新

在此阶段,数据库中应该有一个类别,两个帖子,每个帖子有一个帖子版本。然而,实际发生的情况是有一个类别,两个帖子,第一个帖子有两个帖子版本,第二个帖子有零个帖子版本。

请求期间的文档本身是正确的,只是希望将其保存到错误的数据库中。我缺少什么?

预期结果:

{
  "_id": ObjectId("4da66baa6dd08df1f6000001"),
  "name": "The Category",
  "posts": [
    {
      "_id": ObjectId("4da66baa6dd08df1f6000002"),
      "activeVersionIndex": 0,
      "versions": [
        {
          "_id": ObjectId("4da66baa6dd08df1f6000003"),
          "name": "One Post",
          "content": "One Content",
          "metaDescription": null,
          "isAutosave": false,
          "createdAt": "Thu, 14 Apr 2011 13:36:10 +1000",
          "createdBy": "Cobby"
        }
      ]
    },
    {
      "_id": ObjectId("4da66baa6dd08df1f6000004"),
      "activeVersionIndex": 0
      "versions": [
        {
          "_id": ObjectId("4da66baa6dd08df1f6000005"),
          "name": "Two Post",
          "content": "Two Content",
          "metaDescription": null,
          "isAutosave": false,
          "createdAt": "Thu, 14 Apr 2011 13:36:10 +1000",
          "createdBy": "Cobby"
        }
      ]
    }
  ]
}

实际结果:

{
  "_id": ObjectId("4da66baa6dd08df1f6000001"),
  "name": "The Category",
  "posts": [
    {
      "_id": ObjectId("4da66baa6dd08df1f6000002"),
      "activeVersionIndex": 0,
      "versions": [
        {
          "_id": ObjectId("4da66baa6dd08df1f6000003"),
          "name": "One Post",
          "content": "One Content",
          "metaDescription": null,
          "isAutosave": false,
          "createdAt": "Thu, 14 Apr 2011 13:36:10 +1000",
          "createdBy": "Cobby"
        },
        {
          "_id": ObjectId("4da66baa6dd08df1f6000005"),
          "name": "Two Post",
          "content": "Two Content",
          "metaDescription": null,
          "isAutosave": false,
          "createdAt": "Thu, 14 Apr 2011 13:36:10 +1000",
          "createdBy": "Cobby"
        }
      ]
    },
    {
      "_id": ObjectId("4da66baa6dd08df1f6000004"),
      "activeVersionIndex": 0
    }
  ]
}

这是我的文档

Category.php

<?php

namespace Documents\Blog;

use Doctrine\Common\Collections\ArrayCollection;

/**
 * @Document(collection="blog")
 * @HasLifecycleCallbacks
 */
class Category
{

    /**
     * @Id
     */
    private $id;

    /**
     * @String
     */
    private $name;

    /**
     * @EmbedMany(targetDocument="Documents\Blog\Post")
     */
    private $posts;

    public function __construct($name = null)
    {
        $this->posts = new ArrayCollection();
        $this->setName($name);
    }

    public function getId()    
    {
        return $this->id;
    }

    public function getName()
    {
        return $this->name;
    }

    public function setName($name)
    {
        $this->name = $name;
    }

    public function getPosts()
    {
        return $this->posts->toArray();
    }

    public function addPost(Post $post)
    {
        $this->posts->add($post);
    }

    public function getPost($id)
    {
        return $this->posts->filter(function($post) use($id){
            return $post->getId() === $id;
        })->first();
    }

}

Post.php

<?php

namespace Documents\Blog;

use Doctrine\Common\Collections\ArrayCollection;

/**
 * @EmbeddedDocument
 * @HasLifecycleCallbacks
 */
class Post
{

    /**
     * @Id
     */
    private $id;

    private $firstVersion;

    private $activeVersion;

    /**
     * @Int
     */
    private $activeVersionIndex;

    /**
     * @EmbedMany(targetDocument="Documents\Blog\PostVersion")
     */
    private $versions;

    static private $currentUser;

    private $isDirty = false;

    public function __construct($name = "", $content = "")
    {
        if(!self::$currentUser){
            throw new \BlogException("Cannot create a post without the current user being set");
        }

        $this->versions      = new ArrayCollection();
        $this->activeVersion = $this->firstVersion = new PostVersion($name, $content, self::$currentUser);
        $this->versions->add($this->firstVersion);
        $this->isDirty = true;
    }

    public function getId()     
    {
        return $this->id;
    }

    public function getFirstVersion()
    {
        return $this->firstVersion;
    }

    public function getActiveVersion()
    {
        return $this->activeVersion;
    }

    public function setName($name)
    {
        $this->_setVersionValue('name', $name);
    }

    public function getName()
    {
        return $this->getActiveVersion()->getName();
    }

    public function setContent($content)
    {
        $this->_setVersionValue('content', $content);
    }

    public function getContent()
    {
        return $this->getActiveVersion()->getContent();
    }

    public function setMetaDescription($metaDescription)
    {
        $this->_setVersionValue('metaDescription', $metaDescription);
    }

    public function getMetaDescription()
    {
        return $this->getActiveVersion()->getMetaDescription();
    }

    public function getVersions()
    {
        return $this->versions->toArray();
    }

    private function _setVersionValue($property, $value)
    {   
        $version = $this->activeVersion;

        if(!$this->isDirty){
        // not dirty, make a new version
            $version = new PostVersion($version->getName(), $version->getContent(), self::getCurrentUser());
        }

        $refl = new \ReflectionProperty(get_class($version), $property);
        $refl->setAccessible(true);

        // updated current user
        $refl->setValue($version, $value);

        // unset ID
        $refl = new \ReflectionProperty(get_class($version), 'id');
        $refl->setAccessible(true);
        $refl->setValue($version, null);

        // updated self
        if(!$this->isDirty){
            $this->activeVersion = $version;
            $this->versions->add($version);
            $this->isDirty = true;
        }

        // no first version, this must be the first
        if($this->versions->count() === 1){
            $this->firstVersion = $version;
        }
    }

    static public function setCurrentUser($user)
    {
        self::$currentUser = $user;
    }

    static public function getCurrentUser()
    {
        return self::$currentUser;
    }

    /**
     * @PostLoad
     */
    public function findFirstVersion()
    {
        $firstVersion = null;
        foreach($this->versions as $version){
            if(null === $firstVersion){
                // first iteration, start with any version
                $firstVersion = $version;
                continue;
            }

            if($version->getCreatedAt() < $firstVersion->getCreatedAt()){
                // current version is newer than existing version
                $firstVersion = $version;
            }
        }

        if(null === $firstVersion){
            throw new \DomainException("No first version found.");
        }

        $this->firstVersion = $firstVersion;
    }

    /**
     * @PostLoad
     */
    public function findActiveVersion()
    {
        $this->activeVersion = $this->versions->get($this->activeVersionIndex);
    }

    /**
     * @PrePersist
     * @PreUpdate
     */
    public function doActiveVersionIndex()
    {
        $this->activeVersionIndex = $this->versions->indexOf($this->activeVersion);
        $this->isDirty = false;
    }

    /**
     * @PostPersist
     * @PostUpdate
     */
    public function makeClean()
    {
        $this->isDirty = false;
    }

    public function getCreatedBy()
    {
        return $this->getFirstVersion()->getCreatedBy();
    }

    public function getCreatedAt()
    {
        return $this->getFirstVersion()->getCreatedAt();
    }

}

PostVersion.php

<?php

namespace Documents\Blog;

/**
 * @EmbeddedDocument
 */
class PostVersion
{

    /**
     * @Id
     */
    private $id;

    /**
     * @String
     */
    private $name;

    /**
     * @String
     */
    private $content;

    /**
     * @String(nullable="true")
     */
    private $metaDescription;

    /**
     * @Boolean
     */
    private $isAutosave = false;

    /**
     * @Date
     */
    private $createdAt;

    /**
     * @String
     */
    private $createdBy;

    public function __construct($name, $content, $author)
    {
        $this->setName($name);
        $this->setContent($content);
        $this->setCreatedBy($author);
        $this->touch();
    }

    public function __clone()
    {
        if($this->id){
            $this->id = null;
            $this->touch();
        }
    }

    private function touch()
    {
        $this->createdAt = new \DateTime();
    }

    public function getId()     
    {
        return $this->id;
    }

    public function getName()
    {
        return $this->name;
    }

    public function setName($name)
    {
        $this->name = $name;
    }

    public function getContent()
    {
        return $this->content;
    }

    public function setContent($content)
    {
        $this->content = $content;
    }

    public function getIsAutosave()
    {
        return $this->isAutosave;
    }

    public function setIsAutosave($isAutosave)
    {
        $this->isAutosave = $isAutosave;
    }

    public function getCreatedAt()
    {
        return $this->createdAt;
    }

    public function setCreatedAt(\DateTime $createdAt)
    {
        $this->createdAt = $createdAt;
    }

    public function getCreatedBy()
    {
        return $this->createdBy;
    }

    public function setCreatedBy($createdBy)
    {
        $this->createdBy = $createdBy;
    }

    public function setMetaDescription($metaDescription)
    {
        $this->metaDescription = $metaDescription;
    }

    public function getMetaDescription()
    {
        return $this->metaDescription;
    }

}

...我想是时候开始使用 xdebug 了。

Update: Pretty certain this a bug, made an issue on Jira: http://bit.ly/gpstW9
Update (5th May 2011): Upon jwage's recommendation I have switch to Referenced relationships between Categories and Post (as opposed to Embdedded).

I'm using the latest version of Doctrine ODM (fresh from Git).

I have three levels of Documents (Two embedded); Category -> EmbedsMany: Post -> EmbedsMany PostVersion.

PostVersion is automatically handled by Post. When I make a new post, it actually makes a new PostVersion under the hood as well.

My issue is that Doctrine get confused with PostVersions, if I retrieve an existing Category and add a new Post to it, the new Post's PostVersions get add to the first Post in the Category's $posts collection.

Step-by-step:

  1. Make a new Post (Post1) and Category
  2. Add Post1 to Category
  3. Persist Category, Flush, Clear
  4. Retrieve Category
  5. Make a new Post (Post2)
  6. Add Post2 to Category
  7. Flush

At this stage in the database, there should be one Category, two Posts and each Post has one PostVersion. However, what actually happens is there is one Category, two Posts, the first Post has two PostVersions and the second Post has zero PostVersions.

The Documents themselves during the request are correct, it's just want is persisted to the database that is wrong. What am I missing?

Expected Result:

{
  "_id": ObjectId("4da66baa6dd08df1f6000001"),
  "name": "The Category",
  "posts": [
    {
      "_id": ObjectId("4da66baa6dd08df1f6000002"),
      "activeVersionIndex": 0,
      "versions": [
        {
          "_id": ObjectId("4da66baa6dd08df1f6000003"),
          "name": "One Post",
          "content": "One Content",
          "metaDescription": null,
          "isAutosave": false,
          "createdAt": "Thu, 14 Apr 2011 13:36:10 +1000",
          "createdBy": "Cobby"
        }
      ]
    },
    {
      "_id": ObjectId("4da66baa6dd08df1f6000004"),
      "activeVersionIndex": 0
      "versions": [
        {
          "_id": ObjectId("4da66baa6dd08df1f6000005"),
          "name": "Two Post",
          "content": "Two Content",
          "metaDescription": null,
          "isAutosave": false,
          "createdAt": "Thu, 14 Apr 2011 13:36:10 +1000",
          "createdBy": "Cobby"
        }
      ]
    }
  ]
}

Actual Result:

{
  "_id": ObjectId("4da66baa6dd08df1f6000001"),
  "name": "The Category",
  "posts": [
    {
      "_id": ObjectId("4da66baa6dd08df1f6000002"),
      "activeVersionIndex": 0,
      "versions": [
        {
          "_id": ObjectId("4da66baa6dd08df1f6000003"),
          "name": "One Post",
          "content": "One Content",
          "metaDescription": null,
          "isAutosave": false,
          "createdAt": "Thu, 14 Apr 2011 13:36:10 +1000",
          "createdBy": "Cobby"
        },
        {
          "_id": ObjectId("4da66baa6dd08df1f6000005"),
          "name": "Two Post",
          "content": "Two Content",
          "metaDescription": null,
          "isAutosave": false,
          "createdAt": "Thu, 14 Apr 2011 13:36:10 +1000",
          "createdBy": "Cobby"
        }
      ]
    },
    {
      "_id": ObjectId("4da66baa6dd08df1f6000004"),
      "activeVersionIndex": 0
    }
  ]
}

Here are my Documents

Category.php

<?php

namespace Documents\Blog;

use Doctrine\Common\Collections\ArrayCollection;

/**
 * @Document(collection="blog")
 * @HasLifecycleCallbacks
 */
class Category
{

    /**
     * @Id
     */
    private $id;

    /**
     * @String
     */
    private $name;

    /**
     * @EmbedMany(targetDocument="Documents\Blog\Post")
     */
    private $posts;

    public function __construct($name = null)
    {
        $this->posts = new ArrayCollection();
        $this->setName($name);
    }

    public function getId()    
    {
        return $this->id;
    }

    public function getName()
    {
        return $this->name;
    }

    public function setName($name)
    {
        $this->name = $name;
    }

    public function getPosts()
    {
        return $this->posts->toArray();
    }

    public function addPost(Post $post)
    {
        $this->posts->add($post);
    }

    public function getPost($id)
    {
        return $this->posts->filter(function($post) use($id){
            return $post->getId() === $id;
        })->first();
    }

}

Post.php

<?php

namespace Documents\Blog;

use Doctrine\Common\Collections\ArrayCollection;

/**
 * @EmbeddedDocument
 * @HasLifecycleCallbacks
 */
class Post
{

    /**
     * @Id
     */
    private $id;

    private $firstVersion;

    private $activeVersion;

    /**
     * @Int
     */
    private $activeVersionIndex;

    /**
     * @EmbedMany(targetDocument="Documents\Blog\PostVersion")
     */
    private $versions;

    static private $currentUser;

    private $isDirty = false;

    public function __construct($name = "", $content = "")
    {
        if(!self::$currentUser){
            throw new \BlogException("Cannot create a post without the current user being set");
        }

        $this->versions      = new ArrayCollection();
        $this->activeVersion = $this->firstVersion = new PostVersion($name, $content, self::$currentUser);
        $this->versions->add($this->firstVersion);
        $this->isDirty = true;
    }

    public function getId()     
    {
        return $this->id;
    }

    public function getFirstVersion()
    {
        return $this->firstVersion;
    }

    public function getActiveVersion()
    {
        return $this->activeVersion;
    }

    public function setName($name)
    {
        $this->_setVersionValue('name', $name);
    }

    public function getName()
    {
        return $this->getActiveVersion()->getName();
    }

    public function setContent($content)
    {
        $this->_setVersionValue('content', $content);
    }

    public function getContent()
    {
        return $this->getActiveVersion()->getContent();
    }

    public function setMetaDescription($metaDescription)
    {
        $this->_setVersionValue('metaDescription', $metaDescription);
    }

    public function getMetaDescription()
    {
        return $this->getActiveVersion()->getMetaDescription();
    }

    public function getVersions()
    {
        return $this->versions->toArray();
    }

    private function _setVersionValue($property, $value)
    {   
        $version = $this->activeVersion;

        if(!$this->isDirty){
        // not dirty, make a new version
            $version = new PostVersion($version->getName(), $version->getContent(), self::getCurrentUser());
        }

        $refl = new \ReflectionProperty(get_class($version), $property);
        $refl->setAccessible(true);

        // updated current user
        $refl->setValue($version, $value);

        // unset ID
        $refl = new \ReflectionProperty(get_class($version), 'id');
        $refl->setAccessible(true);
        $refl->setValue($version, null);

        // updated self
        if(!$this->isDirty){
            $this->activeVersion = $version;
            $this->versions->add($version);
            $this->isDirty = true;
        }

        // no first version, this must be the first
        if($this->versions->count() === 1){
            $this->firstVersion = $version;
        }
    }

    static public function setCurrentUser($user)
    {
        self::$currentUser = $user;
    }

    static public function getCurrentUser()
    {
        return self::$currentUser;
    }

    /**
     * @PostLoad
     */
    public function findFirstVersion()
    {
        $firstVersion = null;
        foreach($this->versions as $version){
            if(null === $firstVersion){
                // first iteration, start with any version
                $firstVersion = $version;
                continue;
            }

            if($version->getCreatedAt() < $firstVersion->getCreatedAt()){
                // current version is newer than existing version
                $firstVersion = $version;
            }
        }

        if(null === $firstVersion){
            throw new \DomainException("No first version found.");
        }

        $this->firstVersion = $firstVersion;
    }

    /**
     * @PostLoad
     */
    public function findActiveVersion()
    {
        $this->activeVersion = $this->versions->get($this->activeVersionIndex);
    }

    /**
     * @PrePersist
     * @PreUpdate
     */
    public function doActiveVersionIndex()
    {
        $this->activeVersionIndex = $this->versions->indexOf($this->activeVersion);
        $this->isDirty = false;
    }

    /**
     * @PostPersist
     * @PostUpdate
     */
    public function makeClean()
    {
        $this->isDirty = false;
    }

    public function getCreatedBy()
    {
        return $this->getFirstVersion()->getCreatedBy();
    }

    public function getCreatedAt()
    {
        return $this->getFirstVersion()->getCreatedAt();
    }

}

PostVersion.php

<?php

namespace Documents\Blog;

/**
 * @EmbeddedDocument
 */
class PostVersion
{

    /**
     * @Id
     */
    private $id;

    /**
     * @String
     */
    private $name;

    /**
     * @String
     */
    private $content;

    /**
     * @String(nullable="true")
     */
    private $metaDescription;

    /**
     * @Boolean
     */
    private $isAutosave = false;

    /**
     * @Date
     */
    private $createdAt;

    /**
     * @String
     */
    private $createdBy;

    public function __construct($name, $content, $author)
    {
        $this->setName($name);
        $this->setContent($content);
        $this->setCreatedBy($author);
        $this->touch();
    }

    public function __clone()
    {
        if($this->id){
            $this->id = null;
            $this->touch();
        }
    }

    private function touch()
    {
        $this->createdAt = new \DateTime();
    }

    public function getId()     
    {
        return $this->id;
    }

    public function getName()
    {
        return $this->name;
    }

    public function setName($name)
    {
        $this->name = $name;
    }

    public function getContent()
    {
        return $this->content;
    }

    public function setContent($content)
    {
        $this->content = $content;
    }

    public function getIsAutosave()
    {
        return $this->isAutosave;
    }

    public function setIsAutosave($isAutosave)
    {
        $this->isAutosave = $isAutosave;
    }

    public function getCreatedAt()
    {
        return $this->createdAt;
    }

    public function setCreatedAt(\DateTime $createdAt)
    {
        $this->createdAt = $createdAt;
    }

    public function getCreatedBy()
    {
        return $this->createdBy;
    }

    public function setCreatedBy($createdBy)
    {
        $this->createdBy = $createdBy;
    }

    public function setMetaDescription($metaDescription)
    {
        $this->metaDescription = $metaDescription;
    }

    public function getMetaDescription()
    {
        return $this->metaDescription;
    }

}

...time to get dirty with xdebug I think.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

々眼睛长脚气 2024-11-08 04:35:26

现在我已经通过创建一个 EventSubscriber 来解决这个问题,它会延迟持久的嵌套嵌入文档,它看起来像这样:

<?php

namespace Application\Blog\Domain\EventSubscribers;

use Application\Blog\Domain\Document\Post,
    Doctrine\ODM\MongoDB\Event\LifecycleEventArgs,
    Doctrine\ODM\MongoDB\Mapping\ClassMetadata;

/**
 * Handles delayed insert of nested embedded documents to work around Doctrine ODM bug :(
 */
class VersionManager implements \Doctrine\Common\EventSubscriber
{

    private $versions = array();

    /**
     * Returns an array of events this subscriber wants to listen to.
     *
     * @return array
     */
    public function getSubscribedEvents()
    {
        return array('prePersist', 'postPersist');
    }

    /**
     * Move versions out of Posts into temporary storage so they are flushed without versions
     *
     * @param \Doctrine\ODM\MongoDB\Event\LifecycleEventArgs $eventArgs
     * @return void
     */
    public function prePersist(LifecycleEventArgs $eventArgs)
    {
        $document = $eventArgs->getDocument();
        if($document instanceof Post){
            $dm = $eventArgs->getDocumentManager();
            $meta = $dm->getClassMetadata(get_class($document));
            $this->addVersion($meta, $document);
            $this->clearVersions($meta, $document);
        }
    }

    /**
     * Move the temporary versions back onto the Posts and flush
     *
     * @param \Doctrine\ODM\MongoDB\Event\LifecycleEventArgs $eventArgs
     * @return void
     */
    public function postPersist(LifecycleEventArgs $eventArgs)
    {
        $dm = $eventArgs->getDocumentManager();
        $hasChanges = count($this->versions) > 0;

        foreach($this->versions as $oid => $value){
            $post = $value['document'];
            $versions = $value['versions'];
            $meta = $dm->getClassMetadata(get_class($post));
            $meta->setFieldValue($post, 'versions', $versions);
            unset($this->versions[$oid]);
        }

        if($hasChanges){
            $dm->flush();
        }
    }

    /**
     * Add versions to temporary storage
     *
     * @param \Doctrine\ODM\MongoDB\Mapping\ClassMetadata $meta
     * @param \Application\Blog\Domain\Document\Post $post
     * @return void
     */
    private function addVersion(ClassMetadata $meta, Post $post)
    {
        $this->versions[spl_object_hash($post)] = array(
            'document' => $post,
            'versions' => $meta->getFieldValue($post, 'versions')
        );
    }

    /**
     * Remove versions from a Post
     *
     * @param \Doctrine\ODM\MongoDB\Mapping\ClassMetadata $meta
     * @param \Application\Blog\Domain\Document\Post $post
     * @return void
     */
    private function clearVersions(ClassMetadata $meta, Post $post)
    {
        $meta->setFieldValue($post, 'versions', null);
    }

}

For now I've worked around the issue by creating an EventSubscriber which delays persisted nested embedded documents, it looks like this:

<?php

namespace Application\Blog\Domain\EventSubscribers;

use Application\Blog\Domain\Document\Post,
    Doctrine\ODM\MongoDB\Event\LifecycleEventArgs,
    Doctrine\ODM\MongoDB\Mapping\ClassMetadata;

/**
 * Handles delayed insert of nested embedded documents to work around Doctrine ODM bug :(
 */
class VersionManager implements \Doctrine\Common\EventSubscriber
{

    private $versions = array();

    /**
     * Returns an array of events this subscriber wants to listen to.
     *
     * @return array
     */
    public function getSubscribedEvents()
    {
        return array('prePersist', 'postPersist');
    }

    /**
     * Move versions out of Posts into temporary storage so they are flushed without versions
     *
     * @param \Doctrine\ODM\MongoDB\Event\LifecycleEventArgs $eventArgs
     * @return void
     */
    public function prePersist(LifecycleEventArgs $eventArgs)
    {
        $document = $eventArgs->getDocument();
        if($document instanceof Post){
            $dm = $eventArgs->getDocumentManager();
            $meta = $dm->getClassMetadata(get_class($document));
            $this->addVersion($meta, $document);
            $this->clearVersions($meta, $document);
        }
    }

    /**
     * Move the temporary versions back onto the Posts and flush
     *
     * @param \Doctrine\ODM\MongoDB\Event\LifecycleEventArgs $eventArgs
     * @return void
     */
    public function postPersist(LifecycleEventArgs $eventArgs)
    {
        $dm = $eventArgs->getDocumentManager();
        $hasChanges = count($this->versions) > 0;

        foreach($this->versions as $oid => $value){
            $post = $value['document'];
            $versions = $value['versions'];
            $meta = $dm->getClassMetadata(get_class($post));
            $meta->setFieldValue($post, 'versions', $versions);
            unset($this->versions[$oid]);
        }

        if($hasChanges){
            $dm->flush();
        }
    }

    /**
     * Add versions to temporary storage
     *
     * @param \Doctrine\ODM\MongoDB\Mapping\ClassMetadata $meta
     * @param \Application\Blog\Domain\Document\Post $post
     * @return void
     */
    private function addVersion(ClassMetadata $meta, Post $post)
    {
        $this->versions[spl_object_hash($post)] = array(
            'document' => $post,
            'versions' => $meta->getFieldValue($post, 'versions')
        );
    }

    /**
     * Remove versions from a Post
     *
     * @param \Doctrine\ODM\MongoDB\Mapping\ClassMetadata $meta
     * @param \Application\Blog\Domain\Document\Post $post
     * @return void
     */
    private function clearVersions(ClassMetadata $meta, Post $post)
    {
        $meta->setFieldValue($post, 'versions', null);
    }

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文