Completed
Pull Request — master (#141)
by
unknown
03:16
created

Sftp   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 103
Duplicated Lines 10.68 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 30.95%

Importance

Changes 0
Metric Value
wmc 14
lcom 1
cbo 4
dl 11
loc 103
ccs 13
cts 42
cp 0.3095
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A checkRequirements() 0 6 2
A getProtocolName() 0 4 1
B sync() 0 22 4
A login() 11 21 3
A getRemoteDirectoryList() 0 14 4

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
namespace phpbu\App\Backup\Sync;
3
4
use phpseclib;
5
use phpbu\App\Result;
6
use phpbu\App\Backup\Target;
7
8
/**
9
 * Sftp sync
10
 *
11
 * @package    phpbu
12
 * @subpackage Backup
13
 * @author     Sebastian Feldmann <[email protected]>
14
 * @copyright  Sebastian Feldmann <[email protected]>
15
 * @license    https://opensource.org/licenses/MIT The MIT License (MIT)
16
 * @link       http://phpbu.de/
17
 * @since      Class available since Release 1.0.0
18
 */
19
class Sftp extends Xtp implements Simulator
20
{
21
    /**
22
     * Check for required loaded libraries or extensions.
23
     *
24
     * @throws \phpbu\App\Backup\Sync\Exception
25
     */
26 7
    protected function checkRequirements()
27
    {
28 7
        if (!class_exists('\\phpseclib\\Net\\SFTP')) {
29
            throw new Exception('phpseclib not installed - use composer to install "phpseclib/phpseclib" version 2.x');
30
        }
31 7
    }
32
33
    /**
34
     * Return implemented (*)TP protocol name.
35
     *
36
     * @return string
37
     */
38 1
    protected function getProtocolName()
39
    {
40 1
        return 'SFTP';
41
    }
42
43
    /**
44
     * (non-PHPDoc)
45
     *
46
     * @see    \phpbu\App\Backup\Sync::sync()
47
     * @param  \phpbu\App\Backup\Target $target
48
     * @param  \phpbu\App\Result        $result
49
     * @throws \phpbu\App\Backup\Sync\Exception
50
     */
51
    public function sync(Target $target, Result $result)
52
    {
53
        $sftp           = $this->login();
54
        $remoteFilename = $target->getFilename();
55
        $localFile      = $target->getPathname();
56
57
        foreach ($this->getRemoteDirectoryList() as $dir) {
58
            if (!$sftp->is_dir($dir)) {
59
                $result->debug(sprintf('creating remote dir \'%s\'', $dir));
60
                $sftp->mkdir($dir);
61
            }
62
            $result->debug(sprintf('change to remote dir \'%s\'', $dir));
63
            $sftp->chdir($dir);
64
        }
65
66
        $result->debug(sprintf('store file \'%s\' as \'%s\'', $localFile, $remoteFilename));
67
        $result->debug(sprintf('last error \'%s\'', $sftp->getLastSFTPError()));
68
69
        if (!$sftp->put($remoteFilename, $localFile, phpseclib\Net\SFTP::SOURCE_LOCAL_FILE)) {
70
            throw new Exception(sprintf('error uploading file: %s - %s', $localFile, $sftp->getLastSFTPError()));
71
        }
72
    }
73
74
    /**
75
     * Create a sftp handle.
76
     *
77
     * @return \phpseclib\Net\SFTP
78
     * @throws \phpbu\App\Backup\Sync\Exception
79
     */
80
    private function login() : phpseclib\Net\SFTP
81
    {
82
        // silence phpseclib
83
        $old  = error_reporting(0);
84
        $sftp = new phpseclib\Net\SFTP($this->host);
85 View Code Duplication
        if (!$sftp->login($this->user, $this->password)) {
86
            error_reporting($old);
87
            throw new Exception(
88
                sprintf(
89
                    'authentication failed for %s@%s%s',
90
                    $this->user,
91
                    $this->host,
92
                    empty($this->password) ? '' : ' with password ****'
93
                )
94
            );
95
        }
96
        // restore old error reporting
97
        error_reporting($old);
98
99
        return $sftp;
100
    }
101
102
    /**
103
     * Return list of remote directories to travers.
104
     *
105
     * @return array
106
     */
107 1
    public function getRemoteDirectoryList() : array
108
    {
109 1
        $remoteDirs = [];
110 1
        if ('' !== $this->remotePath) {
111 1
            $remoteDirs = explode('/', $this->remotePath);
112
            // if path is absolute, fix first part of array that was empty string
113 1
            if (substr($this->remotePath, 0, 1) === '/') {
114 1
                if (isset($remoteDirs[0])) {
115 1
                    $remoteDirs[0] = '/';
116
                }
117
            }
118
        }
119 1
        return array_filter($remoteDirs);
120
    }
121
}
122