Controllers+Views+JS+Route: Implement cache purging
This commit is contained in:
@@ -4,18 +4,81 @@ namespace App\Controllers;
|
|||||||
|
|
||||||
use App\Classes\Config;
|
use App\Classes\Config;
|
||||||
use App\Classes\Http\Http;
|
use App\Classes\Http\Http;
|
||||||
|
use App\Classes\Session;
|
||||||
use App\Model\ConfigModel;
|
use App\Model\ConfigModel;
|
||||||
|
|
||||||
class CacheController extends PageController {
|
class CacheController extends PageController {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maximum amount of files that can be purged on a single request
|
||||||
|
*/
|
||||||
|
public static int $purgeLimit = 30;
|
||||||
|
|
||||||
public function cacheAction(): void
|
public function cacheAction(): void
|
||||||
{
|
{
|
||||||
$config = $this->getConfigValues();
|
$config = $this->getConfigValues();
|
||||||
|
|
||||||
$this->router->service()->config = $config;
|
$this->router->service()->config = $config;
|
||||||
|
$this->router->service()->csrfToken = Session::token();
|
||||||
|
$this->router->service()->purgeUrl = $this->url . '/purge';
|
||||||
parent::view();
|
parent::view();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function purgeAction(): void
|
||||||
|
{
|
||||||
|
if (!$this->validatePostRequest()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$token = Config::c('CLOUDFLARE_TOKEN');
|
||||||
|
$zone = Config::c('CLOUDFLARE_ZONE');
|
||||||
|
|
||||||
|
$url = "https://api.cloudflare.com/client/v4/zones/$zone/purge_cache";
|
||||||
|
|
||||||
|
if (!_exists($_POST, 'type')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$bodies = [];
|
||||||
|
switch($_POST['type']) {
|
||||||
|
case 'css-js':
|
||||||
|
$body = self::generateUrls(['css', 'js']);
|
||||||
|
$chunks = array_chunk($body['files'], self::$purgeLimit);
|
||||||
|
foreach($chunks as $chunk) {
|
||||||
|
$bodies[]['files'] = $chunk;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'fonts-images':
|
||||||
|
$body = self::generateUrls(['fonts', 'img', 'media']);
|
||||||
|
$chunks = array_chunk($body['files'], self::$purgeLimit);
|
||||||
|
foreach($chunks as $chunk) {
|
||||||
|
$bodies[]['files'] = $chunk;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'all':
|
||||||
|
$bodies[] = ['purge_everything' => true];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$response = null;
|
||||||
|
foreach($bodies as $body) {
|
||||||
|
$response = (new Http)->withToken($token)
|
||||||
|
->asJson()
|
||||||
|
->acceptJson()
|
||||||
|
->post($url, $body);
|
||||||
|
if (empty($response->body())
|
||||||
|
|| !json_decode($response->body(), true)['success']) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($response) {
|
||||||
|
echo $response->body();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function toggleAction(): void
|
public function toggleAction(): void
|
||||||
{
|
{
|
||||||
if (Config::c('CLOUDFLARE_ENABLED') != '1') {
|
if (Config::c('CLOUDFLARE_ENABLED') != '1') {
|
||||||
@@ -40,14 +103,41 @@ class CacheController extends PageController {
|
|||||||
$this->saveConfigValues($response->body());
|
$this->saveConfigValues($response->body());
|
||||||
|
|
||||||
echo $response->body();
|
echo $response->body();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------//
|
//-------------------------------------//
|
||||||
|
|
||||||
|
private function validatePostRequest(): bool
|
||||||
|
{
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] == 'GET') {
|
||||||
|
parent::throw404();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Config::c('CLOUDFLARE_ENABLED') != '1') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Session::validateToken($_POST)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function generateUrls(array $directories): array
|
||||||
|
{
|
||||||
|
$result = [];
|
||||||
|
|
||||||
|
foreach ($directories as $directory) {
|
||||||
|
$files = array_diff(scandir($directory), ['..', '.']);
|
||||||
|
foreach ($files as $file) {
|
||||||
|
$result['files'][] = Config::c('APP_URL') . "/$directory/$file";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
private static function getConfigValues(): array
|
private static function getConfigValues(): array
|
||||||
{
|
{
|
||||||
$result = [];
|
$result = [];
|
||||||
|
|||||||
@@ -23,7 +23,8 @@ use \App\Classes\Config;
|
|||||||
</div>
|
</div>
|
||||||
<div class="col-3 col-md-2 col-lg-2 col-xl-2">
|
<div class="col-3 col-md-2 col-lg-2 col-xl-2">
|
||||||
<div class="d-flex justify-content-center">
|
<div class="d-flex justify-content-center">
|
||||||
<button id="" class="btn btn-dark">Purge</button>
|
<a class="js-purge btn btn-dark" href="<?= $this->purgeUrl; ?>"
|
||||||
|
data-type="css-js" data-token="<?= $this->csrfToken; ?>">Purge</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -35,7 +36,8 @@ use \App\Classes\Config;
|
|||||||
</div>
|
</div>
|
||||||
<div class="col-3 col-md-2 col-lg-2 col-xl-2">
|
<div class="col-3 col-md-2 col-lg-2 col-xl-2">
|
||||||
<div class="d-flex justify-content-center">
|
<div class="d-flex justify-content-center">
|
||||||
<button id="" class="btn btn-danger">Purge</button>
|
<a class="js-purge btn btn-danger" href="<?= $this->purgeUrl; ?>"
|
||||||
|
data-type="fonts-images" data-token="<?= $this->csrfToken; ?>">Purge</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -47,7 +49,8 @@ use \App\Classes\Config;
|
|||||||
</div>
|
</div>
|
||||||
<div class="col-3 col-md-2 col-lg-2 col-xl-2">
|
<div class="col-3 col-md-2 col-lg-2 col-xl-2">
|
||||||
<div class="d-flex justify-content-center">
|
<div class="d-flex justify-content-center">
|
||||||
<button id="" class="btn btn-danger">Purge</button>
|
<a class="js-purge btn btn-danger" href="<?= $this->purgeUrl; ?>"
|
||||||
|
data-type="all" data-token="<?= $this->csrfToken; ?>">Purge</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -229,6 +229,40 @@ $(document).ready(function() {
|
|||||||
|
|
||||||
//------------------------------------------
|
//------------------------------------------
|
||||||
|
|
||||||
|
$('.js-purge').on('click', function(event)
|
||||||
|
{
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
const purgeType = $(this).attr('data-type');
|
||||||
|
const csrfToken = $(this).attr('data-token');
|
||||||
|
|
||||||
|
if (!confirm('Are you sure you want to continue?')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: $(this).attr('href'),
|
||||||
|
type: 'POST',
|
||||||
|
data: { type: purgeType, _token: csrfToken },
|
||||||
|
success: function(data)
|
||||||
|
{
|
||||||
|
if (data == '') {
|
||||||
|
alert("Cache could not be purged!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = JSON.parse(data);
|
||||||
|
if (response.success == false) {
|
||||||
|
console.log(data);
|
||||||
|
alert("Cache could not be purged!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
alert("Cache has been purged.");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// Developer mode
|
// Developer mode
|
||||||
$('#development-mode').on('click', function(e)
|
$('#development-mode').on('click', function(e)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ return [
|
|||||||
['/admin', 'AdminController', '', ''],
|
['/admin', 'AdminController', '', ''],
|
||||||
['/admin/cache', 'CacheController', 'cache', ''],
|
['/admin/cache', 'CacheController', 'cache', ''],
|
||||||
['/admin/toggle', 'AdminController', 'toggle', ''],
|
['/admin/toggle', 'AdminController', 'toggle', ''],
|
||||||
|
['/admin/cache/purge', 'CacheController', 'purge', ''],
|
||||||
['/admin/cache/toggle', 'CacheController', 'toggle', ''],
|
['/admin/cache/toggle', 'CacheController', 'toggle', ''],
|
||||||
['/admin/syntax-highlighting', 'AdminController', 'syntax', ''],
|
['/admin/syntax-highlighting', 'AdminController', 'syntax', ''],
|
||||||
['/test', 'TestController', '', ''],
|
['/test', 'TestController', '', ''],
|
||||||
|
|||||||
Reference in New Issue
Block a user