public FormBuilderInterface::doBuildForm($form_id, &$element, FormStateInterface &$form_state)
Builds and processes all elements in the structured form array.
Adds any required properties to each element, maps the incoming input data to the proper elements, and executes any #process handlers attached to a specific element.
This is one of the three primary functions that recursively iterates a form array. This one does it for completing the form building process. The other two are self::doValidateForm() (invoked via self::validateForm() and used to invoke validation logic for each element) and drupal_render() (for rendering each element). Each of these three pipelines provides ample opportunity for modules to customize what happens. For example, during this function's life cycle, the following functions get called for each element:
There are similar properties containing callback functions invoked by self::doValidateForm() and drupal_render(), appropriate for those operations.
Developers are strongly encouraged to integrate the functionality needed by their form or module within one of these three pipelines, using the appropriate callback property, rather than implementing their own recursive traversal of a form array. This facilitates proper integration between multiple modules. For example, module developers are familiar with the relative order in which hook_form_alter() implementations and #process functions run. A custom traversal function that affects the building of a form is likely to not integrate with hook_form_alter() and #process in the expected way. Also, deep recursion within PHP is both slow and memory intensive, so it is best to minimize how often it's done.
As stated above, each element's #process functions are executed after its #value has been set. This enables those functions to execute conditional logic based on the current value. However, all of self::doBuildForm() runs before self::validateForm() is called, so during #process function execution, the element's #value has not yet been validated, so any code that requires validated values must reside within a submit handler.
As a security measure, user input is used for an element's #value only if the element exists within $form, is not disabled (as per the #disabled property), and can be accessed (as per the #access property, except that forms submitted using self::submitForm() bypass #access restrictions). When user input is ignored due to #disabled and #access restrictions, the element's default value is used.
Because of the preorder traversal, where #process functions of an element run before user input for its child elements is processed, and because of the Form API security of user input processing with respect to #access and #disabled described above, this generally means that #process functions should not use an element's (unvalidated) #value to affect the #disabled or #access of child elements. Use-cases where a developer may be tempted to implement such conditional logic usually fall into one of two categories:
string $form_id: A unique string identifying the form for validation, submission, theming, and hook_form_alter functions.
array $element: An associative array containing the structure of the current element.
\Drupal\Core\Form\FormStateInterface $form_state: The current state of the form. In this context, it is used to accumulate information about which button was clicked when the form was submitted, as well as the sanitized \Drupal::request()->request data.
public function doBuildForm($form_id, &$element, FormStateInterface &$form_state);
© 2001–2016 by the original authors
Licensed under the GNU General Public License, version 2 and later.
Drupal is a registered trademark of Dries Buytaert.