It's amazing that I can't find a solution for something that seems so straight forward.
My website has a simple settings page. All settings are stored in a simple table:
| id | name | label | type | value | is_user_created | is_editable | edit_date | original_name | category | file | subcategory |
+----+---------------------+---------------------------------------------------+--------+-----------------------+-----------------+-------------+---------------------+---------------+------------------+----------------------+-------------+
| 21 | index_header_large | Large header for index page | bool | true | 0 | 1 | 2018-09-17 13:22:20 | | Layout | | Heading |
| 25 | website_title | Short title | string | My website | 0 | 1 | 2018-09-17 13:22:20 | | Details website | | |
| 26 | website_owner | Name of the owner | string | Not specified | 0 | 1 | 2018-09-17 13:22:20 | | Gegevens website | | |
+----+---------------------+---------------------------------------------------+--------+-----------------------+-----------------+-------------+---------------------+---------------+------------------+----------------------+-------------+
The settings table has a column called type
. I use this to generate a FormType
that has the correct fields / asserts for the type of value the form will have to render.
They all look very similar, this type of for a string type:
class SettingsType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
/* @var $entity \App\Entity\Setting */
$entity=$builder->getData();
$builder
->add('value', TextType::class, array(
'label' => $entity->getLabel(),
'trim' => true,
'translation_domain' => 'app'
));
;
}
}
In the controller I fetch the settings and iterate them to create the forms
$settings = $repSettings->findAllOrderedByCategory();
$settingForms = [];
/* @var $setting Setting */
foreach ($settings as $setting) {
if ($setting->getType() === 'bool') {
array_push($settingForms, $this->createForm(SettingsBoolType::class, $setting, array(
'action' => $this->generateUrl(
'admin_set_setting_value',
array(
"_locale" => $request->getLocale(),
"_id" => $setting->getId()
)
)
))->createView());
} else if ($setting->getType() === 'file') {
array_push($settingForms, $this->createForm(SettingsFileType::class, $setting, array(
'action' => $this->generateUrl(
'admin_set_setting_file',
array(
"_locale" => $request->getLocale(),
"_id" => $setting->getId())
)
))->createView());
} else {
array_push($settingForms, $this->createForm(SettingsType::class, $setting, array(
'action' => $this->generateUrl(
'admin_set_setting_value',
array(
"_locale" => $request->getLocale(),
"_id" => $setting->getId())
)
))->createView());
}
}
return $this->render('admin/manage_settings.html.twig', array_merge(
array(
'settingForms' => $settingForms,
)
));
Good so far, the forms render and work because each form has a unique ID set in the action url. But this method has some issues.
Wrong values submitted: It seems to work for string value forms, but sometimes a boolean value form submits a value for the wrong setting.
Duplicate IDs: The
block_prefixes
for each form is set to the class name (e.g settings_value).
I know this is not the way you should to this, but I'm clueless as to how I should. A collection maybe? Should I create a super class in order to render a CollectionType
? In that case I need to know how I can apply my own layout, because I render headers for every category
and subcategory
column in the settings table.
A push in the right direction would be appreciated :)
createForm
method?createForm
method is derived from theControllerInterface
. I can't change the code behind it :) In case you haven't seen it in my code, it's in the third code block:array_push($settingForms, $this->createForm(...)
else/if
xD)