ConvertScript::executionIsFromPhar()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace PhpCfdi\CfdiToPdf\Script;
6
7
use CfdiUtils\Nodes\XmlNodeUtils;
8
use CfdiUtils\XmlResolver\XmlResolver;
9
use DirectoryIterator;
10
use Generator;
11
use LogicException;
12
use PhpCfdi\CfdiCleaner\Cleaner;
13
use PhpCfdi\CfdiToPdf\Builders\Html2PdfBuilder;
14
use PhpCfdi\CfdiToPdf\CfdiDataBuilder;
15
use PhpCfdi\CfdiToPdf\Converter;
16
use RuntimeException;
17
use SplFileInfo;
18
19
class ConvertScript
20
{
21
    /**
22
     * @param ConvertOptions $options
23
     * @return void
24
     */
25 1
    public function run(ConvertOptions $options): void
26
    {
27 1
        $source = $this->openSource($options->inputFile(), $options->doCleanInput());
28
29 1
        $comprobante = XmlNodeUtils::nodeFromXmlString($source);
30 1
        $cfdiData = $this->createCfdiDataBuilder()
31 1
            ->withXmlResolver($this->createXmlResolver($options->resolverLocation()))
32 1
            ->build($comprobante);
33
34 1
        $converter = $this->defaultConverter();
35
36 1
        $fontsDirectory = $options->fontsDirectory();
37 1
        $removeFontsDirectory = false;
38 1
        if ($this->executionIsFromPhar() && '' === $fontsDirectory) {
39
            $fontsDirectory = $this->extractFontsToTemporaryFolder();
40
            $removeFontsDirectory = true;
41
        }
42 1
        if ('' !== $fontsDirectory) {
43
            $fontsDirectory = rtrim($fontsDirectory, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
44
            if (! define('K_PATH_FONTS', $fontsDirectory)) {
45
                throw new LogicException("Unable to define K_PATH_FONTS as $fontsDirectory");
46
            }
47
        }
48
49 1
        $converter->createPdfAs($cfdiData, $options->outputFile());
50
51 1
        if ($removeFontsDirectory) {
52
            $this->recursiveRemove($fontsDirectory);
53
        }
54
    }
55
56 6
    public function openSource(string $inputfile, bool $doCleanInput): string
57
    {
58 6
        if ('' === $inputfile) {
59 1
            throw new RuntimeException('Did not provide an input file');
60
        }
61 5
        $filename = (string) realpath($inputfile);
62 5
        if ('' === $filename) {
63 1
            throw new RuntimeException("The file $inputfile does not exists");
64
        }
65 4
        if (! is_file($filename)) {
66 1
            throw new RuntimeException("The path $inputfile is not a file");
67
        }
68
69
        /** @noinspection PhpUsageOfSilenceOperatorInspection */
70 3
        $source = strval(@file_get_contents($filename));
71 3
        if ('' === $source) {
72 1
            throw new RuntimeException("The file $inputfile is empty");
73
        }
74 2
        if ($doCleanInput) {
75 2
            $source = $this->cleanSource($source);
76
        }
77
78 2
        return $source;
79
    }
80
81 1
    public function cleanSource(string $source): string
82
    {
83 1
        return Cleaner::staticClean($source);
84
    }
85
86 1
    public function createXmlResolver(string $resolverLocation): XmlResolver
87
    {
88 1
        return new XmlResolver($resolverLocation);
89
    }
90
91 1
    public function createCfdiDataBuilder(): CfdiDataBuilder
92
    {
93 1
        return new CfdiDataBuilder();
94
    }
95
96 1
    public function defaultConverter(): Converter
97
    {
98 1
        return new Converter(new Html2PdfBuilder());
99
    }
100
101 1
    private function executionIsFromPhar(): bool
102
    {
103 1
        return 'phar://' === substr(__FILE__, 0, 7);
104
    }
105
106
    private function extractFontsToTemporaryFolder(): string
107
    {
108
        $source = __DIR__ . '/../../vendor/tecnickcom/tcpdf/fonts';
109
        $temporaryFolder = tempnam('', '');
110
        if (false === $temporaryFolder) {
111
            throw new RuntimeException('Unable to create a temporary name');
112
        }
113
        unlink($temporaryFolder);
114
        $this->recursiveCopy($source, $temporaryFolder);
115
        return $temporaryFolder;
116
    }
117
118
    private function recursiveCopy(string $sourceDirectory, string $destinationDirectory): void
119
    {
120
        mkdir($destinationDirectory);
121
        /** @var SplFileInfo $origin */
122
        foreach ($this->readDirectory($sourceDirectory) as $origin) {
123
            $destination = $destinationDirectory . DIRECTORY_SEPARATOR . $origin->getBasename();
124
            if ($origin->isFile()) {
125
                copy($origin->getPathname(), $destination);
126
            }
127
            if ($origin->isDir()) {
128
                $this->recursiveCopy($origin->getPathname(), $destination);
129
            }
130
        }
131
    }
132
133
    private function recursiveRemove(string $directory): void
134
    {
135
        /** @var SplFileInfo $current */
136
        foreach ($this->readDirectory($directory) as $current) {
137
            if ($current->isFile()) {
138
                unlink($current->getPathname());
139
            }
140
            if ($current->isDir()) {
141
                $this->recursiveRemove($current->getPathname());
142
            }
143
        }
144
        rmdir($directory);
145
    }
146
147
    /**
148
     * @param string $directory
149
     * @return Generator
150
     */
151
    private function readDirectory(string $directory): Generator
152
    {
153
        $directoryIterator = new DirectoryIterator($directory);
154
        foreach ($directoryIterator as $splFileInfo) {
155
            if ($splFileInfo->isDot()) {
156
                continue;
157
            }
158
159
            yield $splFileInfo;
160
        }
161
    }
162
}
163