Completed
Push — master ( 5302a2...ba9418 )
by Tomáš
06:32 queued 04:07
created

FakeReferencesPass::processReferences()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 12
ccs 8
cts 8
cp 1
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 7
nc 3
nop 1
crap 3
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 2
    public function process(ContainerBuilder $container)
37
    {
38 2
        $this->container = $container;
39
40 2
        foreach ($container->getDefinitions() as $id => $definition) {
41 2
            $this->processDefinition($definition);
42
        }
43 2
    }
44
45
    /**
46
     * @param mixed $definition
47
     */
48 2
    private function processDefinition($definition)
49
    {
50 2
        if (!$definition instanceof Definition) {
51 2
            return;
52
        }
53
54 2
        $this->processReferences($definition->getArguments());
55 2
        $this->processReferences($definition->getMethodCalls());
56 2
        $this->processReferences($definition->getProperties());
57 2
    }
58
59
    /**
60
     * @param mixed $arguments
61
     */
62 2
    private function processReferences($arguments)
63
    {
64 2
        if (!is_array($arguments)) {
65 2
            return;
66
        }
67
68 2
        foreach ($arguments as $argument) {
69 2
            $this->processReferences($argument);
70 2
            $this->processDefinition($argument);
71 2
            $this->addMissingDefinitionReferenceToContainer($argument);
72
        }
73 2
    }
74
75
    /**
76
     * @param mixed $argument
77
     */
78 2
    private function addMissingDefinitionReferenceToContainer($argument)
79
    {
80 2
        if (!$this->isMissingDefinitionReference($argument)) {
81 2
            return;
82
        }
83
84 2
        $serviceName = (string) $argument;
85 2
        if (class_exists($serviceName)) {
86
            $serviceName = (new ReflectionClass($serviceName))->name;
87
        }
88
89 2
        if (!$this->container->has($serviceName)) {
90
            $this->container->setDefinition($serviceName, new Definition(stdClass::class));
91
        }
92 2
    }
93
94
    /**
95
     * @param mixed $argument
96
     */
97 2
    private function isMissingDefinitionReference($argument) : bool
98
    {
99 2
        return $argument instanceof Reference
100 2
        && $argument->getInvalidBehavior() === ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE;
101
    }
102
}
103