Skip to content

Commit 1e5d22b

Browse files
mbabkerphansys
authored andcommitted
Rewrite the soft deleteable extension documentation
1 parent 85f3f1d commit 1e5d22b

File tree

7 files changed

+290
-292
lines changed

7 files changed

+290
-292
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ flushed in a behavioral way.
5252
#### ORM Only
5353

5454
- [**IpTraceable**](/doc/ip_traceable.md) - inherited from Timestampable, sets IP address instead of timestamp
55-
- [**SoftDeleteable**](/doc/softdeleteable.md) - allows to implicitly remove records
55+
- [**SoftDeleteable**](/doc/soft-deleteable.md) - allows to implicitly remove records
5656
- [**Sortable**](/doc/sortable.md) - makes any document or entity sortable
5757
- [**Uploadable**](/doc/uploadable.md) - provides file upload handling in entity fields
5858

doc/annotations.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -647,7 +647,7 @@ Optional Attributes:
647647

648648
### Soft Deleteable Extension
649649

650-
The below annotations are used to configure the [Soft Deleteable extension](./softdeleteable.md).
650+
The below annotations are used to configure the [Soft Deleteable extension](./soft-deleteable.md).
651651

652652
#### `@Gedmo\Mapping\Annotation\SoftDeleteable`
653653

doc/attributes.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -558,7 +558,7 @@ class Article
558558
559559
### Soft Deleteable Extension
560560

561-
The below attributes are used to configure the [Soft Deleteable extension](./softdeleteable.md).
561+
The below attributes are used to configure the [Soft Deleteable extension](./soft-deleteable.md).
562562

563563
#### `#[Gedmo\Mapping\Annotation\SoftDeleteable]`
564564

doc/frameworks/laminas.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ $ vendor/bin/doctrine-module orm:info
320320

321321
### Soft Deleteable Filter
322322

323-
When using the [Soft Deleteable](../softdeleteable.md) extension, a filter is available which allows configuring whether
323+
When using the [Soft Deleteable](../soft-deleteable.md) extension, a filter is available which allows configuring whether
324324
soft-deleted objects are included in query results.
325325

326326
> [!NOTE]

doc/frameworks/symfony.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ $ bin/console doctrine:mapping:info
328328

329329
### Soft Deleteable Filter
330330

331-
When using the [Soft Deleteable](../softdeleteable.md) extension, a filter is available which allows configuring whether
331+
When using the [Soft Deleteable](../soft-deleteable.md) extension, a filter is available which allows configuring whether
332332
soft-deleted objects are included in query results.
333333

334334
> [!NOTE]

doc/soft-deleteable.md

Lines changed: 285 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,285 @@
1+
# Soft Deleteable Behavior Extension for Doctrine
2+
3+
The **Soft Deleteable** behavior allows you to "soft delete" objects by marking them as deleted with a timestamp instead
4+
of removing them from the database.
5+
6+
## Index
7+
8+
- [Getting Started](#getting-started)
9+
- [Configuring Soft Deleteable Objects](#configuring-soft-deleteable-objects)
10+
- [Using Traits](#using-traits)
11+
- [Working with Filters](#working-with-filters)
12+
- [Bulk Delete Support](#bulk-delete-support)
13+
- [Time-Aware Soft Deletion](#time-aware-soft-deletion)
14+
- ["Hard Delete" Soft Deleted Records](#hard-delete-soft-deleted-records)
15+
16+
## Getting Started
17+
18+
The soft deleteable behavior can be added to a supported Doctrine object manager by registering its event subscriber
19+
when creating the manager.
20+
21+
```php
22+
use Gedmo\SoftDeleteable\SoftDeleteableListener;
23+
24+
$listener = new SoftDeleteableListener();
25+
26+
// The $om is either an instance of the ORM's entity manager or the MongoDB ODM's document manager
27+
$om->getEventManager()->addEventSubscriber($listener);
28+
```
29+
30+
### Configuring Filters
31+
32+
To automatically filter out soft-deleted records from all queries, you need to register and enable the appropriate filter for your object manager.
33+
34+
#### For Doctrine ORM
35+
36+
```php
37+
use Doctrine\ORM\Configuration;
38+
use Gedmo\SoftDeleteable\Filter\SoftDeleteableFilter;
39+
40+
// Register the filter during configuration
41+
$config = new Configuration();
42+
$config->addFilter('soft-deleteable', SoftDeleteableFilter::class);
43+
44+
// Enable the filter (usually in your application bootstrap)
45+
$em->getFilters()->enable('soft-deleteable');
46+
```
47+
48+
#### For MongoDB ODM
49+
50+
```php
51+
use Doctrine\ODM\MongoDB\Configuration;
52+
use Gedmo\SoftDeleteable\Filter\ODM\SoftDeleteableFilter;
53+
54+
// Register the filter during configuration
55+
$config = new Configuration();
56+
$config->addFilter('soft-deleteable', SoftDeleteableFilter::class);
57+
58+
// Enable the filter (usually in your application bootstrap)
59+
$dm->getFilterCollection()->enable('soft-deleteable');
60+
```
61+
62+
## Configuring Soft Deleteable Objects
63+
64+
The soft deleteable extension can be configured with [annotations](./annotations.md#soft-deleteable-extension),
65+
[attributes](./attributes.md#soft-deleteable-extension), or XML configuration (matching the mapping of
66+
your domain models). The full configuration for annotations and attributes can be reviewed in
67+
the linked documentation.
68+
69+
The below examples show the basic configuration for the extension, marking a class as soft deleteable.
70+
71+
### Attribute Configuration
72+
73+
```php
74+
<?php
75+
namespace App\Entity;
76+
77+
use Doctrine\DBAL\Types\Types;
78+
use Doctrine\ORM\Mapping as ORM;
79+
use Gedmo\Mapping\Annotation as Gedmo;
80+
81+
#[ORM\Entity]
82+
#[Gedmo\SoftDeleteable]
83+
class Article
84+
{
85+
#[ORM\Id]
86+
#[ORM\GeneratedValue]
87+
#[ORM\Column(type: Types::INTEGER)]
88+
public ?int $id = null;
89+
90+
#[ORM\Column(type: Types::STRING)]
91+
public ?string $title = null;
92+
93+
#[ORM\Column(type: Types::DATETIME_IMMUTABLE, nullable: true)]
94+
public ?\DateTimeImmutable $deletedAt = null;
95+
}
96+
```
97+
98+
### XML Configuration
99+
100+
```xml
101+
<?xml version="1.0" encoding="UTF-8"?>
102+
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
103+
xmlns:gedmo="http://gediminasm.org/schemas/orm/doctrine-extensions-mapping">
104+
105+
<entity name="App\Model\Article" table="articles">
106+
<id name="id" type="integer" column="id">
107+
<generator strategy="AUTO"/>
108+
</id>
109+
110+
<field name="title" type="string"/>
111+
<field name="deletedAt" type="datetime_immutable" nullable="true"/>
112+
113+
<gedmo:soft-deleteable field-name="deletedAt"/>
114+
</entity>
115+
</doctrine-mapping>
116+
```
117+
118+
### Annotation Configuration
119+
120+
> [!NOTE]
121+
> Support for annotations is deprecated and will be removed in 4.0.
122+
123+
```php
124+
<?php
125+
namespace App\Entity;
126+
127+
use Doctrine\ORM\Mapping as ORM;
128+
use Gedmo\Mapping\Annotation as Gedmo;
129+
130+
/**
131+
* @ORM\Entity
132+
* @Gedmo\SoftDeleteable
133+
*/
134+
class Article
135+
{
136+
/**
137+
* @ORM\Id
138+
* @ORM\GeneratedValue
139+
* @ORM\Column(type="integer")
140+
*/
141+
public ?int $id = null;
142+
143+
/**
144+
* @ORM\Column(type="string")
145+
*/
146+
public ?string $title = null;
147+
148+
/**
149+
* @ORM\Column(type="datetime_immutable", nullable=true)
150+
*/
151+
public ?\DateTimeImmutable $deletedAt = null;
152+
}
153+
```
154+
155+
### Supported Field Types
156+
157+
The soft deleteable extension supports the following field types for the deletion timestamp field:
158+
159+
- Date (`date` and `date_immutable`)
160+
- Time (`time` and `time_immutable`)
161+
- Date/Time (`datetime` and `datetime_immutable`)
162+
- Date/Time with timezone (`datetimetz` and `datetimetz_immutable`)
163+
- Timestamp (`timestamp`)
164+
165+
## Using Traits
166+
167+
The soft deleteable extension provides traits which can be used to quickly add a deletion timestamp field, and
168+
optionally the mapping configuration, to your models. This trait is provided as a convenience for common configurations.
169+
170+
- `Gedmo\SoftDeleteable\Traits\SoftDeleteable` adds a `$deletedAt` property with getter and setter
171+
- `Gedmo\SoftDeleteable\Traits\SoftDeleteableDocument` adds a `$deletedAt` property with getters and setters
172+
and mapping annotations and attributes for the MongoDB ODM
173+
- `Gedmo\SoftDeleteable\Traits\SoftDeleteableEntity` adds a `$deletedAt` property with getters and setters
174+
and mapping annotations and attributes for the ORM
175+
176+
## Working with Filters
177+
178+
Once you have configured your soft deleteable objects and registered the appropriate filter, you can control the
179+
visibility of soft-deleted records using the filter system.
180+
181+
### Basic Filter Operations
182+
183+
```php
184+
// Enable the filter to hide soft-deleted records (recommended for most use cases)
185+
$em->getFilters()->enable('soft-deleteable');
186+
187+
// Disable the filter to show all records, including soft-deleted ones
188+
$em->getFilters()->disable('soft-deleteable');
189+
190+
// Check if the filter is enabled
191+
$isEnabled = $em->getFilters()->isEnabled('soft-deleteable');
192+
```
193+
194+
### Per-Object Filter Control
195+
196+
You can enable or disable the filter for specific object types using the enable and disable methods on the filter classes.
197+
For example, when using the ORM:
198+
199+
```php
200+
// Get the filter instance
201+
$filter = $em->getFilters()->enable('soft-deleteable');
202+
203+
// Disable filtering for a specific entity (show all records, including soft-deleted)
204+
$filter->disableForEntity(Article::class);
205+
206+
// Re-enable filtering for a specific entity
207+
$filter->enableForEntity(Article::class);
208+
```
209+
210+
For MongoDB ODM users, replace "Entity" with "Document" in the method names (i.e. `enableForDocument` and `disableForDocument`).
211+
212+
## Bulk DELETE Support
213+
214+
> [!NOTE]
215+
> This feature is only available with the ORM.
216+
217+
The soft deleteable extension includes a query walker that automatically converts DQL DELETE statements into UPDATE
218+
statements that set the deletion timestamp, allowing you to perform bulk soft-deletion operations.
219+
220+
### Using the Query Walker
221+
222+
To use DQL DELETE queries with soft deleteable entities, you need to specify the `SoftDeleteableWalker` as a custom output walker:
223+
224+
```php
225+
use Doctrine\ORM\Query;
226+
use Gedmo\SoftDeleteable\Query\TreeWalker\SoftDeleteableWalker;
227+
228+
// Create a DQL DELETE query
229+
$query = $em->createQuery('DELETE FROM App\Entity\Article a WHERE a.category = :category');
230+
$query->setParameter('category', $category);
231+
232+
// Set the query walker to convert the DELETE query to UPDATE
233+
$query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, SoftDeleteableWalker::class);
234+
235+
// Execute the query
236+
$query->execute();
237+
```
238+
239+
## Time-Aware Soft Deletion
240+
241+
The soft deleteable extension supports "time-aware" deletion, where you can schedule objects for deletion at a future time.
242+
243+
### Enabling Time-Aware Support
244+
245+
```php
246+
#[ORM\Entity]
247+
#[Gedmo\SoftDeleteable(timeAware: true)]
248+
class Article
249+
{
250+
#[ORM\Id]
251+
#[ORM\GeneratedValue]
252+
#[ORM\Column(type: Types::INTEGER)]
253+
public ?int $id = null;
254+
255+
#[ORM\Column(type: Types::STRING)]
256+
public ?string $title = null;
257+
258+
#[ORM\Column(type: Types::DATETIME_IMMUTABLE, nullable: true)]
259+
public ?\DateTimeImmutable $deletedAt = null;
260+
}
261+
```
262+
263+
### Usage Example
264+
265+
```php
266+
// Schedule an article for deletion in the future
267+
$article = new Article();
268+
$article->setTitle('Scheduled for deletion');
269+
$article->setDeletedAt(new \DateTimeImmutable('+1 week')); // Delete in 1 week
270+
$em->persist($article);
271+
$em->flush();
272+
273+
// The article will be visible now (deletion time hasn't passed)
274+
$found = $em->getRepository(Article::class)->findOneBy(['title' => 'Scheduled for deletion']);
275+
assert($found !== null); // Found because deletion time is in the future
276+
277+
// After the scheduled time passes, the article will be automatically filtered out
278+
// (without needing to run any cleanup processes)
279+
```
280+
281+
## "Hard Delete" Soft Deleted Records
282+
283+
By default, the soft deleteable extension allows soft deleted records to be "hard deleted" (fully removed from the database)
284+
by deleting them a second time. However, by setting the `hardDelete` parameter in the configuration to `false`, you can
285+
prevent soft deleted records from being deleted at all.

0 commit comments

Comments
 (0)