• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

nette / di / 6739035766

02 Nov 2023 10:44PM UTC coverage: 52.037% (-41.8%) from 93.846%
6739035766

push

github

dg
x

1009 of 1939 relevant lines covered (52.04%)

0.52 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

41.0
/src/DI/Extensions/ServicesExtension.php
1
<?php
2

3
/**
4
 * This file is part of the Nette Framework (https://nette.org)
5
 * Copyright (c) 2004 David Grudl (https://davidgrudl.com)
6
 */
7

8
declare(strict_types=1);
9

10
namespace Nette\DI\Extensions;
11

12
use Nette;
13
use Nette\DI\Definitions;
14
use Nette\DI\Definitions\Statement;
15
use Nette\DI\Helpers;
16

17

18
/**
19
 * Service definitions loader.
20
 */
21
final class ServicesExtension extends Nette\DI\CompilerExtension
22
{
23
        use Nette\SmartObject;
24

25
        public function getConfigSchema(): Nette\Schema\Schema
26
        {
27
                return Nette\Schema\Expect::arrayOf(new DefinitionSchema($this->getContainerBuilder()));
1✔
28
        }
29

30

31
        public function loadConfiguration()
32
        {
33
                $this->loadDefinitions($this->config);
1✔
34
        }
1✔
35

36

37
        /**
38
         * Loads list of service definitions.
39
         */
40
        public function loadDefinitions(array $config)
1✔
41
        {
42
                foreach ($config as $key => $defConfig) {
1✔
43
                        $this->loadDefinition($this->convertKeyToName($key), $defConfig);
1✔
44
                }
45
        }
1✔
46

47

48
        /**
49
         * Loads service definition from normalized configuration.
50
         */
51
        private function loadDefinition(?string $name, \stdClass $config): void
1✔
52
        {
53
                try {
54
                        if ((array) $config === [false]) {
1✔
55
                                $this->getContainerBuilder()->removeDefinition($name);
×
56
                                return;
×
57
                        } elseif (!empty($config->alteration) && !$this->getContainerBuilder()->hasDefinition($name)) {
1✔
58
                                throw new Nette\DI\InvalidConfigurationException('missing original definition for alteration.');
×
59
                        }
60

61
                        $def = $this->retrieveDefinition($name, $config);
1✔
62

63
                        $methods = [
64
                                Definitions\ServiceDefinition::class => 'updateServiceDefinition',
1✔
65
                                Definitions\AccessorDefinition::class => 'updateAccessorDefinition',
66
                                Definitions\FactoryDefinition::class => 'updateFactoryDefinition',
67
                                Definitions\LocatorDefinition::class => 'updateLocatorDefinition',
68
                                Definitions\ImportedDefinition::class => 'updateImportedDefinition',
69
                        ];
70
                        $this->{$methods[$config->defType]}($def, $config);
1✔
71
                        $this->updateDefinition($def, $config);
1✔
72
                } catch (\Throwable $e) {
×
73
                        throw new Nette\DI\InvalidConfigurationException(($name ? "Service '$name': " : '') . $e->getMessage(), 0, $e);
×
74
                }
75
        }
1✔
76

77

78
        /**
79
         * Updates service definition according to normalized configuration.
80
         */
81
        private function updateServiceDefinition(Definitions\ServiceDefinition $definition, \stdClass $config): void
1✔
82
        {
83
                if ($config->create) {
1✔
84
                        $definition->setCreator(Helpers::filterArguments([$config->create])[0]);
1✔
85
                        $definition->setType(null);
1✔
86
                }
87

88
                if ($config->type) {
1✔
89
                        $definition->setType($config->type);
×
90
                }
91

92
                if ($config->arguments) {
1✔
93
                        $arguments = Helpers::filterArguments($config->arguments);
×
94
                        if (empty($config->reset['arguments']) && !Nette\Utils\Arrays::isList($arguments)) {
×
95
                                $arguments = array_replace($definition->getCreator()->arguments, $arguments);
×
96
                        }
97

98
                        $definition->setArguments($arguments);
×
99
                }
100

101
                if (isset($config->setup)) {
1✔
102
                        if (!empty($config->reset['setup'])) {
1✔
103
                                $definition->setSetup([]);
×
104
                        }
105

106
                        foreach (Helpers::filterArguments($config->setup) as $id => $setup) {
1✔
107
                                if (is_array($setup)) {
×
108
                                        $setup = new Statement(key($setup), array_values($setup));
×
109
                                }
110

111
                                $definition->addSetup($setup);
×
112
                        }
113
                }
114

115
                if (isset($config->inject)) {
1✔
116
                        $definition->addTag(InjectExtension::TagInject, $config->inject);
×
117
                }
118
        }
1✔
119

120

121
        private function updateAccessorDefinition(Definitions\AccessorDefinition $definition, \stdClass $config): void
122
        {
123
                if (isset($config->implement)) {
×
124
                        $definition->setImplement($config->implement);
×
125
                }
126

127
                if ($ref = $config->create ?? $config->type ?? null) {
×
128
                        $definition->setReference($ref);
×
129
                }
130
        }
131

132

133
        private function updateFactoryDefinition(Definitions\FactoryDefinition $definition, \stdClass $config): void
134
        {
135
                $resultDef = $definition->getResultDefinition();
×
136

137
                if (isset($config->implement)) {
×
138
                        $definition->setImplement($config->implement);
×
139
                        $definition->setAutowired(true);
×
140
                }
141

142
                if ($config->create) {
×
143
                        $resultDef->setCreator(Helpers::filterArguments([$config->create])[0]);
×
144
                }
145

146
                if ($config->type) {
×
147
                        $resultDef->setCreator($config->type);
×
148
                }
149

150
                if ($config->arguments) {
×
151
                        $arguments = Helpers::filterArguments($config->arguments);
×
152
                        if (empty($config->reset['arguments']) && !Nette\Utils\Arrays::isList($arguments)) {
×
153
                                $arguments = array_replace($resultDef->getCreator()->arguments, $arguments);
×
154
                        }
155

156
                        $resultDef->setArguments($arguments);
×
157
                }
158

159
                if (isset($config->setup)) {
×
160
                        if (!empty($config->reset['setup'])) {
×
161
                                $resultDef->setSetup([]);
×
162
                        }
163

164
                        foreach (Helpers::filterArguments($config->setup) as $id => $setup) {
×
165
                                if (is_array($setup)) {
×
166
                                        $setup = new Statement(key($setup), array_values($setup));
×
167
                                }
168

169
                                $resultDef->addSetup($setup);
×
170
                        }
171
                }
172

173
                if (isset($config->parameters)) {
×
174
                        $definition->setParameters($config->parameters);
×
175
                }
176

177
                if (isset($config->inject)) {
×
178
                        $definition->addTag(InjectExtension::TagInject, $config->inject);
×
179
                }
180
        }
181

182

183
        private function updateLocatorDefinition(Definitions\LocatorDefinition $definition, \stdClass $config): void
184
        {
185
                if (isset($config->implement)) {
×
186
                        $definition->setImplement($config->implement);
×
187
                }
188

189
                if (isset($config->references)) {
×
190
                        $definition->setReferences($config->references);
×
191
                }
192

193
                if (isset($config->tagged)) {
×
194
                        $definition->setTagged($config->tagged);
×
195
                }
196
        }
197

198

199
        private function updateImportedDefinition(Definitions\ImportedDefinition $definition, \stdClass $config): void
200
        {
201
                if ($config->type) {
×
202
                        $definition->setType($config->type);
×
203
                }
204
        }
205

206

207
        private function updateDefinition(Definitions\Definition $definition, \stdClass $config): void
1✔
208
        {
209
                if (isset($config->autowired)) {
1✔
210
                        $definition->setAutowired($config->autowired);
×
211
                }
212

213
                if (isset($config->tags)) {
1✔
214
                        if (!empty($config->reset['tags'])) {
1✔
215
                                $definition->setTags([]);
×
216
                        }
217

218
                        foreach ($config->tags as $tag => $attrs) {
1✔
219
                                if (is_int($tag) && is_string($attrs)) {
×
220
                                        $definition->addTag($attrs);
×
221
                                } else {
222
                                        $definition->addTag($tag, $attrs);
×
223
                                }
224
                        }
225
                }
226
        }
1✔
227

228

229
        private function convertKeyToName($key): ?string
230
        {
231
                if (is_int($key)) {
1✔
232
                        return null;
1✔
233
                } elseif (preg_match('#^@[\w\\\\]+$#D', $key)) {
1✔
234
                        return $this->getContainerBuilder()->getByType(substr($key, 1), true);
×
235
                }
236

237
                return $key;
1✔
238
        }
239

240

241
        private function retrieveDefinition(?string $name, \stdClass $config): Definitions\Definition
1✔
242
        {
243
                $builder = $this->getContainerBuilder();
1✔
244
                if (!empty($config->reset['all'])) {
1✔
245
                        $builder->removeDefinition($name);
×
246
                }
247

248
                return $name && $builder->hasDefinition($name)
1✔
249
                        ? $builder->getDefinition($name)
×
250
                        : $builder->addDefinition($name, new $config->defType);
1✔
251
        }
252
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc