PluginProbe
Depicter — Popup & Slider Builder / 1.3.2
Depicter — Popup & Slider Builder v1.3.2
4.8.1 trunk 1.0.0 1.1.0 1.1.2 1.1.4 1.1.6 1.1.7 1.1.8 1.1.9 1.2.0 1.3.0 1.3.1 1.3.2 1.3.3 1.3.5 1.3.8 1.5.0 1.5.1 1.5.2 1.5.5 1.6.0 1.6.1 1.6.2 1.7.0 All 76 releases
depicter / vendor / symfony / console / Output / ConsoleSectionOutput.php

ConsoleSectionOutput.php in Depicter — Popup & Slider Builder 1.3.2, at vendor/symfony/console/Output/ConsoleSectionOutput.php

144 lines 4.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
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
12 namespace Symfony\Component\Console\Output;
13
14 use Symfony\Component\Console\Formatter\OutputFormatterInterface;
15 use Symfony\Component\Console\Helper\Helper;
16 use Symfony\Component\Console\Terminal;
17
18 /**
19 * @author Pierre du Plessis <pdples@gmail.com>
20 * @author Gabriel Ostrolucký <gabriel.ostrolucky@gmail.com>
21 */
22 class ConsoleSectionOutput extends StreamOutput
23 {
24 private $content = [];
25 private $lines = 0;
26 private $sections;
27 private $terminal;
28
29 /**
30 * @param resource $stream
31 * @param ConsoleSectionOutput[] $sections
32 */
33 public function __construct($stream, array &$sections, int $verbosity, bool $decorated, OutputFormatterInterface $formatter)
34 {
35 parent::__construct($stream, $verbosity, $decorated, $formatter);
36 array_unshift($sections, $this);
37 $this->sections = &$sections;
38 $this->terminal = new Terminal();
39 }
40
41 /**
42 * Clears previous output for this section.
43 *
44 * @param int $lines Number of lines to clear. If null, then the entire output of this section is cleared
45 */
46 public function clear(int $lines = null)
47 {
48 if (empty($this->content) || !$this->isDecorated()) {
49 return;
50 }
51
52 if ($lines) {
53 array_splice($this->content, -($lines * 2)); // Multiply lines by 2 to cater for each new line added between content
54 } else {
55 $lines = $this->lines;
56 $this->content = [];
57 }
58
59 $this->lines -= $lines;
60
61 parent::doWrite($this->popStreamContentUntilCurrentSection($lines), false);
62 }
63
64 /**
65 * Overwrites the previous output with a new message.
66 *
67 * @param array|string $message
68 */
69 public function overwrite($message)
70 {
71 $this->clear();
72 $this->writeln($message);
73 }
74
75 public function getContent(): string
76 {
77 return implode('', $this->content);
78 }
79
80 /**
81 * @internal
82 */
83 public function addContent(string $input)
84 {
85 foreach (explode(\PHP_EOL, $input) as $lineContent) {
86 $this->lines += ceil($this->getDisplayLength($lineContent) / $this->terminal->getWidth()) ?: 1;
87 $this->content[] = $lineContent;
88 $this->content[] = \PHP_EOL;
89 }
90 }
91
92 /**
93 * {@inheritdoc}
94 */
95 protected function doWrite($message, $newline)
96 {
97 if (!$this->isDecorated()) {
98 parent::doWrite($message, $newline);
99
100 return;
101 }
102
103 $erasedContent = $this->popStreamContentUntilCurrentSection();
104
105 $this->addContent($message);
106
107 parent::doWrite($message, true);
108 parent::doWrite($erasedContent, false);
109 }
110
111 /**
112 * At initial stage, cursor is at the end of stream output. This method makes cursor crawl upwards until it hits
113 * current section. Then it erases content it crawled through. Optionally, it erases part of current section too.
114 */
115 private function popStreamContentUntilCurrentSection(int $numberOfLinesToClearFromCurrentSection = 0): string
116 {
117 $numberOfLinesToClear = $numberOfLinesToClearFromCurrentSection;
118 $erasedContent = [];
119
120 foreach ($this->sections as $section) {
121 if ($section === $this) {
122 break;
123 }
124
125 $numberOfLinesToClear += $section->lines;
126 $erasedContent[] = $section->getContent();
127 }
128
129 if ($numberOfLinesToClear > 0) {
130 // move cursor up n lines
131 parent::doWrite(sprintf("\x1b[%dA", $numberOfLinesToClear), false);
132 // erase to end of screen
133 parent::doWrite("\x1b[0J", false);
134 }
135
136 return implode('', array_reverse($erasedContent));
137 }
138
139 private function getDisplayLength(string $text): string
140 {
141 return Helper::strlenWithoutDecoration($this->getFormatter(), str_replace("\t", ' ', $text));
142 }
143 }
144