toolshed-8.x-1.x-dev/src/Entity/EntityBundleBase.php

src/Entity/EntityBundleBase.php
<?php

namespace Drupal\toolshed\Entity;

use Drupal\Component\Render\MarkupInterface;
use Drupal\Component\Utility\Html;
use Drupal\Core\Config\Entity\ConfigEntityBundleBase;
use Drupal\Core\Entity\EntityStorageException;
use Drupal\Core\Entity\EntityStorageInterface;

/**
 * A bundle entity which checks for content using the bundle before deleting.
 */
abstract class EntityBundleBase extends ConfigEntityBundleBase {

  /**
   * Check if this bundle has content data.
   *
   * New config entities cannot have any content created for them yet, so will
   * always return FALSE.
   *
   * @return bool
   *   TRUE if there is content using the type as a bundle, or FALSE is there
   *   is no data of this type.
   */
  public function hasData(): bool {
    $bundleOf = $this->getEntityType()->getBundleOf();

    if (!$this->isNew() && $bundleOf) {
      $entityTypeManager = \Drupal::entityTypeManager();
      $bundleKey = $entityTypeManager
        ->getDefinition($bundleOf)
        ->getKey('bundle');

      return (bool) $entityTypeManager->getStorage($bundleOf)
        ->getQuery()
        ->accessCheck(FALSE)
        ->condition($bundleKey, $this->id())
        ->range(0, 1)
        ->execute();
    }

    return FALSE;
  }

  /**
   * {@inheritdoc}
   */
  public static function preDelete(EntityStorageInterface $storage, array $entities): void {
    $entityTypeManager = \Drupal::entityTypeManager();

    // Sort the entities by their entity type. This should only ever be
    // one entity type, but it's worth doing this safely, by checking first.
    $byBundleOf = [];

    foreach ($entities as $entity) {
      if ($bundleOf = $entity->getEntityType()->getBundleOf()) {
        $label = $entity->label();
        $byBundleOf[$bundleOf][$entity->id()] = $label instanceof MarkupInterface ? $label : Html::escape($label);
      }
    }

    foreach ($byBundleOf as $contentTypeId => $bundles) {
      $contentEntityType = $entityTypeManager->getDefinition($contentTypeId);

      $query = $entityTypeManager
        ->getStorage($contentTypeId)
        ->getQuery()
        ->accessCheck(FALSE)
        ->range(0, 1);

      $bundleIds = array_keys($bundles);
      if (count($bundles) === 1) {
        $query->condition($contentEntityType->getKey('bundle'), reset($bundleIds));
      }
      else {
        $query->condition($contentEntityType->getKey('bundle'), $bundleIds, 'IN');
      }

      if ((bool) $query->execute()) {
        $msg = count($bundles)
          ? 'The %s bundle contains data and can not be deleted.'
          : 'The some or all of the following %s bundles contain data and cannot be delete.';

        // Use the 409 (Conflict) status code to indicate that the deletion
        // could not be completed due to a conflict with the current state of
        // the target resource.
        $msg = sprintf($msg, implode(', ', $bundles));
        throw new EntityStorageException($msg, 409);
      }
    }

    parent::preDelete($storage, $entities);
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc