Completed
Push — master ( f42a52...0a9499 )
by Thierry
02:50 queued 01:16
created

Config::_setOptions()   B

Complexity

Conditions 7
Paths 7

Size

Total Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
nc 7
nop 3
dl 0
loc 29
rs 8.5226
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Config.php - Jaxon config manager
5
 *
6
 * Read and set Jaxon config options.
7
 *
8
 * @package jaxon-core
9
 * @author Thierry Feuzeu <[email protected]>
10
 * @copyright 2016 Thierry Feuzeu <[email protected]>
11
 * @license https://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
12
 * @link https://github.com/jaxon-php/jaxon-core
13
 */
14
15
namespace Jaxon\Utils\Config;
16
17
class Config
18
{
19
    /**
20
     * The config options
21
     *
22
     * @var array
23
     */
24
    protected $aOptions = [];
25
26
    /**
27
     * The constructor
28
     *
29
     * @param array             $aOptions           The options array
30
     * @param string            $sKeys              The keys of the options in the array
31
     *
32
     * @param array
33
     */
34
    public function __construct(array $aOptions = [], $sKeys = '')
35
    {
36
        if(count($aOptions) > 0)
37
        {
38
            $this->setOptions($aOptions, $sKeys);
39
        }
40
    }
41
42
    /**
43
     * Set the value of a config option
44
     *
45
     * @param string            $sName              The option name
46
     * @param mixed             $xValue             The option value
47
     *
48
     * @return void
49
     */
50
    public function setOption($sName, $xValue)
51
    {
52
        $this->aOptions[$sName] = $xValue;
53
    }
54
55
    /**
56
     * Recursively set Jaxon options from a data array
57
     *
58
     * @param array             $aOptions           The options array
59
     * @param string            $sPrefix            The prefix for option names
60
     * @param integer           $nDepth             The depth from the first call
61
     *
62
     * @return void
63
     */
64
    private function _setOptions(array $aOptions, $sPrefix = '', $nDepth = 0)
65
    {
66
        $sPrefix = trim((string)$sPrefix);
67
        $nDepth = intval($nDepth);
68
        // Check the max depth
69
        if($nDepth < 0 || $nDepth > 9)
70
        {
71
            throw new \Jaxon\Utils\Config\Exception\Data(jaxon_trans('config.errors.data.depth',
72
                ['key' => $sPrefix, 'depth' => $nDepth]));
73
        }
74
        foreach($aOptions as $sName => $xOption)
75
        {
76
            if(is_int($sName))
77
            {
78
                continue;
79
            }
80
81
            $sName = trim($sName);
82
            $sFullName = ($sPrefix) ? $sPrefix . '.' . $sName : $sName;
83
            // Save the value of this option
84
            $this->aOptions[$sFullName] = $xOption;
85
            // Save the values of its sub-options
86
            if(is_array($xOption))
87
            {
88
                // Recursively read the options in the array
89
                $this->_setOptions($xOption, $sFullName, $nDepth + 1);
90
            }
91
        }
92
    }
93
94
    /**
95
     * Set the values of an array of config options
96
     *
97
     * @param array             $aOptions           The options array
98
     * @param string            $sKeys              The keys of the options in the array
99
     *
100
     * @return Config
101
     */
102
    public function setOptions(array $aOptions, $sKeys = '')
103
    {
104
        // Find the config array in the input data
105
        $aKeys = explode('.', (string)$sKeys);
106
        foreach ($aKeys as $sKey)
107
        {
108
            if(($sKey))
109
            {
110
                if(!array_key_exists($sKey, $aOptions) || !is_array($aOptions[$sKey]))
111
                {
112
                    return;
113
                }
114
                $aOptions = $aOptions[$sKey];
115
            }
116
        }
117
        $this->_setOptions($aOptions);
118
119
        return $this;
120
    }
121
122
    /**
123
     * Get the value of a config option
124
     *
125
     * @param string            $sName              The option name
126
     * @param mixed             $xDefault           The default value, to be returned if the option is not defined
127
     *
128
     * @return mixed            The option value, or its default value
129
     */
130
    public function getOption($sName, $xDefault = null)
131
    {
132
        return (array_key_exists($sName, $this->aOptions) ? $this->aOptions[$sName] : $xDefault);
133
    }
134
135
    /**
136
     * Check the presence of a config option
137
     *
138
     * @param string            $sName              The option name
139
     *
140
     * @return bool             True if the option exists, and false if not
141
     */
142
    public function hasOption($sName)
143
    {
144
        return array_key_exists($sName, $this->aOptions);
145
    }
146
147
    /**
148
     * Get the names of the options matching a given prefix
149
     *
150
     * @param string            $sPrefix            The prefix to match
151
     *
152
     * @return array            The options matching the prefix
153
     */
154
    public function getOptionNames($sPrefix)
155
    {
156
        $sPrefix = trim((string)$sPrefix);
157
        $sPrefix = rtrim($sPrefix, '.') . '.';
158
        $sPrefixLen = strlen($sPrefix);
159
        $aOptions = [];
160
        foreach($this->aOptions as $sName => $xValue)
161
        {
162
            if(substr($sName, 0, $sPrefixLen) == $sPrefix)
163
            {
164
                $iNextDotPos = strpos($sName, '.', $sPrefixLen);
165
                $sOptionName = $iNextDotPos === false ? substr($sName, $sPrefixLen) :
166
                    substr($sName, $sPrefixLen, $iNextDotPos - $sPrefixLen);
167
                $aOptions[$sOptionName] = $sPrefix . $sOptionName;
168
            }
169
        }
170
        return $aOptions;
171
    }
172
}
173