Skip to content

Instantly share code, notes, and snippets.

@mxr576
Last active September 4, 2021 18:14
Show Gist options
  • Save mxr576/f5a0a5854c13696571c78cbdabe86274 to your computer and use it in GitHub Desktop.
Save mxr576/f5a0a5854c13696571c78cbdabe86274 to your computer and use it in GitHub Desktop.
"Smart" (content) entity type base in Drupal 8/9/10?
<?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();
}
}
<?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