Reputation: 8548
I have an entity "container" with this property
/**
* @ORM\OneToMany(targetEntity="BizTV\ContentManagementBundle\Entity\Content", mappedBy="container")
*/
private $content;
the property is an array collection...
public function __construct() {
$this->content = new \Doctrine\Common\Collections\ArrayCollection();
}
...with these two standard methods
/**
* Add content
*
* @param BizTV\ContentManagementBundle\Entity\Content $content
*/
public function addContent(\BizTV\ContentManagementBundle\Entity\Content $content)
{
$this->content[] = $content;
}
/**
* Get content
*
* @return Doctrine\Common\Collections\Collection
*/
public function getContent()
{
return $this->content;
}
Now my question is, is there a smooth way to build a sorting feature into this, perhaps on the getContent() call? I am no php wiz and certainly not seasoned in symfony2 but I learn as I go.
The content entity itself has a sorting INT like this that I want to sort it on:
/**
* @var integer $sortOrder
*
* @ORM\Column(name="sort_order", type="integer")
*/
private $sortOrder;
Upvotes: 35
Views: 58954
Reputation: 6480
You can also sort ArrayCollection
by Criteria
property orderBy
like so:
<?php
namespace App/Service;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Criteria;
/**
* Class SortService
*
* @package App\Service
*/
class SortService {
/**
* @param SomeAbstractObject $object
* @return SomeCollectionItem[]
*/
public function sorted(SomeAbstractObject $object): array {
/** $var ArrayCollection|SomeCollectionItem[] */
$collection = $object->getCollection();
// convert normal array to array collection object
if(\is_array(collection)) {
$collection = new ArrayCollection(collection);
}
// order collection items by position property
$orderBy = (Criteria::create())->orderBy([
'position' => Criteria::ASC,
]);
// return sorted SomeCollectionItem array
return $collection->matching($orderBy)->toArray();
}
}
?>
Upvotes: 3
Reputation: 1524
If you want to be sure that you always get your relations in the order based on current property values, you can do something like this:
$sort = new Criteria(null, ['Order' => Criteria::ASC]);
return $this->yourCollectionProperty->matching($sort);
Use that for example if you've changed the Order property. Works great for a "Last modified date" as well.
Upvotes: 24
Reputation: 435
You can write
@ORM\OrderBy({"date" = "ASC", "time" = "ASC"})
for multiple criteria ordering.
Upvotes: 16
Reputation: 3353
You should be able to use the @ORM\OrderBy statement which allows you to specify columns to order collections on:
/**
* @ORM\OneToMany(targetEntity="BizTV\ContentManagementBundle\Entity\Content", mappedBy="container")
* @ORM\OrderBy({"sort_order" = "ASC"})
*/
private $content;
In fact this may be a duplicate of How to OrderBy on OneToMany/ManyToOne
Checking for implementation advice it appears that you must fetch the tables with a join query to the collection in order for the @ORM\OrderBy annotation to work: http://www.krueckeberg.org/notes/d2.html
This means that you must write a method in the repository to return the container with the contents table joined.
Upvotes: 77