1<?php 2 3namespace Drupal\comment\Plugin\Field\FieldType; 4 5use Drupal\comment\CommentInterface; 6use Drupal\comment\CommentManagerInterface; 7use Drupal\comment\Entity\CommentType; 8use Drupal\Core\Field\FieldDefinitionInterface; 9use Drupal\Core\Field\FieldStorageDefinitionInterface; 10use Drupal\Core\Form\FormStateInterface; 11use Drupal\Core\TypedData\DataDefinition; 12use Drupal\Core\Field\FieldItemBase; 13use Drupal\Core\Session\AnonymousUserSession; 14use Drupal\Core\Url; 15 16/** 17 * Plugin implementation of the 'comment' field type. 18 * 19 * @FieldType( 20 * id = "comment", 21 * label = @Translation("Comments"), 22 * description = @Translation("This field manages configuration and presentation of comments on an entity."), 23 * list_class = "\Drupal\comment\CommentFieldItemList", 24 * default_widget = "comment_default", 25 * default_formatter = "comment_default", 26 * cardinality = 1, 27 * ) 28 */ 29class CommentItem extends FieldItemBase implements CommentItemInterface { 30 31 /** 32 * {@inheritdoc} 33 */ 34 public static function defaultStorageSettings() { 35 return [ 36 'comment_type' => '', 37 ] + parent::defaultStorageSettings(); 38 } 39 40 /** 41 * {@inheritdoc} 42 */ 43 public static function defaultFieldSettings() { 44 return [ 45 'default_mode' => CommentManagerInterface::COMMENT_MODE_THREADED, 46 'per_page' => 50, 47 'form_location' => CommentItemInterface::FORM_BELOW, 48 'anonymous' => CommentInterface::ANONYMOUS_MAYNOT_CONTACT, 49 'preview' => DRUPAL_OPTIONAL, 50 ] + parent::defaultFieldSettings(); 51 } 52 53 /** 54 * {@inheritdoc} 55 */ 56 public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) { 57 $properties['status'] = DataDefinition::create('integer') 58 ->setLabel(t('Comment status')) 59 ->setRequired(TRUE); 60 61 $properties['cid'] = DataDefinition::create('integer') 62 ->setLabel(t('Last comment ID')); 63 64 $properties['last_comment_timestamp'] = DataDefinition::create('integer') 65 ->setLabel(t('Last comment timestamp')) 66 ->setDescription(t('The time that the last comment was created.')); 67 68 $properties['last_comment_name'] = DataDefinition::create('string') 69 ->setLabel(t('Last comment name')) 70 ->setDescription(t('The name of the user posting the last comment.')); 71 72 $properties['last_comment_uid'] = DataDefinition::create('integer') 73 ->setLabel(t('Last comment user ID')); 74 75 $properties['comment_count'] = DataDefinition::create('integer') 76 ->setLabel(t('Number of comments')) 77 ->setDescription(t('The number of comments.')); 78 79 return $properties; 80 } 81 82 /** 83 * {@inheritdoc} 84 */ 85 public static function schema(FieldStorageDefinitionInterface $field_definition) { 86 return [ 87 'columns' => [ 88 'status' => [ 89 'description' => 'Whether comments are allowed on this entity: 0 = no, 1 = closed (read only), 2 = open (read/write).', 90 'type' => 'int', 91 'default' => 0, 92 ], 93 ], 94 'indexes' => [], 95 'foreign keys' => [], 96 ]; 97 } 98 99 /** 100 * {@inheritdoc} 101 */ 102 public function fieldSettingsForm(array $form, FormStateInterface $form_state) { 103 $element = []; 104 105 $settings = $this->getSettings(); 106 107 $anonymous_user = new AnonymousUserSession(); 108 109 $element['default_mode'] = [ 110 '#type' => 'checkbox', 111 '#title' => t('Threading'), 112 '#default_value' => $settings['default_mode'], 113 '#description' => t('Show comment replies in a threaded list.'), 114 ]; 115 $element['per_page'] = [ 116 '#type' => 'number', 117 '#title' => t('Comments per page'), 118 '#default_value' => $settings['per_page'], 119 '#required' => TRUE, 120 '#min' => 1, 121 '#max' => 1000, 122 ]; 123 $element['anonymous'] = [ 124 '#type' => 'select', 125 '#title' => t('Anonymous commenting'), 126 '#default_value' => $settings['anonymous'], 127 '#options' => [ 128 CommentInterface::ANONYMOUS_MAYNOT_CONTACT => t('Anonymous posters may not enter their contact information'), 129 CommentInterface::ANONYMOUS_MAY_CONTACT => t('Anonymous posters may leave their contact information'), 130 CommentInterface::ANONYMOUS_MUST_CONTACT => t('Anonymous posters must leave their contact information'), 131 ], 132 '#access' => $anonymous_user->hasPermission('post comments'), 133 ]; 134 $element['form_location'] = [ 135 '#type' => 'checkbox', 136 '#title' => t('Show reply form on the same page as comments'), 137 '#default_value' => $settings['form_location'], 138 ]; 139 $element['preview'] = [ 140 '#type' => 'radios', 141 '#title' => t('Preview comment'), 142 '#default_value' => $settings['preview'], 143 '#options' => [ 144 DRUPAL_DISABLED => t('Disabled'), 145 DRUPAL_OPTIONAL => t('Optional'), 146 DRUPAL_REQUIRED => t('Required'), 147 ], 148 ]; 149 150 return $element; 151 } 152 153 /** 154 * {@inheritdoc} 155 */ 156 public static function mainPropertyName() { 157 return 'status'; 158 } 159 160 /** 161 * {@inheritdoc} 162 */ 163 public function isEmpty() { 164 // There is always a value for this field, it is one of 165 // CommentItemInterface::OPEN, CommentItemInterface::CLOSED or 166 // CommentItemInterface::HIDDEN. 167 return FALSE; 168 } 169 170 /** 171 * {@inheritdoc} 172 */ 173 public function storageSettingsForm(array &$form, FormStateInterface $form_state, $has_data) { 174 $element = []; 175 176 // @todo Inject entity storage once typed-data supports container injection. 177 // See https://www.drupal.org/node/2053415 for more details. 178 $comment_types = CommentType::loadMultiple(); 179 $options = []; 180 $entity_type = $this->getEntity()->getEntityTypeId(); 181 foreach ($comment_types as $comment_type) { 182 if ($comment_type->getTargetEntityTypeId() == $entity_type) { 183 $options[$comment_type->id()] = $comment_type->label(); 184 } 185 } 186 $element['comment_type'] = [ 187 '#type' => 'select', 188 '#title' => t('Comment type'), 189 '#options' => $options, 190 '#required' => TRUE, 191 '#description' => $this->t('Select the Comment type to use for this comment field. Manage the comment types from the <a href=":url">administration overview page</a>.', [':url' => Url::fromRoute('entity.comment_type.collection')->toString()]), 192 '#default_value' => $this->getSetting('comment_type'), 193 '#disabled' => $has_data, 194 ]; 195 return $element; 196 } 197 198 /** 199 * {@inheritdoc} 200 */ 201 public static function generateSampleValue(FieldDefinitionInterface $field_definition) { 202 $statuses = [ 203 CommentItemInterface::HIDDEN, 204 CommentItemInterface::CLOSED, 205 CommentItemInterface::OPEN, 206 ]; 207 return [ 208 'status' => $statuses[mt_rand(0, count($statuses) - 1)], 209 ]; 210 } 211 212} 213