Completed
Push — master ( 5c71f2...630401 )
by Oleg
07:36
created

GetUsersAction::process()   A

Complexity

Conditions 5
Paths 32

Size

Total Lines 30

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 19
CRAP Score 5

Importance

Changes 0
Metric Value
dl 0
loc 30
ccs 19
cts 19
cp 1
rs 9.1288
c 0
b 0
f 0
cc 5
nc 32
nop 2
crap 5
1
<?php
2
declare(strict_types=1);
3
4
namespace SlayerBirden\DataFlowServer\Domain\Controller;
5
6
use Doctrine\Common\Collections\Criteria;
7
use Doctrine\Common\Collections\Selectable;
8
use Doctrine\ORM\ORMException;
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
use Psr\Log\LoggerInterface;
14
use SlayerBirden\DataFlowServer\Stdlib\Validation\GeneralErrorResponseFactory;
15
use SlayerBirden\DataFlowServer\Stdlib\Validation\GeneralSuccessResponseFactory;
16
use Zend\Hydrator\HydratorInterface;
17
18
final class GetUsersAction implements MiddlewareInterface
19
{
20
    /**
21
     * @var LoggerInterface
22
     */
23
    private $logger;
24
    /**
25
     * @var HydratorInterface
26
     */
27
    private $hydrator;
28
    /**
29
     * @var Selectable
30
     */
31
    private $userRepository;
32
33 6
    public function __construct(
34
        Selectable $userRepository,
35
        LoggerInterface $logger,
36
        HydratorInterface $hydrator
37
    ) {
38 6
        $this->userRepository = $userRepository;
39 6
        $this->logger = $logger;
40 6
        $this->hydrator = $hydrator;
41 6
    }
42
43
    /**
44
     * @inheritdoc
45
     */
46 6
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
47
    {
48 6
        $data = $request->getQueryParams();
49 6
        $page = isset($data['p']) ? abs($data['p']) : 1;
50 6
        $limit = isset($data['l']) ? abs($data['l']) : 10;
51 6
        $filters = $data['f'] ?? [];
52 6
        $sorting = $data['s'] ?? [];
53
54
        try {
55 6
            $criteria = $this->buildCriteria($filters, $sorting, $page, $limit);
56
57 6
            $users = $this->userRepository->matching($criteria);
58
            // before collection load to count all records without pagination
59 6
            $count = $users->count();
60
61 5
            if ($count > 0) {
62
                $arrayUsers = array_map(function ($user) {
63 4
                    return $this->hydrator->extract($user);
64 4
                }, $users->toArray());
65 4
                return (new GeneralSuccessResponseFactory())('Success', 'users', $arrayUsers, 200, $count);
66
            } else {
67 1
                $msg = 'Could not find users using given conditions.';
68 1
                return (new GeneralErrorResponseFactory())($msg, 'users', 404, [], 0);
69
            }
70 1
        } catch (ORMException $exception) {
71 1
            $this->logger->error((string)$exception);
72 1
            $msg = 'There was an error while fetching users.';
73 1
            return (new GeneralErrorResponseFactory())($msg, 'users', 400, [], 0);
74
        }
75
    }
76
77 6
    private function buildCriteria(array $filters = [], array $sorting = [], int $page = 1, int $limit = 10): Criteria
78
    {
79 6
        $criteria = Criteria::create();
80 6
        $criteria->setFirstResult(($page - 1) * $limit)
81 6
            ->setMaxResults($limit);
82 6
        foreach ($filters as $key => $value) {
83 3
            if (is_string($value)) {
84 3
                $criteria->andWhere(Criteria::expr()->contains($key, $value));
85
            } else {
86
                $criteria->andWhere(Criteria::expr()->eq($key, $value));
87
            }
88
        }
89 6
        if (! empty($sorting)) {
90 1
            foreach ($sorting as $key => $dir) {
91 1
                $criteria->orderBy($sorting);
92
            }
93
        }
94
95 6
        return $criteria;
96
    }
97
}
98