public FormBuilder::rebuildForm($form_id, FormStateInterface &$form_state, $old_form = NULL)
Constructs a new $form from the information in $form_state.
This is the key function for making multi-step forms advance from step to step. It is called by self::processForm() when all user input processing, including calling validation and submission handlers, for the request is finished. If a validate or submit handler set $form_state->isRebuilding() to TRUE, and if other conditions don't preempt a rebuild from happening, then this function is called to generate a new $form, the next step in the form workflow, to be returned for rendering.
Ajax form submissions are almost always multi-step workflows, so that is one common use-case during which form rebuilding occurs.
Parameters
string $form_id: The unique string identifying the desired form. If a function with that name exists, it is called to build the form array.
\Drupal\Core\Form\FormStateInterface $form_state: The current state of the form.
array|null $old_form: (optional) A previously built $form. Used to retain the #build_id and #action properties in Ajax callbacks and similar partial form rebuilds. The only properties copied from $old_form are the ones which both exist in $old_form and for which $form_state->getRebuildInfo()['copy'][PROPERTY] is TRUE. If $old_form is not passed, the entire $form is rebuilt freshly. 'rebuild_info' needs to be a separate top-level property next to 'build_info', since the contained data must not be cached.
Return value
array The newly built form.
Overrides FormBuilderInterface::rebuildForm
See also
self::processForm()
File
- core/lib/Drupal/Core/Form/FormBuilder.php, line 363
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 | public function rebuildForm( $form_id , FormStateInterface & $form_state , $old_form = NULL) { $form = $this ->retrieveForm( $form_id , $form_state ); // Only GET and POST are valid form methods. If the form receives its input // via POST, then $form_state must be persisted when it is rebuilt between // submissions. If the form receives its input via GET, then persisting // state is forbidden by $form_state->setCached(), and the form must use // the URL itself to transfer its state across steps. Although $form_state // throws an exception based on the request method rather than the form's // method, we base the decision to cache on the form method, because: // - It's the form method that defines what the form needs to do to manage // its state. // - rebuildForm() should only be called after successful input processing, // which means the request method matches the form method, and if not, // there's some other error, so it's ok if an exception is thrown. if ( $form_state ->isMethodType( 'POST' )) { $form_state ->setCached(); } // If only parts of the form will be returned to the browser (e.g., Ajax or // RIA clients), or if the form already had a new build ID regenerated when // it was retrieved from the form cache, reuse the existing #build_id. // Otherwise, a new #build_id is generated, to not clobber the previous // build's data in the form cache; also allowing the user to go back to an // earlier build, make changes, and re-submit. // @see self::prepareForm() $rebuild_info = $form_state ->getRebuildInfo(); $enforce_old_build_id = isset( $old_form [ '#build_id' ]) && ! empty ( $rebuild_info [ 'copy' ][ '#build_id' ]); $old_form_is_mutable_copy = isset( $old_form [ '#build_id_old' ]); if ( $enforce_old_build_id || $old_form_is_mutable_copy ) { $form [ '#build_id' ] = $old_form [ '#build_id' ]; if ( $old_form_is_mutable_copy ) { $form [ '#build_id_old' ] = $old_form [ '#build_id_old' ]; } } else { if (isset( $old_form [ '#build_id' ])) { $form [ '#build_id_old' ] = $old_form [ '#build_id' ]; } $form [ '#build_id' ] = 'form-' . Crypt::randomBytesBase64(); } // #action defaults to $request->getRequestUri(), but in case of Ajax and // other partial rebuilds, the form is submitted to an alternate URL, and // the original #action needs to be retained. if (isset( $old_form [ '#action' ]) && ! empty ( $rebuild_info [ 'copy' ][ '#action' ])) { $form [ '#action' ] = $old_form [ '#action' ]; } $this ->prepareForm( $form_id , $form , $form_state ); // Caching is normally done in self::processForm(), but what needs to be // cached is the $form structure before it passes through // self::doBuildForm(), so we need to do it here. // @todo For Drupal 8, find a way to avoid this code duplication. if ( $form_state ->isCached()) { $this ->setCache( $form [ '#build_id' ], $form , $form_state ); } // Clear out all group associations as these might be different when // re-rendering the form. $form_state ->setGroups([]); // Return a fully built form that is ready for rendering. return $this ->doBuildForm( $form_id , $form , $form_state ); } |
Please login to continue.