Version 1
[yaffs-website] / web / core / lib / Drupal / Core / EventSubscriber / RssResponseRelativeUrlFilter.php
diff --git a/web/core/lib/Drupal/Core/EventSubscriber/RssResponseRelativeUrlFilter.php b/web/core/lib/Drupal/Core/EventSubscriber/RssResponseRelativeUrlFilter.php
new file mode 100644 (file)
index 0000000..b69317f
--- /dev/null
@@ -0,0 +1,81 @@
+<?php
+
+namespace Drupal\Core\EventSubscriber;
+
+use Drupal\Component\Utility\Html;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
+use Symfony\Component\HttpKernel\KernelEvents;
+
+/**
+ * Subscribes to filter RSS responses, to make relative URIs absolute.
+ */
+class RssResponseRelativeUrlFilter implements EventSubscriberInterface {
+
+  /**
+   * Converts relative URLs to absolute URLs.
+   *
+   * @param \Symfony\Component\HttpKernel\Event\FilterResponseEvent $event
+   *   The response event.
+   */
+  public function onResponse(FilterResponseEvent $event) {
+    // Only care about RSS responses.
+    if (stripos($event->getResponse()->headers->get('Content-Type'), 'application/rss+xml') === FALSE) {
+      return;
+    }
+
+    $response = $event->getResponse();
+    $response->setContent($this->transformRootRelativeUrlsToAbsolute($response->getContent(), $event->getRequest()));
+  }
+
+  /**
+   * Converts all root-relative URLs to absolute URLs in RSS markup.
+   *
+   * Does not change any existing protocol-relative or absolute URLs.
+   *
+   * @param string $rss_markup
+   *   The RSS markup to update.
+   * @param \Symfony\Component\HttpFoundation\Request $request
+   *   The current request.
+   *
+   * @return string
+   *   The updated RSS markup.
+   */
+  protected function transformRootRelativeUrlsToAbsolute($rss_markup, Request $request) {
+    $rss_dom = new \DOMDocument();
+
+    // Load the RSS, if there are parsing errors, abort and return the unchanged
+    // markup.
+    $previous_value = libxml_use_internal_errors(TRUE);
+    $rss_dom->loadXML($rss_markup);
+    $errors = libxml_get_errors();
+    libxml_use_internal_errors($previous_value);
+    if ($errors) {
+      return $rss_markup;
+    }
+
+    // Invoke Html::transformRootRelativeUrlsToAbsolute() on all HTML content
+    // embedded in this RSS feed.
+    foreach ($rss_dom->getElementsByTagName('description') as $node) {
+      $html_markup = $node->nodeValue;
+      if (!empty($html_markup)) {
+        $node->nodeValue = Html::transformRootRelativeUrlsToAbsolute($html_markup, $request->getSchemeAndHttpHost());
+      }
+    }
+
+    return $rss_dom->saveXML();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getSubscribedEvents() {
+    // Should run after any other response subscriber that modifies the markup.
+    // @see \Drupal\Core\EventSubscriber\ActiveLinkResponseFilter
+    $events[KernelEvents::RESPONSE][] = ['onResponse', -512];
+
+    return $events;
+  }
+
+}