Completed
Push — master ( 607404...69c683 )
by Sebastien
10:30 queued 07:46
created

Cerbere::dedupeProjectList()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 15
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 15
rs 9.4286
cc 3
eloc 7
nc 3
nop 1
1
<?php
2
3
namespace Cerbere;
4
5
use Cerbere\Action\ActionInterface;
6
use Cerbere\Event\CerbereEvents;
7
use Cerbere\Event\CerbereFileDiscoverEvent;
8
use Cerbere\Event\CerberePostActionEvent;
9
use Cerbere\Event\CerberePreActionEvent;
10
use Cerbere\Event\DispatcherAwareInterface;
11
use Cerbere\Model\Job;
12
use Cerbere\Model\Project;
13
use Cerbere\Parser\ParserInterface;
14
use Symfony\Component\EventDispatcher\EventDispatcher;
15
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
16
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
17
18
/**
19
 * Class Cerbere
20
 *
21
 * @package Cerbere
22
 */
23
class Cerbere implements DispatcherAwareInterface
24
{
25
    /**
26
     * @var ParserInterface[]
27
     */
28
    protected $parsers = array();
29
30
    /**
31
     * @var EventDispatcherInterface
32
     */
33
    protected $dispatcher;
34
35
    /**
36
     */
37
    public function __construct()
38
    {
39
    }
40
41
    /**
42
     * @param EventSubscriberInterface $listener
43
     */
44
    public function addLoggerListener(EventSubscriberInterface $listener)
45
    {
46
        $this->getDispatcher()->addSubscriber($listener);
47
    }
48
49
    /**
50
     * Gets the dispatcher used by this library to dispatch events.
51
     *
52
     * @return EventDispatcherInterface
53
     */
54
    public function getDispatcher()
55
    {
56
        if (!isset($this->dispatcher)) {
57
            $this->dispatcher = new EventDispatcher();
58
        }
59
60
        return $this->dispatcher;
61
    }
62
63
    /**
64
     * Sets the dispatcher used by this library to dispatch events.
65
     *
66
     * @param EventDispatcherInterface $dispatcher
67
     *   The Symfony event dispatcher object.
68
     *
69
     * @return $this
70
     */
71
    public function setDispatcher(EventDispatcherInterface $dispatcher)
72
    {
73
        $this->dispatcher = $dispatcher;
74
    }
75
76
    /**
77
     * @param ParserInterface $parser
78
     *
79
     * @return $this
80
     */
81
    public function addParser(ParserInterface $parser)
82
    {
83
        $this->parsers[$parser->getCode()] = $parser;
84
85
        return $this;
86
    }
87
88
    /**
89
     * @param string $code
90
     *
91
     * @return ParserInterface|null
92
     */
93
    public function getParser($code)
94
    {
95
        if (isset($this->parsers[$code])) {
96
            return $this->parsers[$code];
97
        }
98
99
        return null;
100
    }
101
102
    /**
103
     * @param Job $job
104
     * @param ActionInterface $action
105
     * @param array $options
106
     *
107
     * @return array
108
     */
109
    public function run(Job $job, ActionInterface $action, $options = array())
110
    {
111
        // Download remote project if remote.
112
        $dir = $job->checkoutRepository();
113
114
        // Move to project folder.
115
        $currentDirectory = getcwd();
116
        chdir($dir);
117
118
        // Load projects from repository.
119
        $projects = $this->getProjectsFromPatterns($job->getPatterns(), $job->isPatternNested());
120
        $projects = $this->dedupeProjectList($projects);
121
122
        $event = new CerberePreActionEvent($this, $job, $action, $projects);
123
        $this->getDispatcher()->dispatch(CerbereEvents::CERBERE_PRE_ACTION, $event);
124
125
        // Do cerbere action.
126
        $report = $action->process($projects, $options);
127
128
        $event = new CerberePostActionEvent($this, $job, $action, $projects);
129
        $this->getDispatcher()->dispatch(CerbereEvents::CERBERE_POST_ACTION, $event);
130
131
        // Restore initial directory.
132
        chdir($currentDirectory);
133
134
        return $report;
135
    }
136
137
    /**
138
     * @param array $patterns
139
     * @param bool|false $nested
140
     *
141
     * @return Project[]
142
     */
143
    public function getProjectsFromPatterns($patterns, $nested = false)
144
    {
145
        $projects = array();
146
147
        foreach ($patterns as $pattern) {
148
            $projects = array_merge($projects, $this->getProjectsFromPattern($pattern, $nested));
149
        }
150
151
        return $projects;
152
    }
153
154
    /**
155
     * @param Project[] $list
156
     * @return Project[]
157
     */
158
    public function dedupeProjectList($list)
159
    {
160
        $projects = array();
161
162
        /** @var Project $project */
163
        foreach ($list as $project) {
164
            if (!isset($projects[$project->getProject()])) {
165
                $projects[$project->getProject()] = $project;
166
            }
167
        }
168
169
        ksort($projects, SORT_NATURAL);
170
171
        return $projects;
172
    }
173
174
    /**
175
     * @param string $pattern
176
     * @param bool|false $nested
177
     *
178
     * @return Project[]
179
     */
180
    public function getProjectsFromPattern($pattern, $nested = false)
181
    {
182
        $projects = array();
183
        $dispatcher = $this->getDispatcher();
184
        $files = $this->getFilesFromPattern($pattern, $nested);
185
186
        foreach ($files as $file) {
187
            foreach ($this->getParsers() as $parser) {
188
                if ($parser->supportedFile($file)) {
189
                    $event = new CerbereFileDiscoverEvent($this, $file, $parser);
190
                    $dispatcher->dispatch(CerbereEvents::CERBERE_FILE_DISCOVERED, $event);
191
                    $parser->processFile($file);
192
                    $projects = array_merge($projects, $parser->getProjects());
193
                }
194
            }
195
        }
196
197
        return $projects;
198
    }
199
200
    /**
201
     * @param string $pattern
202
     * @param bool|false $nested
203
     * @param int $flags
204
     *
205
     * @return array
206
     */
207
    public function getFilesFromPattern($pattern, $nested = false, $flags = 0)
208
    {
209
        $files = glob($pattern, $flags);
210
211
        if ($nested) {
212
            foreach (glob(dirname($pattern) . DIRECTORY_SEPARATOR . '*', GLOB_ONLYDIR | GLOB_NOSORT) as $dir) {
213
                $files = array_merge(
214
                  $files,
215
                  $this->getFilesFromPattern($dir . DIRECTORY_SEPARATOR . basename($pattern), $nested, $flags)
216
                );
217
            }
218
        }
219
220
        return $files;
221
    }
222
223
    /**
224
     * @return ParserInterface[]
225
     */
226
    public function getParsers()
227
    {
228
        return $this->parsers;
229
    }
230
}
231