PdftkWrapper::guessBinary()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 5
c 1
b 0
f 0
dl 0
loc 9
ccs 5
cts 5
cp 1
rs 10
cc 2
nc 2
nop 1
crap 2
1
<?php
2
/**
3
 * PDFtk wrapper
4
 *
5
 * @copyright 2014-2019 Institute of Legal Medicine, Medical University of Innsbruck
6
 * @author Martin Pircher <[email protected]>
7
 * @author Andreas Erhard <[email protected]>
8
 * @license LGPL-3.0-only
9
 * @link http://www.gerichtsmedizin.at/
10
 *
11
 * @package pdftk
12
 */
13
14
namespace Gmi\Toolkit\Pdftk;
15
16
use Symfony\Component\Process\Process;
17
18
use Gmi\Toolkit\Pdftk\Exception\FileNotFoundException;
19
use Gmi\Toolkit\Pdftk\Exception\PdfException;
20
use Gmi\Toolkit\Pdftk\Util\ProcessFactory;
21
22
use Exception;
23
24
/**
25
 * Wrapper for PDFtk.
26
 *
27
 * @internal
28
 */
29
class PdftkWrapper
30
{
31
    /**
32
     * @var string pdftk binary including full path
33
     */
34
    private $pdftkBinary;
35
36
    /**
37
     * @var ProcessFactory
38
     */
39
    private $processFactory;
40
41
    /**
42
     * Constructor.
43
     *
44
     * @param string         $pdftkBinary
45
     * @param ProcessFactory $processFactory
46
     *
47
     * @throws FileNotFoundException
48
     */
49 39
    public function __construct($pdftkBinary = null, $processFactory = null)
50
    {
51 39
        $this->setBinary($pdftkBinary ?: $this->guessBinary(PHP_OS));
52 38
        $this->processFactory = $processFactory ?: new ProcessFactory();
53 38
    }
54
55
    /**
56
     * Guesses the pdftk binary path based on the operating system.
57
     *
58
     * @return string
59
     */
60 33
    public function guessBinary($operatingSystemString)
61
    {
62 33
        if (strtoupper(substr($operatingSystemString, 0, 3)) === 'WIN') {
63 1
            $binary = 'C:\\Program Files (x86)\\PDFtk Server\\bin\\pdftk.exe';
64
        } else {
65 33
            $binary = '/usr/bin/pdftk';
66
        }
67
68 33
        return $binary;
69
    }
70
71
    /**
72
     * Set pdftk binary to use.
73
     *
74
     * @param string $binary
75
     *
76
     * @return self
77
     *
78
     * @throws FileNotFoundException
79
     */
80 39
    public function setBinary($binary)
81
    {
82 39
        if (!file_exists($binary)) {
83 1
            throw new FileNotFoundException(sprintf('Binary "%s" not found', $binary));
84
        }
85
86 38
        $this->pdftkBinary = $binary;
87
88 38
        return $this;
89
    }
90
91
    /**
92
     * Get current used pdftk binary.
93
     *
94
     * @param bool $escaped shellescape binary
95
     *
96
     * @return string
97
     */
98 16
    public function getBinary($escaped = true)
99
    {
100 16
        return $escaped ? escapeshellarg($this->pdftkBinary) : $this->pdftkBinary;
101
    }
102
103
    /**
104
     * Creates a (pdftk) process using the ProcessFactory.
105
     *
106
     * @param string $commandLine
107
     *
108
     * @return Process
109
     */
110 15
    public function createProcess($commandLine)
111
    {
112 15
        return $this->processFactory->createProcess($commandLine);
113
    }
114
115
    /**
116
     * Get data dump.
117
     *
118
     * @param string $pdf
119
     *
120
     * @return string
121
     *
122
     * @throws PdfException
123
     */
124 15
    public function getPdfDataDump($pdf)
125
    {
126 15
        if (!file_exists($pdf)) {
127 2
            throw new FileNotFoundException(sprintf('PDF "%s" not found', $pdf));
128
        }
129
130 13
        $tempfile = tempnam(sys_get_temp_dir(), 'pdf');
131 13
        $cmd = sprintf(
132 13
            '%s %s dump_data_utf8 output %s',
133 13
            $this->getBinary(),
134 13
            escapeshellarg($pdf),
135 13
            escapeshellarg($tempfile)
136
        );
137
138 13
        $process = $this->createProcess($cmd);
139
140
        try {
141 13
            $process->mustRun();
142 2
        } catch (Exception $e) {
143 2
            $exception = new PdfException(
144 2
                sprintf('Failed to read PDF data from "%s"! Error: %s', $pdf, $e->getMessage()),
145 2
                0,
146 2
                $e,
147 2
                $process->getErrorOutput(),
148 2
                $process->getOutput()
149
            );
150
        }
151
152 13
        $dump = file_get_contents($tempfile);
153 13
        unlink($tempfile);
154
155 13
        if (isset($exception)) {
156 2
            throw $exception;
157
        }
158
159 11
        return $dump;
160
    }
161
162
    /**
163
     * Update PDF data from dump.
164
     *
165
     * @param string $pdf         input file
166
     * @param string $data        dump data or filename of containing dump data
167
     * @param string $outfile     output file (is input when null)
168
     *
169
     * @throws PdfException
170
     */
171 9
    public function updatePdfDataFromDump($pdf, $data, $outfile = null)
172
    {
173 9
        $temporaryOutFile = false;
174
175 9
        if (!file_exists($pdf)) {
176 2
            throw new FileNotFoundException(sprintf('PDF "%s" not found', $pdf));
177
        }
178
179 7
        if ($outfile === null || $pdf === $outfile) {
180 2
            $temporaryOutFile = true;
181 2
            $outfile = tempnam(sys_get_temp_dir(), 'pdf');
182
        }
183
184 7
        $tempfile = tempnam(sys_get_temp_dir(), 'pdf');
185 7
        file_put_contents($tempfile, $data);
186
187 7
        $cmd = sprintf(
188 7
            '%s %s update_info_utf8 %s output %s',
189 7
            $this->getBinary(),
190 7
            escapeshellarg($pdf),
191 7
            escapeshellarg($tempfile),
192 7
            escapeshellarg($outfile)
193
        );
194
195 7
        $process = $this->createProcess($cmd);
196
197
        try {
198 7
            $process->mustRun();
199 2
        } catch (Exception $e) {
200 2
            $exception = new PdfException(
201 2
                sprintf('Failed to write PDF data to "%s"! Error: %s', $outfile, $e->getMessage()),
202 2
                0,
203 2
                $e,
204 2
                $process->getErrorOutput(),
205 2
                $process->getOutput()
206
            );
207
        }
208
209 7
        unlink($tempfile);
210
211 7
        if ($temporaryOutFile && !isset($exception)) {
212 2
            unlink($pdf);
213 2
            rename($outfile, $pdf);
214
        }
215
216 7
        if (isset($exception)) {
217 2
            throw $exception;
218
        }
219 5
    }
220
}
221