PluginProbe
Packeta / trunk
Packeta vtrunk
2.3.2 2.3.1 trunk 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.3.0 1.3.1 1.3.2 1.4 1.4.1 1.4.2 1.4.3 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 All 56 releases
packeta / deps / nette / di / src / DI / Extensions / ServicesExtension.php

ServicesExtension.php in Packeta trunk, at deps/nette/di/src/DI/Extensions/ServicesExtension.php

192 lines 7.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
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 declare (strict_types=1);
8 namespace Packetery\Nette\DI\Extensions;
9
10 use Packetery\Nette;
11 use Packetery\Nette\DI\Definitions;
12 use Packetery\Nette\DI\Definitions\Statement;
13 use Packetery\Nette\DI\Helpers;
14 /**
15 * Services definitions loader.
16 */
17 final class ServicesExtension extends \Packetery\Nette\DI\CompilerExtension
18 {
19 use \Packetery\Nette\SmartObject;
20 public function getConfigSchema() : \Packetery\Nette\Schema\Schema
21 {
22 return \Packetery\Nette\Schema\Expect::arrayOf(new DefinitionSchema($this->getContainerBuilder()));
23 }
24 public function loadConfiguration()
25 {
26 $this->loadDefinitions($this->config);
27 }
28 /**
29 * Loads list of service definitions.
30 */
31 public function loadDefinitions(array $config)
32 {
33 foreach ($config as $key => $defConfig) {
34 $this->loadDefinition($this->convertKeyToName($key), $defConfig);
35 }
36 }
37 /**
38 * Loads service definition from normalized configuration.
39 */
40 private function loadDefinition(?string $name, \stdClass $config) : void
41 {
42 try {
43 if ((array) $config === [\false]) {
44 $this->getContainerBuilder()->removeDefinition($name);
45 return;
46 } elseif (!empty($config->alteration) && !$this->getContainerBuilder()->hasDefinition($name)) {
47 throw new \Packetery\Nette\DI\InvalidConfigurationException('missing original definition for alteration.');
48 }
49 $def = $this->retrieveDefinition($name, $config);
50 $methods = [Definitions\ServiceDefinition::class => 'updateServiceDefinition', Definitions\AccessorDefinition::class => 'updateAccessorDefinition', Definitions\FactoryDefinition::class => 'updateFactoryDefinition', Definitions\LocatorDefinition::class => 'updateLocatorDefinition', Definitions\ImportedDefinition::class => 'updateImportedDefinition'];
51 $this->{$methods[$config->defType]}($def, $config);
52 $this->updateDefinition($def, $config);
53 } catch (\Throwable $e) {
54 throw new \Packetery\Nette\DI\InvalidConfigurationException(($name ? "Service '{$name}': " : '') . $e->getMessage(), 0, $e);
55 }
56 }
57 /**
58 * Updates service definition according to normalized configuration.
59 */
60 private function updateServiceDefinition(Definitions\ServiceDefinition $definition, \stdClass $config) : void
61 {
62 if ($config->create) {
63 $definition->setCreator(Helpers::filterArguments([$config->create])[0]);
64 $definition->setType(null);
65 }
66 if ($config->type) {
67 $definition->setType($config->type);
68 }
69 if ($config->arguments) {
70 $arguments = Helpers::filterArguments($config->arguments);
71 if (empty($config->reset['arguments']) && !Nette\Utils\Arrays::isList($arguments)) {
72 $arguments = \array_replace($definition->getCreator()->arguments, $arguments);
73 }
74 $definition->setArguments($arguments);
75 }
76 if (isset($config->setup)) {
77 if (!empty($config->reset['setup'])) {
78 $definition->setSetup([]);
79 }
80 foreach (Helpers::filterArguments($config->setup) as $setup) {
81 if (\is_array($setup)) {
82 $setup = new Statement(\key($setup), \array_values($setup));
83 }
84 $definition->addSetup($setup);
85 }
86 }
87 if (isset($config->inject)) {
88 $definition->addTag(InjectExtension::TagInject, $config->inject);
89 }
90 }
91 private function updateAccessorDefinition(Definitions\AccessorDefinition $definition, \stdClass $config) : void
92 {
93 if (isset($config->implement)) {
94 $definition->setImplement($config->implement);
95 }
96 if ($ref = $config->create ?? $config->type ?? null) {
97 $definition->setReference($ref);
98 }
99 }
100 private function updateFactoryDefinition(Definitions\FactoryDefinition $definition, \stdClass $config) : void
101 {
102 $resultDef = $definition->getResultDefinition();
103 if (isset($config->implement)) {
104 $definition->setImplement($config->implement);
105 $definition->setAutowired();
106 }
107 if ($config->create) {
108 $resultDef->setCreator(Helpers::filterArguments([$config->create])[0]);
109 }
110 if ($config->type) {
111 $resultDef->setCreator($config->type);
112 }
113 if ($config->arguments) {
114 $arguments = Helpers::filterArguments($config->arguments);
115 if (empty($config->reset['arguments']) && !Nette\Utils\Arrays::isList($arguments)) {
116 $arguments = \array_replace($resultDef->getCreator()->arguments, $arguments);
117 }
118 $resultDef->setArguments($arguments);
119 }
120 if (isset($config->setup)) {
121 if (!empty($config->reset['setup'])) {
122 $resultDef->setSetup([]);
123 }
124 foreach (Helpers::filterArguments($config->setup) as $setup) {
125 if (\is_array($setup)) {
126 $setup = new Statement(\key($setup), \array_values($setup));
127 }
128 $resultDef->addSetup($setup);
129 }
130 }
131 if (isset($config->parameters)) {
132 $definition->setParameters($config->parameters);
133 }
134 if (isset($config->inject)) {
135 $definition->addTag(InjectExtension::TagInject, $config->inject);
136 }
137 }
138 private function updateLocatorDefinition(Definitions\LocatorDefinition $definition, \stdClass $config) : void
139 {
140 if (isset($config->implement)) {
141 $definition->setImplement($config->implement);
142 }
143 if (isset($config->references)) {
144 $definition->setReferences($config->references);
145 }
146 if (isset($config->tagged)) {
147 $definition->setTagged($config->tagged);
148 }
149 }
150 private function updateImportedDefinition(Definitions\ImportedDefinition $definition, \stdClass $config) : void
151 {
152 if ($config->type) {
153 $definition->setType($config->type);
154 }
155 }
156 private function updateDefinition(Definitions\Definition $definition, \stdClass $config) : void
157 {
158 if (isset($config->autowired)) {
159 $definition->setAutowired($config->autowired);
160 }
161 if (isset($config->tags)) {
162 if (!empty($config->reset['tags'])) {
163 $definition->setTags([]);
164 }
165 foreach ($config->tags as $tag => $attrs) {
166 if (\is_int($tag) && \is_string($attrs)) {
167 $definition->addTag($attrs);
168 } else {
169 $definition->addTag($tag, $attrs);
170 }
171 }
172 }
173 }
174 private function convertKeyToName($key) : ?string
175 {
176 if (\is_int($key)) {
177 return null;
178 } elseif (\preg_match('#^@[\\w\\\\]+$#D', $key)) {
179 return $this->getContainerBuilder()->getByType(\substr($key, 1), \true);
180 }
181 return $key;
182 }
183 private function retrieveDefinition(?string $name, \stdClass $config) : Definitions\Definition
184 {
185 $builder = $this->getContainerBuilder();
186 if (!empty($config->reset['all'])) {
187 $builder->removeDefinition($name);
188 }
189 return $name && $builder->hasDefinition($name) ? $builder->getDefinition($name) : $builder->addDefinition($name, new $config->defType());
190 }
191 }
192