Issues (8)

src/Middleware/ApiCollectionPaginator.php (2 issues)

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Bone\BoneDoctrine\Middleware;
6
7
use Doctrine\ORM\EntityManagerInterface;
8
use Laminas\Diactoros\Response\JsonResponse;
0 ignored issues
show
The type Laminas\Diactoros\Response\JsonResponse was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
9
use Psr\Http\Message\ResponseInterface;
10
use Psr\Http\Message\ServerRequestInterface;
11
use Psr\Http\Server\MiddlewareInterface;
12
use Psr\Http\Server\RequestHandlerInterface;
13
14
abstract class ApiCollectionPaginator implements MiddlewareInterface
15
{
16
    public function __construct(
17
        private EntityManagerInterface $entityManager,
18
    ) {}
19
20
    abstract public function getEntityClass(): string;
21
    abstract public function getWhereCriteria(): array;
22
    abstract public function getOrderByCriteria(): array;
23
    abstract public function getRequestAttributeName(): string;
24
25
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
26
    {
27
        $params = $request->getQueryParams();
28
        $page = isset($params['page']) ? (int) $params['page'] : 1;
29
        $limit = isset($params['limit']) ? (int) $params['limit'] : 25;
30
        $offset = ($page *  $limit) - $limit;
31
        $entityClass = $this->getEntityClass();
32
        $whereCriteria = $this->getWhereCriteria();
33
        $orderByCriteria = $this->getWhereCriteria();
34
        $requestAttributeName = $this->getRequestAttributeName();
0 ignored issues
show
The assignment to $requestAttributeName is dead and can be removed.
Loading history...
35
        $entities = $this->entityManager->getRepository($entityClass)->findBy($whereCriteria, $orderByCriteria, $limit, $offset);
36
        $totalRecords = $this->entityManager->getRepository($entityClass)->count($whereCriteria);
37
        $totalPages = (int) ceil($totalRecords / $limit);
38
        $uri = $request->getUri();
39
40
        $hal = [
41
            '_links' => [
42
                'self' => [
43
                    'href' => $uri->getScheme() . '://' . $uri->getHost() . $uri->getPath(),
44
                ],
45
                'first' => [
46
                    'href' => $uri->getScheme() . '://' . $uri->getHost() . $uri->getPath(),
47
                ],
48
            ],
49
        ];
50
51
        if ($page !== 1) {
52
            $hal['_links']['prev'] = [
53
                'href' => $uri->getScheme() . '://' . $uri->getHost() . $uri->getPath() . '?page=' . ($page - 1),
54
            ];
55
        }
56
57
        if ($page !== $totalPages) {
58
            $hal['_links']['next'] = [
59
                'href' => $uri->getScheme() . '://' . $uri->getHost() . $uri->getPath() . '?page=' . ($page + 1),
60
            ];
61
        }
62
63
        $hal['_links']['last'] = [
64
            'href' => $uri->getScheme() . '://' . $uri->getHost() . $uri->getPath() . '?page=' . $totalPages,
65
        ];
66
67
        $hal['_embedded'] = [];
68
69
        foreach ($entities as $entity) {
70
            $hal['_embedded'][] = $entity->toArray();
71
        }
72
73
        $hal['totalPages'] = $totalPages;
74
        $hal['totalRecords'] = $totalRecords;
75
        /** @todo add _self links for entities in collection */
76
        foreach ($hal['_embedded'] as $key => $value) {
77
            $hal['_embedded'][$key]['_links'] = [
78
                'self' => [
79
                    'href' => $uri->getScheme() . '://' . $uri->getHost() . $uri->getPath() . '/' . $value['id'],
80
                ],
81
            ];
82
        }
83
84
        $response = new JsonResponse($hal);
85
        $response = $response->withHeader('Content-Type', 'application/hal+json');
86
87
        return $response;
88
    }
89
}
90