Passed
Push — master ( d96a4c...76b07c )
by Carlos C
05:39
created

XlsToXlsxConverter::convert()   B

Complexity

Conditions 7
Paths 5

Size

Total Lines 39
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 21
CRAP Score 7.3484

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 25
c 1
b 0
f 0
dl 0
loc 39
ccs 21
cts 26
cp 0.8077
rs 8.5866
cc 7
nc 5
nop 2
crap 7.3484
1
<?php
2
3
declare(strict_types=1);
4
5
namespace PhpCfdi\SatCatalogosPopulate\Converters;
6
7
use LogicException;
8
use PhpCfdi\SatCatalogosPopulate\Utils\ShellExec;
9
use function PhpCfdi\SatCatalogosPopulate\Utils\tempdir;
10
use PhpCfdi\SatCatalogosPopulate\Utils\WhichTrait;
11
use RuntimeException;
12
13
class XlsToXlsxConverter
14
{
15 1
    use WhichTrait;
16
17
    /** @var string Location of soffice executable */
18
    private $sofficePath;
19
20 3
    public function __construct(string $sofficePath = '')
21
    {
22 3
        if ('' === $sofficePath) {
23 3
            $sofficePath = $this->which('soffice');
24
        }
25 3
        $this->sofficePath = $sofficePath;
26 3
    }
27
28 3
    public function sofficePath(): string
29
    {
30 3
        return $this->sofficePath;
31
    }
32
33 3
    public function convert(string $source, string $destination): void
34
    {
35 3
        if (! file_exists($source) || is_dir($source) || ! is_readable($source)) {
36
            throw new RuntimeException("File $source does not exists");
37
        }
38
39 3
        $destinationDir = dirname($destination);
40 3
        $this->checkDirectory($destinationDir);
41
42 3
        $tempdir = tempdir();
43 3
        $this->checkDirectory($tempdir);
44 3
        $outfile = $tempdir . DIRECTORY_SEPARATOR . basename($source) . 'x';
45 3
        if (file_exists($outfile)) {
46
            throw new RuntimeException("File $destination must not exists");
47
        }
48
49 3
        $command = escapeshellarg($this->sofficePath()) . ' ' . implode(' ', array_map('escapeshellarg', [
50 3
            '--headless',
51 3
            '--nolockcheck',
52 3
            '--convert-to',
53 3
            'xlsx',
54 3
            '--outdir',
55 3
            $tempdir,
56 3
            $source,
57
        ]));
58
59 3
        $execution = ShellExec::run($command);
60 3
        if (0 !== $execution->exitStatus()) {
61
            throw new RuntimeException(
62
                "Execution of soffice convertion return a non zero status code [{$execution->exitStatus()}]"
63
            );
64
        }
65
66 3
        if (! file_exists($outfile)) {
67
            throw new RuntimeException("File $outfile was not created, are other soffice instances running?");
68
        }
69
70 3
        rename($outfile, $destination);
71 3
        rmdir($tempdir);
72 3
    }
73
74 3
    private function checkDirectory(string $directory): void
75
    {
76 3
        if ('' === $directory) {
77
            throw new LogicException('Directory path is empty');
78
        }
79 3
        if (! is_dir($directory)) {
80
            throw new RuntimeException("Path $directory is not a directory");
81
        }
82 3
        if (! is_writable($directory)) {
83
            throw new RuntimeException("Path $directory is not writable");
84
        }
85 3
    }
86
}
87