I'm working on a log parser that uses a database table to "translate" log events into human-readable equivalents for reporting.
For example, a log entry like "start_application_minecraft" would get converted to "Started Minecraft".
I'm trying to make a web interface for adding/updating the display text, but I can't figure out how to get them into a Symfony Form object.
I have a LogEvent
entity (with properties for ID
, Text
, and DisplayText
), and I've created a Form Type that corresponds to these properties.
It works fine for modifying one event at a time, but I'd like to have them all on one page with a single Submit button to update everything. The problem is that all the documentation I can find on embedding Forms deals with entities that are related (e.g. a Category containing multiple Products), but in my case all of the entities I need to work with are completely unrelated. What's the best way to go about setting this up?
Use a Symfony 'Collection' form field type and use Doctrine to find the LogEvent entities you want and pass that to the Collection.
Example: http://symfony.com/doc/current/cookbook/form/form_collections.html
Reference: http://symfony.com/doc/current/reference/forms/types/collection.html
So, first you would make your LogEvent form type:
class LogEventType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('text');
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'My\Bundle\Entity\LogEvent',
));
}
public function getName()
{
return 'log_event';
}
}
Then make your form type that holds the Collection of LogEvent entities:
class MultiLogEventType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add(
'logEvents', 'collection', array('type' => new LogEventType())
);
}
public function getName()
{
return 'multi_log_event';
}
}
Then in your Controller, create the form and pass your log events to it:
public function indexAction()
{
// replace findAll() with a more restrictive query if you need to
$logEvents = $this->getDoctrine()->getManager()
->getRepository('MyBundle:LogEvent')->findAll();
$form = $this->createForm(
new MultiLogEventType(),
array('logEvents' => $logEvents)
);
return array('form' => $form->createView());
}
Then in your edit action you can loop through the log events and do whatever you need to:
public function editAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
$editForm = $this->createForm(new MultiLogEventType());
$editForm->handleRequest($request);
if ($editForm->isValid())
{
foreach ($logEvents as $logEvent) {
// perform any logic you need to here
// (ex: removing the log event; $em->remove($logEvent);)
}
$em->flush();
}
return $this->redirect($this->generateUrl('log_event_edit'));
}
You can create a Form Type, which adds all the entities as children. IF you make your "data" an array, you can have an arbitrary number of form items.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With