Skip to content

Commit

Permalink
ParametersExtension: WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
dg committed Sep 21, 2023
1 parent de7ac91 commit 1429d91
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 16 deletions.
2 changes: 1 addition & 1 deletion src/DI/Compiler.php
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ public function getConfig(): array
public function setDynamicParameterNames(array $names)
{
assert($this->extensions[self::Parameters] instanceof Extensions\ParametersExtension);
$this->extensions[self::Parameters]->dynamicParams = $names;
$this->extensions[self::Parameters]->dynamicParams = array_flip($names);
return $this;
}

Expand Down
15 changes: 15 additions & 0 deletions src/DI/Container.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,21 @@ public function getParameters(): array
}


public function getParameter($key)
{
if (!array_key_exists($key, $this->parameters)) {
$this->parameters[$key] = $this->getDynamicParameter($key);
}
return $this->parameters[$key];
}


protected function getDynamicParameter($key)
{
throw new Nette\InvalidStateException(sprintf('Dynamic parameter %s not found.', $key));
}


/**
* Adds the service to the container.
* @param object $service service or its factory
Expand Down
68 changes: 53 additions & 15 deletions src/DI/Extensions/ParametersExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
*/
final class ParametersExtension extends Nette\DI\CompilerExtension
{
/** @var string[] */
/** @var array */
public $dynamicParams = [];

/** @var string[][] */
Expand All @@ -38,17 +38,24 @@ public function loadConfiguration()
{
$builder = $this->getContainerBuilder();
$params = $this->config;
$resolver = new Nette\DI\Resolver($builder);
$generator = new Nette\DI\PhpGenerator($builder);

foreach ($this->dynamicParams as $key) {
$params[$key] = array_key_exists($key, $params)
? new DynamicParameter($generator->formatPhp('($this->parameters[?] \?\? ?)', $resolver->completeArguments(Nette\DI\Helpers::filterArguments([$key, $params[$key]]))))
: new DynamicParameter((new Nette\PhpGenerator\Dumper)->format('$this->parameters[?]', $key));
// auto-tagging of parameters as dynamic
foreach ($params as $key => $value) {
$tmp = [$value];
array_walk_recursive($tmp, function ($val) use ($key): void {
if ($val instanceof Nette\DI\Definitions\Statement) {
$this->dynamicParams[$key] = null;
}
});
}

foreach ($this->dynamicParams as $key => $foo) {
$params[$key] = new DynamicParameter((new Nette\PhpGenerator\Dumper)->format('$this->getParameter(?)', $key));
}

$builder->parameters = Nette\DI\Helpers::expand($params, $params, true);


// expand all except 'services'
$slice = array_diff_key($this->compilerConfig, ['services' => 1]);
$slice = Nette\DI\Helpers::expand($slice, $builder->parameters);
Expand All @@ -58,18 +65,49 @@ public function loadConfiguration()

public function afterCompile(Nette\PhpGenerator\ClassType $class)
{
$params = $this->getContainerBuilder()->parameters;
array_walk_recursive($params, function (&$val): void {
if ($val instanceof Nette\DI\Definitions\Statement) {
$val = '* unavailable value *';
}
});
$builder = $this->getContainerBuilder();

// static parameters
$staticParams = $builder->parameters;
foreach ($staticParams as $key => $value) {
$tmp = [$value];
array_walk_recursive($tmp, function ($val) use ($key, &$staticParams): void {
if ($val instanceof DynamicParameter) {
$this->dynamicParams[$key] = null;
unset($staticParams[$key]);
}
});
}

$cnstr = $class->getMethod('__construct');
$cnstr->addBody('$this->parameters += ?;', [$params]);
$cnstr->addBody('$this->parameters += ?;', [$staticParams]);

// dynamic parameters
$getter = $class->addMethod('getDynamicParameter')->setProtected();
$getter->addParameter('key'); //->setType('string|int');
/*$body = 'return match($key) {';
foreach ($this->dynamicParams as $key => $value) {
unset($params[$key]);
$body .= "\n\t" . var_export($key, true) . ' => ' . $value . ',';
}
$body .= "\n\t" . 'default => parent::getDynamicParameter($key),' . "\n};";*/
$body = 'switch (true) {';

$resolver = new Nette\DI\Resolver($builder);
$generator = new Nette\DI\PhpGenerator($builder);
foreach ($this->dynamicParams as $key => $foo) {
$value = Nette\DI\Helpers::expand($this->config[$key] ?? null, $builder->parameters); // or $params?
$value = $resolver->completeArguments(Nette\DI\Helpers::filterArguments([$value]));
$body .= "\n\t" . 'case $key === ' . var_export($key, true) . ': return ' . $generator->formatPhp('?', $value) . ';';
}
$body .= "\n\t" . 'default: parent::getDynamicParameter($key);' . "\n};";
$getter->addBody($body);

// dynamic parameters validation
$initialize = $class->getMethod('initialize');
foreach ($this->dynamicValidators as [$param, $expected]) {
if (!$param instanceof Nette\DI\Definitions\Statement) {
$cnstr->addBody('Nette\Utils\Validators::assert(?, ?, ?);', [$param, $expected, 'dynamic parameter']);
$initialize->addBody('Nette\Utils\Validators::assert(?, ?, ?);', [$param, $expected, 'dynamic parameter']);
}
}
}
Expand Down

0 comments on commit 1429d91

Please sign in to comment.