Completed
Pull Request — master (#1)
by Arnaud
08:08 queued 05:21
created

TaskRunner::filterSources()   B

Complexity

Conditions 6
Paths 5

Size

Total Lines 23
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 23
ccs 0
cts 13
cp 0
rs 8.5906
cc 6
eloc 10
nc 5
nop 2
crap 42
1
<?php
2
3
namespace JK\Sam\Task;
4
5
use Exception;
6
use JK\Sam\File\Locator;
7
use JK\Sam\Filter\FilterInterface;
8
use SplFileInfo;
9
10
class TaskRunner
11
{
12
    /**
13
     * @var FilterInterface[]
14
     */
15
    protected $filters;
16
17
    /**
18
     * @var Locator
19
     */
20
    protected $locator;
21
22
    /**
23
     * TaskRunner constructor.
24
     *
25
     * @param FilterInterface[] $filters
26
     * @param Locator $locator
27
     */
28
    public function __construct(array $filters, Locator $locator)
29
    {
30
        $this->filters = $filters;
31
        $this->locator = $locator;
32
    }
33
34
    /**
35
     * Run a task, load its sources before and call the clean method on the filter.
36
     *
37
     * @param Task $task
38
     * @throws Exception
39
     */
40
    public function run(Task $task)
41
    {
42
        // get configured filters for this task
43
        $filters = $task
44
            ->getConfiguration()
45
            ->getParameter('filters');
46
47
        // get sources files
48
        $sources = $this->fetchSources($task);
49
        $destinations = $this->fetchDestinations($task);
50
51
        foreach ($filters as $filterName) {
52
            // get current configured filter
53
            $filter = $this->getFilter($filterName);
54
55
            // filter the files supported by this filter
56
            $filteredSources = $this->filterSources($sources, $filter);
57
58
            // apply the filter
59
            $updatedSources = $filter->run($filteredSources, $destinations);
60
61
            if ($updatedSources === null) {
62
                $updatedSources = [];
63
            }
64
65
            // clean the generated files by the filter
66
            $filter->clean();
67
            
68
            // update new sources
69
            $sources = $this->updateSources($sources, $filteredSources, $updatedSources);
70
        }
71
    }
72
73
    /**
74
     * Return a filter by its name. Throw an exception if it is not exists.
75
     *
76
     * @param string $name
77
     * @return FilterInterface
78
     * @throws Exception
79
     */
80
    protected function getFilter($name)
81
    {
82
        // filters must exists in configured filters
83
        if (!array_key_exists($name, $this->filters)) {
84
            throw new Exception('Invalid filter '.$name.'. Check your mapping configuration');
85
        }
86
87
        return $this->filters[$name];
88
    }
89
90
    /**
91
     * Fetch the source files from the task and return and array of SplInfo.
92
     *
93
     * @param Task $task
94
     * @return array
95
     */
96
    protected function fetchSources(Task $task)
97
    {
98
        $sources = [];
99
100
        foreach ($task->getSources() as $source) {
101
            // locate new resource and merge them to the existing sources
102
            $sources = array_merge($sources, $this->locator->locate($source));
103
        }
104
105
        return $sources;
106
    }
107
108
    /**
109
     * Fetch the destination files from the task and return and array of SplInfo.
110
     *
111
     * @param Task $task
112
     * @return SplFileInfo[]
113
     */
114
    protected function fetchDestinations(Task $task)
115
    {
116
        $sources = [];
117
118
        foreach ($task->getDestinations() as $source) {
119
            // locate new resource and merge them to the existing sources
120
            $sources[] = new SplFileInfo($source);
121
        }
122
123
        return $sources;
124
    }
125
126
    /**
127
     * Filter only the sources supported by the current filter.
128
     *
129
     * @param SplFileInfo[] $sources
130
     * @param FilterInterface $filter
131
     * @return array
132
     * @throws Exception
133
     */
134
    protected function filterSources(array $sources, FilterInterface $filter)
135
    {
136
        $filteredSources = [];
137
138
        // if the filter supports no extension, there is an error
139
        if (!is_array($filter->getSupportedExtensions()) || !count($filter->getSupportedExtensions())) {
140
            throw new Exception('No supported extensions found for the filter '.$filter->getName());
141
        }
142
143
        // if the filter support all the files types, no need to filter
144
        if (in_array('*', $filter->getSupportedExtensions())) {
145
            return $sources;
146
        }
147
148
        foreach ($sources as $source) {
149
150
            if (in_array($source->getExtension(), $filter->getSupportedExtensions())) {
151
                $filteredSources[] = $source;
152
            }
153
        }
154
155
        return $filteredSources;
156
    }
157
158
    /**
159
     * Remove the filtered files from the sources, and merge with the new ones.
160
     *
161
     * @param SplFileInfo[] $originalSources
162
     * @param SplFileInfo[] $filteredSources
163
     * @param SplFileInfo[] $updatedSources
164
     * @return SplFileInfo[]
165
     * @throws Exception
166
     */
167
    protected function updateSources(array $originalSources, array $filteredSources, array $updatedSources)
168
    {
169
        $sources = [];
170
171
        // keep only the not filtered files
172
        foreach ($originalSources as $source) {
173
174
            if (!in_array($source, $filteredSources)) {
175
                $sources[] = $source;
176
            }
177
        }
178
        // check updated files
179
        foreach ($updatedSources as $index => $source) {
180
            if (is_string($source)) {
181
                $updatedSources[$index] = new SplFileInfo($source);
182
            } else if (!($source instanceof SplFileInfo)) {
183
                throw new Exception('Invalid source file type '.gettype($source));
184
            }
185
        }
186
        // merge with the new sources
187
        $sources = array_merge($sources, $updatedSources);
188
189
        return $sources;
190
    }
191
}
192