Skip to content

Commit

Permalink
feature #30501 [FrameworkBundle][Routing] added Configurators to hand…
Browse files Browse the repository at this point in the history
…le template and redirect controllers (HeahDude)

This PR was merged into the 5.1-dev branch.

Discussion
----------

[FrameworkBundle][Routing] added Configurators to handle template and redirect controllers

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | let's see
| Fixed tickets | partially #24640, #25145
| License       | MIT
| Doc PR        | symfony/symfony-docs#11120

While working on symfony/symfony-docs#11085, I felt bad about the long notations required for simple [redirects](https://symfony.com/doc/current/routing/redirect_in_config.html) and [templates rendering](https://symfony.com/doc/current/templating/render_without_controller.html) template actions, but I love and use those features since always. Then I gave it a try yesterday night and now I realised I missed #24640 and that #25145 has been closed x).

So here we go, here's my WIP. WDYT of this implementation? ping @javiereguiluz?

I'm going to open the PR in the docs so we can discuss the DX changes there too, and keep focus on the code here.

Cheers!

EDIT
----
This PR now only update PHP-DSL configurators.

______________

TODO:

- [x] gather reviews
- ~[x] fix xml schema~
- [x] add some tests
- ~[ ] handle xsd auto discovery~
- [x] rebase on top of #30507
- [x] ~add shortcuts for #30514~

Commits
-------

de74794 [FrameworkBundle][Routing] added Configurators to handle template and redirect controllers
  • Loading branch information
nicolas-grekas committed Feb 9, 2020
2 parents 9bfa258 + de74794 commit 477ee19
Show file tree
Hide file tree
Showing 25 changed files with 788 additions and 205 deletions.
7 changes: 4 additions & 3 deletions src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md
Expand Up @@ -4,6 +4,7 @@ CHANGELOG
5.1.0
-----

* Added `Routing\Loader` and `Routing\Loader\Configurator` namespaces to ease defining routes with default controllers
* Added the `framework.router.context` configuration node to configure the `RequestContext`
* Made `MicroKernelTrait::configureContainer()` compatible with `ContainerConfigurator`
* Added a new `mailer.message_bus` option to configure or disable the message bus to use to send mails.
Expand All @@ -29,7 +30,7 @@ CHANGELOG
* Removed the `translator.selector` and `session.save_listener` services
* Removed `SecurityUserValueResolver`, use `UserValueResolver` instead
* Removed `routing.loader.service`.
* Service route loaders must be tagged with `routing.route_loader`.
* Service route loaders must be tagged with `routing.route_loader`.
* Added `slugger` service and `SluggerInterface` alias
* Removed the `lock.store.flock`, `lock.store.semaphore`, `lock.store.memcached.abstract` and `lock.store.redis.abstract` services.
* Removed the `router.cache_class_prefix` parameter.
Expand Down Expand Up @@ -81,8 +82,8 @@ CHANGELOG
options if you're using Symfony's serializer.
* [BC Break] Removed the `framework.messenger.routing.send_and_handle` configuration.
Instead of setting it to true, configure a `SyncTransport` and route messages to it.
* Added information about deprecated aliases in `debug:autowiring`
* Added php ini session options `sid_length` and `sid_bits_per_character`
* Added information about deprecated aliases in `debug:autowiring`
* Added php ini session options `sid_length` and `sid_bits_per_character`
to the `session` section of the configuration
* Added support for Translator paths, Twig paths in translation commands.
* Added support for PHP files with translations in translation commands.
Expand Down
Expand Up @@ -11,14 +11,14 @@

namespace Symfony\Bundle\FrameworkBundle\Kernel;

use Symfony\Bundle\FrameworkBundle\Routing\Loader\Configurator\RoutingConfigurator;
use Symfony\Bundle\FrameworkBundle\Routing\Loader\PhpFileLoader as RoutingPhpFileLoader;
use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\Configurator\AbstractConfigurator;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader as ContainerPhpFileLoader;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator;
use Symfony\Component\Routing\Loader\PhpFileLoader as RoutingPhpFileLoader;
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\RouteCollectionBuilder;

Expand Down
Expand Up @@ -25,7 +25,7 @@
<argument type="service" id="file_locator" />
</service>

<service id="routing.loader.php" class="Symfony\Component\Routing\Loader\PhpFileLoader">
<service id="routing.loader.php" class="Symfony\Bundle\FrameworkBundle\Routing\Loader\PhpFileLoader">
<tag name="routing.loader" />
<argument type="service" id="file_locator" />
</service>
Expand Down
@@ -0,0 +1,33 @@
<?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\FrameworkBundle\Routing\Loader\Configurator;

use Symfony\Bundle\FrameworkBundle\Routing\Loader\Configurator\Traits\AddTrait;
use Symfony\Component\Routing\Loader\Configurator\RouteConfigurator;

/**
* @author Nicolas Grekas <p@tchwork.com>
*/
class GoneRouteConfigurator extends RouteConfigurator
{
use AddTrait;

/**
* @param bool $permanent Whether the redirection is permanent
*
* @return $this
*/
final public function permanent(bool $permanent = true)
{
return $this->defaults(['permanent' => $permanent]);
}
}
@@ -0,0 +1,63 @@
<?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\FrameworkBundle\Routing\Loader\Configurator;

use Symfony\Bundle\FrameworkBundle\Routing\Loader\Configurator\Traits\AddTrait;
use Symfony\Component\Routing\Loader\Configurator\RouteConfigurator;

/**
* @author Jules Pietri <jules@heahprod.com>
*/
class RedirectRouteConfigurator extends RouteConfigurator
{
use AddTrait;

/**
* @param bool $permanent Whether the redirection is permanent
*
* @return $this
*/
final public function permanent(bool $permanent = true)
{
return $this->defaults(['permanent' => $permanent]);
}

/**
* @param bool|array $ignoreAttributes Whether to ignore attributes or an array of attributes to ignore
*
* @return $this
*/
final public function ignoreAttributes($ignoreAttributes = true)
{
return $this->defaults(['ignoreAttributes' => $ignoreAttributes]);
}

/**
* @param bool $keepRequestMethod Whether redirect action should keep HTTP request method
*
* @return $this
*/
final public function keepRequestMethod(bool $keepRequestMethod = true)
{
return $this->defaults(['keepRequestMethod' => $keepRequestMethod]);
}

/**
* @param bool $keepQueryParams Whether redirect action should keep query parameters
*
* @return $this
*/
final public function keepQueryParams(bool $keepQueryParams = true)
{
return $this->defaults(['keepQueryParams' => $keepQueryParams]);
}
}
@@ -0,0 +1,73 @@
<?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\FrameworkBundle\Routing\Loader\Configurator;

use Symfony\Bundle\FrameworkBundle\Controller\RedirectController;
use Symfony\Bundle\FrameworkBundle\Controller\TemplateController;
use Symfony\Component\Routing\Loader\Configurator\RouteConfigurator as BaseRouteConfigurator;

/**
* @author Jules Pietri <jules@heahprod.com>
*/
class RouteConfigurator extends BaseRouteConfigurator
{
/**
* @param string $template The template name
* @param array $context The template variables
*/
final public function template(string $template, array $context = []): TemplateRouteConfigurator
{
return (new TemplateRouteConfigurator($this->collection, $this->route, $this->name, $this->parentConfigurator, $this->prefixes))
->defaults([
'_controller' => TemplateController::class,
'template' => $template,
'context' => $context,
])
;
}

/**
* @param string $route The route name to redirect to
*/
final public function redirectToRoute(string $route): RedirectRouteConfigurator
{
return (new RedirectRouteConfigurator($this->collection, $this->route, $this->name, $this->parentConfigurator, $this->prefixes))
->defaults([
'_controller' => RedirectController::class.'::redirectAction',
'route' => $route,
])
;
}

/**
* @param string $url The relative path or URL to redirect to
*/
final public function redirectToUrl(string $url): UrlRedirectRouteConfigurator
{
return (new UrlRedirectRouteConfigurator($this->collection, $this->route, $this->name, $this->parentConfigurator, $this->prefixes))
->defaults([
'_controller' => RedirectController::class.'::urlRedirectAction',
'path' => $url,
])
;
}

final public function gone(): GoneRouteConfigurator
{
return (new GoneRouteConfigurator($this->collection, $this->route, $this->name, $this->parentConfigurator, $this->prefixes))
->defaults([
'_controller' => RedirectController::class.'::redirectAction',
'route' => '',
])
;
}
}
@@ -0,0 +1,20 @@
<?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\FrameworkBundle\Routing\Loader\Configurator;

use Symfony\Bundle\FrameworkBundle\Routing\Loader\Configurator\Traits\AddTrait;
use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator as BaseRoutingConfigurator;

class RoutingConfigurator extends BaseRoutingConfigurator
{
use AddTrait;
}
@@ -0,0 +1,53 @@
<?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\FrameworkBundle\Routing\Loader\Configurator;

use Symfony\Bundle\FrameworkBundle\Routing\Loader\Configurator\Traits\AddTrait;
use Symfony\Component\Routing\Loader\Configurator\RouteConfigurator;

/**
* @author Jules Pietri <jules@heahprod.com>
*/
class TemplateRouteConfigurator extends RouteConfigurator
{
use AddTrait;

/**
* @param int|null $maxAge Max age for client caching
*
* @return $this
*/
final public function maxAge(?int $maxAge)
{
return $this->defaults(['maxAge' => $maxAge]);
}

/**
* @param int|null $sharedMaxAge Max age for shared (proxy) caching
*
* @return $this
*/
final public function sharedMaxAge(?int $sharedMaxAge)
{
return $this->defaults(['sharedAge' => $sharedMaxAge]);
}

/**
* @param bool|null $private Whether or not caching should apply for client caches only
*
* @return $this
*/
final public function private(?bool $private = true)
{
return $this->defaults(['private' => $private]);
}
}
@@ -0,0 +1,46 @@
<?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\FrameworkBundle\Routing\Loader\Configurator\Traits;

use Symfony\Bundle\FrameworkBundle\Routing\Loader\Configurator\RouteConfigurator;
use Symfony\Component\Routing\Loader\Configurator\CollectionConfigurator;
use Symfony\Component\Routing\Loader\Configurator\RouteConfigurator as BaseRouteConfigurator;

trait AddTrait
{
/**
* Adds a route.
*
* @param string|array $path the path, or the localized paths of the route
*
* @return RouteConfigurator
*/
public function add(string $name, $path): BaseRouteConfigurator
{
$parentConfigurator = $this instanceof CollectionConfigurator ? $this : ($this instanceof RouteConfigurator ? $this->parentConfigurator : null);
$route = $this->createLocalizedRoute($this->collection, $name, $path, $this->name, $this->prefixes);

return new RouteConfigurator($this->collection, $route, $this->name, $parentConfigurator, $this->prefixes);
}

/**
* Adds a route.
*
* @param string|array $path the path, or the localized paths of the route
*
* @return RouteConfigurator
*/
final public function __invoke(string $name, $path): BaseRouteConfigurator
{
return $this->add($name, $path);
}
}

0 comments on commit 477ee19

Please sign in to comment.