Completed
Pull Request — master (#145)
by Vitaly
02:41
created

Ftp::checkRequirements()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2.0625

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 3
cts 4
cp 0.75
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 3
nc 2
nop 0
crap 2.0625
1
<?php
2
namespace phpbu\App\Backup\Sync;
3
4
use phpbu\App\Backup\Collector;
5
use phpbu\App\Result;
6
use phpbu\App\Backup\Target;
7
use phpbu\App\Util\Arr;
8
use phpbu\App\Util\Path;
9
use phpbu\App\Util\Str;
10
11
/**
12
 * Ftp sync
13
 *
14
 * @package    phpbu
15
 * @subpackage Backup
16
 * @author     Chris Hawes <[email protected]>
17
 * @copyright  Sebastian Feldmann <[email protected]>
18
 * @license    https://opensource.org/licenses/MIT The MIT License (MIT)
19
 * @link       http://phpbu.de/
20
 */
21
class Ftp extends Xtp
22
{
23
    use Clearable;
24
25
    /**
26
     * FTP connection stream
27
     *
28
     * @var resource
29
     */
30
    protected $ftpConnection;
31
32
    /**
33
     * Determine should ftp connects via passive mode.
34
     *
35
     * @var bool
36
     */
37
    protected $passive;
38
39
    /**
40
     * Setup the Ftp sync.
41
     *
42
     * @param  array $config
43
     * @throws \phpbu\App\Backup\Sync\Exception
44
     * @throws \phpbu\App\Exception
45
     */
46 6
    public function setup(array $config)
47
    {
48 6
        $path = Arr::getValue($config, 'path', '');
49 6
        if ('/' === substr($path, 0, 1)) {
50 1
            throw new Exception('absolute path is not allowed');
51
        }
52 5
        if (!Arr::isSetAndNotEmptyString($config, 'password')) {
53 1
            throw new Exception('option \'password\' is missing');
54
        }
55 4
        parent::setup($config);
56
57 2
        $this->passive = Str::toBoolean(Arr::getValue($config, 'passive', ''), false);
58 2
        $this->setUpClearable($config);
59 2
    }
60
61
    /**
62
     * Check for required loaded libraries or extensions.
63
     *
64
     * @throws \phpbu\App\Backup\Sync\Exception
65
     */
66 4
    protected function checkRequirements()
67
    {
68 4
        if (!function_exists('ftp_connect')) {
69
            throw new Exception('ftp functions not enabled');
70
        }
71 4
    }
72
73
    /**
74
     * Return implemented (*)TP protocol name.
75
     *
76
     * @return string
77
     */
78 1
    protected function getProtocolName()
79
    {
80 1
        return 'FTP';
81
    }
82
83
    /**
84
     * (non-PHPDoc)
85
     *
86
     * @see    \phpbu\App\Backup\Sync::sync()
87
     * @param  \phpbu\App\Backup\Target $target
88
     * @param  \phpbu\App\Result        $result
89
     * @throws \phpbu\App\Backup\Sync\Exception
90
     */
91
    public function sync(Target $target, Result $result)
92
    {
93
        // silence ftp errors
94
        $old = error_reporting(0);
95
        if (!$this->ftpConnection = ftp_connect($this->host)) {
96
            throw new Exception(
97
                sprintf(
98
                    'Unable to connect to ftp server %s',
99
                    $this->host
100
                )
101
            );
102
        }
103
104
        if (!ftp_login($this->ftpConnection, $this->user, $this->password)) {
105
            error_reporting($old);
106
            throw new Exception(
107
                sprintf(
108
                    'authentication failed for %s@%s%s',
109
                    $this->user,
110
                    $this->host,
111
                    empty($this->password) ? '' : ' with password ****'
112
                )
113
            );
114
        }
115
116
        // Set passive mode if needed
117
        ftp_pasv($this->ftpConnection, $this->passive);
118
119
        $remoteFilename = $target->getFilename();
120
        $localFile      = $target->getPathname();
121
122
        if ('' !== $this->remotePath) {
123
            $remoteDirs = Path::getDirectoryListFromPath($this->remotePath);
124
            foreach ($remoteDirs as $dir) {
125
                if (!ftp_chdir($this->ftpConnection, $dir)) {
126
                    $result->debug(sprintf('creating remote dir \'%s\'', $dir));
127
                    ftp_mkdir($this->ftpConnection, $dir);
128
                    ftp_chdir($this->ftpConnection, $dir);
129
                } else {
130
                    $result->debug(sprintf('change to remote dir \'%s\'', $dir));
131
                }
132
            }
133
        }
134
        $result->debug(sprintf('store file \'%s\' as \'%s\'', $localFile, $remoteFilename));
135
136
        if (!ftp_put($this->ftpConnection, $remoteFilename, $localFile, FTP_BINARY)) {
137
            $error   = error_get_last();
138
            $message = $error['message'];
139
            throw new Exception(sprintf('error uploading file: %s - %s', $localFile, $message));
140
        }
141
142
        error_reporting($old);
143
144
        $this->cleanup($target, $result);
145
    }
146
147
    /**
148
     * Creates collector for FTP
149
     *
150
     * @param \phpbu\App\Backup\Target $target
151
     * @return \phpbu\App\Backup\Collector
152
     */
153
    protected function createCollector(Target $target): Collector
154
    {
155
        return new \phpbu\App\Backup\Collector\Ftp($target, $this->ftpConnection);
156
    }
157
}
158