2015-09-25 86 views
0

的後續行動,我剛纔的問題Doctrine2 ORM訪問多對多連接表

Doctrine2 ORM OneToOne not working UPDATE changed to ManyToMany but not fully working

我接受了非常有用的答案,因爲它指出了我的正確方向。不幸的是,我努力讓其餘的工作,但由於這個問題太長和混亂,我開始一個新的問題。

我有一個頁面,用戶可以寫廣告。用戶還可以收藏他們喜歡的廣告,稍後在其用戶部分查看它們。

我有3個數據庫表

advert (id, advert_title....) 
user (id, user_name....) 
bookmarks (advert_id, user_id) 

正如我剛纔的問題勸,我已經建立2個實體,廣告和用戶實體(見下文)

Advert.php

namespace Advert\Entity; 

use Doctrine\ORM\Mapping as ORM; 
use Doctrine\Common\Collections\ArrayCollection; 
use DateTime; 
use Zend\Stdlib\ArrayObject; 

/** Advert 
* 
* @ORM\Table(name="advert") 
* @ORM\Entity(repositoryClass="Advert\Repository\AdvertRepository") 
*/ 

class Advert 
{ 
/** 
* @var integer 
* @ORM\Column(name="id", type="integer", nullable=false) 
* @ORM\Id 
* @ORM\GeneratedValue(strategy="IDENTITY") 
*/ 
    private $id; 

/** 
* @ORM\ManyToMany(targetEntity="Advert\Entity\User", mappedBy="bookmarks", cascade={"persist"}) 
* @ORM\JoinTable(name="bookmarks", 
*  joinColumns={@ORM\JoinColumn(name="advert_id", referencedColumnName="id")}, 
*  inverseJoinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")} 
*  ) 
*/ 
    private $bookmarks; 


    public function __construct() 
    { 
     $this->categories = new ArrayCollection(); 
     $this->images = new ArrayCollection(); 
     $this->advertCreated = new \DateTime("now"); 
    } 

/** 
* Set ID 
* 
* @param integer $id 
* @return Advert 
*/ 
    public function setId($id) 
    { 
     $this->id = $id; 
     return $this; 
    } 

/** 
* Get id 
* 
* @return integer 
*/ 
    public function getId() 
    { 
     return $this->id; 
    } 

/** 
* Set bookmark 
* 
* @param $bookmark 
* @return bookmark 
*/ 
    public function setBookmark($bookmark) 
    { 
     $this->bookmark = $bookmark; 
     return $this; 
    } 


/** 
* Get bookmark 
* 
* @return ArrayCollection 
*/ 
    public function getBookmark() 
    { 
     return $this->bookmarks; 
    } 


/** 
* @param Collection $bookmark 
*/ 
    public function addBookmark($bookmarks) 
    { 
     $this->bookmarks->add($bookmarks); 
    } 

/** 
* @param Collection $bookmark 
*/ 
    public function removeBookmark($bookmarks) 
    { 
     $this->bookmarks->removeElement($bookmarks);  
    } 
} 

User.php

namespace Advert\Entity; 

use Doctrine\ORM\Mapping as ORM; 
use ZfcUser\Entity\User as ZfcUser; 
use Doctrine\Common\Collections\ArrayCollection; 
use Doctrine\Common\Collections\Collection; 


/** 
* User 
* @ORM\Table(name="user") 
* @ORM\Entity(repositoryClass="Advert\Repository\UserRepository") 
*/ 

class User extends ZfcUser 
{ 
/** 
* @var integer 
* 
* @ORM\Column(name="id", type="integer", nullable=false) 
* @ORM\Id 
* @ORM\GeneratedValue(strategy="IDENTITY") 
*/ 
protected $id; 

/** 
* @ORM\ManyToMany(targetEntity="Advert\Entity\Advert", inversedBy="bookmarks", cascade={"persist"}) 
* @ORM\JoinTable(name="bookmarks", 
*  joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")}, 
*  inverseJoinColumns={@ORM\JoinColumn(name="advert_id", referencedColumnName="id")} 
*  ) 
*/ 
private $bookmarks; 


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

public function getBookmarks() { 
    return $this->bookmarks; 
} 

/** 
* @param Collection $bookmarks 
*/ 
public function addBookmarks(Collection $bookmarks) 
{ 
    foreach ($bookmarks as $bookmark) { 
     $this->bookmarks->add($bookmark); 
    } 
} 

/** 
* @param Collection $bookmarks 
*/ 
public function removeBookmarks(Collection $bookmarks) 
{ 
    foreach ($bookmarks as $bookmark) { 
     $this->bookmarks->removeElement($bookmark); 
    } 
} 
} 

我現在有一個服務來檢查廣告是否已被收藏,刪除書籤或設置書籤。這意味着我必須直接輸入UserId和AdvertId到Join Table Bookmarks中。但是,如果我沒有帶有setUserId和setAdvertId的書籤實體,我該怎麼做?

這是我的服務到目前爲止,最後2種方法(保存和刪除)顯示我在刪除書籤實體之前使用的內容。我現在該如何閱讀Join Table以檢查Bookmark是否已經存在,因此請檢查userId和advertId?再次,我將如何訪問此表以直接刪除書籤?如果廣告被所有者刪除,那麼書籤將被刪除,但很明顯,用戶也需要刪除一個書籤。我如何實現這一目標?

BookmarkAdvertService.php

public function checkAdvertBookmarkStatus($advertId) 
{ 
    $userId = $this->getUserEntity()->getId(); 
    $advert = $this->getEntityManager()->find('Advert\Entity\Advert', $advertId); 
    $bookmarkStatus= $advert->getBookmark(); 
    return $bookmarkStatus; 
} 

public function saveAdvertBookmark($advertId) 
{ 
    //this is what I used before 
    $bookmark = new BookmarkEntity(); 
    $userId = $this->getUserEntity()->getId(); 

    // $bookmark->addBookmark($advertId); ??? like this 
    $bookmark->setAdvertId($advertId); 
    $bookmark->setUserId($userId); 

    # write new bookmmark to database tbl bookmark 
    $this->getEntityManager()->persist($bookmark); 
    $this->getEntityManager()->flush(); 
} 


public function removeAdvertBookmark($advertId) 
{ 
    // this is what I used before 
    $userId = $this->getUserEntity()->getId(); 
    $bookmark = $this->getEntityManager()->getRepository('Advert\Entity\Bookmark') 
             ->findOneBy(array('advertId' => $advertId, 'userId' => $userId)); 

    # remove bookmmark from tbl bookmark 
    $this->getEntityManager()->remove($bookmark); 
    $this->getEntityManager()->flush(); 
} 

更新1不工作

我得到2個錯誤消息:

get_class() expects parameter 1 to be object, string given

vendor\doctrine\common\lib\Doctrine\Common\Persistence\Mapping\MappingException.php:96 

Message: 

Class '' does not exist 

廣告\服務\ BookmarkAdvertService.php

class BookmarkAdvertService 
{ 

    public function saveAdvertBookmark($advert) 
    { 
    $user = $this->getUserEntity()->getId(); 

    # create a new, empty entity 
    $bookmark = new \Advert\Entity\Bookmark(); 
    $bookmark->setUser($user); 
    $bookmark->setAdvert($advert); 
    # write new bookmmark to database tbl bookmark 
    $this->getEntityManager()->persist($bookmark); 
    $this->getEntityManager()->flush(); 
    } 

廣告/實體/ Bookmark.php

namespace Advert\Entity; 
use Doctrine\ORM\Mapping as ORM; 
use Doctrine\Common\Collections\Collection; 

/** Bookmark 
* 
* @ORM\Table(name="bookmarks") 
* @ORM\Entity(repositoryClass="Advert\Repository\BookmarkRepository") 
*/ 
class Bookmark 
{ 
/** 
* @ORM\Id 
* @ORM\ManyToOne(targetEntity="Advert\Entity\Advert", inversedBy="bookmark") 
* @ORM\JoinColumn(name="advert_id", referencedColumnName="id") 
*/ 
private $advert; 

/** 
* @ORM\Id 
* @ORM\ManyToOne(targetEntity="Advert\Entity\User", inversedBy="bookmark") 
* @ORM\JoinColumn(name="user_id", referencedColumnName="id") 
*/ 
private $user; 


public function setAdvert($advert) 
{ 
    $this->advert = $advert; 
    return $this; 
} 

public function getAdvert() 
{ 
    return $this->advert; 
} 


public function setUser($user) 
{ 
    $this->user = $user; 
    return $this; 
} 

public function getUser() 
{ 
    return $this->user; 
}  
} 

廣告\實體\廣告。PHP

namespace Advert\Entity; 
use Advert\Entity; 
use Doctrine\Common\Collections\ArrayCollection; 
use Doctrine\Common\Collections\Collection; 
/** Advert 
* 
* @ORM\Table(name="advert") 
* @ORM\Entity(repositoryClass="Advert\Repository\AdvertRepository") 
*/ 
class Advert 
{ 
/** 
* @var integer 
* 
* @ORM\Column(name="id", type="integer", nullable=false) 
* @ORM\Id 
* @ORM\GeneratedValue(strategy="IDENTITY") 
*/ 
private $id; 

/** 
* @ORM\OneToMany(targetEntity="Bookmark", mappedBy="advert", cascade={"persist", "remove"}) 
* @ORM\JoinColumn(name="advert_id", referencedColumnName="id") 
*/ 
private $bookmarks; 

public function setBookmark($bookmark) 
{ 
    $this->bookmark = $bookmark; 
    return $this; 
} 


/** 
* Get bookmark 
* 
* @return ArrayCollection 
*/ 
public function getBookmarks() 
{ 
    return $this->bookmarks; 
} 

/** 
* @param Collection $bookmarks 
*/ 
public function removeBookmarks(Collection $bookmarks) 
{ 
    foreach ($bookmarks as $bookmark) { 
    $this->bookmarks->removeElement($bookmark); 
} 
} 

廣告\實體\ user.php的

namespace Advert\Entity; 

use Doctrine\ORM\Mapping as ORM; 
use ZfcUser\Entity\User as ZfcUser; 
use Doctrine\Common\Collections\ArrayCollection; 
use Doctrine\Common\Collections\Collection; 

/** 
* User 
* 
* @ORM\Table(name="user") 
* @ORM\Entity(repositoryClass="Advert\Repository\UserRepository") 
*/ 

class User extends ZfcUser 
{ 
/** 
* @var integer 
* 
* @ORM\Column(name="id", type="integer", nullable=false) 
* @ORM\Id 
* @ORM\GeneratedValue(strategy="IDENTITY") 
*/ 
protected $id; 

/** 
* @ORM\OneToMany(targetEntity="Bookmark", mappedBy="user", cascade={"persist", "remove"}) 
* @ORM\JoinColumn(name="user_id", referencedColumnName="id") 
*/ 
private $bookmarks; 


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


public function getBookmarks() 
{ 
    return $this->bookmarks; 
} 

/** 
* @param Collection $bookmarks 
*/ 
public function addBookmarks(Collection $bookmarks) 
{ 
    foreach ($bookmarks as $bookmark) { 
     $this->bookmarks->add($bookmark); 
    } 
} 

/** 
* @param Collection $bookmarks 
*/ 
public function removeBookmarks(Collection $bookmarks) 
{ 
    foreach ($bookmarks as $bookmark) { 
     $this->bookmarks->removeElement($bookmark); 
    } 
} 

UPDATE 2個工作

public function saveAdvertBookmark($advertId) 
{ 
    $userId = $this->getUserEntity()->getId(); 
    $user = $this->getEntityManager()->find('Advert\Entity\User', $userId); 
    $advert = $this->getEntityManager()->find('Advert\Entity\Advert', $advertId); 
    # create a new, empty entity 
    $bookmark = new \Advert\Entity\Bookmark(); 
    $bookmark->setUser($user); 
    $bookmark->setAdvert($advert); 
    # write new bookmmark to database tbl bookmark 
    $this->getEntityManager()->persist($bookmark); 
    $this->getEntityManager()->flush(); 
} 


public function removeAdvertBookmark($advert) 
{ 
    $user = $this->getUserEntity()->getId(); 
    $advert = $this->getEntityManager()->getRepository('Advert\Entity\Bookmark') 
             ->findOneBy(array('advert' => $advert, 'user' => $user)); 
    if ($advert !== NULL){ 

     # write new bookmmark to database tbl bookmark 
     $this->getEntityManager()->remove($advert); 
     $this->getEntityManager()->flush(); 
    }else{ 
     return false; 
    } 
} 

回答

1

你的映射似乎是錯誤的。 在我看來,你的書籤本身也是一個實體。該實體有一個User和一個Advert。這兩個組合創建一個組合鍵。

因此,從UserBookmark的關係是一對多關係。和用戶多對一的書籤。

AdvertBookmark的關係是一個一對多和從BookmarkAdvert多到一個。

Bookmark實體應該是這個樣子:

class Bookmark 
{ 
    /** 
    * @ORM\Id 
    * @ORM\ManyToOne(targetEntity="Advert\Entity\Advert", inversedBy="bookmarks") 
    * @ORM\JoinColumn(name="advert_id", referencedColumnName="id") 
    */ 
    private $advert; 

    /** 
    * @ORM\Id 
    * @ORM\ManyToOne(targetEntity="User\Entity\User", inversedBy="bookmarks") 
    * @ORM\JoinColumn(name="user_id", referencedColumnName="id") 
    */ 
    private $user; 

    /** 
    * @param Advert $advert 
    * @return self 
    */ 
    public function setAdvert(Advert $advert) 
    { 
     $this->advert = $advert; 
     $advert->addBookMark($this); 
     return $this; 
    } 

    /** 
    * @return Advert 
    */ 
    public function getAdvert() 
    { 
     return $this->advert; 
    } 

    /** 
    * @param User $user 
    * @return self 
    */ 
    public function setUser(User $user) 
    { 
     $this->user = $user; 
     $user->addBookMark($this); 
     return $this; 
    } 

    /** 
    * @return User 
    */ 
    public function getUser() 
    { 
     return $this->user; 
    }  
} 

然後在您的User

/** 
* @ORM\OneToMany(targetEntity="Advert\Entity\BookMark", mappedBy="user", cascade={"remove"}) 
*/ 
private $bookmarks; 

/** 
* @return Collection 
*/ 
public function getBookmarks() 
{ 
    return $this->bookmarks; 
} 

/** 
* @param BookMark $bookmark 
*/ 
public function addBookmark(BookMark $bookmark) 
{ 
    $this->bookmarks->add($bookmark); 
} 

/** 
* @param Collection $bookmarks 
*/ 
public function addBookmarks(Collection $bookmarks) 
{ 
    foreach ($bookmarks as $bookmark) { 
     $this->addBookMark($bookmark); 
    } 
} 

/** 
* @param BookMark $bookmark 
*/ 
public function removeBookmark(BookMark $bookmark) 
{ 
    $this->bookmarks->removeElement($bookmark); 
} 

/** 
* @param Collection $bookmarks 
*/ 
public function removeBookmarks(Collection $bookmarks) 
{ 
    foreach ($bookmarks as $bookmark) { 
     $this->removeBookmark($bookmark); 
    } 
} 

而在你Advert

/** 
* @ORM\OneToMany(targetEntity="Advert\Entity\BookMark", mappedBy="advert", cascade={"remove"}) 
*/ 
private $bookmarks; 

/** 
* @return Collection 
*/ 
public function getBookmarks() 
{ 
    return $this->bookmarks; 
} 

/** 
* @param BookMark $bookmark 
*/ 
public function addBookmark(BookMark $bookmark) 
{ 
    $this->bookmarks->add($bookmark); 
} 

/** 
* @param Collection $bookmarks 
*/ 
public function addBookmarks(Collection $bookmarks) 
{ 
    foreach ($bookmarks as $bookmark) { 
     $this->addBookMark($bookmark); 
    } 
} 

/** 
* @param BookMark $bookmark 
*/ 
public function removeBookmark(BookMark $bookmark) 
{ 
    $this->bookmarks->removeElement($bookmark); 
} 

/** 
* @param Collection $bookmarks 
*/ 
public function removeBookmarks(Collection $bookmarks) 
{ 
    foreach ($bookmarks as $bookmark) { 
     $this->removeBookmark($bookmark); 
    } 
} 

在服務:

/** 
* @param int $advertId 
*/ 
public function saveAdvertBookmark($advertId) 
{ 
    $entityManager = $this->getEntityManager(): 
    $user = $this->getUserEntity(); 

    $advert = $entityManager->find('Advert\Entity\Advert', $advertId): 
    $bookmark = new \Advert\Entity\Bookmark(); 
    $bookmark->setUser($user); 
    $bookmark->setAdvert($advert); 

    $entityManager->persist($bookmark); 
    $entityManager->flush(); 
} 

要當您刪除UserAdvert只是在這些實體書籤之間的關係添加cascade={"remove"}刪除所有書籤。