Skip to content

Instantly share code, notes, and snippets.

@pakaufmann
Created July 19, 2012 13:00
Show Gist options
  • Save pakaufmann/3143729 to your computer and use it in GitHub Desktop.
Save pakaufmann/3143729 to your computer and use it in GitHub Desktop.
Translatable Field type for Admingeneratorgenerator
params:
model: Admingenerator\PropelDemoBundle\Model\Movie
namespace_prefix: Admingenerator
bundle_name: PropelDemoBundle
fields:
movieI18ns:
label: Translations
dbType: collection
formType: translatable_collection
addFormOptions:
i18n_class: \Admingenerator\PropelDemoBundle\Model\MovieI18n
columns:
title:
label: Custom title label
subtitle:
type: textarea
...
builders:
edit:
params:
title: Edit "{{ Movie.title }}"
messages:
success: "Film edited"
error: "An error occurred"
display:
"NONE": [ movieI18ns, release_date ]
parameters:
languages: [de, fr, en]
<?xml version="1.0" encoding="UTF-8"?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<service id="form.type.translatable_collection" class="Admingenerator\PropelDemoBundle\Form\Type\TranslationCollectionType">
<tag name="form.type" alias="translatable_collection" />
<call method="setContainer">
<argument type="service" id="service_container" />
</call>
</service>
<service id="form.type.translation_type" class="Admingenerator\PropelDemoBundle\Form\Type\TranslationType">
<tag name="form.type" alias="translation_type" />
</service>
</services>
</container>
<?php
namespace Admingenerator\PropelDemoBundle\Form\Type;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\Form\Event\DataEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
/**
* Created by JetBrains PhpStorm.
* User: patrickkaufmann
* Date: 7/12/12
* Time: 11:51 AM
* To change this template use File | Settings | File Templates.
*/
class TranslationCollectionType extends CollectionType implements ContainerAwareInterface
{
/**
* @var ContainerInterface
*/
private $container;
public function buildForm(FormBuilderInterface $builder, array $options)
{
$languages = $options['languages'];
$i18nClass = $options['i18n_class'];
$options['options']['data_class'] = $i18nClass;
$options['options']['columns'] = $options['columns'];
$builder->addEventListener(FormEvents::PRE_SET_DATA, function(DataEvent $event) use ($builder, $languages, $i18nClass) {
$form = $event->getForm();
$data = $event->getData();
if($data == null)
{
return;
}
//get the class name of the i18nClass
$temp = explode('\\', $i18nClass);
$dataClass = end($temp);
$rootData = $form->getRoot()->getData();
//add a database row for every needed language
foreach($languages as $lang)
{
$found = false;
foreach($data as $i18n)
{
if($i18n->getLocale() == $lang)
{
$found = true;
break;
}
}
if(!$found)
{
$newTranslation = new $i18nClass();
$newTranslation->setLocale($lang);
$addFunction = 'add'.$dataClass;
$rootData->$addFunction($newTranslation);
}
}
});
parent::buildForm($builder, $options);
}
public function getName()
{
return 'translatable_collection';
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
parent::setDefaultOptions($resolver);
$resolver->setDefaults(array(
'languages' => array(),
'i18n_class' => '',
'attr' => array('class' => 'type_collection'),
'columns' => array(),
'type' => 'translation_type',
'allow_add' => false,
'allow_delete' => false,
'languages' => $this->container->getParameter('languages')
));
}
/**
* Sets the Container.
*
* @param ContainerInterface $container A ContainerInterface instance
*
* @api
*/
public function setContainer(ContainerInterface $container = null)
{
$this->container = $container;
}
}
<?php
namespace Admingenerator\PropelDemoBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Event\DataEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormBuilderInterface;
/**
* Created by JetBrains PhpStorm.
* User: patrickkaufmann
* Date: 7/12/12
* Time: 8:31 AM
* To change this template use File | Settings | File Templates.
*/
class TranslationType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$columns = $options['columns'];
$dataClass = $options['data_class'];
$builder->addEventListener(FormEvents::PRE_SET_DATA, function(DataEvent $event) use ($builder, $columns, $dataClass) {
$form = $event->getForm();
$data = $event->getData();
if(!$data instanceof $dataClass)
{
return;
}
//loop over all columns and add the input
foreach($columns as $column => $options)
{
if($options == null) $options = array();
$type = 'text';
if(array_key_exists('type', $options))
{
$type = $options['type'];
}
$label = $column;
if(array_key_exists('label', $options))
{
$label = $options['label'];
}
$customOptions = array();
if(array_key_exists('options', $options))
{
$customOptions = $options['options'];
}
$options = array(
'label' => $label.' '.strtoupper($data->getLocale())
);
$options = array_merge($options, $customOptions);
$form->add($builder->getFormFactory()->createNamed($column, $type, null, $options));
}
});
}
public function getName()
{
return 'translation_type';
}
public function getDefaultOptions()
{
return array(
'columns' => array(),
'language' => ''
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment