Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
D
drupal
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Custom Issue Tracker
Custom Issue Tracker
Labels
Merge Requests
310
Merge Requests
310
Requirements
Requirements
List
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Analytics
Analytics
Code Review
Insights
Issue
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
project
drupal
Commits
5f67fd1d
Commit
5f67fd1d
authored
Jun 20, 2013
by
Dries
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Issue
#1893820
by fago, das-peter, Berdir: Manage entity field definitions in the entity manager.
parent
98b6331e
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
202 additions
and
138 deletions
+202
-138
core/core.services.yml
core/core.services.yml
+1
-1
core/includes/entity.api.php
core/includes/entity.api.php
+18
-18
core/lib/Drupal/Core/Config/Entity/ConfigStorageController.php
...lib/Drupal/Core/Config/Entity/ConfigStorageController.php
+3
-2
core/lib/Drupal/Core/Entity/DatabaseStorageController.php
core/lib/Drupal/Core/Entity/DatabaseStorageController.php
+2
-72
core/lib/Drupal/Core/Entity/DatabaseStorageControllerNG.php
core/lib/Drupal/Core/Entity/DatabaseStorageControllerNG.php
+1
-1
core/lib/Drupal/Core/Entity/EntityManager.php
core/lib/Drupal/Core/Entity/EntityManager.php
+167
-2
core/lib/Drupal/Core/Entity/EntityNG.php
core/lib/Drupal/Core/Entity/EntityNG.php
+2
-4
core/lib/Drupal/Core/Entity/EntityStorageControllerInterface.php
...b/Drupal/Core/Entity/EntityStorageControllerInterface.php
+7
-37
core/lib/Drupal/Core/Entity/Field/Type/EntityWrapper.php
core/lib/Drupal/Core/Entity/Field/Type/EntityWrapper.php
+1
-1
No files found.
core/core.services.yml
View file @
5f67fd1d
...
...
@@ -150,7 +150,7 @@ services:
-
{
name
:
persist
}
plugin.manager.entity
:
class
:
Drupal\Core\Entity\EntityManager
arguments
:
[
'
@container.namespaces'
,
'
@service_container'
]
arguments
:
[
'
@container.namespaces'
,
'
@service_container'
,
'
@module_handler'
,
'
@cache.cache'
,
'
@language_manager'
]
plugin.manager.archiver
:
class
:
Drupal\Core\Archiver\ArchiverManager
arguments
:
[
'
@container.namespaces'
,
'
@cache.cache'
,
'
@language_manager'
,
'
@module_handler'
]
...
...
core/includes/entity.api.php
View file @
5f67fd1d
...
...
@@ -473,26 +473,26 @@ function hook_entity_form_display_alter(\Drupal\entity\Plugin\Core\Entity\Entity
}
/**
* Define custom entity
propertie
s.
* Define custom entity
field
s.
*
* @param string $entity_type
* The entity type for which to define entity
propertie
s.
* The entity type for which to define entity
field
s.
*
* @return array
* An array of property information having the following optional entries:
* - definitions: An array of property definitions to add all entities of this
* type, keyed by property name. See
* Drupal\Core\TypedData\TypedDataManager::create() for a list of supported
* keys in property definitions.
* - optional: An array of property definitions for optional properties keyed
* by property name. Optional properties are properties that only exist for
* certain bundles of the entity type.
* - bundle map: An array keyed by bundle name containing the names of
* optional properties that entities of this bundle have.
*
* @see Drupal\Core\TypedData\TypedDataManager::create()
* An array of entity field information having the following optional entries:
* - definitions: An array of field definitions to add all entities of this
* type, keyed by field name. See
* \Drupal\Core\Entity\EntityManager::getFieldDefinitions() for a list of
* supported keys in field definitions.
* - optional: An array of field definitions for optional entity fields, keyed
* by field name. Optional fields are fields that only exist for certain
* bundles of the entity type.
* - bundle map: An array keyed by bundle name, containing the names of
* optional fields that entities of this bundle have.
*
* @see hook_entity_field_info_alter()
* @see Drupal\Core\Entity\StorageControllerInterface::getPropertyDefinitions()
* @see \Drupal\Core\Entity\EntityManager::getFieldDefinitions()
* @see \Drupal\Core\TypedData\TypedDataManager::create()
*/
function
hook_entity_field_info
(
$entity_type
)
{
if
(
mymodule_uses_entity_type
(
$entity_type
))
{
...
...
@@ -521,12 +521,12 @@ function hook_entity_field_info($entity_type) {
}
/**
* Alter defined entity
propertie
s.
* Alter defined entity
field
s.
*
* @param array $info
* The
property
info array as returned by hook_entity_field_info().
* The
entity field
info array as returned by hook_entity_field_info().
* @param string $entity_type
* The entity type for which entity
propertie
s are defined.
* The entity type for which entity
field
s are defined.
*
* @see hook_entity_field_info()
*/
...
...
core/lib/Drupal/Core/Config/Entity/ConfigStorageController.php
View file @
5f67fd1d
...
...
@@ -401,9 +401,10 @@ public function save(EntityInterface $entity) {
}
/**
*
Implements Drupal\Core\Entity\EntityStorageControllerInterface::getFieldDefinitions().
*
{@inheritdoc}
*/
public
function
getFieldDefinitions
(
array
$constraints
)
{
public
function
baseFieldDefinitions
()
{
// @todo: Define abstract once all entity types have been converted.
return
array
();
}
...
...
core/lib/Drupal/Core/Entity/DatabaseStorageController.php
View file @
5f67fd1d
...
...
@@ -26,22 +26,6 @@
*/
class
DatabaseStorageController
extends
EntityStorageControllerBase
{
/**
* An array of field information, i.e. containing definitions.
*
* @var array
*
* @see hook_entity_field_info()
*/
protected
$entityFieldInfo
;
/**
* Static cache of field definitions per bundle.
*
* @var array
*/
protected
$fieldDefinitions
;
/**
* Name of entity's revision database table field, if it supports revisions.
*
...
...
@@ -555,64 +539,10 @@ protected function invokeHook($hook, EntityInterface $entity) {
}
/**
* Implements \Drupal\Core\Entity\EntityStorageControllerInterface::getFieldDefinitions().
*/
public
function
getFieldDefinitions
(
array
$constraints
)
{
if
(
!
isset
(
$this
->
entityFieldInfo
))
{
// First, try to load from cache.
$cid
=
'entity_field_definitions:'
.
$this
->
entityType
.
':'
.
language
(
Language
::
TYPE_INTERFACE
)
->
langcode
;
if
(
$cache
=
cache
()
->
get
(
$cid
))
{
$this
->
entityFieldInfo
=
$cache
->
data
;
}
else
{
$this
->
entityFieldInfo
=
array
(
'definitions'
=>
$this
->
baseFieldDefinitions
(),
// Contains definitions of optional (per-bundle) fields.
'optional'
=>
array
(),
// An array keyed by bundle name containing the optional fields added
// by the bundle.
'bundle map'
=>
array
(),
);
// Invoke hooks.
$result
=
module_invoke_all
(
$this
->
entityType
.
'_property_info'
);
$this
->
entityFieldInfo
=
NestedArray
::
mergeDeep
(
$this
->
entityFieldInfo
,
$result
);
$result
=
module_invoke_all
(
'entity_field_info'
,
$this
->
entityType
);
$this
->
entityFieldInfo
=
NestedArray
::
mergeDeep
(
$this
->
entityFieldInfo
,
$result
);
$hooks
=
array
(
'entity_field_info'
,
$this
->
entityType
.
'_property_info'
);
drupal_alter
(
$hooks
,
$this
->
entityFieldInfo
,
$this
->
entityType
);
// Enforce fields to be multiple by default.
foreach
(
$this
->
entityFieldInfo
[
'definitions'
]
as
&
$definition
)
{
$definition
[
'list'
]
=
TRUE
;
}
foreach
(
$this
->
entityFieldInfo
[
'optional'
]
as
&
$definition
)
{
$definition
[
'list'
]
=
TRUE
;
}
cache
()
->
set
(
$cid
,
$this
->
entityFieldInfo
,
CacheBackendInterface
::
CACHE_PERMANENT
,
array
(
'entity_info'
=>
TRUE
));
}
}
$bundle
=
!
empty
(
$constraints
[
'Bundle'
])
?
$constraints
[
'Bundle'
]
:
FALSE
;
// Add in per-bundle fields.
if
(
!
isset
(
$this
->
fieldDefinitions
[
$bundle
]))
{
$this
->
fieldDefinitions
[
$bundle
]
=
$this
->
entityFieldInfo
[
'definitions'
];
if
(
$bundle
&&
isset
(
$this
->
entityFieldInfo
[
'bundle map'
][
$bundle
]))
{
$this
->
fieldDefinitions
[
$bundle
]
+=
array_intersect_key
(
$this
->
entityFieldInfo
[
'optional'
],
array_flip
(
$this
->
entityFieldInfo
[
'bundle map'
][
$bundle
]));
}
}
return
$this
->
fieldDefinitions
[
$bundle
];
}
/**
* Defines the base properties of the entity type.
*
* @todo: Define abstract once all entity types have been converted.
* {@inheritdoc}
*/
public
function
baseFieldDefinitions
()
{
// @todo: Define abstract once all entity types have been converted.
return
array
();
}
...
...
core/lib/Drupal/Core/Entity/DatabaseStorageControllerNG.php
View file @
5f67fd1d
...
...
@@ -309,7 +309,7 @@ protected function attachPropertyData(array &$entities, $revision_id = FALSE) {
}
$data
=
$query
->
execute
();
$field_definition
=
$this
->
getFieldDefinitions
(
array
()
);
$field_definition
=
\
Drupal
::
entityManager
()
->
getFieldDefinitions
(
$this
->
entityType
);
if
(
$this
->
revisionTable
)
{
$data_fields
=
array_flip
(
array_diff
(
drupal_schema_fields_sql
(
$this
->
entityInfo
[
'revision_table'
]),
drupal_schema_fields_sql
(
$this
->
entityInfo
[
'base_table'
])));
}
...
...
core/lib/Drupal/Core/Entity/EntityManager.php
View file @
5f67fd1d
...
...
@@ -9,6 +9,9 @@
use
Drupal\Component\Plugin\PluginManagerBase
;
use
Drupal\Component\Plugin\Factory\DefaultFactory
;
use
Drupal\Component\Utility\NestedArray
;
use
Drupal\Core\Extension\ModuleHandlerInterface
;
use
Drupal\Core\Language\LanguageManager
;
use
Drupal\Core\Language\Language
;
use
Drupal\Core\Plugin\Discovery\AlterDecorator
;
use
Drupal\Core\Plugin\Discovery\CacheDecorator
;
...
...
@@ -47,6 +50,43 @@ class EntityManager extends PluginManagerBase {
*/
protected
$controllers
=
array
();
/**
* The module handler.
*
* @var \Drupal\Core\Extension\ModuleHandlerInterface
*/
protected
$moduleHandler
;
/**
* The cache backend to use.
*
* @var \Drupal\Core\Cache\CacheBackendInterface
*/
protected
$cache
;
/**
* The language manager.
*
* @var \Drupal\Core\Language\LanguageManager
*/
protected
$languageManager
;
/**
* An array of field information per entity type, i.e. containing definitions.
*
* @var array
*
* @see hook_entity_field_info()
*/
protected
$entityFieldInfo
;
/**
* Static cache of field definitions per bundle and entity type.
*
* @var array
*/
protected
$fieldDefinitions
;
/**
* Constructs a new Entity plugin manager.
*
...
...
@@ -55,16 +95,27 @@ class EntityManager extends PluginManagerBase {
* keyed by the corresponding namespace to look for plugin implementations,
* @param \Symfony\Component\DependencyInjection\ContainerInterface $container
* The service container this object should use.
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
* The module handler.
* @param \Drupal\Core\Cache\CacheBackendInterface $cache
* The cache backend to use.
* @param \Drupal\Core\Language\LanguageManager $language_manager
* The language manager.
*/
public
function
__construct
(
\
Traversable
$namespaces
,
ContainerInterface
$container
)
{
public
function
__construct
(
\
Traversable
$namespaces
,
ContainerInterface
$container
,
ModuleHandlerInterface
$module_handler
,
CacheBackendInterface
$cache
,
LanguageManager
$language_manager
)
{
// Allow the plugin definition to be altered by hook_entity_info_alter().
$annotation_namespaces
=
array
(
'Drupal\Core\Entity\Annotation'
=>
DRUPAL_ROOT
.
'/core/lib'
,
);
$this
->
moduleHandler
=
$module_handler
;
$this
->
cache
=
$cache
;
$this
->
languageManager
=
$language_manager
;
$this
->
discovery
=
new
AnnotatedClassDiscovery
(
'Core/Entity'
,
$namespaces
,
$annotation_namespaces
,
'Drupal\Core\Entity\Annotation\EntityType'
);
$this
->
discovery
=
new
InfoHookDecorator
(
$this
->
discovery
,
'entity_info'
);
$this
->
discovery
=
new
AlterDecorator
(
$this
->
discovery
,
'entity_info'
);
$this
->
discovery
=
new
CacheDecorator
(
$this
->
discovery
,
'entity_info:'
.
l
anguage
(
Language
::
TYPE_INTERFACE
)
->
langcode
,
'cache'
,
CacheBackendInterface
::
CACHE_PERMANENT
,
array
(
'entity_info'
=>
TRUE
));
$this
->
discovery
=
new
CacheDecorator
(
$this
->
discovery
,
'entity_info:'
.
$this
->
languageManager
->
getL
anguage
(
Language
::
TYPE_INTERFACE
)
->
langcode
,
'cache'
,
CacheBackendInterface
::
CACHE_PERMANENT
,
array
(
'entity_info'
=>
TRUE
));
$this
->
factory
=
new
DefaultFactory
(
$this
->
discovery
);
$this
->
container
=
$container
;
...
...
@@ -289,4 +340,118 @@ public function getAdminPath($entity_type, $bundle) {
return
$admin_path
;
}
/**
* Gets an array of entity field definitions.
*
* If a bundle is passed, fields specific to this bundle are included. Entity
* fields are always multi-valued, so 'list' is TRUE for each returned field
* definition.
*
* @param string $entity_type
* The entity type to get field definitions for.
* @param string $bundle
* (optional) The entity bundle for which to get field definitions. If NULL
* is passed, no bundle-specific fields are included. Defaults to NULL.
*
* @return array
* An array of field definitions of entity fields, keyed by field
* name. In addition to the typed data definition keys as described at
* \Drupal\Core\TypedData\TypedDataManager::create() the following keys are
* supported:
* - queryable: Whether the field is queryable via QueryInterface.
* Defaults to TRUE if 'computed' is FALSE or not set, to FALSE otherwise.
* - translatable: Whether the field is translatable. Defaults to FALSE.
* - configurable: A boolean indicating whether the field is configurable
* via field.module. Defaults to FALSE.
*
* @see \Drupal\Core\TypedData\TypedDataManager::create()
* @see \Drupal\Core\Entity\EntityManager::getFieldDefinitionsByConstraints()
*/
public
function
getFieldDefinitions
(
$entity_type
,
$bundle
=
NULL
)
{
if
(
!
isset
(
$this
->
entityFieldInfo
[
$entity_type
]))
{
// First, try to load from cache.
$cid
=
'entity_field_definitions:'
.
$entity_type
.
':'
.
$this
->
languageManager
->
getLanguage
(
Language
::
TYPE_INTERFACE
)
->
langcode
;
if
(
$cache
=
$this
->
cache
->
get
(
$cid
))
{
$this
->
entityFieldInfo
[
$entity_type
]
=
$cache
->
data
;
}
else
{
$this
->
entityFieldInfo
[
$entity_type
]
=
array
(
'definitions'
=>
$this
->
getStorageController
(
$entity_type
)
->
baseFieldDefinitions
(),
// Contains definitions of optional (per-bundle) fields.
'optional'
=>
array
(),
// An array keyed by bundle name containing the optional fields added
// by the bundle.
'bundle map'
=>
array
(),
);
// Invoke hooks.
$result
=
$this
->
moduleHandler
->
invokeAll
(
$entity_type
.
'_field_info'
);
$this
->
entityFieldInfo
[
$entity_type
]
=
NestedArray
::
mergeDeep
(
$this
->
entityFieldInfo
[
$entity_type
],
$result
);
$result
=
$this
->
moduleHandler
->
invokeAll
(
'entity_field_info'
,
array
(
$entity_type
));
$this
->
entityFieldInfo
[
$entity_type
]
=
NestedArray
::
mergeDeep
(
$this
->
entityFieldInfo
[
$entity_type
],
$result
);
$hooks
=
array
(
'entity_field_info'
,
$entity_type
.
'_field_info'
);
$this
->
moduleHandler
->
alter
(
$hooks
,
$this
->
entityFieldInfo
[
$entity_type
],
$entity_type
);
// Enforce fields to be multiple by default.
foreach
(
$this
->
entityFieldInfo
[
$entity_type
][
'definitions'
]
as
&
$definition
)
{
$definition
[
'list'
]
=
TRUE
;
}
foreach
(
$this
->
entityFieldInfo
[
$entity_type
][
'optional'
]
as
&
$definition
)
{
$definition
[
'list'
]
=
TRUE
;
}
$this
->
cache
->
set
(
$cid
,
$this
->
entityFieldInfo
[
$entity_type
],
CacheBackendInterface
::
CACHE_PERMANENT
,
array
(
'entity_info'
=>
TRUE
,
'entity_field_info'
=>
TRUE
));
}
}
if
(
!
$bundle
)
{
return
$this
->
entityFieldInfo
[
$entity_type
][
'definitions'
];
}
else
{
// Add in per-bundle fields.
if
(
!
isset
(
$this
->
fieldDefinitions
[
$entity_type
][
$bundle
]))
{
$this
->
fieldDefinitions
[
$entity_type
][
$bundle
]
=
$this
->
entityFieldInfo
[
$entity_type
][
'definitions'
];
if
(
isset
(
$this
->
entityFieldInfo
[
$entity_type
][
'bundle map'
][
$bundle
]))
{
$this
->
fieldDefinitions
[
$entity_type
][
$bundle
]
+=
array_intersect_key
(
$this
->
entityFieldInfo
[
$entity_type
][
'optional'
],
array_flip
(
$this
->
entityFieldInfo
[
$entity_type
][
'bundle map'
][
$bundle
]));
}
}
return
$this
->
fieldDefinitions
[
$entity_type
][
$bundle
];
}
}
/**
* Gets an array of entity field definitions based on validation constraints.
*
* @param string $entity_type
* The entity type to get field definitions for.
* @param array $constraints
* An array of entity constraints as used for entities in typed data
* definitions, i.e. an array optionally including a 'Bundle' key.
* For example the constraints used by an entity reference could be:
* @code
* array(
* 'Bundle' => 'article',
* )
* @endcode
*
* @return array
* An array of field definitions of entity fields, keyed by field
* name.
*
* @see \Drupal\Core\Entity\EntityManager::getFieldDefinitions()
*/
public
function
getFieldDefinitionsByConstraints
(
$entity_type
,
array
$constraints
)
{
// @todo: Add support for specifying multiple bundles.
return
$this
->
getFieldDefinitions
(
$entity_type
,
isset
(
$constraints
[
'Bundle'
])
?
$constraints
[
'Bundle'
]
:
NULL
);
}
/**
* Clears static and persistent field definition caches.
*/
public
function
clearCachedFieldDefinitions
()
{
unset
(
$this
->
entityFieldInfo
);
unset
(
$this
->
fieldDefinitions
);
$this
->
cache
->
deleteTags
(
array
(
'entity_field_info'
=>
TRUE
));
}
}
core/lib/Drupal/Core/Entity/EntityNG.php
View file @
5f67fd1d
...
...
@@ -281,10 +281,8 @@ public function getPropertyDefinition($name) {
*/
public
function
getPropertyDefinitions
()
{
if
(
!
isset
(
$this
->
fieldDefinitions
))
{
$this
->
fieldDefinitions
=
\
Drupal
::
entityManager
()
->
getStorageController
(
$this
->
entityType
)
->
getFieldDefinitions
(
array
(
'EntityType'
=>
$this
->
entityType
,
'Bundle'
=>
$this
->
bundle
,
));
$bundle
=
$this
->
bundle
!=
$this
->
entityType
?
$this
->
bundle
:
NULL
;
$this
->
fieldDefinitions
=
\
Drupal
::
entityManager
()
->
getFieldDefinitions
(
$this
->
entityType
,
$bundle
);
}
return
$this
->
fieldDefinitions
;
}
...
...
core/lib/Drupal/Core/Entity/EntityStorageControllerInterface.php
View file @
5f67fd1d
...
...
@@ -126,46 +126,16 @@ public function delete(array $entities);
public
function
save
(
EntityInterface
$entity
);
/**
* Gets an array of entity field definitions.
*
* If a 'bundle' key is present in the given entity definition, fields
* specific to this bundle are included.
* Entity fields are always multi-valued, so 'list' is TRUE for each
* returned field definition.
*
* @param array $constraints
* An array of entity constraints as used for entities in typed data
* definitions, i.e. an array having an 'entity type' and optionally a
* 'bundle' key. For example:
* @code
* array(
* 'EntityType' => 'node',
* 'Bundle' => 'article',
* )
* @endcode
* Defines the base fields of the entity type.
*
* @return array
* An array of field definitions of entity fields, keyed by field
* name. In addition to the typed data definition keys as described at
* \Drupal::typedData()->create() the follow keys are supported:
* - queryable: Whether the field is queryable via QueryInterface.
* Defaults to TRUE if 'computed' is FALSE or not set, to FALSE otherwise.
* - translatable: Whether the field is translatable. Defaults to FALSE.
* - configurable: A boolean indicating whether the field is configurable
* via field.module. Defaults to FALSE.
* - property_constraints: An array of constraint arrays applying to the
* field item properties, keyed by property name. E.g. the following
* validates the value property to have a maximum length of 128:
* @code
* array(
* 'value' => array('Length' => array('max' => 128)),
* )
* @endcode
*
* @see Drupal\Core\TypedData\TypedDataManager::create()
* @see \Drupal::typedData()
* An array of entity field definitions as specified by
* \Drupal\Core\Entity\EntityManager::getFieldDefinitions(), keyed by field
* name.
*
* @see \Drupal\Core\Entity\EntityManager::getFieldDefinitions()
*/
public
function
getFieldDefinitions
(
array
$constraints
);
public
function
baseFieldDefinitions
(
);
/**
* Gets the name of the service for the query for this entity storage.
...
...
core/lib/Drupal/Core/Entity/Field/Type/EntityWrapper.php
View file @
5f67fd1d
...
...
@@ -178,7 +178,7 @@ public function getPropertyDefinition($name) {
*/
public
function
getPropertyDefinitions
()
{
// @todo: Support getting definitions if multiple bundles are specified.
return
\
Drupal
::
entityManager
()
->
get
StorageController
(
$this
->
entityType
)
->
getFieldDefinitions
(
$this
->
definition
[
'constraints'
]);
return
\
Drupal
::
entityManager
()
->
get
FieldDefinitionsByConstraints
(
$this
->
entityType
,
$this
->
definition
[
'constraints'
]);
}
/**
...
...
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