Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

[TwigBundle] Fix bug where namespaced paths don't take parent bundles in account#19586

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Conversation

@wesleylancel
Copy link
Contributor

@wesleylancelwesleylancel commentedAug 10, 2016
edited
Loading

QA
Branch?2.7
Bug fix?yes
New feature?no
BC breaks?no
Deprecations?no
Tests pass?yes
Fixed tickets#6919
LicenseMIT
Doc PR

Currently namespaced paths for templates such as{% extends '@App/Layout/layout.html.twig' %} do not work with bundles that have overruled templates using thegetParent() method in another bundle. See attached ticket. This change prepends the path of the bundle implementinggetParent() to the paths of the namespace of bundle returned as a parent.

jverdeyen, veloxy, ro0NL, mhujer, Gemorroj, nicraMarcin, GhostSt, chalasr, and Remiii reacted with thumbs up emoji
@jakzal
Copy link
Contributor

We'll need a test case for this.

@wesleylancelwesleylancelforce-pushed thenamespaced-paths-parent-bundles branch fromb3d4a15 to4ddc9edCompareAugust 10, 2016 09:26
@wesleylancel
Copy link
ContributorAuthor

@jakzal I modified the TwigExtensionTest to include a test case for this situation.

@wesleylancelwesleylancelforce-pushed thenamespaced-paths-parent-bundles branch from4ddc9ed to57eceb7CompareAugust 10, 2016 09:30
@wesleylancel
Copy link
ContributorAuthor

AppVeyor ran on an outdated commit, might have to be restarted.

if (is_dir($dir)) {
$this->addTwigPath($twigFilesystemLoaderDefinition,$dir,$bundle);

$classMock =new$class();
Copy link
Contributor

@ro0NLro0NLAug 10, 2016
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

This is not really a mock :) what about$object or just$bundle? However im not sure we should couple this here, this way. But i guess for now we dont have much choice...

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I'll rename the variable. Don't think there are any options to retrieve the parent in this situation.

Copy link
Contributor

@ro0NLro0NLAug 10, 2016
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Maybe you could callregisterBundles once =/ Basicallynew $class() is somewhat fragile.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I agree, and this won't work with a third level (ChildChildTwigBundle). How would you recommend callingregisterBundles here? Is there any way to reach the kernel?

Copy link
Contributor

@ro0NLro0NLAug 10, 2016
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

kernel service is out of scope, so i guess not. Maybe you can kick in atTwigBundle::createContainerExtension, without breaking BC.

This is somewhat related to#18563 in terms of improving the ecosystem.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

What about using reflection andnewInstanceWithoutConstructor() here?

Copy link
Member

@chalasrchalasrDec 29, 2016
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

@xabbuh some bundles may use constructor arguments in theirgetParent() method.
I tried to solve a similar issue in#18579

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

That's true, but the only ways to solve that issue completely would be to either pass bundles to extension classes or to write some logic that determines the paths during cache warmup.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Couldn't a parameter returning the bundle map be envisaged?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

The issue is that you still would not have access to actual instances of the bundles (so this would not solve#19586 (comment)).

@xabbuh
Copy link
Member

@wesleylancel Do you think you can finish this one?

@wesleylancel
Copy link
ContributorAuthor

@xabbuh: I wish, as this is something that would be extremely useful for us. But, as pointed out by@ro0NL, bundles can extend infinitely A > B > C > D. My PR currently only checks for one level of extending. Ideally, I would be able to access the bundle map that is part of the kernel, but that's not available at this stage yet. If you could point me towards a possible solution I'd be happy to adjust my code accordingly.

@ro0NL
Copy link
Contributor

ro0NL commentedDec 28, 2016
edited
Loading

Seeing the related ticket this goes back to 2013. And quite some issues are involved. I've not experienced it myself, but the template problem seems real.

Either way allowing kernel introspection would beextremely useful for everybody. Preferably with an immutable kernel. Practically we can movethis a few lines up. Relying on a synthetic service before compilation.

We also can expose bundles thru parameters, we only need stringish values here.BundleInterface only defines name, path and namespace anyway. So passing a stringish bundle map could work, and seems to make sense as we also provide kernel info already. Any further details can be provided withBundle::build.

But mayve@ogizanagi has more idea's? As i also liked his approach with a contextual builder. Maybe it can be simplified.

@ogizanagi
Copy link
Contributor

Unfortunately#19646 was my only attempt to provide a naive feature for sharing some contextual information while the container is building, avoiding the need to rely on pseudo tmp synthetic services. Along with theBootingKernel andBootingBundle classes, it allowed to solves issues related to this one as a demonstration of the possibilities.
But despite the implementation is simple, it somehow looks overkilled for the few needs.

As you suggested, maybe exposing a simple representation of the bundle map and bundles informations in a kernel parameter could be the way. But I don't remember all the ins and outs and if it was easily feasible at this point. :/

@ro0NL
Copy link
Contributor

ro0NL commentedDec 28, 2016
edited
Loading

But despite the implementation is simple, it somehow looks overkilled for the few needs.

Agree 👍 I feel the same about my own attempts now. Eventually having a builder with context can be done in userland easily. But it doesnt solve it for SF.

If there arent any other insights, i'd say go for%kernel.bundle_map% 👍

@chalasr
Copy link
Member

i'd say go for %kernel.bundle_map%

Not sure it's doable. PuttingKernel::$bundleMap in a new kernel parameter would just lead to

Unable to dump a service container if a parameter is an object or a resource.

@ro0NL
Copy link
Contributor

ro0NL commentedDec 29, 2016
edited
Loading

It's a stringish map, that's actually cached :) we're not passing bundle instances around here.

array(  'name' => ['parent' => 'name2', 'namespace' => 'NS', 'path' => '/bundles/name' ],  'name2' => //)

Something like that i guess.

I mean.. this would lead to a nested<argument> collection in XML right?

@ro0NL
Copy link
Contributor

ro0NL commentedDec 29, 2016
edited
Loading

Ie. looking at the issues, im not really sure we need true bundle instances here. Only metadata from bundle introspection. To build things properly.

I truly dont hope we're looking for ways to do this since 2013 😆 as it would definitely require theBootingKernel idea from@ogizanagi..

chalasr reacted with thumbs up emoji

StijnMaenhaut referenced this pull request in FriendsOfSymfony/FOSUserBundleDec 30, 2016
This makes the template compatible with projects disabling the Templatingcomponent in recent Symfony versions.
@xabbuh
Copy link
Member

👍 I checked this with the issues described inFriendsOfSymfony/FOSUserBundle#2376 andFriendsOfSymfony/FOSUserBundle#2378 and I can confirm that this patch fixes them.

Status: Reviewed

chalasr, wesleylancel, maxime-pasquier, veloxy, and alexislefebvre reacted with hooray emoji

@maxime-pasquier
Copy link

@xabbuh great news! Could you tell us on which branches this patch will be applied ?

@chalasr
Copy link
Member

@Kmelia Once merged, this will be available in the next patch releases of each maintained branch (i.e. from 2.7 to 3.2) and the current development version (3.3).

}

if (null !==$bundle['parent']) {
$this->prependParentPaths($twigFilesystemLoaderDefinition,$container,$name,$bundle['parent']);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Does this handle a chain of parents ?

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

@stof: Yes, this handles that. Should be covered with the changed test.

Copy link
Contributor

@ro0NLro0NLJan 6, 2017
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

prependParentPaths was confusing at first. Maybe keep actual path registration explicit inload()

while ($parent) {// add parent}// add self

Basically we dont need any path prepending or recursion, only adding paths in the right calling order.

Maybe utilize withaddBundlePaths or so.

}

if (null !==$bundle['parent']) {
$this->prependParentPaths($twigFilesystemLoaderDefinition,$container,$name,$bundle['parent']);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Prepending paths looks wrong to me here, as it would overwrite user-configured paths for the same namespace too.
What you should do is collecting the child bundles for each bundle, and then adding paths for child bundles before adding the path of the bundle itself

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

@stof: Did not now about that. That'll require some change to adding the normal paths too, I'll see how to best fix this. Is there an easy way to cover this in the test?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Add a path in the user-configured paths for the same namespace, and ensure that it ends up as the first path in the loader config for this namespace

@maxime-pasquier
Copy link

@chalasr thanks!

array(__DIR__.'/Fixtures/Bundle/ChildTwigBundle/Resources/views','Twig'),
array(__DIR__.'/Fixtures/Bundle/ChildChildTwigBundle/Resources/views','ChildTwig'),
array(__DIR__.'/Fixtures/Bundle/ChildChildTwigBundle/Resources/views','Twig'),
),$prependPaths);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

The way these tests are written does not ensure that paths are added in the right order for each namespace. there is nothing guaranteeing that the combinations of appended paths and prepended paths is actually giving us the right priority.

What we should do to have reliable tests is rebuilding the internal structure ofTwig_Loader_Filesystem::$path (i.e. the result of the configuration) and ensuring that it looks good for each namespace.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

@stof: I think whatever gets prepended last will have the most priority. If the array above is in this order, the correct path will end up on top. However, this doesn't keep those user-configured paths in mind. I'm not sure where these get added to the loader, but if they get prepended after the bundle paths get prepended, it should work all right? Not sure if that's testable in the existing test though.

If the Twig internals of that loader do need to be changed, I don't think this can be merged before that is resolved?

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

@stof: What if we move these lineshttps://github.com/symfony/symfony/blob/master/src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigExtension.php#L84-L90 to herehttps://github.com/symfony/symfony/blob/master/src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigExtension.php#L109 and change the method call toprependPath instead ofaddPath? This should make sure that user-defined paths from config take precedence over anything else.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

the issue is that the way the test is written does not allow to quickly validate what the final order will be when looking at it. This is why I think the test should not be written this way. We don't want to assert 2 separate lists, as we care about a single list (the one being used at runtime).

thus, the test is even confusing when looking at it, because the list ofprependPath here is in reverse order compared to the order of paths in the loader (as prepending adds at the beginning while you append in$prependPaths), making it even harder to validate/understand the assertion.

ro0NL and chalasr reacted with thumbs up emoji
Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

@stof I'll see if I can collect all the paths before actually adding them to the loader so they can all be tested together in order.

@wesleylancel
Copy link
ContributorAuthor

@stof I've added a separate commit so it's easier to see what I've changed (can be squashed later). A hierarchy of bundles is now built first, after that the paths are added to the loader. I'm not sure if I could simplify the code, especially the building of the hierarchy.

I could improve the test by asserting the array per namespace if that helps for readability?

@xabbuh
Copy link
Member

xabbuh commentedJan 7, 2017
edited
Loading

I think an easier implementation could be to have two loops. The first would collect path information for bundles we override without actually registering them. The second would then first register the additional paths from child bundles followed by paths the bundle provides itself.

maryo added a commit to vaniocz/vanio-user-bundle that referenced this pull requestJan 9, 2017
@wesleylancel
Copy link
ContributorAuthor

@xabbuh: Isn't that what I'm doing now? First the hierarchy is built and then the paths are registered.

);
}

if (is_dir($dir =$container->getParameter('kernel.root_dir').'/Resources/'.$name.'/views')) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Note to maintainers: when merging to newer branches, we need to take care of the FileExistenceResource objects here (git conflicts should remind us about this btw)

@stof
Copy link
Member

👍

chalasr, veloxy, wesleylancel, ogizanagi, and alexislefebvre reacted with hooray emoji

1 similar comment
@dunglas
Copy link
Member

👍

@fabpot
Copy link
Member

Thank you@wesleylancel.

fabpot added a commit that referenced this pull requestJan 11, 2017
…ent bundles in account (wesleylancel)This PR was squashed before being merged into the 2.7 branch (closes#19586).Discussion----------[TwigBundle] Fix bug where namespaced paths don't take parent bundles in account| Q | A || --- | --- || Branch? | 2.7 || Bug fix? | yes || New feature? | no || BC breaks? | no || Deprecations? | no || Tests pass? | yes || Fixed tickets |#6919 || License | MIT || Doc PR |  |Currently namespaced paths for templates such as `{% extends '@App/Layout/layout.html.twig' %}` do not work with bundles that have overruled templates using the `getParent()` method in another bundle. See attached ticket. This change prepends the path of the bundle implementing `getParent()` to the paths of the namespace of bundle returned as a parent.Commits-------0c77ce2 [TwigBundle] Fix bug where namespaced paths don't take parent bundles in account
@fabpotfabpot closed thisJan 11, 2017
@fabpotfabpot mentioned this pull requestJan 12, 2017
@homersimpsons
Copy link
Contributor

@fabpot Do you have any hint about the new release (containing this fix) date?

@chalasr
Copy link
Member

@homersimpsons today :) see#21258

homersimpsons reacted with thumbs up emoji

Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

@stofstofstof left review comments

@chalasrchalasrchalasr left review comments

@xabbuhxabbuhxabbuh approved these changes

+1 more reviewer

@ro0NLro0NLro0NL left review comments

Reviewers whose approvals may not affect merge requirements

Assignees

No one assigned

Projects

None yet

Milestone

2.7

Development

Successfully merging this pull request may close these issues.

13 participants

@wesleylancel@jakzal@xabbuh@ro0NL@ogizanagi@chalasr@fabpot@dunglas@maxime-pasquier@stof@homersimpsons@nicolas-grekas@carsonbot

[8]ページ先頭

©2009-2025 Movatter.jp