Search code examples
phpsymfonyinternationalizationlocaleintl

Manipulate the list of countries provided by Symfony Intl and the form choice type


Politics aside, I need to provide Kosovo as a form choice when selecting a country.

What's the most elegant way of doing this with Symfony's built-in form choice type country, while also providing translations for the Kosovo name?

Here's what I've done so far and it works but I'm concerned this might be a bit hack-ish.

<?php

namespace Acme\Bundle\DemoBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\Intl\Intl;

class LocationType extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        // Kosovo is not listed as a choice provided by the method call
        // `Symfony\Component\Intl\Intl::getRegionBundle()->getCountryNames()`
        // although it is mostly recognized as in independent state, including by Google Maps.
        // This is because no ISO 3166-1 alpha-2 code as been assigned to that country.
        // However, a temporary code 'XK' is available.

        $countries = Intl::getRegionBundle()->getCountryNames();
        $countries['XK'] = "Kosovo";

        $builder
            ->add('country', 'country', array(
                'choices' => $countries,
                'preferred_choices' => array(
                    'XK', // Kosovo
                    'AL', // Albania
                    'MK', // Macedonia
                    'ME', // Montenegro
                    'GB', // United Kingdom
                    'US', // United States
                ),
            ))
            ->add('district', 'text', array('required' => false))
            ->add('town', 'text', array('required' => false))
        ;
    }
}

Solution

  • You should create your service, in wich you use Intl's static method (like above) and add your custom countries. Then, inject that service into your form type. Or (even better), define your custom type (something like "MyCountry") and use it instead of standard country one.