2015-08-18 00:00:26 +00: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\HttpKernel\Fragment ;
use Symfony\Component\HttpFoundation\Request ;
use Symfony\Component\HttpFoundation\Response ;
use Symfony\Component\Templating\EngineInterface ;
use Symfony\Component\HttpKernel\Controller\ControllerReference ;
use Symfony\Component\HttpKernel\UriSigner ;
/**
* Implements the Hinclude rendering strategy .
*
* @ author Fabien Potencier < fabien @ symfony . com >
*/
class HIncludeFragmentRenderer extends RoutableFragmentRenderer
{
private $globalDefaultTemplate ;
private $signer ;
private $templating ;
private $charset ;
/**
* Constructor .
*
* @ param EngineInterface | \Twig_Environment $templating An EngineInterface or a \Twig_Environment instance
* @ param UriSigner $signer A UriSigner instance
* @ param string $globalDefaultTemplate The global default content ( it can be a template name or the content )
* @ param string $charset
*/
public function __construct ( $templating = null , UriSigner $signer = null , $globalDefaultTemplate = null , $charset = 'utf-8' )
{
$this -> setTemplating ( $templating );
$this -> globalDefaultTemplate = $globalDefaultTemplate ;
$this -> signer = $signer ;
$this -> charset = $charset ;
}
/**
* Sets the templating engine to use to render the default content .
*
* @ param EngineInterface | \Twig_Environment | null $templating An EngineInterface or a \Twig_Environment instance
*
* @ throws \InvalidArgumentException
*/
public function setTemplating ( $templating )
{
if ( null !== $templating && ! $templating instanceof EngineInterface && ! $templating instanceof \Twig_Environment ) {
throw new \InvalidArgumentException ( 'The hinclude rendering strategy needs an instance of \Twig_Environment or Symfony\Component\Templating\EngineInterface' );
}
$this -> templating = $templating ;
}
/**
* Checks if a templating engine has been set .
*
* @ return bool true if the templating engine has been set , false otherwise
*/
public function hasTemplating ()
{
return null !== $this -> templating ;
}
/**
* { @ inheritdoc }
*
* Additional available options :
*
* * default : The default content ( it can be a template name or the content )
* * id : An optional hx : include tag id attribute
* * attributes : An optional array of hx : include tag attributes
*/
public function render ( $uri , Request $request , array $options = array ())
{
if ( $uri instanceof ControllerReference ) {
if ( null === $this -> signer ) {
throw new \LogicException ( 'You must use a proper URI when using the Hinclude rendering strategy or set a URL signer.' );
}
// we need to sign the absolute URI, but want to return the path only.
$uri = substr ( $this -> signer -> sign ( $this -> generateFragmentUri ( $uri , $request , true )), strlen ( $request -> getSchemeAndHttpHost ()));
}
// We need to replace ampersands in the URI with the encoded form in order to return valid html/xml content.
$uri = str_replace ( '&' , '&' , $uri );
$template = isset ( $options [ 'default' ]) ? $options [ 'default' ] : $this -> globalDefaultTemplate ;
if ( null !== $this -> templating && $template && $this -> templateExists ( $template )) {
$content = $this -> templating -> render ( $template );
} else {
$content = $template ;
}
$attributes = isset ( $options [ 'attributes' ]) && is_array ( $options [ 'attributes' ]) ? $options [ 'attributes' ] : array ();
if ( isset ( $options [ 'id' ]) && $options [ 'id' ]) {
$attributes [ 'id' ] = $options [ 'id' ];
}
$renderedAttributes = '' ;
if ( count ( $attributes ) > 0 ) {
if ( PHP_VERSION_ID >= 50400 ) {
$flags = ENT_QUOTES | ENT_SUBSTITUTE ;
} else {
$flags = ENT_QUOTES ;
}
foreach ( $attributes as $attribute => $value ) {
$renderedAttributes .= sprintf (
' %s="%s"' ,
htmlspecialchars ( $attribute , $flags , $this -> charset , false ),
htmlspecialchars ( $value , $flags , $this -> charset , false )
);
}
}
return new Response ( sprintf ( '<hx:include src="%s"%s>%s</hx:include>' , $uri , $renderedAttributes , $content ));
}
/**
* @ param string $template
*
* @ return bool
*/
private function templateExists ( $template )
{
if ( $this -> templating instanceof EngineInterface ) {
try {
return $this -> templating -> exists ( $template );
} catch ( \InvalidArgumentException $e ) {
return false ;
}
}
$loader = $this -> templating -> getLoader ();
2017-02-03 00:28:38 +00:00
if ( $loader instanceof \Twig_ExistsLoaderInterface || method_exists ( $loader , 'exists' )) {
2015-08-18 00:00:26 +00:00
return $loader -> exists ( $template );
}
try {
2017-02-03 00:28:38 +00:00
if ( method_exists ( $loader , 'getSourceContext' )) {
$loader -> getSourceContext ( $template );
} else {
$loader -> getSource ( $template );
}
2015-08-18 00:00:26 +00:00
return true ;
} catch ( \Twig_Error_Loader $e ) {
}
return false ;
}
/**
* { @ inheritdoc }
*/
public function getName ()
{
return 'hinclude' ;
}
}