Last active
September 4, 2021 18:14
-
-
Save mxr576/f5a0a5854c13696571c78cbdabe86274 to your computer and use it in GitHub Desktop.
"Smart" (content) entity type base in Drupal 8/9/10?
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
declare(strict_types = 1); | |
namespace Drupal\my_module_entity\Annotation; | |
use Drupal\Core\Entity\Annotation\EntityType; | |
use Drupal\Core\StringTranslation\TranslatableMarkup; | |
use Drupal\my_module_entity\Entity\MyModuleEntityType as MyModuleEntityTypeClass; | |
/** | |
* Defines a my_module entity type annotation object. | |
* | |
* @Annotation | |
*/ | |
final class MyModuleEntityType extends EntityType { | |
/** | |
* {@inheritdoc} | |
*/ | |
public $entity_type_class = MyModuleEntityTypeClass::class; | |
/** | |
* {@inheritdoc} | |
*/ | |
public $group = 'my_module_entity'; | |
/** | |
* {@inheritdoc} | |
*/ | |
public function get() { | |
$this->definition['group_label'] = new TranslatableMarkup('My Module Entity', [], ['context' => 'Entity type group']); | |
return parent::get(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
declare(strict_types = 1); | |
namespace Drupal\my_module_entity\Entity; | |
use Drupal\Component\Utility\NestedArray; | |
use Drupal\Core\Entity\ContentEntityType; | |
use Drupal\entity\Menu\DefaultEntityLocalTaskProvider; | |
use Drupal\entity\Routing\DefaultHtmlRouteProvider; | |
use Drupal\entity\UncacheableEntityAccessControlHandler; | |
use Drupal\my_module_entity\Access\EntityPermissionProvider; | |
use Drupal\my_module_entity\Form\MyModuleEntityDeleteForm; | |
use Drupal\my_module_entity\Form\MyModuleEntityForm; | |
use Drupal\my_module_entity\MyModuleEntityListBuilder; | |
use Drupal\my_module_entity\MyModuleEntityViewBuilder; | |
use Drupal\my_module_entity\Storage\MyModuleEntityStorage; | |
use Drupal\views\EntityViewsData; | |
/** | |
* Generic entity type definition for My Module entities. | |
*/ | |
class MyModuleEntityType extends ContentEntityType { | |
/** | |
* {@inheritdoc} | |
*/ | |
protected $common_reference_target = TRUE; | |
/** | |
* Constructs a new object. | |
* | |
* @param array $definition | |
* Array of properties and values. | |
*/ | |
public function __construct(array $definition) { | |
// Provide sane defaults for all entity types. | |
$defaults = [ | |
'entity_keys' => [ | |
// It seems all revisionable entity has to have a numerical identifier | |
// otherwise system collapse with "Field storage definition for '' could | |
// not be found.". The UUID of an entity cannot be used as an id either. | |
'id' => 'id', | |
'label' => 'name', | |
'uuid' => 'uuid', | |
'owner' => 'uid', | |
'published' => 'published', | |
// We need to have language code to all our entities because it is | |
// required by things like sub path aliases. | |
'langcode' => 'langcode', | |
// @todo This should be only set if the entity is revisionable. | |
'revision' => 'revision_id', | |
], | |
// @todo This should be only set if the entity is revisionable. | |
'revision_metadata_keys' => [ | |
'revision_user' => 'revision_user', | |
'revision_created' => 'revision_created', | |
'revision_log_message' => 'revision_log_message', | |
], | |
'handlers' => [ | |
'access' => UncacheableEntityAccessControlHandler::class, | |
'permission_provider' => EntityPermissionProvider::class, | |
'storage' => MyModuleEntityStorage::class, | |
'view_builder' => MyModuleEntityViewBuilder::class, | |
'list_builder' => MyModuleEntityListBuilder::class, | |
'form' => [ | |
'default' => MyModuleEntityForm::class, | |
'delete' => MyModuleEntityDeleteForm::class, | |
], | |
'route_provider' => ['html' => DefaultHtmlRouteProvider::class], | |
'local_task_provider' => ['default' => DefaultEntityLocalTaskProvider::class], | |
], | |
]; | |
// DI is not available here. | |
/** @var \Drupal\Core\Extension\ModuleHandlerInterface $module_handler */ | |
$module_handler = \Drupal::service('module_handler'); | |
if ($module_handler->moduleExists('views')) { | |
$defaults['handlers']['views_data'] = EntityViewsData::class; | |
} | |
$definition = NestedArray::mergeDeepArray([$defaults, $definition]); | |
/* @noinspection PhpUnhandledExceptionInspection */ | |
parent::__construct($definition); | |
$this->base_table = $this->base_table ?? $definition['id']; | |
// @see https://www.drupal.org/project/drupal/issues/3198925 | |
// #DrupalFootgun | |
if ($this->isTranslatable()) { | |
$this->data_table = $this->data_table ?? $definition['id'] . '_field_data'; | |
} | |
if ($this->isRevisionable()) { | |
$this->revision_table = $this->revision_table ?? $definition['id'] . '_revision'; | |
$this->show_revision_ui = TRUE; | |
} | |
if ($this->isTranslatable() && $this->isRevisionable()) { | |
$this->revision_data_table = $this->revision_data_table ?? $definition['id'] . '_field_revision'; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment