1<?php
2
3/*
4 * This file is part of the Symfony package.
5 *
6 * (c) Fabien Potencier <fabien@symfony.com>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12namespace Symfony\Component\Console\Helper;
13
14/**
15 * Helps outputting debug information when running an external program from a command.
16 *
17 * An external program can be a Process, an HTTP request, or anything else.
18 *
19 * @author Fabien Potencier <fabien@symfony.com>
20 */
21class DebugFormatterHelper extends Helper
22{
23    private $colors = ['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white', 'default'];
24    private $started = [];
25    private $count = -1;
26
27    /**
28     * Starts a debug formatting session.
29     *
30     * @return string
31     */
32    public function start(string $id, string $message, string $prefix = 'RUN')
33    {
34        $this->started[$id] = ['border' => ++$this->count % \count($this->colors)];
35
36        return sprintf("%s<bg=blue;fg=white> %s </> <fg=blue>%s</>\n", $this->getBorder($id), $prefix, $message);
37    }
38
39    /**
40     * Adds progress to a formatting session.
41     *
42     * @return string
43     */
44    public function progress(string $id, string $buffer, bool $error = false, string $prefix = 'OUT', string $errorPrefix = 'ERR')
45    {
46        $message = '';
47
48        if ($error) {
49            if (isset($this->started[$id]['out'])) {
50                $message .= "\n";
51                unset($this->started[$id]['out']);
52            }
53            if (!isset($this->started[$id]['err'])) {
54                $message .= sprintf('%s<bg=red;fg=white> %s </> ', $this->getBorder($id), $errorPrefix);
55                $this->started[$id]['err'] = true;
56            }
57
58            $message .= str_replace("\n", sprintf("\n%s<bg=red;fg=white> %s </> ", $this->getBorder($id), $errorPrefix), $buffer);
59        } else {
60            if (isset($this->started[$id]['err'])) {
61                $message .= "\n";
62                unset($this->started[$id]['err']);
63            }
64            if (!isset($this->started[$id]['out'])) {
65                $message .= sprintf('%s<bg=green;fg=white> %s </> ', $this->getBorder($id), $prefix);
66                $this->started[$id]['out'] = true;
67            }
68
69            $message .= str_replace("\n", sprintf("\n%s<bg=green;fg=white> %s </> ", $this->getBorder($id), $prefix), $buffer);
70        }
71
72        return $message;
73    }
74
75    /**
76     * Stops a formatting session.
77     *
78     * @return string
79     */
80    public function stop(string $id, string $message, bool $successful, string $prefix = 'RES')
81    {
82        $trailingEOL = isset($this->started[$id]['out']) || isset($this->started[$id]['err']) ? "\n" : '';
83
84        if ($successful) {
85            return sprintf("%s%s<bg=green;fg=white> %s </> <fg=green>%s</>\n", $trailingEOL, $this->getBorder($id), $prefix, $message);
86        }
87
88        $message = sprintf("%s%s<bg=red;fg=white> %s </> <fg=red>%s</>\n", $trailingEOL, $this->getBorder($id), $prefix, $message);
89
90        unset($this->started[$id]['out'], $this->started[$id]['err']);
91
92        return $message;
93    }
94
95    private function getBorder(string $id): string
96    {
97        return sprintf('<bg=%s> </>', $this->colors[$this->started[$id]['border']]);
98    }
99
100    /**
101     * {@inheritdoc}
102     */
103    public function getName()
104    {
105        return 'debug_formatter';
106    }
107}
108