Passed
Pull Request — master (#222)
by Alexander
04:33 queued 02:13
created

Count::__construct()   B

Complexity

Conditions 10
Paths 4

Size

Total Lines 60
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 10

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 10
eloc 8
c 1
b 0
f 0
nc 4
nop 11
dl 0
loc 60
ccs 8
cts 8
cp 1
crap 10
rs 7.6666

How to fix   Long Method    Complexity    Many Parameters   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Validator\Rule;
6
7
use Attribute;
8
use Closure;
9
use Countable;
10
use InvalidArgumentException;
11
use JetBrains\PhpStorm\ArrayShape;
12
use Yiisoft\Validator\ParametrizedRuleInterface;
13
use Yiisoft\Validator\PreValidatableRuleInterface;
14
use Yiisoft\Validator\Rule\Trait\HandlerClassNameTrait;
0 ignored issues
show
Bug introduced by
A parse error occurred: Syntax error, unexpected T_TRAIT, expecting T_STRING or '{' on line 14 at column 27
Loading history...
15
use Yiisoft\Validator\Rule\Trait\PreValidatableTrait;
16
use Yiisoft\Validator\Rule\Trait\RuleNameTrait;
17
18
/**
19
 * Validates that the value contains certain number of items. Can be applied to arrays or classes implementing
20
 * {@see Countable} interface.
21
 */
22
#[Attribute(Attribute::TARGET_PROPERTY)]
23
final class Count implements ParametrizedRuleInterface, PreValidatableRuleInterface
24
{
25
    use HandlerClassNameTrait;
26
    use PreValidatableTrait;
27
    use RuleNameTrait;
28
29 7
    public function __construct(
30
        /**
31
         * @var int|null minimum number of items. null means no minimum number limit.
32
         *
33
         * @see $tooFewItemsMessage for the customized message for a value with too few items.
34
         */
35
        private ?int $min = null,
36
        /**
37
         * @var int|null maximum number of items. null means no maximum number limit.
38
         *
39
         * @see $tooManyItemsMessage for the customized message for a value wuth too many items.
40
         */
41
        private ?int $max = null,
42
        /**
43
         * @var int|null exact number of items. null means no strict comparison. Mutually exclusive with {@see $min} and
44
         * {@see $max}.
45
         */
46
        private ?int $exactly = null,
47
        /**
48
         * @var string user-defined error message used when the value is neither an array nor implementing
49
         * {@see \Countable} interface.
50
         *
51
         * @see Countable
52
         */
53
        private string $message = 'This value must be an array or implement \Countable interface.',
54
        /**
55
         * @var string user-defined error message used when the number of items is smaller than {@see $min}.
56
         */
57
        private string $tooFewItemsMessage = 'This value must contain at least {min, number} ' .
58
        '{min, plural, one{item} other{items}}.',
59
        /**
60
         * @var string user-defined error message used when the number of items is greater than {@see $max}.
61
         */
62
        private string $tooManyItemsMessage = 'This value must contain at most {max, number} ' .
63
        '{max, plural, one{item} other{items}}.',
64
        /**
65
         * @var string user-defined error message used when the number of items does not equal {@see $exactly}.
66
         */
67
        private string $notExactlyMessage = 'This value must contain exactly {max, number} ' .
68
        '{max, plural, one{item} other{items}}.',
69
        private bool $skipOnEmpty = false,
70
        private bool $skipOnError = false,
71
        private ?Closure $when = null,
72
    ) {
73 7
        if (!$this->min && !$this->max && !$this->exactly) {
74 1
            throw new InvalidArgumentException(
75
                'At least one of these attributes must be specified: $min, $max, $exactly.'
76
            );
77
        }
78
79 6
        if ($this->exactly && ($this->min || $this->max)) {
80 3
            throw new InvalidArgumentException('$exactly is mutually exclusive with $min and $max.');
81
        }
82
83 3
        if ($this->min && $this->max && $this->min === $this->max) {
84 1
            throw new InvalidArgumentException('Use $exactly instead.');
85
        }
86
    }
87
88
    /**
89
     * @return int|null
90
     */
91 18
    public function getMin(): ?int
92
    {
93 18
        return $this->min;
94
    }
95
96
    /**
97
     * @return int|null
98
     */
99 18
    public function getMax(): ?int
100
    {
101 18
        return $this->max;
102
    }
103
104
    /**
105
     * @return int|null
106
     */
107 19
    public function getExactly(): ?int
108
    {
109 19
        return $this->exactly;
110
    }
111
112
    /**
113
     * @return string
114
     */
115
    public function getMessage(): string
116
    {
117
        return $this->message;
118
    }
119
120
    /**
121
     * @return string
122
     */
123 9
    public function getTooFewItemsMessage(): string
124
    {
125 9
        return $this->tooFewItemsMessage;
126
    }
127
128
    /**
129
     * @return string
130
     */
131 2
    public function getTooManyItemsMessage(): string
132
    {
133 2
        return $this->tooManyItemsMessage;
134
    }
135
136
    /**
137
     * @return string
138
     */
139 1
    public function getNotExactlyMessage(): string
140
    {
141 1
        return $this->notExactlyMessage;
142
    }
143
144 1
    #[ArrayShape([
145
        'min' => 'int|null',
146
        'max' => 'int|null',
147
        'exactly' => 'int|null',
148
        'message' => 'string[]',
149
        'tooFewItemsMessage' => 'array',
150
        'tooManyItemsMessage' => 'array',
151
        'notExactlyMessage' => 'array',
152
        'skipOnEmpty' => 'bool',
153
        'skipOnError' => 'bool',
154
    ])]
155
    public function getOptions(): array
156
    {
157
        return [
158 1
            'min' => $this->min,
159 1
            'max' => $this->max,
160 1
            'exactly' => $this->exactly,
161
            'message' => [
162 1
                'message' => $this->message,
163
            ],
164
            'tooFewItemsMessage' => [
165 1
                'message' => $this->tooFewItemsMessage,
166 1
                'parameters' => ['min' => $this->min],
167
            ],
168
            'tooManyItemsMessage' => [
169 1
                'message' => $this->tooManyItemsMessage,
170 1
                'parameters' => ['max' => $this->max],
171
            ],
172
            'notExactlyMessage' => [
173 1
                'message' => $this->notExactlyMessage,
174 1
                'parameters' => ['exactly' => $this->exactly],
175
            ],
176 1
            'skipOnEmpty' => $this->skipOnEmpty,
177 1
            'skipOnError' => $this->skipOnError,
178
        ];
179
    }
180
}
181