class FormAjaxSubscriber
Same name in other branches
- 9 core/lib/Drupal/Core/Form/EventSubscriber/FormAjaxSubscriber.php \Drupal\Core\Form\EventSubscriber\FormAjaxSubscriber
- 8.9.x core/lib/Drupal/Core/Form/EventSubscriber/FormAjaxSubscriber.php \Drupal\Core\Form\EventSubscriber\FormAjaxSubscriber
- 11.x core/lib/Drupal/Core/Form/EventSubscriber/FormAjaxSubscriber.php \Drupal\Core\Form\EventSubscriber\FormAjaxSubscriber
Wraps AJAX form submissions that are triggered via an exception.
Hierarchy
- class \Drupal\Core\Form\EventSubscriber\FormAjaxSubscriber implements \Symfony\Component\EventDispatcher\EventSubscriberInterface uses \Drupal\Core\StringTranslation\StringTranslationTrait
Expanded class hierarchy of FormAjaxSubscriber
1 file declares its use of FormAjaxSubscriber
- FormAjaxSubscriberTest.php in core/
tests/ Drupal/ Tests/ Core/ Form/ EventSubscriber/ FormAjaxSubscriberTest.php
1 string reference to 'FormAjaxSubscriber'
- core.services.yml in core/
core.services.yml - core/core.services.yml
1 service uses FormAjaxSubscriber
File
-
core/
lib/ Drupal/ Core/ Form/ EventSubscriber/ FormAjaxSubscriber.php, line 24
Namespace
Drupal\Core\Form\EventSubscriberView source
class FormAjaxSubscriber implements EventSubscriberInterface {
use StringTranslationTrait;
/**
* The form AJAX response builder.
*
* @var \Drupal\Core\Form\FormAjaxResponseBuilderInterface
*/
protected $formAjaxResponseBuilder;
/**
* The messenger.
*
* @var \Drupal\Core\Messenger\MessengerInterface
*/
protected $messenger;
/**
* Constructs a new FormAjaxSubscriber.
*
* @param \Drupal\Core\Form\FormAjaxResponseBuilderInterface $form_ajax_response_builder
* The form AJAX response builder.
* @param \Drupal\Core\StringTranslation\TranslationInterface $string_translation
* The string translation.
* @param \Drupal\Core\Messenger\MessengerInterface $messenger
* The messenger.
*/
public function __construct(FormAjaxResponseBuilderInterface $form_ajax_response_builder, TranslationInterface $string_translation, MessengerInterface $messenger) {
$this->formAjaxResponseBuilder = $form_ajax_response_builder;
$this->stringTranslation = $string_translation;
$this->messenger = $messenger;
}
/**
* Alters the wrapper format if this is an AJAX form request.
*
* @param \Symfony\Component\HttpKernel\Event\ViewEvent $event
* The event to process.
*/
public function onView(ViewEvent $event) {
// To support an AJAX form submission of a form within a block, make the
// later VIEW subscribers process the controller result as though for
// HTML display (i.e., add blocks). During that block building, when the
// submitted form gets processed, an exception gets thrown by
// \Drupal\Core\Form\FormBuilderInterface::buildForm(), allowing
// self::onException() to return an AJAX response instead of an HTML one.
$request = $event->getRequest();
if ($request->query
->has(FormBuilderInterface::AJAX_FORM_REQUEST)) {
$request->query
->set(MainContentViewSubscriber::WRAPPER_FORMAT, 'html');
}
}
/**
* Catches a form AJAX exception and build a response from it.
*
* @param \Symfony\Component\HttpKernel\Event\ExceptionEvent $event
* The event to process.
*/
public function onException(ExceptionEvent $event) {
$exception = $event->getThrowable();
$request = $event->getRequest();
// Render a nice error message in case we have a file upload which exceeds
// the configured upload limit.
if ($exception instanceof BrokenPostRequestException && $request->query
->has(FormBuilderInterface::AJAX_FORM_REQUEST)) {
$this->messenger
->addError($this->t('An unrecoverable error occurred. The uploaded file likely exceeded the maximum file size (@size) that this server supports.', [
'@size' => ByteSizeMarkup::create((int) $exception->getSize()),
]));
$response = new AjaxResponse(NULL, 200);
$status_messages = [
'#type' => 'status_messages',
];
$response->addCommand(new PrependCommand(NULL, $status_messages));
$event->allowCustomResponseCode();
$event->setResponse($response);
return;
}
// Extract the form AJAX exception (it may have been passed to another
// exception before reaching here).
if ($exception = $this->getFormAjaxException($exception)) {
$request = $event->getRequest();
$form = $exception->getForm();
$form_state = $exception->getFormState();
// Set the build ID from the request as the old build ID on the form.
$form['#build_id_old'] = $request->request
->get('form_build_id');
try {
$response = $this->formAjaxResponseBuilder
->buildResponse($request, $form, $form_state, []);
// Since this response is being set in place of an exception, explicitly
// mark this as a 200 status.
$response->setStatusCode(200);
$event->allowCustomResponseCode();
$event->setResponse($response);
} catch (\Exception $e) {
// Otherwise, replace the existing exception with the new one.
$event->setThrowable($e);
}
}
}
/**
* Extracts a form AJAX exception.
*
* @param \Throwable $e
* A generic exception that might contain a form AJAX exception.
*
* @return \Drupal\Core\Form\FormAjaxException|null
* Either the form AJAX exception, or NULL if none could be found.
*/
protected function getFormAjaxException(\Throwable $e) {
$exception = NULL;
while ($e) {
if ($e instanceof FormAjaxException) {
$exception = $e;
break;
}
$e = $e->getPrevious();
}
return $exception;
}
/**
* Wraps format_size()
*
* @return string
* The formatted size.
*
* @deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use
* \Drupal\Core\StringTranslation\ByteSizeMarkup::create() instead.
*
* @see https://www.drupal.org/node/2999981
*/
protected function formatSize($size) {
@trigger_error(__METHOD__ . '() is deprecated in drupal:10.2.0 and is removed from drupal:11.0.0. Use \\Drupal\\Core\\StringTranslation\\ByteSizeMarkup::create() instead. See https://www.drupal.org/node/2999981', E_USER_DEPRECATED);
return format_size($size);
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents() : array {
// Run before exception.logger.
$events[KernelEvents::EXCEPTION] = [
'onException',
51,
];
// Run before main_content_view_subscriber.
$events[KernelEvents::VIEW][] = [
'onView',
1,
];
return $events;
}
}
Members
Title Sort descending | Deprecated | Modifiers | Object type | Summary | Overrides |
---|---|---|---|---|---|
FormAjaxSubscriber::$formAjaxResponseBuilder | protected | property | The form AJAX response builder. | ||
FormAjaxSubscriber::$messenger | protected | property | The messenger. | ||
FormAjaxSubscriber::formatSize | Deprecated | protected | function | Wraps format_size() | |
FormAjaxSubscriber::getFormAjaxException | protected | function | Extracts a form AJAX exception. | ||
FormAjaxSubscriber::getSubscribedEvents | public static | function | |||
FormAjaxSubscriber::onException | public | function | Catches a form AJAX exception and build a response from it. | ||
FormAjaxSubscriber::onView | public | function | Alters the wrapper format if this is an AJAX form request. | ||
FormAjaxSubscriber::__construct | public | function | Constructs a new FormAjaxSubscriber. | ||
StringTranslationTrait::$stringTranslation | protected | property | The string translation service. | 3 | |
StringTranslationTrait::formatPlural | protected | function | Formats a string containing a count of items. | ||
StringTranslationTrait::getNumberOfPlurals | protected | function | Returns the number of plurals supported by a given language. | ||
StringTranslationTrait::getStringTranslation | protected | function | Gets the string translation service. | ||
StringTranslationTrait::setStringTranslation | public | function | Sets the string translation service to use. | 2 | |
StringTranslationTrait::t | protected | function | Translates a string to the current language or to a given language. |
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.