1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace App\Core\Infrastructure\Utility; |
4
|
|
|
|
5
|
|
|
use FilesystemIterator; |
6
|
|
|
use RecursiveDirectoryIterator; |
7
|
|
|
use RecursiveIteratorIterator; |
8
|
|
|
|
9
|
|
|
/** |
10
|
|
|
* Adds version number to js imports to break cache on version change. |
11
|
|
|
*/ |
12
|
|
|
final class JsImportCacheBuster |
13
|
|
|
{ |
14
|
|
|
private ?string $version; |
15
|
|
|
private string $assetPath; |
16
|
|
|
|
17
|
17 |
|
public function __construct(Settings $settings) |
18
|
|
|
{ |
19
|
17 |
|
$deploymentSettings = $settings->get('deployment'); |
20
|
17 |
|
$this->version = $deploymentSettings['version']; |
21
|
17 |
|
$this->assetPath = $deploymentSettings['asset_path']; |
22
|
|
|
} |
23
|
|
|
|
24
|
|
|
/** |
25
|
|
|
* All js files inside the given directory that contain ES6 imports |
26
|
|
|
* are modified so that the imports have the version number at the |
27
|
|
|
* end of the file name as query parameters to break cache on |
28
|
|
|
* version change. |
29
|
|
|
* This function is called in PhpRendererMiddleware only on dev env. |
30
|
|
|
* Performance wise, this function takes between 10 and 20ms when content |
31
|
|
|
* is unchanged and between 30 and 50ms when content is replaced. |
32
|
|
|
* |
33
|
|
|
* @return void |
34
|
|
|
*/ |
35
|
|
|
public function addVersionToJsImports(): void |
36
|
|
|
{ |
37
|
|
|
// $start = hrtime(true); |
38
|
|
|
if (is_dir($this->assetPath)) { |
39
|
|
|
$rii = new RecursiveIteratorIterator( |
40
|
|
|
new RecursiveDirectoryIterator($this->assetPath, FilesystemIterator::SKIP_DOTS) |
41
|
|
|
); |
42
|
|
|
|
43
|
|
|
foreach ($rii as $file) { |
44
|
|
|
$fileInfo = pathinfo($file->getPathname()); |
45
|
|
|
|
46
|
|
|
if (isset($fileInfo['extension']) && $fileInfo['extension'] === 'js') { |
47
|
|
|
$content = file_get_contents($file->getPathname()) ?: ''; |
48
|
|
|
$originalContent = $content; |
49
|
|
|
// Matches lines that have 'import ' then any string then ' from ' and single or double quote opening then |
50
|
|
|
// any string (path) then '.js' and optionally v GET param '?v=234' and '";' at the end with single or double quotes |
51
|
|
|
preg_match_all('/import (.|\n|\r|\t)*? from ("|\')(.*?)\.js(\?v=.*?)?("|\');/', $content, $matches); |
52
|
|
|
// $matches is an array that contains all matches. In this case, the content is the following: |
53
|
|
|
// Key [0] is the entire matching string including the search |
54
|
|
|
// Key [1] first variable unknown string after the 'import ' word (e.g. '{requestDropdownOptions}', '{createModal}') |
55
|
|
|
// Key [2] single or double quotes of path opening after "from" |
56
|
|
|
// Key [3] variable unknown string after the opening single or double quotes after from (only path) e.g. |
57
|
|
|
// '../general/js/requestUtil/fail-handler' |
58
|
|
|
// Key [4] optional '?v=2' GET param and [5] closing quotes |
59
|
|
|
// Loop over import paths |
60
|
|
|
foreach ($matches[3] as $key => $importPath) { |
61
|
|
|
$oldFullImport = $matches[0][$key]; |
62
|
|
|
// Remove query params if the version is null |
63
|
|
|
if ($this->version === null) { |
64
|
|
|
$newImportPath = $importPath . '.js'; |
65
|
|
|
} else { |
66
|
|
|
$newImportPath = $importPath . '.js?v=' . $this->version; |
67
|
|
|
} |
68
|
|
|
// Old import path potentially with GET param |
69
|
|
|
$existingImportPath = $importPath . '.js' . $matches[4][$key]; |
70
|
|
|
// Search for old import path and replace with new one |
71
|
|
|
$newFullImport = str_replace($existingImportPath, $newImportPath, $oldFullImport); |
72
|
|
|
// Replace in file content |
73
|
|
|
$content = str_replace($oldFullImport, $newFullImport, $content); |
74
|
|
|
} |
75
|
|
|
// Replace file contents with modified one if there are changes |
76
|
|
|
if ($originalContent !== $content) { |
77
|
|
|
file_put_contents($file->getPathname(), $content); |
78
|
|
|
} |
79
|
|
|
} |
80
|
|
|
} |
81
|
|
|
} |
82
|
|
|
// Divided by a million gets milliseconds and a billion (+9) seconds |
83
|
|
|
// var_dump('Time used: ' . (hrtime(true) - $start) / 1e+6 . ' ms'); |
84
|
|
|
} |
85
|
|
|
} |
86
|
|
|
|