KnpPaginatorBundle icon indicating copy to clipboard operation
KnpPaginatorBundle copied to clipboard

Unexcpected behavior: Empty pagination items for array target

Open iggyster opened this issue 6 years ago • 23 comments

Workflow: Homestead: v6.2.2 Symfony: 3.4 KnpPaginatorBundle: 2.6

Controller method:

...
/** @var Paginator $paginator */

$search = $request->query->get('q');
$page = $request->query->get('page', 1);
$limit = 12;
$offset = ($page - 1) * $limit;
$max = $search ? $this->getMaxItems($search) : 0;
$results = $search ? $this->getSearchResult($search, $offset, $limit) : [];

dump($results);

$paginator = $this->get('knp_paginator');
$pagination = $paginator->paginate($results, $page, $limit);
$pagination->setTotalItemCount($max);
$pagination->setCurrentPageNumber($page);

dump($pagination);
exit();

return [
    'results' => $pagination,
    'keyWord' => $search,
];
...

For the 1st page request: /search?q=a&page=1 everything works well. But for the second one: /search?q=a&page=2 it's failed, because items is empty in the SlidingPagination instance which is stored in $pagination.

Here are dump results for the $results & $pagination variables:

SearchController.php on line 49:
array:12 [▼
  0 => array:110 [▶]
  1 => array:110 [▶]
  2 => array:110 [▶]
  3 => array:110 [▶]
  4 => array:110 [▶]
  5 => array:110 [▶]
  6 => array:110 [▶]
  7 => array:110 [▶]
  8 => array:110 [▶]
  9 => array:110 [▶]
  10 => array:110 [▶]
  11 => array:110 [▶]
]
SearchController.php on line 54:
SlidingPagination {#4223 ▼
  -route: "search"
  -params: array:2 [▼
    "q" => "a"
    "page" => "2"
  ]
  -pageRange: 3
  -template: "partials/pagination/sliding.html.twig"
  -sortableTemplate: "partials/pagination/sortable.html.twig"
  -filtrationTemplate: "KnpPaginatorBundle:Pagination:filtration.html.twig"
  #currentPageNumber: "2"
  #numItemsPerPage: 12
  #items: []
  #totalCount: 85
  #paginatorOptions: array:6 [▼
    "pageParameterName" => "page"
    "sortFieldParameterName" => "sort"
    "sortDirectionParameterName" => "direction"
    "filterFieldParameterName" => "filterField"
    "filterValueParameterName" => "filterValue"
    "distinct" => true
  ]
  #customParameters: []
}

Seems like something went wrong

iggyster avatar Mar 30 '18 08:03 iggyster

Any Help please !!!

mohamedwajih avatar Apr 03 '18 21:04 mohamedwajih

Hello, was it working before? I think searching in array is not yet implemented in the bundle.

polc avatar Apr 04 '18 08:04 polc

It's working now, i haven't data in my database Thank you

Le mer. 4 avr. 2018 à 09:14, Paul Le Corre [email protected] a écrit :

Hello, was it working before? I think searching in array is not yet implemented in the bundle.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/KnpLabs/KnpPaginatorBundle/issues/480#issuecomment-378518298, or mute the thread https://github.com/notifications/unsubscribe-auth/AicXKqj3t4Qi_UXz4qY9nnIUzb7lx8yPks5tlIDTgaJpZM4TBcKU .

mohamedwajih avatar Apr 04 '18 16:04 mohamedwajih

@polc The issue is not about search feature at all it's about the pagination of array target. Right now pagination works with Query target, but if you put an array it will fail for the example below.

iggyster avatar Apr 05 '18 11:04 iggyster

okay, could you give me your version of knp-components? And could you tell me if it's a regression or if it has never worked?

I tested a bit lately and it was working fine on my side :/

polc avatar Apr 05 '18 11:04 polc

@polc I've made some investigation and figure out that the issue comes from Knp/Component/Pager/Paginator.php in method paginate in line 132. Look at it:

public function paginate($target, $page = 1, $limit = 10, array $options = array())
{
    ...
    $paginationView->setItems($itemsEvent->items);
    // after
    $afterEvent = new Event\AfterEvent($paginationView);
    $this->eventDispatcher->dispatch('knp_pager.after', $afterEvent);
    return $paginationView;
}

If you place

$paginationView->setItems($itemsEvent->target)

instead of

$paginationView->setItems($itemsEvent->items);

everything will work for array target, but it failes for Query target.

Will this help to solve an issue?

iggyster avatar Apr 05 '18 11:04 iggyster

I'll take a look later, could you give me the result of this command : composer info knplabs/knp-components ?

polc avatar Apr 05 '18 11:04 polc

okay, could you give me your version of knp-components?

Version of knp-components is: 1.3.5

And could you tell me if it's a regression or if it has never worked?

It works well with Query. But for me it fails with array target. Seems, like it's a regression

iggyster avatar Apr 05 '18 11:04 iggyster

maybe try a composer update knplabs/knp-paginator-bundle ?

polc avatar Apr 05 '18 12:04 polc

@polc

I'll take a look later, could you give me the result of this command : composer info knplabs/knp-components ?

vagrant@local:/var/www/local$ php composer.phar info knplabs/knp-components
name : knplabs/knp-components 
descrip. : Knplabs component library 
keywords : components, knp, knplabs, pager, paginator 
versions : * 1.3.5 
type : library 
license : MIT License (MIT) (OSI approved) https://spdx.org/licenses/MIT.html#licenseText 
source : [git] https://github.com/KnpLabs/knp-components.git a03bbd87ecf9e56db6f7533db2c63d6da6cd5f33 
dist : [zip] https://api.github.com/repos/KnpLabs/knp-components/zipball/a03bbd87ecf9e56db6f7533db2c63d6da6cd5f33 a03bbd87ecf9e56db6f7533db2c63d6da6cd5f33 
names : knplabs/knp-components

autoload 
psr-0 
Knp\Component => src 

requires 
php >=5.3.2
 
requires (dev) 
doctrine/mongodb-odm ~1.0@beta 
doctrine/orm ~2.4 
doctrine/phpcr-odm ~1.2 
jackalope/jackalope-doctrine-dbal ~1.2 
phpunit/phpunit ~4.2 
ruflin/elastica ~1.0 
symfony/event-dispatcher ~2.5 
symfony/property-access >=2.3 

suggests 
doctrine/common to allow usage pagination with Doctrine ArrayCollection 
doctrine/mongodb-odm to allow usage pagination with Doctrine ODM MongoDB 
doctrine/orm to allow usage pagination with Doctrine ORM 
doctrine/phpcr-odm to allow usage pagination with Doctrine ODM PHPCR 
propel/propel1 to allow usage pagination with Propel ORM 
ruflin/Elastica to allow usage pagination with ElasticSearch Client 
solarium/solarium to allow usage pagination with Solarium Client 
symfony/property-access To allow sorting arrays

maybe try a composer update knplabs/knp-paginator-bundle ?

It didn't help.

iggyster avatar Apr 05 '18 12:04 iggyster

I have a problem with the number of items and totalCount

 $repo = $this->getDoctrine()->getRepository(MyEntity::class);
 $resQuery = $repo->findAll();

 $paginator = $this->get('knp_paginator');
 $pagination = $paginator->paginate($resQuery,  $request->query->getInt('page', 1), 12);
 dump($pagination);
SlidingPagination {#4151 ▼
  -route: "spp"
  -params: array: []
  -pageRange: 3
  -template: "/partials/pagination/template.html.twig"
  -sortableTemplate: "/partials/pagination/sortable.html.twig"
  -filtrationTemplate: "KnpPaginatorBundle:Pagination:filtration.html.twig"
  #currentPageNumber: 1
  #numItemsPerPage: 12
  #items: array:18 [▼
    0 => array:8 [▶]
    1 => array:8 [▶]
    2 => array:8 [▶]
    3 => array:8 [▶]
    4 => array:8 [▶]
    5 => array:8 [▶]
    6 => array:8 [▶]
    7 => array:8 [▶]
    8 => array:8 [▶]
    9 => array:8 [▶]
    10 => array:8 [▶]
    11 => array:8 [▶]
    12 => array:8 [▶]
    13 => array:8 [▶]
    14 => array:8 [▶]
    15 => array:8 [▶]
    16 => array:8 [▶]
    17 => array:8 [▶]
  ]
  #totalCount: 23
  #paginatorOptions: array:6 [▼
    "pageParameterName" => "page"
    "sortFieldParameterName" => "sort"
    "sortDirectionParameterName" => "direction"
    "filterFieldParameterName" => "filterField"
    "filterValueParameterName" => "filterValue"
    "distinct" => true
  ]
  #customParameters: []
}

totalCount: 23 In database count - 19

Version of knp-components is: 1.3.5

vagrant@max :/www/max$ php composer.phar info knplabs/knp-components
name     : knplabs/knp-components
descrip. : Knplabs component library
keywords : components, knp, knplabs, pager, paginator
versions : * 1.3.5
type     : library
license  : MIT License (MIT) (OSI approved) https://spdx.org/licenses/MIT.html#licenseText
source   : [git] https://github.com/KnpLabs/knp-components.git a03bbd87ecf9e56db6f7533db2c63d6da6cd5f33
dist     : [zip] https://api.github.com/repos/KnpLabs/knp-components/zipball/a03bbd87ecf9e56db6f7533db2c63d6da6cd5f33 a03bbd87ecf9e56db6f7533db2c63d6da6cd5f33
names    : knplabs/knp-components

autoload
psr-0
Knp\Component => src

requires
php >=5.3.2

requires (dev)
doctrine/mongodb-odm ~1.0@beta
doctrine/orm ~2.4
doctrine/phpcr-odm ~1.2
jackalope/jackalope-doctrine-dbal ~1.2
phpunit/phpunit ~4.2
ruflin/elastica ~1.0
symfony/event-dispatcher ~2.5
symfony/property-access >=2.3

suggests
doctrine/common to allow usage pagination with Doctrine ArrayCollection
doctrine/mongodb-odm to allow usage pagination with Doctrine ODM MongoDB
doctrine/orm to allow usage pagination with Doctrine ORM
doctrine/phpcr-odm to allow usage pagination with Doctrine ODM PHPCR
propel/propel1 to allow usage pagination with Propel ORM
ruflin/Elastica to allow usage pagination with ElasticSearch Client
solarium/solarium to allow usage pagination with Solarium Client
symfony/property-access To allow sorting arrays

u7ter avatar Apr 28 '18 10:04 u7ter

Hey I am facing same problem as @iggyster. Paginator items are empty when paginating array and page is not equal 1.

Symfony 3.3.17, Knp Paginator 2.8.0, I also tried older versions same problem there.

Problem seems to be here.

mssimi avatar Jun 20 '18 07:06 mssimi

Currently having this problem.

$pagination = $paginator->paginate($query->getResult(), $request->query->getInt(‘page’, 1), 50);

The above code works ^ If I pass it just the $query then the SlidingPagination objects comes back with zero items.

lukejsimonetti avatar Jan 15 '19 16:01 lukejsimonetti

Hi there, i have the same issue with an array.

    $page = $request->query->get('page', 1);
        $response = $this->serviceClient->getSomeElements($searchData, $page);
        $maxElements = $response->getPage()->getTotalElements();
        $elementList = $response->getResultList(SomeModel::class);

        $paginator = $this->paginator->paginate(
            $elementList,
            $page,
            10// limit per page
        );
        $paginator->setTotalItemCount($maxElements);

For the 1st page everything works well. But for the second one it shows an empty table,

If i set $page in $paginator to 1. It shows the Items but, the navigation is broken.

knp-paginator-bundle: "v3.0.0", php: "7.2" Symfony: "4.0"

shwosh avatar Apr 02 '19 17:04 shwosh

Hi there, i have the same issue with an array.

[....] $paginator = $this->paginator->paginate( $elementList, $page, 10// limit per page ); $paginator->setTotalItemCount($maxElements); [....]

This problem can be solved by using the Items setter.

         $paginator = $this->paginator->paginate(
             [],
             $page,
             10// limit per page
         );
         $paginator->setTotalItemCount($maxElements);
         /** @var array $elementList */
         $paginator->setItems($elementList);

It is kind of a workaround but solves the issue and the pagination works as expected.

BeyerJC avatar Apr 03 '19 08:04 BeyerJC

I can't find any problem in paginating arrays with latest bundle/library versions. Can you confirm that?

garak avatar Jul 21 '19 17:07 garak

The issue still exists for me. If i dont set the items with $paginator->setItems($data) every page except the first is empty.

"name": "knplabs/knp-paginator-bundle","version": "v4.0.0", "name": "knplabs/knp-components", "version": "v2.1.0",

BeyerJC avatar Jul 22 '19 14:07 BeyerJC

I'm trying to reproduce, no luck. This is my code (just a Symfony default project where I added KnpPaginatorBundle):

<?php

namespace App\Controller;

use Knp\Component\Pager\PaginatorInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;

final class DefaultController extends AbstractController
{
    /** 
     * @Route("/default", name="default")
     */
    public function index(PaginatorInterface $paginator, Request $request)
    {   
        $pagination = $paginator->paginate(range(1, 99), $request->query->getInt('page', 1));

        return $this->render('default/index.html.twig', [
            'pagination' => $pagination,
        ]);
    }   
}

template

{% extends 'base.html.twig' %}

{% block body %}
    <ul>
        {% for item in pagination %}
            <li>{{ item }}</li>
        {% endfor %}
    </ul>
    {{ knp_pagination_render(pagination) }}
{% endblock %}

garak avatar Jul 22 '19 16:07 garak

Para que funcione con un array el page en $paginator->paginate($data, $page, $limit) debe ser siempre igual a 1 $page = 1, y el page de $pagination->setCurrentPageNumber($page); debe tener el numero de la pagina actual. Esto es porque knp_paginator intente realizar la búsqueda en la siguiente pagina, debido a que los resultados ya se encuentran filtrados.

$search = $request->query->get('q');
$page = $request->query->get('page', 1);
$limit = 12;
$offset = ($page - 1) * $limit;
$max = $search ? $this->getMaxItems($search) : 0;
$results = $search ? $this->getSearchResult($search, $offset, $limit) : [];

$paginator = $this->get('knp_paginator');
$pagination = $paginator->paginate($results, 1, $limit);
$pagination->setTotalItemCount($max);
$pagination->setCurrentPageNumber($page);

javierjaraya avatar Dec 27 '21 21:12 javierjaraya

If no one is able to provide a way to reproduce the problem, the issue will be closed. Thank you.

garak avatar Dec 28 '21 07:12 garak

I have exactly the same problem. If I set the $limit in ->paginate() with an array as $target, the items are not loaded for any pages above 1.

richard-bridgeman avatar Jun 30 '22 13:06 richard-bridgeman

@richard-bridgeman again, can you provide a way to reproduce it?

garak avatar Jul 03 '22 09:07 garak

@richard-bridgeman again, can you provide a way to reproduce it?

Will try to create a reproducible example. Please give me some time

iggyster avatar Jul 04 '22 12:07 iggyster

I recently encountered this and did not do any debugging but, as a work around:

class PaginateSubscriber implements EventSubscriberInterface
{
    private $items = [];

    public function getItems(ItemsEvent $event): ItemsEvent
    {
        $this->items = $event->target;
        return $event;
    }

    public function setItems(AfterEvent $event): AfterEvent
    {
        $event->getPaginationView()->setItems($this->items);
        return $event;
    }

    public static function getSubscribedEvents()
    {
        return [
            'knp_pager.items' => ['getItems'],
            'knp_pager.after' => ['setItems']
        ];
    }
}

SchillerPaul avatar Jan 20 '23 13:01 SchillerPaul

I'm closing this for missing feedback. Feel free to open a new issue if needed.

garak avatar Jan 21 '23 08:01 garak