Symfony 2.5 - Data transformer and View transformer

12,390

You must build transformed field via FormBuilderInterface::create():

$builder
    // ...
    ->add(
        $builder->create('paciente','text')
            ->addModelTransformer($transformer)
    );

See How to Use Data Transformers, the manual is pretty clear at this point.

Share:
12,390
Carlos Delgado
Author by

Carlos Delgado

Enthusiast software developer. Founder of Our Code World and maintainer of the JS Library Artyom.js I have knowledge in the following technologies too: Symfony [1.4, 2, 3, 4] PHP 5 & 7 OOP MySql Doctrine 1 & 2 SVN, Git HTML5, CSS3 (Bootstrap) Twig Javascript (jQuery, ReactJS) TypeScript Cordova Mobile Apps Framework C# .NET Framework If you want to contact me, use the contact form of Our Code World.

Updated on June 04, 2022

Comments

  • Carlos Delgado
    Carlos Delgado almost 2 years

    I'm working on a symfony 2.5 project, I used reverse engineering (doctrine:mapping:import) and I need a data transformer on a form that saves the patient in order of make an appointment in the database but I need the user to write his identification number (the field name is numeroRegistro). I read about it and implemented it, and I'm having problems at the moment of creation.

    this is my Type :

    <?php
    
    namespace frontend\citasBundle\Form;
    
    use Symfony\Component\Form\AbstractType;
    use Symfony\Component\Form\FormBuilderInterface;
    use Symfony\Component\OptionsResolver\OptionsResolverInterface;
    use frontend\citasBundle\Form\DataTransformer\IssueToNumberTransformer;
    
    class CitasType extends AbstractType
    {
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $entityManager = $options['em'];
        $transformer = new IssueToNumberTransformer($entityManager);
    
    
        $builder
            ->add('estado')
            ->add('tipo')
            ->add('encargado')
            ->add('eps')
            ->add('fechaInicio')
            ->add('fechaFin')
            ->add('comentario')
            ->add('fechaAsignacion')
            ->add('usuarioAsigna')
            ->add('paciente','text')->addModelTransformer($transformer)
            ->add('consultorios')
        ;
    }
    
    /**
     * @param OptionsResolverInterface $resolver
     */
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'frontend\citasBundle\Entity\Citas'
        ))
            ->setRequired(array(
            'em',
        ))
        ->setAllowedTypes(array(
            'em' => 'Doctrine\Common\Persistence\ObjectManager',
        ));
    
    }
    
    /**
     * @return string
     */
    public function getName()
    {
        return 'frontend_citasbundle_citas';
    }
    }
    

    This is the datatransformer :

    <?php
    
    // src/Acme/TaskBundle/Form/DataTransformer/IssueToNumberTransformer.php
    namespace frontend\citasBundle\Form\DataTransformer;
    use Symfony\Component\Form\DataTransformerInterface;
    use Symfony\Component\Form\Exception\TransformationFailedException;
    use Doctrine\Common\Persistence\ObjectManager;
    //use frontend\citasBundle\Entity\Issue;
    
    class IssueToNumberTransformer implements DataTransformerInterface
    {
    /**
     * @var ObjectManager
     */
    private $om;
    
    /**
     * @param ObjectManager $om
     */
    public function __construct(ObjectManager $om)
    {
        $this->om = $om;
    }
    
    /**
     * Transforms an object (issue) to a string (number).
     *
     * @param  Issue|null $issue
     * @return string
     */
    public function transform($issue)
    {
        if (null === $issue) {
            return "";
        }
    
        return $issue->getId();
    }
    
    /**
     * Transforms a string (number) to an object (issue).
     *
     * @param  string $number
     *
     * @return Issue|null
     *
     * @throws TransformationFailedException if object (issue) is not found.
     */
    public function reverseTransform($number)
    {
        if (!$number) {
            return null;
        }
    
        $issue = $this->om
            ->getRepository('frontendpacienteBundle:Paciente')
            ->findOneBy(array('numeroRegistro' => $number))
        ;
    
        if (null === $issue) {
            throw new TransformationFailedException(sprintf(
                'An issue with number "%s" does not exist!',
                $number
            ));
        }
    
        return $issue;
    }
    }
    

    And finally my entity :

    <?php
    
    namespace frontend\citasBundle\Entity;
    
    use Doctrine\ORM\Mapping as ORM;
    
    /**
      * Citas
     */
    class Citas
    {
    /**
     * @var integer
     */
    private $id;
    
    /**
     * @var boolean
     */
    private $estado;
    
    /**
     * @var string
     */
    private $tipo;
    
    /**
     * @var integer
     */
    private $encargado;
    
    /**
     * @var string
     */
    private $eps;
    
    /**
     * @var \DateTime
     */
    private $fechaInicio;
    
    /**
     * @var \DateTime
     */
    private $fechaFin;
    
    /**
     * @var string
     */
    private $comentario;
    
    /**
     * @var \DateTime
     */
    private $fechaAsignacion;
    
    /**
     * @var string
     */
    private $usuarioAsigna;
    
    /**
     * @var \frontend\citasBundle\Entity\Paciente
     */
    private $paciente;
    
    /**
     * @var \frontend\citasBundle\Entity\Consultorios
     */
    private $consultorios;
    
    
    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }
    
    /**
     * Set estado
     *
     * @param boolean $estado
     * @return Citas
     */
    public function setEstado($estado)
    {
        $this->estado = $estado;
    
        return $this;
    }
    
    /**
     * Get estado
     *
     * @return boolean 
     */
    public function getEstado()
    {
        return $this->estado;
    }
    
    /**
     * Set tipo
     *
     * @param string $tipo
     * @return Citas
     */
    public function setTipo($tipo)
    {
        $this->tipo = $tipo;
    
        return $this;
    }
    
    /**
     * Get tipo
     *
     * @return string 
     */
    public function getTipo()
    {
        return $this->tipo;
    }
    
    /**
     * Set encargado
     *
     * @param integer $encargado
     * @return Citas
     */
    public function setEncargado($encargado)
    {
        $this->encargado = $encargado;
    
        return $this;
    }
    
    /**
     * Get encargado
     *
     * @return integer 
     */
    public function getEncargado()
    {
        return $this->encargado;
    }
    
    /**
     * Set eps
     *
     * @param string $eps
     * @return Citas
     */
    public function setEps($eps)
    {
        $this->eps = $eps;
    
        return $this;
    }
    
    /**
     * Get eps
     *
     * @return string 
     */
    public function getEps()
    {
        return $this->eps;
    }
    
    /**
     * Set fechaInicio
     *
     * @param \DateTime $fechaInicio
     * @return Citas
     */
    public function setFechaInicio($fechaInicio)
    {
        $this->fechaInicio = $fechaInicio;
    
        return $this;
    }
    
    /**
     * Get fechaInicio
     *
     * @return \DateTime 
     */
    public function getFechaInicio()
    {
        return $this->fechaInicio;
    }
    
    /**
     * Set fechaFin
     *
     * @param \DateTime $fechaFin
     * @return Citas
     */
    public function setFechaFin($fechaFin)
    {
        $this->fechaFin = $fechaFin;
    
        return $this;
    }
    
    /**
     * Get fechaFin
     *
     * @return \DateTime 
     */
    public function getFechaFin()
    {
        return $this->fechaFin;
    }
    
    /**
     * Set comentario
     *
     * @param string $comentario
     * @return Citas
     */
    public function setComentario($comentario)
    {
        $this->comentario = $comentario;
    
        return $this;
    }
    
    /**
     * Get comentario
     *
     * @return string 
     */
    public function getComentario()
    {
        return $this->comentario;
    }
    
    /**
     * Set fechaAsignacion
     *
     * @param \DateTime $fechaAsignacion
     * @return Citas
     */
    public function setFechaAsignacion($fechaAsignacion)
    {
        $this->fechaAsignacion = $fechaAsignacion;
    
        return $this;
    }
    
    /**
     * Get fechaAsignacion
     *
     * @return \DateTime 
     */
    public function getFechaAsignacion()
    {
        return $this->fechaAsignacion;
    }
    
    /**
     * Set usuarioAsigna
     *
     * @param string $usuarioAsigna
     * @return Citas
     */
    public function setUsuarioAsigna($usuarioAsigna)
    {
        $this->usuarioAsigna = $usuarioAsigna;
    
        return $this;
    }
    
    /**
     * Get usuarioAsigna
     *
     * @return string 
     */
    public function getUsuarioAsigna()
    {
        return $this->usuarioAsigna;
    }
    
    /**
     * Set paciente
     *
     * @param \frontend\citasBundle\Entity\Paciente $paciente
     * @return Citas
     */
    public function setPaciente(\frontend\citasBundle\Entity\Paciente $paciente = null)
    {
        $this->paciente = $paciente;
    
        return $this;
    }
    
    /**
     * Get paciente
     *
     * @return \frontend\citasBundle\Entity\Paciente 
     */
    public function getPaciente()
    {
        return $this->paciente;
    }
    
    /**
     * Set consultorios
     *
     * @param \frontend\citasBundle\Entity\Consultorios $consultorios
     * @return Citas
     */
    public function setConsultorios(\frontend\citasBundle\Entity\Consultorios $consultorios = null)
    {
        $this->consultorios = $consultorios;
    
        return $this;
    }
    
    /**
     * Get consultorios
     *
     * @return \frontend\citasBundle\Entity\Consultorios 
     */
    public function getConsultorios()
    {
        return $this->consultorios;
    }
    }
    

    I thought with that was enough but when i submit i get this error :

    Catchable Fatal Error: Argument 1 passed to frontend\citasBundle\Entity\Citas::setPaciente() must           be an instance of frontend\citasBundle\Entity\Paciente, string given, called in C:\xampp\htdocs\genoma\vendor\symfony\symfony\src\Symfony\Component\PropertyAccess\PropertyAccessor.php on line 438 and defined in C:\xampp\htdocs\genoma\src\frontend\citasBundle\Entity\Citas.php line   296
    

    Am i improperly configuring the data transformer ? and if i try edit a register inserted via database i get this :

    The form's view data is expected to be an instance of class frontend\citasBundle\Entity\Citas, but is a(n) string. You can avoid this error by setting the "data_class" option to null or by adding a view transformer that transforms a(n) string to an instance of frontend\citasBundle\Entity\Citas.
    

    I used the datatransformer because i need to enter the identification number of the patient in the form in a text field -- and the same when edit the register.

    **I'm getting crazy with this thing. I appreciate your help since now. **

  • Carlos Delgado
    Carlos Delgado over 9 years
    i add this : $builder ->add( $builder->create('paciente','text') ->addModelTransformer($transformer) ); and comment : ->add('paciente','text')->addModelTransformer($transformer) but still the same error : Catchable Fatal Error: Argument 1 passed to frontend\citasBundle\Entity\Citas::setPaciente() must be an instance of frontend\citasBundle\Entity\Paciente, string given, called in htdocs\genoma\vendor\symfony\symfony\src\Symfony\Component\P‌​ropertyAccess\Proper‌​tyAccessor.php on line and defined in src\frontend\citasBundle\Entity\Citas.php
  • Carlos Delgado
    Carlos Delgado over 9 years
    Thanks for the support
  • Carlos Delgado
    Carlos Delgado over 9 years
    PLUS : I try to edit a register and doesn't throw the error mentioned in the question :) thanks , but still the problem in update and create.
  • ozahorulia
    ozahorulia over 9 years
    @CarlosDelgado Sorry, when exactly you're getting the error?
  • ozahorulia
    ozahorulia over 9 years
    Okay, seems strange then. Try to make some breakpoints inside both transform() and setPaciente() methods. See, what exactly do they return or accept as an argument.
  • Carlos Delgado
    Carlos Delgado over 9 years
    Hast, thanks ! symfony was giving me the answer :( , I'm colombian my english is not perfect jaja in my issueTransformer i had : ->getRepository('frontendPACIENTEBundle:Paciente') ->findOneBy(array('numeroRegistro' => $number)) and was expecting ->getRepository('frontendCITASBundle:Paciente') ->findOneBy(array('numeroRegistro' => $number)) .
  • Carlos Delgado
    Carlos Delgado over 9 years
    Thanks for all your support !
  • ozahorulia
    ozahorulia over 9 years
    @CarlosDelgado please, accept the answer, if it helped you. You are welcome.