mooru
mooru

Reputation: 71

remove duplicate values from entity reference fields

When i import feeds into an entity reference field, it creates duplicate values that look like the code below (using devel module)

$field_tags_people['und'][0]['target_id'] = 578
$field_tags_people['und'][1]['target_id'] = 578
$field_tags_people['und'][2]['target_id'] = 594

each of the target_id should have different values but turns out some are duplicates. I have tried this code

$field_tags_people['und'] = array_unique($field_tags_people['und'])

but it removes all terms except the first one. This seems strange due to the target_id key. How can I make this work?

Upvotes: 0

Views: 1788

Answers (4)

Justme
Justme

Reputation: 221

In order to make the array unique you can easily use

$field_tags_people= array_unique($field_tags_people, SORT_REGULAR);

Upvotes: 0

Denis Viunyk
Denis Viunyk

Reputation: 121

  /**
   * Delete duplicate values.
   *
   * @param \Drupal\Core\Entity\ContentEntityInterface $entity
   *   Entity.
   * @param string $field_name
   *   Field name.
   * @param bool $need_save
   *   Save entity or not.
   *
   * @throws \Drupal\Core\Entity\EntityStorageException
   */
  public static function deleteDuplicateValues(ContentEntityInterface $entity, string $field_name, $need_save = FALSE) {
    $result = [];
    /** @var \Drupal\Core\Field\EntityReferenceFieldItemListInterface $reference_field */
    $reference_field = $entity->get($field_name);
    $referenced_entities = $reference_field->referencedEntities();
    /** @var \Drupal\Core\Entity\ContentEntityInterface $item */
    foreach ($referenced_entities as $item) {
      $result[$item->id()] = $item;
    }
    $entity->set($field_name, $result);
    if ($need_save) {
      $entity->save();
    }
  }

And use this like :

CLASS_NAME::deleteDuplicateValues($entity, 'tags_people');

Upvotes: 0

LucasHodge
LucasHodge

Reputation: 1

I solved this with by implementing hook_feeds_presave in a custom module.

The following checks field_my_field_name for duplicates in the array by key value and removes them before the node is imported/saved.

<?php
function my_module_feeds_presave(FeedsSource $source, $entity, $item) {
  $items_array = $entity->field_my_field_name[LANGUAGE_NONE];
  $entity->field_my_field_name[LANGUAGE_NONE] = unique_multidim_array($items_array,'value');
}

function unique_multidim_array($array, $key) {
  $temp_array = array();
  $i = 0;
  $key_array = array();

  foreach($array as $val) {
    if (!in_array($val[$key], $key_array)) {
      $key_array[$i] = $val[$key];
      $temp_array[$i] = $val;
    }
    $i++;
  }
  return $temp_array;
}
?>

Upvotes: 0

Josh S.
Josh S.

Reputation: 597

There's probably better ways to accomplish this but here's a solution.

$unique = [];

$field_tags_people['und'] = array_filter($field_tags_people['und'],
    function ($val) use (&$unique) {
        if (!in_array($val['target_id'],$unique)) {
            $unique[] = $val['target_id'];
            return true;
        }
        return false; 
    }
);

unset($unique);

This'll trim the duplicates out for you. but be reminded that the key structure will not be reset so you could have keys going in the order like 0, 1, 6, 7, 10

Cheers

EDIT: Online Example: http://sandbox.onlinephpfunctions.com/code/9b4323a0b07ab8cd46b34a3715ea030f83e0b100

Upvotes: 0

Related Questions