{"id":15026703,"url":"https://github.com/andanteproject/soft-deletable-bundle","last_synced_at":"2025-04-09T20:21:31.165Z","repository":{"id":54328658,"uuid":"341197156","full_name":"andanteproject/soft-deletable-bundle","owner":"andanteproject","description":"A Symfony Bundle to handle soft deletable with Doctrine Entities","archived":false,"fork":false,"pushed_at":"2024-03-11T18:34:27.000Z","size":73,"stargazers_count":10,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-23T22:13:03.527Z","etag":null,"topics":["doctrine","doctrine-orm","php","php7","php74","soft-delete","symfony","symfony-bundle"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/andanteproject.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-02-22T12:43:35.000Z","updated_at":"2025-03-18T11:24:35.000Z","dependencies_parsed_at":"2024-09-28T20:01:14.038Z","dependency_job_id":"f91ef500-a91f-436f-9670-d5f9ced668c7","html_url":"https://github.com/andanteproject/soft-deletable-bundle","commit_stats":{"total_commits":64,"total_committers":5,"mean_commits":12.8,"dds":0.578125,"last_synced_commit":"a2764059f1a5c7af84de941cfc36fc5e1ebceaac"},"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andanteproject%2Fsoft-deletable-bundle","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andanteproject%2Fsoft-deletable-bundle/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andanteproject%2Fsoft-deletable-bundle/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andanteproject%2Fsoft-deletable-bundle/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/andanteproject","download_url":"https://codeload.github.com/andanteproject/soft-deletable-bundle/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248104348,"owners_count":21048327,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["doctrine","doctrine-orm","php","php7","php74","soft-delete","symfony","symfony-bundle"],"created_at":"2024-09-24T20:04:54.569Z","updated_at":"2025-04-09T20:21:31.129Z","avatar_url":"https://github.com/andanteproject.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Andante Project Logo](https://github.com/andanteproject/soft-deletable-bundle/blob/main/andanteproject-logo.png?raw=true)\n# Soft Deletable Bundle \n#### Symfony Bundle - [AndanteProject](https://github.com/andanteproject)\n[![Latest Version](https://img.shields.io/github/release/andanteproject/soft-deletable-bundle.svg)](https://github.com/andanteproject/soft-deletable-bundle/releases)\n![Github actions](https://github.com/andanteproject/soft-deletable-bundle/actions/workflows/workflow.yml/badge.svg?branch=main)\n![Framework](https://img.shields.io/badge/Symfony-4.x|5.x-informational?Style=flat\u0026logo=symfony)\n![Php7](https://img.shields.io/badge/PHP-%207.4|8.x-informational?style=flat\u0026logo=php)\n![PhpStan](https://img.shields.io/badge/PHPStan-Level%208-syccess?style=flat\u0026logo=php) \n\nSimple Symfony Bundle to handle [soft delete](https://en.wiktionary.org/wiki/soft_deletion) for doctrine entities. So your entities \"_are not going to be deleted for real from the database_\". 🙌 \n\n## Requirements\nSymfony 4.x-5.x and PHP 7.4.\n\n## Install\nVia [Composer](https://getcomposer.org/):\n```bash\n$ composer require andanteproject/soft-deletable-bundle\n```\n\n## Features\n- No configuration required to be ready to go but fully customizabile;\n- `deleteAt` property is as a `?\\DateTimeImmutable`;\n- You can disable the filter runtime even for just some entities; \n- No annotation required;\n- Works like magic ✨.\n\n## Basic usage\nAfter [install](#install), make sure you have the bundle registered in your symfony bundles list (`config/bundles.php`):\n```php\nreturn [\n    /// bundles...\n    Andante\\SoftDeletableBundle\\AndanteSoftDeletableBundle::class =\u003e ['all' =\u003e true],\n    /// bundles...\n];\n```\nThis should have been done automagically if you are using [Symfony Flex](https://flex.symfony.com). Otherwise, just register it by yourself.\n\nLet's suppose we have a `App\\Entity\\Article` doctrine entity we want to enable to soft-deletion.\nAll you have to do is to implement `Andante\\SoftDeletableBundle\\SoftDeletable\\SoftDeletableInterface` and use `Andante\\SoftDeletableBundle\\SoftDeletable\\SoftDeletableTrait` trait.\n\n```php\n\u003c?php\n\nnamespace App\\Entity;\n\nuse Doctrine\\ORM\\Mapping as ORM;\nuse Andante\\SoftDeletableBundle\\SoftDeletable\\SoftDeletableInterface;\nuse Andante\\SoftDeletableBundle\\SoftDeletable\\SoftDeletableTrait;\n\n/**\n * @ORM\\Entity()\n */\nclass Article implements SoftDeletableInterface // \u003c-- implement this\n{\n    use SoftDeletableTrait; // \u003c-- add this\n\n    /**\n     * @ORM\\Id\n     * @ORM\\GeneratedValue\n     * @ORM\\Column(type=\"integer\")\n     */\n    private ?int $id = null;\n\n    /**\n     * @ORM\\Column(type=\"string\")\n     */\n    private string $title;\n    \n    public function __construct(string $title)\n    {\n        $this-\u003etitle = $title;\n    }\n    \n    // ...\n    // Some others beautiful properties and methods ...\n    // ...\n}\n```\nMake sure to update you database schema following your doctrine workflow (`bin/console doctrine:schema:update --force` if you are a badass devil guy or with a [migration](https://www.doctrine-project.org/projects/doctrine-migrations/en/3.0/reference/introduction.html) if you choosed the be a better developer!).\n\nYou shoud see a new column named `deleted_at` ([can i change this?](#configuration-completely-optional)) or something similar based on your [doctrine naming strategy](https://www.doctrine-project.org/projects/doctrine-orm/en/2.8/reference/namingstrategy.html). \n\n#### Congrats! You're done! 🎉\nFrom now on, when you delete your entity, it will be not hard-deleted from the database.\nFor example, let's suppose to save a new `Article`:\n```php\n$article = new Article('Free 🍕 for everyone!');\n$entityManager-\u003epersist($article);\n$entityManager-\u003eflush();\n```\nAnd so we will have it on our database.\n\n| id | title | ... | deleted_at | \n| --- | --- | --- | --- |\n| 1 | Free 🍕 for everyone! | ... | `NULL` |\n\nBut, if you delete it with Doctrine, the row will still be there but with the `deleted_at` populated with the date of its delation.\n\n```php\n$entityManager-\u003eremove($article);\n$entityManager-\u003eflush();    \n```\n| id | title | ... | deleted_at | \n| --- | --- | --- | --- |\n| 1 | Free 🍕 for everyone! | ... | `2021-01-01 10:30:00` |\n\nAnd the **entity will be no more available** from your app queries. ([Is there a way I can restore them?](#disabling-soft-delete-filter))\n\n```php\n$articleArrayWithNoFreePizza = $entityManager-\u003egetRepsitory(Article::class)-\u003efindAll();\n//Every entity with a deleted_at date is going to be ignored from your queries\n```\n\n## Gosh, what are you  doing to my poor entities?! 🤭\nNo entity was mistreated while using this bundle 🙌.\n\nWe suggest you to use `Andante\\SoftDeletableBundle\\SoftDeletable\\SoftDeletableTrait` trait to make your life easier. It does nothing special under the hood:\nit adds a `\\DateTimeImmutable deletedAt` property to your entity mapped with our `deleted_at` **doctrine type** and a getter/setter to handle it.\n\nBut, for whatever reason, you are free to do it yourself (implementing `SoftDeletableInterface` is mandatory instead).\n\n## Usage with no trait\n```php\n\u003c?php\n\nnamespace App\\Entity;\n\nuse Doctrine\\ORM\\Mapping as ORM;\nuse Andante\\SoftDeletableBundle\\SoftDeletable\\SoftDeletableInterface;\n\n/**\n * @ORM\\Entity()\n */\nclass Article implements SoftDeletableInterface // \u003c-- implement this\n{\n    // No trait needed\n    \n    /**\n     * @ORM\\Id\n     * @ORM\\GeneratedValue\n     * @ORM\\Column(type=\"integer\")\n     */\n    private ?int $id = null;\n\n    /**\n     * @ORM\\Column(type=\"string\")\n     */\n    private string $title;\n    \n    // DO NOT use ORM annotations to map this property. See bundle configuration section for more info \n    private ?\\DateTimeImmutable $deletedAt = null; \n    \n    public function __construct(string $title)\n    {\n        $this-\u003etitle = $title;\n    }\n    \n    public function getDeletedAt() : ?\\DateTimeImmutable\n    {\n        return $this-\u003edeletedAt;\n    }\n\n    public function setDeletedAt(\\DateTimeImmutable $deletedAt = null) : void\n    {\n        $this-\u003edeletedAt = $deletedAt;\n    }\n}\n```\nThis allows you to, for instance, to have **a different name** for your property (E.g. `deleted` instead of `deletedAt`).\nBut you will need to explicit this in [bundle configuration](#configuration-completely-optional).\n\n## Disabling soft-delete filter\nYou can disable the filter entirely runtime by doing this to your Entity Manager.\n```php\nuse Andante\\SoftDeletableBundle\\Doctrine\\Filter\\SoftDeletableFilter;\n/** @var $entityManager \\Doctrine\\ORM\\EntityManagerInterface */\n$entityManager-\u003egetFilters()-\u003edisable(SoftDeletableFilter::NAME);\n// From now on, entities with a \"deletedAt\" date are again available.\n// If you want to enable the filter back:\n$entityManager-\u003egetFilters()-\u003eenable(SoftDeletableFilter::NAME);\n```\nIf you want you can also disable the filter for just one or more entities by doing this:\n```php\n/** @var $softDeletableFilter Andante\\SoftDeletableBundle\\Doctrine\\Filter\\SoftDeletableFilter */\n$softDeletableFilter = $entityManager-\u003egetFilters()-\u003egetFilter(SoftDeletableFilter::NAME);\n$softDeletableFilter-\u003edisableForEntity(Article::class);\n// From now on, filter is still on but disabled just for Articles\n$softDeletableFilter-\u003eenableForEntity(Article::class);\n```\n## Configuration (completely optional)\nThis bundle is build thinking how to save you time and follow best practices as close as possible.\n\nThis means you can even ignore to have a `andante_soft_deletable.yaml` config file in your application.\n\nHowever, for whatever reason (legacy code?), use the bundle configuration to change most of the behaviors as your needs.\n```yaml\nandante_soft_deletable:\n  deleted_date_aware: true # default: true\n                           # Set the filter to also check deleted date value.\n                           # If set true, Future date will still be avaiable \n  default:\n    property_name: deletedAt # default: deletedAt\n                             # The property to be used by default as deletedAt date \n                             # inside entities implementing SoftDeletableInterface\n    \n    column_name: deleted_at # default: null\n                           # Column name to be used on database. \n                           # If set to NULL will use your default doctrine naming strategy\n    table_index: false # default: true\n                       # Adds automatically a table index to deleted date column\n    \n    always_update_deleted_at: true # default: false\n                                   # if set to true, when you delete an entity which has already\n                                   # a deleted date, the date will be updated to last deletion.\n  entity: # You can use per-entity configuration to override default config\n    Andante\\SoftDeletableBundle\\Tests\\Fixtures\\Entity\\Organization:\n      property_name: deletedAt\n      table_index: true\n    Andante\\SoftDeletableBundle\\Tests\\Fixtures\\Entity\\Address:\n      property_name: deleted\n      column_name: delete_date\n      table_index: false\n      always_update_deleted_at: false\n```\n\n## Please note\n- This bundle does not handle direct [DQL](https://www.doctrine-project.org/projects/doctrine-orm/en/2.7/reference/dql-doctrine-query-language.html) queries;\n- The default setting of `deleted_date_aware` is `false`. The filter is going to exclude whatever row with a `NOT NULL` deleted date. If you want to exclude only rows with a `deletedAt` date in the past and still retrieving the ones with future dates, you need to set `deleted_date_aware` to `true`. \n\nBuilt with love ❤️ by [AndanteProject](https://github.com/andanteproject) team.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandanteproject%2Fsoft-deletable-bundle","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fandanteproject%2Fsoft-deletable-bundle","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandanteproject%2Fsoft-deletable-bundle/lists"}