Skip to content

Instantly share code, notes, and snippets.

@chx
Last active June 21, 2023 12:58
Show Gist options
  • Save chx/ec7a6f1ec990016c218d6c0cf5a1372e to your computer and use it in GitHub Desktop.
Save chx/ec7a6f1ec990016c218d6c0cf5a1372e to your computer and use it in GitHub Desktop.
diff --git a/src/Form/ReplicateConfirmForm.php b/src/Form/ReplicateConfirmForm.php
index f8334a2dbd0..d0a4718324a 100644
--- a/src/Form/ReplicateConfirmForm.php
+++ b/src/Form/ReplicateConfirmForm.php
@@ -7,7 +7,9 @@
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Url;
+use Drupal\replicate_ui\ReplicateUiOnlyUntranslatedEvent;
use Symfony\Component\DependencyInjection\ContainerInterface;
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
class ReplicateConfirmForm extends ContentEntityConfirmFormBase {
@@ -21,11 +23,17 @@ class ReplicateConfirmForm extends ContentEntityConfirmFormBase {
*/
protected $replicator;
+ /**
+ * @var \Symfony\Component\EventDispatcher\EventDispatcherInterface
+ */
+ protected EventDispatcherInterface $eventDispatcher;
+
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
$form = parent::create($container);
+ $form->eventDispatcher = $container->get('event_dispatcher');
$form->replicator = $container->get('replicate.replicator');
return $form;
}
@@ -97,7 +105,9 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
$entity = $this->routeMatch->getParameter($this->getEntityTypeId());;
$label_key = $entity->getEntityType()->getKey('label');
if ($entity instanceof TranslatableInterface) {
- $only_untranslated = $form_state->getValue('only_untranslated');
+ if ($only_untranslated = $form_state->getValue('only_untranslated')) {
+ $this->eventDispatcher->dispatch(new ReplicateUiOnlyUntranslatedEvent($entity));
+ }
foreach ($entity->getTranslationLanguages() as $translation_language) {
$langcode = $translation_language->getId();
$translation = $entity->getTranslation($langcode);
diff --git a/src/ReplicateUiOnlyUntranslatedEvent.php b/src/ReplicateUiOnlyUntranslatedEvent.php
new file mode 100644
index 00000000000..6a9c41bdd68
--- /dev/null
+++ b/src/ReplicateUiOnlyUntranslatedEvent.php
@@ -0,0 +1,18 @@
+<?php
+
+namespace Drupal\replicate_ui;
+
+use Drupal\Core\Entity\TranslatableInterface;
+use Symfony\Contracts\EventDispatcher\Event;
+
+
+final class ReplicateUiOnlyUntranslatedEvent extends Event {
+
+ public function __construct(protected TranslatableInterface $entity) {
+ }
+
+ public function getEntity(): TranslatableInterface {
+ return $this->entity;
+ }
+
+}
diff --git a/src/Form/ReplicateConfirmForm.php b/src/Form/ReplicateConfirmForm.php
index 3b7069f58f..5fce6564ee 100644
--- a/src/Form/ReplicateConfirmForm.php
+++ b/src/Form/ReplicateConfirmForm.php
@@ -60,6 +60,13 @@ public function buildForm(array $form, FormStateInterface $form_state, RouteMatc
]),
];
}
+
+ $args = ['@language' => $entity->getUntranslated()->language()->getName()];
+ $form['only_untranslated'] = [
+ '#type' => 'checkbox',
+ '#title' => $this->t('@language only', $args),
+ '#description' => $this->t('Replicate only the @language version of this entity', $args),
+ ];
}
else {
$form['new_label'] = [
@@ -90,11 +97,14 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
$entity = $this->routeMatch->getParameter($this->getEntityTypeId());;
$label_key = $entity->getEntityType()->getKey('label');
if ($entity instanceof TranslatableInterface) {
+ $only_untranslated = $form_state->getValue('only_untranslated');
foreach ($entity->getTranslationLanguages() as $translation_language) {
$langcode = $translation_language->getId();
- if ($new_label = $form_state->getValue('new_label_' . $langcode)) {
- /** @var \Drupal\Core\Entity\TranslatableInterface $translation */
- $translation = $entity->getTranslation($langcode);
+ $translation = $entity->getTranslation($langcode);
+ if ($only_untranslated && !$translation->isDefaultTranslation()) {
+ $entity->removeTranslation($langcode);
+ }
+ elseif ($new_label = $form_state->getValue('new_label_' . $langcode)) {
$translation->set($label_key, $new_label);
}
}
<?php
namespace Drupal\paragraphs\EventSubscriber;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\paragraphs\ParagraphInterface;
use Drupal\replicate\Events\ReplicateEntityFieldEvent;
use Drupal\replicate\Events\ReplicatorEvents;
use Drupal\replicate\Replicator;
use Drupal\replicate_ui\ReplicateUiOnlyUntranslatedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
* Event subscriber that handles cloning through the Replicate module.
*/
class ReplicateFieldSubscriber implements EventSubscriberInterface {
/**
* The replicator service.
*
* @var \Drupal\replicate\Replicator
*/
protected $replicator;
protected \SplObjectStorage $onlyUnTranslated;
/**
* ReplicateFieldSubscriber constructor.
*
* @param \Drupal\replicate\Replicator $replicator
* The replicator service.
*/
public function __construct(Replicator $replicator) {
$this->replicator = $replicator;
$this->onlyUnTranslated = new \SplObjectStorage();
}
/**
* Replicates paragraphs when the parent entity is being replicated.
*
* @param \Drupal\replicate\Events\ReplicateEntityFieldEvent $event
*/
public function onClone(ReplicateEntityFieldEvent $event) {
foreach ($this->getParagraphReferencingFieldItems($event->getFieldItemList()) as $field_item) {
// On the top, the children are pre-populated by
// ::onReplicateUiOnlyUntranslatedEvent(), later only the parent entity
// is.
$only_untranslated = $this->onlyUnTranslated->contains($event->getEntity()) || $this->onlyUnTranslated->contains($field_item->entity);
if ($only_untranslated) {
$this->onlyUnTranslated->attach($field_item->entity);
}
$field_item->entity = $this->replicator->replicateEntity($field_item->entity);
if ($only_untranslated) {
foreach ($field_item->entity->getTranslationLanguages() as $translation_language) {
$langcode = $translation_language->getId();
$translation = $field_item->entity->getTranslation($langcode);
if (!$translation->isDefaultTranslation()) {
$field_item->entity->removeTranslation($langcode);
}
}
}
}
}
public function onReplicateUiOnlyUntranslatedEvent(ReplicateUiOnlyUntranslatedEvent $event) {
$entity = $event->getEntity();
// Pre-populate the store with paragraphs, onClone() does not get the
// parent entity.
if ($entity instanceof ContentEntityInterface) {
foreach ($entity->getFields() as $field_item_list) {
foreach ($this->getParagraphReferencingFieldItems($field_item_list) as $item) {
$this->onlyUnTranslated->attach($item->entity);
}
}
}
}
/**
* @param \Drupal\Core\Field\FieldItemListInterface $field_item_list
*
* @return \Generator<\Drupal\Core\Field\FieldItemInterface>
* Every field item has a paragraph in $field_item->entity.
*/
protected function getParagraphReferencingFieldItems(FieldItemListInterface $field_item_list): \Generator {
if ($field_item_list->getItemDefinition()->getSetting('target_type') === 'paragraph') {
foreach ($field_item_list as $field_item) {
if ($field_item->entity instanceof ParagraphInterface) {
yield $field_item;
}
}
}
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents() {
$events[ReplicatorEvents::replicateEntityField('entity_reference_revisions')][] = 'onClone';
$events['Drupal\replicate_ui\ReplicateUiOnlyUntranslatedEvent'][] = 'onReplicateUiOnlyUntranslatedEvent';
return $events;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment