<commit_before><?php
namespace Oro\Bundle\AddressBundle\Form\EventListener;

use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\PropertyAccess\PropertyAccess;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

use Oro\Bundle\AddressBundle\Entity\AbstractTypedAddress;

/**
 * When address is created/updated from single form, it will ensure the rules of one primary address and address types
 * uniqueness
 */
class FixAddressesPrimaryAndTypesSubscriber implements EventSubscriberInterface
{
    /**
     * Property path to collection of all addresses (e.g. 'owner.address' means $address->getOwner()->getAddresses())
     *
     * @var string
     */
    protected $addressesProperty;

    /**
     * @var PropertyAccess
     */
    protected $addressAccess;

    public function __construct($addressesProperty)
    {
        $this->addressesAccess = PropertyAccess::createPropertyAccessor();
        $this->addressesProperty = $addressesProperty;
    }

    /**
     * {@inheritdoc}
     */
    public static function getSubscribedEvents()
    {
        return array(
            FormEvents::POST_SUBMIT => 'postSubmit'
        );
    }

    /**
     * Removes empty collection elements.
     *
     * @param FormEvent $event
     */
    public function postSubmit(FormEvent $event)
    {
        /** @var AbstractTypedAddress $address */
        $address = $event->getData();

        /** @var AbstractTypedAddress[] $allAddresses */
        $allAddresses = $this->addressesAccess->getValue($address, $this->addressesProperty);

        /**
         * Only one address must be primary
         */
        if ($address->isPrimary()) {
            foreach ($allAddresses as $otherAddresses) {
                if (!$address->isEqual($otherAddresses)) {
                    $otherAddresses->setPrimary(false);
                }
            }
            $address->setPrimary(true);
        } elseif (count($allAddresses) == 1) {
            $address->setPrimary(true);
        }

        /**
         * Two addresses must not have same types
         */
        $types = $address->getTypes();
        if (count($types)) {
            foreach ($allAddresses as $otherAddresses) {
                if (!$address->isEqual($otherAddresses)) {
                    foreach ($types as $type) {
                        $otherAddresses->removeType($type);
                    }
                }
            }
        }
    }
}
<commit_msg>CRM-333: Address add/edit form widget - fix issue with primary address<commit_after><?php
namespace Oro\Bundle\AddressBundle\Form\EventListener;

use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\PropertyAccess\PropertyAccess;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

use Oro\Bundle\AddressBundle\Entity\AbstractTypedAddress;

/**
 * When address is created/updated from single form, it will ensure the rules of one primary address and address types
 * uniqueness
 */
class FixAddressesPrimaryAndTypesSubscriber implements EventSubscriberInterface
{
    /**
     * Property path to collection of all addresses (e.g. 'owner.address' means $address->getOwner()->getAddresses())
     *
     * @var string
     */
    protected $addressesProperty;

    /**
     * @var PropertyAccess
     */
    protected $addressAccess;

    public function __construct($addressesProperty)
    {
        $this->addressesAccess = PropertyAccess::createPropertyAccessor();
        $this->addressesProperty = $addressesProperty;
    }

    /**
     * {@inheritdoc}
     */
    public static function getSubscribedEvents()
    {
        return array(
            FormEvents::POST_SUBMIT => 'postSubmit'
        );
    }

    /**
     * Removes empty collection elements.
     *
     * @param FormEvent $event
     */
    public function postSubmit(FormEvent $event)
    {
        /** @var AbstractTypedAddress $address */
        $address = $event->getData();

        /** @var AbstractTypedAddress[] $allAddresses */
        $allAddresses = $this->addressesAccess->getValue($address, $this->addressesProperty);

        /**
         * Only one address must be primary
         */
        if ($address->isPrimary()) {
            foreach ($allAddresses as $otherAddresses) {
                $otherAddresses->setPrimary(false);
            }
            $address->setPrimary(true);
        } elseif (count($allAddresses) == 1) {
            $address->setPrimary(true);
        }

        /**
         * Two addresses must not have same types
         */
        $types = $address->getTypes();
        if (count($types)) {
            foreach ($allAddresses as $otherAddresses) {
                foreach ($types as $type) {
                    $otherAddresses->removeType($type);
                }
            }
            foreach ($types as $type) {
                $address->addType($type);
            }
        }
    }
}

{'fraction_non_alphanumeric': 0.11379657603222558, 'fraction_numerical': 0.0010070493454179255, 'mean_word_length': 2.216321243523316, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 36, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6748246', 'n_tokens_mistral': 1301, 'n_tokens_neox': 1279, 'n_words': 282}