diff --git a/core/lib/Drupal/Core/AjaxController.php b/core/lib/Drupal/Core/AjaxController.php new file mode 100644 index 0000000..d1e0f6b --- /dev/null +++ b/core/lib/Drupal/Core/AjaxController.php @@ -0,0 +1,78 @@ +attributes; + $controller = $_content; + + // We need to clean up the derived information and such so that the + // subrequest can be processed properly without leaking data through. + $attributes->remove('system_path'); + $attributes->remove('_content'); + + // Remove the accept header so the subrequest does not end up back in this + // controller. + $request->headers->remove('accept'); + + $response = $this->container->get('http_kernel')->forward($controller, $attributes->all(), $request->query->all()); + // For successful (HTTP status 200) responses. + if ($response->isOk()) { + // If there is already an AjaxResponse, then return it without + // manipulation. + if (!($response instanceof AjaxResponse)) { + // Pull the content out of the response. + $content = $response->getContent(); + // A page callback could return a render array or a string. + $html = is_string($content) ? $content : drupal_render($content); + $response = new AjaxResponse(); + // The selector for the insert command is NULL as the new content will + // replace the element making the ajax call. The default 'replaceWith' + // behavior can be changed with #ajax['method']. + $response->addCommand(new InsertCommand(NULL, $html)); + $status_messages = theme('status_messages'); + if (!empty($status_messages)) { + $response->addCommand(new PrependCommand(NULL, $status_messages)); + } + } + } + return $response; + } +} + + diff --git a/core/lib/Drupal/Core/EventSubscriber/RouteProcessorSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/RouteProcessorSubscriber.php index 0061530..40ccc65 100644 --- a/core/lib/Drupal/Core/EventSubscriber/RouteProcessorSubscriber.php +++ b/core/lib/Drupal/Core/EventSubscriber/RouteProcessorSubscriber.php @@ -38,7 +38,11 @@ public function __construct(ContentNegotiation $negotiation) { public function onRequestSetController(GetResponseEvent $event) { $request = $event->getRequest(); - if (!$request->attributes->has('_controller') && $this->negotiation->getContentType($request) === 'html') { + if ($request->headers->has('accept') && strpos($request->headers->get('accept'), 'application/vnd.drupal-ajax') !== FALSE && !$request->attributes->has('_content')) { + $request->attributes->set('_content', $request->attributes->get('_controller')); + $request->attributes->set('_controller', '\Drupal\Core\AjaxController::content'); + } + elseif (!$request->attributes->has('_controller') && $this->negotiation->getContentType($request) === 'html') { $request->attributes->set('_controller', '\Drupal\Core\HtmlPageController::content'); } } @@ -55,4 +59,5 @@ static function getSubscribedEvents() { return $events; } + } diff --git a/core/misc/ajax.js b/core/misc/ajax.js index 53351ad..7ca4463 100644 --- a/core/misc/ajax.js +++ b/core/misc/ajax.js @@ -208,6 +208,9 @@ Drupal.ajax = function (base, element, element_settings) { } }, dataType: 'json', + accepts: { + json: 'application/vnd.drupal-ajax' + }, type: 'POST' };