View source
<?php
namespace Drupal\paragraphs_edit;
use Drupal\Component\Utility\Html;
use Drupal\Core\Entity\ContentEntityForm;
use Drupal\Core\Form\FormStateInterface;
class ParagraphCloneForm extends ContentEntityForm {
protected $originalEntity;
protected function prepareEntity() {
parent::prepareEntity();
$account = \Drupal::currentUser();
$uuid_generator = \Drupal::service('uuid');
$this->originalEntity = clone $this->entity;
$paragraph = $this->entity;
$paragraph
->enforceIsNew();
$paragraph
->setNewRevision(TRUE);
$paragraph
->set('id', NULL);
$paragraph
->set('revision_id', NULL);
$paragraph
->set('uuid', $uuid_generator
->generate());
$paragraph
->set('created', REQUEST_TIME);
$paragraph
->setOwnerId($account
->id());
$paragraph
->setRevisionAuthorId($account
->id());
}
public function form(array $form, FormStateInterface $form_state) {
$route_match = $this
->getRouteMatch();
$node = $route_match
->getParameter('node');
$field_name = $route_match
->getParameter('field');
$field = $node
->get($field_name);
$field_definition = $field
->getFieldDefinition();
$field_label = $field_definition
->getLabel();
$delta = $route_match
->getParameter('delta');
$wrapper_id = Html::getUniqueId('paragraphs-edit-clone');
$form['paragraphs_edit'] = [
'#type' => 'fieldset',
'#title' => $this
->t('Clone to'),
'#id' => $wrapper_id,
'#tree' => TRUE,
];
$potential_destinations = $this
->getPotentialCloneDestinations($this->entity
->bundle());
$form['paragraphs_edit']['bundle'] = [
'#type' => 'select',
'#title' => $this
->t('Type'),
'#options' => $potential_destinations['bundles'],
'#required' => TRUE,
'#ajax' => [
'callback' => '::paragraphEditChangeAjax',
'wrapper' => $wrapper_id,
],
];
$selection_settings = [];
$bundle = $form_state
->getValue([
'paragraphs_edit',
'bundle',
], NULL);
if (!empty($bundle)) {
$selection_settings['target_bundles'] = [
$bundle,
];
}
$form['paragraphs_edit']['parent'] = [
'#type' => 'entity_autocomplete',
'#title' => $this
->t('Parent'),
'#target_type' => 'node',
'#selection_handler' => 'default',
'#selection_settings' => $selection_settings,
'#required' => TRUE,
'#disabled' => empty($bundle),
];
$form['paragraphs_edit']['field'] = [
'#type' => 'select',
'#title' => $this
->t('Field'),
'#options' => !empty($bundle) ? $potential_destinations['fields'][$bundle] : [],
'#required' => TRUE,
'#disabled' => empty($bundle),
];
if (count($form['paragraphs_edit']['field']['#options']) == 1) {
$form['paragraphs_edit']['field']['#default_value'] = key($form['paragraphs_edit']['field']['#options']);
}
$form = parent::form($form, $form_state);
$form['#title'] = $this
->t('Clone #@delta of @field of %label', [
'@delta' => $delta,
'@field' => $field_label,
'%label' => $node
->label(),
]);
return $form;
}
public function paragraphEditChangeAjax($form) {
return $form['paragraphs_edit'];
}
protected function getPotentialCloneDestinations($paragraph_type) {
$bundles_labels = node_type_get_names();
$types_with_paragraphs = $this->entityManager
->getFieldMapByFieldType('entity_reference_revisions');
$field_definitions_bundle = [];
$destinations = [];
foreach ($types_with_paragraphs['node'] as $field => $info) {
foreach ($info['bundles'] as $bundle) {
if (!isset($field_definitions_bundle[$bundle])) {
$field_definitions_bundle[$bundle] = $this->entityManager
->getFieldDefinitions('node', $bundle);
}
$field_definition = $field_definitions_bundle[$bundle][$field];
$destinations['bundles'][$bundle] = $bundles_labels[$bundle];
$destinations['fields'][$bundle][$field] = $field_definition
->getLabel();
}
}
return $destinations;
}
public function validateForm(array &$form, FormStateInterface $form_state) {
$destination_entity_id = $form_state
->getValue([
'paragraphs_edit',
'parent',
]);
$destination_field = $form_state
->getValue([
'paragraphs_edit',
'field',
]);
if ($destination_entity_id && $destination_field) {
$destination_entity = $this->entityManager
->getStorage('node')
->load($destination_entity_id);
if ($destination_entity) {
if (!$destination_entity
->access('update')) {
$form_state
->setError($form['paragraphs_edit']['parent'], 'You are not allowed to update this content.');
}
if (!$destination_entity
->get($destination_field)
->access('edit')) {
$form_state
->setError($form['paragraphs_edit']['field'], 'You are not allowed to edit this field.');
}
}
}
return parent::validateForm($form, $form_state);
}
public function save(array $form, FormStateInterface $form_state) {
$route_match = $this
->getRouteMatch();
$node = $route_match
->getParameter('node');
$field_name = $route_match
->getParameter('field');
$field = $node
->get($field_name);
$field_definition = $field
->getFieldDefinition();
$field_label = $field_definition
->getLabel();
$delta = $route_match
->getParameter('delta');
$destination_entity_id = $form_state
->getValue([
'paragraphs_edit',
'parent',
]);
$destination_entity = $this->entityManager
->getStorage('node')
->load($destination_entity_id);
$destination_field = $form_state
->getValue([
'paragraphs_edit',
'field',
]);
$this->entity
->save();
$destination_entity
->get($destination_field)
->appendItem([
'target_id' => $this->entity
->id(),
'target_revision_id' => $this->entity
->getRevisionId(),
]);
$destination_entity
->save();
drupal_set_message($this
->t('Cloned #@delta of @field of %label to %destination_label', [
'@delta' => $delta,
'@field' => $field_label,
'%label' => $node
->label(),
'%destination_label' => $destination_entity
->label(),
]));
$request = \Drupal::request();
if ($request->query
->has('destination')) {
$request->query
->remove('destination');
}
$form_state
->setRedirectUrl($destination_entity
->toUrl());
}
}