Passed
Pull Request — master (#223)
by Arman
03:12
created

FileSystemFactory::getAdapterClass()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 3
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 7
rs 10
1
<?php
2
3
/**
4
 * Quantum PHP Framework
5
 *
6
 * An open source software development framework for PHP
7
 *
8
 * @package Quantum
9
 * @author Arman Ag. <[email protected]>
10
 * @copyright Copyright (c) 2018 Softberg LLC (https://softberg.org)
11
 * @link http://quantum.softberg.org/
12
 * @since 2.9.6
13
 */
14
15
namespace Quantum\Libraries\Storage\Factories;
16
17
use Quantum\Libraries\Storage\Adapters\GoogleDrive\GoogleDriveFileSystemAdapter;
18
use Quantum\Libraries\Storage\Adapters\Dropbox\DropboxFileSystemAdapter;
19
use Quantum\Libraries\Storage\Adapters\Local\LocalFileSystemAdapter;
20
use Quantum\Libraries\Storage\Adapters\GoogleDrive\GoogleDriveApp;
21
use Quantum\Libraries\Storage\Contracts\TokenServiceInterface;
22
use Quantum\Libraries\Storage\Exceptions\FileSystemException;
23
use Quantum\Libraries\Storage\Adapters\Dropbox\DropboxApp;
24
use Quantum\Libraries\Storage\Contracts\CloudAppInterface;
25
use Quantum\Libraries\Config\Exceptions\ConfigException;
26
use Quantum\Libraries\HttpClient\HttpClient;
27
use Quantum\Libraries\Storage\FileSystem;
28
use Quantum\Exceptions\ServiceException;
29
use Quantum\Di\Exceptions\DiException;
30
use Quantum\Exceptions\BaseException;
31
use Quantum\Factory\ServiceFactory;
32
use Quantum\Loader\Setup;
33
use ReflectionException;
34
35
/**
36
 * Class FileSystemFactory
37
 * @package Quantum\Libraries\Storage
38
 */
39
class FileSystemFactory
40
{
41
42
    /**
43
     * Supported adapters
44
     */
45
    const ADAPTERS = [
46
        FileSystem::LOCAL => LocalFileSystemAdapter::class,
47
        FileSystem::DROPBOX => DropboxFileSystemAdapter::class,
48
        FileSystem::GDRIVE => GoogleDriveFileSystemAdapter::class,
49
    ];
50
51
    /**
52
     * Supported apps
53
     */
54
    const APPS = [
55
        FileSystem::DROPBOX => DropboxApp::class,
56
        FileSystem::GDRIVE => GoogleDriveApp::class,
57
    ];
58
59
    /**
60
     * @var array
61
     */
62
    private static $instances = [];
63
64
    /**
65
     * @param string|null $adapter
66
     * @return FileSystem
67
     * @throws BaseException
68
     * @throws DiException
69
     * @throws ReflectionException
70
     * @throws ConfigException
71
     */
72
    public static function get(?string $adapter = null): FileSystem
73
    {
74
        if (!config()->has('fs')) {
75
            config()->import(new Setup('Config', 'fs'));
76
        }
77
78
        $adapter = $adapter ?? config()->get('fs.default');
79
80
        $adapterClass = self::getAdapterClass($adapter);
0 ignored issues
show
Bug introduced by
It seems like $adapter can also be of type null; however, parameter $adapter of Quantum\Libraries\Storag...tory::getAdapterClass() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

80
        $adapterClass = self::getAdapterClass(/** @scrutinizer ignore-type */ $adapter);
Loading history...
81
82
        if (!isset(self::$instances[$adapter])) {
83
            self::$instances[$adapter] = self::createInstance($adapterClass, $adapter);
84
        }
85
86
        return self::$instances[$adapter];
87
    }
88
89
    /**
90
     * @param string $adapterClass
91
     * @param string $adapter
92
     * @return FileSystem
93
     * @throws DiException
94
     * @throws FileSystemException
95
     * @throws ReflectionException
96
     * @throws ServiceException
97
     */
98
    private static function createInstance(string $adapterClass, string $adapter): FileSystem
99
    {
100
        return new FileSystem(new $adapterClass(
101
            self::createCloudApp($adapter)
102
        ));
103
    }
104
105
    /**
106
     * @param string $adapter
107
     * @return string
108
     * @throws BaseException
109
     */
110
    private static function getAdapterClass(string $adapter): string
111
    {
112
        if (!array_key_exists($adapter, self::ADAPTERS)) {
113
            throw FileSystemException::adapterNotSupported($adapter);
114
        }
115
116
        return self::ADAPTERS[$adapter];
117
    }
118
119
    /**
120
     * @param string $adapter
121
     * @return CloudAppInterface|null
122
     * @throws DiException
123
     * @throws FileSystemException
124
     * @throws ReflectionException
125
     * @throws ServiceException
126
     */
127
    private static function createCloudApp(string $adapter): ?CloudAppInterface
128
    {
129
        if ($adapter === FileSystem::LOCAL || !isset(self::APPS[$adapter])) {
130
            return null;
131
        }
132
133
        $cloudAppClass = self::APPS[$adapter];
134
135
        return new $cloudAppClass(
136
            config()->get('fs.' . $adapter . '.params.app_key'),
137
            config()->get('fs.' . $adapter . '.params.app_secret'),
138
            self::createTokenService($adapter),
139
            new HttpClient()
140
        );
141
    }
142
143
    /**
144
     * @param string $adapter
145
     * @return TokenServiceInterface
146
     * @throws FileSystemException
147
     * @throws DiException
148
     * @throws ServiceException
149
     * @throws ReflectionException
150
     */
151
    private static function createTokenService(string $adapter): TokenServiceInterface
152
    {
153
        $tokenService = ServiceFactory::create(config()->get('fs.' . $adapter . '.service'));
0 ignored issues
show
Bug introduced by
It seems like config()->get('fs.' . $adapter . '.service') can also be of type null; however, parameter $serviceClass of Quantum\Factory\ServiceFactory::create() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

153
        $tokenService = ServiceFactory::create(/** @scrutinizer ignore-type */ config()->get('fs.' . $adapter . '.service'));
Loading history...
154
155
        if (!$tokenService instanceof TokenServiceInterface) {
156
            throw FileSystemException::incorrectTokenService();
157
        }
158
159
        return $tokenService;
160
    }
161
}