Hello everyone!

We have been investing plenty of personal time and energy for many years to share our knowledge with you all. However, we now need your help to keep this blog running. All you have to do is just click one of the adverts on the site, otherwise it will sadly be taken down due to hosting etc. costs. Thank you.

See the logic flow below to understand what this example does. Remember to register all the "yml" files in ApplicationBackendExtension.php file.


Logic flow



Install Knp Paginator Bundle


Install "knplabs/knp-paginator-bundle": "2.4.2" with composer and enable it in AppKernel.php by adding new Knp\Bundle\PaginatorBundle\KnpPaginatorBundle() into $bundles array.


Controller


namespace Application\BackendBundle\Controller;

use Application\BackendBundle\Service\UserServiceInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

/**
* @Route("user", service="application_backend.controller.user")
*/
class UserController extends Controller
{
private $userService;

public function __construct(UserServiceInterface $userService)
{
$this->userService = $userService;
}

/**
* @param Request $request
*
* @Route("")
* @Method({"GET"})
*
* @return Response
*/
public function listAction(Request $request)
{
$list = $this->userService->getList(
$request->query->get('page', 1),
$request->query->get('limit', 2)
);

return $this->createJsonResponse($list); # You might need to change this
}
}

Controllers.yml


services:
application_backend.controller.user:
class: Application\BackendBundle\Controller\UserController
arguments:
- @application_backend.service.user

User Service


namespace Application\BackendBundle\Service;

interface UserServiceInterface
{
/**
* @param integer $page
* @param integer $limit
*
* @return mixed
*/
public function getList($page, $limit);
}

namespace Application\BackendBundle\Service;

use Application\BackendBundle\Entity\User;
use Application\BackendBundle\Factory\UserModelFactoryInterface;
use Application\BackendBundle\Model\User\Result;
use Application\BackendBundle\Repository\UserRepository;
use Knp\Component\Pager\Pagination\PaginationInterface;

class UserService implements UserServiceInterface
{
private $userRepository;
private $paginator;
private $userModelFactory;

public function __construct(
UserRepository $userRepository,
PaginatorInterface $paginator,
UserModelFactoryInterface $userModelFactory
) {
$this->userRepository = $userRepository;
$this->paginator = $paginator;
$this->userModelFactory = $userModelFactory;
}

public function getList($page = 1, $limit = 10)
{
$queryResult = $this->userRepository->getList($page, $limit);

$pagination = $this->paginator->paginate($queryResult, $page, $limit);

return
$this->createUserListResult(
$pagination->getItems(),
$page,
$limit,
$pagination->getTotalItemCount()
);
}

/**
* @param User[] $users
* @param int $page
* @param int $limit
* @param int $total
*
* @return Result
*/
private function createUserListResult($users, $page = null, $limit = null, $total = null)
{
return $this->userModelFactory->createUserListResult($users, $page, $limit, $total);
}
}

Service.yml


You don't have to create an additional service for pagination. Instead, you can simply pass @knp_paginator as parameter to the UserService. It uses use Knp\Component\Pager\Paginator class. As a result you would get rid of Pagination services we created below.


services:
application_backend.service.user:
class: Application\BackendBundle\Service\UserService
arguments:
- @application_backend.repository.user # Repository service
- @application_backend.service.paginator # Paginator service
- @application_backend.factory.user # Factory service

application_backend.service.paginator:
class: Application\BackendBundle\Service\Paginator
tags:
- {name:knp_paginator.injectable, paginator:knp_paginator} # Compulsory

Pagination service


namespace Application\BackendBundle\Service;

use Knp\Component\Pager\Pagination\PaginationInterface;

interface PaginatorInterface
{
/**
* @param mixed $query
* @param integer $page
* @param integer $limit
*
* @return PaginationInterface
*/
public function paginate($query, $page, $limit);
}

namespace Application\BackendBundle\Service;

use Knp\Bundle\PaginatorBundle\Definition\PaginatorAware;
use Knp\Component\Pager\Pagination\PaginationInterface;

class Paginator extends PaginatorAware implements PaginatorInterface
{
/**
* @param mixed $query
* @param integer $page
* @param integer $limit
*
* @return PaginationInterface
*/
public function paginate($query, $page, $limit)
{
$paginator = $this->getPaginator();

return $paginator->paginate($query, $page, $limit, ['distinct' => false]);
}
}

User entity


namespace Application\BackendBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;

/**
* @ORM\Entity(repositoryClass="Application\BackendBundle\Repository\UserRepository")
* @ORM\Table(name="user")
* @UniqueEntity(fields="username", message="Username is already in use.")
*/
class User
{
/**
* @var int
*
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;

/**
* @var string
*
* @ORM\Column(name="username", type="string", length=20, unique=true)
*/
protected $username;

/**
* @var string
*
* @ORM\Column(name="password", type="string", length=40)
*/
protected $password;

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

/**
* Set username
*
* @param string $username
* @return User
*/
public function setUsername($username)
{
$this->username = $username;

return $this;
}

/**
* Get username
*
* @return string
*/
public function getUsername()
{
return $this->username;
}

/**
* Set password
*
* @param string $password
* @return User
*/
public function setPassword($password)
{
$this->password = $password;

return $this;
}

/**
* Get password
*
* @return string
*/
public function getPassword()
{
return $this->password;
}
}

User repository


namespace Application\BackendBundle\Repository;

use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\Query;

class UserRepository extends EntityRepository
{
public function getList()
{
return
$this
->createQueryBuilder('u')
->orderBy('u.id', 'ASC')
->getQuery(Query::HYDRATE_SCALAR);
}
}

Repositories.yml


services:
application_backend.repository.user:
class: Application\BackendBundle\Repository\UserRepository # Your repository class
factory: [@doctrine.orm.entity_manager, getRepository] # Compulsory
arguments: [Application\BackendBundle\Entity\User] # Your actual entity class

Model classes


User.php


namespace Application\BackendBundle\Model\User;

class User
{
/**
* @var int
*/
public $id;

/**
* @var string
*/
public $username;

/**
* @var string
*/
public $password;
}

Result.php


namespace Application\BackendBundle\Model\User;

class Result
{
/**
* @var User[]
*/
public $users = [];

/**
* @var int
*/
public $page;

/**
* @var int
*/
public $limit;

/**
* @var int
*/
public $total;
}

Model factory


namespace Application\BackendBundle\Factory;

use Application\BackendBundle\Model\User\Result;

interface UserModelFactoryInterface
{
/**
* @param array $users
* @param null|int $page
* @param null|int $limit
* @param null|int $total
*
* @return Result
*/
public function createUserListResult(array $users, $page = null, $limit = null, $total = null);
}

namespace Application\BackendBundle\Factory;

use Application\BackendBundle\Entity\User;
use Application\BackendBundle\Model\User\Result as UserResult;
use Application\BackendBundle\Model\User\User as UserModel;

class UserModelFactory implements UserModelFactoryInterface
{
public function createUserListResult(array $users, $page = null, $limit = null, $total = null)
{
$result = new UserResult();
$result->page = $page;
$result->limit = $limit;
$result->users = [];
$result->total = $total;

foreach ($users as $user) {
$result->users[] = $this->createUser($user);
}

return $result;
}

/**
* @param User $user
*
* @return UserModel
*/
private function createUser(User $user)
{
$model = new UserModel();
$model->id = $user->getId();
$model->username = $user->getUsername();
$model->password = $user->getPassword();

Return $model;
}
}

Factories.yml


services:
application_backend.factory.user:
class: Application\BackendBundle\Factory\UserModelFactory

Test


Call to http://football.local/app_dev.php/backend/user?page=2&limit=3 url, will produce result below.


{
"users": [
{
"id": 4,
"username": "andygarcia",
"password": "09cd68a2a77b22a312dded612dd0d9988685189f"
},
{
"id": 5,
"username": "joepesci",
"password": "09cd68a2a77b22a312dded612dd0d9988685189f"
},
{
"id": 6,
"username": "rayliotta",
"password": "09cd68a2a77b22a312dded612dd0d9988685189f"
}
],
"page": "2",
"limit": "3",
"total": 6
}