Completed
Push — master ( f97949...b57571 )
by Michael
02:55
created

ConfigFileProcessingTrait   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 97
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 2

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 9
c 0
b 0
f 0
lcom 0
cbo 2
dl 0
loc 97
ccs 0
cts 32
cp 0
rs 10

2 Methods

Rating   Name   Duplication   Size   Complexity  
C doSubstitutions() 0 36 7
A parserConfigFile() 0 12 2
1
<?php
2
declare(strict_types = 1);
3
/**
4
 * Contains trait ConfigFileProcessingTrait.
5
 *
6
 * PHP version 7.0+
7
 *
8
 * LICENSE:
9
 * This file is part of Yet Another Php Eve Api Library also know as Yapeal
10
 * which can be used to access the Eve Online API data and place it into a
11
 * database.
12
 * Copyright (C) 2016 Michael Cummings
13
 *
14
 * This program is free software: you can redistribute it and/or modify it
15
 * under the terms of the GNU Lesser General Public License as published by the
16
 * Free Software Foundation, either version 3 of the License, or (at your
17
 * option) any later version.
18
 *
19
 * This program is distributed in the hope that it will be useful, but WITHOUT
20
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
22
 * for more details.
23
 *
24
 * You should have received a copy of the GNU Lesser General Public License
25
 * along with this program. If not, see
26
 * <http://spdx.org/licenses/LGPL-3.0.html>.
27
 *
28
 * You should be able to find a copy of this license in the COPYING-LESSER.md
29
 * file. A copy of the GNU GPL should also be available in the COPYING.md file.
30
 *
31
 * @author    Michael Cummings <[email protected]>
32
 * @copyright 2016 Michael Cummings
33
 * @license   LGPL-3.0+
34
 */
35
namespace Yapeal\Configuration;
36
37
use Yapeal\Cli\Yapeal\YamlConfigFile;
38
use Yapeal\Container\ContainerInterface;
39
use Yapeal\FileSystem\SafeFileHandlingTrait;
40
41
/**
42
 * Trait ConfigFileProcessingTrait.
43
 */
44
trait ConfigFileProcessingTrait
45
{
46
    use SafeFileHandlingTrait;
47
    /**
48
     * Looks for and replaces any {Yapeal.*} it finds in values with the corresponding other setting value.
49
     *
50
     * This will replace full value or part of the value. Examples:
51
     *
52
     *     $settings = [
53
     *         'Yapeal.baseDir' => '/my/junk/path/Yapeal/',
54
     *         'Yapeal.libDir' => '{Yapeal.baseDir}lib/'
55
     *         'Yapeal.Sql.dir' => '{Yapeal.libDir}Sql/'
56
     *     ];
57
     *
58
     * After doSubstitutions would be:
59
     *
60
     *     $settings = [
61
     *         'Yapeal.baseDir' => '/my/junk/path/Yapeal/',
62
     *         'Yapeal.libDir' => '/my/junk/path/Yapeal/lib/'
63
     *         'Yapeal.Sql.dir' => '/my/junk/path/Yapeal/lib/Sql/'
64
     *     ];
65
     *
66
     * Note that order in which subs are done is undefined so it could have
67
     * done libDir first and then baseDir into both or done baseDir into libDir
68
     * then libDir into Sql.dir.
69
     *
70
     * Subs from within $settings itself are used first with $dic used to
71
     * fill-in as needed for any unknown ones.
72
     *
73
     * Subs are tried up to 10 times as long as any {Yapeal.*} are found before
74
     * giving up to prevent infinite loop.
75
     *
76
     * @param array              $settings
77
     * @param ContainerInterface $dic
78
     *
79
     * @return array
80
     * @throws \DomainException
81
     */
82
    protected function doSubstitutions(array $settings, ContainerInterface $dic): array
83
    {
84
        if (0 === count($settings)) {
85
            return [];
86
        }
87
        $depth = 0;
88
        $maxDepth = 10;
89
        $regEx = '%(?<all>\{(?<name>Yapeal(?:\.\w+)+)\})%';
90
        do {
91
            $settings = preg_replace_callback($regEx,
92
                function ($match) use ($settings, $dic) {
93
                    if (array_key_exists($match['name'], $settings)) {
94
                        return $settings[$match['name']];
95
                    }
96
                    if (!empty($dic[$match['name']])) {
97
                        return $dic[$match['name']];
98
                    }
99
                    return $match['all'];
100
                },
101
                $settings,
102
                -1,
103
                $count);
104
            if (++$depth > $maxDepth) {
105
                $mess = 'Exceeded maximum depth, check for possible circular reference(s)';
106
                throw new \DomainException($mess);
107
            }
108
            $lastError = preg_last_error();
109
            if (PREG_NO_ERROR !== $lastError) {
110
                $constants = array_flip(get_defined_constants(true)['pcre']);
111
                $lastError = $constants[$lastError];
112
                $mess = 'Received preg error ' . $lastError;
113
                throw new \DomainException($mess);
114
            }
115
        } while ($count > 0);
116
        return $settings;
117
    }
118
    /**
119
     * Converts any depth Yaml config file into a flattened array with '.' separators and values.
120
     *
121
     * @param string $configFile
122
     * @param array  $existing
123
     *
124
     * @return array
125
     * @throws \LogicException
126
     * @throws \DomainException
127
     */
128
    protected function parserConfigFile(string $configFile, array $existing = []): array
129
    {
130
        /**
131
         * @var YamlConfigFile $yaml
132
         */
133
        $yaml = $this->getDic()['Yapeal.Config.Yaml'];
0 ignored issues
show
Bug introduced by
It seems like getDic() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
134
        $settings = $yaml->setPathFile($configFile)->read()->getSettings();
135
        if (0 === count($settings)) {
136
            return $existing;
137
        }
138
        return array_replace($existing, $settings);
139
    }
140
}
141