FeatureActivator   A
last analyzed

Complexity

Total Complexity 18

Size/Duplication

Total Lines 136
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 98.15%

Importance

Changes 0
Metric Value
wmc 18
lcom 1
cbo 4
dl 0
loc 136
ccs 53
cts 54
cp 0.9815
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A addFeature() 0 8 2
A activateFeatures() 0 17 4
A sort() 0 9 2
B activateFeature() 0 52 8
A getFeatures() 0 4 1
1
<?php
2
namespace PSB\Core\Feature;
3
4
5
use PSB\Core\ObjectBuilder\BuilderInterface;
6
use PSB\Core\Pipeline\PipelineModifications;
7
use PSB\Core\Util\Settings;
8
9
class FeatureActivator
10
{
11
    /**
12
     * @var Settings
13
     */
14
    private $settings;
15
16
    /**
17
     * @var Feature[]
18
     */
19
    private $features = [];
20
21
    /**
22
     * @param Settings $settings
23
     */
24 8
    public function __construct(Settings $settings)
25
    {
26 8
        $this->settings = $settings;
27 8
    }
28
29
    /**
30
     * @param Feature $feature
31
     */
32 7
    public function addFeature(Feature $feature)
33
    {
34 7
        if ($feature->isEnabledByDefault()) {
35 2
            FeatureSettingsExtensions::enableFeatureByDefault(get_class($feature), $this->settings);
36
        }
37
38 7
        $this->features[] = $feature;
39 7
    }
40
41
    /**
42
     * @param BuilderInterface      $builder
43
     * @param PipelineModifications $pipelineModifications
44
     */
45 5
    public function activateFeatures(BuilderInterface $builder, PipelineModifications $pipelineModifications)
46
    {
47 5
        $sortedFeatures = $this->sort();
48 5
        $enabledFeatures = [];
49
50 5
        foreach ($sortedFeatures as $feature) {
51 5
            $featureFqcn = get_class($feature);
52 5
            if (FeatureSettingsExtensions::isFeatureEnabled($featureFqcn, $this->settings)) {
53 5
                $enabledFeatures[$featureFqcn] = $feature;
54 5
                $feature->configureDefaults($this->settings);
55
            }
56
        }
57
58 5
        foreach ($enabledFeatures as $feature) {
59 5
            $this->activateFeature($feature, $enabledFeatures, $builder, $pipelineModifications);
60
        }
61 5
    }
62
63
    /**
64
     * @return Feature[]
65
     */
66 5
    private function sort()
67
    {
68 5
        if (empty($this->features)) {
69
            return [];
70
        }
71
72 5
        $dependencyGraphBuilder = new FeatureDependencyGraphBuilder($this->features);
73 5
        return $dependencyGraphBuilder->build()->sort();
74
    }
75
76
    /**
77
     * @param Feature               $feature
78
     * @param Feature[]             $enabledFeatures
79
     * @param BuilderInterface      $builder
80
     * @param PipelineModifications $pipelineModifications
81
     *
82
     * @return bool
83
     */
84 5
    private function activateFeature(
85
        Feature $feature,
86
        $enabledFeatures,
87
        BuilderInterface $builder,
88
        PipelineModifications $pipelineModifications
89
    ) {
90 5
        if ($feature->isActive()) {
91 2
            return true;
92
        }
93
94 4
        $dependencyGroups = $feature->getDependencies();
95 4
        $groupsActivationStatus = [];
96
97 4
        foreach ($dependencyGroups as $dependencyGroup) {
98 2
            $dependentFeaturesToActivate = [];
99 2
            foreach ($dependencyGroup as $dependencyFqcn) {
100 2
                if (isset($enabledFeatures[$dependencyFqcn])) {
101 2
                    $dependentFeaturesToActivate[$dependencyFqcn] = $enabledFeatures[$dependencyFqcn];
102
                }
103
            }
104
105 2
            $dependenciesActivationStatus = [];
106 2
            foreach ($dependentFeaturesToActivate as $featureFqcn => $dependentFeature) {
107 2
                $dependenciesActivationStatus[$featureFqcn] = $this->activateFeature(
108 2
                    $dependentFeature,
109 2
                    $enabledFeatures,
110 2
                    $builder,
111 2
                    $pipelineModifications
112
                );
113
            }
114
115
            // if at least one dependency in the group has been activated
116 2
            $groupsActivationStatus[] = in_array(true, $dependenciesActivationStatus);
117
        }
118
119 4
        $featureFqcn = get_class($feature);
120
121
        // if all groups have been activated
122 4
        if (!in_array(false, $groupsActivationStatus)) {
123 4
            if (!$feature->checkPrerequisites($this->settings, $builder, $pipelineModifications)) {
124 2
                FeatureSettingsExtensions::markFeatureAsInactive($featureFqcn, $this->settings);
125 2
                return false;
126
            }
127
128 2
            FeatureSettingsExtensions::markFeatureAsActive($featureFqcn, $this->settings);
129 2
            $feature->activate($this->settings, $builder, $pipelineModifications);
130 2
            return true;
131
        }
132
133 1
        FeatureSettingsExtensions::markFeatureAsInactive($featureFqcn, $this->settings);
134 1
        return false;
135
    }
136
137
    /**
138
     * @return Feature[]
139
     */
140 1
    public function getFeatures()
141
    {
142 1
        return $this->features;
143
    }
144
}
145