View source
<?php
namespace Drupal\entity_usage\Plugin\EntityUsage\Track;
use Drupal\Core\Config\Entity\ConfigEntityTypeInterface;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\entity_usage\EntityUsage;
use Drupal\entity_usage\EntityUsageTrackBase;
use Drupal\entity_usage\EntityUsageTrackInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
class EntityReference extends EntityUsageTrackBase {
protected $entityFieldManager;
protected $entityTypeManager;
public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityUsage $usage_service, EntityFieldManagerInterface $entity_field_manager, EntityTypeManagerInterface $entity_type_manager) {
parent::__construct($configuration, $plugin_id, $plugin_definition, $usage_service);
$this->entityFieldManager = $entity_field_manager;
$this->entityTypeManager = $entity_type_manager;
}
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static($configuration, $plugin_id, $plugin_definition, $container
->get('entity_usage.usage'), $container
->get('entity_field.manager'), $container
->get('entity_type.manager'));
}
public function trackOnEntityCreation(ContentEntityInterface $entity) {
foreach ($this
->entityReferenceFieldsAvailable($entity) as $field_name) {
if (!$entity->{$field_name}
->isEmpty()) {
foreach ($entity->{$field_name} as $field_item) {
$this
->incrementEntityReferenceUsage($entity, $field_name, $field_item->target_id);
}
}
}
}
public function trackOnEntityUpdate(ContentEntityInterface $entity) {
$translations = [];
$originals = [];
$languages = $entity
->getTranslationLanguages();
foreach ($languages as $langcode => $language) {
if (!$entity
->hasTranslation($langcode)) {
continue;
}
$translations[] = $entity
->getTranslation($langcode);
if (!$entity->original
->hasTranslation($langcode)) {
continue;
}
$originals[] = $entity->original
->getTranslation($langcode);
}
foreach ($this
->entityReferenceFieldsAvailable($entity) as $field_name) {
$current_target_ids = [];
foreach ($translations as $translation) {
if (!$translation->{$field_name}
->isEmpty()) {
foreach ($translation->{$field_name} as $field_item) {
$current_target_ids[] = $field_item->target_id;
}
}
}
$original_target_ids = [];
foreach ($originals as $original) {
if (!$original->{$field_name}
->isEmpty()) {
foreach ($original->{$field_name} as $field_item) {
$original_target_ids[] = $field_item->target_id;
}
}
}
$original_target_ids = array_unique($original_target_ids);
$current_target_ids = array_unique($current_target_ids);
$added_ids = array_diff($current_target_ids, $original_target_ids);
$removed_ids = array_diff($original_target_ids, $current_target_ids);
foreach ($added_ids as $id) {
$this
->incrementEntityReferenceUsage($entity, $field_name, $id);
}
foreach ($removed_ids as $id) {
$this
->decrementEntityReferenceUsage($entity, $field_name, $id);
}
}
}
public function trackOnEntityDeletion(ContentEntityInterface $entity) {
$translations = [];
if ($entity === $entity
->getUntranslated()) {
$languages = $entity
->getTranslationLanguages();
foreach ($languages as $langcode => $language) {
if (!$entity
->hasTranslation($langcode)) {
continue;
}
$translations[] = $entity
->getTranslation($langcode);
}
}
else {
$translations = [
$entity,
];
}
foreach ($this
->entityReferenceFieldsAvailable($entity) as $field_name) {
foreach ($translations as $translation) {
if (!$translation->{$field_name}
->isEmpty()) {
foreach ($translation->{$field_name} as $field_item) {
$this
->decrementEntityReferenceUsage($entity, $field_name, $field_item->target_id);
}
}
}
}
}
private function entityReferenceFieldsAvailable(ContentEntityInterface $entity) {
$return_fields = [];
$fields_on_entity = $this->entityFieldManager
->getFieldDefinitions($entity
->getEntityTypeId(), $entity
->bundle());
$entityref_fields_on_this_entity_type = [];
if (!empty($this->entityFieldManager
->getFieldMapByFieldType('entity_reference')[$entity
->getEntityTypeId()])) {
$entityref_fields_on_this_entity_type = $this->entityFieldManager
->getFieldMapByFieldType('entity_reference')[$entity
->getEntityTypeId()];
}
$entityref_on_this_bundle = array_intersect_key($fields_on_entity, $entityref_fields_on_this_entity_type);
$basefields = $this->entityFieldManager
->getBaseFieldDefinitions($entity
->getEntityTypeId());
$entityref_on_this_bundle = array_diff_key($entityref_on_this_bundle, $basefields);
if (!empty($entityref_on_this_bundle)) {
foreach ($entityref_on_this_bundle as $key => $entityref) {
$target_type = $entityref_on_this_bundle[$key]
->getItemDefinition()
->getSettings()['target_type'];
$entity_type = $this->entityTypeManager
->getStorage($target_type)
->getEntityType();
if ($entity_type instanceof ConfigEntityTypeInterface) {
unset($entityref_on_this_bundle[$key]);
}
}
$return_fields = array_keys($entityref_on_this_bundle);
}
return $return_fields;
}
private function incrementEntityReferenceUsage(ContentEntityInterface $entity, $field_name, $target_id) {
$definition = $this->entityFieldManager
->getFieldDefinitions($entity
->getEntityTypeId(), $entity
->bundle())[$field_name];
$referenced_entity_type = $definition
->getSetting('target_type');
$this->usageService
->add($target_id, $referenced_entity_type, $entity
->id(), $entity
->getEntityTypeId(), $this->pluginId);
}
private function decrementEntityReferenceUsage(ContentEntityInterface $entity, $field_name, $target_id) {
$definition = $this->entityFieldManager
->getFieldDefinitions($entity
->getEntityTypeId(), $entity
->bundle())[$field_name];
$referenced_entity_type = $definition
->getSetting('target_type');
$this->usageService
->delete($target_id, $referenced_entity_type, $entity
->id(), $entity
->getEntityTypeId());
}
}