Completed
Push — master ( 610136...82575c )
by De Cramer
06:15 queued 03:00
created

RuleApplier   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 131
Duplicated Lines 0 %

Test Coverage

Coverage 97.56%

Importance

Changes 0
Metric Value
dl 0
loc 131
ccs 40
cts 41
cp 0.9756
rs 10
c 0
b 0
f 0
wmc 17

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 2
D apply() 0 31 10
B applyRule() 0 28 4
A registerRule() 0 3 1
1
<?php
2
3
namespace Oliverde8\Component\RuleEngine;
4
5
use Oliverde8\Component\RuleEngine\Exceptions\RuleException;
6
use Oliverde8\Component\RuleEngine\Exceptions\UnknownRuleException;
7
use Oliverde8\Component\RuleEngine\Rules\RuleInterface;
8
use Psr\Log\LoggerInterface;
9
10
/**
11
 * Class RuleApplier
12
 *
13
 * @author    de Cramer Oliver<[email protected]>
14
 * @copyright 2018 Oliverde8
15
 * @package Oliverde8\Component\RuleEngine\RuleApplier
16
 */
17
class RuleApplier
18
{
19
    /** @var LoggerInterface */
20
    protected $logger;
21
22
    /** @var RuleInterface[] */
23
    protected $rules;
24
25
    /** @var boolean When vali */
26
    protected $validate;
27
28
    /** @var array */
29
    protected $currentIdentity;
30
31
    /**
32
     * RuleApplier constructor.
33
     *
34
     * @param LoggerInterface $logger   Standard logger to use to log errors or debug information.
35
     * @param RuleInterface[] $rules    List of rules defined.
36
     * @param boolean         $validate When validation is active rules are validated and clear messages are displayed
37
     *                                  when a rule is not well coded. But performance is worsened.
38
     */
39 28
    public function __construct(LoggerInterface $logger, array $rules, $validate = false)
40
    {
41 28
        $this->logger = $logger;
42 28
        $this->validate = $validate;
43
44 28
        foreach ($rules as $rule) {
45
            $this->registerRule($rule);
46
        }
47 28
    }
48
49
    /**
50
     * Register a rule to the rule engine.
51
     *
52
     * @param RuleInterface $rule
53
     */
54 7
    public function registerRule(RuleInterface $rule)
55
    {
56 7
        $this->rules[$rule->getRuleCode()] = $rule;
57 7
    }
58
59
60
    /**
61
     * Apply rules to data.
62
     *
63
     * @param array|string $rowData         Data that is being trasformed.
64
     * @param array        $transformedData Transformed data at the current stage
65
     * @param array|string $rules           Rules to apply, if string is given the string is returned.
66
     * @param array        $options         Options to be used by the rules.
67
     * @param array        $identifier      Identity of the line rule is applied on to log & display.
68
     *
69
     * @return null|string
70
     * @throws UnknownRuleException
71
     * @throws RuleException
72
     */
73 11
    public function apply($rowData, $transformedData, $rules, $options = [], $identifier = [])
74
    {
75
        // There is no rule apply.
76 11
        if (!is_array($rules)) {
77 5
            return $rules;
78
        }
79
80 6
        if (!empty($identifier)) {
81 6
            $this->currentIdentity = $identifier;
82
        }
83
84 6
        foreach ($rules as $ruleData) {
85
            // There is no rule apply.
86 6
            if (!is_array($ruleData)) {
87 1
                return $ruleData;
88
            }
89
90 6
            foreach ($ruleData as $rule => $ruleOptions) {
91 6
                $value = $this->applyRule($rule, $ruleOptions, $rowData, $transformedData, $options);
0 ignored issues
show
Bug introduced by
It seems like $rowData can also be of type string; however, parameter $rowData of Oliverde8\Component\Rule...uleApplier::applyRule() does only seem to accept array, 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

91
                $value = $this->applyRule($rule, $ruleOptions, /** @scrutinizer ignore-type */ $rowData, $transformedData, $options);
Loading history...
92
93 4
                if (!empty($value) || $value === 0 || $value === "0") {
94 4
                    return $value;
95
                }
96
            }
97
        }
98
99 1
        if (!empty($this->currentIdentity)) {
100 1
            $this->logger->warning("Rules were not resolved for line.", $this->currentIdentity);
101
        }
102
103 1
        return "";
104
    }
105
106
    /**
107
     * Apply a rule to a data set.
108
     *
109
     * @param string $rule            Code of the rule to apply.
110
     * @param array  $ruleOptions     Options to use when applying the rule
111
     * @param array  $rowData         Row that needs conversion.
112
     * @param array  $transformedData Current state of the transformed rule.
113
     * @param array  $options         Other options.
114
     *
115
     * @throws RuleException
116
     *
117
     * @return null|string
118
     * @throws UnknownRuleException
119
     */
120 6
    protected function applyRule($rule, $ruleOptions, $rowData, $transformedData, $options)
121
    {
122 6
        if (!isset($this->rules[$rule])) {
123 1
            throw new UnknownRuleException("Rule '$rule' was not found!");
124
        }
125 5
        $ruleObject = $this->rules[$rule];
126
127 5
        $options = array_merge($options, $ruleOptions);
128
129 5
        if ($this->validate) {
130
            try {
131 5
                $ruleObject->validate($options);
132 1
            } catch (RuleException $ruleException) {
133 1
                $this->logger->error(
134 1
                    "An exception accured when executing rules!",
135 1
                    array_merge(
136 1
                        $this->currentIdentity,
137 1
                        ['message' => $ruleException->getMessage()]
138
                    )
139
                );
140 1
                throw $ruleException;
141
            }
142
        }
143
144 4
        $ruleObject->setApplier($this);
145 4
        $result = $ruleObject->apply($rowData, $transformedData, $options);
146
147 4
        return $result;
148
    }
149
}