First, best wishes to all for this 2016 new year !
I'm facing a problem I did not manage to resolve on my own.
I'm working on a Silex (~1.3) application. I coded simple CRUDs on my domain classes. I created as well some Type forms to be able to modify my basic domain classes. In this case, I have to manage the notion of State within a Country. Each is a specific class, and a State has one Country attribute.
In my form, I declared some text fields, and a Choice field to be able to select the country (the form class is copied below).
My problem is that when I try to modify an existing State with the following controller, the text fields name, code, unloc are filled with the data from the database, but not the choices country nor hub (the controller class is copied below).
Please note that i'm NOT using Doctrine, but a home-made (and quite basic) DAO.
Here is my code and some information :
The view is done using twig, with the 'standard' bootstrap example which can be found here : Form Customization, using Bootstrap layout and Form layout :
{% extends 'layout.html.twig' %} {% block title %}{{ title }}{% endblock %} {% block content %} {% if form and is_granted('IS_AUTHENTICATED_FULLY') and is_granted('ROLE_ADMIN')%} {% form_theme form 'bootstrap_3_layout.html.twig' %} {{ form_start(form) }} <div class="form-group"> {{ form_errors(form) }} {{ form_widget(form) }} <input type="submit" class="btn btn-primary" value={% if button is not defined %} "Save"{% else %}"{{ button }}"{% endif %} /> </div> {{ form_end(form) }} {% else %} <div> <p>Ask an admin to add/modify information.</p> </div> {% endif %} {% endblock %}composer.json content :
{ "require": { "silex/silex": "~1.3", "doctrine/dbal": "2.5.*", "symfony/security": "2.7.*", "twig/twig": "1.21.*", "symfony/twig-bridge": "2.7.*", "symfony/form": "2.7.*", "symfony/translation": "2.7.*", "symfony/config": "2.7.*", "jasongrimes/silex-simpleuser": "*", "twig/extensions": "1.3.*", "symfony/validator": "2.*", "phpoffice/phpexcel": "1.*" }, "require-dev": { "phpunit/phpunit": "*", "symfony/browser-kit": "*", "symfony/css-selector": "*", "silex/web-profiler": "*", "symfony/monolog-bridge": "*" }, "autoload":{ "psr-4":{"Easytrip2\\": "src"} } }Form code :
<?php namespace Easytrip2\Form\Type; use Easytrip2\DAO\CountryDAO; use Easytrip2\DAO\GeopointDAO; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceList; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; class StateType extends AbstractType { /** * @CountryDAO * \Easytrip2\DAO\CountryDAO * allow to find the Country for the form. */ private $countryDAO; /** * @GeopointDAO * \Easytrip2\DAO\GeopointDAO * allow to find the Country for the form. */ private $geopointDAO; /** * * {@inheritDoc} * * @see \Symfony\Component\Form\AbstractType::buildForm() */ public function buildForm(FormBuilderInterface $builder, array $options) { $builder->add ( 'name', 'text', array ( 'label' => 'State name' ) ); $builder->add ( 'code', 'text', array ( 'label' => 'State code' ) ); $builder->add ( 'unloc', 'text', array ( 'label' => 'State code' ) ); $countries = $this->countryDAO->findAll (); $choices = array (); $labels = array (); foreach ( $countries as $value ) { $choices [] = $value; $labels [] = $value->getName (); } $builder->add ( 'country', 'choice', array ( 'choice_list' => new ChoiceList ( $choices, $labels ) ) ); $hubs = $this->geopointDAO->findAllHubs (); $choices = array (); $labels = array (); foreach ( $hubs as $value ) { $choices [] = $value; $labels [] = $value->getName (); } $builder->add ( 'hub', 'choice', array ( 'choice_list' => new ChoiceList ( $choices, $labels ), 'required' => false ) ); } /** * * {@inheritDoc} * * @see \Symfony\Component\Form\AbstractType::configureOptions() */ public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults ( array ( 'data_class' => 'Easytrip2\Domain\State' ) ); } /** * * {@inheritDoc} * * @see \Symfony\Component\Form\FormTypeInterface::getName() */ public function getName() { return 'state'; } /** * allow use of a CountryDAO */ public function __construct(CountryDAO $countryDAO, GeopointDAO $geopointDAO) { $this->geopointDAO = $geopointDAO; $this->countryDAO = $countryDAO; } }Controller content :
public function stateUpdateByIdAction($id, Request $request, Application $app) { if ($app ['security.authorization_checker']->isGranted ( 'IS_AUTHENTICATED_FULLY' ) and $app ['security.authorization_checker']->isGranted ( 'ROLE_ADMIN' )) { $obj = $app ['dao.state']->findById ( $id ); $form = $app ['form.factory']->create ( new StateType ( $app ['dao.country'], $app ['dao.geopoint'] ), $obj ); $form->handleRequest ( $request ); if ($form->isSubmitted () && $form->isValid ()) { if ($app ['dao.state']->save ( $obj )) { $app ['session']->getFlashBag ()->add ( 'success', 'The state was succesfully updated.' ); return $app->redirect ( $app ['url_generator']->generate ( 'state' ) ); } else { $app ['session']->getFlashBag ()->add ( 'error', 'Something went wrong...' ); } } return $app ['twig']->render ( 'form.html.twig', array ( 'form' => $form->createView (), 'title' => 'Edit states' ) ); } else { $app ['session']->getFlashBag ()->add ( 'error', 'Don\'t have the rights...' ); return $app->redirect ( $app ['url_generator']->generate ( 'home' ) ); } }