Completed
Push — master ( 49a2f1...c8064a )
by Sebastian
03:33
created

Sftp   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 97
Duplicated Lines 11.34 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 40.54%

Importance

Changes 0
Metric Value
wmc 12
lcom 1
cbo 4
dl 11
loc 97
ccs 15
cts 37
cp 0.4054
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 8 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 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
    protected function checkRequirements()
27
    {
28
        if (!class_exists('\\phpseclib\\Net\\SFTP')) {
29
            throw new Exception('phpseclib not installed - use composer to install "phpseclib/phpseclib" version 2.x');
30
        }
31
    }
32
33
    /**
34
     * Return implemented (*)TP protocol name.
35
     *
36
     * @return string
37
     */
38
    protected function getProtocolName()
39
    {
40
        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 5
                $result->debug(sprintf('creating remote dir \'%s\'', $dir));
60
                $sftp->mkdir($dir);
61 5
            }
62
            $result->debug(sprintf('change to remote dir \'%s\'', $dir));
63
            $sftp->chdir($dir);
64 5
        }
65 1
66
        $result->debug(sprintf('store file \'%s\' as \'%s\'', $localFile, $remoteFilename));
67 4
        $result->debug(sprintf('last error \'%s\'', $sftp->getLastSFTPError()));
68 1
69
        if (!$sftp->put($remoteFilename, $localFile, phpseclib\Net\SFTP::SOURCE_LOCAL_FILE)) {
70 3
            throw new Exception(sprintf('error uploading file: %s - %s', $localFile, $sftp->getLastSFTPError()));
71 2
        }
72
    }
73 1
74 1
    /**
75
     * Create a sftp handle.
76
     *
77 1
     * @return \phpseclib\Net\SFTP
78 1
     * @throws \phpbu\App\Backup\Sync\Exception
79 1
     */
80 1
    private function login() : phpseclib\Net\SFTP
81 1
    {
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
    private function getRemoteDirectoryList() : array
108
    {
109
        $remoteDirs = [];
110
        if ('' !== $this->remotePath) {
111
            $remoteDirs = explode('/', $this->remotePath);
112
        }
113
        return $remoteDirs;
114
    }
115
}
116