Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UHF-7324: Support deleting old revisions #133

Merged
merged 7 commits into from
Sep 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ A base module for [drupal-helfi-platform](https://github.com/City-of-Helsinki/dr

- [API user manager](documentation/api-accounts.md): Allows API users to be created/managed from an environment variable.
- [Automatic external cache invalidation](documentation/automatic-external-cache-invalidation.md): Invalidate caches from external projects using [PubSub messaging](documentation/pubsub-messaging.md) service.
- [Automatic revision deletion](documentation/revisions.md): Clean up old entity revisions automatically.
- [Debug collector](documentation/debug.md): A plugin to collect and show various debug information in one place.
- [Deploy hooks](documentation/deploy-hooks.md): Allows custom tasks to be run before or after deployment.
- [Environment resolver](documentation/environment-resolver.md): A service to fetch metadata for given project.
Expand Down
8 changes: 8 additions & 0 deletions config/schema/helfi_api_base.schema.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,11 @@ helfi_api_base.environment_resolver.settings:
project_name:
type: string
label: 'The currently active project name'

helfi_api_base.delete_revisions:
type: config_entity
mapping:
entity_types:
type: sequence
sequence:
type: string
36 changes: 36 additions & 0 deletions documentation/revisions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Automatic entity revision deletion

Allows old revisions to be deleted. By default, five revisions are kept per entity translation.

## Configuration

This can be configured in code with:
```php

# public/sites/default/*.settings.php
$config['helfi_api_base.delete_revisions']['entity_types'] = [
'node',
'paragraph',
'tpr_unit',
'tpr_service',
'tpr_errand_service',
];
```

or by creating a configuration yml file:

```yaml
# conf/cmi/helfi_api_base.delete_revisions.yml
entity_types:
- node
- paragraph
- tpr_unit
- tpr_service
- tpr_errand_service
```

## Usage

All configured entities are queued for clean up on entity save.

To clean up existing entities at once, run: `drush helfi:revision:delete {entity_type}`.
8 changes: 8 additions & 0 deletions drush.services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,11 @@ services:
arguments: ['@language_manager', '@file_system', '@string_translation', '@extension.list.module']
tags:
- { name: drush.command }
helfi_api_base.revision_commands:
class: \Drupal\helfi_api_base\Commands\RevisionCommands
arguments:
- '@helfi_api_base.revision_manager'
- '@entity_type.manager'
- '@database'
tags:
- { name: drush.command }
23 changes: 23 additions & 0 deletions helfi_api_base.install
Original file line number Diff line number Diff line change
Expand Up @@ -171,3 +171,26 @@ function helfi_api_base_update_9009() : void {
function helfi_api_base_update_9013() : void {
helfi_api_base_install();
}

/**
* Enable 'delete old revisions' feature.
*/
function helfi_api_base_update_9014() : void {
/** @var \Drupal\helfi_api_base\Environment\EnvironmentResolverInterface $service */
$service = \Drupal::service('helfi_api_base.environment_resolver');
try {
$service->getActiveProject();

\Drupal::configFactory()->getEditable('helfi_api_base.delete_revisions')
->set('entity_types', [
'node',
'paragraph',
'tpr_unit',
'tpr_service',
'tpr_errand_service',
])->save();
}
catch (\InvalidArgumentException) {
}

}
23 changes: 23 additions & 0 deletions helfi_api_base.module
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

declare(strict_types = 1);

use Drupal\Core\Entity\EntityInterface;
use Drupal\helfi_api_base\Link\LinkProcessor;

/**
Expand Down Expand Up @@ -65,3 +66,25 @@ function helfi_api_base_mail_alter(&$message) : void {
catch (\InvalidArgumentException) {
}
}

/**
* Implements hook_entity_update().
*/
function helfi_api_base_entity_update(EntityInterface $entity) : void {
/** @var \Drupal\helfi_api_base\Entity\Revision\RevisionManager $revisionManager */
$revisionManager = \Drupal::service('helfi_api_base.revision_manager');

if (!$revisionManager->entityTypeIsSupported($entity->getEntityTypeId())) {
return;
}
$revisions = $revisionManager->getRevisions($entity->getEntityTypeId(), $entity->id());

// Queue entity revisions for deletion.
if ($revisions) {
$queue = \Drupal::queue('helfi_api_base_revision');
$queue->createItem([
'entity_id' => $entity->id(),
'entity_type' => $entity->getEntityTypeId(),
]);
}
}
7 changes: 7 additions & 0 deletions helfi_api_base.services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -129,3 +129,10 @@ services:
- '@cache_tags.invalidator'
tags:
- { name: event_subscriber }

helfi_api_base.revision_manager:
class: Drupal\helfi_api_base\Entity\Revision\RevisionManager
arguments:
- '@entity_type.manager'
- '@config.factory'
- '@database'
88 changes: 88 additions & 0 deletions src/Commands/RevisionCommands.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<?php

declare(strict_types=1);

namespace Drupal\helfi_api_base\Commands;

use Drupal\Component\Render\FormattableMarkup;
use Drupal\Core\Database\Connection;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\helfi_api_base\Entity\Revision\RevisionManager;
use Drush\Attributes\Command;
use Drush\Attributes\Option;
use Drush\Commands\DrushCommands;

/**
* A drush command file to manage revisions.
*/
final class RevisionCommands extends DrushCommands {

/**
* Constructs a new instance.
*
* @param \Drupal\helfi_api_base\Entity\Revision\RevisionManager $revisionManager
* The revision manager service.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
* The entity type manager service.
* @param \Drupal\Core\Database\Connection $connection
* The connection service.
*/
public function __construct(
private readonly RevisionManager $revisionManager,
private readonly EntityTypeManagerInterface $entityTypeManager,
private readonly Connection $connection,
) {
}

/**
* Deletes the old revisions.
*
* @param string $entityType
* The entity type.
* @param array $options
* The options.
*
* @return int
* The exit code.
*/
#[Command(name: 'helfi:revision:delete')]
#[Option(name: 'keep', description: 'Number of revisions to keep')]
public function delete(string $entityType, array $options = ['keep' => RevisionManager::KEEP_REVISIONS]) : int {
if (!$this->revisionManager->entityTypeIsSupported($entityType)) {
$this->io()->writeln('Given entity type is not supported.');
return DrushCommands::EXIT_SUCCESS;
}

$definition = $this->entityTypeManager->getDefinition($entityType);
$entityIds = $this->connection->select($definition->getBaseTable(), 't')
->fields('t', [$definition->getKey('id')])
->execute()
->fetchCol();

$totalEntities = $remainingEntities = count($entityIds);
$this->io()->writeln((string) new FormattableMarkup('Found @count @type entities', [
'@count' => $totalEntities,
'@type' => $entityType,
]));

foreach ($entityIds as $id) {
$revisions = $this->revisionManager->getRevisions($entityType, $id, $options['keep']);
$revisionCount = count($revisions);

$message = sprintf('Entity has less than %s revisions. Skipping', $options['keep']);

if ($revisionCount > 0) {
$message = (string) new FormattableMarkup('Deleting @count revisions', ['@count' => $revisionCount]);
}
$this->io()->writeln((string) new FormattableMarkup('[@current/@entities] @message ...', [
'@current' => $remainingEntities--,
'@entities' => $totalEntities,
'@message' => $message,
]));
$this->revisionManager->deleteRevisions($entityType, $revisions);
}

return DrushCommands::EXIT_SUCCESS;
}

}
Loading
Loading