ForAtLeast   A
last analyzed

Complexity

Total Complexity 8

Size/Duplication

Total Lines 57
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 22
c 1
b 0
f 0
dl 0
loc 57
rs 10
wmc 8

2 Methods

Rating   Name   Duplication   Size   Complexity  
A validate() 0 28 5
A __construct() 0 11 3
1
<?php
2
/*
3
 * This file is part of Phypes <https://github.com/2DSharp/Phypes>.
4
 *
5
 * (c) Dedipyaman Das <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
12
namespace Phypes\Rule\Aggregate;
13
14
15
use Phypes\Error\Error;
16
use Phypes\Exception\InvalidAggregateRule;
17
use Phypes\Result\Failure;
18
use Phypes\Result\Result;
19
use Phypes\Result\Success;
20
use Phypes\Rule\Rule;
21
22
/**
23
 * Class ForAtLeast
24
 * @package Phypes\Rule\Aggregate
25
 * @author Dedipyaman Das <[email protected]>
26
 *
27
 * Rule to aggregate different rules and validity depends on passing at least the number of specified rules out of all.
28
 */
29
class ForAtLeast implements Rule
30
{
31
    /**
32
     * @var int $minimum
33
     */
34
    private $minimum;
35
    /**
36
     * @var array|Rule[] $rules
37
     */
38
    private $rules = [];
39
    /**
40
     * ForAtLeast constructor.
41
     * @param int $numOfRules
42
     * @param Rule ...$rules
43
     * @throws InvalidAggregateRule
44
     */
45
    public function __construct(int $numOfRules, Rule... $rules)
46
    {
47
        if (empty($rules))
48
            throw new InvalidAggregateRule("No rules specified for aggregate rule", ForAtLeast::class);
49
50
        if (count($rules) < $numOfRules)
51
            throw new InvalidAggregateRule('Minimum passing rule number is greater than supplied rules',
52
                ForAtLeast::class);
53
54
        $this->rules = $rules;
55
        $this->minimum = $numOfRules;
56
    }
57
58
    public function validate($data): Result
59
    {
60
        /**
61
         * @var array|Error[] $errors
62
         */
63
        $errors = [];
64
        $passed = 0;
65
66
        foreach ($this->rules as $rule) {
67
            $result = $rule->validate($data);
68
69
            if (!$result->isValid()) {
70
                /**
71
                 * @var Failure $result
72
                 * @var Error $error
73
                 */
74
                foreach ($result->getErrors() as $error) {
75
                    $errors[] = $error;
76
                }
77
            }
78
            else {
79
                $passed++;
80
            }
81
82
            if ($passed >= $this->minimum)
83
                return new Success();
84
        }
85
        return new Failure(...$errors);
86
    }
87
}