Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[php-di v7] DefinitionGlob #18

Open
wants to merge 9 commits into
base: mod7
Choose a base branch
from
11 changes: 8 additions & 3 deletions .php-cs-fixer.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,14 @@
'@Symfony' => true,
'@Symfony:risky' => true,
'array_syntax' => ['syntax' => 'short'],
'braces' => [
'allow_single_line_closure' => true,
],
'single_space_around_construct' => true,
'control_structure_braces' => true,
'control_structure_continuation_position' => true,
'declare_parentheses' => true,
'no_multiple_statements_per_line' => true,
'braces_position' => true,
'statement_indentation' => true,
'no_extra_blank_lines' => true,
'concat_space' => [
'spacing' => 'one',
],
Expand Down
3 changes: 3 additions & 0 deletions src/ContainerBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use DI\Definition\Source\AttributeBasedAutowiring;
use DI\Definition\Source\DefinitionArray;
use DI\Definition\Source\DefinitionFile;
use DI\Definition\Source\DefinitionGlob;
use DI\Definition\Source\DefinitionSource;
use DI\Definition\Source\NoAutowiring;
use DI\Definition\Source\ReflectionBasedAutowiring;
Expand Down Expand Up @@ -116,6 +117,8 @@ public function build()
}
if (is_array($definitions)) {
return new DefinitionArray($definitions, $autowiring);
} elseif ($definitions instanceof DefinitionGlob) {
$definitions->setAutowiring($autowiring);
}

return $definitions;
Expand Down
67 changes: 67 additions & 0 deletions src/Definition/Source/DefinitionGlob.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php

declare(strict_types=1);

namespace DI\Definition\Source;

use DI\Definition\Definition;

/**
* Reads DI definitions from files matching glob pattern.
*/
class DefinitionGlob implements DefinitionSource
{
private bool $initialized = false;

private ?Autowiring $autowiring = null;

private ?SourceChain $sourceChain = null;

/**
* @param string $pattern Glob pattern to files containing definitions
*/
public function __construct(
/**
* Glob pattern to files containing definitions.
*/
private string $pattern
) {
}

public function setAutowiring(Autowiring $autowiring) : void
{
$this->autowiring = $autowiring;
}

public function getDefinition(string $name) : Definition|null
{
$this->initialize();

return $this->sourceChain->getDefinition($name);
}

public function getDefinitions() : array
{
$this->initialize();

return $this->sourceChain->getDefinitions();
}

/**
* Lazy-loading of the definitions.
*/
private function initialize() : void
{
if ($this->initialized === true) {
return;
}

// prevent errors due to GLOB_BRACE that does not exist e.g. Alpine Linux
$flags = defined('GLOB_BRACE') ? \GLOB_BRACE : 0;
$paths = glob($this->pattern, $flags);
$sources = array_map(fn (string $path) => new DefinitionFile($path, $this->autowiring), $paths);

$this->sourceChain = new SourceChain($sources);
$this->initialized = true;
}
}
53 changes: 53 additions & 0 deletions tests/UnitTest/Definition/Source/DefinitionGlobTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

declare(strict_types=1);

namespace DI\Test\UnitTest\Definition\Source;

use DI\Definition\Source\DefinitionGlob;
use DI\Definition\ValueDefinition;
use PHPUnit\Framework\TestCase;
use ReflectionClass;

/**
* @covers \DI\Definition\Source\DefinitionGlob
*/
class DefinitionGlobTest extends TestCase
{
/**
* @test
*/
public function should_load_definitions_from_glob()
{
$pattern = __DIR__ . '/*/definitions.php';
$source = new DefinitionGlob($pattern);

$class = new ReflectionClass(DefinitionGlob::class);
$property = $class->getProperty('sourceChain');
$property->setAccessible(true);
$sourceChain = $property->getValue($source);
// sources are not initialized (and files are not read) before getting definitions
$this->assertNull($sourceChain);

$definitions = $source->getDefinitions();
$this->assertCount(2, $definitions);

/** @var ValueDefinition $definition */
$definition = $definitions['foo'];
$this->assertInstanceOf(ValueDefinition::class, $definition);
$this->assertEquals('bar', $definition->getValue());
$this->assertIsString($definition->getValue());
}

/**
* @test
*/
public function empty_definitions_for_pattern_not_matching_any_files()
{
$pattern = __DIR__ . '/*/no-definitions-here.php';
$source = new DefinitionGlob($pattern);

$definitions = $source->getDefinitions();
$this->assertCount(0, $definitions);
}
}
Loading