Пагинация PagerFanta Symfony4 - PullRequest
0 голосов
/ 04 мая 2018

Я делаю API с Symfony4 и Я использую комплект PagerFanta. Я создал абстрактный класс AbstractRepository для своей нумерации страниц:

<?php

namespace App\Repository;

use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\QueryBuilder;
use Pagerfanta\Adapter\DoctrineORMAdapter;
use Pagerfanta\Pagerfanta;

class AbstractRepository extends EntityRepository
{
    protected function paginate(QueryBuilder $qb, $limit = 20, $offset = 0)
    {
        if (0 == $limit || 0 == $offset) {
            throw new \LogicException('$limit & $offstet must be greater 

than 0.');
            }

            $pager = new Pagerfanta(new DoctrineORMAdapter($qb));
            $currentPage = ceil($offset + 1) / $limit;
            $pager->setCurrentPage($currentPage);
            $pager->setMaxPerPage((int)$limit);

            return $pager;
        }
    }

My Entity Article:

    <?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use JMS\Serializer\Annotation\Expose;
use JMS\Serializer\Annotation\ExclusionPolicy;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * Class Article
 * @ORM\Entity(repositoryClass="App\Repository\ArticleRepository")
 * @ORM\Table(name="article")
 *
 * @ExclusionPolicy("all")
 */
class Article
{
    /**
     * @ORM\Id()
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue()
     *
     * @Expose()
     */
    private $id;

    /**
     * @ORM\Column(type="string")
     * @Assert\NotBlank(groups={"Create"})
     * @Expose()
     */
    private $title;

    /**
     * @ORM\Column(type="string")
     * @Assert\NotBlank(groups={"Create"})
     * @Expose()
     */
    private $content;

    /**
     * @return mixed
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * @param mixed $id
     */
    public function setId($id): void
    {
        $this->id = $id;
    }

    /**
     * @return mixed
     */
    public function getTitle()
    {
        return $this->title;
    }

    /**
     * @param mixed $title
     */
    public function setTitle($title): void
    {
        $this->title = $title;
    }

    /**
     * @return mixed
     */
    public function getContent()
    {
        return $this->content;
    }

    /**
     * @param mixed $content
     */
    public function setContent($content): void
    {
        $this->content = $content;
    }
}

Я тестировал переменную var_dump $ qb, но я не получаю элементы, Мой ArticleRepository:

<?php

namespace App\Repository;

class ArticleRepository extends AbstractRepository
{
    public function search($term, $order = 'asc', $limit = 20, $offset = 0)
    {
        $qb = $this
            ->createQueryBuilder('a')
            ->select('a')
            ->orderBy('a.title', $order);

        if ($term) {
            $qb
                ->where('a.title LIKE ?1')
                ->setParameter(1, '%'.$term.'%');
        }

        return $this->paginate($qb, $limit, $offset);
    }
}

Мой ArticleController:

<?php

namespace App\Controller;

use App\Entity\Article;
use FOS\RestBundle\Controller\Annotations as Rest;
use FOS\RestBundle\Controller\FOSRestController;
use FOS\RestBundle\Request\ParamFetcherInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use App\Representation\Articles;
use Symfony\Component\Validator\ConstraintViolationList;

class ArticleController extends FOSRestController
{
    /**
     * @Rest\Get(
     *     path = "/articles/{id}",
     *     name = "app_article_show",
     *     requirements = {"id"="\d+"}
     * )
     * @Rest\View()
     */
    public function showAction(Article $article)
    {
        return $article;
    }

    /**
     * @Rest\Post(
     *     path = "/articles",
     *     name= "app_article_show",
     *  )
     * @Rest\View(StatusCode= 201)
     * @ParamConverter(
     *     "article", converter="fos_rest.request_body",
     *     options={
                "validator"={ "groups"="Create"}
     *     }
     * )
     */
    public function createAction(Article $article, ConstraintViolationList $violations)
    {
        if (count($violations)) {
            return $this->view($violations, Response::HTTP_BAD_REQUEST);
        }

        $em = $this->getDoctrine()->getManager();

        $em->persist($article);
        $em->flush();

        return $this->view(
            $article,
            Response::HTTP_CREATED,
            [
                'Location' => $this->generateUrl('app_article_show', ['id', $article->getId()], UrlGeneratorInterface::ABSOLUTE_URL)
            ]
        );
    }

    /**
     * @Rest\Get(
     *     path="/articles",
     *     name="app_article_list"
     * )
     * @Rest\QueryParam(
     *     name="keyword",
     *     requirements="[a-zA-Z0-9]",
     *     nullable=true,
     *     description="The keyword to search for."
     * )
     * @Rest\QueryParam(
     *     name="order",
     *     requirements="asc|desc",
     *     default="asc",
     *     description="Sort order (asc or desc)"
     * )
     * @Rest\QueryParam(
     *     name="limit",
     *     requirements="\d+",
     *     default="15",
     *     description="Max number of movies per page."
     * )
     * @Rest\QueryParam(
     *     name="offset",
     *     requirements="\d+",
     *     default="0",
     *     description="The pagination offset"
     * )
     * @Rest\View()
     */
    public function listAction(ParamFetcherInterface $paramFetcher)
    {
        $pager = $this->getDoctrine()->getRepository('App:Article')->search(
            $paramFetcher->get('keyword'),
            $paramFetcher->get('order'),
            $paramFetcher->get('limit'),
            $paramFetcher->get('offset')
        );

        return new Articles($pager);
    }
}

Мои статьи в представительстве:

<?php

namespace App\Representation;

use Pagerfanta\Pagerfanta;
use JMS\Serializer\Annotation\Type;

class Articles
{
    /**
     * @Type("ArrayCollection<App\Entity\Article>")
     */
    public $data;

    public $meta;

    public function __construct(Pagerfanta $data)
    {
        $this->data = $data->getCurrentPageResults();

        $this->addMeta('limit', $data->getMaxPerPage());
        $this->addMeta('current_items', count($data->getCurrentPageResults()));
        $this->addMeta('total_items', $data->getNbResults());
        $this->addMeta('offset', $data->getCurrentPageOffsetStart());
    }

    public function addMeta($name, $value)
    {
        if (isset($this->meta[$name])) {
            throw new \LogicException(sprintf('This meta already exists. You are trying to override this meta, use the setMeta method instead for the %s meta.', $name));
        }

        $this->setMeta($name, $value);
    }

    public function setMeta($name, $value)
    {
        $this->meta[$name] = $value;
    }
}

И это ошибка, которая возвращает мне почтальона:

Ошибка почтальона

Когда я помещаю var_dump в репозиторий, я уже не восстанавливаю статьи, но не понимаю, почему

Спасибо за помощь.

1 Ответ

0 голосов
/ 04 мая 2018

Я вижу, что моя проблема в AbstractRepository заменяет

$currentPage = ceil($offset + 1) / $limit;

за:

$currentPage = ceil(($offset + 1) / $limit);

И мой ArticleController заменяет

* @Rest\QueryParam(
 *     name="offset",
 *     requirements="\d+",
 *     default="0",
 *     description="The pagination offset"
 * )
 * @Rest\View()
 */

в

* @Rest\QueryParam(
 *     name="offset",
 *     requirements="\d+",
 *     default="1",
 *     description="The pagination offset"
 * )
 * @Rest\View()
 */

Спасибо

...