Completed
Push — master ( 2ef37c...52cad6 )
by Oleg
02:13
created

GetUsersAction   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 90
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 9

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
dl 0
loc 90
ccs 46
cts 46
cp 1
rs 10
c 0
b 0
f 0
wmc 9
lcom 1
cbo 9

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 9 1
B process() 0 44 4
A buildCriteria() 0 16 4
1
<?php
2
declare(strict_types=1);
3
4
namespace SlayerBirden\DataFlowServer\Domain\Controller;
5
6
use Doctrine\Common\Collections\Collection;
7
use Doctrine\Common\Collections\Criteria;
8
use Doctrine\ORM\EntityManagerInterface;
9
use Doctrine\ORM\ORMException;
10
use Psr\Http\Server\MiddlewareInterface;
11
use SlayerBirden\DataFlowServer\Domain\Entities\User;
12
use SlayerBirden\DataFlowServer\Notification\DangerMessage;
13
use Psr\Http\Message\ResponseInterface;
14
use Psr\Http\Message\ServerRequestInterface;
15
use Psr\Http\Server\RequestHandlerInterface;
16
use Psr\Log\LoggerInterface;
17
use Zend\Diactoros\Response\JsonResponse;
18
use Zend\Hydrator\ExtractionInterface;
19
20
class GetUsersAction implements MiddlewareInterface
21
{
22
    /**
23
     * @var EntityManagerInterface
24
     */
25
    private $entityManager;
26
    /**
27
     * @var LoggerInterface
28
     */
29
    private $logger;
30
    /**
31
     * @var ExtractionInterface
32
     */
33
    private $extraction;
34
35 6
    public function __construct(
36
        EntityManagerInterface $entityManager,
37
        LoggerInterface $logger,
38
        ExtractionInterface $extraction
39
    ) {
40 6
        $this->entityManager = $entityManager;
41 6
        $this->logger = $logger;
42 6
        $this->extraction = $extraction;
43 6
    }
44
45
    /**
46
     * @inheritdoc
47
     */
48 6
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
49
    {
50 6
        $data = $request->getQueryParams();
51 6
        $page = isset($data['p']) ? abs($data['p']) : null;
52 6
        $filters = $data['f'] ?? [];
53 6
        $sorting = $data['s'] ?? [];
54 6
        $success = false;
55 6
        $msg = '';
56 6
        $status = 200;
57
58
        try {
59 6
            $criteria = $this->buildCriteria($filters, $sorting, $page);
60
61
            /** @var Collection $users */
62 6
            $users = $this->entityManager
63 6
                ->getRepository(User::class)
64 6
                ->matching($criteria);
65
            // before collection load to count all records without pagination
66 6
            $count = $users->count();
67
68 5
            if ($count > 0) {
69 4
                $arrayUsers = array_map(function ($user) {
70 4
                    return $this->extraction->extract($user);
71 4
                }, $users->toArray());
72 4
                $success = true;
73
            } else {
74 1
                $msg = new DangerMessage('Could not find users using given conditions.');
75 1
                $status = 404;
76
            }
77 1
        } catch (ORMException $exception) {
78 1
            $this->logger->error((string)$exception);
79 1
            $msg = new DangerMessage('Could not fetch users.');
80 1
            $status = 400;
81
        }
82
83 6
        return new JsonResponse([
84 6
            'data' => [
85 6
                'users' => $arrayUsers ?? [],
86 6
                'count' => $count ?? 0,
87
            ],
88 6
            'success' => $success,
89 6
            'msg' => $msg,
90 6
        ], $status);
91
    }
92
93 6
    private function buildCriteria(array $filters = [], array $sorting = [], ?int $page, int $limit = 10): Criteria
0 ignored issues
show
Coding Style introduced by
Parameters which have default values should be placed at the end.

If you place a parameter with a default value before a parameter with a default value, the default value of the first parameter will never be used as it will always need to be passed anyway:

// $a must always be passed; it's default value is never used.
function someFunction($a = 5, $b) { }
Loading history...
94
    {
95 6
        $criteria = Criteria::create();
96 6
        if ($page !== null) {
97 1
            $criteria->setFirstResult(($page - 1) * $limit)
98 1
                ->setMaxResults($limit);
99
        }
100 6
        foreach ($filters as $key => $value) {
101 3
            $criteria->andWhere(Criteria::expr()->contains($key, $value));
102
        }
103 6
        if ($sorting) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $sorting of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
104 1
            $criteria->orderBy($sorting);
105
        }
106
107 6
        return $criteria;
108
    }
109
}
110