1: <?php
2:
3: namespace Charcoal\App\ServiceProvider;
4:
5: use Exception;
6: use InvalidArgumentException;
7: use UnexpectedValueException;
8:
9:
10: use Pimple\ServiceProviderInterface;
11: use Pimple\Container;
12:
13:
14: use Aws\S3\S3Client;
15:
16:
17: use Dropbox\Client as DropboxClient;
18:
19:
20: use League\Flysystem\MountManager;
21: use League\Flysystem\Filesystem;
22: use League\Flysystem\Adapter\Local as LocalAdapter;
23: use League\Flysystem\Adapter\Ftp as FtpAdapter;
24: use League\Flysystem\Adapter\NullAdapter;
25:
26:
27: use League\Flysystem\AwsS3v3\AwsS3Adapter;
28:
29:
30: use League\Flysystem\Dropbox\DropboxAdapter;
31:
32:
33: use League\Flysystem\Sftp\SftpAdapter;
34:
35:
36: use League\Flysystem\Memory\MemoryAdapter;
37:
38:
39: use Charcoal\App\Config\FilesystemConfig;
40:
41: 42: 43:
44: class FilesystemServiceProvider implements ServiceProviderInterface
45: {
46: 47: 48: 49:
50: public function register(Container $container)
51: {
52: 53: 54: 55:
56: $container['filesystem/config'] = function (Container $container) {
57: $appConfig = $container['config'];
58:
59: return new FilesystemConfig($appConfig['filesystem']);
60: };
61:
62: 63: 64: 65:
66: $container['filesystem/manager'] = function () {
67: return new MountManager();
68: };
69:
70: $container['filesystems'] = function (Container $container) {
71: $filesystemConfig = $container['filesystem/config'];
72: $filesystems = new Container();
73:
74: foreach ($filesystemConfig['connections'] as $ident => $connection) {
75: $fs = $this->createConnection($connection);
76: $filesystems[$ident] = $fs;
77: $container['filesystem/manager']->mountFilesystem($ident, $fs);
78: }
79:
80: return $filesystems;
81: };
82: }
83:
84: 85: 86: 87: 88: 89:
90: private function createConnection(array $config)
91: {
92: if (!isset($config['type'])) {
93: throw new Exception(
94: 'No filesystem type defined'
95: );
96: }
97:
98: $type = $config['type'];
99:
100: if ($type == 'local') {
101: $adapter = $this->createLocalAdapter($config);
102: } elseif ($type == 's3') {
103: $adapter = $this->createS3Adapter($config);
104: } elseif ($type == 'dropbox') {
105: $adapter = $this->createDropboxAdapter($config);
106: } elseif ($type == 'ftp') {
107: $adapter = $this->createFtpAdapter($config);
108: } elseif ($type == 'sftp') {
109: $adapter = $this->createSftpAdapter($config);
110: } elseif ($type == 'memory') {
111: $adapter = $this->createMemoryAdapter($config);
112: } elseif ($type == 'noop') {
113: $adapter = $this->createNullAdapter($config);
114: } else {
115: throw new UnexpectedValueException(
116: sprintf('Invalid filesystem type "%s"', $type)
117: );
118: }
119:
120: return new Filesystem($adapter);
121: }
122:
123: 124: 125: 126: 127:
128: private function createLocalAdapter(array $config)
129: {
130: if (!isset($config['path']) || !$config['path']) {
131: throw new InvalidArgumentException(
132: 'No "path" configured for local filesystem.'
133: );
134: }
135: $defaults = [
136: 'lock' => null,
137: 'links' => null,
138: 'permissions' => []
139: ];
140: $config = array_merge($defaults, $config);
141:
142: return new LocalAdapter($config['path'], $config['lock'], $config['links'], $config['permissions']);
143: }
144:
145: 146: 147: 148: 149:
150: private function createS3Adapter(array $config)
151: {
152: if (!isset($config['key']) || !$config['key']) {
153: throw new InvalidArgumentException(
154: 'No "key" configured for S3 filesystem.'
155: );
156: }
157: if (!isset($config['secret']) || !$config['secret']) {
158: throw new InvalidArgumentException(
159: 'No "secret" configured for S3 filesystem.'
160: );
161: }
162:
163: if (!isset($config['bucket']) || !$config['bucket']) {
164: throw new InvalidArgumentException(
165: 'No "bucket" configured for S3 filesystem.'
166: );
167: }
168:
169: $defaults = [
170: 'region' => '',
171: 'version' => 'latest',
172: 'prefix' => null
173: ];
174: $config = array_merge($defaults, $config);
175:
176: $client = S3Client::factory([
177: 'credentials' => [
178: 'key' => $config['key'],
179: 'secret' => $config['secret'],
180: ],
181: 'region' => $config['region'],
182: 'version' => $config['version'],
183: ]);
184:
185: if (isset($config['public']) && !$config['public']) {
186: $permissions = null;
187: } else {
188: $permissions = [
189: 'ACL' => 'public-read'
190: ];
191: }
192:
193: return new AwsS3Adapter($client, $config['bucket'], $config['prefix'], $permissions);
194: }
195:
196: 197: 198: 199: 200:
201: private function createDropboxAdapter(array $config)
202: {
203: if (!isset($config['token']) || !$config['token']) {
204: throw new InvalidArgumentException(
205: 'No access "token" configured for dropbox filesystem adapter.'
206: );
207: }
208:
209: if (!isset($config['secret']) || !$config['secret']) {
210: throw new InvalidArgumentException(
211: 'No app "secret" configured for dropbox filesystem adapter.'
212: );
213: }
214:
215: $defaults = [
216: 'prefix' => ''
217: ];
218: $config = array_merge($defaults, $config);
219:
220: $client = new DropboxClient($config['token'], $config['secret']);
221: return new DropboxAdapter($client, $config['prefix']);
222: }
223:
224: 225: 226: 227: 228:
229: private function createFtpAdapter(array $config)
230: {
231: if (!$config['host']) {
232: throw new InvalidArgumentException(
233: 'No host configured for FTP filesystem filesystem adapter.'
234: );
235: }
236: if (!$config['username']) {
237: throw new InvalidArgumentException(
238: 'No username configured for FTP filesystem filesystem adapter.'
239: );
240: }
241: if (!$config['password']) {
242: throw new InvalidArgumentException(
243: 'No password configured for FTP filesystem filesystem adapter.'
244: );
245: }
246:
247: $defaults = [
248: 'port' => null,
249: 'root' => null,
250: 'passive' => null,
251: 'ssl' => null,
252: 'timeout' => null
253: ];
254: $config = array_merge($defaults, $config);
255:
256: return new FtpAdapter($config);
257: }
258:
259: 260: 261: 262: 263:
264: private function createSftpAdapter(array $config)
265: {
266: if (!$config['host']) {
267: throw new InvalidArgumentException(
268: 'No host configured for SFTP filesystem filesystem adapter.'
269: );
270: }
271: if (!$config['username']) {
272: throw new InvalidArgumentException(
273: 'No username configured for SFTP filesystem filesystem adapter.'
274: );
275: }
276: if (!$config['password']) {
277: throw new InvalidArgumentException(
278: 'No password configured for SFTP filesystem filesystem adapter.'
279: );
280: }
281:
282: $defaults = [
283: 'port' => null,
284: 'privateKey' => null,
285: 'root' => null,
286: 'timeout' => null
287: ];
288: $config = array_merge($defaults, $config);
289:
290: return new SftpAdapter($config);
291: }
292:
293: 294: 295:
296: private function createMemoryAdapter()
297: {
298: return new MemoryAdapter();
299: }
300:
301: 302: 303:
304: private function createNullAdapter()
305: {
306: return new NullAdapter();
307: }
308: }
309: