Skip to content

Commit

Permalink
Merge branch 'master' of github.com:jbtronics/settings-bundle
Browse files Browse the repository at this point in the history
  • Loading branch information
jbtronics committed Jan 23, 2024
2 parents 2c8d2a7 + e6f03f6 commit 14b165e
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 20 deletions.
7 changes: 7 additions & 0 deletions config/services.php
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,13 @@
]);
}

$services->set('jbtronics.settings.env_processor', \Jbtronics\SettingsBundle\DependencyInjection\SettingsEnvProcessor::class)
->tag('container.env_var_processor')
->args([
'$settingsManager' => service('jbtronics.settings.settings_manager'),
'$metadataManager' => service('jbtronics.settings.metadata_manager'),
]);

/*********************************************************************************
* Form subsystem
*********************************************************************************/
Expand Down
74 changes: 74 additions & 0 deletions src/DependencyInjection/SettingsEnvProcessor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?php
/*
* This file is part of jbtronics/settings-bundle (https://github.com/jbtronics/settings-bundle).
*
* Copyright (c) 2024 Jan Böhmer
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

declare(strict_types=1);


namespace Jbtronics\SettingsBundle\DependencyInjection;

use Jbtronics\SettingsBundle\Helper\PropertyAccessHelper;
use Jbtronics\SettingsBundle\Manager\SettingsManagerInterface;
use Jbtronics\SettingsBundle\Metadata\MetadataManagerInterface;
use Symfony\Component\DependencyInjection\EnvVarProcessorInterface;
use Symfony\Component\DependencyInjection\Exception\EnvNotFoundException;

/**
* This env var processor allows to use settings in container parameters, via the syntax "%env(settings:settingsName:parameterName)%"
* You should try to avoid using this processor, as it is not very performant. Instead, you should use the SettingsManager to retrieve the settings, whenever possible.
*/
class SettingsEnvProcessor implements EnvVarProcessorInterface
{

public function __construct(private readonly SettingsManagerInterface $settingsManager,
private readonly MetadataManagerInterface $metadataManager)
{
}

public function getEnv(string $prefix, string $name, \Closure $getEnv): mixed
{
//Split the name into the settings name (before :) and the parameter name
$nameParts = explode(':', $name);
if (count($nameParts) !== 2) {
throw new EnvNotFoundException(sprintf('The environment variable "%s" is not valid. It must be in the format "settingsName:parameterName".', $name));
}
[$settingsName, $parameterName] = $nameParts;

//Retrieve the settings instance
$settings = $this->settingsManager->get($settingsName);

//And resolve the parameter name
$propertyName = $this->metadataManager->getSettingsMetadata($settingsName)->getParameter($parameterName)->getPropertyName();

//Retrieve the parameter value via reflection
return PropertyAccessHelper::getProperty($settings, $propertyName);
}

public static function getProvidedTypes(): array
{
return [
'settings' => 'bool|int|float|string|array|' . \BackedEnum::class,
];
}
}
44 changes: 24 additions & 20 deletions src/Manager/SettingsRegistry.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,37 +55,41 @@ public function __construct(
public function getSettingsClasses(): array
{
if ($this->debug_mode) {
return $this->searchInPathes($this->directories);
return $this->getSettingsClassUncached();
}

return $this->cache->get(self::CACHE_KEY, function () {
$classes = $this->searchInPathes($this->directories);

$tmp = [];
return $this->getSettingsClassUncached();
});
}
private function getSettingsClassUncached(): array
{
$classes = $this->searchInPathes($this->directories);

//Determine the short name for each class
foreach ($classes as $class) {
$reflClass = new \ReflectionClass($class);
$attributes = $reflClass->getAttributes(Settings::class);
$tmp = [];

if (count($attributes) > 0) {
$attribute = $attributes[0];
/** @var Settings $settings */
$settings = $attribute->newInstance();
//Determine the short name for each class
foreach ($classes as $class) {
$reflClass = new \ReflectionClass($class);
$attributes = $reflClass->getAttributes(Settings::class);

$name = $settings->name ?? self::generateDefaultNameFromClassName($class);
if (count($attributes) > 0) {
$attribute = $attributes[0];
/** @var Settings $settings */
$settings = $attribute->newInstance();

//Ensure that the name is unique
if (isset($tmp[$name])) {
throw new \InvalidArgumentException(sprintf('There is already a class with the name %s (%s)!', $name, $tmp[$name]));
}
$name = $settings->name ?? self::generateDefaultNameFromClassName($class);

$tmp[$name] = $class;
//Ensure that the name is unique
if (isset($tmp[$name])) {
throw new \InvalidArgumentException(sprintf('There is already a class with the name %s (%s)!', $name, $tmp[$name]));
}

$tmp[$name] = $class;
}
}

return $tmp;
});
return $tmp;
}

/**
Expand Down

0 comments on commit 14b165e

Please sign in to comment.