View source
<?php
namespace Drupal\gdpr_tasks\Traversal;
use Drupal\anonymizer\Anonymizer\AnonymizerFactory;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\FieldableEntityInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\TypedData\Exception\ReadOnlyException;
use Drupal\gdpr_fields\Entity\GdprField;
use Drupal\gdpr_fields\Entity\GdprFieldConfigEntity;
use Drupal\gdpr_fields\EntityTraversal;
use Exception;
use Symfony\Component\DependencyInjection\ContainerInterface;
class RightToBeForgottenEntityTraversal extends EntityTraversal {
private $anonymizerFactory;
private $moduleHandler;
public static function create(ContainerInterface $container, EntityInterface $base_entity) {
return new static($container
->get('entity_type.manager'), $container
->get('entity_field.manager'), $base_entity, $container
->get('module_handler'), $container
->get('anonymizer.anonymizer_factory'));
}
public function __construct(EntityTypeManagerInterface $entityTypeManager, EntityFieldManagerInterface $entityFieldManager, $base_entity, ModuleHandlerInterface $module_handler, AnonymizerFactory $anonymizer_factory) {
parent::__construct($entityTypeManager, $entityFieldManager, $base_entity);
$this->moduleHandler = $module_handler;
$this->anonymizerFactory = $anonymizer_factory;
}
public function traverseEntity(EntityInterface $entity) {
$this->results = [
'errors' => [],
'successes' => [],
'failures' => [],
'log' => [],
'to_delete' => [],
];
$this
->doTraversalRecursive($entity);
}
protected function processEntity(FieldableEntityInterface $entity, GdprFieldConfigEntity $config, $row_id, GdprField $parent_config = NULL) {
$entity_success = TRUE;
$entity_type = $entity
->getEntityTypeId();
$fields = $this->entityFieldManager
->getFieldDefinitions($entity_type, $entity
->bundle());
$field_configs = $config
->getFieldsForBundle($entity
->bundle());
$entity = $this->entityTypeManager
->getStorage($entity_type)
->loadUnchanged($entity
->id());
foreach ($fields as $field_id => $field_definition) {
$field_config = isset($field_configs[$field_id]) ? $field_configs[$field_id] : NULL;
if ($field_config === NULL || !$field_config->enabled || !in_array($field_config->rtf, [
'anonymize',
'remove',
'maybe',
])) {
continue;
}
$mode = $field_config->rtf;
$field = $entity
->get($field_id);
$success = TRUE;
$msg = NULL;
$anonymizer = '';
if ($mode == 'anonymize') {
list($success, $msg, $anonymizer) = $this
->anonymize($field, $field_definition, $field_config);
}
elseif ($mode == 'remove') {
list($success, $msg, $should_delete) = $this
->remove($field, $field_config, $entity);
}
if ($success === TRUE) {
$this->results['log'][] = [
'entity_id' => $entity
->id(),
'entity_type' => $entity_type . '.' . $entity
->bundle(),
'field_name' => $field
->getName(),
'action' => $mode,
'anonymizer' => $anonymizer,
];
}
else {
$entity_success = FALSE;
$this->results['errors'][] = $msg;
}
}
if ($entity_success) {
if (isset($should_delete) && $should_delete) {
$this->results['to_delete'][] = $entity;
}
else {
$this->results['successes'][] = $entity;
}
}
else {
$this->results['failures'][] = $entity;
}
}
private function remove(FieldItemListInterface $field, GdprField $field_config, EntityInterface $entity) {
try {
$should_delete = FALSE;
$entity_type = $entity
->getEntityType();
$error_message = NULL;
if ($entity_type
->getKey('id') == $field
->getName()) {
$should_delete = TRUE;
return [
TRUE,
NULL,
$should_delete,
];
}
if (!$field_config
->propertyCanBeRemoved($field
->getFieldDefinition(), $error_message)) {
return [
FALSE,
$error_message,
$should_delete,
];
}
$field
->setValue(NULL);
return [
TRUE,
NULL,
$should_delete,
];
} catch (ReadOnlyException $e) {
return [
FALSE,
$e
->getMessage(),
$should_delete,
];
}
}
private function anonymize(FieldItemListInterface $field, FieldDefinitionInterface $field_definition, GdprField $field_config) {
$anonymizer_id = $this
->getAnonymizerId($field_definition, $field_config);
if (!$anonymizer_id) {
return [
FALSE,
"Could not anonymize field {$field->getName()}. Please consider changing this field from 'anonymize' to 'remove', or register a custom anonymizer.",
NULL,
];
}
try {
$anonymizer = $this->anonymizerFactory
->get($anonymizer_id);
$field
->setValue($anonymizer
->anonymize($field->value, $field));
return [
TRUE,
NULL,
$anonymizer_id,
];
} catch (Exception $e) {
return [
FALSE,
$e
->getMessage(),
NULL,
];
}
}
private function getAnonymizerId(FieldDefinitionInterface $field_definition, GdprField $field_config) {
$anonymizer = $field_config->anonymizer;
$type = $field_definition
->getType();
if (!$anonymizer) {
$anonymizers = [
'string' => 'gdpr_text_anonymizer',
'datetime' => 'gdpr_date_anonymizer',
];
$this->moduleHandler
->alter('gdpr_type_anonymizers', $anonymizers);
$anonymizer = $anonymizers[$type];
}
return $anonymizer;
}
}