Doctrine 2 Criteria using multiple orderings #4925

Closed
opened 2026-01-22 14:52:07 +01:00 by admin · 12 comments
Owner

Originally created by @pettersoderlund on GitHub (Dec 9, 2015).

I'm trying to order a selection created by Doctrine\Common\Collections\Criteria, http://doctrine-orm.readthedocs.org/projects/doctrine-orm/en/latest/reference/working-with-associations.html#filtering-collections with multiple order attributes as specified possible (?) in the specification of criteria

/**
 * @param array $orderings
 * @return Criteria
 */
public function orderBy(array $orderings);

however, the collection sorted only takes notice of my first entry in the sorting array. My array of $orderings looks like

array(5) { ["col1"]=> string(3) "ASC" ["col2"]=> string(3) "ASC" ["col3"]=> string(3) "ASC" ["col4"]=> string(3) "ASC" ["col5"]=> string(3) "ASC" }

Any ideas? The docs mentions andX() in the bottom of the page linked earlier but I can't figure out how I would use it in this case.

Cheers, P

Originally created by @pettersoderlund on GitHub (Dec 9, 2015). I'm trying to order a selection created by Doctrine\Common\Collections\Criteria, http://doctrine-orm.readthedocs.org/projects/doctrine-orm/en/latest/reference/working-with-associations.html#filtering-collections with multiple order attributes as specified possible (?) in the specification of criteria ``` php /** * @param array $orderings * @return Criteria */ public function orderBy(array $orderings); ``` however, the collection sorted only takes notice of my first entry in the sorting array. My array of $orderings looks like ``` array(5) { ["col1"]=> string(3) "ASC" ["col2"]=> string(3) "ASC" ["col3"]=> string(3) "ASC" ["col4"]=> string(3) "ASC" ["col5"]=> string(3) "ASC" } ``` Any ideas? The docs mentions andX() in the bottom of the page linked earlier but I can't figure out how I would use it in this case. Cheers, P
admin added the Bug label 2026-01-22 14:52:07 +01:00
admin closed this issue 2026-01-22 14:52:07 +01:00
Author
Owner

@Ocramius commented on GitHub (Dec 10, 2015):

I think this is a genuine bug that requires a failing test case.

@Ocramius commented on GitHub (Dec 10, 2015): I think this is a genuine bug that requires a failing test case.
Author
Owner

@koprivajakub commented on GitHub (Dec 15, 2015):

I have easy fix for this. Could you assign this to me? I need to solve it :)

@koprivajakub commented on GitHub (Dec 15, 2015): I have easy fix for this. Could you assign this to me? I need to solve it :)
Author
Owner

@pettersoderlund commented on GitHub (Dec 19, 2015):

Whats the ETA on fixing this you'd think @Ocramius ? Need to consider changing strategy or not :)

@pettersoderlund commented on GitHub (Dec 19, 2015): Whats the ETA on fixing this you'd think @Ocramius ? Need to consider changing strategy or not :)
Author
Owner

@billschaller commented on GitHub (Dec 19, 2015):

@pettersoderlund If you can provide a test case it should be easy enough to fix. Ocramius is on holiday till the 24th.

@billschaller commented on GitHub (Dec 19, 2015): @pettersoderlund If you can provide a test case it should be easy enough to fix. Ocramius is on holiday till the 24th.
Author
Owner

@pettersoderlund commented on GitHub (Dec 19, 2015):

@zeroedin-bill thanks for getting back so quickly!

I did not really figure out where to put a relevant test case but found some changes that might sort it out (pun intended). In the file /doctrine/collections/lib/Doctrine/Common/Collections/ArrayCollection.php

I made the following changes from line 370 according to the comments:

    if ($orderings = $criteria->getOrderings()) {
        $lnext = null; // history next
        foreach (array_reverse($orderings) as $field => $ordering) {
            $next = ClosureExpressionVisitor::sortByField($field, $ordering == Criteria::DESC ? -1 : 1, $lnext); // added the history variable
            $lnext = $next; // saved history
        }

        uasort($filtered, $next);
    }
@pettersoderlund commented on GitHub (Dec 19, 2015): @zeroedin-bill thanks for getting back so quickly! I did not really figure out where to put a relevant test case but found some changes that might sort it out (pun intended). In the file /doctrine/collections/lib/Doctrine/Common/Collections/ArrayCollection.php I made the following changes from line 370 according to the comments: ``` if ($orderings = $criteria->getOrderings()) { $lnext = null; // history next foreach (array_reverse($orderings) as $field => $ordering) { $next = ClosureExpressionVisitor::sortByField($field, $ordering == Criteria::DESC ? -1 : 1, $lnext); // added the history variable $lnext = $next; // saved history } uasort($filtered, $next); } ```
Author
Owner

@pettersoderlund commented on GitHub (Dec 20, 2015):

Gave a shot at a test case in (that is atm failing) collections/tests/Doctrine/Tests/Common/Collections/ArrayCollectionTest.php

public function testMatchingWithMultipleKeysSortingPreservesyKeys()
{
    $object1 = new \stdClass();
    $object2 = new \stdClass();

    $object1->sortField = 1;
    $object2->sortField = 1;
    $object1->sortField2 = 1;
    $object2->sortField2 = 2;

    $collection = new ArrayCollection(array(
        'object1' => $object1,
        'object2' => $object2,
    ));

    $this->assertSame(
        array(
            'object1' => $object1,
            'object2' => $object2,
        ),
        $collection
            ->matching(new Criteria(null, array('sortField' => Criteria::ASC, 'sortField2' => Criteria::ASC)))
            ->toArray()
    );
}
@pettersoderlund commented on GitHub (Dec 20, 2015): Gave a shot at a test case in (that is atm failing) collections/tests/Doctrine/Tests/Common/Collections/ArrayCollectionTest.php ``` public function testMatchingWithMultipleKeysSortingPreservesyKeys() { $object1 = new \stdClass(); $object2 = new \stdClass(); $object1->sortField = 1; $object2->sortField = 1; $object1->sortField2 = 1; $object2->sortField2 = 2; $collection = new ArrayCollection(array( 'object1' => $object1, 'object2' => $object2, )); $this->assertSame( array( 'object1' => $object1, 'object2' => $object2, ), $collection ->matching(new Criteria(null, array('sortField' => Criteria::ASC, 'sortField2' => Criteria::ASC))) ->toArray() ); } ```
Author
Owner

@webjoaoneto commented on GitHub (Mar 15, 2016):

This code fixed this bug for me:

foreach (array_reverse($orderings) as $field => $ordering) { $next = ClosureExpressionVisitor::sortByField($field, $ordering == Criteria::DESC ? -1 : 1, $next ); }

@webjoaoneto commented on GitHub (Mar 15, 2016): This code fixed this bug for me: `foreach (array_reverse($orderings) as $field => $ordering) { $next = ClosureExpressionVisitor::sortByField($field, $ordering == Criteria::DESC ? -1 : 1, $next ); }`
Author
Owner

@MalteHillmann commented on GitHub (Mar 21, 2016):

Thank you @joao-gsneto , your code works fine.
I hope this will soon be fixed in the official doctrine release.

@MalteHillmann commented on GitHub (Mar 21, 2016): Thank you @joao-gsneto , your code works fine. I hope this will soon be fixed in the official doctrine release.
Author
Owner

@cdaguerre commented on GitHub (Feb 10, 2017):

This was actually fixed in v1.4.0 by 4b1e0f4682,
but is it expected that the indexes are not updated?
As a result, calling Collection::offsetGet() or Collection::indexOf() after sorting still returns items/indexes before sorting...

@cdaguerre commented on GitHub (Feb 10, 2017): This was actually fixed in [v1.4.0](https://github.com/doctrine/collections/releases/tag/v1.4.0) by https://github.com/doctrine/collections/commit/4b1e0f4682337c0e0e286de9ab0513eb7d5d284f, but is it expected that the indexes are not updated? As a result, calling `Collection::offsetGet()` or `Collection::indexOf()` after sorting still returns items/indexes before sorting...
Author
Owner

@guaycuru commented on GitHub (Nov 26, 2020):

Is there an open issue for that @cdaguerre ? I've just come across this (more than 3 years old) problem...

@guaycuru commented on GitHub (Nov 26, 2020): Is there an open issue for that @cdaguerre ? I've just come across this (more than 3 years old) problem...
Author
Owner

@tautis154 commented on GitHub (Dec 10, 2024):

How is this still not fixed and occurring.

@tautis154 commented on GitHub (Dec 10, 2024): How is this still not fixed and occurring.
Author
Owner

@greg0ire commented on GitHub (Dec 10, 2024):

@tautis154 as mentioned by @cdaguerre in 2017, this has been fixed for years.

@greg0ire commented on GitHub (Dec 10, 2024): @tautis154 as mentioned by @cdaguerre in 2017, this has been fixed for years.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#4925