ORM Pagination

Permalink 2 users found helpful
Hi,

Playing with Doctrine's ORM in C5.7.4.x. Works nice, like it

I've created an EntityRepository where I have some functions to get 'lists' of entities by some criteria. Also works fine. (it's like itemlists).
Now I'm trying to get pagination working, but the C5 Pagination works with ItemList (I also see an (empty) EntityItemList.

Are there any examples out there yet? Using ORM with pagination? (the ORM has an paginator).

Or should I use the PagerFanta directly?

SnefIT
 
A3020 replied on at Permalink Reply
A3020
Really good questions. It seems the core isn't using the ORM functionality yet. Also the EntityItemList class you're talking about seems unused:https://github.com/concrete5/concrete5/search?utf8=%E2%9C%93&q=E...

Have you gotten any further in the meanwhile?

I'm working on similar things, maybe you can share an example of a List class?
SnefIT replied on at Permalink Reply
SnefIT
I have puzzled a little bit.

I've created a base itemlist object that extends EntityItemList. It has the basic things in it.
When I need an entityitemlist, I extend the itemlist just created (for the basic things) and add things needed for that list.

I'm still experimenting and adjusting when needed ;)

The baseclass looks like:
<?php
namespace Concrete\Package\Blablabla\Src\Base;
defined('C5_EXECUTE') or die('Access Denied');
use Concrete\Core\Search\ItemList\EntityItemList;
use Concrete\Core\Search\Pagination\Pagination;
use Doctrine\ORM\QueryBuilder;
use Pagerfanta\Adapter\DoctrineORMAdapter;
class ItemList extends EntityItemList {
    protected $qb;
    public function __construct($entityManager = null) {
        // Set entity manager.
        if ($entityManager) {
            // Use given manager.
            $this->manager = $entityManager;
        } else {


The itemlist looks like:

<?php
namespace Concrete\Package\Blablabla\Src\Item;
defined('C5_EXECUTE') or die('Access Denied');
use Concrete\Package\Blablabla\Src\Base\ItemList as BaseItemList;
class ItemList extends BaseItemList {
    public function __construct($entityManager = null) {
        // Parental contruct.
        parent::__construct($entityManager);
        // Start building query.
        $this->qb->select('i')
            ->from('Concrete\Package\Blablabla\Src\Item\Item', 'i')
            ;
        // Setup automatic sorting.
        $this->setupAutomaticSorting();
    }


As already told... still experimenting with Doctrine ORM in C5. The entities are working fine, database tables are generated.
A3020 replied on at Permalink Reply
A3020
Nice! This is what I was looking for. I'm gonna implement it now and if I find something useful I'll share it here. Bedankt. ;)
SnefIT replied on at Permalink Reply
SnefIT
[dutch]
Graag gedaan!
[/dutch]

Don't forget to mark it as 'best answer' ;)
A3020 replied on at Permalink Reply
A3020
Chief, I can't mark it as best answer cause it's your own topic ;)
SnefIT replied on at Permalink Reply
SnefIT
you're right :')
A3020 replied on at Permalink Reply
A3020
What are you currently doing with the displayPaging function? Was it your plan to port that also to the BaseItemList? That depends on a lot more code from ItemList. (like getSummary, getTotal, etc.) and would result in a lot of duplicate code.
A3020 replied on at Permalink Reply
A3020
Hm this might be helpful: Concrete\Core\Search\Result\Result.php
SnefIT replied on at Permalink Reply
SnefIT
I created this itemlist for use in the pagination. If it was only for the list, then I would add some filtering in the custom entityrepository.

I use(d) it this way:

In the controller
// Create productlist.
$list = new ItemList();
// Do some filtering/ordering...
// $list->orderByName('asc');
// Max items per page.
$list->setItemsPerPage(25);
// Pagination
$pagination = $list->getPagination();
// Get items (for this page only).
$items = $pagination->getCurrentPageResults();
// Set variables.
$this->set('products', $products);
$this->set('pagination', $pagination);


in the view:
<div class="ccm-search-results-pagination">
<?php
if ($pagination->haveToPaginate()) {
    echo $pagination->renderDefaultView();
} 
?>
</div>
A3020 replied on at Permalink Reply
A3020
In 5.7.5 the method "createQuery" from EntityItemList also needs to be implemented.https://github.com/concrete5/concrete5/blob/develop/web/concrete/src...
blakeage replied on at Permalink Reply
blakeage
So this is what I've done, using an EntityItemList.

Say you have an entity called Appointment. You need to create an AppointmentEntityList class that extends ItemList, and fill out the abstract methods from ItemList, in that class.

Here is my AppointmentEntityList.php:
<?php
namespace Concrete\Package\Scheduler\Src\Scheduler;
defined('C5_EXECUTE') or die(_("Access Denied."));
use Concrete\Core\Search\ItemList\EntityItemList;
use Concrete\Core\Search\Pagination\Pagination;
use Package;
use Concrete\Core\Search\Result;
use Pagerfanta\Adapter\DoctrineORMAdapter;
class AppointmentEntityList extends EntityItemList
{
  public function createQuery() {
    $qb = $this->getEntityManager()->createQueryBuilder();
    $qb->addSelect("a FROM Concrete\Package\Scheduler\Src\Entity\Appointment a");
    $this->query = $qb;
  }


I'm not certain the sort code above works, as I haven't full implemented sorting yet. It was a first draft of the method.

In your controller, you'll do something like this:
$list = new AppointmentEntityList();
$list->createQuery();
$list->setItemsPerPage(Constants::$APPTS_PER_PAGE);
$pagination = $list->getPagination();
$appointments = $pagination->getCurrentPageResults();
$this->set('appointments', $appointments);
$this->set('pagination', $pagination);


In your view, you would loop over $appointments, as is an array of Appointment entities. And to display the pagination, it's just:
<div class="ccm-search-results-pagination">
  <?php
    if ($pagination->haveToPaginate()) {
      echo $pagination->renderDefaultView();
    }
  ?>
</div>