Translate Symfony TimezoneType Field Type

The TimezoneType Field Type

Symfony has an specific Field Type to create a Timezone select widget in forms called TimezoneType. Very handy because it’s a pretty usual need in web applications.


It uses \DateTimeZone::listIdentifiers() to create the texts and as you can see those texts are in english:

    public static function getTimezones()
        if (null === static::$timezones) {
            static::$timezones = array();

            foreach (\DateTimeZone::listIdentifiers() as $timezone) {
                $parts = explode('/', $timezone);

                if (count($parts) > 2) {
                    $region = $parts[0];
                    $name = $parts[1].' - '.$parts[2];
                } elseif (count($parts) > 1) {
                    $region = $parts[0];
                    $name = $parts[1];
                } else {
                    $region = 'Other';
                    $name = $parts[0];

                static::$timezones[$region][$timezone] = str_replace('_', ' ', $name);

        return static::$timezones;

¿But what if you want to translate all those texts to your language?

Note: I’m going to assume that you are storing the users timezone in the database as it’s defined in PHP. For example “Europe/Madrid” for Spain (without the Canary Islands) or “America/North_Dakota/New_Salem” for the Morton County in USA. This is the timezone we are going to use as an example.

As you can see the timezones are divided in different parts using the “/” character. The first one designates an area (more or less a continent but not exactly) and then a city. In some cases it has 3 parts for a more specific area. We also have some special ones like UTC for the Universal Time Clock.

We are going to start by creating our form with the TimezoneType for the user profile edit page:


namespace AppBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Security\Core\Validator\Constraints\UserPassword;

class ProfileFormType extends AbstractType
    private $class;

    public function __construct($class)
        $this->class = $class;

    public function buildForm(FormBuilderInterface $builder, array $options)
        $constraint = new UserPassword();

        $this->buildUserForm($builder, $options);

            ->add('timezone', 'timezone', array(
                'label' => 'form.timezone',
                'translation_domain' => 'AppBundle',
                'choice_translation_domain' => true,
            ->add('current_password', 'password', array(
                'label' => 'form.current_password',
                'translation_domain' => 'FOSUserBundle',
                'mapped' => false,
                'constraints' => $constraint,

    public function configureOptions(OptionsResolver $resolver)
            'data_class' => $this->class,
            'intention'  => 'profile',

    public function getName()
        return 'app_user_profile_form_type';

    protected function buildUserForm(FormBuilderInterface $builder, array $options)
            ->add('email', 'email', array(
                'label' => '',
                'translation_domain' => 'FOSUserBundle',

It’s VERY important to use the translation_domain and choice_translation_domain options as seen above or this won’t work.

Then we have to create the translation files. Assuming you are following the Symfony Best Practices you have one bundle called AppBundle and its translation files, in YAML format, are in app/Resources/translations. The file name uses the locale code to designate the language, for example for spanish it would be You can download a list of all the texts for english in this AppBundle.en.yml file so you can use it as a template for your language. This are some of those texts translated to spanish with our example in bold:

## app/Resources/translations/
# Timezone areas
Africa: "África"
America: "América"
Antarctica: "Antártida"
Arctic: "Ártico"
Asia: "Asia"
Atlantic: "Atlántico"
Australia: "Australia"
Europe: "Europa"
Indian: "India"
Pacific: "Pacífico"
# Specific timezones
Abidjan: "Abidjan"
Accra: "Accra"
Addis Ababa: "Addis Ababa"
Algiers: "Algiers"
# ... more and more timezones here ...
North Dakota - New Salem: "Dakota del Norte - New Salem"
# ... more and more timezones here ...

All we have to do now to see our TimezoneType Field Type translated to spanish is clear the cache ($ php app/console cache:clear --env=dev) and open our form page using the spanish locale. To force our application the spanish locale, if you aren’t already using multilanguage in your app, you can edit app/config/config.yml:

    translator:      { fallbacks: ["es"] }
    default_locale:  "es"

This is how my translated widget looks like:


But we also want to translate the timezone stored in the database when showing it in the users profile page. Remember that we store the users timezone in its original PHP timezone string: “America/North_Dakota/New_Salem“. If we want to reuse all the translations we did before we can use this approach in Twig:

{{ (user.timezone|split("/")|first)|trans({}, 'AppBundle') }}

{{ (user.timezone|split("/", 2)|last|replace({'_': ' '})|replace({'/': ' - '}))|trans({}, 'AppBundle') }}

The first line will translate the timezone area (Africa, America, etc.) by spliting the timezone using the “/” character and then getting the first element. Becareful and remember using the opening and closing parenthesis before “|trans()” or this won’t work.

The second line is a little bit tricky. It splits the timezone string using the “/” character but limits the amount of parts to 2 and then gets the last item so we can discard the timezone area. If we take as an example “America/North_Dakota/New_Salem” we’ll have “North_Dakota/New_Salem” in this first step. Now we replace “_” with spaces and “/” with “ - “. This will convert “North_Dakota/New_Salem” to “North Dakota - New Salem” and if you look up there in the translation written in bold that’s exactly the key for the translation.


¡HEY! ¡Don’t forget to clear your cache everytime you change or add a translation! They are not created on every request.

$ php app/console cache:clear --env=dev

Fix “This field was locked by vendor” in Plesk Updates source and installation settings

I was trying to install some new components to one on my Plesk managed servers but I got this error when going to “Server > Tools & Settings > Plesk > Updates and Upgrades”:

Failed to read product information from the file : Can't process products.inf3: Failed to download the package The requested URL returned error: 404 Can't process versions.inf3: Failed to download the package The requested URL returned error: 404

I asked OVH technical service and they told me more or less this: “Yep, that URL is no longer available but we only provide it on first automated install. Fix it yourself.”. I have to say that this happened with the customer service from Spain, something that of course didn’t surprise me. We are used to this kind of “help” from customer services here.

So I tried to change the product information source to the official Plesk one but I noticed that the field was disabled, as it said “This field was locked by vendor.”.


I started to search for the original URL in /root/parallels in order to edit it with no luck. When I did a search for this problem on the Internet I got to the most surreal fix I’ve ever come around: Open the browsers devtools and remove the “disabled” option to the “URL to the directory with .inf3 file” input field, change the URL to the correct one ( and click “Save”. It worked!




Hide Mac OS X Recovery partition

Sometimes the Mac OS X Recovery partition can be seen because it’s mounted automatically on boot. This is usually caused because you moved the operating system to another disk (clone) or because you used an app that changed the disks partitions (rEFInd in my case).

Recovery HD

To fix this you can run this script:


PARTITION=`mount | grep "Recovery HD" | awk '{print $1}'`
if [ -n "$PARTITION" ]; then
    sudo diskutil unmount $PARTITION
    sudo asr adjust --target $PARTITION -settype Apple_Boot

Then SHUTDOWN (don’t just reboot) and turn on the computer.

You can also unmount that partition from the Disk Utility if you enable the debug option from the command line, but this will only work one time as it will be mounted again on next boot:

$ defaults write DUDebugMenuEnabled 1



Remove old Linux kernels in Ubuntu

As time goes new kernel versions are released. After a kernel update old installed versions are not removed automatically, they are keep in case something goes wrong so you can boot again to a previous version.


But you may end up having lots of old versions you’ll never use. To remove them first you need to find all the installed versions:

$ dpkg -l | grep linux-image | grep -v extra | awk '{print $2}'

Then remove all the unwanted versions using apt-get autoremove:

$ sudo apt-get autoremove linux-image-3.16.0-30-generic linux-image-3.16.0-31-generic linux-image-3.16.0-34-generic

You should probably leave at least the latests 2 versions just in case.


Deactivate VCS (Version Control System) in PHPStorm

You can enable VCS (Version Control System) in PHPStorm from the VCS menu but, how do you deactivate it?


I didn’t found an option for that anywhere so this is the solution: Remove the .idea/vcs.xml file and restart PHPStorm.

Ref: How to disable version control in phpstorm?