Completed
Push — master ( cac190...51e389 )
by WEBEWEB
01:21
created

OcrProvider::getLogger()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
/*
4
 * This file is part of the core-library package.
5
 *
6
 * (c) 2020 WEBEWEB
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace WBW\Library\Core\ThirdParty\OcrLad\Provider;
13
14
use Closure;
15
use Psr\Log\LoggerInterface;
16
use WBW\Library\Core\Model\Attribute\StringHostnameTrait;
17
use WBW\Library\Core\Model\Attribute\StringPasswordTrait;
18
use WBW\Library\Core\Model\Attribute\StringUsernameTrait;
19
use WBW\Library\Core\Network\FTP\Client\FtpClient;
20
use WBW\Library\Core\Network\FTP\Exception\FtpException;
21
use WBW\Library\Core\Provider\AbstractProvider;
22
use WBW\Library\Core\Security\Authenticator;
23
use WBW\Library\Core\Security\PasswordAuthentication;
24
use WBW\Library\Core\ThirdParty\OcrLad\Model\IOFile;
25
26
/**
27
 * OCR provider.
28
 *
29
 * @author webeweb <https://github.com/webeweb>
30
 * @package WBW\Library\Core\ThirdParty\OcrLad\Provider
31
 */
32
class OcrProvider extends AbstractProvider {
33
34
    use StringHostnameTrait;
35
    use StringPasswordTrait;
36
    use StringUsernameTrait;
37
38
    /**
39
     * FTP client.
40
     *
41
     * @var FtpClient
42
     */
43
    private $ftpClient;
44
45
    /**
46
     * Local directory "after".
47
     *
48
     * @var string
49
     */
50
    private $localDirectoryAfter;
51
52
    /**
53
     * Local directory "before".
54
     *
55
     * @var string
56
     */
57
    private $localDirectoryBefore;
58
59
    /**
60
     * Local directory "error".
61
     *
62
     * @var string
63
     */
64
    private $localDirectoryError;
65
66
    /**
67
     * Remote directory "after".
68
     *
69
     * @var string
70
     */
71
    private $remoteDirectoryAfter;
72
73
    /**
74
     * Remote directory "before".
75
     *
76
     * @var string
77
     */
78
    private $remoteDirectoryBefore;
79
80
    /**
81
     * Remote directory "error".
82
     *
83
     * @var string
84
     */
85
    private $remoteDirectoryError;
86
87
    /**
88
     * Constructor.
89
     *
90
     * @param LoggerInterface $logger The logger.
91
     */
92
    public function __construct(LoggerInterface $logger) {
93
        parent::__construct($logger);
94
        $this->setRemoteDirectoryAfter("/Apres");
95
        $this->setRemoteDirectoryBefore("/Avant");
96
        $this->setRemoteDirectoryError("/Erreur");
97
    }
98
99
    /**
100
     * Destructor.
101
     *
102
     * @throws FtpException Throws a FTP exception if an error occurs.
103
     */
104
    public function __destruct() {
105
106
        if (null !== $this->ftpClient) {
107
108
            $this->getLogger()->info("OCR provider closes the FTP connection", ["_hostname" => $this->getHostname()]);
109
            $this->ftpClient->close();
110
            $this->ftpClient = null;
111
        }
112
    }
113
114
    /**
115
     * Build the file paths.
116
     *
117
     * @param IOFile $file The file.
118
     * @return array Returns the file paths.
119
     */
120
    protected function buildFilePaths(IOFile $file) {
121
        return [
122
            "upload" => implode("/", [$this->getRemoteDirectoryBefore(), $file->getUniqFilenamePdf()]),
123
            "remote" => [
124
                implode("/", [$this->getRemoteDirectoryAfter(), $file->getUniqFilenameDer()]),
125
                implode("/", [$this->getRemoteDirectoryAfter(), $file->getUniqFilenamePdf()]),
126
                implode("/", [$this->getRemoteDirectoryAfter(), $file->getUniqFilenameXml()]),
127
                implode("/", [$this->getRemoteDirectoryAfter(), $file->getUniqFilenameTif()]),
128
            ],
129
            "local"  => [
130
                implode("/", [$this->getLocalDirectoryAfter(), $file->getUniqFilenameDer()]),
131
                implode("/", [$this->getLocalDirectoryAfter(), $file->getUniqFilenamePdf()]),
132
                implode("/", [$this->getLocalDirectoryAfter(), $file->getUniqFilenameXml()]),
133
                implode("/", [$this->getLocalDirectoryAfter(), $file->getUniqFilenameTif()]),
134
            ],
135
        ];
136
    }
137
138
    /**
139
     * Delete the files.
140
     *
141
     * @param IOFile $file The I/O file.
142
     * @return void
143
     * @throws FtpException Throws an FTP exception if an error occurs.
144
     */
145
    public function deleteFiles(IOFile $file) {
146
147
        $provider = $this;
148
149
        /**
150
         * Delete the remote files.
151
         *
152
         * @param string $directory The directory.
153
         * @return void
154
         * @var Closure
155
         */
156
        $deleteClosure = function($directory) use ($provider, $file) {
157
158
            $paths = $provider->buildFilePaths($file);
159
160
            $provider->getLogger()->info("OCR provider list files in a given directory", ["_directory" => $directory]);
161
            $files = $provider->getFtpClient()->nlist($directory);
162
            foreach ($files as $current) {
163
164
                if (false === in_array($current, $paths["remote"])) {
165
                    continue;
166
                }
167
168
                $provider->getLogger()->info("OCR provider deletes a file on the FTP server", ["_remote" => $current]);
169
                $provider->getFtpClient()->delete($current);
170
            }
171
        };
172
173
        $deleteClosure($this->getRemoteDirectoryBefore());
174
        $deleteClosure($this->getRemoteDirectoryAfter());
175
        //$deleteClosure($this->getRemoteDirectoryError());
176
    }
177
178
    /**
179
     * Download the files.
180
     *
181
     * @param IOFile $file The I/O file.
182
     * @return bool Returns true in case of success, false otherwise.
183
     * @throws FtpException Throws an FTP exception if an error occurs.
184
     */
185
    public function downloadFiles(IOFile $file) {
186
187
        $paths = $this->buildFilePaths($file);
188
189
        $files = $this->getFtpClient()->nlist($this->getRemoteDirectoryAfter());
190
        if (false === in_array($paths["remote"][0], $files)) {
191
            return false;
192
        }
193
194
        $provider = $this;
195
196
        /**
197
         * Download a remote file.
198
         *
199
         * @param string $local The local file.
200
         * @param string $remote The remote file.
201
         * @return void
202
         * @var Closure
203
         */
204
        $downloadClosure = function($local, $remote) use ($provider) {
205
            $provider->getLogger()->info("OCR provider downloads a file  from the FTP server", ["_local" => $local, "_remote" => $remote]);
206
            $provider->getFtpClient()->get($local, $remote);
207
        };
208
209
        $downloadClosure($paths["local"][0], $paths["remote"][0]);
210
        $downloadClosure($paths["local"][1], $paths["remote"][1]);
211
        $downloadClosure($paths["local"][2], $paths["remote"][2]);
212
        $downloadClosure($paths["local"][3], $paths["remote"][3]);
213
214
        return true;
215
    }
216
217
    /**
218
     * Get the FTP client.
219
     *
220
     * @return FtpClient Returns the FTP client.
221
     * @throws FtpException Throws an FTP exception if an error occurs.
222
     */
223
    public function getFtpClient() {
224
225
        if (null === $this->ftpClient) {
226
227
            $authentication = new PasswordAuthentication($this->getUsername(), $this->getPassword());
228
            $authenticator  = new Authenticator($this->getHostname(), $authentication);
229
230
            $this->ftpClient = new FtpClient($authenticator);
231
232
            $this->getLogger()->info("OCR provider opens an FTP connection to FTP", ["_hostname" => $this->getHostname()]);
233
            $this->ftpClient->connect();
234
235
            $this->getLogger()->info("OCR provider logs in to the FTP connection", ["_username" => $this->getUsername()]);
236
            $this->ftpClient->login();
237
238
            $this->getLogger()->info("OCR provider turns passive mode on");
239
            $this->ftpClient->pasv(true);
240
        }
241
242
        return $this->ftpClient;
243
    }
244
245
    /**
246
     * Get the local directory "after".
247
     *
248
     * @return string Returns the local directory "after".
249
     */
250
    public function getLocalDirectoryAfter() {
251
        return $this->localDirectoryAfter;
252
    }
253
254
    /**
255
     * Get the local directory "before".
256
     *
257
     * @return string Returns the local directory "before"
258
     */
259
    public function getLocalDirectoryBefore() {
260
        return $this->localDirectoryBefore;
261
    }
262
263
    /**
264
     * Get the local directory "error".
265
     *
266
     * @return string Returns the local directory "error".
267
     */
268
    public function getLocalDirectoryError() {
269
        return $this->localDirectoryError;
270
    }
271
272
    /**
273
     * Ge the remote directory "after".
274
     *
275
     * @return string Returns the remote directory "after".
276
     */
277
    public function getRemoteDirectoryAfter() {
278
        return $this->remoteDirectoryAfter;
279
    }
280
281
    /**
282
     * Get the remote directory "before".
283
     *
284
     * @return string Returns the remote directory "before".
285
     */
286
    public function getRemoteDirectoryBefore() {
287
        return $this->remoteDirectoryBefore;
288
    }
289
290
    /**
291
     * Get the remote directory "error".
292
     *
293
     * @return string Returns the remote directory "error".
294
     */
295
    public function getRemoteDirectoryError() {
296
        return $this->remoteDirectoryError;
297
    }
298
299
    /**
300
     * Scan a file.
301
     *
302
     * @param IOFile $file The I/O file.
303
     * @param int $retry The retry count.
304
     * @param int $wait The waiting time (in seconds) between retries.
305
     * @return bool Returns true in case of success, false otherwise.
306
     * @throws FtpException Throws an FTP exception in case of success, false otherwise.
307
     */
308
    public function scanFile(IOFile $file, $retry = 30, $wait = 5) {
309
310
        $paths = $this->buildFilePaths($file);
311
312
        $this->uploadFile($file);
313
314
        $result = false;
315
316
        for ($i = 0; $i < $retry; ++$i) {
317
318
            if (true === $this->downloadFiles($file)) {
319
                $result = true;
320
                break;
321
            }
322
323
            $this->getLogger()->info("OCR provider is waiting for...", ["_remote" => $paths["remote"][0]]);
324
            sleep($wait);
325
        }
326
327
        if (false === $result) {
328
            $this->getLogger()->info("OCR provider fail to download a file from the FTP server", ["_local" => $paths["local"][0], "_remote" => $paths["remote"][0]]);
329
            $this->getLogger()->info("OCR provider fail to download a file from the FTP server", ["_local" => $paths["local"][1], "_remote" => $paths["remote"][1]]);
330
            $this->getLogger()->info("OCR provider fail to download a file from the FTP server", ["_local" => $paths["local"][2], "_remote" => $paths["remote"][2]]);
331
        }
332
333
        return $result;
334
    }
335
336
    /**
337
     * Set the local directory "after".
338
     *
339
     * @param string $localDirectoryAfter The local directory "after".
340
     * @return OcrProvider Returns this OCR provider.
341
     */
342
    public function setLocalDirectoryAfter($localDirectoryAfter) {
343
        $this->localDirectoryAfter = $localDirectoryAfter;
344
        return $this;
345
    }
346
347
    /**
348
     * Set the local directory "before".
349
     *
350
     * @param string $localDirectoryBefore The local directory "before"
351
     * @return OcrProvider Returns this OCR provider.
352
     */
353
    public function setLocalDirectoryBefore($localDirectoryBefore) {
354
        $this->localDirectoryBefore = $localDirectoryBefore;
355
        return $this;
356
    }
357
358
    /**
359
     * Set the local directory "error".
360
     *
361
     * @param string $localDirectoryError The local directory "error".
362
     * @return OcrProvider Returns this OCR provider.
363
     */
364
    public function setLocalDirectoryError($localDirectoryError) {
365
        $this->localDirectoryError = $localDirectoryError;
366
        return $this;
367
    }
368
369
    /**
370
     * Set the remote directory "after".
371
     *
372
     * @param string $remoteDirectoryAfter The remote directory "after".
373
     * @return OcrProvider Returns this OCR provider.
374
     */
375
    public function setRemoteDirectoryAfter($remoteDirectoryAfter) {
376
        $this->remoteDirectoryAfter = $remoteDirectoryAfter;
377
        return $this;
378
    }
379
380
    /**
381
     * Set the remote directory "before".
382
     *
383
     * @param string $remoteDirectoryBefore The remote directory "before".
384
     * @return OcrProvider Returns this OCR provider.
385
     */
386
    public function setRemoteDirectoryBefore($remoteDirectoryBefore) {
387
        $this->remoteDirectoryBefore = $remoteDirectoryBefore;
388
        return $this;
389
    }
390
391
    /**
392
     * Set the remote directory "error".
393
     *
394
     * @param string $remoteDirectoryError The remote directory "error".
395
     * @return OcrProvider Returns this OCR provider.
396
     */
397
    public function setRemoteDirectoryError($remoteDirectoryError) {
398
        $this->remoteDirectoryError = $remoteDirectoryError;
399
        return $this;
400
    }
401
402
    /**
403
     * Upload a file.
404
     *
405
     * @param IOFile $file The I/O file.
406
     * @return void
407
     * @throws FtpException Throws an FTP exception if an error occurs.
408
     */
409
    public function uploadFile(IOFile $file) {
410
411
        $paths = $this->buildFilePaths($file);
412
413
        $this->getLogger()->info("OCR provider upload a file to the FTP server", ["_local" => $file->getPathname(), "_remote" => $paths["upload"]]);
414
        $this->getFtpClient()->put($file->getPathname(), $paths["upload"]);
415
    }
416
}