eca-1.0.x-dev/modules/content/src/Plugin/Action/CloneEntity.php
modules/content/src/Plugin/Action/CloneEntity.php
<?php
namespace Drupal\eca_content\Plugin\Action;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Action\Attribute\Action;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\eca\Attribute\EcaAction;
use Drupal\eca\Plugin\Action\ConfigurableActionBase;
use Drupal\eca\Plugin\ECA\PluginFormTrait;
use Drupal\eca_content\Event\ContentEntityPrepareForm;
/**
* Clone an existing content entity without saving it.
*/
#[Action(
id: 'eca_clone_entity',
label: new TranslatableMarkup('Entity: clone existing'),
type: 'entity',
)]
#[EcaAction(
description: new TranslatableMarkup('Clone an existing content entity without saving it.'),
version_introduced: '2.1.0',
)]
class CloneEntity extends ConfigurableActionBase {
use PluginFormTrait;
/**
* The instantiated entity.
*
* @var \Drupal\Core\Entity\EntityInterface|null
*/
protected ?EntityInterface $entity;
/**
* {@inheritdoc}
*/
public function defaultConfiguration(): array {
return [
'token_name' => '',
'label' => '',
'published' => FALSE,
'owner' => '',
] + parent::defaultConfiguration();
}
/**
* {@inheritdoc}
*/
public function buildConfigurationForm(array $form, FormStateInterface $form_state): array {
$form['token_name'] = [
'#type' => 'textfield',
'#title' => $this->t('Name of token'),
'#default_value' => $this->configuration['token_name'],
'#description' => $this->t('Provide the name of a token that holds the new entity.'),
'#weight' => -60,
'#eca_token_reference' => TRUE,
];
$form['label'] = [
'#type' => 'textfield',
'#title' => $this->t('Entity label'),
'#default_value' => $this->configuration['label'],
'#description' => $this->t('The label of the new entity.'),
'#weight' => -30,
];
$form['published'] = [
'#type' => 'checkbox',
'#title' => $this->t('Published'),
'#default_value' => $this->configuration['published'],
'#description' => $this->t('Whether the entity should be published or not.'),
'#weight' => -20,
];
$form['owner'] = [
'#type' => 'textfield',
'#title' => $this->t('Owner UID'),
'#default_value' => $this->configuration['owner'],
'#description' => $this->t('The owner UID of the new entity.'),
'#weight' => -10,
];
return parent::buildConfigurationForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
public function submitConfigurationForm(array &$form, FormStateInterface $form_state): void {
$this->configuration['token_name'] = $form_state->getValue('token_name');
$this->configuration['label'] = $form_state->getValue('label');
$this->configuration['published'] = !empty($form_state->getValue('published'));
$this->configuration['owner'] = $form_state->getValue('owner');
parent::submitConfigurationForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
public function access($object, ?AccountInterface $account = NULL, $return_as_object = FALSE) {
if (!($object instanceof ContentEntityInterface)) {
$access_result = AccessResult::forbidden('No content entity provided');
}
else {
/** @var \Drupal\Core\Access\AccessResultInterface $access_result */
$access_result = parent::access($object, $account, TRUE);
if ($access_result->isAllowed()) {
$account = $account ?? $this->currentUser;
$entity_type_id = $object->getEntityTypeId();
$bundle = $object->bundle();
if (!$this->entityTypeManager->hasHandler($entity_type_id, 'access')) {
$access_result = AccessResult::forbidden('Cannot determine access without an access handler.');
}
else {
/**
* @var \Drupal\Core\Entity\EntityAccessControlHandlerInterface $access_handler
*/
$access_handler = $this->entityTypeManager->getHandler($entity_type_id, 'access');
$access_result = $access_handler->createAccess($bundle, $account, [], TRUE);
}
}
}
return $return_as_object ? $access_result : $access_result->isAllowed();
}
/**
* {@inheritdoc}
*/
public function execute(mixed $entity = NULL): void {
if (!($entity instanceof ContentEntityInterface)) {
return;
}
$newEntity = $entity->createDuplicate();
$config = &$this->configuration;
$definition = $this->entityTypeManager->getDefinition($newEntity->getEntityTypeId());
$entity_keys = $definition->get('entity_keys');
if (isset($entity_keys['label'])) {
$label = trim((string) $this->tokenService->replace($config['label'], [], ['clear' => TRUE]));
if ($label !== '') {
$newEntity->set($entity_keys['label'], $label);
}
}
if (isset($entity_keys['published'])) {
$newEntity->set($entity_keys['published'], (int) $this->configuration['published']);
}
if (isset($entity_keys['owner'])) {
$owner_id = trim((string) $this->tokenService->replace($config['owner'], [], ['clear' => TRUE]));
if ($owner_id === '') {
$owner_id = $this->currentUser->id();
}
$newEntity->set($entity_keys['owner'], $owner_id);
}
if ($newEntity->hasField('created')) {
$newEntity->set('created', $this->time->getRequestTime());
}
$this->entity = $newEntity;
$this->tokenService->addTokenData($config['token_name'], $newEntity);
if ($this->event instanceof ContentEntityPrepareForm) {
$this->event->setEntity($newEntity);
}
}
}
