Completed
Push — master ( afa40a...8eb04e )
by Greg
01:25
created

SiteAliasFileDiscovery::splitLocationFromSite()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
namespace Consolidation\SiteAlias;
3
4
use Symfony\Component\Finder\Finder;
5
6
/**
7
 * Discover alias files named:
8
 *
9
 * - sitename.site.yml: contains multiple aliases, one for each of the
10
 *     environments of 'sitename'.
11
 *
12
 * Drush aliases that contain both a site name and an environment
13
 * (e.g. @site.env) will cause Drush to find the file named after
14
 * the respective site name and retrieve the specified environment
15
 * record.
16
 *
17
 * Sites may also define a special alias file self.site.yml, which
18
 * may be stored in the drush/sites directory relative to either
19
 * the Drupal root or the Composer root of the site. The environments
20
 * in this file will be merged with the available environments for
21
 * the element @self, however it is defined.
22
 */
23
class SiteAliasFileDiscovery
24
{
25
    protected $searchLocations;
26
    protected $locationFilter;
27
    protected $depth;
28
29
    public function __construct($searchLocations = [], $depth = '<= 1', $locationFilter = null)
30
    {
31
        $this->locationFilter = $locationFilter;
32
        $this->searchLocations = $searchLocations;
33
        $this->depth = $depth;
34
    }
35
36
    /**
37
     * Add a location that alias files may be found.
38
     *
39
     * @param string $path
0 ignored issues
show
Bug introduced by
There is no parameter named $path. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
40
     * @return $this
41
     */
42
    public function addSearchLocation($paths)
43
    {
44
        foreach ((array)$paths as $path) {
45
            if (is_dir($path)) {
46
                $this->searchLocations[] = $path;
47
            }
48
        }
49
        return $this;
50
    }
51
52
    /**
53
     * Return all of the paths where alias files may be found.
54
     * @return string[]
55
     */
56
    public function searchLocations()
57
    {
58
        return $this->searchLocations;
59
    }
60
61
    public function locationFilter()
62
    {
63
        return $this->locationFilter;
64
    }
65
66
    /**
67
     * Set the search depth for finding alias files
68
     *
69
     * @param string|int $depth (@see \Symfony\Component\Finder\Finder::depth)
70
     * @return $this
71
     */
72
    public function depth($depth)
73
    {
74
        $this->depth = $depth;
75
        return $this;
76
    }
77
78
    /**
79
     * Only search for aliases that are in alias files stored in directories
80
     * whose basename or key matches the specified location.
81
     */
82
    public function filterByLocation($location)
83
    {
84
        if (empty($location)) {
85
            return $this;
86
        }
87
88
        return new SiteAliasFileDiscovery($this->searchLocations(), $this->depth, $location);
89
    }
90
91
    /**
92
     * Find an alias file SITENAME.site.yml in one
93
     * of the specified search locations.
94
     *
95
     * @param string $siteName
96
     * @return string[]
97
     */
98
    public function find($siteName)
99
    {
100
        return $this->searchForAliasFiles("$siteName.site.yml");
101
    }
102
103
    /**
104
     * Find an alias file SITENAME.site.yml in one
105
     * of the specified search locations.
106
     *
107
     * @param string $siteName
108
     * @return string|bool
109
     */
110
    public function findSingleSiteAliasFile($siteName)
111
    {
112
        $matches = $this->find($siteName);
113
        if (empty($matches)) {
114
            return false;
115
        }
116
        return reset($matches);
117
    }
118
119
    /**
120
     * Return a list of all SITENAME.site.yml files in any of
121
     * the search locations.
122
     *
123
     * @return string[]
124
     */
125
    public function findAllSingleAliasFiles()
126
    {
127
        return $this->searchForAliasFiles('*.site.yml');
128
    }
129
130
    /**
131
     * Return all of the legacy alias files used in previous Drush versions.
132
     *
133
     * @return string[]
134
     */
135
    public function findAllLegacyAliasFiles()
136
    {
137
        return array_merge(
138
            $this->searchForAliasFiles('*.alias.drushrc.php'),
139
            $this->searchForAliasFiles('*.aliases.drushrc.php'),
140
            $this->searchForAliasFiles('aliases.drushrc.php')
141
        );
142
    }
143
144
    /**
145
     * Create a Symfony Finder object to search all available search locations
146
     * for the specified search pattern.
147
     *
148
     * @param string $searchPattern
149
     * @return Finder
150
     */
151
    protected function createFinder($searchPattern)
152
    {
153
        $finder = new Finder();
154
        $finder->files()
155
            ->name($searchPattern)
156
            ->in($this->searchLocations)
157
            ->depth($this->depth);
158
        return $finder;
159
    }
160
161
    /**
162
     * Return a list of all alias files matching the provided pattern.
163
     *
164
     * @param string $searchPattern
165
     * @return string[]
166
     */
167
    protected function searchForAliasFiles($searchPattern)
168
    {
169
        if (empty($this->searchLocations)) {
170
            return [];
171
        }
172
        list($match, $site) = $this->splitLocationFromSite($this->locationFilter);
173
        if (!empty($site)) {
174
            $searchPattern = str_replace('*', $site, $searchPattern);
175
        }
176
        $finder = $this->createFinder($searchPattern);
177
        $result = [];
178
        foreach ($finder as $file) {
179
            $path = $file->getRealPath();
180
            $result[] = $path;
181
        }
182
        // Find every location where the parent directory name matches
183
        // with the first part of the search pattern.
184
        // In theory we can use $finder->path() instead. That didn't work well,
185
        // in practice, though; had trouble correctly escaping the path separators.
186
        if (!empty($this->locationFilter)) {
187
            $result = array_filter($result, function ($path) use ($match) {
188
                return SiteAliasName::locationFromPath($path) === $match;
189
            });
190
        }
191
192
        return $result;
193
    }
194
195
    /**
196
     * splitLocationFromSite returns the part of 'site' before the first
197
     * '.' as the "path match" component, and the part after the first
198
     * '.' as the "site" component.
199
     */
200
    protected function splitLocationFromSite($site)
201
    {
202
        $parts = explode('.', $site, 3) + ['', '', ''];
203
204
        return array_slice($parts, 0, 2);
205
    }
206
207
208
    // TODO: Seems like this could just be basename()
209
    protected function extractKey($basename, $filenameExensions)
210
    {
211
        return str_replace($filenameExensions, '', $basename);
212
    }
213
}
214