这是我的问题:
我有3个实体:联系,邮寄和 MailTemplate
邮件仅用于向许多联系人发送 MailTemplate ;在关系方面,邮件由 ManyTomany 与联系人的关系以及 ManyToOne 与<的关系定义强> MailTemplate
我的一些 MailTemplate 实体有一个布尔字段“unique”,以便说这个模板应该多次发送给同一个联系人。说到前端,我有一个视图,我可以选择联系人并向他们发送邮件模板。
以下是这样的事情:我想限制显示的联系人,仅限于那些我没有发送邮件模板的人!
因此,如果 MailTemplate 的字段为“唯一”,我只想获得尚未收到此模板的联系实体;我尝试了很多东西,但是无法用DQL或Query Builder来解决这个问题。因为联系和 MailTemplate 邮件 > ...
我可以获取所有联系人,然后循环浏览邮件并删除其中一些,但我希望这更加优化。
编辑 - 我的实体:
与
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Table
* @ORM\Entity(repositoryClass="AppBundle\Entity\ContactRepository")
*/
class Contact
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\ManyToOne(targetEntity="ContactType", fetch="EAGER")
*/
protected $type;
/**
* @ORM\Column(type="string", length=255)
*/
protected $name;
/**
* @ORM\ManyToOne(targetEntity="Place", fetch="EAGER", cascade={"ALL"})
*/
protected $place;
/**
* @ORM\Column(type="string", length=255)
*/
protected $email;
/**
* @ORM\Column(type="string", length=20)
*/
protected $phone;
/**
* @ORM\Column(type="string", length=255)
*/
protected $website;
/**
* @ORM\Column(type="text")
*/
protected $description;
/**
* @ORM\ManyToOne(targetEntity="User", fetch="EAGER")
*/
protected $createdBy;
/**
* @ORM\OneToMany(targetEntity="Action", mappedBy="contact")
*/
protected $actions;
/**
* @ORM\OneToMany(targetEntity="MailSent", mappedBy="contact")
*/
protected $mailSent;
/*
* Custom methods
*/
public function isMailSent(\AppBundle\Entity\MailTemplate $template)
{
foreach ($this->getMailSent() as $mailSent) {
if ($mailSent->getTemplate() == $template) {
return true;
}
}
return false;
}
/*
* Getters & Setters
*/
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* @param string $name
* @return Contact
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Set email
*
* @param string $email
* @return Contact
*/
public function setEmail($email)
{
$this->email = $email;
return $this;
}
/**
* Get email
*
* @return string
*/
public function getEmail()
{
return $this->email;
}
/**
* Set phone
*
* @param string $phone
* @return Contact
*/
public function setPhone($phone)
{
$this->phone = $phone;
return $this;
}
/**
* Get phone
*
* @return string
*/
public function getPhone()
{
return $this->phone;
}
/**
* Set website
*
* @param string $website
* @return Contact
*/
public function setWebsite($website)
{
$this->website = $website;
return $this;
}
/**
* Get website
*
* @return string
*/
public function getWebsite()
{
return $this->website;
}
/**
* Set description
*
* @param string $description
* @return Contact
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* @return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Set type
*
* @param \AppBundle\Entity\ContactType $type
* @return Contact
*/
public function setType(\AppBundle\Entity\ContactType $type = null)
{
$this->type = $type;
return $this;
}
/**
* Get type
*
* @return \AppBundle\Entity\ContactType
*/
public function getType()
{
return $this->type;
}
/**
* Set place
*
* @param \AppBundle\Entity\Place $place
* @return Contact
*/
public function setPlace(\AppBundle\Entity\Place $place = null)
{
$this->place = $place;
return $this;
}
/**
* Get place
*
* @return \AppBundle\Entity\Place
*/
public function getPlace()
{
return $this->place;
}
/**
* Set createdBy
*
* @param \AppBundle\Entity\User $createdBy
* @return Contact
*/
public function setCreatedBy(\AppBundle\Entity\User $createdBy = null)
{
$this->createdBy = $createdBy;
return $this;
}
/**
* Get createdBy
*
* @return \AppBundle\Entity\User
*/
public function getCreatedBy()
{
return $this->createdBy;
}
/**
* Constructor
*/
public function __construct()
{
$this->actions = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Add actions
*
* @param \AppBundle\Entity\Action $actions
* @return Contact
*/
public function addAction(\AppBundle\Entity\Action $actions)
{
$this->actions[] = $actions;
return $this;
}
/**
* Remove actions
*
* @param \AppBundle\Entity\Action $actions
*/
public function removeAction(\AppBundle\Entity\Action $actions)
{
$this->actions->removeElement($actions);
}
/**
* Get actions
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getActions()
{
return $this->actions;
}
/**
* Add mailSent
*
* @param \AppBundle\Entity\MailSent $mailSent
* @return Contact
*/
public function addMailSent(\AppBundle\Entity\MailSent $mailSent)
{
$this->mailSent[] = $mailSent;
return $this;
}
/**
* Remove mailSent
*
* @param \AppBundle\Entity\MailSent $mailSent
*/
public function removeMailSent(\AppBundle\Entity\MailSent $mailSent)
{
$this->mailSent->removeElement($mailSent);
}
/**
* Get mailSent
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getMailSent()
{
return $this->mailSent;
}
}
邮寄
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
*/
class Mailing
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\ManyToMany(targetEntity="Contact")
*/
protected $contacts;
/**
* @ORM\ManyToOne(targetEntity="MailTemplate")
*/
protected $template;
/**
* Constructor
*/
public function __construct()
{
$this->contacts = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Add contacts
*
* @param \AppBundle\Entity\Contact $contacts
* @return Mailing
*/
public function addContact(\AppBundle\Entity\Contact $contacts)
{
$this->contacts[] = $contacts;
return $this;
}
/**
* Remove contacts
*
* @param \AppBundle\Entity\Contact $contacts
*/
public function removeContact(\AppBundle\Entity\Contact $contacts)
{
$this->contacts->removeElement($contacts);
}
/**
* Get contacts
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getContacts()
{
return $this->contacts;
}
/**
* Set template
*
* @param \AppBundle\Entity\MailTemplate $template
* @return Mailing
*/
public function setTemplate(\AppBundle\Entity\MailTemplate $template = null)
{
$this->template = $template;
return $this;
}
/**
* Get template
*
* @return \AppBundle\Entity\MailTemplate
*/
public function getTemplate()
{
return $this->template;
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
}
MailTemplate
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\HttpFoundation\File\UploadedFile;
/**
* @ORM\Table
* @ORM\Entity
* @ORM\HasLifecycleCallbacks()
*/
class MailTemplate
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(type="string", length=255)
*/
protected $label;
/**
* @ORM\Column(type="string", length=255)
*/
protected $subject;
/**
* @ORM\Column(type="text", nullable=true)
*/
protected $content;
/**
* @ORM\Column(name="uniqueSend", type="boolean")
*/
protected $unique = false;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
protected $templatePath;
/**
* @Assert\File(maxSize="6000000")
*/
private $file;
private $temp;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set label
*
* @param string $label
* @return MailTemplate
*/
public function setLabel($label)
{
$this->label = $label;
return $this;
}
/**
* Get label
*
* @return string
*/
public function getLabel()
{
return $this->label;
}
/**
* Set subject
*
* @param string $subject
* @return MailTemplate
*/
public function setSubject($subject)
{
$this->subject = $subject;
return $this;
}
/**
* Get subject
*
* @return string
*/
public function getSubject()
{
return $this->subject;
}
/**
* Set content
*
* @param string $content
* @return MailTemplate
*/
public function setContent($content)
{
$this->content = $content;
return $this;
}
/**
* Get content
*
* @return string
*/
public function getContent()
{
return $this->content;
}
/**
* Set templatePath
*
* @param string $templatePath
* @return MailTemplate
*/
public function setTemplatePath($templatePath)
{
$this->templatePath = $templatePath;
return $this;
}
/**
* Get templatePath
*
* @return string
*/
public function getTemplatePath()
{
return $this->templatePath;
}
public function getAbsolutePath()
{
return null === $this->templatePath
? null
: $this->getUploadRootDir() . '/' . $this->templatePath;
}
public function getWebPath()
{
return null === $this->templatePath
? null
: $this->getUploadDir() . '/' . $this->templatePath;
}
protected function getUploadRootDir()
{
// the absolute directory path where uploaded
// documents should be saved
return __DIR__ . '/../../../web/' . $this->getUploadDir();
}
protected function getUploadDir()
{
return 'uploads/templates';
}
/**
* Sets file.
*
* @param UploadedFile $file
*/
public function setFile(UploadedFile $file = null)
{
$this->file = $file;
// check if we have an old image path
if (isset($this->templatePath)) {
// store the old name to delete after the update
$this->temp = $this->templatePath;
$this->templatePath = null;
} else {
$this->templatePath = 'initial';
}
}
/**
* Get file.
*
* @return UploadedFile
*/
public function getFile()
{
return $this->file;
}
/**
* @ORM\PrePersist()
* @ORM\PreUpdate()
*/
public function preUpload()
{
if (null !== $this->getFile()) {
// do whatever you want to generate a unique name
$filename = sha1(uniqid(mt_rand(), true));
$this->templatePath = $filename.'.'.$this->getFile()->guessExtension();
}
}
/**
* @ORM\PostPersist()
* @ORM\PostUpdate()
*/
public function upload()
{
if (null === $this->getFile()) {
return;
}
// if there is an error when moving the file, an exception will
// be automatically thrown by move(). This will properly prevent
// the entity from being persisted to the database on error
$this->getFile()->move($this->getUploadRootDir(), $this->templatePath);
// check if we have an old image
if (isset($this->temp) && file_exists($this->getUploadRootDir() . '/' . $this->temp)) {
// delete the old image
unlink($this->getUploadRootDir().'/'.$this->temp);
// clear the temp image path
$this->temp = null;
}
$this->file = null;
}
/**
* @ORM\PostRemove()
*/
public function removeUpload()
{
$file = $this->getAbsolutePath();
if ($file) {
if (file_exists($file)) {
unlink($file);
}
}
}
/**
* Set unique
*
* @param boolean $unique
* @return MailTemplate
*/
public function setUnique($unique)
{
$this->unique = $unique;
return $this;
}
/**
* Get unique
*
* @return boolean
*/
public function getUnique()
{
return $this->unique;
}
}
示例数据
template1 : MailTemplate { id: 1, unique: true }
template2 : MailTemplate { id: 2, unique: false }
template3: MailTemplate { id: 3, unique: true }
user1 : { id: 1 }
user2 : { id: 2 }
user3 : { id: 3}
mailing1 : Mailing { id: 1, contacts: { 1, 2 }, template: 1 }
mailing2: Mailing { id: 2, contacts: { 1 }, template: 3 }
应该导致:
Users available for template1 : user3
Users available for template2 : user1, user2, user3
Users available for template3 : user2, user3
答案 0 :(得分:0)
首先,您必须使关系联系&lt; - &gt;邮寄双向。这意味着必须有一个财产&#34;邮件&#34;在您的联系人实体中。然后,您可以在表单中使用查询构建器属性,如下所示:
$template = $builder->getData()->getTemplate();
$builder
->add('contact', 'entity',
array(
'class' => 'AppBundle:Contact',
'query_builder' => function($contactRepository) use ($template){
return $contactRepository->createQueryBuilder('c')
->leftJoin('c.mailings', 'm', 'WITH', 'm.template = :template')
->where('m.template IS NULL')
->setParameter('template', $template);
}
);
这应该只返回没有相关邮件的联系人,模板是当前模板。