diff --git a/core/lib/Drupal/Core/Field/FieldItemBase.php b/core/lib/Drupal/Core/Field/FieldItemBase.php index 33ec95c..39b9412 100644 --- a/core/lib/Drupal/Core/Field/FieldItemBase.php +++ b/core/lib/Drupal/Core/Field/FieldItemBase.php @@ -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(); } diff --git a/core/lib/Drupal/Core/Field/FieldItemInterface.php b/core/lib/Drupal/Core/Field/FieldItemInterface.php index 3943bad..693a39a 100644 --- a/core/lib/Drupal/Core/Field/FieldItemInterface.php +++ b/core/lib/Drupal/Core/Field/FieldItemInterface.php @@ -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. diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/DecimalItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/DecimalItem.php index 30d33c5..10d03b3 100644 --- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/DecimalItem.php +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/DecimalItem.php @@ -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(); diff --git a/core/modules/comment/comment.install b/core/modules/comment/comment.install index 0c35aae..f5601f0 100644 --- a/core/modules/comment/comment.install +++ b/core/modules/comment/comment.install @@ -49,12 +49,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' => 32, + 'description' => 'The field_name of the field that was used to add this comment.', ), 'cid' => array( 'type' => 'int', @@ -89,7 +89,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'), diff --git a/core/modules/comment/comment.local_actions.yml b/core/modules/comment/comment.local_actions.yml new file mode 100644 index 0000000..0f65c76 --- /dev/null +++ b/core/modules/comment/comment.local_actions.yml @@ -0,0 +1,5 @@ +comment_type_add: + route_name: comment.type_add + title: 'Add comment type' + appears_on: + - comment.type_list diff --git a/core/modules/comment/comment.local_tasks.yml b/core/modules/comment/comment.local_tasks.yml index 8826d1d..ecf92e9 100644 --- a/core/modules/comment/comment.local_tasks.yml +++ b/core/modules/comment/comment.local_tasks.yml @@ -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 diff --git a/core/modules/comment/comment.menu_links.yml b/core/modules/comment/comment.menu_links.yml index 7f0af78..e4d4488 100644 --- a/core/modules/comment/comment.menu_links.yml +++ b/core/modules/comment/comment.menu_links.yml @@ -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.' diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module index 8fc5537..459a9bc 100644 --- a/core/modules/comment/comment.module +++ b/core/modules/comment/comment.module @@ -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\Core\Entity\ContentEntityInterface; use Drupal\Core\Entity\EntityInterface; @@ -20,6 +21,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; @@ -92,42 +94,13 @@ function comment_help($route_name, Request $request) { $output .= ''; return $output; - case 'comment.bundle_list': - $output = '

' . 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.') . '

'; + case 'comment.type_list': + $output = '

' . 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.') . '

'; 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. */ function comment_uri(CommentInterface $comment) { @@ -145,23 +118,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() { } /** - * 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'. */ function comment_field_instance_config_create(FieldInstanceConfigInterface $instance) { @@ -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'. */ function comment_field_config_insert(FieldConfigInterface $field) { @@ -256,8 +208,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()); } } @@ -267,9 +217,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); } @@ -283,6 +233,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'), ), @@ -337,7 +291,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') @@ -359,11 +313,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(); @@ -577,10 +531,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); @@ -669,7 +625,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') @@ -682,7 +638,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') @@ -784,21 +740,6 @@ function comment_view_multiple($comments, $view_mode = 'full', $langcode = NULL) /** * 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(). - */ function comment_form_field_ui_field_overview_form_alter(&$form, $form_state) { $request = \Drupal::request(); if ($form['#entity_type'] == 'comment' && $request->attributes->has('commented_entity_type')) { @@ -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(). * * @see \Drupal\comment\Plugin\Field\FieldType\CommentItem::propertyDefinitions() @@ -883,14 +802,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; @@ -1165,7 +1081,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() @@ -1197,7 +1113,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')) { diff --git a/core/modules/comment/comment.routing.yml b/core/modules/comment/comment.routing.yml index 1a6ac59..04b4b7e 100644 --- a/core/modules/comment/comment.routing.yml +++ b/core/modules/comment/comment.routing.yml @@ -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 diff --git a/core/modules/comment/comment.services.yml b/core/modules/comment/comment.services.yml index 13846b1..b0fc2ad 100644 --- a/core/modules/comment/comment.services.yml +++ b/core/modules/comment/comment.services.yml @@ -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} diff --git a/core/modules/comment/comment.views.inc b/core/modules/comment/comment.views.inc index dddf7ef..aa6008c 100644 --- a/core/modules/comment/comment.views.inc +++ b/core/modules/comment/comment.views.inc @@ -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, ), ), ), diff --git a/core/modules/comment/config/schema/comment.schema.yml b/core/modules/comment/config/schema/comment.schema.yml index 3b322b2..82c9e30 100644 --- a/core/modules/comment/config/schema/comment.schema.yml +++ b/core/modules/comment/config/schema/comment.schema.yml @@ -43,6 +43,34 @@ action.configuration.comment_unpublish_action: type: action_configuration_default label: 'Unpublish comment configuration' +comment.type.*: + type: mapping + label: 'Comment type settings' + mapping: + id: + type: string + label: 'Machine-readable name' + uuid: + type: string + label: 'UUID' + target_entity_type_id: + type: string + label: 'Target Entity Type ID' + label: + type: label + label: 'Label' + description: + type: text + label: 'Description' + status: + type: boolean + label: 'Status' + langcode: + type: string + label: 'Default language' + dependencies: + type: config_dependencies + label: 'Dependencies' field.comment.settings: type: sequence diff --git a/core/modules/comment/src/CommentFieldNameItem.php b/core/modules/comment/src/CommentFieldNameItem.php deleted file mode 100644 index 94b8587..0000000 --- a/core/modules/comment/src/CommentFieldNameItem.php +++ /dev/null @@ -1,31 +0,0 @@ -setLabel(t('String value')) - ->setClass('\Drupal\comment\CommentFieldNameValue') - ->setComputed(TRUE); - - return $properties; - } - -} diff --git a/core/modules/comment/src/CommentFieldNameValue.php b/core/modules/comment/src/CommentFieldNameValue.php deleted file mode 100644 index 0190b8d..0000000 --- a/core/modules/comment/src/CommentFieldNameValue.php +++ /dev/null @@ -1,53 +0,0 @@ -value)) { - if (!isset($this->parent)) { - throw new InvalidArgumentException('Computed properties require context for computation.'); - } - $field = $this->parent->getParent(); - $entity = $field->getParent(); - // Field id is of the form {entity_type}__{field_name}. We set the - // optional limit param to explode() in case the user adds a field with __ - // in the name. - $parts = explode('__', $entity->getFieldId(), 2); - if ($parts && count($parts) == 2) { - $this->value = end($parts); - } - } - return $this->value; - } - - /** - * {@inheritdoc} - */ - public function setValue($value, $notify = TRUE) { - if (isset($value)) { - $this->field_name = $value; - // Also set the field id. - $field = $this->parent->getParent(); - $entity = $field->getParent(); - $entity->field_id = $entity->getCommentedEntityTypeId() . '__' . $value; - } - } - -} diff --git a/core/modules/comment/src/CommentForm.php b/core/modules/comment/src/CommentForm.php index 1c9b085..b804aaa 100644 --- a/core/modules/comment/src/CommentForm.php +++ b/core/modules/comment/src/CommentForm.php @@ -14,6 +14,7 @@ use Drupal\Core\Datetime\DrupalDateTime; use Drupal\Core\Entity\ContentEntityForm; use Drupal\Core\Entity\EntityManagerInterface; +use Drupal\Core\Language\Language; use Drupal\Core\Language\LanguageInterface; use Drupal\Core\Session\AccountInterface; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -156,6 +157,15 @@ public function form(array $form, array &$form_state) { $form['author']['name']['#account'] = $this->currentUser; } + $language_configuration = \Drupal::moduleHandler()->invoke('language', 'get_default_configuration', array('comment', $comment->getTypeId())); + $form['langcode'] = array( + '#title' => t('Language'), + '#type' => 'language_select', + '#default_value' => $comment->getUntranslated()->language()->id, + '#languages' => Language::STATE_ALL, + '#access' => isset($language_configuration['language_show']) && $language_configuration['language_show'], + ); + // Add author email and homepage fields depending on the current user. $form['author']['mail'] = array( '#type' => 'email', @@ -211,13 +221,6 @@ public function form(array $form, array &$form_state) { '#value' => ($comment->id() ? !$comment->getOwnerId() : $this->currentUser->isAnonymous()), ); - // Add internal comment properties. - $original = $comment->getUntranslated(); - foreach (array('cid', 'pid', 'entity_id', 'entity_type', 'field_id', 'uid', 'langcode') as $key) { - $key_name = key($comment->$key->getFieldDefinition()->getPropertyDefinitions()); - $form[$key] = array('#type' => 'value', '#value' => $original->$key->{$key_name}); - } - return parent::form($form, $form_state, $comment); } @@ -263,8 +266,9 @@ protected function actions(array $form, array &$form_state) { */ public function validate(array $form, array &$form_state) { parent::validate($form, $form_state); + $entity = $this->entity; - if (!empty($form_state['values']['cid'])) { + if (!$entity->isNew()) { // Verify the name in case it is being changed from being anonymous. $accounts = $this->entityManager->getStorage('user')->loadByProperties(array('name' => $form_state['values']['name'])); $account = reset($accounts); @@ -364,8 +368,8 @@ public function preview(array &$form, array &$form_state) { * Overrides Drupal\Core\Entity\EntityForm::save(). */ public function save(array $form, array &$form_state) { - $entity = entity_load($form_state['values']['entity_type'], $form_state['values']['entity_id']); $comment = $this->entity; + $entity = $comment->getCommentedEntity(); $field_name = $comment->getFieldName(); $uri = $entity->urlInfo(); diff --git a/core/modules/comment/src/CommentInterface.php b/core/modules/comment/src/CommentInterface.php index 347b1f6..d2fd09a 100644 --- a/core/modules/comment/src/CommentInterface.php +++ b/core/modules/comment/src/CommentInterface.php @@ -67,24 +67,15 @@ public function getCommentedEntityId(); public function getCommentedEntityTypeId(); /** - * Returns the field ID of the comment field the comment is attached to. - * - * @return string - * The field identifier of the field the comment is attached to. - */ - public function getFieldId(); - - /** * Sets the field ID for which this comment is attached. * - * @param string $field_id - * The field identifier, usually formatted: {entity_type}__{field_name}, - * for example, node__comment. + * @param string $field_name + * The field name through which the comment was added. * * @return $this * The class instance that this method is called on. */ - public function setFieldId($field_id); + public function setFieldName($field_name); /** * Returns the name of the field the comment is attached to. @@ -258,4 +249,12 @@ public function setThread($thread); */ public function permalink(); + /** + * Get the comment type id for this comment. + * + * @return string + * The id of the comment type. + */ + public function getTypeId(); + } diff --git a/core/modules/comment/src/CommentManager.php b/core/modules/comment/src/CommentManager.php index 7bd9f0f..2b639a2 100644 --- a/core/modules/comment/src/CommentManager.php +++ b/core/modules/comment/src/CommentManager.php @@ -9,6 +9,7 @@ use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface; use Drupal\Component\Utility\String; +use Drupal\Component\Utility\Unicode; use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityManagerInterface; @@ -16,6 +17,8 @@ use Drupal\Core\Session\AccountInterface; use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\Core\StringTranslation\TranslationInterface; +use Drupal\field\Entity\FieldConfig; +use Drupal\field\Entity\FieldInstanceConfig; /** * Comment manager contains common functions to manage comment fields. @@ -103,9 +106,27 @@ public function getAllFields() { /** * {@inheritdoc} */ - public function addDefaultField($entity_type, $bundle, $field_name = 'comment', $default_value = CommentItemInterface::OPEN) { + public function addDefaultField($entity_type, $bundle, $field_name = 'comment', $default_value = CommentItemInterface::OPEN, $comment_type_id = 'comment') { + $comment_type_storage = $this->entityManager->getStorage('comment_type'); + if ($comment_type = $comment_type_storage->load($comment_type_id)) { + if ($comment_type->getTargetEntityTypeId() !== $entity_type) { + throw new \InvalidArgumentException(String::format('The given comment type id %id can only be used with the %entity_type entity type', array( + '%id' => $comment_type_id, + '%entity_type' => $entity_type, + ))); + } + } + else { + // Silently create the comment-type for the calling code. + $comment_type_storage->create(array( + 'id' => $comment_type_id, + 'label' => Unicode::ucfirst($comment_type_id), + 'target_entity_type_id' => $entity_type, + 'description' => 'Default comment field', + ))->save(); + } // Make sure the field doesn't already exist. - if (!$this->entityManager->getStorage('field_config')->load($entity_type . '.' . $field_name)) { + if (!FieldConfig::loadByName($entity_type, $field_name)) { // Add a default comment field for existing node comments. $field = $this->entityManager->getStorage('field_config')->create(array( 'entity_type' => $entity_type, @@ -113,14 +134,14 @@ public function addDefaultField($entity_type, $bundle, $field_name = 'comment', 'type' => 'comment', 'translatable' => '0', 'settings' => array( - 'description' => 'Default comment field', + 'comment_type' => $comment_type_id, ), )); // Create the field. $field->save(); } // Make sure the instance doesn't already exist. - if (!$this->entityManager->getStorage('field_instance_config')->load($entity_type . '.' . $bundle . '.' . $field_name)) { + if (!array_key_exists($field_name, $this->entityManager->getFieldDefinitions($entity_type, $bundle))) { $instance = $this->entityManager->getStorage('field_instance_config')->create(array( 'label' => 'Comment settings', 'description' => '', @@ -164,7 +185,7 @@ public function addDefaultField($entity_type, $bundle, $field_name = 'comment', 'weight' => 20, )) ->save(); - // The comment field should be hidden in all other view displays. + // The comment field should be hidden in all other view displays. foreach ($this->entityManager->getViewModes($entity_type) as $id => $view_mode) { $display = entity_get_display($entity_type, $bundle, $id); // Only update existing displays. @@ -174,15 +195,15 @@ public function addDefaultField($entity_type, $bundle, $field_name = 'comment', } } - $this->addBodyField($entity_type, $field_name); + $this->addBodyField($comment_type_id); } /** * {@inheritdoc} */ - public function addBodyField($entity_type, $field_name) { + public function addBodyField($comment_type_id) { // Create the field if needed. - $field = $this->entityManager->getStorage('field_config')->load('comment.comment_body'); + $field = FieldConfig::loadByName('comment', 'comment_body'); if (!$field) { $field = $this->entityManager->getStorage('field_config')->create(array( 'name' => 'comment_body', @@ -191,32 +212,27 @@ public function addBodyField($entity_type, $field_name) { )); $field->save(); } - // Create the instance if needed, field name defaults to 'comment'. - $comment_bundle = $entity_type . '__' . $field_name; - $field_instance = $this->entityManager - ->getStorage('field_instance_config') - ->load("comment.$comment_bundle.comment_body"); - if (!$field_instance) { + if (!FieldInstanceConfig::loadByName('comment', $comment_type_id, 'comment_body')) { // Attaches the body field by default. $field_instance = $this->entityManager->getStorage('field_instance_config')->create(array( 'field_name' => 'comment_body', 'label' => 'Comment', 'entity_type' => 'comment', - 'bundle' => $comment_bundle, + 'bundle' => $comment_type_id, 'settings' => array('text_processing' => 1), 'required' => TRUE, )); $field_instance->save(); // Assign widget settings for the 'default' form mode. - entity_get_form_display('comment', $comment_bundle, 'default') + entity_get_form_display('comment', $comment_type_id, 'default') ->setComponent('comment_body', array( 'type' => 'text_textarea', )) ->save(); // Assign display settings for the 'default' view mode. - entity_get_display('comment', $comment_bundle, 'default') + entity_get_display('comment', $comment_type_id, 'default') ->setComponent('comment_body', array( 'label' => 'hidden', 'type' => 'text_default', @@ -229,16 +245,6 @@ public function addBodyField($entity_type, $field_name) { /** * {@inheritdoc} */ - public function getFieldUIPageTitle($commented_entity_type, $field_name) { - $field_info = $this->getFields($commented_entity_type); - $sample_bundle = reset($field_info[$field_name]['bundles']); - $sample_definition = $this->entityManager->getFieldDefinitions($commented_entity_type, $sample_bundle)[$field_name]; - return String::checkPlain($sample_definition->getLabel()); - } - - /** - * {@inheritdoc} - */ public function forbiddenMessage(EntityInterface $entity, $field_name) { if (!isset($this->authenticatedCanPostComments)) { // We only output a link if we are certain that users will get the diff --git a/core/modules/comment/src/CommentManagerInterface.php b/core/modules/comment/src/CommentManagerInterface.php index f302e18..8797065 100644 --- a/core/modules/comment/src/CommentManagerInterface.php +++ b/core/modules/comment/src/CommentManagerInterface.php @@ -48,36 +48,24 @@ public function getAllFields(); * @param string $bundle * The bundle to attach the default comment field instance to. * @param string $field_name - * (optional) Field name to use for the comment field. Defaults to 'comment'. + * (optional) Field name to use for the comment field. Defaults to + * 'comment'. * @param int $default_value * (optional) Default value, one of CommentItemInterface::HIDDEN, * CommentItemInterface::OPEN, CommentItemInterface::CLOSED. Defaults to * CommentItemInterface::OPEN. + * @param string $comment_type_id + * (optional) ID of comment type to use. Defaults to 'comment'. */ - public function addDefaultField($entity_type, $bundle, $field_name = 'comment', $default_value = CommentItemInterface::OPEN); + public function addDefaultField($entity_type, $bundle, $field_name = 'comment', $default_value = CommentItemInterface::OPEN, $comment_type_id = 'comment'); /** * Creates a comment_body field instance. * - * @param string $entity_type - * The type of the entity to which the comment field attached. - * @param string $field_name - * Name of the comment field to add comment_body field. - */ - public function addBodyField($entity_type, $field_name); - - /** - * Builds human readable page title for field_ui management screens. - * - * @param string $commented_entity_type - * The entity type to which the comment field is attached. - * @param string $field_name - * The comment field for which the overview is to be displayed. - * - * @return string - * The human readable field name. + * @param string $comment_type + * The comment bundle. */ - public function getFieldUIPageTitle($commented_entity_type, $field_name); + public function addBodyField($comment_type); /** * Provides a message if posting comments is forbidden. diff --git a/core/modules/comment/src/CommentStatistics.php b/core/modules/comment/src/CommentStatistics.php index 9e3fbd1..fbbdff4 100644 --- a/core/modules/comment/src/CommentStatistics.php +++ b/core/modules/comment/src/CommentStatistics.php @@ -95,7 +95,7 @@ public function create(ContentEntityInterface $entity, $fields) { ->fields(array( 'entity_id', 'entity_type', - 'field_id', + 'field_name', 'cid', 'last_comment_timestamp', 'last_comment_name', @@ -126,7 +126,7 @@ public function create(ContentEntityInterface $entity, $fields) { $query->values(array( 'entity_id' => $entity->id(), 'entity_type' => $entity->getEntityTypeId(), - 'field_id' => $entity->getEntityTypeId() . '__' . $field_name, + 'field_name' => $field_name, 'cid' => 0, 'last_comment_timestamp' => $last_comment_timestamp, 'last_comment_name' => NULL, @@ -157,7 +157,7 @@ public function getRankingInfo() { 'alias' => 'ces', // Default to comment field as this is the most common use case for // nodes. - 'on' => "ces.entity_id = i.sid AND ces.entity_type = 'node' AND ces.field_id = 'node__comment'", + 'on' => "ces.entity_id = i.sid AND ces.entity_type = 'node' AND ces.field_name = 'comment'", ), // Inverse law that maps the highest reply count on the site to 1 and 0 // to 0. Note that the CAST here is necessary for PostgreSQL, because the @@ -183,7 +183,7 @@ public function update(CommentInterface $comment) { $query->addExpression('COUNT(cid)'); $count = $query->condition('c.entity_id', $comment->getCommentedEntityId()) ->condition('c.entity_type', $comment->getCommentedEntityTypeId()) - ->condition('c.field_id', $comment->getFieldId()) + ->condition('c.field_name', $comment->getFieldName()) ->condition('c.status', CommentInterface::PUBLISHED) ->execute() ->fetchField(); @@ -194,7 +194,7 @@ public function update(CommentInterface $comment) { ->fields('c', array('cid', 'name', 'changed', 'uid')) ->condition('c.entity_id', $comment->getCommentedEntityId()) ->condition('c.entity_type', $comment->getCommentedEntityTypeId()) - ->condition('c.field_id', $comment->getFieldId()) + ->condition('c.field_name', $comment->getFieldName()) ->condition('c.status', CommentInterface::PUBLISHED) ->orderBy('c.created', 'DESC') ->range(0, 1) @@ -212,7 +212,7 @@ public function update(CommentInterface $comment) { ->keys(array( 'entity_id' => $comment->getCommentedEntityId(), 'entity_type' => $comment->getCommentedEntityTypeId(), - 'field_id' => $comment->getFieldId(), + 'field_name' => $comment->getFieldName(), )) ->execute(); } @@ -241,7 +241,7 @@ public function update(CommentInterface $comment) { )) ->condition('entity_id', $comment->getCommentedEntityId()) ->condition('entity_type', $comment->getCommentedEntityTypeId()) - ->condition('field_id', $comment->getFieldId()) + ->condition('field_name', $comment->getFieldName()) ->execute(); } } diff --git a/core/modules/comment/src/CommentStorage.php b/core/modules/comment/src/CommentStorage.php index 5526d2b..2cffb5e 100644 --- a/core/modules/comment/src/CommentStorage.php +++ b/core/modules/comment/src/CommentStorage.php @@ -95,7 +95,7 @@ public function updateEntityStatistics(CommentInterface $comment) { public function getMaxThread(EntityInterface $comment) { $query = $this->database->select('comment', 'c') ->condition('entity_id', $comment->getCommentedEntityId()) - ->condition('field_id', $comment->getFieldId()) + ->condition('field_name', $comment->getFieldName()) ->condition('entity_type', $comment->getCommentedEntityTypeId()); $query->addExpression('MAX(thread)', 'thread'); return $query->execute() @@ -108,7 +108,7 @@ public function getMaxThread(EntityInterface $comment) { public function getMaxThreadPerThread(EntityInterface $comment) { $query = $this->database->select('comment', 'c') ->condition('entity_id', $comment->getCommentedEntityId()) - ->condition('field_id', $comment->getFieldId()) + ->condition('field_name', $comment->getFieldName()) ->condition('entity_type', $comment->getCommentedEntityTypeId()) ->condition('thread', $comment->getParentComment()->getThread() . '.%', 'LIKE'); $query->addExpression('MAX(thread)', 'thread'); @@ -138,7 +138,6 @@ public function getSchema() { $schema['comment']['fields']['pid']['not null'] = TRUE; $schema['comment']['fields']['status']['not null'] = TRUE; $schema['comment']['fields']['entity_id']['not null'] = TRUE; - $schema['comment']['fields']['field_id']['not null'] = TRUE; $schema['comment']['fields']['created']['not null'] = TRUE; $schema['comment']['fields']['thread']['not null'] = TRUE; @@ -149,7 +148,7 @@ public function getSchema() { 'comment__num_new' => array( 'entity_id', array('entity_type', 32), - array('field_id', 32), + 'comment_type', 'status', 'created', 'cid', @@ -158,7 +157,7 @@ public function getSchema() { 'comment__entity_langcode' => array( 'entity_id', array('entity_type', 32), - array('field_id', 32), + 'comment_type', 'langcode', ), 'comment__created' => array('created'), diff --git a/core/modules/comment/src/CommentTypeForm.php b/core/modules/comment/src/CommentTypeForm.php new file mode 100644 index 0000000..2454a87 --- /dev/null +++ b/core/modules/comment/src/CommentTypeForm.php @@ -0,0 +1,152 @@ +get('entity.manager'), + $container->get('logger.factory')->get('comment') + ); + } + + /** + * Constructs a CommentTypeFormController + * + * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager + * The entity manager service. + * @param \Drupal\Core\Logger\LoggerChannelInterface + * The logger channel. + */ + function __construct(EntityManagerInterface $entity_manager, LoggerChannelInterface $logger) { + $this->entityManager = $entity_manager; + $this->logger = $logger; + } + + /** + * {@inheritdoc} + */ + public function form(array $form, array &$form_state) { + $form = parent::form($form, $form_state); + + $comment_type = $this->entity; + + $form['label'] = array( + '#type' => 'textfield', + '#title' => t('Label'), + '#maxlength' => 255, + '#default_value' => $comment_type->label(), + '#required' => TRUE, + ); + $form['id'] = array( + '#type' => 'machine_name', + '#default_value' => $comment_type->id(), + '#machine_name' => array( + 'exists' => '\Drupal\comment\Entity\CommentType::load', + ), + '#maxlength' => EntityTypeInterface::BUNDLE_MAX_LENGTH, + '#disabled' => !$comment_type->isNew(), + ); + + $form['description'] = array( + '#type' => 'textarea', + '#default_value' => $comment_type->description, + '#description' => t('Describe this comment type. The text will be displayed on the Comment types administration overview page'), + '#title' => t('Description'), + ); + + $options = array(); + foreach ($this->entityManager->getDefinitions() as $entity_type) { + if ($entity_type->isFieldable()) { + $options[$entity_type->id()] = $entity_type->getLabel(); + } + } + $form['target_entity_type_id'] = array( + '#type' => 'select', + '#default_value' => $comment_type->getTargetEntityTypeId(), + '#title' => t('Target entity type'), + '#options' => $options, + ); + + if ($this->moduleHandler->moduleExists('content_translation')) { + $form['language'] = array( + '#type' => 'details', + '#title' => t('Language settings'), + '#group' => 'additional_settings', + ); + + $language_configuration = language_get_default_configuration('comment', $comment_type->id()); + $form['language']['language_configuration'] = array( + '#type' => 'language_configuration', + '#entity_information' => array( + 'entity_type' => 'comment', + 'bundle' => $comment_type->id(), + ), + '#default_value' => $language_configuration, + ); + + $form['#submit'][] = 'language_configuration_element_submit'; + } + + $form['actions'] = array('#type' => 'actions'); + $form['actions']['submit'] = array( + '#type' => 'submit', + '#value' => t('Save'), + ); + + return $form; + } + + /** + * {@inheritdoc} + */ + public function save(array $form, array &$form_state) { + $comment_type = $this->entity; + $status = $comment_type->save(); + + $edit_link = \Drupal::linkGenerator()->generateFromUrl($this->t('Edit'), $this->entity->urlInfo()); + if ($status == SAVED_UPDATED) { + drupal_set_message(t('Comment type %label has been updated.', array('%label' => $comment_type->label()))); + $this->logger->notice('Comment type %label has been updated.', array('%label' => $comment_type->label(), 'link' => $edit_link)); + } + else { + drupal_set_message(t('Comment type %label has been added.', array('%label' => $comment_type->label()))); + $this->logger->notice('Comment type %label has been added.', array('%label' => $comment_type->label(), 'link' => $edit_link)); + } + + $form_state['redirect_route']['route_name'] = 'comment.type_list'; + } + +} diff --git a/core/modules/comment/src/CommentTypeInterface.php b/core/modules/comment/src/CommentTypeInterface.php new file mode 100644 index 0000000..2ccc0c1 --- /dev/null +++ b/core/modules/comment/src/CommentTypeInterface.php @@ -0,0 +1,43 @@ +label()); + $row['description'] = Xss::filterAdmin($entity->getDescription()); + return $row + parent::buildRow($entity); + } + +} diff --git a/core/modules/comment/src/CommentViewBuilder.php b/core/modules/comment/src/CommentViewBuilder.php index 5b68530..b7cba52 100644 --- a/core/modules/comment/src/CommentViewBuilder.php +++ b/core/modules/comment/src/CommentViewBuilder.php @@ -110,7 +110,7 @@ public function buildComponents(array &$build, array $entities, array $displays, throw new \InvalidArgumentException(t('Invalid entity for comment.')); } $build[$id]['#entity'] = $entity; - $build[$id]['#theme'] = 'comment__' . $entity->getFieldId() . '__' . $commented_entity->bundle(); + $build[$id]['#theme'] = 'comment__' . $entity->getFieldName() . '__' . $commented_entity->bundle(); $callback = '\Drupal\comment\CommentViewBuilder::renderLinks'; $context = array( 'comment_entity_id' => $entity->id(), diff --git a/core/modules/comment/src/Controller/AdminController.php b/core/modules/comment/src/Controller/AdminController.php index 9c8d43c..4c1592f 100644 --- a/core/modules/comment/src/Controller/AdminController.php +++ b/core/modules/comment/src/Controller/AdminController.php @@ -7,12 +7,8 @@ namespace Drupal\comment\Controller; -use Drupal\comment\CommentManagerInterface; -use Drupal\field\FieldConfigInterface; -use Drupal\Component\Utility\String; use Drupal\Core\Controller\ControllerBase; use Drupal\Core\Form\FormBuilderInterface; -use Drupal\field_ui\FieldUI; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -22,13 +18,6 @@ class AdminController extends ControllerBase { /** - * The comment manager service. - * - * @var \Drupal\comment\CommentManagerInterface - */ - protected $commentManager; - - /** * The form builder. * * @var \Drupal\Core\Form\FormBuilderInterface @@ -40,7 +29,6 @@ class AdminController extends ControllerBase { */ public static function create(ContainerInterface $container) { return new static( - $container->get('comment.manager'), $container->get('form_builder') ); } @@ -48,137 +36,14 @@ public static function create(ContainerInterface $container) { /** * Constructs an AdminController object. * - * @param \Drupal\comment\CommentManagerInterface $comment_manager - * The comment manager service. * @param \Drupal\Core\Form\FormBuilderInterface $form_builder * The form builder. */ - public function __construct(CommentManagerInterface $comment_manager, FormBuilderInterface $form_builder) { - $this->commentManager = $comment_manager; + public function __construct(FormBuilderInterface $form_builder) { $this->formBuilder = $form_builder; } /** - * Returns an overview of comment fields in use on the site. - * - * @return array - * A renderable array containing a list of comment fields, the entity - * type and bundle combinations on which they are in use and various - * operation links for configuring each field. - */ - public function overviewBundles() { - $header = array( - 'field_name' => $this->t('Field name'), - 'description' => array( - 'data' => $this->t('Description'), - 'class' => array(RESPONSIVE_PRIORITY_MEDIUM), - ), - 'usage' => array( - 'data' => $this->t('Used in'), - 'class' => array(RESPONSIVE_PRIORITY_MEDIUM), - ), - 'type' => $this->t('Type'), - ); - - // Add a column for field UI operations if the Field UI module is enabled. - $field_ui_enabled = $this->moduleHandler()->moduleExists('field_ui'); - if ($field_ui_enabled) { - $header['operations'] = $this->t('Operations'); - } - - $entity_bundles = $this->entityManager()->getAllBundleInfo(); - $entity_types = $this->entityManager()->getDefinitions(); - $rows = array(); - - // Fetch a list of all comment fields. - $fields = $this->commentManager->getAllFields(); - - foreach ($fields as $entity_type => $data) { - $field_storage_definitions = $this->entityManager()->getFieldStorageDefinitions($entity_type); - foreach ($data as $field_name => $field_info_map) { - $storage_definition = $field_storage_definitions[$field_name]; - // Initialize the row. - $row = array( - 'class' => $storage_definition->get('locked') ? array('field-disabled') : array(''), - ); - - $label = $storage_definition->getLabel(); - if ($storage_definition instanceof FieldConfigInterface) { - $bundles = $storage_definition->getBundles(); - $sample_bundle = reset($bundles); - $field_definitions = $this->entityManager()->getFieldDefinitions($entity_type, $sample_bundle); - $label = $field_definitions[$field_name]->getLabel(); - } - - $tokens = array( - '@label' => $label, - '@field_name' => $field_name, - ); - $row['data']['field_name']['data'] = $storage_definition->get('locked') ? $this->t('@label (@field_name) (Locked)', $tokens) : $this->t('@label (@field_name)', $tokens); - - $row['data']['description']['data'] = $storage_definition->getSetting('description'); - $row['data']['usage']['data'] = array( - '#theme' => 'item_list', - '#items' => array(), - ); - foreach ($field_info_map['bundles'] as $bundle) { - if (isset($entity_bundles[$entity_type][$bundle])) { - // Add the current instance. - if ($field_ui_enabled && $route_info = FieldUI::getOverviewRouteInfo($entity_type, $bundle)) { - $row['data']['usage']['data']['#items'][] = \Drupal::linkGenerator()->generateFromUrl($entity_bundles[$entity_type][$bundle]['label'], $route_info); - } - else { - $row['data']['usage']['data']['#items'][] = $entity_bundles[$entity_type][$bundle]['label']; - } - } - } - - $row['data']['type']['data'] = String::checkPlain($entity_types[$entity_type]->getLabel()); - - if ($field_ui_enabled) { - if ($this->currentUser()->hasPermission('administer comment fields')) { - $links['fields'] = array( - 'title' => $this->t('Manage fields'), - 'href' => 'admin/structure/comments/manage/' . $entity_type . '__' . $field_name . '/fields', - 'weight' => 5, - ); - } - if ($this->currentUser()->hasPermission('administer comment display')) { - $links['display'] = array( - 'title' => $this->t('Manage display'), - 'href' => 'admin/structure/comments/manage/' . $entity_type . '__' . $field_name . '/display', - 'weight' => 10, - ); - } - if ($this->currentUser()->hasPermission('administer comment form display')) { - $links['form_display'] = array( - 'title' => $this->t('Manage form display'), - 'href' => 'admin/structure/comments/manage/' . $entity_type . '__' . $field_name . '/form-display', - 'weight' => 10, - ); - } - - $row['data']['operations']['data'] = array( - '#type' => 'operations', - '#links' => $links, - ); - } - $rows[$entity_type . '__' . $field_name] = $row; - } - } - - $build['overview'] = array( - '#type' => 'table', - '#header' => $header, - '#rows' => $rows, - '#empty' => $this->t('No comment forms available.'), - ); - $build['#title'] = $this->t('Comment forms'); - - return $build; - } - - /** * Presents an administrative comment listing. * * @param \Symfony\Component\HttpFoundation\Request $request diff --git a/core/modules/comment/src/Controller/CommentController.php b/core/modules/comment/src/Controller/CommentController.php index 1e73008..94fb25e 100644 --- a/core/modules/comment/src/Controller/CommentController.php +++ b/core/modules/comment/src/Controller/CommentController.php @@ -255,7 +255,7 @@ public function getReplyForm(Request $request, $entity_type, $entity_id, $field_ 'entity_id' => $entity->id(), 'pid' => $pid, 'entity_type' => $entity->getEntityTypeId(), - 'field_id' => $entity->getEntityTypeId() . '__' . $field_name, + 'field_name' => $field_name, )); $build['comment_form'] = $this->entityFormBuilder()->getForm($comment); diff --git a/core/modules/comment/src/Entity/Comment.php b/core/modules/comment/src/Entity/Comment.php index 8afc5b3..d7c7d11 100644 --- a/core/modules/comment/src/Entity/Comment.php +++ b/core/modules/comment/src/Entity/Comment.php @@ -13,7 +13,7 @@ use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Field\FieldDefinition; -use Drupal\Core\TypedData\DataDefinition; +use Drupal\field\Entity\FieldConfig; use Drupal\user\UserInterface; /** @@ -39,7 +39,7 @@ * translatable = TRUE, * entity_keys = { * "id" = "cid", - * "bundle" = "field_id", + * "bundle" = "comment_type", * "label" = "subject", * "uuid" = "uuid" * }, @@ -47,8 +47,9 @@ * "canonical" = "comment.permalink", * "delete-form" = "comment.confirm_delete", * "edit-form" = "comment.edit_page", - * "admin-form" = "comment.bundle" - * } + * "admin-form" = "comment.type_edit" + * }, + * bundle_entity_type = "comment_type" * ) */ class Comment extends ContentEntityBase implements CommentInterface { @@ -284,20 +285,15 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { ->setLabel(t('Entity type')) ->setDescription(t('The entity type to which this comment is attached.')); - // @todo Convert to the entity_reference field in - // https://drupal.org/node/2149859. - $fields['field_id'] = FieldDefinition::create('string') - ->setLabel(t('Field ID')) - ->setDescription(t('The comment field id.')); + $fields['comment_type'] = FieldDefinition::create('entity_reference') + ->setLabel(t('Comment Type')) + ->setDescription(t('The comment type.')) + ->setSetting('target_type', 'comment_type'); $fields['field_name'] = FieldDefinition::create('string') ->setLabel(t('Comment field name')) ->setDescription(t('The field name through which this comment was added.')) - ->setComputed(TRUE); - - $item_definition = $fields['field_name']->getItemDefinition(); - $item_definition->setClass('\Drupal\comment\CommentFieldNameItem'); - $fields['field_name']->setItemDefinition($item_definition); + ->setSetting('max_length', 32); return $fields; } @@ -306,10 +302,12 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { * {@inheritdoc} */ public static function bundleFieldDefinitions(EntityTypeInterface $entity_type, $bundle, array $base_field_definitions) { - list($target_type) = explode('__', $bundle, 2); - $fields['entity_id'] = clone $base_field_definitions['entity_id']; - $fields['entity_id']->setSetting('target_type', $target_type); - return $fields; + if ($comment_type = CommentType::load($bundle)) { + $fields['entity_id'] = clone $base_field_definitions['entity_id']; + $fields['entity_id']->setSetting('target_type', $comment_type->getTargetEntityTypeId()); + return $fields; + } + return array(); } /** @@ -351,15 +349,8 @@ public function getCommentedEntityTypeId() { /** * {@inheritdoc} */ - public function getFieldId() { - return $this->get('field_id')->value; - } - - /** - * {@inheritdoc} - */ - public function setFieldId($field_id) { - $this->set('field_id', $field_id); + public function setFieldName($field_name) { + $this->set('field_name', $field_name); return $this; } @@ -505,8 +496,9 @@ public function getChangedTime() { * {@inheritdoc} */ public static function preCreate(EntityStorageInterface $storage, array &$values) { - if (empty($values['field_id']) && !empty($values['field_name']) && !empty($values['entity_type'])) { - $values['field_id'] = $values['entity_type'] . '__' . $values['field_name']; + if (empty($values['comment_type']) && !empty($values['field_name']) && !empty($values['entity_type'])) { + $field = FieldConfig::loadByName($values['entity_type'], $values['field_name']); + $values['comment_type'] = $field->getSetting('comment_type'); } } @@ -540,4 +532,14 @@ public function setOwner(UserInterface $account) { return $this; } + /** + * Get the comment type ID for this comment. + * + * @return string + * The ID of the comment type. + */ + public function getTypeId() { + return $this->bundle(); + } + } diff --git a/core/modules/comment/src/Entity/CommentType.php b/core/modules/comment/src/Entity/CommentType.php new file mode 100644 index 0000000..4d7dd1d --- /dev/null +++ b/core/modules/comment/src/Entity/CommentType.php @@ -0,0 +1,105 @@ +description; + } + + /** + * {@inheritdoc} + */ + public function setDescription($description) { + $this->description = $description; + return $this; + } + + /** + * {@inheritdoc} + */ + public function getTargetEntityTypeId() { + return $this->target_entity_type_id; + } + + /** + * {@inheritdoc} + */ + public function postSave(EntityStorageInterface $storage, $update = TRUE) { + parent::postSave($storage, $update); + if (!$update && !$this->isSyncing()) { + \Drupal::service('comment.manager')->addBodyField($this->id()); + } + } + +} diff --git a/core/modules/comment/src/Form/CommentTypeDeleteForm.php b/core/modules/comment/src/Form/CommentTypeDeleteForm.php new file mode 100644 index 0000000..9c32d2f --- /dev/null +++ b/core/modules/comment/src/Form/CommentTypeDeleteForm.php @@ -0,0 +1,150 @@ +queryFactory = $query_factory; + $this->commentManager = $comment_manager; + $this->entityManager = $entity_manager; + $this->logger = $logger; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container) { + return new static( + $container->get('entity.query'), + $container->get('comment.manager'), + $container->get('entity.manager'), + $container->get('logger.factory')->get('comment') + ); + } + + /** + * {@inheritdoc} + */ + public function getQuestion() { + return $this->t('Are you sure you want to delete %label?', array('%label' => $this->entity->label())); + } + + /** + * {@inheritdoc} + */ + public function getCancelRoute() { + return new Url('comment.type_list'); + } + + /** + * {@inheritdoc} + */ + public function getConfirmText() { + return $this->t('Delete'); + } + + /** + * {@inheritdoc} + */ + public function buildForm(array $form, array &$form_state) { + $comments = $this->queryFactory->get('comment')->condition('comment_type', $this->entity->id())->execute(); + $entity_type = $this->entity->getTargetEntityTypeId(); + $caption = ''; + foreach (array_keys($this->commentManager->getFields($entity_type)) as $field_name) { + /** @var \Drupal\field\FieldConfigInterface $field */ + if (($field = FieldConfig::loadByName($entity_type, $field_name)) && $field->getSetting('comment_type') == $this->entity->id() && !$field->deleted) { + $caption .= '

' . $this->t('%label is used by the %field field on your site. You can not remove this comment type until you have removed the field.', array( + '%label' => $this->entity->label(), + '%field' => $field->label(), + )) . '

'; + } + } + + if (!empty($comments)) { + $caption .= '

' . $this->formatPlural(count($comments), '%label is used by 1 comment on your site. You can not remove this comment type until you have removed all of the %label comments.', '%label is used by @count comments on your site. You may not remove %label until you have removed all of the %label comments.', array('%label' => $this->entity->label())) . '

'; + } + if ($caption) { + $form['description'] = array('#markup' => $caption); + return $form; + } + else { + return parent::buildForm($form, $form_state); + } + } + + /** + * {@inheritdoc} + */ + public function submit(array $form, array &$form_state) { + $this->entity->delete(); + $form_state['redirect_route']['route_name'] = 'comment.type_list'; + drupal_set_message($this->t('Comment type %label has been deleted.', array('%label' => $this->entity->label()))); + $this->logger->notice('comment type %label has been deleted.', array('%label' => $this->entity->label())); + } + +} diff --git a/core/modules/comment/src/Plugin/Field/FieldType/CommentItem.php b/core/modules/comment/src/Plugin/Field/FieldType/CommentItem.php index 50799b8..5b94740 100644 --- a/core/modules/comment/src/Plugin/Field/FieldType/CommentItem.php +++ b/core/modules/comment/src/Plugin/Field/FieldType/CommentItem.php @@ -7,6 +7,9 @@ namespace Drupal\comment\Plugin\Field\FieldType; +use Drupal\comment\CommentTypeInterface; +use Drupal\comment\Entity\CommentType; +use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Field\FieldStorageDefinitionInterface; use Drupal\Core\TypedData\DataDefinition; use Drupal\Core\Field\FieldItemBase; @@ -30,7 +33,7 @@ class CommentItem extends FieldItemBase implements CommentItemInterface { */ public static function defaultSettings() { return array( - 'description' => '', + 'comment_type' => '', ) + parent::defaultSettings(); } @@ -102,16 +105,12 @@ public function instanceSettingsForm(array $form, array &$form_state) { $settings = $this->getSettings(); - $entity_type = $this->getEntity()->getEntityTypeId(); - $field_name = $this->getFieldDefinition()->getName(); $anonymous_user = new AnonymousUserSession(); $element['comment'] = array( '#type' => 'details', '#title' => t('Comment form settings'), '#open' => TRUE, - '#bundle' => "{$entity_type}__{$field_name}", - '#process' => array(array(get_class($this), 'processSettingsElement')), '#attributes' => array( 'class' => array('comment-instance-settings-form'), ), @@ -194,39 +193,28 @@ public function isEmpty() { } /** - * Process callback to add submit handler for instance settings form. - * - * Attaches the required translation entity handlers for the instance which - * correlates one to one with the comment bundle. - */ - public static function processSettingsElement($element) { - // Settings should not be stored as nested. - $parents = $element['#parents']; - array_pop($parents); - $element['#parents'] = $parents; - // Add translation entity handlers. - if (\Drupal::moduleHandler()->moduleExists('content_translation')) { - $comment_form = $element; - $comment_form_state['content_translation']['key'] = 'language_configuration'; - $element += content_translation_enable_widget('comment', $element['#bundle'], $comment_form, $comment_form_state); - $element['content_translation']['#parents'] = $element['content_translation']['#array_parents'] = array( - 'content_translation' - ); - } - return $element; - } - - /** * {@inheritdoc} */ - public function settingsForm(array $form, array &$form_state, $has_data) { + public function settingsForm(array &$form, array &$form_state, $has_data) { $element = array(); - $element['description'] = array( - '#type' => 'textarea', - '#title' => t('Field description'), - '#description' => t('Describe this comment field. The text will be displayed on the Comments Forms page.'), - '#default_value' => $this->getSetting('description'), + // @todo Inject entity storage once typed-data supports container injection. + // See https://drupal.org/node/2053415 for more details. + $comment_types = CommentType::loadMultiple(); + $options = array(); + $entity_type = $this->getEntity()->getEntityTypeId(); + foreach ($comment_types as $comment_type) { + if ($comment_type->getTargetEntityTypeId() == $entity_type) { + $options[$comment_type->id()] = $comment_type->label(); + } + } + $element['comment_type'] = array( + '#type' => 'select', + '#title' => t('Comment type'), + '#options' => $options, + '#description' => t('Select the Comment type to use for this comment field.'), + '#default_value' => $this->getSetting('comment_type'), + '#disabled' => $has_data, ); return $element; } diff --git a/core/modules/comment/src/Routing/CommentBundleEnhancer.php b/core/modules/comment/src/Routing/CommentBundleEnhancer.php deleted file mode 100644 index 783fcda..0000000 --- a/core/modules/comment/src/Routing/CommentBundleEnhancer.php +++ /dev/null @@ -1,53 +0,0 @@ -entityManager = $entity_manager; - } - - /** - * {@inheritdoc} - */ - public function enhance(array $defaults, Request $request) { - if (isset($defaults['bundle']) && ($bundles = $this->entityManager->getBundleInfo('comment')) && isset($bundles[$defaults['bundle']])) { - list($entity_type, $field_name) = explode('__', $defaults['bundle'], 2); - $defaults['commented_entity_type'] = $entity_type; - $defaults['field_name'] = $field_name; - } - return $defaults; - } - -} diff --git a/core/modules/comment/src/Tests/CommentAdminTest.php b/core/modules/comment/src/Tests/CommentAdminTest.php index 4f2f211..11d4113 100644 --- a/core/modules/comment/src/Tests/CommentAdminTest.php +++ b/core/modules/comment/src/Tests/CommentAdminTest.php @@ -157,11 +157,10 @@ public function testCommentAdmin() { // Login. $this->drupalLogin($this->admin_user); // Browse to comment bundle overview. - $this->drupalGet('admin/structure/comments'); + $this->drupalGet('admin/structure/comment'); $this->assertResponse(200); // Make sure titles visible. - $this->assertText('Field name'); - $this->assertText('Used in'); + $this->assertText('Comment type'); $this->assertText('Description'); // Make sure the description is present. $this->assertText('Default comment field'); diff --git a/core/modules/comment/src/Tests/CommentDefaultFormatterCacheTagsTest.php b/core/modules/comment/src/Tests/CommentDefaultFormatterCacheTagsTest.php index ff8c05a..08fee4e 100644 --- a/core/modules/comment/src/Tests/CommentDefaultFormatterCacheTagsTest.php +++ b/core/modules/comment/src/Tests/CommentDefaultFormatterCacheTagsTest.php @@ -57,25 +57,7 @@ public function setUp() { // Set up a field, so that the entity that'll be referenced bubbles up a // cache tag when rendering it entirely. - entity_create('field_config', array( - 'name' => 'comment', - 'entity_type' => 'entity_test', - 'type' => 'comment', - 'settings' => array(), - ))->save(); - entity_create('field_instance_config', array( - 'entity_type' => 'entity_test', - 'bundle' => 'entity_test', - 'field_name' => 'comment', - 'label' => 'Comment', - 'settings' => array(), - ))->save(); - entity_get_display('entity_test', 'entity_test', 'default') - ->setComponent('comment', array( - 'type' => 'comment_default', - 'settings' => array(), - )) - ->save(); + \Drupal::service('comment.manager')->addDefaultField('entity_test', 'entity_test'); } /** @@ -110,6 +92,7 @@ public function testCacheTags() { 'entity_id' => $commented_entity->id(), 'entity_type' => 'entity_test', 'field_name' => 'comment', + 'comment_type' => 'comment', 'status' => CommentInterface::PUBLISHED, 'uid' => $user->id(), )); diff --git a/core/modules/comment/src/Tests/CommentFieldsTest.php b/core/modules/comment/src/Tests/CommentFieldsTest.php index d7657e1..5dd3bb7 100644 --- a/core/modules/comment/src/Tests/CommentFieldsTest.php +++ b/core/modules/comment/src/Tests/CommentFieldsTest.php @@ -41,7 +41,7 @@ function testCommentDefaultFields() { $this->container->get('comment.manager')->addDefaultField('node', 'test_node_type'); // Check that the 'comment_body' field is present on the comment bundle. - $instance = FieldInstanceConfig::loadByName('comment', 'node__comment', 'comment_body'); + $instance = FieldInstanceConfig::loadByName('comment', 'comment', 'comment_body'); $this->assertTrue(!empty($instance), 'The comment_body field is added when a comment bundle is created'); $instance->delete(); @@ -59,11 +59,11 @@ function testCommentDefaultFields() { // new comment bundle. $field = FieldConfig::loadByName('comment', 'comment_body'); $this->assertTrue($field, 'The comment_body field exists'); - $instance = FieldInstanceConfig::loadByName('comment', 'node__comment', 'comment_body'); + $instance = FieldInstanceConfig::loadByName('comment', 'comment', 'comment_body'); $this->assertTrue(isset($instance), format_string('The comment_body field is present for comments on type @type', array('@type' => $type_name))); // Test adding a field that defaults to CommentItemInterface::CLOSED. - $this->container->get('comment.manager')->addDefaultField('node', 'test_node_type', 'who_likes_ponies', CommentItemInterface::CLOSED); + $this->container->get('comment.manager')->addDefaultField('node', 'test_node_type', 'who_likes_ponies', CommentItemInterface::CLOSED, 'who_likes_ponies'); $field = entity_load('field_instance_config', 'node.test_node_type.who_likes_ponies'); $this->assertEqual($field->default_value[0]['status'], CommentItemInterface::CLOSED); } @@ -130,10 +130,10 @@ function testCommentFormat() { // Disable text processing for comments. $this->drupalLogin($this->admin_user); $edit = array('instance[settings][text_processing]' => 0); - $this->drupalPostForm('admin/structure/comments/manage/node__comment/fields/comment.node__comment.comment_body', $edit, t('Save settings')); + $this->drupalPostForm('admin/structure/comment/manage/comment/fields/comment.comment.comment_body', $edit, t('Save settings')); // Change formatter settings. - $this->drupalGet('admin/structure/comments/manage/node__comment/display'); + $this->drupalGet('admin/structure/comment/manage/comment/display'); $edit = array('fields[comment_body][type]' => 'text_trimmed', 'refresh_rows' => 'comment_body'); $commands = $this->drupalPostAjaxForm(NULL, $edit, array('op' => t('Refresh'))); $this->assertTrue($commands, 'Ajax commands returned'); diff --git a/core/modules/comment/src/Tests/CommentLanguageTest.php b/core/modules/comment/src/Tests/CommentLanguageTest.php index 260834f..aa3d5aa 100644 --- a/core/modules/comment/src/Tests/CommentLanguageTest.php +++ b/core/modules/comment/src/Tests/CommentLanguageTest.php @@ -121,7 +121,7 @@ function testCommentLanguage() { ->fields('c', array('cid')) ->condition('entity_id', $node->id()) ->condition('entity_type', 'node') - ->condition('field_id', 'node__comment') + ->condition('field_name', 'comment') ->orderBy('cid', 'DESC') ->range(0, 1) ->execute() diff --git a/core/modules/comment/src/Tests/CommentNonNodeTest.php b/core/modules/comment/src/Tests/CommentNonNodeTest.php index 8f53832..66f3d57 100644 --- a/core/modules/comment/src/Tests/CommentNonNodeTest.php +++ b/core/modules/comment/src/Tests/CommentNonNodeTest.php @@ -8,6 +8,8 @@ namespace Drupal\comment\Tests; use Drupal\comment\CommentInterface; +use Drupal\comment\CommentTypeInterface; +use Drupal\comment\Entity\CommentType; use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface; use Drupal\field\Entity\FieldInstanceConfig; use Drupal\simpletest\WebTestBase; @@ -40,12 +42,18 @@ function setUp() { // Create a bundle for entity_test. entity_test_create_bundle('entity_test', 'Entity Test', 'entity_test'); + entity_create('comment_type', array( + 'id' => 'comment', + 'label' => 'Comment settings', + 'description' => 'Comment settings', + 'target_entity_type_id' => 'entity_test', + ))->save(); // Create comment field on entity_test bundle. $this->container->get('comment.manager')->addDefaultField('entity_test', 'entity_test'); // Verify that bundles are defined correctly. $bundles = \Drupal::entityManager()->getBundleInfo('comment'); - $this->assertEqual($bundles['entity_test__comment']['label'], 'Comment settings'); + $this->assertEqual($bundles['comment']['label'], 'Comment settings'); // Create test user. $this->admin_user = $this->drupalCreateUser(array( @@ -355,6 +363,15 @@ function testCommentFunctionality() { $this->assertFieldChecked('edit-default-value-input-comment-0-status-1'); $this->assertNoFieldChecked('edit-default-value-input-comment-0-status-2'); + // Add a new comment-type. + $bundle = CommentType::create(array( + 'id' => 'foobar', + 'label' => 'Foobar', + 'description' => '', + 'target_entity_type_id' => 'entity_test', + )); + $bundle->save(); + // Add a new comment field. $this->drupalGet('entity_test/structure/entity_test/fields'); $edit = array( @@ -363,10 +380,33 @@ function testCommentFunctionality() { 'fields[_add_new_field][type]' => 'comment', ); $this->drupalPostForm(NULL, $edit, t('Save')); - $this->drupalPostForm(NULL, array(), t('Save field settings')); + $this->drupalPostForm(NULL, array( + 'field[settings][comment_type]' => 'foobar', + ), t('Save field settings')); + $this->drupalPostForm(NULL, array(), t('Save settings')); $this->assertRaw(t('Saved %name configuration', array('%name' => 'Foobar'))); + // Add a third comment field. + $this->drupalGet('entity_test/structure/entity_test/fields'); + $edit = array( + 'fields[_add_new_field][label]' => 'Barfoo', + 'fields[_add_new_field][field_name]' => 'barfoo', + 'fields[_add_new_field][type]' => 'comment', + ); + $this->drupalPostForm(NULL, $edit, t('Save')); + // Re-use another comment type. + $this->drupalPostForm(NULL, array( + 'field[settings][comment_type]' => 'foobar', + ), t('Save field settings')); + $this->drupalPostForm(NULL, array(), t('Save settings')); + $this->assertRaw(t('Saved %name configuration', array('%name' => 'Barfoo'))); + + // Check the field contains the correct comment type. + $field = entity_load('field_config', 'entity_test.field_barfoo'); + $this->assertTrue($field); + $this->assertEqual($field->getSetting('comment_type'), 'foobar'); + // Test the new entity commenting inherits default. $random_label = $this->randomName(); $data = array('bundle' => 'entity_test', 'name' => $random_label); diff --git a/core/modules/comment/src/Tests/CommentStringIdEntitiesTest.php b/core/modules/comment/src/Tests/CommentStringIdEntitiesTest.php index 014b3b1..e1be25d 100644 --- a/core/modules/comment/src/Tests/CommentStringIdEntitiesTest.php +++ b/core/modules/comment/src/Tests/CommentStringIdEntitiesTest.php @@ -7,6 +7,7 @@ namespace Drupal\comment\Tests; +use Drupal\comment\Entity\CommentType; use Drupal\simpletest\KernelTestBase; /** @@ -19,7 +20,15 @@ class CommentStringIdEntitiesTest extends KernelTestBase { * * @var array */ - public static $modules = array('comment', 'user', 'field', 'field_ui', 'entity_test'); + public static $modules = array( + 'comment', + 'user', + 'field', + 'field_ui', + 'entity', + 'entity_test', + 'text', + ); public static function getInfo() { return array( @@ -40,10 +49,19 @@ public function setUp() { */ public function testCommentFieldNonStringId() { try { + $bundle = CommentType::create(array( + 'id' => 'foo', + 'label' => 'foo', + 'description' => '', + 'target_entity_type_id' => 'entity_test_string_id', + )); + $bundle->save(); $field = entity_create('field_config', array( 'name' => 'foo', 'entity_type' => 'entity_test_string_id', - 'settings' => array(), + 'settings' => array( + 'comment_type' => 'entity_test_string_id', + ), 'type' => 'comment', )); $field->save(); diff --git a/core/modules/comment/src/Tests/CommentTestBase.php b/core/modules/comment/src/Tests/CommentTestBase.php index 1931c9e..a93110b 100644 --- a/core/modules/comment/src/Tests/CommentTestBase.php +++ b/core/modules/comment/src/Tests/CommentTestBase.php @@ -7,6 +7,7 @@ namespace Drupal\comment\Tests; +use Drupal\comment\Entity\CommentType; use Drupal\comment\CommentInterface; use Drupal\field\Entity\FieldInstanceConfig; use Drupal\simpletest\WebTestBase; @@ -58,6 +59,7 @@ function setUp() { $this->admin_user = $this->drupalCreateUser(array( 'administer content types', 'administer comments', + 'administer comment types', 'administer comment fields', 'administer comment display', 'skip comment approval', @@ -353,4 +355,24 @@ function getUnapprovedComment($subject) { return $match[2]; } + /** + * Creates a comment comment type (bundle). + * + * @param string $label + * The comment type label. + * + * @return \Drupal\comment\Entity\CommentType + * Created comment type. + */ + protected function createCommentType($label) { + $bundle = CommentType::create(array( + 'id' => $label, + 'label' => $label, + 'description' => '', + 'target_entity_type_id' => 'node', + )); + $bundle->save(); + return $bundle; + } + } diff --git a/core/modules/comment/src/Tests/CommentTranslationUITest.php b/core/modules/comment/src/Tests/CommentTranslationUITest.php index 1749e1f..7314c30 100644 --- a/core/modules/comment/src/Tests/CommentTranslationUITest.php +++ b/core/modules/comment/src/Tests/CommentTranslationUITest.php @@ -39,7 +39,7 @@ public static function getInfo() { function setUp() { $this->entityTypeId = 'comment'; $this->nodeBundle = 'article'; - $this->bundle = 'node__comment_article'; + $this->bundle = 'comment_article'; $this->testLanguageSelector = FALSE; $this->subject = $this->randomName(); parent::setUp(); @@ -52,14 +52,14 @@ function setupBundle() { parent::setupBundle(); $this->drupalCreateContentType(array('type' => $this->nodeBundle, 'name' => $this->nodeBundle)); // Add a comment field to the article content type. - $this->container->get('comment.manager')->addDefaultField('node', 'article', 'comment_article'); + $this->container->get('comment.manager')->addDefaultField('node', 'article', 'comment_article', CommentItemInterface::OPEN, 'comment_article'); // Create a page content type. $this->drupalCreateContentType(array('type' => 'page', 'name' => 'page')); // Add a comment field to the page content type - this one won't be // translatable. $this->container->get('comment.manager')->addDefaultField('node', 'page', 'comment'); // Mark this bundle as translatable. - content_translation_set_config('comment', 'node__comment_article', 'enabled', TRUE); + content_translation_set_config('comment', 'comment_article', 'enabled', TRUE); } /** @@ -82,12 +82,8 @@ function setupTestFields() { /** * Overrides \Drupal\content_translation\Tests\ContentTranslationUITest::createEntity(). */ - protected function createEntity($values, $langcode, $node_bundle = 'node__comment_article') { - // The argument is called 'node_bundle' but its actually just the entity - // bundle. Comment entity's bundle is of the form - // {entity_type}__{field_name}. Based on the passed bundle we need to - // determine the type of node and the name of the comment field. - if ($node_bundle == 'node__comment_article') { + protected function createEntity($values, $langcode, $comment_type = 'comment_article') { + if ($comment_type == 'comment_article') { // This is the article node type, with the 'comment_article' field. $node_type = 'article'; $field_name = 'comment_article'; @@ -105,9 +101,9 @@ protected function createEntity($values, $langcode, $node_bundle = 'node__commen )); $values['entity_id'] = $node->id(); $values['entity_type'] = 'node'; - $values['field_id'] = $node_bundle; + $values['field_name'] = $field_name; $values['uid'] = $node->getOwnerId(); - return parent::createEntity($values, $langcode, $node_bundle); + return parent::createEntity($values, $langcode, $comment_type); } /** @@ -157,7 +153,7 @@ function testTranslateLinkCommentAdminPage() { $this->drupalLogin($this->admin_user); $cid_translatable = $this->createEntity(array(), $this->langcodes[0]); - $cid_untranslatable = $this->createEntity(array(), $this->langcodes[0], 'node__comment'); + $cid_untranslatable = $this->createEntity(array(), $this->langcodes[0], 'comment'); // Verify translation links. $this->drupalGet('admin/content/comment'); diff --git a/core/modules/comment/src/Tests/CommentTypeTest.php b/core/modules/comment/src/Tests/CommentTypeTest.php new file mode 100644 index 0000000..1919fe2 --- /dev/null +++ b/core/modules/comment/src/Tests/CommentTypeTest.php @@ -0,0 +1,189 @@ +adminUser = $this->drupalCreateUser($this->permissions); + } + + /** + * Declares test information. + */ + public static function getInfo() { + return array( + 'name' => 'Comment types', + 'description' => 'Ensures that comment type functions work correctly.', + 'group' => 'Comment', + ); + } + + /** + * Tests creating a comment type programmatically and via a form. + */ + public function testCommentTypeCreation() { + // Create a comment type programmaticaly. + $type = $this->createCommentType('other'); + + $comment_type = CommentType::load('other'); + $this->assertTrue($comment_type, 'The new comment type has been created.'); + + // Login a test user. + $this->drupalLogin($this->adminUser); + + $this->drupalGet('admin/structure/comment/manage/' . $type->id()); + $this->assertResponse(200, 'The new comment type can be accessed at the edit form.'); + + // Create a comment type via the user interface. + $edit = array( + 'id' => 'foo', + 'label' => 'title for foo', + 'description' => '', + 'target_entity_type_id' => 'node', + ); + $this->drupalPostForm('admin/structure/comment/types/add', $edit, t('Save')); + $comment_type = CommentType::load('foo'); + $this->assertTrue($comment_type, 'The new comment type has been created.'); + + // Check that the comment type was created in site default language. + $default_langcode = \Drupal::languageManager()->getDefaultLanguage()->id; + $this->assertEqual($comment_type->langcode, $default_langcode); + } + + /** + * Tests editing a comment type using the UI. + */ + public function testCommentTypeEditing() { + $this->drupalLogin($this->adminUser); + + $instance = FieldInstanceConfig::loadByName('comment', 'comment', 'comment_body'); + $this->assertEqual($instance->getLabel(), 'Comment', 'Comment body field was found.'); + + // Change the comment type name. + $this->drupalGet('admin/structure/comment'); + $edit = array( + 'label' => 'Bar', + ); + $this->drupalPostForm('admin/structure/comment/manage/comment', $edit, t('Save')); + + $this->drupalGet('admin/structure/comment'); + $this->assertRaw('Bar', 'New name was displayed.'); + $this->clickLink('Manage fields'); + $this->assertEqual(url('admin/structure/comment/manage/comment/fields', array('absolute' => TRUE)), $this->getUrl(), 'Original machine name was used in URL.'); + + // Remove the body field. + $this->drupalPostForm('admin/structure/comment/manage/comment/fields/comment.comment.comment_body/delete', array(), t('Delete')); + // Resave the settings for this type. + $this->drupalPostForm('admin/structure/comment/manage/comment', array(), t('Save')); + // Check that the body field doesn't exist. + $this->drupalGet('admin/structure/comment/manage/comment/fields'); + $this->assertNoRaw('comment_body', 'Body field was not found.'); + } + + /** + * Tests deleting a comment type that still has content. + */ + public function testCommentTypeDeletion() { + // Create a comment type programmatically. + $type = $this->createCommentType('foo'); + $this->drupalCreateContentType(array('type' => 'page')); + \Drupal::service('comment.manager')->addDefaultField('node', 'page', 'foo', CommentItemInterface::OPEN, 'foo'); + $field = FieldConfig::loadByName('node', 'foo'); + + $this->drupalLogin($this->adminUser); + + // Create a node. + $node = Node::create(array( + 'type' => 'page', + 'title' => 'foo', + )); + $node->save(); + + // Add a new comment of this type. + $comment = Comment::create(array( + 'comment_type' => 'foo', + 'entity_type' => 'node', + 'field_name' => 'foo', + 'entity_id' => $node->id(), + )); + $comment->save(); + + // Attempt to delete the comment type, which should not be allowed. + $this->drupalGet('admin/structure/comment/manage/' . $type->id() . '/delete'); + $this->assertRaw( + t('%label is used by 1 comment on your site. You can not remove this comment type until you have removed all of the %label comments.', array('%label' => $type->label())), + 'The comment type will not be deleted until all comments of that type are removed.' + ); + $this->assertRaw( + t('%label is used by the %field field on your site. You can not remove this comment type until you have removed the field.', array( + '%label' => 'foo', + '%field' => 'node.foo', + )), + 'The comment type will not be deleted until all fields of that type are removed.' + ); + $this->assertNoText(t('This action cannot be undone.'), 'The comment type deletion confirmation form is not available.'); + + // Delete the comment and the field. + $comment->delete(); + $field->delete(); + // Attempt to delete the comment type, which should now be allowed. + $this->drupalGet('admin/structure/comment/manage/' . $type->id() . '/delete'); + $this->assertRaw( + t('Are you sure you want to delete %type?', array('%type' => $type->id())), + 'The comment type is available for deletion.' + ); + $this->assertText(t('This action cannot be undone.'), 'The comment type deletion confirmation form is available.'); + + // Test exception thrown when re-using an existing comment type. + try { + \Drupal::service('comment.manager')->addDefaultField('comment', 'comment', 'bar'); + $this->fail('Exception not thrown.'); + } + catch (\InvalidArgumentException $e) { + $this->pass('Exception thrown if attempting to re-use comment-type from another entity type.'); + } + + // Delete the comment type. + $this->drupalPostForm('admin/structure/comment/manage/' . $type->id() . '/delete', array(), t('Delete')); + $this->assertNull(CommentType::load($type->id()), 'Comment type deleted.'); + $this->assertRaw(t('Comment type %label has been deleted.', array('%label' => $type->label()))); + } + +} diff --git a/core/modules/comment/src/Tests/CommentValidationTest.php b/core/modules/comment/src/Tests/CommentValidationTest.php index b56ed6b..b705b16 100644 --- a/core/modules/comment/src/Tests/CommentValidationTest.php +++ b/core/modules/comment/src/Tests/CommentValidationTest.php @@ -47,11 +47,21 @@ public function setUp() { * Tests the comment validation constraints. */ public function testValidation() { + // Add comment type. + $this->entityManager->getStorage('comment_type')->create(array( + 'id' => 'comment', + 'label' => 'comment', + 'target_entity_type_id' => 'node', + ))->save(); + // Add comment field to content. $this->entityManager->getStorage('field_config')->create(array( 'entity_type' => 'node', 'name' => 'comment', 'type' => 'comment', + 'settings' => array( + 'comment_type' => 'comment', + ) ))->save(); // Create a page node type. diff --git a/core/modules/comment/tests/src/Routing/CommentBundleEnhancerTest.php b/core/modules/comment/tests/src/Routing/CommentBundleEnhancerTest.php deleted file mode 100644 index 95fbe8f..0000000 --- a/core/modules/comment/tests/src/Routing/CommentBundleEnhancerTest.php +++ /dev/null @@ -1,102 +0,0 @@ - 'Comment route enhancer test', - 'description' => 'Tests the comment route enhancer.', - 'group' => 'Comment', - ); - } - - /** - * Data provider for testEnhancer(). - * - * @see testEnhancer() - * - * @return array - * An array of arrays containing strings: - * - The bundle name. - * - The commented entity type. - * - The field name. - */ - public function providerTestEnhancer() { - return array( - array( - 'node__comment', - 'comment', - 'node', - ), - array( - 'node__comment_forum__schnitzel', - 'comment_forum__schnitzel', - 'node', - ), - array( - 'node__field_foobar', - FALSE, - FALSE - ), - ); - } - /** - * Tests the enhancer method. - * - * @param string $bundle - * The bundle name to test. - * @param string $field_name - * The field name expected to be extracted from the bundle. - * @param string $commented_entity_type - * The entity type expected to be extracted from the bundle. - * - * @see \Drupal\comment\Routing\CommentBundleEnhancer::enhancer() - * - * @group Drupal - * @group Routing - * - * @dataProvider providerTestEnhancer - */ - public function testEnhancer($bundle, $field_name, $commented_entity_type) { - $entity_manager = $this->getMock('Drupal\Core\Entity\EntityManagerInterface'); - $entity_manager->expects($this->any()) - ->method('getBundleInfo') - ->will($this->returnValue(array( - 'node__comment' => array(), - // Test two sets of __. - 'node__comment_forum__schnitzel' => array(), - ))); - $route_enhancer = new CommentBundleEnhancer($entity_manager); - - // Test the enhancer. - $request = new Request(); - $defaults = array('bundle' => $bundle); - $new_defaults = $route_enhancer->enhance($defaults, $request); - if ($commented_entity_type) { - // A valid comment bundle. - $this->assertEquals($new_defaults['field_name'], $field_name); - $this->assertEquals($new_defaults['commented_entity_type'], $commented_entity_type); - } - else { - // Non-comment bundle. - $this->assertTrue(empty($new_defaults['field_name'])); - $this->assertTrue(empty($new_defaults['commented_entity_type'])); - } - } - -} diff --git a/core/modules/content_translation/src/Tests/ContentTranslationSettingsTest.php b/core/modules/content_translation/src/Tests/ContentTranslationSettingsTest.php index 8f3b803..084900c 100644 --- a/core/modules/content_translation/src/Tests/ContentTranslationSettingsTest.php +++ b/core/modules/content_translation/src/Tests/ContentTranslationSettingsTest.php @@ -7,7 +7,8 @@ namespace Drupal\content_translation\Tests; -use Drupal\Core\Language\LanguageInterface; +use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface; +use Drupal\Core\Language\Language; use Drupal\field\Entity\FieldConfig; use Drupal\simpletest\WebTestBase; @@ -38,9 +39,9 @@ function setUp() { // bundles. $this->drupalCreateContentType(array('type' => 'article')); $this->drupalCreateContentType(array('type' => 'page')); - $this->container->get('comment.manager')->addDefaultField('node', 'article', 'comment_article'); + $this->container->get('comment.manager')->addDefaultField('node', 'article', 'comment_article', CommentItemInterface::OPEN, 'comment_article'); - $admin_user = $this->drupalCreateUser(array('access administration pages', 'administer languages', 'administer content translation', 'administer content types', 'administer node fields', 'administer comment fields')); + $admin_user = $this->drupalCreateUser(array('access administration pages', 'administer languages', 'administer content translation', 'administer content types', 'administer node fields', 'administer comment fields', 'administer comments', 'administer comment types')); $this->drupalLogin($admin_user); } @@ -54,21 +55,21 @@ function testSettingsUI() { $this->assertText('Configure language and translation support for content.'); // Test that the translation settings are ignored if the bundle is marked // translatable but the entity type is not. - $edit = array('settings[comment][node__comment_article][translatable]' => TRUE); + $edit = array('settings[comment][comment_article][translatable]' => TRUE); $this->assertSettings('comment', NULL, FALSE, $edit); // Test that the translation settings are ignored if only a field is marked // as translatable and not the related entity type and bundle. - $edit = array('settings[comment][node__comment_article][fields][comment_body]' => TRUE); + $edit = array('settings[comment][comment_article][fields][comment_body]' => TRUE); $this->assertSettings('comment', NULL, FALSE, $edit); // Test that the translation settings are not stored if an entity type and // bundle are marked as translatable but no field is. $edit = array( 'entity_types[comment]' => TRUE, - 'settings[comment][node__comment_article][translatable]' => TRUE, + 'settings[comment][comment_article][translatable]' => TRUE, ); - $this->assertSettings('comment', 'node__comment_article', FALSE, $edit); + $this->assertSettings('comment', 'comment_article', FALSE, $edit); $xpath_err = '//div[contains(@class, "error")]'; $this->assertTrue($this->xpath($xpath_err), 'Enabling translation only for entity bundles generates a form error.'); @@ -76,36 +77,36 @@ function testSettingsUI() { // language is set as default and the language selector is hidden. $edit = array( 'entity_types[comment]' => TRUE, - 'settings[comment][node__comment_article][settings][language][langcode]' => LanguageInterface::LANGCODE_NOT_SPECIFIED, - 'settings[comment][node__comment_article][settings][language][language_show]' => FALSE, - 'settings[comment][node__comment_article][translatable]' => TRUE, - 'settings[comment][node__comment_article][fields][comment_body]' => TRUE, + 'settings[comment][comment_article][settings][language][langcode]' => Language::LANGCODE_NOT_SPECIFIED, + 'settings[comment][comment_article][settings][language][language_show]' => FALSE, + 'settings[comment][comment_article][translatable]' => TRUE, + 'settings[comment][comment_article][fields][comment_body]' => TRUE, ); - $this->assertSettings('comment', 'node__comment_article', FALSE, $edit); + $this->assertSettings('comment', 'comment_article', FALSE, $edit); $this->assertTrue($this->xpath($xpath_err), 'Enabling translation with a fixed non-configurable language generates a form error.'); // Test that a field shared among different bundles can be enabled without // needing to make all the related bundles translatable. $edit = array( 'entity_types[comment]' => TRUE, - 'settings[comment][node__comment_article][settings][language][langcode]' => 'current_interface', - 'settings[comment][node__comment_article][settings][language][language_show]' => TRUE, - 'settings[comment][node__comment_article][translatable]' => TRUE, - 'settings[comment][node__comment_article][fields][comment_body]' => TRUE, + 'settings[comment][comment_article][settings][language][langcode]' => 'current_interface', + 'settings[comment][comment_article][settings][language][language_show]' => TRUE, + 'settings[comment][comment_article][translatable]' => TRUE, + 'settings[comment][comment_article][fields][comment_body]' => TRUE, ); - $this->assertSettings('comment', 'node__comment_article', TRUE, $edit); + $this->assertSettings('comment', 'comment_article', TRUE, $edit); $field = FieldConfig::loadByName('comment', 'comment_body'); $this->assertTrue($field->isTranslatable(), 'Comment body is translatable.'); // Test that language settings are correctly stored. - $language_configuration = language_get_default_configuration('comment', 'node__comment_article'); + $language_configuration = language_get_default_configuration('comment', 'comment_article'); $this->assertEqual($language_configuration['langcode'], 'current_interface', 'The default language for article comments is set to the current interface language.'); $this->assertTrue($language_configuration['language_show'], 'The language selector for article comments is shown.'); - // Verify language widget appears on node type form. - $this->drupalGet('admin/structure/comments/manage/node__comment_article/fields/comment.node__comment_article.comment_body/field'); - $this->assertField('field[translatable]'); - $this->assertFieldChecked('edit-field-translatable'); + // Verify language widget appears on comment type form. + $this->drupalGet('admin/structure/comment/manage/comment_article'); + $this->assertField('language_configuration[content_translation]'); + $this->assertFieldChecked('edit-language-configuration-content-translation'); // Verify that translation may be enabled for the article content type. $edit = array( diff --git a/core/modules/datetime/src/Plugin/Field/FieldType/DateTimeItem.php b/core/modules/datetime/src/Plugin/Field/FieldType/DateTimeItem.php index e3669de..615ca1e 100644 --- a/core/modules/datetime/src/Plugin/Field/FieldType/DateTimeItem.php +++ b/core/modules/datetime/src/Plugin/Field/FieldType/DateTimeItem.php @@ -83,7 +83,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(); $element['datetime_type'] = array( diff --git a/core/modules/entity_reference/src/ConfigurableEntityReferenceItem.php b/core/modules/entity_reference/src/ConfigurableEntityReferenceItem.php index e5ad209..36769ef 100644 --- a/core/modules/entity_reference/src/ConfigurableEntityReferenceItem.php +++ b/core/modules/entity_reference/src/ConfigurableEntityReferenceItem.php @@ -159,7 +159,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['target_type'] = array( '#type' => 'select', '#title' => t('Type of item to reference'), diff --git a/core/modules/entity_reference/src/Tests/EntityReferenceSelectionAccessTest.php b/core/modules/entity_reference/src/Tests/EntityReferenceSelectionAccessTest.php index 8f9ce99..7c96563 100644 --- a/core/modules/entity_reference/src/Tests/EntityReferenceSelectionAccessTest.php +++ b/core/modules/entity_reference/src/Tests/EntityReferenceSelectionAccessTest.php @@ -451,7 +451,7 @@ public function testCommentHandler() { array(NULL, 'CONTAINS'), ), 'result' => array( - 'node__comment' => array( + 'comment' => array( $comments['published_published']->cid->value => $comment_labels['published_published'], ), ), @@ -461,7 +461,7 @@ public function testCommentHandler() { array('Published', 'CONTAINS'), ), 'result' => array( - 'node__comment' => array( + 'comment' => array( $comments['published_published']->cid->value => $comment_labels['published_published'], ), ), @@ -490,7 +490,7 @@ public function testCommentHandler() { array(NULL, 'CONTAINS'), ), 'result' => array( - 'node__comment' => array( + 'comment' => array( $comments['published_published']->cid->value => $comment_labels['published_published'], $comments['published_unpublished']->cid->value => $comment_labels['published_unpublished'], ), @@ -508,7 +508,7 @@ public function testCommentHandler() { array(NULL, 'CONTAINS'), ), 'result' => array( - 'node__comment' => array( + 'comment' => array( $comments['published_published']->cid->value => $comment_labels['published_published'], $comments['published_unpublished']->cid->value => $comment_labels['published_unpublished'], $comments['unpublished_published']->cid->value => $comment_labels['unpublished_published'], diff --git a/core/modules/field/tests/modules/field_test/src/Plugin/Field/FieldType/TestItem.php b/core/modules/field/tests/modules/field_test/src/Plugin/Field/FieldType/TestItem.php index e215833..e21b180 100644 --- a/core/modules/field/tests/modules/field_test/src/Plugin/Field/FieldType/TestItem.php +++ b/core/modules/field/tests/modules/field_test/src/Plugin/Field/FieldType/TestItem.php @@ -76,7 +76,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) { $form['test_field_setting'] = array( '#type' => 'textfield', '#title' => t('Field test field setting'), diff --git a/core/modules/field_ui/src/Form/FieldEditForm.php b/core/modules/field_ui/src/Form/FieldEditForm.php index 068bd71..68e6849 100644 --- a/core/modules/field_ui/src/Form/FieldEditForm.php +++ b/core/modules/field_ui/src/Form/FieldEditForm.php @@ -151,6 +151,8 @@ public function buildForm(array $form, array &$form_state, FieldInstanceConfigIn $form['actions'] = array('#type' => 'actions'); $form['actions']['submit'] = array('#type' => 'submit', '#value' => $this->t('Save field settings')); + $form['#submit'][] = array($this, 'submitForm'); + $form['#validate'][] = array($this, 'validateForm'); return $form; } diff --git a/core/modules/file/src/Plugin/Field/FieldType/FileItem.php b/core/modules/file/src/Plugin/Field/FieldType/FileItem.php index 27ce2ab..7f479dd 100644 --- a/core/modules/file/src/Plugin/Field/FieldType/FileItem.php +++ b/core/modules/file/src/Plugin/Field/FieldType/FileItem.php @@ -106,7 +106,7 @@ public static function propertyDefinitions(FieldStorageDefinitionInterface $fiel /** * {@inheritdoc} */ - public function settingsForm(array $form, array &$form_state, $has_data) { + public function settingsForm(array &$form, array &$form_state, $has_data) { $element = array(); $element['#attached']['library'][] = 'file/drupal.file'; diff --git a/core/modules/file/src/Tests/FileFieldWidgetTest.php b/core/modules/file/src/Tests/FileFieldWidgetTest.php index 2657289..3978501 100644 --- a/core/modules/file/src/Tests/FileFieldWidgetTest.php +++ b/core/modules/file/src/Tests/FileFieldWidgetTest.php @@ -258,7 +258,7 @@ function testPrivateFileComment() { 'fields[_add_new_field][field_name]' => $name = strtolower($this->randomName()), 'fields[_add_new_field][type]' => 'file', ); - $this->drupalPostForm('admin/structure/comments/manage/node__comment/fields', $edit, t('Save')); + $this->drupalPostForm('admin/structure/comment/manage/comment/fields', $edit, t('Save')); $edit = array('field[settings][uri_scheme]' => 'private'); $this->drupalPostForm(NULL, $edit, t('Save field settings')); $this->drupalPostForm(NULL, array(), t('Save settings')); diff --git a/core/modules/forum/forum.install b/core/modules/forum/forum.install index dafedba..1f5ed4f 100644 --- a/core/modules/forum/forum.install +++ b/core/modules/forum/forum.install @@ -4,6 +4,8 @@ * @file * Install, update, and uninstall functions for the Forum module. */ + +use Drupal\comment\Plugin\Field\FieldType\CommentItemInterface; use Drupal\field\Entity\FieldConfig; /** @@ -84,7 +86,7 @@ function forum_install() { 'include_deleted' => FALSE, )); if (empty($fields)) { - Drupal::service('comment.manager')->addDefaultField('node', 'forum', 'comment_forum'); + Drupal::service('comment.manager')->addDefaultField('node', 'forum', 'comment_forum', CommentItemInterface::OPEN, 'comment_forum'); } } } diff --git a/core/modules/forum/src/ForumIndexStorage.php b/core/modules/forum/src/ForumIndexStorage.php index 2d257a4..d732806 100644 --- a/core/modules/forum/src/ForumIndexStorage.php +++ b/core/modules/forum/src/ForumIndexStorage.php @@ -96,14 +96,14 @@ public function update(NodeInterface $node) { */ public function updateIndex(NodeInterface $node) { $nid = $node->id(); - $count = $this->database->query("SELECT COUNT(cid) FROM {comment} c INNER JOIN {forum_index} i ON c.entity_id = i.nid WHERE c.entity_id = :nid AND c.field_id = 'node__comment_forum' AND c.entity_type = 'node' AND c.status = :status", array( + $count = $this->database->query("SELECT COUNT(cid) FROM {comment} c INNER JOIN {forum_index} i ON c.entity_id = i.nid WHERE c.entity_id = :nid AND c.field_name = 'comment_forum' AND c.entity_type = 'node' AND c.status = :status", array( ':nid' => $nid, ':status' => CommentInterface::PUBLISHED, ))->fetchField(); if ($count > 0) { // Comments exist. - $last_reply = $this->database->queryRange("SELECT cid, name, created, uid FROM {comment} WHERE entity_id = :nid AND field_id = 'node__comment_forum' AND entity_type = 'node' AND status = :status ORDER BY cid DESC", 0, 1, array( + $last_reply = $this->database->queryRange("SELECT cid, name, created, uid FROM {comment} WHERE entity_id = :nid AND field_name = 'comment_forum' AND entity_type = 'node' AND status = :status ORDER BY cid DESC", 0, 1, array( ':nid' => $nid, ':status' => CommentInterface::PUBLISHED, ))->fetchObject(); diff --git a/core/modules/forum/src/ForumManager.php b/core/modules/forum/src/ForumManager.php index 8b87680..1609899 100644 --- a/core/modules/forum/src/ForumManager.php +++ b/core/modules/forum/src/ForumManager.php @@ -169,7 +169,7 @@ public function getTopics($tid, AccountInterface $account) { ->extend('Drupal\Core\Database\Query\TableSortExtender'); $query->fields('n', array('nid')); - $query->join('comment_entity_statistics', 'ces', "n.nid = ces.entity_id AND ces.field_id = 'node__comment_forum' AND ces.entity_type = 'node'"); + $query->join('comment_entity_statistics', 'ces', "n.nid = ces.entity_id AND ces.field_name = 'comment_forum' AND ces.entity_type = 'node'"); $query->fields('ces', array( 'cid', 'last_comment_uid', @@ -340,7 +340,7 @@ protected function getLastPost($tid) { // Query "Last Post" information for this forum. $query = $this->connection->select('node_field_data', 'n'); $query->join('forum', 'f', 'n.vid = f.vid AND f.tid = :tid', array(':tid' => $tid)); - $query->join('comment_entity_statistics', 'ces', "n.nid = ces.entity_id AND ces.field_id = 'node__comment_forum' AND ces.entity_type = 'node'"); + $query->join('comment_entity_statistics', 'ces', "n.nid = ces.entity_id AND ces.field_name = 'comment_forum' AND ces.entity_type = 'node'"); $query->join('users', 'u', 'ces.last_comment_uid = u.uid'); $query->addExpression('CASE ces.last_comment_uid WHEN 0 THEN ces.last_comment_name ELSE u.name END', 'last_comment_name'); @@ -378,7 +378,7 @@ protected function getForumStatistics($tid) { if (empty($this->forumStatistics)) { // Prime the statistics. $query = $this->connection->select('node_field_data', 'n'); - $query->join('comment_entity_statistics', 'ces', "n.nid = ces.entity_id AND ces.field_id = 'node__comment_forum' AND ces.entity_type = 'node'"); + $query->join('comment_entity_statistics', 'ces', "n.nid = ces.entity_id AND ces.field_name = 'comment_forum' AND ces.entity_type = 'node'"); $query->join('forum', 'f', 'n.vid = f.vid'); $query->addExpression('COUNT(n.nid)', 'topic_count'); $query->addExpression('SUM(ces.comment_count)', 'comment_count'); diff --git a/core/modules/forum/src/Tests/ForumUninstallTest.php b/core/modules/forum/src/Tests/ForumUninstallTest.php index 130143f..3b38876 100644 --- a/core/modules/forum/src/Tests/ForumUninstallTest.php +++ b/core/modules/forum/src/Tests/ForumUninstallTest.php @@ -77,7 +77,7 @@ function testForumUninstallWithField() { // We want to test the handling of removing the forum comment field, so we // ensure there is at least one other comment field attached to a node type // so that comment_entity_load() runs for nodes. - \Drupal::service('comment.manager')->addDefaultField('node', 'forum', 'another_comment_field', CommentItemInterface::OPEN); + \Drupal::service('comment.manager')->addDefaultField('node', 'forum', 'another_comment_field', CommentItemInterface::OPEN, 'another_comment_field'); $this->drupalGet('node/' . $node->nid->value); $this->assertResponse(200); diff --git a/core/modules/hal/src/Tests/EntityTest.php b/core/modules/hal/src/Tests/EntityTest.php index 8bc3fed..d9a9004 100644 --- a/core/modules/hal/src/Tests/EntityTest.php +++ b/core/modules/hal/src/Tests/EntityTest.php @@ -54,6 +54,15 @@ public function testNode() { $user = entity_create('user', array('name' => $this->randomName())); $user->save(); + // Add comment type. + $this->container->get('entity.manager')->getStorage('comment_type')->create(array( + 'id' => 'comment', + 'label' => 'comment', + 'target_entity_type_id' => 'node', + ))->save(); + + $this->container->get('comment.manager')->addDefaultField('node', 'example_type'); + $node = entity_create('node', array( 'title' => $this->randomName(), 'uid' => $user->id(), @@ -129,6 +138,15 @@ public function testComment() { $user = entity_create('user', array('name' => $this->randomName())); $user->save(); + // Add comment type. + $this->container->get('entity.manager')->getStorage('comment_type')->create(array( + 'id' => 'comment', + 'label' => 'comment', + 'target_entity_type_id' => 'node', + ))->save(); + + $this->container->get('comment.manager')->addDefaultField('node', 'example_type'); + $node = entity_create('node', array( 'title' => $this->randomName(), 'uid' => $user->id(), @@ -143,8 +161,6 @@ public function testComment() { )); $node->save(); - $this->container->get('comment.manager')->addDefaultField('node', 'example_type'); - $comment = entity_create('comment', array( 'uid' => $user->id(), 'subject' => $this->randomName(), diff --git a/core/modules/image/src/Plugin/Field/FieldType/ImageItem.php b/core/modules/image/src/Plugin/Field/FieldType/ImageItem.php index f94c51d..49d2e25 100644 --- a/core/modules/image/src/Plugin/Field/FieldType/ImageItem.php +++ b/core/modules/image/src/Plugin/Field/FieldType/ImageItem.php @@ -152,7 +152,7 @@ public static function propertyDefinitions(FieldStorageDefinitionInterface $fiel /** * {@inheritdoc} */ - public function settingsForm(array $form, array &$form_state, $has_data) { + public function settingsForm(array &$form, array &$form_state, $has_data) { $element = array(); // We need the field-level 'default_image' setting, and $this->getSettings() diff --git a/core/modules/migrate_drupal/config/install/migrate.migration.d6_comment.yml b/core/modules/migrate_drupal/config/install/migrate.migration.d6_comment.yml index 961cb40..34e681e 100644 --- a/core/modules/migrate_drupal/config/install/migrate.migration.d6_comment.yml +++ b/core/modules/migrate_drupal/config/install/migrate.migration.d6_comment.yml @@ -3,7 +3,8 @@ label: Drupal 6 comments source: plugin: d6_comment constants: - field_id: node__comment + field_name: comment + comment_type: comment entity_type: node process: cid: cid @@ -19,7 +20,8 @@ process: migration: d6_node source: nid entity_type: constants.entity_type - field_id: constants.field_id + field_name: constants.field_name + comment_type: constants.comment_type subject: subject uid: - @@ -44,6 +46,8 @@ process: destination: plugin: entity:comment migration_dependencies: + optional: + - d6_comment_type required: - d6_node - d6_user diff --git a/core/modules/migrate_drupal/config/install/migrate.migration.d6_comment_field.yml b/core/modules/migrate_drupal/config/install/migrate.migration.d6_comment_field.yml index 5c4dd3b..2a5ccc4 100644 --- a/core/modules/migrate_drupal/config/install/migrate.migration.d6_comment_field.yml +++ b/core/modules/migrate_drupal/config/install/migrate.migration.d6_comment_field.yml @@ -7,10 +7,13 @@ source: type: comment id: node.comment name: comment + settings: + content_type: comment process: entity_type: constants.entity_type id: constants.id name: constants.name type: constants.type + settings: constants.settings destination: plugin: entity:field_config diff --git a/core/modules/migrate_drupal/config/install/migrate.migration.d6_comment_type.yml b/core/modules/migrate_drupal/config/install/migrate.migration.d6_comment_type.yml new file mode 100644 index 0000000..6bd490b --- /dev/null +++ b/core/modules/migrate_drupal/config/install/migrate.migration.d6_comment_type.yml @@ -0,0 +1,25 @@ +id: d6_comment_type +label: Drupal 6 comment type +source: + plugin: variable + variables: + # Ensure that we get at least one row to process by using variables that exist + # on every Drupal 6 site. We just need a single one of these, but include a + # few to be sure. + - site_name + - menu_expanded + - menu_masks + - css_js_query_string + - clean_url + constants: + entity_type: node + id: comment + label: comment + description: comment +process: + target_entity_type_id: constants.entity_type + id: constants.id + label: constants.label + description: constants.description +destination: + plugin: entity:comment_type diff --git a/core/modules/migrate_drupal/src/Tests/d6/MigrateCommentTest.php b/core/modules/migrate_drupal/src/Tests/d6/MigrateCommentTest.php index c8cb1a6..d07b02b 100644 --- a/core/modules/migrate_drupal/src/Tests/d6/MigrateCommentTest.php +++ b/core/modules/migrate_drupal/src/Tests/d6/MigrateCommentTest.php @@ -13,7 +13,7 @@ use Drupal\migrate_drupal\Tests\MigrateDrupalTestBase; /** - * Tests the Drupal 6 to Drupal 6 comment migration. + * Tests the Drupal 6 to Drupal 8 comment migration. */ class MigrateCommentTest extends MigrateDrupalTestBase { @@ -37,6 +37,12 @@ public static function getInfo() { public function setUp() { parent::setUp(); entity_create('node_type', array('type' => 'page'))->save(); + $this->container->get('entity.manager')->getStorage('comment_type')->create(array( + 'id' => 'comment', + 'label' => 'comment', + 'target_entity_type_id' => 'node', + ))->save(); + $node = entity_create('node', array( 'type' => 'page', 'nid' => 1, @@ -65,7 +71,7 @@ public function setUp() { } /** - * Tests the Drupal 6 to Drupal 6 comment migration. + * Tests the Drupal 6 to Drupal 8 comment migration. */ public function testComments() { /** @var Comment $comment */ diff --git a/core/modules/migrate_drupal/src/Tests/d6/MigrateCommentTypeTest.php b/core/modules/migrate_drupal/src/Tests/d6/MigrateCommentTypeTest.php new file mode 100644 index 0000000..9550df3 --- /dev/null +++ b/core/modules/migrate_drupal/src/Tests/d6/MigrateCommentTypeTest.php @@ -0,0 +1,58 @@ + 'Migrate comment type.', + 'description' => 'Upgrade comment type.', + 'group' => 'Migrate Drupal', + ); + } + + + /** + * {@inheritdoc} + */ + public function setUp() { + parent::setUp(); + + /** @var \Drupal\migrate\entity\Migration $migration */ + $migration = entity_load('migration', 'd6_comment_type'); + + $dumps = array( + $this->getDumpDirectory() . '/Drupal6SystemSite.php', + ); + $this->prepare($migration, $dumps); + $executable = new MigrateExecutable($migration, $this); + $executable->import(); + } + + /** + * Tests the Drupal 6 to Drupal 8 comment type migration. + */ + public function testCommentType() { + $comment_type = entity_load('comment_type', 'comment'); + $this->assertEqual('node', $comment_type->getTargetEntityTypeId()); + } +} diff --git a/core/modules/migrate_drupal/src/Tests/d6/MigrateDrupal6Test.php b/core/modules/migrate_drupal/src/Tests/d6/MigrateDrupal6Test.php index 79f11da..592992e 100644 --- a/core/modules/migrate_drupal/src/Tests/d6/MigrateDrupal6Test.php +++ b/core/modules/migrate_drupal/src/Tests/d6/MigrateDrupal6Test.php @@ -61,6 +61,7 @@ class MigrateDrupal6Test extends MigrateFullDrupalTestBase { 'd6_book_settings', 'd6_cck_field_values:*', 'd6_cck_field_revision:*', + 'd6_comment_type', 'd6_comment', 'd6_comment_entity_display', 'd6_comment_entity_form_display', @@ -228,6 +229,7 @@ protected function getTestClassesList() { __NAMESPACE__ . '\MigrateBookConfigsTest', __NAMESPACE__ . '\MigrateCckFieldValuesTest', __NAMESPACE__ . '\MigrateCckFieldRevisionTest', + __NAMESPACE__ . '\MigrateCommentTypeTest', __NAMESPACE__ . '\MigrateCommentTest', __NAMESPACE__ . '\MigrateCommentVariableEntityDisplay', __NAMESPACE__ . '\MigrateCommentVariableEntityFormDisplay', diff --git a/core/modules/options/src/Plugin/Field/FieldType/ListBooleanItem.php b/core/modules/options/src/Plugin/Field/FieldType/ListBooleanItem.php index 095c89c..5d16585 100644 --- a/core/modules/options/src/Plugin/Field/FieldType/ListBooleanItem.php +++ b/core/modules/options/src/Plugin/Field/FieldType/ListBooleanItem.php @@ -102,7 +102,7 @@ public function isEmpty() { /** * {@inheritdoc} */ - public function settingsForm(array $form, array &$form_state, $has_data) { + public function settingsForm(array &$form, array &$form_state, $has_data) { $allowed_values = $this->getSetting('allowed_values'); $allowed_values_function = $this->getSetting('allowed_values_function'); diff --git a/core/modules/options/src/Plugin/Field/FieldType/ListItemBase.php b/core/modules/options/src/Plugin/Field/FieldType/ListItemBase.php index 64604e5..d61aef1 100644 --- a/core/modules/options/src/Plugin/Field/FieldType/ListItemBase.php +++ b/core/modules/options/src/Plugin/Field/FieldType/ListItemBase.php @@ -72,7 +72,7 @@ public function isEmpty() { /** * {@inheritdoc} */ - public function settingsForm(array $form, array &$form_state, $has_data) { + public function settingsForm(array &$form, array &$form_state, $has_data) { $allowed_values = $this->getSetting('allowed_values'); $allowed_values_function = $this->getSetting('allowed_values_function'); diff --git a/core/modules/rdf/src/Tests/CommentAttributesTest.php b/core/modules/rdf/src/Tests/CommentAttributesTest.php index d3cacfd..d58e44b 100644 --- a/core/modules/rdf/src/Tests/CommentAttributesTest.php +++ b/core/modules/rdf/src/Tests/CommentAttributesTest.php @@ -68,7 +68,7 @@ public function setUp() { $user_mapping->setFieldMapping('homepage', array('properties' => array('foaf:page'), 'mapping_type' => 'rel'))->save(); // Save comment mapping. - $mapping = rdf_get_mapping('comment', 'node__comment'); + $mapping = rdf_get_mapping('comment', 'comment'); $mapping->setBundleMapping(array('types' => array('sioc:Post', 'sioct:Comment')))->save(); $field_mappings = array( 'subject' => array( diff --git a/core/modules/taxonomy/src/Plugin/Field/FieldType/TaxonomyTermReferenceItem.php b/core/modules/taxonomy/src/Plugin/Field/FieldType/TaxonomyTermReferenceItem.php index cc8ef7e..fb6a93e 100644 --- a/core/modules/taxonomy/src/Plugin/Field/FieldType/TaxonomyTermReferenceItem.php +++ b/core/modules/taxonomy/src/Plugin/Field/FieldType/TaxonomyTermReferenceItem.php @@ -119,7 +119,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) { $vocabularies = entity_load_multiple('taxonomy_vocabulary'); $options = array(); foreach ($vocabularies as $vocabulary) { diff --git a/core/modules/text/src/Plugin/Field/FieldType/TextItem.php b/core/modules/text/src/Plugin/Field/FieldType/TextItem.php index b2ba0a1..6bacea6 100644 --- a/core/modules/text/src/Plugin/Field/FieldType/TextItem.php +++ b/core/modules/text/src/Plugin/Field/FieldType/TextItem.php @@ -78,7 +78,7 @@ public function getConstraints() { /** * {@inheritdoc} */ - public function settingsForm(array $form, array &$form_state, $has_data) { + public function settingsForm(array &$form, array &$form_state, $has_data) { $element = array(); $element['max_length'] = array( diff --git a/core/profiles/standard/config/install/comment.type.comment.yml b/core/profiles/standard/config/install/comment.type.comment.yml new file mode 100644 index 0000000..6510287 --- /dev/null +++ b/core/profiles/standard/config/install/comment.type.comment.yml @@ -0,0 +1,6 @@ +id: comment +label: 'Default comments' +description: 'Allows commenting on content' +target_entity_type_id: node +status: true +langcode: en diff --git a/core/profiles/standard/config/install/rdf.mapping.comment.node__comment.yml b/core/profiles/standard/config/install/rdf.mapping.comment.comment.yml similarity index 87% rename from core/profiles/standard/config/install/rdf.mapping.comment.node__comment.yml rename to core/profiles/standard/config/install/rdf.mapping.comment.comment.yml index 70f25b1..00abf0c 100644 --- a/core/profiles/standard/config/install/rdf.mapping.comment.node__comment.yml +++ b/core/profiles/standard/config/install/rdf.mapping.comment.comment.yml @@ -1,6 +1,6 @@ -id: comment.node__comment +id: comment.comment targetEntityType: comment -bundle: node__comment +bundle: comment types: - 'schema:Comment' fieldMappings: @@ -27,3 +27,5 @@ fieldMappings: dependencies: module: - comment + entity: + - comment.type.comment