Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Open sidebar
project
drupal
Commits
1601b088
Commit
1601b088
authored
Jan 05, 2015
by
alexpott
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Issue
#2350503
by dawehner: Add route generation handlers for entities
parent
d7e814a6
Changes
14
Show whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
303 additions
and
55 deletions
+303
-55
core/core.services.yml
core/core.services.yml
+5
-0
core/lib/Drupal/Core/Entity/EntityManager.php
core/lib/Drupal/Core/Entity/EntityManager.php
+14
-0
core/lib/Drupal/Core/Entity/EntityManagerInterface.php
core/lib/Drupal/Core/Entity/EntityManagerInterface.php
+10
-0
core/lib/Drupal/Core/Entity/EntityType.php
core/lib/Drupal/Core/Entity/EntityType.php
+14
-0
core/lib/Drupal/Core/Entity/EntityTypeInterface.php
core/lib/Drupal/Core/Entity/EntityTypeInterface.php
+20
-0
core/lib/Drupal/Core/Entity/Routing/EntityRouteProviderInterface.php
...upal/Core/Entity/Routing/EntityRouteProviderInterface.php
+29
-0
core/lib/Drupal/Core/EventSubscriber/EntityRouteProviderSubscriber.php
...al/Core/EventSubscriber/EntityRouteProviderSubscriber.php
+74
-0
core/modules/node/node.routing.yml
core/modules/node/node.routing.yml
+0
-27
core/modules/node/src/Entity/Node.php
core/modules/node/src/Entity/Node.php
+3
-0
core/modules/node/src/Entity/NodeRouteProvider.php
core/modules/node/src/Entity/NodeRouteProvider.php
+51
-0
core/modules/user/src/Entity/User.php
core/modules/user/src/Entity/User.php
+3
-0
core/modules/user/src/Entity/UserRouteProvider.php
core/modules/user/src/Entity/UserRouteProvider.php
+54
-0
core/modules/user/user.routing.yml
core/modules/user/user.routing.yml
+0
-28
core/tests/Drupal/Tests/Core/Entity/EntityManagerTest.php
core/tests/Drupal/Tests/Core/Entity/EntityManagerTest.php
+26
-0
No files found.
core/core.services.yml
View file @
1601b088
...
@@ -311,6 +311,11 @@ services:
...
@@ -311,6 +311,11 @@ services:
parent
:
container.trait
parent
:
container.trait
tags
:
tags
:
-
{
name
:
plugin_manager_cache_clear
}
-
{
name
:
plugin_manager_cache_clear
}
entity_route_subscriber
:
class
:
Drupal\Core\EventSubscriber\EntityRouteProviderSubscriber
arguments
:
[
'
@entity.manager'
]
tags
:
-
{
name
:
event_subscriber
}
entity.definitions.installed
:
entity.definitions.installed
:
class
:
Drupal\Core\KeyValueStore\KeyValueStoreInterface
class
:
Drupal\Core\KeyValueStore\KeyValueStoreInterface
factory_method
:
get
factory_method
:
get
...
...
core/lib/Drupal/Core/Entity/EntityManager.php
View file @
1601b088
...
@@ -300,6 +300,20 @@ public function getFormObject($entity_type, $operation) {
...
@@ -300,6 +300,20 @@ public function getFormObject($entity_type, $operation) {
return
$this
->
handlers
[
'form'
][
$operation
][
$entity_type
];
return
$this
->
handlers
[
'form'
][
$operation
][
$entity_type
];
}
}
/**
* {@inheritdoc}
*/
public
function
getRouteProviders
(
$entity_type
)
{
if
(
!
isset
(
$this
->
handlers
[
'route_provider'
][
$entity_type
]))
{
$route_provider_classes
=
$this
->
getDefinition
(
$entity_type
,
TRUE
)
->
getRouteProviderClasses
();
foreach
(
$route_provider_classes
as
$type
=>
$class
)
{
$this
->
handlers
[
'route_provider'
][
$entity_type
][
$type
]
=
$this
->
createHandlerInstance
(
$class
,
$this
->
getDefinition
(
$entity_type
));
}
}
return
isset
(
$this
->
handlers
[
'route_provider'
][
$entity_type
])
?
$this
->
handlers
[
'route_provider'
][
$entity_type
]
:
[];
}
/**
/**
* {@inheritdoc}
* {@inheritdoc}
*/
*/
...
...
core/lib/Drupal/Core/Entity/EntityManagerInterface.php
View file @
1601b088
...
@@ -223,6 +223,16 @@ public function getListBuilder($entity_type);
...
@@ -223,6 +223,16 @@ public function getListBuilder($entity_type);
*/
*/
public
function
getFormObject
(
$entity_type
,
$operation
);
public
function
getFormObject
(
$entity_type
,
$operation
);
/**
* Gets all route provider instances.
*
* @param string $entity_type
* The entity type for this route providers.
*
* @return \Drupal\Core\Entity\Routing\EntityRouteProviderInterface[]
*/
public
function
getRouteProviders
(
$entity_type
);
/**
/**
* Checks whether a certain entity type has a certain handler.
* Checks whether a certain entity type has a certain handler.
*
*
...
...
core/lib/Drupal/Core/Entity/EntityType.php
View file @
1601b088
...
@@ -433,6 +433,13 @@ public function hasFormClasses() {
...
@@ -433,6 +433,13 @@ public function hasFormClasses() {
return
!
empty
(
$this
->
handlers
[
'form'
]);
return
!
empty
(
$this
->
handlers
[
'form'
]);
}
}
/**
* {@inheritdoc}
*/
public
function
hasRouteProviders
()
{
return
!
empty
(
$this
->
handlers
[
'route_provider'
]);
}
/**
/**
* {@inheritdoc}
* {@inheritdoc}
*/
*/
...
@@ -477,6 +484,13 @@ public function hasViewBuilderClass() {
...
@@ -477,6 +484,13 @@ public function hasViewBuilderClass() {
return
$this
->
hasHandlerClass
(
'view_builder'
);
return
$this
->
hasHandlerClass
(
'view_builder'
);
}
}
/**
* {@inheritdoc}
*/
public
function
getRouteProviderClasses
()
{
return
!
empty
(
$this
->
handlers
[
'route_provider'
])
?
$this
->
handlers
[
'route_provider'
]
:
[];
}
/**
/**
* {@inheritdoc}
* {@inheritdoc}
*/
*/
...
...
core/lib/Drupal/Core/Entity/EntityTypeInterface.php
View file @
1601b088
...
@@ -225,6 +225,10 @@ public function getHandlerClass($handler_type);
...
@@ -225,6 +225,10 @@ public function getHandlerClass($handler_type);
* - access: The name of the class that is used for access checks. The class
* - access: The name of the class that is used for access checks. The class
* must implement \Drupal\Core\Entity\EntityAccessControlHandlerInterface.
* must implement \Drupal\Core\Entity\EntityAccessControlHandlerInterface.
* Defaults to \Drupal\Core\Entity\EntityAccessControlHandler.
* Defaults to \Drupal\Core\Entity\EntityAccessControlHandler.
* - route_provider: (optional) A list of class names, keyed by a group
* string, which will be used to define routes related to this entity
* type. These classes must implement
* \Drupal\Core\Entity\Routing\EntityRouteProviderInterface.
*/
*/
public
function
getHandlerClasses
();
public
function
getHandlerClasses
();
...
@@ -282,6 +286,22 @@ public function setFormClass($operation, $class);
...
@@ -282,6 +286,22 @@ public function setFormClass($operation, $class);
*/
*/
public
function
hasFormClasses
();
public
function
hasFormClasses
();
/**
* Indicates if this entity type has any route provider.
*
* @return bool
*/
public
function
hasRouteProviders
();
/**
* Gets all the route provide handlers.
*
* Much like forms you can define multiple route provider handlers.
*
* @return string[]
*/
public
function
getRouteProviderClasses
();
/**
/**
* Returns the list class.
* Returns the list class.
*
*
...
...
core/lib/Drupal/Core/Entity/Routing/EntityRouteProviderInterface.php
0 → 100644
View file @
1601b088
<?php
/**
* @file
* Contains \Drupal\Core\Entity\Routing\EntityRouteProviderInterface.
*/
namespace
Drupal\Core\Entity\Routing
;
use
Drupal\Core\Entity\EntityTypeInterface
;
/**
* Allows entity types to provide routes.
*/
interface
EntityRouteProviderInterface
{
/**
* Provides routes for entities.
*
* @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
* The entity type
*
* @return \Symfony\Component\Routing\RouteCollection|\Symfony\Component\Routing\Route[]
* Returns a route collection or an array of routes keyed by name, like
* route_callbacks inside 'routing.yml' files.
*/
public
function
getRoutes
(
EntityTypeInterface
$entity_type
);
}
core/lib/Drupal/Core/EventSubscriber/EntityRouteProviderSubscriber.php
0 → 100644
View file @
1601b088
<?php
/**
* @file
* Contains \Drupal\Core\EventSubscriber\EntityRouteProviderSubscriber.
*/
namespace
Drupal\Core\EventSubscriber
;
use
Drupal\Core\Entity\EntityManagerInterface
;
use
Drupal\Core\Routing\RouteBuildEvent
;
use
Drupal\Core\Routing\RoutingEvents
;
use
Symfony\Component\EventDispatcher\EventSubscriberInterface
;
use
Symfony\Component\Routing\RouteCollection
;
/**
* Ensures that routes can be provided by entity types.
*/
class
EntityRouteProviderSubscriber
implements
EventSubscriberInterface
{
/**
* The entity manager.
*
* @var \Drupal\Core\Entity\EntityManagerInterface
*/
protected
$entityManager
;
/**
* Constructs a new EntityRouteProviderSubscriber instance.
*
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
* The entity manager.
*/
public
function
__construct
(
EntityManagerInterface
$entity_manager
)
{
$this
->
entityManager
=
$entity_manager
;
}
/**
* Provides routes on route rebuild time.
*
* @param \Drupal\Core\Routing\RouteBuildEvent $event
* The route build event.
*/
public
function
onDynamicRouteEvent
(
RouteBuildEvent
$event
)
{
$route_collection
=
$event
->
getRouteCollection
();
foreach
(
$this
->
entityManager
->
getDefinitions
()
as
$entity_type
)
{
if
(
$entity_type
->
hasRouteProviders
())
{
foreach
(
$this
->
entityManager
->
getRouteProviders
(
$entity_type
->
id
())
as
$route_provider
)
{
// Allow to both return an array of routes or a route collection,
// like route_callbacks in the routing.yml file.
$routes
=
$route_provider
->
getRoutes
(
$entity_type
);
if
(
$routes
instanceof
RouteCollection
)
{
$route_collection
->
addCollection
(
$routes
);
}
elseif
(
is_array
(
$routes
))
{
foreach
(
$routes
as
$route_name
=>
$route
)
{
$route_collection
->
add
(
$route_name
,
$route
);
}
}
}
}
}
}
/**
* {@inheritdoc}
*/
public
static
function
getSubscribedEvents
()
{
$events
[
RoutingEvents
::
DYNAMIC
][]
=
[
'onDynamicRouteEvent'
];
return
$events
;
}
}
core/modules/node/node.routing.yml
View file @
1601b088
...
@@ -5,15 +5,6 @@ node.multiple_delete_confirm:
...
@@ -5,15 +5,6 @@ node.multiple_delete_confirm:
requirements
:
requirements
:
_permission
:
'
administer
nodes'
_permission
:
'
administer
nodes'
entity.node.edit_form
:
path
:
'
/node/{node}/edit'
defaults
:
_entity_form
:
'
node.edit'
requirements
:
_entity_access
:
'
node.update'
options
:
_node_operation_route
:
TRUE
node.add_page
:
node.add_page
:
path
:
'
/node/add'
path
:
'
/node/add'
defaults
:
defaults
:
...
@@ -48,24 +39,6 @@ entity.node.preview:
...
@@ -48,24 +39,6 @@ entity.node.preview:
node_preview
:
node_preview
:
type
:
'
node_preview'
type
:
'
node_preview'
entity.node.canonical
:
path
:
'
/node/{node}'
defaults
:
_controller
:
'
\Drupal\node\Controller\NodeViewController::view'
_title_callback
:
'
\Drupal\node\Controller\NodeViewController::title'
requirements
:
_entity_access
:
'
node.view'
entity.node.delete_form
:
path
:
'
/node/{node}/delete'
defaults
:
_entity_form
:
'
node.delete'
_title
:
'
Delete'
requirements
:
_entity_access
:
'
node.delete'
options
:
_node_operation_route
:
TRUE
entity.node.version_history
:
entity.node.version_history
:
path
:
'
/node/{node}/revisions'
path
:
'
/node/{node}/revisions'
defaults
:
defaults
:
...
...
core/modules/node/src/Entity/Node.php
View file @
1601b088
...
@@ -34,6 +34,9 @@
...
@@ -34,6 +34,9 @@
* "delete" = "Drupal\node\Form\NodeDeleteForm",
* "delete" = "Drupal\node\Form\NodeDeleteForm",
* "edit" = "Drupal\node\NodeForm"
* "edit" = "Drupal\node\NodeForm"
* },
* },
* "route_provider" = {
* "html" = "Drupal\node\Entity\NodeRouteProvider",
* },
* "list_builder" = "Drupal\node\NodeListBuilder",
* "list_builder" = "Drupal\node\NodeListBuilder",
* "translation" = "Drupal\node\NodeTranslationHandler"
* "translation" = "Drupal\node\NodeTranslationHandler"
* },
* },
...
...
core/modules/node/src/Entity/NodeRouteProvider.php
0 → 100644
View file @
1601b088
<?php
/**
* @file
* Contains \Drupal\node\Entity\NodeRouteProvider.
*/
namespace
Drupal\node\Entity
;
use
Drupal\Core\Entity\EntityTypeInterface
;
use
Drupal\Core\Entity\Routing\EntityRouteProviderInterface
;
use
Symfony\Component\Routing\Route
;
use
Symfony\Component\Routing\RouteCollection
;
/**
* Provides routes for nodes.
*/
class
NodeRouteProvider
implements
EntityRouteProviderInterface
{
/**
* {@inheritdoc}
*/
public
function
getRoutes
(
EntityTypeInterface
$entity_type
)
{
$route_collection
=
new
RouteCollection
();
$route
=
(
new
Route
(
'/node/{node}'
))
->
addDefaults
([
'_controller'
=>
'\Drupal\node\Controller\NodeViewController::view'
,
'_title_callback'
=>
'\Drupal\node\Controller\NodeViewController::title'
,
])
->
setRequirement
(
'_entity_access'
,
'node.view'
);
$route_collection
->
add
(
'entity.node.canonical'
,
$route
);
$route
=
(
new
Route
(
'/node/{node}/delete'
))
->
addDefaults
([
'_entity_form'
=>
'node.delete'
,
'_title'
=>
'Delete'
,
])
->
setRequirement
(
'_entity_access'
,
'node.delete'
)
->
setOption
(
'_node_operation_route'
,
TRUE
);
$route_collection
->
add
(
'entity.node.delete_form'
,
$route
);
$route
=
(
new
Route
(
'/node/{node}/edit'
))
->
setDefault
(
'_entity_form'
,
'node.edit'
)
->
setRequirement
(
'_entity_access'
,
'node.update'
)
->
setOption
(
'_node_operation_route'
,
TRUE
);
$route_collection
->
add
(
'entity.node.edit_form'
,
$route
);
return
$route_collection
;
}
}
core/modules/user/src/Entity/User.php
View file @
1601b088
...
@@ -30,6 +30,9 @@
...
@@ -30,6 +30,9 @@
* "list_builder" = "Drupal\user\UserListBuilder",
* "list_builder" = "Drupal\user\UserListBuilder",
* "view_builder" = "Drupal\Core\Entity\EntityViewBuilder",
* "view_builder" = "Drupal\Core\Entity\EntityViewBuilder",
* "views_data" = "Drupal\user\UserViewsData",
* "views_data" = "Drupal\user\UserViewsData",
* "route_provider" = {
* "html" = "Drupal\user\Entity\UserRouteProvider",
* },
* "form" = {
* "form" = {
* "default" = "Drupal\user\ProfileForm",
* "default" = "Drupal\user\ProfileForm",
* "cancel" = "Drupal\user\Form\UserCancelForm",
* "cancel" = "Drupal\user\Form\UserCancelForm",
...
...
core/modules/user/src/Entity/UserRouteProvider.php
0 → 100644
View file @
1601b088
<?php
/**
* @file
* Contains \Drupal\user\Entity\UserRouteProvider.
*/
namespace
Drupal\user\Entity
;
use
Drupal\Core\Entity\EntityTypeInterface
;
use
Drupal\Core\Entity\Routing\EntityRouteProviderInterface
;
use
Symfony\Component\Routing\Route
;
use
Symfony\Component\Routing\RouteCollection
;
/**
* Provides routes for the user entity.
*/
class
UserRouteProvider
implements
EntityRouteProviderInterface
{
/**
* {@inheritdoc}
*/
public
function
getRoutes
(
EntityTypeInterface
$entity_type
)
{
$route_collection
=
new
RouteCollection
();
$route
=
(
new
Route
(
'/user/{user}'
))
->
setDefaults
([
'_entity_view'
=>
'user.full'
,
'_title_callback'
=>
'Drupal\user\Controller\UserController::userTitle'
,
])
->
setRequirement
(
'_entity_access'
,
'user.view'
);
$route_collection
->
add
(
'entity.user.canonical'
,
$route
);
$route
=
(
new
Route
(
'/user/{user}/edit'
))
->
setDefaults
([
'_entity_form'
=>
'user.default'
,
'_title_callback'
=>
'Drupal\user\Controller\UserController::userTitle'
,
])
->
setOption
(
'_admin_route'
,
TRUE
)
->
setRequirement
(
'_entity_access'
,
'user.update'
);
$route_collection
->
add
(
'entity.user.edit_form'
,
$route
);
$route
=
(
new
Route
(
'/user/{user}/cancel'
))
->
setDefaults
([
'_title'
=>
'Cancel account'
,
'_entity_form'
=>
'user.cancel'
,
])
->
setOption
(
'_admin_route'
,
TRUE
)
->
setRequirement
(
'_entity_access'
,
'user.delete'
);
$route_collection
->
add
(
'entity.user.cancel_form'
,
$route
);
return
$route_collection
;
}
}
core/modules/user/user.routing.yml
View file @
1601b088
...
@@ -133,14 +133,6 @@ user.page:
...
@@ -133,14 +133,6 @@ user.page:
requirements
:
requirements
:
_user_is_logged_in
:
'
TRUE'
_user_is_logged_in
:
'
TRUE'
entity.user.canonical
:
path
:
'
/user/{user}'
defaults
:
_entity_view
:
'
user.full'
_title_callback
:
'
Drupal\user\Controller\UserController::userTitle'
requirements
:
_entity_access
:
'
user.view'
user.login
:
user.login
:
path
:
'
/user/login'
path
:
'
/user/login'
defaults
:
defaults
:
...
@@ -151,26 +143,6 @@ user.login:
...
@@ -151,26 +143,6 @@ user.login:
options
:
options
:
_maintenance_access
:
TRUE
_maintenance_access
:
TRUE
entity.user.edit_form
:
path
:
'
/user/{user}/edit'
defaults
:
_entity_form
:
'
user.default'
_title_callback
:
'
Drupal\user\Controller\UserController::userTitle'
options
:
_admin_route
:
TRUE
requirements
:
_entity_access
:
'
user.update'
entity.user.cancel_form
:
path
:
'
/user/{user}/cancel'
defaults
:
_title
:
'
Cancel
account'
_entity_form
:
'
user.cancel'
options
:
_admin_route
:
TRUE
requirements
:
_entity_access
:
'
user.delete'
user.cancel_confirm
:
user.cancel_confirm
:
path
:
'
/user/{user}/cancel/confirm/{timestamp}/{hashed_pass}'
path
:
'
/user/{user}/cancel/confirm/{timestamp}/{hashed_pass}'
defaults
:
defaults
:
...
...
core/tests/Drupal/Tests/Core/Entity/EntityManagerTest.php
View file @
1601b088
...
@@ -1366,6 +1366,24 @@ public function testGetEntityTypeFromClassAmbiguous() {
...
@@ -1366,6 +1366,24 @@ public function testGetEntityTypeFromClassAmbiguous() {
$this
->
entityManager
->
getEntityTypeFromClass
(
'\Drupal\apple\Entity\Apple'
);
$this
->
entityManager
->
getEntityTypeFromClass
(
'\Drupal\apple\Entity\Apple'
);
}
}
/**
* @covers ::getRouteProviders
*/
public
function
testGetRouteProviders
()
{
$apple
=
$this
->
getMock
(
'Drupal\Core\Entity\EntityTypeInterface'
);
$apple
->
expects
(
$this
->
once
())
->
method
(
'getRouteProviderClasses'
)
->
willReturn
([
'default'
=>
'Drupal\Tests\Core\Entity\TestRouteProvider'
]);
$this
->
setUpEntityManager
(
array
(
'apple'
=>
$apple
,
));
$apple_route_provider
=
$this
->
entityManager
->
getRouteProviders
(
'apple'
);
$this
->
assertInstanceOf
(
'Drupal\Tests\Core\Entity\TestRouteProvider'
,
$apple_route_provider
[
'default'
]);
$this
->
assertAttributeInstanceOf
(
'Drupal\Core\Extension\ModuleHandlerInterface'
,
'moduleHandler'
,
$apple_route_provider
[
'default'
]);
$this
->
assertAttributeInstanceOf
(
'Drupal\Core\StringTranslation\TranslationInterface'
,
'stringTranslation'
,
$apple_route_provider
[
'default'
]);
}
/**
/**
* Gets a mock controller class name.
* Gets a mock controller class name.
*
*
...
@@ -1546,6 +1564,14 @@ public static function create(ContainerInterface $container) {
...
@@ -1546,6 +1564,14 @@ public static function create(ContainerInterface $container) {
}
}
/**
* Provides a test entity route provider.
*/
class
TestRouteProvider
extends
EntityHandlerBase
{
}
/**
/**
* Provides a test config entity storage for base field overrides.
* Provides a test config entity storage for base field overrides.
*/
*/
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment