Completed
Push — @debug ( b8003a...96cfc2 )
by Maarten
49:23
created

FtpService::scan()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 18
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 3

Importance

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