Skip to content

Commit b2440b9

Browse files
authored
Merge pull request #3 from Jibbarth/feature/check-config-before-write
Feature/check config before write
2 parents f3a73e8 + 1924fd3 commit b2440b9

File tree

5 files changed

+93
-78
lines changed

5 files changed

+93
-78
lines changed

README.md

Lines changed: 12 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ References this [documentation example](http://symfony.com/doc/current/bundles/c
77

88
The mechanism behind is to retrieve all available configuration for a bundle, display it in a form, and dump the submitted data in a new _config file_ that will override the default configuration.
99

10-
1110
## Installation
1211

1312
### Step 1: Download the Bundle
@@ -18,36 +17,6 @@ Open a command console, enter your project directory and execute:
1817
$ composer require barth/simple-config-bundle
1918
```
2019

21-
> :warning: This is not already available as I didn't yet submit this package to [Packagist](https://packagist.org)
22-
> Stay tuned for update by giving a :star: ?
23-
24-
Or open your `composer.json`, and add following content :
25-
26-
```js
27-
{
28-
// ...
29-
"repositories": [
30-
{
31-
"type": "vcs",
32-
"url": "git@github.com:Jibbarth/SimpleConfigBundle",
33-
"vendor-alias": "barth"
34-
}
35-
],
36-
"require": {
37-
//...
38-
"barth/simple-config-bundle": "dev-master"
39-
}
40-
//...
41-
}
42-
```
43-
44-
Open a command console, enter your project directory and execute the
45-
following command to download the latest stable version of this bundle:
46-
47-
```console
48-
$ composer update
49-
```
50-
5120
This command requires you to have Composer installed globally, as explained
5221
in the [installation chapter](https://getcomposer.org/doc/00-intro.md)
5322
of the Composer documentation.
@@ -67,32 +36,7 @@ return [
6736
];
6837
```
6938

70-
### Step 3: Active the override for configuration
71-
72-
In your `src/Kernel.php`, alter the `configureContainer` function :
73-
74-
```php
75-
protected function configureContainer(ContainerBuilder $container, LoaderInterface $loader)
76-
{
77-
$container->addResource(new FileResource($this->getProjectDir().'/config/bundles.php'));
78-
// Feel free to remove the "container.autowiring.strict_mode" parameter
79-
// if you are using symfony/dependency-injection 4.0+ as it's the default behavior
80-
$container->setParameter('container.autowiring.strict_mode', true);
81-
$container->setParameter('container.dumper.inline_class_loader', true);
82-
$confDir = $this->getProjectDir().'/config';
83-
84-
$loader->load($confDir.'/{packages}/*'.self::CONFIG_EXTS, 'glob');
85-
$loader->load($confDir.'/{packages}/'.$this->environment.'/**/*'.self::CONFIG_EXTS, 'glob');
86-
87-
// ADD THIS LINE
88-
$loader->load($confDir.'/{packages}/override/**/*'.self::CONFIG_EXTS, 'glob');
89-
90-
$loader->load($confDir.'/{services}'.self::CONFIG_EXTS, 'glob');
91-
$loader->load($confDir.'/{services}_'.$this->environment.self::CONFIG_EXTS, 'glob');
92-
}
93-
```
94-
95-
### Step 4: Import routes
39+
### Step 3: Import routes
9640

9741
In your `config/routes.yaml`, add the following route definition :
9842

@@ -132,10 +76,16 @@ When installation is completed, you have two new routes :
13276
* http://yourdomain.org/admin/config That exposes all available configuration routes
13377
* http://yourdomain.org/admin/config/{package} That display your form configuration
13478

135-
## Customize
79+
## Customization and Integration
80+
81+
### Custom Backend
13682

13783
By default, pages don't look very pretty. To integrate it in your template, don't hesitate to override the `base.html.twig` template by creating a new one in `templates/bundles/BarthSimpleConfigBundle/` and make it extend your base template.
13884

85+
### Third-party bundles
86+
87+
SimpleConfigBundle can easily be integrated in [EasyAdminBundle](https://github.com/EasyCorp/EasyAdminBundle).
88+
Just require it.
13989

14090
## Contribute
14191

@@ -145,10 +95,11 @@ If you find any typo/misconfiguration/... please send me a PR or open an issue.
14595

14696
Also, while creating your PR, please write a description which gives the context and/or explains why you are creating it.
14797

148-
14998
## TODOs
15099

151-
- [ ] Make installation as simple as a `composer require barth/simple-config-bundle`, so submit it to packagist
152-
- [ ] Process configuration when form is submitted to validate it immediatly.
100+
- [x] Make installation as simple as a `composer require barth/simple-config-bundle`, so submit it to packagist
101+
- [x] Process configuration when form is submitted to validate it immediatly.
153102
- [ ] Write Tests Suite
154103
- [ ] Add translations
104+
- [x] Integration with [EasyAdminBundle](https://github.com/EasyCorp/EasyAdminBundle)
105+
- [ ] Integration with [Sonata](https://sonata-project.org/)

src/Controller/DefaultController.php

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -74,25 +74,36 @@ public function editAction(
7474
FormConfigService $formConfigService
7575
): Response {
7676
$extension = $this->extensionLocatorService->retrieveByPackageName($package);
77-
$config = $this->extensionConfigurationService->getConfiguration($extension);
77+
$config = $this->extensionConfigurationService->getCurrentConfiguration($extension);
7878

7979
$form = $formConfigService->getFormForConfig($config);
8080
$form->handleRequest($request);
8181

8282
if ($form->isSubmitted() && $form->isValid()) {
83+
$nameConverter = new SnakeCaseToCamelCaseNameConverter();
8384
$data = $this->cleanData($form->getData());
84-
// TODO validate configuration
85+
try {
86+
$data = $this->configService->parseConfig($data);
87+
$data = $this->extensionConfigurationService->validateConfiguration($extension, [$extension->getAlias() => $data]);
88+
$this->configService->saveNewConfig($package, $data);
89+
if ($this->configService->isOverrideConfigForPackageExist($package)) {
90+
$nameConverter = new SnakeCaseToCamelCaseNameConverter();
91+
$this->get('session')->getFlashBag()->add(
92+
'success',
93+
'Successfully registered config for ' . $nameConverter->handle($package)
94+
);
95+
}
8596

86-
$this->configService->saveNewConfig($package, $data);
87-
if ($this->configService->isOverrideConfigForPackageExist($package)) {
88-
$nameConverter = new SnakeCaseToCamelCaseNameConverter();
97+
return $this->redirect($this->generateUrl('barth_simpleconfig_index'));
98+
} catch (\Throwable $throwable) {
8999
$this->get('session')->getFlashBag()->add(
90-
'success',
91-
'Successfully registered config for ' . $nameConverter->handle($package)
100+
'error',
101+
sprintf('Error for %s : %s',
102+
$nameConverter->handle($package),
103+
$throwable->getMessage()
104+
)
92105
);
93106
}
94-
95-
return $this->redirect($this->generateUrl('barth_simpleconfig_index'));
96107
}
97108

98109
$nameConverter = new SnakeCaseToCamelCaseNameConverter();

src/Service/ConfigService.php

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,30 @@ public function saveNewConfig(string $package, array $config): void
2929
{
3030
$fs = new Filesystem();
3131
$packageOverrideFile = $this->getOverridePackagePath() . \DIRECTORY_SEPARATOR . $package . '.yaml';
32+
$config = $this->parseConfig($config);
33+
34+
$fs->dumpFile($packageOverrideFile, Yaml::dump([$package => $config], 4));
35+
}
36+
37+
public function parseConfig(array $config): array
38+
{
3239
foreach ($config as $key => $value) {
33-
if (\strpos('-', $key)) {
40+
if (\strpos($key, '_dot_')) {
3441
unset($config[$key]);
35-
$key = \str_replace('.', '-', $key);
42+
$key = \str_replace('_dot_', '.', $key);
43+
$config[$key] = $value;
44+
}
45+
if (\strpos($key, '_backslash_')) {
46+
unset($config[$key]);
47+
$key = \str_replace('_backslash_', '\\', $key);
3648
$config[$key] = $value;
3749
}
3850
if (\strpos($key, ':')) {
3951
$this->unflattenArray($config, $key, $value);
4052
unset($config[$key]);
4153
}
4254
}
43-
$fs->dumpFile($packageOverrideFile, Yaml::dump([$package => $config], 4));
55+
return $config;
4456
}
4557

4658
public function isOverrideConfigForPackageExist(string $package): bool

src/Service/ExtensionConfigurationService.php

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Barth\SimpleConfigBundle\Service;
44

55
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
6+
use Symfony\Component\Config\Definition\ConfigurationInterface;
67
use Symfony\Component\Config\Definition\Processor;
78
use Symfony\Component\DependencyInjection\ContainerBuilder;
89
use Symfony\Component\DependencyInjection\Extension\ExtensionInterface;
@@ -26,23 +27,40 @@ public function __construct(
2627
$this->kernel = $kernel;
2728
}
2829

29-
public function getConfiguration(ExtensionInterface $extension): array
30+
/**
31+
* @throws \Exception
32+
*/
33+
public function validateConfiguration(ExtensionInterface $extension, array $configs): array
34+
{
35+
$configs[$extension->getAlias()] = $this->cleanConfig($configs[$extension->getAlias()], $this->getCurrentConfiguration($extension));
36+
$processor = new Processor();
37+
$container = $this->getContainerBuilder();
38+
$container->resolveEnvPlaceholders(
39+
$container->getParameterBag()->resolveValue(
40+
$processor->processConfiguration($this->getExtensionConfiguration($extension), $configs)
41+
)
42+
);
43+
44+
45+
return $configs[$extension->getAlias()];
46+
}
47+
48+
public function getCurrentConfiguration(ExtensionInterface $extension): array
3049
{
3150
$config = [];
3251

3352
try {
3453
$container = $this->getContainerBuilder();
3554
$configs = $container->getExtensionConfig($extension->getAlias());
3655

37-
$configuration = $extension->getConfiguration($configs, $container);
3856
$configs = $container->resolveEnvPlaceholders(
3957
$container->getParameterBag()->resolveValue($configs)
4058
);
41-
$processor = new Processor();
4259

60+
$processor = new Processor();
4361
$config = $container->resolveEnvPlaceholders(
4462
$container->getParameterBag()->resolveValue(
45-
$processor->processConfiguration($configuration, $configs)
63+
$processor->processConfiguration($this->getExtensionConfiguration($extension), $configs)
4664
)
4765
);
4866
} catch (\Throwable $throwable) {
@@ -62,6 +80,14 @@ public function getTreeBuilderForExtension(ExtensionInterface $extension): TreeB
6280
return $configuration->getConfigTreeBuilder();
6381
}
6482

83+
protected function getExtensionConfiguration(ExtensionInterface $extension): ConfigurationInterface
84+
{
85+
$container = $this->getContainerBuilder();
86+
$configs = $container->getExtensionConfig($extension->getAlias());
87+
88+
return $extension->getConfiguration($configs, $container);
89+
}
90+
6591
protected function getContainerBuilder(): ContainerBuilder
6692
{
6793
if (null === $this->containerBuilder) {
@@ -78,4 +104,18 @@ protected function getContainerBuilder(): ContainerBuilder
78104

79105
return $this->containerBuilder;
80106
}
107+
108+
/**
109+
* Remove key that is equals to current configuration
110+
*/
111+
protected function cleanConfig(array $configs, array $currentConfig): array
112+
{
113+
foreach ($configs as $key => $config) {
114+
if (isset($currentConfig[$key]) && $currentConfig[$key] === $config ) {
115+
unset($configs[$key]);
116+
}
117+
}
118+
119+
return $configs;
120+
}
81121
}

src/Service/FormConfigService.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,8 @@ protected function addToForm(FormBuilderInterface $formBuilder, string $key, $fi
7272
if ('' !== $parentKey) {
7373
$key = $parentKey . ':' . $key;
7474
}
75-
$key = \str_replace('.', '-', $key);
75+
$key = \str_replace('.', '_dot_', $key);
76+
$key = \str_replace('\\', '_backslash_', $key);
7677
$formBuilder->add($key, $type, $params);
7778
}
7879

0 commit comments

Comments
 (0)