Compare commits

..

No commits in common. 'ef9b1a19989f4f3110b231a1039e8ce63453cef6' and '8e8d5714b48ea904fb7ff83b0e987b0f8376a90b' have entirely different histories.

  1. 128
      app/controllers/CacheController.php
  2. 7
      app/helper.php
  3. 23
      app/model/ConfigModel.php
  4. 114
      app/model/Model.php
  5. 82
      app/views/admin/cache.php
  6. 2
      app/views/admin/crud/show.php
  7. 2
      app/views/layouts/default.php
  8. 6
      app/views/partials/admin.php
  9. 4
      app/views/partials/script.php
  10. 4
      config.php.example
  11. 34
      public/js/app.js
  12. 3
      route.php

128
app/controllers/CacheController.php

@ -1,128 +0,0 @@
<?php
namespace App\Controllers;
use App\Classes\Config;
use App\Model\ConfigModel;
class CacheController extends PageController {
public function cacheAction(): void
{
$config = $this->getConfigValues();
$this->router->service()->config = $config;
parent::view();
}
public function developmentAction(): void
{
if (Config::c('CLOUDFLARE_ENABLED') != '1') {
return;
}
$token = Config::c('CLOUDFLARE_TOKEN');
$zone = Config::c('CLOUDFLARE_ZONE');
$url = "https://api.cloudflare.com/client/v4/zones/$zone/settings/development_mode";
$headers = [
"Authorization: Bearer $token",
"Content-Type: application/json"
];
$config = $this->getConfigValues();
$currentState = $config['CLOUDFLARE_DEVELOPMENT_MODE_ENABLED'];
$newState = $currentState == '1' ? 'off' : 'on';
$data = '{"value": "' . $newState . '"}';
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'PATCH');
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
// curl_setopt($curl, CURLINFO_HEADER_OUT, 1);
$response = curl_exec($curl);
// $info = curl_getinfo($curl, CURLINFO_HEADER_OUT);
curl_close($curl);
$this->saveConfigValues($response);
echo $response;
// echo $info;
}
//-------------------------------------//
private static function getConfigValues(): array
{
$result = [];
$config = [
'CLOUDFLARE_DEVELOPMENT_MODE_ENABLED' => '0',
'CLOUDFLARE_DEVELOPMENT_MODE_UPDATED_AT' => '',
'CLOUDFLARE_DEVELOPMENT_MODE_EXPIRES_IN' => '',
];
foreach ($config as $key => $value) {
$result[$key] = ConfigModel::firstOrCreate(
['key' => $key],
['value' => $value]
)->value;
}
if ($result['CLOUDFLARE_DEVELOPMENT_MODE_ENABLED']) {
$expiresIn = $result['CLOUDFLARE_DEVELOPMENT_MODE_EXPIRES_IN'];
$updatedAt = $result['CLOUDFLARE_DEVELOPMENT_MODE_UPDATED_AT'];
$expiresAtObject = new \DateTime($updatedAt);
$expiresAt = $expiresAtObject
->modify("+ $expiresIn seconds")
->format('Y-m-d H:i:s');
$nowObject = new \DateTime('now');
$now = $nowObject->format('Y-m-d H:i:s');
if ($now >= $expiresAt) {
ConfigModel::updateOrCreate(
['key' => 'CLOUDFLARE_DEVELOPMENT_MODE_ENABLED'],
['value' => 0]);
$result['CLOUDFLARE_DEVELOPMENT_MODE_ENABLED'] = 0;
}
else {
$result['enabled-remaining'] = $expiresAtObject->modify(
'- ' . $nowObject->getTimestamp() . ' seconds'
)->format('H:i:s');
}
}
return $result;
}
private static function saveConfigValues(string $response): void
{
$decodedResponse = json_decode($response, true);
if ($decodedResponse['success'] == true) {
$state = $decodedResponse['result']['value'];
$expiresIn = $decodedResponse['result']['time_remaining'];
$updatedAt = $decodedResponse['result']['modified_on'];
$updatedAtFormatted = (new \DateTime($updatedAt))->format('Y-m-d H:i:s');
ConfigModel::updateOrCreate(
['key' => 'CLOUDFLARE_DEVELOPMENT_MODE_ENABLED'],
['value' => $state == 'on' ? 1 : 0]);
ConfigModel::updateOrCreate(
['key' => 'CLOUDFLARE_DEVELOPMENT_MODE_EXPIRES_IN'],
['value' => $expiresIn]);
ConfigModel::updateOrCreate(
['key' => 'CLOUDFLARE_DEVELOPMENT_MODE_UPDATED_AT'],
['value' => $updatedAtFormatted]);
}
}
}

7
app/helper.php

@ -51,17 +51,14 @@ function _randomStr(int $length, string $keyspace =
* Print variable inside of a <pre> and exit
*
* @param mixed[] $output The variable (single/array) to print
* @param bool $die Call die(); after printing
*
* @return void Nothing
*/
function _log($output, bool $die = true): void {
function _log($output): void {
echo '<pre>';
var_dump($output);
echo '</pre>';
if ($die) {
die();
}
die();
}
//-------------------------------------//

23
app/model/ConfigModel.php

@ -1,23 +0,0 @@
<?php
namespace App\Model;
use App\Traits\Log;
class ConfigModel extends Model {
use Log;
protected $table = 'config';
protected $sort = 'key';
public $title = "Config";
// Attribute rules
// Name | Type | Required | Filtered
public $rules = [
["key", "text", 1, 0],
["value", "text", 0, 0],
["log_id", "text", 1, 1],
];
}

114
app/model/Model.php

@ -63,41 +63,21 @@ abstract class Model {
//-------------------------------------//
/**
* Retreive data via PDO prepared statements
*
* The most frequently used constants for PDO are listed below,
* find more at: {@link https://www.php.net/manual/en/pdo.constants.php}
* - PDO::PARAM_BOOL
* - PDO::PARAM_NULL
* - PDO::PARAM_INT
* - PDO::PARAM_STR
*
* Usage:
* self::query(
* "SELECT * FROM `example` WHERE `id` = :id AND `number` = :number AND `text` = :text", [
* [':id', 1],
* [':number', 7, \PDO::PARAM_INT],
* [':text', 'A random string', \PDO::PARAM_STR],
* ]);
*
* self::query(
* 'SELECT * FROM `example` WHERE `id` IN (?, ?, ?) AND `thing` = ?, [
* 1, 2, 3, 'stuff'
* ],
* '?'
* );
*
* @param $query The full prepared query statement
* @param $parameters The values to insert into the prepared statement
* @param $type Type of prepared statement, ':' for named placeholders,
* '?' for value placeholders
*
* @return array|null Retreived data, or null
*/
protected static function query(string $query, array $parameters = [],
$type = ':'): ?array
{
// Example
// $parameters = [
// [':id', 1],
// [':number', 7, \PDO::PARAM_INT],
// [':string', 'A random string', \PDO::PARAM_STR],
// ];
// PDO::PARAM_BOOL
// PDO::PARAM_NULL
// PDO::PARAM_INT
// PDO::PARAM_STR
if (substr_count($query, $type) != count($parameters)) {
return null;
}
@ -257,7 +237,7 @@ abstract class Model {
$required = false;
foreach ($this->rules as $rule) {
if ($rule[0] == $attribute && $rule[2] == 1 && $rule[3] == 0) {
if ($rule[0] == $attribute && $rule[2] == 1) {
$required = true;
break;
}
@ -345,6 +325,16 @@ abstract class Model {
return $model;
}
// $media = MediaModel::selectAll(
// '*', 'ORDER BY id DESC LIMIT :offset, :limit', [
// [':offset', $offset, \PDO::PARAM_INT],
// [':limit', $limit, \PDO::PARAM_INT],
// ]
// );
//
// $contents = ContentModel::selectAll(
// '*', 'WHERE id IN (?, ?, ?)', [1, 2, 3], '?'
// );
public static function selectAll(string $select = '*', string $filter = '',
array $parameters = [], $type = ':'): ?array
{
@ -423,15 +413,14 @@ abstract class Model {
}
/**
* Load all Models, optionally with a limit or pagination
* Load Model data: all, with a limit or pagination
*
* @param int $limitOrPage Treated as page if $limit is provided, limit otherwise
* @param int $limit The amount to limit by
*
* @return array|null The found model data, or null
*/
public static function all(int $limitOrPage = -1, int $limit = -1): ?array
{
public static function all(int $limitOrPage = -1, int $limit = -1): ?array {
$class = get_called_class();
$model = new $class;
@ -462,9 +451,7 @@ abstract class Model {
/**
* Retreive Model, or instantiate
*
* Usage:
* $model = \App\Model\Example::firstOrNew(['name' => 'Example name']);
* Usage: $model = \App\Model\Example::firstOrNew(['name' => 'Example name']);
*
* @param $search Retrieve by
* @param $data Instantiate with search plus data
@ -487,16 +474,13 @@ abstract class Model {
/**
* Create new Model
*
* Usage:
* $model = \App\Model\Example::create(['name' => 'Example name']);
* Usage: $model = \App\Model\Example::create(['name' => 'Example name']);
*
* @param $data Create with this data
*
* @return Model The Model
*/
public static function create(array $data): Model
{
public static function create(array $data): Model {
$class = get_called_class();
$model = new $class;
$model->fill($data);
@ -505,20 +489,15 @@ abstract class Model {
}
/**
* Retreive Model, create if it doesn't exist
*
* Usage:
* $model = \App\Model\AddressModel::firstOrCreate(
* ['zip_code' => '1234AB', 'house_number' => 3],
* ['street' => 'Example lane']);
* Retreive Model, or create
* Usage: $model = \App\Model\Example::firstOrCreate(['name' => 'Example name']);
*
* @param $search Retrieve by
* @param $data Data used for creation
* @param $data Instantiate with search plus data
*
* @return Model The Model
*/
public static function firstOrCreate(array $search, array $data = []): Model
{
public static function firstOrCreate(array $search, array $data = []): Model {
$model = self::firstOrNew($search, $data);
if (!$model->exists()) {
@ -528,27 +507,14 @@ abstract class Model {
return $model;
}
/**
* Update Model, create if it doesn't exist
*
* Usage:
* $model = \App\Model\FlightModel::updateOrCreate(
* ['departure' => 'Oakland', 'desination' => 'San Diego'],
* ['price' => 99]);
*
* @param $search Retrieve by
* @param $data Data used for creation
*
* @return Model The Model
*/
public static function updateOrCreate(array $search, array $data): Model
{
$model = self::firstOrNew($search, $data);
$model->fill($data);
$model->save();
return $model;
}
// // Update existing Model, or create it if doesn't exist
// public static function updateOrCreate(array $data, array $data): Model {
// // $flight = App\Flight::updateOrCreate(
// // ['departure' => 'Oakland', 'destination' => 'San Diego'],
// // ['price' => 99]
// // );
// return new Model;
// }
}

82
app/views/admin/cache.php

@ -1,82 +0,0 @@
<?php
use \App\Classes\Config;
?>
<div class="content shadow p-4 mb-4">
<h3 class="mb-4">Cache</h3>
<?php if (Config::c('CLOUDFLARE_ENABLED') != '1') { ?>
To enable the Cloudflare cache options,
make sure to set the following option in the <p>config.php</p> file:
<pre class="line-numbers mb-4 language-php"><p class="language-php"><span class="token single-quoted-string string">'CLOUDFLARE_ENABLED'</span> <span class="token operator">=</span><span class="token operator">&gt;</span> <span class="token single-quoted-string string">'1'</span><span class="token punctuation">,</span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></p></pre>
</p><?php } else { ?>
<div>
<p>
Cloudflare cache options:
</p>
</div>
<hr>
<div class="row align-items-center">
<div class="col-9 col-md-10 col-lg-11">
<h5>Purge CSS/JavaScript</h5>
<p class="mb-0">Granuarly remove .css and .js files from Cloudflare&apos;s cache.</p>
</div>
<div class="col-3 col-md-2 col-lg-1">
<div class="d-flex justify-content-end">
<button id="" class="btn btn-dark">Purge</button>
</div>
</div>
</div>
<hr>
<div class="row align-items-center">
<div class="col-9 col-md-10 col-lg-11">
<h5>Purge Fonts/Images</h5>
<p class="mb-0">Granuarly remove font and images files from Cloudflare&apos;s cache.</p>
</div>
<div class="col-3 col-md-2 col-lg-1">
<div class="d-flex justify-content-end">
<button id="" class="btn btn-danger">Purge</button>
</div>
</div>
</div>
<hr>
<div class="row align-items-center">
<div class="col-9 col-md-10 col-lg-11">
<h5>Purge All Files</h5>
<p class="mb-0">Remove ALL files from Cloudflare&apos;s cache.</p>
</div>
<div class="col-3 col-md-2 col-lg-1">
<div class="d-flex justify-content-end">
<button id="" class="btn btn-danger">Purge</button>
</div>
</div>
</div>
<hr>
<div class="row align-items-center">
<div class="col-9 col-mlg-10 col-xl-11">
<h5>Enable Development Mode</h5>
<p class="mb-0">
This will bypass Cloudflare&apos;s accelerated cache and slow down your site,
but is useful if you are making changes to cacheable content
(like images, CSS, or JavaScript) and would like to see those changes right away.
Once entered, development mode will last for 3 hours and then automatically toggle off.
<?php $state = $this->config['CLOUDFLARE_DEVELOPMENT_MODE_ENABLED']; ?>
<span id="develop-enabled" style="visibility: <?= $state == '1' ? 'visible' : 'hidden'; ?>;">
Enabled for another
<code id="develop-remaining">
<?= $state == '1' ? $this->config['enabled-remaining'] : ''; ?>
</code> hours.
</span>
</p>
</div>
<div class="col-3 col-lg-2 col-xl-1">
<div class="d-flex justify-content-start">
<input type="checkbox" id="development-mode"
<?= $this->config['CLOUDFLARE_DEVELOPMENT_MODE_ENABLED'] ? 'checked' : ''; ?>>
</div>
</div>
</div>
<?php } ?>
<div class="pb-5"></div>
</div>

2
app/views/admin/crud/show.php

@ -1,7 +1,7 @@
<div class="row">
<div class="col-12">
<div class="content shadow p-4 mb-4">
<h3><?= property_exists($this->model, 'title') ? ($this->escape)($this->model->title) : 'Show'; ?></h3>
<h3><?= _exists([$this->model->title]) ? ($this->escape)($this->model->title) : 'Show'; ?></h3>
<table class="table table-bordered table-striped">
<thead>

2
app/views/layouts/default.php

@ -22,7 +22,7 @@
<link href="https://cdn.jsdelivr.net/npm/prismjs@1.22.0/themes/prism-tomorrow.min.css" rel="stylesheet" integrity="sha384-rG0ypOerdVJPawfZS6juq8t8GVE9oCCPJbOXV/bF+e61zYW9Ib6u9WwSbTOK6CKA" crossorigin="anonymous">
<link href="https://cdn.jsdelivr.net/npm/prismjs@1.22.0/plugins/line-numbers/prism-line-numbers.min.css" rel="stylesheet" integrity="sha384-n3/UuPVL3caytud/opHXuyFoezGp2oAUB0foYaCAIs2QwGv/nV0kULHS2WAaJuxR" crossorigin="anonymous">
<link href="<?= Config::c('APP_URL'); ?>/css/style.css" rel="stylesheet">
<link href="<?= Config::c('APP_URL'); ?>/css/style.css?v=<?= rand(); ?>" rel="stylesheet">
<title><?= ($this->escape)($this->pageTitle); ?><?= $this->pageTitle != '' ? ' - ' : '' ?>Rick van Vonderen</title>
<link rel="icon" type="image/png" href="<?= Config::c('APP_URL'); ?>/img/favicon.png">

6
app/views/partials/admin.php

@ -22,12 +22,6 @@
<br>
- <a href="<?= \App\Classes\Config::c('APP_URL'); ?>/admin/syntax-highlighting">Syntax Highlighting</a>
<hr>
<h5>Config</h5>
- <a href="<?= \App\Classes\Config::c('APP_URL'); ?>/admin/cache">Cache</a>
<br>
- <a href="<?= \App\Classes\Config::c('APP_URL'); ?>/admin/config">Config</a>
<hr>
- <a href="<?= \App\Classes\Config::c('APP_URL'); ?>/logout">Log out</a>
</div>

4
app/views/partials/script.php

@ -23,6 +23,6 @@
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.22.0/plugins/line-numbers/prism-line-numbers.min.js" integrity="sha384-xktrwc/DkME39VrlkNS1tFEeq/S0JFbc8J9Q8Bjx7Xy16Z3NnmUi+94RuffrOQZR" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.22.0/plugins/highlight-keywords/prism-highlight-keywords.min.js" integrity="sha384-Rk2xv6YOAfQH8z3ZAK37pgnQihXfgkER8B5EYhoFc+mMNPzf+t7g2J9U74FAvy2T" crossorigin="anonymous"></script>
<script src="<?= Config::c('APP_URL'); ?>/js/app.js"></script>
<script src="<?= Config::c('APP_URL'); ?>/js/app.js?v=<?= rand(); ?>"></script>
<?php } ?>
<script src="<?= Config::c('APP_URL'); ?>/js/site.js"></script>
<script src="<?= Config::c('APP_URL'); ?>/js/site.js?v=<?= rand(); ?>"></script>

4
config.php.example

@ -14,8 +14,4 @@ return [
'MAIL_NAME' => '',
'MAIL_USERNAME' => '',
'MAIL_PASSWORD' => '',
'CLOUDFLARE_ENABLED' => '',
'CLOUDFLARE_TOKEN' => '',
'CLOUDFLARE_ZONE' => '',
];

34
public/js/app.js

@ -227,40 +227,6 @@ $(document).ready(function() {
});
//------------------------------------------
// Developer mode
$('#development-mode').on('click', function(e)
{
e.preventDefault();
if (!confirm('Are you sure you want to continue?')) {
return;
}
$.get('/admin/toggle-development-mode').done(function(data)
{
const response = JSON.parse(data);
if (response.success == true) {
if (response.result.value == 'on') {
e.target.checked = true;
$('#develop-enabled').css('visibility', 'visible');
$('#develop-remaining').text('03:00:00');
}
else {
e.target.checked = false;
$('#develop-enabled').css('visibility', 'hidden');
}
alert("Development mode has been set to: '" + response.result.value + "'");
}
else {
console.log(data);
alert("Development mode could not be enabled!")
}
});
});
});
// @Todo

3
route.php

@ -2,7 +2,6 @@
use \App\Classes\Router;
Router::resource('/admin/config', 'CrudController');
Router::resource('/admin/section', 'CrudController');
Router::resource('/admin/page', 'CrudController');
Router::resource('/admin/content', 'CrudController');
@ -21,9 +20,7 @@ return [
['/reset-password', 'LoginController', 'reset', ['', 'Reset password', '']],
['/logout', 'LoginController', 'logout', ''],
['/admin', 'AdminController', '', ''],
['/admin/cache', 'CacheController', 'cache', ''],
['/admin/toggle', 'AdminController', 'toggle', ''],
['/admin/toggle-development-mode', 'CacheController', 'development', ''],
['/admin/syntax-highlighting', 'AdminController', 'syntax', ''],
['/test', 'TestController', '', ''],
// ["", "", "", ""],

Loading…
Cancel
Save