-
-
Notifications
You must be signed in to change notification settings - Fork 9.7k
Closed
Labels
Description
Hello,
I'm using a a2lix/TranslationsForm, with this entities:
namespace Catalogue\OptionBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Gedmo\Mapping\Annotation as Gedmo;
use Doctrine\ORM\Mapping as ORM;
use Catalogue\OptionBundle\Entity\OptionValue;
/**
* @ORM\Table(name="option_", options={"comment":"Criado por Paulo Dias"})
* @ORM\Entity(repositoryClass="Catalogue\OptionBundle\Repository\OptionRepository")
*/
class Option
{
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue
*/
private $id;
/**
* @Gedmo\Translatable
* @ORM\Column(length=200)
*/
private $name;
/**
* @Gedmo\Translatable
* @ORM\Column(type="text", nullable=false)
*/
private $presentation;
/**
* @ORM\OneToMany(targetEntity="Catalogue\OptionBundle\Entity\OptionValue", mappedBy="option", cascade={"all"})
*/
private $optionvalues;
/**
* @Gedmo\Timestampable(on="create")
* @ORM\Column(type="datetime")
*/
private $created;
/**
* @Gedmo\Timestampable(on="update")
* @ORM\Column(type="datetime")
*/
private $updated;
/**
* @ORM\OneToMany(
* targetEntity="OptionTranslation",
* mappedBy="object",
* indexBy="locale",
* cascade={"all"}
* )
*/
private $translations;
public function __construct()
{
$this->translations = new ArrayCollection();
$this->optionvalues = new ArrayCollection();
$this->created = new \DateTime();
}
/**
* Get id
*
* @return Integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* @param String $name
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* @return String
*/
public function getName()
{
return $this->name;
}
/**
* Set presentation
*
* @param String $presentation
*/
public function setPresentation($presentation)
{
$this->presentation = $presentation;
return $this;
}
/**
* Get presentation
*
* @return String
*/
public function getPresentation()
{
return $this->presentation;
}
/**
* Set values
*
* @param Doctrine\Common\Collections\Collection $values
*/
/*public function setValues(Collection $values)
{
$this->values = $values;
return $this;
}*/
/**
* Get options values
*
* @return Doctrine\Common\Collections\Collection
*/
public function getOptionValues()
{
return $this->optionvalues;
}
/**
* Add option value
*
* @param Catalogue\OptionBundle\Entity\OptionValue $optionvalue
*/
public function addOptionValue(OptionValue $optionvalue)
{
if(!$this->hasValue($optionvalue)) {
$optionvalue->setOption($this);
$this->optionvalues->add($optionvalue);
}
return $this;
}
/**
* Remove option value
*
* @param Catalogue\OptionBundle\Entity\OptionValue $optionvalue
*/
public function removeOptionValue(OptionValue $optionvalue)
{
if ($this->optionvalues->contains($optionvalue)) {
$this->optionvalues->removeElement($optionvalue);
}
}
/**
* Option have value
*/
public function hasValue(OptionValue $optionvalue)
{
return $this->optionvalues->contains($optionvalue);
}
/**
* Get created
*
* @return DateTime
*/
public function getCreated()
{
return $this->created;
}
/**
* Get updated
*
* @return DateTime
*/
public function getUpdated()
{
return $this->updated;
}
/**
* Get translations
*
* @return Doctrine\Common\Collections\Collection
*/
public function getTranslations()
{
return $this->translations;
}
/**
* Add translation
*
* @param Catalogue\OptionBundle\Entity\OptionTranslation $t
*/
public function addTranslation(OptionTranslation $t)
{
if (!$this->translations->contains($t)) {
$t->setObject($this);
$this->translations->set($t->getLocale(), $t);
}
}
/**
* Remove translation
*
* @param Catalogue\OptionBundle\Entity\OptionTranslation $t
*/
public function removeTranslation(OptionTranslation $t)
{
if ($this->translations->contains($t)) {
$this->translations->removeElement($t);
}
}
public function __toString()
{
return $this->getPresentation();
}
}
namespace Catalogue\OptionBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Translatable\Entity\MappedSuperclass\AbstractTranslation;
use Gedmo\Mapping\Annotation as Gedmo;
use Symfony\Component\Validator\Constraints as Assert;
/**
* @ORM\Entity
* @ORM\Table(uniqueConstraints={
* @ORM\UniqueConstraint(name="option_translation_unique_idx", columns={"locale", "object_id"})
* }, options={"comment":"Criado por Paulo Dias"})
*/
class OptionTranslation extends AbstractTranslation
{
/**
* @ORM\ManyToOne(targetEntity="Option", inversedBy="translations")
* @ORM\JoinColumn(name="object_id", referencedColumnName="id", onDelete="CASCADE", nullable=false)
*/
protected $object;
/**
* @ORM\Column(length=200)
* @Assert\NotBlank(message = "option.name.not_blank")
*/
private $name;
/**
* @ORM\Column(type="text", nullable=false)
* @Assert\NotBlank(message = "option.presentation.not_blank")
*/
private $presentation;
/**
* Convinient constructor
*
* @param string $locale
* @param string $name
* @param string $presentation
*/
public function __construct($locale = null, $name = null, $presentation = null)
{
$this->locale = $locale;
$this->name = $name;
$this->presentation = $presentation;
}
public function setName($name)
{
$this->name = $name;
return $this;
}
public function getName()
{
return $this->name;
}
public function setPresentation($presentation)
{
$this->presentation = $presentation;
return $this;
}
public function getPresentation()
{
return $this->presentation;
}
}
namespace Catalogue\OptionBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Gedmo\Mapping\Annotation as Gedmo;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Catalogue\OptionBundle\Entity\Option;
use Catalogue\OptionBundle\Entity\OptionValueTranslation;
/**
* @ORM\Table(name="optionvalue", options={"comment":"Criado por Paulo Dias"})
* @ORM\Entity(repositoryClass="Catalogue\OptionBundle\Repository\OptionRepository")
*/
class OptionValue
{
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue
*/
private $id;
/**
* @Assert\NotNull(message = "optionvalue.option.not_null")
* @ORM\ManyToOne(targetEntity="Catalogue\OptionBundle\Entity\Option", inversedBy="optionvalues")
* @ORM\JoinColumn(name="option", referencedColumnName="id")
*/
private $option;
/**
* @Gedmo\Translatable
* @ORM\Column(type="text", nullable=false)
*/
private $value;
/**
* @ORM\OneToMany(
* targetEntity="OptionValueTranslation",
* mappedBy="object",
* indexBy="locale",
* cascade={"all"}
* )
*/
private $translations;
public function __construct()
{
$this->translations = new ArrayCollection();
}
public function getId()
{
return $this->id;
}
/**
* Set option
*
* @param Catalogue\OptionBundle\Entity\Option $option
*/
public function setOption(Option $option = null)
{
$this->option = $option;
return $this;
}
/**
* Get option
*
* @return Catalogue\OptionBundle\Entity\Option
*/
public function getOption()
{
return $this->option;
}
/**
* Set value
*
* @param String $value
*/
public function setValue($value)
{
$this->value = $value;
return $this;
}
/**
* Get value
*
* @return string
*/
public function getValue()
{
return $this->value;
}
/**
* Get option name
*
* @return string
*/
public function getName()
{
if (null === $this->option) {
throw new \BadMethodCallException('The option have not been created yet so you cannot access proxy methods.');
}
return $this->option->getName();
}
/**
* Get voption presentation
*
* @return string
*/
public function getPresentation()
{
if (null === $this->option) {
throw new \BadMethodCallException('The option have not been created yet so you cannot access proxy methods.');
}
return $this->option->getPresentation();
}
/**
* Get translations
*
* @return Doctrine\Common\Collections\Collection
*/
public function getTranslations()
{
return $this->translations;
}
/**
* Add translation
*
* @param Catalogue\OptionBundle\Entity\OptionValueTranslation $t
*/
public function addTranslations(OptionValueTranslation $t)
{
if (!$this->translations->contains($t)) {
$t->setObject($this);
$this->translations->set($t->getLocale(), $t);
}
}
/**
* Remove translation
*
* @param Catalogue\OptionBundle\Entity\OptionValueTranslation $t
*/
public function removeTranslations(OptionValueTranslation $t)
{
if ($this->translations->contains($t)) {
$this->translations->removeElement($t);
}
}
}
namespace Catalogue\OptionBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Translatable\Entity\MappedSuperclass\AbstractTranslation;
use Gedmo\Mapping\Annotation as Gedmo;
use Symfony\Component\Validator\Constraints as Assert;
/**
* @ORM\Entity
* @ORM\Table(uniqueConstraints={
* @ORM\UniqueConstraint(name="optionvalue_translation_unique_idx", columns={"locale", "object_id"})
* }, options={"comment":"Criado por Paulo Dias"})
*/
class OptionValueTranslation extends AbstractTranslation
{
/**
* @ORM\ManyToOne(targetEntity="OptionValue", inversedBy="translations")
* @ORM\JoinColumn(name="object_id", referencedColumnName="id", onDelete="CASCADE", nullable=false)
*/
protected $object;
/**
* @Assert\NotBlank(message = "optionvalue.value.not_blank")
* @ORM\Column(type="text", nullable=false)
*/
private $value;
/**
* Convinient constructor
*
* @param string $locale
* @param string $value
*/
public function __construct($locale = null, $value = null)
{
$this->locale = $locale;
$this->value = $value;
}
public function setValue($value)
{
$this->value = $value;
return $this;
}
public function getValue()
{
return $this->value;
}
}
And I use this Form Types:
namespace Catalogue\OptionBundle\Form\Type;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
class OptionValueType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add(
'translations',
'a2lix_translations',
array(
'attr'=>array('class'=>'form-control'),
'label_attr'=>array('class' =>'sr-only'),
'fields'=>array(
'value'=>array(
'field_type'=>'text',
'attr'=>array('class'=>'form-control'),
),
),
)
);
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver
->setDefaults(array(
'data_class'=>'Catalogue\OptionBundle\Entity\OptionValue',
));
}
public function getName()
{
return 'optionvalue';
}
}
namespace Catalogue\OptionBundle\Form\Type;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormEvent;
class OptionType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add(
'translations',
'a2lix_translations',
array(
'attr'=>array('class'=>'form-control'),
'label_attr'=>array('class' =>'sr-only'),
'fields'=>array(
'name'=>array(
'field_type'=>'text',
'attr'=>array('class'=>'form-control'),
),
'presentation'=>array(
'field_type'=>'text',
'attr'=>array('class'=>'form-control'),
),
),
)
);
$builder->add('optionvalues', 'collection', array(
'type'=> new OptionValueType(),
'by_reference'=>false,
'allow_add'=>true,
'allow_delete'=>true,
));
$builder->add('save', 'submit', array('label'=>'Save', 'attr'=>array('class'=>'btn btn-cms btn-sm')));
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver
->setDefaults(array(
'data_class'=>'Catalogue\OptionBundle\Entity\Option',
'cascade_validation'=>true, //Necessário
));
}
public function getName()
{
return 'option';
}
}
In the code of OptionType I have a collection of OptionValuesType.
If I not add any element (OptionValue) to collection and submit the form, everything is fine.
But if I add an element to the collection, gives me an error, which I think it is not in the bundleI a2lix.
An example of data submitted:
Form->submit(array(
'translations' => array(
'en' => array(
'name' => 'My Option',
'presentation' => 'Option'
),
'pt' => array(
'name' => '',
'presentation' => ''
)
),
'optionvalues' => array(
array(
'translations' => array(
'en' => array(
'value' => 'Red'
),
'pt' => array(
'value' => 'Vermelho'
)
)
)
),
'save' => '',
'_token' => 'eCMv2xRfeJcd0pJj-J5I9zgSMV999_lxniJ2kgtGxQA'
), true)
And I have this error:
in C:\EasyPHP\www\sym\src\Catalogue\OptionBundle\Entity\Option.php line 213
at ErrorHandler->handle('4096', 'Argument 1 passed to Catalogue\OptionBundle\Entity\Option::addTranslation() must be an instance of Catalogue\OptionBundle\Entity\OptionTranslation, instance of Catalogue\OptionBundle\Entity\OptionValueTranslation given', 'C:\EasyPHP\www\sym\src\Catalogue\OptionBundle\Entity\Option.php', '213', array('this' => object(Option))) in C:\EasyPHP\www\sym\src\Catalogue\OptionBundle\Entity\Option.php line 213
at Option->addTranslation(object(OptionValueTranslation))
at call_user_func(array(object(Option), 'addTranslation'), object(OptionValueTranslation)) in C:\EasyPHP\www\sym\vendor\symfony\symfony\src\Symfony\Component\PropertyAccess\PropertyAccessor.php line 363
at PropertyAccessor->writeProperty(object(Option), 'translations', null, object(ArrayCollection)) in C:\EasyPHP\www\sym\vendor\symfony\symfony\src\Symfony\Component\PropertyAccess\PropertyAccessor.php line 102
at PropertyAccessor->setValue(object(Option), object(PropertyPath), object(ArrayCollection)) in C:\EasyPHP\www\sym\vendor\symfony\symfony\src\Symfony\Component\Form\Extension\Core\DataMapper\PropertyPathMapper.php line 87
at PropertyPathMapper->mapFormsToData(object(RecursiveIteratorIterator), object(Option)) in C:\EasyPHP\www\sym\vendor\symfony\symfony\src\Symfony\Component\Form\Form.php line 616
at Form->submit(array('translations' => array('en' => array('name' => 'My Option', 'presentation' => 'Option'), 'pt' => array('name' => '', 'presentation' => '')), 'optionvalues' => array(array('translations' => array('en' => array('value' => 'Red'), 'pt' => array('value' => 'Vermelho')))), 'save' => '', '_token' => 'eCMv2xRfeJcd0pJj-J5I9zgSMV999_lxniJ2kgtGxQA'), true) in C:\EasyPHP\www\sym\vendor\symfony\symfony\src\Symfony\Component\Form\Extension\HttpFoundation\HttpFoundationRequestHandler.php line 80
at HttpFoundationRequestHandler->handleRequest(object(Form), object(Request)) in C:\EasyPHP\www\sym\vendor\symfony\symfony\src\Symfony\Component\Form\Form.php line 488
at Form->handleRequest(object(Request)) in C:\EasyPHP\www\sym\src\Catalogue\OptionBundle\Controller\OptionController.php line 59
at OptionController->addAction('1', object(Request))
at call_user_func_array(array(object(OptionController), 'addAction'), array('1', object(Request))) in C:\EasyPHP\www\sym\app\bootstrap.php.cache line 2911
at HttpKernel->handleRaw(object(Request), '1') in C:\EasyPHP\www\sym\app\bootstrap.php.cache line 2883
at HttpKernel->handle(object(Request), '1', true) in C:\EasyPHP\www\sym\app\bootstrap.php.cache line 3022
at ContainerAwareHttpKernel->handle(object(Request), '1', true) in C:\EasyPHP\www\sym\app\bootstrap.php.cache line 2303
at Kernel->handle(object(Request)) in C:\EasyPHP\www\sym\public_html\app_dev.php line 28
I do not know why, but this PropertyAccessor.php call my object Option with the parameter OptionValueTranslation, should call with OptionTranslation.
call_user_func(array(object(Option), 'addTranslation'), object(OptionValueTranslation)) in C:\EasyPHP\www\sym\vendor\symfony\symfony\src\Symfony\Component\PropertyAccess\PropertyAccessor.php line 363
I use Symfony2 2.4.1.
Thanks.