Completed
Push — develop ( a2ba3f...6fbee4 )
by Tino
07:18
created

Rate::executePost()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 19
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 12
nc 2
nop 1
dl 0
loc 19
rs 9.8666
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Copyright (c) by the ACP3 Developers.
5
 * See the LICENSE file at the top-level module directory for licensing details.
6
 */
7
8
namespace ACP3\Modules\ACP3\Share\Controller\Frontend\Index;
9
10
use ACP3\Core\Controller\AbstractFrontendAction;
11
use ACP3\Core\Controller\Context\FrontendContext;
12
use ACP3\Modules\ACP3\Share\Model\Repository\ShareRatingsRepository;
13
use ACP3\Modules\ACP3\Share\Model\Repository\ShareRepository;
14
use ACP3\Modules\ACP3\Share\Model\ShareRatingModel;
15
16
class Rate extends AbstractFrontendAction
17
{
18
    /**
19
     * @var \ACP3\Modules\ACP3\Share\Model\Repository\ShareRepository
20
     */
21
    private $shareRepository;
22
    /**
23
     * @var \ACP3\Modules\ACP3\Share\Model\Repository\ShareRatingsRepository
24
     */
25
    private $shareRatingsRepository;
26
    /**
27
     * @var \ACP3\Modules\ACP3\Share\Model\ShareRatingModel
28
     */
29
    private $shareRatingModel;
30
    /**
31
     * @var bool|null
32
     */
33
    private $alredyRated;
34
35
    /**
36
     * Rate constructor.
37
     *
38
     * @param \ACP3\Core\Controller\Context\FrontendContext                    $context
39
     * @param \ACP3\Modules\ACP3\Share\Model\Repository\ShareRepository        $shareRepository
40
     * @param \ACP3\Modules\ACP3\Share\Model\Repository\ShareRatingsRepository $shareRatingsRepository
41
     * @param \ACP3\Modules\ACP3\Share\Model\ShareRatingModel                  $shareRatingModel
42
     */
43
    public function __construct(
44
        FrontendContext $context,
45
        ShareRepository $shareRepository,
46
        ShareRatingsRepository $shareRatingsRepository,
47
        ShareRatingModel $shareRatingModel)
48
    {
49
        parent::__construct($context);
50
51
        $this->shareRepository = $shareRepository;
52
        $this->shareRatingsRepository = $shareRatingsRepository;
53
        $this->shareRatingModel = $shareRatingModel;
54
    }
55
56
    /**
57
     * @param int $id
58
     *
59
     * @return array
60
     *
61
     * @throws \Doctrine\DBAL\DBALException
62
     */
63
    public function executePost(int $id): array
64
    {
65
        $stars = (int) $this->request->getPost()->get('stars', 0);
66
        $ipAddress = $this->request->getSymfonyRequest()->getClientIp();
67
68
        if ($this->canSaveRating($id, $stars, $ipAddress) === true) {
0 ignored issues
show
Bug introduced by Tino Goratsch
It seems like $ipAddress can also be of type null; however, parameter $ipAddress of ACP3\Modules\ACP3\Share\...x\Rate::canSaveRating() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

68
        if ($this->canSaveRating($id, $stars, /** @scrutinizer ignore-type */ $ipAddress) === true) {
Loading history...
69
            $this->shareRatingModel->save([
70
                'share_id' => $id,
71
                'stars' => $stars,
72
                'ip' => $ipAddress,
73
            ]);
74
        }
75
76
        return [
77
            'rating' => \array_merge(
78
                $this->shareRatingsRepository->getRatingStatistics($id),
79
                [
80
                    'share_id' => $id,
81
                    'already_rated' => $this->hasAlreadyRated($ipAddress, $id),
0 ignored issues
show
Bug introduced by Tino Goratsch
It seems like $ipAddress can also be of type null; however, parameter $ipAddress of ACP3\Modules\ACP3\Share\...Rate::hasAlreadyRated() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

81
                    'already_rated' => $this->hasAlreadyRated(/** @scrutinizer ignore-type */ $ipAddress, $id),
Loading history...
82
                ]
83
            ),
84
        ];
85
    }
86
87
    /**
88
     * @param int    $shareId
89
     * @param int    $stars
90
     * @param string $ipAddress
91
     *
92
     * @return bool
93
     *
94
     * @throws \Doctrine\DBAL\DBALException
95
     */
96
    private function canSaveRating(int $shareId, int $stars, string $ipAddress): bool
97
    {
98
        if (!($stars >= 1 && $stars <= 5)) {
99
            return false;
100
        }
101
        if ($this->shareRepository->resultExistsById($shareId) === false) {
102
            return false;
103
        }
104
        if ($this->hasAlreadyRated($ipAddress, $shareId) === true) {
105
            return false;
106
        }
107
108
        return true;
109
    }
110
111
    /**
112
     * @param string $ipAddress
113
     * @param int    $shareId
114
     *
115
     * @return bool
116
     *
117
     * @throws \Doctrine\DBAL\DBALException
118
     */
119
    private function hasAlreadyRated(string $ipAddress, int $shareId): bool
120
    {
121
        if ($this->alredyRated === null) {
122
            $this->alredyRated = $this->shareRatingsRepository->hasAlreadyRated($ipAddress, $shareId);
123
        }
124
125
        return $this->alredyRated;
126
    }
127
}
128