【发布时间】:2019-07-29 14:54:59
【问题描述】:
我正在尝试在 symfony 中创建具有 ManyToMany 关系的两个表之间的链接。我有一个 Post 表,它基本上是一个用于存储来自用户的所有帖子(如 Facebook 帖子、带有 cmets、likes、users 等)的表,我还有一个标签表,用于存储用户创建的所有不同标签。 manytomany 的关系是为了帮助我在帖子和它的标签之间建立一个链接。
它适用于上述用户,其工作方式与标签完全相同。 (提到的用户就像标签,但你只能标签人)。实际的标签是为了让用户可以在帖子中标记事件和公司。然后他们将能够搜索所有现有的标签,有点像 Instagram。
这是我的标签实体:
<?php
namespace AppBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* Tag
*
* @ORM\Table(name="tag", uniqueConstraints={@ORM\UniqueConstraint(name="tag_id_uindex", columns={"id"})})
* @ORM\Entity
*/
class Tag
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="libelle", type="string", length=255, nullable=false)
*/
private $libelle;
/**
* @var Collection
*
* @ORM\ManyToMany(targetEntity="Post", mappedBy="tags")
*/
private $posts;
/**
* Constructor
*/
public function __construct()
{
$this->posts = new ArrayCollection();
}
/**
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* @param int $id
*/
public function setId($id)
{
$this->id = $id;
}
/**
* @return string
*/
public function getLibelle()
{
return $this->libelle;
}
/**
* @param string $libelle
*/
public function setLibelle($libelle)
{
$this->libelle = $libelle;
}
/**
* @return Collection
*/
public function getPosts()
{
return $this->posts;
}
/**
* @param Collection $posts
*/
public function setPosts($posts)
{
$this->posts = $posts;
}
}
这是我的帖子实体:
<?php
namespace AppBundle\Entity;
use DateTime;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\Mapping\OneToMany;
/**
* Post
*
* @ORM\Table(name="post", uniqueConstraints={@ORM\UniqueConstraint(name="post_id_uindex", columns={"id"})}, indexes={@ORM\Index(name="post_post_type_id_fk", columns={"post_type_id"}), @ORM\Index(name="post_club_id_fk", columns={"club_id"}), @ORM\Index(name="post_user_id_fk", columns={"user_id"})})
* @ORM\Entity(repositoryClass="AppBundle\Repository\PostRepository")
*/
class Post
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @var boolean
*
* @ORM\Column(name="enabled", type="boolean", nullable=false)
*/
private $enabled = true;
/**
* @var DateTime
*
* @ORM\Column(name="create_date", type="datetime", nullable=false)
*/
private $createDate;
/**
* @var string
*
* @ORM\Column(name="content", type="text", length=65535, nullable=false)
*/
private $content;
///**
// * @var string
// *
// * @ORM\Column(name="title", type="string", length=255, nullable=false)
// */
//private $title;
/**
* @var string
*
* @ORM\Column(name="attachment", type="string", length=255, nullable=false)
*/
private $attachment;
/**
* @var Club
*
* @ORM\ManyToOne(targetEntity="Club")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="club_id", referencedColumnName="id")
* })
*/
private $club;
/**
* @var PostType
*
* @ORM\ManyToOne(targetEntity="PostType")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="post_type_id", referencedColumnName="id")
* })
*/
private $postType;
/**
* @var User
*
* @ORM\ManyToOne(targetEntity="User")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="user_id", referencedColumnName="id")
* })
*/
private $user;
/**
* @var Manager
*
* @ORM\ManyToOne(targetEntity="Manager")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="manager_id", referencedColumnName="id")
* })
*/
private $manager;
/**
* @var Collection
*
* @ORM\ManyToMany(targetEntity="Tag", mappedBy="posts")
* @ORM\JoinTable(name="post_has_tag",
* joinColumns={
* @ORM\JoinColumn(name="post_id", referencedColumnName="id")
* },
* inverseJoinColumns={
* @ORM\JoinColumn(name="tag_id", referencedColumnName="id")
* }
* )
*/
private $tags;
/**
* @var Collection
*
* @ORM\ManyToMany(targetEntity="User", inversedBy="posts")
* @ORM\JoinTable(name="post_has_user",
* joinColumns={
* @ORM\JoinColumn(name="post_id", referencedColumnName="id")
* },
* inverseJoinColumns={
* @ORM\JoinColumn(name="mentioned_user_id", referencedColumnName="id")
* }
* )
*/
private $mentionedUsers;
/**
* @ORM\OneToMany(targetEntity="PostComment", mappedBy="post")
* @ORM\JoinColumn(nullable=false)
*/
private $comments;
/**
* @ORM\OneToMany(targetEntity="PostLike", mappedBy="post")
* @ORM\JoinColumn(nullable=false)
*/
private $likes;
/**
* Constructor
*/
public function __construct()
{
$this->tags = new ArrayCollection();
$this->mentionedUsers = new ArrayCollection();
$this->comments = new ArrayCollection();
$this->likes = new ArrayCollection();
}
/**
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* @param int $id
*/
public function setId($id)
{
$this->id = $id;
}
/**
* @return Manager
*/
public function getManager()
{
return $this->manager;
}
/**
* @param Manager $manager
*/
public function setManager($manager)
{
$this->manager = $manager;
}
/**
* @return bool
*/
public function isEnabled()
{
return $this->enabled;
}
/**
* @param bool $enabled
*/
public function setEnabled($enabled)
{
$this->enabled = $enabled;
}
/**
* @return DateTime
*/
public function getCreateDate()
{
return $this->createDate;
}
/**
* @param DateTime $createDate
*/
public function setCreateDate($createDate)
{
$this->createDate = $createDate;
}
/**
* @return string
*/
public function getContent()
{
return $this->content;
}
/**
* @param string $content
*/
public function setContent($content)
{
$this->content = $content;
}
/**
* @return string
*/
public function getTitle()
{
return $this->title;
}
/**
* @param string $title
*/
public function setTitle($title)
{
$this->title = $title;
}
/**
* @return Club
*/
public function getClub()
{
return $this->club;
}
/**
* @param Club $club
*/
public function setClub($club)
{
$this->club = $club;
}
/**
* @return PostType
*/
public function getPostType()
{
return $this->postType;
}
/**
* @param PostType $postType
*/
public function setPostType($postType)
{
$this->postType = $postType;
}
/**
* @return User
*/
public function getUser()
{
return $this->user;
}
/**
* @param User $user
*/
public function setUser($user)
{
$this->user = $user;
}
/**
* @return Collection
*/
public function getTags()
{
return $this->tags;
}
/**
* @param Collection $tags
*/
public function setTags($tags)
{
$this->tags = $tags;
}
/**
* @return Collection
*/
public function getMentionedUsers()
{
return $this->mentionedUsers;
}
/**
* @param Collection $mentionedUsers
*/
public function setMentionedUsers($mentionedUsers)
{
$this->mentionedUsers = $mentionedUsers;
}
/**
* @return string
*/
public function getAttachment()
{
return $this->attachment;
}
/**
* @param string $attachment
*/
public function setAttachment($attachment)
{
$this->attachment = $attachment;
}
/**
* @return mixed
*/
public function getComments()
{
return $this->comments;
}
/**
* @param mixed $comments
*/
public function setComments($comments)
{
$this->comments = $comments;
}
/**
* @return mixed
*/
public function getLikes()
{
return $this->likes;
}
/**
* @param mixed $likes
*/
public function setLikes($likes)
{
$this->likes = $likes;
}
}
这也是我的用户实体,可以很好地与帖子实体配合使用:
<?php
namespace AppBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
/**
* User
*
* @ORM\Table(name="user", uniqueConstraints={@ORM\UniqueConstraint(name="user_email_uindex", columns={"email"}), @ORM\UniqueConstraint(name="user_id_uindex", columns={"id"})}, indexes={@ORM\Index(name="user_company_id_fk", columns={"company_id"})})
* @ORM\Entity(repositoryClass="AppBundle\Repository\UserRepository")
* @UniqueEntity(fields={"email"}, message="username already taken")
*/
class User
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="first_name", type="string", length=50, nullable=false)
*/
private $firstName;
/**
* @var string
*
* @ORM\Column(name="last_name", type="string", length=50, nullable=false)
*/
private $lastName;
/**
* @var string
*
* @ORM\Column(name="email", type="string", length=50, nullable=false)
*/
private $email;
/**
* @var Company
*
* @ORM\ManyToOne(targetEntity="Company", inversedBy="users")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="company_id", referencedColumnName="id")
* })
*/
private $company;
/**
* @var Collection
*
* @ORM\ManyToMany(targetEntity="Post", mappedBy="mentionedUsers")
*/
private $posts;
/**
* @var string
*
* @ORM\Column(name="position", type="string", length=255)
*/
private $position;
/**
* @var string
*
* @ORM\Column(name="avatar", type="string", length=255)
*/
private $avatar;
/**
* @var integer
*
* @ORM\Column(name="phone_number", type="integer")
*/
private $phone_number;
/**
* @var string
*
* @ORM\Column(name="linkedin_url", type="string", length=255)
*/
private $linkedin_url;
private $current_club;
/**
* Constructor
*/
public function __construct()
{
$this->posts = new ArrayCollection();
}
/**
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* @param int $id
*/
public function setId($id)
{
$this->id = $id;
}
/**
* @return string
*/
public function getFirstName()
{
return $this->firstName;
}
/**
* @param string $firstName
*/
public function setFirstName($firstName)
{
$this->firstName = $firstName;
}
/**
* @return string
*/
public function getLastName()
{
return $this->lastName;
}
/**
* @param string $lastName
*/
public function setLastName($lastName)
{
$this->lastName = $lastName;
}
/**
* @return string
*/
public function getEmail()
{
return $this->email;
}
/**
* @param string $email
*/
public function setEmail($email)
{
$this->email = $email;
}
/**
* @return Company
*/
public function getCompany()
{
return $this->company;
}
/**
* @param Company $company
*/
public function setCompany($company)
{
$this->company = $company;
}
/**
* @return Collection
*/
public function getPosts()
{
return $this->posts;
}
/**
* @param Collection $posts
*/
public function setPosts($posts)
{
$this->posts = $posts;
}
/**
* @return string
*/
public function getPosition()
{
return $this->position;
}
/**
* @param string $position
*/
public function setPosition($position)
{
$this->position = $position;
}
/**
* @return string
*/
public function getAvatar()
{
return $this->avatar;
}
/**
* @param string $avatar
*/
public function setAvatar($avatar)
{
$this->avatar = $avatar;
}
/**
* @return int
*/
public function getPhoneNumber()
{
return $this->phone_number;
}
/**
* @param int $phone_number
*/
public function setPhoneNumber($phone_number)
{
$this->phone_number = $phone_number;
}
/**
* @return string
*/
public function getLinkedinUrl()
{
return $this->linkedin_url;
}
/**
* @param string $linkedin_url
*/
public function setLinkedinUrl($linkedin_url)
{
$this->linkedin_url = $linkedin_url;
}
/**
* @return mixed
*/
public function getCurrentClub()
{
return $this->current_club;
}
/**
* @param mixed $current_club
*/
public function setCurrentClub($current_club)
{
$this->current_club = $current_club;
}
}
这是我的控制器中的一个 sn-p,它在创建帖子时处理帖子和标签之间的关系:
/**
* @Rest\Post(
* path="posts",
* name="post_creation"
* )
* @Rest\RequestParam(
* name="content",
* description="content of post"
* )
* @Rest\RequestParam(
* name="postType",
* description="type of post: text, image, video or gallery"
* )
*
* @Rest\View(serializerGroups={"post_creation"})
*/
public function postCreateAction(Request $request)
{
$text = $this->getDoctrine()->getRepository(PostType::class)->find('1');
$image = $this->getDoctrine()->getRepository(PostType::class)->find('2');
$video = $this->getDoctrine()->getRepository(PostType::class)->find('3');
//$gallery = $this->getDoctrine()->getRepository(PostType::class)->find('4');
$em = $this->getDoctrine()->getManager();
//$title = $request->request->get('title');
$content = $request->request->get('content');
$postType = $request->request->get('postType');
if ($content == null) {
return new JsonResponse('invalid post');
}
$post = new Post();
$now = new DateTime('now');
switch ($postType) {
case text_type:
$user = $this->getUser()->getUser();
$post->setClub($user->getCurrentClub());
$post->setPostType($text);
$post->setCreateDate($now);
$post->setContent($content);
$post->setUser($user);
$em->persist($post);
$em->flush();
$post_tags = json_decode($request->request->get('tags'), true);
if ($post_tags != null) {
foreach ($post_tags as $post_tag) {
$tag = $this->getDoctrine()->getRepository(Tag::class)->findOneBy(['libelle' => $post_tag]);
if ($tag == null) {
$new_tag = new Tag();
$new_tag->setLibelle($post_tag);
$em->persist($new_tag);
$em->flush();
$post->getTags()->add($new_tag);
} else {
$post->getTags()->add($tag);
$em->flush();
}
}
}
//handle mentioned users
$mentioned_users_id = json_decode($request->request->get('mentioned_users_id'), true);
if ($mentioned_users_id != null) {
foreach ($mentioned_users_id as $mentioned_user_id) {
$mentioned_user_input = $this->getDoctrine()->getRepository(User::class)->findOneBy(['id' => $mentioned_user_id]);
if ($mentioned_user_input != null) {
$post->getMentionedUsers()->add($mentioned_user_input);
}
}
}
$em->flush();
return $post;
break;
case image_type:
$filePath = tempnam(sys_get_temp_dir(), 'UploadedFile');
$file = fopen($filePath, "w");
stream_filter_append($file, 'convert.base64-decode');
fwrite($file, $request->request->get('attachment'));
$meta_data = stream_get_meta_data($file);
$path = $meta_data['uri'];
fclose($file);
$fileName = $this->getUser()->getId() . "_" . uniqid() . '.' . $request->request->get("ext");
$new_path = $this->getParameter('post_directory') . $fileName;
rename($path, $new_path);
$user = $this->getUser()->getUser();
$post->setClub($user->getCurrentClub());
$post->setPostType($image);
$post->setCreateDate($now);
$post->setContent($content);
$post->setUser($user);
$post->setAttachment($fileName);
$em = $this->getDoctrine()->getManager();
$em->flush();
return $post;
case video_type:
$video_file = $request->request->get('attachment');
$user = $this->getUser()->getUser();
$post->setClub($user->getCurrentClub());
$post->setPostType($video);
$post->setCreateDate($now);
$post->setContent($content);
$post->setUser($user);
$post->setAttachment($video_file);
$em = $this->getDoctrine()->getManager();
$em->flush();
return $post;
//case gallery_type:
// $gallery_file_array = [];
// $gallery_array = explode(',', $request->request->get('attachment'));
// foreach ($gallery_array as $image) {
// if ($image) {
// $filePath = tempnam(sys_get_temp_dir(), 'UploadedFile');
// $file = fopen($filePath, "w");
// stream_filter_append($file, 'convert.base64-decode');
// fwrite($file, $image);
// $meta_data = stream_get_meta_data($file);
// $path = $meta_data['uri'];
// fclose($file);
// $fileName = $this->getUser()->getId() . "_" . uniqid() . '.' . $request->request->get("ext");
// $new_path = $this->getParameter('post_directory') . $fileName;
// rename($path, $new_path);
// $gallery_file_array[] = $fileName;
// }
// }
//
// if (count($gallery_file_array)) {
// $post->setAttachment(json_encode($gallery_file_array));
// $current_user = $this->getUser()->getUser();
// $post->setClub($this->getUser()->getManager()->getClub());
// $post->setPostType($gallery);
// $post->setCreateDate($now);
// $post->setTitle($title);
// $post->setContent($content);
// $post->setUser($current_user);
// $em = $this->getDoctrine()->getManager();
// $em->persist($post);
// $em->flush();
// return $post;
// }
// break;
default:
return new JsonResponse('post creation invalid');
}
}
我没有任何错误消息。如果标签尚不存在,则会创建标签表。对于提到的用户,一切正常。这只是似乎没有创建的链接并将我的 post_has_tag 表上传到我的数据库中。
这是我在 phpmyadmin 中的 post_has_tag 类的屏幕: enter image description here
【问题讨论】:
标签: php database symfony doctrine many-to-many