[CONFIG] Make it possible to write module configuration in a config.{php,yml,yaml,xml} file and set each value as properties in the module object

This commit is contained in:
Hugo Sales 2021-08-21 22:30:24 +01:00
parent 3587b8dc1d
commit c71a4b06ef
Signed by: someonewithpc
GPG Key ID: 7D0C7EAFC9D835A0
6 changed files with 83 additions and 19 deletions

View File

@ -224,6 +224,10 @@ class GNUsocial implements EventSubscriberInterface
/**
* Load configuration files
*
* Happens at "compile time"
*
* @codeCoverageIgnore
*/
public static function configureContainer(ContainerBuilder $container, LoaderInterface $loader): void
{
@ -241,8 +245,27 @@ class GNUsocial implements EventSubscriberInterface
$loader->load(INSTALLDIR . '/social' . Kernel::CONFIG_EXTS, 'glob');
$container->setParameter('gnusocial_defaults', $container->getParameter('gnusocial'));
$configs = array_replace_recursive($container->getParameter('gnusocial'), $locals['gnusocial']);
$container->setParameter('gnusocial', $configs);
// Load module config
$parameters = ModuleManager::configureContainer($container, $loader);
// Merge parameter $from with values already set in $to
$merge_config = function ($from, $to = null) use ($container, $locals) {
$to = $to ?? $from;
$wrapper = $container->hasParameter($to) ? $container->getParameter($to) : [];
$content = [$from => $container->getParameter($from)];
$container->getParameterBag()->remove($from);
$locals = isset($locals[$from]) ? [$from => $locals[$from]] : [];
$configs = array_replace_recursive($wrapper, $content, $locals);
$container->setParameter($to, $configs);
};
// Override and merge any of the previous settings from the locals
if (is_array($locals)) {
$merge_config('gnusocial');
foreach ($parameters as $mod => $type) {
$merge_config($mod, $type);
}
}
}
/**

View File

@ -33,12 +33,14 @@
namespace App\Core;
use App\Kernel;
use App\Util\Formatting;
use AppendIterator;
use FilesystemIterator;
use Functional as F;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
@ -166,10 +168,47 @@ class ModuleManager
$obj = require CACHE_FILE;
foreach ($obj->modules as $module) {
$module->loadConfig();
}
foreach ($obj->events as $event => $callables) {
foreach ($callables as $callable) {
Event::addHandler($event, $callable);
}
}
}
/**
* Load Module settings and setup Twig template load paths
*
* Happens at "compile time"
*
* @codeCoverageIgnore
*/
public static function configureContainer(ContainerBuilder $container, LoaderInterface $loader): array
{
$template_modules = array_merge(glob(INSTALLDIR . '/components/*/templates'), glob(INSTALLDIR . '/plugins/*/templates'));
// Regular template location
$templates = ['%kernel.project_dir%/templates' => 'default_path', '%kernel.project_dir%/public' => 'public_path'];
// Path => alias
foreach ($template_modules as $mod) {
$templates[$mod] = null;
}
$container->loadFromExtension('twig', ['paths' => $templates]);
$modules = array_merge(glob(INSTALLDIR . '/components/*'), glob(INSTALLDIR . '/plugins/*'));
$parameters = [];
foreach ($modules as $mod) {
$path = "{$mod}/config" . Kernel::CONFIG_EXTS;
$loader->load($path, 'glob'); // Is supposed to, but doesn't return anything that would let us identify if loading worked
foreach (explode(',', substr(Kernel::CONFIG_EXTS, 2, -1)) as $ext) {
if (file_exists("{$mod}/config.{$ext}")) {
$parameters[basename(strtolower($mod))] = basename(dirname(strtolower($mod)));
break;
}
}
}
return $parameters;
}
}

View File

@ -4,4 +4,5 @@ namespace App\Core\Modules;
abstract class Component extends Module
{
}
const MODULE_TYPE = 'component';
}

View File

@ -27,18 +27,25 @@ use App\Util\Common;
abstract class Module
{
/**
* TODO Handle configuration
*
* @codeCoverageIgnore
* Load values from the config and set them as properties on each module object
*/
public function __construct()
public function loadConfig()
{
// Load Module settings
foreach (Common::config(static::class) as $aname => $avalue) {
$this->{$aname} = $avalue;
foreach (Common::config(static::MODULE_TYPE . 's') as $module => $values) {
if ($module == $this->name()) {
foreach ($values as $property => $value) {
$this->{$property} = $value;
}
}
}
}
public static function name()
{
return mb_strtolower(explode('\\', static::class)[2]);
}
/**
* Serialize the class to store in the cache
*

View File

@ -11,15 +11,7 @@ use App\Core\Event;
*/
abstract class Plugin extends Module
{
public function __construct()
{
parent::__construct();
}
public function name()
{
return mb_substr(static::class, 0, -6);
}
const MODULE_TYPE = 'plugin';
public function version()
{

View File

@ -49,7 +49,9 @@ abstract class Common
private static ?array $config = null;
public static function setupConfig(ContainerBagInterface $config)
{
self::$config = $config->get('gnusocial');
$components = $config->has('components') ? $config->get('components') : [];
$plugins = $config->has('plugins') ? $config->get('plugins') : [];
self::$config = array_merge($config->get('gnusocial'), ['components' => $components], ['plugins' => $plugins]);
self::$defaults = $config->get('gnusocial_defaults');
}