Completed
Pull Request — master (#84)
by Maxime
04:42 queued 02:58
created

MediaInfoCommandRunner   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 132
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 91.3%

Importance

Changes 0
Metric Value
wmc 12
c 0
b 0
f 0
lcom 1
cbo 1
dl 0
loc 132
ccs 42
cts 46
cp 0.913
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
B __construct() 0 49 6
A run() 0 9 2
A start() 0 6 1
A wait() 0 15 3
1
<?php
2
3
namespace Mhor\MediaInfo\Runner;
4
5
use Symfony\Component\Process\Process;
6
7
class MediaInfoCommandRunner
8
{
9
    const FORCED_OLDXML_OUTPUT_FORMAT_ARGUMENTS = ['--OUTPUT=OLDXML', '-f'];
10
    const XML_OUTPUT_FORMAT_ARGUMENTS = ['--OUTPUT=XML', '-f'];
11
12
    /**
13
     * @var string
14
     */
15
    protected $filePath;
16
17
    /**
18
     * @var Process
19
     */
20
    protected $process;
21
22
    /**
23
     * @var string
24
     */
25
    protected $command = 'mediainfo';
26
27
    /**
28
     * @var array
29
     */
30
    protected $arguments = [];
31
32
    /**
33
     * @param string  $filePath
34
     * @param string  $command
35
     * @param array   $arguments
36
     * @param Process $process
37
     * @param bool    $forceOldXmlOutput
38
     */
39 6
    public function __construct(
40
        $filePath,
41
        $command = null,
42
        array $arguments = null,
43
        Process $process = null,
44
        $forceOldXmlOutput = false
45
    ) {
46 6
        $this->filePath = $filePath;
47 6
        if ($command !== null) {
48 2
            $this->command = $command;
49 2
        }
50
51 6
        $this->arguments = self::XML_OUTPUT_FORMAT_ARGUMENTS;
52 6
        if ($forceOldXmlOutput) {
53
            $this->arguments = self::FORCED_OLDXML_OUTPUT_FORMAT_ARGUMENTS;
54
        }
55
56 6
        if ($arguments !== null) {
57 3
            $this->arguments = $arguments;
58 3
        }
59
60
        // /path/to/mediainfo $MEDIAINFO_VAR0 $MEDIAINFO_VAR1...
61
        // args are given through ENV vars in order to have system escape them
62
63 6
        $args = $this->arguments;
64 6
        array_unshift($args, $this->filePath);
65
66
        $env = [
67 6
            'LANG' => setlocale(LC_CTYPE, 0),
68 6
        ];
69 6
        $finalCommand = [$this->command];
70
71 6
        $i = 0;
72 6
        foreach ($args as $value) {
73 6
            $var = 'MEDIAINFO_VAR_'.$i++;
74 6
            $finalCommand[] = '$'.$var;
75 6
            $env[$var] = $value;
76 6
        }
77
78 6
        $finalCommandString = implode(' ', $finalCommand);
79
80 6
        if (null !== $process) {
81 3
            $process->setCommandLine($finalCommandString);
82 3
            $process->setEnv($env);
83 3
            $this->process = $process;
84 3
        } else {
85 3
            $this->process = new Process($finalCommandString, null, $env);
86
        }
87 6
    }
88
89
    /**
90
     * @throws \RuntimeException
91
     *
92
     * @return string
93
     */
94 2
    public function run()
95
    {
96 2
        $this->process->run();
97 2
        if (!$this->process->isSuccessful()) {
98 1
            throw new \RuntimeException($this->process->getErrorOutput());
99
        }
100
101 1
        return $this->process->getOutput();
102
    }
103
104
    /**
105
     * Asynchronously start mediainfo operation.
106
     * Make call to MediaInfoCommandRunner::wait() afterwards to receive output.
107
     */
108 1
    public function start()
109
    {
110
        // just takes advantage of symfony's underlying Process framework
111
        // process runs in background
112 1
        $this->process->start();
113 1
    }
114
115
    /**
116
     * Blocks until call is complete.
117
     *
118
     * @throws \Exception        If this function is called before start()
119
     * @throws \RuntimeException
120
     *
121
     * @return string
122
     */
123 1
    public function wait()
124
    {
125 1
        if ($this->process == null) {
126
            throw new \Exception('You must run `start` before running `wait`');
127
        }
128
129
        // blocks here until process completes
130 1
        $this->process->wait();
131
132 1
        if (!$this->process->isSuccessful()) {
133
            throw new \RuntimeException($this->process->getErrorOutput());
134
        }
135
136 1
        return $this->process->getOutput();
137
    }
138
}
139