I'm trying to understand how to port the following D7 code.
function x_menu() {
$menu['x/form/test/%/%'] = [
'page callback' => 'drupal_get_form',
'page arguments' => ['x_form_test', 3, 4],
'type' => MENU_CALLBACK,
'title' => 'Test Form',
];
return $menu;
}
function x_form_test(&$form, $form_state, $arg1, $arg2) {
return $form;
}
From what I can glean from the documentation of the Routing and Form API, the new way to connect a path to a form is to put this in x.routing.yml
:
x.form_test:
path: 'x/form/{arg1}/{arg2}',
defaults:
_form: '\Drupal\x\XFormTest'
_title: 'Test Form'
and then create a form class XFormTest
that ultimately descends from FormBase
.
However, it's clearly impossible to add extra arguments to inherited functions like public FormInterface::buildForm(array $form, FormStateInterface $form_state)
.
See comment below.
How can I read $arg1
and $arg2
in buildForm
, preferably while still pointing the route at the form rather than putting a Controller around it?
Comments
Maybe its just me, but I got
Maybe its just me, but I got the impression from the documentation on Drupal 8 that the system functions on a request/response basis. Therefore, information in a request is ALWAYS available. So if I wanted the information for 'arg1' and didn't have more specific information handy, I would just use \Drupal::request()->get('arg1') to get the arg1 value.
That should make argument information available no matter where you are. You can also setup default values for arguments in the routing file.
I'm sure there is likely more specific information available but I'm only looking at things from a very rudimentary level.
Never mind
I misinterpreted the error I was getting when I tried to override the buildForm() function. When it failed with an "incompatible arguments" error, I assumed that PHP inheritance was similarly restricted as Java (which does require exact signature matches).
PHP, which has optional function arguments (instead of overloading), allows adding such arguments to the overriding function as they do not alter the "contract", but merely extend it transparently. There's nothing wrong with directly transferring the D7 form builder arguments ($form, $form_state, $arg1 = '...') into the D8 arguments (array $form, FormStateInterface $form_state, $arg1 = '...').
The "incompatible" error I got was actually due to accidentally copying the submitForm() signature and turning $form into &$form. Switching an argument to by-reference does alter the contract, so it's not allowed.