Cerbere::getProjectsFromPatterns()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 2
dl 0
loc 10
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Drush Cerbere command line tools.
5
 * Copyright (C) 2015 - Sebastien Malot <[email protected]>
6
 *
7
 * This program is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 2 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License along
18
 * with this program; if not, write to the Free Software Foundation, Inc.,
19
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
 */
21
22
namespace Cerbere;
23
24
use Cerbere\Event\CerbereEvents;
25
use Cerbere\Event\CerbereFileDiscoverEvent;
26
use Cerbere\Event\CerberePostActionEvent;
27
use Cerbere\Event\CerberePreActionEvent;
28
use Cerbere\Event\DispatcherAwareInterface;
29
use Cerbere\Model\Job;
30
use Cerbere\Model\Project;
31
use Cerbere\Parser\ParserInterface;
32
use Symfony\Component\EventDispatcher\EventDispatcher;
33
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
34
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
35
36
/**
37
 * Class Cerbere
38
 * @package Cerbere
39
 */
40
class Cerbere implements DispatcherAwareInterface
41
{
42
    /**
43
     * @var ParserInterface[]
44
     */
45
    protected $parsers = array();
46
47
    /**
48
     * @var EventDispatcherInterface
49
     */
50
    protected $dispatcher;
51
52
    /**
53
     *
54
     */
55
    public function __construct()
56
    {
57
    }
58
59
    /**
60
     * @param EventSubscriberInterface $listener
61
     */
62
    public function addLoggerListener(EventSubscriberInterface $listener)
63
    {
64
        $this->getDispatcher()->addSubscriber($listener);
65
    }
66
67
    /**
68
     * Gets the dispatcher used by this library to dispatch events.
69
     *
70
     * @return EventDispatcherInterface
71
     */
72
    public function getDispatcher()
73
    {
74
        if (!isset($this->dispatcher)) {
75
            $this->dispatcher = new EventDispatcher();
76
        }
77
78
        return $this->dispatcher;
79
    }
80
81
    /**
82
     * Sets the dispatcher used by this library to dispatch events.
83
     *
84
     * @param EventDispatcherInterface $dispatcher
85
     *   The Symfony event dispatcher object.
86
     *
87
     * @return $this
88
     */
89
    public function setDispatcher(EventDispatcherInterface $dispatcher)
90
    {
91
        $this->dispatcher = $dispatcher;
92
    }
93
94
    /**
95
     * @param ParserInterface $parser
96
     *
97
     * @return $this
98
     */
99
    public function addParser(ParserInterface $parser)
100
    {
101
        $this->parsers[$parser->getCode()] = $parser;
102
103
        return $this;
104
    }
105
106
    /**
107
     * @param string $code
108
     *
109
     * @return ParserInterface|null
110
     */
111
    public function getParser($code)
112
    {
113
        if (isset($this->parsers[$code])) {
114
            return $this->parsers[$code];
115
        }
116
117
        return null;
118
    }
119
120
    /**
121
     * @param Job $job
122
     * @param array $options
123
     *
124
     * @return array
125
     */
126
    public function run(Job $job, $options = array())
127
    {
128
        // Download remote project if remote.
129
        $dir = $job->checkoutRepository();
130
131
        // Move to project folder.
132
        $currentDirectory = getcwd();
133
        chdir($dir);
134
135
        // Load projects from repository.
136
        $projects = $this->getProjectsFromPatterns($job->getPatterns(), $job->isPatternNested());
137
        $projects = $this->dedupeProjectList($projects);
138
139
        $event = new CerberePreActionEvent($this, $job, $job->getAction(), $projects);
140
        $this->getDispatcher()->dispatch(CerbereEvents::CERBERE_PRE_ACTION, $event);
141
142
        // Do cerbere action.
143
        $job->getAction()->prepare();
144
        $report = $job->getAction()->process($projects, $options);
145
146
        $event = new CerberePostActionEvent($this, $job, $job->getAction(), $projects);
147
        $this->getDispatcher()->dispatch(CerbereEvents::CERBERE_POST_ACTION, $event);
148
149
        // Restore initial directory.
150
        chdir($currentDirectory);
151
152
        return $report;
153
    }
154
155
    /**
156
     * @param array $patterns
157
     * @param bool|false $nested
158
     *
159
     * @return Project[]
160
     */
161
    public function getProjectsFromPatterns($patterns, $nested = false)
162
    {
163
        $projects = array();
164
165
        foreach ($patterns as $pattern) {
166
            $projects = array_merge($projects, $this->getProjectsFromPattern($pattern, $nested));
167
        }
168
169
        return $projects;
170
    }
171
172
    /**
173
     * @param Project[] $list
174
     * @return Project[]
175
     */
176
    public function dedupeProjectList($list)
177
    {
178
        $projects = array();
179
180
        /** @var Project $project */
181
        foreach ($list as $project) {
182
            if (!isset($projects[$project->getProject()])) {
183
                $projects[$project->getProject()] = $project;
184
            }
185
        }
186
187
        if (defined('SORT_NATURAL')) {
188
            ksort($projects, SORT_NATURAL);
189
        } else {
190
            ksort($projects);
191
        }
192
193
        return $projects;
194
    }
195
196
    /**
197
     * @param string $pattern
198
     * @param bool|false $nested
199
     *
200
     * @return Project[]
201
     */
202
    public function getProjectsFromPattern($pattern, $nested = false)
203
    {
204
        $projects = array();
205
        $dispatcher = $this->getDispatcher();
206
        $files = $this->getFilesFromPattern($pattern, $nested);
207
208
        foreach ($files as $file) {
209
            foreach ($this->getParsers() as $parser) {
210
                if ($parser->supportedFile($file)) {
211
                    $event = new CerbereFileDiscoverEvent($this, $file, $parser);
212
                    $dispatcher->dispatch(CerbereEvents::CERBERE_FILE_DISCOVERED, $event);
213
                    $parser->processFile($file);
214
                    $projects = array_merge($projects, $parser->getProjects());
215
                }
216
            }
217
        }
218
219
        return $projects;
220
    }
221
222
    /**
223
     * @param string $pattern
224
     * @param bool|false $nested
225
     * @param int $flags
226
     *
227
     * @return array
228
     */
229
    public function getFilesFromPattern($pattern, $nested = false, $flags = 0)
230
    {
231
        $files = glob($pattern, $flags);
232
233
        if ($nested) {
234
            foreach (glob(dirname($pattern) . DIRECTORY_SEPARATOR . '*', GLOB_ONLYDIR | GLOB_NOSORT) as $dir) {
235
                $files = array_merge(
236
                  $files,
237
                  $this->getFilesFromPattern($dir . DIRECTORY_SEPARATOR . basename($pattern), $nested, $flags)
238
                );
239
            }
240
        }
241
242
        return $files;
243
    }
244
245
    /**
246
     * @return ParserInterface[]
247
     */
248
    public function getParsers()
249
    {
250
        return $this->parsers;
251
    }
252
}
253