3 namespace Drupal\Core\Config\Entity;
5 use Drupal\Core\Config\ConfigNameException;
6 use Drupal\Core\Entity\EntityStorageInterface;
9 * A base class for config entity types that act as bundles.
11 * Entity types that want to use this base class must use bundle_of in their
12 * annotation to specify for which entity type they are providing bundles for.
14 abstract class ConfigEntityBundleBase extends ConfigEntityBase {
17 * Deletes display if a bundle is deleted.
19 protected function deleteDisplays() {
20 // Remove entity displays of the deleted bundle.
21 if ($displays = $this->loadDisplays('entity_view_display')) {
22 $storage = $this->entityManager()->getStorage('entity_view_display');
23 $storage->delete($displays);
26 // Remove entity form displays of the deleted bundle.
27 if ($displays = $this->loadDisplays('entity_form_display')) {
28 $storage = $this->entityManager()->getStorage('entity_form_display');
29 $storage->delete($displays);
36 public function postSave(EntityStorageInterface $storage, $update = TRUE) {
37 parent::postSave($storage, $update);
39 $entity_manager = $this->entityManager();
40 $bundle_of = $this->getEntityType()->getBundleOf();
42 $entity_manager->onBundleCreate($this->id(), $bundle_of);
45 // Invalidate the render cache of entities for which this entity
47 if ($entity_manager->hasHandler($bundle_of, 'view_builder')) {
48 $entity_manager->getViewBuilder($bundle_of)->resetCache();
50 // Entity bundle field definitions may depend on bundle settings.
51 $entity_manager->clearCachedFieldDefinitions();
52 $entity_manager->clearCachedBundles();
59 public static function postDelete(EntityStorageInterface $storage, array $entities) {
60 parent::postDelete($storage, $entities);
62 foreach ($entities as $entity) {
63 $entity->deleteDisplays();
64 \Drupal::entityManager()->onBundleDelete($entity->id(), $entity->getEntityType()->getBundleOf());
69 * Acts on an entity before the presave hook is invoked.
71 * Used before the entity is saved and before invoking the presave hook.
73 * Ensure that config entities which are bundles of other entities cannot have
76 * @param \Drupal\Core\Entity\EntityStorageInterface $storage
77 * The entity storage object.
79 * @throws \Drupal\Core\Config\ConfigNameException
80 * Thrown when attempting to rename a bundle entity.
82 public function preSave(EntityStorageInterface $storage) {
83 parent::preSave($storage);
85 // Only handle renames, not creations.
86 if (!$this->isNew() && $this->getOriginalId() !== $this->id()) {
87 $bundle_type = $this->getEntityType();
88 $bundle_of = $bundle_type->getBundleOf();
89 if (!empty($bundle_of)) {
90 throw new ConfigNameException("The machine name of the '{$bundle_type->getLabel()}' bundle cannot be changed.");
96 * Returns view or form displays for this bundle.
98 * @param string $entity_type_id
99 * The entity type ID of the display type to load.
101 * @return \Drupal\Core\Entity\Display\EntityDisplayInterface[]
102 * A list of matching displays.
104 protected function loadDisplays($entity_type_id) {
105 $ids = \Drupal::entityQuery($entity_type_id)
106 ->condition('id', $this->getEntityType()->getBundleOf() . '.' . $this->getOriginalId() . '.', 'STARTS_WITH')
109 $storage = $this->entityManager()->getStorage($entity_type_id);
110 return $storage->loadMultiple($ids);