SecLibSshProcess::run()   A
last analyzed

Complexity

Conditions 3
Paths 4

Size

Total Lines 23
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 6
c 1
b 0
f 0
nc 4
nop 8
dl 0
loc 23
rs 10

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
/*
4
 * This file is part of the GitCommandBundle package.
5
 *
6
 * (c) Paul Schweppe <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace VersionControl\GitCommandBundle\Service;
13
14
use InvalidArgumentException;
15
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
16
use VersionControl\GitCommandBundle\GitCommands\Exception\RunGitCommandException;
17
use phpseclib\Net\SSH2;
18
use phpseclib\Crypt\RSA;
19
20
/**
21
 * Use PhpSecLib to make SSH2 requests.
22
 *
23
 * @link https://github.com/phpseclib/phpseclib
24
 *
25
 * @author Paul Schweppe <[email protected]>
26
 */
27
class SecLibSshProcess implements SshProcessInterface
28
{
29
    /**
30
     * @var EventDispatcherInterface
31
     */
32
    protected $dispatcher;
33
34
    /**
35
     * @var array
36
     */
37
    protected $config;
38
39
    /**
40
     * @var SSH2|null
41
     */
42
    protected $shell;
43
44
    /**
45
     * @var array
46
     */
47
    protected $stdout;
48
49
    /**
50
     * @var array
51
     */
52
    protected $stderr;
53
54
    /**
55
     * //EventDispatcherInterface $eventDispatcher,.
56
     *
57
     */
58
    public function __construct()
59
    {
60
        $this->shell = null;
61
        $this->stdout = array();
62
        $this->stdin = array();
0 ignored issues
show
Bug Best Practice introduced by
The property stdin does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
63
        $this->stderr = array();
64
    }
65
66
    /**
67
     * @param string $glue
68
     *
69
     * @return array|string
70
     */
71
    public function getStdout($glue = "\n")
72
    {
73
        if (!$glue) {
74
            $output = $this->stdout;
75
        } else {
76
            $output = implode($glue, $this->stdout);
77
        }
78
79
        return $output;
80
    }
81
82
    /**
83
     * @param string $glue
84
     *
85
     * @return array|string
86
     */
87
    public function getStderr($glue = "\n")
88
    {
89
        if (!$glue) {
90
            return $this->stderr;
91
        }
92
93
        return implode($glue, $this->stderr);
94
    }
95
96
    /**
97
     * @param array $commands
98
     * @param string $host
99
     * @param string $username
100
     * @param int $port
101
     * @param string $password
102
     * @param string|null $publicKeyFile
103
     * @param string|null $privateKeyFile
104
     * @param string $passphrase
105
     *
106
     * @return array
107
     * @throws RunGitCommandException
108
     */
109
    public function run(
110
        array $commands,
111
        string $host,
112
        string $username,
113
        int $port = 22,
114
        ?string $password = null,
115
        ?string $publicKeyFile = null,
116
        ?string $privateKeyFile = null,
117
        ?string $passphrase = null
118
    ): array {
119
        $this->reset();
120
121
        if ($this->shell === null) {
122
            $this->connect($host, $username, $port, $password, $pubkeyFile, $privkeyFile, $passphrase);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $pubkeyFile seems to be never defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable $privkeyFile seems to be never defined.
Loading history...
Bug introduced by
It seems like $password can also be of type string; however, parameter $password of VersionControl\GitComman...ibSshProcess::connect() does only seem to accept null, 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

122
            $this->connect($host, $username, $port, /** @scrutinizer ignore-type */ $password, $pubkeyFile, $privkeyFile, $passphrase);
Loading history...
Bug introduced by
It seems like $passphrase can also be of type string; however, parameter $privateKeyPassword of VersionControl\GitComman...ibSshProcess::connect() does only seem to accept null, 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

122
            $this->connect($host, $username, $port, $password, $pubkeyFile, $privkeyFile, /** @scrutinizer ignore-type */ $passphrase);
Loading history...
123
        }
124
125
        foreach ($commands as $command) {
126
            $this->execute($command);
127
        }
128
129
        //$this->disconnect();
130
131
        return $this->stdout;
132
    }
133
134
    /**
135
     * Resets out puts for next command.
136
     */
137
    protected function reset()
138
    {
139
        $this->stdout = array();
140
        $this->stdin = array();
0 ignored issues
show
Bug Best Practice introduced by
The property stdin does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
141
        $this->stderr = array();
142
    }
143
144
    /**
145
     * @param $host
146
     * @param $username
147
     * @param int $port
148
     * @param null $password
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $password is correct as it would always require null to be passed?
Loading history...
149
     * @param null $pubkeyFile
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $pubkeyFile is correct as it would always require null to be passed?
Loading history...
150
     * @param null $privateKey
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $privateKey is correct as it would always require null to be passed?
Loading history...
151
     * @param null $privateKeyPassword
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $privateKeyPassword is correct as it would always require null to be passed?
Loading history...
152
     *
153
     * @throws InvalidArgumentException
154
     */
155
    protected function connect(
156
        $host,
157
        $username,
158
        $port = 22,
159
        $password = null,
160
        $pubkeyFile = null,
161
        $privateKey = null,
162
        $privateKeyPassword = null
163
    ) {
164
        $this->shell = new SSH2($host, $port);
165
166
        if (!$this->shell) {
167
            throw new InvalidArgumentException(sprintf('SSH connection failed on "%s:%s"', $host, $port));
168
        }
169
170
        if (isset($username) && trim($privateKey)) {
171
            $key = new RSA();
172
            if ($privateKeyPassword) {
0 ignored issues
show
introduced by
$privateKeyPassword is of type null, thus it always evaluated to false.
Loading history...
173
                $key->setPassword($privateKeyPassword);
174
            }
175
            $key->loadKey($privateKey);
176
            if (!$this->shell->login($username, $key)) {
177
                throw new InvalidArgumentException(sprintf('SSH authentication failed for user "%s" using private key',
178
                    $username, $pubkeyFile));
179
            }
180
        } elseif ($username && $password) {
0 ignored issues
show
introduced by
$password is of type null, thus it always evaluated to false.
Loading history...
181
            if (!$this->shell->login($username, $password)) {
182
                throw new InvalidArgumentException(sprintf('SSH authentication failed for user "%s"', $username));
183
            }
184
        }
185
        $this->shell->getServerPublicHostKey();
186
187
        $this->stdout = array();
188
        $this->stdin = array();
0 ignored issues
show
Bug Best Practice introduced by
The property stdin does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
189
    }
190
191
    public function disconnect()
192
    {
193
        if ($this->shell) {
194
            //$this->shell->disconnect();
195
        }
196
    }
197
198
    /**
199
     * @param array $command
200
     *
201
     * @throws RunGitCommandException
202
     */
203
    protected function execute($command)
204
    {
205
        $this->shell->enableQuietMode();
0 ignored issues
show
Bug introduced by
The method enableQuietMode() does not exist on null. ( Ignorable by Annotation )

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

205
        $this->shell->/** @scrutinizer ignore-call */ 
206
                      enableQuietMode();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
206
207
        $stdOutput = $this->shell->exec($command);
0 ignored issues
show
Bug introduced by
$command of type array is incompatible with the type string expected by parameter $command of phpseclib\Net\SSH2::exec(). ( Ignorable by Annotation )

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

207
        $stdOutput = $this->shell->exec(/** @scrutinizer ignore-type */ $command);
Loading history...
208
        $stdError = $this->shell->getStdError();
209
        $exitStatus = $this->shell->getExitStatus();
210
211
        $stdout = explode("\n", $stdOutput);
212
        $stderr = array_filter(explode("\n", $stdError));
213
214
        if ($exitStatus != 0) {
215
            //print_r($stderr);
216
            throw new RunGitCommandException(
217
                sprintf(
218
                    "Error in command shell:%s \n Error Response:%s%s",
219
                    $command,
0 ignored issues
show
Bug introduced by
$command of type array is incompatible with the type string expected by parameter $args of sprintf(). ( Ignorable by Annotation )

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

219
                    /** @scrutinizer ignore-type */ $command,
Loading history...
220
                    implode("\n", $stderr),
221
                    $stdOutput
222
                )
223
            );
224
        }
225
226
        $this->stdout = array_merge($this->stdout, $stdout);
227
228
        if (is_array($stderr)) {
0 ignored issues
show
introduced by
The condition is_array($stderr) is always true.
Loading history...
229
            $this->stderr = array_merge($this->stderr, $stderr);
230
231
            if ($exitStatus === 0) {
232
                $this->stdout = array_merge($this->stdout, $stderr);
233
            }
234
        }
235
    }
236
237
    /**
238
     * Get exit status
239
     * @return false|int
240
     */
241
    public function getExitStatus()
242
    {
243
        return $this->shell->getExitStatus();
244
    }
245
246
    public function __destruct()
247
    {
248
        $this->disconnect();
249
    }
250
}
251