diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
index fdcd1be7fe..0adf3cb6f8 100644
--- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
+++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
@@ -458,7 +458,6 @@ class FrameworkExtension extends Extension
private function registerTemplatingConfiguration(array $config, $ide, ContainerBuilder $container, XmlFileLoader $loader)
{
$loader->load('templating.xml');
- $loader->load('templating_php.xml');
$links = array(
'textmate' => 'txmt://open?url=file://%%f&line=%%l',
@@ -468,12 +467,26 @@ class FrameworkExtension extends Extension
);
$container->setParameter('templating.helper.code.file_link_format', isset($links[$ide]) ? $links[$ide] : $ide);
- $container->setParameter('templating.helper.form.resources', $config['form']['resources']);
$container->setParameter('fragment.renderer.hinclude.global_template', $config['hinclude_default_template']);
- if ($container->getParameter('kernel.debug')) {
- $loader->load('templating_debug.xml');
+ $loader->load('old_assets.xml');
+ // create package definitions and add them to the assets helper
+ $defaultPackage = $this->createTemplatingPackageDefinition($container, $config['assets_base_urls']['http'], $config['assets_base_urls']['ssl'], $config['assets_version'], $config['assets_version_format']);
+ $container->setDefinition('templating.asset.default_package', $defaultPackage);
+ $namedPackages = array();
+ foreach ($config['packages'] as $name => $package) {
+ $namedPackage = $this->createTemplatingPackageDefinition($container, $package['base_urls']['http'], $package['base_urls']['ssl'], $package['version'], $package['version_format'], $name);
+ $container->setDefinition('templating.asset.package.'.$name, $namedPackage);
+ $namedPackages[$name] = new Reference('templating.asset.package.'.$name);
+ }
+
+ $container->getDefinition('templating.helper.assets')->setArguments(array(
+ new Reference('templating.asset.default_package'),
+ $namedPackages,
+ ));
+
+ if ($container->getParameter('kernel.debug')) {
$logger = new Reference('logger', ContainerInterface::IGNORE_ON_INVALID_REFERENCE);
$container->getDefinition('templating.loader.cache')
@@ -482,25 +495,8 @@ class FrameworkExtension extends Extension
$container->getDefinition('templating.loader.chain')
->addTag('monolog.logger', array('channel' => 'templating'))
->addMethodCall('setLogger', array($logger));
-
- $container->setDefinition('templating.engine.php', $container->findDefinition('debug.templating.engine.php'));
- $container->setAlias('debug.templating.engine.php', 'templating.engine.php');
}
- // create package definitions and add them to the assets helper
- $defaultPackage = $this->createPackageDefinition($container, $config['assets_base_urls']['http'], $config['assets_base_urls']['ssl'], $config['assets_version'], $config['assets_version_format']);
- $container->setDefinition('templating.asset.default_package', $defaultPackage);
- $namedPackages = array();
- foreach ($config['packages'] as $name => $package) {
- $namedPackage = $this->createPackageDefinition($container, $package['base_urls']['http'], $package['base_urls']['ssl'], $package['version'], $package['version_format'], $name);
- $container->setDefinition('templating.asset.package.'.$name, $namedPackage);
- $namedPackages[$name] = new Reference('templating.asset.package.'.$name);
- }
- $container->getDefinition('templating.helper.assets')->setArguments(array(
- new Reference('templating.asset.default_package'),
- $namedPackages,
- ));
-
if (!empty($config['loaders'])) {
$loaders = array_map(function ($loader) { return new Reference($loader); }, $config['loaders']);
@@ -530,14 +526,6 @@ class FrameworkExtension extends Extension
$container->findDefinition('templating.locator')->getClass(),
));
- if (in_array('php', $config['engines'], true)) {
- $this->addClassesToCompile(array(
- 'Symfony\\Component\\Templating\\Storage\\FileStorage',
- 'Symfony\\Bundle\\FrameworkBundle\\Templating\\PhpEngine',
- 'Symfony\\Bundle\\FrameworkBundle\\Templating\\Loader\\FilesystemLoader',
- ));
- }
-
$container->setParameter('templating.engines', $config['engines']);
$engines = array_map(function ($engine) { return new Reference('templating.engine.'.$engine); }, $config['engines']);
@@ -550,12 +538,32 @@ class FrameworkExtension extends Extension
}
$container->setAlias('templating', 'templating.engine.delegating');
}
+
+ // configure the PHP engine if needed
+ if (in_array('php', $config['engines'], true)) {
+ $loader->load('templating_php.xml');
+
+ $container->setParameter('templating.helper.form.resources', $config['form']['resources']);
+
+ if ($container->getParameter('kernel.debug')) {
+ $loader->load('templating_debug.xml');
+
+ $container->setDefinition('templating.engine.php', $container->findDefinition('debug.templating.engine.php'));
+ $container->setAlias('debug.templating.engine.php', 'templating.engine.php');
+ }
+
+ $this->addClassesToCompile(array(
+ 'Symfony\\Component\\Templating\\Storage\\FileStorage',
+ 'Symfony\\Bundle\\FrameworkBundle\\Templating\\PhpEngine',
+ 'Symfony\\Bundle\\FrameworkBundle\\Templating\\Loader\\FilesystemLoader',
+ ));
+ }
}
/**
* Returns a definition for an asset package.
*/
- private function createPackageDefinition(ContainerBuilder $container, array $httpUrls, array $sslUrls, $version, $format, $name = null)
+ private function createTemplatingPackageDefinition(ContainerBuilder $container, array $httpUrls, array $sslUrls, $version, $format, $name = null)
{
if (!$httpUrls) {
$package = new DefinitionDecorator('templating.asset.path_package');
diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/old_assets.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/old_assets.xml
new file mode 100644
index 0000000000..90d935906d
--- /dev/null
+++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/old_assets.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+ Symfony\Bundle\FrameworkBundle\Templating\Asset\PathPackage
+ Symfony\Component\Templating\Asset\UrlPackage
+ Symfony\Bundle\FrameworkBundle\Templating\Asset\PackageFactory
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/templating.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/templating.xml
index 59da78fc41..efec555b87 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/templating.xml
+++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/templating.xml
@@ -14,6 +14,7 @@
Symfony\Component\Templating\Loader\CacheLoader
Symfony\Component\Templating\Loader\ChainLoader
Symfony\Bundle\FrameworkBundle\CacheWarmer\TemplateFinder
+ Symfony\Component\Templating\Helper\CoreAssetsHelper
@@ -58,5 +59,15 @@
+
+
+
+
+
+
+
diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/templating_php.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/templating_php.xml
index e0a9234d02..5b4f8073fe 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/templating_php.xml
+++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/templating_php.xml
@@ -7,7 +7,6 @@
Symfony\Bundle\FrameworkBundle\Templating\PhpEngine
Symfony\Component\Templating\Helper\SlotsHelper
- Symfony\Component\Templating\Helper\CoreAssetsHelper
Symfony\Bundle\FrameworkBundle\Templating\Helper\ActionsHelper
Symfony\Bundle\FrameworkBundle\Templating\Helper\RouterHelper
Symfony\Bundle\FrameworkBundle\Templating\Helper\RequestHelper
@@ -19,9 +18,6 @@
Symfony\Component\Form\Extension\Templating\TemplatingRendererEngine
Symfony\Component\Form\FormRenderer
Symfony\Bundle\FrameworkBundle\Templating\GlobalVariables
- Symfony\Bundle\FrameworkBundle\Templating\Asset\PathPackage
- Symfony\Component\Templating\Asset\UrlPackage
- Symfony\Bundle\FrameworkBundle\Templating\Asset\PackageFactory
@@ -37,35 +33,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/Symfony/Bundle/FrameworkBundle/Templating/GlobalVariables.php b/src/Symfony/Bundle/FrameworkBundle/Templating/GlobalVariables.php
index 51fe53f2e0..c2a2c7888c 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Templating/GlobalVariables.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Templating/GlobalVariables.php
@@ -18,7 +18,7 @@ use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\SecurityContext;
/**
- * GlobalVariables is the entry point for Symfony global variables in Twig templates.
+ * GlobalVariables is the entry point for Symfony global variables in PHP templates.
*
* @author Fabien Potencier
*/
diff --git a/src/Symfony/Bundle/TwigBundle/AppVariable.php b/src/Symfony/Bundle/TwigBundle/AppVariable.php
new file mode 100644
index 0000000000..f40cba5cd1
--- /dev/null
+++ b/src/Symfony/Bundle/TwigBundle/AppVariable.php
@@ -0,0 +1,160 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Bundle\TwigBundle;
+
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\RequestStack;
+use Symfony\Component\HttpFoundation\Session\Session;
+use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
+use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
+use Symfony\Component\Security\Core\SecurityContextInterface;
+
+/**
+ * Exposes some Symfony parameters and services as an "app" global variable.
+ *
+ * @author Fabien Potencier
+ */
+class AppVariable
+{
+ private $security;
+ private $tokenStorage;
+ private $requestStack;
+ private $environment;
+ private $debug;
+
+ /**
+ * @deprecated since version 2.7, to be removed in 3.0.
+ */
+ public function setSecurity(SecurityContextInterface $security)
+ {
+ $this->security = $security;
+ }
+
+ public function setTokenStorage(TokenStorageInterface $tokenStorage)
+ {
+ $this->tokenStorage = $tokenStorage;
+ }
+
+ public function setRequestStack(RequestStack $requestStack)
+ {
+ $this->requestStack = $requestStack;
+ }
+
+ public function setEnvironment($environment)
+ {
+ $this->environment = $environment;
+ }
+
+ public function setDebug($debug)
+ {
+ $this->debug = (bool) $debug;
+ }
+
+ /**
+ * Returns the security context service.
+ *
+ * @deprecated since version 2.6, to be removed in 3.0.
+ *
+ * @return SecurityContext|null The security context
+ */
+ public function getSecurity()
+ {
+ trigger_error('The "app.security" variable is deprecated since version 2.6 and will be removed in 3.0.', E_USER_DEPRECATED);
+
+ if (null === $this->security) {
+ throw new \RuntimeException('The "app.security" variable is not available.');
+ }
+
+ return $this->security;
+ }
+
+ /**
+ * Returns the current user.
+ *
+ * @return mixed
+ *
+ * @see TokenInterface::getUser()
+ */
+ public function getUser()
+ {
+ if (null === $this->tokenStorage) {
+ throw new \RuntimeException('The "app.user" variable is not available.');
+ }
+
+ if (!$token = $this->tokenStorage->getToken()) {
+ return;
+ }
+
+ $user = $token->getUser();
+ if (is_object($user)) {
+ return $user;
+ }
+ }
+
+ /**
+ * Returns the current request.
+ *
+ * @return Request|null The HTTP request object
+ */
+ public function getRequest()
+ {
+ if (null === $this->requestStack) {
+ throw new \RuntimeException('The "app.request" variable is not available.');
+ }
+
+ return $this->requestStack->getCurrentRequest();
+ }
+
+ /**
+ * Returns the current session.
+ *
+ * @return Session|null The session
+ */
+ public function getSession()
+ {
+ if (null === $this->requestStack) {
+ throw new \RuntimeException('The "app.session" variable is not available.');
+ }
+
+ if ($request = $this->getRequest()) {
+ return $request->getSession();
+ }
+ }
+
+ /**
+ * Returns the current app environment.
+ *
+ * @return string The current environment string (e.g 'dev')
+ */
+ public function getEnvironment()
+ {
+ if (null === $this->environment) {
+ throw new \RuntimeException('The "app.environment" variable is not available.');
+ }
+
+ return $this->environment;
+ }
+
+ /**
+ * Returns the current app debug mode.
+ *
+ * @return bool The current debug mode
+ */
+ public function getDebug()
+ {
+ if (null === $this->debug) {
+ throw new \RuntimeException('The "app.debug" variable is not available.');
+ }
+
+ return $this->debug;
+ }
+}
diff --git a/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/ExtensionPass.php b/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/ExtensionPass.php
index c4bd1d372a..953a9dd9dd 100644
--- a/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/ExtensionPass.php
+++ b/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/ExtensionPass.php
@@ -46,5 +46,24 @@ class ExtensionPass implements CompilerPassInterface
if ($container->has('request_stack')) {
$container->getDefinition('twig.extension.httpfoundation')->addTag('twig.extension');
}
+
+ if ($container->hasParameter('templating.helper.code.file_link_format')) {
+ $container->getDefinition('twig.extension.code')->replaceArgument(0, $container->getParameter('templating.helper.code.file_link_format'));
+ }
+
+ if ($container->has('templating')) {
+ $container->getDefinition('twig.cache_warmer')->addTag('kernel.cache_warmer');
+
+ if ($container->getParameter('kernel.debug')) {
+ $container->setDefinition('templating.engine.twig', $container->findDefinition('debug.templating.engine.twig'));
+ $container->setAlias('debug.templating.engine.twig', 'templating.engine.twig');
+ }
+ } else {
+ $loader = $container->getDefinition('twig.loader.native_filesystem');
+ $loader->addTag('twig.loader');
+ $loader->setMethodCalls($container->getDefinition('twig.loader.filesystem')->getMethodCalls());
+
+ $container->setDefinition('twig.loader.filesystem', $loader);
+ }
}
}
diff --git a/src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigExtension.php b/src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigExtension.php
index 9883daeded..c9595ff219 100644
--- a/src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigExtension.php
+++ b/src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigExtension.php
@@ -103,9 +103,6 @@ class TwigExtension extends Extension
if ($container->getParameter('kernel.debug')) {
$loader->load('debug.xml');
-
- $container->setDefinition('templating.engine.twig', $container->findDefinition('debug.templating.engine.twig'));
- $container->setAlias('debug.templating.engine.twig', 'templating.engine.twig');
}
if (isset($config['autoescape_service']) && isset($config['autoescape_service_method'])) {
diff --git a/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml b/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml
index 40dbaa9fbb..41f9c2d361 100644
--- a/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml
+++ b/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml
@@ -34,16 +34,27 @@
%twig.options%
app
-
+
+
+ %kernel.environment%
+ %kernel.debug%
+
+
+
+
+
-
+
+
+
+
@@ -76,7 +87,7 @@
- %templating.helper.code.file_link_format%
+
%kernel.root_dir%
%kernel.charset%
diff --git a/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/TwigExtensionTest.php b/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/TwigExtensionTest.php
index 05d450db73..9709059caf 100644
--- a/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/TwigExtensionTest.php
+++ b/src/Symfony/Bundle/TwigBundle/Tests/DependencyInjection/TwigExtensionTest.php
@@ -99,7 +99,7 @@ class TwigExtensionTest extends TestCase
// Globals
$calls = $container->getDefinition('twig')->getMethodCalls();
$this->assertEquals('app', $calls[0][1][0], '->load() registers services as Twig globals');
- $this->assertEquals(new Reference('templating.globals'), $calls[0][1][1]);
+ $this->assertEquals(new Reference('twig.app_variable'), $calls[0][1][1]);
$this->assertEquals('foo', $calls[1][1][0], '->load() registers services as Twig globals');
$this->assertEquals(new Reference('bar'), $calls[1][1][1], '->load() registers services as Twig globals');
$this->assertEquals('baz', $calls[2][1][0], '->load() registers variables as Twig globals');
diff --git a/src/Symfony/Bundle/TwigBundle/Tests/Functional/NoTemplatingEntryTest.php b/src/Symfony/Bundle/TwigBundle/Tests/Functional/NoTemplatingEntryTest.php
new file mode 100644
index 0000000000..068a10526c
--- /dev/null
+++ b/src/Symfony/Bundle/TwigBundle/Tests/Functional/NoTemplatingEntryTest.php
@@ -0,0 +1,78 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Bundle\TwigBundle\Tests;
+
+use Symfony\Component\HttpKernel\Kernel;
+use Symfony\Component\Config\Loader\LoaderInterface;
+use Symfony\Component\Filesystem\Filesystem;
+use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
+use Symfony\Bundle\TwigBundle\TwigBundle;
+
+class NoTemplatingEntryTest extends \PHPUnit_Framework_TestCase
+{
+ public function test()
+ {
+ $kernel = new NoTemplatingEntryKernel('dev', true);
+ $kernel->boot();
+
+ $container = $kernel->getContainer();
+ $content = $container->get('twig')->render('index.html.twig');
+ $this->assertContains('{ a: b }', $content);
+ }
+
+ protected function setUp()
+ {
+ $this->deleteTempDir();
+ }
+
+ protected function tearDown()
+ {
+ $this->deleteTempDir();
+ }
+
+ protected function deleteTempDir()
+ {
+ if (!file_exists($dir = sys_get_temp_dir().'/'.Kernel::VERSION.'/NoTemplatingEntryKernel')) {
+ return;
+ }
+
+ $fs = new Filesystem();
+ $fs->remove($dir);
+ }
+}
+
+class NoTemplatingEntryKernel extends Kernel
+{
+ public function registerBundles()
+ {
+ return array(new FrameworkBundle(), new TwigBundle());
+ }
+
+ public function registerContainerConfiguration(LoaderInterface $loader)
+ {
+ $loader->load(function ($container) {
+ $container->loadFromExtension('framework', array(
+ 'secret' => '$ecret',
+ ));
+ });
+ }
+
+ public function getCacheDir()
+ {
+ return sys_get_temp_dir().'/'.Kernel::VERSION.'/NoTemplatingEntryKernel/cache/'.$this->environment;
+ }
+
+ public function getLogDir()
+ {
+ return sys_get_temp_dir().'/'.Kernel::VERSION.'/NoTemplatingEntryKernel/logs';
+ }
+}
diff --git a/src/Symfony/Bundle/TwigBundle/Tests/Functional/Resources/views/index.html.twig b/src/Symfony/Bundle/TwigBundle/Tests/Functional/Resources/views/index.html.twig
new file mode 100644
index 0000000000..ddc4eb4404
--- /dev/null
+++ b/src/Symfony/Bundle/TwigBundle/Tests/Functional/Resources/views/index.html.twig
@@ -0,0 +1 @@
+{{ {a: 'b'}|yaml_encode }}
diff --git a/src/Symfony/Bundle/TwigBundle/composer.json b/src/Symfony/Bundle/TwigBundle/composer.json
index b1e51bd726..6d5e4dbd75 100644
--- a/src/Symfony/Bundle/TwigBundle/composer.json
+++ b/src/Symfony/Bundle/TwigBundle/composer.json
@@ -17,7 +17,7 @@
],
"require": {
"php": ">=5.3.9",
- "symfony/twig-bridge": "~2.6|~3.0.0",
+ "symfony/twig-bridge": "~2.7|~3.0.0",
"symfony/http-foundation": "~2.5|~3.0.0",
"symfony/http-kernel": "~2.3.24|~2.5.9|~2.6,>=2.6.2|~3.0.0"
},
@@ -28,7 +28,7 @@
"symfony/config": "~2.2|~3.0.0",
"symfony/routing": "~2.1|~3.0.0",
"symfony/templating": "~2.1|~3.0.0",
- "symfony/framework-bundle": "~2.1|~3.0.0"
+ "symfony/framework-bundle": "~2.7|~3.0.0"
},
"autoload": {
"psr-0": { "Symfony\\Bundle\\TwigBundle\\": "" }