Question

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 */
}
Était-ce utile?

La solution

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.

Autres conseils

    $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)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top