Passed
Pull Request — master (#8)
by
unknown
05:29
created

CDNMiddleware::getCdnPath()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 4
c 1
b 0
f 0
nc 2
nop 0
dl 0
loc 7
rs 10
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
  * CDN Path prefix
86
  * @var string
87
  */
88
  private static $cdnpath = '';
89
90
91
 /**
92
  * @config
93
  *
94
  * Add dns-prefetch links to the html head
95
  * @var boolean
96
  */
97
 private static $add_prefetch = false;
98
99
 /**
100
  * Process the request
101
  * @param HTTPRequest $request
102
  * @param $delegate
103
  * @return
104
  */
105
 public function process(HTTPRequest $request, callable $delegate)
106
 {
107
108
  $response = $delegate($request);
109
110
  if (($this->canRun() === true) && ($response !== null)) {
111
   $response->addHeader('X-CDN', 'Enabled');
112
113
   if ($this->getIsAdmin($request) === false) {
114
    $body = $response->getBody();
115
    $this->updateBody($body, $response);
116
    $response->setBody($body);
117
   }
118
119
   if ($this->config()->get('add_debug_headers') == true) {
120
    $response->addHeader('X-CDN-Domain', $this->config()->get('cdn_domain'));
121
    $response->addHeader('X-CDN-Dir', $this->getSubdirectory());
122
   }
123
  }
124
125
  return $response;
126
 }
127
128
 private function canRun()
129
 {
130
  $confEnabled = $this->config()->get('cdn_rewrite');
131
  $devEnabled = ((!Director::isDev()) || ($this->config()->get('enable_in_dev')));
132
133
  return ($confEnabled && $devEnabled);
134
 }
135
136
 private function updateBody(&$body, &$response)
137
 {
138
139
  if ($this->config()->get('rewrite_assets') === true) {
140
   $this->rewriteAssets($body, $response);
141
  }
142
143
  if ($this->config()->get('rewrite_resources') === true) {
144
   $this->rewriteResources($body, $response);
145
  }
146
147
  if ($this->config()->get('rewrite_themes') === true) {
148
   $this->rewriteThemes($body, $response);
149
  }
150
151
  if ($this->config()->get('add_prefetch') === true) {
152
   $this->addPrefetch($body, $response);
153
  }
154
 }
155
156
 private function rewriteAssets(&$body, &$response)
157
 {
158
159
  $cdn = $this->config()->get('cdn_domain');
160
  $subDir = $this->getSubdirectory();
161
  $cdnPath = $this->getCdnPath();
162
163
  $search = [
164
      'src="' . $subDir . 'assets/',
165
      'src="/' . $subDir . 'assets/',
166
      'src=\"/' . $subDir . 'assets/',
167
      'href="/' . $subDir . 'assets/',
168
      Director::absoluteBaseURL() . 'assets/'
169
  ];
170
171
  $replace = [
172
      'src="' . $cdn . '/' . $cdnPath . $subDir . 'assets/',
173
      'src="' . $cdn . '/' . $cdnPath . $subDir . 'assets/',
174
      'src=\"' . $cdn . '/' . $cdnPath . $subDir . 'assets/',
175
      'href="' . $cdn . '/' . $cdnPath . $subDir . 'assets/',
176
      $cdn . '/' . $cdnPath . $subDir . 'assets/'
177
  ];
178
179
  $body = str_replace($search, $replace, $body);
180
181
  if ($this->config()->get('add_debug_headers') == true) {
182
   $response->addHeader('X-CDN-Assets', 'Enabled');
183
  }
184
 }
185
186
 private function rewriteThemes(&$body, &$response)
187
 {
188
189
  $cdn = $this->config()->get('cdn_domain');
190
  $subDir = $this->getSubdirectory();
191
  $cdnPath = $this->getCdnPath();
192
193
  $search = [
194
      'src="' . $subDir . 'themes/',
195
      'src="/' . $subDir . 'themes/',
196
      'src=\"/' . $subDir . 'themes/',
197
      'href="/' . $subDir . 'themes/',
198
      Director::absoluteBaseURL() . 'themes/'
199
  ];
200
201
  $replace = [
202
      'src="' . $cdn . '/' . $cdnPath . $subDir . 'themes/',
203
      'src="' . $cdn . '/' . $cdnPath . $subDir . 'themes/',
204
      'src=\"' . $cdn . '/' . $cdnPath . $subDir . 'themes/',
205
      'href="' . $cdn . '/' . $cdnPath . $subDir . 'themes/',
206
      $cdn . '/' . $cdnPath . $subDir . 'themes/'
207
  ];
208
209
  $body = str_replace($search, $replace, $body);
210
211
  if ($this->config()->get('add_debug_headers') == true) {
212
   $response->addHeader('X-CDN-Themes', 'Enabled');
213
  }
214
 }
215
216
 private function rewriteResources(&$body, &$response)
217
 {
218
219
  $cdn = $this->config()->get('cdn_domain');
220
  $subDir = $this->getSubdirectory();
221
  $cdnPath = $this->getCdnPath();
222
223
  $search = [
224
      'src="/' . $subDir . 'resources/',
225
      'src="' . Director::absoluteBaseURL() . $subDir . 'resources/',
226
      'href="/' . $subDir . 'resources/',
227
      'href="' . Director::absoluteBaseURL() . $subDir . 'resources/'
228
  ];
229
230
  $replace = [
231
      'src="' . $cdn . '/' . $cdnPath . $subDir . 'resources/',
232
      'src="' . $cdn . '/' . $cdnPath . $subDir . 'resources/',
233
      'href="' . $cdn . '/' . $cdnPath . $subDir . 'resources/',
234
      'href="' . $cdn . '/' . $cdnPath . $subDir . 'resources/'
235
  ];
236
237
  $body = str_replace($search, $replace, $body);
238
239
  if ($this->config()->get('add_debug_headers') == true) {
240
   $response->addHeader('X-CDN-Resources', 'Enabled');
241
  }
242
 }
243
244
 private function addPrefetch(&$body, &$response)
245
 {
246
  $prefetchTag = $this->getPrefetchTag();
247
  $body = str_replace('<head>', "<head>" . $prefetchTag, $body);
248
  if ($this->config()->get('add_debug_headers') == true) {
249
   $response->addHeader('X-CDN-Prefetch', 'Enabled');
250
  }
251
 }
252
253
 private function getSubdirectory()
254
 {
255
  $subDir = trim($this->config()->get('subdirectory'), '/');
256
  if ($subDir != "") {
257
   $subDir = $subDir . '/';
258
  }
259
  return $subDir;
260
 }
261
262
 private function getCdnPath()
263
 {
264
    $cdnPath = trim($this->config()->get('cdnpath'), '/');
265
  if ($cdnPath != "") {
266
   $cdnPath = $cdnPath . '/';
267
  }
268
  return $cdnPath;
269
 }
270
271
 private function getPrefetchTag()
272
 {
273
  $atts = [
274
      'rel' => 'dns-prefetch',
275
      'href' => $this->config()->get('cdn_domain')
276
  ];
277
  $pfTag = "\n" . HTML::createTag('link', $atts);
278
279
  return $pfTag;
280
 }
281
282
 /**
283
  * Determine whether the website is being viewed from an admin protected area or not
284
  * (shamelessly based on https://github.com/silverstripe/silverstripe-subsites)
285
  *
286
  * @param  HTTPRequest $request
287
  * @return bool
288
  */
289
 private function getIsAdmin(HTTPRequest $request)
290
 {
291
  $adminPath = AdminRootController::admin_url();
292
  $currentPath = rtrim($request->getURL(), '/') . '/';
293
   if (substr($currentPath, 0, strlen($adminPath)) === $adminPath) {
294
    return true;
295
   }
296
  return false;
297
 }
298
}
299