I have a symfony 2 form that describes a package:
class PackageType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->setMethod('POST')
->add('deliveryNote')
->add('receiver', new ReceiverType());
// field stockitem exists, added dynamically NOT good
}
/**
* @param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'IREnterprise\AppBundle\Entity\Package',
'csrf_protection' => false,
'allow_extra_fields' => true
));
}
/**
* @return string
*/
public function getName()
{
return 'IREnterprise_AppBundle_package';
}
}
Each package has 1 receiver, and a dynamic amount of package lines that are associated with the package, each package line contains one stockitem.
The idea is that the user is able to add existing StockItems, as package lines.
I have achieved that, and it looks like this:
every time the user clicks addPackageLine a package line is added to the form, and he can pick a stockItem and the amount of that stockItem.
Anyway, i had to do something hackish to get around the formBuilder.
So the controller ends up looking like this:
public function newPackageAction(Request $request)
{
$package = new Package();
$form = $this->createForm(new PackageType(), $package);
$form->handleRequest($request);
// Test if stock item belongs to user, and add to package
$formStockItems = $request->request->get('IREnterprise_AppBundle_package[stockItems]', null, true);
// This is bad ... very bad, should be a doctrine validation
if (empty($formStockItems)) {
$form->add('packageLines')->addError(new FormError('Package Lines cannot be null'));
}
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$package->setUser($this->getUser());
foreach ($formStockItems as $formStockItem) {
$stockItem = $em->getRepository('IREnterpriseAppBundle:StockItem')
->findByUserAndId($this->getUser(), $formStockItem['item']);
if (!empty($stockItem)) {
// Create a package line for the stock item, and add it the line to the package
$packageLine = new PackageLine();
$packageLine->setStockItem($stockItem);
$packageLine->setAmount($formStockItem['quantity']);
$packageLine->setPackage($package);
$package->addPackageLine($packageLine);
}
}
$em->persist($package);
$em->flush();
$response = View::create($package);
return $response;
}
return View::create($form, Response::HTTP_BAD_REQUEST);
}
I would like to do this in a less hackish way, so that form->isValid() also validates all the packageLiens sent along, because my form errors become messed up with this approach, any suggestions?