first commit
This commit is contained in:
		
							
								
								
									
										127
									
								
								vendor/symfony/console/Helper/DebugFormatterHelper.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										127
									
								
								vendor/symfony/console/Helper/DebugFormatterHelper.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,127 @@ | ||||
| <?php | ||||
|  | ||||
| /* | ||||
|  * This file is part of the Symfony package. | ||||
|  * | ||||
|  * (c) Fabien Potencier <fabien@symfony.com> | ||||
|  * | ||||
|  * For the full copyright and license information, please view the LICENSE | ||||
|  * file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| namespace Symfony\Component\Console\Helper; | ||||
|  | ||||
| /** | ||||
|  * Helps outputting debug information when running an external program from a command. | ||||
|  * | ||||
|  * An external program can be a Process, an HTTP request, or anything else. | ||||
|  * | ||||
|  * @author Fabien Potencier <fabien@symfony.com> | ||||
|  */ | ||||
| class DebugFormatterHelper extends Helper | ||||
| { | ||||
|     private $colors = ['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white', 'default']; | ||||
|     private $started = []; | ||||
|     private $count = -1; | ||||
|  | ||||
|     /** | ||||
|      * Starts a debug formatting session. | ||||
|      * | ||||
|      * @param string $id      The id of the formatting session | ||||
|      * @param string $message The message to display | ||||
|      * @param string $prefix  The prefix to use | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     public function start($id, $message, $prefix = 'RUN') | ||||
|     { | ||||
|         $this->started[$id] = ['border' => ++$this->count % \count($this->colors)]; | ||||
|  | ||||
|         return sprintf("%s<bg=blue;fg=white> %s </> <fg=blue>%s</>\n", $this->getBorder($id), $prefix, $message); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Adds progress to a formatting session. | ||||
|      * | ||||
|      * @param string $id          The id of the formatting session | ||||
|      * @param string $buffer      The message to display | ||||
|      * @param bool   $error       Whether to consider the buffer as error | ||||
|      * @param string $prefix      The prefix for output | ||||
|      * @param string $errorPrefix The prefix for error output | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     public function progress($id, $buffer, $error = false, $prefix = 'OUT', $errorPrefix = 'ERR') | ||||
|     { | ||||
|         $message = ''; | ||||
|  | ||||
|         if ($error) { | ||||
|             if (isset($this->started[$id]['out'])) { | ||||
|                 $message .= "\n"; | ||||
|                 unset($this->started[$id]['out']); | ||||
|             } | ||||
|             if (!isset($this->started[$id]['err'])) { | ||||
|                 $message .= sprintf('%s<bg=red;fg=white> %s </> ', $this->getBorder($id), $errorPrefix); | ||||
|                 $this->started[$id]['err'] = true; | ||||
|             } | ||||
|  | ||||
|             $message .= str_replace("\n", sprintf("\n%s<bg=red;fg=white> %s </> ", $this->getBorder($id), $errorPrefix), $buffer); | ||||
|         } else { | ||||
|             if (isset($this->started[$id]['err'])) { | ||||
|                 $message .= "\n"; | ||||
|                 unset($this->started[$id]['err']); | ||||
|             } | ||||
|             if (!isset($this->started[$id]['out'])) { | ||||
|                 $message .= sprintf('%s<bg=green;fg=white> %s </> ', $this->getBorder($id), $prefix); | ||||
|                 $this->started[$id]['out'] = true; | ||||
|             } | ||||
|  | ||||
|             $message .= str_replace("\n", sprintf("\n%s<bg=green;fg=white> %s </> ", $this->getBorder($id), $prefix), $buffer); | ||||
|         } | ||||
|  | ||||
|         return $message; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Stops a formatting session. | ||||
|      * | ||||
|      * @param string $id         The id of the formatting session | ||||
|      * @param string $message    The message to display | ||||
|      * @param bool   $successful Whether to consider the result as success | ||||
|      * @param string $prefix     The prefix for the end output | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     public function stop($id, $message, $successful, $prefix = 'RES') | ||||
|     { | ||||
|         $trailingEOL = isset($this->started[$id]['out']) || isset($this->started[$id]['err']) ? "\n" : ''; | ||||
|  | ||||
|         if ($successful) { | ||||
|             return sprintf("%s%s<bg=green;fg=white> %s </> <fg=green>%s</>\n", $trailingEOL, $this->getBorder($id), $prefix, $message); | ||||
|         } | ||||
|  | ||||
|         $message = sprintf("%s%s<bg=red;fg=white> %s </> <fg=red>%s</>\n", $trailingEOL, $this->getBorder($id), $prefix, $message); | ||||
|  | ||||
|         unset($this->started[$id]['out'], $this->started[$id]['err']); | ||||
|  | ||||
|         return $message; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param string $id The id of the formatting session | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     private function getBorder($id) | ||||
|     { | ||||
|         return sprintf('<bg=%s> </>', $this->colors[$this->started[$id]['border']]); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * {@inheritdoc} | ||||
|      */ | ||||
|     public function getName() | ||||
|     { | ||||
|         return 'debug_formatter'; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										94
									
								
								vendor/symfony/console/Helper/DescriptorHelper.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								vendor/symfony/console/Helper/DescriptorHelper.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,94 @@ | ||||
| <?php | ||||
|  | ||||
| /* | ||||
|  * This file is part of the Symfony package. | ||||
|  * | ||||
|  * (c) Fabien Potencier <fabien@symfony.com> | ||||
|  * | ||||
|  * For the full copyright and license information, please view the LICENSE | ||||
|  * file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| namespace Symfony\Component\Console\Helper; | ||||
|  | ||||
| use Symfony\Component\Console\Descriptor\DescriptorInterface; | ||||
| use Symfony\Component\Console\Descriptor\JsonDescriptor; | ||||
| use Symfony\Component\Console\Descriptor\MarkdownDescriptor; | ||||
| use Symfony\Component\Console\Descriptor\TextDescriptor; | ||||
| use Symfony\Component\Console\Descriptor\XmlDescriptor; | ||||
| use Symfony\Component\Console\Exception\InvalidArgumentException; | ||||
| use Symfony\Component\Console\Output\OutputInterface; | ||||
|  | ||||
| /** | ||||
|  * This class adds helper method to describe objects in various formats. | ||||
|  * | ||||
|  * @author Jean-François Simon <contact@jfsimon.fr> | ||||
|  */ | ||||
| class DescriptorHelper extends Helper | ||||
| { | ||||
|     /** | ||||
|      * @var DescriptorInterface[] | ||||
|      */ | ||||
|     private $descriptors = []; | ||||
|  | ||||
|     public function __construct() | ||||
|     { | ||||
|         $this | ||||
|             ->register('txt', new TextDescriptor()) | ||||
|             ->register('xml', new XmlDescriptor()) | ||||
|             ->register('json', new JsonDescriptor()) | ||||
|             ->register('md', new MarkdownDescriptor()) | ||||
|         ; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Describes an object if supported. | ||||
|      * | ||||
|      * Available options are: | ||||
|      * * format: string, the output format name | ||||
|      * * raw_text: boolean, sets output type as raw | ||||
|      * | ||||
|      * @param OutputInterface $output | ||||
|      * @param object          $object | ||||
|      * @param array           $options | ||||
|      * | ||||
|      * @throws InvalidArgumentException when the given format is not supported | ||||
|      */ | ||||
|     public function describe(OutputInterface $output, $object, array $options = []) | ||||
|     { | ||||
|         $options = array_merge([ | ||||
|             'raw_text' => false, | ||||
|             'format' => 'txt', | ||||
|         ], $options); | ||||
|  | ||||
|         if (!isset($this->descriptors[$options['format']])) { | ||||
|             throw new InvalidArgumentException(sprintf('Unsupported format "%s".', $options['format'])); | ||||
|         } | ||||
|  | ||||
|         $descriptor = $this->descriptors[$options['format']]; | ||||
|         $descriptor->describe($output, $object, $options); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Registers a descriptor. | ||||
|      * | ||||
|      * @param string              $format | ||||
|      * @param DescriptorInterface $descriptor | ||||
|      * | ||||
|      * @return $this | ||||
|      */ | ||||
|     public function register($format, DescriptorInterface $descriptor) | ||||
|     { | ||||
|         $this->descriptors[$format] = $descriptor; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * {@inheritdoc} | ||||
|      */ | ||||
|     public function getName() | ||||
|     { | ||||
|         return 'descriptor'; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										106
									
								
								vendor/symfony/console/Helper/FormatterHelper.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								vendor/symfony/console/Helper/FormatterHelper.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,106 @@ | ||||
| <?php | ||||
|  | ||||
| /* | ||||
|  * This file is part of the Symfony package. | ||||
|  * | ||||
|  * (c) Fabien Potencier <fabien@symfony.com> | ||||
|  * | ||||
|  * For the full copyright and license information, please view the LICENSE | ||||
|  * file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| namespace Symfony\Component\Console\Helper; | ||||
|  | ||||
| use Symfony\Component\Console\Formatter\OutputFormatter; | ||||
|  | ||||
| /** | ||||
|  * The Formatter class provides helpers to format messages. | ||||
|  * | ||||
|  * @author Fabien Potencier <fabien@symfony.com> | ||||
|  */ | ||||
| class FormatterHelper extends Helper | ||||
| { | ||||
|     /** | ||||
|      * Formats a message within a section. | ||||
|      * | ||||
|      * @param string $section The section name | ||||
|      * @param string $message The message | ||||
|      * @param string $style   The style to apply to the section | ||||
|      * | ||||
|      * @return string The format section | ||||
|      */ | ||||
|     public function formatSection($section, $message, $style = 'info') | ||||
|     { | ||||
|         return sprintf('<%s>[%s]</%s> %s', $style, $section, $style, $message); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Formats a message as a block of text. | ||||
|      * | ||||
|      * @param string|array $messages The message to write in the block | ||||
|      * @param string       $style    The style to apply to the whole block | ||||
|      * @param bool         $large    Whether to return a large block | ||||
|      * | ||||
|      * @return string The formatter message | ||||
|      */ | ||||
|     public function formatBlock($messages, $style, $large = false) | ||||
|     { | ||||
|         if (!\is_array($messages)) { | ||||
|             $messages = [$messages]; | ||||
|         } | ||||
|  | ||||
|         $len = 0; | ||||
|         $lines = []; | ||||
|         foreach ($messages as $message) { | ||||
|             $message = OutputFormatter::escape($message); | ||||
|             $lines[] = sprintf($large ? '  %s  ' : ' %s ', $message); | ||||
|             $len = max($this->strlen($message) + ($large ? 4 : 2), $len); | ||||
|         } | ||||
|  | ||||
|         $messages = $large ? [str_repeat(' ', $len)] : []; | ||||
|         for ($i = 0; isset($lines[$i]); ++$i) { | ||||
|             $messages[] = $lines[$i].str_repeat(' ', $len - $this->strlen($lines[$i])); | ||||
|         } | ||||
|         if ($large) { | ||||
|             $messages[] = str_repeat(' ', $len); | ||||
|         } | ||||
|  | ||||
|         for ($i = 0; isset($messages[$i]); ++$i) { | ||||
|             $messages[$i] = sprintf('<%s>%s</%s>', $style, $messages[$i], $style); | ||||
|         } | ||||
|  | ||||
|         return implode("\n", $messages); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Truncates a message to the given length. | ||||
|      * | ||||
|      * @param string $message | ||||
|      * @param int    $length | ||||
|      * @param string $suffix | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     public function truncate($message, $length, $suffix = '...') | ||||
|     { | ||||
|         $computedLength = $length - $this->strlen($suffix); | ||||
|  | ||||
|         if ($computedLength > $this->strlen($message)) { | ||||
|             return $message; | ||||
|         } | ||||
|  | ||||
|         if (false === $encoding = mb_detect_encoding($message, null, true)) { | ||||
|             return substr($message, 0, $length).$suffix; | ||||
|         } | ||||
|  | ||||
|         return mb_substr($message, 0, $length, $encoding).$suffix; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * {@inheritdoc} | ||||
|      */ | ||||
|     public function getName() | ||||
|     { | ||||
|         return 'formatter'; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										138
									
								
								vendor/symfony/console/Helper/Helper.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										138
									
								
								vendor/symfony/console/Helper/Helper.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,138 @@ | ||||
| <?php | ||||
|  | ||||
| /* | ||||
|  * This file is part of the Symfony package. | ||||
|  * | ||||
|  * (c) Fabien Potencier <fabien@symfony.com> | ||||
|  * | ||||
|  * For the full copyright and license information, please view the LICENSE | ||||
|  * file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| namespace Symfony\Component\Console\Helper; | ||||
|  | ||||
| use Symfony\Component\Console\Formatter\OutputFormatterInterface; | ||||
|  | ||||
| /** | ||||
|  * Helper is the base class for all helper classes. | ||||
|  * | ||||
|  * @author Fabien Potencier <fabien@symfony.com> | ||||
|  */ | ||||
| abstract class Helper implements HelperInterface | ||||
| { | ||||
|     protected $helperSet = null; | ||||
|  | ||||
|     /** | ||||
|      * {@inheritdoc} | ||||
|      */ | ||||
|     public function setHelperSet(HelperSet $helperSet = null) | ||||
|     { | ||||
|         $this->helperSet = $helperSet; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * {@inheritdoc} | ||||
|      */ | ||||
|     public function getHelperSet() | ||||
|     { | ||||
|         return $this->helperSet; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Returns the length of a string, using mb_strwidth if it is available. | ||||
|      * | ||||
|      * @param string $string The string to check its length | ||||
|      * | ||||
|      * @return int The length of the string | ||||
|      */ | ||||
|     public static function strlen($string) | ||||
|     { | ||||
|         if (false === $encoding = mb_detect_encoding($string, null, true)) { | ||||
|             return \strlen($string); | ||||
|         } | ||||
|  | ||||
|         return mb_strwidth($string, $encoding); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Returns the subset of a string, using mb_substr if it is available. | ||||
|      * | ||||
|      * @param string   $string String to subset | ||||
|      * @param int      $from   Start offset | ||||
|      * @param int|null $length Length to read | ||||
|      * | ||||
|      * @return string The string subset | ||||
|      */ | ||||
|     public static function substr($string, $from, $length = null) | ||||
|     { | ||||
|         if (false === $encoding = mb_detect_encoding($string, null, true)) { | ||||
|             return substr($string, $from, $length); | ||||
|         } | ||||
|  | ||||
|         return mb_substr($string, $from, $length, $encoding); | ||||
|     } | ||||
|  | ||||
|     public static function formatTime($secs) | ||||
|     { | ||||
|         static $timeFormats = [ | ||||
|             [0, '< 1 sec'], | ||||
|             [1, '1 sec'], | ||||
|             [2, 'secs', 1], | ||||
|             [60, '1 min'], | ||||
|             [120, 'mins', 60], | ||||
|             [3600, '1 hr'], | ||||
|             [7200, 'hrs', 3600], | ||||
|             [86400, '1 day'], | ||||
|             [172800, 'days', 86400], | ||||
|         ]; | ||||
|  | ||||
|         foreach ($timeFormats as $index => $format) { | ||||
|             if ($secs >= $format[0]) { | ||||
|                 if ((isset($timeFormats[$index + 1]) && $secs < $timeFormats[$index + 1][0]) | ||||
|                     || $index == \count($timeFormats) - 1 | ||||
|                 ) { | ||||
|                     if (2 == \count($format)) { | ||||
|                         return $format[1]; | ||||
|                     } | ||||
|  | ||||
|                     return floor($secs / $format[2]).' '.$format[1]; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public static function formatMemory($memory) | ||||
|     { | ||||
|         if ($memory >= 1024 * 1024 * 1024) { | ||||
|             return sprintf('%.1f GiB', $memory / 1024 / 1024 / 1024); | ||||
|         } | ||||
|  | ||||
|         if ($memory >= 1024 * 1024) { | ||||
|             return sprintf('%.1f MiB', $memory / 1024 / 1024); | ||||
|         } | ||||
|  | ||||
|         if ($memory >= 1024) { | ||||
|             return sprintf('%d KiB', $memory / 1024); | ||||
|         } | ||||
|  | ||||
|         return sprintf('%d B', $memory); | ||||
|     } | ||||
|  | ||||
|     public static function strlenWithoutDecoration(OutputFormatterInterface $formatter, $string) | ||||
|     { | ||||
|         return self::strlen(self::removeDecoration($formatter, $string)); | ||||
|     } | ||||
|  | ||||
|     public static function removeDecoration(OutputFormatterInterface $formatter, $string) | ||||
|     { | ||||
|         $isDecorated = $formatter->isDecorated(); | ||||
|         $formatter->setDecorated(false); | ||||
|         // remove <...> formatting | ||||
|         $string = $formatter->format($string); | ||||
|         // remove already formatted characters | ||||
|         $string = preg_replace("/\033\[[^m]*m/", '', $string); | ||||
|         $formatter->setDecorated($isDecorated); | ||||
|  | ||||
|         return $string; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										39
									
								
								vendor/symfony/console/Helper/HelperInterface.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								vendor/symfony/console/Helper/HelperInterface.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | ||||
| <?php | ||||
|  | ||||
| /* | ||||
|  * This file is part of the Symfony package. | ||||
|  * | ||||
|  * (c) Fabien Potencier <fabien@symfony.com> | ||||
|  * | ||||
|  * For the full copyright and license information, please view the LICENSE | ||||
|  * file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| namespace Symfony\Component\Console\Helper; | ||||
|  | ||||
| /** | ||||
|  * HelperInterface is the interface all helpers must implement. | ||||
|  * | ||||
|  * @author Fabien Potencier <fabien@symfony.com> | ||||
|  */ | ||||
| interface HelperInterface | ||||
| { | ||||
|     /** | ||||
|      * Sets the helper set associated with this helper. | ||||
|      */ | ||||
|     public function setHelperSet(HelperSet $helperSet = null); | ||||
|  | ||||
|     /** | ||||
|      * Gets the helper set associated with this helper. | ||||
|      * | ||||
|      * @return HelperSet A HelperSet instance | ||||
|      */ | ||||
|     public function getHelperSet(); | ||||
|  | ||||
|     /** | ||||
|      * Returns the canonical name of this helper. | ||||
|      * | ||||
|      * @return string The canonical name | ||||
|      */ | ||||
|     public function getName(); | ||||
| } | ||||
							
								
								
									
										108
									
								
								vendor/symfony/console/Helper/HelperSet.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								vendor/symfony/console/Helper/HelperSet.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,108 @@ | ||||
| <?php | ||||
|  | ||||
| /* | ||||
|  * This file is part of the Symfony package. | ||||
|  * | ||||
|  * (c) Fabien Potencier <fabien@symfony.com> | ||||
|  * | ||||
|  * For the full copyright and license information, please view the LICENSE | ||||
|  * file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| namespace Symfony\Component\Console\Helper; | ||||
|  | ||||
| use Symfony\Component\Console\Command\Command; | ||||
| use Symfony\Component\Console\Exception\InvalidArgumentException; | ||||
|  | ||||
| /** | ||||
|  * HelperSet represents a set of helpers to be used with a command. | ||||
|  * | ||||
|  * @author Fabien Potencier <fabien@symfony.com> | ||||
|  */ | ||||
| class HelperSet implements \IteratorAggregate | ||||
| { | ||||
|     /** | ||||
|      * @var Helper[] | ||||
|      */ | ||||
|     private $helpers = []; | ||||
|     private $command; | ||||
|  | ||||
|     /** | ||||
|      * @param Helper[] $helpers An array of helper | ||||
|      */ | ||||
|     public function __construct(array $helpers = []) | ||||
|     { | ||||
|         foreach ($helpers as $alias => $helper) { | ||||
|             $this->set($helper, \is_int($alias) ? null : $alias); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Sets a helper. | ||||
|      * | ||||
|      * @param HelperInterface $helper The helper instance | ||||
|      * @param string          $alias  An alias | ||||
|      */ | ||||
|     public function set(HelperInterface $helper, $alias = null) | ||||
|     { | ||||
|         $this->helpers[$helper->getName()] = $helper; | ||||
|         if (null !== $alias) { | ||||
|             $this->helpers[$alias] = $helper; | ||||
|         } | ||||
|  | ||||
|         $helper->setHelperSet($this); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Returns true if the helper if defined. | ||||
|      * | ||||
|      * @param string $name The helper name | ||||
|      * | ||||
|      * @return bool true if the helper is defined, false otherwise | ||||
|      */ | ||||
|     public function has($name) | ||||
|     { | ||||
|         return isset($this->helpers[$name]); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Gets a helper value. | ||||
|      * | ||||
|      * @param string $name The helper name | ||||
|      * | ||||
|      * @return HelperInterface The helper instance | ||||
|      * | ||||
|      * @throws InvalidArgumentException if the helper is not defined | ||||
|      */ | ||||
|     public function get($name) | ||||
|     { | ||||
|         if (!$this->has($name)) { | ||||
|             throw new InvalidArgumentException(sprintf('The helper "%s" is not defined.', $name)); | ||||
|         } | ||||
|  | ||||
|         return $this->helpers[$name]; | ||||
|     } | ||||
|  | ||||
|     public function setCommand(Command $command = null) | ||||
|     { | ||||
|         $this->command = $command; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Gets the command associated with this helper set. | ||||
|      * | ||||
|      * @return Command A Command instance | ||||
|      */ | ||||
|     public function getCommand() | ||||
|     { | ||||
|         return $this->command; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return Helper[] | ||||
|      */ | ||||
|     public function getIterator() | ||||
|     { | ||||
|         return new \ArrayIterator($this->helpers); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										33
									
								
								vendor/symfony/console/Helper/InputAwareHelper.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								vendor/symfony/console/Helper/InputAwareHelper.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,33 @@ | ||||
| <?php | ||||
|  | ||||
| /* | ||||
|  * This file is part of the Symfony package. | ||||
|  * | ||||
|  * (c) Fabien Potencier <fabien@symfony.com> | ||||
|  * | ||||
|  * For the full copyright and license information, please view the LICENSE | ||||
|  * file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| namespace Symfony\Component\Console\Helper; | ||||
|  | ||||
| use Symfony\Component\Console\Input\InputAwareInterface; | ||||
| use Symfony\Component\Console\Input\InputInterface; | ||||
|  | ||||
| /** | ||||
|  * An implementation of InputAwareInterface for Helpers. | ||||
|  * | ||||
|  * @author Wouter J <waldio.webdesign@gmail.com> | ||||
|  */ | ||||
| abstract class InputAwareHelper extends Helper implements InputAwareInterface | ||||
| { | ||||
|     protected $input; | ||||
|  | ||||
|     /** | ||||
|      * {@inheritdoc} | ||||
|      */ | ||||
|     public function setInput(InputInterface $input) | ||||
|     { | ||||
|         $this->input = $input; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										156
									
								
								vendor/symfony/console/Helper/ProcessHelper.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										156
									
								
								vendor/symfony/console/Helper/ProcessHelper.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,156 @@ | ||||
| <?php | ||||
|  | ||||
| /* | ||||
|  * This file is part of the Symfony package. | ||||
|  * | ||||
|  * (c) Fabien Potencier <fabien@symfony.com> | ||||
|  * | ||||
|  * For the full copyright and license information, please view the LICENSE | ||||
|  * file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| namespace Symfony\Component\Console\Helper; | ||||
|  | ||||
| use Symfony\Component\Console\Output\ConsoleOutputInterface; | ||||
| use Symfony\Component\Console\Output\OutputInterface; | ||||
| use Symfony\Component\Process\Exception\ProcessFailedException; | ||||
| use Symfony\Component\Process\Process; | ||||
|  | ||||
| /** | ||||
|  * The ProcessHelper class provides helpers to run external processes. | ||||
|  * | ||||
|  * @author Fabien Potencier <fabien@symfony.com> | ||||
|  * | ||||
|  * @final since Symfony 4.2 | ||||
|  */ | ||||
| class ProcessHelper extends Helper | ||||
| { | ||||
|     /** | ||||
|      * Runs an external process. | ||||
|      * | ||||
|      * @param OutputInterface $output    An OutputInterface instance | ||||
|      * @param array|Process   $cmd       An instance of Process or an array of the command and arguments | ||||
|      * @param string|null     $error     An error message that must be displayed if something went wrong | ||||
|      * @param callable|null   $callback  A PHP callback to run whenever there is some | ||||
|      *                                   output available on STDOUT or STDERR | ||||
|      * @param int             $verbosity The threshold for verbosity | ||||
|      * | ||||
|      * @return Process The process that ran | ||||
|      */ | ||||
|     public function run(OutputInterface $output, $cmd, $error = null, callable $callback = null, $verbosity = OutputInterface::VERBOSITY_VERY_VERBOSE) | ||||
|     { | ||||
|         if ($output instanceof ConsoleOutputInterface) { | ||||
|             $output = $output->getErrorOutput(); | ||||
|         } | ||||
|  | ||||
|         $formatter = $this->getHelperSet()->get('debug_formatter'); | ||||
|  | ||||
|         if ($cmd instanceof Process) { | ||||
|             $cmd = [$cmd]; | ||||
|         } | ||||
|  | ||||
|         if (!\is_array($cmd)) { | ||||
|             @trigger_error(sprintf('Passing a command as a string to "%s()" is deprecated since Symfony 4.2, pass it the command as an array of arguments instead.', __METHOD__), E_USER_DEPRECATED); | ||||
|             $cmd = [method_exists(Process::class, 'fromShellCommandline') ? Process::fromShellCommandline($cmd) : new Process($cmd)]; | ||||
|         } | ||||
|  | ||||
|         if (\is_string($cmd[0] ?? null)) { | ||||
|             $process = new Process($cmd); | ||||
|             $cmd = []; | ||||
|         } elseif (($cmd[0] ?? null) instanceof Process) { | ||||
|             $process = $cmd[0]; | ||||
|             unset($cmd[0]); | ||||
|         } else { | ||||
|             throw new \InvalidArgumentException(sprintf('Invalid command provided to "%s()": the command should be an array whose first element is either the path to the binary to run or a "Process" object.', __METHOD__)); | ||||
|         } | ||||
|  | ||||
|         if ($verbosity <= $output->getVerbosity()) { | ||||
|             $output->write($formatter->start(spl_object_hash($process), $this->escapeString($process->getCommandLine()))); | ||||
|         } | ||||
|  | ||||
|         if ($output->isDebug()) { | ||||
|             $callback = $this->wrapCallback($output, $process, $callback); | ||||
|         } | ||||
|  | ||||
|         $process->run($callback, $cmd); | ||||
|  | ||||
|         if ($verbosity <= $output->getVerbosity()) { | ||||
|             $message = $process->isSuccessful() ? 'Command ran successfully' : sprintf('%s Command did not run successfully', $process->getExitCode()); | ||||
|             $output->write($formatter->stop(spl_object_hash($process), $message, $process->isSuccessful())); | ||||
|         } | ||||
|  | ||||
|         if (!$process->isSuccessful() && null !== $error) { | ||||
|             $output->writeln(sprintf('<error>%s</error>', $this->escapeString($error))); | ||||
|         } | ||||
|  | ||||
|         return $process; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Runs the process. | ||||
|      * | ||||
|      * This is identical to run() except that an exception is thrown if the process | ||||
|      * exits with a non-zero exit code. | ||||
|      * | ||||
|      * @param OutputInterface $output   An OutputInterface instance | ||||
|      * @param string|Process  $cmd      An instance of Process or a command to run | ||||
|      * @param string|null     $error    An error message that must be displayed if something went wrong | ||||
|      * @param callable|null   $callback A PHP callback to run whenever there is some | ||||
|      *                                  output available on STDOUT or STDERR | ||||
|      * | ||||
|      * @return Process The process that ran | ||||
|      * | ||||
|      * @throws ProcessFailedException | ||||
|      * | ||||
|      * @see run() | ||||
|      */ | ||||
|     public function mustRun(OutputInterface $output, $cmd, $error = null, callable $callback = null) | ||||
|     { | ||||
|         $process = $this->run($output, $cmd, $error, $callback); | ||||
|  | ||||
|         if (!$process->isSuccessful()) { | ||||
|             throw new ProcessFailedException($process); | ||||
|         } | ||||
|  | ||||
|         return $process; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Wraps a Process callback to add debugging output. | ||||
|      * | ||||
|      * @param OutputInterface $output   An OutputInterface interface | ||||
|      * @param Process         $process  The Process | ||||
|      * @param callable|null   $callback A PHP callable | ||||
|      * | ||||
|      * @return callable | ||||
|      */ | ||||
|     public function wrapCallback(OutputInterface $output, Process $process, callable $callback = null) | ||||
|     { | ||||
|         if ($output instanceof ConsoleOutputInterface) { | ||||
|             $output = $output->getErrorOutput(); | ||||
|         } | ||||
|  | ||||
|         $formatter = $this->getHelperSet()->get('debug_formatter'); | ||||
|  | ||||
|         return function ($type, $buffer) use ($output, $process, $callback, $formatter) { | ||||
|             $output->write($formatter->progress(spl_object_hash($process), $this->escapeString($buffer), Process::ERR === $type)); | ||||
|  | ||||
|             if (null !== $callback) { | ||||
|                 $callback($type, $buffer); | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     private function escapeString($str) | ||||
|     { | ||||
|         return str_replace('<', '\\<', $str); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * {@inheritdoc} | ||||
|      */ | ||||
|     public function getName() | ||||
|     { | ||||
|         return 'process'; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										527
									
								
								vendor/symfony/console/Helper/ProgressBar.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										527
									
								
								vendor/symfony/console/Helper/ProgressBar.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,527 @@ | ||||
| <?php | ||||
|  | ||||
| /* | ||||
|  * This file is part of the Symfony package. | ||||
|  * | ||||
|  * (c) Fabien Potencier <fabien@symfony.com> | ||||
|  * | ||||
|  * For the full copyright and license information, please view the LICENSE | ||||
|  * file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| namespace Symfony\Component\Console\Helper; | ||||
|  | ||||
| use Symfony\Component\Console\Exception\LogicException; | ||||
| use Symfony\Component\Console\Output\ConsoleOutputInterface; | ||||
| use Symfony\Component\Console\Output\ConsoleSectionOutput; | ||||
| use Symfony\Component\Console\Output\OutputInterface; | ||||
| use Symfony\Component\Console\Terminal; | ||||
|  | ||||
| /** | ||||
|  * The ProgressBar provides helpers to display progress output. | ||||
|  * | ||||
|  * @author Fabien Potencier <fabien@symfony.com> | ||||
|  * @author Chris Jones <leeked@gmail.com> | ||||
|  */ | ||||
| final class ProgressBar | ||||
| { | ||||
|     private $barWidth = 28; | ||||
|     private $barChar; | ||||
|     private $emptyBarChar = '-'; | ||||
|     private $progressChar = '>'; | ||||
|     private $format; | ||||
|     private $internalFormat; | ||||
|     private $redrawFreq = 1; | ||||
|     private $output; | ||||
|     private $step = 0; | ||||
|     private $max; | ||||
|     private $startTime; | ||||
|     private $stepWidth; | ||||
|     private $percent = 0.0; | ||||
|     private $formatLineCount; | ||||
|     private $messages = []; | ||||
|     private $overwrite = true; | ||||
|     private $terminal; | ||||
|     private $firstRun = true; | ||||
|  | ||||
|     private static $formatters; | ||||
|     private static $formats; | ||||
|  | ||||
|     /** | ||||
|      * @param OutputInterface $output An OutputInterface instance | ||||
|      * @param int             $max    Maximum steps (0 if unknown) | ||||
|      */ | ||||
|     public function __construct(OutputInterface $output, int $max = 0) | ||||
|     { | ||||
|         if ($output instanceof ConsoleOutputInterface) { | ||||
|             $output = $output->getErrorOutput(); | ||||
|         } | ||||
|  | ||||
|         $this->output = $output; | ||||
|         $this->setMaxSteps($max); | ||||
|         $this->terminal = new Terminal(); | ||||
|  | ||||
|         if (!$this->output->isDecorated()) { | ||||
|             // disable overwrite when output does not support ANSI codes. | ||||
|             $this->overwrite = false; | ||||
|  | ||||
|             // set a reasonable redraw frequency so output isn't flooded | ||||
|             $this->setRedrawFrequency($max / 10); | ||||
|         } | ||||
|  | ||||
|         $this->startTime = time(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Sets a placeholder formatter for a given name. | ||||
|      * | ||||
|      * This method also allow you to override an existing placeholder. | ||||
|      * | ||||
|      * @param string   $name     The placeholder name (including the delimiter char like %) | ||||
|      * @param callable $callable A PHP callable | ||||
|      */ | ||||
|     public static function setPlaceholderFormatterDefinition(string $name, callable $callable): void | ||||
|     { | ||||
|         if (!self::$formatters) { | ||||
|             self::$formatters = self::initPlaceholderFormatters(); | ||||
|         } | ||||
|  | ||||
|         self::$formatters[$name] = $callable; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Gets the placeholder formatter for a given name. | ||||
|      * | ||||
|      * @param string $name The placeholder name (including the delimiter char like %) | ||||
|      * | ||||
|      * @return callable|null A PHP callable | ||||
|      */ | ||||
|     public static function getPlaceholderFormatterDefinition(string $name): ?callable | ||||
|     { | ||||
|         if (!self::$formatters) { | ||||
|             self::$formatters = self::initPlaceholderFormatters(); | ||||
|         } | ||||
|  | ||||
|         return isset(self::$formatters[$name]) ? self::$formatters[$name] : null; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Sets a format for a given name. | ||||
|      * | ||||
|      * This method also allow you to override an existing format. | ||||
|      * | ||||
|      * @param string $name   The format name | ||||
|      * @param string $format A format string | ||||
|      */ | ||||
|     public static function setFormatDefinition(string $name, string $format): void | ||||
|     { | ||||
|         if (!self::$formats) { | ||||
|             self::$formats = self::initFormats(); | ||||
|         } | ||||
|  | ||||
|         self::$formats[$name] = $format; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Gets the format for a given name. | ||||
|      * | ||||
|      * @param string $name The format name | ||||
|      * | ||||
|      * @return string|null A format string | ||||
|      */ | ||||
|     public static function getFormatDefinition(string $name): ?string | ||||
|     { | ||||
|         if (!self::$formats) { | ||||
|             self::$formats = self::initFormats(); | ||||
|         } | ||||
|  | ||||
|         return isset(self::$formats[$name]) ? self::$formats[$name] : null; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Associates a text with a named placeholder. | ||||
|      * | ||||
|      * The text is displayed when the progress bar is rendered but only | ||||
|      * when the corresponding placeholder is part of the custom format line | ||||
|      * (by wrapping the name with %). | ||||
|      * | ||||
|      * @param string $message The text to associate with the placeholder | ||||
|      * @param string $name    The name of the placeholder | ||||
|      */ | ||||
|     public function setMessage(string $message, string $name = 'message') | ||||
|     { | ||||
|         $this->messages[$name] = $message; | ||||
|     } | ||||
|  | ||||
|     public function getMessage(string $name = 'message') | ||||
|     { | ||||
|         return $this->messages[$name]; | ||||
|     } | ||||
|  | ||||
|     public function getStartTime(): int | ||||
|     { | ||||
|         return $this->startTime; | ||||
|     } | ||||
|  | ||||
|     public function getMaxSteps(): int | ||||
|     { | ||||
|         return $this->max; | ||||
|     } | ||||
|  | ||||
|     public function getProgress(): int | ||||
|     { | ||||
|         return $this->step; | ||||
|     } | ||||
|  | ||||
|     private function getStepWidth(): int | ||||
|     { | ||||
|         return $this->stepWidth; | ||||
|     } | ||||
|  | ||||
|     public function getProgressPercent(): float | ||||
|     { | ||||
|         return $this->percent; | ||||
|     } | ||||
|  | ||||
|     public function setBarWidth(int $size) | ||||
|     { | ||||
|         $this->barWidth = max(1, $size); | ||||
|     } | ||||
|  | ||||
|     public function getBarWidth(): int | ||||
|     { | ||||
|         return $this->barWidth; | ||||
|     } | ||||
|  | ||||
|     public function setBarCharacter(string $char) | ||||
|     { | ||||
|         $this->barChar = $char; | ||||
|     } | ||||
|  | ||||
|     public function getBarCharacter(): string | ||||
|     { | ||||
|         if (null === $this->barChar) { | ||||
|             return $this->max ? '=' : $this->emptyBarChar; | ||||
|         } | ||||
|  | ||||
|         return $this->barChar; | ||||
|     } | ||||
|  | ||||
|     public function setEmptyBarCharacter(string $char) | ||||
|     { | ||||
|         $this->emptyBarChar = $char; | ||||
|     } | ||||
|  | ||||
|     public function getEmptyBarCharacter(): string | ||||
|     { | ||||
|         return $this->emptyBarChar; | ||||
|     } | ||||
|  | ||||
|     public function setProgressCharacter(string $char) | ||||
|     { | ||||
|         $this->progressChar = $char; | ||||
|     } | ||||
|  | ||||
|     public function getProgressCharacter(): string | ||||
|     { | ||||
|         return $this->progressChar; | ||||
|     } | ||||
|  | ||||
|     public function setFormat(string $format) | ||||
|     { | ||||
|         $this->format = null; | ||||
|         $this->internalFormat = $format; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Sets the redraw frequency. | ||||
|      * | ||||
|      * @param int|float $freq The frequency in steps | ||||
|      */ | ||||
|     public function setRedrawFrequency(int $freq) | ||||
|     { | ||||
|         $this->redrawFreq = max($freq, 1); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Starts the progress output. | ||||
|      * | ||||
|      * @param int|null $max Number of steps to complete the bar (0 if indeterminate), null to leave unchanged | ||||
|      */ | ||||
|     public function start(int $max = null) | ||||
|     { | ||||
|         $this->startTime = time(); | ||||
|         $this->step = 0; | ||||
|         $this->percent = 0.0; | ||||
|  | ||||
|         if (null !== $max) { | ||||
|             $this->setMaxSteps($max); | ||||
|         } | ||||
|  | ||||
|         $this->display(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Advances the progress output X steps. | ||||
|      * | ||||
|      * @param int $step Number of steps to advance | ||||
|      */ | ||||
|     public function advance(int $step = 1) | ||||
|     { | ||||
|         $this->setProgress($this->step + $step); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Sets whether to overwrite the progressbar, false for new line. | ||||
|      */ | ||||
|     public function setOverwrite(bool $overwrite) | ||||
|     { | ||||
|         $this->overwrite = $overwrite; | ||||
|     } | ||||
|  | ||||
|     public function setProgress(int $step) | ||||
|     { | ||||
|         if ($this->max && $step > $this->max) { | ||||
|             $this->max = $step; | ||||
|         } elseif ($step < 0) { | ||||
|             $step = 0; | ||||
|         } | ||||
|  | ||||
|         $prevPeriod = (int) ($this->step / $this->redrawFreq); | ||||
|         $currPeriod = (int) ($step / $this->redrawFreq); | ||||
|         $this->step = $step; | ||||
|         $this->percent = $this->max ? (float) $this->step / $this->max : 0; | ||||
|         if ($prevPeriod !== $currPeriod || $this->max === $step) { | ||||
|             $this->display(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public function setMaxSteps(int $max) | ||||
|     { | ||||
|         $this->format = null; | ||||
|         $this->max = max(0, $max); | ||||
|         $this->stepWidth = $this->max ? Helper::strlen((string) $this->max) : 4; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Finishes the progress output. | ||||
|      */ | ||||
|     public function finish(): void | ||||
|     { | ||||
|         if (!$this->max) { | ||||
|             $this->max = $this->step; | ||||
|         } | ||||
|  | ||||
|         if ($this->step === $this->max && !$this->overwrite) { | ||||
|             // prevent double 100% output | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         $this->setProgress($this->max); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Outputs the current progress string. | ||||
|      */ | ||||
|     public function display(): void | ||||
|     { | ||||
|         if (OutputInterface::VERBOSITY_QUIET === $this->output->getVerbosity()) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         if (null === $this->format) { | ||||
|             $this->setRealFormat($this->internalFormat ?: $this->determineBestFormat()); | ||||
|         } | ||||
|  | ||||
|         $this->overwrite($this->buildLine()); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Removes the progress bar from the current line. | ||||
|      * | ||||
|      * This is useful if you wish to write some output | ||||
|      * while a progress bar is running. | ||||
|      * Call display() to show the progress bar again. | ||||
|      */ | ||||
|     public function clear(): void | ||||
|     { | ||||
|         if (!$this->overwrite) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         if (null === $this->format) { | ||||
|             $this->setRealFormat($this->internalFormat ?: $this->determineBestFormat()); | ||||
|         } | ||||
|  | ||||
|         $this->overwrite(''); | ||||
|     } | ||||
|  | ||||
|     private function setRealFormat(string $format) | ||||
|     { | ||||
|         // try to use the _nomax variant if available | ||||
|         if (!$this->max && null !== self::getFormatDefinition($format.'_nomax')) { | ||||
|             $this->format = self::getFormatDefinition($format.'_nomax'); | ||||
|         } elseif (null !== self::getFormatDefinition($format)) { | ||||
|             $this->format = self::getFormatDefinition($format); | ||||
|         } else { | ||||
|             $this->format = $format; | ||||
|         } | ||||
|  | ||||
|         $this->formatLineCount = substr_count($this->format, "\n"); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Overwrites a previous message to the output. | ||||
|      */ | ||||
|     private function overwrite(string $message): void | ||||
|     { | ||||
|         if ($this->overwrite) { | ||||
|             if (!$this->firstRun) { | ||||
|                 if ($this->output instanceof ConsoleSectionOutput) { | ||||
|                     $lines = floor(Helper::strlen($message) / $this->terminal->getWidth()) + $this->formatLineCount + 1; | ||||
|                     $this->output->clear($lines); | ||||
|                 } else { | ||||
|                     // Erase previous lines | ||||
|                     if ($this->formatLineCount > 0) { | ||||
|                         $message = str_repeat("\x1B[1A\x1B[2K", $this->formatLineCount).$message; | ||||
|                     } | ||||
|  | ||||
|                     // Move the cursor to the beginning of the line and erase the line | ||||
|                     $message = "\x0D\x1B[2K$message"; | ||||
|                 } | ||||
|             } | ||||
|         } elseif ($this->step > 0) { | ||||
|             $message = PHP_EOL.$message; | ||||
|         } | ||||
|  | ||||
|         $this->firstRun = false; | ||||
|  | ||||
|         $this->output->write($message); | ||||
|     } | ||||
|  | ||||
|     private function determineBestFormat(): string | ||||
|     { | ||||
|         switch ($this->output->getVerbosity()) { | ||||
|             // OutputInterface::VERBOSITY_QUIET: display is disabled anyway | ||||
|             case OutputInterface::VERBOSITY_VERBOSE: | ||||
|                 return $this->max ? 'verbose' : 'verbose_nomax'; | ||||
|             case OutputInterface::VERBOSITY_VERY_VERBOSE: | ||||
|                 return $this->max ? 'very_verbose' : 'very_verbose_nomax'; | ||||
|             case OutputInterface::VERBOSITY_DEBUG: | ||||
|                 return $this->max ? 'debug' : 'debug_nomax'; | ||||
|             default: | ||||
|                 return $this->max ? 'normal' : 'normal_nomax'; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private static function initPlaceholderFormatters(): array | ||||
|     { | ||||
|         return [ | ||||
|             'bar' => function (self $bar, OutputInterface $output) { | ||||
|                 $completeBars = floor($bar->getMaxSteps() > 0 ? $bar->getProgressPercent() * $bar->getBarWidth() : $bar->getProgress() % $bar->getBarWidth()); | ||||
|                 $display = str_repeat($bar->getBarCharacter(), $completeBars); | ||||
|                 if ($completeBars < $bar->getBarWidth()) { | ||||
|                     $emptyBars = $bar->getBarWidth() - $completeBars - Helper::strlenWithoutDecoration($output->getFormatter(), $bar->getProgressCharacter()); | ||||
|                     $display .= $bar->getProgressCharacter().str_repeat($bar->getEmptyBarCharacter(), $emptyBars); | ||||
|                 } | ||||
|  | ||||
|                 return $display; | ||||
|             }, | ||||
|             'elapsed' => function (self $bar) { | ||||
|                 return Helper::formatTime(time() - $bar->getStartTime()); | ||||
|             }, | ||||
|             'remaining' => function (self $bar) { | ||||
|                 if (!$bar->getMaxSteps()) { | ||||
|                     throw new LogicException('Unable to display the remaining time if the maximum number of steps is not set.'); | ||||
|                 } | ||||
|  | ||||
|                 if (!$bar->getProgress()) { | ||||
|                     $remaining = 0; | ||||
|                 } else { | ||||
|                     $remaining = round((time() - $bar->getStartTime()) / $bar->getProgress() * ($bar->getMaxSteps() - $bar->getProgress())); | ||||
|                 } | ||||
|  | ||||
|                 return Helper::formatTime($remaining); | ||||
|             }, | ||||
|             'estimated' => function (self $bar) { | ||||
|                 if (!$bar->getMaxSteps()) { | ||||
|                     throw new LogicException('Unable to display the estimated time if the maximum number of steps is not set.'); | ||||
|                 } | ||||
|  | ||||
|                 if (!$bar->getProgress()) { | ||||
|                     $estimated = 0; | ||||
|                 } else { | ||||
|                     $estimated = round((time() - $bar->getStartTime()) / $bar->getProgress() * $bar->getMaxSteps()); | ||||
|                 } | ||||
|  | ||||
|                 return Helper::formatTime($estimated); | ||||
|             }, | ||||
|             'memory' => function (self $bar) { | ||||
|                 return Helper::formatMemory(memory_get_usage(true)); | ||||
|             }, | ||||
|             'current' => function (self $bar) { | ||||
|                 return str_pad($bar->getProgress(), $bar->getStepWidth(), ' ', STR_PAD_LEFT); | ||||
|             }, | ||||
|             'max' => function (self $bar) { | ||||
|                 return $bar->getMaxSteps(); | ||||
|             }, | ||||
|             'percent' => function (self $bar) { | ||||
|                 return floor($bar->getProgressPercent() * 100); | ||||
|             }, | ||||
|         ]; | ||||
|     } | ||||
|  | ||||
|     private static function initFormats(): array | ||||
|     { | ||||
|         return [ | ||||
|             'normal' => ' %current%/%max% [%bar%] %percent:3s%%', | ||||
|             'normal_nomax' => ' %current% [%bar%]', | ||||
|  | ||||
|             'verbose' => ' %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%', | ||||
|             'verbose_nomax' => ' %current% [%bar%] %elapsed:6s%', | ||||
|  | ||||
|             'very_verbose' => ' %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%/%estimated:-6s%', | ||||
|             'very_verbose_nomax' => ' %current% [%bar%] %elapsed:6s%', | ||||
|  | ||||
|             'debug' => ' %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%/%estimated:-6s% %memory:6s%', | ||||
|             'debug_nomax' => ' %current% [%bar%] %elapsed:6s% %memory:6s%', | ||||
|         ]; | ||||
|     } | ||||
|  | ||||
|     private function buildLine(): string | ||||
|     { | ||||
|         $regex = "{%([a-z\-_]+)(?:\:([^%]+))?%}i"; | ||||
|         $callback = function ($matches) { | ||||
|             if ($formatter = $this::getPlaceholderFormatterDefinition($matches[1])) { | ||||
|                 $text = $formatter($this, $this->output); | ||||
|             } elseif (isset($this->messages[$matches[1]])) { | ||||
|                 $text = $this->messages[$matches[1]]; | ||||
|             } else { | ||||
|                 return $matches[0]; | ||||
|             } | ||||
|  | ||||
|             if (isset($matches[2])) { | ||||
|                 $text = sprintf('%'.$matches[2], $text); | ||||
|             } | ||||
|  | ||||
|             return $text; | ||||
|         }; | ||||
|         $line = preg_replace_callback($regex, $callback, $this->format); | ||||
|  | ||||
|         // gets string length for each sub line with multiline format | ||||
|         $linesLength = array_map(function ($subLine) { | ||||
|             return Helper::strlenWithoutDecoration($this->output->getFormatter(), rtrim($subLine, "\r")); | ||||
|         }, explode("\n", $line)); | ||||
|  | ||||
|         $linesWidth = max($linesLength); | ||||
|  | ||||
|         $terminalWidth = $this->terminal->getWidth(); | ||||
|         if ($linesWidth <= $terminalWidth) { | ||||
|             return $line; | ||||
|         } | ||||
|  | ||||
|         $this->setBarWidth($this->barWidth - $linesWidth + $terminalWidth); | ||||
|  | ||||
|         return preg_replace_callback($regex, $callback, $this->format); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										269
									
								
								vendor/symfony/console/Helper/ProgressIndicator.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										269
									
								
								vendor/symfony/console/Helper/ProgressIndicator.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,269 @@ | ||||
| <?php | ||||
|  | ||||
| /* | ||||
|  * This file is part of the Symfony package. | ||||
|  * | ||||
|  * (c) Fabien Potencier <fabien@symfony.com> | ||||
|  * | ||||
|  * For the full copyright and license information, please view the LICENSE | ||||
|  * file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| namespace Symfony\Component\Console\Helper; | ||||
|  | ||||
| use Symfony\Component\Console\Exception\InvalidArgumentException; | ||||
| use Symfony\Component\Console\Exception\LogicException; | ||||
| use Symfony\Component\Console\Output\OutputInterface; | ||||
|  | ||||
| /** | ||||
|  * @author Kevin Bond <kevinbond@gmail.com> | ||||
|  */ | ||||
| class ProgressIndicator | ||||
| { | ||||
|     private $output; | ||||
|     private $startTime; | ||||
|     private $format; | ||||
|     private $message; | ||||
|     private $indicatorValues; | ||||
|     private $indicatorCurrent; | ||||
|     private $indicatorChangeInterval; | ||||
|     private $indicatorUpdateTime; | ||||
|     private $started = false; | ||||
|  | ||||
|     private static $formatters; | ||||
|     private static $formats; | ||||
|  | ||||
|     /** | ||||
|      * @param OutputInterface $output | ||||
|      * @param string|null     $format                  Indicator format | ||||
|      * @param int             $indicatorChangeInterval Change interval in milliseconds | ||||
|      * @param array|null      $indicatorValues         Animated indicator characters | ||||
|      */ | ||||
|     public function __construct(OutputInterface $output, string $format = null, int $indicatorChangeInterval = 100, array $indicatorValues = null) | ||||
|     { | ||||
|         $this->output = $output; | ||||
|  | ||||
|         if (null === $format) { | ||||
|             $format = $this->determineBestFormat(); | ||||
|         } | ||||
|  | ||||
|         if (null === $indicatorValues) { | ||||
|             $indicatorValues = ['-', '\\', '|', '/']; | ||||
|         } | ||||
|  | ||||
|         $indicatorValues = array_values($indicatorValues); | ||||
|  | ||||
|         if (2 > \count($indicatorValues)) { | ||||
|             throw new InvalidArgumentException('Must have at least 2 indicator value characters.'); | ||||
|         } | ||||
|  | ||||
|         $this->format = self::getFormatDefinition($format); | ||||
|         $this->indicatorChangeInterval = $indicatorChangeInterval; | ||||
|         $this->indicatorValues = $indicatorValues; | ||||
|         $this->startTime = time(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Sets the current indicator message. | ||||
|      * | ||||
|      * @param string|null $message | ||||
|      */ | ||||
|     public function setMessage($message) | ||||
|     { | ||||
|         $this->message = $message; | ||||
|  | ||||
|         $this->display(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Starts the indicator output. | ||||
|      * | ||||
|      * @param $message | ||||
|      */ | ||||
|     public function start($message) | ||||
|     { | ||||
|         if ($this->started) { | ||||
|             throw new LogicException('Progress indicator already started.'); | ||||
|         } | ||||
|  | ||||
|         $this->message = $message; | ||||
|         $this->started = true; | ||||
|         $this->startTime = time(); | ||||
|         $this->indicatorUpdateTime = $this->getCurrentTimeInMilliseconds() + $this->indicatorChangeInterval; | ||||
|         $this->indicatorCurrent = 0; | ||||
|  | ||||
|         $this->display(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Advances the indicator. | ||||
|      */ | ||||
|     public function advance() | ||||
|     { | ||||
|         if (!$this->started) { | ||||
|             throw new LogicException('Progress indicator has not yet been started.'); | ||||
|         } | ||||
|  | ||||
|         if (!$this->output->isDecorated()) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         $currentTime = $this->getCurrentTimeInMilliseconds(); | ||||
|  | ||||
|         if ($currentTime < $this->indicatorUpdateTime) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         $this->indicatorUpdateTime = $currentTime + $this->indicatorChangeInterval; | ||||
|         ++$this->indicatorCurrent; | ||||
|  | ||||
|         $this->display(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Finish the indicator with message. | ||||
|      * | ||||
|      * @param $message | ||||
|      */ | ||||
|     public function finish($message) | ||||
|     { | ||||
|         if (!$this->started) { | ||||
|             throw new LogicException('Progress indicator has not yet been started.'); | ||||
|         } | ||||
|  | ||||
|         $this->message = $message; | ||||
|         $this->display(); | ||||
|         $this->output->writeln(''); | ||||
|         $this->started = false; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Gets the format for a given name. | ||||
|      * | ||||
|      * @param string $name The format name | ||||
|      * | ||||
|      * @return string|null A format string | ||||
|      */ | ||||
|     public static function getFormatDefinition($name) | ||||
|     { | ||||
|         if (!self::$formats) { | ||||
|             self::$formats = self::initFormats(); | ||||
|         } | ||||
|  | ||||
|         return isset(self::$formats[$name]) ? self::$formats[$name] : null; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Sets a placeholder formatter for a given name. | ||||
|      * | ||||
|      * This method also allow you to override an existing placeholder. | ||||
|      * | ||||
|      * @param string   $name     The placeholder name (including the delimiter char like %) | ||||
|      * @param callable $callable A PHP callable | ||||
|      */ | ||||
|     public static function setPlaceholderFormatterDefinition($name, $callable) | ||||
|     { | ||||
|         if (!self::$formatters) { | ||||
|             self::$formatters = self::initPlaceholderFormatters(); | ||||
|         } | ||||
|  | ||||
|         self::$formatters[$name] = $callable; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Gets the placeholder formatter for a given name. | ||||
|      * | ||||
|      * @param string $name The placeholder name (including the delimiter char like %) | ||||
|      * | ||||
|      * @return callable|null A PHP callable | ||||
|      */ | ||||
|     public static function getPlaceholderFormatterDefinition($name) | ||||
|     { | ||||
|         if (!self::$formatters) { | ||||
|             self::$formatters = self::initPlaceholderFormatters(); | ||||
|         } | ||||
|  | ||||
|         return isset(self::$formatters[$name]) ? self::$formatters[$name] : null; | ||||
|     } | ||||
|  | ||||
|     private function display() | ||||
|     { | ||||
|         if (OutputInterface::VERBOSITY_QUIET === $this->output->getVerbosity()) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         $self = $this; | ||||
|  | ||||
|         $this->overwrite(preg_replace_callback("{%([a-z\-_]+)(?:\:([^%]+))?%}i", function ($matches) use ($self) { | ||||
|             if ($formatter = $self::getPlaceholderFormatterDefinition($matches[1])) { | ||||
|                 return $formatter($self); | ||||
|             } | ||||
|  | ||||
|             return $matches[0]; | ||||
|         }, $this->format)); | ||||
|     } | ||||
|  | ||||
|     private function determineBestFormat() | ||||
|     { | ||||
|         switch ($this->output->getVerbosity()) { | ||||
|             // OutputInterface::VERBOSITY_QUIET: display is disabled anyway | ||||
|             case OutputInterface::VERBOSITY_VERBOSE: | ||||
|                 return $this->output->isDecorated() ? 'verbose' : 'verbose_no_ansi'; | ||||
|             case OutputInterface::VERBOSITY_VERY_VERBOSE: | ||||
|             case OutputInterface::VERBOSITY_DEBUG: | ||||
|                 return $this->output->isDecorated() ? 'very_verbose' : 'very_verbose_no_ansi'; | ||||
|             default: | ||||
|                 return $this->output->isDecorated() ? 'normal' : 'normal_no_ansi'; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Overwrites a previous message to the output. | ||||
|      */ | ||||
|     private function overwrite(string $message) | ||||
|     { | ||||
|         if ($this->output->isDecorated()) { | ||||
|             $this->output->write("\x0D\x1B[2K"); | ||||
|             $this->output->write($message); | ||||
|         } else { | ||||
|             $this->output->writeln($message); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private function getCurrentTimeInMilliseconds() | ||||
|     { | ||||
|         return round(microtime(true) * 1000); | ||||
|     } | ||||
|  | ||||
|     private static function initPlaceholderFormatters() | ||||
|     { | ||||
|         return [ | ||||
|             'indicator' => function (self $indicator) { | ||||
|                 return $indicator->indicatorValues[$indicator->indicatorCurrent % \count($indicator->indicatorValues)]; | ||||
|             }, | ||||
|             'message' => function (self $indicator) { | ||||
|                 return $indicator->message; | ||||
|             }, | ||||
|             'elapsed' => function (self $indicator) { | ||||
|                 return Helper::formatTime(time() - $indicator->startTime); | ||||
|             }, | ||||
|             'memory' => function () { | ||||
|                 return Helper::formatMemory(memory_get_usage(true)); | ||||
|             }, | ||||
|         ]; | ||||
|     } | ||||
|  | ||||
|     private static function initFormats() | ||||
|     { | ||||
|         return [ | ||||
|             'normal' => ' %indicator% %message%', | ||||
|             'normal_no_ansi' => ' %message%', | ||||
|  | ||||
|             'verbose' => ' %indicator% %message% (%elapsed:6s%)', | ||||
|             'verbose_no_ansi' => ' %message% (%elapsed:6s%)', | ||||
|  | ||||
|             'very_verbose' => ' %indicator% %message% (%elapsed:6s%, %memory:6s%)', | ||||
|             'very_verbose_no_ansi' => ' %message% (%elapsed:6s%, %memory:6s%)', | ||||
|         ]; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										474
									
								
								vendor/symfony/console/Helper/QuestionHelper.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										474
									
								
								vendor/symfony/console/Helper/QuestionHelper.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,474 @@ | ||||
| <?php | ||||
|  | ||||
| /* | ||||
|  * This file is part of the Symfony package. | ||||
|  * | ||||
|  * (c) Fabien Potencier <fabien@symfony.com> | ||||
|  * | ||||
|  * For the full copyright and license information, please view the LICENSE | ||||
|  * file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| namespace Symfony\Component\Console\Helper; | ||||
|  | ||||
| use Symfony\Component\Console\Exception\RuntimeException; | ||||
| use Symfony\Component\Console\Formatter\OutputFormatter; | ||||
| use Symfony\Component\Console\Formatter\OutputFormatterStyle; | ||||
| use Symfony\Component\Console\Input\InputInterface; | ||||
| use Symfony\Component\Console\Input\StreamableInputInterface; | ||||
| use Symfony\Component\Console\Output\ConsoleOutputInterface; | ||||
| use Symfony\Component\Console\Output\ConsoleSectionOutput; | ||||
| use Symfony\Component\Console\Output\OutputInterface; | ||||
| use Symfony\Component\Console\Question\ChoiceQuestion; | ||||
| use Symfony\Component\Console\Question\Question; | ||||
|  | ||||
| /** | ||||
|  * The QuestionHelper class provides helpers to interact with the user. | ||||
|  * | ||||
|  * @author Fabien Potencier <fabien@symfony.com> | ||||
|  */ | ||||
| class QuestionHelper extends Helper | ||||
| { | ||||
|     private $inputStream; | ||||
|     private static $shell; | ||||
|     private static $stty; | ||||
|  | ||||
|     /** | ||||
|      * Asks a question to the user. | ||||
|      * | ||||
|      * @return mixed The user answer | ||||
|      * | ||||
|      * @throws RuntimeException If there is no data to read in the input stream | ||||
|      */ | ||||
|     public function ask(InputInterface $input, OutputInterface $output, Question $question) | ||||
|     { | ||||
|         if ($output instanceof ConsoleOutputInterface) { | ||||
|             $output = $output->getErrorOutput(); | ||||
|         } | ||||
|  | ||||
|         if (!$input->isInteractive()) { | ||||
|             $default = $question->getDefault(); | ||||
|  | ||||
|             if (null === $default) { | ||||
|                 return $default; | ||||
|             } | ||||
|  | ||||
|             if ($validator = $question->getValidator()) { | ||||
|                 return \call_user_func($question->getValidator(), $default); | ||||
|             } elseif ($question instanceof ChoiceQuestion) { | ||||
|                 $choices = $question->getChoices(); | ||||
|  | ||||
|                 if (!$question->isMultiselect()) { | ||||
|                     return isset($choices[$default]) ? $choices[$default] : $default; | ||||
|                 } | ||||
|  | ||||
|                 $default = explode(',', $default); | ||||
|                 foreach ($default as $k => $v) { | ||||
|                     $v = trim($v); | ||||
|                     $default[$k] = isset($choices[$v]) ? $choices[$v] : $v; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             return $default; | ||||
|         } | ||||
|  | ||||
|         if ($input instanceof StreamableInputInterface && $stream = $input->getStream()) { | ||||
|             $this->inputStream = $stream; | ||||
|         } | ||||
|  | ||||
|         if (!$question->getValidator()) { | ||||
|             return $this->doAsk($output, $question); | ||||
|         } | ||||
|  | ||||
|         $interviewer = function () use ($output, $question) { | ||||
|             return $this->doAsk($output, $question); | ||||
|         }; | ||||
|  | ||||
|         return $this->validateAttempts($interviewer, $output, $question); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * {@inheritdoc} | ||||
|      */ | ||||
|     public function getName() | ||||
|     { | ||||
|         return 'question'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Prevents usage of stty. | ||||
|      */ | ||||
|     public static function disableStty() | ||||
|     { | ||||
|         self::$stty = false; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Asks the question to the user. | ||||
|      * | ||||
|      * @return bool|mixed|string|null | ||||
|      * | ||||
|      * @throws RuntimeException In case the fallback is deactivated and the response cannot be hidden | ||||
|      */ | ||||
|     private function doAsk(OutputInterface $output, Question $question) | ||||
|     { | ||||
|         $this->writePrompt($output, $question); | ||||
|  | ||||
|         $inputStream = $this->inputStream ?: STDIN; | ||||
|         $autocomplete = $question->getAutocompleterValues(); | ||||
|  | ||||
|         if (null === $autocomplete || !$this->hasSttyAvailable()) { | ||||
|             $ret = false; | ||||
|             if ($question->isHidden()) { | ||||
|                 try { | ||||
|                     $ret = trim($this->getHiddenResponse($output, $inputStream)); | ||||
|                 } catch (RuntimeException $e) { | ||||
|                     if (!$question->isHiddenFallback()) { | ||||
|                         throw $e; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             if (false === $ret) { | ||||
|                 $ret = fgets($inputStream, 4096); | ||||
|                 if (false === $ret) { | ||||
|                     throw new RuntimeException('Aborted.'); | ||||
|                 } | ||||
|                 $ret = trim($ret); | ||||
|             } | ||||
|         } else { | ||||
|             $ret = trim($this->autocomplete($output, $question, $inputStream, \is_array($autocomplete) ? $autocomplete : iterator_to_array($autocomplete, false))); | ||||
|         } | ||||
|  | ||||
|         if ($output instanceof ConsoleSectionOutput) { | ||||
|             $output->addContent($ret); | ||||
|         } | ||||
|  | ||||
|         $ret = \strlen($ret) > 0 ? $ret : $question->getDefault(); | ||||
|  | ||||
|         if ($normalizer = $question->getNormalizer()) { | ||||
|             return $normalizer($ret); | ||||
|         } | ||||
|  | ||||
|         return $ret; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Outputs the question prompt. | ||||
|      */ | ||||
|     protected function writePrompt(OutputInterface $output, Question $question) | ||||
|     { | ||||
|         $message = $question->getQuestion(); | ||||
|  | ||||
|         if ($question instanceof ChoiceQuestion) { | ||||
|             $maxWidth = max(array_map([$this, 'strlen'], array_keys($question->getChoices()))); | ||||
|  | ||||
|             $messages = (array) $question->getQuestion(); | ||||
|             foreach ($question->getChoices() as $key => $value) { | ||||
|                 $width = $maxWidth - $this->strlen($key); | ||||
|                 $messages[] = '  [<info>'.$key.str_repeat(' ', $width).'</info>] '.$value; | ||||
|             } | ||||
|  | ||||
|             $output->writeln($messages); | ||||
|  | ||||
|             $message = $question->getPrompt(); | ||||
|         } | ||||
|  | ||||
|         $output->write($message); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Outputs an error message. | ||||
|      */ | ||||
|     protected function writeError(OutputInterface $output, \Exception $error) | ||||
|     { | ||||
|         if (null !== $this->getHelperSet() && $this->getHelperSet()->has('formatter')) { | ||||
|             $message = $this->getHelperSet()->get('formatter')->formatBlock($error->getMessage(), 'error'); | ||||
|         } else { | ||||
|             $message = '<error>'.$error->getMessage().'</error>'; | ||||
|         } | ||||
|  | ||||
|         $output->writeln($message); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Autocompletes a question. | ||||
|      * | ||||
|      * @param OutputInterface $output | ||||
|      * @param Question        $question | ||||
|      * @param resource        $inputStream | ||||
|      */ | ||||
|     private function autocomplete(OutputInterface $output, Question $question, $inputStream, array $autocomplete): string | ||||
|     { | ||||
|         $fullChoice = ''; | ||||
|         $ret = ''; | ||||
|  | ||||
|         $i = 0; | ||||
|         $ofs = -1; | ||||
|         $matches = $autocomplete; | ||||
|         $numMatches = \count($matches); | ||||
|  | ||||
|         $sttyMode = shell_exec('stty -g'); | ||||
|  | ||||
|         // Disable icanon (so we can fread each keypress) and echo (we'll do echoing here instead) | ||||
|         shell_exec('stty -icanon -echo'); | ||||
|  | ||||
|         // Add highlighted text style | ||||
|         $output->getFormatter()->setStyle('hl', new OutputFormatterStyle('black', 'white')); | ||||
|  | ||||
|         // Read a keypress | ||||
|         while (!feof($inputStream)) { | ||||
|             $c = fread($inputStream, 1); | ||||
|  | ||||
|             // as opposed to fgets(), fread() returns an empty string when the stream content is empty, not false. | ||||
|             if (false === $c || ('' === $ret && '' === $c && null === $question->getDefault())) { | ||||
|                 shell_exec(sprintf('stty %s', $sttyMode)); | ||||
|                 throw new RuntimeException('Aborted.'); | ||||
|             } elseif ("\177" === $c) { // Backspace Character | ||||
|                 if (0 === $numMatches && 0 !== $i) { | ||||
|                     --$i; | ||||
|                     $fullChoice = substr($fullChoice, 0, -1); | ||||
|                     // Move cursor backwards | ||||
|                     $output->write("\033[1D"); | ||||
|                 } | ||||
|  | ||||
|                 if (0 === $i) { | ||||
|                     $ofs = -1; | ||||
|                     $matches = $autocomplete; | ||||
|                     $numMatches = \count($matches); | ||||
|                 } else { | ||||
|                     $numMatches = 0; | ||||
|                 } | ||||
|  | ||||
|                 // Pop the last character off the end of our string | ||||
|                 $ret = substr($ret, 0, $i); | ||||
|             } elseif ("\033" === $c) { | ||||
|                 // Did we read an escape sequence? | ||||
|                 $c .= fread($inputStream, 2); | ||||
|  | ||||
|                 // A = Up Arrow. B = Down Arrow | ||||
|                 if (isset($c[2]) && ('A' === $c[2] || 'B' === $c[2])) { | ||||
|                     if ('A' === $c[2] && -1 === $ofs) { | ||||
|                         $ofs = 0; | ||||
|                     } | ||||
|  | ||||
|                     if (0 === $numMatches) { | ||||
|                         continue; | ||||
|                     } | ||||
|  | ||||
|                     $ofs += ('A' === $c[2]) ? -1 : 1; | ||||
|                     $ofs = ($numMatches + $ofs) % $numMatches; | ||||
|                 } | ||||
|             } elseif (\ord($c) < 32) { | ||||
|                 if ("\t" === $c || "\n" === $c) { | ||||
|                     if ($numMatches > 0 && -1 !== $ofs) { | ||||
|                         $ret = $matches[$ofs]; | ||||
|                         // Echo out remaining chars for current match | ||||
|                         $remainingCharacters = substr($ret, \strlen(trim($this->mostRecentlyEnteredValue($fullChoice)))); | ||||
|                         $output->write($remainingCharacters); | ||||
|                         $fullChoice .= $remainingCharacters; | ||||
|                         $i = \strlen($fullChoice); | ||||
|                     } | ||||
|  | ||||
|                     if ("\n" === $c) { | ||||
|                         $output->write($c); | ||||
|                         break; | ||||
|                     } | ||||
|  | ||||
|                     $numMatches = 0; | ||||
|                 } | ||||
|  | ||||
|                 continue; | ||||
|             } else { | ||||
|                 if ("\x80" <= $c) { | ||||
|                     $c .= fread($inputStream, ["\xC0" => 1, "\xD0" => 1, "\xE0" => 2, "\xF0" => 3][$c & "\xF0"]); | ||||
|                 } | ||||
|  | ||||
|                 $output->write($c); | ||||
|                 $ret .= $c; | ||||
|                 $fullChoice .= $c; | ||||
|                 ++$i; | ||||
|  | ||||
|                 $tempRet = $ret; | ||||
|  | ||||
|                 if ($question instanceof ChoiceQuestion && $question->isMultiselect()) { | ||||
|                     $tempRet = $this->mostRecentlyEnteredValue($fullChoice); | ||||
|                 } | ||||
|  | ||||
|                 $numMatches = 0; | ||||
|                 $ofs = 0; | ||||
|  | ||||
|                 foreach ($autocomplete as $value) { | ||||
|                     // If typed characters match the beginning chunk of value (e.g. [AcmeDe]moBundle) | ||||
|                     if (0 === strpos($value, $tempRet)) { | ||||
|                         $matches[$numMatches++] = $value; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             // Erase characters from cursor to end of line | ||||
|             $output->write("\033[K"); | ||||
|  | ||||
|             if ($numMatches > 0 && -1 !== $ofs) { | ||||
|                 // Save cursor position | ||||
|                 $output->write("\0337"); | ||||
|                 // Write highlighted text, complete the partially entered response | ||||
|                 $charactersEntered = \strlen(trim($this->mostRecentlyEnteredValue($fullChoice))); | ||||
|                 $output->write('<hl>'.OutputFormatter::escapeTrailingBackslash(substr($matches[$ofs], $charactersEntered)).'</hl>'); | ||||
|                 // Restore cursor position | ||||
|                 $output->write("\0338"); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Reset stty so it behaves normally again | ||||
|         shell_exec(sprintf('stty %s', $sttyMode)); | ||||
|  | ||||
|         return $fullChoice; | ||||
|     } | ||||
|  | ||||
|     private function mostRecentlyEnteredValue($entered) | ||||
|     { | ||||
|         // Determine the most recent value that the user entered | ||||
|         if (false === strpos($entered, ',')) { | ||||
|             return $entered; | ||||
|         } | ||||
|  | ||||
|         $choices = explode(',', $entered); | ||||
|         if (\strlen($lastChoice = trim($choices[\count($choices) - 1])) > 0) { | ||||
|             return $lastChoice; | ||||
|         } | ||||
|  | ||||
|         return $entered; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Gets a hidden response from user. | ||||
|      * | ||||
|      * @param OutputInterface $output      An Output instance | ||||
|      * @param resource        $inputStream The handler resource | ||||
|      * | ||||
|      * @throws RuntimeException In case the fallback is deactivated and the response cannot be hidden | ||||
|      */ | ||||
|     private function getHiddenResponse(OutputInterface $output, $inputStream): string | ||||
|     { | ||||
|         if ('\\' === \DIRECTORY_SEPARATOR) { | ||||
|             $exe = __DIR__.'/../Resources/bin/hiddeninput.exe'; | ||||
|  | ||||
|             // handle code running from a phar | ||||
|             if ('phar:' === substr(__FILE__, 0, 5)) { | ||||
|                 $tmpExe = sys_get_temp_dir().'/hiddeninput.exe'; | ||||
|                 copy($exe, $tmpExe); | ||||
|                 $exe = $tmpExe; | ||||
|             } | ||||
|  | ||||
|             $value = rtrim(shell_exec($exe)); | ||||
|             $output->writeln(''); | ||||
|  | ||||
|             if (isset($tmpExe)) { | ||||
|                 unlink($tmpExe); | ||||
|             } | ||||
|  | ||||
|             return $value; | ||||
|         } | ||||
|  | ||||
|         if ($this->hasSttyAvailable()) { | ||||
|             $sttyMode = shell_exec('stty -g'); | ||||
|  | ||||
|             shell_exec('stty -echo'); | ||||
|             $value = fgets($inputStream, 4096); | ||||
|             shell_exec(sprintf('stty %s', $sttyMode)); | ||||
|  | ||||
|             if (false === $value) { | ||||
|                 throw new RuntimeException('Aborted.'); | ||||
|             } | ||||
|  | ||||
|             $value = trim($value); | ||||
|             $output->writeln(''); | ||||
|  | ||||
|             return $value; | ||||
|         } | ||||
|  | ||||
|         if (false !== $shell = $this->getShell()) { | ||||
|             $readCmd = 'csh' === $shell ? 'set mypassword = $<' : 'read -r mypassword'; | ||||
|             $command = sprintf("/usr/bin/env %s -c 'stty -echo; %s; stty echo; echo \$mypassword'", $shell, $readCmd); | ||||
|             $value = rtrim(shell_exec($command)); | ||||
|             $output->writeln(''); | ||||
|  | ||||
|             return $value; | ||||
|         } | ||||
|  | ||||
|         throw new RuntimeException('Unable to hide the response.'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Validates an attempt. | ||||
|      * | ||||
|      * @param callable        $interviewer A callable that will ask for a question and return the result | ||||
|      * @param OutputInterface $output      An Output instance | ||||
|      * @param Question        $question    A Question instance | ||||
|      * | ||||
|      * @return mixed The validated response | ||||
|      * | ||||
|      * @throws \Exception In case the max number of attempts has been reached and no valid response has been given | ||||
|      */ | ||||
|     private function validateAttempts(callable $interviewer, OutputInterface $output, Question $question) | ||||
|     { | ||||
|         $error = null; | ||||
|         $attempts = $question->getMaxAttempts(); | ||||
|         while (null === $attempts || $attempts--) { | ||||
|             if (null !== $error) { | ||||
|                 $this->writeError($output, $error); | ||||
|             } | ||||
|  | ||||
|             try { | ||||
|                 return $question->getValidator()($interviewer()); | ||||
|             } catch (RuntimeException $e) { | ||||
|                 throw $e; | ||||
|             } catch (\Exception $error) { | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         throw $error; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Returns a valid unix shell. | ||||
|      * | ||||
|      * @return string|bool The valid shell name, false in case no valid shell is found | ||||
|      */ | ||||
|     private function getShell() | ||||
|     { | ||||
|         if (null !== self::$shell) { | ||||
|             return self::$shell; | ||||
|         } | ||||
|  | ||||
|         self::$shell = false; | ||||
|  | ||||
|         if (file_exists('/usr/bin/env')) { | ||||
|             // handle other OSs with bash/zsh/ksh/csh if available to hide the answer | ||||
|             $test = "/usr/bin/env %s -c 'echo OK' 2> /dev/null"; | ||||
|             foreach (['bash', 'zsh', 'ksh', 'csh'] as $sh) { | ||||
|                 if ('OK' === rtrim(shell_exec(sprintf($test, $sh)))) { | ||||
|                     self::$shell = $sh; | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return self::$shell; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Returns whether Stty is available or not. | ||||
|      */ | ||||
|     private function hasSttyAvailable(): bool | ||||
|     { | ||||
|         if (null !== self::$stty) { | ||||
|             return self::$stty; | ||||
|         } | ||||
|  | ||||
|         exec('stty 2>&1', $output, $exitcode); | ||||
|  | ||||
|         return self::$stty = 0 === $exitcode; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										96
									
								
								vendor/symfony/console/Helper/SymfonyQuestionHelper.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								vendor/symfony/console/Helper/SymfonyQuestionHelper.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,96 @@ | ||||
| <?php | ||||
|  | ||||
| /* | ||||
|  * This file is part of the Symfony package. | ||||
|  * | ||||
|  * (c) Fabien Potencier <fabien@symfony.com> | ||||
|  * | ||||
|  * For the full copyright and license information, please view the LICENSE | ||||
|  * file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| namespace Symfony\Component\Console\Helper; | ||||
|  | ||||
| use Symfony\Component\Console\Formatter\OutputFormatter; | ||||
| use Symfony\Component\Console\Output\OutputInterface; | ||||
| use Symfony\Component\Console\Question\ChoiceQuestion; | ||||
| use Symfony\Component\Console\Question\ConfirmationQuestion; | ||||
| use Symfony\Component\Console\Question\Question; | ||||
| use Symfony\Component\Console\Style\SymfonyStyle; | ||||
|  | ||||
| /** | ||||
|  * Symfony Style Guide compliant question helper. | ||||
|  * | ||||
|  * @author Kevin Bond <kevinbond@gmail.com> | ||||
|  */ | ||||
| class SymfonyQuestionHelper extends QuestionHelper | ||||
| { | ||||
|     /** | ||||
|      * {@inheritdoc} | ||||
|      */ | ||||
|     protected function writePrompt(OutputInterface $output, Question $question) | ||||
|     { | ||||
|         $text = OutputFormatter::escapeTrailingBackslash($question->getQuestion()); | ||||
|         $default = $question->getDefault(); | ||||
|  | ||||
|         switch (true) { | ||||
|             case null === $default: | ||||
|                 $text = sprintf(' <info>%s</info>:', $text); | ||||
|  | ||||
|                 break; | ||||
|  | ||||
|             case $question instanceof ConfirmationQuestion: | ||||
|                 $text = sprintf(' <info>%s (yes/no)</info> [<comment>%s</comment>]:', $text, $default ? 'yes' : 'no'); | ||||
|  | ||||
|                 break; | ||||
|  | ||||
|             case $question instanceof ChoiceQuestion && $question->isMultiselect(): | ||||
|                 $choices = $question->getChoices(); | ||||
|                 $default = explode(',', $default); | ||||
|  | ||||
|                 foreach ($default as $key => $value) { | ||||
|                     $default[$key] = $choices[trim($value)]; | ||||
|                 } | ||||
|  | ||||
|                 $text = sprintf(' <info>%s</info> [<comment>%s</comment>]:', $text, OutputFormatter::escape(implode(', ', $default))); | ||||
|  | ||||
|                 break; | ||||
|  | ||||
|             case $question instanceof ChoiceQuestion: | ||||
|                 $choices = $question->getChoices(); | ||||
|                 $text = sprintf(' <info>%s</info> [<comment>%s</comment>]:', $text, OutputFormatter::escape(isset($choices[$default]) ? $choices[$default] : $default)); | ||||
|  | ||||
|                 break; | ||||
|  | ||||
|             default: | ||||
|                 $text = sprintf(' <info>%s</info> [<comment>%s</comment>]:', $text, OutputFormatter::escape($default)); | ||||
|         } | ||||
|  | ||||
|         $output->writeln($text); | ||||
|  | ||||
|         if ($question instanceof ChoiceQuestion) { | ||||
|             $width = max(array_map('strlen', array_keys($question->getChoices()))); | ||||
|  | ||||
|             foreach ($question->getChoices() as $key => $value) { | ||||
|                 $output->writeln(sprintf("  [<comment>%-${width}s</comment>] %s", $key, $value)); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         $output->write(' > '); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * {@inheritdoc} | ||||
|      */ | ||||
|     protected function writeError(OutputInterface $output, \Exception $error) | ||||
|     { | ||||
|         if ($output instanceof SymfonyStyle) { | ||||
|             $output->newLine(); | ||||
|             $output->error($error->getMessage()); | ||||
|  | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         parent::writeError($output, $error); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										813
									
								
								vendor/symfony/console/Helper/Table.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										813
									
								
								vendor/symfony/console/Helper/Table.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,813 @@ | ||||
| <?php | ||||
|  | ||||
| /* | ||||
|  * This file is part of the Symfony package. | ||||
|  * | ||||
|  * (c) Fabien Potencier <fabien@symfony.com> | ||||
|  * | ||||
|  * For the full copyright and license information, please view the LICENSE | ||||
|  * file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| namespace Symfony\Component\Console\Helper; | ||||
|  | ||||
| use Symfony\Component\Console\Exception\InvalidArgumentException; | ||||
| use Symfony\Component\Console\Exception\RuntimeException; | ||||
| use Symfony\Component\Console\Formatter\OutputFormatter; | ||||
| use Symfony\Component\Console\Formatter\WrappableOutputFormatterInterface; | ||||
| use Symfony\Component\Console\Output\ConsoleSectionOutput; | ||||
| use Symfony\Component\Console\Output\OutputInterface; | ||||
|  | ||||
| /** | ||||
|  * Provides helpers to display a table. | ||||
|  * | ||||
|  * @author Fabien Potencier <fabien@symfony.com> | ||||
|  * @author Саша Стаменковић <umpirsky@gmail.com> | ||||
|  * @author Abdellatif Ait boudad <a.aitboudad@gmail.com> | ||||
|  * @author Max Grigorian <maxakawizard@gmail.com> | ||||
|  * @author Dany Maillard <danymaillard93b@gmail.com> | ||||
|  */ | ||||
| class Table | ||||
| { | ||||
|     private const SEPARATOR_TOP = 0; | ||||
|     private const SEPARATOR_TOP_BOTTOM = 1; | ||||
|     private const SEPARATOR_MID = 2; | ||||
|     private const SEPARATOR_BOTTOM = 3; | ||||
|     private const BORDER_OUTSIDE = 0; | ||||
|     private const BORDER_INSIDE = 1; | ||||
|  | ||||
|     private $headerTitle; | ||||
|     private $footerTitle; | ||||
|  | ||||
|     /** | ||||
|      * Table headers. | ||||
|      */ | ||||
|     private $headers = []; | ||||
|  | ||||
|     /** | ||||
|      * Table rows. | ||||
|      */ | ||||
|     private $rows = []; | ||||
|  | ||||
|     /** | ||||
|      * Column widths cache. | ||||
|      */ | ||||
|     private $effectiveColumnWidths = []; | ||||
|  | ||||
|     /** | ||||
|      * Number of columns cache. | ||||
|      * | ||||
|      * @var int | ||||
|      */ | ||||
|     private $numberOfColumns; | ||||
|  | ||||
|     /** | ||||
|      * @var OutputInterface | ||||
|      */ | ||||
|     private $output; | ||||
|  | ||||
|     /** | ||||
|      * @var TableStyle | ||||
|      */ | ||||
|     private $style; | ||||
|  | ||||
|     /** | ||||
|      * @var array | ||||
|      */ | ||||
|     private $columnStyles = []; | ||||
|  | ||||
|     /** | ||||
|      * User set column widths. | ||||
|      * | ||||
|      * @var array | ||||
|      */ | ||||
|     private $columnWidths = []; | ||||
|     private $columnMaxWidths = []; | ||||
|  | ||||
|     private static $styles; | ||||
|  | ||||
|     private $rendered = false; | ||||
|  | ||||
|     public function __construct(OutputInterface $output) | ||||
|     { | ||||
|         $this->output = $output; | ||||
|  | ||||
|         if (!self::$styles) { | ||||
|             self::$styles = self::initStyles(); | ||||
|         } | ||||
|  | ||||
|         $this->setStyle('default'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Sets a style definition. | ||||
|      * | ||||
|      * @param string     $name  The style name | ||||
|      * @param TableStyle $style A TableStyle instance | ||||
|      */ | ||||
|     public static function setStyleDefinition($name, TableStyle $style) | ||||
|     { | ||||
|         if (!self::$styles) { | ||||
|             self::$styles = self::initStyles(); | ||||
|         } | ||||
|  | ||||
|         self::$styles[$name] = $style; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Gets a style definition by name. | ||||
|      * | ||||
|      * @param string $name The style name | ||||
|      * | ||||
|      * @return TableStyle | ||||
|      */ | ||||
|     public static function getStyleDefinition($name) | ||||
|     { | ||||
|         if (!self::$styles) { | ||||
|             self::$styles = self::initStyles(); | ||||
|         } | ||||
|  | ||||
|         if (isset(self::$styles[$name])) { | ||||
|             return self::$styles[$name]; | ||||
|         } | ||||
|  | ||||
|         throw new InvalidArgumentException(sprintf('Style "%s" is not defined.', $name)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Sets table style. | ||||
|      * | ||||
|      * @param TableStyle|string $name The style name or a TableStyle instance | ||||
|      * | ||||
|      * @return $this | ||||
|      */ | ||||
|     public function setStyle($name) | ||||
|     { | ||||
|         $this->style = $this->resolveStyle($name); | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Gets the current table style. | ||||
|      * | ||||
|      * @return TableStyle | ||||
|      */ | ||||
|     public function getStyle() | ||||
|     { | ||||
|         return $this->style; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Sets table column style. | ||||
|      * | ||||
|      * @param int               $columnIndex Column index | ||||
|      * @param TableStyle|string $name        The style name or a TableStyle instance | ||||
|      * | ||||
|      * @return $this | ||||
|      */ | ||||
|     public function setColumnStyle($columnIndex, $name) | ||||
|     { | ||||
|         $columnIndex = (int) $columnIndex; | ||||
|  | ||||
|         $this->columnStyles[$columnIndex] = $this->resolveStyle($name); | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Gets the current style for a column. | ||||
|      * | ||||
|      * If style was not set, it returns the global table style. | ||||
|      * | ||||
|      * @param int $columnIndex Column index | ||||
|      * | ||||
|      * @return TableStyle | ||||
|      */ | ||||
|     public function getColumnStyle($columnIndex) | ||||
|     { | ||||
|         return $this->columnStyles[$columnIndex] ?? $this->getStyle(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Sets the minimum width of a column. | ||||
|      * | ||||
|      * @param int $columnIndex Column index | ||||
|      * @param int $width       Minimum column width in characters | ||||
|      * | ||||
|      * @return $this | ||||
|      */ | ||||
|     public function setColumnWidth($columnIndex, $width) | ||||
|     { | ||||
|         $this->columnWidths[(int) $columnIndex] = (int) $width; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Sets the minimum width of all columns. | ||||
|      * | ||||
|      * @param array $widths | ||||
|      * | ||||
|      * @return $this | ||||
|      */ | ||||
|     public function setColumnWidths(array $widths) | ||||
|     { | ||||
|         $this->columnWidths = []; | ||||
|         foreach ($widths as $index => $width) { | ||||
|             $this->setColumnWidth($index, $width); | ||||
|         } | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Sets the maximum width of a column. | ||||
|      * | ||||
|      * Any cell within this column which contents exceeds the specified width will be wrapped into multiple lines, while | ||||
|      * formatted strings are preserved. | ||||
|      * | ||||
|      * @return $this | ||||
|      */ | ||||
|     public function setColumnMaxWidth(int $columnIndex, int $width): self | ||||
|     { | ||||
|         if (!$this->output->getFormatter() instanceof WrappableOutputFormatterInterface) { | ||||
|             throw new \LogicException(sprintf('Setting a maximum column width is only supported when using a "%s" formatter, got "%s".', WrappableOutputFormatterInterface::class, \get_class($this->output->getFormatter()))); | ||||
|         } | ||||
|  | ||||
|         $this->columnMaxWidths[$columnIndex] = $width; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     public function setHeaders(array $headers) | ||||
|     { | ||||
|         $headers = array_values($headers); | ||||
|         if (!empty($headers) && !\is_array($headers[0])) { | ||||
|             $headers = [$headers]; | ||||
|         } | ||||
|  | ||||
|         $this->headers = $headers; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     public function setRows(array $rows) | ||||
|     { | ||||
|         $this->rows = []; | ||||
|  | ||||
|         return $this->addRows($rows); | ||||
|     } | ||||
|  | ||||
|     public function addRows(array $rows) | ||||
|     { | ||||
|         foreach ($rows as $row) { | ||||
|             $this->addRow($row); | ||||
|         } | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     public function addRow($row) | ||||
|     { | ||||
|         if ($row instanceof TableSeparator) { | ||||
|             $this->rows[] = $row; | ||||
|  | ||||
|             return $this; | ||||
|         } | ||||
|  | ||||
|         if (!\is_array($row)) { | ||||
|             throw new InvalidArgumentException('A row must be an array or a TableSeparator instance.'); | ||||
|         } | ||||
|  | ||||
|         $this->rows[] = array_values($row); | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Adds a row to the table, and re-renders the table. | ||||
|      */ | ||||
|     public function appendRow($row): self | ||||
|     { | ||||
|         if (!$this->output instanceof ConsoleSectionOutput) { | ||||
|             throw new RuntimeException(sprintf('Output should be an instance of "%s" when calling "%s".', ConsoleSectionOutput::class, __METHOD__)); | ||||
|         } | ||||
|  | ||||
|         if ($this->rendered) { | ||||
|             $this->output->clear($this->calculateRowCount()); | ||||
|         } | ||||
|  | ||||
|         $this->addRow($row); | ||||
|         $this->render(); | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     public function setRow($column, array $row) | ||||
|     { | ||||
|         $this->rows[$column] = $row; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     public function setHeaderTitle(?string $title): self | ||||
|     { | ||||
|         $this->headerTitle = $title; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     public function setFooterTitle(?string $title): self | ||||
|     { | ||||
|         $this->footerTitle = $title; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Renders table to output. | ||||
|      * | ||||
|      * Example: | ||||
|      * | ||||
|      *     +---------------+-----------------------+------------------+ | ||||
|      *     | ISBN          | Title                 | Author           | | ||||
|      *     +---------------+-----------------------+------------------+ | ||||
|      *     | 99921-58-10-7 | Divine Comedy         | Dante Alighieri  | | ||||
|      *     | 9971-5-0210-0 | A Tale of Two Cities  | Charles Dickens  | | ||||
|      *     | 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien | | ||||
|      *     +---------------+-----------------------+------------------+ | ||||
|      */ | ||||
|     public function render() | ||||
|     { | ||||
|         $rows = array_merge($this->headers, [$divider = new TableSeparator()], $this->rows); | ||||
|         $this->calculateNumberOfColumns($rows); | ||||
|  | ||||
|         $rows = $this->buildTableRows($rows); | ||||
|         $this->calculateColumnsWidth($rows); | ||||
|  | ||||
|         $isHeader = true; | ||||
|         $isFirstRow = false; | ||||
|         foreach ($rows as $row) { | ||||
|             if ($divider === $row) { | ||||
|                 $isHeader = false; | ||||
|                 $isFirstRow = true; | ||||
|  | ||||
|                 continue; | ||||
|             } | ||||
|             if ($row instanceof TableSeparator) { | ||||
|                 $this->renderRowSeparator(); | ||||
|  | ||||
|                 continue; | ||||
|             } | ||||
|             if (!$row) { | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             if ($isHeader || $isFirstRow) { | ||||
|                 if ($isFirstRow) { | ||||
|                     $this->renderRowSeparator(self::SEPARATOR_TOP_BOTTOM); | ||||
|                     $isFirstRow = false; | ||||
|                 } else { | ||||
|                     $this->renderRowSeparator(self::SEPARATOR_TOP, $this->headerTitle, $this->style->getHeaderTitleFormat()); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             $this->renderRow($row, $isHeader ? $this->style->getCellHeaderFormat() : $this->style->getCellRowFormat()); | ||||
|         } | ||||
|         $this->renderRowSeparator(self::SEPARATOR_BOTTOM, $this->footerTitle, $this->style->getFooterTitleFormat()); | ||||
|  | ||||
|         $this->cleanup(); | ||||
|         $this->rendered = true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Renders horizontal header separator. | ||||
|      * | ||||
|      * Example: | ||||
|      * | ||||
|      *     +-----+-----------+-------+ | ||||
|      */ | ||||
|     private function renderRowSeparator(int $type = self::SEPARATOR_MID, string $title = null, string $titleFormat = null) | ||||
|     { | ||||
|         if (0 === $count = $this->numberOfColumns) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         $borders = $this->style->getBorderChars(); | ||||
|         if (!$borders[0] && !$borders[2] && !$this->style->getCrossingChar()) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         $crossings = $this->style->getCrossingChars(); | ||||
|         if (self::SEPARATOR_MID === $type) { | ||||
|             list($horizontal, $leftChar, $midChar, $rightChar) = [$borders[2], $crossings[8], $crossings[0], $crossings[4]]; | ||||
|         } elseif (self::SEPARATOR_TOP === $type) { | ||||
|             list($horizontal, $leftChar, $midChar, $rightChar) = [$borders[0], $crossings[1], $crossings[2], $crossings[3]]; | ||||
|         } elseif (self::SEPARATOR_TOP_BOTTOM === $type) { | ||||
|             list($horizontal, $leftChar, $midChar, $rightChar) = [$borders[0], $crossings[9], $crossings[10], $crossings[11]]; | ||||
|         } else { | ||||
|             list($horizontal, $leftChar, $midChar, $rightChar) = [$borders[0], $crossings[7], $crossings[6], $crossings[5]]; | ||||
|         } | ||||
|  | ||||
|         $markup = $leftChar; | ||||
|         for ($column = 0; $column < $count; ++$column) { | ||||
|             $markup .= str_repeat($horizontal, $this->effectiveColumnWidths[$column]); | ||||
|             $markup .= $column === $count - 1 ? $rightChar : $midChar; | ||||
|         } | ||||
|  | ||||
|         if (null !== $title) { | ||||
|             $titleLength = Helper::strlenWithoutDecoration($formatter = $this->output->getFormatter(), $formattedTitle = sprintf($titleFormat, $title)); | ||||
|             $markupLength = Helper::strlen($markup); | ||||
|             if ($titleLength > $limit = $markupLength - 4) { | ||||
|                 $titleLength = $limit; | ||||
|                 $formatLength = Helper::strlenWithoutDecoration($formatter, sprintf($titleFormat, '')); | ||||
|                 $formattedTitle = sprintf($titleFormat, Helper::substr($title, 0, $limit - $formatLength - 3).'...'); | ||||
|             } | ||||
|  | ||||
|             $titleStart = ($markupLength - $titleLength) / 2; | ||||
|             if (false === mb_detect_encoding($markup, null, true)) { | ||||
|                 $markup = substr_replace($markup, $formattedTitle, $titleStart, $titleLength); | ||||
|             } else { | ||||
|                 $markup = mb_substr($markup, 0, $titleStart).$formattedTitle.mb_substr($markup, $titleStart + $titleLength); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         $this->output->writeln(sprintf($this->style->getBorderFormat(), $markup)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Renders vertical column separator. | ||||
|      */ | ||||
|     private function renderColumnSeparator($type = self::BORDER_OUTSIDE) | ||||
|     { | ||||
|         $borders = $this->style->getBorderChars(); | ||||
|  | ||||
|         return sprintf($this->style->getBorderFormat(), self::BORDER_OUTSIDE === $type ? $borders[1] : $borders[3]); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Renders table row. | ||||
|      * | ||||
|      * Example: | ||||
|      * | ||||
|      *     | 9971-5-0210-0 | A Tale of Two Cities  | Charles Dickens  | | ||||
|      */ | ||||
|     private function renderRow(array $row, string $cellFormat) | ||||
|     { | ||||
|         $rowContent = $this->renderColumnSeparator(self::BORDER_OUTSIDE); | ||||
|         $columns = $this->getRowColumns($row); | ||||
|         $last = \count($columns) - 1; | ||||
|         foreach ($columns as $i => $column) { | ||||
|             $rowContent .= $this->renderCell($row, $column, $cellFormat); | ||||
|             $rowContent .= $this->renderColumnSeparator($last === $i ? self::BORDER_OUTSIDE : self::BORDER_INSIDE); | ||||
|         } | ||||
|         $this->output->writeln($rowContent); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Renders table cell with padding. | ||||
|      */ | ||||
|     private function renderCell(array $row, int $column, string $cellFormat) | ||||
|     { | ||||
|         $cell = isset($row[$column]) ? $row[$column] : ''; | ||||
|         $width = $this->effectiveColumnWidths[$column]; | ||||
|         if ($cell instanceof TableCell && $cell->getColspan() > 1) { | ||||
|             // add the width of the following columns(numbers of colspan). | ||||
|             foreach (range($column + 1, $column + $cell->getColspan() - 1) as $nextColumn) { | ||||
|                 $width += $this->getColumnSeparatorWidth() + $this->effectiveColumnWidths[$nextColumn]; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // str_pad won't work properly with multi-byte strings, we need to fix the padding | ||||
|         if (false !== $encoding = mb_detect_encoding($cell, null, true)) { | ||||
|             $width += \strlen($cell) - mb_strwidth($cell, $encoding); | ||||
|         } | ||||
|  | ||||
|         $style = $this->getColumnStyle($column); | ||||
|  | ||||
|         if ($cell instanceof TableSeparator) { | ||||
|             return sprintf($style->getBorderFormat(), str_repeat($style->getBorderChars()[2], $width)); | ||||
|         } | ||||
|  | ||||
|         $width += Helper::strlen($cell) - Helper::strlenWithoutDecoration($this->output->getFormatter(), $cell); | ||||
|         $content = sprintf($style->getCellRowContentFormat(), $cell); | ||||
|  | ||||
|         return sprintf($cellFormat, str_pad($content, $width, $style->getPaddingChar(), $style->getPadType())); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Calculate number of columns for this table. | ||||
|      */ | ||||
|     private function calculateNumberOfColumns($rows) | ||||
|     { | ||||
|         $columns = [0]; | ||||
|         foreach ($rows as $row) { | ||||
|             if ($row instanceof TableSeparator) { | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             $columns[] = $this->getNumberOfColumns($row); | ||||
|         } | ||||
|  | ||||
|         $this->numberOfColumns = max($columns); | ||||
|     } | ||||
|  | ||||
|     private function buildTableRows($rows) | ||||
|     { | ||||
|         /** @var WrappableOutputFormatterInterface $formatter */ | ||||
|         $formatter = $this->output->getFormatter(); | ||||
|         $unmergedRows = []; | ||||
|         for ($rowKey = 0; $rowKey < \count($rows); ++$rowKey) { | ||||
|             $rows = $this->fillNextRows($rows, $rowKey); | ||||
|  | ||||
|             // Remove any new line breaks and replace it with a new line | ||||
|             foreach ($rows[$rowKey] as $column => $cell) { | ||||
|                 $colspan = $cell instanceof TableCell ? $cell->getColspan() : 1; | ||||
|  | ||||
|                 if (isset($this->columnMaxWidths[$column]) && Helper::strlenWithoutDecoration($formatter, $cell) > $this->columnMaxWidths[$column]) { | ||||
|                     $cell = $formatter->formatAndWrap($cell, $this->columnMaxWidths[$column] * $colspan); | ||||
|                 } | ||||
|                 if (!strstr($cell, "\n")) { | ||||
|                     continue; | ||||
|                 } | ||||
|                 $escaped = implode("\n", array_map([OutputFormatter::class, 'escapeTrailingBackslash'], explode("\n", $cell))); | ||||
|                 $cell = $cell instanceof TableCell ? new TableCell($escaped, ['colspan' => $cell->getColspan()]) : $escaped; | ||||
|                 $lines = explode("\n", str_replace("\n", "<fg=default;bg=default>\n</>", $cell)); | ||||
|                 foreach ($lines as $lineKey => $line) { | ||||
|                     if ($colspan > 1) { | ||||
|                         $line = new TableCell($line, ['colspan' => $colspan]); | ||||
|                     } | ||||
|                     if (0 === $lineKey) { | ||||
|                         $rows[$rowKey][$column] = $line; | ||||
|                     } else { | ||||
|                         $unmergedRows[$rowKey][$lineKey][$column] = $line; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return new TableRows(function () use ($rows, $unmergedRows) { | ||||
|             foreach ($rows as $rowKey => $row) { | ||||
|                 yield $this->fillCells($row); | ||||
|  | ||||
|                 if (isset($unmergedRows[$rowKey])) { | ||||
|                     foreach ($unmergedRows[$rowKey] as $row) { | ||||
|                         yield $row; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     private function calculateRowCount(): int | ||||
|     { | ||||
|         $numberOfRows = \count(iterator_to_array($this->buildTableRows(array_merge($this->headers, [new TableSeparator()], $this->rows)))); | ||||
|  | ||||
|         if ($this->headers) { | ||||
|             ++$numberOfRows; // Add row for header separator | ||||
|         } | ||||
|  | ||||
|         ++$numberOfRows; // Add row for footer separator | ||||
|  | ||||
|         return $numberOfRows; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * fill rows that contains rowspan > 1. | ||||
|      * | ||||
|      * @throws InvalidArgumentException | ||||
|      */ | ||||
|     private function fillNextRows(array $rows, int $line): array | ||||
|     { | ||||
|         $unmergedRows = []; | ||||
|         foreach ($rows[$line] as $column => $cell) { | ||||
|             if (null !== $cell && !$cell instanceof TableCell && !is_scalar($cell) && !(\is_object($cell) && method_exists($cell, '__toString'))) { | ||||
|                 throw new InvalidArgumentException(sprintf('A cell must be a TableCell, a scalar or an object implementing __toString, %s given.', \gettype($cell))); | ||||
|             } | ||||
|             if ($cell instanceof TableCell && $cell->getRowspan() > 1) { | ||||
|                 $nbLines = $cell->getRowspan() - 1; | ||||
|                 $lines = [$cell]; | ||||
|                 if (strstr($cell, "\n")) { | ||||
|                     $lines = explode("\n", str_replace("\n", "<fg=default;bg=default>\n</>", $cell)); | ||||
|                     $nbLines = \count($lines) > $nbLines ? substr_count($cell, "\n") : $nbLines; | ||||
|  | ||||
|                     $rows[$line][$column] = new TableCell($lines[0], ['colspan' => $cell->getColspan()]); | ||||
|                     unset($lines[0]); | ||||
|                 } | ||||
|  | ||||
|                 // create a two dimensional array (rowspan x colspan) | ||||
|                 $unmergedRows = array_replace_recursive(array_fill($line + 1, $nbLines, []), $unmergedRows); | ||||
|                 foreach ($unmergedRows as $unmergedRowKey => $unmergedRow) { | ||||
|                     $value = isset($lines[$unmergedRowKey - $line]) ? $lines[$unmergedRowKey - $line] : ''; | ||||
|                     $unmergedRows[$unmergedRowKey][$column] = new TableCell($value, ['colspan' => $cell->getColspan()]); | ||||
|                     if ($nbLines === $unmergedRowKey - $line) { | ||||
|                         break; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         foreach ($unmergedRows as $unmergedRowKey => $unmergedRow) { | ||||
|             // we need to know if $unmergedRow will be merged or inserted into $rows | ||||
|             if (isset($rows[$unmergedRowKey]) && \is_array($rows[$unmergedRowKey]) && ($this->getNumberOfColumns($rows[$unmergedRowKey]) + $this->getNumberOfColumns($unmergedRows[$unmergedRowKey]) <= $this->numberOfColumns)) { | ||||
|                 foreach ($unmergedRow as $cellKey => $cell) { | ||||
|                     // insert cell into row at cellKey position | ||||
|                     array_splice($rows[$unmergedRowKey], $cellKey, 0, [$cell]); | ||||
|                 } | ||||
|             } else { | ||||
|                 $row = $this->copyRow($rows, $unmergedRowKey - 1); | ||||
|                 foreach ($unmergedRow as $column => $cell) { | ||||
|                     if (!empty($cell)) { | ||||
|                         $row[$column] = $unmergedRow[$column]; | ||||
|                     } | ||||
|                 } | ||||
|                 array_splice($rows, $unmergedRowKey, 0, [$row]); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return $rows; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * fill cells for a row that contains colspan > 1. | ||||
|      */ | ||||
|     private function fillCells($row) | ||||
|     { | ||||
|         $newRow = []; | ||||
|         foreach ($row as $column => $cell) { | ||||
|             $newRow[] = $cell; | ||||
|             if ($cell instanceof TableCell && $cell->getColspan() > 1) { | ||||
|                 foreach (range($column + 1, $column + $cell->getColspan() - 1) as $position) { | ||||
|                     // insert empty value at column position | ||||
|                     $newRow[] = ''; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return $newRow ?: $row; | ||||
|     } | ||||
|  | ||||
|     private function copyRow(array $rows, int $line): array | ||||
|     { | ||||
|         $row = $rows[$line]; | ||||
|         foreach ($row as $cellKey => $cellValue) { | ||||
|             $row[$cellKey] = ''; | ||||
|             if ($cellValue instanceof TableCell) { | ||||
|                 $row[$cellKey] = new TableCell('', ['colspan' => $cellValue->getColspan()]); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return $row; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Gets number of columns by row. | ||||
|      */ | ||||
|     private function getNumberOfColumns(array $row): int | ||||
|     { | ||||
|         $columns = \count($row); | ||||
|         foreach ($row as $column) { | ||||
|             $columns += $column instanceof TableCell ? ($column->getColspan() - 1) : 0; | ||||
|         } | ||||
|  | ||||
|         return $columns; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Gets list of columns for the given row. | ||||
|      */ | ||||
|     private function getRowColumns(array $row): array | ||||
|     { | ||||
|         $columns = range(0, $this->numberOfColumns - 1); | ||||
|         foreach ($row as $cellKey => $cell) { | ||||
|             if ($cell instanceof TableCell && $cell->getColspan() > 1) { | ||||
|                 // exclude grouped columns. | ||||
|                 $columns = array_diff($columns, range($cellKey + 1, $cellKey + $cell->getColspan() - 1)); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return $columns; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Calculates columns widths. | ||||
|      */ | ||||
|     private function calculateColumnsWidth(iterable $rows) | ||||
|     { | ||||
|         for ($column = 0; $column < $this->numberOfColumns; ++$column) { | ||||
|             $lengths = []; | ||||
|             foreach ($rows as $row) { | ||||
|                 if ($row instanceof TableSeparator) { | ||||
|                     continue; | ||||
|                 } | ||||
|  | ||||
|                 foreach ($row as $i => $cell) { | ||||
|                     if ($cell instanceof TableCell) { | ||||
|                         $textContent = Helper::removeDecoration($this->output->getFormatter(), $cell); | ||||
|                         $textLength = Helper::strlen($textContent); | ||||
|                         if ($textLength > 0) { | ||||
|                             $contentColumns = str_split($textContent, ceil($textLength / $cell->getColspan())); | ||||
|                             foreach ($contentColumns as $position => $content) { | ||||
|                                 $row[$i + $position] = $content; | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 $lengths[] = $this->getCellWidth($row, $column); | ||||
|             } | ||||
|  | ||||
|             $this->effectiveColumnWidths[$column] = max($lengths) + Helper::strlen($this->style->getCellRowContentFormat()) - 2; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private function getColumnSeparatorWidth(): int | ||||
|     { | ||||
|         return Helper::strlen(sprintf($this->style->getBorderFormat(), $this->style->getBorderChars()[3])); | ||||
|     } | ||||
|  | ||||
|     private function getCellWidth(array $row, int $column): int | ||||
|     { | ||||
|         $cellWidth = 0; | ||||
|  | ||||
|         if (isset($row[$column])) { | ||||
|             $cell = $row[$column]; | ||||
|             $cellWidth = Helper::strlenWithoutDecoration($this->output->getFormatter(), $cell); | ||||
|         } | ||||
|  | ||||
|         $columnWidth = isset($this->columnWidths[$column]) ? $this->columnWidths[$column] : 0; | ||||
|         $cellWidth = max($cellWidth, $columnWidth); | ||||
|  | ||||
|         return isset($this->columnMaxWidths[$column]) ? min($this->columnMaxWidths[$column], $cellWidth) : $cellWidth; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Called after rendering to cleanup cache data. | ||||
|      */ | ||||
|     private function cleanup() | ||||
|     { | ||||
|         $this->effectiveColumnWidths = []; | ||||
|         $this->numberOfColumns = null; | ||||
|     } | ||||
|  | ||||
|     private static function initStyles() | ||||
|     { | ||||
|         $borderless = new TableStyle(); | ||||
|         $borderless | ||||
|             ->setHorizontalBorderChars('=') | ||||
|             ->setVerticalBorderChars(' ') | ||||
|             ->setDefaultCrossingChar(' ') | ||||
|         ; | ||||
|  | ||||
|         $compact = new TableStyle(); | ||||
|         $compact | ||||
|             ->setHorizontalBorderChars('') | ||||
|             ->setVerticalBorderChars(' ') | ||||
|             ->setDefaultCrossingChar('') | ||||
|             ->setCellRowContentFormat('%s') | ||||
|         ; | ||||
|  | ||||
|         $styleGuide = new TableStyle(); | ||||
|         $styleGuide | ||||
|             ->setHorizontalBorderChars('-') | ||||
|             ->setVerticalBorderChars(' ') | ||||
|             ->setDefaultCrossingChar(' ') | ||||
|             ->setCellHeaderFormat('%s') | ||||
|         ; | ||||
|  | ||||
|         $box = (new TableStyle()) | ||||
|             ->setHorizontalBorderChars('─') | ||||
|             ->setVerticalBorderChars('│') | ||||
|             ->setCrossingChars('┼', '┌', '┬', '┐', '┤', '┘', '┴', '└', '├') | ||||
|         ; | ||||
|  | ||||
|         $boxDouble = (new TableStyle()) | ||||
|             ->setHorizontalBorderChars('═', '─') | ||||
|             ->setVerticalBorderChars('║', '│') | ||||
|             ->setCrossingChars('┼', '╔', '╤', '╗', '╢', '╝', '╧', '╚', '╟', '╠', '╪', '╣') | ||||
|         ; | ||||
|  | ||||
|         return [ | ||||
|             'default' => new TableStyle(), | ||||
|             'borderless' => $borderless, | ||||
|             'compact' => $compact, | ||||
|             'symfony-style-guide' => $styleGuide, | ||||
|             'box' => $box, | ||||
|             'box-double' => $boxDouble, | ||||
|         ]; | ||||
|     } | ||||
|  | ||||
|     private function resolveStyle($name) | ||||
|     { | ||||
|         if ($name instanceof TableStyle) { | ||||
|             return $name; | ||||
|         } | ||||
|  | ||||
|         if (isset(self::$styles[$name])) { | ||||
|             return self::$styles[$name]; | ||||
|         } | ||||
|  | ||||
|         throw new InvalidArgumentException(sprintf('Style "%s" is not defined.', $name)); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										68
									
								
								vendor/symfony/console/Helper/TableCell.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								vendor/symfony/console/Helper/TableCell.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,68 @@ | ||||
| <?php | ||||
|  | ||||
| /* | ||||
|  * This file is part of the Symfony package. | ||||
|  * | ||||
|  * (c) Fabien Potencier <fabien@symfony.com> | ||||
|  * | ||||
|  * For the full copyright and license information, please view the LICENSE | ||||
|  * file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| namespace Symfony\Component\Console\Helper; | ||||
|  | ||||
| use Symfony\Component\Console\Exception\InvalidArgumentException; | ||||
|  | ||||
| /** | ||||
|  * @author Abdellatif Ait boudad <a.aitboudad@gmail.com> | ||||
|  */ | ||||
| class TableCell | ||||
| { | ||||
|     private $value; | ||||
|     private $options = [ | ||||
|         'rowspan' => 1, | ||||
|         'colspan' => 1, | ||||
|     ]; | ||||
|  | ||||
|     public function __construct(string $value = '', array $options = []) | ||||
|     { | ||||
|         $this->value = $value; | ||||
|  | ||||
|         // check option names | ||||
|         if ($diff = array_diff(array_keys($options), array_keys($this->options))) { | ||||
|             throw new InvalidArgumentException(sprintf('The TableCell does not support the following options: \'%s\'.', implode('\', \'', $diff))); | ||||
|         } | ||||
|  | ||||
|         $this->options = array_merge($this->options, $options); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Returns the cell value. | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     public function __toString() | ||||
|     { | ||||
|         return $this->value; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Gets number of colspan. | ||||
|      * | ||||
|      * @return int | ||||
|      */ | ||||
|     public function getColspan() | ||||
|     { | ||||
|         return (int) $this->options['colspan']; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Gets number of rowspan. | ||||
|      * | ||||
|      * @return int | ||||
|      */ | ||||
|     public function getRowspan() | ||||
|     { | ||||
|         return (int) $this->options['rowspan']; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										32
									
								
								vendor/symfony/console/Helper/TableRows.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								vendor/symfony/console/Helper/TableRows.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | ||||
| <?php | ||||
|  | ||||
| /* | ||||
|  * This file is part of the Symfony package. | ||||
|  * | ||||
|  * (c) Fabien Potencier <fabien@symfony.com> | ||||
|  * | ||||
|  * For the full copyright and license information, please view the LICENSE | ||||
|  * file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| namespace Symfony\Component\Console\Helper; | ||||
|  | ||||
| /** | ||||
|  * @internal | ||||
|  */ | ||||
| class TableRows implements \IteratorAggregate | ||||
| { | ||||
|     private $generator; | ||||
|  | ||||
|     public function __construct(callable $generator) | ||||
|     { | ||||
|         $this->generator = $generator; | ||||
|     } | ||||
|  | ||||
|     public function getIterator() | ||||
|     { | ||||
|         $g = $this->generator; | ||||
|  | ||||
|         return $g(); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										25
									
								
								vendor/symfony/console/Helper/TableSeparator.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								vendor/symfony/console/Helper/TableSeparator.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | ||||
| <?php | ||||
|  | ||||
| /* | ||||
|  * This file is part of the Symfony package. | ||||
|  * | ||||
|  * (c) Fabien Potencier <fabien@symfony.com> | ||||
|  * | ||||
|  * For the full copyright and license information, please view the LICENSE | ||||
|  * file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| namespace Symfony\Component\Console\Helper; | ||||
|  | ||||
| /** | ||||
|  * Marks a row as being a separator. | ||||
|  * | ||||
|  * @author Fabien Potencier <fabien@symfony.com> | ||||
|  */ | ||||
| class TableSeparator extends TableCell | ||||
| { | ||||
|     public function __construct(array $options = []) | ||||
|     { | ||||
|         parent::__construct('', $options); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										458
									
								
								vendor/symfony/console/Helper/TableStyle.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										458
									
								
								vendor/symfony/console/Helper/TableStyle.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,458 @@ | ||||
| <?php | ||||
|  | ||||
| /* | ||||
|  * This file is part of the Symfony package. | ||||
|  * | ||||
|  * (c) Fabien Potencier <fabien@symfony.com> | ||||
|  * | ||||
|  * For the full copyright and license information, please view the LICENSE | ||||
|  * file that was distributed with this source code. | ||||
|  */ | ||||
|  | ||||
| namespace Symfony\Component\Console\Helper; | ||||
|  | ||||
| use Symfony\Component\Console\Exception\InvalidArgumentException; | ||||
| use Symfony\Component\Console\Exception\LogicException; | ||||
|  | ||||
| /** | ||||
|  * Defines the styles for a Table. | ||||
|  * | ||||
|  * @author Fabien Potencier <fabien@symfony.com> | ||||
|  * @author Саша Стаменковић <umpirsky@gmail.com> | ||||
|  * @author Dany Maillard <danymaillard93b@gmail.com> | ||||
|  */ | ||||
| class TableStyle | ||||
| { | ||||
|     private $paddingChar = ' '; | ||||
|     private $horizontalOutsideBorderChar = '-'; | ||||
|     private $horizontalInsideBorderChar = '-'; | ||||
|     private $verticalOutsideBorderChar = '|'; | ||||
|     private $verticalInsideBorderChar = '|'; | ||||
|     private $crossingChar = '+'; | ||||
|     private $crossingTopRightChar = '+'; | ||||
|     private $crossingTopMidChar = '+'; | ||||
|     private $crossingTopLeftChar = '+'; | ||||
|     private $crossingMidRightChar = '+'; | ||||
|     private $crossingBottomRightChar = '+'; | ||||
|     private $crossingBottomMidChar = '+'; | ||||
|     private $crossingBottomLeftChar = '+'; | ||||
|     private $crossingMidLeftChar = '+'; | ||||
|     private $crossingTopLeftBottomChar = '+'; | ||||
|     private $crossingTopMidBottomChar = '+'; | ||||
|     private $crossingTopRightBottomChar = '+'; | ||||
|     private $headerTitleFormat = '<fg=black;bg=white;options=bold> %s </>'; | ||||
|     private $footerTitleFormat = '<fg=black;bg=white;options=bold> %s </>'; | ||||
|     private $cellHeaderFormat = '<info>%s</info>'; | ||||
|     private $cellRowFormat = '%s'; | ||||
|     private $cellRowContentFormat = ' %s '; | ||||
|     private $borderFormat = '%s'; | ||||
|     private $padType = STR_PAD_RIGHT; | ||||
|  | ||||
|     /** | ||||
|      * Sets padding character, used for cell padding. | ||||
|      * | ||||
|      * @param string $paddingChar | ||||
|      * | ||||
|      * @return $this | ||||
|      */ | ||||
|     public function setPaddingChar($paddingChar) | ||||
|     { | ||||
|         if (!$paddingChar) { | ||||
|             throw new LogicException('The padding char must not be empty'); | ||||
|         } | ||||
|  | ||||
|         $this->paddingChar = $paddingChar; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Gets padding character, used for cell padding. | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getPaddingChar() | ||||
|     { | ||||
|         return $this->paddingChar; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Sets horizontal border characters. | ||||
|      * | ||||
|      * <code> | ||||
|      * ╔═══════════════╤══════════════════════════╤══════════════════╗ | ||||
|      * 1 ISBN          2 Title                    │ Author           ║ | ||||
|      * ╠═══════════════╪══════════════════════════╪══════════════════╣ | ||||
|      * ║ 99921-58-10-7 │ Divine Comedy            │ Dante Alighieri  ║ | ||||
|      * ║ 9971-5-0210-0 │ A Tale of Two Cities     │ Charles Dickens  ║ | ||||
|      * ║ 960-425-059-0 │ The Lord of the Rings    │ J. R. R. Tolkien ║ | ||||
|      * ║ 80-902734-1-6 │ And Then There Were None │ Agatha Christie  ║ | ||||
|      * ╚═══════════════╧══════════════════════════╧══════════════════╝ | ||||
|      * </code> | ||||
|      * | ||||
|      * @param string      $outside Outside border char (see #1 of example) | ||||
|      * @param string|null $inside  Inside border char (see #2 of example), equals $outside if null | ||||
|      */ | ||||
|     public function setHorizontalBorderChars(string $outside, string $inside = null): self | ||||
|     { | ||||
|         $this->horizontalOutsideBorderChar = $outside; | ||||
|         $this->horizontalInsideBorderChar = $inside ?? $outside; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Sets horizontal border character. | ||||
|      * | ||||
|      * @param string $horizontalBorderChar | ||||
|      * | ||||
|      * @return $this | ||||
|      * | ||||
|      * @deprecated since Symfony 4.1, use {@link setHorizontalBorderChars()} instead. | ||||
|      */ | ||||
|     public function setHorizontalBorderChar($horizontalBorderChar) | ||||
|     { | ||||
|         @trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.1, use setHorizontalBorderChars() instead.', __METHOD__), E_USER_DEPRECATED); | ||||
|  | ||||
|         return $this->setHorizontalBorderChars($horizontalBorderChar, $horizontalBorderChar); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Gets horizontal border character. | ||||
|      * | ||||
|      * @return string | ||||
|      * | ||||
|      * @deprecated since Symfony 4.1, use {@link getBorderChars()} instead. | ||||
|      */ | ||||
|     public function getHorizontalBorderChar() | ||||
|     { | ||||
|         @trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.1, use getBorderChars() instead.', __METHOD__), E_USER_DEPRECATED); | ||||
|  | ||||
|         return $this->horizontalOutsideBorderChar; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Sets vertical border characters. | ||||
|      * | ||||
|      * <code> | ||||
|      * ╔═══════════════╤══════════════════════════╤══════════════════╗ | ||||
|      * ║ ISBN          │ Title                    │ Author           ║ | ||||
|      * ╠═══════1═══════╪══════════════════════════╪══════════════════╣ | ||||
|      * ║ 99921-58-10-7 │ Divine Comedy            │ Dante Alighieri  ║ | ||||
|      * ║ 9971-5-0210-0 │ A Tale of Two Cities     │ Charles Dickens  ║ | ||||
|      * ╟───────2───────┼──────────────────────────┼──────────────────╢ | ||||
|      * ║ 960-425-059-0 │ The Lord of the Rings    │ J. R. R. Tolkien ║ | ||||
|      * ║ 80-902734-1-6 │ And Then There Were None │ Agatha Christie  ║ | ||||
|      * ╚═══════════════╧══════════════════════════╧══════════════════╝ | ||||
|      * </code> | ||||
|      * | ||||
|      * @param string      $outside Outside border char (see #1 of example) | ||||
|      * @param string|null $inside  Inside border char (see #2 of example), equals $outside if null | ||||
|      */ | ||||
|     public function setVerticalBorderChars(string $outside, string $inside = null): self | ||||
|     { | ||||
|         $this->verticalOutsideBorderChar = $outside; | ||||
|         $this->verticalInsideBorderChar = $inside ?? $outside; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Sets vertical border character. | ||||
|      * | ||||
|      * @param string $verticalBorderChar | ||||
|      * | ||||
|      * @return $this | ||||
|      * | ||||
|      * @deprecated since Symfony 4.1, use {@link setVerticalBorderChars()} instead. | ||||
|      */ | ||||
|     public function setVerticalBorderChar($verticalBorderChar) | ||||
|     { | ||||
|         @trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.1, use setVerticalBorderChars() instead.', __METHOD__), E_USER_DEPRECATED); | ||||
|  | ||||
|         return $this->setVerticalBorderChars($verticalBorderChar, $verticalBorderChar); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Gets vertical border character. | ||||
|      * | ||||
|      * @return string | ||||
|      * | ||||
|      * @deprecated since Symfony 4.1, use {@link getBorderChars()} instead. | ||||
|      */ | ||||
|     public function getVerticalBorderChar() | ||||
|     { | ||||
|         @trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.1, use getBorderChars() instead.', __METHOD__), E_USER_DEPRECATED); | ||||
|  | ||||
|         return $this->verticalOutsideBorderChar; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Gets border characters. | ||||
|      * | ||||
|      * @internal | ||||
|      */ | ||||
|     public function getBorderChars() | ||||
|     { | ||||
|         return [ | ||||
|             $this->horizontalOutsideBorderChar, | ||||
|             $this->verticalOutsideBorderChar, | ||||
|             $this->horizontalInsideBorderChar, | ||||
|             $this->verticalInsideBorderChar, | ||||
|         ]; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Sets crossing characters. | ||||
|      * | ||||
|      * Example: | ||||
|      * <code> | ||||
|      * 1═══════════════2══════════════════════════2══════════════════3 | ||||
|      * ║ ISBN          │ Title                    │ Author           ║ | ||||
|      * 8'══════════════0'═════════════════════════0'═════════════════4' | ||||
|      * ║ 99921-58-10-7 │ Divine Comedy            │ Dante Alighieri  ║ | ||||
|      * ║ 9971-5-0210-0 │ A Tale of Two Cities     │ Charles Dickens  ║ | ||||
|      * 8───────────────0──────────────────────────0──────────────────4 | ||||
|      * ║ 960-425-059-0 │ The Lord of the Rings    │ J. R. R. Tolkien ║ | ||||
|      * ║ 80-902734-1-6 │ And Then There Were None │ Agatha Christie  ║ | ||||
|      * 7═══════════════6══════════════════════════6══════════════════5 | ||||
|      * </code> | ||||
|      * | ||||
|      * @param string      $cross          Crossing char (see #0 of example) | ||||
|      * @param string      $topLeft        Top left char (see #1 of example) | ||||
|      * @param string      $topMid         Top mid char (see #2 of example) | ||||
|      * @param string      $topRight       Top right char (see #3 of example) | ||||
|      * @param string      $midRight       Mid right char (see #4 of example) | ||||
|      * @param string      $bottomRight    Bottom right char (see #5 of example) | ||||
|      * @param string      $bottomMid      Bottom mid char (see #6 of example) | ||||
|      * @param string      $bottomLeft     Bottom left char (see #7 of example) | ||||
|      * @param string      $midLeft        Mid left char (see #8 of example) | ||||
|      * @param string|null $topLeftBottom  Top left bottom char (see #8' of example), equals to $midLeft if null | ||||
|      * @param string|null $topMidBottom   Top mid bottom char (see #0' of example), equals to $cross if null | ||||
|      * @param string|null $topRightBottom Top right bottom char (see #4' of example), equals to $midRight if null | ||||
|      */ | ||||
|     public function setCrossingChars(string $cross, string $topLeft, string $topMid, string $topRight, string $midRight, string $bottomRight, string $bottomMid, string $bottomLeft, string $midLeft, string $topLeftBottom = null, string $topMidBottom = null, string $topRightBottom = null): self | ||||
|     { | ||||
|         $this->crossingChar = $cross; | ||||
|         $this->crossingTopLeftChar = $topLeft; | ||||
|         $this->crossingTopMidChar = $topMid; | ||||
|         $this->crossingTopRightChar = $topRight; | ||||
|         $this->crossingMidRightChar = $midRight; | ||||
|         $this->crossingBottomRightChar = $bottomRight; | ||||
|         $this->crossingBottomMidChar = $bottomMid; | ||||
|         $this->crossingBottomLeftChar = $bottomLeft; | ||||
|         $this->crossingMidLeftChar = $midLeft; | ||||
|         $this->crossingTopLeftBottomChar = $topLeftBottom ?? $midLeft; | ||||
|         $this->crossingTopMidBottomChar = $topMidBottom ?? $cross; | ||||
|         $this->crossingTopRightBottomChar = $topRightBottom ?? $midRight; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Sets default crossing character used for each cross. | ||||
|      * | ||||
|      * @see {@link setCrossingChars()} for setting each crossing individually. | ||||
|      */ | ||||
|     public function setDefaultCrossingChar(string $char): self | ||||
|     { | ||||
|         return $this->setCrossingChars($char, $char, $char, $char, $char, $char, $char, $char, $char); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Sets crossing character. | ||||
|      * | ||||
|      * @param string $crossingChar | ||||
|      * | ||||
|      * @return $this | ||||
|      * | ||||
|      * @deprecated since Symfony 4.1. Use {@link setDefaultCrossingChar()} instead. | ||||
|      */ | ||||
|     public function setCrossingChar($crossingChar) | ||||
|     { | ||||
|         @trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.1. Use setDefaultCrossingChar() instead.', __METHOD__), E_USER_DEPRECATED); | ||||
|  | ||||
|         return $this->setDefaultCrossingChar($crossingChar); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Gets crossing character. | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getCrossingChar() | ||||
|     { | ||||
|         return $this->crossingChar; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Gets crossing characters. | ||||
|      * | ||||
|      * @internal | ||||
|      */ | ||||
|     public function getCrossingChars(): array | ||||
|     { | ||||
|         return [ | ||||
|             $this->crossingChar, | ||||
|             $this->crossingTopLeftChar, | ||||
|             $this->crossingTopMidChar, | ||||
|             $this->crossingTopRightChar, | ||||
|             $this->crossingMidRightChar, | ||||
|             $this->crossingBottomRightChar, | ||||
|             $this->crossingBottomMidChar, | ||||
|             $this->crossingBottomLeftChar, | ||||
|             $this->crossingMidLeftChar, | ||||
|             $this->crossingTopLeftBottomChar, | ||||
|             $this->crossingTopMidBottomChar, | ||||
|             $this->crossingTopRightBottomChar, | ||||
|         ]; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Sets header cell format. | ||||
|      * | ||||
|      * @param string $cellHeaderFormat | ||||
|      * | ||||
|      * @return $this | ||||
|      */ | ||||
|     public function setCellHeaderFormat($cellHeaderFormat) | ||||
|     { | ||||
|         $this->cellHeaderFormat = $cellHeaderFormat; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Gets header cell format. | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getCellHeaderFormat() | ||||
|     { | ||||
|         return $this->cellHeaderFormat; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Sets row cell format. | ||||
|      * | ||||
|      * @param string $cellRowFormat | ||||
|      * | ||||
|      * @return $this | ||||
|      */ | ||||
|     public function setCellRowFormat($cellRowFormat) | ||||
|     { | ||||
|         $this->cellRowFormat = $cellRowFormat; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Gets row cell format. | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getCellRowFormat() | ||||
|     { | ||||
|         return $this->cellRowFormat; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Sets row cell content format. | ||||
|      * | ||||
|      * @param string $cellRowContentFormat | ||||
|      * | ||||
|      * @return $this | ||||
|      */ | ||||
|     public function setCellRowContentFormat($cellRowContentFormat) | ||||
|     { | ||||
|         $this->cellRowContentFormat = $cellRowContentFormat; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Gets row cell content format. | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getCellRowContentFormat() | ||||
|     { | ||||
|         return $this->cellRowContentFormat; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Sets table border format. | ||||
|      * | ||||
|      * @param string $borderFormat | ||||
|      * | ||||
|      * @return $this | ||||
|      */ | ||||
|     public function setBorderFormat($borderFormat) | ||||
|     { | ||||
|         $this->borderFormat = $borderFormat; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Gets table border format. | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getBorderFormat() | ||||
|     { | ||||
|         return $this->borderFormat; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Sets cell padding type. | ||||
|      * | ||||
|      * @param int $padType STR_PAD_* | ||||
|      * | ||||
|      * @return $this | ||||
|      */ | ||||
|     public function setPadType($padType) | ||||
|     { | ||||
|         if (!\in_array($padType, [STR_PAD_LEFT, STR_PAD_RIGHT, STR_PAD_BOTH], true)) { | ||||
|             throw new InvalidArgumentException('Invalid padding type. Expected one of (STR_PAD_LEFT, STR_PAD_RIGHT, STR_PAD_BOTH).'); | ||||
|         } | ||||
|  | ||||
|         $this->padType = $padType; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Gets cell padding type. | ||||
|      * | ||||
|      * @return int | ||||
|      */ | ||||
|     public function getPadType() | ||||
|     { | ||||
|         return $this->padType; | ||||
|     } | ||||
|  | ||||
|     public function getHeaderTitleFormat(): string | ||||
|     { | ||||
|         return $this->headerTitleFormat; | ||||
|     } | ||||
|  | ||||
|     public function setHeaderTitleFormat(string $format): self | ||||
|     { | ||||
|         $this->headerTitleFormat = $format; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     public function getFooterTitleFormat(): string | ||||
|     { | ||||
|         return $this->footerTitleFormat; | ||||
|     } | ||||
|  | ||||
|     public function setFooterTitleFormat(string $format): self | ||||
|     { | ||||
|         $this->footerTitleFormat = $format; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user