Skip to content

Commit

Permalink
Config\Processor use Schema
Browse files Browse the repository at this point in the history
  • Loading branch information
dg committed Mar 15, 2019
1 parent dde79da commit 7e4108f
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 87 deletions.
158 changes: 72 additions & 86 deletions src/DI/Config/Processor.php
Expand Up @@ -13,7 +13,6 @@
use Nette\DI\Definitions;
use Nette\DI\Definitions\Statement;
use Nette\DI\Extensions;
use Nette\Utils\Validators;


/**
Expand All @@ -23,65 +22,8 @@ class Processor
{
use Nette\SmartObject;

private $schemes = [
Definitions\ServiceDefinition::class => [
'method' => 'updateServiceDefinition',
'fields' => [
'type' => 'string|Nette\DI\Definitions\Statement',
'factory' => 'callable|Nette\DI\Definitions\Statement',
'arguments' => 'array',
'setup' => 'list',
'inject' => 'bool',
'autowired' => 'bool|string|array',
'tags' => 'array',
],
],
Definitions\AccessorDefinition::class => [
'method' => 'updateAccessorDefinition',
'fields' => [
'type' => 'string',
'implement' => 'string',
'factory' => 'callable|Nette\DI\Definitions\Statement',
'autowired' => 'bool|string|array',
'tags' => 'array',
],
],
Definitions\FactoryDefinition::class => [
'method' => 'updateFactoryDefinition',
'fields' => [
'type' => 'string',
'factory' => 'callable|Nette\DI\Definitions\Statement',
'implement' => 'string',
'arguments' => 'array',
'setup' => 'list',
'parameters' => 'array',
'references' => 'array',
'tagged' => 'string',
'inject' => 'bool',
'autowired' => 'bool|string|array',
'tags' => 'array',
],
],
Definitions\LocatorDefinition::class => [
'method' => 'updateLocatorDefinition',
'fields' => [
'implement' => 'string',
'references' => 'array',
'tagged' => 'string',
'autowired' => 'bool|string|array',
'tags' => 'array',
],
],
Definitions\ImportedDefinition::class => [
'method' => 'updateImportedDefinition',
'fields' => [
'type' => 'string',
'imported' => 'bool',
'autowired' => 'bool|string|array',
'tags' => 'array',
],
],
];
/** @var array */
private $schemas;

/** @var Nette\DI\ContainerBuilder */
private $builder;
Expand All @@ -90,6 +32,7 @@ class Processor
public function __construct(Nette\DI\ContainerBuilder $builder)
{
$this->builder = $builder;
$this->schemas = $this->getServiceSchemas();
}


Expand Down Expand Up @@ -139,8 +82,8 @@ public function normalizeConfig($config): array
$res += $config->arguments;
} elseif (count($config->arguments) > 1) {
$res['references'] = $config->arguments;
} else {
$res['factory'] = array_shift($config->arguments);
} elseif ($factory = array_shift($config->arguments)) {
$res['factory'] = $factory;
}
return $res;

Expand Down Expand Up @@ -192,9 +135,9 @@ private function loadDefinition(?string $name, array $config): void

$config = $this->expandParameters($config);
$def = $this->retrieveDefinition($name, $config);
$scheme = $this->schemes[get_class($def)];
$this->validateFields($config, $scheme['fields']);
$this->{$scheme['method']}($def, $config, $name);
$schema = $this->schemas[get_class($def)];
$schema['schema']->complete($config, $name ? [$name] : []);
$this->{$schema['method']}($def, $config, $name);
$this->updateDefinition($def, $config);
} catch (\Exception $e) {
throw new Nette\DI\InvalidConfigurationException(($name ? "Service '$name': " : '') . $e->getMessage(), [], $e);
Expand Down Expand Up @@ -236,7 +179,6 @@ private function updateServiceDefinition(Definitions\ServiceDefinition $definiti
$definition->setSetup([]);
}
foreach ($config['setup'] as $id => $setup) {
Validators::assert($setup, 'callable|Nette\DI\Definitions\Statement|array:1', "setup item #$id");
if (is_array($setup)) {
$setup = new Statement(key($setup), array_values($setup));
}
Expand Down Expand Up @@ -294,7 +236,6 @@ private function updateFactoryDefinition(Definitions\FactoryDefinition $definiti
$resultDef->setSetup([]);
}
foreach ($config['setup'] as $id => $setup) {
Validators::assert($setup, 'callable|Nette\DI\Definitions\Statement|array:1', "setup item #$id");
if (is_array($setup)) {
$setup = new Statement(key($setup), array_values($setup));
}
Expand Down Expand Up @@ -357,25 +298,6 @@ private function updateDefinition(Definitions\Definition $definition, array $con
}


private function validateFields(array $config, array $fields): void
{
$expected = array_keys($fields);
if ($error = array_diff(array_keys($config), $expected)) {
$hints = array_filter(array_map(function ($error) use ($expected) {
return Nette\Utils\ObjectHelpers::getSuggestion($expected, $error);
}, $error));
$hint = $hints ? ", did you mean '" . implode("', '", $hints) . "'?" : '.';
throw new Nette\DI\InvalidConfigurationException(sprintf("Unknown key '%s' in definition of service$hint", implode("', '", $error)));
}

foreach ($fields as $field => $expected) {
if (isset($config[$field])) {
Validators::assertField($config, $field, $expected);
}
}
}


private function convertKeyToName($key): ?string
{
if (is_int($key)) {
Expand Down Expand Up @@ -448,4 +370,68 @@ public static function processArguments(array $args): array
}
return $args;
}


public function getServiceSchemas(): array
{
return [
Definitions\ServiceDefinition::class => [
'method' => 'updateServiceDefinition',
'schema' => Expect::array([
'type' => Expect::type('string|Nette\DI\Definitions\Statement'),
'factory' => Expect::type('callable|Nette\DI\Definitions\Statement'),
'arguments' => Expect::array(),
'setup' => Expect::listOf('callable|Nette\DI\Definitions\Statement|array:1'),
'inject' => Expect::bool(),
'autowired' => Expect::type('bool|string|array'),
'tags' => Expect::array(),
]),
],
Definitions\AccessorDefinition::class => [
'method' => 'updateAccessorDefinition',
'schema' => Expect::array([
'type' => Expect::string(),
'implement' => Expect::string(),
'factory' => Expect::type('callable|Nette\DI\Definitions\Statement'),
'autowired' => Expect::type('bool|string|array'),
'tags' => Expect::array(),
]),
],
Definitions\FactoryDefinition::class => [
'method' => 'updateFactoryDefinition',
'schema' => Expect::array([
'type' => Expect::string(),
'factory' => Expect::type('callable|Nette\DI\Definitions\Statement'),
'implement' => Expect::string(),
'arguments' => Expect::array(),
'setup' => Expect::listOf('callable|Nette\DI\Definitions\Statement|array:1'),
'parameters' => Expect::array(),
'references' => Expect::array(),
'tagged' => Expect::string(),
'inject' => Expect::bool(),
'autowired' => Expect::type('bool|string|array'),
'tags' => Expect::array(),
]),
],
Definitions\LocatorDefinition::class => [
'method' => 'updateLocatorDefinition',
'schema' => Expect::array([
'implement' => Expect::string(),
'references' => Expect::array(),
'tagged' => Expect::string(),
'autowired' => Expect::type('bool|string|array'),
'tags' => Expect::array(),
]),
],
Definitions\ImportedDefinition::class => [
'method' => 'updateImportedDefinition',
'schema' => Expect::array([
'type' => Expect::string(),
'imported' => Expect::bool(),
'autowired' => Expect::type('bool|string|array'),
'tags' => Expect::array(),
]),
],
];
}
}
2 changes: 1 addition & 1 deletion tests/DI/Compiler.unknownDefinitionKey.phpt
Expand Up @@ -22,4 +22,4 @@ Assert::throws(function () {
setups: []
foo: bar
');
}, Nette\DI\InvalidConfigurationException::class, "Unknown key 'autowire', 'setups', 'foo' in definition of service, did you mean 'autowired', 'setup'?");
}, Nette\DI\InvalidConfigurationException::class, "Unexpected option 'autowire', did you mean 'autowired'?");

0 comments on commit 7e4108f

Please sign in to comment.