Обработка сложной формы Symfony2 с отношениями нескольких сущностей

У меня есть форма (все еще не закончена и отсутствует много полей), которая обрабатывается как мастер с шагами, в которых обрабатываются поля из нескольких объектов. Это сама форма:

public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('tipo_tramite', 'entity', array(
'class' => 'ComunBundle:TipoTramite',
'property' => 'nombre',
'required' => TRUE,
'label' => "Tipo de Trámite",
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('q')
->where('q.activo = :valorActivo')
->setParameter('valorActivo', TRUE);
}
))
->add('oficina_regional', 'entity', array(
'class' => 'ComunBundle:OficinaRegional',
'property' => 'nombre',
'required' => TRUE,
'label' => "Oficina Regional",
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('q')
->where('q.activo = :valorActivo')
->setParameter('valorActivo', TRUE);
}
))
->add('procedencia_producto', 'entity', array(
'class' => 'ComunBundle:ProcedenciaProducto',
'property' => 'nombre',
'required' => TRUE,
'label' => "Procedencia del Producto"))
->add('finalidad_producto', 'entity', array(
'class' => 'ComunBundle:FinalidadProducto',
'property' => 'nombre',
'required' => TRUE,
'label' => "Finalidad del Producto"))
->add('condicion_producto', 'entity', array(
'class' => 'ComunBundle:CondicionProducto',
'property' => 'nombre',
'required' => TRUE,
'label' => "Condición del Producto"))
->add('lote', 'integer', array(
'required' => TRUE,
'label' => "Tamaño del Lote"))
->add('observaciones', 'text', array(
'required' => FALSE,
'label' => "Observaciones"));

}

У меня есть вопрос относительно того, как обрабатывать параметр data_class в этом случае, поэтому я не должен делать магию в контроллере. Когда я говорю магию, я имею в виду следующее:

public function empresaAction()
{
$entity = new Empresa();
$form = $this->createForm(new EmpresaFormType(), $entity);
return array( 'entity' => $entity, 'form' => $form->createView() );

}

public function guardarEmpresaAction(Request $request)
{
$em = $this->getDoctrine()->getManager();

/** @var $userManager \FOS\UserBundle\Model\UserManagerInterface */
$userManager = $this->container->get('fos_user.user_manager');
/** @var $dispatcher \Symfony\Component\EventDispatcher\EventDispatcherInterface */
$dispatcher = $this->container->get('event_dispatcher');
/** @var $mailer FOS\UserBundle\Mailer\MailerInterface */
$mailer = $this->container->get('fos_user.mailer');

$request_empresa = $request->get('empresa');
$request_sucursal = $request->get('sucursal');
$request_chkRif = $request->get('chkRif');

$request_estado = $request_empresa[ 'estado' ];
$request_municipio = $request->get('municipio');
$request_ciudad = $request->get('ciudad');
$request_parroquia = $request->get('parroquia');

$user = $userManager->createUser();

$event = new GetResponseUserEvent($user, $request);
$dispatcher->dispatch(FOSUserEvents::REGISTRATION_INITIALIZE, $event);

if (null !== $event->getResponse())
{
return $event->getResponse();
}

$entity = new Empresa();
$form = $this->createForm(new EmpresaFormType(), $entity);
$form->handleRequest($request);

$success = $url = $errors = "";

if ($form->isValid())
{
if ($request_sucursal != NULL || $request_sucursal != "")
{
$padreEntity = $em->getRepository('UsuarioBundle:Empresa')->findOneBy(array( "padre" => $request_sucursal ));

if (!$padreEntity)
{
$padreEntity = $em->getRepository('UsuarioBundle:Empresa')->findOneBy(array( "id" => $request_sucursal ));
}

if ($request_chkRif != NULL || $request_chkRif != "")
{
$rifUsuario = $request_empresa[ 'tipo_identificacion' ] . $request_empresa[ 'rif' ];
}
else
{
$originalRif = $padreEntity->getRif();
$sliceRif = substr($originalRif, 10, 1);
$rifUsuario = $originalRif . ($sliceRif === false ? 1 : $sliceRif + 1);
}

$entity->setPadre($padreEntity);
}
else
{
$rifUsuario = $request_empresa[ 'tipo_identificacion' ] . $request_empresa[ 'rif' ];
}

$user->setUsername($rifUsuario);
$user->setRepresentativeName($request_empresa[ 'razon_social' ]);
$user->setEmail($request_empresa[ 'usuario' ][ 'email' ]);
$user->setPlainPassword($request_empresa[ 'usuario' ][ 'plainPassword' ][ 'first' ]);

$pais = $em->getRepository('ComunBundle:Pais')->findOneBy(array( "id" => 23 ));
$user->setPais($pais);

$estado_id = $request_estado ? $request_estado : 0;
$estado = $em->getRepository('ComunBundle:Estado')->findOneBy(array( "id" => $estado_id ));
$user->setEstado($estado);

$municipio_id = $request_municipio ? $request_municipio : 0;
$municipio = $em->getRepository('ComunBundle:Municipio')->findOneBy(array( "id" => $municipio_id ));
$user->setMunicipio($municipio);

$ciudad_id = $request_ciudad ? $request_ciudad : 0;
$ciudad = $em->getRepository('ComunBundle:Ciudad')->findOneBy(array( "id" => $ciudad_id ));
$user->setCiudad($ciudad);

$parroquia_id = $request_parroquia ? $request_parroquia : 0;
$parroquia = $em->getRepository('ComunBundle:Parroquia')->findOneBy(array( "id" => $parroquia_id ));
$user->setParroquia($parroquia);

...
}
else
{
$errors = $this->getFormErrors($form);
$success = FALSE;
}

return new JsonResponse(array( 'success' => $success, 'errors' => $errors, 'redirect_to' => $url ));

}

Так как ‘data_classonEmpresaFormTypeis set toUsuarioBundle \ Entity \ Empresa`, тогда мне нужно обработать любой дополнительный параметр, как показано в примере выше, с помощью getter / setter, и это очень много для сложных / больших форм.

В образце формы поля tipo_tramite будет сохраняться в классе ComunBundle\Entity\Producto но поле oficina_regional будет сохраняться в классе ComunBundle\Entity\SolicitudUsuario и так с другими, которые не помещены даже здесь, но находятся в форме, в целом должны сохраняться как 3 или 4 сущности, включая отношения во многих случаях, как вы справляетесь с этим?

Я знаю, что есть CraueFormFlowBundle это может охватывать этот процесс / поток, но не уверен, что это решение.

Любой совет?

1

Решение

Просто работал с многошаговой формой несколько дней назад. Я думаю тебе нужно встроенные формы Вот. В любом случае может предложить вам еще один приятный пакет для создания мастера: SyliusFlowBundle. ИМО более гибок и проще для понимания, чем CraueFormFlowBundle.

Кстати, почему вы хотите хранить все в одной форме? Мы использовали одну форму для каждого шага, и мне понравился этот подход.

1

Другие решения

Других решений пока нет …