src/Form/Customer/AddressType.php line 25

Open in your IDE?
  1. <?php
  2. namespace App\Form\Customer;
  3. use App\Entity\BillingAddress;
  4. use Exception;
  5. use App\Entity\Address;
  6. use App\Entity\Country;
  7. use App\Form\DataTransformer\FilterPhoneTransformer;
  8. use Doctrine\ORM\EntityRepository;
  9. use Symfony\Bridge\Doctrine\Form\Type\EntityType;
  10. use Symfony\Component\Form\AbstractType;
  11. use Symfony\Component\Form\Extension\Core\Type\TelType;
  12. use Symfony\Component\Form\Extension\Core\Type\TextType;
  13. use Symfony\Component\Form\Extension\Core\Type\EmailType;
  14. use Symfony\Component\Form\Extension\Core\Type\SubmitType;
  15. use Symfony\Component\Form\FormBuilderInterface;
  16. use Symfony\Component\OptionsResolver\OptionsResolver;
  17. use Symfony\Contracts\Translation\TranslatorInterface;
  18. /**
  19.  * Formular pro vykresleni poli entity Address
  20.  * Formular ma povinnoy options atribut 'entityManager'
  21.  */
  22. class AddressType extends AbstractType
  23. {
  24.     public const TYPE_DELIVERY 1;
  25.     public const TYPE_RETURN 2;
  26.     public const TYPE_BILLING 3;
  27.     public const TYPE_DELIVERY_FRONTEND 4;
  28.     protected TranslatorInterface $translator;
  29.     protected FilterPhoneTransformer $filterFormTransformer;
  30.     public function __construct(TranslatorInterface $translatorFilterPhoneTransformer $transformer)
  31.     {
  32.         $this->translator $translator;
  33.         $this->filterFormTransformer $transformer;
  34.     }
  35.     public function buildForm(FormBuilderInterface $builder, array $options): void
  36.     {
  37.         $requiredEmail false;
  38.         $phoneLabel $this->translator->trans('Telefon');
  39.         switch ($options['addressType']) {
  40.             case self::TYPE_DELIVERY:
  41.                 $phoneLabel $this->translator->trans('Telefon příjemce:');
  42.                 $builder->add('district'TextType::class, [
  43.                 'label' => $this->translator->trans('Městská čtvrť:'),
  44.                 'required' => false,
  45.                 'attr' => ['minlength' => '2''maxlength' => '63']
  46.             ]);
  47.                 break;
  48.             case self::TYPE_RETURN:
  49.                 $requiredEmail true;
  50.                 break;
  51.             case self::TYPE_BILLING:
  52.                 $options['data_class'] = BillingAddress::class;
  53.                 $builder
  54.                     ->add('companyName'TextType::class, [
  55.                         'label' => $this->translator->trans('Název společnosti:'),
  56.                         'required' => false,
  57.                         'attr' => ['maxlength' => '60''pattern' => '^[a-zA-Z0-9_,\.| ]*$''reqStar' => 0]
  58.                     ])
  59.                     ->add('companyRegNumber'TextType::class, [
  60.                         'label' => $this->translator->trans('IČO:'),
  61.                         'required' => false,
  62.                         'attr' => ['maxlength' => '60''pattern' => '^[a-zA-Z0-9_,\.| ]*$''reqStar' => 0]
  63.                     ])
  64.                     ->add('vatNumber'TextType::class, [
  65.                         'label' => $this->translator->trans('DIČ:'),
  66.                         'required' => false,
  67.                         'attr' => ['maxlength' => '60''pattern' => '^[a-zA-Z0-9_,\.| ]*$''reqStar' => 0]
  68.                     ]);
  69.                 break;
  70.             case self::TYPE_DELIVERY_FRONTEND:
  71.                 break;
  72.             default:
  73.                 throw new Exception('Neplatny typ adresy!');
  74.         }
  75.         $builder
  76.             ->add('name'TextType::class, [
  77.                 'label' => $this->translator->trans('Jméno:'),
  78.                 'required' => true,
  79.                 'attr' => ['minlength' => '2''maxlength' => '60']
  80.             ])
  81.             ->add('address1'TextType::class, [
  82.                 'label' => $this->translator->trans('Ulice a č. p.:'),
  83.                 'required' => true,
  84.                 'attr' => ['minlength' => '2''maxlength' => '255']
  85.             ])
  86.             ->add('address2'TextType::class, [
  87.                 'label' => $this->translator->trans('Doplňující adresa:'),
  88.                 'required' => false,
  89.                 'attr' => ['minlength' => '2''maxlength' => '255']
  90.             ])
  91.             ->add('city'TextType::class, [
  92.                 'label' => $this->translator->trans('Město:'),
  93.                 'required' => true,
  94.                 'attr' => ['minlength' => '1''maxlength' => '255']
  95.             ])
  96.             ->add('zipCode'TextType::class, [
  97.                 'label' => $this->translator->trans('PSČ:'),
  98.                 'required' => true,
  99.                 'attr' => ['minlength' => '5''maxlength' => '6']
  100.             ])
  101.             ->add('phone'TelType::class, [
  102.                 'label' => $phoneLabel,
  103.                 'required' => true,
  104.                 'attr' => ['minlength' => '6''maxlength' => '18']
  105.             ])
  106.             ->add('email'EmailType::class, [
  107.                 'label' => $this->translator->trans('E-mail:'),
  108.                 'required' => $requiredEmail,
  109.                 'attr' => ['minlength' => '5''maxlength' => '60']
  110.             ]);
  111.         /**
  112.          * Podle typu formulare se rozhoduji, jeslti:
  113.          * - vykresluji do formulare pole select pro Country
  114.          * - nic nevykresluji a zemi nastavim na defaultni hodnotu
  115.          */
  116.         // pokud uz mam country ve formu predanou (tj. treba v edit address) pouziju ji, jinak ji najdu v db
  117. //        dump($builder->getData());
  118. //        dd($options);
  119.         $address $builder->getData();
  120.         if ($address->getCountry() !== null) {
  121.             $country $address->getCountry();
  122.         } else {
  123.             $countryRepo $options['entityManager']->getRepository(Country::class);
  124.             $country $countryRepo->findOneBy(['iso' => $options['countryIso']]);
  125.         }
  126.         if ($options['renderCountry'] === true) {
  127.             // vykresluji select se seznamem zemi, kazdy typ formulare ma sve $countryOptions
  128.             $countryOptions $this->setCountryParams($options);
  129.             // pokud znam $country, nastavuji ji vychozi do formu
  130.             if ($country !== null) {
  131.                 $countryOptions['data'] = $country;
  132.             }
  133.             //pokud mam zvoleny neaktivni select, nastavuji ho neaktivni
  134.             if ($options['disabledCountry'] === true) {
  135.                 $countryOptions['disabled'] = true;
  136.             }
  137.             $builder->add('country'EntityType::class, $countryOptions);
  138.         } else {
  139.             // nevykresluji select, rovnou nastavuji vychozi zemi, ktera musi existovat
  140.             if ($country === null) {
  141.                 throw new Exception('Nepodařilo se najít zemi s ISO: "'.$options['countryIso'].'"!');
  142.             }
  143.             $address $builder->getData();
  144.             $address->setCountry($country);
  145.         }
  146.         if ($options['renderSubmitButton']) {
  147.             $builder->add('submit'SubmitType::class, [
  148.                 'attr' => ['class' => 'btn btn-success'],
  149.                 'label' => $this->translator->trans('Odeslat')
  150.             ]);
  151.         }
  152.         $builder->get('phone')
  153.             ->addModelTransformer($this->filterFormTransformer);
  154.     }
  155.     public function configureOptions(OptionsResolver $resolver): void
  156.     {
  157.         $required = [];
  158.         $required[] = 'entityManager'// POVINNY ATRIBUT - pri inicializaci formulare
  159.         $required[] = 'addressType'// POVINNY ATRIBUT - pri inicializaci formulare
  160.         $required[] = 'renderSubmitButton'// bool, jestli chci vykreslit tlacitko odeslat
  161.         $required[] = 'renderCountry'// bool jestli chci vykreslovat select s vyberem zemi nebo priradit adrese country podle countryIso
  162.         $required[] = 'countryIso'//iso, ktera zeme se ma ukazovat (pokud ma ale adresa uz nastavenou country, toto nepouziju)
  163.         $required[] = 'disabledCountry'//bool jestli ma byt pole country disabled
  164.         $resolver->setRequired($required);
  165.         $resolver->setDefaults(
  166.             [
  167.                 'data_class' => Address::class,
  168.                 'renderSubmitButton' => false,
  169.                 'countryIso' => 'cz',
  170.                 'renderCountry' => false,
  171.                 'disabledCountry' => false
  172.             ]
  173.         );
  174.     }
  175.     /**
  176.      * Medoda nastavuje formulare u adresy pole country podle toho, jeslti chceme sklonovany nebo obycejny select
  177.      * pokud je $options['addressType] === 4 (delivery frondend), tak se jedna o SimpleOrderForm na frontendu, vykresluji zeme sklonovane
  178.      * pokud je $options['addressType] !== 4 tak vykresluji noramlne zeme z db
  179.      * @param array $formOptions options formulare
  180.      * @return array options pro form pole country
  181.      */
  182.     public function setCountryParams(array $formOptions): array
  183.     {
  184.         $options = [];
  185.         $options['class'] = Country::class;
  186.         $options['expanded'] = false;
  187.         $options['multiple'] = false;
  188.         $options['label'] = $this->translator->trans('Země:');
  189.         if ($formOptions['addressType'] === self::TYPE_DELIVERY_FRONTEND) {
  190.             $options['choices'] = $formOptions['entityManager']
  191.                 ->getRepository(Country::class)->findActiveCountries();
  192.             $options['choice_value'] = static function (Country $c) {
  193.                 return $c->getIso(); // iso je potreba jako klic ve formulari kvuli ajax pozadavkum na prepocet ceny
  194.             };
  195.             $options['choice_label'] = function (Country $c) {
  196.                 return $this->translator->trans(
  197.                     'send_package',
  198.                     ['country_iso' => $c->getIso(), 'case' => 2], // v formulari ukazuji prelozene zeme
  199.                     'messages'
  200.                 );
  201.             };
  202.         } else {
  203.             $options['query_builder'] = static function (EntityRepository $er) {
  204.                 return $er->createQueryBuilder('c')
  205.                     ->orderBy('c.name''ASC');
  206.             };
  207.             $options['choice_label'] = 'name';
  208.         }
  209.         return $options;
  210.     }
  211. }