1
|
|
|
<?php |
2
|
|
|
namespace CfdiUtils\CadenaOrigen; |
3
|
|
|
|
4
|
|
|
use CfdiUtils\Utils\Internal\ShellExec; |
5
|
|
|
use CfdiUtils\Utils\Internal\TemporaryFile; |
6
|
|
|
|
7
|
|
|
class SaxonbCliBuilder extends AbstractXsltBuilder |
8
|
|
|
{ |
9
|
|
|
/** @var string */ |
10
|
|
|
private $executablePath; |
11
|
|
|
|
12
|
12 |
|
public function __construct(string $executablePath) |
13
|
|
|
{ |
14
|
12 |
|
$this->setExecutablePath($executablePath); |
15
|
11 |
|
} |
16
|
|
|
|
17
|
9 |
|
public function getExecutablePath(): string |
18
|
|
|
{ |
19
|
9 |
|
return $this->executablePath; |
20
|
|
|
} |
21
|
|
|
|
22
|
12 |
|
public function setExecutablePath(string $executablePath) |
23
|
|
|
{ |
24
|
12 |
|
if ('' === $executablePath) { |
25
|
1 |
|
throw new \UnexpectedValueException('The executable path for SabonB cannot be empty'); |
26
|
|
|
} |
27
|
11 |
|
$this->executablePath = $executablePath; |
28
|
11 |
|
} |
29
|
|
|
|
30
|
|
|
/** |
31
|
|
|
* SECURITY: This method does not work as expected on non POSIX system (as MS Windows) |
32
|
|
|
* It was never intented to be public. It is not used by this class and will be removed on 3.0.0 |
33
|
|
|
* |
34
|
|
|
* @param string $xmlFile |
35
|
|
|
* @param string $xsltLocation |
36
|
|
|
* @return string |
37
|
|
|
* @deprecated 2.9.0 Will be removed with no replacement, never intented to be public |
38
|
|
|
*/ |
39
|
|
|
public function createCommand(string $xmlFile, string $xsltLocation): string |
40
|
|
|
{ |
41
|
|
|
// if is running on windows then use NUL instead of /dev/null |
42
|
|
|
return [ |
|
|
|
|
43
|
|
|
$this->getExecutablePath(), |
44
|
|
|
'-s:' . $xmlFile, |
45
|
|
|
'-xsl:' . $xsltLocation, |
46
|
|
|
'-warnings:silent', // default recover |
47
|
|
|
]; |
48
|
|
|
} |
49
|
|
|
|
50
|
11 |
|
public function build(string $xmlContent, string $xsltLocation): string |
51
|
|
|
{ |
52
|
11 |
|
$this->assertBuildArguments($xmlContent, $xsltLocation); |
53
|
|
|
|
54
|
9 |
|
$executable = $this->getExecutablePath(); |
55
|
9 |
|
if (! file_exists($executable)) { |
56
|
1 |
|
throw new XsltBuildException('The executable path for SabonB does not exists'); |
57
|
|
|
} |
58
|
8 |
|
if (is_dir($executable)) { |
59
|
1 |
|
throw new XsltBuildException('The executable path for SabonB is a directory'); |
60
|
|
|
} |
61
|
7 |
|
if (! is_executable($executable)) { |
62
|
1 |
|
throw new XsltBuildException('The executable path for SabonB is not executable'); |
63
|
|
|
} |
64
|
|
|
|
65
|
6 |
|
$temporaryFile = TemporaryFile::create(); |
66
|
6 |
|
return $temporaryFile->runAndRemove( |
67
|
|
|
function () use ($temporaryFile, $xmlContent, $xsltLocation) { |
68
|
6 |
|
$temporaryFile->storeContents($xmlContent); |
69
|
|
|
|
70
|
|
|
$command = [ |
71
|
6 |
|
$this->getExecutablePath(), |
72
|
6 |
|
'-s:' . $temporaryFile->getPath(), |
73
|
6 |
|
'-xsl:' . $xsltLocation, |
74
|
6 |
|
'-warnings:silent', // default recover |
75
|
|
|
]; |
76
|
|
|
|
77
|
6 |
|
$execution = (new ShellExec($command))->run(); |
78
|
|
|
|
79
|
6 |
|
if (0 !== $execution->exitStatus()) { |
80
|
3 |
|
throw new XsltBuildException('Transformation error'); |
81
|
|
|
} |
82
|
3 |
|
$output = trim($execution->output()); |
83
|
3 |
|
if ('<?xml version="1.0" encoding="UTF-8"?>' === $output) { |
84
|
1 |
|
throw new XsltBuildException('Transformation error'); |
85
|
|
|
} |
86
|
2 |
|
return $output; |
87
|
6 |
|
} |
88
|
|
|
); |
89
|
|
|
} |
90
|
|
|
} |
91
|
|
|
|