diff --git a/doc/loggable.md b/doc/loggable.md
index 806d4cf6b..c14519d9e 100644
--- a/doc/loggable.md
+++ b/doc/loggable.md
@@ -1,305 +1,240 @@
-# Loggable behavioral extension for Doctrine
+# Loggable Behavior Extension for Doctrine
-**Loggable** behavior tracks your record changes and is able to
-manage versions.
+The **Loggable** behavior adds support for logging changes to and restoring prior versions of your Doctrine objects.
-Features:
+> [!NOTE]
+> The Loggable extension is NOT compatible with `doctrine/dbal` 4.0 or later
-- Automatic storage of log entries in database
-- ORM and ODM support using same listener
-- Can be nested with other behaviors
-- Objects can be reverted to previous versions
-- Attributes, Annotation and Xml mapping support for extensions
+## Index
-This article will cover the basic installation and functionality of **Loggable**
-behavior
+- [Getting Started](#getting-started)
+- [Configuring Loggable Objects](#configuring-loggable-objects)
+- [Customizing The Log Entry Model](#customizing-the-log-entry-model)
+- [Object Repositories](#object-repositories)
+ - [Fetching a Model's Log Entries](#fetching-a-models-log-entries)
+ - [Revert a Model to a Previous Version](#revert-a-model-to-a-previous-version)
-Content:
+## Getting Started
-- [Including](#including-extension) the extension
-- Entity [example](#entity-mapping)
-- Document [example](#document-mapping)
-- [Xml](#xml-mapping) mapping example
-- Basic usage [examples](#basic-examples)
+The loggable behavior can be added to a supported Doctrine object manager by registering its event subscriber
+when creating the manager.
-
+```php
+use Gedmo\Loggable\LoggableListener;
-## Setup and autoloading
+$listener = new LoggableListener();
-Read the [documentation](./annotations.md#em-setup)
-or check the [example code](../example)
-on how to setup and use the extensions in most optimized way.
+// The $om is either an instance of the ORM's entity manager or the MongoDB ODM's document manager
+$om->getEventManager()->addEventSubscriber($listener);
+```
-### Loggable annotations:
+Then, once your application has it available (i.e. after validating the authentication for your user during an HTTP request),
+you can set a reference to the user who performed actions on a loggable model by calling the listener's `setUsername` method.
-- **@Gedmo\Mapping\Annotation\Loggable(logEntryClass="My\LoggableModel")** this class annotation will store logs to optionally
- specified **logEntryClass**. The class provided in this annotation MUST implement ``Gedmo\Loggable\LogEntryInterface``. You will
- still need to specify versioned fields with the following annotation.
-- **@Gedmo\Mapping\Annotation\Versioned** tracks annotated property for changes
+```php
+// The $user can be either an object or a string
+$listener->setUsername($user);
+```
-### Loggable attributes:
+## Configuring Loggable Objects
-- **\#[Gedmo\Mapping\Annotation\Loggable(logEntryClass: My\LoggableModel::class]** this class attribute will store logs to optionally
- specified **logEntryClass**. The class provided in this attribute MUST implement ``Gedmo\Loggable\LogEntryInterface``. You will
- still need to specify versioned fields with the following attribute.
-- **\#[Gedmo\Mapping\Annotation\Versioned]** tracks attributed property for changes
+The loggable extension can be configured with [annotations](./annotations.md#loggable-extension),
+[attributes](./attributes.md#loggable-extension), or XML configuration (matching the mapping of
+your domain models). The full configuration for annotations and attributes can be reviewed in
+the linked documentation.
-### Loggable username:
+The below examples show the simplest and default configuration for the extension, logging changes for defined fields.
-In order to set the username, when adding the loggable listener you need to set it this way:
+### Attribute Configuration
```php
setAnnotationReader($cachedAnnotationReader);
-$loggableListener->setUsername('admin');
-$evm->addEventSubscriber($loggableListener);
+#[ORM\Entity]
+#[Gedmo\Loggable]
+class Article
+{
+ #[ORM\Id]
+ #[ORM\GeneratedValue]
+ #[ORM\Column(type: Types::INTEGER)]
+ public ?int $id = null;
+
+ #[ORM\Column(type: Types::BOOLEAN)]
+ public bool $published = false;
+
+ #[ORM\Column(type: Types::STRING)]
+ #[Gedmo\Versioned]
+ public ?string $title = null;
+}
```
-
+### XML Configuration
+
+```xml
+
+
+
+
+
+
+
+
+
+
+
+
+
-## Loggable Entity example:
+
+
+
+```
-**Note:** that Loggable interface is not necessary, except in cases where
-you need to identify an entity as being Loggable. The metadata is loaded only once when
-cache is active
+### Annotation Configuration
-**Note:** this example is using annotations and attributes for mapping, you should use
-one of them, not both.
+> [!NOTE]
+> Support for annotations is deprecated and will be removed in 4.0.
```php
id;
- }
-
- public function setTitle($title)
- {
- $this->title = $title;
- }
-
- public function getTitle()
- {
- return $this->title;
- }
+ public ?string $title = null;
}
```
-
+## Customizing The Log Entry Model
+
+When configuring loggable models, you are able to specify a custom model to be used for the log entries for objects
+of that type using the `logEntryClass` parameter:
-## Loggable Document example:
+### Attribute Configuration
```php
title;
- }
-
- public function getId()
- {
- return $this->id;
- }
-
- public function setTitle($title)
- {
- $this->title = $title;
- }
-
- public function getTitle()
- {
- return $this->title;
- }
+ #[ORM\Id]
+ #[ORM\GeneratedValue]
+ #[ORM\Column(type: Types::INTEGER)]
+ public ?int $id = null;
}
```
-
-
-## Xml mapping example
+### XML Configuration
```xml
-
-
+
-
-
-
-
-
-
-
-
-
-
+
```
-
+A custom model must implement `Gedmo\Loggable\LogEntryInterface`. For convenience, we recommend extending from
+`Gedmo\Loggable\Entity\MappedSuperClass\AbstractLogEntry` for Doctrine ORM users or
+`Gedmo\Loggable\Document\MappedSuperClass\AbstractLogEntry` for Doctrine MongoDB ODM users, which provides a default
+mapping configuration for each object manager.
-## Custom LogEntry class
+## Object Repositories
-```php
- 'DYNAMIC'])]
-#[ORM\Index(name: 'log_class_lookup_idx', columns: ['object_class'])]
-#[ORM\Index(name: 'log_date_lookup_idx', columns: ['logged_at'])]
-#[ORM\Index(name: 'log_user_lookup_idx', columns: ['username'])]
-#[ORM\Index(name: 'log_version_lookup_idx', columns: ['object_id', 'object_class', 'version'])]
-class ParameterHistory extends AbstractLogEntry
-{
- /*
- * All required columns are mapped through inherited superclass
- */
-}
-```
+The repository classes provide a `getLogEntries` method which allows fetching the list of log entries for a given model.
-
+```php
+use App\Entity\Article;
+use Doctrine\ORM\EntityManagerInterface;
+use Gedmo\Loggable\Entity\LogEntry;
+use Gedmo\Loggable\Entity\Repository\LogEntryRepository;
+use Gedmo\Loggable\LoggableListener;
-## Basic usage examples:
+/** @var EntityManagerInterface $em */
-```php
-find(Article::class, 1);
-use Entity\Article;
+// Next, get the LogEntry repository
+/** @var LogEntryRepository $repo */
+$repo = $em->getRepository(LogEntry::class);
-$article = new Article();
-$article->setTitle('my title');
-$em->persist($article);
-$em->flush();
+// Lastly, get the article's log entries
+$logs = $repo->getLogEntries($article);
```
-This inserted an article and inserted the logEntry for it, which contains
-all new changeset. In case if there is **OneToOne or ManyToOne** relation,
-it will store only identifier of that object to avoid storing proxies
+### Revert a Model to a Previous Version
-Now lets update our article:
+The repository classes provide a `revert` method which allows reverting a model to a previous version. The repository
+will incrementally revert back to the version specified (for example, a model is currently on version 5, and you want to
+revert to version 2, it will restore the state of version 4, then version 3, and finally, version 2).
```php
-find(Article::class, 1 /*article id*/);
-$article->setTitle('my new title');
-$em->persist($article);
-$em->flush();
-```
+// Load our loggable model
+$article = $em->find(Article::class, 1);
-This updated an article and inserted the logEntry for update action with new changeset
-Now lets revert it to previous version:
+// Next, get the LogEntry repository
+/** @var LogEntryRepository $repo */
+$repo = $em->getRepository(LogEntry::class);
-```php
-getRepository(LogEntry::class); // we use default log entry class
-$article = $em->find(Article::class, 1 /*article id*/);
-$logs = $repo->getLogEntries($article);
-/* $logs contains 2 logEntries */
-// lets revert to first version
-$repo->revert($article, 1/*version*/);
-// notice article is not persisted yet, you need to persist and flush it
-echo $article->getTitle(); // prints "my title"
-$em->persist($article);
-$em->flush();
-// if article had changed relation, it would be reverted also.
+// We are now able to revert to an older version
+$repo->revert($article, 2);
```
-
-Easy like that, any suggestions on improvements are very welcome