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.
Parameters
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
File
- core/lib/Drupal/Core/Form/FormBuilder.php, line 675
Class
- FormBuilder
- Provides form building and processing.
Namespace
Drupal\Core\Form
Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 | 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 $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 ); } |
Please login to continue.