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

Appearance settings

[Form] set unique block prefix with any namespace #17874

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
wants to merge 1 commit into from
Closed

[Form] set unique block prefix with any namespace #17874

wants to merge 1 commit into from

Conversation

andrey1s
Copy link

Q A
Bug fix? yes
New feature? no
BC breaks? no
Deprecations? no
Tests pass? yes
Fixed tickets -
License MIT
Doc PR -

if there is no block hidden_locale_row when error

An exception has been thrown during the rendering of a template ("Unable to
render the form as none of the following blocks exist: "_form_texts_0_row",
"hidden_locale_row", "hidden_locale_row", "form_row", "form_row".") in
form_div_layout.html.twig at line 312.

@andrey1s andrey1s changed the title set unique block prefix with any namespace [Form] set unique block prefix with any namespace Feb 21, 2016
@enumag
Copy link
Contributor

enumag commented Mar 4, 2016

👍 I've just noticed similar error in my own application. The problem seems to occur when a prefix is repeated in the block_prefixes array. The exception is thrown too early - in the example from @andrey1s the block form_row certainly exists even though the exception says otherwise.

@webmozart
Copy link
Contributor

Hi, thanks for reporting this problem :) How can it happen that a block name is repeated in the chain? Can you provide code that reproduces your problem?

@andrey1s
Copy link
Author

andrey1s commented Mar 7, 2016

for example

//src/AppBundle/Controller/IndexController.php
<?php

namespace AppBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use AppBundle\Form\Type\Other\SimpleType;

class IndexController extends Controller
{
    /**
     * @Route("/", name="homepage")
     */
    public function homepageAction(Request $request)
    {
        $form = $this
            ->createFormBuilder()
            ->add('simple', SimpleType::class)
            ->getForm()
        ;

        return $this->render('@App/Index/homepage.html.twig', ['form' => $form->createView()]);
    }
}

forms

<?php
//src/AppBundle/Form/Type/Other/SimpleType.php
namespace AppBundle\Form\Type\Other;

use Symfony\Component\Form\AbstractType;
use AppBundle\Form\Type\SimpleType as BaseType;

class SimpleType extends AbstractType
{
    public function getParent()
    {
        return BaseType::class;
    }
}
<?php
//src/AppBundle/Form/Type/SimpleType.php
namespace AppBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextType;

class SimpleType extends AbstractType
{
    public function getParent()
    {
        return TextType::class;
    }
}

when there are two blocks with the same name is an error.
We can quickly fix the error in the form for example:

<?php
//src/AppBundle/Form/Type/Other/SimpleType.php
namespace AppBundle\Form\Type\Other;

use Symfony\Component\Form\AbstractType;
use AppBundle\Form\Type\SimpleType as BaseType;

class SimpleType extends AbstractType
{
    public function getParent()
    {
        return BaseType::class;
    }

    public function getBlockPrefix()
    {
        return 'text';
    }
}

@@ -171,7 +171,7 @@ private function loadResourceForBlockNameHierarchy($cacheKey, FormView $view, ar
// The next two if statements contain slightly duplicated code. This is by intention
// and tries to avoid execution of unnecessary checks in order to increase performance.

if (isset($this->resources[$cacheKey][$parentBlockName])) {
if (isset($this->resources[$cacheKey][$parentBlockName]) && $this->resources[$cacheKey][$parentBlockName] !== false) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This change is missing a corresponding test.

Also you are reducing the impact of a performance optimization here. Could you benchmark the result for big forms?

Copy link
Author

Choose a reason for hiding this comment

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

i can't find any test for the Symfony\Component\Form\AbstractRendererEngine or Symfony\Component\Form\Extension\Templating\TemplatingRendererEngine, could you show where are they located?

could you show the current benchmark?

Copy link
Contributor

@issei-m issei-m May 12, 2016

Choose a reason for hiding this comment

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

Should be the yoda style like:

false !== $this->resources[$cacheKey][$parentBlockName]

@webmozart
Copy link
Contributor

Thanks for the example, I understand your use case now. This conveys a bigger problem IMO.

In a template, a block (e.g. checkbox_widget) expects a specific block when rendering the block for the parent type (form_widget). By returning the block of another type from getBlockPrefix() we mess up that inheritance chain:

  • Twig blocks can't expect deterministic parent blocks anymore.
  • We can't short-circuit the loading of parent blocks anymore as we did so far, reducing the potential for performance improvements.

We should consider to recommend returning unique values from getBlockPrefix().

@enumag
Copy link
Contributor

enumag commented Mar 8, 2016

@webmozart In that case we should modify the exception - if there is a duplicate in the array throw an exception about that instead of what is thrown currently. Probably only when a problem like this occurs to avoid unnecessary checking for non-unique prefixes for every field.

@andrey1s
Copy link
Author

andrey1s commented Mar 8, 2016

@webmozart if we need to use a unique template, then Yes, otherwise it's not necessary.
if use unique block_prefix, may be better to use by default, e.g. like this AppBundle\Form\Type\Other\SimpleType => other_simple and AppBundle\Form\Type\SimpleType => simple or AppBundle\Form\Type\Other\Another\SimpleType => other_ another_simple

or AbstractType::getBlockPrefix() should return an empty block name. And add only if not empty.

@webmozart
Copy link
Contributor

@enumag Throwing an exception sounds like the best solution to me.

@andrey1s Changing the default block name is not possible without breaking BC.

@fabpot
Copy link
Member

fabpot commented Jun 16, 2016

IIUC, this change should not be merged but a new exception should be added, is that correct? How do we moved forward?

@enumag
Copy link
Contributor

enumag commented Jun 19, 2016

@fabpot I think adding an exeption like this solves the problem (at least the exception message is not so confusing anymore). However I was unable to write a test for it since FormRenderer class doesn't have any tests.

@fabpot
Copy link
Member

fabpot commented Jun 21, 2016

@enumag Can you update this PR with the commit you mentioned above? Tests can be added later or by someone else if needed.

@enumag
Copy link
Contributor

enumag commented Jun 21, 2016

@fabpot I'm not the author of this PR so I'll have to create a new one instead. Wait a moment...

@xabbuh
Copy link
Member

xabbuh commented Jun 21, 2016

Does that mean we should close here in favour of #19127?

@fabpot
Copy link
Member

fabpot commented Jun 21, 2016

Closing in favor of #19127

@fabpot fabpot closed this Jun 21, 2016
fabpot added a commit that referenced this pull request Jun 21, 2016
…k names (enumag)

This PR was merged into the 2.7 branch.

Discussion
----------

[Form] Add exception to FormRenderer about non-unique block names

| Q             | A
| ------------- | ---
| Branch?       | 2.7
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #17874
| License       | MIT
| Doc PR        |

Commits
-------

c6db6f3 [Form] Add exception to FormRenderer about non-unique block names
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants
Morty Proxy This is a proxified and sanitized view of the page, visit original site.