Currently only a fixed set of field type can clone their referenced entities: 'entity_reference' and 'entity_reference_revisions'. I have a field type which extends EntityReferenceRevisionsFieldItemList and therefore have a different field type id. If we check that the field implements EntityReferenceFieldItemListInterface we can cover both 'entity_reference' and 'entity_reference_revisions' plus any other field implementing that interface.

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

NiCo_O created an issue. See original summary.

NiCo_O’s picture

StatusFileSize
new4.31 KB

Here is the patch checking for EntityReferenceRevisionsFieldItemList rather then a fixed list of field type

mglaman’s picture

Status: Active » Needs work
+++ b/src/EntityClone/Content/ContentEntityCloneBase.php
@@ -62,12 +62,10 @@ class ContentEntityCloneBase implements EntityHandlerInterface, EntityCloneInter
-        if ($this->fieldIsClonable($field_definition)) {
-          $field = $entity->get($field_id);
-          /** @var \Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem $value */
-          if ($field->count() > 0) {
-            $cloned_entity->set($field_id, $this->cloneReferencedEntities($field, $field_definition, $properties));
-          }

The check should be moved into fieldIsClonable.

NiCo_O’s picture

I thought about this, but this method is used only in one place, although it should also be used in ContentEntityCloneFormBase as well. Maybe we can move fieldIsClonable to a service or something more appropriate?

mglaman’s picture

I thought about this, but this method is used only in one place,

True, but it makes it easier to override in child classes.

although it should also be used in ContentEntityCloneFormBase as well

That would make sense for a service. That way you're not overriding _all_ instances of the clone and clone form classes. Just swapping the service.

NiCo_O’s picture

StatusFileSize
new7.98 KB

Here is another patch with a service to centralize the fieldIsClonable method so it can be used in both places

NiCo_O’s picture

StatusFileSize
new8.41 KB
NiCo_O’s picture

StatusFileSize
new8.68 KB
NiCo_O’s picture

Status: Needs work » Needs review

The last submitted patch, 2: 3013286-2.patch, failed testing. View results

NiCo_O’s picture

kevinfunk’s picture

Status: Needs review » Reviewed & tested by the community

@NiCo_O 's patch from #8 is the main reason I switched from Replicate to Entity Clone. I've been using the patch for awhile without any issues.

colan’s picture

Status: Reviewed & tested by the community » Needs work

Patch doesn't apply to HEAD cleanly.

katherined’s picture

Status: Needs work » Needs review
StatusFileSize
new8.64 KB

Patch reroll.

Status: Needs review » Needs work

The last submitted patch, 14: 3013286-14.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

alberto56’s picture

The patch in #14 no longer applies as of today's 8.x-1.0-beta6 version. (It applies to 8.x-1.0-beta5)

suresh prabhu parkala’s picture

Status: Needs work » Needs review
StatusFileSize
new9.27 KB

Re-rolled patch of #14.

suresh prabhu parkala’s picture

StatusFileSize
new9.27 KB

Sorry for that. The previous patch had PHPLint failures. Please review this updated patch.
Thank you.

rzb’s picture

StatusFileSize
new9.25 KB

Re-roll after fail.

Status: Needs review » Needs work

The last submitted patch, 19: 3013286-19.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

rzb’s picture

Status: Needs work » Needs review
StatusFileSize
new9.25 KB

Re-roll

rzb’s picture

StatusFileSize
new9.91 KB

The patch was not taking in consideration the work done for the issue #3037470. Re-roll.

rzb’s picture

StatusFileSize
new9.94 KB

Sorry, here is the good patch reroll.

Rajeshreeputra made their first commit to this issue’s fork.

8ballsteve’s picture

StatusFileSize
new9.63 KB

Looks like this needs another reroll against the latest 1.x branch - see attached

8ballsteve’s picture

StatusFileSize
new9.91 KB

Here's a patch that applies to 8.x-1.0-beta7

8ballsteve’s picture

StatusFileSize
new9.63 KB

...and here's a patch that applied to 2.0.0-alpha1

jonathanshaw’s picture

Status: Needs review » Reviewed & tested by the community

This looks like a good solution.

jonathanshaw’s picture

Status: Reviewed & tested by the community » Needs work

Actually I have doubts about the implementation. This uses a generic service that applies to all entity types, but I doubt that the most common use case for customising this is to want to customise it for all entity types.

I'd imagine it's much more common to customise it for a specific entity type based on the specific fields of that entity type. In which case, it would be better if the clone form handler could call out to clone handler so customisation could be done there. A problem though is that fieldIsClonable is a protected method.

Solution:

1. Remove method fieldIsClonable from ContentEntityCloneFormBase.

2. Add an isFieldClonable method to ContentEntityCloneBase and the relevant interface:

  public function isFieldClonable(FieldItemListInterface $field) {
    // For backwards-compatability use a custom fieldIsClonable method if it exists,
    // otherwise use the clonable field service. 
    if (method_exists('fieldIsClonable')) {
      trigger_error(E_USER_DEPRECATED, 'fieldIsclonable' is deprecated, override isFieldClonableInstead');
      return $this->fieldIsClonable($field->getFieldDefinition());
    }
    return $this->entityCloneClonableField->isClonable($field)
  }

3. In ContentEntityCloneFormBase call the clone handler:

+        $entity_clone_handler = $this->entityTypeManager->getHandler($entity->getEntityTypeId(), 'entity_clone');
+        if ($entity_clone_handler->isFieldClonable($field)) {
+          $form['recursive'] = array_merge($form['recursive'], $this->getRecursiveFormElement($field_definition, $field_id, $field, $discovered_entities));
alberto56’s picture

StatusFileSize
new9.65 KB

I took @8ballsteve's patch at #27 and made a new version which works with 2.0.0-beta3.

ankitv18’s picture

Version: 8.x-1.x-dev » 2.x-dev
ankitv18’s picture

Assigned: Unassigned » ankitv18
ankitv18’s picture

Assigned: ankitv18 » Unassigned

@Rajeshreeputra please check below error as tests are not executing for this MR!46
No syntax errors detected in /var/www/html/modules/contrib/entity_clone/src/EntityClone/Content/ContentEntityCloneBase.php
No syntax errors detected in /var/www/html/modules/contrib/entity_clone/src/EntityCloneClonableField.php
--- Errors ---
PHP Parse error: syntax error, unexpected '*', expecting function (T_FUNCTION) or const (T_CONST) in /var/www/html/modules/contrib/entity_clone/src/EntityClone/Content/ContentEntityCloneFormBase.php on line 62
xargs: php: exited with status 255; aborting

vishalkhode’s picture

Looks like couple of changes needed:

  • Looks like there's a syntax error in MR. See here.
  • Use the dependency injection in Class src/EntityCloneClonableField.phphere
  • Remove the unused use statement: use Drupal\Core\Entity\ContentEntityStorageInterface from Class src/EntityClone/Content/ContentEntityCloneFormBase.php.
  • Developers won't be able to alter the service because the class ContentEntityCloneFormBase need constructor of the class \Drupal\entity_clone\EntityCloneClonableField. We need to tweak it like:
    1. Create a new interface EntityCloneClonableFieldInterface:
      namespace Drupal\entity_clone;
      
      use Drupal\Core\Field\FieldDefinitionInterface;
      use Drupal\Core\Field\FieldItemListInterface;
      
      /**
       * The interface for class EntityCloneClonableField.
       */
      interface EntityCloneClonableFieldInterface {
      
        /**
         * Return whether a field can be cloned or not.
         *
         * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
         *   The field definition.
         * @param \Drupal\Core\Field\FieldItemListInterface $field
         *   The field.
         *
         * @return bool
         *   True if the entity can be cloned.
         *
         * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
         * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
         */
        public function isClonable(FieldDefinitionInterface $field_definition, FieldItemListInterface $field): bool;
      
      }
      
    2. Update the class ContentEntityCloneFormBase from:
      public function __construct(
          EntityTypeManagerInterface $entity_type_manager,
          TranslationManager $translation_manager,
          EntityCloneSettingsManager $entity_clone_settings_manager,
          ConfigFactoryInterface $config_factory,
          EntityCloneClonableField $entity_clone_clonable_field) {
          $this->entityTypeManager = $entity_type_manager;
          $this->translationManager = $translation_manager;
          $this->entityCloneSettingsManager = $entity_clone_settings_manager;
          $this->configFactory = $config_factory;
          $this->entityCloneClonableField = $entity_clone_clonable_field;
        }
      

      To:

      public function __construct(
          EntityTypeManagerInterface $entity_type_manager,
          TranslationManager $translation_manager,
          EntityCloneSettingsManager $entity_clone_settings_manager,
          ConfigFactoryInterface $config_factory,
          EntityCloneClonableFieldInterface $entity_clone_clonable_field) {
          $this->entityTypeManager = $entity_type_manager;
          $this->translationManager = $translation_manager;
          $this->entityCloneSettingsManager = $entity_clone_settings_manager;
          $this->configFactory = $config_factory;
          $this->entityCloneClonableField = $entity_clone_clonable_field;
        }
      

sakthi_dev made their first commit to this issue’s fork.

sakthi_dev’s picture

Status: Needs work » Needs review

Please review. Updated MR based on #35.

vishalkhode’s picture

Status: Needs review » Needs work

Needs work here, as there are PHP syntax error. The interface can't implement the method. The interface will only define the method and class with implement the method defined in the interface.

chandu7929’s picture

Assigned: Unassigned » chandu7929
chandu7929’s picture

Assigned: chandu7929 » Unassigned
Status: Needs work » Needs review

Will check separatly for D10.1.x

vishalkhode’s picture

Status: Needs review » Reviewed & tested by the community

Reviewed changes and looks good to me.

  • Rajeshreeputra committed ef45b191 on 2.x
    Issue #3013286 by Rajeshreeputra, NiCo_O, rzb, 8ballsteve, chandu7929,...
rajeshreeputra’s picture

Status: Reviewed & tested by the community » Fixed

merged release to follow shortly. Wil release 2.0.0-beta4!

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.