Beispiel #1
1
  /**
   * Build all necessary things for child form (form state, etc.).
   *
   * @param \Drupal\Core\Entity\EntityFormInterface $controller
   *   Entity form controller for child form.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   Parent form state object.
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   Entity object.
   * @param string $operation
   *   Operation that is to be performed in inline form.
   * @param array $parents
   *   Entity form #parents.
   *
   * @return \Drupal\Core\Form\FormStateInterface
   *   Child form state object.
   */
  public static function buildChildFormState(EntityFormInterface $controller, FormStateInterface $form_state, EntityInterface $entity, $operation, $parents) {
    $child_form_state = new FormState();

    $child_form_state->addBuildInfo('callback_object', $controller);
    $child_form_state->addBuildInfo('base_form_id', $controller->getBaseFormID());
    $child_form_state->addBuildInfo('form_id', $controller->getFormID());
    $child_form_state->addBuildInfo('args', array());

    // Copy values to child form.
    $child_form_state->setCompleteForm($form_state->getCompleteForm());
    $child_form_state->setUserInput($form_state->getUserInput());

    // Filter out all submitted values that are not directly relevant for this
    // IEF. Otherwise they might mess things up.
    $form_state_values = $form_state->getValues();
    $form_state_values = static::extractArraySequence($form_state_values, $parents);

    $child_form_state->setValues($form_state_values);
    $child_form_state->setStorage($form_state->getStorage());
    $value = \Drupal::entityTypeManager()->getStorage('entity_form_display')->load($entity->getEntityTypeId() . '.' . $entity->bundle() . '.' . $operation);
    $child_form_state->set('form_display', $value);

    // Since some of the submit handlers are run, redirects need to be disabled.
    $child_form_state->disableRedirect();

    // When a form is rebuilt after Ajax processing, its #build_id and #action
    // should not change.
    // @see drupal_rebuild_form()
    $rebuild_info = $child_form_state->getRebuildInfo();
    $rebuild_info['copy']['#build_id'] = TRUE;
    $rebuild_info['copy']['#action'] = TRUE;
    $child_form_state->setRebuildInfo($rebuild_info);

    $child_form_state->set('inline_entity_form', $form_state->get('inline_entity_form'));
    $child_form_state->set('langcode', $entity->language()->getId());

    $child_form_state->set('field', $form_state->get('field'));
    $child_form_state->setTriggeringElement($form_state->getTriggeringElement());
    $child_form_state->setSubmitHandlers($form_state->getSubmitHandlers());

    return $child_form_state;
  }
 /**
  * Displays the edit feature form.
  */
 public function featureEdit(NodeInterface $node, $fid, $pfid)
 {
     $func = uc_product_feature_data($fid, 'callback');
     $form_state = new FormState();
     $form_state->setBuildInfo(array('args' => array($node, uc_product_feature_load($pfid))));
     return $this->formBuilder()->buildForm($func, $form_state);
 }
  /**
   * @covers ::processMachineName
   */
  public function testProcessMachineName() {
    $form_state = new FormState();

    $element = [
      '#id' => 'test',
      '#field_suffix' => 'test_suffix',
      '#field_prefix' => 'test_prefix',
      '#machine_name' => [
        'source' => [
          'test_source',
        ],
        'maxlength' => 32,
        'additional_property' => TRUE,
        '#additional_property_with_hash' => TRUE,
      ]
    ];

    $complete_form = [
      'test_source' => [
        '#type' => 'textfield',
        '#id' => 'source',
      ],
      'test_machine_name' => $element
    ];

    $form_state->setCompleteForm($complete_form);

    $language = $this->prophesize(LanguageInterface::class);
    $language->getId()->willReturn('xx-lolspeak');

    $language_manager = $this->prophesize(LanguageManagerInterface::class);
    $language_manager->getCurrentLanguage()->willReturn($language);

    $csrf_token = $this->prophesize(CsrfTokenGenerator::class);
    $csrf_token->get('[^a-z0-9_]+')->willReturn('tis-a-fine-token');

    $container = $this->prophesize(ContainerInterface::class);
    $container->get('language_manager')->willReturn($language_manager->reveal());
    $container->get('csrf_token')->willReturn($csrf_token->reveal());
    \Drupal::setContainer($container->reveal());

    $element = MachineName::processMachineName($element, $form_state, $complete_form);
    $settings = $element['#attached']['drupalSettings']['machineName']['#source'];

    $allowed_options = [
      'replace_pattern',
      'replace',
      'maxlength',
      'target',
      'label',
      'field_prefix',
      'field_suffix',
      'suffix',
      'replace_token',
    ];
    $this->assertEmpty(array_diff_key($settings, array_flip($allowed_options)));
    foreach ($allowed_options as $key) {
      $this->assertArrayHasKey($key, $settings);
    }
  }
 /**
  * {@inheritdoc}
  */
 public function getForm($formClass)
 {
     $args = func_get_args();
     array_shift($args);
     if (!class_exists($formClass)) {
         $this->logger->log(LogLevel::CRITICAL, "Form class '@class' does not exists", ['@class' => $formClass]);
         return [];
     }
     if (!method_exists($formClass, 'create')) {
         $this->logger->log(LogLevel::CRITICAL, "Form class '@class' does not implements ::create()", ['@class' => $formClass]);
         return [];
     }
     // God, I do hate Drupal 8...
     $form = call_user_func([$formClass, 'create'], $this->container);
     if (!$form instanceof FormInterface) {
         $this->logger->log(LogLevel::CRITICAL, "Form class '@class' does not implement \\Drupal\\Core\\Form\\FormInterface", ['@class' => $formClass]);
         return [];
     }
     $formId = $form->getFormId();
     $data = [];
     $data['build_info']['args'] = $args;
     $formState = new FormState($data);
     $formState->setFormObject($form);
     $this->formMap[$formId] = [$form, $formState];
     return drupal_build_form($formId, $data);
 }
 /**
  * Page that triggers a programmatic form submission.
  *
  * Returns the validation errors triggered by the form submission as json.
  */
 public function submitFormPage()
 {
     $form_state = new FormState();
     $values = ['name' => 'robo-user', 'mail' => '*****@*****.**', 'op' => t('Submit')];
     $form_state->setValues($values);
     \Drupal::formBuilder()->submitForm('\\Drupal\\user\\Form\\UserPasswordForm', $form_state);
     return new JsonResponse($form_state->getErrors());
 }
 /**
  * Tests the 'validation_complete' $form_state flag.
  *
  * @covers ::validateForm
  * @covers ::finalizeValidation
  */
 public function testValidationComplete()
 {
     $form_validator = $this->getMockBuilder('Drupal\\Core\\Form\\FormValidator')->setConstructorArgs([new RequestStack(), $this->getStringTranslationStub(), $this->csrfToken, $this->logger, $this->formErrorHandler])->setMethods(NULL)->getMock();
     $form = array();
     $form_state = new FormState();
     $this->assertFalse($form_state->isValidationComplete());
     $form_validator->validateForm('test_form_id', $form, $form_state);
     $this->assertTrue($form_state->isValidationComplete());
 }
 /**
  * Tests the 'validation_complete' $form_state flag.
  *
  * @covers ::validateForm
  * @covers ::finalizeValidation
  */
 public function testValidationComplete()
 {
     $form_validator = $this->getMockBuilder('Drupal\\Core\\Form\\FormValidator')->disableOriginalConstructor()->setMethods(NULL)->getMock();
     $form = array();
     $form_state = new FormState();
     $this->assertFalse($form_state->isValidationComplete());
     $form_validator->validateForm('test_form_id', $form, $form_state);
     $this->assertTrue($form_state->isValidationComplete());
 }
 /**
  * @covers ::handleFormErrors
  * @covers ::setElementErrorsFromFormState
  */
 public function testSetElementErrorsFromFormState()
 {
     $form_error_handler = $this->getMockBuilder('Drupal\\Core\\Form\\FormErrorHandler')->setMethods(['drupalSetMessage'])->getMock();
     $form = ['#parents' => []];
     $form['test'] = ['#type' => 'textfield', '#title' => 'Test', '#parents' => ['test'], '#id' => 'edit-test'];
     $form_state = new FormState();
     $form_state->setErrorByName('test', 'invalid');
     $form_error_handler->handleFormErrors($form, $form_state);
     $this->assertSame('invalid', $form['test']['#errors']);
 }
Beispiel #9
0
 /**
  * @covers ::handleFormErrors
  * @covers ::setElementErrorsFromFormState
  */
 public function testSetElementErrorsFromFormState()
 {
     $form_error_handler = $this->getMockBuilder('Drupal\\Core\\Form\\FormErrorHandler')->setConstructorArgs([$this->getStringTranslationStub(), $this->getMock('Drupal\\Core\\Utility\\LinkGeneratorInterface')])->setMethods(['drupalSetMessage'])->getMock();
     $form = ['#parents' => []];
     $form['test'] = ['#type' => 'textfield', '#title' => 'Test', '#parents' => ['test'], '#id' => 'edit-test'];
     $form_state = new FormState();
     $form_state->setErrorByName('test', 'invalid');
     $form_error_handler->handleFormErrors($form, $form_state);
     $this->assertSame('invalid', $form['test']['#errors']);
 }
Beispiel #10
0
 /**
  * @covers ::getSelected
  *
  * @dataProvider providerTestGetSelected
  */
 public function testGetSelected($expected, $element = [], $parents = [], $user_input = [], $not_rebuilding_expected = NULL)
 {
     $not_rebuilding_expected = $not_rebuilding_expected ?: $expected;
     $form_state = new FormState();
     $form_state->setUserInput($user_input);
     $actual = WizardPluginBase::getSelected($form_state, $parents, 'the_default_value', $element);
     $this->assertSame($not_rebuilding_expected, $actual);
     $this->assertSame($user_input, $form_state->getUserInput());
     $form_state->setRebuild();
     $actual = WizardPluginBase::getSelected($form_state, $parents, 'the_default_value', $element);
     $this->assertSame($expected, $actual);
     $this->assertSame($user_input, $form_state->getUserInput());
 }
 /**
  * Tests that #limit_validation_errors of the only submit button takes effect.
  */
 function testLimitValidationErrors()
 {
     // Programmatically submit the form.
     $form_state = new FormState();
     $form_state->setValue('section', 'one');
     $form_builder = $this->container->get('form_builder');
     $form_builder->submitForm($this, $form_state);
     // Verify that only the specified section was validated.
     $errors = $form_state->getErrors();
     $this->assertTrue(isset($errors['one']), "Section 'one' was validated.");
     $this->assertFalse(isset($errors['two']), "Section 'two' was not validated.");
     // Verify that there are only values for the specified section.
     $this->assertTrue($form_state->hasValue('one'), "Values for section 'one' found.");
     $this->assertFalse($form_state->hasValue('two'), "Values for section 'two' not found.");
 }
 /**
  * Tests the root user account form section in the "Configure site" form.
  */
 function testInstallConfigureForm()
 {
     require_once \Drupal::root() . '/core/includes/install.core.inc';
     require_once \Drupal::root() . '/core/includes/install.inc';
     $install_state = install_state_defaults();
     $form_state = new FormState();
     $form_state->addBuildInfo('args', [&$install_state]);
     $form = $this->container->get('form_builder')->buildForm('Drupal\\Core\\Installer\\Form\\SiteConfigureForm', $form_state);
     // Verify name and pass field order.
     $this->assertFieldOrder($form['admin_account']['account']);
     // Verify that web browsers may autocomplete the email value and
     // autofill/prefill the name and pass values.
     foreach (array('mail', 'name', 'pass') as $key) {
         $this->assertFalse(isset($form['account'][$key]['#attributes']['autocomplete']), "'{$key}' field: 'autocomplete' attribute not found.");
     }
 }
 /**
  * Tests the entity row handler.
  */
 public function testEntityRow()
 {
     $vocab = Vocabulary::create(['name' => $this->randomMachineName(), 'vid' => strtolower($this->randomMachineName())]);
     $vocab->save();
     $term = Term::create(['name' => $this->randomMachineName(), 'vid' => $vocab->id()]);
     $term->save();
     $view = Views::getView('test_entity_row');
     $build = $view->preview();
     $this->render($build);
     $this->assertText($term->getName(), 'The rendered entity appears as row in the view.');
     // Tests the available view mode options.
     $form = array();
     $form_state = new FormState();
     $form_state->set('view', $view->storage);
     $view->rowPlugin->buildOptionsForm($form, $form_state);
     $this->assertTrue(isset($form['view_mode']['#options']['default']), 'Ensure that the default view mode is available');
 }
 /**
  * @covers ::extractFormValues
  */
 public function testExtractFormValues()
 {
     $menu_link_manager = $this->prophesize(MenuLinkManagerInterface::class);
     $menu_parent_form_selector = $this->prophesize(MenuParentFormSelectorInterface::class);
     $module_handler = $this->prophesize(ModuleHandlerInterface::class);
     $menu_link_form = new MenuLinkDefaultForm($menu_link_manager->reveal(), $menu_parent_form_selector->reveal(), $this->getStringTranslationStub(), $module_handler->reveal());
     $static_override = $this->prophesize(StaticMenuLinkOverridesInterface::class);
     $menu_link = new MenuLinkDefault([], 'my_plugin_id', [], $static_override->reveal());
     $menu_link_form->setMenuLinkInstance($menu_link);
     $form_state = new FormState();
     $form_state->setValue('id', 'my_plugin_id');
     $form_state->setValue('enabled', FALSE);
     $form_state->setValue('weight', 5);
     $form_state->setValue('expanded', TRUE);
     $form_state->setValue('menu_parent', 'foo:bar');
     $form = [];
     $result = $menu_link_form->extractFormValues($form, $form_state);
     $this->assertEquals(['id' => 'my_plugin_id', 'enabled' => 0, 'weight' => 5, 'expanded' => 1, 'parent' => 'bar', 'menu_name' => 'foo'], $result);
 }
Beispiel #15
0
 /**
  * @covers ::setCache
  */
 public function testSetCacheWithSafeStrings()
 {
     // A call to SafeMarkup::set() is appropriate in this test as a way to add a
     // string to the safe list in the simplest way possible. Normally, avoid it.
     SafeMarkup::set('a_safe_string');
     $form_build_id = 'the_form_build_id';
     $form = ['#form_id' => 'the_form_id'];
     $form_state = new FormState();
     $this->formCacheStore->expects($this->once())->method('setWithExpire')->with($form_build_id, $form, $this->isType('int'));
     $form_state_data = $form_state->getCacheableArray();
     $form_state_data['build_info']['safe_strings'] = ['a_safe_string' => ['html' => TRUE]];
     $this->formStateCacheStore->expects($this->once())->method('setWithExpire')->with($form_build_id, $form_state_data, $this->isType('int'));
     $this->formCache->setCache($form_build_id, $form, $form_state);
 }
Beispiel #16
0
 /**
  * Check several empty values for required forms elements.
  *
  * Carriage returns, tabs, spaces, and unchecked checkbox elements are not
  * valid content for a required field.
  *
  * If the form field is found in $form_state->getErrors() then the test pass.
  */
 function testRequiredFields()
 {
     // Originates from https://www.drupal.org/node/117748.
     // Sets of empty strings and arrays.
     $empty_strings = array('""' => "", '"\\n"' => "\n", '" "' => " ", '"\\t"' => "\t", '" \\n\\t "' => " \n\t ", '"\\n\\n\\n\\n\\n"' => "\n\n\n\n\n");
     $empty_arrays = array('array()' => array());
     $empty_checkbox = array(NULL);
     $elements['textfield']['element'] = array('#title' => $this->randomMachineName(), '#type' => 'textfield');
     $elements['textfield']['empty_values'] = $empty_strings;
     $elements['telephone']['element'] = array('#title' => $this->randomMachineName(), '#type' => 'tel');
     $elements['telephone']['empty_values'] = $empty_strings;
     $elements['url']['element'] = array('#title' => $this->randomMachineName(), '#type' => 'url');
     $elements['url']['empty_values'] = $empty_strings;
     $elements['search']['element'] = array('#title' => $this->randomMachineName(), '#type' => 'search');
     $elements['search']['empty_values'] = $empty_strings;
     $elements['password']['element'] = array('#title' => $this->randomMachineName(), '#type' => 'password');
     $elements['password']['empty_values'] = $empty_strings;
     $elements['password_confirm']['element'] = array('#title' => $this->randomMachineName(), '#type' => 'password_confirm');
     // Provide empty values for both password fields.
     foreach ($empty_strings as $key => $value) {
         $elements['password_confirm']['empty_values'][$key] = array('pass1' => $value, 'pass2' => $value);
     }
     $elements['textarea']['element'] = array('#title' => $this->randomMachineName(), '#type' => 'textarea');
     $elements['textarea']['empty_values'] = $empty_strings;
     $elements['radios']['element'] = array('#title' => $this->randomMachineName(), '#type' => 'radios', '#options' => array('' => t('None'), $this->randomMachineName(), $this->randomMachineName(), $this->randomMachineName()));
     $elements['radios']['empty_values'] = $empty_arrays;
     $elements['checkbox']['element'] = array('#title' => $this->randomMachineName(), '#type' => 'checkbox', '#required' => TRUE);
     $elements['checkbox']['empty_values'] = $empty_checkbox;
     $elements['checkboxes']['element'] = array('#title' => $this->randomMachineName(), '#type' => 'checkboxes', '#options' => array($this->randomMachineName(), $this->randomMachineName(), $this->randomMachineName()));
     $elements['checkboxes']['empty_values'] = $empty_arrays;
     $elements['select']['element'] = array('#title' => $this->randomMachineName(), '#type' => 'select', '#options' => array('' => t('None'), $this->randomMachineName(), $this->randomMachineName(), $this->randomMachineName()));
     $elements['select']['empty_values'] = $empty_strings;
     $elements['file']['element'] = array('#title' => $this->randomMachineName(), '#type' => 'file');
     $elements['file']['empty_values'] = $empty_strings;
     // Regular expression to find the expected marker on required elements.
     $required_marker_preg = '@<.*?class=".*?form-required.*?">@';
     // Go through all the elements and all the empty values for them.
     foreach ($elements as $type => $data) {
         foreach ($data['empty_values'] as $key => $empty) {
             foreach (array(TRUE, FALSE) as $required) {
                 $form_id = $this->randomMachineName();
                 $form = array();
                 $form_state = new FormState();
                 $form['op'] = array('#type' => 'submit', '#value' => t('Submit'));
                 $element = $data['element']['#title'];
                 $form[$element] = $data['element'];
                 $form[$element]['#required'] = $required;
                 $user_input[$element] = $empty;
                 $user_input['form_id'] = $form_id;
                 $form_state->setUserInput($user_input);
                 $form_state->setFormObject(new StubForm($form_id, $form));
                 $form_state->setMethod('POST');
                 // The form token CSRF protection should not interfere with this test,
                 // so we bypass it by setting the token to FALSE.
                 $form['#token'] = FALSE;
                 \Drupal::formBuilder()->prepareForm($form_id, $form, $form_state);
                 \Drupal::formBuilder()->processForm($form_id, $form, $form_state);
                 $errors = $form_state->getErrors();
                 // Form elements of type 'radios' throw all sorts of PHP notices
                 // when you try to render them like this, so we ignore those for
                 // testing the required marker.
                 // @todo Fix this work-around (https://www.drupal.org/node/588438).
                 $form_output = $type == 'radios' ? '' : \Drupal::service('renderer')->renderRoot($form);
                 if ($required) {
                     // Make sure we have a form error for this element.
                     $this->assertTrue(isset($errors[$element]), "Check empty({$key}) '{$type}' field '{$element}'");
                     if (!empty($form_output)) {
                         // Make sure the form element is marked as required.
                         $this->assertTrue(preg_match($required_marker_preg, $form_output), "Required '{$type}' field is marked as required");
                     }
                 } else {
                     if (!empty($form_output)) {
                         // Make sure the form element is *not* marked as required.
                         $this->assertFalse(preg_match($required_marker_preg, $form_output), "Optional '{$type}' field is not marked as required");
                     }
                     if ($type == 'select') {
                         // Select elements are going to have validation errors with empty
                         // input, since those are illegal choices. Just make sure the
                         // error is not "field is required".
                         $this->assertTrue(empty($errors[$element]) || strpos('field is required', $errors[$element]) === FALSE, "Optional '{$type}' field '{$element}' is not treated as a required element");
                     } else {
                         // Make sure there is *no* form error for this element.
                         $this->assertTrue(empty($errors[$element]), "Optional '{$type}' field '{$element}' has no errors with empty input");
                     }
                 }
             }
         }
     }
     // Clear the expected form error messages so they don't appear as exceptions.
     drupal_get_messages();
 }
 /**
  * Helper function for the option check test to submit a form while collecting errors.
  *
  * @param $form_element
  *   A form element to test.
  * @param $edit
  *   An array containing post data.
  *
  * @return
  *   An array containing the processed form, the form_state and any errors.
  */
 private function formSubmitHelper($form, $edit)
 {
     $form_id = $this->randomMachineName();
     $form_state = new FormState();
     $form['op'] = array('#type' => 'submit', '#value' => t('Submit'));
     // The form token CSRF protection should not interfere with this test, so we
     // bypass it by setting the token to FALSE.
     $form['#token'] = FALSE;
     $edit['form_id'] = $form_id;
     // Disable page redirect for forms submitted programmatically. This is a
     // solution to skip the redirect step (there are no pages, then the redirect
     // isn't possible).
     $form_state->disableRedirect();
     $form_state->setUserInput($edit);
     $form_state->setFormObject(new StubForm($form_id, $form));
     \Drupal::formBuilder()->prepareForm($form_id, $form, $form_state);
     \Drupal::formBuilder()->processForm($form_id, $form, $form_state);
     $errors = $form_state->getErrors();
     // Clear errors and messages.
     drupal_get_messages();
     $form_state->clearErrors();
     // Return the processed form together with form_state and errors
     // to allow the caller lowlevel access to the form.
     return array($form, $form_state, $errors);
 }
 /**
  * Tests the handling of a redirect when FormStateInterface::$response exists.
  */
 public function testHandleRedirectWithResponse()
 {
     $form_id = 'test_form_id';
     $expected_form = $form_id();
     // Set up a response that will be used.
     $response = $this->getMockBuilder('Symfony\\Component\\HttpFoundation\\Response')->disableOriginalConstructor()->getMock();
     // Set up a redirect that will not be called.
     $redirect = $this->getMockBuilder('Symfony\\Component\\HttpFoundation\\RedirectResponse')->disableOriginalConstructor()->getMock();
     $form_arg = $this->getMockForm($form_id, $expected_form);
     $form_arg->expects($this->any())->method('submitForm')->will($this->returnCallback(function ($form, FormStateInterface $form_state) use($response, $redirect) {
         // Set both the response and the redirect.
         $form_state->setResponse($response);
         $form_state->set('redirect', $redirect);
     }));
     $form_state = new FormState();
     try {
         $input['form_id'] = $form_id;
         $form_state->setUserInput($input);
         $this->simulateFormSubmission($form_id, $form_arg, $form_state, FALSE);
         $this->fail('EnforcedResponseException was not thrown.');
     } catch (EnforcedResponseException $e) {
         $this->assertSame($response, $e->getResponse());
     }
     $this->assertSame($response, $form_state->getResponse());
 }
Beispiel #19
0
 /**
  * {@inheritdoc}
  */
 public function processForm($form_id, &$form, FormStateInterface &$form_state)
 {
     $form_state->setValues([]);
     // With GET, these forms are always submitted if requested.
     if ($form_state->isMethodType('get') && $form_state->getAlwaysProcess()) {
         $input = $form_state->getUserInput();
         if (!isset($input['form_build_id'])) {
             $input['form_build_id'] = $form['#build_id'];
         }
         if (!isset($input['form_id'])) {
             $input['form_id'] = $form_id;
         }
         if (!isset($input['form_token']) && isset($form['#token'])) {
             $input['form_token'] = $this->csrfToken->get($form['#token']);
         }
         $form_state->setUserInput($input);
     }
     // self::doBuildForm() finishes building the form by calling element
     // #process functions and mapping user input, if any, to #value properties,
     // and also storing the values in $form_state->getValues(). We need to
     // retain the unprocessed $form in case it needs to be cached.
     $unprocessed_form = $form;
     $form = $this->doBuildForm($form_id, $form, $form_state);
     // Only process the input if we have a correct form submission.
     if ($form_state->isProcessingInput()) {
         // Form values for programmed form submissions typically do not include a
         // value for the submit button. But without a triggering element, a
         // potentially existing #limit_validation_errors property on the primary
         // submit button is not taken account. Therefore, check whether there is
         // exactly one submit button in the form, and if so, automatically use it
         // as triggering_element.
         $buttons = $form_state->getButtons();
         if ($form_state->isProgrammed() && !$form_state->getTriggeringElement() && count($buttons) == 1) {
             $form_state->setTriggeringElement(reset($buttons));
         }
         $this->formValidator->validateForm($form_id, $form, $form_state);
         // \Drupal\Component\Utility\Html::getUniqueId() maintains a cache of
         // element IDs it has seen, so it can prevent duplicates. We want to be
         // sure we reset that cache when a form is processed, so scenarios that
         // result in the form being built behind the scenes and again for the
         // browser don't increment all the element IDs needlessly.
         if (!FormState::hasAnyErrors()) {
             // In case of errors, do not break HTML IDs of other forms.
             Html::resetSeenIds();
         }
         // If there are no errors and the form is not rebuilding, submit the form.
         if (!$form_state->isRebuilding() && !FormState::hasAnyErrors()) {
             $submit_response = $this->formSubmitter->doSubmitForm($form, $form_state);
             // If this form was cached, delete it from the cache after submission.
             if ($form_state->isCached()) {
                 $this->deleteCache($form['#build_id']);
             }
             // If the form submission directly returned a response, return it now.
             if ($submit_response) {
                 return $submit_response;
             }
         }
         // Don't rebuild or cache form submissions invoked via self::submitForm().
         if ($form_state->isProgrammed()) {
             return;
         }
         // If $form_state->isRebuilding() has been set and input has been
         // processed without validation errors, we are in a multi-step workflow
         // that is not yet complete. A new $form needs to be constructed based on
         // the changes made to $form_state during this request. Normally, a submit
         // handler sets $form_state->isRebuilding() if a fully executed form
         // requires another step. However, for forms that have not been fully
         // executed (e.g., Ajax submissions triggered by non-buttons), there is no
         // submit handler to set $form_state->isRebuilding(). It would not make
         // sense to redisplay the identical form without an error for the user to
         // correct, so we also rebuild error-free non-executed forms, regardless
         // of $form_state->isRebuilding().
         // @todo Simplify this logic; considering Ajax and non-HTML front-ends,
         //   along with element-level #submit properties, it makes no sense to
         //   have divergent form execution based on whether the triggering element
         //   has #executes_submit_callback set to TRUE.
         if (($form_state->isRebuilding() || !$form_state->isExecuted()) && !FormState::hasAnyErrors()) {
             // Form building functions (e.g., self::handleInputElement()) may use
             // $form_state->isRebuilding() to determine if they are running in the
             // context of a rebuild, so ensure it is set.
             $form_state->setRebuild();
             $form = $this->rebuildForm($form_id, $form_state, $form);
         }
     }
     // After processing the form, the form builder or a #process callback may
     // have called $form_state->setCached() to indicate that the form and form
     // state shall be cached. But the form may only be cached if
     // $form_state->disableCache() is not called. Only cache $form as it was
     // prior to self::doBuildForm(), because self::doBuildForm() must run for
     // each request to accommodate new user input. Rebuilt forms are not cached
     // here, because self::rebuildForm() already takes care of that.
     if (!$form_state->isRebuilding() && $form_state->isCached()) {
         $this->setCache($form['#build_id'], $unprocessed_form, $form_state);
     }
 }
Beispiel #20
0
 /**
  * Form submit handler to flush Mollom session and form information from cache.
  *
  * This is necessary as the entity forms will no longer automatically save
  * the data with the entity.
  *
  * @todo: Possible problems:
  *   - This submit handler is invoked too late; the primary submit handler might
  *     send out e-mails directly after saving the entity (e.g.,
  *     user_register_form_submit()), so mollom_mail_alter() is invoked before
  *     Mollom session data has been saved.
  */
 public static function submitForm($form, FormState $form_state)
 {
     // Some modules are implementing multi-step forms without separate form
     // submit handlers. In case we reach here and the form will be rebuilt, we
     // need to defer our submit handling until final submission.
     $is_rebuilding = $form_state->isRebuilding();
     if ($is_rebuilding) {
         return;
     }
     $mollom = $form_state->getValue('mollom');
     $form_object = $form_state->getFormObject();
     // If an 'entity' and a 'post_id' mapping was provided via
     // hook_mollom_form_info(), try to automatically store Mollom session data.
     if (empty($mollom) || empty($mollom['entity']) || !$form_state->getFormObject() instanceof EntityFormInterface) {
         return;
     }
     /* @var $form_object \Drupal\Core\Entity\EntityFormInterface */
     $entity_id = $form_object->getEntity()->id();
     $data = (object) $mollom;
     $data->id = $entity_id;
     $data->moderate = $mollom['require_moderation'] ? 1 : 0;
     $stored_data = ResponseDataStorage::save($data);
     $form_state->setValue(['mollom', 'data'], $stored_data);
 }
 /**
  * @covers ::actions
  * @covers ::getPaymentMethodManager
  */
 public function testActionsWithoutAvailablePlugins()
 {
     $form = [];
     $form_state = new FormState();
     $form_state->set('plugin_selector', $this->pluginSelector);
     $this->paymentMethodManager->expects($this->atLeastOnce())->method('getDefinitions')->willReturn([]);
     $method = new \ReflectionMethod($this->sut, 'actions');
     $method->setAccessible(TRUE);
     $actions = $method->invokeArgs($this->sut, [$form, $form_state]);
     $this->assertTrue($actions['submit']['#disabled']);
 }
Beispiel #22
0
 /**
  * {@inheritdoc}
  */
 public static function hasAnyErrors()
 {
     return FormState::hasAnyErrors();
 }
 /**
  * @covers ::copyFormValuesToEntity
  */
 public function testCopyFormValuesToEntity()
 {
     $description = $this->randomMachineName();
     $id = $this->randomMachineName();
     $label = $this->randomMachineName();
     $parent_id = $this->randomMachineName();
     $this->paymentStatus->expects($this->once())->method('setDescription')->with($description);
     $this->paymentStatus->expects($this->once())->method('setId')->with($id);
     $this->paymentStatus->expects($this->once())->method('setLabel')->with($label);
     $this->paymentStatus->expects($this->once())->method('setParentId')->with($parent_id);
     $parent_status = $this->getMock(PluginSelectorInterface::class);
     $parent_status->expects($this->atLeastOnce())->method('getPluginId')->willReturn($parent_id);
     $parent_selector = $this->getMock(PluginSelectorInterface::class);
     $parent_selector->expects($this->atLeastOnce())->method('getSelectedPlugin')->willReturn($parent_status);
     $this->pluginSelectorManager->expects($this->atLeastOnce())->method('createInstance')->willReturn($parent_selector);
     $form = [];
     $form_state = new FormState();
     $form_state->setValue('description', $description);
     $form_state->setValue('id', $id);
     $form_state->setValue('label', $label);
     $form_state->setValue('parent_id', $parent_id);
     $method = new \ReflectionMethod($this->sut, 'copyFormValuesToEntity');
     $method->setAccessible(TRUE);
     $method->invokeArgs($this->sut, array($this->paymentStatus, $form, $form_state));
 }
 /**
  * {@inheritdoc}
  */
 public function submitForm(array &$form, FormStateInterface $form_state)
 {
     $pass = $form_state->getValue('filter_pass') ? explode(',', $form_state->getValue('filter_pass')) : array();
     $fail = $form_state->getValue('filter_fail') ? explode(',', $form_state->getValue('filter_fail')) : array();
     if ($form_state->getValue('filter') == 'all') {
         $classes = array_merge($pass, $fail);
     } elseif ($form_state->getValue('filter') == 'pass') {
         $classes = $pass;
     } else {
         $classes = $fail;
     }
     if (!$classes) {
         $form_state->setRedirect('simpletest.test_form');
         return;
     }
     $form_execute = array();
     $form_state_execute = new FormState();
     foreach ($classes as $class) {
         $form_state_execute->setValue(['tests', $class], $class);
     }
     // Submit the simpletest test form to rerun the tests.
     // Under normal circumstances, a form object's submitForm() should never be
     // called directly, FormBuilder::submitForm() should be called instead.
     // However, it calls $form_state->setProgrammed(), which disables the Batch API.
     $simpletest_test_form = SimpletestTestForm::create(\Drupal::getContainer());
     $simpletest_test_form->buildForm($form_execute, $form_state_execute);
     $simpletest_test_form->submitForm($form_execute, $form_state_execute);
     if ($redirect = $form_state_execute->getRedirect()) {
         $form_state->setRedirectUrl($redirect);
     }
 }
Beispiel #25
0
 /**
  * Build the query for the view.
  */
 public function build($display_id = NULL)
 {
     if (!empty($this->built)) {
         return;
     }
     if (empty($this->current_display) || $display_id) {
         if (!$this->setDisplay($display_id)) {
             return FALSE;
         }
     }
     // Let modules modify the view just prior to building it.
     $module_handler = \Drupal::moduleHandler();
     $module_handler->invokeAll('views_pre_build', array($this));
     // Attempt to load from cache.
     // @todo Load a build_info from cache.
     $start = microtime(TRUE);
     // If that fails, let's build!
     $this->build_info = array('query' => '', 'count_query' => '', 'query_args' => array());
     $this->initQuery();
     // Call a module hook and see if it wants to present us with a
     // pre-built query or instruct us not to build the query for
     // some reason.
     // @todo: Implement this. Use the same mechanism Panels uses.
     // Run through our handlers and ensure they have necessary information.
     $this->initHandlers();
     // Let the handlers interact with each other if they really want.
     $this->_preQuery();
     if ($this->display_handler->usesExposed()) {
         $exposed_form = $this->display_handler->getPlugin('exposed_form');
         $this->exposed_widgets = $exposed_form->renderExposedForm();
         if (FormState::hasAnyErrors() || !empty($this->build_info['abort'])) {
             $this->built = TRUE;
             // Don't execute the query, $form_state, but rendering will still be executed to display the empty text.
             $this->executed = TRUE;
             return empty($this->build_info['fail']);
         }
     }
     // Build all the relationships first thing.
     $this->_build('relationship');
     // Set the filtering groups.
     if (!empty($this->filter)) {
         $filter_groups = $this->display_handler->getOption('filter_groups');
         if ($filter_groups) {
             $this->query->setGroupOperator($filter_groups['operator']);
             foreach ($filter_groups['groups'] as $id => $operator) {
                 $this->query->setWhereGroup($operator, $id);
             }
         }
     }
     // Build all the filters.
     $this->_build('filter');
     $this->build_sort = TRUE;
     // Arguments can, in fact, cause this whole thing to abort.
     if (!$this->_buildArguments()) {
         $this->build_time = microtime(TRUE) - $start;
         $this->attachDisplays();
         return $this->built;
     }
     // Initialize the style; arguments may have changed which style we use,
     // so waiting as long as possible is important. But we need to know
     // about the style when we go to build fields.
     if (!$this->initStyle()) {
         $this->build_info['fail'] = TRUE;
         return FALSE;
     }
     if ($this->style_plugin->usesFields()) {
         $this->_build('field');
     }
     // Build our sort criteria if we were instructed to do so.
     if (!empty($this->build_sort)) {
         // Allow the style handler to deal with sorting.
         if ($this->style_plugin->buildSort()) {
             $this->_build('sort');
         }
         // allow the plugin to build second sorts as well.
         $this->style_plugin->buildSortPost();
     }
     // Allow area handlers to affect the query.
     $this->_build('header');
     $this->_build('footer');
     $this->_build('empty');
     // Allow display handler to affect the query:
     $this->display_handler->query($this->display_handler->useGroupBy());
     // Allow style handler to affect the query:
     $this->style_plugin->query($this->display_handler->useGroupBy());
     // Allow exposed form to affect the query:
     if (isset($exposed_form)) {
         $exposed_form->query();
     }
     if (\Drupal::config('views.settings')->get('sql_signature')) {
         $this->query->addSignature($this);
     }
     // Let modules modify the query just prior to finalizing it.
     $this->query->alter($this);
     // Only build the query if we weren't interrupted.
     if (empty($this->built)) {
         // Build the necessary info to execute the query.
         $this->query->build($this);
     }
     $this->built = TRUE;
     $this->build_time = microtime(TRUE) - $start;
     // Attach displays
     $this->attachDisplays();
     // Let modules modify the view just after building it.
     $module_handler->invokeAll('views_post_build', array($this));
     return TRUE;
 }
Beispiel #26
0
 /**
  * @covers ::doBuildForm
  *
  * @dataProvider providerTestInvalidToken
  */
 public function testInvalidToken($expected, $valid_token, $user_is_authenticated)
 {
     $form_token = 'the_form_token';
     $form_id = 'test_form_id';
     if (is_bool($valid_token)) {
         $this->csrfToken->expects($this->any())->method('get')->willReturnArgument(0);
         $this->csrfToken->expects($this->atLeastOnce())->method('validate')->willReturn($valid_token);
     }
     $current_user = $this->prophesize(AccountInterface::class);
     $current_user->isAuthenticated()->willReturn($user_is_authenticated);
     $property = new \ReflectionProperty(FormBuilder::class, 'currentUser');
     $property->setAccessible(TRUE);
     $property->setValue($this->formBuilder, $current_user->reveal());
     $expected_form = $form_id();
     $form_arg = $this->getMockForm($form_id, $expected_form);
     $form_state = new FormState();
     $input['form_id'] = $form_id;
     $input['form_token'] = $form_token;
     $form_state->setUserInput($input);
     $this->simulateFormSubmission($form_id, $form_arg, $form_state, FALSE);
     $this->assertSame($expected, $form_state->hasInvalidToken());
 }
 /**
  * @covers ::setCache
  */
 public function testSetCacheImmutableForm()
 {
     $form_build_id = 'the_form_build_id';
     $form = ['#form_id' => 'the_form_id'];
     $form_state = new FormState();
     $this->formCacheStore->expects($this->once())->method('setWithExpire')->with($form_build_id, $form, $this->isType('int'));
     $form_state_data = $form_state->getCacheableArray();
     $form_state_data['build_info']['safe_strings'] = [];
     // Ensure that the form is marked immutable.
     $form_state_data['build_info']['immutable'] = TRUE;
     $this->formStateCacheStore->expects($this->once())->method('setWithExpire')->with($form_build_id, $form_state_data, $this->isType('int'));
     // Rebuild the FormCache with a config factory that will return a config
     // object with the internal page cache enabled.
     $this->configFactory = $this->getConfigFactoryStub(['system.performance' => ['cache.page.use_internal' => TRUE]]);
     $this->formCache = $this->getMockBuilder('Drupal\\Core\\Form\\FormCache')->setConstructorArgs([$this->keyValueExpirableFactory, $this->moduleHandler, $this->account, $this->csrfToken, $this->logger, $this->configFactory, $this->requestStack, $this->requestPolicy])->setMethods(['isPageCacheable'])->getMock();
     $this->formCache->expects($this->once())->method('isPageCacheable')->willReturn(TRUE);
     $this->formCache->setCache($form_build_id, $form, $form_state);
 }
Beispiel #28
0
 /**
  * @covers ::setCache
  */
 public function testSetCacheAuthUser()
 {
     $form_build_id = 'the_form_build_id';
     $form = [];
     $form_state = new FormState();
     $cache_token = 'the_cache_token';
     $form_data = $form;
     $form_data['#cache_token'] = $cache_token;
     $this->formCacheStore->expects($this->once())->method('setWithExpire')->with($form_build_id, $form_data, $this->isType('int'));
     $form_state_data = $form_state->getCacheableArray();
     $this->formStateCacheStore->expects($this->once())->method('setWithExpire')->with($form_build_id, $form_state_data, $this->isType('int'));
     $this->csrfToken->expects($this->once())->method('get')->willReturn($cache_token);
     $this->account->expects($this->once())->method('isAuthenticated')->willReturn(TRUE);
     $this->formCache->setCache($form_build_id, $form, $form_state);
 }
 /**
  * @covers ::setCache
  */
 public function testSetCacheWithSafeStrings()
 {
     SafeMarkup::set('a_safe_string');
     $form_build_id = 'the_form_build_id';
     $form = ['#form_id' => 'the_form_id'];
     $form_state = new FormState();
     $this->formCacheStore->expects($this->once())->method('setWithExpire')->with($form_build_id, $form, $this->isType('int'));
     $form_state_data = $form_state->getCacheableArray();
     $form_state_data['build_info']['safe_strings'] = ['a_safe_string' => ['html' => TRUE]];
     $this->formStateCacheStore->expects($this->once())->method('setWithExpire')->with($form_build_id, $form_state_data, $this->isType('int'));
     $this->formCache->setCache($form_build_id, $form, $form_state);
 }
 /**
  * @covers ::submitForm
  * @covers ::getPluginSelector
  */
 public function testSubmitForm()
 {
     $form = ['plugin_selector' => ['foo' => $this->randomMachineName()]];
     $form_state = new FormState();
     $form_state->setValues(['plugin_selector_id' => $this->configFactoryConfiguration['payment_form.payment_type']['plugin_selector_id'], 'allowed_plugin_ids' => $this->configFactoryConfiguration['payment_form.payment_type']['allowed_plugin_ids'], 'limit_allowed_plugins' => $this->configFactoryConfiguration['payment_form.payment_type']['limit_allowed_plugins']]);
     $map = [['payment_radios', [], $this->pluginSelector], [$this->configFactoryConfiguration['payment_form.payment_type']['plugin_selector_id'], [], $this->selectedPluginSelector]];
     $this->pluginSelectorManager->expects($this->atLeast(count($map)))->method('createInstance')->willReturnMap($map);
     $this->pluginSelector->expects($this->once())->method('submitSelectorForm')->with($form['plugin_selector'], $form_state);
     $this->pluginSelector->expects($this->once())->method('getSelectedPlugin')->willReturn($this->selectedPluginSelector);
     $this->sut->submitForm($form, $form_state);
 }