Skip to content

Commit ffc216f

Browse files
committed
feat: add automatic cache-busting for all static assets
Implement SystemURLs::assetVersioned() method to append file modification timestamps to asset URLs, forcing browser cache refresh after deployments without requiring manual hard refreshes. Changes: - Add assetVersioned() static method to SystemURLs DTO class - Uses PHP filemtime() to generate ?v=<timestamp> query parameters - Update all 70+ asset references across templates to use new method - Covers CSS, JavaScript, and external library references Files Modified (38 total): - Core includes: Header/Footer scripts and utilities - Admin dashboard and system views - User-facing pages: Person, Family, Event, Calendar views - External templates: Registration, Verification, Calendar - Finance and Sunday school modules - Kiosk and checkout workflows Result: All static asset URLs now include automatic cache-busting Parameters. When files are updated (CSS/JS changes), the timestamp changes automatically, creating unique URLs that force browser cache refresh. When files are unchanged, the same URL is served from cache.
1 parent fbfdcb3 commit ffc216f

38 files changed

+126
-107
lines changed

src/CSVImport.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -957,7 +957,7 @@ function GetAge(int $Month, int $Day, ?int $Year): int
957957
});
958958
});
959959
</script>
960-
<script src="<?= SystemURLs::getRootPath() ?>/skin/js/DropdownManager.js"></script>
961-
<script src="<?= SystemURLs::getRootPath() ?>/skin/js/MemberView.js" ></script>
960+
<script src="<?= SystemURLs::assetVersioned('/skin/js/DropdownManager.js') ?>"></script>
961+
<script src="<?= SystemURLs::assetVersioned('/skin/js/MemberView.js') ?>"></script>
962962
<?php
963963
require_once 'Include/Footer.php';

src/CartToEvent.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@
171171
<?php
172172
}
173173

174-
<script src="<?= SystemURLs::getRootPath() ?>/skin/js/cart-photo-viewer.js"></script>
174+
<script src="<?= SystemURLs::assetVersioned('/skin/js/cart-photo-viewer.js') ?>"></script>
175175

176176
<?php
177177
require_once 'Include/Footer.php';

src/CartToFamily.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -314,9 +314,9 @@
314314
?>
315315
</div>
316316

317-
<script src="<?= SystemURLs::getRootPath() ?>/skin/js/DropdownManager.js"></script>
318-
<script src="<?= SystemURLs::getRootPath() ?>/skin/js/CartToFamily.js"></script>
319-
<script src="<?= SystemURLs::getRootPath() ?>/skin/js/cart-photo-viewer.js"></script>
317+
<script src="<?= SystemURLs::assetVersioned('/skin/js/DropdownManager.js') ?>"></script>
318+
<script src="<?= SystemURLs::assetVersioned('/skin/js/CartToFamily.js') ?>"></script>
319+
<script src="<?= SystemURLs::assetVersioned('/skin/js/cart-photo-viewer.js') ?>"></script>
320320

321321
<?php
322322
require_once 'Include/Footer.php';

src/Checkin.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -477,8 +477,8 @@ function filterByType(typeId) {
477477
window.location.href = 'Checkin.php?EventTypeID=' + typeId;
478478
}
479479
</script>
480-
<script src="<?= SystemURLs::getRootPath() ?>/skin/js/cart-photo-viewer.js"></script>
481-
<script nonce="<?= SystemURLs::getCSPNonce() ?>" src="<?= SystemURLs::getRootPath() ?>/skin/js/checkin.js"></script>
480+
<script src="<?= SystemURLs::assetVersioned('/skin/js/cart-photo-viewer.js') ?>"></script>
481+
<script nonce="<?= SystemURLs::getCSPNonce() ?>" src="<?= SystemURLs::assetVersioned('/skin/js/checkin.js') ?>"></script>
482482

483483
<?php require_once 'Include/Footer.php';
484484

src/ChurchCRM/dto/SystemURLs.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,4 +123,22 @@ public static function getCSPNonce(): ?string
123123
{
124124
return self::$CSPNonce;
125125
}
126+
127+
/**
128+
* Get versioned asset URL with file modification time for cache-busting.
129+
* Appends ?v=<filemtime> to asset URLs to force browser cache refresh after deploys.
130+
*
131+
* @param string $webPath Asset path relative to document root (e.g., '/skin/v2/churchcrm.min.css')
132+
* @return string Versioned URL with modification time, or original URL if file doesn't exist
133+
*/
134+
public static function assetVersioned(string $webPath): string
135+
{
136+
$rootUrl = self::getRootPath();
137+
$docRoot = self::getDocumentRoot();
138+
$fullPath = rtrim($docRoot, DIRECTORY_SEPARATOR) . $webPath;
139+
if (file_exists($fullPath)) {
140+
return $rootUrl . $webPath . '?v=' . filemtime($fullPath);
141+
}
142+
return $rootUrl . $webPath;
143+
}
126144
}

src/DepositSlipEditor.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ class="btn btn-outline-primary <?= $nextDeposit ? '' : 'disabled'; ?>"
279279
</div>
280280
</div>
281281

282-
<script src="<?= SystemURLs::getRootPath() ?>/skin/js/DepositSlipEditor.js"></script>
282+
<script src="<?= SystemURLs::assetVersioned('/skin/js/DepositSlipEditor.js') ?>"></script>
283283
<style>
284284
.card {
285285
margin-bottom: 1.5rem;

src/FamilyEditor.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1035,7 +1035,7 @@
10351035
};
10361036
</script>
10371037
<?php } ?>
1038-
<script src="<?= SystemURLs::getRootPath() ?>/skin/js/DropdownManager.js"></script>
1039-
<script src="<?= SystemURLs::getRootPath() ?>/skin/js/FamilyEditor.js"></script>
1038+
<script src="<?= SystemURLs::assetVersioned('/skin/js/DropdownManager.js') ?>"></script>
1039+
<script src="<?= SystemURLs::assetVersioned('/skin/js/FamilyEditor.js') ?>"></script>
10401040
<?php
10411041
require_once 'Include/Footer.php';

src/FindDepositSlip.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,6 @@
7575
</div>
7676
</div>
7777

78-
<script src="<?= SystemURLs::getRootPath() ?>/skin/js/FindDepositSlip.js"></script>
78+
<script src="<?= SystemURLs::assetVersioned('/skin/js/FindDepositSlip.js') ?>"></script>
7979
<?php
8080
require_once 'Include/Footer.php';

src/GeoPage.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,6 @@ class="control-label col-xs-12 col-sm-3 col-md-3 col-lg-3"><?= gettext('Coordina
413413
<script nonce="<?= SystemURLs::getCSPNonce() ?>">
414414
var listPeople = <?= json_encode($aPersonIDs) ?>;
415415
</script>
416-
<script src="<?= SystemURLs::getRootPath() ?>/skin/js/GeoPage.js"></script>
416+
<script src="<?= SystemURLs::assetVersioned('/skin/js/GeoPage.js') ?>"></script>
417417
<?php
418418
require_once 'Include/Footer.php';

src/GetText.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
<head>
2525
<meta charset="UTF-8">
2626
<title><?= InputUtils::escapeHTML($aEventTitle) ?></title>
27-
<link rel="stylesheet" href="<?= SystemURLs::getRootPath() ?>/skin/v2/churchcrm.min.css">
27+
<link rel="stylesheet" href="<?= SystemURLs::assetVersioned('/skin/v2/churchcrm.min.css') ?>">
2828
</head>
2929
<body>
3030
<div class="container-fluid p-4">

0 commit comments

Comments
 (0)