src/Form/EventListener/DynamicFieldsSubscriber.php line 40

Open in your IDE?
  1. <?php
  2. namespace App\Form\EventListener;
  3. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  4. use Symfony\Component\Form\FormEvent;
  5. use Symfony\Component\Form\FormEvents;
  6. use Symfony\Component\Form\FormInterface;
  7. use Symfony\Component\Validator\Constraints\NotBlank;
  8. use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
  9. use App\Entity\Country;
  10. use App\Entity\County;
  11. use GeoNames\Client as GeoNamesClient;
  12. use Symfony\Component\HttpKernel\KernelInterface;
  13. use App\Service\ConfigDataService;
  14. use GuzzleHttp\Exception\ClientException;
  15. class DynamicFieldsSubscriber implements EventSubscriberInterface 
  16. {
  17.     /** KernelInterface $appKernel */
  18.     private $appKernel;
  19.     private $configDataService;
  20.     public function __construct(KernelInterface $appKernelConfigDataService $configDataService)
  21.     {
  22.         $this->appKernel $appKernel;
  23.         $this->configDataService $configDataService;
  24.     }
  25.     public static function getSubscribedEvents(): array
  26.     {
  27.         return [
  28.             FormEvents::PRE_SET_DATA    => 'preSetData',
  29.             FormEvents::PRE_SUBMIT         => 'preSubmitData',
  30.         ];
  31.     }
  32.      /**
  33.      * Handling form fields before form renders.
  34.      * @param FormEvent $event
  35.      */
  36.     public function preSetData(FormEvent $event)
  37.     {
  38.         $data $event->getData();
  39.         $form $event->getForm();
  40.         //dd($data);
  41.         $country null;
  42.         if($data != null) {
  43.             $country $data->getCountry();
  44.             //dd($data->getCountry());
  45.         }
  46.         $this->addCountyData($form$country); 
  47.     }
  48.      /**
  49.      * Handling form fields before form renders.
  50.      * @param FormEvent $event
  51.      */
  52.     public function preSubmitData(FormEvent $event)
  53.     {
  54.         $location['country'] = $event->getData();
  55.         //dd($event->getData());
  56.         if(!empty($location['country'] && array_key_exists('country'$location['country']))) { 
  57.             //dd($location);
  58.             $countryObj = new Country();
  59.             $countryObj->setName($location['country']['country']);
  60.             //dd($country);
  61.             $this->addCountyData($event->getForm(), $countryObj);
  62.         }  else if (!empty($location['country']['county']))  {
  63.             $country null;
  64.             $countyGeoId $location['country']['county'];
  65.             //dd($countyGeoId);
  66.             $this->addCityData($event->getForm(), $countyGeoId);
  67.         }           
  68.     }
  69.     /**
  70.      * Method to Add State Field. (first dynamic field.)
  71.      * @param FormInterface $form
  72.      * @param type $county
  73.      */
  74.     private function addCountyData(FormInterface $formCountry $country null) {
  75.         $countiesArray = [];
  76.         if($country != null && $country->getName() != 'RO') {
  77.             $geoNameUser $this->configDataService->get('geonames');
  78.             $geoNamesClient = new GeoNamesClient($geoNameUser);
  79.             try {
  80.                 [$countryGeoNames] = $geoNamesClient->countryInfo([
  81.                     'country' => $country->getName(),
  82.                 ]);
  83.                 if($countryGeoNames) {
  84.                     $countryName $countryGeoNames->geonameId;
  85.                     $countiesJson $geoNamesClient->children(['geonameId' => $countryName]);
  86.                     foreach($countiesJson as $countyJson) {
  87.                         $countiesArray[$countyJson->toponymName] = $countyJson->geonameId;
  88.                     }
  89.                 }   
  90.             }
  91.             catch (ClientException $e) {
  92.                 if($e->getCode() == '401') {
  93.                     //dd($e->getMessage());
  94.                 };
  95.                         // Throw a custom exception here and handle this in your controller,
  96.                         // to show an error message to the user
  97.                // throw new Exception(sprintf('Cannot change the state of the event, because %s', $e->getMessage()), 0, $e);
  98.         }
  99.                                         
  100.         } else if($country != null && $country->getName() == 'RO') {
  101.             $regions json_decode(file_get_contents($this->appKernel->getProjectDir() . '/assets/json/ro_regions.json'));
  102.             foreach ($regions as $key=>$regionName) {
  103.                 $keyLower mb_strtolower($key'UTF-8');
  104.                 $keyLowerUpper ucfirst($keyLower);
  105.                 $countiesArray[$keyLowerUpper] = $keyLowerUpper;
  106.             }
  107.         }
  108.         $counties null === $countiesArray ? [] : $countiesArray;        
  109.         $form->add('county'ChoiceType::class, [
  110.             'placeholder' => 'Choose an option'
  111.             'mapped'  => false,
  112.             'label' => false,
  113.             //'required' => false,
  114.             'attr' => [
  115.                 'class' => 'form-control mb-3'
  116.             ],
  117.             'choices' => $counties,
  118.             // 'constraints' => [
  119.             //     new NotBlank([
  120.             //         'message' => 'not null',
  121.             //     ]),
  122.             // ],
  123.            // 'data'  => 'Tirana',
  124.                      
  125.         ]);
  126.     }
  127.       /**
  128.      * Method to Add State Field. (first dynamic field.)
  129.      * @param FormInterface $form
  130.      * @param type $city
  131.      */
  132.     private function addCityData(FormInterface $form$county null) {
  133.         $citiesArray = [];
  134.         $county_number preg_match('/\d/'$county);
  135.         if($county != null && $county_number == ) {
  136.             $geoNameUser $this->configDataService->get('geonames');
  137.             $geoNamesClient = new GeoNamesClient($geoNameUser);
  138.             
  139.             $citiesJson $geoNamesClient->children(['geonameId' => $county]);
  140.             
  141.             foreach($citiesJson as $cityJson) {
  142.                 $citiesArray[$cityJson->toponymName] = $cityJson->toponymName;
  143.             }
  144.         } else if($county != null && $county_number == 0) {
  145.             $regions json_decode(file_get_contents($this->appKernel->getProjectDir() . '/assets/json/ro_regions.json'));
  146.             $citiesArray = [];
  147.             foreach ($regions as $key=>$cities2) {
  148.                 $countyUp mb_strtoupper($county'UTF-8');
  149.                 if($key == $countyUp) {
  150.                     foreach($cities2 as $city) {
  151.                         $cityLower strtolower($city->name);
  152.                         $cityFirst ucwords($cityLower);
  153.                         //dd($cityFirst);
  154.                         $citiesArray[$cityFirst] = $cityFirst;
  155.                     }
  156.                 }
  157.             }
  158.         }
  159.         $cities null === $citiesArray ? [] : $citiesArray;
  160.         $form->add('city'ChoiceType::class, [
  161.             'placeholder' => 'Choose an option'
  162.             'mapped'  => false,
  163.             'attr' => [
  164.                 'class' => 'form-control'
  165.             ],
  166.             'choices' => $cities,
  167.             'constraints' => [
  168.                 new NotBlank([
  169.                     'message' => 'not null',
  170.                 ]),
  171.             ],
  172.         ]);
  173.     }
  174. }