diff --git a/src/Controller/AdminPanel.php b/src/Controller/AdminPanel.php index 2c6776199f..8b1cd89baf 100644 --- a/src/Controller/AdminPanel.php +++ b/src/Controller/AdminPanel.php @@ -33,7 +33,6 @@ namespace App\Controller; use App\Core\Controller; -use App\Core\DB\DefaultSettings; use App\Core\Form; use function App\Core\I18n\_m; use App\Util\Common; @@ -48,7 +47,7 @@ class AdminPanel extends Controller { public function site(Request $request) { - $defaults = DefaultSettings::$defaults; + $defaults = Common::getConfigDefaults(); $options = []; foreach ($defaults as $key => $inner) { $options[$key] = []; @@ -71,6 +70,8 @@ class AdminPanel extends Controller $value = $data['value']; if (preg_match('/^[0-9]+$/', $value)) { $value = (int) $value; + } elseif (strstr($value, ',') === false) { + // empty, string } elseif (Formatting::toArray($value, $value)) { // empty } elseif (preg_match('/true|false/i', $value)) { diff --git a/src/Core/DB/DB.php b/src/Core/DB/DB.php index a4c5fea12d..4a5558b9c4 100644 --- a/src/Core/DB/DB.php +++ b/src/Core/DB/DB.php @@ -126,6 +126,7 @@ abstract class DB public static function __callStatic(string $name, array $args) { foreach (['find', 'getReference', 'getPartialReference', 'getRepository'] as $m) { + // TODO Plugins $pref = '\App\Entity\\'; if ($name == $m && Formatting::startsWith($name, $pref) === false) { $args[0] = $pref . ucfirst(Formatting::snakeCaseToCamelCase($args[0])); diff --git a/src/Core/GNUsocial.php b/src/Core/GNUsocial.php index 5d41273a70..55510fbdbe 100644 --- a/src/Core/GNUsocial.php +++ b/src/Core/GNUsocial.php @@ -130,7 +130,7 @@ class GNUsocial implements EventSubscriberInterface public function initialize(): void { if (!$this->initialized) { - Common::setConfigBag($this->config); + Common::setupConfig($this->config); Log::setLogger($this->logger); Event::setDispatcher($this->event_dispatcher); I18n::setTranslator($this->translator); diff --git a/src/Core/ModuleManager.php b/src/Core/ModuleManager.php index c3af8af47c..294b471410 100644 --- a/src/Core/ModuleManager.php +++ b/src/Core/ModuleManager.php @@ -89,7 +89,6 @@ class ModuleManager $module_manager = new self(); $entity_paths = []; foreach ($module_paths as $path) { - // 'modules' and 'plugins' have the same length $type = ucfirst(preg_replace('%' . INSTALLDIR . '/(component|plugin)s/.*%', '\1', $path)); $dir = dirname($path); $module = basename($dir); diff --git a/src/Twig/Extension.php b/src/Twig/Extension.php index c1b99595df..3f9541365f 100644 --- a/src/Twig/Extension.php +++ b/src/Twig/Extension.php @@ -50,6 +50,7 @@ class Extension extends AbstractExtension new TwigFunction('active', [Runtime::class, 'isCurrentRouteActive']), new TwigFunction('is_route', [Runtime::class, 'isCurrentRoute']), new TwigFunction('get_note_actions', [Runtime::class, 'getNoteActions']), + new TwigFunction('config', [Runtime::class, 'getConfig']), ]; } } diff --git a/src/Twig/Runtime.php b/src/Twig/Runtime.php index d1d0022505..601e305179 100644 --- a/src/Twig/Runtime.php +++ b/src/Twig/Runtime.php @@ -32,6 +32,7 @@ namespace App\Twig; use App\Core\Event; use App\Entity\Note; +use App\Util\Common; use App\Util\Formatting; use Functional as F; use Symfony\Component\EventDispatcher\EventSubscriberInterface; @@ -43,8 +44,9 @@ use Twig\Extension\RuntimeExtensionInterface; class Runtime implements RuntimeExtensionInterface, EventSubscriberInterface { private Request $request; - public function __constructor() + public function __constructor(Request $req) { + $this->request = $req; } public function isCurrentRouteActive(string ...$routes): string @@ -65,6 +67,11 @@ class Runtime implements RuntimeExtensionInterface, EventSubscriberInterface return $actions; } + public function getConfig(...$args) + { + return Common::config(...$args); + } + // ---------------------------------------------------------- // Request is not a service, can't find a better way to get it diff --git a/src/Util/Common.php b/src/Util/Common.php index d029f74d02..97e7f4c021 100644 --- a/src/Util/Common.php +++ b/src/Util/Common.php @@ -32,7 +32,6 @@ namespace App\Util; -use App\Core\DB\DB; use App\Core\Router\Router; use App\Core\Security; use App\Entity\GSActor; @@ -41,13 +40,16 @@ use App\Util\Exception\NoLoggedInUser; use Exception; use Functional as F; use Symfony\Component\DependencyInjection\ParameterBag\ContainerBagInterface; +use Symfony\Component\Yaml; abstract class Common { + private static array $defaults; private static ?array $config = null; - public static function setConfigBag(ContainerBagInterface $config) + public static function setupConfig(ContainerBagInterface $config) { - self::$config = $config->get('gnusocial'); + self::$config = $config->get('gnusocial'); + self::$defaults = $config->get('gnusocial_defaults'); } /** @@ -55,7 +57,7 @@ abstract class Common */ public static function config(string $section, string $setting) { - return $config[$section][$setting]; + return self::$config[$section][$setting]; } /** @@ -65,14 +67,16 @@ abstract class Common */ public static function setConfig(string $section, string $setting, $value): void { - throw new Exception('Implement this, ya dingus'); - $c = DB::getPartialReference('config', ['section' => $section, 'setting' => $setting]); - if ($c === null) { - throw new \Exception("The field section = {$section} and setting = {$setting} doesn't exist"); - } + self::$config[$section][$setting] = $value; + $diff = self::array_diff_recursive(self::$config, self::$defaults); + $yaml = (new Yaml\Dumper(2))->dump(['parameters' => ['gnusocial' => $diff]], Yaml\Yaml::DUMP_OBJECT_AS_MAP); + rename(INSTALLDIR . '/social.local.yaml', INSTALLDIR . '/social.local.yaml.back'); + file_put_contents(INSTALLDIR . '/social.local.yaml', $yaml); + } - $c->setValue(serialize($value)); - DB::flush(); + public static function getConfigDefaults() + { + return self::$defaults; } public static function user(): ?LocalUser @@ -110,6 +114,52 @@ abstract class Common } } + // function array_diff_recursive($arr1, $arr2) + // { + // $outputDiff = []; + + // foreach ($arr1 as $key => $value) { + // // if the key exists in the second array, recursively call this function + // // if it is an array, otherwise check if the value is in arr2 + // if (array_key_exists($key, $arr2)) { + // if (is_array($value)) { + // $recursiveDiff = self::array_diff_recursive($value, $arr2[$key]); + // if (count($recursiveDiff)) { + // $outputDiff[$key] = $recursiveDiff; + // } + // } else if (!in_array($value, $arr2)) { + // $outputDiff[$key] = $value; + // } + // } else if (!in_array($value, $arr2)) { + // // if the key is not in the second array, check if the value is in + // // the second array (this is a quirk of how array_diff works) + // $outputDiff[$key] = $value; + // } + // } + + // return $outputDiff; + // } + + public function array_diff_recursive(array $array1, array $array2) + { + $difference = []; + foreach ($array1 as $key => $value) { + if (is_array($value)) { + if (!isset($array2[$key]) || !is_array($array2[$key])) { + $difference[$key] = $value; + } else { + $new_diff = self::array_diff_recursive($value, $array2[$key]); + if (!empty($new_diff)) { + $difference[$key] = $new_diff; + } + } + } elseif ((!isset($array2[$key]) || $array2[$key] != $value) && !($array2[$key] === null && $value === null)) { + $difference[$key] = $value; + } + } + return $difference ?? false; + } + /** * Remove keys from the _values_ of $keys from the array $from */