resolveDefinition()   F
last analyzed

Complexity

Conditions 20
Paths > 20000

Size

Total Lines 100
Code Lines 59

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 100
rs 2
cc 20
eloc 59
nc 106497
nop 2

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/*
4
 * This file is part of the Symfony package.
5
 *
6
 * (c) Fabien Potencier <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Symfony\Component\DependencyInjection\Compiler;
13
14
use Symfony\Component\DependencyInjection\Definition;
15
use Symfony\Component\DependencyInjection\DefinitionDecorator;
16
use Symfony\Component\DependencyInjection\ContainerBuilder;
17
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
18
19
/**
20
 * This replaces all DefinitionDecorator instances with their equivalent fully
21
 * merged Definition instance.
22
 *
23
 * @author Johannes M. Schmitt <[email protected]>
24
 */
25
class ResolveDefinitionTemplatesPass implements CompilerPassInterface
26
{
27
    private $container;
28
    private $compiler;
29
    private $formatter;
30
31
    /**
32
     * Process the ContainerBuilder to replace DefinitionDecorator instances with their real Definition instances.
33
     *
34
     * @param ContainerBuilder $container
35
     */
36
    public function process(ContainerBuilder $container)
37
    {
38
        $this->container = $container;
39
        $this->compiler = $container->getCompiler();
40
        $this->formatter = $this->compiler->getLoggingFormatter();
41
42
        foreach ($container->getDefinitions() as $id => $definition) {
43
            // yes, we are specifically fetching the definition from the
44
            // container to ensure we are not operating on stale data
45
            $definition = $container->getDefinition($id);
46
            if (!$definition instanceof DefinitionDecorator || $definition->isAbstract()) {
47
                continue;
48
            }
49
50
            $this->resolveDefinition($id, $definition);
51
        }
52
    }
53
54
    /**
55
     * Resolves the definition.
56
     *
57
     * @param string              $id         The definition identifier
58
     * @param DefinitionDecorator $definition
59
     *
60
     * @return Definition
61
     *
62
     * @throws \RuntimeException When the definition is invalid
63
     */
64
    private function resolveDefinition($id, DefinitionDecorator $definition)
65
    {
66
        if (!$this->container->hasDefinition($parent = $definition->getParent())) {
67
            throw new RuntimeException(sprintf('The parent definition "%s" defined for definition "%s" does not exist.', $parent, $id));
68
        }
69
70
        $parentDef = $this->container->getDefinition($parent);
71
        if ($parentDef instanceof DefinitionDecorator) {
72
            $parentDef = $this->resolveDefinition($parent, $parentDef);
73
        }
74
75
        $this->compiler->addLogMessage($this->formatter->formatResolveInheritance($this, $id, $parent));
76
        $def = new Definition();
77
78
        // merge in parent definition
79
        // purposely ignored attributes: scope, abstract, tags
80
        $def->setClass($parentDef->getClass());
81
        $def->setArguments($parentDef->getArguments());
82
        $def->setMethodCalls($parentDef->getMethodCalls());
83
        $def->setProperties($parentDef->getProperties());
84
        if ($parentDef->getFactoryClass(false)) {
0 ignored issues
show
Deprecated Code introduced by
The method Symfony\Component\Depend...tion::getFactoryClass() has been deprecated with message: since version 2.6, to be removed in 3.0.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
Bug Best Practice introduced by
The expression $parentDef->getFactoryClass(false) of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
85
            $def->setFactoryClass($parentDef->getFactoryClass(false));
0 ignored issues
show
Deprecated Code introduced by
The method Symfony\Component\Depend...tion::getFactoryClass() has been deprecated with message: since version 2.6, to be removed in 3.0.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
Deprecated Code introduced by
The method Symfony\Component\Depend...tion::setFactoryClass() has been deprecated with message: since version 2.6, to be removed in 3.0.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
86
        }
87
        if ($parentDef->getFactoryMethod(false)) {
0 ignored issues
show
Deprecated Code introduced by
The method Symfony\Component\Depend...ion::getFactoryMethod() has been deprecated with message: since version 2.6, to be removed in 3.0.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
Bug Best Practice introduced by
The expression $parentDef->getFactoryMethod(false) of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
88
            $def->setFactoryMethod($parentDef->getFactoryMethod(false));
0 ignored issues
show
Deprecated Code introduced by
The method Symfony\Component\Depend...ion::getFactoryMethod() has been deprecated with message: since version 2.6, to be removed in 3.0.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
Deprecated Code introduced by
The method Symfony\Component\Depend...ion::setFactoryMethod() has been deprecated with message: since version 2.6, to be removed in 3.0.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
89
        }
90
        if ($parentDef->getFactoryService(false)) {
0 ignored issues
show
Deprecated Code introduced by
The method Symfony\Component\Depend...on::getFactoryService() has been deprecated with message: since version 2.6, to be removed in 3.0.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
Bug Best Practice introduced by
The expression $parentDef->getFactoryService(false) of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
91
            $def->setFactoryService($parentDef->getFactoryService(false));
0 ignored issues
show
Deprecated Code introduced by
The method Symfony\Component\Depend...on::getFactoryService() has been deprecated with message: since version 2.6, to be removed in 3.0.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
Deprecated Code introduced by
The method Symfony\Component\Depend...on::setFactoryService() has been deprecated with message: since version 2.6, to be removed in 3.0.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
92
        }
93
        $def->setFactory($parentDef->getFactory());
94
        $def->setConfigurator($parentDef->getConfigurator());
0 ignored issues
show
Bug introduced by
It seems like $parentDef->getConfigurator() targeting Symfony\Component\Depend...tion::getConfigurator() can also be of type null; however, Symfony\Component\Depend...tion::setConfigurator() does only seem to accept callable, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
95
        $def->setFile($parentDef->getFile());
96
        $def->setPublic($parentDef->isPublic());
97
        $def->setLazy($parentDef->isLazy());
98
99
        // overwrite with values specified in the decorator
100
        $changes = $definition->getChanges();
101
        if (isset($changes['class'])) {
102
            $def->setClass($definition->getClass());
103
        }
104
        if (isset($changes['factory_class'])) {
105
            $def->setFactoryClass($definition->getFactoryClass(false));
0 ignored issues
show
Deprecated Code introduced by
The method Symfony\Component\Depend...tion::getFactoryClass() has been deprecated with message: since version 2.6, to be removed in 3.0.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
Deprecated Code introduced by
The method Symfony\Component\Depend...tion::setFactoryClass() has been deprecated with message: since version 2.6, to be removed in 3.0.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
106
        }
107
        if (isset($changes['factory_method'])) {
108
            $def->setFactoryMethod($definition->getFactoryMethod(false));
0 ignored issues
show
Deprecated Code introduced by
The method Symfony\Component\Depend...ion::getFactoryMethod() has been deprecated with message: since version 2.6, to be removed in 3.0.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
Deprecated Code introduced by
The method Symfony\Component\Depend...ion::setFactoryMethod() has been deprecated with message: since version 2.6, to be removed in 3.0.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
109
        }
110
        if (isset($changes['factory_service'])) {
111
            $def->setFactoryService($definition->getFactoryService(false));
0 ignored issues
show
Deprecated Code introduced by
The method Symfony\Component\Depend...on::getFactoryService() has been deprecated with message: since version 2.6, to be removed in 3.0.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
Deprecated Code introduced by
The method Symfony\Component\Depend...on::setFactoryService() has been deprecated with message: since version 2.6, to be removed in 3.0.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
112
        }
113
        if (isset($changes['factory'])) {
114
            $def->setFactory($definition->getFactory());
115
        }
116
        if (isset($changes['configurator'])) {
117
            $def->setConfigurator($definition->getConfigurator());
0 ignored issues
show
Bug introduced by
It seems like $definition->getConfigurator() targeting Symfony\Component\Depend...tion::getConfigurator() can also be of type null; however, Symfony\Component\Depend...tion::setConfigurator() does only seem to accept callable, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
118
        }
119
        if (isset($changes['file'])) {
120
            $def->setFile($definition->getFile());
121
        }
122
        if (isset($changes['public'])) {
123
            $def->setPublic($definition->isPublic());
124
        }
125
        if (isset($changes['lazy'])) {
126
            $def->setLazy($definition->isLazy());
127
        }
128
129
        // merge arguments
130
        foreach ($definition->getArguments() as $k => $v) {
131
            if (is_numeric($k)) {
132
                $def->addArgument($v);
133
                continue;
134
            }
135
136
            if (0 !== strpos($k, 'index_')) {
137
                throw new RuntimeException(sprintf('Invalid argument key "%s" found.', $k));
138
            }
139
140
            $index = (int) substr($k, strlen('index_'));
141
            $def->replaceArgument($index, $v);
142
        }
143
144
        // merge properties
145
        foreach ($definition->getProperties() as $k => $v) {
146
            $def->setProperty($k, $v);
147
        }
148
149
        // append method calls
150
        if (count($calls = $definition->getMethodCalls()) > 0) {
151
            $def->setMethodCalls(array_merge($def->getMethodCalls(), $calls));
152
        }
153
154
        // these attributes are always taken from the child
155
        $def->setAbstract($definition->isAbstract());
156
        $def->setScope($definition->getScope());
157
        $def->setTags($definition->getTags());
158
159
        // set new definition on container
160
        $this->container->setDefinition($id, $def);
161
162
        return $def;
163
    }
164
}
165