diff --git a/config/schema/group.schema.yml b/config/schema/group.schema.yml index 340838e..4829d1b 100644 --- a/config/schema/group.schema.yml +++ b/config/schema/group.schema.yml @@ -33,6 +33,9 @@ group.type.*: sequence: type: 'string' label: 'Group role ID' + use_revisions: + type: boolean + label: 'User revisions' group_content_enabler.config.group_cardinality: type: 'integer' diff --git a/group.info.yml b/group.info.yml index 172ffc5..1e8ef1f 100644 --- a/group.info.yml +++ b/group.info.yml @@ -8,3 +8,4 @@ configure: 'group.settings' dependencies: - 'drupal:options' - 'drupal:system (>=8.5.0)' + - 'drupal:entity' diff --git a/group.post_update.php b/group.post_update.php index 1b2df17..6c5f3ee 100644 --- a/group.post_update.php +++ b/group.post_update.php @@ -8,6 +8,8 @@ use Drupal\group\Entity\GroupType; use Drupal\group\Entity\GroupContentType; use Drupal\user\Entity\Role; +use Drupal\Core\Entity\Sql\SqlContentEntityStorageSchemaConverter; +use Drupal\group\Entity\Group; /** * Recalculate group type and group content type dependencies after moving the @@ -45,3 +47,41 @@ function group_post_update_grant_access_overview_permission() { } } } + +/** + * Update Group to be revisionable. + */ +function group_post_update_make_group_revisionable(&$sandbox) { + $schema_converter = new SqlContentEntityStorageSchemaConverter( + 'group', + \Drupal::entityTypeManager(), + \Drupal::entityDefinitionUpdateManager(), + \Drupal::service('entity.last_installed_schema.repository'), + \Drupal::keyValue('entity.storage_schema.sql'), + \Drupal::database() + ); + + $schema_converter->convertToRevisionable( + $sandbox, + [ + 'label', + 'uid', + 'created', + 'changed', + ] + ); +} + +/** + * Set values to the new revision fields. + */ +function group_post_update_set_values_revision_table() { + // Update groups_revision.revision_created and groups_revision.revision_update + $groups = Group::loadMultiple(); + foreach ($groups as $group) { + /** @var Drupal\group\Entity\Group $group */ + $group->setRevisionCreationTime($group->getCreatedTime()); + $group->setRevisionUser($group->getOwner()); + $group->save(); + } +} diff --git a/src/Entity/Form/GroupForm.php b/src/Entity/Form/GroupForm.php index 28f49d6..dc77d14 100644 --- a/src/Entity/Form/GroupForm.php +++ b/src/Entity/Form/GroupForm.php @@ -156,4 +156,19 @@ class GroupForm extends ContentEntityForm { $request->query->remove('destination'); } + /** + * {@inheritdoc} + */ + public function buildEntity(array $form, FormStateInterface $form_state) { + /** @var \Drupal\group\Entity\GroupInterface $entity */ + $entity = parent::buildEntity($form, $form_state); + + // Mark a new revision if the group type enforces revisions. + /** @var \Drupal\group\Entity\GroupTypeInterface $group_type */ + $group_type = $this->entityTypeManager->getStorage('group_type')->load($entity->bundle()); + $entity->setNewRevision($group_type->shouldCreateNewRevision()); + + return $entity; + } + } diff --git a/src/Entity/Form/GroupTypeForm.php b/src/Entity/Form/GroupTypeForm.php index a511d77..605e893 100644 --- a/src/Entity/Form/GroupTypeForm.php +++ b/src/Entity/Form/GroupTypeForm.php @@ -159,6 +159,12 @@ class GroupTypeForm extends BundleEntityFormBase { } } + $form['use_revisions'] = [ + '#type' => 'checkbox', + '#title' => $this->t('Create a new revision when a group is modified'), + '#default_value' => $type->shouldCreateNewRevision(), + ]; + return $this->protectBundleIdElement($form); } diff --git a/src/Entity/Group.php b/src/Entity/Group.php index 8636e58..4086ea2 100644 --- a/src/Entity/Group.php +++ b/src/Entity/Group.php @@ -3,12 +3,12 @@ namespace Drupal\group\Entity; use Drupal\Core\Field\BaseFieldDefinition; -use Drupal\Core\Entity\ContentEntityBase; use Drupal\Core\Entity\ContentEntityInterface; use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Entity\EntityChangedTrait; use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Session\AccountInterface; +use Drupal\entity\Revision\RevisionableContentEntityBase; use Drupal\user\UserInterface; /** @@ -32,6 +32,7 @@ use Drupal\user\UserInterface; * "list_builder" = "Drupal\group\Entity\Controller\GroupListBuilder", * "route_provider" = { * "html" = "Drupal\group\Entity\Routing\GroupRouteProvider", + * "revision" = "\Drupal\entity\Routing\RevisionRouteProvider", * }, * "form" = { * "add" = "Drupal\group\Entity\Form\GroupForm", @@ -43,28 +44,40 @@ use Drupal\user\UserInterface; * admin_permission = "administer group", * base_table = "groups", * data_table = "groups_field_data", + * revision_table = "groups_revision", + * revision_data_table = "groups_field_revision", + * show_revision_ui = TRUE, * translatable = TRUE, * entity_keys = { * "id" = "id", * "uuid" = "uuid", + * "revision" = "revision_id", * "langcode" = "langcode", * "bundle" = "type", * "label" = "label" * }, + * revision_metadata_keys = { + * "revision_user" = "revision_user", + * "revision_created" = "revision_created", + * "revision_log_message" = "revision_log" + * }, * links = { + * "canonical" = "/group/{group}", * "add-form" = "/group/add/{group_type}", * "add-page" = "/group/add", - * "canonical" = "/group/{group}", * "collection" = "/admin/group", * "edit-form" = "/group/{group}/edit", - * "delete-form" = "/group/{group}/delete" + * "delete-form" = "/group/{group}/delete", + * "revision" = "/group/{group}/revisions/{group_revision}/view", + * "revision-revert-form" = "/group/{group}/revisions/{group_revision}/revert", + * "version-history" = "/group/{group}/revisions" * }, * bundle_entity_type = "group_type", * field_ui_base_route = "entity.group_type.edit_form", * permission_granularity = "bundle" * ) */ -class Group extends ContentEntityBase implements GroupInterface { +class Group extends RevisionableContentEntityBase implements GroupInterface { use EntityChangedTrait; @@ -240,6 +253,7 @@ class Group extends ContentEntityBase implements GroupInterface { ->setLabel(t('Title')) ->setRequired(TRUE) ->setTranslatable(TRUE) + ->setRevisionable(TRUE) ->setSetting('max_length', 255) ->setDisplayOptions('view', [ 'label' => 'hidden', @@ -257,6 +271,7 @@ class Group extends ContentEntityBase implements GroupInterface { ->setLabel(t('Group creator')) ->setDescription(t('The username of the group creator.')) ->setSetting('target_type', 'user') + ->setRevisionable(TRUE) ->setSetting('handler', 'default') ->setDefaultValueCallback('Drupal\group\Entity\Group::getCurrentUserId') ->setTranslatable(TRUE) @@ -267,6 +282,7 @@ class Group extends ContentEntityBase implements GroupInterface { ->setLabel(t('Created on')) ->setDescription(t('The time that the group was created.')) ->setTranslatable(TRUE) + ->setRevisionable(TRUE) ->setDisplayOptions('view', [ 'label' => 'hidden', 'type' => 'hidden', @@ -278,6 +294,7 @@ class Group extends ContentEntityBase implements GroupInterface { ->setLabel(t('Changed on')) ->setDescription(t('The time that the group was last edited.')) ->setTranslatable(TRUE) + ->setRevisionable(TRUE) ->setDisplayOptions('view', [ 'label' => 'hidden', 'type' => 'hidden', @@ -342,4 +359,16 @@ class Group extends ContentEntityBase implements GroupInterface { } } + /** + * {@inheritdoc} + */ + protected function urlRouteParameters($rel) { + $uri_route_parameters = parent::urlRouteParameters($rel); + if ($rel == 'add-form') { + $uri_route_parameters['group_type'] = $this->getGroupType()->id(); + } + + return $uri_route_parameters; + } + } diff --git a/src/Entity/GroupType.php b/src/Entity/GroupType.php index 43f3a8b..2e90bf8 100644 --- a/src/Entity/GroupType.php +++ b/src/Entity/GroupType.php @@ -53,6 +53,7 @@ use Drupal\Core\Entity\EntityStorageInterface; * "creator_membership", * "creator_wizard", * "creator_roles", + * "use_revisions", * } * ) */ @@ -80,6 +81,13 @@ class GroupType extends ConfigEntityBundleBase implements GroupTypeInterface { protected $description; /** + * Should groups of this type always generate revisions. + * + * @var bool + */ + protected $use_revisions = FALSE; + + /** * The group creator automatically receives a membership. * * @var bool @@ -117,6 +125,13 @@ class GroupType extends ConfigEntityBundleBase implements GroupTypeInterface { /** * {@inheritdoc} */ + public function shouldCreateNewRevision() { + return $this->use_revisions; + } + + /** + * {@inheritdoc} + */ public function setDescription($description) { $this->description = $description; return $this; diff --git a/src/Entity/GroupTypeInterface.php b/src/Entity/GroupTypeInterface.php index 0f2e378..ce8de74 100644 --- a/src/Entity/GroupTypeInterface.php +++ b/src/Entity/GroupTypeInterface.php @@ -4,11 +4,12 @@ namespace Drupal\group\Entity; use Drupal\Core\Config\Entity\ConfigEntityInterface; use Drupal\Core\Entity\EntityDescriptionInterface; +use Drupal\Core\Entity\RevisionableEntityBundleInterface; /** * Provides an interface defining a group type entity. */ -interface GroupTypeInterface extends ConfigEntityInterface, EntityDescriptionInterface { +interface GroupTypeInterface extends ConfigEntityInterface, EntityDescriptionInterface, RevisionableEntityBundleInterface { /** * The maximum length of the ID, in characters.