Passed
Push — master ( 90adda...8182c6 )
by Maxime
37s
created

MediaInfoCommandRunner   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 121
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 95.24%

Importance

Changes 0
Metric Value
wmc 11
lcom 1
cbo 1
dl 0
loc 121
ccs 40
cts 42
cp 0.9524
rs 10
c 0
b 0
f 0

4 Methods

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