8000 Duplicated cache file after upgrade Twig to 1.30.x · Issue #21055 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content
8000

Duplicated cache file after upgrade Twig to 1.30.x #21055

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
lcobucci opened this issue Dec 26, 2016 · 10 comments
Closed

Duplicated cache file after upgrade Twig to 1.30.x #21055

lcobucci opened this issue Dec 26, 2016 · 10 comments

Comments

@lcobucci
Copy link
Contributor
lcobucci commented Dec 26, 2016
Q A
Bug report? yes
Feature request? no
BC Break report? yes
RFC? no
Symfony version 3.1.8

On our application we're using in some places the twig namespace syntax (@namespace/folder1/template.html.twig) and in templates that uses embed twig uses the SF TemplateReference to get the logical name which leads to the SF syntax (Bundle:folder1:template.html.twig).

What happens is that twig loader loads @namespace/folder1/template.html.twig but fails on Bundle:folder1:template.html.twig then SF filesystem loader is used as fallback. The problem is that twig loader uses realpath() since v1.27 and SF loader doesn't.

I've solved that on our application by overriding SF loader and using realpath() as well but although it works fine I'm not 100% sure if that's the way to go (that's why I didn't send a PR):

use Symfony\Bundle\TwigBundle\Loader\FilesystemLoader;

final class TemplateLoader extends FilesystemLoader
{
    protected function findTemplate($template, $throw = true)
    {
        $file = parent::findTemplate($template, $throw);

        if ($absolutePath = realpath($file)) {
            $file = $absolutePath;
        }

        return $this->cache[(string) $template] = $file;
    }
}
@xabbuh
Copy link
Member
xabbuh commented Dec 27, 2016

@lcobucci Could you please create a simple example project (best by forking the Symfony Standard Edition) that makes it possible to reproduc 8000 e the issue you experience?

@lcobucci
Copy link
Contributor Author

@xabbuh sure, will do that ASAP and link the fork here 😉

@lcobucci
Copy link
Contributor Author
lcobucci commented Dec 28, 2016

@xabbuh I managed to reproduce the issue on https://github.com/lcobucci/symfony-standard/tree/template-issues

# bin/console cache:clear --no-debug --env=prod
# grep 'testing.html.twig' -r var/cache/prod/

var/cache/prod//templates.php:86:  'AppBundle::testing.html.twig' => __DIR__.'/../../../src/AppBundle/Resources/views/testing.html.twig',
var/cache/prod//twig/60/60fbe9c12702aa8e1d6d51debf3d7b3f897cab33c2a20251ef6d89a0ceee3205.php:3:/* @App/testing.html.twig */
var/cache/prod//twig/60/60fbe9c12702aa8e1d6d51debf3d7b3f897cab33c2a20251ef6d89a0ceee3205.php:11:        $this->parent = $this->loadTemplate("AppBundle::base.html.twig", "@App/testing.html.twig", 1);
var/cache/prod//twig/60/60fbe9c12702aa8e1d6d51debf3d7b3f897cab33c2a20251ef6d89a0ceee3205.php:52:        $this->loadTemplate("@App/testing.html.twig", "@App/testing.html.twig", 12, "155133146")->display($context);
var/cache/prod//twig/60/60fbe9c12702aa8e1d6d51debf3d7b3f897cab33c2a20251ef6d89a0ceee3205.php:57:        return "@App/testing.html.twig";
var/cache/prod//twig/60/60fbe9c12702aa8e1d6d51debf3d7b3f897cab33c2a20251ef6d89a0ceee3205.php:80:        return new Twig_Source("", "@App/testing.html.twig", "/Users/lcobucci/vms/symfony-standard/src/AppBundle/Resources/views/testing.html.twig");
var/cache/prod//twig/60/60fbe9c12702aa8e1d6d51debf3d7b3f897cab33c2a20251ef6d89a0ceee3205.php:85:/* @App/testing.html.twig */
var/cache/prod//twig/60/60fbe9c12702aa8e1d6d51debf3d7b3f897cab33c2a20251ef6d89a0ceee3205.php:100:        return $this->loadTemplate(($context["template"] ?? null), "@App/testing.html.twig", 12);
var/cache/prod//twig/60/60fbe9c12702aa8e1d6d51debf3d7b3f897cab33c2a20251ef6d89a0ceee3205.php:128:        return "@App/testing.html.twig";
var/cache/prod//twig/60/60fbe9c12702aa8e1d6d51debf3d7b3f897cab33c2a20251ef6d89a0ceee3205.php:151:        return new Twig_Source("", "@App/testing.html.twig", "/Users/lcobucci/vms/symfony-standard/src/AppBundle/Resources/views/testing.html.twig");
var/cache/prod//twig/dc/dc5bbd702e150d2eacc80255a6a1616d6d5131cddfd195dc212b2262723affb3.php:3:/* AppBundle::testing.html.twig */
var/cache/prod//twig/dc/dc5bbd702e150d2eacc80255a6a1616d6d5131cddfd195dc212b2262723affb3.php:11:        $this->parent = $this->loadTemplate("AppBundle::base.html.twig", "AppBundle::testing.html.twig", 1);
var/cache/prod//twig/dc/dc5bbd702e150d2eacc80255a6a1616d6d5131cddfd195dc212b2262723affb3.php:52:        $this->loadTemplate("AppBundle::testing.html.twig", "AppBundle::testing.html.twig", 12, "834562958")->display($context);
var/cache/prod//twig/dc/dc5bbd702e150d2eacc80255a6a1616d6d5131cddfd195dc212b2262723affb3.php:57:        return "AppBundle::testing.html.twig";
var/cache/prod//twig/dc/dc5bbd702e150d2eacc80255a6a1616d6d5131cddfd195dc212b2262723affb3.php:80:        return new Twig_Source("", "AppBundle::testing.html.twig", "/Users/lcobucci/vms/symfony-standard/var/cache/prod/../../../src/AppBundle/Resources/views/testing.html.twig");
var/cache/prod//twig/dc/dc5bbd702e150d2eacc80255a6a1616d6d5131cddfd195dc212b2262723affb3.php:85:/* AppBundle::testing.html.twig */
var/cache/prod//twig/dc/dc5bbd702e150d2eacc80255a6a1616d6d5131cddfd195dc212b2262723affb3.php:100:   
8000
     return $this->loadTemplate(($context["template"] ?? null), "AppBundle::testing.html.twig", 12);
var/cache/prod//twig/dc/dc5bbd702e150d2eacc80255a6a1616d6d5131cddfd195dc212b2262723affb3.php:128:        return "AppBundle::testing.html.twig";
var/cache/prod//twig/dc/dc5bbd702e150d2eacc80255a6a1616d6d5131cddfd195dc212b2262723affb3.php:151:        return new Twig_Source("", "AppBundle::testing.html.twig", "/Users/lcobucci/vms/symfony-standard/var/cache/prod/../../../src/AppBundle/Resources/views/testing.html.twig");

After changing Symfony\Bundle\TwigBundle\Loader\FilesystemLoader to:

<?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\Bundle\TwigBundle\Loader;

use Symfony\Component\Config\FileLocatorInterface;
use Symfony\Component\Templating\TemplateNameParserInterface;
use Symfony\Component\Templating\TemplateReferenceInterface;

/**
 * FilesystemLoader extends the default Twig filesystem loader
 * to work with the Symfony paths and template references.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class FilesystemLoader extends \Twig_Loader_Filesystem
{
    protected $locator;
    protected $parser;

    /**
     * Constructor.
     *
     * @param FileLocatorInterface        $locator  A FileLocatorInterface instance
     * @param TemplateNameParserInterface $parser   A TemplateNameParserInterface instance
     * @param string|null                 $rootPath The root path common to all relative paths (null for getcwd())
     */
    public function __construct(FileLocatorInterface $locator, TemplateNameParserInterface $parser, $rootPath = null)
    {
        parent::__construct(array(), $rootPath);

        $this->locator = $locator;
        $this->parser = $parser;
    }

    /**
     * {@inheritdoc}
     *
     * The name parameter might also be a TemplateReferenceInterface.
     */
    public function exists($name)
    {
        return parent::exists((string) $name);
    }

    /**
     * Returns the path to the template file.
     *
     * The file locator is used to locate the template when the naming convention
     * is the symfony one (i.e. the name can be parsed).
     * Otherwise the template is located using the locator from the twig library.
     *
     * @param string|TemplateReferenceInterface $template The template
     * @param bool                              $throw    When true, a \Twig_Error_Loader exception will be thrown if a template could not be found
     *
     * @return string The path to the template file
     *
     * @throws \Twig_Error_Loader if the template could not be found
     */
    protected function findTemplate($template, $throw = true)
    {
        $logicalName = (string) $template;

        if (isset($this->cache[$logicalName])) {
            return $this->cache[$logicalName];
        }

        $file = null;
        $previous = null;
        try {
            $file = parent::findTemplate($logicalName);
        } catch (\Twig_Error_Loader $e) {
            $twigLoaderException = $e;

            // for BC
            try {
                $template = $this->parser->parse($template);
                $file = $this->locator->locate($template);

                if (false !== $realpath = realpath($file)) {
                    $file = $realpath;
                }
            } catch (\Exception $e) {
            }
        }

        if (false === $file || null === $file) {
            if ($throw) {
                throw $twigLoaderException;
            }

            return false;
        }

        return $this->cache[$logicalName] = $file;
    }
}

I have this result:

# bin/console cache:clear --no-debug --env=prod
# grep 'testing.html.twig' -r var/cache/prod/

var/cache/prod//templates.php:86:  'AppBundle::testing.html.twig' => __DIR__.'/../../../src/AppBundle/Resources/views/testing.html.twig',
var/cache/prod//twig/60/60fbe9c12702aa8e1d6d51debf3d7b3f897cab33c2a20251ef6d89a0ceee3205.php:3:/* @App/testing.html.twig */
var/cache/prod//twig/60/60fbe9c12702aa8e1d6d51debf3d7b3f897cab33c2a20251ef6d89a0ceee3205.php:11:        $this->parent = $this->loadTemplate("AppBundle::base.html.twig", "@App/testing.html.twig", 1);
var/cache/prod//twig/60/60fbe9c12702aa8e1d6d51debf3d7b3f897cab33c2a20251ef6d89a0ceee3205.php:52:        $this->loadTemplate("@App/testing.html.twig", "@App/testing.html.twig", 12, "2063719950")->display($context);
var/cache/prod//twig/60/60fbe9c12702aa8e1d6d51debf3d7b3f897cab33c2a20251ef6d89a0ceee3205.php:57:        return "@App/testing.html.twig";
var/cache/prod//twig/60/60fbe9c12702aa8e1d6d51debf3d7b3f897cab33c2a20251ef6d89a0ceee3205.php:80:        return new Twig_Source("", "@App/testing.html.twig", "/Users/lcobucci/vms/symfony-standard/src/AppBundle/Resources/views/testing.html.twig");
var/cache/prod//twig/60/60fbe9c12702aa8e1d6d51debf3d7b3f897cab33c2a20251ef6d89a0ceee3205.php:85:/* @App/testing.html.twig */
var/cache/prod//twig/60/60fbe9c12702aa8e1d6d51debf3d7b3f897cab33c2a20251ef6d89a0ceee3205.php:100:        return $this->loadTemplate(($context["template"] ?? null), "@App/testing.html.twig", 12);
var/cache/prod//twig/60/60fbe9c12702aa8e1d6d51debf3d7b3f897cab33c2a20251ef6d89a0ceee3205.php:128:        return "@App/testing.html.twig";
var/cache/prod//twig/60/60fbe9c12702aa8e1d6d51debf3d7b3f897cab33c2a20251ef6d89a0ceee3205.php:151:        return new Twig_Source("", "@App/testing.html.twig", "/Users/lcobucci/vms/symfony-standard/src/AppBundle/Resources/views/testing.html.twig");

I just didn't manage to reproduce the fatal error I'm having with our application (trying to define the class twice).

@mvrhov
Copy link
mvrhov commented Dec 28, 2016

realpath is not a solution, as this means that this won't work inside a phar.

@lcobucci
Copy link
Contributor Author

@mvrhov it would work inside a phar since it would behave the same way as Twig_Loader_Filesystem - as in just overriding when realpath($file) !== false.

We have a problem because the two behaviours are incompatible.

@xabbuh
Copy link
Member
xabbuh commented Dec 31, 2016

@lcobucci Thank you for the example project. However, I do not see any usage of the native Twig namespace syntax to reference a template. Did I miss that?

@lcobucci
Copy link
Contributor Author
lcobucci commented Dec 31, 2016

@xabbuh indeed, I forgot to mention that I was able to reproduce it even without using the twig namespace syntax by just doing the cache warmup

@4rthem
Copy link
Contributor
4rthem commented Jan 4, 2017
8000

I think my issue explains yours: #21130

@xabbuh
Copy link
Member
xabbuh commented Jan 12, 2017

Could you please check if the changes made in #21237 already fix your issue?

@lcobucci
Copy link
Contributor Author

@xabbuh yes it does 😉. Closing...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants
0