/**
  * {@inheritdoc}
  */
 public function buildResponse(Request $request, array $form, FormStateInterface $form_state, array $commands)
 {
     // If the form build ID has changed, issue an Ajax command to update it.
     if (isset($form['#build_id_old']) && $form['#build_id_old'] !== $form['#build_id']) {
         $commands[] = new UpdateBuildIdCommand($form['#build_id_old'], $form['#build_id']);
     }
     // We need to return the part of the form (or some other content) that needs
     // to be re-rendered so the browser can update the page with changed
     // content. It is up to the #ajax['callback'] function of the element (may
     // or may not be a button) that triggered the Ajax request to determine what
     // needs to be rendered.
     $callback = NULL;
     if (($triggering_element = $form_state->getTriggeringElement()) && isset($triggering_element['#ajax']['callback'])) {
         $callback = $triggering_element['#ajax']['callback'];
     }
     $callback = $form_state->prepareCallback($callback);
     if (empty($callback) || !is_callable($callback)) {
         throw new HttpException(500, 'The specified #ajax callback is empty or not callable.');
     }
     $result = call_user_func_array($callback, [&$form, &$form_state, $request]);
     // If the callback is an #ajax callback, the result is a render array, and
     // we need to turn it into an AJAX response, so that we can add any commands
     // we got earlier; typically the UpdateBuildIdCommand when handling an AJAX
     // submit from a cached page.
     if ($result instanceof AjaxResponse) {
         $response = $result;
     } else {
         /** @var \Drupal\Core\Ajax\AjaxResponse $response */
         $response = $this->ajaxRenderer->renderResponse($result, $request, $this->routeMatch);
     }
     foreach ($commands as $command) {
         $response->addCommand($command, TRUE);
     }
     return $response;
 }
 /**
  * @covers ::buildResponse
  */
 public function testBuildResponseWithUpdateCommand()
 {
     $triggering_element = ['#ajax' => ['callback' => function (array $form, FormStateInterface $form_state) {
         return new AjaxResponse([]);
     }]];
     $request = new Request();
     $form = ['#build_id' => 'the_build_id', '#build_id_old' => 'a_new_build_id', 'test' => ['#type' => 'textfield']];
     $form_state = new FormState();
     $form_state->setTriggeringElement($triggering_element);
     $commands = [new AlertCommand('alert!')];
     $commands_expected = [];
     $commands_expected[] = ['command' => 'update_build_id', 'old' => 'a_new_build_id', 'new' => 'the_build_id'];
     $commands_expected[] = ['command' => 'alert', 'text' => 'alert!'];
     $this->renderer->expects($this->never())->method('renderResponse');
     $result = $this->formAjaxResponseBuilder->buildResponse($request, $form, $form_state, $commands);
     $this->assertInstanceOf('\\Drupal\\Core\\Ajax\\AjaxResponse', $result);
     $this->assertSame($commands_expected, $result->getCommands());
 }
Example #3
0
 /**
  * Processes an Ajax form submission.
  *
  * @param \Symfony\Component\HttpFoundation\Request $request
  *   The current request object.
  *
  * @return mixed
  *   Whatever is returned by the triggering element's #ajax['callback']
  *   function. One of:
  *   - A render array containing the new or updated content to return to the
  *     browser. This is commonly an element within the rebuilt form.
  *   - A \Drupal\Core\Ajax\AjaxResponse object containing commands for the
  *     browser to process.
  *
  * @throws \Symfony\Component\HttpKernel\Exception\HttpExceptionInterface
  */
 public function content(Request $request)
 {
     /** @var $ajaxForm \Drupal\system\FileAjaxForm */
     $ajaxForm = $this->getForm($request);
     $form = $ajaxForm->getForm();
     $form_state = $ajaxForm->getFormState();
     $commands = $ajaxForm->getCommands();
     $this->formBuilder->processForm($form['#form_id'], $form, $form_state);
     // We need to return the part of the form (or some other content) that needs
     // to be re-rendered so the browser can update the page with changed content.
     // Since this is the generic menu callback used by many Ajax elements, it is
     // up to the #ajax['callback'] function of the element (may or may not be a
     // button) that triggered the Ajax request to determine what needs to be
     // rendered.
     $callback = NULL;
     /** @var $form_state \Drupal\Core\Form\FormStateInterface */
     if ($triggering_element = $form_state->getTriggeringElement()) {
         $callback = $triggering_element['#ajax']['callback'];
     }
     $callback = $form_state->prepareCallback($callback);
     if (empty($callback) || !is_callable($callback)) {
         throw new HttpException(500, 'The specified #ajax callback is empty or not callable.');
     }
     $result = call_user_func_array($callback, [&$form, &$form_state]);
     // If the callback is an #ajax callback, the result is a render array, and
     // we need to turn it into an AJAX response, so that we can add any commands
     // we got earlier; typically the UpdateBuildIdCommand when handling an AJAX
     // submit from a cached page.
     if ($result instanceof AjaxResponse) {
         $response = $result;
     } else {
         /** @var \Drupal\Core\Ajax\AjaxResponse $response */
         $response = $this->ajaxRenderer->renderResponse($result, $request, $this->routeMatch);
     }
     foreach ($commands as $command) {
         $response->addCommand($command, TRUE);
     }
     return $response;
 }