Passed
Push — master ( 9eae0f...2acd13 )
by Thomas
02:35
created

ServiceWorkerController::phpToJsVar()   B

Complexity

Conditions 7
Paths 7

Size

Total Lines 14
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 7
eloc 12
c 2
b 0
f 0
nc 7
nop 1
dl 0
loc 14
rs 8.8333
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
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 string
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;
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;
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
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('self::phpToJsVar', array_values($map));
150
        $script = str_replace(array_keys($map), $values, $script);
151
        return $script;
152
    }
153
154
    /**
155
     * @param string $file
156
     * @return string
157
     */
158
    protected static function getJsContent($file)
159
    {
160
        $script = file_get_contents($file);
161
        $script = self::replaceConstants($script);
162
        $script = self::minifyJs($script);
163
        return $script;
164
    }
165
166
    /**
167
     * @param string $js
168
     * @return string
169
     */
170
    public static function minifyJs($js)
171
    {
172
        // Remove comments with //
173
        $js = preg_replace('/\n(\s+)?\/\/[^\n]*/', "", $js);
174
        // Remove extra space
175
        $js = preg_replace(["/\s+\n/", "/\n\s+/", "/ +/"], ["\n", "\n ", " "], $js);
176
        return $js;
177
    }
178
179
    /**
180
     * Base URL
181
     * @return string
182
     */
183
    public static function BaseUrl()
184
    {
185
        return Director::absoluteBaseURL();
186
    }
187
188
    /**
189
     * Debug mode
190
     * @return bool
191
     */
192
    public static function DebugMode()
193
    {
194
        return Director::isDev();
195
    }
196
197
    /**
198
     * @return string
199
     */
200
    public static function CacheName()
201
    {
202
        return self::config()->get('version');
203
    }
204
205
    /**
206
     * @return string
207
     */
208
    public static function getEnableClientJs()
209
    {
210
        return self::config()->get('enable_client_js');
211
    }
212
213
    /**
214
     * @param array $manifest
215
     * @return string
216
     */
217
    public static function Version($manifest = [])
218
    {
219
        if (self::config()->get('auto_version') || Director::isDev()) {
220
            $base = Director::baseFolder();
221
            $t = "";
222
            foreach ($manifest as $file) {
223
                $t .= filemtime($base . $file);
224
            }
225
            $t .= filemtime(self::getSwPath());
226
            return md5($t);
227
        }
228
        return self::config()->get('version');
229
    }
230
231
    /**
232
     * A list with file to cache in the install event
233
     * @return array
234
     */
235
    public static function CacheOnInstall()
236
    {
237
        $paths = [];
238
        foreach (ClassInfo::implementorsOf(ServiceWorkerCacheProvider::class) as $class) {
239
            $paths = array_merge($paths, $class::getServiceWorkerCachedPaths());
240
        }
241
        // Make sure we get a proper array even when stuff was deleted
242
        return array_merge([], array_unique($paths));
243
    }
244
245
    public static function get_template_global_variables()
246
    {
247
        return [
248
            'EnableClientJs' => 'getEnableClientJs',
249
        ];
250
    }
251
}
252