Passed
Push — master ( f4a5d0...60523e )
by Tim
03:50
created

CDNMiddleware::addPrefetch()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 2
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
1
<?php
2
namespace DorsetDigital\CDNRewrite;
3
4
use SilverStripe\Control\Middleware\HTTPMiddleware;
5
use SilverStripe\Control\HTTPRequest;
6
use SilverStripe\Core\Config\Configurable;
7
use SilverStripe\Core\Injector\Injectable;
8
use SilverStripe\Control\Director;
9
use SilverStripe\Admin\AdminRootController;
10
use SilverStripe\View\HTML;
11
12
class CDNMiddleware implements HTTPMiddleware
13
{
14
15
 use Injectable;
16
 use Configurable;
17
18
 /**
19
  * @config
20
  *
21
  * Enable rewriting
22
  * @var bool
23
  */
24
 private static $cdn_rewrite = false;
25
26
 /**
27
  * @config
28
  *
29
  * The cdn domain incl. protocol
30
  * @var string
31
  */
32
 private static $cdn_domain = '';
33
34
 /**
35
  * @config
36
  *
37
  * Enable rewrite in dev mode
38
  * @var bool
39
  */
40
 private static $enable_in_dev = false;
41
42
 /**
43
  * @config
44
  *
45
  * should assets be rewritten?
46
  * @var bool
47
  */
48
 private static $rewrite_assets = false;
49
50
 /**
51
  * @config
52
  *
53
  * should resources also be rewritten?
54
  * @var bool
55
  */
56
 private static $rewrite_resources = false;
57
58
 /**
59
  * @config
60
  *
61
  * should themes also be rewritten?
62
  * @var bool
63
  */
64
 private static $rewrite_themes = false;
65
66
 /**
67
  * @config
68
  *
69
  * Add debug headers for each operation
70
  * @var bool
71
  */
72
 private static $add_debug_headers = false;
73
74
 /**
75
  * @config
76
  *
77
  * Subdirectory name for the site
78
  * @var string
79
  */
80
 private static $subdirectory = '';
81
82
 /**
83
  * @config
84
  *
85
  * Add dns-prefetch links to the html head
86
  * @var boolean
87
  */
88
 private static $add_prefetch = false;
89
90
 /**
91
  * Process the request
92
  * @param HTTPRequest $request
93
  * @param $delegate
94
  * @return
95
  */
96
 public function process(HTTPRequest $request, callable $delegate)
97
 {
98
99
  $response = $delegate($request);
100
101
  if (($this->canRun() === true) && ($response !== null)) {
102
   $response->addHeader('X-CDN', 'Enabled');
103
104
   if ($this->getIsAdmin($request) === false) {
105
    $body = $response->getBody();
106
    $this->updateBody($body, $response);
107
    $response->setBody($body);
108
   }
109
110
   if ($this->config()->get('add_debug_headers') == true) {
111
    $response->addHeader('X-CDN-Domain', $this->config()->get('cdn_domain'));
112
    $response->addHeader('X-CDN-Dir', $this->getSubdirectory());
113
   }
114
  }
115
116
  return $response;
117
 }
118
119
 private function canRun()
120
 {
121
  $confEnabled = $this->config()->get('cdn_rewrite');
122
  $devEnabled = ((!Director::isDev()) || ($this->config()->get('enable_in_dev')));
123
124
  return ($confEnabled && $devEnabled);
125
 }
126
127
 private function updateBody(&$body, &$response)
128
 {
129
130
  if ($this->config()->get('rewrite_assets') === true) {
131
   $this->rewriteAssets($body, $response);
132
  }
133
134
  if ($this->config()->get('rewrite_resources') === true) {
135
   $this->rewriteResources($body, $response);
136
  }
137
138
  if ($this->config()->get('rewrite_themes') === true) {
139
   $this->rewriteThemes($body, $response);
140
  }
141
142
  if ($this->config()->get('add_prefetch') === true) {
143
   $this->addPrefetch($body, $response);
144
  }
145
 }
146
147
 private function rewriteAssets(&$body, &$response)
148
 {
149
150
  $cdn = $this->config()->get('cdn_domain');
151
  $subDir = $this->getSubdirectory();
152
153
  $search = [
154
      'src="' . $subDir . 'assets/',
155
      'src="/' . $subDir . 'assets/',
156
      'src=\"/' . $subDir . 'assets/',
157
      'href="/' . $subDir . 'assets/',
158
      Director::absoluteBaseURL() . 'assets/'
159
  ];
160
161
  $replace = [
162
      'src="' . $cdn . '/' . $subDir . 'assets/',
163
      'src="' . $cdn . '/' . $subDir . 'assets/',
164
      'src=\"' . $cdn . '/' . $subDir . 'assets/',
165
      'href="' . $cdn . '/' . $subDir . 'assets/',
166
      $cdn . '/' . $subDir . 'assets/'
167
  ];
168
169
  $body = str_replace($search, $replace, $body);
170
171
  if ($this->config()->get('add_debug_headers') == true) {
172
   $response->addHeader('X-CDN-Assets', 'Enabled');
173
  }
174
 }
175
176
 private function rewriteThemes(&$body, &$response)
177
 {
178
179
  $cdn = $this->config()->get('cdn_domain');
180
  $subDir = $this->getSubdirectory();
181
182
  $search = [
183
      'src="' . $subDir . 'themes/',
184
      'src="/' . $subDir . 'themes/',
185
      'src=\"/' . $subDir . 'themes/',
186
      'href="/' . $subDir . 'themes/',
187
      Director::absoluteBaseURL() . 'themes/'
188
  ];
189
190
  $replace = [
191
      'src="' . $cdn . '/' . $subDir . 'themes/',
192
      'src="' . $cdn . '/' . $subDir . 'themes/',
193
      'src=\"' . $cdn . '/' . $subDir . 'themes/',
194
      'href="' . $cdn . '/' . $subDir . 'themes/',
195
      $cdn . '/' . $subDir . 'themes/'
196
  ];
197
198
  $body = str_replace($search, $replace, $body);
199
200
  if ($this->config()->get('add_debug_headers') == true) {
201
   $response->addHeader('X-CDN-Themes', 'Enabled');
202
  }
203
 }
204
205
 private function rewriteResources(&$body, &$response)
206
 {
207
208
  $cdn = $this->config()->get('cdn_domain');
209
  $subDir = $this->getSubdirectory();
210
211
  $search = [
212
      'src="/' . $subDir . 'resources/',
213
      'src="' . Director::absoluteBaseURL() . $subDir . 'resources/',
214
      'href="/' . $subDir . 'resources/',
215
      'href="' . Director::absoluteBaseURL() . $subDir . 'resources/'
216
  ];
217
218
  $replace = [
219
      'src="' . $cdn . '/' . $subDir . 'resources/',
220
      'src="' . $cdn . '/' . $subDir . 'resources/',
221
      'href="' . $cdn . '/' . $subDir . 'resources/',
222
      'href="' . $cdn . '/' . $subDir . 'resources/'
223
  ];
224
225
  $body = str_replace($search, $replace, $body);
226
227
  if ($this->config()->get('add_debug_headers') == true) {
228
   $response->addHeader('X-CDN-Resources', 'Enabled');
229
  }
230
 }
231
232
 private function addPrefetch(&$body, &$response)
233
 {
234
  $prefetchTag = $this->getPrefetchTag();
235
  $body = str_replace('<head>', "<head>" . $prefetchTag, $body);
236
  if ($this->config()->get('add_debug_headers') == true) {
237
   $response->addHeader('X-CDN-Prefetch', 'Enabled');
238
  }
239
 }
240
241
 private function getSubdirectory()
242
 {
243
  $subDir = trim($this->config()->get('subdirectory'), '/');
244
  if ($subDir != "") {
245
   $subDir = $subDir . '/';
246
  }
247
  return $subDir;
248
 }
249
250
 private function getPrefetchTag()
251
 {
252
  $atts = [
253
      'rel' => 'dns-prefetch',
254
      'href' => $this->config()->get('cdn_domain')
255
  ];
256
  $pfTag = "\n" . HTML::createTag('link', $atts);
257
258
  return $pfTag;
259
 }
260
261
 /**
262
  * Determine whether the website is being viewed from an admin protected area or not
263
  * (shamelessly stolen from https://github.com/silverstripe/silverstripe-subsites)
264
  *
265
  * @param  HTTPRequest $request
266
  * @return bool
267
  */
268
 private function getIsAdmin(HTTPRequest $request)
269
 {
270
  $adminPaths = static::config()->get('admin_url_paths');
271
  $adminPaths[] = AdminRootController::config()->get('url_base') . '/';
272
  $currentPath = rtrim($request->getURL(), '/') . '/';
273
  foreach ($adminPaths as $adminPath) {
274
   if (substr($currentPath, 0, strlen($adminPath)) === $adminPath) {
275
    return true;
276
   }
277
  }
278
  return false;
279
 }
280
}
281