chamber-orchestra/doctrine-extensions-bundle
Install the Bundle Add to your project via Composer:
composer require chamber-orchestra/doctrine-extensions-bundle
Enable the bundle in config/bundles.php:
return [
// ...
ChamberOrchestra\DoctrineExtensionsBundle\ChamberOrchestraDoctrineExtensionsBundle::class => ['all' => true],
];
Register Doctrine Extensions
Add the following to your config/packages/doctrine.yaml:
doctrine:
orm:
dql:
string_functions:
RANDOM: ChamberOrchestra\DoctrineExtensionsBundle\DQL\RandomFunction
mappings:
App:
is_bundle: false
type: attribute
dir: "%kernel.project_dir%/src/Entity"
prefix: "App\Entity"
alias: App
First Use Case: Soft Deletes
Apply the SoftDeletable trait to an entity:
use ChamberOrchestra\DoctrineExtensionsBundle\Model\SoftDeletableTrait;
#[ORM\Entity(repositoryClass: ChamberOrchestra\DoctrineExtensionsBundle\Repository\SoftDeletableRepository::class)]
class Post
{
use SoftDeletableTrait;
// ...
}
Enable the soft-delete filter in config/packages/doctrine.yaml:
doctrine:
orm:
filters:
softdeleteable:
class: ChamberOrchestra\DoctrineExtensionsBundle\Filter\SoftDeleteFilter
enabled: true
deletedAt column and methods (isDeleted(), delete(), restore()).
#[ORM\Entity(repositoryClass: SoftDeletableRepository::class)]
class User
{
use SoftDeletableTrait;
}
decimal fields with precision/scale.
use ChamberOrchestra\DoctrineExtensionsBundle\Model\DecimalTrait;
class Product
{
use DecimalTrait;
#[ORM\Column(type: 'decimal', precision: 10, scale: 2)]
private $price;
}
Extend SoftDeletableRepository for soft-delete-aware queries:
use ChamberOrchestra\DoctrineExtensionsBundle\Repository\SoftDeletableRepository;
class PostRepository extends SoftDeletableRepository
{
public function findPublished(): array
{
return $this->createQueryBuilder('p')
->andWhere('p.publishedAt <= :now')
->setParameter('now', new \DateTime())
->getQuery()
->getResult();
}
}
Use RANDOM() in queries for shuffling results:
$qb = $this->createQueryBuilder('u')
->addSelect('RANDOM() as random_sort')
->orderBy('random_sort');
Soft Deletes:
$post->delete(); $em->flush();$post->restore(); $em->flush();$posts = $repo->findAll(); (automatically excludes soft-deleted).Decimal Handling:
@ORM\Column and use getDecimal()/setDecimal() methods.Randomization:
RANDOM() in ORDER BY for shuffling or SELECT RANDOM() as random_value for weighted logic.Soft-Delete Filter Scope:
$qb->disableSoftDeleteFilter();
findAll() or findBy() cautiously—soft-deleted records are excluded by default.Decimal Precision:
InvalidArgumentException if precision/scale exceed PostgreSQL limits (e.g., precision > 131072).DQL Function Registration:
RANDOM in doctrine.yaml causes Unknown DQL function 'RANDOM' errors.php bin/console debug:container chamber_orchestra.doctrine_extensions.dql.random_function
Repository Inheritance:
SoftDeletableRepository only if using soft deletes. Mixing traits/repos incorrectly may break query building.Soft-Delete Queries: Enable SQL logging to verify filters:
doctrine:
dbal:
logging: true
logging_format: '%%sql%%'
Look for WHERE deletedAt IS NULL in generated SQL.
Decimal Issues:
Check for Doctrine\DBAL\Exception\InvalidFieldNameException if column names conflict with trait methods (e.g., deletedAt vs. deleted_at).
Custom Filters:
Extend ChamberOrchestra\DoctrineExtensionsBundle\Filter\AbstractFilter to create reusable query filters.
DQL Functions:
Add new functions by implementing Doctrine\ORM\Query\AST\Functions\FunctionNode and registering them in the bundle’s Resources/config/services.yaml.
Traits:
Override trait methods (e.g., getDeletedAt()) to customize behavior, but document changes clearly.
$em->getFilters()->disable('softdeleteable');
decimal type relies on PostgreSQL’s numeric type. MySQL users may need a custom DBAL type.How can I help you explore Laravel packages today?