Completed
Push — master ( 3bc7c8...a199f7 )
by Oleg
03:54
created

GetUsersAction   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 80
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 9

Test Coverage

Coverage 97.22%

Importance

Changes 0
Metric Value
wmc 11
lcom 1
cbo 9
dl 0
loc 80
ccs 35
cts 36
cp 0.9722
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 9 1
A process() 0 30 5
A buildCriteria() 0 20 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 12
    public function __construct(
34
        Selectable $userRepository,
35
        LoggerInterface $logger,
36
        HydratorInterface $hydrator
37
    ) {
38 12
        $this->userRepository = $userRepository;
39 12
        $this->logger = $logger;
40 12
        $this->hydrator = $hydrator;
41 12
    }
42
43
    /**
44
     * @inheritdoc
45
     */
46 12
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
47
    {
48 12
        $data = $request->getQueryParams();
49 12
        $page = isset($data['p']) ? abs($data['p']) : 1;
50 12
        $limit = isset($data['l']) ? abs($data['l']) : 10;
51 12
        $filters = $data['f'] ?? [];
52 12
        $sorting = $data['s'] ?? [];
53
54
        try {
55 12
            $criteria = $this->buildCriteria($filters, $sorting, $page, $limit);
56
57 12
            $users = $this->userRepository->matching($criteria);
58
            // before collection load to count all records without pagination
59 12
            $count = $users->count();
60
61 10
            if ($count > 0) {
62
                $arrayUsers = array_map(function ($user) {
63 8
                    return $this->hydrator->extract($user);
64 8
                }, $users->toArray());
65 8
                return (new GeneralSuccessResponseFactory())('Success', 'users', $arrayUsers, 200, $count);
66
            } else {
67 2
                $msg = 'Could not find users using given conditions.';
68 2
                return (new GeneralErrorResponseFactory())($msg, 'users', 404, [], 0);
69
            }
70 2
        } catch (ORMException $exception) {
71 2
            $this->logger->error((string)$exception);
72 2
            $msg = 'There was an error while fetching users.';
73 2
            return (new GeneralErrorResponseFactory())($msg, 'users', 400, [], 0);
74
        }
75
    }
76
77 12
    private function buildCriteria(array $filters = [], array $sorting = [], int $page = 1, int $limit = 10): Criteria
78
    {
79 12
        $criteria = Criteria::create();
80 12
        $criteria->setFirstResult(($page - 1) * $limit)
81 12
            ->setMaxResults($limit);
82 12
        foreach ($filters as $key => $value) {
83 6
            if (is_string($value)) {
84 6
                $criteria->andWhere(Criteria::expr()->contains($key, $value));
85
            } else {
86
                $criteria->andWhere(Criteria::expr()->eq($key, $value));
87
            }
88
        }
89 12
        if (! empty($sorting)) {
90 2
            foreach ($sorting as $key => $dir) {
91 2
                $criteria->orderBy($sorting);
92
            }
93
        }
94
95 12
        return $criteria;
96
    }
97
}
98