diff core/lib/Drupal/Core/EventSubscriber/MainContentViewSubscriber.php @ 0:4c8ae668cc8c

Initial import (non-working)
author Chris Cannam
date Wed, 29 Nov 2017 16:09:58 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/lib/Drupal/Core/EventSubscriber/MainContentViewSubscriber.php	Wed Nov 29 16:09:58 2017 +0000
@@ -0,0 +1,110 @@
+<?php
+
+namespace Drupal\Core\EventSubscriber;
+
+use Drupal\Core\Cache\CacheableMetadata;
+use Drupal\Core\Cache\CacheableResponseInterface;
+use Drupal\Core\DependencyInjection\ClassResolverInterface;
+use Drupal\Core\Routing\RouteMatchInterface;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent;
+use Symfony\Component\HttpKernel\KernelEvents;
+
+/**
+ * View subscriber rendering main content render arrays into responses.
+ *
+ * Additional target rendering formats can be defined by adding another service
+ * that implements \Drupal\Core\Render\MainContent\MainContentRendererInterface
+ * and tagging it as a @code render.main_content_renderer @endcode, then
+ * \Drupal\Core\Render\MainContent\MainContentRenderersPass will detect it and
+ * use it when appropriate.
+ *
+ * @see \Drupal\Core\Render\MainContent\MainContentRendererInterface
+ * @see \Drupal\Core\Render\MainContentControllerPass
+ */
+class MainContentViewSubscriber implements EventSubscriberInterface {
+
+  /**
+   * The class resolver service.
+   *
+   * @var \Drupal\Core\Controller\ControllerResolverInterface
+   */
+  protected $classResolver;
+
+  /**
+   * The current route match.
+   *
+   * @var \Drupal\Core\Routing\RouteMatchInterface
+   */
+  protected $routeMatch;
+
+  /**
+   * The available main content renderer services, keyed per format.
+   *
+   * @var array
+   */
+  protected $mainContentRenderers;
+
+  /**
+   * URL query attribute to indicate the wrapper used to render a request.
+   *
+   * The wrapper format determines how the HTML is wrapped, for example in a
+   * modal dialog.
+   */
+  const WRAPPER_FORMAT = '_wrapper_format';
+
+  /**
+   * Constructs a new MainContentViewSubscriber object.
+   *
+   * @param \Drupal\Core\DependencyInjection\ClassResolverInterface $class_resolver
+   *   The class resolver service.
+   * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
+   *   The current route match.
+   * @param array $main_content_renderers
+   *   The available main content renderer service IDs, keyed by format.
+   */
+  public function __construct(ClassResolverInterface $class_resolver, RouteMatchInterface $route_match, array $main_content_renderers) {
+    $this->classResolver = $class_resolver;
+    $this->routeMatch = $route_match;
+    $this->mainContentRenderers = $main_content_renderers;
+  }
+
+  /**
+   * Sets a response given a (main content) render array.
+   *
+   * @param \Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent $event
+   *   The event to process.
+   */
+  public function onViewRenderArray(GetResponseForControllerResultEvent $event) {
+    $request = $event->getRequest();
+    $result = $event->getControllerResult();
+
+    // Render the controller result into a response if it's a render array.
+    if (is_array($result) && ($request->query->has(static::WRAPPER_FORMAT) || $request->getRequestFormat() == 'html')) {
+      $wrapper = $request->query->get(static::WRAPPER_FORMAT, 'html');
+
+      // Fall back to HTML if the requested wrapper envelope is not available.
+      $wrapper = isset($this->mainContentRenderers[$wrapper]) ? $wrapper : 'html';
+
+      $renderer = $this->classResolver->getInstanceFromDefinition($this->mainContentRenderers[$wrapper]);
+      $response = $renderer->renderResponse($result, $request, $this->routeMatch);
+      // The main content render array is rendered into a different Response
+      // object, depending on the specified wrapper format.
+      if ($response instanceof CacheableResponseInterface) {
+        $main_content_view_subscriber_cacheability = (new CacheableMetadata())->setCacheContexts(['url.query_args:' . static::WRAPPER_FORMAT]);
+        $response->addCacheableDependency($main_content_view_subscriber_cacheability);
+      }
+      $event->setResponse($response);
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getSubscribedEvents() {
+    $events[KernelEvents::VIEW][] = ['onViewRenderArray'];
+
+    return $events;
+  }
+
+}