FtpService   A
last analyzed

Complexity

Total Complexity 23

Size/Duplication

Total Lines 257
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 23
lcom 1
cbo 3
dl 0
loc 257
ccs 90
cts 90
cp 1
rs 10
c 0
b 0
f 0

13 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A send() 0 19 2
A scan() 0 18 3
A receive() 0 20 2
A processed() 0 21 2
A getConnection() 0 7 2
A connect() 0 22 3
A setConfig() 0 9 3
A getHostname() 0 4 1
A getPort() 0 4 1
A getTimeout() 0 4 1
A getUsername() 0 4 1
A getPassword() 0 4 1
1
<?php
2
/**
3
 * This file is part of the Amplexor\XConnect library
4
 *
5
 * @license http://opensource.org/licenses/MIT
6
 * @link https://github.com/amplexor-drupal/xconnect/
7
 * @version 1.0.0
8
 * @package Amplexor.XConnect
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Amplexor\XConnect\Service;
15
16
use Amplexor\XConnect\Request\File\FileInterface;
17
18
/**
19
 * FTP Service.
20
 */
21
class FtpService extends ServiceAbstract
22
{
23
    /**
24
     * The FTP transfer mode.
25
     *
26
     * We set this value = 2, thats the same as the FTP_BINARY constant.
27
     *
28
     * @var int
29
     */
30
    const TRANSFER_MODE = 2;
31
32
    /**
33
     * Service connection configuration.
34
     *
35
     * @var array
36
     */
37
    private $config = array(
38
        'hostname' => '',
39
        'port' => 21,
40
        'timeout' => 90,
41
        'username' => '',
42
        'password' => '',
43
    );
44
45
    /**
46
     * The FTP connection resource.
47
     *
48
     * @var resource
49
     */
50
    private $ftp;
51
52
    /**
53
     * Class constructor.
54
     *
55
     * Create a new service by passing the configuration:
56
     * - hostname : The hostname of the FTP service.
57
     * - port : The FRP port.
58
     * - username : The username to connect to the FTP service.
59
     * - password : The password to connect to the FTP service.
60
     *
61
     * Optional configuration:
62
     * - directory_send : The remote directory to store the request file in.
63
     * - directory_send_processed : The remote directory where the processed
64
     *   request files are stored.
65
     * - directory_receive : The remote directory where the translated files are
66
     *   stored to be picked up.
67
     * - directory_receive_processed : The repome directory where to put the
68
     *   translation files that are successfully processed by the local system.
69
     *
70
     * @param array $config
71
     */
72 81
    public function __construct(array $config)
73
    {
74 81
        parent::__construct($config);
75 81
        $this->setConfig($config);
76 81
    }
77
78
    /**
79
     * @inheritDoc
80
     */
81 18
    public function send(FileInterface $file)
82
    {
83 18
        $connection = $this->getConnection();
84 12
        $from = $file->getPath();
85 12
        $to = $this->getDirectorySend() . '/' . $file->getFileName();
86 12
        $result = ftp_put($connection, $to, $from, self::TRANSFER_MODE);
87
88 12
        if (!$result) {
89 3
            throw new ServiceException(
90 3
                sprintf(
91 3
                    'File "%s" could not be uploaded to "%s".',
92 3
                    $from,
93
                    $to
94 3
                )
95 3
            );
96
        }
97
98 9
        return $result;
99
    }
100
101
    /**
102
     * @inheritDoc
103
     */
104 6
    public function scan()
105
    {
106 6
        $connection = $this->getConnection();
107 6
        $directory = $this->getDirectoryReceive();
108
109
        // Get the full file list.
110 6
        $files = ftp_nlist($connection, $directory);
111
112
        // We only want files, no directories.
113 6
        foreach ($files as $key => $file) {
114 6
            if (ftp_size($connection, $directory . '/' . $file) < 0) {
115 6
                unset($files[$key]);
116 6
                continue;
117
            }
118 6
        }
119
120 6
        return array_values($files);
121
    }
122
123
    /**
124
     * @inheritDoc
125
     */
126 9
    public function receive($fileName, $directory)
127
    {
128 9
        $connection = $this->getConnection();
129 9
        $to = $directory . '/' . $fileName;
130 9
        $from = $this->getDirectoryReceive() . '/' . $fileName;
131
132 9
        $result = ftp_get($connection, $to, $from, self::TRANSFER_MODE);
133
134 9
        if (!$result) {
135 3
            throw new ServiceException(
136 3
                sprintf(
137 3
                    'File "%s" could not be downloaded to "%s".',
138 3
                    $from,
139
                    $to
140 3
                )
141 3
            );
142
        }
143
144 6
        return $to;
145
    }
146
147
    /**
148
     * @inheritDoc
149
     */
150 9
    public function processed($fileName)
151
    {
152 9
        $connection = $this->getConnection();
153
154 9
        $from = $this->getDirectoryReceive() . '/' . $fileName;
155 9
        $to = $this->getDirectoryReceiveProcessed() . '/' . $fileName;
156
157 9
        $result = ftp_rename($connection, $from, $to);
158
159 9
        if (!$result) {
160 3
            throw new ServiceException(
161 3
                sprintf(
162 3
                    'File "%s" could not be moved to "%s".',
163 3
                    $from,
164
                    $to
165 3
                )
166 3
            );
167
        }
168
169 6
        return $result;
170
    }
171
172
    /**
173
     * Get the connection.
174
     *
175
     * @return resource
176
     *   A FTP connection resource.
177
     */
178 42
    protected function getConnection()
179
    {
180 42
        if (!$this->ftp) {
181 42
            $this->connect();
182 36
        }
183 36
        return $this->ftp;
184
    }
185
186
    /**
187
     * Connect to the FTP server.
188
     */
189 42
    protected function connect()
190
    {
191 42
        $connection = ftp_connect($this->getHostname(), $this->getPort(), $this->getTimeout());
192 42
        if (!$connection) {
193 3
            throw new ServiceException(
194 3
                sprintf('Can\'t connect to host "%s"', $this->getHostname())
195 3
            );
196
        }
197
198
        // Login to host.
199 39
        $result = ftp_login($connection, $this->getUsername(), $this->getPassword());
200 39
        if (!$result) {
201 3
            throw new ServiceException(
202 3
                sprintf('Can\'t login with user "%s"', $this->getUsername())
203 3
            );
204
        }
205
206
        // Set connection to passive mode.
207 36
        ftp_pasv($connection, true);
208
209 36
        $this->ftp = $connection;
210 36
    }
211
212
213
    /**
214
     * Write the config to the config array.
215
     *
216
     * @param array $config
217
     */
218 81
    protected function setConfig(array $config)
219
    {
220 81
        $keyNames = array_keys($this->config);
221 81
        foreach ($keyNames as $key) {
222 81
            if (array_key_exists($key, $config)) {
223 48
                $this->config[$key] = $config[$key];
224 48
            }
225 81
        }
226 81
    }
227
228
    /**
229
     * Get the hostname from the config.
230
     *
231
     * @return string
232
     */
233 42
    protected function getHostname()
234
    {
235 42
        return $this->config['hostname'];
236
    }
237
238
    /**
239
     * Get the portnumber from the config.
240
     *
241
     * @return int
242
     */
243 42
    protected function getPort()
244
    {
245 42
        return (int) $this->config['port'];
246
    }
247
248
    /**
249
     * Get the timeout from the config.
250
     *
251
     * @return int
252
     */
253 42
    protected function getTimeout()
254
    {
255 42
        return (int) $this->config['timeout'];
256
    }
257
258
    /**
259
     * Get the username.
260
     *
261
     * @return string
262
     */
263 78
    protected function getUsername()
264
    {
265 78
        return $this->config['username'];
266
    }
267
268
    /**
269
     * Get the password.
270
     *
271
     * @return string
272
     */
273 78
    protected function getPassword()
274
    {
275 78
        return $this->config['password'];
276
    }
277
}
278