public FormBuilder::prepareForm($form_id, &$form, FormStateInterface &$form_state)
Prepares a structured form array.
Adds required elements, executes any hook_form_alter functions, and optionally inserts a validation token to prevent tampering.
string $form_id: A unique string identifying the form for validation, submission, theming, and hook_form_alter functions.
array $form: An associative array containing the structure of the form.
\Drupal\Core\Form\FormStateInterface $form_state: The current state of the form. Passed in here so that hook_form_alter() calls can use it, as well.
Overrides FormBuilderInterface::prepareForm
public function prepareForm($form_id, &$form, FormStateInterface &$form_state) { $user = $this->currentUser(); $form['#type'] = 'form'; // Only update the action if it is not already set. if (!isset($form['#action'])) { // Instead of setting an actual action URL, we set the placeholder, which // will be replaced at the very last moment. This ensures forms with // dynamically generated action URLs don't have poor cacheability. // Use the proper API to generate the placeholder, when we have one. See // https://www.drupal.org/node/2562341. $placeholder = 'form_action_' . hash('crc32b', __METHOD__); $form['#attached']['placeholders'][$placeholder] = [ '#lazy_builder' => ['form_builder:renderPlaceholderFormAction', []], ]; $form['#action'] = $placeholder; } // Fix the form method, if it is 'get' in $form_state, but not in $form. if ($form_state->isMethodType('get') && !isset($form['#method'])) { $form['#method'] = 'get'; } // GET forms should not use a CSRF token. if (isset($form['#method']) && $form['#method'] === 'get') { // Merges in a default, this means if you've explicitly set #token to the // the $form_id on a GET form, which we don't recommend, it will work. $form += [ '#token' => FALSE, ]; } // Generate a new #build_id for this form, if none has been set already. // The form_build_id is used as key to cache a particular build of the form. // For multi-step forms, this allows the user to go back to an earlier // build, make changes, and re-submit. // @see self::buildForm() // @see self::rebuildForm() if (!isset($form['#build_id'])) { $form['#build_id'] = 'form-' . Crypt::randomBytesBase64(); } $form['form_build_id'] = array( '#type' => 'hidden', '#value' => $form['#build_id'], '#id' => $form['#build_id'], '#name' => 'form_build_id', // Form processing and validation requires this value, so ensure the // submitted form value appears literally, regardless of custom #tree // and #parents being set elsewhere. '#parents' => array('form_build_id'), ); // Add a token, based on either #token or form_id, to any form displayed to // authenticated users. This ensures that any submitted form was actually // requested previously by the user and protects against cross site request // forgeries. // This does not apply to programmatically submitted forms. Furthermore, // since tokens are session-bound and forms displayed to anonymous users are // very likely cached, we cannot assign a token for them. // During installation, there is no $user yet. // Form constructors may explicitly set #token to FALSE when cross site // request forgery is irrelevant to the form, such as search forms. if ($form_state->isProgrammed() || (isset($form['#token']) && $form['#token'] === FALSE)) { unset($form['#token']); } else { $form['#cache']['contexts'][] = 'user.roles:authenticated'; if ($user && $user->isAuthenticated()) { // Generate a public token based on the form id. // Generates a placeholder based on the form ID. $placeholder = 'form_token_placeholder_' . hash('crc32b', $form_id); $form['#token'] = $placeholder; $form['form_token'] = array( '#id' => Html::getUniqueId('edit-' . $form_id . '-form-token'), '#type' => 'token', '#default_value' => $placeholder, // Form processing and validation requires this value, so ensure the // submitted form value appears literally, regardless of custom #tree // and #parents being set elsewhere. '#parents' => array('form_token'), // Instead of setting an actual CSRF token, we've set the placeholder // in form_token's #default_value and #placeholder. These will be // replaced at the very last moment. This ensures forms with a CSRF // token don't have poor cacheability. '#attached' => [ 'placeholders' => [ $placeholder => [ '#lazy_builder' => ['form_builder:renderFormTokenPlaceholder', [$placeholder]] ] ] ], '#cache' => [ 'max-age' => 0, ], ); } } if (isset($form_id)) { $form['form_id'] = array( '#type' => 'hidden', '#value' => $form_id, '#id' => Html::getUniqueId("edit-$form_id"), // Form processing and validation requires this value, so ensure the // submitted form value appears literally, regardless of custom #tree // and #parents being set elsewhere. '#parents' => array('form_id'), ); } if (!isset($form['#id'])) { $form['#id'] = Html::getUniqueId($form_id); // Provide a selector usable by JavaScript. As the ID is unique, its not // possible to rely on it in JavaScript. $form['#attributes']['data-drupal-selector'] = Html::getId($form_id); } $form += $this->elementInfo->getInfo('form'); $form += array('#tree' => FALSE, '#parents' => array()); $form['#validate'][] = '::validateForm'; $form['#submit'][] = '::submitForm'; $build_info = $form_state->getBuildInfo(); // If no #theme has been set, automatically apply theme suggestions. // The form theme hook itself, which is rendered by form.html.twig, // is in #theme_wrappers. Therefore, the #theme function only has to care // for rendering the inner form elements, not the form itself. if (!isset($form['#theme'])) { $form['#theme'] = array($form_id); if (isset($build_info['base_form_id'])) { $form['#theme'][] = $build_info['base_form_id']; } } // Invoke hook_form_alter(), hook_form_BASE_FORM_ID_alter(), and // hook_form_FORM_ID_alter() implementations. $hooks = array('form'); if (isset($build_info['base_form_id'])) { $hooks[] = 'form_' . $build_info['base_form_id']; } $hooks[] = 'form_' . $form_id; $this->moduleHandler->alter($hooks, $form, $form_state, $form_id); $this->themeManager->alter($hooks, $form, $form_state, $form_id); }
© 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.
https://api.drupal.org/api/drupal/core!lib!Drupal!Core!Form!FormBuilder.php/function/FormBuilder::prepareForm/8.1.x