Skip to content

Instantly share code, notes, and snippets.

@ohthehugemanatee
Created September 18, 2017 11:10
Show Gist options
  • Save ohthehugemanatee/50e8f0f4ef0958a2e48414ab4b98e8bc to your computer and use it in GitHub Desktop.
Save ohthehugemanatee/50e8f0f4ef0958a2e48414ab4b98e8bc to your computer and use it in GitHub Desktop.
Add revisions to an existing entity. In a project for RAS I had to add revisions to an existing entity. There are some small modifications necessary to the entity class itself, and two update hooks to apply the schema changes (core's normal process won't allow you to modify the schema of an entity type with existing data). Note that entity_ui=TR…
/**
* Add revisions to Restaurant entity schema.
*/
function ras_restaurants_update_8001() {
// @see https://www.drupal.org/node/2346013
// @see https://www.drupal.org/node/1916790
$definitionUpdateManager = \Drupal::service('entity.definition_update_manager');
if ($definitionUpdateManager->needsUpdates()) {
// Create new revision table and base fields outside of the normal schema
// update process (GASP!).
$entityTypeId = 'restaurant';
$entityDefinition = \Drupal::entityTypeManager()
->getDefinition($entityTypeId);
// Ensure all tables are created.
/** @var \Drupal\Core\Entity\Sql\SqlContentEntityStorageSchema $entityStorageSchema */
\Drupal::entityTypeManager()
->getHandler($entityTypeId, 'storage')
->onEntityTypeCreate($entityDefinition);
// Compare current with installed storage definitions.
$storageDefinitions = \Drupal::service('entity_field.manager')
->getFieldStorageDefinitions($entityTypeId);
$installedStorageDefinitions = \Drupal::service('entity.last_installed_schema.repository')
->getLastInstalledFieldStorageDefinitions($entityTypeId);
foreach (array_diff_key($storageDefinitions, $installedStorageDefinitions) as $storageDefinition) {
// Install new fields (the diff result) manually.
/* @var $storageDefinition \Drupal\Core\Field\FieldStorageDefinitionInterface */
if ($storageDefinition->getProvider() == 'ras_restaurants') {
$definitionUpdateManager->installFieldStorageDefinition($storageDefinition->getName(), $entityTypeId, 'ras_restaurants', $storageDefinition);
}
}
// Update the stored definition to match the one in code.
\Drupal::service('entity.last_installed_schema.repository')->setLastInstalledDefinition($entityDefinition);
}
}
/**
* Set an initial value for restaurant revision ID fields.
*/
function ras_restaurants_update_8002() {
$connection = \Drupal::database();
// "UPDATE restaurant SET revision_id=id, revision_created=created;".
$updateQuery = $connection->update('restaurant');
$updateQuery
->expression('revision_id', 'id')
->expression('revision_created', 'created')
->execute();
// "INSERT INTO restaurant_revision (id, revision_id, langcode,
// revision_created, status) SELECT id, id, langcode, created, status FROM
// restaurant;".
$insertQuery = $connection->insert('restaurant_revision');
$insertQuery
->fields([
'id',
'revision_id',
'langcode',
'revision_created',
'status',
]);
$insertQuery->from(
$connection->select('restaurant', 'r')
->fields('r', ['id', 'id', 'langcode', 'created', 'status'])
);
$insertQuery->execute();
}
use Drupal\Core\Entity\EntityStorageInterface;
+use Drupal\Core\Entity\RevisionableContentEntityBase;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Entity\ContentEntityBase;
use Drupal\Core\Entity\EntityChangedTrait;
@@ -19,6 +20,7 @@
* @ContentEntityType(
* id = "restaurant",
* label = @Translation("Restaurant"),
+ * show_revision_ui = TRUE,
* handlers = {
* "view_builder" = "Drupal\Core\Entity\EntityViewBuilder",
* "list_builder" = "Drupal\ras_restaurants\RestaurantEntityListBuilder",
@@ -36,9 +38,11 @@
* },
* },
* base_table = "restaurant",
+ * revision_table = "restaurant_revision",
* admin_permission = "administer restaurant entities",
* entity_keys = {
* "id" = "id",
+ * "revision" = "revision_id",
* "uuid" = "uuid",
* "langcode" = "langcode",
* "status" = "status",
@@ -56,7 +60,7 @@
* }
* )
*/
-class RestaurantEntity extends ContentEntityBase implements RestaurantEntityInterface {
+class RestaurantEntity extends RevisionableContentEntityBase implements RestaurantEntityInterface {
use EntityChangedTrait;
@@ -126,6 +130,7 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
$fields['status'] = BaseFieldDefinition::create('boolean')
->setLabel(t('Publishing status'))
->setDescription(t('A boolean indicating whether the Restaurant is published.'))
+ ->setRevisionable(TRUE)
->setDefaultValue(TRUE);
$fields['created'] = BaseFieldDefinition::create('created')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment