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\Output ;
2016-04-20 09:56:34 -07:00
use Symfony\Component\Console\Exception\InvalidArgumentException ;
use Symfony\Component\Console\Exception\RuntimeException ;
2015-08-17 17:00:26 -07:00
use Symfony\Component\Console\Formatter\OutputFormatterInterface ;
/**
* StreamOutput writes the output to a given stream .
*
* Usage :
*
2018-11-23 12:29:20 +00:00
* $output = new StreamOutput ( fopen ( 'php://stdout' , 'w' ));
2015-08-17 17:00:26 -07:00
*
* As `StreamOutput` can use any stream , you can also use a file :
*
2018-11-23 12:29:20 +00:00
* $output = new StreamOutput ( fopen ( '/path/to/output.log' , 'a' , false ));
2015-08-17 17:00:26 -07:00
*
* @ author Fabien Potencier < fabien @ symfony . com >
*/
class StreamOutput extends Output
{
private $stream ;
/**
2015-10-08 11:40:12 -07:00
* @ param resource $stream A stream resource
2015-08-17 17:00:26 -07:00
* @ param int $verbosity The verbosity level ( one of the VERBOSITY constants in OutputInterface )
* @ param bool | null $decorated Whether to decorate messages ( null for auto - guessing )
* @ param OutputFormatterInterface | null $formatter Output formatter instance ( null to use default OutputFormatter )
*
2016-04-20 09:56:34 -07:00
* @ throws InvalidArgumentException When first argument is not a real stream
2015-08-17 17:00:26 -07:00
*/
public function __construct ( $stream , $verbosity = self :: VERBOSITY_NORMAL , $decorated = null , OutputFormatterInterface $formatter = null )
{
2018-11-23 12:29:20 +00:00
if ( ! \is_resource ( $stream ) || 'stream' !== get_resource_type ( $stream )) {
2016-04-20 09:56:34 -07:00
throw new InvalidArgumentException ( 'The StreamOutput class needs a stream as its first argument.' );
2015-08-17 17:00:26 -07:00
}
$this -> stream = $stream ;
if ( null === $decorated ) {
$decorated = $this -> hasColorSupport ();
}
parent :: __construct ( $verbosity , $decorated , $formatter );
}
/**
* Gets the stream attached to this StreamOutput instance .
*
* @ return resource A stream resource
*/
public function getStream ()
{
return $this -> stream ;
}
/**
* { @ inheritdoc }
*/
protected function doWrite ( $message , $newline )
{
2018-11-23 12:29:20 +00:00
if ( $newline ) {
$message .= PHP_EOL ;
}
if ( false === @ fwrite ( $this -> stream , $message )) {
2015-08-17 17:00:26 -07:00
// should never happen
2016-04-20 09:56:34 -07:00
throw new RuntimeException ( 'Unable to write output.' );
2015-08-17 17:00:26 -07:00
}
fflush ( $this -> stream );
}
/**
* Returns true if the stream supports colorization .
*
* Colorization is disabled if not supported by the stream :
*
2018-11-23 12:29:20 +00:00
* This is tricky on Windows , because Cygwin , Msys2 etc emulate pseudo
* terminals via named pipes , so we can only check the environment .
*
* Reference : Composer\XdebugHandler\Process :: supportsColor
* https :// github . com / composer / xdebug - handler
2015-08-17 17:00:26 -07:00
*
* @ return bool true if the stream supports colorization , false otherwise
*/
protected function hasColorSupport ()
{
2018-11-23 12:29:20 +00:00
if ( 'Hyper' === getenv ( 'TERM_PROGRAM' )) {
return true ;
}
if ( \DIRECTORY_SEPARATOR === '\\' ) {
return ( \function_exists ( 'sapi_windows_vt100_support' )
&& @ sapi_windows_vt100_support ( $this -> stream ))
2017-02-02 16:28:38 -08:00
|| false !== getenv ( 'ANSICON' )
|| 'ON' === getenv ( 'ConEmuANSI' )
|| 'xterm' === getenv ( 'TERM' );
2015-08-17 17:00:26 -07:00
}
2018-11-23 12:29:20 +00:00
if ( \function_exists ( 'stream_isatty' )) {
return @ stream_isatty ( $this -> stream );
}
if ( \function_exists ( 'posix_isatty' )) {
return @ posix_isatty ( $this -> stream );
}
$stat = @ fstat ( $this -> stream );
// Check if formatted mode is S_IFCHR
return $stat ? 0020000 === ( $stat [ 'mode' ] & 0170000 ) : false ;
2015-08-17 17:00:26 -07:00
}
}