Completed
Pull Request — master (#1)
by Greg
65:22 queued 63:19
created

SiteAliasFileDiscovery::filterByLocation()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

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