Completed
Pull Request — master (#2)
by Mathieu
15:51 queued 09:51
created

FilesystemServiceProvider::createDropboxAdapter()   B

Complexity

Conditions 5
Paths 3

Size

Total Lines 22
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 22
rs 8.6737
c 0
b 0
f 0
cc 5
eloc 12
nc 3
nop 1
1
<?php
2
3
namespace Charcoal\App\ServiceProvider;
4
5
use Exception;
6
use InvalidArgumentException;
7
use UnexpectedValueException;
8
9
// Dependencies from `pimple/pimple`
10
use Pimple\ServiceProviderInterface;
11
use Pimple\Container;
12
13
// Dependencies from AWS S3 SDK
14
use Aws\S3\S3Client;
15
16
// Dependencies from Dropbox
17
use Dropbox\Client as DropboxClient;
18
19
// Dependencies from `league/flysystem`
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
// Dependency from `league/flysystem-aws-s3-v3`
27
use League\Flysystem\AwsS3v3\AwsS3Adapter;
28
29
// Dependency from `league/flysystem-dropbox`
30
use League\Flysystem\Dropbox\DropboxAdapter;
31
32
// Dependency from `league/flysystem-sftp`
33
use League\Flysystem\Sftp\SftpAdapter;
34
35
// Dependency from `league/flysystem-memory`
36
use League\Flysystem\Memory\MemoryAdapter;
37
38
// Local namespace depdency
39
use Charcoal\App\Config\FilesystemConfig;
40
41
/**
42
 *
43
 */
44
class FilesystemServiceProvider implements ServiceProviderInterface
45
{
46
    /**
47
     * @param Container $container Pimple DI Container.
48
     * @return void
49
     */
50
    public function register(Container $container)
51
    {
52
        /**
53
         * @param Container $container Pimple DI Container.
54
         * @return FlysystemConfig
55
         */
56
        $container['filesystem/config'] = function (Container $container) {
57
            $appConfig = $container['config'];
58
59
            return new FilesystemConfig($appConfig['filesystem']);
60
        };
61
62
        /**
63
         * @param Container $container Pimple DI Container.
64
         * @return MountManager
65
         */
66
        $container['filesystem/manager'] = function (Container $container) {
0 ignored issues
show
Unused Code introduced by
The parameter $container is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
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
     * @param array $config The driver (adapter) configuration.
86
     * @throws Exception If the filesystem type is not defined in config.
87
     * @throws UnexpectedValueException If the filesystem type is invalid / unsupported.
88
     * @return Filesystem
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
     * @param array $config The driver (adapter) configuration.
125
     * @throws InvalidArgumentException If the path is not defined in config.
126
     * @return LocalAdapter
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
     * @param array $config The driver (adapter) configuration.
147
     * @throws InvalidArgumentException If the key, secret or bucket is not defined in config.
148
     * @return AwsS3Adapter
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([
0 ignored issues
show
Deprecated Code introduced by
The method Aws\AwsClient::factory() has been deprecated.

This method has been deprecated.

Loading history...
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);
0 ignored issues
show
Bug introduced by
It seems like $permissions defined by null on line 186 can also be of type null; however, League\Flysystem\AwsS3v3...3Adapter::__construct() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
194
    }
195
196
    /**
197
     * @param array $config The driver (adapter) configuration.
198
     * @throws InvalidArgumentException If the token or secret is not defined in config.
199
     * @return FtpAdapter
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
     * @param array $config The driver (adapter) configuration.
226
     * @throws InvalidArgumentException If the host, username or password is not defined in config.
227
     * @return FtpAdapter
228
     */
229 View Code Duplication
    private function createFtpAdapter(array $config)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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
     * @param array $config The driver (adapter) configuration.
261
     * @throws InvalidArgumentException If the host, username or password is not defined in config.
262
     * @return SftpAdapter
263
     */
264 View Code Duplication
    private function createSftpAdapter(array $config)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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
291
        return new SftpAdapter($config);
292
    }
293
294
    /**
295
     * @param array $config The driver (adapter) configuration.
296
     * @return MemoryAdapter
297
     */
298
    private function createMemoryAdapter(array $config)
0 ignored issues
show
Unused Code introduced by
The parameter $config is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
299
    {
300
        return new MemoryAdapter();
301
    }
302
303
    /**
304
     * @param array $config The driver (adapter) configuration.
305
     * @return NullAdapter
306
     */
307
    private function createNullAdapter(array $config)
0 ignored issues
show
Unused Code introduced by
The parameter $config is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
308
    {
309
        return new NullAdapter();
310
    }
311
}
312