Symfony2中的计费和发货地址管理 - 如果相等,则在db中重复地址

时间:2014-11-28 23:26:29

标签: symfony

我有一个表单客户注册类型,带有嵌入地址表单(billingAddress和其他可选的ShippingAddress)。 如果用户没有检查"不同的送货地址"复选框,我的数据库地址表中应该只有一个地址。即便如此,我在地址表中得到两个不同的地址(具有相同的信息)。 但是,我查看" addAddress"如果在添加新地址之前地址已经存在。实际上在我的Customer FormType中,我以shippingAdress形式复制billingAddress表单数据,但在hasAdress方法中,$ this-> addresses-> contains($ address)返回false。我不明白为什么......

由于

这里是代码:

客户类

<?php

namespace DRMS\CustomerBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Validator\Constraints as Assert;

use DRMS\AddressingBundle\Entity\Address;

/**
 * DRMS\CustomerBundle\Entity\Customer
 *
 * @ORM\Entity(repositoryClass="DRMS\CustomerBundle\Repository\CustomerRepository")
 * @ORM\Table(name="customer", uniqueConstraints={@ORM\UniqueConstraint(name="customer_id_UNIQUE", columns={"customer_id"})})
 */
class Customer
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer", name="customer_id")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $customerId;

    // Others attributes
    // ...

    /**
     * @ORM\OneToOne(targetEntity="DRMS\AddressingBundle\Entity\Address")
     * @ORM\JoinColumn(name="billing_address_id", referencedColumnName="address_id")
     */
    protected $billingAddress;

    /**
     * @ORM\OneToOne(targetEntity="DRMS\AddressingBundle\Entity\Address")
     * @ORM\JoinColumn(name="shipping_address_id", referencedColumnName="address_id")
     */        
    protected $shippingAddress;

    /**
     * @ORM\OneToMany(targetEntity="DRMS\AddressingBundle\Entity\Address", mappedBy="customer", cascade={"remove", "persist"})
     ** ORM\JoinColumn(name="customer_id", referencedColumnName="customer_id", onDelete="CASCADE")
     */
    protected $addresses;


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

    /**
     * Set the value of customerId.
     *
     * @param integer $customerId
     * @return \DRMS\CustomerBundle\Entity\Customer
     */
    public function setCustomerId($customerId)
    {
        $this->customerId = $customerId;

        return $this;
    }

    /**
     * Get the value of customerId.
     *
     * @return integer
     */
    public function getCustomerId()
    {
        return $this->customerId;
    }

    // Others Getters/Setters
    // ...

     /**
     * Set billingAddress
     *
     * @param \DRMS\AddressingBundle\Entity\Address $billingAddress
     * @return Customer
     */
    public function setBillingAddress(Address $billingAddress = null)
    {
        $this->billingAddress = $billingAddress;
        if (null !== $billingAddress && !$this->hasAddress($billingAddress)) {
            $this->addAddress($billingAddress);
        }

        return $this;
    }

    /**
     * Get billingAddress
     *
     * @return \DRMS\AddressingBundle\Entity\Address
     */
    public function getBillingAddress()
    {
        return $this->billingAddress;
    }

    /**
     * Set shippingAddress
     *
     * @param \DRMS\AddressingBundle\Entity\Address $shippingAddress
     * @return Customer
     */
    public function setShippingAddress(Address $shippingAddress = null)
    {
        $this->shippingAddress = $shippingAddress;
        if (null !== $shippingAddress && !$this->hasAddress($shippingAddress)) {
            $this->addAddress($shippingAddress);
        }

        return $this;
    }

    /**
     * Get shippingAddress
     *
     * @return \DRMS\AddressingBundle\Entity\Address
     */
    public function getShippingAddress()
    {
        return $this->shippingAddress;
    }

   /**
     * Add Address entity to collection (one to many).
     *
     * @param \DRMS\AddressingBundle\Entity\Address $address
     * @return \DRMS\CustomerBundle\Entity\Customer
     */
    public function addAddress(Address $address)
    {
        if (!$this->hasAddress($address)) {
            $this->addresses->add($address);
            $address->setCustomer($this);
        }

        return $this;
    }

    /**
     * Remove Address
     * 
     * @param \DRMS\AddressingBundle\Entity\Address $address
     * @return \DRMS\CustomerBundle\Entity\Customer
     */
    public function removeAddress(Address $address) {

        $this->addresses->removeElement($address);

        return $this;
    }

    /**
     * Get Address entity collection (one to many).
     *
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getAddresses()
    {
        return $this->addresses;
    }

    /**
     * Has address
     *
     * @param \DRMS\AddressingBundle\Entity\Address $address
     * @return bool
     */
    public function hasAddress(Address $address)
    {
        return $this->addresses->contains($address);
    }

}

地址类

<?php

namespace DRMS\AddressingBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * DRMS\AddressingBundle\Entity\Address
 *
 * @ORM\Entity(repositoryClass="DRMS\AddressingBundle\Repository\AddressRepository")
 * @ORM\Table(name="address"), uniqueConstraints={@ORM\UniqueConstraint(name="customer_adress_UNIQUE", columns={"customer_id","address_id"})}
 */
class Address
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $address_id;


    // Others attributes
    // ...


    /**
     * @ORM\ManyToOne(targetEntity="DRMS\CustomerBundle\Entity\Customer", inversedBy="addresses", cascade={"remove"})
     * @ORM\JoinColumn(name="customer_id", referencedColumnName="customer_id", onDelete="CASCADE")
     */
    protected $customer;


    /**
     * Get the value of address_id.
     *
     * @return integer
     */
    public function getAddressId()
    {
        return $this->address_id;
    }


    /**
     * Set customer
     *
     * @param \DRMS\CustomerBundle\Entity\Customer $customer
     * @return Address
     */
    public function setCustomer(\DRMS\CustomerBundle\Entity\Customer $customer)
    {
        $this->customer = $customer;

        return $this;
    }

    /**
     * Get customer
     *
     * @return \DRMS\CustomerBundle\Entity\Customer 
     */
    public function getCustomer()
    {
        return $this->customer;
    }
}

Customer FormType

<?php
# src\DRMS\CustomerBundle\Form\Type\CustomerType.php

namespace DRMS\CustomerBundle\Form\Type;

/**
 * Description of CustomerType
 *
 */

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\Form\FormEvents; 
use Symfony\Component\Form\FormEvent; 


class CustomerType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {

        $builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) { 
                    $data = $event->getData(); 

                    if (!array_key_exists('differentShippingAddress', $data) || false === $data['differentShippingAddress']) { 
                        $data['shippingAddress'] = $data['billingAddress']; 

                        $event->setData($data); 
                    } 
                });

        $builder->add('customerName', null)
                ->add('customerFirstname', null)
                ->add('phone')
                ->add('mobilePhone')

                ->add('billingAddress', 'drms_address', array( 
                    'label' => 'drms.form.customer.billing_address',
                )) 
                ->add('differentShippingAddress', 'checkbox', array( 
                    'mapped'    => false,
                    'label'     => 'drms.form.customer.different_shipping_address',
                    'required'  => false,
                )) 
                ->add('shippingAddress', 'drms_address', array( 
                    'label' => 'drms.form.customer.shipping_address',
                )) 

                ;

    }

    /**
     * @param OptionsResolverInterface $resolver
     * 
     * If checkbox vatNumberOwner is checked, apply "vat_number_required" validation group for activate Vat Number test
     */
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'DRMS\CustomerBundle\Entity\Customer',
            'validation_groups' => function(FormInterface $form) {
                $validation_groups = array('Registration');
                if($form->get('differentShippingAddress')->getData() == true) {
                    $validation_groups[] = 'ShippingAddressRequired';
                }
                return $validation_groups;
             },
        ));
    }

    public function getName()
    {
        return 'drms_customer';
    }

}

1 个答案:

答案 0 :(得分:1)

contains()实现如此https://github.com/doctrine/collections/blob/master/lib/Doctrine/Common/Collections/ArrayCollection.php#L189这意味着您正在对对象标识进行严格比较。由于地址对象是由表单创建的,而不是由身份映射中的Doctrine管理,因此它不会与Doctrine创建的对象进行比较。由于不支持自定义集合,我建议您将in_array逻辑更改为不严格,并将其直接放在您的实体中。