Example #1
0
 /**
  * {@inheritdoc}
  */
 public function buildForm(array $form, FormStateInterface $form_state)
 {
     if ($form_state->isRebuilding()) {
         $form_state->setUserInput(array());
     }
     // Initialize
     $storage = $form_state->getStorage();
     if (empty($storage)) {
         $user_input = $form_state->getUserInput();
         if (empty($user_input)) {
             $_SESSION['constructions'] = 0;
         }
         // Put the initial thing into the storage
         $storage = ['thing' => ['title' => 'none', 'value' => '']];
         $form_state->setStorage($storage);
     }
     // Count how often the form is constructed.
     $_SESSION['constructions']++;
     drupal_set_message("Form constructions: " . $_SESSION['constructions']);
     $form['title'] = array('#type' => 'textfield', '#title' => 'Title', '#default_value' => $storage['thing']['title'], '#required' => TRUE);
     $form['value'] = array('#type' => 'textfield', '#title' => 'Value', '#default_value' => $storage['thing']['value'], '#element_validate' => array('::elementValidateValueCached'));
     $form['continue_button'] = array('#type' => 'button', '#value' => 'Reset');
     $form['continue_submit'] = array('#type' => 'submit', '#value' => 'Continue submit', '#submit' => array('::continueSubmitForm'));
     $form['submit'] = array('#type' => 'submit', '#value' => 'Save');
     if (\Drupal::request()->get('cache')) {
         // Manually activate caching, so we can test that the storage keeps working
         // when it's enabled.
         $form_state->setCached();
     }
     if ($this->getRequest()->get('immutable')) {
         $form_state->addBuildInfo('immutable', TRUE);
     }
     return $form;
 }
 /**
  * @covers ::addBuildInfo
  */
 public function testAddBuildInfo()
 {
     $property = 'FOO';
     $value = 'BAR';
     $this->decoratedFormState->addBuildInfo($property, $value)->shouldBeCalled();
     $this->assertSame($this->formStateDecoratorBase, $this->formStateDecoratorBase->addBuildInfo($property, $value));
 }
Example #3
0
 /**
  * {@inheritdoc}
  */
 public function buildForm(array $form, FormStateInterface $form_state)
 {
     if ($form_state->isRebuilding()) {
         $form_state->setUserInput(array());
     }
     // Initialize
     $storage = $form_state->getStorage();
     if (empty($storage)) {
         $user_input = $form_state->getUserInput();
         if (empty($user_input)) {
             $_SESSION['constructions'] = 0;
         }
         // Put the initial thing into the storage
         $storage = ['thing' => ['title' => 'none', 'value' => '']];
         $form_state->setStorage($storage);
     }
     // Count how often the form is constructed.
     $_SESSION['constructions']++;
     drupal_set_message("Form constructions: " . $_SESSION['constructions']);
     $form['title'] = array('#type' => 'textfield', '#title' => 'Title', '#default_value' => $storage['thing']['title'], '#required' => TRUE);
     $form['value'] = array('#type' => 'textfield', '#title' => 'Value', '#default_value' => $storage['thing']['value'], '#element_validate' => array('::elementValidateValueCached'));
     $form['continue_button'] = array('#type' => 'button', '#value' => 'Reset');
     $form['continue_submit'] = array('#type' => 'submit', '#value' => 'Continue submit', '#submit' => array('::continueSubmitForm'));
     $form['submit'] = array('#type' => 'submit', '#value' => 'Save');
     // @todo Remove this in https://www.drupal.org/node/2524408, because form
     //   cache immutability is no longer necessary, because we no longer cache
     //   forms during safe HTTP methods. In the meantime, because
     //   Drupal\system\Tests\Form still has test coverage for a poisoned form
     //   cache following a GET request, trick $form_state into caching the form
     //   to keep that test working until we either remove it or change it in
     //   that issue.
     if ($this->getRequest()->get('immutable')) {
         $form_state->addBuildInfo('immutable', TRUE);
         if ($this->getRequest()->get('cache') && $this->getRequest()->isMethodSafe()) {
             $form_state->setRequestMethod('FAKE');
             $form_state->setCached();
         }
     }
     return $form;
 }
Example #4
0
 /**
  * {@inheritdoc}
  */
 public function setCache($form_build_id, $form, FormStateInterface $form_state)
 {
     // 6 hours cache life time for forms should be plenty.
     $expire = 21600;
     // Ensure that the form build_id embedded in the form structure is the same
     // as the one passed in as a parameter. This is an additional safety measure
     // to prevent legacy code operating directly with
     // \Drupal::formBuilder()->getCache() and \Drupal::formBuilder()->setCache()
     // from accidentally overwriting immutable form state.
     if (isset($form['#build_id']) && $form['#build_id'] != $form_build_id) {
         $this->logger->error('Form build-id mismatch detected while attempting to store a form in the cache.');
         return;
     }
     // Cache form structure.
     if (isset($form)) {
         if ($this->currentUser->isAuthenticated()) {
             $form['#cache_token'] = $this->csrfToken->get();
         }
         unset($form['#build_id_old']);
         $this->keyValueExpirableFactory->get('form')->setWithExpire($form_build_id, $form, $expire);
     }
     // Cache form state.
     if ($this->configFactory->get('system.performance')->get('cache.page.use_internal') && $this->isPageCacheable()) {
         $form_state->addBuildInfo('immutable', TRUE);
     }
     // Store the known list of safe strings for form re-use.
     // @todo Ensure we are not storing an excessively large string list in:
     //   https://www.drupal.org/node/2295823
     $form_state->addBuildInfo('safe_strings', SafeMarkup::getAll());
     if ($data = $form_state->getCacheableArray()) {
         $this->keyValueExpirableFactory->get('form_state')->setWithExpire($form_build_id, $data, $expire);
     }
 }
Example #5
0
 /**
  * {@inheritdoc}
  */
 public function retrieveForm($form_id, FormStateInterface &$form_state)
 {
     // Record the $form_id.
     $form_state->addBuildInfo('form_id', $form_id);
     // We save two copies of the incoming arguments: one for modules to use
     // when mapping form ids to constructor functions, and another to pass to
     // the constructor function itself.
     $build_info = $form_state->getBuildInfo();
     $args = $build_info['args'];
     $callback = [$form_state->getFormObject(), 'buildForm'];
     $form = array();
     // Assign a default CSS class name based on $form_id.
     // This happens here and not in self::prepareForm() in order to allow the
     // form constructor function to override or remove the default class.
     $form['#attributes']['class'][] = Html::getClass($form_id);
     // Same for the base form ID, if any.
     if (isset($build_info['base_form_id'])) {
         $form['#attributes']['class'][] = Html::getClass($build_info['base_form_id']);
     }
     // We need to pass $form_state by reference in order for forms to modify it,
     // since call_user_func_array() requires that referenced variables are
     // passed explicitly.
     $args = array_merge(array($form, &$form_state), $args);
     $form = call_user_func_array($callback, $args);
     // If the form returns a response, skip subsequent page construction by
     // throwing an exception.
     // @see Drupal\Core\EventSubscriber\EnforcedFormResponseSubscriber
     //
     // @todo Exceptions should not be used for code flow control. However, the
     //   Form API currently allows any form builder functions to return a
     //   response.
     //   @see https://www.drupal.org/node/2363189
     if ($form instanceof Response) {
         throw new EnforcedResponseException($form);
     }
     $form['#form_id'] = $form_id;
     return $form;
 }
Example #6
0
 /**
  * {@inheritdoc}
  */
 public function addBuildInfo($property, $value)
 {
     $this->mainFormState->addBuildInfo($property, $value);
     return $this;
 }
Example #7
0
 /**
  * {@inheritdoc}
  */
 public function buildForm(array $form, FormStateInterface $form_state, ViewExecutable $view = NULL, $output = [])
 {
     if (!($step = $form_state->get('step'))) {
         $step = 'views_form_views_form';
         $form_state->set('step', $step);
     }
     $form_state->set(['step_controller', 'views_form_views_form'], 'Drupal\\views\\Form\\ViewsFormMainForm');
     // Add the base form ID.
     $form_state->addBuildInfo('base_form_id', $this->getBaseFormId());
     $form = array();
     $query = $this->requestStack->getCurrentRequest()->query->all();
     $query = UrlHelper::filterQueryParameters($query, array(), '');
     $options = array('query' => $query);
     $form['#action'] = $view->hasUrl() ? $view->getUrl()->setOptions($options)->toString() : Url::fromRoute('<current>')->setOptions($options)->toString();
     // Tell the preprocessor whether it should hide the header, footer, pager,
     // etc.
     $form['show_view_elements'] = array('#type' => 'value', '#value' => $step == 'views_form_views_form' ? TRUE : FALSE);
     $form_object = $this->getFormObject($form_state);
     $form += $form_object->buildForm($form, $form_state, $view, $output);
     return $form;
 }
Example #8
0
 /**
  * {@inheritdoc}
  */
 public function retrieveForm($form_id, FormStateInterface &$form_state)
 {
     // Record the $form_id.
     $form_state->addBuildInfo('form_id', $form_id);
     // We save two copies of the incoming arguments: one for modules to use
     // when mapping form ids to constructor functions, and another to pass to
     // the constructor function itself.
     $args = $form_state['build_info']['args'];
     $callback = array($form_state['build_info']['callback_object'], 'buildForm');
     $form = array();
     // Assign a default CSS class name based on $form_id.
     // This happens here and not in self::prepareForm() in order to allow the
     // form constructor function to override or remove the default class.
     $form['#attributes']['class'][] = $this->drupalHtmlClass($form_id);
     // Same for the base form ID, if any.
     if (isset($form_state['build_info']['base_form_id'])) {
         $form['#attributes']['class'][] = $this->drupalHtmlClass($form_state['build_info']['base_form_id']);
     }
     // We need to pass $form_state by reference in order for forms to modify it,
     // since call_user_func_array() requires that referenced variables are
     // passed explicitly.
     $args = array_merge(array($form, &$form_state), $args);
     $form = call_user_func_array($callback, $args);
     // If the form returns some kind of response, deliver it.
     if ($form instanceof Response) {
         $this->sendResponse($form);
         exit;
     }
     $form['#form_id'] = $form_id;
     return $form;
 }