Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sort custom field enum #819

Closed
BaptisteChabrol opened this issue Jan 13, 2025 · 8 comments
Closed

Sort custom field enum #819

BaptisteChabrol opened this issue Jan 13, 2025 · 8 comments

Comments

@BaptisteChabrol
Copy link

Feature Request

Q A
New Feature yes
RFC no
BC Break no

Summary

I have a custom field in my entity that is converted to an enum field in my database. I did this because dbal enum allows to sort this field automatically in custom order.
This works with EasyAdmin crud controller and custom request in repositories, but not with paginator.
Is it a bug or a new feature to implement ?
Link to custom type doctrine to make enum field

image

@garak
Copy link
Collaborator

garak commented Jan 13, 2025

How do you expect the sorting to work?

@BaptisteChabrol
Copy link
Author

I don't know, it works in repositories and Easyadmin i don't know why it doesn't work with Paginator

@garak
Copy link
Collaborator

garak commented Jan 13, 2025

I mean: what's your current expectation, and what's your actual result instead?

@tsiatka
Copy link

tsiatka commented Jan 13, 2025

The difference between a doctrine query and KnpPaginator is that when you use addOrderBy it orders the enum according to the order of the possible values ​​of the enum that has been defined in the type in the database.

Whereas KnpPaginator uses a usort().

We could add this piece of code in the sortFunction method of the Knp\Component\Pager\Event\Subscriber\Sortable\ArraySubscriber
:


private function sortFunction(object|array $object1, object|array $object2): int
{
     ...

        if ($fieldValue1 instanceof \UnitEnum && $fieldValue2 instanceof \UnitEnum && $fieldValue1::class === $fieldValue2::class) {
            $cases = array_values($fieldValue1::cases());
            $index1 = array_search($fieldValue1, $cases, true);
            $index2 = array_search($fieldValue2, $cases, true);

            return ($index1 <=> $index2) * $this->getSortCoefficient();
        }

	return ($fieldValue1 > $fieldValue2 ? 1 : -1) * $this->getSortCoefficient();
}

This works in the case where the Enum typed field uses a PHP Enum: as explained in this KNPLabs article.

@garak
Copy link
Collaborator

garak commented Jan 13, 2025

Why don't you use native Doctrine enums?

@garak
Copy link
Collaborator

garak commented Jan 13, 2025

By the way, ArraySubscriber is used when you sort arrays. If you sort a query, QuerySubscriber is used instead

@tsiatka
Copy link

tsiatka commented Jan 13, 2025

Why don't you use native Doctrine enums?

Because with native Doctrine enums, the enums are sorted by alphabetical order

By the way, ArraySubscriber is used when you sort arrays. If you sort a query, QuerySubscriber is used instead

Thank you it's working with the QuerySubscriber, we were using the Collection (->getQuery()->getResult()) inside the paginate method instead of the query

Are there any other differences between passing a query or a collection of objects to the paginator?

@garak
Copy link
Collaborator

garak commented Jan 13, 2025

You must pass the Query (or the QueryBuilder).
If you pass the result, the query is executed and you're paginating the full array of results (which doesn't make much sense)

@garak garak closed this as not planned Won't fix, can't repro, duplicate, stale Jan 18, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants