Passed
Pull Request — master (#11)
by Marcin
04:29
created

Api::wsGetPdf()   B

Complexity

Conditions 7
Paths 11

Size

Total Lines 47
Code Lines 31

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 20
CRAP Score 9.5839

Importance

Changes 0
Metric Value
eloc 31
dl 0
loc 47
rs 8.4906
c 0
b 0
f 0
ccs 20
cts 32
cp 0.625
cc 7
nc 11
nop 2
crap 9.5839
1
<?php
2
/**
3
 * Created by Marcin.
4
 * Date: 03.03.2019
5
 * Time: 14:22
6
 */
7
8
namespace Mrcnpdlk\Api\Unoconv;
9
10
use mikehaertl\shellcommand\Command;
11
use Mrcnpdlk\Api\Unoconv\Enum\FormatType;
12
use Mrcnpdlk\Api\Unoconv\Exception\DomainException;
13
use Mrcnpdlk\Api\Unoconv\Exception\InvalidFileArgumentException;
14
use Mrcnpdlk\Api\Unoconv\Exception\UnoconvException;
15
use SplFileObject;
16
17
/**
18
 * Class Api
19
 */
20
class Api
21
{
22
    /**
23
     * @var array
24
     */
25
    private $params = [];
26
    /** @noinspection PhpUndefinedClassInspection */
27
    /**
28
     * @var \Psr\Log\LoggerInterface
29
     */
30
    private $logger;
31
    /**
32
     * @var string
33
     */
34
    private $ws;
35
36
    /**
37
     * Api constructor.
38
     *
39
     * @param \Mrcnpdlk\Api\Unoconv\Config $oConfig
40
     *
41
     * @throws \Mrcnpdlk\Api\Unoconv\Exception
42
     */
43 6
    public function __construct(Config $oConfig = null)
44
    {
45 6
        $oConfig                    = $oConfig ?? new Config();
46 6
        $this->logger               = $oConfig->getLogger();
47 6
        $this->ws                   = $oConfig->getWebservice();
48 6
        $this->params['connection'] = $oConfig->getConnectionString();
49 6
        $this->params['timeout']    = $oConfig->getTimeout();
50 6
        $this->params['docType']    = $oConfig->getDocType();
51 6
        $this->params['format']     = $oConfig->getFormat();
52 6
    }
53
54
    /**
55
     * @param string          $sourceFile  Path to input file
56
     * @param FormatType|null $format      Default PDF
57
     * @param string|null     $destination Path to output file or directory
58
     * @param array           $exportOpts  Export options
59
     *
60
     * @throws \Mrcnpdlk\Api\Unoconv\Exception\DomainException
61
     * @throws \Mrcnpdlk\Api\Unoconv\Exception\InvalidFileArgumentException
62
     * @throws \Mrcnpdlk\Api\Unoconv\Exception\UnoconvException
63
     *
64
     * @return SplFileObject
65
     */
66 4
    public function transcode(string $sourceFile, ?FormatType $format, ?string $destination, array $exportOpts = []): SplFileObject
67
    {
68 4
        $sourceFile = realpath($sourceFile);
69
70 4
        if (!is_file($sourceFile)) {
71 1
            throw new InvalidFileArgumentException(sprintf('Input file "%s" not exists', $sourceFile));
72
        }
73 3
        if (!is_readable($sourceFile)) {
74
            throw new InvalidFileArgumentException(sprintf('Input file "%s" is not readable', $sourceFile));
75
        }
76
77 3
        $format       = $format ?? $this->params['format'];
78 3
        $fromPathInfo = pathinfo($sourceFile);
79
80 3
        if (null === $destination) {
81 1
            $destination = sprintf('%s%s%s.%s',
82 1
                $fromPathInfo['dirname'],
83 1
                DIRECTORY_SEPARATOR,
84 1
                $fromPathInfo['filename'],
85 1
                $format->getExtension()
86
            );
87 2
        } elseif (is_dir($destination)) {
88 2
            $destination = sprintf('%s%s%s.%s',
89 2
                $destination,
90 2
                DIRECTORY_SEPARATOR,
91 2
                $fromPathInfo['filename'],
92 2
                $format->getExtension()
93
            );
94
        }
95
96 3
        $this->logger->debug(sprintf('Creating "%s" from "%s"', $destination, $sourceFile));
97
98 3
        $command = new Command($this->params['connection']);
99
        $command
100 3
            ->addArg('--doctype', $this->params['docType'], false)
101 3
            ->addArg('--format', $format, false)
102 3
            ->addArg('--timeout', $this->params['timeout'], false)
103 3
            ->addArg('--output', $destination, false)
104
        ;
105
106 3
        foreach ($exportOpts as $key => $value) {
107 2
            if (is_bool($value)) {
108 1
                $value = $value ? 'true' : 'false';
109 2
            } elseif (is_string($value)) {
110 1
                $value = sprintf('"%s"', $value);
111 1
            } elseif (!is_int($value)) {
112 1
                throw new DomainException(
113 1
                    sprintf('Invalid type of export argument "%s", only %s are allowed.',
114 1
                        gettype($value),
115 1
                        implode(',', ['int', 'string', 'bool']))
116
                );
117
            }
118
119 1
            $command->addArg('--export', sprintf('%s=%s', $key, $value), false);
120
        }
121
122 2
        $command->addArg($sourceFile);
123
124 2
        $this->logger->debug(sprintf('Executing command: %s', $command->getExecCommand()));
0 ignored issues
show
Bug introduced by
It seems like $command->getExecCommand() can also be of type false; however, parameter $args of sprintf() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

124
        $this->logger->debug(sprintf('Executing command: %s', /** @scrutinizer ignore-type */ $command->getExecCommand()));
Loading history...
125
126 2
        if ($command->execute()) {
127
            return new SplFileObject($destination);
128
        }
129 2
        throw new UnoconvException(sprintf('Unoconv error: %s', $command->getError()), $command->getExitCode());
130
    }
131
132
    /**
133
     * Generate PDF using external WebService
134
     *
135
     * @see https://github.com/zrrrzzt/docker-unoconv-webservice
136
     *
137
     * @param string      $sourceFile
138
     * @param string|null $destination
139
     *
140
     * @throws \Mrcnpdlk\Api\Unoconv\Exception\InvalidFileArgumentException
141
     * @throws \Mrcnpdlk\Api\Unoconv\Exception\UnoconvException
142
     *
143
     * @return \SplFileObject
144
     */
145 1
    public function wsGetPdf(string $sourceFile, ?string $destination): SplFileObject
146
    {
147 1
        $sourceFile = realpath($sourceFile);
148
149 1
        if (!is_file($sourceFile)) {
150
            throw new InvalidFileArgumentException(sprintf('Input file "%s" not exists', $sourceFile));
151
        }
152 1
        if (!is_readable($sourceFile)) {
153
            throw new InvalidFileArgumentException(sprintf('Input file "%s" is not readable', $sourceFile));
154
        }
155
156 1
        $fromPathInfo = pathinfo($sourceFile);
157
158 1
        if (null === $destination) {
159
            $destination = sprintf('%s%s%s.pdf',
160
                $fromPathInfo['dirname'],
161
                DIRECTORY_SEPARATOR,
162
                $fromPathInfo['filename']
163
            );
164 1
        } elseif (is_dir($destination)) {
165 1
            $destination = sprintf('%s%s%s.pdf',
166 1
                $destination,
167 1
                DIRECTORY_SEPARATOR,
168 1
                $fromPathInfo['filename']
169
            );
170
        }
171
172 1
        $this->logger->debug(sprintf('Creating "%s" from "%s"', $destination, $sourceFile));
173
174 1
        $ch = curl_init();
175 1
        curl_setopt($ch, \CURLOPT_URL, sprintf('%s/unoconv/pdf', $this->ws));
0 ignored issues
show
Bug introduced by
It seems like $ch can also be of type false; however, parameter $ch of curl_setopt() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

175
        curl_setopt(/** @scrutinizer ignore-type */ $ch, \CURLOPT_URL, sprintf('%s/unoconv/pdf', $this->ws));
Loading history...
176 1
        curl_setopt($ch, \CURLOPT_RETURNTRANSFER, 1);
177 1
        curl_setopt($ch, \CURLOPT_POST, true);
178 1
        curl_setopt($ch, \CURLOPT_POSTFIELDS, ['file' => new \CURLFile($sourceFile)]);
179 1
        $output = curl_exec($ch);
0 ignored issues
show
Bug introduced by
It seems like $ch can also be of type false; however, parameter $ch of curl_exec() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

179
        $output = curl_exec(/** @scrutinizer ignore-type */ $ch);
Loading history...
180 1
        if (false === $output) {
181 1
            throw new UnoconvException('Curl error: ' . curl_error($ch));
0 ignored issues
show
Bug introduced by
It seems like $ch can also be of type false; however, parameter $ch of curl_error() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

181
            throw new UnoconvException('Curl error: ' . curl_error(/** @scrutinizer ignore-type */ $ch));
Loading history...
182
        }
183
        $ret = json_decode($output);
0 ignored issues
show
Bug introduced by
It seems like $output can also be of type true; however, parameter $json of json_decode() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

183
        $ret = json_decode(/** @scrutinizer ignore-type */ $output);
Loading history...
184
        if (\JSON_ERROR_NONE === json_last_error()) {
185
            throw new UnoconvException('WebService Error: ' . $ret->message);
186
        }
187
188
        curl_close($ch);
0 ignored issues
show
Bug introduced by
It seems like $ch can also be of type false; however, parameter $ch of curl_close() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

188
        curl_close(/** @scrutinizer ignore-type */ $ch);
Loading history...
189
        file_put_contents($destination, $output);
190
191
        return new SplFileObject($destination);
192
    }
193
}
194