3 namespace Drupal\paragraphs\Entity;
5 use Drupal\Component\Utility\NestedArray;
6 use Drupal\Core\Entity\EntityStorageInterface;
7 use Drupal\Core\Field\BaseFieldDefinition;
8 use Drupal\Core\Entity\ContentEntityBase;
9 use Drupal\Core\Entity\EntityTypeInterface;
10 use Drupal\Core\TypedData\TranslatableInterface;
11 use Drupal\field\Entity\FieldStorageConfig;
12 use Drupal\entity_reference_revisions\EntityNeedsSaveInterface;
13 use Drupal\entity_reference_revisions\EntityNeedsSaveTrait;
14 use Drupal\paragraphs\ParagraphInterface;
15 use Drupal\user\UserInterface;
18 * Defines the Paragraph entity.
24 * label = @Translation("Paragraph"),
25 * bundle_label = @Translation("Paragraph type"),
27 * "view_builder" = "Drupal\paragraphs\ParagraphViewBuilder",
28 * "access" = "Drupal\paragraphs\ParagraphAccessControlHandler",
29 * "storage_schema" = "Drupal\paragraphs\ParagraphStorageSchema",
31 * "default" = "Drupal\Core\Entity\ContentEntityForm",
32 * "delete" = "Drupal\Core\Entity\ContentEntityDeleteForm",
33 * "edit" = "Drupal\Core\Entity\ContentEntityForm"
35 * "views_data" = "Drupal\views\EntityViewsData",
37 * base_table = "paragraphs_item",
38 * data_table = "paragraphs_item_field_data",
39 * revision_table = "paragraphs_item_revision",
40 * revision_data_table = "paragraphs_item_revision_field_data",
41 * translatable = TRUE,
42 * entity_revision_parent_type_field = "parent_type",
43 * entity_revision_parent_id_field = "parent_id",
44 * entity_revision_parent_field_name_field = "parent_field_name",
49 * "langcode" = "langcode",
50 * "revision" = "revision_id"
52 * bundle_entity_type = "paragraphs_type",
53 * field_ui_base_route = "entity.paragraphs_type.edit_form",
54 * common_reference_revisions_target = TRUE,
55 * content_translation_ui_skip = TRUE,
56 * render_cache = FALSE,
57 * default_reference_revision_settings = {
58 * "field_storage_config" = {
61 * "target_type" = "paragraph"
66 * "handler" = "default:paragraph"
69 * "entity_form_display" = {
70 * "type" = "entity_reference_paragraphs"
72 * "entity_view_display" = {
73 * "type" = "entity_reference_revisions_entity_view"
78 class Paragraph extends ContentEntityBase implements ParagraphInterface, EntityNeedsSaveInterface {
80 use EntityNeedsSaveTrait;
83 * The behavior plugin data for the paragraph entity.
85 protected $unserializedBehaviorSettings;
90 public function getParentEntity() {
91 if (!isset($this->get('parent_type')->value) || !isset($this->get('parent_id')->value)) {
95 $parent = \Drupal::entityTypeManager()->getStorage($this->get('parent_type')->value)->load($this->get('parent_id')->value);
97 // Return current translation of parent entity, if it exists.
98 if ($parent != NULL && ($parent instanceof TranslatableInterface) && $parent->hasTranslation($this->language()->getId())) {
99 return $parent->getTranslation($this->language()->getId());
108 public function label() {
110 if ($parent = $this->getParentEntity()) {
111 $parent_field = $this->get('parent_field_name')->value;
112 $values = $parent->{$parent_field};
113 foreach ($values as $key => $value) {
114 if ($value->entity->id() == $this->id()) {
115 $label = $parent->label() . ' > ' . $value->getFieldDefinition()->getLabel();
125 public function preSave(EntityStorageInterface $storage) {
126 parent::preSave($storage);
128 // If no owner has been set explicitly, make the current user the owner.
129 if (!$this->getOwner()) {
130 $this->setOwnerId(\Drupal::currentUser()->id());
132 // If no revision author has been set explicitly, make the node owner the
134 if (!$this->getRevisionAuthor()) {
135 $this->setRevisionAuthorId($this->getOwnerId());
138 // If behavior settings are not set then get them from the entity.
139 if ($this->unserializedBehaviorSettings !== NULL) {
140 $this->set('behavior_settings', serialize($this->unserializedBehaviorSettings));
145 * Gets all the behavior settings.
148 * The array of behavior settings.
150 public function getAllBehaviorSettings() {
151 if ($this->unserializedBehaviorSettings === NULL) {
152 $this->unserializedBehaviorSettings = unserialize($this->get('behavior_settings')->value);
154 if (!is_array($this->unserializedBehaviorSettings)) {
155 $this->unserializedBehaviorSettings = [];
157 return $this->unserializedBehaviorSettings;
161 * Gets the behavior setting of an specific plugin.
163 * @param string $plugin_id
164 * The plugin ID for which to get the settings.
165 * @param string|array $key
166 * Values are stored as a multi-dimensional associative array. If $key is a
167 * string, it will return $values[$key]. If $key is an array, each element
168 * of the array will be used as a nested key. If $key = array('foo', 'bar')
169 * it will return $values['foo']['bar'].
170 * @param mixed $default
171 * (optional) The default value if the specified key does not exist.
174 * The value for the given key.
176 public function &getBehaviorSetting($plugin_id, $key, $default = NULL) {
177 $settings = $this->getAllBehaviorSettings();
179 $value = &NestedArray::getValue($settings, array_merge((array) $plugin_id, (array) $key), $exists);
187 * Sets all the behavior settings of a plugin.
189 * @param array $settings
190 * The behavior settings from the form.
192 public function setAllBehaviorSettings(array $settings) {
193 // Set behavior settings fields.
194 $this->unserializedBehaviorSettings = $settings;
198 * Sets the behavior settings of a plugin.
200 * @param string $plugin_id
201 * The plugin ID for which to set the settings.
202 * @param array $settings
203 * The behavior settings from the form.
205 public function setBehaviorSettings($plugin_id, array $settings) {
206 // Set behavior settings fields.
207 $this->unserializedBehaviorSettings[$plugin_id] = $settings;
213 public function postSave(EntityStorageInterface $storage, $update = TRUE) {
214 $this->setNeedsSave(FALSE);
215 parent::postSave($storage, $update);
221 public function preSaveRevision(EntityStorageInterface $storage, \stdClass $record) {
222 parent::preSaveRevision($storage, $record);
228 public function getCreatedTime() {
229 return $this->get('created')->value;
235 public function getOwner() {
236 return $this->get('uid')->entity;
242 public function getOwnerId() {
243 return $this->get('uid')->target_id;
249 public function setOwnerId($uid) {
250 $this->set('uid', $uid);
257 public function setOwner(UserInterface $account) {
258 $this->set('uid', $account->id());
265 public function getType() {
266 return $this->bundle();
272 public function getParagraphType() {
273 return $this->type->entity;
279 public function getRevisionAuthor() {
280 return $this->get('revision_uid')->entity;
286 public function setRevisionAuthorId($uid) {
287 $this->set('revision_uid', $uid);
294 public function getRevisionLog() {
301 public function setRevisionLog($revision_log) {
308 public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
309 $fields['id'] = BaseFieldDefinition::create('integer')
311 ->setDescription(t('The ID of the Paragraphs entity.'))
313 ->setSetting('unsigned', TRUE);
315 $fields['uuid'] = BaseFieldDefinition::create('uuid')
316 ->setLabel(t('UUID'))
317 ->setDescription(t('The UUID of the paragraphs entity.'))
320 $fields['revision_id'] = BaseFieldDefinition::create('integer')
321 ->setLabel(t('Revision ID'))
322 ->setDescription(t('The paragraphs entity revision ID.'))
324 ->setSetting('unsigned', TRUE);
326 $fields['type'] = BaseFieldDefinition::create('entity_reference')
327 ->setLabel(t('Type'))
328 ->setDescription(t('The paragraphs type.'))
329 ->setSetting('target_type', 'paragraphs_type')
332 $fields['langcode'] = BaseFieldDefinition::create('language')
333 ->setLabel(t('Language code'))
334 ->setDescription(t('The paragraphs entity language code.'))
335 ->setRevisionable(TRUE);
337 $fields['uid'] = BaseFieldDefinition::create('entity_reference')
338 ->setLabel(t('Authored by'))
339 ->setDescription(t('The user ID of the paragraphs author.'))
340 ->setRevisionable(TRUE)
341 ->setSetting('target_type', 'user')
342 ->setSetting('handler', 'default')
343 ->setDefaultValueCallback('Drupal\paragraphs\Entity\Paragraph::getCurrentUserId')
344 ->setTranslatable(TRUE)
345 ->setDisplayOptions('form', array(
349 ->setDisplayConfigurable('form', TRUE);
351 $fields['status'] = BaseFieldDefinition::create('boolean')
352 ->setLabel(t('Published'))
353 ->setRevisionable(TRUE)
354 ->setTranslatable(TRUE)
355 ->setDefaultValue(TRUE)
356 ->setDisplayConfigurable('form', TRUE);
358 $fields['created'] = BaseFieldDefinition::create('created')
359 ->setLabel(t('Authored on'))
360 ->setDescription(t('The time that the Paragraph was created.'))
361 ->setRevisionable(TRUE)
362 ->setTranslatable(TRUE)
363 ->setDisplayOptions('form', array(
367 ->setDisplayConfigurable('form', TRUE);
369 $fields['revision_uid'] = BaseFieldDefinition::create('entity_reference')
370 ->setLabel(t('Revision user ID'))
371 ->setDescription(t('The user ID of the author of the current revision.'))
372 ->setSetting('target_type', 'user')
373 ->setQueryable(FALSE)
374 ->setRevisionable(TRUE);
376 $fields['parent_id'] = BaseFieldDefinition::create('string')
377 ->setLabel(t('Parent ID'))
378 ->setDescription(t('The ID of the parent entity of which this entity is referenced.'))
379 ->setSetting('is_ascii', TRUE);
381 $fields['parent_type'] = BaseFieldDefinition::create('string')
382 ->setLabel(t('Parent type'))
383 ->setDescription(t('The entity parent type to which this entity is referenced.'))
384 ->setSetting('is_ascii', TRUE)
385 ->setSetting('max_length', EntityTypeInterface::ID_MAX_LENGTH);
387 $fields['parent_field_name'] = BaseFieldDefinition::create('string')
388 ->setLabel(t('Parent field name'))
389 ->setDescription(t('The entity parent field name to which this entity is referenced.'))
390 ->setSetting('is_ascii', TRUE)
391 ->setSetting('max_length', FieldStorageConfig::NAME_MAX_LENGTH);
393 $fields['behavior_settings'] = BaseFieldDefinition::create('string_long')
394 ->setLabel(t('Behavior settings'))
395 ->setDescription(t('The behavior plugin settings'))
396 ->setRevisionable(TRUE)
397 ->setDefaultValue(serialize([]));
403 * Default value callback for 'uid' base field definition.
405 * @see ::baseFieldDefinitions()
408 * An array of default values.
410 public static function getCurrentUserId() {
411 return array(\Drupal::currentUser()->id());
417 public function createDuplicate() {
418 $duplicate = parent::createDuplicate();
419 // Loop over entity fields and duplicate nested paragraphs.
420 foreach ($duplicate->getFields() as $field) {
421 if ($field->getFieldDefinition()->getType() == 'entity_reference_revisions') {
422 if ($field->getFieldDefinition()->getTargetEntityTypeId() == "paragraph") {
423 foreach ($field as $item) {
424 $item->entity = $item->entity->createDuplicate();