Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
project
drupal
Commits
da026cf5
Commit
da026cf5
authored
May 15, 2014
by
Alex Pott
Browse files
Issue
#2116363
by Berdir, jessebeach | fago: Unified repository of field definitions (cache + API).
parent
8723cb96
Changes
98
Hide whitespace changes
Inline
Side-by-side
core/includes/install.core.inc
View file @
da026cf5
...
...
@@ -965,7 +965,7 @@ function install_base_system(&$install_state) {
// Enable the user module so that sessions can be recorded during the
// upcoming bootstrap step.
\
Drupal
::
moduleHandler
()
->
install
(
array
(
'field'
,
'user'
),
FALSE
);
\
Drupal
::
moduleHandler
()
->
install
(
array
(
'user'
),
FALSE
);
// Save the list of other modules to install for the upcoming tasks.
// State can be set to the database now that system.module is installed.
...
...
core/lib/Drupal/Core/Entity/ContentEntityDatabaseStorage.php
View file @
da026cf5
...
...
@@ -11,7 +11,6 @@
use
Drupal\Core\Entity\Query\QueryInterface
;
use
Drupal\Core\Field\FieldStorageDefinitionInterface
;
use
Drupal\Core\Language\Language
;
use
Drupal\field\FieldInfo
;
use
Drupal\field\FieldConfigUpdateForbiddenException
;
use
Drupal\field\FieldConfigInterface
;
use
Drupal\field\FieldInstanceConfigInterface
;
...
...
@@ -66,11 +65,11 @@ class ContentEntityDatabaseStorage extends ContentEntityStorageBase {
protected
$database
;
/**
* The
field info object
.
* The
entity manager
.
*
* @var \Drupal\
field\FieldInfo
* @var \Drupal\
Core\Entity\EntityManagerInterface
*/
protected
$
fieldInfo
;
protected
$
entityManager
;
/**
* {@inheritdoc}
...
...
@@ -79,7 +78,7 @@ public static function createInstance(ContainerInterface $container, EntityTypeI
return
new
static
(
$entity_type
,
$container
->
get
(
'database'
),
$container
->
get
(
'
field.info
'
)
$container
->
get
(
'
entity.manager
'
)
);
}
...
...
@@ -90,14 +89,14 @@ public static function createInstance(ContainerInterface $container, EntityTypeI
* The entity type definition.
* @param \Drupal\Core\Database\Connection $database
* The database connection to be used.
* @param \Drupal\
field\FieldInfo $field_info
* The
field info service
.
* @param \Drupal\
Core\Entity\EntityManagerInterface $entity_manager
* The
entity manager
.
*/
public
function
__construct
(
EntityTypeInterface
$entity_type
,
Connection
$database
,
FieldInfo
$field_info
)
{
public
function
__construct
(
EntityTypeInterface
$entity_type
,
Connection
$database
,
EntityManagerInterface
$entity_manager
)
{
parent
::
__construct
(
$entity_type
);
$this
->
database
=
$database
;
$this
->
fieldInfo
=
$field_info
;
$this
->
entityManager
=
$entity_manager
;
// Check if the entity type supports UUIDs.
$this
->
uuidKey
=
$this
->
entityType
->
getKey
(
'uuid'
);
...
...
@@ -716,8 +715,10 @@ protected function doLoadFieldItems($entities, $age) {
// Collect impacted fields.
$fields
=
array
();
foreach
(
$bundles
as
$bundle
=>
$v
)
{
foreach
(
$this
->
fieldInfo
->
getBundleInstances
(
$this
->
entityTypeId
,
$bundle
)
as
$field_name
=>
$instance
)
{
$fields
[
$field_name
]
=
$instance
->
getField
();
foreach
(
$this
->
entityManager
->
getFieldDefinitions
(
$this
->
entityTypeId
,
$bundle
)
as
$field_name
=>
$instance
)
{
if
(
$instance
instanceof
FieldInstanceConfigInterface
)
{
$fields
[
$field_name
]
=
$instance
->
getField
();
}
}
}
...
...
@@ -781,7 +782,10 @@ protected function doSaveFieldItems(EntityInterface $entity, $update) {
$vid
=
$id
;
}
foreach
(
$this
->
fieldInfo
->
getBundleInstances
(
$entity_type
,
$bundle
)
as
$field_name
=>
$instance
)
{
foreach
(
$this
->
entityManager
->
getFieldDefinitions
(
$entity_type
,
$bundle
)
as
$field_name
=>
$instance
)
{
if
(
!
(
$instance
instanceof
FieldInstanceConfigInterface
))
{
continue
;
}
$field
=
$instance
->
getField
();
$table_name
=
static
::
_fieldTableName
(
$field
);
$revision_name
=
static
::
_fieldRevisionTableName
(
$field
);
...
...
@@ -855,7 +859,10 @@ protected function doSaveFieldItems(EntityInterface $entity, $update) {
* {@inheritdoc}
*/
protected
function
doDeleteFieldItems
(
EntityInterface
$entity
)
{
foreach
(
$this
->
fieldInfo
->
getBundleInstances
(
$entity
->
getEntityTypeId
(),
$entity
->
bundle
())
as
$instance
)
{
foreach
(
$this
->
entityManager
->
getFieldDefinitions
(
$entity
->
getEntityTypeId
(),
$entity
->
bundle
())
as
$instance
)
{
if
(
!
(
$instance
instanceof
FieldInstanceConfigInterface
))
{
continue
;
}
$field
=
$instance
->
getField
();
$table_name
=
static
::
_fieldTableName
(
$field
);
$revision_name
=
static
::
_fieldRevisionTableName
(
$field
);
...
...
@@ -874,7 +881,10 @@ protected function doDeleteFieldItems(EntityInterface $entity) {
protected
function
doDeleteFieldItemsRevision
(
EntityInterface
$entity
)
{
$vid
=
$entity
->
getRevisionId
();
if
(
isset
(
$vid
))
{
foreach
(
$this
->
fieldInfo
->
getBundleInstances
(
$entity
->
getEntityTypeId
(),
$entity
->
bundle
())
as
$instance
)
{
foreach
(
$this
->
entityManager
->
getFieldDefinitions
(
$entity
->
getEntityTypeId
(),
$entity
->
bundle
())
as
$instance
)
{
if
(
!
(
$instance
instanceof
FieldInstanceConfigInterface
))
{
continue
;
}
$revision_name
=
static
::
_fieldRevisionTableName
(
$instance
->
getField
());
$this
->
database
->
delete
(
$revision_name
)
->
condition
(
'entity_id'
,
$entity
->
id
())
...
...
core/lib/Drupal/Core/Entity/EntityDatabaseStorage.php
View file @
da026cf5
...
...
@@ -39,13 +39,6 @@ class EntityDatabaseStorage extends EntityStorageBase {
*/
protected
$database
;
/**
* The field info object.
*
* @var \Drupal\field\FieldInfo
*/
protected
$fieldInfo
;
/**
* {@inheritdoc}
*/
...
...
core/lib/Drupal/Core/Entity/EntityManager.php
View file @
da026cf5
...
...
@@ -136,6 +136,16 @@ class EntityManager extends PluginManagerBase implements EntityManagerInterface,
*/
protected
$displayModeInfo
=
array
();
/**
* An array keyed by entity type. Each value is an array whose keys are
* field names and whose value is an array with two entries:
* - type: The field type.
* - bundles: The bundles in which the field appears.
*
* @return array
*/
protected
$fieldMap
=
array
();
/**
* Constructs a new Entity plugin manager.
*
...
...
@@ -521,6 +531,35 @@ public function getFieldStorageDefinitions($entity_type_id) {
return
$this
->
fieldStorageDefinitions
[
$entity_type_id
];
}
/**
* {@inheritdoc}
*/
public
function
getFieldMap
()
{
if
(
!
$this
->
fieldMap
)
{
// Not prepared, try to load from cache.
$cid
=
'entity_field_map'
;
if
(
$cache
=
$this
->
cache
->
get
(
$cid
))
{
$this
->
fieldMap
=
$cache
->
data
;
}
else
{
// Rebuild the definitions and put it into the cache.
foreach
(
$this
->
getDefinitions
()
as
$entity_type_id
=>
$entity_type
)
{
if
(
$entity_type
->
isSubclassOf
(
'\Drupal\Core\Entity\ContentEntityInterface'
))
{
foreach
(
$this
->
getBundleInfo
(
$entity_type_id
)
as
$bundle
=>
$bundle_info
)
{
foreach
(
$this
->
getFieldDefinitions
(
$entity_type_id
,
$bundle
)
as
$field_name
=>
$field_definition
)
{
$this
->
fieldMap
[
$entity_type_id
][
$field_name
][
'type'
]
=
$field_definition
->
getType
();
$this
->
fieldMap
[
$entity_type_id
][
$field_name
][
'bundles'
][]
=
$bundle
;
}
}
}
}
$this
->
cache
->
set
(
$cid
,
$this
->
fieldMap
,
Cache
::
PERMANENT
,
array
(
'entity_types'
=>
TRUE
,
'entity_field_info'
=>
TRUE
));
}
}
return
$this
->
fieldMap
;
}
/**
* Builds field storage definitions for an entity type.
*
...
...
@@ -565,6 +604,7 @@ public function clearCachedFieldDefinitions() {
$this
->
baseFieldDefinitions
=
array
();
$this
->
fieldDefinitions
=
array
();
$this
->
fieldStorageDefinitions
=
array
();
$this
->
fieldMap
=
array
();
Cache
::
deleteTags
(
array
(
'entity_field_info'
=>
TRUE
));
}
...
...
core/lib/Drupal/Core/Entity/EntityManagerInterface.php
View file @
da026cf5
...
...
@@ -80,6 +80,17 @@ public function getFieldDefinitions($entity_type_id, $bundle);
*/
public
function
getFieldStorageDefinitions
(
$entity_type_id
);
/**
* Collects a lightweight map of fields across bundles.
*
* @return array
* An array keyed by entity type. Each value is an array which keys are
* field names and value is an array with two entries:
* - type: The field type.
* - bundles: The bundles in which the field appears.
*/
public
function
getFieldMap
();
/**
* Creates a new access controller instance.
*
...
...
core/lib/Drupal/Core/Entity/Query/Sql/Tables.php
View file @
da026cf5
...
...
@@ -8,12 +8,12 @@
namespace
Drupal\Core\Entity\Query\Sql
;
use
Drupal\Core\Database\Query\SelectInterface
;
use
Drupal\Core\Entity\ContentEntityTypeInterface
;
use
Drupal\Core\Entity\EntityStorageInterface
;
use
Drupal\Core\Entity\ContentEntityDatabaseStorage
;
use
Drupal\Core\Entity\Plugin\DataType\EntityReference
;
use
Drupal\Core\Entity\Query\QueryException
;
use
Drupal\field\Entity\FieldConfig
;
use
Drupal\field\Field
as
FieldInfo
;
use
Drupal\field\Field
ConfigInterface
;
/**
* Adds tables and fields to the SQL entity query.
...
...
@@ -58,7 +58,6 @@ public function __construct(SelectInterface $sql_query) {
public
function
addField
(
$field
,
$type
,
$langcode
)
{
$entity_type_id
=
$this
->
sqlQuery
->
getMetaData
(
'entity_type'
);
$entity_manager
=
\
Drupal
::
entityManager
();
$field_info
=
FieldInfo
::
fieldInfo
();
$age
=
$this
->
sqlQuery
->
getMetaData
(
'age'
);
// This variable ensures grouping works correctly. For example:
// ->condition('tags', 2, '>')
...
...
@@ -75,11 +74,13 @@ public function addField($field, $type, $langcode) {
// system.
$propertyDefinitions
=
array
();
$entity_type
=
$entity_manager
->
getDefinition
(
$entity_type_id
);
// Use the lightweight and fast field map for checking whether a specifier
// is a field or not. While calling field_info_field() on every specifier
// delivers the same information, if no specifiers are using the field API
// it is much faster if field_info_field() is never called.
$field_map
=
$field_info
->
getFieldMap
();
$field_storage_definitions
=
array
();
// @todo Needed for menu links, make this implementation content entity
// specific after https://drupal.org/node/2256521.
if
(
$entity_type
instanceof
ContentEntityTypeInterface
)
{
$field_storage_definitions
=
$entity_manager
->
getFieldStorageDefinitions
(
$entity_type_id
);
}
for
(
$key
=
0
;
$key
<=
$count
;
$key
++
)
{
// If there is revision support and only the current revision is being
// queried then use the revision id. Otherwise, the entity id will do.
...
...
@@ -95,25 +96,27 @@ public function addField($field, $type, $langcode) {
$entity_id_field
=
$entity_type
->
getKey
(
'id'
);
$field_id_field
=
'entity_id'
;
}
// This can either be the name of an entity
property (non-
configurable
// field
), a field API field (a configurable field)
.
// This can either be the name of an entity
base field or a
configurable
// field.
$specifier
=
$specifiers
[
$key
];
// First, check for field API fields by trying to retrieve the field specified.
// Normally it is a field name, but field_purge_batch() is passing in
// id:$field_id so check that first.
/* @var \Drupal\Core\Field\FieldDefinitionInterface $field */
if
(
substr
(
$specifier
,
0
,
3
)
==
'id:'
)
{
$field
=
$field_info
->
getFieldById
((
substr
(
$specifier
,
3
)));
if
(
$fields
=
entity_load_multiple_by_properties
(
'field_config'
,
array
(
'uuid'
=>
substr
(
$specifier
,
3
),
'include_deleted'
=>
TRUE
)))
{
$field
=
current
(
$fields
);
}
}
elseif
(
isset
(
$field_
map
[
$entity_type_id
]
[
$specifier
]))
{
$field
=
$field_
info
->
getField
(
$entity_type_id
,
$specifier
)
;
elseif
(
isset
(
$field_
storage_definitions
[
$specifier
]))
{
$field
=
$field_
storage_definitions
[
$specifier
]
;
}
else
{
$field
=
FALSE
;
}
// If we managed to retrieve
th
e field, process it.
if
(
$field
)
{
// If we managed to retrieve
a configurabl
e field, process it.
if
(
$field
instanceof
FieldConfigInterface
)
{
// Find the field column.
$column
=
FALSE
;
$column
=
$field
->
getMainPropertyName
()
;
if
(
$key
<
$count
)
{
$next
=
$specifiers
[
$key
+
1
];
// Is this a field column?
...
...
@@ -133,39 +136,16 @@ public function addField($field, $type, $langcode) {
// also use the property definitions for column.
if
(
$key
<
$count
)
{
$relationship_specifier
=
$specifiers
[
$key
+
1
];
$propertyDefinitions
=
$field
->
getPropertyDefinitions
();
// Get the field definitions form a mocked entity.
$values
=
array
();
$field_name
=
$field
->
getName
();
// If there are bundles, pick one.
if
(
$bundle_key
=
$entity_type
->
getKey
(
'bundle'
))
{
$values
[
$bundle_key
]
=
reset
(
$field_map
[
$entity_type_id
][
$field_name
][
'bundles'
]);
}
$entity
=
$entity_manager
->
getStorage
(
$entity_type_id
)
->
create
(
$values
);
$propertyDefinitions
=
$entity
->
$field_name
->
getFieldDefinition
()
->
getPropertyDefinitions
();
// If the column is not yet known, ie. the
// $node->field_image->entity case then use first property as
// column, i.e. target_id or fid.
// Otherwise, the code executing the relationship will throw an
// exception anyways so no need to do it here.
if
(
!
$column
&&
isset
(
$propertyDefinitions
[
$relationship_specifier
])
&&
$entity
->
{
$field
->
getName
()}
->
first
()
->
get
(
'entity'
)
instanceof
EntityReference
)
{
$column
=
current
(
array_keys
(
$propertyDefinitions
));
}
// Prepare the next index prefix.
$next_index_prefix
=
"
$relationship_specifier
.
$column
"
;
}
}
else
{
// If this is the last specifier, default to value.
$column
=
'value'
;
}
$table
=
$this
->
ensureFieldTable
(
$index_prefix
,
$field
,
$type
,
$langcode
,
$base_table
,
$entity_id_field
,
$field_id_field
);
$sql_column
=
ContentEntityDatabaseStorage
::
_fieldColumnName
(
$field
,
$column
);
}
// This is an entity
property
(non-configurable field).
// This is an entity
base field
(non-configurable field).
else
{
// ensureEntityTable() decides whether an entity property will be
// queried from the data table or the base table based on where it
...
...
@@ -182,31 +162,20 @@ public function addField($field, $type, $langcode) {
$table
=
$this
->
ensureEntityTable
(
$index_prefix
,
$specifier
,
$type
,
$langcode
,
$base_table
,
$entity_id_field
,
$entity_tables
);
}
// If there are more specifiers to come, it's a relationship.
if
(
$key
<
$count
)
{
if
(
$field
&&
$key
<
$count
)
{
// Computed fields have prepared their property definition already, do
// it for properties as well.
if
(
!
$propertyDefinitions
)
{
// Create a relevant entity to find the definition for this
// property.
$values
=
array
();
// If there are bundles, pick one. It does not matter which,
// properties exist on all bundles.
if
(
$bundle_key
=
$entity_type
->
getKey
(
'bundle'
))
{
$bundles
=
entity_get_bundles
(
$entity_type_id
);
$values
[
$bundle_key
]
=
key
(
$bundles
);
}
$entity
=
$entity_manager
->
getStorage
(
$entity_type_id
)
->
create
(
$values
);
$propertyDefinitions
=
$entity
->
$specifier
->
getFieldDefinition
()
->
getPropertyDefinitions
();
$propertyDefinitions
=
$field
->
getPropertyDefinitions
();
$relationship_specifier
=
$specifiers
[
$key
+
1
];
$next_index_prefix
=
$relationship_specifier
;
}
// Check for a valid relationship.
if
(
isset
(
$propertyDefinitions
[
$relationship_specifier
])
&&
$
entity
->
get
(
$specifier
)
->
first
()
->
get
(
'entity'
)
instanceof
E
ntity
R
eference
)
{
if
(
isset
(
$propertyDefinitions
[
$relationship_specifier
])
&&
$
field
->
getPropertyDefinition
(
'entity'
)
->
getDataType
()
==
'e
ntity
_r
eference
'
)
{
// If it is, use the entity type.
$entity_type_id
=
$propertyDefinitions
[
$relationship_specifier
]
->
getTargetDefinition
()
->
getEntityTypeId
();
$entity_type
=
$entity_manager
->
getDefinition
(
$entity_type_id
);
$field_storage_definitions
=
$entity_manager
->
getFieldStorageDefinitions
(
$entity_type_id
);
// Add the new entity base table using the table and sql column.
$join_condition
=
'%alias.'
.
$entity_type
->
getKey
(
'id'
)
.
" =
$table
.
$sql_column
"
;
$base_table
=
$this
->
sqlQuery
->
leftJoin
(
$entity_type
->
getBaseTable
(),
NULL
,
$join_condition
);
...
...
core/modules/block/custom_block/custom_block.module
View file @
da026cf5
...
...
@@ -8,6 +8,8 @@
use
Drupal\custom_block
\
Entity\CustomBlockType
;
use
Drupal\custom_block
\
Entity\CustomBlock
;
use
Symfony\Component\HttpFoundation\Request
;
use
Drupal\field\Entity\FieldConfig
;
use
Drupal\field\Entity\FieldInstanceConfig
;
/**
* Implements hook_help().
...
...
@@ -115,8 +117,8 @@ function custom_block_entity_bundle_info() {
*/
function
custom_block_add_body_field
(
$block_type_id
,
$label
=
'Body'
)
{
// Add or remove the body field, as needed.
$field
=
f
ield
_info_field
(
'custom_block'
,
'body'
);
$instance
=
f
ield
_info_instanc
e
(
'custom_block'
,
'body'
,
$block_type_id
);
$field
=
F
ield
Config
::
loadByName
(
'custom_block'
,
'body'
);
$instance
=
F
ield
InstanceConfig
::
loadByNam
e
(
'custom_block'
,
$block_type_id
,
'body'
);
if
(
empty
(
$field
))
{
$field
=
entity_create
(
'field_config'
,
array
(
'name'
=>
'body'
,
...
...
core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockTypeTest.php
View file @
da026cf5
...
...
@@ -78,8 +78,8 @@ public function testCustomBlockTypeEditing() {
// We need two block types to prevent /block/add redirecting.
$this
->
createCustomBlockType
(
'other'
);
$
instance
=
field_info_instance
(
'custom_block'
,
'
body'
,
'basic'
)
;
$this
->
assertEqual
(
$
instance
->
getLabel
(),
'Body'
,
'Body field was found.'
);
$
field_definition
=
\
Drupal
::
entityManager
()
->
getFieldDefinitions
(
'custom_block'
,
'
other'
)[
'body'
]
;
$this
->
assertEqual
(
$
field_definition
->
getLabel
(),
'Body'
,
'Body field was found.'
);
// Verify that title and body fields are displayed.
$this
->
drupalGet
(
'block/add/basic'
);
...
...
core/modules/comment/comment.module
View file @
da026cf5
...
...
@@ -15,6 +15,7 @@
use
Drupal\Core\Entity\EntityInterface
;
use
Drupal\entity\Entity\EntityViewDisplay
;
use
Drupal\Core\Entity\Display\EntityViewDisplayInterface
;
use
Drupal\Core\Field\FieldDefinitionInterface
;
use
Drupal\Core\Render\Element
;
use
Drupal\Core\Url
;
use
Drupal\field\FieldInstanceConfigInterface
;
...
...
@@ -98,14 +99,25 @@ function comment_help($route_name, Request $request) {
*/
function
comment_entity_bundle_info
()
{
$bundles
=
array
();
foreach
(
\
Drupal
::
service
(
'comment.manager'
)
->
getAllFields
()
as
$entity_type
=>
$fields
)
{
foreach
(
$fields
as
$field_name
=>
$field_info
)
{
$sample_bundle
=
reset
(
$field_info
[
'bundles'
]);
// We cannot use field info API here because it will result in recursion.
$config
=
\
Drupal
::
config
(
'field.instance.'
.
$entity_type
.
'.'
.
$sample_bundle
.
'.'
.
$field_name
);
$bundles
[
'comment'
][
$entity_type
.
'__'
.
$field_name
]
=
array
(
'label'
=>
$config
->
get
(
'label'
),
);
$ids
=
\
Drupal
::
entityQuery
(
'field_config'
)
->
condition
(
'type'
,
'comment'
)
->
execute
();
$config_factory
=
\
Drupal
::
configFactory
();
foreach
(
$ids
as
$id
)
{
// @todo: We can not rely on the field map here, so we need to manually look
// for a matching field instance to use for the label. Remove this in
// https://drupal.org/node/2228763.
list
(
$entity_type_id
,
$field_name
)
=
explode
(
'.'
,
$id
);
$instance_ids
=
$config_factory
->
listAll
(
'field.instance.'
.
$entity_type_id
.
'.'
);
// Look for an instance for this field.
foreach
(
$instance_ids
as
$instance_id
)
{
$instance_field_name
=
substr
(
$instance_id
,
strrpos
(
$instance_id
,
'.'
)
+
1
);
if
(
$instance_field_name
==
$field_name
)
{
$config
=
\
Drupal
::
config
(
$instance_id
);
$bundles
[
'comment'
][
$entity_type_id
.
'__'
.
$field_name
]
=
array
(
'label'
=>
$config
->
get
(
'label'
),
);
}
}
}
return
$bundles
;
...
...
@@ -407,7 +419,7 @@ function comment_node_links_alter(array &$node_links, NodeInterface $node, array
$links
=
array
();
$commenting_status
=
$node
->
get
(
$field_name
)
->
status
;
if
(
$commenting_status
)
{
$
instance
=
\
Drupal
::
service
(
'field.info'
)
->
getInstance
(
'node'
,
$node
->
bundle
(),
$field_name
);
$
field_definition
=
$node
->
getFieldDefinition
(
$field_name
);
// Node have commenting open or close.
if
(
$view_mode
==
'rss'
)
{
// Add a comments RSS element which is a URL to the comments of this node.
...
...
@@ -449,7 +461,7 @@ function comment_node_links_alter(array &$node_links, NodeInterface $node, array
}
// Provide a link to new comment form.
if
(
$commenting_status
==
CommentItemInterface
::
OPEN
)
{
$comment_form_location
=
$
instance
->
getSetting
(
'form_location'
);
$comment_form_location
=
$
field_definition
->
getSetting
(
'form_location'
);
if
(
user_access
(
'post comments'
))
{
$links
[
'comment-add'
]
=
array
(
'title'
=>
t
(
'Add new comment'
),
...
...
@@ -481,7 +493,7 @@ function comment_node_links_alter(array &$node_links, NodeInterface $node, array
// Node in other view modes: add a "post comment" link if the user is
// allowed to post comments and if this node is allowing new comments.
if
(
$commenting_status
==
CommentItemInterface
::
OPEN
)
{
$comment_form_location
=
$
instance
->
getSetting
(
'form_location'
);
$comment_form_location
=
$
field_definition
->
getSetting
(
'form_location'
);
if
(
user_access
(
'post comments'
))
{
// Show the "post comment" link if the form is on another page, or
// if there are existing comments that the link will skip past.
...
...
@@ -1135,16 +1147,15 @@ function comment_num_new($entity_id, $entity_type, $field_name = NULL, $timestam
*
* @param int $cid
* The comment ID.
* @param
array $instance
* Field
instance as returned from field_info_instance()
.
* @param
\Drupal\Core\Field\FieldDefinitionInterface $field_definition
* Field
definition of the comments
.
*
* @return int
* The display ordinal for the comment.
*
* @see comment_get_display_page()
* @see field_info_instance().
*/
function
comment_get_display_ordinal
(
$cid
,
$instance
)
{
function
comment_get_display_ordinal
(
$cid
,
FieldDefinitionInterface
$field_definition
)
{
// Count how many comments (c1) are before $cid (c2) in display order. This is
// the 0-based display ordinal.
$query
=
db_select
(
'comment'
,
'c1'
);
...
...
@@ -1155,7 +1166,7 @@ function comment_get_display_ordinal($cid, $instance) {
$query
->
condition
(
'c1.status'
,
CommentInterface
::
PUBLISHED
);
}
if
(
$
instance
->
getSetting
(
'default_mode'
)
==
COMMENT_MODE_FLAT
)
{
if
(
$
field_definition
->
getSetting
(
'default_mode'
)
==
COMMENT_MODE_FLAT
)
{
// For flat comments, cid is used for ordering comments due to
// unpredictable behavior with timestamp, so we make the same assumption
// here.
...
...
@@ -1179,15 +1190,15 @@ function comment_get_display_ordinal($cid, $instance) {
*
* @param int $cid
* The comment ID.
* @param
array $instance
* Field
instance as returned from field_info_instance()
.
* @param
\Drupal\Core\Field\FieldDefinitionInterface $field_definition
* Field
definition of the comments
.
*
* @return int
* The page number.
*/
function
comment_get_display_page
(
$cid
,
$instance
)
{
$ordinal
=
comment_get_display_ordinal
(
$cid
,
$
instance
);
$comments_per_page
=
$
instance
->
getSetting
(
'per_page'
);
function
comment_get_display_page
(
$cid
,
FieldDefinitionInterface
$field_definition
)
{
$ordinal
=
comment_get_display_ordinal
(
$cid
,
$
field_definition
);
$comments_per_page
=
$
field_definition
->
getSetting
(
'per_page'
);
return
floor
(
$ordinal
/
$comments_per_page
);
}
...
...
core/modules/comment/comment.services.yml
View file @
da026cf5
...
...
@@ -7,7 +7,7 @@ services:
comment.manager
:
class
:
Drupal\comment\CommentManager
arguments
:
[
'
@field.info'
,
'
@entity.manager'
,
'
@config.factory'
,
'
@string_translation'
,
'
@url_generator'
]
arguments
:
[
'
@entity.manager'
,
'
@config.factory'
,
'
@string_translation'
,
'
@url_generator'
]
comment.statistics
:
class
:
Drupal\comment\CommentStatistics
...
...
core/modules/comment/lib/Drupal/comment/CommentForm.php
View file @
da026cf5
...
...
@@ -16,7 +16,6 @@
use
Drupal\Core\Entity\EntityManagerInterface
;
use
Drupal\Core\Language\Language
;
use
Drupal\Core\Session\AccountInterface
;
use
Drupal\field\FieldInfo
;
use
Symfony\Component\DependencyInjection\ContainerInterface
;
/**
...
...
@@ -24,13 +23,6 @@
*/
class
CommentForm
extends
ContentEntityForm
{
/**
* The field info service.
*
* @var \Drupal\field\FieldInfo
*/
protected
$fieldInfo
;
/**
* The current user.
*
...
...
@@ -44,7 +36,6 @@ class CommentForm extends ContentEntityForm {
public
static
function
create
(
ContainerInterface
$container
)
{
return
new
static
(
$container
->
get
(
'entity.manager'
),
$container
->
get
(
'field.info'
),
$container
->
get
(
'current_user'
)
);
}
...
...
@@ -59,9 +50,8 @@ public static function create(ContainerInterface $container) {
* @param \Drupal\Core\Session\AccountInterface $current_user
* The current user.
*/
public
function
__construct
(
EntityManagerInterface
$entity_manager
,
FieldInfo
$field_info
,
AccountInterface
$current_user
)
{
public
function
__construct
(
EntityManagerInterface
$entity_manager
,
AccountInterface
$current_user
)
{
parent
::
__construct
(
$entity_manager
);
$this
->
fieldInfo
=
$field_info
;
$this
->
currentUser
=
$current_user
;
}
...
...
@@ -89,13 +79,13 @@ public function form(array $form, array &$form_state) {
$comment
=
$this
->
entity
;
$entity
=
$this
->
entityManager
->
getStorage
(
$comment
->
getCommentedEntityTypeId
())
->
load
(
$comment
->
getCommentedEntityId
());
$field_name
=
$comment
->
getFieldName
();
$
instance
=
$this
->
fieldInfo
->
getInstance
(
$entity
->
getEntityTypeId
(),
$entity
->
bundle
()
,
$f
ield
_n
ame
)
;
$
field_definition
=
$this
->
entityManager
->
getFieldDefinitions
(
$entity
->
getEntityTypeId
(),
$entity
->
bundle
()
)[
$comment
->
getF
ield
N
ame
()]
;
// Use #comment-form as unique jump target, regardless of entity type.
$form
[
'#id'
]
=
drupal_html_id
(
'comment_form'
);
$form
[
'#theme'
]
=
array
(
'comment_form__'
.
$entity
->
getEntityTypeId
()
.
'__'
.
$entity
->
bundle
()
.
'__'
.
$field_name
,
'comment_form'
);
$anonymous_contact
=
$
instance
->
getSetting
(
'anonymous'
);
$anonymous_contact
=
$
field_definition
->
getSetting
(
'anonymous'
);
$is_admin
=
$comment
->
id
()
&&
$this
->
currentUser
->
hasPermission
(
'administer comments'
);
if
(
!
$this
->
currentUser
->
isAuthenticated
()
&&
$anonymous_contact
!=
COMMENT_ANONYMOUS_MAYNOT_CONTACT
)
{
...
...
@@ -214,7 +204,7 @@ public function form(array $form, array &$form_state) {
'#title'
=>
$this
->
t
(
'Subject'
),
'#maxlength'
=>
64
,
'#default_value'
=>
$comment
->
getSubject
(),
'#access'
=>
$
instance
->
getSetting
(
'subject'
),
'#access'
=>
$
field_definition
->
getSetting
(
'subject'
),
);
// Used for conditional validation of author fields.
...
...
@@ -241,8 +231,8 @@ protected function actions(array $form, array &$form_state) {
/* @var \Drupal\comment\CommentInterface $comment */
$comment
=
$this
->
entity
;
$entity
=
$comment
->
getCommentedEntity
();
$
instance
=
$this
->
fieldInfo
->
getInstance
(
$comment
->
getCommented
EntityTypeId
(),
$entity
->
bundle
()
,
$comment
->
getFieldName
()
)
;
$preview_mode
=
$
instance
->
getSetting
(
'preview'
);
$
field_definition
=
$this
->
entityManager
->
getFieldDefinitions
(
$entity
->
get
EntityTypeId
(),
$entity
->
bundle
()
)[
$comment
->
getFieldName
()
]
;
$preview_mode
=
$
field_definition
->
getSetting
(
'preview'
);
// No delete action on the comment form.
unset
(
$element
[
'delete'
]);
...
...
@@ -404,8 +394,8 @@ public function save(array $form, array &$form_state) {
}
$query
=
array
();
// Find the current display page for this comment.