FlysystemExtension::registerService()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 2.0054

Importance

Changes 0
Metric Value
dl 0
loc 16
ccs 8
cts 9
cp 0.8889
rs 9.7333
c 0
b 0
f 0
cc 2
nc 2
nop 5
crap 2.0054
1
<?php
2
/**
3
 * FlysystemExtension.php
4
 *
5
 * @copyright      More in license.md
6
 * @license        https://www.ipublikuj.eu
7
 * @author         Adam Kadlec <[email protected]>
8
 * @package        iPublikuj:Flysystem!
9
 * @subpackage     DI
10
 * @since          1.0.0
11
 *
12
 * @date           05.04.16
13
 */
14
15
declare(strict_types = 1);
16
17
namespace IPub\Flysystem\DI;
18
19
use Nette;
20
use Nette\DI;
21
use Nette\Utils;
22
23
use League\Flysystem;
24
25
use IPub\Flysystem\Exceptions;
26
use IPub\Flysystem\Factories;
27
use IPub\Flysystem\Loaders;
28
29
/**
30
 * Flysystem extension container
31
 *
32
 * @package        iPublikuj:Flysystem!
33
 * @subpackage     DI
34
 *
35
 * @author         Adam Kadlec <[email protected]>
36
 */
37 1
class FlysystemExtension extends DI\CompilerExtension
38
{
39
	/**
40
	 * @var array
41
	 */
42
	private $defaults = [
43
		'adapters'    => [],
44
		'cache'       => [],
45
		'filesystems' => [],
46
	];
47
48
	/**
49
	 * @void
50
	 *
51
	 * @throws Utils\AssertionException
52
	 */
53
	public function loadConfiguration() : void
54
	{
55
		/** @var DI\ContainerBuilder $builder */
56 1
		$builder = $this->getContainerBuilder();
57
		// Get extension configuration
58 1
		$configuration = $this->validateConfig($this->defaults);
0 ignored issues
show
Deprecated Code introduced by
The method Nette\DI\CompilerExtension::validateConfig() has been deprecated with message: use getConfigSchema()

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...
59
60
		// Load all configured adapters
61 1
		$this->loadServices($configuration['adapters'], 'adapters');
62
63
		// Load all configured cache systems
64 1
		$this->loadServices($configuration['cache'], 'cache');
65
66 1
		$mountManager = $builder->addDefinition($this->prefix('mountmanager'))
67 1
			->setType(Flysystem\MountManager::class)
68 1
			->setArguments([[]]);
69
70 1
		foreach ($configuration['filesystems'] as $name => $filesystem) {
71
			// Check if filesystem is with cache
72 1
			if (array_key_exists('cache', $filesystem)) {
73
				// Create adapter name
74 1
				$adapterName = 'cached_' . $filesystem['adapter'] . '_' . $filesystem['cache'] . '_' . uniqid();
75
76
				// Create cached adapter
77 1
				$this->registerService(
78 1
					'adapters',
79
					$adapterName,
80 1
					Flysystem\Cached\CachedAdapter::class,
81 1
					'IPub\Flysystem\Factories\Adapters\CachedFactory::create',
82
					[
83 1
						'adapterServiceName' => $this->prefix('adapters.' . $filesystem['adapter']),
84 1
						'cacheServiceName'   => $this->prefix('cache.' . $filesystem['cache']),
85
					]
86
				);
87
88
			} else {
89 1
				$adapterName = $filesystem['adapter'];
90
			}
91
92 1
			$builder->addDefinition($this->prefix('filesystem.' . $name))
93 1
				->setType(Flysystem\Filesystem::class)
94 1
				->setArguments(['adapter' => '@' . $this->prefix('adapters.' . $adapterName)])
95 1
				->addTag('ipub.flysystem.filesystem');
96
97 1
			$mountManager->addSetup('?->mountFilesystem(?, ?)', [$mountManager, $name, '@' . $this->prefix('filesystem.' . $name)]);
98
		}
99 1
	}
100
101
	/**
102
	 * @param array $services
103
	 * @param string $type
104
	 *
105
	 * @return void
106
	 *
107
	 * @throws Utils\AssertionException
108
	 */
109
	private function loadServices(array $services, string $type) : void
110
	{
111
		// Get neon file adapter
112 1
		$neonAdapter = new Loaders\NeonFileLoader;
113
114
		// Load adapters factories list
115 1
		$definitions = $neonAdapter->load(__DIR__ . DIRECTORY_SEPARATOR . $type . '.neon');
116
117 1
		foreach ($services as $serviceName => $configuration) {
118 1
			if (isset($configuration['type']) && array_key_exists($configuration['type'], $definitions)) {
119 1
				$service = $definitions[$configuration['type']];
120 1
				$serviceConfiguration = $this->validateParameters($service['parameters'], $configuration, $serviceName);
121
122 1
				$this->registerService($type, $serviceName, $service['class'], $service['factory'], [
123 1
					'parameters' => $serviceConfiguration,
124
				]);
125
126
			} else {
127 1
				throw new Exceptions\InvalidAdapterException(sprintf('The service "%s" is not defined in Flysystem configuration.', $serviceName));
128
			}
129
		}
130 1
	}
131
132
	/**
133
	 * @param string $type
134
	 * @param string $name
135
	 * @param string $class
136
	 * @param string $factory
137
	 * @param array $arguments
138
	 *
139
	 * @return void
140
	 */
141
	private function registerService(string $type, string $name, string $class, string $factory, array $arguments = []) : void
142
	{
143
		// Check if service class exists
144 1
		if (!class_exists($class)) {
145
			throw new Exceptions\InvalidArgumentException(sprintf('Class "%s" for service "%s" of "%s" does not exists.', $class, $name, $type));
146
		}
147
148
		/** @var DI\ContainerBuilder $builder */
149 1
		$builder = $this->getContainerBuilder();
150
151 1
		$builder->addDefinition($this->prefix($type . '.' . $name))
152 1
			->setType($class)
153 1
			->setFactory($factory)
154 1
			->setArguments($arguments)
155 1
			->addTag('ipub.flysystem.' . $type);
156 1
	}
157
158
	/**
159
	 * @param array|NULL $parameters
160
	 * @param array $configuration
161
	 * @param string $serviceName
162
	 *
163
	 * @return Utils\ArrayHash
164
	 *
165
	 * @throws Exceptions\InvalidParameterException
166
	 * @throws Exceptions\InvalidAdapterException
167
	 * @throws Utils\AssertionException
168
	 */
169
	private function validateParameters(?array $parameters, array $configuration, string $serviceName) : Utils\ArrayHash
170
	{
171 1
		$collection = [];
172
173 1
		if ($parameters === NULL) {
174 1
			return Utils\ArrayHash::from([]);
175
		}
176
177 1
		foreach ($parameters as $name => $definition) {
178 1
			if (!array_key_exists($name, $configuration) && $definition['required']) {
179
				throw new Exceptions\InvalidParameterException(sprintf('The parameter "%s" for "%s" is required.', $name, $serviceName));
180
			}
181
182 1
			if (array_key_exists('default', $definition)) {
183 1
				$collection[$name] = $definition['default'];
184
			}
185
186 1
			if (array_key_exists($name, $configuration)) {
187 1
				Utils\Validators::assert($configuration[$name], $definition['type'], $name);
188
189 1
				if (isset($definition['values']) && !in_array($configuration[$name], $definition['values'])) {
190
					throw new Exceptions\InvalidParameterException(sprintf('The parameter "%s" for "%s" is not in allowed range [%s].', $name, $serviceName, implode(', ', $definition['values'])));
191
				}
192
193 1
				$collection[$name] = $configuration[$name];
194
			}
195
		}
196
197 1
		$collection['extensionPrefix'] = $this->name;
198
199 1
		return Utils\ArrayHash::from($collection);
200
	}
201
202
	/**
203
	 * @param Nette\Configurator $config
204
	 * @param string $extensionName
205
	 *
206
	 * @return void
207
	 */
208
	public static function register(Nette\Configurator $config, string $extensionName = 'flysystem') : void
209
	{
210 1
		$config->onCompile[] = function (Nette\Configurator $config, Nette\DI\Compiler $compiler) use ($extensionName) {
211 1
			$compiler->addExtension($extensionName, new FlysystemExtension);
212 1
		};
213 1
	}
214
}
215