### Run Doctrine Extensions Example
Source: https://github.com/doctrine-extensions/doctrineextensions/blob/main/README.md
Steps to set up and run the example provided with Doctrine Extensions. Ensure you have Composer installed and configure your database connection in `example/em.php`.
```bash
composer install
```
```bash
php example/bin/console
```
```bash
php example/bin/console orm:schema-tool:create
```
```bash
php example/bin/console app:print-category-translation-tree
```
--------------------------------
### Example Usage of Sluggable Handlers
Source: https://github.com/doctrine-extensions/doctrineextensions/blob/main/doc/sluggable.md
Demonstrates the creation and persistence of Company and User entities, showing how the slugs are generated and updated.
```php
setTitle('KnpLabs');
$em->persist($company);
$gedi = new User;
$gedi->setUsername('Gedi');
$gedi->setCompany($company);
$em->persist($gedi);
$em->flush();
echo $gedi->getSlug(); // outputs "knplabs/gedi"
$company->setTitle('KnpLabs Nantes');
$em->persist($company);
$em->flush();
echo $gedi->getSlug(); // outputs "knplabs-nantes/gedi"
```
--------------------------------
### Basic Sluggable Usage Example
Source: https://github.com/doctrine-extensions/doctrineextensions/blob/main/doc/sluggable.md
Demonstrates how to create an Article entity, set its fields, persist it, and flush to generate the slug.
```php
setTitle('the title');
$article->setCode('my code');
$this->em->persist($article);
$this->em->flush();
echo $article->getSlug();
// prints: the-title-my-code
```
--------------------------------
### Run Doctrine Extensions Tests
Source: https://github.com/doctrine-extensions/doctrineextensions/blob/main/README.md
Use these commands to set up Docker containers, enter the PHP environment, install dependencies, and run the test suite.
```bash
docker compose up -d
```
```bash
docker compose exec php bash
```
```bash
composer install
```
```bash
vendor/bin/phpunit
```
--------------------------------
### Custom FileInfo Implementation
Source: https://github.com/doctrine-extensions/doctrineextensions/blob/main/doc/uploadable.md
Provides an example of creating a custom class that implements the FileInfoInterface to handle files from sources other than direct uploads, such as URLs or existing server files. This example sets `isUploadedFile` to false to use the `copy` function.
```php
use Gedmo\Uploadable\FileInfo\FileInfoInterface;
class CustomFileInfo implements FileInfoInterface
{
protected $path;
protected $name;
protected $size;
protected $type;
protected $filename;
protected $error = 0;
public function __construct($path)
{
$this->path = $path;
// Now, process the file and fill the rest of the properties.
}
// This returns the actual path of the file
public function getTmpName()
{
return $this->path;
}
// This returns the filename
public function getName()
{
return $this->name;
}
// This returns the file size in bytes
public function getSize()
{
return $this->size;
}
// This returns the mime type
public function getType()
{
return $this->type;
}
public function getError()
{
// This should return 0, as it's only used to return the codes from PHP file upload errors.
return $this->error;
}
// If this method returns true, it will produce that the extension uses "move_uploaded_file" function to move
// the file. If it returns false, the extension will use the "copy" function.
public function isUploadedFile()
{
return false;
}
}
```
--------------------------------
### Changelog Entry Example
Source: https://github.com/doctrine-extensions/doctrineextensions/blob/main/CONTRIBUTING.md
Format for adding an entry to the changelog, including the extension name and GitHub issue number if applicable.
```markdown
## [Unreleased]
### Fixed
- Loggable: Allow emoji in the docs (#123)
```
--------------------------------
### Install Doctrine Extensions for ORM
Source: https://github.com/doctrine-extensions/doctrineextensions/blob/main/doc/frameworks/laminas.md
Use this Composer command to install Doctrine Extensions and required dependencies for Doctrine ORM.
```shell
composer require doctrine/dbal doctrine/doctrine-module doctrine/doctrine-orm-module doctrine/orm gedmo/doctrine-extensions
```
--------------------------------
### Install Doctrine Extensions with Composer
Source: https://github.com/doctrine-extensions/doctrineextensions/blob/main/README.md
Use Composer to install the Doctrine Extensions package. This is the primary method for integrating the extensions into your project.
```bash
composer require gedmo/doctrine-extensions
```
--------------------------------
### Install Doctrine Extensions for MongoDB ODM
Source: https://github.com/doctrine-extensions/doctrineextensions/blob/main/doc/frameworks/laminas.md
Use this Composer command to install Doctrine Extensions and required dependencies for MongoDB ODM.
```shell
composer require doctrine/doctrine-module doctrine/doctrine-mongo-odm-module doctrine/mongodb-odm gedmo/doctrine-extensions
```
--------------------------------
### Persisting Entities with Personal Translations
Source: https://github.com/doctrine-extensions/doctrineextensions/blob/main/doc/translatable.md
Example demonstrating how to create and persist entities with multiple personal translations for different locales and fields.
```php
setTitle('Food');
$food->addTranslation(new Entity\CategoryTranslation('lt', 'title', 'Maistas'));
$fruits = new Entity\Category;
$fruits->setParent($food);
$fruits->setTitle('Fruits');
$fruits->addTranslation(new Entity\CategoryTranslation('lt', 'title', 'Vaisiai'));
$fruits->addTranslation(new Entity\CategoryTranslation('ru', 'title', 'rus trans'));
$em->persist($food);
$em->persist($fruits);
$em->flush();
```
--------------------------------
### XML Configuration for IP Traceable
Source: https://github.com/doctrine-extensions/doctrineextensions/blob/main/doc/ip_traceable.md
Configure the IP traceable extension using XML mapping files. This example sets the 'updatedFromIp' field to be updated on 'update' actions.
```xml
```
--------------------------------
### Full Uploadable Entity Configuration with Annotations
Source: https://github.com/doctrine-extensions/doctrineextensions/blob/main/doc/uploadable.md
An example of a fully configured Uploadable entity using annotations, demonstrating options for path, callback, filename generator, overwrite, and number appending.
```php
getRepository(Category::class);
echo $repo->childCount($food); // 3 (all descendants)
echo $repo->childCount($food, true); // 2 (direct children only)
$path = $repo->getPath($carrots);
// [Food, Vegetables, Carrots]
```
--------------------------------
### Usage Example: 'nullify' ReferenceIntegrity
Source: https://github.com/doctrine-extensions/doctrineextensions/blob/main/doc/reference_integrity.md
Demonstrates the 'nullify' behavior. When a Type document is removed, its reference in the associated Article document is automatically set to null.
```php
setTitle('My Article');
$type = new Type;
$type->setTitle('Published');
$article->setType($type);
$em->persist($article);
$em->persist($type);
$em->flush();
$type = $em->getRepository('Document\Type')->findByTitle('Published');
$em->remove($type);
$em->flush();
$article = $em->getRepository('Document\Article')->findByTitle('My Article');
$article->getType(); // won't be referenced to Type anymore
```
--------------------------------
### IpTraceable Listener Setup and Usage in PHP
Source: https://context7.com/doctrine-extensions/doctrineextensions/llms.txt
Sets up the IpTraceable listener, allowing direct IP value provision or using a provider. Demonstrates logging IP on entity creation and field change.
```php
// --- Listener setup ---
use Gedmo\IpTraceable\IpTraceableListener;
$ipTraceableListener = new IpTraceableListener();
// Provide IP directly
$ipTraceableListener->setIpValue($_SERVER['REMOTE_ADDR'] ?? '127.0.0.1');
// Or via a provider implementing Gedmo\Tool\IpAddressProviderInterface
// $ipTraceableListener->setIpAddressProvider($provider);
$em->getEventManager()->addEventSubscriber($ipTraceableListener);
// --- Usage ---
$article = new Article();
$em->persist($article);
$em->flush();
echo $article->createdFromIp; // "127.0.0.1"
$article->published = true;
$em->flush();
echo $article->publishedFromIp; // "127.0.0.1"
// Use traits for convenience:
// use Gedmo\IpTraceable\Traits\IpTraceableEntity; // adds $createdFromIp and $updatedFromIp
```
--------------------------------
### Listener Setup and Usage
Source: https://context7.com/doctrine-extensions/doctrineextensions/llms.txt
Initialize the LoggableListener, set the username, and add it as an event subscriber to your entity manager. Log entries are automatically created on persist and flush operations.
```php
// --- Listener setup ---
use Gedmo\Loggable\LoggableListener;
$loggableListener = new LoggableListener();
$loggableListener->setUsername('admin');
$em->getEventManager()->addEventSubscriber($loggableListener);
```
```php
// --- Create and update (log entries are created automatically) ---
$article = new Article();
$article->title = 'Version 1';
$em->persist($article);
$em->flush(); // creates log entry: action=create, version=1
$article->title = 'Version 2';
$em->flush(); // creates log entry: action=update, version=2
$article->title = 'Version 3';
$em->flush(); // creates log entry: action=update, version=3
```
--------------------------------
### Translatable Listener Setup
Source: https://context7.com/doctrine-extensions/doctrineextensions/llms.txt
Configure the TranslatableListener with default locale, translatable locale, and fallback settings. Add the listener as an event subscriber to the entity manager.
```php
use Gedmo\Translatable\TranslatableListener;
$translatableListener = new TranslatableListener();
$translatableListener->setDefaultLocale('en');
$translatableListener->setTranslatableLocale('en');
$translatableListener->setTranslationFallback(true); // fall back to default locale
$em->getEventManager()->addEventSubscriber($translatableListener);
```
--------------------------------
### Annotation Configuration for IP Traceable
Source: https://github.com/doctrine-extensions/doctrineextensions/blob/main/doc/ip_traceable.md
Configure the IP traceable extension using annotations. This example sets the 'updatedFromIp' field. Note: Support for annotations is deprecated and will be removed in 4.0.
```php
```
--------------------------------
### Retrieve Tree as HTML
Source: https://github.com/doctrine-extensions/doctrineextensions/blob/main/doc/tree.md
Generate an HTML tree structure (ul - li) from the category hierarchy. This example loads all children and uses default decoration.
```php
getRepository(Category::class);
$htmlTree = $repo->childrenHierarchy(
null, /* starting from root nodes */
false, /* true: load all children, false: only direct */
[
'decorate' => true,
'representationField' => 'slug',
'html' => true
]
);
```
--------------------------------
### Attribute Configuration for IP Traceable
Source: https://github.com/doctrine-extensions/doctrineextensions/blob/main/doc/ip_traceable.md
Configure the IP traceable extension using attributes on your entity class properties. This example shows setting the 'updatedFromIp' field.
```php
```
--------------------------------
### Implement Symfony Actor Provider
Source: https://github.com/doctrine-extensions/doctrineextensions/blob/main/doc/utils/actor-provider.md
Example of an actor provider implementation using Symfony's Security components. It retrieves the current user from the token storage.
```php
namespace App\Utils;
use Gedmo\Tool\ActorProviderInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
final class SymfonyActorProvider implements ActorProviderInterface
{
private TokenStorageInterface $tokenStorage;
public function __construct(TokenStorageInterface $tokenStorage)
{
$this->tokenStorage = $tokenStorage;
}
/**
* @return object|string|null
*/
public function getActor()
{
$token = $this->tokenStorage->getToken();
return $token ? $token->getUser() : null;
}
}
```
--------------------------------
### Initiating Transaction with Pessimistic Lock
Source: https://github.com/doctrine-extensions/doctrineextensions/blob/main/doc/transaction-safety.md
Demonstrates how to start a transaction and acquire a pessimistic lock on a Shop entity to prevent concurrent modifications. This is crucial for maintaining data integrity during atomic updates of related entities like Categories.
```php
getEntityManager();
$conn = $em->getConnection();
$categoryRepository = $em->getRepository("App\Entity\Category");
// start transaction
$conn->beginTransaction();
try {
// select shop for update - locks it for any read attempts until this transaction ends
```
--------------------------------
### Usage Example: 'pull' ReferenceIntegrity
Source: https://github.com/doctrine-extensions/doctrineextensions/blob/main/doc/reference_integrity.md
Demonstrates the 'pull' behavior for ReferenceMany associations. When a Type document is removed from a collection, it is automatically removed from the Article's types list.
```php
setTitle('My Article');
$type1 = new Type;
$type1->setTitle('Published');
$type2 = new Type;
$type2->setTitle('Info');
$article->addType($type1);
$article->addType($type2);
$em->persist($article);
$em->persist($type1);
$em->persist($type2);
$em->flush();
$type2 = $em->getRepository('Document\Type')->findByTitle('Info');
$em->remove($type2);
$em->flush();
$article = $em->getRepository('Document\Article')->findByTitle('My Article');
$article->getTypes(); // will only contain $type1 ('Published')
```
--------------------------------
### Advanced HTML Tree with Custom Decorators and Routes
Source: https://github.com/doctrine-extensions/doctrineextensions/blob/main/doc/tree.md
Generate an HTML tree using custom root/child decorators and a node decorator that utilizes controller routes for generating links. This example also demonstrates limiting levels.
```php
childrenHierarchy(null, false, [
'decorate' => true,
'rootOpen' => static function (array $tree): ?string {
if ([] !== $tree && 0 == $tree[0]['lvl']) {
return '
';
}
return null;
},
'rootClose' => static function (array $child): ?string {
if ([] !== $child && 0 == $child[0]['lvl']) {
return '
';
}
return null;
},
'childOpen' => '',
'childClose' => '',
'nodeDecorator' => static function (array $node) use (&$controller): ?string {
if (1 == $node['lvl']) {
return ''.$node['title'].'
';
}
if ($node["isVisibleOnHome"]) {
return ' $node['id']]).'">'.$node['title'].' ';
}
return null;
}
]);
```
--------------------------------
### Custom IP Address Provider Implementation
Source: https://github.com/doctrine-extensions/doctrineextensions/blob/main/doc/utils/ip-address-provider.md
Implement the `IpAddressProviderInterface` to provide IP addresses. This example uses Symfony's HttpFoundation component to retrieve the client's IP address. Ensure the `RequestStack` is available in your application's service container.
```php
namespace App\Utils;
use Gedmo\Tool\IpAddressProviderInterface;
use Symfony\Component\HttpFoundation\RequestStack;
final class RequestIpAddressProvider implements IpAddressProviderInterface
{
private RequestStack $requestStack;
public function __construct(RequestStack $requestStack)
{
$this->requestStack = $requestStack;
}
public function getAddress(): ?string
{
$request = $this->requestStack->getMainRequest();
return $request ? $request->getClientIp() : null;
}
}
```
--------------------------------
### Entity Setup for Translatable Fields
Source: https://context7.com/doctrine-extensions/doctrineextensions/llms.txt
Define an entity that implements the Translatable interface and mark fields for translation using the Gedmo\Translatable annotation. You can also override the global locale per entity instance.
```php
title = 'Food';
$fruits = new Category(); $fruits->title = 'Fruits'; $fruits->parent = $food;
$veggies = new Category(); $veggies->title = 'Vegetables'; $veggies->parent = $food;
$carrots = new Category(); $carrots->title = 'Carrots'; $carrots->parent = $veggies;
$em->persist($food); $em->persist($fruits); $em->persist($veggies); $em->persist($carrots);
$em->flush();
// DB: food(1-8), fruits(2-3), vegetables(4-7), carrots(5-6)
```
--------------------------------
### XML Configuration for Blameable Field
Source: https://github.com/doctrine-extensions/doctrineextensions/blob/main/doc/blameable.md
Configure a field as blameable using XML mapping. This example sets the 'updatedBy' field on update.
```xml
```
--------------------------------
### Test Sluggable Behavior
Source: https://github.com/doctrine-extensions/doctrineextensions/blob/main/doc/sluggable.md
Demonstrates how to create an entity, set its fields, persist it, and then retrieve the generated slug.
```php
setTitle('the title');
$article->setCode('my code');
$this->em->persist($article);
$this->em->flush();
echo $article->getSlug();
// prints: The_Title_My_Code
```
--------------------------------
### Sluggable Annotation Mapping Example
Source: https://github.com/doctrine-extensions/doctrineextensions/blob/main/doc/sluggable.md
Defines an Article document with a slug generated from 'title' and 'code' fields using Doctrine ODM annotations.
```php
id;
}
public function setTitle($title)
{
$this->title = $title;
}
public function getTitle()
{
return $this->title;
}
public function setCode($code)
{
$this->code = $code;
}
public function getCode()
{
return $this->code;
}
public function getSlug()
{
return $this->slug;
}
}
```
--------------------------------
### PHP: Creating and Saving Tree Entities
Source: https://github.com/doctrine-extensions/doctrineextensions/blob/main/doc/tree.md
Demonstrates how to create new category entities, set their parent-child relationships, and persist them to generate a tree structure. Ensure the entity manager is available for persisting and flushing changes.
```php
setTitle('Food');
$fruits = new Category();
$fruits->setTitle('Fruits');
$fruits->setParent($food);
$vegetables = new Category();
$vegetables->setTitle('Vegetables');
$vegetables->setParent($food);
$carrots = new Category();
$carrots->setTitle('Carrots');
$carrots->setParent($vegetables);
$this->em->persist($food);
$this->em->persist($fruits);
$this->em->persist($vegetables);
$this->em->persist($carrots);
$this->em->flush();
```
--------------------------------
### Basic Sluggable Usage and Regeneration
Source: https://context7.com/doctrine-extensions/doctrineextensions/llms.txt
Demonstrates basic usage of the Sluggable behavior, including entity instantiation, persistence, and slug regeneration by setting the slug field to null.
```php
// --- Basic usage ---
$article = new Article();
$article->title = 'Hello World';
$article->code = 'hw';
$em->persist($article);
$em->flush();
echo $article->slug; // "hello-world-hw"
echo $article->fixedSlug; // "Hello_World"
// Regenerate slug by setting to null
$article->slug = null;
$em->flush();
// Set manually (Sluggable ensures uniqueness)
$article->slug = 'custom-slug';
$em->flush();
echo $article->slug; // "custom-slug" (or "custom-slug-1" if taken)
```
--------------------------------
### ReferenceManyEmbed Attribute Example
Source: https://github.com/doctrine-extensions/doctrineextensions/blob/main/doc/attributes.md
Use ReferenceManyEmbed to establish a reference between objects in different databases or object managers, similar to MongoDB ODM's ReferenceMany.
```php
*/
#[Gedmo\ReferenceManyEmbed(type: 'entity', class: Comment::class, identifier: 'metadata.commentId')]
private Collection $comments;
public function __construct()
{
$this->comments = new ArrayCollection();
}
}
```
--------------------------------
### Setting Default Upload Path and Processing Files
Source: https://github.com/doctrine-extensions/doctrineextensions/blob/main/doc/uploadable.md
Demonstrates how to set a default upload path on the listener and process uploaded files from the $_FILES array, associating them with entities.
```php
setDefaultPath('/my/app/web/upload');
if (isset($_FILES['images']) && is_array($_FILES['images'])) {
foreach ($_FILES['images'] as $fileInfo) {
$file = new File();
$listener->addEntityFileInfo($file, $fileInfo);
// You can set the file info directly with a FileInfoInterface object, like this:
//
// $listener->addEntityFileInfo($file, new FileInfoArray($fileInfo));
//
// Or create your own class which implements FileInfoInterface
//
// $listener->addEntityFileInfo($file, new MyOwnFileInfo($fileInfo));
$em->persist($file);
}
}
$em->flush();
```
--------------------------------
### Using Repository Functions for Tree Operations
Source: https://github.com/doctrine-extensions/doctrineextensions/blob/main/doc/tree.md
Demonstrates various repository functions for interacting with tree structures, such as finding nodes, counting children, retrieving paths, verifying tree integrity, recovering corrupted trees, and removing nodes.
```php
getRepository(Category::class);
$food = $repo->findOneByTitle('Food');
echo $repo->childCount($food);
// prints: 3
echo $repo->childCount($food, true/*direct*/);
// prints: 2
$children = $repo->children($food);
// $children contains:
// 3 nodes
$children = $repo->children($food, false, 'title');
// will sort the children by title
$carrots = $repo->findOneByTitle('Carrots');
$path = $repo->getPath($carrots);
/* $path contains:
0 => Food
1 => Vegetables
2 => Carrots
*/
$stringPath = $repo->getPathAsString([
'includeNode' => false,
'separator' => '/',
'stringMethod' => 'getTitle',
]);
// $stringPath is 'Food/Vegetables'
// verification and recovery of tree
// can return TRUE if tree is valid, or array of errors found on tree
$repo->verify();
// if tree has errors it will try to fix all tree nodes
$repo->recover([
'flush' => false, // Do not auto-flush each entity manager after each node is recovered
'treeRootNode' => $rootNode, // Only recover the $rootNode tree (when you have a forest with multiple root nodes)
'skipVerify' => false, // Try to verify the tree first and do not attempt recovery if not necessary
'sortByField' => 'hierarchy', // Reorder sibling nodes by this field during recovery
'sortDirection' => 'DESC',
]);
$em->flush(); // important: flush recovered nodes, unless you used ['flush' => true]
// For large trees normal recovery can take a while, use this if speed is a priority.
// No need to flush as it operates outside the entity manager (see phpdoc for side effects)
$repo->recoverFast([
'sortByField' => 'hierarchy', // Reorder sibling nodes by this field during recovery
'sortDirection' => 'DESC',
]);
// UNSAFE: be sure to backup before running this method when necessary, if you can use $em->remove($node);
// which would cascade to children
// single node removal
$vegies = $repo->findOneByTitle('Vegetables');
$repo->removeFromTree($vegies);
$em->clear(); // clear cached nodes
// it will remove this node from tree and reparent all children
// reordering the tree
$food = $repo->findOneByTitle('Food');
$repo->reorder($food, 'title');
// it will reorder all "Food" tree node left-right values by the title
```
--------------------------------
### Shop Entity Definition
Source: https://github.com/doctrine-extensions/doctrineextensions/blob/main/doc/transaction-safety.md
Defines the basic Shop entity for an e-commerce platform. No specific setup is required beyond standard Doctrine entity mapping.
```php
name = $name;
return $this;
}
public function getName()
{
return $this->name;
}
}
```
--------------------------------
### Configure Blameable Attribute for Creation
Source: https://github.com/doctrine-extensions/doctrineextensions/blob/main/doc/attributes.md
Use the Blameable attribute to track the user who created an entity. This example sets the `createdBy` field upon entity creation.
```php
name = 'Alpha'; $a->category = 'tech';
$b = new Item(); $b->name = 'Beta'; $b->category = 'tech';
$em->persist($a); $em->persist($b); $em->flush();
// $a->position === 0, $b->position === 1
// --- Insert at specific position ---
$c = new Item(); $c->name = 'Zero'; $c->category = 'tech'; $c->position = 0;
$em->persist($c); $em->flush();
// $c->position===0, $a->position===1, $b->position===2
// --- Reorder by setting position ---
$b->position = 0;
$em->flush();
// $b->position===0, $c->position===1, $a->position===2
// --- Move to end with -1 ---
$c->position = -1;
$em->flush();
// --- Query by group ---
/** @var SortableRepository $repo */
$repo = $em->getRepository(Item::class);
$items = $repo->getBySortableGroupsQuery(['category' => 'tech'])->getResult();
foreach ($items as $item) {
echo $item->position . ': ' . $item->name . PHP_EOL;
}
// 0: Beta
// 1: Alpha
// 2: Zero (was moved to end via -1)
```
--------------------------------
### Register ORM Listeners for Doctrine Behavioral Extensions
Source: https://context7.com/doctrine-extensions/doctrineextensions/llms.txt
Manually attach all Doctrine Behavioral Extension listeners to an ORM EntityManager. This setup is required for the extensions to function.
```php
getEventManager();
// Register each extension as an event subscriber
$evm->addEventSubscriber(new TreeListener());
$evm->addEventSubscriber(new SluggableListener());
$evm->addEventSubscriber(new SortableListener());
$evm->addEventSubscriber(new SoftDeleteableListener());
$timestampableListener = new TimestampableListener();
$timestampableListener->setClock(new Symfony Components Clock NativeClock()); // optional PSR-20 clock
$evm->addEventSubscriber($timestampableListener);
$blameableListener = new BlameableListener();
$blameableListener->setUserValue('admin'); // or set an object
$evm->addEventSubscriber($blameableListener);
$ipTraceableListener = new IpTraceableListener();
$ipTraceableListener->setIpValue('127.0.0.1');
$evm->addEventSubscriber($ipTraceableListener);
$loggableListener = new LoggableListener();
$loggableListener->setUsername('admin');
$evm->addEventSubscriber($loggableListener);
$translatableListener = new TranslatableListener();
$translatableListener->setDefaultLocale('en');
$translatableListener->setTranslatableLocale('en');
$evm->addEventSubscriber($translatableListener);
// Register the soft-deleteable ORM filter
$em->getConfiguration()->addFilter('soft-deleteable', Gedmo SoftDeleteable Filter SoftDeleteableFilter::class);
$em->getFilters()->enable('soft-deleteable');
```
--------------------------------
### Inject IP Address Provider into Listener
Source: https://github.com/doctrine-extensions/doctrineextensions/blob/main/doc/utils/ip-address-provider.md
After creating your IP address provider, inject it into the relevant extension listener using the `setIpAddressProvider` method. This ensures the extension uses your custom logic for retrieving IP addresses.
```php
/** @var Gedmo\IpTraceable\IpTraceableListener $listener */
$listener->setIpAddressProvider($provider);
```
--------------------------------
### Inserting Nodes in Different Positions
Source: https://github.com/doctrine-extensions/doctrineextensions/blob/main/doc/tree.md
Illustrates how to insert new nodes into the tree at specific positions, such as the first child, last child, or as a sibling to an existing node.
```php
setTitle('Food');
$fruits = new Category();
$fruits->setTitle('Fruits');
$vegetables = new Category();
$vegetables->setTitle('Vegetables');
$carrots = new Category();
$carrots->setTitle('Carrots');
$treeRepository
->persistAsFirstChild($food)
->persistAsFirstChildOf($fruits, $food)
->persistAsLastChildOf($vegetables, $food)
->persistAsNextSiblingOf($carrots, $fruits);
$em->flush();
```
--------------------------------
### Slug Attribute Basic Example
Source: https://github.com/doctrine-extensions/doctrineextensions/blob/main/doc/attributes.md
Configure the Slug attribute to specify the field for storing the generated slug. The 'fields' parameter is mandatory and lists the source fields for slug generation.
```php
id;
}
public function setTitle($title)
{
$this->title = $title;
}
public function getTitle()
{
return $this->title;
}
public function setCode($code)
{
$this->code = $code;
}
public function getCode()
{
return $this->code;
}
public function getSlug()
{
return $this->slug;
}
public function getUniqueSlug()
{
return $this->uniqueSlug;
}
}
```
--------------------------------
### Setting IP Address Provider or Value
Source: https://github.com/doctrine-extensions/doctrineextensions/blob/main/doc/ip_traceable.md
You can set the IP address to be recorded either through an IP address provider service implementing Gedmo\Tool\IpAddressProviderInterface or by directly calling the listener's setIpValue method.
```php
// The $provider must be an implementation of Gedmo\Tool\IpAddressProviderInterface
$listener->setIpAddressProvider($provider);
$listener->setIpValue('127.0.0.1');
```