Passed
Push — master ( b97c32...e7e450 )
by Carlos C
10:36 queued 12s
created

XlsToXlsxConverter   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 71
Duplicated Lines 0 %

Test Coverage

Coverage 75%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 37
c 1
b 0
f 0
dl 0
loc 71
ccs 24
cts 32
cp 0.75
rs 10
wmc 14

4 Methods

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