4 * This file is part of the Symfony package.
6 * (c) Fabien Potencier <fabien@symfony.com>
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
12 namespace Symfony\Component\Finder\Shell;
14 @trigger_error('The '.__NAMESPACE__.'\Command class is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
17 * @author Jean-François Simon <contact@jfsimon.fr>
19 * @deprecated since 2.8, to be removed in 3.0.
31 private $bits = array();
36 private $labels = array();
41 private $errorHandler;
46 * @param Command|null $parent Parent command
48 public function __construct(Command $parent = null)
50 $this->parent = $parent;
54 * Returns command as string.
58 public function __toString()
64 * Creates a new Command instance.
66 * @param Command|null $parent Parent command
70 public static function create(Command $parent = null)
72 return new self($parent);
76 * Escapes special chars from input.
78 * @param string $input A string to escape
80 * @return string The escaped string
82 public static function escape($input)
84 return escapeshellcmd($input);
90 * @param string $input An argument string
92 * @return string The quoted string
94 public static function quote($input)
96 return escapeshellarg($input);
100 * Appends a string or a Command instance.
102 * @param string|Command $bit
106 public function add($bit)
108 $this->bits[] = $bit;
114 * Prepends a string or a command instance.
116 * @param string|Command $bit
120 public function top($bit)
122 array_unshift($this->bits, $bit);
124 foreach ($this->labels as $label => $index) {
125 $this->labels[$label] += 1;
132 * Appends an argument, will be quoted.
138 public function arg($arg)
140 $this->bits[] = self::quote($arg);
146 * Appends escaped special command chars.
152 public function cmd($esc)
154 $this->bits[] = self::escape($esc);
160 * Inserts a labeled command to feed later.
162 * @param string $label The unique label
164 * @return self|string
166 * @throws \RuntimeException If label already exists
168 public function ins($label)
170 if (isset($this->labels[$label])) {
171 throw new \RuntimeException(sprintf('Label "%s" already exists.', $label));
174 $this->bits[] = self::create($this);
175 $this->labels[$label] = count($this->bits) - 1;
177 return $this->bits[$this->labels[$label]];
181 * Retrieves a previously labeled command.
183 * @param string $label
185 * @return self|string
187 * @throws \RuntimeException
189 public function get($label)
191 if (!isset($this->labels[$label])) {
192 throw new \RuntimeException(sprintf('Label "%s" does not exist.', $label));
195 return $this->bits[$this->labels[$label]];
199 * Returns parent command (if any).
203 * @throws \RuntimeException If command has no parent
205 public function end()
207 if (null === $this->parent) {
208 throw new \RuntimeException('Calling end on root command doesn\'t make sense.');
211 return $this->parent;
215 * Counts bits stored in command.
217 * @return int The bits count
219 public function length()
221 return count($this->bits);
225 * @param \Closure $errorHandler
229 public function setErrorHandler(\Closure $errorHandler)
231 $this->errorHandler = $errorHandler;
237 * @return \Closure|null
239 public function getErrorHandler()
241 return $this->errorHandler;
245 * Executes current command.
247 * @return array The command result
249 * @throws \RuntimeException
251 public function execute()
253 if (null === $errorHandler = $this->errorHandler) {
254 exec($this->join(), $output);
256 $process = proc_open($this->join(), array(0 => array('pipe', 'r'), 1 => array('pipe', 'w'), 2 => array('pipe', 'w')), $pipes);
257 $output = preg_split('~(\r\n|\r|\n)~', stream_get_contents($pipes[1]), -1, PREG_SPLIT_NO_EMPTY);
259 if ($error = stream_get_contents($pipes[2])) {
260 $errorHandler($error);
263 proc_close($process);
266 return $output ?: array();
274 public function join()
276 return implode(' ', array_filter(
277 array_map(function ($bit) {
278 return $bit instanceof Command ? $bit->join() : ($bit ?: null);
280 function ($bit) { return null !== $bit; }
285 * Insert a string or a Command instance before the bit at given position $index (index starts from 0).
287 * @param string|Command $bit
292 public function addAtIndex($bit, $index)
294 array_splice($this->bits, $index, 0, $bit instanceof self ? array($bit) : $bit);