Completed
Pull Request — master (#140)
by
unknown
02:55
created

Sftp   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 141
Duplicated Lines 14.18 %

Coupling/Cohesion

Components 1
Dependencies 7

Test Coverage

Coverage 66.04%

Importance

Changes 0
Metric Value
wmc 16
lcom 1
cbo 7
dl 20
loc 141
ccs 35
cts 53
cp 0.6604
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A setup() 0 6 1
A checkRequirements() 0 6 2
A getProtocolName() 0 4 1
B sync() 0 25 4
A login() 11 21 3
A getRemoteDirectoryList() 0 13 3
A cleanup() 9 9 2

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