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

nette / di / 4405606637

pending completion
4405606637

push

github

David Grudl
more self explanatory message for factory and service mismatch (closes #199) (#284)

8 of 8 new or added lines in 1 file covered. (100.0%)

2118 of 2238 relevant lines covered (94.64%)

0.95 hits per line

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

96.33
/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);
1✔
56
                                return;
1✔
57
                        } elseif (!empty($config->alteration) && !$this->getContainerBuilder()->hasDefinition($name)) {
1✔
58
                                throw new Nette\DI\InvalidConfigurationException('Missing original definition for alteration.');
1✔
59
                        }
60

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

63
                        $methods = [
1✔
64
                                Definitions\ServiceDefinition::class => 'updateServiceDefinition',
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) {
1✔
73
                        $message = $e->getMessage();
1✔
74
                        if ($name && !str_starts_with($message, '[Service ')) {
1✔
75
                                $message = "[Service '$name']\n$message";
1✔
76
                        }
77

78
                        throw new Nette\DI\InvalidConfigurationException($message, 0, $e);
1✔
79
                }
80
        }
1✔
81

82

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

93
                if ($config->type) {
1✔
94
                        $definition->setType($config->type);
1✔
95
                }
96

97
                if ($config->arguments) {
1✔
98
                        $arguments = Helpers::filterArguments($config->arguments);
1✔
99
                        if (empty($config->reset['arguments']) && !Nette\Utils\Arrays::isList($arguments)) {
1✔
100
                                $arguments = array_replace($definition->getCreator()->arguments, $arguments);
1✔
101
                        }
102

103
                        $definition->setArguments($arguments);
1✔
104
                }
105

106
                if (isset($config->setup)) {
1✔
107
                        if (!empty($config->reset['setup'])) {
1✔
108
                                $definition->setSetup([]);
×
109
                        }
110

111
                        foreach (Helpers::filterArguments($config->setup) as $id => $setup) {
1✔
112
                                if (is_array($setup)) {
1✔
113
                                        $setup = new Statement(key($setup), array_values($setup));
1✔
114
                                }
115

116
                                $definition->addSetup($setup);
1✔
117
                        }
118
                }
119

120
                if (isset($config->inject)) {
1✔
121
                        $definition->addTag(InjectExtension::TagInject, $config->inject);
1✔
122
                }
123
        }
1✔
124

125

126
        private function updateAccessorDefinition(Definitions\AccessorDefinition $definition, \stdClass $config): void
1✔
127
        {
128
                if (isset($config->implement)) {
1✔
129
                        $definition->setImplement($config->implement);
1✔
130
                }
131

132
                if ($ref = $config->create ?? $config->type ?? null) {
1✔
133
                        $definition->setReference($ref);
1✔
134
                }
135
        }
1✔
136

137

138
        private function updateFactoryDefinition(Definitions\FactoryDefinition $definition, \stdClass $config): void
1✔
139
        {
140
                $resultDef = $definition->getResultDefinition();
1✔
141

142
                if (isset($config->implement)) {
1✔
143
                        $definition->setImplement($config->implement);
1✔
144
                        $definition->setAutowired(true);
1✔
145
                }
146

147
                if ($config->create) {
1✔
148
                        $resultDef->setCreator(Helpers::filterArguments([$config->create])[0]);
1✔
149
                }
150

151
                if ($config->type) {
1✔
152
                        $resultDef->setCreator($config->type);
1✔
153
                }
154

155
                if ($config->arguments) {
1✔
156
                        $arguments = Helpers::filterArguments($config->arguments);
1✔
157
                        if (empty($config->reset['arguments']) && !Nette\Utils\Arrays::isList($arguments)) {
1✔
158
                                $arguments = array_replace($resultDef->getCreator()->arguments, $arguments);
×
159
                        }
160

161
                        $resultDef->setArguments($arguments);
1✔
162
                }
163

164
                if (isset($config->setup)) {
1✔
165
                        if (!empty($config->reset['setup'])) {
1✔
166
                                $resultDef->setSetup([]);
×
167
                        }
168

169
                        foreach (Helpers::filterArguments($config->setup) as $id => $setup) {
1✔
170
                                if (is_array($setup)) {
1✔
171
                                        $setup = new Statement(key($setup), array_values($setup));
1✔
172
                                }
173

174
                                $resultDef->addSetup($setup);
1✔
175
                        }
176
                }
177

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

183

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

190
                if (isset($config->references)) {
1✔
191
                        $definition->setReferences($config->references);
1✔
192
                }
193

194
                if (isset($config->tagged)) {
1✔
195
                        $definition->setTagged($config->tagged);
1✔
196
                }
197
        }
1✔
198

199

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

207

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

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

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

229

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

238
                return $key;
1✔
239
        }
240

241

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

249
                return $name && $builder->hasDefinition($name)
1✔
250
                        ? $builder->getDefinition($name)
1✔
251
                        : $builder->addDefinition($name, new $config->defType);
1✔
252
        }
253
}
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