Doctrine OneToOne remove entity - symfony

When I remove entity, relations OneToOne has not been removed. Gallery has been removed successfully from database, but largeImage, mediumImage and smallImage not.
What I do wrong?
Delete action in controller:
public function deleteAction($id)
{
$em = $this->getDoctrine()->getManager();
$offer = $em->getRepository('ToCmsBundle:Offer')->find($id);
if($offer) {
if(!$offer->getGallery()->isEmpty()) {
foreach($offer->getGallery() as $key => $image) {
$image->setOffer(null);
$offer->removeGallery($image);
//$em->remove($image);
//$em->flush();
echo $image->getPath() . '<br/>';
}
} else {
echo 'gallery is empty';
}
$offer->setLargeImage(null);
$offer->setMediumImage(null);
$offer->setSmallImage(null);
$em->remove($offer);
$em->flush();
}
return $this->redirect($this->generateUrl('to_offer_list'));
}
My owner class:
/**
* Offer
*
* #ORM\Table(name="to_offer")
* #ORM\HasLifecycleCallbacks
* #ORM\Entity(repositoryClass="To\CmsBundle\Repository\OfferRepository")
*/
class Offer {
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="title", type="string", length=255)
*/
private $title;
/**
* #var string
*
* #ORM\Column(name="content", type="text")
*/
private $content;
/**
* #var ArrayCollection
*
* #ORM\OneToMany(targetEntity="Image", mappedBy="offer", cascade={"all"}, orphanRemoval=true)
*/
private $gallery;
/**
* #var Image
*
* #ORM\OneToOne(targetEntity="Image", cascade={"all"}, orphanRemoval=true)
*/
public $largeImage;
/**
* #var Image
*
* #ORM\OneToOne(targetEntity="Image", cascade={"all"}, orphanRemoval=true)
*/
public $mediumImage;
/**
* #var Image
*
* #ORM\OneToOne(targetEntity="Image", cascade={"all"}, orphanRemoval=true)
*/
public $smallImage;
/**
* #var ArrayCollection
*
* #ORM\ManyToMany(targetEntity="Category", inversedBy="articles")
* #ORM\JoinTable(name="to_articles_categories")
*/
private $categories;
/**
* #var User
*
* #ORM\ManyToOne(targetEntity="User")
* #ORM\JoinColumn(name="author_id", referencedColumnName="id")
*/
private $author;
public function __construct() {
$this->gallery = new ArrayCollection();
$this->categories = new ArrayCollection();
}
/** other stuff */
}
Image class:
/**
* Image
*
* #ORM\Table(name="to_images")
* #ORM\Entity(repositoryClass="To\CmsBundle\Repository\ImageRepository")
* #ORM\HasLifecycleCallbacks
*/
class Image
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* #var string
*
* #ORM\Column(name="hashName", type="string", length=255)
*/
private $hashName;
/**
* #var integer
*
* #ORM\Column(name="position", type="integer")
*/
private $position;
/**
* #var string
*
* #ORM\Column(name="path", type="string", length=255)
*/
private $path;
/**
* #var string
*
* #ORM\Column(name="thumbnail", type="string", length=255)
*/
private $thumbnail;
/**
* #var string
*
* #ORM\Column(name="originalImage", type="string", length=255)
*/
private $originalImage;
/**
* #var Offer
*
* #ORM\ManyToOne(targetEntity="Offer", inversedBy="gallery")
* #ORM\JoinColumn(name="offer_id", referencedColumnName="id", nullable=true)
*/
private $offer;
/**
* #var \DateTime
*
* #Gedmo\Timestampable(on="create")
* #ORM\Column(name="createdAt", type="datetime")
*/
private $createdAt;
/**
* #var \DateTime
*
* #Gedmo\Timestampable(on="update")
* #ORM\Column(name="updatedAt", type="datetime")
*/
private $updatedAt;
/**
* #var integer
*
* #ORM\Column(name="x", type="integer")
*/
protected $x = 0;
/**
* #var integer
*
* #ORM\Column(name="y", type="integer")
*/
protected $y = 0;
/**
* #var integer
*
* #ORM\Column(name="w", type="integer")
*/
protected $w = 0;
/**
* #var integer
*
* #ORM\Column(name="h", type="integer")
*/
protected $h = 0;
/**
* #var boolean
*
* #ORM\Column(name="defaultImage", type="boolean")
*/
private $default = 0;
public function __construct() {
$this->position = 0;
$this->default = 0;
$this->x = 0;
$this->y = 0;
}
/**
* #ORM\PrePersist()
* #ORM\PreUpdate()
*/
public function preUpload()
{
$this->position = $this->position ?: 0;
$this->default = $this->default ?: 0;
$this->x = $this->x ?: 0;
$this->y = $this->y ?: 0;
/*if (null !== $this->getFile()) {
// do whatever you want to generate a unique name
$this->name = sha1(uniqid(mt_rand(), true));
$this->originName = $this->getFile()->getClientOriginalName();
$this->extension = $this->getFile()->guessExtension();
$this->path = $this->name.'.'.$this->extension;
}*/
}
/**
* #ORM\PreRemove()
*/
public function removeUpload()
{
echo $this->getRootPath().$this->originalImage; echo '<br/>';
echo $this->getRootPath().$this->thumbnail; echo '<br/>';
echo $this->getRootPath().$this->path; echo '<br/>';
echo '<br/><br/>';
if(file_exists($this->getRootPath().$this->originalImage))
unlink($this->getRootPath().$this->originalImage);
if(file_exists($this->getRootPath().$this->thumbnail))
unlink($this->getRootPath().$this->thumbnail);
if(file_exists($this->getRootPath().$this->path))
unlink($this->getRootPath().$this->path);
}
/** other stuff */
}

Your entities are referencing each other so you should try remove these :
$offer->setLargeImage(null);
$offer->setMediumImage(null);
$offer->setSmallImage(null);
and call flush() once before $em->remove($offer); and once after.
foreach ($offer->getGallery() as $image) {
$offer->removeGallery($image);
}
$em->flush();
$em->remove($offer);
$em->flush();
This will only work as is if all the images are "privately owned", meaning that they are not referenced multiple times in this entity or in another entity.

$offer->setLargeImage(null);
$offer->setMediumImage(null);
$offer->setSmallImage(null);
Your "$offer" doesn't have the images anymore when you're deleting it.
UPDATE
When you are doing your 'find()' you don't have the image object, but a proxy because of the lazy loading. If you need the offer with image objects, create a query with leftJoin on the images to get the offer AND images. And then, I think that you'll not have problems.
(look at the end of this tutorial to have an example of a leftjoin on objects : http://symfony.com/fr/doc/current/cookbook/security/entity_provider.html#gerer-les-roles-via-la-base-de-donnees)

Related

Symfony3 - Left Join does not work properly

Trying to solve this problem with Join in Symfony3.
Somehow the resultset has mixed up values, i.e
ID Exploit Author
ID Author Author
Please see the attached screenshot.
OpenX should have Author Metasploit and the second row shouldn't be there.
Have this code in the controller:
public function indexAction()
{
$exploits = $this->getDoctrine()
->getRepository('AppBundle:Exploit')->createQueryBuilder('e')
->add('select', 'a,e')
->add('from', 'AppBundle:Exploit e')
->leftJoin('AppBundle:Author', 'a')
->where('e.author = a.id')
->getQuery()
->getResult();
return $this->render('exploit/index.html.twig', array(
'exploits' => $exploits
));
}
This view:
<tbody>
{% for exploit in exploits %}
<tr>
<th scope="row">{{ exploit.id }}</th>
<td>{{ exploit.name }}</td>
<td> {{ exploit.author }} </td>
<td>
View
Edit
Delete
</td>
</tr>
{% endfor %}
And these Entities:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Author
*
* #ORM\Table(name="author", indexes={#ORM\Index(name="author_name_id_idx", columns={"id"})})
* #ORM\Entity
*/
class Author
{
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255, nullable=false)
*/
private $name;
/**
* #var \Exploit
*
* #ORM\Id
* #ORM\GeneratedValue(strategy="NONE")
* #ORM\OneToOne(targetEntity="Exploit")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="id", referencedColumnName="author")
* })
*/
private $id;
/**
* Set name
*
* #param string $name
*
* #return Author
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
public function getAuthor()
{
return $this->name;
}
}
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Author
*
* #ORM\Table(name="author", indexes={#ORM\Index(name="author_name_id_idx", columns={"id"})})
* #ORM\Entity
*/
class Author
{
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255, nullable=false)
*/
private $name;
/**
* #var \Exploit
*
* #ORM\Id
* #ORM\GeneratedValue(strategy="NONE")
* #ORM\OneToOne(targetEntity="Exploit")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="id", referencedColumnName="author")
* })
*/
private $id;
}
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Category
*
* #ORM\Table(name="category", indexes={#ORM\Index(name="category_name_id_idx", columns={"id"})})
* #ORM\Entity
*/
class Category
{
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255, nullable=false)
*/
private $name;
/**
* #var \Exploit
*
* #ORM\Id
* #ORM\GeneratedValue(strategy="NONE")
* #ORM\OneToOne(targetEntity="Exploit")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="id", referencedColumnName="category")
* })
*/
private $id;
/**
* Set name
*
* #param string $name
*
* #return Category
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
}
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Category
*
* #ORM\Table(name="category", indexes={#ORM\Index(name="category_name_id_idx", columns={"id"})})
* #ORM\Entity
*/
class Category
{
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255, nullable=false)
*/
private $name;
/**
* #var \Exploit
*
* #ORM\Id
* #ORM\GeneratedValue(strategy="NONE")
* #ORM\OneToOne(targetEntity="Exploit")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="id", referencedColumnName="category")
* })
*/
private $id;
}
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Exploit
*
* #ORM\Table(name="exploit", indexes={#ORM\Index(name="exploit_category_idx", columns={"category"}), #ORM\Index(name="exploit_type_idx", columns={"type"}), #ORM\Index(name="exploit_author_idx", columns={"author"})})
* #ORM\Entity
*/
class Exploit
{
/**
* #var integer
*
* #ORM\Column(name="id", type="bigint", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="edb_id", type="string", length=100, nullable=false)
*/
private $edbId;
/**
* #var \DateTime
*
* #ORM\Column(name="date", type="datetime", nullable=false)
*/
private $date;
/**
* #var integer
*
* #ORM\Column(name="author", type="bigint", nullable=false)
*/
private $author;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255, nullable=false)
*/
private $name;
/**
* #var integer
*
* #ORM\Column(name="category", type="bigint", nullable=false)
*/
private $category;
/**
* #var string
*
* #ORM\Column(name="version", type="string", length=255, nullable=false)
*/
private $version;
/**
* #var integer
*
* #ORM\Column(name="type", type="bigint", nullable=false)
*/
private $type;
/**
* #var string
*
* #ORM\Column(name="content", type="text", nullable=false)
*/
private $content;
/**
* #var string
*
* #ORM\Column(name="dork", type="string", length=255, nullable=true)
*/
private $dork;
/**
* #var string
*
* #ORM\Column(name="software_link", type="string", length=255, nullable=true)
*/
private $softwareLink;
/**
* #var string
*
* #ORM\Column(name="tested_on", type="string", length=255, nullable=true)
*/
private $testedOn;
/**
* Set edbId
*
* #param integer $edbId
*
* #return Exploit
*/
public function setEdbId($edbId)
{
$this->edbId = $edbId;
return $this;
}
/**
* Get edbId
*
* #return integer
*/
public function getEdbId()
{
return $this->edbId;
}
/**
* Set date
*
* #param \DateTime $date
*
* #return Exploit
*/
public function setDate($date)
{
$this->date = $date;
return $this;
}
/**
* Get date
*
* #return \DateTime
*/
public function getDate()
{
return $this->date;
}
/**
* Set author
*
* #param integer $author
*
* #return Exploit
*/
public function setAuthor($author)
{
$this->author = $author;
return $this;
}
/**
* Get author
*
* #return integer
*/
public function getAuthor()
{
return $this->author;
}
/**
* Set name
*
* #param string $name
*
* #return Exploit
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set category
*
* #param integer $category
*
* #return Exploit
*/
public function setCategory($category)
{
$this->category = $category;
return $this;
}
/**
* Get category
*
* #return integer
*/
public function getCategory()
{
return $this->category;
}
/**
* Set version
*
* #param string $version
*
* #return Exploit
*/
public function setVersion($version)
{
$this->version = $version;
return $this;
}
/**
* Get version
*
* #return string
*/
public function getVersion()
{
return $this->version;
}
/**
* Set type
*
* #param integer $type
*
* #return Exploit
*/
public function setType($type)
{
$this->type = $type;
return $this;
}
/**
* Get type
*
* #return integer
*/
public function getType()
{
return $this->type;
}
/**
* Set content
*
* #param string $content
*
* #return Exploit
*/
public function setContent($content)
{
$this->content = $content;
return $this;
}
/**
* Get content
*
* #return string
*/
public function getContent()
{
return $this->content;
}
/**
* Set dork
*
* #param string $dork
*
* #return Exploit
*/
public function setDork($dork)
{
$this->dork = $dork;
return $this;
}
/**
* Get dork
*
* #return string
*/
public function getDork()
{
return $this->dork;
}
/**
* Set softwareLink
*
* #param string $softwareLink
*
* #return Exploit
*/
public function setSoftwareLink($softwareLink)
{
$this->softwareLink = $softwareLink;
return $this;
}
/**
* Get softwareLink
*
* #return string
*/
public function getSoftwareLink()
{
return $this->softwareLink;
}
/**
* Set testedOn
*
* #param string $testedOn
*
* #return Exploit
*/
public function setTestedOn($testedOn)
{
$this->testedOn = $testedOn;
return $this;
}
/**
* Get testedOn
*
* #return string
*/
public function getTestedOn()
{
return $this->testedOn;
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
}
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Exploit
*
* #ORM\Table(name="exploit", indexes={#ORM\Index(name="exploit_category_idx", columns={"category"}), #ORM\Index(name="exploit_type_idx", columns={"type"}), #ORM\Index(name="exploit_author_idx", columns={"author"})})
* #ORM\Entity
*/
class Exploit
{
/**
* #var integer
*
* #ORM\Column(name="id", type="bigint", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="edb_id", type="string", length=100, nullable=false)
*/
private $edbId;
/**
* #var \DateTime
*
* #ORM\Column(name="date", type="datetime", nullable=false)
*/
private $date;
/**
* #var integer
*
* #ORM\Column(name="author", type="bigint", nullable=false)
*/
private $author;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255, nullable=false)
*/
private $name;
/**
* #var integer
*
* #ORM\Column(name="category", type="bigint", nullable=false)
*/
private $category;
/**
* #var string
*
* #ORM\Column(name="version", type="string", length=255, nullable=false)
*/
private $version;
/**
* #var integer
*
* #ORM\Column(name="type", type="bigint", nullable=false)
*/
private $type;
/**
* #var string
*
* #ORM\Column(name="content", type="text", nullable=false)
*/
private $content;
/**
* #var string
*
* #ORM\Column(name="dork", type="string", length=255, nullable=true)
*/
private $dork;
/**
* #var string
*
* #ORM\Column(name="software_link", type="string", length=255, nullable=true)
*/
private $softwareLink;
/**
* #var string
*
* #ORM\Column(name="tested_on", type="string", length=255, nullable=true)
*/
private $testedOn;
}
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Type
*
* #ORM\Table(name="type", indexes={#ORM\Index(name="type_name_id_idx", columns={"id"})})
* #ORM\Entity
*/
class Type
{
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255, nullable=false)
*/
private $name;
/**
* #var \Exploit
*
* #ORM\Id
* #ORM\GeneratedValue(strategy="NONE")
* #ORM\OneToOne(targetEntity="Exploit")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="id", referencedColumnName="type")
* })
*/
private $id;
/**
* Set name
*
* #param string $name
*
* #return Type
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
}
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Type
*
* #ORM\Table(name="type", indexes={#ORM\Index(name="type_name_id_idx", columns={"id"})})
* #ORM\Entity
*/
class Type
{
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255, nullable=false)
*/
private $name;
/**
* #var \Exploit
*
* #ORM\Id
* #ORM\GeneratedValue(strategy="NONE")
* #ORM\OneToOne(targetEntity="Exploit")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="id", referencedColumnName="type")
* })
*/
private $id;
}
Anybody know how to correct my join query ? Or why it behaves like this?
Thanks,
Try this:
->leftJoin('AppBundle:Author', 'a', "WITH", "e.author = a.id")
Instead of this:
->leftJoin('AppBundle:Author', 'a')
->where('e.author = a.id')
Try
public function indexAction()
{
$exploits = $this->getDoctrine()
->getRepository('AppBundle:Exploit')->createQueryBuilder('e')
->leftjoin('e.author','a')
->addSelect('a')
->getQuery()
->getResult();
return $this->render('exploit/index.html.twig', array(
'exploits' => $exploits
));
}
and in the view
<tbody>
{% for exploit in exploits %}
<tr>
<th scope="row">{{ exploit.id }}</th>
<td>{{ exploit.name }}</td>
<td> {{ exploit.author.name }} </td>
<td>
View
Edit
Delete
</td>
</tr>
{% endfor %}
</tbody>

Use php-imap classes to parse new mails from server, with Symfony 2.7

I'm working on Symfony 2.7. I have to create a mail client to retrieve and send mails from the mail server (IMAP protocol); to do this, I used the php-imap classes, with a bundle (included with composer). But I'm not sure about the way I should use them : Do I extend the classes to represent my Mail and Mailbox objects, or should I create new classes from scratch ?
I don't want to manipulate IMAP straight from my controllers, I think it would be too long to process. Is that right?
Is it a good idea to create a "watcher" (periodic command executed by cron) to parse new mails every 2 minutes or so, create new mails entity from them, and send the waiting ones?
Could I do that while extending the php-imap classes? This way I would use one class only? But wouldn't that be too heavy to store for the database ?
What's the correct way to fetch only new mails ? Do I have to use a specific function, like imap_check, or do I do that by a search criteria (like date from the last check) ? I tried with criteria "NEW", but that was unsuccessful.
Also, the mailboxes I have to parse are quite heavy. I tried to make a search in one of them with "ALL" criteria, but it's really long to process ! Am I doing it right ? Do I just have to be patient ?
Here's what I did for the "watcher" function :
use PhpImap\Mailbox as ImapMailbox;
class GetNewMailsCommand extends ContainerAwareCommand
{
$em = $this->getContainer()->get('doctrine')->getEntityManager();
$mailboxes = $em->getRepository('MIPMailBundle:MailBox')->findAllActive();
foreach ($mailboxes as $mailbox){
$imapBox = new ImapMailbox('{'.$mailbox->getServer().':143/notls/norsh/novalidate-cert}INBOX', $mailbox->getAdress(), $mailbox->getPassword());
if ($mailbox->getMails() == null || empty($mailbox->getMails())){
$mailsIds = $imapBox->searchMailbox('ALL');
if(!$mailsIds) {
$output->writeln($mailbox->getAdress() . " is empty");
}
} else {
$mailsIds = $imapBox->searchMailbox('NEW');
if(!$mailsIds) {
$output->writeln("No new mail for " . $mailbox->getAdress());
}
}
foreach ($mailsIds as $mailId){
$imapMail = $imapBox->getMail($mailId);
$mail = new Mail($mailbox, false);
$mail->setSubject($imapMail->subject);
$mail->setSender($imapMail->fromAddress);
$mail->setCc($imapMail->cc);
$mail->setBcc($imapMail->bcc);
$mail->setToString($imapMail->toString);
$mail->setContent($imapMail->textPlain);
$mail->setDate(new \DateTime($imapMail->date));
foreach ($imapMail->to as $toAddress){
$mail->addRecipient($toAddress);
}
$em->persist($mail);
}
}
$em->flush();
And here's my entities :
class MailBox
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var
*
* #ORM\OneToOne(targetEntity="\MIP\CRMBundle\Entity\Agency", inversedBy="mailBox", cascade={"persist"})
* #ORM\JoinColumn(name="user_id", referencedColumnName="id", nullable=true)
*/
private $user;
/**
* #var Agency
*
* #ORM\ManyToMany(targetEntity="\MIP\CRMBundle\Entity\Agency", inversedBy="mailBoxShared")
* #ORM\JoinTable(name="mailbox_shared")
*/
private $sharedTo;
/**
* #var
*
* #ORM\OneToMany(targetEntity="Mail", mappedBy="mailBox")
*/
private $mails;
/**
* #var boolean
*
* #ORM\Column(name="active", type="boolean")
*/
private $active;
/**
* #var string
*
* #ORM\Column(name="adress", type="string", length=255)
*/
private $adress;
/**
* #var string
*
* #ORM\Column(name="server", type="string", length=255)
*/
private $server;
/**
* #var string
*
* #ORM\Column(name="password", type="string", length=255)
*/
private $password;
/**
* #var integer
*
* #ORM\Column(name="port", type="integer")
*/
private $port;
/**
* MailBox constructor.
*/
public function __construct()
{
$this->sharedTo = new ArrayCollection();
$this->mails = new ArrayCollection();
}
class Mail
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="sender", type="string", length=255)
*/
private $sender;
/**
* #var array
*
* #ORM\Column(name="recipients", type="json_array", nullable=true)
*/
private $recipients;
/**
* #var string
*
* #ORM\Column(name="toString", type="string", nullable=true)
*/
private $toString;
/**
* #var array
*
* #ORM\Column(name="cc", type="json_array", nullable=true)
*/
private $cc;
/**
* #var array
*
* #ORM\Column(name="bcc", type="json_array", nullable=true)
*/
private $bcc;
/**
* #var string
*
* #ORM\Column(name="subject", type="string", length=255, nullable=true)
*/
private $subject;
/**
* #var \DateTime
*
* #ORM\Column(name="date", type="datetime")
*/
private $date;
/**
* #var string
*
* #ORM\Column(name="content", type="text", nullable=true)
*/
private $content;
/**
* #var
*
* #ORM\OneToMany(targetEntity="MIP\CRMBundle\Entity\File", mappedBy="mail", cascade={"persist", "remove"})
* #ORM\JoinColumn(name="file_id", referencedColumnName="id", nullable=true)
*/
protected $files;
/**
* #var ArrayCollection
*/
private $attached;
/**
* #var MailBox
* #ORM\ManyToOne(targetEntity="MailBox", inversedBy="mails")
* #ORM\JoinColumn(name="mailBox_id", referencedColumnName="id")
*/
private $mailBox;
/**
* #var LabelSticker
*
* #ORM\ManyToMany(targetEntity="\MIP\MailBundle\Entity\LabelSticker", mappedBy="mails")
*/
private $labels;
/**
* #var boolean
*/
private $readed;
/**
* #var boolean
*/
private $sent;
/**
* Constructor
* #param MailBox $mailbox
* #param boolean $readed
*/
public function __construct($mailbox, $readed)
{
$this->files = new ArrayCollection();
$this->date = new \DateTime('now');
$this->mailBox = $mailbox;
$this->readed = $readed;
}
Thanks for your help !

Symfony Circular Reference Exception with Doctrine tree extension

I have a Circular Reference Exception because of Doctrine Tree Extension when I'm tring to load my fixture with Alice fixture.
[Doctrine\Common\DataFixtures\Exception\CircularReferenceException]
Graph contains cyclic dependency. An example of this problem would be
the following: Class C has class B as its dependency. Then, class B
has class A has its dependency. Finally, class A has class C as
its dependency.
I have found the same problem here:
https://github.com/doctrine/data-fixtures/issues/232 but the solution does not work for me :( ...
I'm using this version of the doctrine fixtures.
"doctrine/data-fixtures": "1.2.1",
Here is my entity
namespace BaseBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use Symfony\Component\Validator\Constraints as Assert;
/**
* BaseCategory
*
* #ORM\Entity()
* #ORM\InheritanceType("JOINED")
* #ORM\DiscriminatorColumn(name="type", type="string")
* #ORM\DiscriminatorMap({
* "article_category" = "AppBundle\Entity\ArticleCategory",
* "page_category" = "AppBundle\Entity\PageCategory",
* })
* #Gedmo\Tree(type="nested")
*/
abstract class BaseCategory
{
use \BaseBundle\Traits\SeoTrait;
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="title", type="string", length=255)
* #Assert\NotBlank()
*/
private $title;
/**
* #var string
*
* #ORM\Column(name="slug", type="string", length=255, unique=true)
* #Gedmo\Slug(fields={"title"})
*/
private $slug;
/**
* #var string
*
* #ORM\Column(name="description", type="text")
*/
private $description;
/**
* #var \DateTime
*
* #ORM\Column(type="datetime")
* #Gedmo\Timestampable(on="create")
*/
private $createdAt;
/**
* #var \DateTime
*
* #ORM\Column(type="datetime")
* #Gedmo\Timestampable(on="update")
*/
private $updatedAt;
/**
* #Gedmo\TreeLeft
* #ORM\Column(type="integer")
*/
private $lft;
/**
* #Gedmo\TreeLevel
* #ORM\Column(type="integer")
*/
private $lvl;
/**
* #Gedmo\TreeRight
* #ORM\Column(type="integer")
*/
private $rgt;
/**
* #Gedmo\TreeRoot
* #ORM\ManyToOne(targetEntity="BaseCategory")
* #ORM\JoinColumn(referencedColumnName="id", onDelete="CASCADE")
*/
private $root;
/**
* #Gedmo\TreeParent
* #ORM\ManyToOne(targetEntity="BaseCategory", inversedBy="children")
* #ORM\JoinColumn(referencedColumnName="id", onDelete="CASCADE")
*/
private $parent;
/**
* #ORM\OneToMany(targetEntity="BaseCategory", mappedBy="parent")
* #ORM\OrderBy({"lft" = "ASC"})
*/
private $children;
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set title
*
* #param string $title
*
* #return BaseCategory
*/
public function setTitle($title)
{
$this->title = $title;
return $this;
}
/**
* Get title
*
* #return string
*/
public function getTitle()
{
return $this->title;
}
/**
* Set slug
*
* #param string $slug
*
* #return BaseCategory
*/
public function setSlug($slug)
{
$this->slug = $slug;
return $this;
}
/**
* Get slug
*
* #return string
*/
public function getSlug()
{
return $this->slug;
}
/**
* Set description
*
* #param string $description
*
* #return BaseCategory
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* #return string
*/
public function getDescription()
{
return $this->description;
}
/**
* #return \DateTime
*/
public function getCreatedAt()
{
return $this->createdAt;
}
/**
* #return \DateTime
*/
public function getUpdatedAt()
{
return $this->updatedAt;
}
public function getRoot()
{
return $this->root;
}
public function setParent(BaseCategory $parent = null)
{
$this->parent = $parent;
}
public function getParent()
{
return $this->parent;
}
}
Is it normal? How can I fix that?

Runtime Notice: Accessing static property Proxies\__CG__\SimpleMediaBundle\Entity\Media::$lazyPropertiesDefaults as non static

I created a custom bundle called SimpleMedia. When I try to load a page that loads a company it gives me the Runtime Notice
Runtime Notice: Accessing static property Proxies__CG__\SimpleMediaBundle\Entity\Media::$lazyPropertiesDefaults as non static.
I know it has something to do with my one to one relation
(logoFile(Company Entity) -> id (Media Entity).
Anyone have any ideas? I am using Symfony 2.7
Controller
/**
* #Route("/{id}", name="api_company_show")
* #Method("GET")
* #param $id
* #return Response $response
*/
public function showAction($id) {
$company = $this->findCompanyById($id);
$response = $this->createApiResponse($company, 200);
return $response;
}
/**
* Find company by id. Throw exception if it does not.
* #param $id
* #return Company $company
*/
private function findCompanyById($id) {
$company = $this->getDoctrine()
->getRepository('AppBundle:Company')
->find($id);
if (!$company) {
throw $this->createNotFoundException(sprintf(
'No company found with id "%d"',
$id
));
}
return $company;
}
Company.php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use AppBundle\Entity\User;
use Symfony\Component\HttpFoundation\File\File;
use SimpleMediaBundle\Entity\Media;
/**
* Company
* #ORM\Table()
* #ORM\Entity(repositoryClass="AppBundle\Repository\CompanyRepository")
*/
class Company
{
/**
* #var integer
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
* #ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* #var string
* #ORM\Column(name="website", type="string", length=255, nullable=true)
*/
private $website;
/**
* #var string
* #ORM\Column(name="address_1", type="string", length=255, nullable=true)
*/
private $address1;
/**
* #var string
* #ORM\Column(name="address_2", type="string", length=255, nullable=true)
*/
private $address2;
/**
* #var string
* #ORM\Column(name="city", type="string", length=255, nullable=true)
*/
private $city;
/**
* #var string
* #ORM\Column(name="state", type="string", length=255, nullable=true)
*/
private $state;
/**
* #var string
* #ORM\Column(name="zipcode", type="string", length=50, nullable=true)
*/
private $zipcode;
/**
* #var string
* #ORM\Column(name="country", type="string", length=255, nullable=true)
*/
private $country;
/**
* #var string
* #ORM\Column(name="phone", type="string", length=50, nullable=true)
*/
private $phone;
/**
* #var string
* #ORM\Column(name="fax", type="string", length=50, nullable=true)
*/
private $fax;
/**
* #var integer
* #ORM\Column(name="years_in_business", type="integer", length=50, nullable=true)
*/
private $yearsInBusiness;
/**
* #var string
* #ORM\Column(name="number_of_employees", type="integer", length=50, nullable=true)
*/
private $numberOfEmployees;
/**
* #var integer
* #ORM\ManyToMany(targetEntity="AppBundle\Entity\User")
*/
private $owners;
/**
* #ORM\OneToOne(targetEntity="SimpleMediaBundle\Entity\Media", cascade={"persist", "remove"}, orphanRemoval=true)
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="logo_file", referencedColumnName="id", nullable=true)
* })
*/
protected $logoFile;
/**
* #ORM\Column(type="datetime", name="updated", nullable=true)
* #var \DateTime $updated
*/
protected $updated;
public function __construct()
{
$this->owners = new ArrayCollection();
$this->logoFile = new ArrayCollection();
}
/**
* Get id
* #return integer
*/
public function getId()
{
return $this->id;
}
// Basic Getter and Setters
/**
* Set logo file id.
* #param Media $media
* #return $this
*/
public function setLogoFile(Media $media)
{
$this->logoFile = $media;
return $this;
}
/**
* Get Log File.
* #return File
*/
public function getLogoFile()
{
return $this->logoFile;
}
}
Media.php
namespace SimpleMediaBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use SimpleMediaBundle\Entity\MediaInterface;
/**
* #ORM\Table()
* #ORM\Entity(repositoryClass="SimpleMediaBundle\Repository\MediaRepository")
*/
class Media implements MediaInterface
{
/**
* #var integer $id
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string $name
* #ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* #var string $path
* #ORM\Column(name="path", type="string", length=500)
*/
private $path;
/**
* #var string $size
* #ORM\Column(name="size", type="integer", nullable=true)
*/
private $size;
/**
* #var string $createdAt
* #ORM\Column(name="created_at", type="datetime")
*/
private $createdAt;
/**
* #var string $createdAt
* #ORM\Column(name="updated_at", type="datetime")
*/
private $updatedAt;
/**
* #var string $contentType
* #ORM\Column(name="content_type", type="string", length=50, nullable=true)
*/
private $contentType;
/**
* #var string $type
* #ORM\Column(name="type", type="string", length=255)
*/
private $type;
public function __construct()
{
$this->createdAt = new \DateTime();
$this->updatedAt = new \DateTime();
}
/**
* Get id
* #return integer
*/
public function getId()
{
return $this->id;
}
// Basic Getter and Setters
/**
* Transform to string
* #return string
*/
public function __toString()
{
return (string) $this->getId();
}
}
Changing the fetch mode to EAGER fixed the issue for me.
/**
* #var Media
*
* #ORM\OneToOne(targetEntity="SimpleMediaBundle\Entity\Media", cascade={"persist", "remove"}, orphanRemoval=true, fetch="EAGER")
* #ORM\JoinColumn(name="logo_file", referencedColumnName="id", nullable=true)
*/
private $logoFile;
I think you have define the relationship wrong. I think should be:
/**
*
* #ORM\OneToOne(targetEntity="SimpleMediaBundle\Entity\Media", cascade={"persist", "remove"}, orphanRemoval=true)
* #ORM\JoinColumn(name="logo_file", referencedColumnName="id", nullable=true)
*/
protected $logoFile;
On the other hand, in the company constructor you dont need initialiser the $logoFile variable because is not a array it is just one value.

How can translatable in many-to-many relationship in Doctrine2? Symfony2

I've used Translatable with a personal translation; I've implemented PysTranslationand I've used ORM query hint in PysRepository. All of this works fine, the problem has been when I've translated the entity Genero. This entity has a many-to-many relationship with Pys entity and the above method doesn't work. How I can translate the $genNombre attribute of Generoentity?
/**
* Pys
*
* #ORM\Table(name="pys")
* #ORM\Entity(repositoryClass="Filmboot\PYSBundle\Entity\PysRepository")
* #Gedmo\TranslationEntity(class="Filmboot\PYSBundle\Entity\PysTranslation")
*/
class Pys
{
/**
* #var integer
*
* #ORM\Column(name="PYS_ID", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $pysId;
/**
* #var string
*
* #ORM\Column(name="PYS_STR", type="string", length=255, nullable=false)
* #Gedmo\Translatable
*/
private $pysStr;
/**
* #var string
*
* #ORM\Column(name="PYS_TITULO", type="string", length=255, nullable=true)
* #Gedmo\Translatable
*/
private $pysTitulo;
/**
* #var integer
*
* #ORM\Column(name="PYS_DURACION", type="integer", nullable=true)
*/
private $pysDuracion;
/**
* #var integer
*
* #ORM\Column(name="PYS_ANYO", type="integer", nullable=true)
*/
private $pysAnyo;
/**
* #var string
*
* #ORM\Column(name="PYS_PAIS", type="string", length=255, nullable=true)
* #Gedmo\Translatable
*/
private $pysPais;
/**
* #var string
*
* #ORM\Column(name="PYS_SINOPSIS", type="string", length=3000, nullable=true)
* #Gedmo\Translatable
*/
private $pysSinopsis;
/**
* #var string
*
* #ORM\Column(name="PYS_GUIONISTA", type="string", length=255, nullable=true)
*/
private $pysGuionista;
/**
* #ORM\ManyToOne(targetEntity="Filmboot\DirectorBundle\Entity\Director", cascade={"remove"})
* #ORM\JoinColumn(name="DIR_ID", referencedColumnName="DIR_ID", onDelete="CASCADE")
*/
private $director;
/**
* #var string
*
* #ORM\Column(name="PYS_IMAGEN", type="string", length=255, nullable=true)
*/
private $pysImagen;
/**
* #var string
*
* #ORM\Column(name="PYS_IMAGEN_GRANDE", type="string", length=255, nullable=true)
*/
private $pysImagenGrande;
/**
* #ORM\ManyToMany(targetEntity="\Filmboot\ActorBundle\Entity\Actor", mappedBy="peliculas", cascade={"remove"})
*/
private $actores;
/**
* #ORM\ManyToMany(targetEntity="\Filmboot\PYSBundle\Entity\Genero", mappedBy="peliculas", cascade={"remove"})
*/
private $generos;
/**
* #ORM\OneToMany(targetEntity="\Filmboot\PYSBundle\Entity\Premio", mappedBy="pys", cascade={"remove"})
* #ORM\JoinColumn(name="PRE_ID", referencedColumnName="PRE_ID", onDelete="CASCADE")
*/
private $premios;
/**
* #ORM\OneToMany(targetEntity="\Filmboot\UsuarioBundle\Entity\Voto", mappedBy="pys", cascade={"remove"})
* #ORM\JoinColumn(name="PYS_ID", referencedColumnName="PYS_ID", onDelete="CASCADE")
*/
private $votaciones;
/**
* #ORM\OneToMany(targetEntity="PysTranslation", mappedBy="object", cascade={"persist", "remove"})
*/
private $translations;
public function __construct()
{
$this->actores = new ArrayCollection();
$this->generos = new ArrayCollection();
$this->votaciones = new ArrayCollection();
$this->translations = new ArrayCollection();
}
public function getTranslations()
{
return $this->translations;
}
public function addTranslation(PysTranslation $t)
{
if (!$this->translations->contains($t)) {
$this->translations[] = $t;
$t->setObject($this);
}
}
This is Genero
<?php
namespace Filmboot\PYSBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Gedmo\Mapping\Annotation as Gedmo;
/**
* Genero
*
* #ORM\Table(name="genero")
* #ORM\Entity
*/
class Genero
{
/**
* #var integer
*
* #ORM\Column(name="GEN_ID", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $genId;
/**
* #var string
*
* #ORM\Column(name="GEN_NOMBRE", type="string", length=255, nullable=true)
* #Gedmo\Translatable
*/
private $genNombre;
/**
* #ORM\ManyToMany(targetEntity="\Filmboot\PYSBundle\Entity\Pys", inversedBy="generos")
* #ORM\JoinTable(name="P_GENERO",
* joinColumns={#ORM\JoinColumn(name="GEN_ID", referencedColumnName="GEN_ID")},
* inverseJoinColumns={#ORM\JoinColumn(name="PYS_ID", referencedColumnName="PYS_ID")}
* )
*/
private $peliculas;
This is PysTranslation
/**
* #ORM\Entity
* #ORM\Table(name="pys_translation", uniqueConstraints={#ORM\UniqueConstraint(name="lookup_unique_idx", columns={"locale", "object_id", "field"})})
*/
class PysTranslation extends AbstractPersonalTranslation
{
/**
* Convinient constructor
*
* #param string $locale
* #param string $field
* #param string $value
*/
public function __construct($locale, $field, $value)
{
$this->setLocale($locale);
$this->setField($field);
$this->setContent($value);
}
/**
* #ORM\ManyToOne(targetEntity="Pys", inversedBy="translations")
* #ORM\JoinColumn(name="object_id", referencedColumnName="PYS_ID", onDelete="CASCADE")
*/
protected $object;
}
This is PysRepository
class PysRepository extends EntityRepository
{
public function findPeliculas()
{
$em = $this->getEntityManager();
$consulta = $em->createQuery('
SELECT p, a, d, g, pr, v
FROM PYSBundle:Pys p
JOIN p.actores a JOIN p.director d JOIN p.generos g JOIN p.premios pr JOIN p.votaciones v
ORDER BY p.pysTitulo ASC
');
return $consulta->setHint(\Doctrine\ORM\Query::HINT_CUSTOM_OUTPUT_WALKER, 'Gedmo\\Translatable\\Query\\TreeWalker\\TranslationWalker')->getResult();
}
/**
*
* #param string $pysStr El slug de la pelĂ­cula
*/
public function findPys($pysStr)
{
$em = $this->getEntityManager();
$consulta = $em->createQuery('
SELECT p, a, d, g, pr, v
FROM PYSBundle:Pys p
JOIN p.actores a JOIN p.director d JOIN p.generos g JOIN p.premios pr JOIN p.votaciones v
WHERE p.pysStr = :pysStr
');
$consulta->setParameter('pysStr', $pysStr);
return $consulta->setHint(\Doctrine\ORM\Query::HINT_CUSTOM_OUTPUT_WALKER, 'Gedmo\\Translatable\\Query\\TreeWalker\\TranslationWalker')->getSingleResult();
}
}
I've solved the problem by adding this line in Genero entity annotations:
/**
* Genero
*
* #ORM\Table(name="genero")
* #ORM\Entity
* #Gedmo\TranslationEntity(class="Filmboot\PYSBundle\Entity\GeneroTranslation")
*/
class Genero

Resources