Passed
Branch master (0f341a)
by Tim
11:11
created

CDNMiddleware::process()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 21
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 11
nc 5
nop 2
dl 0
loc 21
rs 8.7624
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;
1 ignored issue
show
introduced by
The private property $enable_in_dev is not used, and could be removed.
Loading history...
41
42
 /**
43
  * @config
44
  *
45
  * should assets be rewritten?
46
  * @var bool
47
  */
48
 private static $rewrite_assets = false;
1 ignored issue
show
introduced by
The private property $rewrite_assets is not used, and could be removed.
Loading history...
49
50
 /**
51
  * @config
52
  *
53
  * should resources also be rewritten?
54
  * @var bool
55
  */
56
 private static $rewrite_resources = false;
1 ignored issue
show
introduced by
The private property $rewrite_resources is not used, and could be removed.
Loading history...
57
58
 /**
59
  * @config
60
  *
61
  * Add debug headers for each operation
62
  * @var bool
63
  */
64
 private static $add_debug_headers = false;
1 ignored issue
show
introduced by
The private property $add_debug_headers is not used, and could be removed.
Loading history...
65
66
 /**
67
  * @config
68
  *
69
  * Subdirectory name for the site
70
  * @var string
71
  */
72
 private static $subdirectory = '';
73
74
 /**
75
  * @config
76
  * 
77
  * Add dns-prefetch links to the html head
78
  * @var boolean
79
  */
80
 private static $add_prefetch = false;
1 ignored issue
show
introduced by
The private property $add_prefetch is not used, and could be removed.
Loading history...
81
 
82
 
83
 /**
84
  * Process the request
85
  * @param HTTPRequest $request
86
  * @param $delegate
87
  * @return
88
  */
89
 public function process(HTTPRequest $request, callable $delegate)
90
 {
91
92
  $response = $delegate($request);
93
94
  if (($this->canRun() === true) && ($response !== null)) {
95
   $response->addHeader('X-CDN', 'Enabled');
96
97
   if ($this->getIsAdmin($request) === false) {
98
    $body = $response->getBody();
99
    $this->updateBody($body, $response);
100
    $response->setBody($body);
101
   }
102
103
   if ($this->config()->get('add_debug_headers') == true) {
104
    $response->addHeader('X-CDN-Domain', $this->config()->get('cdn_domain'));
105
    $response->addHeader('X-CDN-Dir', $this->getSubdirectory());
106
   }
107
  }
108
109
  return $response;
110
 }
111
112
 private function canRun()
113
 {
114
  $confEnabled = $this->config()->get('cdn_rewrite');
115
  $devEnabled = ((!Director::isDev()) || ($this->config()->get('enable_in_dev')));
116
117
  return ($confEnabled && $devEnabled);
118
 }
119
120
 private function updateBody(&$body, &$response)
121
 {
122
  $cdn = $this->config()->get('cdn_domain');
123
  $subDir = $this->getSubdirectory();
124
125
  if ($this->config()->get('rewrite_assets') === true) {
126
127
   $search = [
128
       'src="' . $subDir . 'assets/',
129
       'src="/' . $subDir . 'assets/',
130
       'src=\"/' . $subDir . 'assets/',
131
       'href="/' . $subDir . 'assets/',
132
       Director::absoluteBaseURL() . 'assets/'
133
   ];
134
135
   $replace = [
136
       'src="' . $cdn . '/' . $subDir . 'assets/',
137
       'src="' . $cdn . '/' . $subDir . 'assets/',
138
       'src=\"' . $cdn . '/' . $subDir . 'assets/',
139
       'href="' . $cdn . '/' . $subDir . 'assets/',
140
       $cdn . '/' . $subDir . 'assets/'
141
   ];
142
143
   $body = str_replace($search, $replace, $body);
144
145
   if ($this->config()->get('add_debug_headers') == true) {
146
    $response->addHeader('X-CDN-Assets', 'Enabled');
147
   }
148
   
149
   if ($this->config()->get('add_prefetch') === true) {
150
     $prefetchTag = $this->getPrefetchTag();
151
     $body = str_replace('<head>', "<head>".$prefetchTag, $body);
152
     if ($this->config()->get('add_debug_headers') == true) {
153
       $response->addHeader('X-CDN-Prefetch', 'Enabled');
154
     }       
155
   }
156
  }
157
158
  if ($this->config()->get('rewrite_resources') === true) {
159
160
   $search = [
161
       'src="/resources/',
162
       'src="' . Director::absoluteBaseURL() . 'resources/',
163
       'href="/resources/',
164
       'href="' . Director::absoluteBaseURL() . 'resources/'
165
   ];
166
167
   $replace = [
168
       'src="' . $cdn . '/resources/',
169
       'src="' . $cdn . '/resources/',
170
       'href="' . $cdn . '/resources/',
171
       'href="' . $cdn . '/resources/'
172
   ];
173
174
   $body = str_replace($search, $replace, $body);
175
176
   if ($this->config()->get('add_debug_headers') == true) {
177
    $response->addHeader('X-CDN-Resources', 'Enabled');
178
   }
179
  }
180
 }
181
182
 private function getSubdirectory()
183
 {
184
  $subDir = trim($this->config()->get('subdirectory'), '/');
185
  if ($subDir != "") {
186
   $subDir = $subDir . '/';
187
  }
188
  return $subDir;
189
 }
190
 
191
 private function getPrefetchTag() 
192
 {
193
   $atts = [
194
     'rel' => 'dns-prefetch',
195
     'href' => $this->config()->get('cdn_domain')
196
   ];
197
   $pfTag = "\n" . HTML::createTag('link', $atts);
198
        
199
   return $pfTag;
200
 }
201
202
 /**
203
  * Determine whether the website is being viewed from an admin protected area or not
204
  * (shamelessly stolen from https://github.com/silverstripe/silverstripe-subsites)
205
  *
206
  * @param  HTTPRequest $request
207
  * @return bool
208
  */
209
 private function getIsAdmin(HTTPRequest $request)
210
 {
211
  $adminPaths = static::config()->get('admin_url_paths');
212
  $adminPaths[] = AdminRootController::config()->get('url_base') . '/';
213
  $currentPath = rtrim($request->getURL(), '/') . '/';
214
  foreach ($adminPaths as $adminPath) {
215
   if (substr($currentPath, 0, strlen($adminPath)) === $adminPath) {
216
    return true;
217
   }
218
  }
219
  return false;
220
 }
221
}
222