2011-10-05 06:22:53 +02:00
< ? php
/*
* This file is part of Twig .
*
2018-05-10 12:24:53 +02:00
* ( c ) Fabien Potencier
* ( c ) Armin Ronacher
2011-10-05 06:22:53 +02:00
*
* For the full copyright and license information , please view the LICENSE
* file that was distributed with this source code .
*/
/**
* Compiles a node to PHP code .
*
2013-08-01 21:20:12 +02:00
* @ author Fabien Potencier < fabien @ symfony . com >
2011-10-05 06:22:53 +02:00
*/
class Twig_Compiler implements Twig_CompilerInterface
{
protected $lastLine ;
protected $source ;
protected $indentation ;
protected $env ;
2018-05-10 12:24:53 +02:00
protected $debugInfo = array ();
2013-08-01 21:20:12 +02:00
protected $sourceOffset ;
protected $sourceLine ;
protected $filename ;
2018-05-10 12:24:53 +02:00
private $varNameSalt = 0 ;
2011-10-05 06:22:53 +02:00
public function __construct ( Twig_Environment $env )
{
$this -> env = $env ;
2013-08-01 21:20:12 +02:00
}
2018-05-10 12:24:53 +02:00
/**
* @ deprecated since 1.25 ( to be removed in 2.0 )
*/
2013-08-01 21:20:12 +02:00
public function getFilename ()
{
2018-05-10 12:24:53 +02:00
@ trigger_error ( sprintf ( 'The %s() method is deprecated since version 1.25 and will be removed in 2.0.' , __FUNCTION__ ), E_USER_DEPRECATED );
2013-08-01 21:20:12 +02:00
return $this -> filename ;
2011-10-05 06:22:53 +02:00
}
/**
* Returns the environment instance related to this compiler .
*
2018-05-10 12:24:53 +02:00
* @ return Twig_Environment
2011-10-05 06:22:53 +02:00
*/
public function getEnvironment ()
{
return $this -> env ;
}
/**
* Gets the current PHP code after compilation .
*
* @ return string The PHP code
*/
public function getSource ()
{
return $this -> source ;
}
/**
* Compiles a node .
*
2013-08-01 21:20:12 +02:00
* @ param Twig_NodeInterface $node The node to compile
2018-05-10 12:24:53 +02:00
* @ param int $indentation The current indentation
2011-10-05 06:22:53 +02:00
*
2018-05-10 12:24:53 +02:00
* @ return $this
2011-10-05 06:22:53 +02:00
*/
public function compile ( Twig_NodeInterface $node , $indentation = 0 )
{
$this -> lastLine = null ;
$this -> source = '' ;
2018-05-10 12:24:53 +02:00
$this -> debugInfo = array ();
2013-08-01 21:20:12 +02:00
$this -> sourceOffset = 0 ;
// source code starts at 1 (as we then increment it when we encounter new lines)
$this -> sourceLine = 1 ;
2011-10-05 06:22:53 +02:00
$this -> indentation = $indentation ;
2018-05-10 12:24:53 +02:00
$this -> varNameSalt = 0 ;
2011-10-05 06:22:53 +02:00
2013-08-01 21:20:12 +02:00
if ( $node instanceof Twig_Node_Module ) {
2018-05-10 12:24:53 +02:00
// to be removed in 2.0
$this -> filename = $node -> getTemplateName ();
2013-08-01 21:20:12 +02:00
}
2011-10-05 06:22:53 +02:00
$node -> compile ( $this );
return $this ;
}
public function subcompile ( Twig_NodeInterface $node , $raw = true )
{
if ( false === $raw ) {
2018-05-10 12:24:53 +02:00
$this -> source .= str_repeat ( ' ' , $this -> indentation * 4 );
2011-10-05 06:22:53 +02:00
}
$node -> compile ( $this );
return $this ;
}
/**
* Adds a raw string to the compiled code .
*
2013-08-01 21:20:12 +02:00
* @ param string $string The string
2011-10-05 06:22:53 +02:00
*
2018-05-10 12:24:53 +02:00
* @ return $this
2011-10-05 06:22:53 +02:00
*/
public function raw ( $string )
{
$this -> source .= $string ;
return $this ;
}
/**
* Writes a string to the compiled code by adding indentation .
*
2018-05-10 12:24:53 +02:00
* @ return $this
2011-10-05 06:22:53 +02:00
*/
public function write ()
{
$strings = func_get_args ();
foreach ( $strings as $string ) {
2018-05-10 12:24:53 +02:00
$this -> source .= str_repeat ( ' ' , $this -> indentation * 4 ) . $string ;
2011-10-05 06:22:53 +02:00
}
return $this ;
}
2013-08-01 21:20:12 +02:00
/**
* Appends an indentation to the current PHP code after compilation .
*
2018-05-10 12:24:53 +02:00
* @ return $this
*
* @ deprecated since 1.27 ( to be removed in 2.0 ) .
2013-08-01 21:20:12 +02:00
*/
2011-10-05 06:22:53 +02:00
public function addIndentation ()
{
2018-05-10 12:24:53 +02:00
@ trigger_error ( 'The ' . __METHOD__ . ' method is deprecated since version 1.27 and will be removed in 2.0. Use write(\'\') instead.' , E_USER_DEPRECATED );
2011-10-05 06:22:53 +02:00
$this -> source .= str_repeat ( ' ' , $this -> indentation * 4 );
return $this ;
}
/**
* Adds a quoted string to the compiled code .
*
2013-08-01 21:20:12 +02:00
* @ param string $value The string
2011-10-05 06:22:53 +02:00
*
2018-05-10 12:24:53 +02:00
* @ return $this
2011-10-05 06:22:53 +02:00
*/
public function string ( $value )
{
$this -> source .= sprintf ( '"%s"' , addcslashes ( $value , " \0 \t \" \$ \\ " ));
return $this ;
}
/**
* Returns a PHP representation of a given value .
*
2013-08-01 21:20:12 +02:00
* @ param mixed $value The value to convert
2011-10-05 06:22:53 +02:00
*
2018-05-10 12:24:53 +02:00
* @ return $this
2011-10-05 06:22:53 +02:00
*/
public function repr ( $value )
{
if ( is_int ( $value ) || is_float ( $value )) {
2018-05-10 12:24:53 +02:00
if ( false !== $locale = setlocale ( LC_NUMERIC , '0' )) {
2013-08-01 21:20:12 +02:00
setlocale ( LC_NUMERIC , 'C' );
}
2011-10-05 06:22:53 +02:00
$this -> raw ( $value );
2013-08-01 21:20:12 +02:00
if ( false !== $locale ) {
setlocale ( LC_NUMERIC , $locale );
}
} elseif ( null === $value ) {
2011-10-05 06:22:53 +02:00
$this -> raw ( 'null' );
2013-08-01 21:20:12 +02:00
} elseif ( is_bool ( $value )) {
2011-10-05 06:22:53 +02:00
$this -> raw ( $value ? 'true' : 'false' );
2013-08-01 21:20:12 +02:00
} elseif ( is_array ( $value )) {
2011-10-05 06:22:53 +02:00
$this -> raw ( 'array(' );
2013-09-19 08:08:25 +02:00
$first = true ;
2018-05-10 12:24:53 +02:00
foreach ( $value as $key => $v ) {
2013-09-19 08:08:25 +02:00
if ( ! $first ) {
2011-10-05 06:22:53 +02:00
$this -> raw ( ', ' );
}
2013-09-19 08:08:25 +02:00
$first = false ;
2011-10-05 06:22:53 +02:00
$this -> repr ( $key );
$this -> raw ( ' => ' );
2018-05-10 12:24:53 +02:00
$this -> repr ( $v );
2011-10-05 06:22:53 +02:00
}
$this -> raw ( ')' );
} else {
$this -> string ( $value );
}
return $this ;
}
/**
* Adds debugging information .
*
2018-05-10 12:24:53 +02:00
* @ return $this
2011-10-05 06:22:53 +02:00
*/
public function addDebugInfo ( Twig_NodeInterface $node )
{
2018-05-10 12:24:53 +02:00
if ( $node -> getTemplateLine () != $this -> lastLine ) {
$this -> write ( sprintf ( " // line %d \n " , $node -> getTemplateLine ()));
2013-08-01 21:20:12 +02:00
// when mbstring.func_overload is set to 2
// mb_substr_count() replaces substr_count()
// but they have different signatures!
if ((( int ) ini_get ( 'mbstring.func_overload' )) & 2 ) {
2018-05-10 12:24:53 +02:00
@ trigger_error ( 'Support for having "mbstring.func_overload" different from 0 is deprecated version 1.29 and will be removed in 2.0.' , E_USER_DEPRECATED );
2013-08-01 21:20:12 +02:00
// this is much slower than the "right" version
$this -> sourceLine += mb_substr_count ( mb_substr ( $this -> source , $this -> sourceOffset ), " \n " );
} else {
$this -> sourceLine += substr_count ( $this -> source , " \n " , $this -> sourceOffset );
}
$this -> sourceOffset = strlen ( $this -> source );
2018-05-10 12:24:53 +02:00
$this -> debugInfo [ $this -> sourceLine ] = $node -> getTemplateLine ();
2013-08-01 21:20:12 +02:00
2018-05-10 12:24:53 +02:00
$this -> lastLine = $node -> getTemplateLine ();
2011-10-05 06:22:53 +02:00
}
return $this ;
}
2013-08-01 21:20:12 +02:00
public function getDebugInfo ()
{
2018-05-10 12:24:53 +02:00
ksort ( $this -> debugInfo );
2013-08-01 21:20:12 +02:00
return $this -> debugInfo ;
}
2011-10-05 06:22:53 +02:00
/**
* Indents the generated code .
*
2018-05-10 12:24:53 +02:00
* @ param int $step The number of indentation to add
2011-10-05 06:22:53 +02:00
*
2018-05-10 12:24:53 +02:00
* @ return $this
2011-10-05 06:22:53 +02:00
*/
public function indent ( $step = 1 )
{
$this -> indentation += $step ;
return $this ;
}
/**
* Outdents the generated code .
*
2018-05-10 12:24:53 +02:00
* @ param int $step The number of indentation to remove
*
* @ return $this
2011-10-05 06:22:53 +02:00
*
2018-05-10 12:24:53 +02:00
* @ throws LogicException When trying to outdent too much so the indentation would become negative
2011-10-05 06:22:53 +02:00
*/
public function outdent ( $step = 1 )
{
2013-08-01 21:20:12 +02:00
// can't outdent by more steps than the current indentation level
if ( $this -> indentation < $step ) {
2018-05-10 12:24:53 +02:00
throw new LogicException ( 'Unable to call outdent() as the indentation would become negative.' );
2011-10-05 06:22:53 +02:00
}
2013-08-01 21:20:12 +02:00
$this -> indentation -= $step ;
2011-10-05 06:22:53 +02:00
return $this ;
}
2018-05-10 12:24:53 +02:00
public function getVarName ()
{
return sprintf ( '__internal_%s' , hash ( 'sha256' , __METHOD__ . $this -> varNameSalt ++ ));
}
2011-10-05 06:22:53 +02:00
}
2018-05-10 12:24:53 +02:00
class_alias ( 'Twig_Compiler' , 'Twig\Compiler' , false );
class_exists ( 'Twig_Node' );