2015-08-17 17:00:26 -07:00
< ? 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\Descriptor ;
use Symfony\Component\Console\Application ;
use Symfony\Component\Console\Command\Command ;
2017-02-02 16:28:38 -08:00
use Symfony\Component\Console\Formatter\OutputFormatter ;
use Symfony\Component\Console\Helper\Helper ;
2015-08-17 17:00:26 -07:00
use Symfony\Component\Console\Input\InputArgument ;
use Symfony\Component\Console\Input\InputDefinition ;
use Symfony\Component\Console\Input\InputOption ;
/**
* Text descriptor .
*
* @ author Jean - François Simon < contact @ jfsimon . fr >
*
* @ internal
*/
class TextDescriptor extends Descriptor
{
/**
* { @ inheritdoc }
*/
protected function describeInputArgument ( InputArgument $argument , array $options = array ())
{
if ( null !== $argument -> getDefault () && ( ! is_array ( $argument -> getDefault ()) || count ( $argument -> getDefault ()))) {
$default = sprintf ( '<comment> [default: %s]</comment>' , $this -> formatDefaultValue ( $argument -> getDefault ()));
} else {
$default = '' ;
}
2017-02-02 16:28:38 -08:00
$totalWidth = isset ( $options [ 'total_width' ]) ? $options [ 'total_width' ] : Helper :: strlen ( $argument -> getName ());
$spacingWidth = $totalWidth - strlen ( $argument -> getName ());
2015-08-17 17:00:26 -07:00
2017-02-02 16:28:38 -08:00
$this -> writeText ( sprintf ( ' <info>%s</info> %s%s%s' ,
2015-08-17 17:00:26 -07:00
$argument -> getName (),
str_repeat ( ' ' , $spacingWidth ),
2017-02-02 16:28:38 -08:00
// + 4 = 2 spaces before <info>, 2 spaces after </info>
preg_replace ( '/\s*[\r\n]\s*/' , " \n " . str_repeat ( ' ' , $totalWidth + 4 ), $argument -> getDescription ()),
2015-08-17 17:00:26 -07:00
$default
), $options );
}
/**
* { @ inheritdoc }
*/
protected function describeInputOption ( InputOption $option , array $options = array ())
{
if ( $option -> acceptValue () && null !== $option -> getDefault () && ( ! is_array ( $option -> getDefault ()) || count ( $option -> getDefault ()))) {
$default = sprintf ( '<comment> [default: %s]</comment>' , $this -> formatDefaultValue ( $option -> getDefault ()));
} else {
$default = '' ;
}
$value = '' ;
if ( $option -> acceptValue ()) {
$value = '=' . strtoupper ( $option -> getName ());
if ( $option -> isValueOptional ()) {
$value = '[' . $value . ']' ;
}
}
$totalWidth = isset ( $options [ 'total_width' ]) ? $options [ 'total_width' ] : $this -> calculateTotalWidthForOptions ( array ( $option ));
$synopsis = sprintf ( '%s%s' ,
$option -> getShortcut () ? sprintf ( '-%s, ' , $option -> getShortcut ()) : ' ' ,
sprintf ( '--%s%s' , $option -> getName (), $value )
);
2017-02-02 16:28:38 -08:00
$spacingWidth = $totalWidth - Helper :: strlen ( $synopsis );
2015-08-17 17:00:26 -07:00
2017-02-02 16:28:38 -08:00
$this -> writeText ( sprintf ( ' <info>%s</info> %s%s%s%s' ,
2015-08-17 17:00:26 -07:00
$synopsis ,
str_repeat ( ' ' , $spacingWidth ),
2017-02-02 16:28:38 -08:00
// + 4 = 2 spaces before <info>, 2 spaces after </info>
preg_replace ( '/\s*[\r\n]\s*/' , " \n " . str_repeat ( ' ' , $totalWidth + 4 ), $option -> getDescription ()),
2015-08-17 17:00:26 -07:00
$default ,
$option -> isArray () ? '<comment> (multiple values allowed)</comment>' : ''
), $options );
}
/**
* { @ inheritdoc }
*/
protected function describeInputDefinition ( InputDefinition $definition , array $options = array ())
{
$totalWidth = $this -> calculateTotalWidthForOptions ( $definition -> getOptions ());
foreach ( $definition -> getArguments () as $argument ) {
2017-02-02 16:28:38 -08:00
$totalWidth = max ( $totalWidth , Helper :: strlen ( $argument -> getName ()));
2015-08-17 17:00:26 -07:00
}
if ( $definition -> getArguments ()) {
$this -> writeText ( '<comment>Arguments:</comment>' , $options );
$this -> writeText ( " \n " );
foreach ( $definition -> getArguments () as $argument ) {
$this -> describeInputArgument ( $argument , array_merge ( $options , array ( 'total_width' => $totalWidth )));
$this -> writeText ( " \n " );
}
}
if ( $definition -> getArguments () && $definition -> getOptions ()) {
$this -> writeText ( " \n " );
}
if ( $definition -> getOptions ()) {
$laterOptions = array ();
$this -> writeText ( '<comment>Options:</comment>' , $options );
foreach ( $definition -> getOptions () as $option ) {
if ( strlen ( $option -> getShortcut ()) > 1 ) {
$laterOptions [] = $option ;
continue ;
}
$this -> writeText ( " \n " );
$this -> describeInputOption ( $option , array_merge ( $options , array ( 'total_width' => $totalWidth )));
}
foreach ( $laterOptions as $option ) {
$this -> writeText ( " \n " );
$this -> describeInputOption ( $option , array_merge ( $options , array ( 'total_width' => $totalWidth )));
}
}
}
/**
* { @ inheritdoc }
*/
protected function describeCommand ( Command $command , array $options = array ())
{
$command -> getSynopsis ( true );
$command -> getSynopsis ( false );
$command -> mergeApplicationDefinition ( false );
$this -> writeText ( '<comment>Usage:</comment>' , $options );
foreach ( array_merge ( array ( $command -> getSynopsis ( true )), $command -> getAliases (), $command -> getUsages ()) as $usage ) {
$this -> writeText ( " \n " );
$this -> writeText ( ' ' . $usage , $options );
}
$this -> writeText ( " \n " );
$definition = $command -> getNativeDefinition ();
if ( $definition -> getOptions () || $definition -> getArguments ()) {
$this -> writeText ( " \n " );
$this -> describeInputDefinition ( $definition , $options );
$this -> writeText ( " \n " );
}
if ( $help = $command -> getProcessedHelp ()) {
$this -> writeText ( " \n " );
$this -> writeText ( '<comment>Help:</comment>' , $options );
$this -> writeText ( " \n " );
2017-02-02 16:28:38 -08:00
$this -> writeText ( ' ' . str_replace ( " \n " , " \n " , $help ), $options );
2015-08-17 17:00:26 -07:00
$this -> writeText ( " \n " );
}
}
/**
* { @ inheritdoc }
*/
protected function describeApplication ( Application $application , array $options = array ())
{
$describedNamespace = isset ( $options [ 'namespace' ]) ? $options [ 'namespace' ] : null ;
$description = new ApplicationDescription ( $application , $describedNamespace );
if ( isset ( $options [ 'raw_text' ]) && $options [ 'raw_text' ]) {
$width = $this -> getColumnWidth ( $description -> getCommands ());
foreach ( $description -> getCommands () as $command ) {
2016-04-20 09:56:34 -07:00
$this -> writeText ( sprintf ( " %- { $width } s %s " , $command -> getName (), $command -> getDescription ()), $options );
2015-08-17 17:00:26 -07:00
$this -> writeText ( " \n " );
}
} else {
if ( '' != $help = $application -> getHelp ()) {
$this -> writeText ( " $help\n\n " , $options );
}
$this -> writeText ( " <comment>Usage:</comment> \n " , $options );
$this -> writeText ( " command [options] [arguments] \n \n " , $options );
$this -> describeInputDefinition ( new InputDefinition ( $application -> getDefinition () -> getOptions ()), $options );
$this -> writeText ( " \n " );
$this -> writeText ( " \n " );
$width = $this -> getColumnWidth ( $description -> getCommands ());
if ( $describedNamespace ) {
$this -> writeText ( sprintf ( '<comment>Available commands for the "%s" namespace:</comment>' , $describedNamespace ), $options );
} else {
$this -> writeText ( '<comment>Available commands:</comment>' , $options );
}
// add commands by namespace
foreach ( $description -> getNamespaces () as $namespace ) {
if ( ! $describedNamespace && ApplicationDescription :: GLOBAL_NAMESPACE !== $namespace [ 'id' ]) {
$this -> writeText ( " \n " );
$this -> writeText ( ' <comment>' . $namespace [ 'id' ] . '</comment>' , $options );
}
foreach ( $namespace [ 'commands' ] as $name ) {
$this -> writeText ( " \n " );
2017-02-02 16:28:38 -08:00
$spacingWidth = $width - Helper :: strlen ( $name );
2015-08-27 12:03:05 -07:00
$this -> writeText ( sprintf ( ' <info>%s</info>%s%s' , $name , str_repeat ( ' ' , $spacingWidth ), $description -> getCommand ( $name ) -> getDescription ()), $options );
2015-08-17 17:00:26 -07:00
}
}
$this -> writeText ( " \n " );
}
}
/**
* { @ inheritdoc }
*/
private function writeText ( $content , array $options = array ())
{
$this -> write (
isset ( $options [ 'raw_text' ]) && $options [ 'raw_text' ] ? strip_tags ( $content ) : $content ,
isset ( $options [ 'raw_output' ]) ? ! $options [ 'raw_output' ] : true
);
}
/**
* Formats input option / argument default value .
*
* @ param mixed $default
*
* @ return string
*/
private function formatDefaultValue ( $default )
{
2017-02-02 16:28:38 -08:00
if ( is_string ( $default )) {
$default = OutputFormatter :: escape ( $default );
} elseif ( is_array ( $default )) {
foreach ( $default as $key => $value ) {
if ( is_string ( $value )) {
$default [ $key ] = OutputFormatter :: escape ( $value );
}
}
}
2015-08-17 17:00:26 -07:00
if ( PHP_VERSION_ID < 50400 ) {
2016-04-20 09:56:34 -07:00
return str_replace ( array ( '\/' , '\\\\' ), array ( '/' , '\\' ), json_encode ( $default ));
2015-08-17 17:00:26 -07:00
}
2016-04-20 09:56:34 -07:00
return str_replace ( '\\\\' , '\\' , json_encode ( $default , JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE ));
2015-08-17 17:00:26 -07:00
}
/**
* @ param Command [] $commands
*
* @ return int
*/
private function getColumnWidth ( array $commands )
{
2015-10-08 11:40:12 -07:00
$widths = array ();
2015-08-17 17:00:26 -07:00
foreach ( $commands as $command ) {
2017-02-02 16:28:38 -08:00
$widths [] = Helper :: strlen ( $command -> getName ());
2015-10-08 11:40:12 -07:00
foreach ( $command -> getAliases () as $alias ) {
2017-02-02 16:28:38 -08:00
$widths [] = Helper :: strlen ( $alias );
2015-10-08 11:40:12 -07:00
}
2015-08-17 17:00:26 -07:00
}
2015-10-08 11:40:12 -07:00
return max ( $widths ) + 2 ;
2015-08-17 17:00:26 -07:00
}
/**
* @ param InputOption [] $options
*
* @ return int
*/
private function calculateTotalWidthForOptions ( $options )
{
$totalWidth = 0 ;
foreach ( $options as $option ) {
2015-08-27 12:03:05 -07:00
// "-" + shortcut + ", --" + name
2017-02-02 16:28:38 -08:00
$nameLength = 1 + max ( strlen ( $option -> getShortcut ()), 1 ) + 4 + Helper :: strlen ( $option -> getName ());
2015-08-17 17:00:26 -07:00
if ( $option -> acceptValue ()) {
2017-02-02 16:28:38 -08:00
$valueLength = 1 + Helper :: strlen ( $option -> getName ()); // = + value
2015-08-17 17:00:26 -07:00
$valueLength += $option -> isValueOptional () ? 2 : 0 ; // [ + ]
$nameLength += $valueLength ;
}
$totalWidth = max ( $totalWidth , $nameLength );
}
return $totalWidth ;
}
}