1

I would love to sort an embedded MongoDB object using PHP Lithium. I have got a Model "Thread" which looks almost like this:

{
   "_id": ObjectId("4f71bf4618b602580f000009"),
   "postings": [
      {text: "a", upvotes: 15, /*...*/},
      {text: "b", upvotes: 23},
      {text: "c", upvotes: 16},
      {text: "d", upvotes: 42}
   ],
   // bla
}

Now I would like to sort the postings depending on their upvotes. I already wrote a method which roughly does what I want:

public function postings_sort_by_upvotes($thread) {
    $postings = $thread->postings->to('array');
    usort($postings, function($a, $b) {
                         return ($a['upvotes'] > $b['upvotes'] ? 1 : -1);
                     });
    return $postings;
}

This works, but obviously it returns the postings as a plain array, while the unsorted postings were a lithium\data\collection\DocumentArray type.

Do I really need to struggle with an array instead of an object or is there a way which allows me to sort them without losing the original data type?

greut
  • 4,305
  • 1
  • 30
  • 49
YMMD
  • 3,730
  • 2
  • 32
  • 43

1 Answers1

4

A DocumentArray object is a Collection, and hopefully, Lithium Collections are sortable. You can call sort() on a $collection different ways :

$collection->sort('field'); //sort naturally by the given field

Or define a custom closure :

$collection->sort(function ($a,$b) {
    if ($a == $b) {
        return 0;
    }
    return ($b > $a ? 1 : -1);
});

Check docs on lithium\data\Collection, from which DocumentArrayinherits, and lithium\util\Collection, the Collection object.

an Introduction to Collectionsby Joe Beeson. He don't cover sorting especially but it worth a read (other articles too)

Mehdi Lahmam B.
  • 2,240
  • 16
  • 22
  • I tried to sort it within my view doing this: `$thread->postings->sort('upvotes')` but it fails with a fatal error: _Uncaught exception 'BadMethodCallException' with message 'No model bound or unhandled method call `sort`.' in D:\xampp\htdocs\AWF\libraries\lithium\data\Entity.php:191_ What you say sounds reasonable to me and also the docs are very clear, but I am still not able to call this method. What am I doing wrong? – YMMD Mar 28 '12 at 10:41
  • I can confirm that it works fine, after running your own code https://github.com/UnionOfRAD/lithium/issues/405#issuecomment-4831856. Be sure that nothing interfere with your entity (before or after create, etc.) – Mehdi Lahmam B. Mar 29 '12 at 22:30
  • It works for me now as I copied the method's source code manually into lithium\util\Collection.php. I have no idea why, but my code did not contain it, although I downloaded version 0.10 only 19 days ago. Thanks for your help and sorry for providing such elusive information. – YMMD Mar 30 '12 at 12:23
  • Sort() method was introduced in July 2011, prior to 0.10 (https://github.com/UnionOfRAD/lithium/commit/74514b870c13aac98236111c524ab5c1bc04656f#util/Collection.php). The master branch is stable. Clone it ;) – Mehdi Lahmam B. Mar 30 '12 at 14:58