/**
  * {@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);
 }
示例#2
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);
 }
示例#4
0
 /**
  * @covers ::prepareCallback
  */
 public function testPrepareCallbackArray()
 {
     $form_state = new FormState();
     $form_state->setFormObject(new PrepareCallbackTestForm());
     $callback = [$form_state->getFormObject(), 'buildForm'];
     $processed_callback = $form_state->prepareCallback($callback);
     $this->assertEquals($callback, $processed_callback);
 }