Issue #1798214 by tnightingale, g.oechsler, fubhy, katbailey, effulgentsia, Crell, dipen chaudhary: Upcast request arguments/attributes to full objects.
parent
5b04198364
commit
c5b09f74eb
|
@ -85,7 +85,10 @@ function current_path() {
|
||||||
// fallback code below, once the path alias logic has been figured out in
|
// fallback code below, once the path alias logic has been figured out in
|
||||||
// http://drupal.org/node/1269742.
|
// http://drupal.org/node/1269742.
|
||||||
if (drupal_container()->isScopeActive('request')) {
|
if (drupal_container()->isScopeActive('request')) {
|
||||||
return drupal_container()->get('request')->attributes->get('system_path');
|
$path = drupal_container()->get('request')->attributes->get('system_path');
|
||||||
|
if ($path !== NULL) {
|
||||||
|
return $path;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// If we are outside the request scope, fall back to using the path stored in
|
// If we are outside the request scope, fall back to using the path stored in
|
||||||
// _current_path().
|
// _current_path().
|
||||||
|
|
|
@ -11,7 +11,9 @@ use Drupal\Core\DependencyInjection\Compiler\RegisterKernelListenersPass;
|
||||||
use Drupal\Core\DependencyInjection\Compiler\RegisterAccessChecksPass;
|
use Drupal\Core\DependencyInjection\Compiler\RegisterAccessChecksPass;
|
||||||
use Drupal\Core\DependencyInjection\Compiler\RegisterMatchersPass;
|
use Drupal\Core\DependencyInjection\Compiler\RegisterMatchersPass;
|
||||||
use Drupal\Core\DependencyInjection\Compiler\RegisterRouteFiltersPass;
|
use Drupal\Core\DependencyInjection\Compiler\RegisterRouteFiltersPass;
|
||||||
|
use Drupal\Core\DependencyInjection\Compiler\RegisterRouteEnhancersPass;
|
||||||
use Drupal\Core\DependencyInjection\Compiler\RegisterSerializationClassesPass;
|
use Drupal\Core\DependencyInjection\Compiler\RegisterSerializationClassesPass;
|
||||||
|
use Drupal\Core\DependencyInjection\Compiler\RegisterParamConvertersPass;
|
||||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||||
use Symfony\Component\DependencyInjection\Reference;
|
use Symfony\Component\DependencyInjection\Reference;
|
||||||
|
@ -206,6 +208,12 @@ class CoreBundle extends Bundle {
|
||||||
$container->register('mime_type_matcher', 'Drupal\Core\Routing\MimeTypeMatcher')
|
$container->register('mime_type_matcher', 'Drupal\Core\Routing\MimeTypeMatcher')
|
||||||
->addTag('route_filter');
|
->addTag('route_filter');
|
||||||
|
|
||||||
|
$container->register('paramconverter_manager', 'Drupal\Core\ParamConverter\ParamConverterManager')
|
||||||
|
->addTag('route_enhancer');
|
||||||
|
$container->register('paramconverter.entity', 'Drupal\Core\ParamConverter\EntityConverter')
|
||||||
|
->addArgument(new Reference('plugin.manager.entity'))
|
||||||
|
->addTag('paramconverter');
|
||||||
|
|
||||||
$container->register('router_processor_subscriber', 'Drupal\Core\EventSubscriber\RouteProcessorSubscriber')
|
$container->register('router_processor_subscriber', 'Drupal\Core\EventSubscriber\RouteProcessorSubscriber')
|
||||||
->addArgument(new Reference('content_negotiation'))
|
->addArgument(new Reference('content_negotiation'))
|
||||||
->addTag('event_subscriber');
|
->addTag('event_subscriber');
|
||||||
|
@ -286,6 +294,9 @@ class CoreBundle extends Bundle {
|
||||||
// Add a compiler pass for registering event subscribers.
|
// Add a compiler pass for registering event subscribers.
|
||||||
$container->addCompilerPass(new RegisterKernelListenersPass(), PassConfig::TYPE_AFTER_REMOVING);
|
$container->addCompilerPass(new RegisterKernelListenersPass(), PassConfig::TYPE_AFTER_REMOVING);
|
||||||
$container->addCompilerPass(new RegisterAccessChecksPass());
|
$container->addCompilerPass(new RegisterAccessChecksPass());
|
||||||
|
// Add a compiler pass for upcasting of entity route parameters.
|
||||||
|
$container->addCompilerPass(new RegisterParamConvertersPass());
|
||||||
|
$container->addCompilerPass(new RegisterRouteEnhancersPass());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Contains Drupal\Core\DependencyInjection\Compiler\RegisterParamConvertersPass.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Drupal\Core\DependencyInjection\Compiler;
|
||||||
|
|
||||||
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||||
|
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||||
|
use Symfony\Component\DependencyInjection\Reference;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers EntityConverter services with the ParamConverterManager.
|
||||||
|
*/
|
||||||
|
class RegisterParamConvertersPass implements CompilerPassInterface {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds services tagged with "paramconverter" to the param converter service.
|
||||||
|
*
|
||||||
|
* @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
|
||||||
|
* The container to process.
|
||||||
|
*/
|
||||||
|
public function process(ContainerBuilder $container) {
|
||||||
|
|
||||||
|
if (!$container->hasDefinition('paramconverter_manager')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$manager = $container->getDefinition('paramconverter_manager');
|
||||||
|
|
||||||
|
$services = array();
|
||||||
|
foreach ($container->findTaggedServiceIds('paramconverter') as $id => $attributes) {
|
||||||
|
$priority = isset($attributes[0]['priority']) ? $attributes[0]['priority'] : 0;
|
||||||
|
|
||||||
|
$services[$priority][] = new Reference($id);
|
||||||
|
}
|
||||||
|
|
||||||
|
krsort($services);
|
||||||
|
|
||||||
|
foreach ($services as $priority) {
|
||||||
|
foreach ($priority as $service) {
|
||||||
|
$manager->addMethodCall('addConverter', array($service));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Contains Drupal\Core\DependencyInjection\Compiler\RegisterRouteEnhancersPass.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Drupal\Core\DependencyInjection\Compiler;
|
||||||
|
|
||||||
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||||
|
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||||
|
use Symfony\Component\DependencyInjection\Reference;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers route enhancer services with the router.
|
||||||
|
*/
|
||||||
|
class RegisterRouteEnhancersPass implements CompilerPassInterface {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds services tagged with "route_enhancer" to the router.
|
||||||
|
*
|
||||||
|
* @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
|
||||||
|
* The container to process.
|
||||||
|
*/
|
||||||
|
public function process(ContainerBuilder $container) {
|
||||||
|
if (!$container->hasDefinition('router.dynamic')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$router = $container->getDefinition('router.dynamic');
|
||||||
|
|
||||||
|
$services = array();
|
||||||
|
foreach ($container->findTaggedServiceIds('route_enhancer') as $id => $attributes) {
|
||||||
|
$priority = isset($attributes[0]['priority']) ? $attributes[0]['priority'] : 0;
|
||||||
|
$router->addMethodCall('addRouteEnhancer', array(new Reference($id), $priority));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,106 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Contains Drupal\Core\ParamConverter\EntityConverter.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Drupal\Core\ParamConverter;
|
||||||
|
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Component\Routing\Route;
|
||||||
|
use Drupal\Core\Entity\EntityManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class allows the upcasting of entity ids to the respective entity
|
||||||
|
* object.
|
||||||
|
*/
|
||||||
|
class EntityConverter implements ParamConverterInterface {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Entity manager which performs the upcasting in the end.
|
||||||
|
*
|
||||||
|
* @var \Drupal\Core\Entity\EntityManager
|
||||||
|
*/
|
||||||
|
protected $entityManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new EntityConverter.
|
||||||
|
*
|
||||||
|
* @param \Drupal\Core\Entity\EntityManager $entityManager
|
||||||
|
* The entity manager.
|
||||||
|
*/
|
||||||
|
public function __construct(EntityManager $entityManager) {
|
||||||
|
$this->entityManager = $entityManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tries to upcast every variable to an entity type.
|
||||||
|
*
|
||||||
|
* If there is a type denoted in the route options it will try to upcast to
|
||||||
|
* it, if there is no definition in the options it will try to upcast to an
|
||||||
|
* entity type of that name. If the chosen enity type does not exists it will
|
||||||
|
* leave the variable untouched.
|
||||||
|
* If the entity type exist, but there is no entity with the given id it will
|
||||||
|
* convert the variable to NULL.
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
*
|
||||||
|
* pattern: '/a/{user}/some/{foo}/and/{bar}/'
|
||||||
|
* options:
|
||||||
|
* converters:
|
||||||
|
* foo: 'node'
|
||||||
|
*
|
||||||
|
* The value for {user} will be converted to a user entity and the value
|
||||||
|
* for {foo} to a node entity, but it will not touch the value for {bar}.
|
||||||
|
*
|
||||||
|
* It will not process variables which are marked as converted. It will mark
|
||||||
|
* any variable it processes as converted.
|
||||||
|
*
|
||||||
|
* @param array &$variables
|
||||||
|
* Array of values to convert to their corresponding objects, if applicable.
|
||||||
|
* @param \Symfony\Component\Routing\Route $route
|
||||||
|
* The route object.
|
||||||
|
* @param array &$converted
|
||||||
|
* Array collecting the names of all variables which have been
|
||||||
|
* altered by a converter.
|
||||||
|
*/
|
||||||
|
public function process(array &$variables, Route $route, array &$converted) {
|
||||||
|
$variable_names = $route->compile()->getVariables();
|
||||||
|
|
||||||
|
$options = $route->getOptions();
|
||||||
|
$configuredTypes = isset($options['converters']) ? $options['converters'] : array();
|
||||||
|
|
||||||
|
$entityTypes = array_keys($this->entityManager->getDefinitions());
|
||||||
|
|
||||||
|
foreach ($variable_names as $name) {
|
||||||
|
// Do not process this variable if it's already marked as converted.
|
||||||
|
if (in_array($name, $converted)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Obtain entity type to convert to from the route configuration or just
|
||||||
|
// use the variable name as default.
|
||||||
|
if (array_key_exists($name, $configuredTypes)) {
|
||||||
|
$type = $configuredTypes[$name];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$type = $name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_array($type, $entityTypes)) {
|
||||||
|
$value = $variables[$name];
|
||||||
|
|
||||||
|
$storageController = $this->entityManager->getStorageController($type);
|
||||||
|
$entities = $storageController->load(array($value));
|
||||||
|
|
||||||
|
// Make sure $entities is null, if upcasting fails.
|
||||||
|
$entity = $entities ? reset($entities) : NULL;
|
||||||
|
$variables[$name] = $entity;
|
||||||
|
|
||||||
|
// Mark this variable as converted.
|
||||||
|
$converted[] = $name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Contains Drupal\Core\ParamConverter\ParamConverterInterface.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Drupal\Core\ParamConverter;
|
||||||
|
|
||||||
|
use Symfony\Component\Routing\Route;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for parameter converters.
|
||||||
|
*/
|
||||||
|
interface ParamConverterInterface {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows to convert variables to their corresponding objects.
|
||||||
|
*
|
||||||
|
* @param array &$variables
|
||||||
|
* Array of values to convert to their corresponding objects, if applicable.
|
||||||
|
* @param \Symfony\Component\Routing\Route $route
|
||||||
|
* The route object.
|
||||||
|
* @param array &$converted
|
||||||
|
* Array collecting the names of all variables which have been
|
||||||
|
* altered by a converter.
|
||||||
|
*/
|
||||||
|
public function process(array &$variables, Route $route, array &$converted);
|
||||||
|
}
|
|
@ -0,0 +1,89 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Contains Drupal\Core\ParamConverter\ParamConverterManager.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Drupal\Core\ParamConverter;
|
||||||
|
|
||||||
|
use Symfony\Component\DependencyInjection\ContainerAware;
|
||||||
|
use Symfony\Cmf\Component\Routing\Enhancer\RouteEnhancerInterface;
|
||||||
|
use Symfony\Cmf\Component\Routing\RouteObjectInterface;
|
||||||
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
|
||||||
|
use Drupal\Core\ParamConverter\ParamConverterInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides a service which allows to enhance (say alter) the arguments coming
|
||||||
|
* from the URL.
|
||||||
|
*
|
||||||
|
* A typical use case for this would be upcasting a node id to a node entity.
|
||||||
|
*
|
||||||
|
* This class will not enhance any of the arguments itself, but allow other
|
||||||
|
* services to register to do so.
|
||||||
|
*/
|
||||||
|
class ParamConverterManager implements RouteEnhancerInterface {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converters managed by the ParamConverterManager.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $converters;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a converter to the paramconverter service.
|
||||||
|
*
|
||||||
|
* @see \Drupal\Core\DependencyInjection\Compiler\RegisterParamConvertersPass
|
||||||
|
*
|
||||||
|
* @param \Drupal\Core\ParamConverter\ParamConverterInterface $converter
|
||||||
|
* The converter to add.
|
||||||
|
*/
|
||||||
|
public function addConverter(ParamConverterInterface $converter) {
|
||||||
|
$this->converters[] = $converter;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements \Symfony\Cmf\Component\Routing\Enhancer\ŖouteEnhancerIterface.
|
||||||
|
*
|
||||||
|
* Iterates over all registered converters and allows them to alter the
|
||||||
|
* defaults.
|
||||||
|
*
|
||||||
|
* @param array $defaults
|
||||||
|
* The getRouteDefaults array.
|
||||||
|
* @param \Symfony\Component\HttpFoundation\Request $request
|
||||||
|
* The current request.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
* The modified defaults.
|
||||||
|
*/
|
||||||
|
public function enhance(array $defaults, Request $request) {
|
||||||
|
// This array will collect the names of all variables which have been
|
||||||
|
// altered by a converter.
|
||||||
|
// This serves two purposes:
|
||||||
|
// 1. It might prevent converters later in the pipeline to process
|
||||||
|
// a variable again.
|
||||||
|
// 2. To check if upcasting was successfull after each converter had
|
||||||
|
// a go. See below.
|
||||||
|
$converters = array();
|
||||||
|
|
||||||
|
$route = $defaults[RouteObjectInterface::ROUTE_OBJECT];
|
||||||
|
|
||||||
|
foreach ($this->converters as $converter) {
|
||||||
|
$converter->process($defaults, $route, $converters);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if all upcasting yielded a result.
|
||||||
|
// If an upcast value is NULL do a 404.
|
||||||
|
foreach ($converters as $variable) {
|
||||||
|
if ($defaults[$variable] === NULL) {
|
||||||
|
throw new NotFoundHttpException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $defaults;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,77 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Contains Drupal\system\Tests\ParamConverter\UpcastingTest.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Drupal\system\Tests\ParamConverter;
|
||||||
|
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||||
|
use Drupal\Core\DependencyInjection\ContainerBuilder;
|
||||||
|
use Drupal\simpletest\WebTestBase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Web tests for the upcasting.
|
||||||
|
*/
|
||||||
|
class UpcastingTest extends WebTestBase {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implement getInfo().
|
||||||
|
*/
|
||||||
|
public static function getInfo() {
|
||||||
|
return array(
|
||||||
|
'name' => 'Upcasting tests',
|
||||||
|
'description' => 'Tests upcasting of url arguments to entities.',
|
||||||
|
'group' => 'ParamConverter',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static $modules = array('paramconverter_test');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Confirms that all parameters are converted as expected.
|
||||||
|
*
|
||||||
|
* All of these requests end up being proccessed by a controller with this
|
||||||
|
* the signature: f($user, $node, $foo) returning either values or labels
|
||||||
|
* like "user: Dries, node: First post, foo: bar"
|
||||||
|
*
|
||||||
|
* The tests shuffle the parameters around an checks if the right thing is
|
||||||
|
* happening.
|
||||||
|
*/
|
||||||
|
public function testUpcasting() {
|
||||||
|
$node = $this->drupalCreateNode(array('title' => $this->randomName(8)));
|
||||||
|
$user = $this->drupalCreateUser(array('access content'));
|
||||||
|
$foo = 'bar';
|
||||||
|
|
||||||
|
// paramconverter_test/test_user_node_foo/{user}/{node}/{foo}
|
||||||
|
$this->drupalGet("paramconverter_test/test_user_node_foo/{$user->uid}/{$node->nid}/$foo");
|
||||||
|
$this->assertRaw("user: {$user->label()}, node: {$node->label()}, foo: $foo", 'user and node upcast by entity name');
|
||||||
|
|
||||||
|
// paramconverter_test/test_node_user_user/{node}/{foo}/{user}
|
||||||
|
// converters:
|
||||||
|
// foo: 'user'
|
||||||
|
$this->drupalGet("paramconverter_test/test_node_user_user/{$node->nid}/{$user->uid}/{$user->uid}");
|
||||||
|
$this->assertRaw("user: {$user->label()}, node: {$node->label()}, foo: {$user->label()}", 'foo converted to user as well');
|
||||||
|
|
||||||
|
// paramconverter_test/test_node_node_foo/{user}/{node}/{foo}
|
||||||
|
// converters:
|
||||||
|
// user: 'node'
|
||||||
|
$this->drupalGet("paramconverter_test/test_node_node_foo/{$node->nid}/{$node->nid}/$foo");
|
||||||
|
$this->assertRaw("user: {$node->label()}, node: {$node->label()}, foo: $foo", 'user is upcast to node (rather than to user)');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Confirms we can upcast to controller arguments of the same type.
|
||||||
|
*/
|
||||||
|
public function testSameTypes() {
|
||||||
|
$node = $this->drupalCreateNode(array('title' => $this->randomName(8)));
|
||||||
|
$parent = $this->drupalCreateNode(array('title' => $this->randomName(8)));
|
||||||
|
// paramconverter_test/node/{node}/set/parent/{parent}
|
||||||
|
// converters:
|
||||||
|
// parent: 'node'
|
||||||
|
$this->drupalGet("paramconverter_test/node/" . $node->nid . "/set/parent/" . $parent->nid);
|
||||||
|
$this->assertRaw("Setting '" . $parent->title . "' as parent of '" . $node->title . "'.");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Contains Drupal\paramconverter_test\TestControllers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Drupal\paramconverter_test;
|
||||||
|
|
||||||
|
use Drupal\node\Plugin\Core\Entity\Node;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controller routine for testing the paramconverter.
|
||||||
|
*/
|
||||||
|
class TestControllers {
|
||||||
|
|
||||||
|
public function testUserNodeFoo($user, $node, $foo) {
|
||||||
|
$retval = "user: " . (is_object($user) ? $user->label() : $user);
|
||||||
|
$retval .= ", node: " . (is_object($node) ? $node->label() : $node);
|
||||||
|
$retval .= ", foo: " . (is_object($foo) ? $foo->label() : $foo);
|
||||||
|
return $retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testNodeSetParent(Node $node, Node $parent) {
|
||||||
|
return "Setting '{$parent->title}' as parent of '{$node->title}'.";
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
name = "ParamConverter test"
|
||||||
|
description = "Support module for paramconverter testing."
|
||||||
|
package = Testing
|
||||||
|
version = VERSION
|
||||||
|
core = 8.x
|
||||||
|
hidden = TRUE
|
|
@ -0,0 +1,6 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Intentionally blank file.
|
||||||
|
*/
|
|
@ -0,0 +1,36 @@
|
||||||
|
paramconverter_test_user_node_foo:
|
||||||
|
pattern: '/paramconverter_test/test_user_node_foo/{user}/{node}/{foo}'
|
||||||
|
defaults:
|
||||||
|
_content: '\Drupal\paramconverter_test\TestControllers::testUserNodeFoo'
|
||||||
|
requirements:
|
||||||
|
_access: 'TRUE'
|
||||||
|
|
||||||
|
paramconverter_test_node_user_user:
|
||||||
|
pattern: '/paramconverter_test/test_node_user_user/{node}/{foo}/{user}'
|
||||||
|
defaults:
|
||||||
|
_content: '\Drupal\paramconverter_test\TestControllers::testUserNodeFoo'
|
||||||
|
requirements:
|
||||||
|
_access: 'TRUE'
|
||||||
|
options:
|
||||||
|
converters:
|
||||||
|
foo: 'user'
|
||||||
|
|
||||||
|
paramconverter_test_node_node_foo:
|
||||||
|
pattern: '/paramconverter_test/test_node_node_foo/{user}/{node}/{foo}'
|
||||||
|
defaults:
|
||||||
|
_content: '\Drupal\paramconverter_test\TestControllers::testUserNodeFoo'
|
||||||
|
requirements:
|
||||||
|
_access: 'TRUE'
|
||||||
|
options:
|
||||||
|
converters:
|
||||||
|
user: 'node'
|
||||||
|
|
||||||
|
paramconverter_test_node_set_parent:
|
||||||
|
pattern: '/paramconverter_test/node/{node}/set/parent/{parent}'
|
||||||
|
requirements:
|
||||||
|
_access: 'TRUE'
|
||||||
|
defaults:
|
||||||
|
_content: '\Drupal\paramconverter_test\TestControllers::testNodeSetParent'
|
||||||
|
options:
|
||||||
|
converters:
|
||||||
|
parent: 'node'
|
Loading…
Reference in New Issue