Passed
Push — main ( 989c75...a2b15c )
by Sugeng
03:11
created

SftpComponent   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 140
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 12
eloc 49
c 2
b 0
f 0
dl 0
loc 140
rs 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
A init() 0 13 6
A initAdapter() 0 19 4
A checksum() 0 7 2
1
<?php
2
3
namespace diecoding\flysystem;
4
5
use diecoding\flysystem\traits\UrlGeneratorTrait;
6
use League\Flysystem\ChecksumAlgoIsNotSupported;
7
use League\Flysystem\ChecksumProvider;
8
use League\Flysystem\Config;
9
use League\Flysystem\PathPrefixing\PathPrefixedAdapter;
10
use League\Flysystem\PhpseclibV3\SftpAdapter;
11
use League\Flysystem\PhpseclibV3\SftpConnectionProvider;
12
use League\Flysystem\UrlGeneration\PublicUrlGenerator;
13
use League\Flysystem\UrlGeneration\TemporaryUrlGenerator;
14
use Yii;
15
use yii\base\InvalidConfigException;
16
17
/**
18
 * Interacting with an sftp filesystem
19
 * This implementation uses version 3 of phpseclib
20
 * ! Notice
21
 * It's important to know this adapter does not fully comply with the adapter contract. The difference(s) is/are:
22
 * - Checksum setting or retrieving is not supported.
23
 * @see https://flysystem.thephpleague.com/docs/adapter/sftp-v3/
24
 * 
25
 * ```php
26
 * 'components' => [
27
 *     'fs' => [
28
 *         'class' => \diecoding\flysystem\SftpComponent::class,
29
 *         'host' => 'hostname',
30
 *         'username' => 'username',
31
 *         'password' => null, // password (optional, default: null) set to null if privateKey is used
32
 *         'privateKey' => '/path/to/my/private_key', // private key (optional, default: null) can be used instead of password, set to null if password is set
33
 *         'passphrase' => 'super-secret-password', // passphrase (optional, default: null), set to null if privateKey is not used or has no passphrase
34
 *         'port' => 22,
35
 *         'useAgent' => true,
36
 *         'timeout' => 10,
37
 *         'maxTries' => 4,
38
 *         'hostFingerprint' => null,
39
 *         'connectivityChecker' => null, // connectivity checker (must be an implementation of `League\Flysystem\PhpseclibV2\ConnectivityChecker` to check if a connection can be established (optional, omit if you don't need some special handling for setting reliable connections)
40
 *         'preferredAlgorithms' => [],
41
 *         'root' => '/root/path/', // or you can use @alias
42
 *         'action' => '/site/file',
43
 *         'prefix' => '', 
44
 *     ],
45
 * ],
46
 * ```
47
 * 
48
 * @link      https://sugengsulistiyawan.my.id/
49
 * @author    Sugeng Sulistiyawan <[email protected]>
50
 * @copyright Copyright (c) 2023
51
 */
52
class SftpComponent extends AbstractComponent implements PublicUrlGenerator, TemporaryUrlGenerator, ChecksumProvider
53
{
54
    use UrlGeneratorTrait;
55
56
    /**
57
     * @var string
58
     */
59
    public $host;
60
61
    /**
62
     * @var string
63
     */
64
    public $username;
65
66
    /**
67
     * @var string
68
     */
69
    public $password;
70
71
    /**
72
     * @var string
73
     */
74
    public $privateKey;
75
76
    /**
77
     * @var string
78
     */
79
    public $passphrase;
80
81
    /**
82
     * @var int
83
     */
84
    public $port;
85
86
    /**
87
     * @var bool
88
     */
89
    public $useAgent;
90
91
    /**
92
     * @var int
93
     */
94
    public $timeout;
95
    /**
96
     * @var int
97
     */
98
    public $maxTries;
99
100
    /**
101
     * @var string
102
     */
103
    public $hostFingerprint;
104
105
    /**
106
     * @var \League\Flysystem\PhpseclibV3\ConnectivityChecker
107
     */
108
    public $connectivityChecker;
109
110
    /**
111
     * @var array
112
     */
113
    public $preferredAlgorithms;
114
115
    /**
116
     * @var string
117
     */
118
    public $root;
119
120
    /**
121
     * @var array
122
     */
123
    protected $_availableOptions = [
124
        'host',
125
        'username',
126
        'password',
127
        'privateKey',
128
        'passphrase',
129
        'port',
130
        'useAgent',
131
        'timeout',
132
        'maxTries',
133
        'hostFingerprint',
134
        'connectivityChecker',
135
        'preferredAlgorithms',
136
    ];
137
138
    /**
139
     * @var SftpConnectionProvider
140
     */
141
    protected $_connectionProvider;
142
143
    /**
144
     * @inheritdoc
145
     */
146
    public function init()
147
    {
148
        if (empty($this->path)) {
0 ignored issues
show
Bug Best Practice introduced by
The property path does not exist on diecoding\flysystem\SftpComponent. Since you implemented __get, consider adding a @property annotation.
Loading history...
149
            throw new InvalidConfigException('The "host" property must be set.');
150
        }
151
        if (empty($this->secret)) {
0 ignored issues
show
Bug Best Practice introduced by
The property secret does not exist on diecoding\flysystem\SftpComponent. Since you implemented __get, consider adding a @property annotation.
Loading history...
152
            throw new InvalidConfigException('The "username" property must be set.');
153
        }
154
155
        $this->passphrase = $this->passphrase ?: ($this->password ?: ($this->username ?: Yii::$app->id));
156
        $this->initEncrypter($this->passphrase);
157
158
        parent::init();
159
    }
160
161
    /**
162
     * @return SftpAdapter|PathPrefixedAdapter
163
     */
164
    protected function initAdapter()
165
    {
166
        $this->root = (string) Yii::getAlias($this->root);
167
168
        $options = [];
169
        foreach ($this->_availableOptions as $property) {
170
            if ($this->$property !== null) {
171
                $options[$property] = $this->$property;
172
            }
173
        }
174
175
        $this->_connectionProvider = SftpConnectionProvider::fromArray($options);
176
177
        $adapter = new SftpAdapter($this->_connectionProvider, $this->root);
178
        if ($this->prefix) {
179
            $adapter = new PathPrefixedAdapter($adapter, $this->prefix);
180
        }
181
182
        return $adapter;
183
    }
184
185
    public function checksum(string $path, Config $config): string
186
    {
187
        if ($this->debug) {
188
            throw new ChecksumAlgoIsNotSupported('SftpComponent does not support this operation.');
189
        }
190
191
        return '';
192
    }
193
}