Completed
Push — master ( 3eb757...3bc7c8 )
by Oleg
03:46
created

GetUsersAction::process()   B

Complexity

Conditions 6
Paths 56

Size

Total Lines 33

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 19
CRAP Score 6.0913

Importance

Changes 0
Metric Value
dl 0
loc 33
ccs 19
cts 22
cp 0.8636
rs 8.7697
c 0
b 0
f 0
cc 6
nc 56
nop 2
crap 6.0913
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
        } catch (\Exception $exception) {
75
            $this->logger->error((string)$exception);
76
            return (new GeneralErrorResponseFactory())('Internal error', 'users', 500, [], 0);
77
        }
78
    }
79
80 12
    private function buildCriteria(array $filters = [], array $sorting = [], int $page = 1, int $limit = 10): Criteria
81
    {
82 12
        $criteria = Criteria::create();
83 12
        $criteria->setFirstResult(($page - 1) * $limit)
84 12
            ->setMaxResults($limit);
85 12
        foreach ($filters as $key => $value) {
86 6
            if (is_string($value)) {
87 6
                $criteria->andWhere(Criteria::expr()->contains($key, $value));
88
            } else {
89
                $criteria->andWhere(Criteria::expr()->eq($key, $value));
90
            }
91
        }
92 12
        if (! empty($sorting)) {
93 2
            foreach ($sorting as $key => $dir) {
94 2
                $criteria->orderBy($sorting);
95
            }
96
        }
97
98 12
        return $criteria;
99
    }
100
}
101