EasyAdminBundle: [3.2] Using reserved names as fields causes a crash when searching
Describe the bug Somewhat related to #3073 An entity containing a reserved keyword name for doctrine will crash the search when configured in configureCrud -> setSearchFields
To Reproduce Create 2 entities with an associations Foo, containing a field called $order (valid for field name, but needs JoinColumn(name=“order_id”) which is an association to another entity called Order (let’s say it just contains the id), needs a special table name like @ORM\Table(name=“sale_order”) to function properly (in my case it’s just sale__order, so it’s not a SQL keyword.)
Create a CrudController for Foo and add
public function configureCrud(
Crud $crud
}: Crud {
return $crud
->setSearchFields(['order.id']);
}
Then try to search anything, you’ll get
[Syntax Error] line 0, col 844: Error: Expected StateFieldPathExpression | string | InputParameter | FunctionsReturningStrings | AggregateExpression, got 'order'
This is not really because it’s a forbidden thing, but because the QueryBuilder passed to
EasyCorp\Bundle\EasyAdminBundle\Factory\PaginatorFactory::create already contains a ready DQL that contains the left join for order as an alias.
This issue can be resolved if the following check is made when creating aliases by the QueryBuilder used in this function
$name = 'Doctrine\ORM\Query\Lexer::T_' . strtoupper($string);
if (defined($name)) {
$type = constant($name);
if ($type > 100) {
return self::SAFE_PREFIX.$string; // fix keyword aliases
}
}
return $string;
where self::SAFE_PREFIX is just a prefix added to left joins when using entities with funky field names and can be anything (ea_reserved_prefix_ or similar suggested), alternatively the prefix could be added to all joins, eliminating the need for the lookup in the first place. This is an issue which can be resolved directly in EA, as I’ve resolved it in another bundle using this trick, but it doesn’t apply to table names, only to join aliases which can be anything.
I’m not quite sure how the result fetching works yet, so I can’t say if it’ll be needed to resolve the aliases back to something sensible if needed or if it’s done automatically via Doctrine.
(OPTIONAL) Additional context Symfony 4.4.20, EA 3.2.8
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Reactions: 3
- Comments: 15 (10 by maintainers)
Commits related to this issue
- Fix for #4306 Avoid error for relation alias on reserved keywords — committed to gaelb80/EasyAdminBundle by gaelb80 3 years ago
- bug #4344 Fix for #4306 (gaelb80) This PR was merged into the 3.0.x-dev branch. Discussion ---------- Fix for #4306 Avoid error for relation alias on reserved keywords <!-- Thanks for your contri... — committed to EasyCorp/EasyAdminBundle by javiereguiluz 3 years ago
This is fixable if you simply assume that each join must have a prefix. So
would change into
then the subsequent search on that field instead of being
order.text LIKE :whateverwould beea_order.text LIKE :whateverThis however could be a breaking change for people that modify these queries, though the fix is rather simple and shouldn’t take too much time. If you’ll tell me where to look (for joins mostly and where they are used later) I could probably look into creating a PR for thisI think that’s the best approach too
Well I guess escaping it is another choice, I kinda forgot about it since all I see is ORM and I kinda got used to it’s limitations. If you’d like I can let you know if your PR fixes the issue on monday morning, if tests pass and everything seems to be working there’s probably no harm in merging it if you’re planning a new release sometime soon, regardless I’ll try to get back to you with this.