View source
<?php
namespace Drupal\entity_usage\Plugin\EntityUsage\Track;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\ContentEntityTypeInterface;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\entity_usage\EntityUsage;
use Drupal\entity_usage\EntityUsageTrackBase;
use Drupal\link\LinkItemInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
class Link 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
->linkFieldsAvailable($entity) as $field_name) {
if ($entity
->hasField($field_name) && !$entity->{$field_name}
->isEmpty()) {
foreach ($entity->{$field_name} as $field_item) {
$target_entity = $this
->getTargetEntity($field_item);
if ($target_entity) {
list($target_type, $target_id) = explode('|', $target_entity);
$this->usageService
->add($target_id, $target_type, $entity
->id(), $entity
->getEntityTypeId(), $this->pluginId);
}
}
}
}
}
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
->linkFieldsAvailable($entity) as $field_name) {
$current_targets = [];
foreach ($translations as $translation) {
if ($translation
->hasField($field_name) && !$translation->{$field_name}
->isEmpty()) {
foreach ($translation->{$field_name} as $field_item) {
$target_entity = $this
->getTargetEntity($field_item);
if ($target_entity) {
$current_targets[] = $target_entity;
}
}
}
}
$original_targets = [];
foreach ($originals as $original) {
if ($original
->hasField($field_name) && !$original->{$field_name}
->isEmpty()) {
foreach ($original->{$field_name} as $field_item) {
$target_entity = $this
->getTargetEntity($field_item);
if ($target_entity) {
$original_targets[] = $target_entity;
}
}
}
}
$original_targets = array_unique($original_targets);
$current_targets = array_unique($current_targets);
$added_ids = array_diff($current_targets, $original_targets);
$removed_ids = array_diff($original_targets, $current_targets);
foreach ($added_ids as $added_entity) {
list($target_type, $target_id) = explode('|', $added_entity);
$this->usageService
->add($target_id, $target_type, $entity
->id(), $entity
->getEntityTypeId(), $this->pluginId);
}
foreach ($removed_ids as $removed_entity) {
list($target_type, $target_id) = explode('|', $removed_entity);
$this->usageService
->delete($target_id, $target_type, $entity
->id(), $entity
->getEntityTypeId());
}
}
}
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
->linkFieldsAvailable($entity) as $field_name) {
foreach ($translations as $translation) {
if ($translation
->hasField($field_name) && !$translation->{$field_name}
->isEmpty()) {
foreach ($translation->{$field_name} as $field_item) {
$target_entity = $this
->getTargetEntity($field_item);
if ($target_entity) {
list($target_type, $target_id) = explode('|', $target_entity);
$this->usageService
->delete($target_id, $target_type, $entity
->id(), $entity
->getEntityTypeId());
}
}
}
}
}
}
private function linkFieldsAvailable(ContentEntityInterface $entity) {
$return_fields = [];
$fields_on_entity = $this->entityFieldManager
->getFieldDefinitions($entity
->getEntityTypeId(), $entity
->bundle());
$link_fields_on_this_entity_type = [];
if (!empty($this->entityFieldManager
->getFieldMapByFieldType('link')[$entity
->getEntityTypeId()])) {
$link_fields_on_this_entity_type = $this->entityFieldManager
->getFieldMapByFieldType('link')[$entity
->getEntityTypeId()];
}
$link_fields_on_this_bundle = array_intersect_key($fields_on_entity, $link_fields_on_this_entity_type);
$basefields = $this->entityFieldManager
->getBaseFieldDefinitions($entity
->getEntityTypeId());
$link_fields_on_this_bundle = array_diff_key($link_fields_on_this_bundle, $basefields);
if (!empty($link_fields_on_this_bundle)) {
$return_fields = array_keys($link_fields_on_this_bundle);
}
return $return_fields;
}
private function getTargetEntity(LinkItemInterface $link) {
$url = $link
->getUrl();
if (!$url
->isRouted() || !preg_match('/^entity\\./', $url
->getRouteName())) {
return NULL;
}
$route_parameters = $url
->getRouteParameters();
$target_type = array_keys($route_parameters)[0];
$target_id = $route_parameters[$target_type];
if (!$this->entityTypeManager
->getDefinition($target_type) instanceof ContentEntityTypeInterface) {
return NULL;
}
return $target_type . '|' . $target_id;
}
}