0
votes

I have a Product entity and a ProductImage entity. Product images are "ManyToOne" and contain a reference field to the product.

I'm using the Zend Framework 2 Form module with a "Collection" fieldset for the images. The form will populate with manually added rows in the database but does not create new rows or delete them.

The product image collection fieldset contains an id, url, and sort field for the image.

When i submit the form with new data, the DoctrineObject hydrator tries to load a ProductImage entity based on identifiers but ProductImage.id is NULL since there is no entity to reference obviously.

I tried creating my own hydrator to extend DoctrineObject and create the entities if they don't exist but the problem there is that Product does not have an ID to reference yet until it's created.

My question is do i need to go full custom on the images? Or is there a way to accomplish this using the DoctrineObject hydrator?

1

1 Answers

0
votes

I am not shure if this will work for you, but I think I have a similar concept with a domain with OneToMany to a Properties table (one domain will have many properties)

Notice my code in Domain->addProperty() where I set the property's Domain id (pretty shure this will also work if the domain doesn't have an ID...

Hope this helps :)

public function indexAction()
{
    $em = $this->getEntityManager();


    $title = new Property();
    /** @var \Common\Entity\Domain $domain */


    $rep = $em->getRepository('Common\Entity\Domain');
    $domain = $rep->findOneBy(array('id' => '3'));

    $title->setProperty("title");
    $title->setValue("WWW . RichardHagen . NO _ TEST");
    $domain->addProperty($title);

    $em->persist($domain);
    $em->flush();

    return new ViewModel(["domain" => $domain]);
}

This is my code for Domain:

<?php
/**
 * Created by PhpStorm.
 * User: Richard
 * Date: 30.11.2014
 * Time: 13:24
 */
namespace Common\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Common\Entity\Property;

/**
 * @ORM\Entity
 * @ORM\Table(name="domain")
 */
class Domain {
    /**
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     * @ORM\Column(type="integer", options={"unsigned":true})
     */
    protected $id;

    /** @ORM\Column(length=127,nullable=true) */
    protected $subdomain;


    /** @ORM\Column(length=255,nullable=true) */
    protected $domain;

    /**
     * @ORM\OneToMany(targetEntity="Property", mappedBy="domain", fetch="EAGER", cascade={"persist"})
     */
    protected $properties;

    /**
     * @param \Common\Entity\Property $property
     */
    public function addProperty($property)
    {
        $property->setDomain($this);
        $this->properties[] = $property;
    }

    /**
     * @param string $name
     * @param bool $default
     * @return bool|string
     */
    public function getPropertyValue($name, $default = false) {
        /** @var Property $property */
        foreach ($this->getProperties() as $property) {
            if ($name == $property->getProperty()) {
                return $property->getValue();
            }
        }
        return $default;
    }

    /**
     * @return mixed
     */
    public function getProperties()
    {
        return $this->properties;
    }

    /**
     * @return mixed
     */
    public function getDomain()
    {
        return $this->domain;
    }

    /**
     * @param mixed $domain
     */
    public function setDomain($domain)
    {
        $this->domain = $domain;
    }

    /**
     * @return mixed
     */
    public function getSubdomain()
    {
        return $this->subdomain;
    }

    /**
     * @param mixed $subdomain
     */
    public function setSubdomain($subdomain)
    {
        $this->subdomain = $subdomain;
    }

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

And in the end the code for Properties:

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="property",options={"collate"="utf8_swedish_ci"})
 */
class Property {
    /**
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     * @ORM\Column(type="integer", options={"unsigned":true})
     */
    protected $id;

    /**
     * @ORM\ManyToOne(targetEntity="Domain", fetch="EAGER", inversedBy="properties")
     */
    protected $domain;

    /**
     * @ORM\Column(length=45,nullable=true)
     */
    protected $property;

    /**
     * @ORM\Column(type="text",nullable=true)
     */
    protected $value;

    /**
     * @return mixed
     */
    public function getDomain()
    {
        return $this->domain;
    }

    /**
     * @param mixed $domain
     */
    public function setDomain($domain)
    {
        $this->domain = $domain;
    }

    /**
     * @return mixed
     */
    public function getProperty()
    {
        return $this->property;
    }

    /**
     * @param mixed $property
     */
    public function setProperty($property)
    {
        $this->property = $property;
    }

    /**
     * @return mixed
     */
    public function getValue()
    {
        return $this->value;
    }

    /**
     * @param mixed $value
     */
    public function setValue($value)
    {
        $this->value = $value;
    }



}