Completed
Push — master ( 57c54d...9135e7 )
by Sebastian
03:47
created

Process::isPiped()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 4
ccs 0
cts 0
cp 0
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 2
1
<?php
2
namespace phpbu\App\Cli;
3
4
use phpbu\App\Exception;
5
use phpbu\App\Util\Cli;
6
7
/**
8
 * Cli Process Runner
9
 *
10
 * @package    phpbu
11
 * @subpackage Backup
12
 * @author     Sebastian Feldmann <[email protected]>
13
 * @copyright  Sebastian Feldmann <[email protected]>
14
 * @license    https://opensource.org/licenses/MIT The MIT License (MIT)
15
 * @link       http://phpbu.de/
16
 * @since      Class available since Release 2.1.0
17
 */
18
class Process
19
{
20
    /**
21
     * List of system commands to execute.
22
     *
23
     * @var \phpbu\App\Cli\Cmd[]
24
     */
25
    private $commands = [];
26
27
    /**
28
     * Redirect the output
29
     *
30
     * @var string
31
     */
32
    private $redirectOutput;
33
34
    /**
35
     * Output pipeline
36
     *
37
     * @var \phpbu\App\Cli\Cmd[]
38 12
     */
39
    private $pipeline = [];
40 12
41 12
    /**
42
     * Redirect the stdOut.
43
     *
44
     * @param string $path
45
     */
46
    public function redirectOutputTo($path)
47
    {
48 1
        $this->redirectOutput = $path;
49
    }
50 1
51
    /**
52
     * Should the output be redirected.
53
     *
54
     * @return boolean
55
     */
56
    public function isOutputRedirected()
57
    {
58 1
        return !empty($this->redirectOutput);
59
    }
60 1
61
    /**
62
     * Redirect getter.
63
     *
64
     * @return string
65
     */
66
    public function getRedirectPath()
67
    {
68 99
        return $this->redirectOutput;
69
    }
70 99
71 99
    /**
72
     * Pipe the command into given command.
73
     *
74
     * @param  \phpbu\App\Cli\Cmd $cmd
75
     * @throws \phpbu\App\Exception
76
     */
77
    public function pipeOutputTo(Cmd $cmd)
78
    {
79 97
        if (!Cli::canPipe()) {
80
            throw new Exception('Can\'t pipe output');
81 97
        }
82 97
        $this->pipeline[] = $cmd;
83 1
    }
84
85 96
    /**
86 96
     * Is there a command pipeline.
87
     *
88 96
     * @return bool
89
     */
90
    public function isPiped()
91
    {
92
        return !empty($this->pipeline);
93
    }
94
95
    /**
96
     * Return command pipeline.
97 1
     *
98
     * @return string
99 1
     */
100 1
    public function getPipeline()
101 1
    {
102 1
        return $this->isPiped() ? ' | ' . implode(' | ', $this->pipeline) : '';
103 1
    }
104 1
105
    /**
106 1
     * Adds a cli command to the command list.
107
     *
108
     * @param \phpbu\App\Cli\Cmd $cmd
109
     */
110
    public function addCommand(Cmd $cmd)
111
    {
112
        $this->commands[] = $cmd;
113
    }
114
115
    /**
116
     * Generates the system command.
117
     *
118
     * @return string
119
     * @throws \phpbu\App\Exception
120
     */
121
    public function getCommandLine()
122
    {
123
        $amount = count($this->commands);
124
        if ($amount < 1) {
125
            throw new Exception('no command to execute');
126
        }
127
        $cmd = ($amount > 1 ? '(' . implode(' && ', $this->commands) . ')' : $this->commands[0])
128
             . $this->getPipeline()
129
             . (!empty($this->redirectOutput) ? ' > ' . $this->redirectOutput : '');
130
131
        return $cmd;
132
    }
133
134
    /**
135
     * Executes the commands.
136
     *
137
     * @return \phpbu\App\Cli\Result
138
     * @throws \phpbu\App\Exception
139
     */
140
    public function run()
141
    {
142
        $cmd            = $this->getCommandLine();
143
        $old            = error_reporting(0);
144
        $descriptorSpec = [
145
            ['pipe', 'r'],
146
            ['pipe', 'w'],
147
            ['pipe', 'w'],
148
        ];
149
150
        $process = proc_open($cmd, $descriptorSpec, $pipes);
151
        if (!is_resource($process)) {
152
            throw new Exception('can\'t execute \'proc_open\'');
153
        }
154
155
        $stdOut = stream_get_contents($pipes[1]);
156
        fclose($pipes[1]);
157
158
        $stdErr = stream_get_contents($pipes[2]);
159
        fclose($pipes[2]);
160
161
        $code = proc_close($process);
162
        error_reporting($old);
163
164
        return new Result($cmd, $code, $stdOut, $stdErr);
165
    }
166
}
167