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

nette / di / 4502239499

pending completion
4502239499

push

github

David Grudl
Accessor, Locator, Factory: generates promoted properties

9 of 9 new or added lines in 3 files covered. (100.0%)

2096 of 2216 relevant lines covered (94.58%)

0.95 hits per line

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

99.09
/src/DI/Extensions/DefinitionSchema.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\Config\Helpers;
14
use Nette\DI\Definitions;
15
use Nette\DI\Definitions\Statement;
16
use Nette\Schema\Context;
17
use Nette\Schema\Expect;
18
use Nette\Schema\Schema;
19

20

21
/**
22
 * Service configuration schema.
23
 */
24
class DefinitionSchema implements Schema
25
{
26
        use Nette\SmartObject;
27

28
        private Nette\DI\ContainerBuilder $builder;
29

30

31
        public function __construct(Nette\DI\ContainerBuilder $builder)
1✔
32
        {
33
                $this->builder = $builder;
1✔
34
        }
1✔
35

36

37
        public function complete($def, Context $context)
1✔
38
        {
39
                if ($def === [false]) {
1✔
40
                        return (object) $def;
1✔
41
                }
42

43
                if (Helpers::takeParent($def)) {
1✔
44
                        $def['reset']['all'] = true;
1✔
45
                }
46

47
                foreach (['arguments', 'setup', 'tags'] as $k) {
1✔
48
                        if (isset($def[$k]) && Helpers::takeParent($def[$k])) {
1✔
49
                                $def['reset'][$k] = true;
1✔
50
                        }
51
                }
52

53
                $type = $this->sniffType(end($context->path), $def);
1✔
54
                $def = $this->getSchema($type)->complete($def, $context);
1✔
55
                if ($def) {
1✔
56
                        $def->defType = $type;
1✔
57
                }
58

59
                return $def;
1✔
60
        }
61

62

63
        public function merge($def, $base)
64
        {
65
                if (!empty($def['alteration'])) {
1✔
66
                        unset($def['alteration']);
1✔
67
                }
68

69
                return Nette\Schema\Helpers::merge($def, $base);
1✔
70
        }
71

72

73
        /**
74
         * Normalizes configuration of service definitions.
75
         */
76
        public function normalize($def, Context $context)
1✔
77
        {
78
                if ($def === null || $def === false) {
1✔
79
                        return (array) $def;
1✔
80

81
                } elseif (is_string($def) && interface_exists($def)) {
1✔
82
                        return ['implement' => $def];
1✔
83

84
                } elseif ($def instanceof Statement && is_string($def->getEntity()) && interface_exists($def->getEntity())) {
1✔
85
                        $res = ['implement' => $def->getEntity()];
1✔
86
                        if (array_keys($def->arguments) === ['tagged']) {
1✔
87
                                $res += $def->arguments;
1✔
88
                        } elseif (array_keys($def->arguments) === [0]) {
1✔
89
                                $res['create'] = $def->arguments[0];
1✔
90
                        } elseif ($def->arguments) {
1✔
91
                                $res['references'] = $def->arguments;
1✔
92
                        }
93

94
                        return $res;
1✔
95

96
                } elseif (!is_array($def) || isset($def[0], $def[1])) {
1✔
97
                        return ['create' => $def];
1✔
98

99
                } elseif (is_array($def)) {
1✔
100
                        // back compatibility
101
                        if (isset($def['factory']) && !isset($def['create'])) {
1✔
102
                                $def['create'] = $def['factory'];
1✔
103
                                unset($def['factory']);
1✔
104
                        } elseif (isset($def['class']) && !isset($def['create']) && !isset($def['imported'])) {
1✔
105
                                $def['create'] = $def['class'];
1✔
106
                                unset($def['class']);
1✔
107
                        }
108

109
                        return $def;
1✔
110

111
                } else {
112
                        throw new Nette\DI\InvalidConfigurationException('Unexpected format of service definition');
×
113
                }
114
        }
115

116

117
        public function completeDefault(Context $context)
118
        {
119
        }
120

121

122
        private function sniffType($key, array $def): string
1✔
123
        {
124
                if (is_string($key)) {
1✔
125
                        $name = preg_match('#^@[\w\\\\]+$#D', $key)
1✔
126
                                ? $this->builder->getByType(substr($key, 1))
1✔
127
                                : $key;
1✔
128

129
                        if ($name && $this->builder->hasDefinition($name)) {
1✔
130
                                return get_class($this->builder->getDefinition($name));
1✔
131
                        }
132
                }
133

134
                if (isset($def['implement'], $def['references']) || isset($def['implement'], $def['tagged'])) {
1✔
135
                        return Definitions\LocatorDefinition::class;
1✔
136

137
                } elseif (isset($def['implement'])) {
1✔
138
                        return method_exists($def['implement'], 'create')
1✔
139
                                ? Definitions\FactoryDefinition::class
1✔
140
                                : Definitions\AccessorDefinition::class;
1✔
141

142
                } elseif (isset($def['imported'])) {
1✔
143
                        return Definitions\ImportedDefinition::class;
1✔
144

145
                } elseif (!$def) {
1✔
146
                        throw new Nette\DI\InvalidConfigurationException("Service '$key': Empty definition.");
1✔
147

148
                } else {
149
                        return Definitions\ServiceDefinition::class;
1✔
150
                }
151
        }
152

153

154
        private static function getSchema(string $type): Schema
1✔
155
        {
156
                static $cache;
1✔
157
                $cache = $cache ?: [
1✔
158
                        Definitions\ServiceDefinition::class => self::getServiceSchema(),
1✔
159
                        Definitions\AccessorDefinition::class => self::getAccessorSchema(),
1✔
160
                        Definitions\FactoryDefinition::class => self::getFactorySchema(),
1✔
161
                        Definitions\LocatorDefinition::class => self::getLocatorSchema(),
1✔
162
                        Definitions\ImportedDefinition::class => self::getImportedSchema(),
1✔
163
                ];
164
                return $cache[$type];
1✔
165
        }
166

167

168
        private static function getServiceSchema(): Schema
169
        {
170
                return Expect::structure([
1✔
171
                        'type' => Expect::type('string'),
1✔
172
                        'create' => Expect::type('callable|Nette\DI\Definitions\Statement'),
1✔
173
                        'arguments' => Expect::array(),
1✔
174
                        'setup' => Expect::listOf('callable|Nette\DI\Definitions\Statement|array:1'),
1✔
175
                        'inject' => Expect::bool(),
1✔
176
                        'autowired' => Expect::type('bool|string|array'),
1✔
177
                        'tags' => Expect::array(),
1✔
178
                        'reset' => Expect::array(),
1✔
179
                        'alteration' => Expect::bool(),
1✔
180
                ]);
181
        }
182

183

184
        private static function getAccessorSchema(): Schema
185
        {
186
                return Expect::structure([
1✔
187
                        'type' => Expect::string(),
1✔
188
                        'implement' => Expect::string(),
1✔
189
                        'create' => Expect::type('callable|Nette\DI\Definitions\Statement'),
1✔
190
                        'autowired' => Expect::type('bool|string|array'),
1✔
191
                        'tags' => Expect::array(),
1✔
192
                ]);
193
        }
194

195

196
        private static function getFactorySchema(): Schema
197
        {
198
                return Expect::structure([
1✔
199
                        'type' => Expect::string(),
1✔
200
                        'create' => Expect::type('callable|Nette\DI\Definitions\Statement'),
1✔
201
                        'implement' => Expect::string(),
1✔
202
                        'arguments' => Expect::array(),
1✔
203
                        'setup' => Expect::listOf('callable|Nette\DI\Definitions\Statement|array:1'),
1✔
204
                        'references' => Expect::array(),
1✔
205
                        'tagged' => Expect::string(),
1✔
206
                        'inject' => Expect::bool(),
1✔
207
                        'autowired' => Expect::type('bool|string|array'),
1✔
208
                        'tags' => Expect::array(),
1✔
209
                        'reset' => Expect::array(),
1✔
210
                ]);
211
        }
212

213

214
        private static function getLocatorSchema(): Schema
215
        {
216
                return Expect::structure([
1✔
217
                        'implement' => Expect::string(),
1✔
218
                        'references' => Expect::array(),
1✔
219
                        'tagged' => Expect::string(),
1✔
220
                        'autowired' => Expect::type('bool|string|array'),
1✔
221
                        'tags' => Expect::array(),
1✔
222
                ]);
223
        }
224

225

226
        private static function getImportedSchema(): Schema
227
        {
228
                return Expect::structure([
1✔
229
                        'type' => Expect::string(),
1✔
230
                        'imported' => Expect::bool(),
1✔
231
                        'autowired' => Expect::type('bool|string|array'),
1✔
232
                        'tags' => Expect::array(),
1✔
233
                ]);
234
        }
235
}
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