Sorting, deleting from a PropelObjectCollection
Propel 1.6 (and Propel 1.5 before it) is pretty sweet (thank you François!). I had some confusion with my model’s array of related objects though, thinking it was a regular PHP array. Actually it’s a Collection, specifically a PropelObjectCollection, which implements PHP 5’s ArrayObject interface. You can do a lot of cool things with them.
Sorting
Not immediately obvious, however, was how to sort them. This did the trick for my case (I have a Sequence field manually re-calculable through a jQueryUI sortable widget. Also note the cool inline anonymous function syntax available since PHP 5.3. Incidentally, I’m not sure the terms lambda or closure are helpful because they’re not quite like Lisp lambdas or JavaScript closures.
// Re-sort them by Sequence, numerically $this->collSegments->uasort(function($a, $b) { return $a->getSequence() - $b->getSequence(); }); |
// Re-sort them as strings, case-insensitively. $this->collSegments->uasort(function($a, $b) { return strnatcasecmp($a->__toString(), $b->__toString(); }); |
Deleting
Thanks to the PropelArrayCollection API Documentation
/* * Remove the provided Segment object. * * @param Segment $s * @return Segment $s that was deleted. */ public function deleteSegment(Segment $s) { $s->delete(); $key = $this->collSegments->search($s); $ret = $this->collSegments->remove($key); return $s; } |
So elsewhere,
$this->deleteSegment($s); |
Ah. This approach leaves the collection with out-of-order array keys. Which will cause grief if you later iterate with a
for()
loop, like this:foreach
loops work fine though.It’s creepy. I wish PHP arrays were less kitchen-sinky; Perl’s division of arrays and hashes would have been good in this case.
Thanks. I used this technique to return a sorted collection from a related table by overwriting the getter in the custom class. In my case, it was a list of questions in a survey that needed to be in order: