/   /   /  OroCommerce For Developers: some lines about customer address in frontend

Note:

For more extensions and themes visit our store

OroCommerce For Developers: some lines about customer address in frontend


In many cases you need to use full customer address form type or just some fields like country region or city , ok to know how to use firstly you should know that oro platform came with a bundle AddressBundle which manage global address structure for example address entity country entity and region entity , this bundle give you ability to add form address or select box of countries box and regions too and managing relation between country and regions by validation and events, as well as you can using the phone field or email field (collection too) ….

All other bundles in OroCommerce like customerBundle based on  AddressBundle to manage addresses , So the big differences between general addresses and customer addresses that the second is typed which means for example billing address or shipping address .

The customer user form is inside vendor/oro/customer-portal/src/Oro/Bundle/CustomerBundle/Form/Type/CustomerTypedAddressType.php you can using inside your custom form or inject by from extension with builder , we have said the parent is:

  1.  
  2.     use Oro\Bundle\AddressBundle\Form\Type\AddressType;
  3.     /**
  4.      * {@inheritdoc}
  5.      */
  6.     public function getParent()
  7.     {
  8.         return AddressType::class;
  9.     } 
  10.  

But this form type by default use a backend route to load the region related to each country on real time after country value get changed 'region_route' => 'oro_api_country_get_regions' inside vendor/oro/platform/src/Oro/Bundle/AddressBundle/Form/Type/AddressType.php:
  1.  
  2.     /**
  3.      * {@inheritdoc}
  4.      */
  5.     public function configureOptions(OptionsResolver $resolver)
  6.     {
  7.         $resolver->setDefaults(
  8.             array(
  9.                 'data_class' => 'Oro\Bundle\AddressBundle\Entity\Address',
  10.                 'csrf_token_id' => 'address',
  11.                 'single_form' => true,
  12.                 'region_route' => 'oro_api_country_get_regions'
  13.             )
  14.         );
  15.     }
  16.  

So if you’re using it for example in frontend by form extension you should be sure that you have use the correct 'region_route' => 'oro_api_frontend_country_get_regions':
  1.  
  2.     /**
  3.      * {@inheritdoc}
  4.      */
  5.     public function buildView(FormView $view, FormInterface $form, array $options) {
  6.         $view->vars['region_route'] = 'oro_api_frontend_country_get_regions';
  7.     }
  8.  

So now let’s create and example of an helper to save Data Address of your form : let’s create Address.php helper inside src/Ibnab/Bundle/CreateCustomerBundle/Helper/Address.php:

  1.  
  2. <?php
  3. namespace Oaklab\Bundle\CreateCustomerBundle\Helper;
  4. use Oro\Bundle\CustomerBundle\Entity\AbstractDefaultTypedAddress;
  5. use Doctrine\Common\Persistence\ManagerRegistry;
  6. use Oro\Bundle\CustomerBundle\Entity\CustomerAddress;
  7. use Doctrine\Common\Collections\ArrayCollection;
  8. class Address
  9. {
  10.      /** @var ObjectRepository|EntityRepository */
  11.     protected $countryRepository;
  12.     /** @var ObjectRepository|EntityRepository */
  13.     protected $regionRepository;
  14.     /** @var ObjectRepository|EntityRepository */
  15.     protected $addressTypeRepository;
  16.     /** @var ManagerRegistry */
  17.     private $registry;
  18.     /**
  19.      * @param ConfigManager $configProvider
  20.      */
  21.     public function __construct(ManagerRegistry $registry)
  22.     {
  23.         $this->registry = $registry;
  24.     }   
  25.     /**
  26.      * @param $data
  27.      * @return AbstractDefaultTypedAddress
  28.      */
  29.     public function createAddress($data)
  30.     {
  31.         $this->initRepositories();
  32.         /** @var Country $country */
  33.         $country = $this->countryRepository->findOneBy(['iso2Code' => $data['country']]);
  34.         if (!$country) {
  35.             throw new \RuntimeException('Can\'t find country with ISO ' . $data['country']);
  36.         }
  37.         /** @var Region $region */
  38.         $region = $this->regionRepository->findOneBy(['country' => $country, 'code' => $data['state']]);
  39.         if (!$region) {
  40.             throw new \RuntimeException(
  41.                 printf('Can\'t find region with country ISO %s and code %s', $data['country'], $data['state'])
  42.             );
  43.         }
  44.         $types = [];
  45.         $typesFromData = explode(',', $data['types']);
  46.         foreach ($typesFromData as $type) {
  47.             $types[] = $this->addressTypeRepository->find($type);
  48.         }
  49.         $defaultTypes = [];
  50.         $defaultTypesFromData = explode(',', $data['defaultTypes']);
  51.         foreach ($defaultTypesFromData as $defaultType) {
  52.             $defaultTypes[] = $this->addressTypeRepository->find($defaultType);
  53.         }
  54.         $address = $this->getNewAddressEntity();
  55.         $address->setTypes(new ArrayCollection($types));
  56.         $address->setDefaults(new ArrayCollection($defaultTypes))
  57.             ->setPrimary(true)
  58.             ->setLabel('Primary address')
  59.             ->setCountry($country)
  60.             ->setStreet($data['street'])
  61.             ->setCity($data['city'])
  62.             ->setRegion($region)
  63.             ->setPostalCode($data['zipCode'])
  64.             ->setFirstName($data['firstName'])
  65.             ->setLastName($data['lastName']);
  66.         return $address;
  67.     }
  68.     protected function initRepositories()
  69.     {
  70.         $this->countryRepository = $this->registry
  71.             ->getManagerForClass('OroAddressBundle:Country')
  72.             ->getRepository('OroAddressBundle:Country');
  73.        $this->regionRepository = $this->registry
  74.             ->getManagerForClass('OroAddressBundle:Region')
  75.             ->getRepository('OroAddressBundle:Region');
  76.         $this->addressTypeRepository = $this->registry
  77.             ->getManagerForClass('OroAddressBundle:AddressType')
  78.             ->getRepository('OroAddressBundle:AddressType');
  79.     }
  80.     public function getRegistry(){
  81.         return $this->registry;
  82.     }
  83.     /**
  84.      * {@inheritdoc}
  85.      */
  86.     protected function getNewAddressEntity()
  87.     {
  88.         return new CustomerAddress();
  89.     }
  90. }
  91.  


the content of class is easy create a a new instance of class CustomerAddress and initialize repositories for country region and addressType entities , so  and add an function createAddress($data) to use for persist data coming from from your form .

You can create a service to use inside your form type extension for example:

  1.  
  2.   ibnab_create_customer.address_helper:
  3.         class: Ibnab\Bundle\CreateCustomerBundle\Helper\Address
  4.         public: true
  5.         arguments:
  6.             - "@doctrine"
  7.  


Even you can use the country and region field separately and using to same technique to pass frontend api url and save . 

Comments

IBNAB is a company made of a group of professionals whose work is providing secure open source solutions. Our company strives for reaching magnificent results with each experience and provides professional open source solutions that cover every part of the business process.