Passed
Push — master ( 7f6baf...50f068 )
by Satoshi
02:16
created

DependencyRuleFactory::create()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 7
nc 3
nop 1
dl 0
loc 12
rs 10
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
4
namespace DependencyAnalyzer\Inspector\RuleViolationDetector;
5
6
use DependencyAnalyzer\Exceptions\InvalidRuleDefinition;
7
use DependencyAnalyzer\Patterns\QualifiedNamePattern;
8
9
class DependencyRuleFactory
10
{
11
    /**
12
     * @param array $ruleDefinitions
13
     * @return DependencyRule[]
14
     */
15
    public function create(array $ruleDefinitions): array
16
    {
17
        $rules = [];
18
        foreach ($ruleDefinitions as $ruleName => $ruleDefinition) {
19
            $this->verifyDefinition($ruleDefinition);
20
            if (is_int($ruleName)) {
21
                $ruleName = (string)$ruleName;
22
            }
23
            $rules[] = $this->createDependencyRule($ruleName, $ruleDefinition);
24
        }
25
26
        return $rules;
27
    }
28
29
    protected function createDependencyRule(string $ruleName, array $ruleDefinition)
30
    {
31
        $componentDefines = [];
32
        foreach ($ruleDefinition as $componentName => $componentDefinition) {
33
            $componentDefines[$componentName] = $componentDefinition['define'];
34
        }
35
36
        $components = [];
37
        foreach ($ruleDefinition as $componentName => $componentDefinition) {
38
            $depender = isset($componentDefinition['depender']) ? $this->createDependPattern($componentDefinition['depender'], $componentDefines) : null;
39
            $dependee = isset($componentDefinition['dependee']) ? $this->createDependPattern($componentDefinition['dependee'], $componentDefines) : null;
40
            $components[] = new Component(
41
                $componentName,
42
                new QualifiedNamePattern($componentDefinition['define']),
43
                $depender,
44
                $dependee
45
            );
46
        }
47
        return new DependencyRule($ruleName, $components);
48
    }
49
50
    protected function createDependPattern(array $dependMatchers, array $componentDefines): QualifiedNamePattern
51
    {
52
        $matchers = [];
53
        $excludeMatchers = [];
54
        foreach ($dependMatchers as $dependMatcher) {
55
            if (preg_match('/^\![^\\\@]/', $dependMatcher) === 1 && isset($componentDefines[substr($dependMatcher, 1)])) {
56
                $excludeMatchers = array_merge($excludeMatchers, $componentDefines[substr($dependMatcher, 1)]);
57
            } elseif (preg_match('/^[^\\\@]/', $dependMatcher) === 1 && isset($componentDefines[$dependMatcher])) {
58
                $matchers = array_merge($matchers, $componentDefines[$dependMatcher]);
59
            } else {
60
                $matchers[] = $dependMatcher;
61
            }
62
        }
63
64
        // TODO: fix it...
65
        return (new QualifiedNamePattern($matchers))->addExcludePatterns($excludeMatchers);
66
    }
67
68
    protected function verifyDefinition(array $ruleDefinition): void
69
    {
70
        foreach ($ruleDefinition as $componentName => $componentDefinition) {
71
            if (!isset($componentDefinition['define']) || !is_array($componentDefinition['define'])) {
72
                throw new InvalidRuleDefinition($ruleDefinition, "component must have 'define'. Invalid your component: {$componentName}");
73
            } elseif (isset($componentDefinition['depender']) && !is_array($componentDefinition['depender'])) {
74
                throw new InvalidRuleDefinition($ruleDefinition, "depenee must be array. Invalid your component: {$componentName}");
75
            } elseif (isset($componentDefinition['dependee']) && !is_array($componentDefinition['dependee'])) {
76
                throw new InvalidRuleDefinition($ruleDefinition, "depenee must be array. Invalid your component: {$componentName}");
77
            }
78
        }
79
    }
80
}
81