View source
<?php
namespace Drupal\entity_usage;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Database\Connection;
use Drupal\Core\Database\IntegrityConstraintViolationException;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\entity_usage\Events\Events;
use Drupal\entity_usage\Events\EntityUsageEvent;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
class EntityUsage implements EntityUsageInterface {
protected $connection;
protected $tableName;
protected $eventDispatcher;
protected $config;
protected $moduleHandler;
public function __construct(Connection $connection, EventDispatcherInterface $event_dispatcher, ConfigFactoryInterface $config_factory, ModuleHandlerInterface $module_handler, $table = 'entity_usage') {
$this->connection = $connection;
$this->tableName = $table;
$this->eventDispatcher = $event_dispatcher;
$this->moduleHandler = $module_handler;
$this->config = $config_factory
->get('entity_usage.settings');
}
public function registerUsage($target_id, $target_type, $source_id, $source_type, $source_langcode, $source_vid) {
$enabled_target_entity_types = $this->config
->get('track_enabled_target_entity_types');
if (is_array($enabled_target_entity_types) && !in_array($target_type, $enabled_target_entity_types, TRUE)) {
return;
}
$context = [
'target_id' => $target_id,
'target_type' => $target_type,
'source_id' => $source_id,
'source_type' => $source_type,
'source_langcode' => $source_langcode,
'source_vid' => $source_vid,
];
$abort = $this->moduleHandler
->invokeAll('entity_usage_block_tracking', $context);
if (in_array(TRUE, $abort, TRUE)) {
return;
}
$target_id_column = $this
->isInt($target_id) ? 'target_id' : 'target_id_string';
$source_id_column = $this
->isInt($source_id) ? 'source_id' : 'source_id_string';
try {
$this->connection
->insert($this->tableName)
->fields([
$target_id_column => $target_id,
'target_type' => $target_type,
$source_id_column => $source_id,
'source_type' => $source_type,
'source_langcode' => $source_langcode,
'source_vid' => $source_vid ?: 0,
])
->execute();
} catch (IntegrityConstraintViolationException $e) {
if (strpos($e
->getMessage(), 'Duplicate entry') !== FALSE) {
return;
}
throw $e;
}
$event = new EntityUsageEvent($target_id, $target_type, $source_id, $source_type, $source_langcode, $source_vid);
$this->eventDispatcher
->dispatch(Events::USAGE_REGISTER, $event);
}
public function deleteUsage($target_id, $target_type, $source_id, $source_type, $source_langcode, $source_vid) {
$target_id_column = $this
->isInt($target_id) ? 'target_id' : 'target_id_string';
$source_id_column = $this
->isInt($source_id) ? 'source_id' : 'source_id_string';
$query = $this->connection
->delete($this->tableName)
->condition('target_type', $target_type)
->condition($target_id_column, $target_id)
->condition('source_type', $source_type)
->condition($source_id_column, $source_id)
->condition('source_langcode', $source_langcode)
->condition('source_vid', $source_vid);
$query
->execute();
$event = new EntityUsageEvent($target_id, $target_type, $source_id, $source_type, $source_langcode, $source_vid);
$this->eventDispatcher
->dispatch(Events::BULK_DELETE_SOURCES, $event);
}
public function bulkDeleteTargets($target_type) {
$query = $this->connection
->delete($this->tableName)
->condition('target_type', $target_type);
$query
->execute();
$event = new EntityUsageEvent(NULL, $target_type, NULL, NULL, NULL, NULL);
$this->eventDispatcher
->dispatch(Events::BULK_DELETE_DESTINATIONS, $event);
}
public function bulkDeleteSources($source_type) {
$query = $this->connection
->delete($this->tableName)
->condition('source_type', $source_type);
$query
->execute();
$event = new EntityUsageEvent(NULL, NULL, NULL, $source_type, NULL, NULL);
$this->eventDispatcher
->dispatch(Events::BULK_DELETE_SOURCES, $event);
}
public function deleteBySourceEntity($source_id, $source_type, $source_langcode = NULL, $source_vid = NULL) {
$source_id_column = $this
->isInt($source_id) ? 'source_id' : 'source_id_string';
$query = $this->connection
->delete($this->tableName)
->condition($source_id_column, $source_id)
->condition('source_type', $source_type);
if ($source_langcode) {
$query
->condition('source_langcode', $source_langcode);
}
if ($source_vid) {
$query
->condition('source_vid', $source_vid);
}
$query
->execute();
$event = new EntityUsageEvent(NULL, NULL, $source_id, $source_type, $source_langcode, $source_vid);
$this->eventDispatcher
->dispatch(Events::DELETE_BY_SOURCE_ENTITY, $event);
}
public function deleteByTargetEntity($target_id, $target_type) {
$target_id_column = $this
->isInt($target_id) ? 'target_id' : 'target_id_string';
$query = $this->connection
->delete($this->tableName)
->condition($target_id_column, $target_id)
->condition('target_type', $target_type);
$query
->execute();
$event = new EntityUsageEvent($target_id, $target_type, NULL, NULL, NULL, NULL);
$this->eventDispatcher
->dispatch(Events::DELETE_BY_TARGET_ENTITY, $event);
}
public function listSources(EntityInterface $target_entity, $nest_results = TRUE) {
$target_id_column = $this
->isInt($target_entity
->id()) ? 'target_id' : 'target_id_string';
$result = $this->connection
->select($this->tableName, 'e')
->fields('e', [
'source_id',
'source_id_string',
'source_type',
'source_langcode',
'source_vid',
])
->condition($target_id_column, $target_entity
->id())
->condition('target_type', $target_entity
->getEntityTypeId())
->orderBy('source_type')
->orderBy('source_id', 'DESC')
->orderBy('source_vid', 'DESC')
->orderBy('source_langcode')
->execute();
$references = [];
foreach ($result as $usage) {
$source_id_value = !empty($usage->source_id) ? (string) $usage->source_id : (string) $usage->source_id_string;
if ($nest_results) {
$references[$usage->source_type][$source_id_value][] = [
'source_langcode' => $usage->source_langcode,
'source_vid' => $usage->source_vid,
];
}
else {
$references[] = [
'source_type' => $usage->source_type,
'source_id' => $source_id_value,
'source_langcode' => $usage->source_langcode,
'source_vid' => $usage->source_vid,
];
}
}
return $references;
}
public function listTargets(EntityInterface $source_entity) {
$source_id_column = $this
->isInt($source_entity
->id()) ? 'source_id' : 'source_id_string';
$result = $this->connection
->select($this->tableName, 'e')
->fields('e', [
'target_id',
'target_id_string',
'target_type',
])
->condition($source_id_column, $source_entity
->id())
->condition('source_type', $source_entity
->getEntityTypeId())
->orderBy('target_id', 'DESC')
->execute();
$references = [];
foreach ($result as $usage) {
$target_id_value = !empty($usage->target_id) ? $usage->target_id : $usage->target_id_string;
$references[$usage->target_type][] = $target_id_value;
}
return $references;
}
protected function isInt($value) {
return (string) (int) $value === (string) $value && strlen($value) < 11;
}
}