Completed
Push — master ( bdc37e...5a8dc8 )
by Daniel
10s
created

AbstractDevice::createProcess()   B

Complexity

Conditions 5
Paths 12

Size

Total Lines 20
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 3
Bugs 0 Features 0
Metric Value
c 3
b 0
f 0
dl 0
loc 20
ccs 0
cts 0
cp 0
rs 8.8571
cc 5
eloc 13
nc 12
nop 1
crap 30
1
<?php
2
/**
3
 * This file is part of the Ghostscript package
4
 *
5
 * @author Daniel Schröder <[email protected]>
6
 */
7
8
namespace GravityMedia\Ghostscript\Device;
9
10
use GravityMedia\Ghostscript\Device\CommandLineParameters\EpsTrait;
11
use GravityMedia\Ghostscript\Device\CommandLineParameters\FontTrait;
12
use GravityMedia\Ghostscript\Device\CommandLineParameters\IccColorTrait;
13
use GravityMedia\Ghostscript\Device\CommandLineParameters\InteractionTrait;
14
use GravityMedia\Ghostscript\Device\CommandLineParameters\OtherTrait;
15
use GravityMedia\Ghostscript\Device\CommandLineParameters\OutputSelectionTrait;
16
use GravityMedia\Ghostscript\Device\CommandLineParameters\PageTrait;
17
use GravityMedia\Ghostscript\Device\CommandLineParameters\RenderingTrait;
18
use GravityMedia\Ghostscript\Device\CommandLineParameters\ResourceTrait;
19
use GravityMedia\Ghostscript\Process\Argument as ProcessArgument;
20
use GravityMedia\Ghostscript\Process\Arguments as ProcessArguments;
21
use Symfony\Component\Process\Process;
22
use Symfony\Component\Process\ProcessBuilder;
23
24
/**
25
 * The abstract device class
26
 *
27
 * @package GravityMedia\Ghostscript\Devices
28
 */
29
abstract class AbstractDevice
30
{
31
    /**
32
     * Use command line options
33
     */
34
    use CommandLineOptionsTrait;
35
36
    /**
37
     * Use rendering parameters
38
     */
39
    use RenderingTrait;
40
41
    /**
42 15
     * Use page parameters
43
     */
44 15
    use PageTrait;
45 15
46 15
    /**
47
     * Use font-related parameters
48
     */
49
    use FontTrait;
50
51
    /**
52
     * Use resource-related parameters
53
     */
54
    use ResourceTrait;
55 6
56
    /**
57 6
     * Use interaction parameters
58
     */
59
    use InteractionTrait;
60
61
    /**
62
     * Use device and output selection parameters
63
     */
64
    use OutputSelectionTrait;
65
66
    /**
67 3
     * Use EPS parameters
68
     */
69 3
    use EpsTrait;
70 3
71 3
    /**
72
     * Use ICC color parameters
73
     */
74 3
    use IccColorTrait;
75
76
    /**
77
     * Use other parameters
78
     */
79
    use OtherTrait;
80
81
    /**
82
     * PostScript commands to be executed via command line when using this device.
83
     */
84 3
    const POSTSCRIPT_COMMANDS = '';
85
86 3
    /**
87
     * The process builder object
88 3
     *
89
     * @var ProcessBuilder
90
     */
91
    private $builder;
92
93
    /**
94
     * The arguments object
95
     *
96
     * @var ProcessArguments
97
     */
98
    private $arguments;
99
100 6
    /**
101
     * List of input files
102 6
     *
103 3
     * @var array
104
     */
105
    private $inputFiles = [];
106 3
107 3
    /**
108
     * Whether to read input from stdin
109 3
     *
110
     * @var bool
111
     */
112
    private $inputStdin = false;
113
114
    /**
115
     * Create abstract device object
116
     *
117
     * @param ProcessBuilder $builder
118
     * @param ProcessArguments $arguments
119
     */
120
    public function __construct(ProcessBuilder $builder, ProcessArguments $arguments)
121
    {
122
        $this->builder = $builder;
123
        $this->arguments = $arguments;
124
    }
125
126
    /**
127
     * Get Argument
128
     *
129
     * @param string $name
130
     *
131
     * @return null|ProcessArgument
132
     */
133
    protected function getArgument($name)
134
    {
135
        return $this->arguments->getArgument($name);
136
    }
137
138
    /**
139
     * Whether argument is set
140
     *
141
     * @param string $name
142
     *
143
     * @return bool
144
     */
145
    protected function hasArgument($name)
146
    {
147
        return $this->getArgument($name) !== null;
148
    }
149
150
    /**
151
     * Get argument value
152
     *
153
     * @param string $name
154
     *
155
     * @return null|string
156
     */
157
    protected function getArgumentValue($name)
158
    {
159
        $argument = $this->getArgument($name);
160
        if (null === $argument) {
161
            return null;
162
        }
163
164
        return $argument->getValue();
165
    }
166
167
    /**
168
     * Set argument
169
     *
170
     * @param string $argument
171
     *
172
     * @return $this
173
     */
174
    protected function setArgument($argument)
175
    {
176
        $this->arguments->setArgument($argument);
177
178
        return $this;
179
    }
180
181
    /**
182
     * Set a generic command line parameter with a string value
183
     *
184
     * @param string $param the parameter name
185
     * @param string $value the parameter value
186
     *
187
     * @return $this
188
     */
189
    public function setStringParameter($param, $value)
190
    {
191
        $this->setArgument(sprintf('-s%s=%s', $param, $value));
192
193
        return $this;
194
    }
195
196
    /**
197
     * Set a generic command line parameter with a token value
198
     *
199
     * @param string $param the parameter name
200
     * @param mixed $value the parameter value
201
     *
202
     * @return $this
203
     */
204
    public function setTokenParameter($param, $value)
205
    {
206
        $this->setArgument(sprintf('-d%s=%s', $param, $value));
207
208
        return $this;
209
    }
210
211
    /**
212
     * Add an input file
213
     *
214
     * @param string $inputFile a path to an existing file
215
     *
216
     * @throws \RuntimeException if $inputFile does not exist
217
     *
218
     * @return $this
219
     */
220
    public function addInputFile($inputFile)
221
    {
222
        if (!is_file($inputFile)) {
223
            throw new \RuntimeException('Input file does not exist');
224
        }
225
        $this->inputFiles[] = $inputFile;
226
227
        return $this;
228
    }
229
230
    /**
231
     * Add an stdin as input file
232
     *
233
     * @return $this
234
     */
235
    public function addInputStdin()
236
    {
237
        $this->inputStdin = true;
238
239
        return $this;
240
    }
241
242
    /**
243
     * Create process object
244
     *
245
     * @param string $inputFile either a path to an existing file or a dash (-) to read input from stdin
246
     *
247
     * @throws \RuntimeException if $inputFile does not exist
248
     *
249
     * @return Process
250
     */
251
    public function createProcess($inputFile = null)
252
    {
253
        if ('-' == $inputFile) {
254
            $this->addInputStdin();
255
        } elseif (null !== $inputFile) {
256
            $this->addInputFile($inputFile);
257
        }
258
259
        $arguments = array_values($this->arguments->toArray());
260
        array_push($arguments, '-c', static::POSTSCRIPT_COMMANDS, '-f');
261
        if (count($this->inputFiles)) {
262
            $arguments = array_merge($arguments, $this->inputFiles);
263
        }
264
        if ($this->inputStdin) {
265
            array_push($arguments, '-');
266
        }
267
        $this->resetInput();
268
269
        return $this->builder->setArguments($arguments)->getProcess();
270
    }
271
272
    /**
273
     * Reset the input-related fields of this device.
274
     * Future processes created from this device will have their own input parameters.
275
     */
276
    private function resetInput()
277
    {
278
        $this->inputFiles = [];
279
        $this->inputStdin = false;
280
    }
281
}
282