Completed
Push — master ( 754609...dfe21c )
by Adam
02:51
created

src/IPub/Flysystem/DI/FlysystemExtension.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * FlysystemExtension.php
4
 *
5
 * @copyright      More in license.md
6
 * @license        http://www.ipublikuj.eu
7
 * @author         Adam Kadlec http://www.ipublikuj.eu
8
 * @package        iPublikuj:Flysystem!
9
 * @subpackage     DI
10
 * @since          1.0.0
11
 *
12
 * @date           05.04.16
13
 */
14
15
namespace IPub\Flysystem\DI;
16
17
use Nette;
18
use Nette\DI;
19
use Nette\Utils;
20
use Nette\PhpGenerator as Code;
21
22
use Tracy;
23
24
use League\Flysystem;
25
26
use IPub;
27
use IPub\Flysystem\Exceptions;
28
use IPub\Flysystem\Factories;
29
use IPub\Flysystem\Loaders;
30
31
/**
32
 * Flysystem extension container
33
 *
34
 * @package        iPublikuj:Flysystem!
35
 * @subpackage     DI
36
 *
37
 * @author         Adam Kadlec <[email protected]>
38
 */
39
class FlysystemExtension extends DI\CompilerExtension
40 1
{
41
	/**
42
	 * @var array
43
	 */
44
	private $defaults = [
45
		'adapters'    => [],
46
		'cache'       => [],
47
		'filesystems' => [],
48
	];
49
50
	public function loadConfiguration()
51 1
	{
52
		// Get container builder
53 1
		$builder = $this->getContainerBuilder();
54
		// Get extension configuration
55 1
		$configuration = $this->getConfig($this->defaults);
56
57
		// Load all configured adapters
58 1
		$this->loadServices($configuration['adapters'], 'adapters');
59
60
		// Load all configured cache systems
61 1
		$this->loadServices($configuration['cache'], 'cache');
62
63 1
		$mountManager = $builder->addDefinition($this->prefix('mountmanager'))
64 1
			->setClass(Flysystem\MountManager::class);
65
66 1
		foreach ($configuration['filesystems'] as $name => $filesystem) {
67
			// Check if filesystem is with cache
68 1
			if (array_key_exists('cache', $filesystem)) {
69
				// Create adapter name
70 1
				$adapterName = 'cached_' . $filesystem['adapter'] .'_'. $filesystem['cache'] .'_'. uniqid();
71
72
				// Create cached adapter
73 1
				$this->registerService(
74 1
					'adapters',
75 1
					$adapterName,
76 1
					Flysystem\Cached\CachedAdapter::class,
77 1
					'IPub\Flysystem\Factories\Adapters\CachedFactory::create',
78
					[
79 1
						'adapterServiceName' => $this->prefix('adapters.' . $filesystem['adapter']),
80 1
						'cacheServiceName'   => $this->prefix('cache.' . $filesystem['cache']),
81
					]
82 1
				);
83
84 1
			} else {
85 1
				$adapterName = $filesystem['adapter'];
86
			}
87
88 1
			$builder->addDefinition($this->prefix('filesystem.' . $name))
89 1
				->setClass(Flysystem\Filesystem::class)
90 1
				->setArguments(['adapter' => '@' . $this->prefix('adapters.' . $adapterName)])
91 1
				->addTag('ipub.flysystem.filesystem');
92
93 1
			$mountManager->addSetup('?->mountFilesystem(?, ?)', [$mountManager, $name, '@' . $this->prefix('filesystem.' . $name)]);
94 1
		}
95 1
	}
96
97
	/**
98
	 * @param array $services
99
	 * @param string $type
100
	 */
101
	private function loadServices(array $services, $type)
102
	{
103
		// Get neon file adapter
104 1
		$neonAdapter = new Loaders\NeonFileLoader;
105
106
		// Load adapters factories list
107 1
		$definitions = $neonAdapter->load(__DIR__ . DIRECTORY_SEPARATOR . $type . '.neon');
108
109 1
		foreach ($services as $serviceName => $configuration) {
110 1
			if (isset($configuration['type']) && array_key_exists($configuration['type'], $definitions)) {
111 1
				$service = $definitions[$configuration['type']];
112 1
				$serviceConfiguration = $this->validateParameters($service['parameters'], $configuration, $serviceName);
113
114 1
				$this->registerService($type, $serviceName, $service['class'], $service['factory'], [
115 1
					'parameters' => $serviceConfiguration,
116 1
				]);
117
118 1
			} else {
119
				throw new Exceptions\InvalidAdapterException(sprintf('The service "%s" is not defined in Flystystem configuration.', $serviceName));
120
			}
121 1
		}
122 1
	}
123
124
	/**
125
	 * @param string $type
126
	 * @param string $name
127
	 * @param string $class
128
	 * @param string $factory
129
	 * @param array $arguments
130
	 */
131
	private function registerService($type, $name, $class, $factory, array $arguments = [])
132
	{
133
		// Check if service class exists
134 1
		if (!class_exists($class)) {
135
			throw new Exceptions\InvalidArgumentException(sprintf('Class "%s" for service "%s" of "%s" does not exists.', $class, $name, $type));
136
		}
137
138
		// Get container builder
139 1
		$builder = $this->getContainerBuilder();
140
141 1
		$builder->addDefinition($this->prefix($type . '.' . $name))
142 1
			->setClass($class)
143 1
			->setFactory($factory)
144 1
			->setArguments($arguments)
145 1
			->addTag('ipub.flysystem.' . $type);
146 1
	}
147
148
	/**
149
	 * @param array $parameters
150
	 * @param array $configuration
151
	 * @param string $serviceName
152
	 *
153
	 * @return Utils\ArrayHash
154
	 *
155
	 * @throws Exceptions\InvalidParameterException
156
	 * @throws Exceptions\InvalidAdapterException
157
	 * @throws Utils\AssertionException
158
	 */
159
	private function validateParameters($parameters, $configuration, $serviceName)
160
	{
161 1
		$collection = [];
162
163 1
		if ($parameters === NULL) {
164 1
			return Utils\ArrayHash::from([]);
165
		}
166
167 1
		foreach ($parameters as $name => $definition) {
168 1
			if (!array_key_exists($name, $configuration) && $definition['required']) {
169
				throw new Exceptions\InvalidParameterException(sprintf('The parameter "%s" for "%s" is required.', $name, $serviceName));
170
			}
171
172 1
			if (array_key_exists('default', $definition)) {
173 1
				$collection[$name] = $definition['default'];
174 1
			}
175
176 1
			if (array_key_exists($name, $configuration)) {
177
				//Utils\Validators::assert($configuration[$name], $definition['type'], $name);
0 ignored issues
show
Unused Code Comprehensibility introduced by
79% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
178
179 1
				if (isset($definition['values']) && !in_array($configuration[$name], $definition['values'])) {
180
					throw new Exceptions\InvalidParameterException(sprintf('The parameter "%s" for "%s" is not in allowed range [%s].', $name, $serviceName, implode(', ', $definition['values'])));
181
				}
182
183 1
				$collection[$name] = $configuration[$name];
184 1
			}
185 1
		}
186
187 1
		$collection['extensionPrefix'] = $this->name;
188
189 1
		return Utils\ArrayHash::from($collection);
190
	}
191
192
	/**
193
	 * @param Nette\Configurator $config
194
	 * @param string $extensionName
195
	 */
196
	public static function register(Nette\Configurator $config, $extensionName = 'flysystem')
197
	{
198 1
		$config->onCompile[] = function (Nette\Configurator $config, Nette\DI\Compiler $compiler) use ($extensionName) {
199 1
			$compiler->addExtension($extensionName, new FlysystemExtension);
200 1
		};
201 1
	}
202
}
203