Completed
Pull Request — develop (#3)
by Maarten
19:16 queued 15:24
created

FtpService   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 246
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 100%

Importance

Changes 7
Bugs 1 Features 3
Metric Value
wmc 22
c 7
b 1
f 3
lcom 1
cbo 3
dl 0
loc 246
ccs 88
cts 88
cp 1
rs 10

12 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 getPassword() 0 4 1
A getUsername() 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
        'username' => '',
41
        'password' => '',
42
    );
43
44
    /**
45
     * The FTP connection resource.
46
     *
47
     * @var resource
48
     */
49
    private $ftp;
50
51
    /**
52
     * Class constructor.
53
     *
54
     * Create a new service by passing the configuration:
55
     * - hostname : The hostname of the FTP service.
56
     * - port : The FRP port.
57
     * - username : The username to connect to the FTP service.
58
     * - password : The password to connect to the FTP service.
59
     *
60
     * Optional configuration:
61
     * - directory_send : The remote directory to store the request file in.
62
     * - directory_send_processed : The remote directory where the processed
63
     *   request files are stored.
64
     * - directory_receive : The remote directory where the translated files are
65
     *   stored to be picked up.
66
     * - directory_receive_processed : The repome directory where to put the
67
     *   translation files that are successfully processed by the local system.
68
     *
69
     * @param array $config
70
     */
71 81
    public function __construct(array $config)
72
    {
73 81
        parent::__construct($config);
74 81
        $this->setConfig($config);
75 81
    }
76
77
    /**
78
     * @inheritDoc
79
     */
80 18
    public function send(FileInterface $file)
81
    {
82 18
        $connection = $this->getConnection();
83 12
        $from = $file->getPath();
84 12
        $to = $this->getDirectorySend() . '/' . $file->getFileName();
85 12
        $result = ftp_put($connection, $to, $from, self::TRANSFER_MODE);
86
87 12
        if (!$result) {
88 3
            throw new ServiceException(
89 3
                sprintf(
90 3
                    'File "%s" could not be uploaded to "%s".',
91 3
                    $from,
92
                    $to
93 3
                )
94 3
            );
95
        }
96
97 9
        return $result;
98
    }
99
100
    /**
101
     * @inheritDoc
102
     */
103 6
    public function scan()
104
    {
105 6
        $connection = $this->getConnection();
106 6
        $directory = $this->getDirectoryReceive();
107
108
        // Get the full file list.
109 6
        $files = ftp_nlist($connection, $directory);
110
111
        // We only want files, no directories.
112 6
        foreach ($files as $key => $file) {
113 6
            if (ftp_size($connection, $directory . '/' . $file) < 0) {
114 6
                unset($files[$key]);
115 6
                continue;
116
            }
117 6
        }
118
119 6
        return array_values($files);
120
    }
121
122
    /**
123
     * @inheritDoc
124
     */
125 9
    public function receive($fileName, $directory)
126
    {
127 9
        $connection = $this->getConnection();
128 9
        $to = $directory . '/' . $fileName;
129 9
        $from = $this->getDirectoryReceive() . '/' . $fileName;
130
131 9
        $result = ftp_get($connection, $to, $from, self::TRANSFER_MODE);
132
133 9
        if (!$result) {
134 3
            throw new ServiceException(
135 3
                sprintf(
136 3
                    'File "%s" could not be downloaded to "%s".',
137 3
                    $from,
138
                    $to
139 3
                )
140 3
            );
141
        }
142
143 6
        return $to;
144
    }
145
146
    /**
147
     * @inheritDoc
148
     */
149 9
    public function processed($fileName)
150
    {
151 9
        $connection = $this->getConnection();
152
153 9
        $from = $this->getDirectoryReceive() . '/' . $fileName;
154 9
        $to = $this->getDirectoryReceiveProcessed() . '/' . $fileName;
155
156 9
        $result = ftp_rename($connection, $from, $to);
157
158 9
        if (!$result) {
159 3
            throw new ServiceException(
160 3
                sprintf(
161 3
                    'File "%s" could not be moved to "%s".',
162 3
                    $from,
163
                    $to
164 3
                )
165 3
            );
166
        }
167
168 6
        return $result;
169
    }
170
171
    /**
172
     * Get the connection.
173
     *
174
     * @return resource
175
     *   A FTP connection resource.
176
     */
177 42
    protected function getConnection()
178
    {
179 42
        if (!$this->ftp) {
180 42
            $this->connect();
181 36
        }
182 36
        return $this->ftp;
183
    }
184
185
    /**
186
     * Connect to the FTP server.
187
     */
188 42
    protected function connect()
189
    {
190 42
        $connection = ftp_connect($this->getHostname(), $this->getPort());
191 42
        if (!$connection) {
192 3
            throw new ServiceException(
193 3
                sprintf('Can\'t connect to host "%s"', $this->getHostname())
194 3
            );
195
        }
196
197
        // Login to host.
198 39
        $result = ftp_login($connection, $this->getUsername(), $this->getPassword());
199 39
        if (!$result) {
200 3
            throw new ServiceException(
201 3
                sprintf('Can\'t login with user "%s"', $this->getUsername())
202 3
            );
203
        }
204
205
        // Set connection to passive mode.
206 36
        ftp_pasv($connection, true);
207
208 36
        $this->ftp = $connection;
209 36
    }
210
211
212
    /**
213
     * Write the config to the config array.
214
     *
215
     * @param array $config
216
     */
217 81
    protected function setConfig(array $config)
218
    {
219 81
        $keyNames = array_keys($this->config);
220 81
        foreach ($keyNames as $key) {
221 81
            if (array_key_exists($key, $config)) {
222 48
                $this->config[$key] = $config[$key];
223 48
            }
224 81
        }
225 81
    }
226
227
    /**
228
     * Get the hostname from the config.
229
     *
230
     * @return string
231
     */
232 42
    protected function getHostname()
233
    {
234 42
        return $this->config['hostname'];
235
    }
236
237
    /**
238
     * Get the portnumber from the config.
239
     *
240
     * @return int
241
     */
242 42
    protected function getPort()
243
    {
244 42
        return (int) $this->config['port'];
245
    }
246
247
    /**
248
     * Get the username.
249
     *
250
     * @return string
251
     */
252 78
    protected function getUsername()
253
    {
254 78
        return $this->config['username'];
255
    }
256
257
    /**
258
     * Get the password.
259
     *
260
     * @return string
261
     */
262 78
    protected function getPassword()
263
    {
264 78
        return $this->config['password'];
265
    }
266
}
267