Completed
Push — master ( 56f069...08b4a2 )
by Greg
01:33
created

SiteAliasFileLoader   F

Complexity

Total Complexity 81

Size/Duplication

Total Lines 614
Duplicated Lines 5.05 %

Coupling/Cohesion

Components 1
Dependencies 6

Importance

Changes 0
Metric Value
wmc 81
lcom 1
cbo 6
dl 31
loc 614
rs 1.986
c 0
b 0
f 0

32 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 2
A setReferenceData() 0 4 1
A setRoot() 0 4 1
A addSearchLocation() 0 5 1
A discovery() 0 4 1
A load() 0 24 3
A loadDefaultEnvFromSitename() 0 16 3
A loadAll() 0 15 4
A listAll() 0 4 1
A loadMultiple() 15 15 3
A loadLocation() 16 16 3
A createSiteAliassFromSiteData() 0 17 6
A isValidEnvName() 0 4 1
A storeSiteAliasInResut() 0 12 3
A loadSingleAliasFile() 0 12 2
A loadSingleSiteAliasFileAtPath() 0 9 2
A siteNameFromPath() 0 8 1
A basenameWithoutExtension() 0 9 2
A loadSingleAliasFileWithNameAtPath() 0 9 2
A loadSiteDataFromPath() 0 10 2
A findSelfSiteAliases() 0 13 5
A loadSelfSiteData() 0 13 4
A loadData() 0 11 4
A getLoader() 0 7 2
A addLoader() 0 4 1
A fetchSiteAliasFromSiteAliasData() 0 20 3
A getRequestedEnvData() 0 14 3
A siteEnvExists() 0 8 3
A adjustIfSingleAlias() 0 12 2
A detectSingleAlias() 0 9 4
A getEnvironmentName() 0 9 2
A getDefaultEnvironmentName() 0 16 4

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like SiteAliasFileLoader often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use SiteAliasFileLoader, and based on these observations, apply Extract Interface, too.

1
<?php
2
namespace Consolidation\SiteAlias;
3
4
use Consolidation\Config\Loader\ConfigProcessor;
5
use Dflydev\DotAccessData\Util as DotAccessDataUtil;
6
7
/**
8
 * Discover alias files:
9
 *
10
 * - sitename.site.yml: contains multiple aliases, one for each of the
11
 *     environments of 'sitename'.
12
 */
13
class SiteAliasFileLoader
14
{
15
    /**
16
     * @var SiteAliasFileDiscovery
17
     */
18
    protected $discovery;
19
20
    /**
21
     * @var array
22
     */
23
    protected $referenceData;
24
25
    /**
26
     * @var array
27
     */
28
    protected $loader;
29
30
    /**
31
     * @var string
32
     */
33
    protected $root;
34
35
    /**
36
     * SiteAliasFileLoader constructor
37
     *
38
     * @param SiteAliasFileDiscovery|null $discovery
39
     */
40
    public function __construct($discovery = null)
41
    {
42
        $this->discovery = $discovery ?: new SiteAliasFileDiscovery();
43
        $this->referenceData = [];
44
        $this->loader = [];
45
    }
46
47
    /**
48
     * Allow configuration data to be used in replacements in the alias file.
49
     */
50
    public function setReferenceData($data)
51
    {
52
        $this->referenceData = $data;
53
    }
54
55
    /**
56
     * Allow 'self.site.yml' to be applied to any alias record found.
57
     */
58
    public function setRoot($root)
59
    {
60
        $this->root = $root;
61
    }
62
63
    /**
64
     * Add a search location to our discovery object.
65
     *
66
     * @param string $path
67
     *
68
     * @return $this
69
     */
70
    public function addSearchLocation($path)
71
    {
72
        $this->discovery()->addSearchLocation($path);
73
        return $this;
74
    }
75
76
    /**
77
     * Return our discovery object.
78
     *
79
     * @return SiteAliasFileDiscovery
80
     */
81
    public function discovery()
82
    {
83
        return $this->discovery;
84
    }
85
86
    /**
87
     * Load the file containing the specified alias name.
88
     *
89
     * @param SiteAliasName $aliasName
90
     *
91
     * @return SiteAlias|false
92
     */
93
    public function load(SiteAliasName $aliasName)
94
    {
95
        // First attempt to load a sitename.site.yml file for the alias.
96
        $aliasRecord = $this->loadSingleAliasFile($aliasName);
97
        if ($aliasRecord) {
98
            return $aliasRecord;
99
        }
100
101
        // If aliasname was provides as @site.env and we did not find it,
102
        // then we are done.
103
        if ($aliasName->hasSitename()) {
104
            return false;
105
        }
106
107
        // If $aliasName was provided as `@foo` (`hasSitename()` returned `false`
108
        // above), then this was interpreted as `@self.foo` when we searched
109
        // above. If we could not find an alias record for `@self.foo`, then we
110
        // will try to search again, this time with the assumption that `@foo`
111
        // might be `@foo.<default>`, where `<default>` is the default
112
        // environment for the specified site. Note that in this instance, the
113
        // sitename will be found in $aliasName->env().
114
        $sitename = $aliasName->env();
115
        return $this->loadDefaultEnvFromSitename($sitename);
116
    }
117
118
    /**
119
     * Given only a site name, load the default environment from it.
120
     */
121
    protected function loadDefaultEnvFromSitename($sitename)
122
    {
123
        $path = $this->discovery()->findSingleSiteAliasFile($sitename);
124
        if (!$path) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $path of type false|string is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
125
            return false;
126
        }
127
        $data = $this->loadSiteDataFromPath($path);
128
        if (!$data) {
129
            return false;
130
        }
131
        $env = $this->getDefaultEnvironmentName($data);
132
133
        $aliasName = new SiteAliasName($sitename, $env);
134
        $processor = new ConfigProcessor();
135
        return $this->fetchSiteAliasFromSiteAliasData($aliasName, $processor, $data);
136
    }
137
138
    /**
139
     * Return a list of all site aliases loadable from any findable path.
140
     *
141
     * @return SiteAlias[]
142
     */
143
    public function loadAll()
144
    {
145
        $result = [];
146
        $paths = $this->discovery()->findAllSingleAliasFiles();
147
        foreach ($paths as $path) {
148
            $aliasRecords = $this->loadSingleSiteAliasFileAtPath($path);
149
            if ($aliasRecords) {
150
                foreach ($aliasRecords as $aliasRecord) {
151
                    $this->storeSiteAliasInResut($result, $aliasRecord);
152
                }
153
            }
154
        }
155
        ksort($result);
156
        return $result;
157
    }
158
159
    /**
160
     * Return a list of all available alias files. Does not include
161
     * legacy files.
162
     *
163
     * @param string $location Only consider alias files in the specified location.
164
     * @return string[]
165
     */
166
    public function listAll($location = '')
167
    {
168
        return $this->discovery()->filterByLocation($location)->findAllSingleAliasFiles();
169
    }
170
171
    /**
172
     * Given an alias name that might represent multiple sites,
173
     * return a list of all matching alias records. If nothing was found,
174
     * or the name represents a single site + env, then we take
175
     * no action and return `false`.
176
     *
177
     * @param string $sitename The site name to return all environments for.
178
     * @return SiteAlias[]|false
179
     */
180 View Code Duplication
    public function loadMultiple($sitename, $location = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
181
    {
182
        $result = [];
183
        foreach ($this->discovery()->filterByLocation($location)->find($sitename) as $path) {
184
            if ($siteData = $this->loadSiteDataFromPath($path)) {
185
                $location = SiteAliasName::locationFromPath($path);
0 ignored issues
show
Documentation introduced by
$path is of type string, but the function expects a object<Consolidation\SiteAlias\type>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
186
                // Convert the raw array into a list of alias records.
187
                $result = array_merge(
188
                    $result,
189
                    $this->createSiteAliassFromSiteData($sitename, $siteData, $location)
190
                );
191
            }
192
        }
193
        return $result;
194
    }
195
196
    /**
197
     * Given a location, return all alias files located there.
198
     *
199
     * @param string $location The location to filter.
200
     * @return SiteAlias[]
201
     */
202 View Code Duplication
    public function loadLocation($location)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
203
    {
204
        $result = [];
205
        foreach ($this->listAll($location) as $path) {
206
            if ($siteData = $this->loadSiteDataFromPath($path)) {
207
                $location = SiteAliasName::locationFromPath($path);
0 ignored issues
show
Documentation introduced by
$path is of type string, but the function expects a object<Consolidation\SiteAlias\type>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
208
                $sitename = $this->siteNameFromPath($path);
209
                // Convert the raw array into a list of alias records.
210
                $result = array_merge(
211
                    $result,
212
                    $this->createSiteAliassFromSiteData($sitename, $siteData, $location)
213
                );
214
            }
215
        }
216
        return $result;
217
    }
218
219
    /**
220
     * @param array $siteData list of sites with its respective data
221
     *
222
     * @param SiteAliasName $aliasName The name of the record being created
0 ignored issues
show
Bug introduced by
There is no parameter named $aliasName. 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...
223
     * @param $siteData An associative array of envrionment => site data
224
     * @return SiteAlias[]
225
     */
226
    protected function createSiteAliassFromSiteData($sitename, $siteData, $location = '')
227
    {
228
        $result = [];
229
        if (!is_array($siteData) || empty($siteData)) {
230
            return $result;
231
        }
232
        foreach ($siteData as $envName => $data) {
233
            if (is_array($data) && $this->isValidEnvName($envName)) {
234
                $aliasName = new SiteAliasName($sitename, $envName, $location);
235
236
                $processor = new ConfigProcessor();
237
                $oneRecord = $this->fetchSiteAliasFromSiteAliasData($aliasName, $processor, $siteData);
238
                $this->storeSiteAliasInResut($result, $oneRecord);
0 ignored issues
show
Security Bug introduced by
It seems like $oneRecord defined by $this->fetchSiteAliasFro... $processor, $siteData) on line 237 can also be of type false; however, Consolidation\SiteAlias\...storeSiteAliasInResut() does only seem to accept object<Consolidation\SiteAlias\SiteAlias>, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
239
            }
240
        }
241
        return $result;
242
    }
243
244
    /**
245
     * isValidEnvName determines if a given entry should be skipped or not
246
     * (e.g. the "common" entry).
247
     *
248
     * @param string $envName The environment name to test
249
     */
250
    protected function isValidEnvName($envName)
251
    {
252
        return $envName != 'common';
253
    }
254
255
    /**
256
     * Store an alias record in a list. If the alias record has
257
     * a known name, then the key of the list will be the record's name.
258
     * Otherwise, append the record to the end of the list with
259
     * a numeric index.
260
     *
261
     * @param &SiteAlias[] $result list of alias records
0 ignored issues
show
Documentation introduced by
The doc-type &SiteAlias[] could not be parsed: Unknown type name "&SiteAlias" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
262
     * @param SiteAlias $aliasRecord one more alias to store in the result
263
     */
264
    protected function storeSiteAliasInResut(&$result, SiteAlias $aliasRecord)
265
    {
266
        if (!$aliasRecord) {
267
            return;
268
        }
269
        $key = $aliasRecord->name();
270
        if (empty($key)) {
271
            $result[] = $aliasRecord;
272
            return;
273
        }
274
        $result[$key] = $aliasRecord;
275
    }
276
277
    /**
278
     * If the alias name is '@sitename', or if it is '@sitename.env', then
279
     * look for a sitename.site.yml file that contains it. We also handle
280
     * '@location.sitename.env' here as well.
281
     *
282
     * @param SiteAliasName $aliasName
283
     *
284
     * @return SiteAlias|false
285
     */
286
    protected function loadSingleAliasFile(SiteAliasName $aliasName)
287
    {
288
        // Check to see if the appropriate sitename.alias.yml file can be
289
        // found. Return if it cannot.
290
        $path = $this->discovery()
291
            ->filterByLocation($aliasName->location())
292
            ->findSingleSiteAliasFile($aliasName->sitename());
293
        if (!$path) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $path of type false|string is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
294
            return false;
295
        }
296
        return $this->loadSingleAliasFileWithNameAtPath($aliasName, $path);
297
    }
298
299
    /**
300
     * Given only the path to an alias file `site.alias.yml`, return all
301
     * of the alias records for every environment stored in that file.
302
     *
303
     * @param string $path
304
     * @return SiteAlias[]
305
     */
306
    protected function loadSingleSiteAliasFileAtPath($path)
307
    {
308
        $sitename = $this->siteNameFromPath($path);
309
        $location = SiteAliasName::locationFromPath($path);
0 ignored issues
show
Documentation introduced by
$path is of type string, but the function expects a object<Consolidation\SiteAlias\type>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
310
        if ($siteData = $this->loadSiteDataFromPath($path)) {
311
            return $this->createSiteAliassFromSiteData($sitename, $siteData, $location);
312
        }
313
        return false;
314
    }
315
316
    /**
317
     * Given the path to a single site alias file `site.alias.yml`,
318
     * return the `site` part.
319
     *
320
     * @param string $path
321
     */
322
    protected function siteNameFromPath($path)
323
    {
324
        return $this->basenameWithoutExtension($path, '.site.yml');
325
326
// OR:
327
//        $filename = basename($path);
328
//        return preg_replace('#\..*##', '', $filename);
329
    }
330
331
    /**
332
     * Chop off the `aliases.yml` or `alias.yml` part of a path. This works
333
     * just like `basename`, except it will throw if the provided path
334
     * does not end in the specified extension.
335
     *
336
     * @param string $path
337
     * @param string $extension
338
     * @return string
339
     * @throws \Exception
340
     */
341
    protected function basenameWithoutExtension($path, $extension)
342
    {
343
        $result = basename($path, $extension);
344
        // It is an error if $path does not end with site.yml
345
        if ($result == basename($path)) {
346
            throw new \Exception("$path must end with '$extension'");
347
        }
348
        return $result;
349
    }
350
351
    /**
352
     * Given an alias name and a path, load the data from the path
353
     * and process it as needed to generate the alias record.
354
     *
355
     * @param SiteAliasName $aliasName
356
     * @param string $path
357
     * @return SiteAlias|false
358
     */
359
    protected function loadSingleAliasFileWithNameAtPath(SiteAliasName $aliasName, $path)
360
    {
361
        $data = $this->loadSiteDataFromPath($path);
362
        if (!$data) {
363
            return false;
364
        }
365
        $processor = new ConfigProcessor();
366
        return $this->fetchSiteAliasFromSiteAliasData($aliasName, $processor, $data);
367
    }
368
369
    /**
370
     * Load the yml from the given path
371
     *
372
     * @param string $path
373
     * @return array|bool
374
     */
375
    protected function loadSiteDataFromPath($path)
376
    {
377
        $data = $this->loadData($path);
378
        if (!$data) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $data of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
379
            return false;
380
        }
381
        $selfSiteAliases = $this->findSelfSiteAliases($data, $path);
382
        $data = array_merge($data, $selfSiteAliases);
383
        return $data;
384
    }
385
386
    /**
387
     * Given an array of site aliases, find the first one that is
388
     * local (has no 'host' item) and also contains a 'self.site.yml' file.
389
     * @param array $data
0 ignored issues
show
Bug introduced by
There is no parameter named $data. 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...
390
     * @return array
391
     */
392
    protected function findSelfSiteAliases($site_aliases, $path)
0 ignored issues
show
Unused Code introduced by
The parameter $path is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
393
    {
394
        foreach ($site_aliases as $site => $data) {
395
            if (!isset($data['host']) && isset($data['root'])) {
396
                $data = $this->loadSelfSiteData($data['root']);
397
                if (!empty($data)) {
398
                    return $data;
399
                }
400
            }
401
        }
402
403
        return $this->loadSelfSiteData($this->root);
404
    }
405
406
    /**
407
     * Check to see if there is a 'drush/sites/self.site.yml' file at
408
     * the provided root, or one directory up from there.
409
     */
410
    protected function loadSelfSiteData($root)
411
    {
412
        if (!$root) {
413
            return [];
414
        }
415
        foreach (['.', '..'] as $relative_path) {
416
            $candidate = $root . '/' . $relative_path . '/drush/sites/self.site.yml';
417
            if (file_exists($candidate)) {
418
                return $this->loadData($candidate);
419
            }
420
        }
421
        return [];
422
    }
423
424
    /**
425
     * Load the contents of the specified file.
426
     *
427
     * @param string $path Path to file to load
428
     * @return array
429
     */
430
    protected function loadData($path)
431
    {
432
        if (empty($path) || !file_exists($path)) {
433
            return [];
434
        }
435
        $loader = $this->getLoader(pathinfo($path, PATHINFO_EXTENSION));
436
        if (!$loader) {
437
            return [];
438
        }
439
        return $loader->load($path);
440
    }
441
442
    /**
443
     * @return DataFileLoaderInterface
444
     */
445
    public function getLoader($extension)
446
    {
447
        if (!isset($this->loader[$extension])) {
448
            return null;
449
        }
450
        return $this->loader[$extension];
451
    }
452
453
    public function addLoader($extension, DataFileLoaderInterface $loader)
454
    {
455
        $this->loader[$extension] = $loader;
456
    }
457
458
    /**
459
     * Given an array containing site alias data, return an alias record
460
     * containing the data for the requested record. If there is a 'common'
461
     * section, then merge that in as well.
462
     *
463
     * @param SiteAliasName $aliasName the alias we are loading
464
     * @param array $data
465
     *
466
     * @return SiteAlias|false
467
     */
468
    protected function fetchSiteAliasFromSiteAliasData(SiteAliasName $aliasName, ConfigProcessor $processor, array $data)
469
    {
470
        $data = $this->adjustIfSingleAlias($data);
471
        $env = $this->getEnvironmentName($aliasName, $data);
472
        $env_data = $this->getRequestedEnvData($data, $env);
473
        if (!$env_data) {
474
            return false;
475
        }
476
477
        // Add the 'common' section if it exists.
478
        if ($this->siteEnvExists($data, 'common')) {
479
            $processor->add($data['common']);
480
        }
481
482
        // Then add the data from the desired environment.
483
        $processor->add($env_data);
484
485
        // Export the combined data and create an SiteAlias object to manage it.
486
        return new SiteAlias($processor->export($this->referenceData + ['env-name' => $env]), '@' . $aliasName->sitenameWithLocation(), $env);
487
    }
488
489
    /**
490
     * getRequestedEnvData fetches the data for the specified environment
491
     * from the provided site record data.
492
     *
493
     * @param array $data The site alias data
494
     * @param string $env The name of the environment desired
495
     * @return array|false
496
     */
497
    protected function getRequestedEnvData(array $data, $env)
498
    {
499
        // If the requested environment exists, we will use it.
500
        if ($this->siteEnvExists($data, $env)) {
501
            return $data[$env];
502
        }
503
504
        // If there is a wildcard environment, then return that instead.
505
        if ($this->siteEnvExists($data, '*')) {
506
            return $data['*'];
507
        }
508
509
        return false;
510
    }
511
512
    /**
513
     * Determine whether there is a valid-looking environment '$env' in the
514
     * provided site alias data.
515
     *
516
     * @param array $data
517
     * @param string $env
518
     * @return bool
519
     */
520
    protected function siteEnvExists(array $data, $env)
521
    {
522
        return (
523
            is_array($data) &&
524
            isset($data[$env]) &&
525
            is_array($data[$env])
526
        );
527
    }
528
529
    /**
530
     * Adjust the alias data for a single-site alias. Usually, a .yml alias
531
     * file will contain multiple entries, one for each of the environments
532
     * of an alias. If there are no environments
533
     *
534
     * @param array $data
535
     * @return array
536
     */
537
    protected function adjustIfSingleAlias($data)
538
    {
539
        if (!$this->detectSingleAlias($data)) {
540
            return $data;
541
        }
542
543
        $result = [
544
            'default' => $data,
545
        ];
546
547
        return $result;
548
    }
549
550
    /**
551
     * A single-environment alias looks something like this:
552
     *
553
     *   ---
554
     *   root: /path/to/drupal
555
     *   uri: https://mysite.org
556
     *
557
     * A multiple-environment alias looks something like this:
558
     *
559
     *   ---
560
     *   default: dev
561
     *   dev:
562
     *     root: /path/to/dev
563
     *     uri: https://dev.mysite.org
564
     *   stage:
565
     *     root: /path/to/stage
566
     *     uri: https://stage.mysite.org
567
     *
568
     * The differentiator between these two is that the multi-environment
569
     * alias always has top-level elements that are associative arrays, and
570
     * the single-environment alias never does.
571
     *
572
     * @param array $data
573
     * @return bool
574
     */
575
    protected function detectSingleAlias($data)
576
    {
577
        foreach ($data as $key => $value) {
578
            if (is_array($value) && DotAccessDataUtil::isAssoc($value)) {
579
                return false;
580
            }
581
        }
582
        return true;
583
    }
584
585
    /**
586
     * Return the name of the environment requested.
587
     *
588
     * @param SiteAliasName $aliasName the alias we are loading
589
     * @param array $data
590
     *
591
     * @return string
592
     */
593
    protected function getEnvironmentName(SiteAliasName $aliasName, array $data)
594
    {
595
        // If the alias name specifically mentions the environment
596
        // to use, then return it.
597
        if ($aliasName->hasEnv()) {
598
            return $aliasName->env();
599
        }
600
        return $this->getDefaultEnvironmentName($data);
601
    }
602
603
    /**
604
     * Given a data array containing site alias environments, determine which
605
     * envirionmnet should be used as the default environment.
606
     *
607
     * @param array $data
608
     * @return string
609
     */
610
    protected function getDefaultEnvironmentName(array $data)
611
    {
612
        // If there is an entry named 'default', it will either contain the
613
        // name of the environment to use by default, or it will itself be
614
        // the default environment.
615
        if (isset($data['default'])) {
616
            return is_array($data['default']) ? 'default' : $data['default'];
617
        }
618
        // If there is an environment named 'dev', it will be our default.
619
        if (isset($data['dev'])) {
620
            return 'dev';
621
        }
622
        // If we don't know which environment to use, just take the first one.
623
        $keys = array_keys($data);
624
        return reset($keys);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The expression reset($keys); of type string|false adds false to the return on line 624 which is incompatible with the return type documented by Consolidation\SiteAlias\...tDefaultEnvironmentName of type string. It seems like you forgot to handle an error condition.
Loading history...
625
    }
626
}
627