Skip to content
Snippets Groups Projects
TrashStorageTrait.php 2.65 KiB
Newer Older
/**
 * Provides the ability to soft-delete entities at the storage level.
 */
trait TrashStorageTrait {

  /**
   * {@inheritdoc}
   */
  public function delete(array $entities) {
    if ($this->getTrashManager()->getTrashContext() !== 'active') {
      parent::delete($entities);
    $revisionable = $this->getEntityType()->isRevisionable();

    foreach ($entities as $entity) {
      $entity->set($field_name, \Drupal::time()->getRequestTime());

      // Always create a new revision if the entity type is revisionable.
      if ($revisionable) {
        /** @var \Drupal\Core\Entity\RevisionableInterface $entity */
        $entity->setNewRevision(TRUE);
      }
      $entity->save();
    }
  }

  /**
   * {@inheritdoc}
   */
  protected function buildQuery($ids, $revision_ids = FALSE) {
    $query = parent::buildQuery($ids, $revision_ids);

    if ($this->getTrashManager()->getTrashContext() !== 'active') {
      return $query;
    }

    $table_mapping = $this->getTableMapping();
    $deleted_column = $table_mapping->getFieldColumnName($this->fieldStorageDefinitions['deleted'], 'value');

    // Ensure that entity_load excludes deleted entities.
    if ($data_table = $this->getDataTable()) {
      $query->join($data_table, 'data', "[data].[{$this->idKey}] = [base].[{$this->idKey}]");
      $query->condition("data.$deleted_column", NULL, 'IS NULL');
    }
    else {
      $query->condition("base.$deleted_column", NULL, 'IS NULL');
    }

    return $query;
  }

  /**
   * {@inheritdoc}
   */
  protected function setPersistentCache($entities) {
    if (!$this->entityType->isPersistentlyCacheable()) {
      return;
    }

    // Ensure that deleted entities are never stored in the persistent cache.
    foreach ($entities as $id => $entity) {
      if (trash_entity_is_deleted($entity)) {
        unset($entities[$id]);
      }
    }

    parent::setPersistentCache($entities);
  }

  /**
   * {@inheritdoc}
   */
  protected function getStorageSchema() {
    if (!isset($this->storageSchema)) {
      $class = $this->entityType->getHandlerClass('storage_schema') ?: 'Drupal\Core\Entity\Sql\SqlContentEntityStorageSchema';

      // Ensure that we use our generated storage schema class.
      $class = _trash_generate_storage_class($class, 'storage_schema');

      $this->storageSchema = new $class($this->entityTypeManager, $this->entityType, $this, $this->database, $this->entityFieldManager);
    }
    return $this->storageSchema;
  }

  /**
   * Gets the trash manager service.
   */
  private function getTrashManager(): TrashManagerInterface {
    return \Drupal::service('trash.manager');
  }