View source
<?php
namespace Drupal\entity_clone\EntityClone\Content;
use Drupal\Component\Datetime\TimeInterface;
use Drupal\Core\Entity\EntityHandlerInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\FieldableEntityInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldConfigInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\entity_clone\EntityClone\EntityCloneInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
class ContentEntityCloneBase implements EntityHandlerInterface, EntityCloneInterface {
protected $entityTypeManager;
protected $entityTypeId;
protected $currentUser;
protected $timeService;
public function __construct(EntityTypeManagerInterface $entity_type_manager, $entity_type_id, TimeInterface $time_service, AccountProxyInterface $currentUser) {
$this->entityTypeManager = $entity_type_manager;
$this->entityTypeId = $entity_type_id;
$this->timeService = $time_service;
$this->currentUser = $currentUser;
}
public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
return new static($container
->get('entity_type.manager'), $entity_type
->id(), $container
->get('datetime.time'), $container
->get('current_user'));
}
public function cloneEntity(EntityInterface $entity, EntityInterface $cloned_entity, array $properties = [], array &$already_cloned = []) {
if (isset($properties['take_ownership']) && $properties['take_ownership'] === 1) {
$cloned_entity
->setOwnerId($this->currentUser
->id());
}
$cloned_entity
->save();
$already_cloned[$entity
->getEntityTypeId()][$entity
->id()] = $cloned_entity;
if ($cloned_entity instanceof FieldableEntityInterface && $entity instanceof FieldableEntityInterface) {
foreach ($cloned_entity
->getFieldDefinitions() as $field_id => $field_definition) {
if ($this
->fieldIsClonable($field_definition)) {
$field = $entity
->get($field_id);
if ($field
->count() > 0) {
$cloned_entity
->set($field_id, $this
->cloneReferencedEntities($field, $field_definition, $properties, $already_cloned));
}
}
}
}
$this
->setClonedEntityLabel($entity, $cloned_entity);
if (method_exists($cloned_entity, 'setCreatedTime')) {
$cloned_entity
->setCreatedTime($this->timeService
->getRequestTime());
}
$cloned_entity
->save();
return $cloned_entity;
}
protected function fieldIsClonable(FieldDefinitionInterface $field_definition) {
$clonable_field_types = [
'entity_reference',
'entity_reference_revisions',
];
$type_is_clonable = in_array($field_definition
->getType(), $clonable_field_types, TRUE);
if ($field_definition instanceof FieldConfigInterface && $type_is_clonable) {
return TRUE;
}
return FALSE;
}
protected function setClonedEntityLabel(EntityInterface $original_entity, EntityInterface $cloned_entity) {
$label_key = $this->entityTypeManager
->getDefinition($this->entityTypeId)
->getKey('label');
if ($label_key && $cloned_entity
->hasField($label_key)) {
$cloned_entity
->set($label_key, $original_entity
->label() . ' - Cloned');
}
}
protected function cloneReferencedEntities(FieldItemListInterface $field, FieldConfigInterface $field_definition, array $properties, array &$already_cloned) {
$referenced_entities = [];
foreach ($field as $value) {
if (!($referenced_entity = $value
->get('entity')
->getTarget())) {
continue;
}
$referenced_entity = $value
->get('entity')
->getTarget()
->getValue();
$child_properties = $this
->getChildProperties($properties, $field_definition, $referenced_entity);
if (!empty($child_properties['clone'])) {
$cloned_reference = $referenced_entity
->createDuplicate();
$entity_clone_handler = $this->entityTypeManager
->getHandler($referenced_entity
->getEntityTypeId(), 'entity_clone');
$entity_clone_handler
->cloneEntity($referenced_entity, $cloned_reference, $child_properties['children'], $already_cloned);
$referenced_entities[] = $cloned_reference;
}
elseif (!empty($child_properties['is_circular'])) {
if (!empty($already_cloned[$referenced_entity
->getEntityTypeId()][$referenced_entity
->id()])) {
$referenced_entities[] = $already_cloned[$referenced_entity
->getEntityTypeId()][$referenced_entity
->id()];
}
else {
$referenced_entities[] = $referenced_entity;
}
}
else {
$referenced_entities[] = $referenced_entity;
}
}
return $referenced_entities;
}
protected function getChildProperties(array $properties, FieldConfigInterface $field_definition, EntityInterface $referenced_entity) {
$child_properties = [];
if (isset($properties['recursive'][$field_definition
->id()]['references'][$referenced_entity
->id()])) {
$child_properties = $properties['recursive'][$field_definition
->id()]['references'][$referenced_entity
->id()];
}
if (!isset($child_properties['children'])) {
$child_properties['children'] = [];
}
return $child_properties;
}
}