oro/doctrine-extensions
Adds extra Doctrine DQL functions and field types for MySQL and PostgreSQL (e.g., DATE/TIME, TIMESTAMPDIFF, CONVERT_TZ, DAY/WEEK/MONTH, MD5). Includes registration examples for common frameworks and guidance for extending platforms/functions.
Installation:
composer require oro/doctrine-extensions
Add to config/packages/doctrine.yaml (Symfony) or equivalent for your framework:
doctrine:
orm:
dql:
datetime_functions:
date: Oro\ORM\Query\AST\Functions\SimpleFunction
numeric_functions:
timestampdiff: Oro\ORM\Query\AST\Functions\Numeric\TimestampDiff
string_functions:
group_concat: Oro\ORM\Query\AST\Functions\String\GroupConcat
First Use Case: Query for records where the day of the month is between 10-15:
$qb = $entityManager->createQueryBuilder();
$qb->select('u')
->from(User::class, 'u')
->where('DAY(u.createdAt) BETWEEN :start AND :end')
->setParameter('start', 10)
->setParameter('end', 15);
Date/Time Manipulation:
// Extract year from a date field
$qb->select('YEAR(u.birthDate) as birthYear')
->from(User::class, 'u');
// Calculate age
$qb->select('TIMESTAMPDIFF(YEAR, u.birthDate, CURRENT_DATE) as age')
->from(User::class, 'u');
Aggregation with GROUP_CONCAT:
$qb->select('GROUP_CONCAT(DISTINCT u.tags) as userTags')
->from(User::class, 'u')
->groupBy('u.id');
Type Casting:
$qb->select('CAST(u.id as string) as userIdString')
->from(User::class, 'u');
String Operations:
$qb->select('CONCAT_WS(", ", u.firstName, u.lastName) as fullName')
->from(User::class, 'u');
Oro\ORM\Query\AST\Functions\SimpleFunction for single-argument functions or create platform-specific implementations for complex logic.MoneyType and PercentType for financial data:
/**
* @ORM\Column(type="money")
*/
private $price;
// Dynamic date filtering
$qb->andWhere('MONTH(u.createdAt) = :month')
->setParameter('month', $month);
// Timezone conversion
$qb->andWhere('CONVERT_TZ(u.eventTime, "+00:00", "+05:30") > :time')
->setParameter('time', $time);
Doctrine ORM 3.0 Migration:
isSupportedType() instead of checkType()).Platform-Specific Behavior:
GROUP_CONCAT syntax differs between MySQL and PostgreSQL. Use the library’s built-in implementation for consistency.TIMESTAMPDIFF units must match the database’s supported units (e.g., YEAR, MONTH).Performance:
WHERE clauses for large datasets (e.g., DATE_FORMAT with wildcards).YEAR()) over application-side calculations.Field Type Quirks:
MoneyType/PercentType require Doctrine ORM 3.0+ and PHP 8.1+.numeric for MoneyType).Doctrine\ORM\Query::getSQL() to inspect the generated query:
$query = $qb->getQuery();
dump($query->getSQL());
$config = $entityManager->getConfiguration();
dump($config->getCustomDatetimeFunctions());
$platform = $entityManager->getConnection()->getDatabasePlatform();
dump($platform->getName());
Adding Custom Functions:
Oro\ORM\Query\AST\Functions\SimpleFunction and register it in your config.Oro\ORM\Query\AST\Functions\AbstractFunctionNode).Oro\ORM\Query\AST\Platform\Functions\MySql\MyCustomFunction).Custom Field Types:
Doctrine\DBAL\Types\Type for new field types. Example for MoneyType:
class MoneyType extends Type {
public function getSQLDeclaration(array $column, AbstractPlatform $platform) {
return $platform->getDecimalTypeDeclarationSQL($column);
}
// ... other required methods
}
Testing:
Oro\Tests\ORM\Query\AST\Functions\FunctionTestCase as a base for custom function tests.config/bundles.php:
return [
// ...
Oro\DoctrineExtensionsBundle\OroDoctrineExtensionsBundle::class => ['all' => true],
];
php bin/console doctrine:cache:clear-metadata
php bin/console doctrine:cache:clear-query
php bin/console doctrine:cache:clear-result
How can I help you explore Laravel packages today?