8000 Autowire route parameters with the PropertyAccess component · Issue #20083 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content

Autowire route parameters with the PropertyAccess component #20083

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
bocharsky-bw opened this issue Sep 29, 2016 · 5 comments
Closed

Autowire route parameters with the PropertyAccess component #20083

bocharsky-bw opened this issue Sep 29, 2016 · 5 comments

Comments

@bocharsky-bw
Copy link
Contributor

Now I should pass route parameters manually when generating URL to a route in any controller which extends Symfony\Bundle\FrameworkBundle\Controller:

$this->generateUrl('blog_post_show', [
  'year' => $post->getYear(),
  'slug' => $post->getSlug(),
]);

What about some sort of autowiring. i.e. allow populating route parameters automatically from specified object:

$this->generateUrl('blog_post_show', $post);

If an object was passed to the generateUrl() method instead of an array as the 2nd argument - let's use the PropertyAccess component to populate route parameters automatically from passed object.

BTW, we can't do it without BC break for the Router component, but can do for path()/url() Twig functions and generateUrl() method of Symfony\Bundle\FrameworkBundle\Controller as it does not implement RouterInterface.

@javiereguiluz
Copy link
Member

This is probably related with this old pending issue: #10395

@linaori
Copy link
Contributor
linaori commented Sep 29, 2016

@bocharsky-bw my bundle provides this functionality in a similar fashion: https://github.com/iltar/http-bundle It doesn't allow a direct value of your object (yet). I have not found out a proper way to do this. If you do know, feel free to open a PR.

@bocharsky-bw
Copy link
Contributor Author
bocharsky-bw commented Oct 6, 2016

It's similar to the #10395 but idea is a bit different and more simple as for me. I suggest to make it possible passing whole object to the generateUrl() method instead of extracting each parameter from the object manually and then passing an array of parameters. The PropertyAccess component can help to extract these values for you, e.g. I mean something like this simple and working implementation (without handling most unexpected errors yet):

abstract class Controller implements ContainerAwareInterface
{
    protected function generateUrl($route, $parameters = array(), $referenceType = UrlGeneratorInterface::ABSOLUTE_PATH)
    {
        if (is_object($parameters)) {
            $object = $parameters;
            $parameters = [];

            $propertyAccessor = $this->get('property_accessor');
            $variables = $this->get('router')->getRouteCollection()->get($route)->compile()->getVariables();
            foreach ($variables as $propertyName) {
                if ($propertyAccessor->isReadable($object, $propertyName)) {
                    $parameters[$propertyName] = $propertyAccessor->getValue($object, $propertyName);
                }
            }
        }

        return $this->container->get('router')->generate($route, $parameters, $referenceType);
    }
}

Of course, this feature does not cover all cases , but some simple like in my example to this issue it handles well. I think in a lot of projects many routes has similar construction: placeholders in routes matches with property names on an entity.

@linaori
Copy link
Contributor
linaori commented Oct 6, 2016

Your case only covers the Controller class like this, which is nice, but the idea is that the controller class merely provides a shortcut for several frequently used services/methods, not to actually provide a unique feature set.

I don't know if the $parameters = array() will ever get an array typehint, so that's why I have not yet build this feature yet. As I said, my bundle could probably do this as it already has a 95% similar feature, if you want to make a PR, go ahead and I can help you with it (otherwise I might make it myself some day). In theory stuff like generate($route, [$o1, $o2, ...]) is also possible without keys.

See:

While this feature is really nice, I don't think the overhead is worth it in the core as resolving the arguments simply costs more time, even though this is a great DX part.

@nicolas-grekas
Copy link
Member

Closing with the same reasoning as in #10395 : not for core, and doable in a bundle (use @iltar's)

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

4 participants
0