Passed
Pull Request — master (#13)
by Marcin
06:15 queued 14s
created

Api   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 173
Duplicated Lines 0 %

Test Coverage

Coverage 83.33%

Importance

Changes 5
Bugs 0 Features 0
Metric Value
wmc 19
eloc 85
c 5
b 0
f 0
dl 0
loc 173
rs 10
ccs 70
cts 84
cp 0.8333

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 9 1
B transcode() 0 64 11
B wsGetPdf() 0 48 7
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
set_time_limit(0);
11
12
use CURLFile;
13
use const CURLOPT_POST;
14
use const CURLOPT_POSTFIELDS;
15
use const CURLOPT_RETURNTRANSFER;
16
use const CURLOPT_URL;
17
use const JSON_ERROR_NONE;
18
use mikehaertl\shellcommand\Command;
19
use Mrcnpdlk\Api\Unoconv\Enum\FormatType;
20
use Mrcnpdlk\Api\Unoconv\Exception\DomainException;
21
use Mrcnpdlk\Api\Unoconv\Exception\InvalidFileArgumentException;
22
use Mrcnpdlk\Api\Unoconv\Exception\UnoconvException;
23
use SplFileObject;
24
25
/**
26
 * Class Api
27
 */
28
class Api
29
{
30
    /**
31
     * @var array
32
     */
33
    private $params = [];
34
    /** @noinspection PhpUndefinedClassInspection */
35
    /**
36
     * @var \Psr\Log\LoggerInterface
37
     */
38
    private $logger;
39
    /**
40
     * @var string
41
     */
42
    private $ws;
43
44
    /**
45
     * Api constructor.
46
     *
47
     * @param \Mrcnpdlk\Api\Unoconv\Config $oConfig
48
     *
49
     * @throws \Mrcnpdlk\Lib\ConfigurationException
50
     */
51 6
    public function __construct(Config $oConfig = null)
52
    {
53 6
        $oConfig                    = $oConfig ?? new Config();
54 6
        $this->logger               = $oConfig->getLogger();
55 6
        $this->ws                   = $oConfig->getWebservice();
56 6
        $this->params['connection'] = $oConfig->getConnectionString();
57 6
        $this->params['timeout']    = $oConfig->getTimeout();
58 6
        $this->params['docType']    = $oConfig->getDocType();
59 6
        $this->params['format']     = $oConfig->getFormat();
60 6
    }
61
62
    /**
63
     * @param string          $sourceFile  Path to input file
64
     * @param FormatType|null $format      Default PDF
65
     * @param string|null     $destination Path to output file or directory
66
     * @param array           $exportOpts  Export options
67
     *
68
     * @throws \Mrcnpdlk\Api\Unoconv\Exception\InvalidFileArgumentException
69
     * @throws \Mrcnpdlk\Api\Unoconv\Exception\UnoconvException
70
     * @throws \Mrcnpdlk\Api\Unoconv\Exception\DomainException
71
     *
72
     * @return SplFileObject
73
     */
74 4
    public function transcode(string $sourceFile, ?FormatType $format, ?string $destination, array $exportOpts = []): SplFileObject
75
    {
76 4
        $sourceFile = realpath($sourceFile);
77
78 4
        if (!is_file($sourceFile)) {
79 1
            throw new InvalidFileArgumentException(sprintf('Input file "%s" not exists', $sourceFile));
80
        }
81 3
        if (!is_readable($sourceFile)) {
82
            throw new InvalidFileArgumentException(sprintf('Input file "%s" is not readable', $sourceFile));
83
        }
84
85 3
        $format       = $format ?? $this->params['format'];
86 3
        $fromPathInfo = pathinfo($sourceFile);
87
88 3
        if (null === $destination) {
89 1
            $destination = sprintf('%s%s%s.%s',
90 1
                $fromPathInfo['dirname'],
91 1
                DIRECTORY_SEPARATOR,
92 1
                $fromPathInfo['filename'],
93 1
                $format->getExtension()
94
            );
95 2
        } elseif (is_dir($destination)) {
96 2
            $destination = sprintf('%s%s%s.%s',
97 2
                $destination,
98 2
                DIRECTORY_SEPARATOR,
99 2
                $fromPathInfo['filename'],
100 2
                $format->getExtension()
101
            );
102
        }
103
104 3
        $this->logger->debug(sprintf('Creating "%s" from "%s"', $destination, $sourceFile));
105
106 3
        $command = new Command($this->params['connection']);
107
        $command
108 3
            ->addArg('--doctype', $this->params['docType'], false)
109 3
            ->addArg('--format', $format, false)
110 3
            ->addArg('--timeout', $this->params['timeout'], false)
111 3
            ->addArg('--output', $destination, false)
112
        ;
113
114 3
        foreach ($exportOpts as $key => $value) {
115 2
            if (is_bool($value)) {
116 1
                $value = $value ? 'true' : 'false';
117 2
            } elseif (is_string($value)) {
118 1
                $value = sprintf('"%s"', $value);
119 1
            } elseif (!is_int($value)) {
120 1
                throw new DomainException(
121 1
                    sprintf('Invalid type of export argument "%s", only %s are allowed.',
122 1
                        gettype($value),
123 1
                        implode(',', ['int', 'string', 'bool']))
124
                );
125
            }
126
127 1
            $command->addArg('--export', sprintf('%s=%s', $key, $value), false);
128
        }
129
130 2
        $command->addArg($sourceFile);
131
132 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

132
        $this->logger->debug(sprintf('Executing command: %s', /** @scrutinizer ignore-type */ $command->getExecCommand()));
Loading history...
133
134 2
        if ($command->execute()) {
135
            return new SplFileObject($destination);
136
        }
137 2
        throw new UnoconvException(sprintf('Unoconv error: %s', $command->getError()), $command->getExitCode());
138
    }
139
140
    /**
141
     * Generate PDF using external WebService
142
     *
143
     * @see https://github.com/zrrrzzt/docker-unoconv-webservice
144
     *
145
     * @param string      $sourceFile
146
     * @param string|null $destination
147
     *
148
     * @throws \Mrcnpdlk\Api\Unoconv\Exception\InvalidFileArgumentException
149
     * @throws \Mrcnpdlk\Api\Unoconv\Exception\UnoconvException
150
     *
151
     * @return \SplFileObject
152
     */
153 1
    public function wsGetPdf(string $sourceFile, ?string $destination): SplFileObject
154
    {
155 1
        $sourceFile = realpath($sourceFile);
156
157 1
        if (!is_file($sourceFile)) {
158
            throw new InvalidFileArgumentException(sprintf('Input file "%s" not exists', $sourceFile));
159
        }
160 1
        if (!is_readable($sourceFile)) {
161
            throw new InvalidFileArgumentException(sprintf('Input file "%s" is not readable', $sourceFile));
162
        }
163
164 1
        $fromPathInfo = pathinfo($sourceFile);
165
166 1
        if (null === $destination) {
167
            $destination = sprintf('%s%s%s.pdf',
168
                $fromPathInfo['dirname'],
169
                DIRECTORY_SEPARATOR,
170
                $fromPathInfo['filename']
171
            );
172 1
        } elseif (is_dir($destination)) {
173 1
            $destination = sprintf('%s%s%s.pdf',
174 1
                $destination,
175 1
                DIRECTORY_SEPARATOR,
176 1
                $fromPathInfo['filename']
177
            );
178
        }
179
180 1
        $this->logger->debug(sprintf('Creating "%s" from "%s"', $destination, $sourceFile));
181
182 1
        $ch = curl_init();
183 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

183
        curl_setopt(/** @scrutinizer ignore-type */ $ch, CURLOPT_URL, sprintf('%s/unoconv/pdf', $this->ws));
Loading history...
184 1
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
185 1
        curl_setopt($ch, CURLOPT_POST, true);
186 1
        curl_setopt($ch, CURLOPT_POSTFIELDS, ['file' => new CURLFile($sourceFile)]);
187 1
        curl_setopt($ch, CURLOPT_TIMEOUT, $this->params['timeout']);
188 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

188
        $output = curl_exec(/** @scrutinizer ignore-type */ $ch);
Loading history...
189 1
        if (false === $output) {
190 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

190
            throw new UnoconvException('Curl error: ' . curl_error(/** @scrutinizer ignore-type */ $ch));
Loading history...
191
        }
192
        $ret = json_decode($output, false);
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

192
        $ret = json_decode(/** @scrutinizer ignore-type */ $output, false);
Loading history...
193
        if (JSON_ERROR_NONE === json_last_error()) {
194
            throw new UnoconvException('WebService Error: ' . $ret->message);
195
        }
196
197
        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

197
        curl_close(/** @scrutinizer ignore-type */ $ch);
Loading history...
198
        file_put_contents($destination, $output);
199
200
        return new SplFileObject($destination);
201
    }
202
}
203