PagerPathSubscriber.php 2.62 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<?php

namespace Drupal\tome_static\EventSubscriber;

use Drupal\tome_static\Event\ModifyDestinationEvent;
use Drupal\tome_static\Event\ModifyHtmlEvent;
use Drupal\tome_static\Event\TomeStaticEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
 * Converts pager query parameters to static paths.
 *
 * @internal
 */
class PagerPathSubscriber implements EventSubscriberInterface {

  /**
   * Reacts to a modify destination event.
   *
   * @param \Drupal\tome_static\Event\ModifyDestinationEvent $event
   *   The event.
   */
  public function modifyDestination(ModifyDestinationEvent $event) {
    $destination = $event->getDestination();
    $destination = $this->modifyUrl($destination);
    $event->setDestination($destination);
  }

  /**
   * Reacts to a modify HTML event.
   *
   * @param \Drupal\tome_static\Event\ModifyHtmlEvent $event
   *   The event.
   */
  public function modifyHtml(ModifyHtmlEvent $event) {
    $html = $event->getHtml();
    $path = $event->getPath();
    $document = new \DOMDocument();
    @$document->loadHTML($html);
    $xpath = new \DOMXPath($document);
    /** @var \DOMElement $node */
42
    foreach ($xpath->query('//a[(contains(@href,"?page=") or contains(@href,"&page="))]') as $node) {
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
      $original_href = $node->getAttribute('href');
      if ($original_href[0] === '?') {
        $new_href = strtok($path, '?') . $original_href;
      }
      else {
        $new_href = $original_href;
      }
      $event->addInvokePath($new_href);
      $new_href = $this->modifyUrl($new_href);
      $event->addExcludePath($new_href);
      $html = str_replace($original_href, $new_href, $html);
      $html = str_replace(htmlentities($original_href), $new_href, $html);
    }
    $event->setHtml($html);
  }

  /**
   * Modifies a URL to replace pager query parameters with paths.
   *
   * @param string $url
   *   A URL.
   *
   * @return string
   *   The modified URL.
   */
  protected function modifyUrl($url) {
    parse_str(parse_url($url, PHP_URL_QUERY), $query);
    if ($query && isset($query['page']) && is_numeric($query['page'])) {
      $base_path = preg_replace('/\?.*/', '', $url);
      if ($query['page'] != 0) {
        if ($base_path === '/') {
          $base_path = '';
        }
        $url = $base_path . '/page/' . ($query['page'] + 1);
      }
      else {
        $url = !empty($base_path) ? $base_path : '/';
      }
    }
    return $url;
  }

  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents() {
    $events[TomeStaticEvents::MODIFY_DESTINATION][] = ['modifyDestination'];
    $events[TomeStaticEvents::MODIFY_HTML][] = ['modifyHtml'];
    return $events;
  }

}