Settings control panel saves to admin-override.toml in the app/config directory, resolves #7

This commit is contained in:
Timothy Warren 2018-10-08 15:45:46 -04:00
parent b625f22d6a
commit 88b68b847c
9 changed files with 142 additions and 37 deletions

View File

@ -1,5 +1,11 @@
# Changelog
## Version 4.1
* Removed MAL integration, added Anilist Integration
* Now uses WebP cache images when the browser supports it
* Replaces JS minifier with pre-minified scripts (Removes the need for one caching folder, too)
* Updated console command to sync Kitsu and Anilist data
## Version 4
* Updated to use Kitsu API after discontinuation of Hummingbird
* Added streaming links to list entries from the Kitsu API

View File

@ -216,8 +216,8 @@ return [
'verb' => 'get',
],
'settings-post' => [
'path' => '/settings',
'action' => 'settings',
'path' => '/settings-save',
'action' => 'settings_post',
'controller' => DEFAULT_CONTROLLER,
'verb' => 'post',
],

View File

@ -6,6 +6,7 @@ if ( ! $auth->isAuthenticated())
}
$sectionMapping = [
'anilist' => 'Anilist API Integration',
'config' => 'General Settings',
'cache' => 'Caching',
'database' => 'Collection Database Settings',
@ -15,9 +16,7 @@ $hiddenFields = [];
$nestedPrefix = 'config';
?>
<pre><?= print_r($_POST, TRUE) ?></pre>
<form action="<?= $_SERVER['REQUEST_URI'] ?>" method="POST">
<form action="<?= $url->generate('settings-post') ?>" method="POST">
<main class='form'>
<button type="submit">Save Changes</button>
<br />

View File

@ -49,7 +49,13 @@ $baseConfig = require $APPCONF_DIR . '/base_config.php';
$di = require $APP_DIR . '/bootstrap.php';
$config = loadToml($CONF_DIR);
$configArray = array_merge($baseConfig, $config);
$overrideFile = $CONF_DIR . '/admin-override.toml';
$overrideConfig = file_exists($overrideFile)
? loadTomlFile($overrideFile)
: [];
$configArray = array_merge($baseConfig, $config, $overrideConfig);
$checkedConfig = (new ConfigType($configArray))->toArray();
$container = $di($checkedConfig);

View File

@ -33,6 +33,11 @@ function loadToml(string $path): array
foreach ($files as $file)
{
$key = str_replace('.toml', '', basename($file));
if ($key === 'admin-override')
{
continue;
}
$config = Toml::parseFile($file);
if ($key === 'config')
@ -71,6 +76,17 @@ function loadTomlByFile(string $path): array
return $output;
}
/**
* Load config from one specific TOML file
*
* @param string $filename
* @return array
*/
function loadTomlFile(string $filename): array
{
return Toml::parseFile($filename);
}
/**
* Is the array sequential, not associative?
*

View File

@ -39,9 +39,6 @@ final class Index extends BaseController {
/**
* Purges the API cache
*
* @throws \Aviat\Ion\Di\ContainerException
* @throws \Aviat\Ion\Di\NotFoundException
* @throws \InvalidArgumentException
* @return void
*/
public function clearCache()
@ -56,9 +53,6 @@ final class Index extends BaseController {
* Show the login form
*
* @param string $status
* @throws \Aviat\Ion\Di\ContainerException
* @throws \Aviat\Ion\Di\NotFoundException
* @throws \InvalidArgumentException
* @return void
*/
public function login(string $status = '')
@ -109,10 +103,6 @@ final class Index extends BaseController {
/**
* Attempt login authentication
*
* @throws \Aviat\Ion\Di\ContainerException
* @throws \Aviat\Ion\Di\NotFoundException
* @throws \Aura\Router\Exception\RouteNotFound
* @throws \InvalidArgumentException
* @return void
*/
public function loginAction()
@ -133,9 +123,6 @@ final class Index extends BaseController {
/**
* Deauthorize the current user
*
* @throws \Aviat\Ion\Di\ContainerException
* @throws \Aviat\Ion\Di\NotFoundException
* @throws \InvalidArgumentException
* @return void
*/
public function logout()
@ -149,9 +136,6 @@ final class Index extends BaseController {
/**
* Show the user profile page
*
* @throws \Aviat\Ion\Di\ContainerException
* @throws \Aviat\Ion\Di\NotFoundException
* @throws \InvalidArgumentException
* @return void
*/
public function me()
@ -188,14 +172,28 @@ final class Index extends BaseController {
]);
}
/**
* Attempt to save the user's settings
*
* @throws \Aura\Router\Exception\RouteNotFound
*/
public function settings_post()
{
$auth = $this->container->get('auth');
$this->outputHTML('settings', [
'auth' => $auth,
'config' => $this->config,
'title' => $this->config->get('whose_list') . "'s Settings",
]);
$post = $this->request->getParsedBody();
// dump($post);
$saved = $this->settingsModel->saveSettingsFile($post);
if ($saved)
{
$this->setFlashMessage('Saved config settings.', 'success');
}
else
{
$this->setFlashMessage('Failed to save config file.', 'error');
}
$this->redirect($this->url->generate('settings'), 303);
}
/**
@ -250,7 +248,7 @@ final class Index extends BaseController {
$baseSavePath = $this->config->get('img_cache_path');
$filePrefix = "{$baseSavePath}/{$type}/{$id}";
[$origWidth, $origHeight] = getimagesizefromstring($data);
[$origWidth] = getimagesizefromstring($data);
$gdImg = imagecreatefromstring($data);
$resizedImg = imagescale($gdImg, $width ?? $origWidth);

View File

@ -83,7 +83,7 @@ final class FormGenerator {
$params['attribs']['label'] = $form['description'];
$params['attribs']['value'] = TRUE;
$params['attribs']['value_unchecked'] = '0'; */
$params['type'] = 'radio';
$params['options'] = [
'1' => 'Yes',

View File

@ -16,6 +16,9 @@
namespace Aviat\AnimeClient\Model;
use function Aviat\AnimeClient\arrayToToml;
use function Aviat\Ion\_dir;
use Aviat\AnimeClient\Types\{Config, UndefinedPropertyException};
use Aviat\Ion\ConfigInterface;
@ -36,7 +39,12 @@ final class Settings {
*/
private const SETTINGS_MAP = [
'anilist' => [
'enabled' => [
'type' => 'boolean',
'title' => 'Enable Anilist Integration',
'default' => FALSE,
'description' => 'Enable syncing data between Kitsu and Anilist. Requires appropriate API keys to be set in config',
],
],
'config' => [
'kitsu_username' => [
@ -265,22 +273,88 @@ final class Settings {
return $output;
}
public function validateSettings(array $settings): bool
public function validateSettings(array $settings)
{
$config = (new Config($settings))->toArray();
$looseConfig = [];
$keyedConfig = [];
// Convert 'boolean' values to true and false
// Also order keys so they can be saved properly
foreach ($config as $key => $val)
{
if (is_scalar($val))
{
if ($val === '1')
{
$looseConfig[$key] = TRUE;
}
elseif ($val === '0')
{
$looseConfig[$key] = FALSE;
}
else
{
$looseConfig[$key] = $val;
}
}
elseif (is_array($val))
{
foreach($val as $k => $v)
{
if ($v === '1')
{
$keyedConfig[$key][$k] = TRUE;
}
elseif($v === '0')
{
$keyedConfig[$key][$k] = FALSE;
}
else
{
$keyedConfig[$key][$k] = $v;
}
}
}
}
ksort($looseConfig);
ksort($keyedConfig);
$output = [];
foreach($looseConfig as $k => $v)
{
$output[$k] = $v;
}
foreach($keyedConfig as $k => $v)
{
$output[$k] = $v;
}
return $output;
}
public function saveSettingsFile(array $settings): bool
{
$settings = $settings['config'];
try
{
new Config($settings);
$settings = $this->validateSettings($settings);
}
catch (UndefinedPropertyException $e)
{
return FALSE;
}
return TRUE;
}
$savePath = realpath(_dir(__DIR__, '..', '..', 'app', 'config'));
$saveFile = _dir($savePath, 'admin-override.toml');
public function saveSettingsFile()
{
$saved = file_put_contents($saveFile, arrayToToml($settings));
return $saved !== FALSE;
}
}

6
sw.js
View File

@ -61,6 +61,12 @@ self.addEventListener('activate', event => {
// Pull css, images, and javascript from cache
self.addEventListener('fetch', event => {
// Only cache things with a file extension,
// Ignore other requests
if ( ! event.request.url.includes('/public/')) {
return;
}
fromCache(event.request).then(cached => {
if (cached !== undefined) {
event.respondWith(cached);