TaskRunner::fetchDestinations()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

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