Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
10 changes: 8 additions & 2 deletions formwork/config/system.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ panel:
assets: '${system.panel.path}/assets'
logs: '${system.panel.path}/logs'
modals: '${system.panel.path}/modals'
config:
app: '${system.panel.path}/config/app.php'
navigation: '${system.panel.path}/config/navigation.php'

users:
paths:
Expand All @@ -97,8 +100,8 @@ users:

routes:
files:
panel: '${system.panel.path}/routes.php'
system: '${%SYSTEM_PATH%}/routes.php'
panel: '${system.panel.path}/config/routes/routes.php'
system: '${%SYSTEM_PATH%}/config/routes/routes.php'

schemes:
paths:
Expand Down Expand Up @@ -141,3 +144,6 @@ views:
paths:
panel: '${system.panel.path}/views'
system: '${%SYSTEM_PATH%}/views'
methods:
panel: '${system.panel.path}/config/views/methods.php'
system: '${%SYSTEM_PATH%}/config/views/methods.php'
File renamed without changes.
18 changes: 4 additions & 14 deletions formwork/src/Cms/App.php
Original file line number Diff line number Diff line change
Expand Up @@ -130,16 +130,6 @@ public function panel(): Panel
return $this->container->get(Panel::class);
}

/**
* Return default options
*
* @return array<string, mixed>
*/
public function defaults(): array
{
return $this->config()->getDefaults('system');
}

/**
* @template T of object
*
Expand Down Expand Up @@ -184,15 +174,15 @@ private function loadServices(Container $container): void

$container->define(self::class, $this);

$container->define(Request::class, fn() => Request::fromGlobals())
->alias('request');

$container->define(Config::class)
->loader(ConfigServiceLoader::class)
->alias('config');

$container->define(ViewFactory::class)
->parameter('methods', fn(Container $container) => $container->call(require SYSTEM_PATH . '/methods.php'));

$container->define(Request::class, fn() => Request::fromGlobals())
->alias('request');
->parameter('methods', fn(Container $container, Config $config) => $container->call(require $config->get('system.views.methods.system')));

$container->define(ErrorsController::class)
->alias(ErrorsControllerInterface::class);
Expand Down
23 changes: 4 additions & 19 deletions formwork/src/Cms/Site.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
use Formwork\Schemes\Schemes;
use Formwork\Templates\Templates;
use Formwork\Users\Users;
use Formwork\Utils\Arr;
use Formwork\Utils\FileSystem;
use Formwork\Utils\Str;
use Stringable;
Expand Down Expand Up @@ -137,18 +136,6 @@ public function site(): Site
return $this;
}

/**
* Return site default data
*
* @return array<string, mixed>
*/
public function defaults(): array
{
$defaults = $this->config->getDefaults('site');

return [...$defaults, ...Arr::reject($this->fields()->pluck('default'), fn($value) => $value === null)];
}

public function parent(): Page|Site|null
{
return $this->parent ??= null;
Expand Down Expand Up @@ -470,11 +457,8 @@ public function load(): void

$this->fields = $this->scheme->fields();
$this->fields->setModel($this);
$this->data = [...$this->defaults(), ...$this->data];

$this->fields->setValues($this->data);

$this->loadRouteAliases();
}

/**
Expand Down Expand Up @@ -558,11 +542,12 @@ protected function setContentPath(string $path): void

/**
* Load site aliases
*
* @param array<string, string> $aliases
*/
protected function loadRouteAliases(): void
protected function setRouteAliases(array $aliases): void
{
$this->routeAliases = [];
foreach ($this->data['routeAliases'] as $from => $to) {
foreach ($aliases as $from => $to) {
$this->routeAliases[trim((string) $from, '/')] = trim((string) $to, '/');
}
}
Expand Down
67 changes: 26 additions & 41 deletions formwork/src/Config/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Formwork\Config;

use Formwork\Config\Exceptions\ConfigLoadingException;
use Formwork\Config\Exceptions\ConfigResolutionException;
use Formwork\Config\Exceptions\UnresolvedConfigException;
use Formwork\Data\Contracts\ArraySerializable;
Expand All @@ -16,18 +17,12 @@ class Config implements ArraySerializable
*/
protected const string INTERPOLATION_REGEX = '/\$(?!\$)\{([%a-z._]+)\}/i';

/**
* Whether the config has been resolved
*/
protected bool $resolved = false;

/**
* @param array<string, mixed> $config
* @param array<string, mixed> $defaults
*/
final public function __construct(
protected array $config = [],
protected array $defaults = [],
protected bool $resolved = false,
) {}

/**
Expand All @@ -38,14 +33,6 @@ public function has(string $key): bool
return Arr::has($this->config, $key);
}

/**
* Check if a key exists in the defaults
*/
public function hasDefaults(string $key): bool
{
return Arr::has($this->defaults, $key);
}

/**
* Get a value from the config
*/
Expand All @@ -57,40 +44,42 @@ public function get(string $key, mixed $default = null): mixed
return Arr::get($this->config, $key, $default);
}

/**
* Get a value from the defaults
*/
public function getDefaults(string $key, mixed $default = null): mixed
{
if (!$this->resolved) {
throw new UnresolvedConfigException('Unresolved config');
}
return Arr::get($this->defaults, $key, $default);
}

/**
* Load config from a path
*/
public function loadFromPath(string $path, bool $defaultConfig = false): void
{
foreach (FileSystem::listFiles($path) as $file) {
$this->loadFile(FileSystem::joinPaths($path, $file), $defaultConfig);
$this->loadFile(FileSystem::joinPaths($path, $file));
}
}

/**
* Load config from a file
*/
public function loadFile(string $path, bool $defaultConfig = false): void
public function loadFile(string $path): void
{
if (FileSystem::isReadable($path) && FileSystem::extension($path) === 'yaml') {
$name = FileSystem::name($path);
$data = (array) Yaml::parseFile($path);
if ($defaultConfig) {
$this->defaults[$name] = isset($this->defaults[$name]) ? array_replace_recursive($this->defaults[$name], $data) : $data;
}
$this->config[$name] = isset($this->config[$name]) ? array_replace_recursive($this->config[$name], $data) : $data;
if (!FileSystem::isFile($path)) {
throw new ConfigLoadingException(sprintf('Config file "%s" does not exist', $path));
}

$name = FileSystem::name($path);
$extension = FileSystem::extension($path);

switch ($extension) {
case 'php':
$data = (array) include $path;
break;

case 'yaml':
$data = (array) Yaml::parseFile($path);
break;

default:
throw new ConfigLoadingException(sprintf('Unsupported config file type "%s"', $extension));
}

$this->config[$name] = isset($this->config[$name]) ? array_replace_recursive($this->config[$name], $data) : $data;
}

/**
Expand Down Expand Up @@ -122,7 +111,6 @@ public function resolve(array $vars = []): void
});
};

$resolver($this->defaults);
$resolver($this->config);

$this->resolved = true;
Expand All @@ -133,15 +121,12 @@ public function toArray(): array
if (!$this->resolved) {
throw new UnresolvedConfigException('Unresolved config');
}
return [
'config' => $this->config,
'defaults' => $this->defaults,
];
return $this->config;
}

public static function fromArray(array $data): static
{
$static = new static($data['config'], $data['defaults']);
$static = new static($data['config']);
$static->resolved = true;
return $static;
}
Expand Down
7 changes: 7 additions & 0 deletions formwork/src/Config/Exceptions/ConfigLoadingException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

namespace Formwork\Config\Exceptions;

use RuntimeException;

class ConfigLoadingException extends RuntimeException {}
20 changes: 17 additions & 3 deletions formwork/src/Panel/Controllers/OptionsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Formwork\Panel\Controllers;

use Formwork\Config\Config;
use Formwork\Fields\FieldCollection;
use Formwork\Http\RequestMethod;
use Formwork\Http\Response;
Expand Down Expand Up @@ -45,9 +46,8 @@ public function systemOptions(Schemes $schemes): Response
$fields = $scheme->fields();

if ($this->request->method() === RequestMethod::POST) {
$data = $this->request->input();
$options = $this->config->get('system');
$defaults = $this->app->defaults();
$defaults = $this->defaultConfig()->get('system');
$fields->setValuesFromRequest($this->request, null)->validate();

$differ = $this->updateOptions('system', $fields, $options, $defaults);
Expand Down Expand Up @@ -90,7 +90,7 @@ public function siteOptions(Schemes $schemes): Response

if ($this->request->method() === RequestMethod::POST) {
$options = $this->site->data();
$defaults = $this->site->defaults();
$defaults = $this->defaultConfig()->get('site');
$fields->setValuesFromRequest($this->request, null)->validate();
$differ = $this->updateOptions('site', $fields, $options, $defaults);

Expand Down Expand Up @@ -118,6 +118,20 @@ public function siteOptions(Schemes $schemes): Response
]));
}

/**
* Get default config
*/
private function defaultConfig(): Config
{
$config = new Config();
$config->loadFromPath(SYSTEM_PATH . '/config/');
$config->resolve([
'%ROOT_PATH%' => ROOT_PATH,
'%SYSTEM_PATH%' => SYSTEM_PATH,
]);
return $config;
}

/**
* Update options of a given type with given data
*
Expand Down
4 changes: 2 additions & 2 deletions formwork/src/Panel/Panel.php
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ public function navigation(): NavigationItemCollection
{
$translation = $this->translations->getCurrent();
if (!isset($this->navigation)) {
$items = $this->container->call(require FileSystem::joinPaths($this->path(), 'navigation.php'), [
$items = $this->container->call(require $this->config->get('system.panel.config.navigation'), [
'translation' => $translation,
]);
$this->navigation = new NavigationItemCollection();
Expand Down Expand Up @@ -228,7 +228,7 @@ public function getCsrfTokenName(): string
*/
public function getAppConfig(): array
{
return $this->container->call(require FileSystem::joinPaths($this->path(), 'appconfig.php'), [
return $this->container->call(require $this->config->get('system.panel.config.app'), [
'translation' => $this->translations->getCurrent(),
]);
}
Expand Down
34 changes: 27 additions & 7 deletions formwork/src/Services/Loaders/ConfigServiceLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,42 @@
namespace Formwork\Services\Loaders;

use Formwork\Config\Config;
use Formwork\Http\Request;
use Formwork\Parsers\Php;
use Formwork\Services\Container;
use Formwork\Services\ServiceLoaderInterface;
use Formwork\Utils\FileSystem;

final class ConfigServiceLoader implements ServiceLoaderInterface
{
public function __construct(
private Request $request,
) {}

public function load(Container $container): Config
{
$config = new Config();
$cachePath = ROOT_PATH . '/cache/config/';
$cacheFile = FileSystem::joinPaths($cachePath, 'config.' . $this->request->host() . '.php');

if (!FileSystem::isDirectory($cachePath, assertExists: false)) {
FileSystem::createDirectory($cachePath);
}

if (FileSystem::exists($cacheFile) && !FileSystem::directoryModifiedSince(ROOT_PATH . '/site/config/', FileSystem::lastModifiedTime($cacheFile))) {
$config = new Config(require $cacheFile, resolved: true);
} else {
$config = new Config();

$config->loadFromPath(SYSTEM_PATH . '/config/');
$config->loadFromPath(ROOT_PATH . '/site/config/');

$config->loadFromPath(SYSTEM_PATH . '/config/', defaultConfig: true);
$config->loadFromPath(ROOT_PATH . '/site/config/');
$config->resolve([
'%ROOT_PATH%' => ROOT_PATH,
'%SYSTEM_PATH%' => SYSTEM_PATH,
]);

$config->resolve([
'%ROOT_PATH%' => ROOT_PATH,
'%SYSTEM_PATH%' => SYSTEM_PATH,
]);
Php::encodeToFile($config->toArray(), $cacheFile);
}

date_default_timezone_set($config->get('system.date.timezone'));

Expand Down
2 changes: 1 addition & 1 deletion formwork/src/Services/Loaders/PanelServiceLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public function load(Container $container): Panel
*/
public function onResolved(object $service, Container $container): void
{
$this->viewFactory->setMethods($container->call(require FileSystem::joinPaths($service->path(), 'methods.php')));
$this->viewFactory->setMethods($container->call(require $this->config->get('system.views.methods.panel')));

$this->schemes->loadFromPath($this->config->get('system.schemes.paths.panel'));

Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.