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;
  }
 /**
  * @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());
 }
Beispiel #3
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 #6
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());
 }
Beispiel #7
0
 /**
  * Builds the form state passed to zone members.
  *
  * @param array $member_parents
  *   The parents array indicating the position of the member form.
  * @param \Drupal\Core\Form\FormStateInterface $form_state
  *   The parent form state.
  *
  * @return \Drupal\Core\Form\FormStateInterface
  *   The new member form state.
  */
 protected function buildMemberFormState($member_parents, FormStateInterface $form_state)
 {
     $member_values = $form_state->getValue($member_parents, []);
     $member_user_input = (array) NestedArray::getValue($form_state->getUserInput(), $member_parents);
     $member_form_state = new FormState();
     $member_form_state->setValues($member_values);
     $member_form_state->setUserInput($member_user_input);
     return $member_form_state;
 }
 /**
  * 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.
  *
  * @return \Drupal\Core\Form\FormStateInterface
  *   Child form state object.
  */
 public static function buildChildFormState(EntityFormInterface $controller, FormStateInterface $form_state, EntityInterface $entity, $operation)
 {
     $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->setUserInput($form_state->getUserInput());
     $child_form_state->setValues($form_state->getValues());
     $child_form_state->setStorage($form_state->getStorage());
     $child_form_state->set('form_display', entity_get_form_display($entity->getEntityTypeId(), $entity->bundle(), $operation));
     // 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;
 }
 /**
  * Tests selectItemAjax().
  *
  * GIVEN the embridge search form
  * WHEN the ajax handler for the select button is run
  * THEN an ajax response should be returned with the expected commands.
  *
  * @covers ::selectItemAjax
  *
  * @test
  */
 public function selectItemAjaxAjaxCallbackReturnsSaveSearchCloseDialogWithNoErrors()
 {
     $form = ['#attached' => ['test']];
     $mock_entity_id = 123456789;
     $input = ['result_chosen' => $mock_entity_id];
     $form_state = new FormState();
     $form_state->setUserInput($input);
     $response = $this->form->selectItemAjax($form, $form_state);
     $this->assertInstanceOf('\\Drupal\\Core\\Ajax\\AjaxResponse', $response);
     $commands = $response->getCommands();
     $this->assertNotEmpty($commands);
     $this->assertCount(2, $commands);
     $this->assertEquals('embridgeSearchDialogSave', $commands[0]['command']);
     $expected_values = ['entity_id' => $mock_entity_id];
     $this->assertEquals($expected_values, $commands[0]['values']);
     $this->assertEquals('closeDialog', $commands[1]['command']);
 }