Commit 4e3ee43e authored by catch's avatar catch

Issue #2228763 by larowlan, alexpott, martin107, jessebeach, xjm: Create a...

Issue #2228763 by larowlan, alexpott, martin107, jessebeach, xjm: Create a comment-type config entity and use that as comment bundles, require selection in field settings form.
parent 1d47e0a0
......@@ -243,7 +243,7 @@ public function deleteRevision() { }
/**
* {@inheritdoc}
*/
public function settingsForm(array $form, array &$form_state, $has_data) {
public function settingsForm(array &$form, array &$form_state, $has_data) {
return array();
}
......
......@@ -252,7 +252,7 @@ public static function defaultInstanceSettings();
* @return
* The form definition for the field settings.
*/
public function settingsForm(array $form, array &$form_state, $has_data);
public function settingsForm(array &$form, array &$form_state, $has_data);
/**
* Returns a form for the instance-level settings.
......
......@@ -63,7 +63,7 @@ public static function schema(FieldStorageDefinitionInterface $field_definition)
/**
* {@inheritdoc}
*/
public function settingsForm(array $form, array &$form_state, $has_data) {
public function settingsForm(array &$form, array &$form_state, $has_data) {
$element = array();
$settings = $this->getSettings();
......
......@@ -5,6 +5,8 @@
* Install, update and uninstall functions for the Comment module.
*/
use Drupal\field\Entity\FieldConfig;
/**
* Implements hook_uninstall().
*/
......@@ -49,12 +51,12 @@ function comment_schema() {
'length' => 255,
'description' => 'The entity_type of the entity to which this comment is a reply.',
),
'field_id' => array(
'field_name' => array(
'type' => 'varchar',
'not null' => TRUE,
'default' => 'node__comment',
'length' => 255,
'description' => 'The field_id of the field that was used to add this comment.',
'default' => '',
'length' => FieldConfig::NAME_MAX_LENGTH,
'description' => 'The field_name of the field that was used to add this comment.',
),
'cid' => array(
'type' => 'int',
......@@ -89,7 +91,7 @@ function comment_schema() {
'description' => 'The total number of comments on this entity.',
),
),
'primary key' => array('entity_id', array('entity_type', 32), array('field_id', 32)),
'primary key' => array('entity_id', 'entity_type', 'field_name'),
'indexes' => array(
'last_comment_timestamp' => array('last_comment_timestamp'),
'comment_count' => array('comment_count'),
......
comment_type_add:
route_name: comment.type_add
title: 'Add comment type'
appears_on:
- comment.type_list
......@@ -29,3 +29,9 @@ comment.admin_approval:
class: Drupal\comment\Plugin\Menu\LocalTask\UnapprovedComments
parent_id: comment.admin
weight: 1
# Default tab for comment type editing.
comment.type_edit:
title: 'Edit'
route_name: comment.type_edit
base_route: comment.type_edit
......@@ -3,8 +3,8 @@ comment.admin:
route_name: comment.admin
parent: system.admin_content
description: 'List and edit site comments and the comment approval queue.'
comment.bundle_list:
title: 'Comment forms'
route_name: comment.bundle_list
comment.type_list:
title: 'Comment types'
route_name: comment.type_list
parent: system.admin_structure
description: 'Manage fields and displays settings for comment forms.'
description: 'Manage form and displays settings of comments.'
......@@ -12,6 +12,7 @@
use Drupal\comment\CommentInterface;
use Drupal\comment\Entity\Comment;
use Drupal\comment\Entity\CommentType;
use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface;
use Drupal\Component\Utility\String;
use Drupal\Core\Entity\ContentEntityInterface;
......@@ -21,6 +22,7 @@
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Render\Element;
use Drupal\Core\Url;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\FieldInstanceConfigInterface;
use Drupal\field\FieldConfigInterface;
use Drupal\file\FileInterface;
......@@ -93,41 +95,12 @@ function comment_help($route_name, Request $request) {
$output .= '</dl>';
return $output;
case 'comment.bundle_list':
$output = '<p>' . t('This page provides a list of all comment forms on the site and allows you to manage the fields, form and display settings for each.') . '</p>';
case 'comment.type_list':
$output = '<p>' . t('This page provides a list of all comment types on the site and allows you to manage the fields, form and display settings for each.') . '</p>';
return $output;
}
}
/**
* Implements hook_entity_bundle_info().
*/
function comment_entity_bundle_info() {
$bundles = array();
$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;
}
/**
* Entity URI callback.
*/
......@@ -146,23 +119,21 @@ function comment_uri(CommentInterface $comment) {
*/
function comment_entity_extra_field_info() {
$return = array();
foreach (\Drupal::service('comment.manager')->getAllFields() as $entity_type => $fields) {
foreach ($fields as $field_name => $field_info) {
$return['comment'][$entity_type . '__' . $field_name] = array(
'form' => array(
'author' => array(
'label' => t('Author'),
'description' => t('Author textfield'),
'weight' => -2,
),
'subject' => array(
'label' => t('Subject'),
'description' => t('Subject textfield'),
'weight' => -1,
),
foreach (CommentType::loadMultiple() as $comment_type) {
$return['comment'][$comment_type->id] = array(
'form' => array(
'author' => array(
'label' => t('Author'),
'description' => t('Author textfield'),
'weight' => -2,
),
);
}
'subject' => array(
'label' => t('Subject'),
'description' => t('Subject textfield'),
'weight' => -1,
),
),
);
}
return $return;
......@@ -196,15 +167,6 @@ function comment_count_unpublished() {
return t('Unapproved comments (@count)', array('@count' => $count));
}
/**
* Implements hook_ENTITY_TYPE_insert() for 'field_instance_config'.
*/
function comment_field_instance_config_insert(FieldInstanceConfigInterface $instance) {
if ($instance->getType() == 'comment' && !$instance->isSyncing()) {
\Drupal::service('comment.manager')->addBodyField($instance->entity_type, $instance->getName());
}
}
/**
* Implements hook_ENTITY_TYPE_create() for 'field_instance_config'.
*/
......@@ -237,16 +199,6 @@ function comment_field_instance_config_update(FieldInstanceConfigInterface $inst
}
}
/**
* Implements hook_ENTITY_TYPE_delete() for 'field_config'.
*/
function comment_field_config_delete(FieldConfigInterface $field) {
if ($field->getType() == 'comment') {
// Delete all fields and displays attached to the comment bundle.
entity_invoke_bundle_hook('delete', 'comment', $field->entity_type . '__' . $field->getName());
}
}
/**
* Implements hook_ENTITY_TYPE_insert() for 'field_config'.
*/
......@@ -257,8 +209,6 @@ function comment_field_config_insert(FieldConfigInterface $field) {
if (!_comment_entity_uses_integer_id($entity_type_id)) {
throw new \UnexpectedValueException('You cannot attach a comment field to an entity with a non-integer ID field');
}
// Delete all fields and displays attached to the comment bundle.
entity_invoke_bundle_hook('insert', 'comment', $entity_type_id . '__' . $field->getName());
}
}
......@@ -268,9 +218,9 @@ function comment_field_config_insert(FieldConfigInterface $field) {
function comment_field_instance_config_delete(FieldInstanceConfigInterface $instance) {
if ($instance->getType() == 'comment') {
// Delete all comments that used by the entity bundle.
$comments = db_query("SELECT cid FROM {comment} WHERE entity_type = :entity_type AND field_id = :field_id", array(
$comments = db_query("SELECT cid FROM {comment} WHERE entity_type = :entity_type AND field_name = :field_name", array(
':entity_type' => $instance->getEntityTypeId(),
':field_id' => $instance->getEntityTypeId() . '__' . $instance->getName(),
':field_name' => $instance->getName(),
))->fetchCol();
entity_delete_multiple('comment', $comments);
}
......@@ -284,6 +234,10 @@ function comment_permission() {
'administer comments' => array(
'title' => t('Administer comments and comment settings'),
),
'administer comment types' => array(
'title' => t('Administer comment types and settings'),
'restrict access' => TRUE,
),
'access comments' => array(
'title' => t('View comments'),
),
......@@ -338,7 +292,7 @@ function comment_new_page_count($num_comments, $new_replies, ContentEntityInterf
->fields('comment', array('thread'))
->condition('entity_id', $entity->id())
->condition('entity_type', $entity->getEntityTypeId())
->condition('field_id', $entity->getEntityTypeId() . '__' . $field_name)
->condition('field_name', $field_name)
->condition('status', CommentInterface::PUBLISHED)
->orderBy('created', 'DESC')
->orderBy('cid', 'DESC')
......@@ -360,11 +314,11 @@ function comment_new_page_count($num_comments, $new_replies, ContentEntityInterf
// Find the number of the first comment of the first unread thread.
$count = db_query('SELECT COUNT(*) FROM {comment} WHERE entity_id = :entity_id
AND entity_type = :entity_type
AND field_id = :field_id
AND field_name = :field_name
AND status = :status AND SUBSTRING(thread, 1, (LENGTH(thread) - 1)) < :thread', array(
':status' => CommentInterface::PUBLISHED,
':entity_id' => $entity->id(),
':field_id' => $entity->getEntityTypeId() . '__' . $field_name,
':field_name' => $field_name,
':entity_type' => $entity->getEntityTypeId(),
':thread' => $first_thread,
))->fetchField();
......@@ -578,10 +532,12 @@ function comment_node_view_alter(array &$build, EntityInterface $node, EntityVie
* The renderable array for the comment addition form.
*/
function comment_add(EntityInterface $entity, $field_name = 'comment', $pid = NULL) {
$field = Fieldconfig::loadByName($entity->getEntityTypeId(), $field_name);
$values = array(
'entity_type' => $entity->getEntityTypeId(),
'entity_id' => $entity->id(),
'field_id' => $entity->getEntityTypeId() . '__' . $field_name,
'field_name' => $field_name,
'comment_type' => $field->getSetting('bundle'),
'pid' => $pid,
);
$comment = entity_create('comment', $values);
......@@ -670,7 +626,7 @@ function comment_get_thread(EntityInterface $entity, $field_name, $mode, $commen
$query
->condition('c.entity_id', $entity->id())
->condition('c.entity_type', $entity->getEntityTypeId())
->condition('c.field_id', $entity->getEntityTypeId() . '__' . $field_name)
->condition('c.field_name', $field_name)
->addTag('entity_access')
->addTag('comment_filter')
->addMetaData('base_table', 'comment')
......@@ -683,7 +639,7 @@ function comment_get_thread(EntityInterface $entity, $field_name, $mode, $commen
$count_query
->condition('c.entity_id', $entity->id())
->condition('c.entity_type', $entity->getEntityTypeId())
->condition('c.field_id', $entity->getEntityTypeId() . '__' . $field_name)
->condition('c.field_name', $field_name)
->addTag('entity_access')
->addTag('comment_filter')
->addMetaData('base_table', 'comment')
......@@ -782,21 +738,6 @@ function comment_view_multiple($comments, $view_mode = 'full', $langcode = NULL)
return entity_view_multiple($comments, $view_mode, $langcode);
}
/**
* Implements hook_form_FORM_ID_alter().
*/
function comment_form_field_ui_field_instance_edit_form_alter(&$form, $form_state) {
if ($form['#field']->getType() == 'comment') {
// Collect translation settings.
if (\Drupal::moduleHandler()->moduleExists('content_translation')) {
array_unshift($form['#submit'], 'comment_translation_configuration_element_submit');
}
// Hide required checkbox.
$form['instance']['required']['#access'] = FALSE;
}
}
/**
* Implements hook_form_FORM_ID_alter().
*/
......@@ -844,28 +785,6 @@ function comment_form_field_ui_field_edit_form_alter(&$form, $form_state) {
}
}
/**
* Form submission handler for field_ui_field_edit_form().
*
* This handles the comment translation settings added by
* _comment_field_instance_settings_form_process().
*
* @see _comment_field_instance_settings_form_process()
*/
function comment_translation_configuration_element_submit($form, &$form_state) {
// The comment translation settings form element is embedded into the instance
// settings form. Hence we need to provide to the regular submit handler a
// manipulated form state to make it process comment settings instead of the
// host entity.
$key = 'language_configuration';
$comment_form_state = array(
'content_translation' => array('key' => $key),
'language' => array($key => array('entity_type' => 'comment', 'bundle' => $form['#field']->name)),
'values' => array($key => array('content_translation' => $form_state['values']['content_translation'])),
);
content_translation_language_configuration_element_submit($form, $comment_form_state);
}
/**
* Implements hook_entity_load().
*
......@@ -884,14 +803,11 @@ function comment_entity_load($entities, $entity_type) {
// comment statistics properties, which are defined on each CommentItem field.
$result = \Drupal::service('comment.statistics')->read($entities, $entity_type);
foreach ($result as $record) {
$parts = explode('__', $record->field_id, 2);
list(, $field_name) = $parts;
// Skip fields that entity does not have.
if (!$entities[$record->entity_id]->hasField($field_name)) {
if (!$entities[$record->entity_id]->hasField($record->field_name)) {
continue;
}
$comment_statistics = $entities[$record->entity_id]->get($field_name);
$comment_statistics = $entities[$record->entity_id]->get($record->field_name);
$comment_statistics->cid = $record->cid;
$comment_statistics->last_comment_timestamp = $record->last_comment_timestamp;
$comment_statistics->last_comment_name = $record->last_comment_name;
......@@ -1166,7 +1082,7 @@ function comment_num_new($entity_id, $entity_type, $field_name = NULL, $timestam
->condition('c.created', $timestamp, '>');
if ($field_name) {
// Limit to a particular field.
$query->condition('c.field_id', $entity_type . '__' . $field_name);
$query->condition('c.field_name', $field_name);
}
return $query->execute()
......@@ -1198,7 +1114,7 @@ function comment_get_display_ordinal($cid, FieldDefinitionInterface $field_defin
// Count how many comments (c1) are before $cid (c2) in display order. This is
// the 0-based display ordinal.
$query = db_select('comment', 'c1');
$query->innerJoin('comment', 'c2', 'c2.entity_id = c1.entity_id AND c2.entity_type = c1.entity_type AND c2.field_id = c1.field_id');
$query->innerJoin('comment', 'c2', 'c2.entity_id = c1.entity_id AND c2.entity_type = c1.entity_type AND c2.field_name = c1.field_name');
$query->addExpression('COUNT(*)', 'count');
$query->condition('c2.cid', $cid);
if (!user_access('administer comments')) {
......
......@@ -66,20 +66,6 @@ comment.new_comments_node_links:
requirements:
_permission: 'access content'
comment.bundle_list:
path: '/admin/structure/comments'
defaults:
_content: '\Drupal\comment\Controller\AdminController::overviewBundles'
_title: 'Comment forms'
requirements:
_permission: 'administer comments'
# This route is only used by Field UI.
comment.bundle:
path: '/admin/structure/comments/manage/{bundle}'
requirements:
_access: 'FALSE'
comment.node_redirect:
path: '/comment/{node}/reply'
defaults:
......@@ -87,3 +73,43 @@ comment.node_redirect:
requirements:
_entity_access: 'node.view'
_module_dependencies: 'node'
comment.type_list:
path: '/admin/structure/comment'
defaults:
_entity_list: 'comment_type'
_title: 'Comment types'
requirements:
_permission: 'administer comment types'
options:
_admin_route: TRUE
comment.type_delete:
path: '/admin/structure/comment/manage/{comment_type}/delete'
defaults:
_entity_form: 'comment_type.delete'
_title: 'Delete'
requirements:
_entity_access: 'comment_type.delete'
options:
_admin_route: TRUE
comment.type_add:
path: '/admin/structure/comment/types/add'
defaults:
_entity_form: 'comment_type.add'
_title: 'Add'
requirements:
_permission: 'administer comment types'
options:
_admin_route: TRUE
comment.type_edit:
path: '/admin/structure/comment/manage/{comment_type}'
defaults:
_entity_form: 'comment_type.edit'
_title: 'Edit'
requirements:
_entity_access: 'comment_type.update'
options:
_admin_route: TRUE
......@@ -12,9 +12,3 @@ services:
comment.statistics:
class: Drupal\comment\CommentStatistics
arguments: ['@database', '@current_user', '@entity.manager', '@state']
comment.route_enhancer:
class: Drupal\comment\Routing\CommentBundleEnhancer
arguments: ['@entity.manager']
tags:
- { name: route_enhancer}
......@@ -332,9 +332,26 @@ function comment_views_data() {
),
);
$data['comment']['field_id'] = array(
'title' => t('Comment field id'),
'help' => t('The Field id from which the comment originated.'),
$data['comment']['field_name'] = array(
'title' => t('Comment field name'),
'help' => t('The Field name from which the comment originated.'),
'field' => array(
'id' => 'standard',
),
'filter' => array(
'id' => 'string',
),
'argument' => array(
'id' => 'string',
),
'sort' => array(
'id' => 'standard',
),
);
$data['comment']['comment_type'] = array(
'title' => t('Comment type'),
'help' => t('The comment type for this comment.'),
'field' => array(
'id' => 'standard',
),
......@@ -567,9 +584,9 @@ function comment_views_data() {
'id' => 'standard',
),
);
$data['comment_entity_statistics']['field_id'] = array(
'title' => t('Comment field ID'),
'help' => t('The field ID from which the comment originated.'),
$data['comment_entity_statistics']['field_name'] = array(
'title' => t('Comment field name'),
'help' => t('The field name from which the comment originated.'),
'field' => array(
'id' => 'standard',
),
......@@ -666,8 +683,8 @@ function comment_views_data_alter(&$data) {
'value' => $entity_type_id,
),
array(
'field' => 'field_id',
'value' => $entity_type_id . '.' . $field_name,
'field' => 'field_name',
'value' => $field_name,
),
),
),
......
......@@ -43,6 +43,16 @@ action.configuration.comment_unpublish_action:
type: action_configuration_default
label: 'Unpublish comment configuration'
comment.type.*:
type: config_entity
label: 'Comment type settings'
mapping:
target_entity_type_id:
type: string
label: 'Target Entity Type ID'
description:
type: text
label: 'Description'
field.comment.settings:
type: sequence
......
<?php
/**
* @file
* Contains \Drupal\comment\CommentFieldNameItem.
*/
namespace Drupal\comment;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\Field\Plugin\Field\FieldType\StringItem;
use Drupal\Core\TypedData\DataDefinition;
/**
* The field item for the 'fieldname' field.
*/
class CommentFieldNameItem extends StringItem {
/**
* {@inheritdoc}
*/
public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
$properties['value'] = DataDefinition::create('string')
->setLabel(t('String value'))
->setClass('\Drupal\comment\CommentFieldNameValue')
->setComputed(TRUE);
return $properties;
}
}
<?php
/**
* @file
* Contains \Drupal\comment\CommentFieldNameValue.
*/
namespace Drupal\comment;
use Drupal\Core\TypedData\TypedData;
use Drupal\Core\TypedData\ReadOnlyException;
use InvalidArgumentException;