* @copyright 2015 - 2018 Timothy J. Warren * @license http://www.opensource.org/licenses/mit-license.html MIT License * @version 4.1 * @link https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient */ namespace Aviat\AnimeClient\Model; use Aviat\AnimeClient\Types\{Config, UndefinedPropertyException}; use Aviat\Ion\ConfigInterface; use Aviat\Ion\Di\ContainerAware; use Aviat\Ion\StringWrapper; /** * Model for handling settings control panel */ final class Settings { use ContainerAware; use StringWrapper; private $config; /** * Map the config values to types and form fields */ private const SETTINGS_MAP = [ 'anilist' => [ ], 'config' => [ 'kitsu_username' => [ 'type' => 'string', 'title' => 'Kitsu Username', 'default' => '', 'readonly' => TRUE, 'description' => 'Username of the account to pull list data from.', ], 'whose_list' => [ 'type' => 'string', 'title' => 'Whose List', 'default' => 'Somebody', 'readonly' => TRUE, 'description' => 'Name of the owner of the list data.', ], 'show_anime_collection' => [ 'type' => 'boolean', 'title' => 'Show Anime Collection', 'default' => FALSE, 'description' => 'Should the anime collection be shown?', ], 'show_manga_collection' => [ 'type' => 'boolean', 'title' => 'Show Manga Collection', 'default' => FALSE, 'description' => 'Should the manga collection be shown?', ], 'asset_path' => [ 'type' => 'string', 'display' => FALSE, 'description' => 'Path to public directory, where images/css/javascript are located', ], 'default_list' => [ 'type' => 'select', 'title' => 'Default List', 'description' => 'Which list to show by default.', 'options' => [ 'Anime' => 'anime', 'Manga' => 'manga', ], ], 'default_anime_list_path' => [ //watching|plan_to_watch|on_hold|dropped|completed|all 'type' => 'select', 'title' => 'Default Anime List Section', 'description' => 'Which part of the anime list to show by default.', 'options' => [ 'Watching' => 'watching', 'Plan to Watch' => 'plan_to_watch', 'On Hold' => 'on_hold', 'Dropped' => 'dropped', 'Completed' => 'completed', 'All' => 'all', ] ], 'default_manga_list_path' => [ //reading|plan_to_read|on_hold|dropped|completed|all 'type' => 'select', 'title' => 'Default Manga List Section', 'description' => 'Which part of the manga list to show by default.', 'options' => [ 'Reading' => 'reading', 'Plan to Read' => 'plan_to_read', 'On Hold' => 'on_hold', 'Dropped' => 'dropped', 'Completed' => 'completed', 'All' => 'all', ] ] ], 'cache' => [ 'driver' => [ 'type' => 'select', 'title' => 'Cache Type', 'description' => 'The Cache backend', 'options' => [ 'APCu' => 'apcu', 'Memcached' => 'memcached', 'Redis' => 'redis', 'No Cache' => 'null' ], ], 'connection' => [ 'type' => 'subfield', 'title' => 'Connection', 'fields' => [ 'host' => [ 'type' => 'string', 'title' => 'Cache Host', 'description' => 'Host of the cache backend to connect to', ], 'port' => [ 'type' => 'string', 'title' => 'Cache Port', 'description' => 'Port of the cache backend to connect to', ], 'password' => [ 'type' => 'string', 'title' => 'Cache Password', 'description' => 'Password to connect to cache backend', ], 'database' => [ 'type' => 'string', 'title' => 'Cache Database', 'description' => 'Cache database number for Redis', ], ], ], ], 'database' => [ 'type' => [ 'type' => 'select', 'title' => 'Database Type', 'options' => [ 'MySQL' => 'mysql', 'PostgreSQL' => 'pgsql', 'SQLite' => 'sqlite', ], 'description' => 'Type of database to connect to', ], 'host' => [ 'type' => 'string', 'title' => 'Host', 'description' => 'The host of the database server', ], 'user' => [ 'type' => 'string', 'title' => 'User', 'description' => 'Database connection user', ], 'pass' => [ 'type' => 'string', 'title' => 'Password', 'description' => 'Database connection password' ], 'port' => [ 'type' => 'string', 'title' => 'Port', 'description' => 'Database connection port' ], 'database' => [ 'type' => 'string', 'title' => 'Database Name', 'description' => 'Name of the database/schema to connect to', ], 'file' => [ 'type' => 'string', 'title' => 'Database File', 'description' => 'Path to the database file, if required by the current database type.' ], ], ]; public function __construct(ConfigInterface $config) { $this->config = $config; } public function getSettings() { $settings = [ 'config' => [], ]; foreach(static::SETTINGS_MAP as $file => $values) { if ($file === 'config') { $keys = array_keys($values); foreach($keys as $key) { $settings['config'][$key] = $this->config->get($key); } } else { $settings[$file] = $this->config->get($file); } } return $settings; } public function getSettingsForm() { $output = []; $settings = $this->getSettings(); foreach($settings as $file => $values) { foreach(static::SETTINGS_MAP[$file] as $key => $value) { if ($value['type'] === 'subfield') { foreach($value['fields'] as $k => $field) { $value['fields'][$k]['value'] = $values[$key][$k] ?? ''; $value['fields'][$k]['display'] = TRUE; $value['fields'][$k]['readonly'] = FALSE; $value['fields'][$k]['disabled'] = FALSE; } } if (is_scalar($values[$key])) { $value['value'] = $values[$key]; } foreach (['readonly', 'disabled'] as $flag) { if ( ! array_key_exists($flag, $value)) { $value[$flag] = FALSE; } } if ( ! array_key_exists('display', $value)) { $value['display'] = TRUE; } $output[$file][$key] = $value; } } return $output; } public function validateSettings(array $settings): bool { try { new Config($settings); } catch (UndefinedPropertyException $e) { return FALSE; } return TRUE; } public function saveSettingsFile() { } }