ServiceWorkerController   A
last analyzed

Complexity

Total Complexity 29

Size/Duplication

Total Lines 244
Duplicated Lines 0 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
eloc 78
c 4
b 0
f 0
dl 0
loc 244
rs 10
wmc 29

16 Methods

Rating   Name   Duplication   Size   Complexity  
A index() 0 8 1
A getJsConstantsMap() 0 10 1
A getSwPath() 0 5 2
B phpToJsVar() 0 14 7
A client() 0 8 1
A getClientPath() 0 5 2
A CacheOnInstall() 0 8 2
A minifyJs() 0 7 1
A CacheName() 0 3 1
A getJsContent() 0 7 2
A Version() 0 12 4
A BaseUrl() 0 3 1
A get_template_global_variables() 0 4 1
A DebugMode() 0 3 1
A getEnableClientJs() 0 3 1
A replaceConstants() 0 8 1
1
<?php
2
3
namespace LeKoala\SsPwa;
4
5
use SilverStripe\Core\ClassInfo;
6
use SilverStripe\Control\Director;
7
use SilverStripe\Control\Controller;
8
use SilverStripe\Control\HTTPResponse;
9
use SilverStripe\View\TemplateGlobalProvider;
10
11
class ServiceWorkerController extends Controller implements TemplateGlobalProvider
12
{
13
14
    /**
15
     * @var array<string>
16
     */
17
    private static $allowed_actions = [
0 ignored issues
show
introduced by
The private property $allowed_actions is not used, and could be removed.
Loading history...
18
        'index',
19
        'client',
20
    ];
21
22
    /**
23
     * @config
24
     * @var string
25
     */
26
    private static $version = "v1";
0 ignored issues
show
introduced by
The private property $version is not used, and could be removed.
Loading history...
27
28
    /**
29
     * @config
30
     * @var bool
31
     */
32
    private static $auto_version = true;
0 ignored issues
show
introduced by
The private property $auto_version is not used, and could be removed.
Loading history...
33
34
    /**
35
     * @config
36
     * @var bool
37
     */
38
    private static $enable_client_cache = false;
0 ignored issues
show
introduced by
The private property $enable_client_cache is not used, and could be removed.
Loading history...
39
40
    /**
41
     * @config
42
     * @var bool
43
     */
44
    private static $enable_client_js = true;
0 ignored issues
show
introduced by
The private property $enable_client_js is not used, and could be removed.
Loading history...
45
46
    /**
47
     * @config
48
     * @var ?string
49
     */
50
    private static $custom_sw_path = null;
0 ignored issues
show
introduced by
The private property $custom_sw_path is not used, and could be removed.
Loading history...
51
52
    /**
53
     * @config
54
     * @var ?string
55
     */
56
    private static $custom_client_path = null;
0 ignored issues
show
introduced by
The private property $custom_client_path is not used, and could be removed.
Loading history...
57
58
    /**
59
     * @return HTTPResponse
60
     */
61
    public function index()
62
    {
63
        $script = self::getJsContent(self::getSwPath());
64
65
        $resp = $this->getResponse();
66
        $resp->addHeader('Content-Type', 'application/javascript; charset="utf-8"');
67
        $resp->setBody($script);
68
        return $resp;
69
    }
70
71
    /**
72
     * @return HTTPResponse
73
     */
74
    public function client()
75
    {
76
        $script = self::getJsContent(self::getClientPath());
77
78
        $resp = $this->getResponse();
79
        $resp->addHeader('Content-Type', 'application/javascript; charset="utf-8"');
80
        $resp->setBody($script);
81
        return $resp;
82
    }
83
84
85
    /**
86
     * @param mixed $v
87
     * @return mixed
88
     */
89
    public static function phpToJsVar($v)
90
    {
91
        switch (gettype($v)) {
92
            case 'boolean':
93
                return $v ? 'true' : 'false';
94
            case 'integer':
95
            case 'double':
96
                return $v;
97
            case 'string':
98
                return "'$v'";
99
            case 'array':
100
                return '["' . implode('","', $v) . '"]';
101
            default;
102
                return json_encode($v, JSON_PRETTY_PRINT);
103
        }
104
    }
105
106
    /**
107
     * @return string
108
     */
109
    protected static function getSwPath()
110
    {
111
        $custom_path = self::config()->get('custom_sw_path');
112
        $default_path = dirname(__DIR__) . '/ressources/sw.js';
113
        return $custom_path ? $custom_path : $default_path;
114
    }
115
116
    /**
117
     * @return string
118
     */
119
    protected static function getClientPath()
120
    {
121
        $custom_path = self::config()->get('custom_client_path');
122
        $default_path = dirname(__DIR__) . '/ressources/client.js';
123
        return $custom_path ? $custom_path : $default_path;
124
    }
125
126
    /**
127
     * @return array<string,mixed>
128
     */
129
    protected static function getJsConstantsMap()
130
    {
131
        $cacheManifest = self::CacheOnInstall();
132
        return [
133
            'self.__SW_DEBUG' => self::DebugMode(),
134
            'self.__SW_CACHE_NAME' => self::CacheName(),
135
            'self.__SW_VERSION' => self::Version(),
136
            'self.__SW_ENABLE_CLIENT_CACHE' => self::config()->get('enable_client_cache') ?? false,
137
            'self.__SW_CACHE_MANIFEST' => $cacheManifest,
138
            'self.__SW_PUSH_PUBLIC_KEY' => PushSubscription::getPublicKey(),
139
        ];
140
    }
141
142
    /**
143
     * @param string $script
144
     * @return string
145
     */
146
    protected static function replaceConstants($script)
147
    {
148
        $map = self::getJsConstantsMap();
149
        $values = array_map(function ($item) {
150
            return self::phpToJsVar($item);
151
        }, array_values($map));
152
        $script = str_replace(array_keys($map), $values, $script);
153
        return $script;
154
    }
155
156
    /**
157
     * @param string $file
158
     * @return string
159
     */
160
    protected static function getJsContent($file)
161
    {
162
        $script = file_get_contents($file);
163
        $script = $script ? $script : '';
164
        $script = self::replaceConstants($script);
165
        $script = self::minifyJs($script);
166
        return $script;
167
    }
168
169
    /**
170
     * @param string $js
171
     * @return string
172
     */
173
    public static function minifyJs($js)
174
    {
175
        // Remove comments with //
176
        $js = preg_replace('/\n(\s+)?\/\/[^\n]*/', "", $js);
177
        // Remove extra space
178
        $js = preg_replace(["/\s+\n/", "/\n\s+/", "/ +/"], ["\n", "\n ", " "], $js);
179
        return $js;
180
    }
181
182
    /**
183
     * Base URL
184
     * @return string
185
     */
186
    public static function BaseUrl()
187
    {
188
        return Director::absoluteBaseURL();
189
    }
190
191
    /**
192
     * Debug mode
193
     * @return bool
194
     */
195
    public static function DebugMode()
196
    {
197
        return Director::isDev();
198
    }
199
200
    /**
201
     * @return string
202
     */
203
    public static function CacheName()
204
    {
205
        return self::config()->get('version');
206
    }
207
208
    /**
209
     * @return string
210
     */
211
    public static function getEnableClientJs()
212
    {
213
        return self::config()->get('enable_client_js');
214
    }
215
216
    /**
217
     * @param array<mixed> $manifest
218
     * @return string
219
     */
220
    public static function Version($manifest = [])
221
    {
222
        if (self::config()->get('auto_version') || Director::isDev()) {
223
            $base = Director::baseFolder();
224
            $t = "";
225
            foreach ($manifest as $file) {
226
                $t .= filemtime($base . $file);
227
            }
228
            $t .= filemtime(self::getSwPath());
229
            return md5($t);
230
        }
231
        return self::config()->get('version');
232
    }
233
234
    /**
235
     * A list with file to cache in the install event
236
     * @return array<string>
237
     */
238
    public static function CacheOnInstall()
239
    {
240
        $paths = [];
241
        foreach (ClassInfo::implementorsOf(ServiceWorkerCacheProvider::class) as $class) {
242
            $paths = array_merge($paths, $class::getServiceWorkerCachedPaths());
243
        }
244
        // Make sure we get a proper array even when stuff was deleted
245
        return array_merge([], array_unique($paths));
246
    }
247
248
    /**
249
     * @return array<string,string>
250
     */
251
    public static function get_template_global_variables()
252
    {
253
        return [
254
            'EnableClientJs' => 'getEnableClientJs',
255
        ];
256
    }
257
}
258