Completed
Push — master ( 646ad7...add88d )
by Tomáš
10:20
created

FakeReferencesPass::isMissingDefinitionReference()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 3
nc 2
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of Symplify.
7
 * Copyright (c) 2016 Tomas Votruba (http://tomasvotruba.cz).
8
 */
9
10
namespace Symplify\NetteAdapaterForSymfonyBundles\Compiler;
11
12
use ReflectionClass;
13
use stdClass;
14
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
15
use Symfony\Component\DependencyInjection\ContainerBuilder;
16
use Symfony\Component\DependencyInjection\ContainerInterface;
17
use Symfony\Component\DependencyInjection\Definition;
18
use Symfony\Component\DependencyInjection\Reference;
19
20
/**
21
 * This compiler pass will disable all missing references to named services.
22
 * Missing parameter resolution shall be resolved in Nette's ContainerBuilder.
23
 *
24
 * Based on {@see Symfony\Component\DependencyInjection\Compiler\CheckExceptionOnInvalidReferenceBehaviorPass}
25
 */
26
final class FakeReferencesPass implements CompilerPassInterface
27
{
28
    /**
29
     * @var ContainerBuilder
30
     */
31
    private $container;
32
33
    /**
34
     * {@inheritdoc}
35
     */
36
    public function process(ContainerBuilder $container)
37
    {
38
        $this->container = $container;
39
40
        foreach ($container->getDefinitions() as $id => $definition) {
41
            $this->processDefinition($definition);
42
        }
43
    }
44
45
    private function processDefinition(Definition $definition)
46
    {
47
        $this->processReferences($definition->getArguments());
48
        $this->processReferences($definition->getMethodCalls());
49
        $this->processReferences($definition->getProperties());
50
    }
51
52
    private function processReferences(array $arguments)
53
    {
54
        foreach ($arguments as $argument) {
55
            if (is_array($argument)) {
56
                $this->processReferences($argument);
57
            } elseif ($argument instanceof Definition) {
58
                $this->processDefinition($argument);
59
            } elseif ($this->isMissingDefinitionReference($argument)) {
60
                $this->addMissingDefinitionReferenceToContainer($argument);
61
            }
62
        }
63
    }
64
65
    /**
66
     * @param mixed $argument
67
     */
68
    private function isMissingDefinitionReference($argument)
69
    {
70
        return $argument instanceof Reference
71
            && $argument->getInvalidBehavior() === ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE;
72
    }
73
74
    private function addMissingDefinitionReferenceToContainer(Reference $argument)
75
    {
76
        $serviceName = (string) $argument;
77
        if (class_exists($serviceName)) {
78
            $serviceName = (new ReflectionClass($serviceName))->name;
79
        }
80
81
        if (!$this->container->has($serviceName)) {
82
            $this->container->setDefinition($serviceName, new Definition(stdClass::class));
83
        }
84
    }
85
}
86