Carlos Delgado Carlos Delgado - 19 days ago 6
PHP Question

Symfony 2.5 - Data transformer and View transformer

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.
**

Answer

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.

Comments