22h/doctrine-garbage-collection-bundle

A Symfony bundle for automated Doctrine entity garbage collection.

Maintainers

Package info

gitlab.com/22h-open/doctrine-garbage-collection-bundle

Issues

Type:symfony-bundle

pkg:composer/22h/doctrine-garbage-collection-bundle

Statistics

Installs: 14

Dependents: 0

Suggesters: 0

Stars: 0

v0.2.0 2026-05-31 20:09 UTC

This package is auto-updated.

Last update: 2026-05-31 18:11:15 UTC


README

A Symfony bundle for automated Doctrine entity garbage collection using PHP 8 attributes.

Features

  • Automated Cleanup: Easily define cleanup rules directly in your services.
  • Simple Configuration: Use attributes to specify which entities should be deleted based on date fields.
  • Complex Logic: Define custom QueryBuilders for more advanced deletion logic.
  • Iterative Deletion: Support for large datasets by iterating and flushing in batches (useful for triggering Lifecycle Events).
  • Dry Run Support: Safely preview what would be deleted before executing.

Installation

Install the bundle via Composer:

composer require 22h/doctrine-garbage-collection-bundle

Usage

1. Tag your Service

To enable garbage collection for a specific entity, create a service and mark it with the SupportsGarbageCollection attribute.

use TwentyTwo\DoctrineGarbageCollection\Attribute\SupportsGarbageCollection;
use TwentyTwo\DoctrineGarbageCollection\Attribute\GarbageCollectionSimple;
use App\Entity\OldLog;

#[SupportsGarbageCollection(entityClass: OldLog::class)]
#[GarbageCollectionSimple(fieldName: 'createdAt', dateInterval: 'P1M')]
class LogGarbageCollector
{
}

2. Simple Garbage Collection

The GarbageCollectionSimple attribute allows you to delete entities where a specific field is older than a given DateInterval.

  • fieldName: The entity field to check (e.g., createdAt).
  • dateInterval: A PHP DateInterval string (e.g., P1M for 1 month, P1Y for 1 year).
  • iteratingResult: If set to true, entities will be loaded and removed one by one (triggering Doctrine events). If false, a single DELETE query is executed.

3. Complex Garbage Collection

For more advanced logic, use the GarbageCollectionComplex attribute on a method that returns a Doctrine QueryBuilder.

use TwentyTwo\DoctrineGarbageCollection\Attribute\SupportsGarbageCollection;
use TwentyTwo\DoctrineGarbageCollection\Attribute\GarbageCollectionComplex;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\QueryBuilder;
use App\Entity\User;

#[SupportsGarbageCollection(entityClass: User::class)]
class UserGarbageCollector
{
    #[GarbageCollectionComplex(iteratingResult: true)]
    public function getUsersToDelete(EntityRepository $repository): QueryBuilder
    {
        return $repository->createQueryBuilder('u')
            ->where('u.lastLogin < :date')
            ->andWhere('u.isVerified = false')
            ->setParameter('date', new \DateTime('-1 year'));
    }
}

## Events

The bundle dispatches several events during the garbage collection process, allowing you to hook into the lifecycle. All events are located in the `TwentyTwo\DoctrineGarbageCollection\Event` namespace.

- **`GarbageCollectionStartEvent`**: Dispatched before any tasks are executed.
- **`GarbageCollectionFinishEvent`**: Dispatched after all tasks have been processed.
- **`PreTaskExecutionEvent`**: Dispatched before each task. This event is stoppable; call `$event->stopPropagation()` to skip the execution of the current task.
- **`PostTaskExecutionEvent`**: Dispatched after a task has been successfully executed.
- **`GarbageCollectionErrorEvent`**: Dispatched if an error occurs during task execution.
- **`GarbageCollectionBatchEvent`**: Dispatched after each batch flush when using `iteratingResult: true`.

### Example Event Subscriber

use Symfony\Component\EventDispatcher\EventSubscriberInterface; use TwentyTwo\DoctrineGarbageCollection\Event\PreTaskExecutionEvent; use TwentyTwo\DoctrineGarbageCollection\Event\GarbageCollectionErrorEvent;

class GarbageCollectionSubscriber implements EventSubscriberInterface {

public static function getSubscribedEvents(): array
{
    return [
        PreTaskExecutionEvent::class => 'onPreTaskExecution',
        GarbageCollectionErrorEvent::class => 'onError',
    ];
}

public function onPreTaskExecution(PreTaskExecutionEvent $event): void
{
    // Custom logic to skip task
    // $event->stopPropagation();
}

public function onError(GarbageCollectionErrorEvent $event): void
{
    $exception = $event->getException();
    // Log the error or send notification
}

}


## Command Line Interface

The bundle provides a console command to execute the garbage collection.

### Dry Run (Default)

See how many entities would be deleted without actually removing them:

php bin/console twenty-two:garbage-collection


### Execute Deletion

Use the `--force` flag to actually delete the entities:

php bin/console twenty-two:garbage-collection --force


### Debugging SQL

To see the generated SQL queries:

php bin/console twenty-two:garbage-collection --dump-sql


### Filtering

You can filter by service or entity:

php bin/console twenty-two:garbage-collection --filter-entity=OldLog php bin/console twenty-two:garbage-collection --filter-service=LogGarbageCollector


## License

This bundle is released under the [MIT License](LICENSE.md).