Passed
Push — master ( 29e061...029172 )
by Satoshi
02:02
created

DependencyRuleFactory::createClassNameMatcher()   A

Complexity

Conditions 6
Paths 4

Size

Total Lines 18
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 10
nc 4
nop 2
dl 0
loc 18
rs 9.2222
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\Matcher\ClassNameMatcher;
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->createClassNameMatcher($componentDefinition['depender'], $componentDefines) : null;
39
            $dependee = isset($componentDefinition['dependee']) ? $this->createClassNameMatcher($componentDefinition['dependee'], $componentDefines) : null;
40
            $components[] = new Component(
41
                $componentName,
42
                new ClassNameMatcher($componentDefinition['define']),
43
                $depender,
44
                $dependee
45
            );
46
        }
47
        return new DependencyRule($ruleName, $components);
48
    }
49
50
    protected function createClassNameMatcher(array $dependPatterns, array $componentDefines): ClassNameMatcher
51
    {
52
        $patterns = [];
53
        $excludePatterns = [];
54
        foreach ($dependPatterns as $dependPattern) {
55
            if (preg_match('/^\![^\\\@]/', $dependPattern) === 1 && isset($componentDefines[substr($dependPattern, 1)])) {
56
                // ex: '!component_name' -> ['\Component\Define']
57
                $excludePatterns = array_merge($excludePatterns, $componentDefines[substr($dependPattern, 1)]);
58
            } elseif (preg_match('/^[^\\\@]/', $dependPattern) === 1 && isset($componentDefines[$dependPattern])) {
59
                // ex: 'component_name' -> ['\Component\Define']
60
                $patterns = array_merge($patterns, $componentDefines[$dependPattern]);
61
            } else {
62
                $patterns[] = $dependPattern;
63
            }
64
        }
65
66
        // TODO: fix it...
67
        return (new ClassNameMatcher($patterns))->addExcludePatterns($excludePatterns);
68
    }
69
70
    protected function verifyDefinition(array $ruleDefinition): void
71
    {
72
        foreach ($ruleDefinition as $componentName => $componentDefinition) {
73
            if (!isset($componentDefinition['define']) || !is_array($componentDefinition['define'])) {
74
                throw new InvalidRuleDefinition($ruleDefinition, "component must have 'define'. Invalid your component: {$componentName}");
75
            } elseif (isset($componentDefinition['depender']) && !is_array($componentDefinition['depender'])) {
76
                throw new InvalidRuleDefinition($ruleDefinition, "depenee must be array. Invalid your component: {$componentName}");
77
            } elseif (isset($componentDefinition['dependee']) && !is_array($componentDefinition['dependee'])) {
78
                throw new InvalidRuleDefinition($ruleDefinition, "depenee must be array. Invalid your component: {$componentName}");
79
            }
80
        }
81
    }
82
}
83