Passed
Branch V2.0.1 (f75052)
by Deric
01:57
created

Subprocess::get_process_info()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 10
nc 1
nop 1
dl 0
loc 13
rs 9.4285
c 0
b 0
f 0
1
<?php
2
namespace Filesystem;
3
4
use Symfony\Component\Process\Exception\ProcessFailedException;
5
use Symfony\Component\Process\Process;
6
7
/**
8
 * Subprocess class.
9
 *
10
 * @package Filesystem
11
 */
12
class Subprocess
13
{
14
    /**
15
     * Stream STDOUT and/or STDERR to file.
16
     *
17
     * @var int
18
     */
19
    const STREAM_FILE = 1;
20
21
    /**
22
     * Stream STDOUT and/or STDERR to STDOUT.
23
     *
24
     * @var int
25
     */
26
    const STREAM_STDOUT = 2;
27
28
    /**
29
     * Stream STDOUT and/or STDERR to file and STDOUT.
30
     *
31
     * @var int
32
     */
33
    const STREAM_BOTH = 3;
34
35
    /**
36
     * Stream STDOUT and/or STDERR to STDOUT (wait for process to finish).
37
     *
38
     * @var int
39
     */
40
    const STREAM_STDOUT_WAIT = 4;
41
42
    /**
43
     * Stream STDOUT and/or STDERR to STDOUT (interactive mode).
44
     *
45
     * @var int
46
     */
47
    const STREAM_STDOUT_TTY = 5;
48
49
    /**
50
     * Constructor.
51
     *
52
     * @return void
53
     */
54
    public function __contruct()
55
    {
56
57
    }
58
59
    /**
60
     * Initiate subprocess.
61
     *
62
     * @param  mixed   $cmd           command(s) being executed
63
     * @param  boolean $stream        whether or not to stream results to console
64
     * @param  boolean $fail_on_error whether or not to fail on error or pass
65
     * @param  mixed   $stdoutfile    STDOUT file for output or NULL
66
     * @param  mixed   $stderrfile    STDERR file for output or NULL
67
     * @return array   STDOUT, STDERR and RETVAL or just RETVAL if streamed
68
     */
69
    final public function subprocess($cmd, $stream = self::STREAM_STDOUT_WAIT, $fail_on_error = false, $stdoutfile = null, $stderrfile = null)
0 ignored issues
show
Coding Style Best Practice introduced by
Please use __construct() instead of a PHP4-style constructor that is named after the class.
Loading history...
70
    {
71
        $process = new Process($cmd);
72
        $process->setTimeout(3600);
73
        $process->setIdleTimeout(3600);
74
75
        switch ($stream)
76
        {
77
            case '1':
78
                return $this->stream_to_file($process, $stdoutfile, $stderrfile);
79
80
            case '2':
81
                return $this->stream_to_stdout($process);
82
                
83
            case '3':
84
                return $this->stream_to_both($process, $stdoutfile, $stderrfile);
85
                
86
            case '4':
87
                return $this->stream_stdout_wait($process, $fail_on_error);
88
                
89
            case '5':
90
                return $this->stream_stdout_tty($process);
91
        }
92
    }
93
94
    /**
95
     * Stream STDOUT and/or STDERR to console.
96
     *
97
     * @param  object $process    process object
98
     * @param  string $stdoutfile STDOUT file for output
99
     * @param  string $stderrfile STDERR file for output
100
     * @return array
101
     */
102
    final protected function stream_to_file(Process $process, $stdoutfile, $stderrfile)
103
    {
104
        if (!isset($stdoutfile))
105
        {
106
            throw new \RuntimeException("Missing output file for STDOUT stream.");
107
        }
108
109
        $GLOBALS['stdoutfile'] = $stdoutfile;
110
        $GLOBALS['stderrfile'] = $stderrfile;
111
112
        $process->run(function($type, $buffer)
113
        {
114
            if (Process::ERR === $type)
115
            {
116
                if ($GLOBALS['stderrfile'] !== null)
117
                {
118
                    file_put_contents($GLOBALS['stderrfile'], $buffer, FILE_APPEND | LOCK_EX);
119
                }
120
                else
121
                {
122
                    file_put_contents($GLOBALS['stdoutfile'], $buffer, FILE_APPEND | LOCK_EX);
123
                }
124
            }
125
            else
126
            {
127
                file_put_contents($GLOBALS['stdoutfile'], $buffer, FILE_APPEND | LOCK_EX);
128
            }
129
        });
130
        return $this->get_process_info($process);
131
    }
132
133
    /**
134
     * Stream STDOUT and STDERR to console.
135
     *
136
     * @param  object $process process object
137
     * @return array
138
     */
139
    final protected function stream_to_stdout(Process $process)
140
    {
141
        $process->run(function($type, $buffer) {
142
            if (Process::ERR === $type)
143
            {
144
                fwrite(STDERR, $buffer);
145
            }
146
147
            if (Process::ERR !== $type)
148
            {
149
                fwrite(STDOUT, $buffer);
150
            }
151
        });
152
        return $this->get_process_info($process);
153
    }
154
155
    /**
156
     * Stream STDOUT and STDERR to console.
157
     *
158
     * @param  object $process    Process object
159
     * @param  string $stdoutfile STDOUT file for output
160
     * @param  string $stderrfile STDERR file for output
161
     * @return array
162
     */
163
    final protected function stream_to_both(Process $process, $stdoutfile, $stderrfile)
164
    {
165
        if (!isset($stdoutfile))
166
        {
167
            throw new \RuntimeException("Missing output file for STDOUT stream.");
168
        }
169
170
        $GLOBALS['stdoutfile'] = $stdoutfile;
171
        $GLOBALS['stderrfile'] = $stderrfile;
172
173
        $process->run(function($type, $buffer) {
174
            if (Process::ERR === $type)
175
            {
176
                if ($GLOBALS['stderrfile'] !== null)
177
                {
178
                    file_put_contents($GLOBALS['stderrfile'], $buffer, FILE_APPEND | LOCK_EX);
179
                }
180
181
                if ($GLOBALS['stderrfile'] === null)
182
                {
183
                    file_put_contents($GLOBALS['stdoutfile'], $buffer, FILE_APPEND | LOCK_EX);
184
                }
185
                fwrite(STDERR, $buffer);
186
            }
187
188
            if (Process::ERR !== $type)
189
            {
190
                file_put_contents($GLOBALS['stdoutfile'], $buffer, FILE_APPEND | LOCK_EX);
191
                fwrite(STDOUT, $buffer);
192
            }
193
        });
194
        return $this->get_process_info($process);
195
    }
196
197
    /**
198
     * Wait for process to finish and return.
199
     *
200
     * @param  object  $process       process object
201
     * @param  boolean $fail_on_error whether or not to fail on error or pass
202
     * @return array
203
     */
204
    final protected function stream_stdout_wait(Process $process, $fail_on_error)
205
    {
206
        $process->run();
207
        if ($fail_on_error && !$process->isSuccessful())
208
        {
209
            throw new ProcessFailedException($process);
210
        }
211
        return $this->get_process_info($process);
212
    }
213
214
    /**
215
     * Stream STDOUT and STDERR to console (interactive mode).
216
     *
217
     * @param  object $process process object
218
     * @return array
219
     */
220
    final protected function stream_stdout_tty(Process $process)
221
    {
222
        $process->setTty(true);
223
        $process->start();
224
        $process->wait();
225
        return $this->get_process_info($process);
226
    }
227
228
    /**
229
     * Returns process information.
230
     *
231
     * @param  object $process process object
232
     * @return array
233
     */
234
    final protected function get_process_info(Process $process)
235
    {
236
        $cmd_executed = $process->getCommandLine();
237
        $stdout = $process->getOutput();
238
        $stderr = $process->getErrorOutput();
239
        $return_value = $process->getExitCode();
240
        $return_value_text = $process->getExitCodeText();
241
242
        return [
243
            'command'    => $cmd_executed,
244
            'stdout'     => $stdout,
245
            'stderr'     => $stderr,
246
            'error_code' => [$return_value, $return_value_text]
247
        ];
248
    }
249
}
250