Completed
Branch master (3c175d)
by Alfred
03:21 queued 01:31
created

ConfigManager::Save()   C

Complexity

Conditions 12
Paths 71

Size

Total Lines 44
Code Lines 37

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 12
eloc 37
nc 71
nop 0
dl 0
loc 44
rs 6.9666
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
namespace Iriven;
3
use Exception;
4
/**
5
 * Created by PhpStorm.
6
 * User: IRIVEN FRANCE
7
 * Date: 21/11/2015
8
 * Time: 10:44
9
 */
10
class ConfigManager
11
{
12
    /**
13
    * Chemin complet du fichier de configuration
14
    */
15
    private $targetFile;
16
    private $Options = [];
17
    /**
18
    * tableau multidimensionnel contenant les donnée de configuration, initialement
19
    * chargées depuis le fichier
20
    */
21
    private $Config = [];
22
    /**
23
    * processeurs de fichier pris en charge par l'application
24
    */
25
    private $availableDrivers = array('JSON', 'PHP','INI','YML');
26
27
    private $defaultSection = 'runtime';
28
29
    /**
30
     * @param $filename
31
     * @param $location
32
     * @throws \Exception
33
     */
34
    public function __construct( $filename, $location=null )
35
    {
36
        $numargs = func_num_args();
37
        try
38
        {
39
            if($numargs > 2)
40
                throw new Exception('SETUP ERROR: configuration manager can accept only up to 2 parameters,'.$numargs.' given!');
41
            $this->configureOptions($filename,$location);
42
            $this->parseConfiguration($this->Options);
43
            return $this;
44
        }
45
        catch(Exception $a)
46
        {
47
            trigger_error($a->getMessage(),E_USER_ERROR);
48
        }
49
    }
50
 /**
51
     * @param $section
52
     * @param $item
53
     * @return array|bool|mixed
54
     */
55
    public function get($section=null, $item=null)
56
    {
57
        if($item) $item = trim(strtolower($item));
58
        if($section) $section = trim(strtolower($section));
59
        if(!count($this->Config)) return false;
60
        if(!$section or !strlen($section)) return $this->Config;
61
        if($section AND $item)
62
        {
63
            if(!isset($this->Config[$section]))
64
            {
65
                $key = $item;
66
                $item = $section;
67
                $section = $this->defaultSection;
68
                if(!isset($this->Config[$section][$item][$key]))
69
                    return false;
70
                return $this->Config[$section][$item][$key];
71
            }
72
        }
73
        elseif(!$item or !strlen($item))
74
        {
75
            $item = $section;
76
            if(isset($this->Config[$item])) return $this->Config[$item];
77
            $section = $this->defaultSection;
78
        }
79
        if(!isset($this->Config[$section][$item])) return false;
80
        return $this->Config[$section][$item];
81
    }
82
83
 /**
84
     * @param $section
85
     * @param $item
86
     * @param $value
87
     * @return bool
88
     */
89
    public function set($section,$item=null,$value=null)
90
    { 
91
        ob_start();
92
        $numarg = func_num_args();
93
        $arguments=func_get_args();
94
        switch($numarg)
95
        {
96
            case 1:
97
                if(!is_array($arguments[0])) return false;
98
                $item=array_change_key_case($arguments[0], CASE_LOWER); $section=null; $value=null;	
99
		break;
100
            case 2:
101
                if(is_array($arguments[0])) return false;
102
                $_arg = strtolower(trim($arguments[0]));
103
                if(is_array($arguments[1])){ $section=$_arg; $item =array_change_key_case($arguments[1], CASE_LOWER);$value=null;}
104
                else {$item = $_arg;$value=$arguments[1];$section=null;}
105
                break;
106
            default:
107
                break;
108
        }
109
        $section = $section? trim(strtolower($section)) : $this->defaultSection;
110
        if(!is_array($item))
111
        {
112
            if(!$value) return false;
113
            $item=trim(strtolower($item));
114
            if(!isset($this->Config[$section][$item]) or !is_array($this->Config[$section][$item])):
115
                $this->Config[$section][$item]=$value;
116
            else:
117
                if(!is_array($value)) $value = array($value);
118
                $this->Config[$section][$item] = array_merge($this->Config[$section][$item],$value);
119
            endif;
120
        }
121
        else
122
        {
123
            if($value) return false;
124
            $item = array_change_key_case($item, CASE_LOWER);
125
            $sectionsize = count($this->Config[$section]);
126
            $itemsize = count($item);
127
            if($sectionsize)
128
            {
129
                if($itemsize=='1')
130
                {
131
                    if(isset($this->Config[$section][key($item)]))
132
                        $this->Config[$section][key($item)] = array_merge($this->Config[$section][key($item)],$item[key($item)]);
133
                    else if(!is_numeric(key($item))) $this->Config[$section][key($item)]=$item[key($item)];
134
                }
135
                else $this->Config[$section] = array_merge($this->Config[$section],$item);
136
            }
137
            else $this->Config[$section] = $item;
138
        }
139
        $re = $this->Save();
140
        ob_end_clean();
141
        return $re;
142
    }
143
/**
144
     * @param $section
145
     * @param $item
146
     * @return bool
147
     */
148
    public function del($section, $item=null)
149
    {
150
        $section = trim(strtolower($section));
151
        if($item and strlen($item))
152
        {
153
            $item = trim(strtolower($item));
154
            if(!isset($this->Config[$section]))
155
            {
156
                $key = $item;
157
                $item = $section;
158
                $section = $this->defaultSection;
159
                if(isset($this->Config[$section][$item][$key]))
160
                {
161
                    $itemSize=count($this->Config[$section][$item]);
162
                    if($itemSize>1) unset($this->Config[$section][$item][$key]);
163
                    else unset($this->Config[$section]);
164
                }
165
            }
166
            else
167
            {
168
                $sectionSize=count($this->Config[$section]);
169
                if(isset($this->Config[$section][$item]))
170
                {
171
                    if($sectionSize>1) unset($this->Config[$section][$item]);
172
                    else unset($this->Config[$section]);
173
                }
174
            } 
175
        }
176
        else
177
        {
178
            $item = $section;
179
            if(!isset($this->Config[$item]))
180
            {
181
                $section = $this->defaultSection;
182
                $defaultSectionSize = count($this->Config[$section]);
183
                if(isset($this->Config[$section][$item]))
184
                {
185
                    if($defaultSectionSize>1) unset($this->Config[$section][$item]);
186
                    else unset($this->Config[$section]);
187
                }
188
            }
189
            else unset($this->Config[$item]);
190
        }
191
        return $this->Save();
192
    }
193
    /**
194
     * @param $file
195
     * @param $location
196
     * @return array|bool
197
     */
198
    private function configureOptions($file,$location=null){
199
        if(!is_string($file) or ($location and !is_string($location)))
200
            throw new Exception('SETUP ERROR: configuration manager can accept string only parameters');
201
        $default=[
202
            'driver' => 'PHP',
203
            'filename' => null,
204
            'directory' => __DIR__,
205
        ];
206
        $Options = [];
207
        if($location)
208
            $Options['directory']=rtrim($this->normalize($location),DIRECTORY_SEPARATOR);
209
        else{
210
            if(basename($file)!==$file)
211
                $Options['directory']= rtrim($this->normalize(pathinfo($file,PATHINFO_DIRNAME)),DIRECTORY_SEPARATOR);
212
        }
213
        $Options['filename'] = basename($file);
214
        if(strpos($Options['filename'],'.')!==false)
215
            $Options['driver'] = strtoupper(pathinfo($Options['filename'], PATHINFO_EXTENSION));
216
        else
217
            $Options['filename']= $Options['filename'].'.'.strtolower($default['driver']);
218
	     if(!in_array($Options['driver'],$this->availableDrivers))
219
            throw new Exception('ERROR: driver "'.$Options['driver'].'" not supported');
220
	    $this->Options = array_merge($default,$Options);
221
        return $this->Options;
222
    }
223
    /**
224
     * @param $path
225
     * @param $relativeTo
226
     * @return string
227
     */
228
    private function normalize($path, $relativeTo = null) {
229
        $path = rtrim(preg_replace('#[/\\\\]+#', DIRECTORY_SEPARATOR, $path), DIRECTORY_SEPARATOR);
230
        $isAbsolute = stripos(PHP_OS, 'win')===0 ? preg_match('/^[A-Za-z]+:/', $path): !strncmp($path, DIRECTORY_SEPARATOR, 1);
231
        if (!$isAbsolute)
232
        {
233
            if (!$relativeTo) $relativeTo = getcwd();
234
            $path = $relativeTo.DIRECTORY_SEPARATOR.$path;
235
        }
236
        if (is_link($path) and ($parentPath = realpath(dirname($path))))
237
            return $parentPath.DIRECTORY_SEPARATOR.$path;
238
        if ($realpath = realpath($path))  return $realpath;
239
        $parts = explode(DIRECTORY_SEPARATOR, trim($path, DIRECTORY_SEPARATOR));
240
        while (end($parts) !== false)
241
        {
242
            array_pop($parts);
243
            $attempt = stripos(PHP_OS, 'win')===0 ? implode(DIRECTORY_SEPARATOR, $parts): DIRECTORY_SEPARATOR.implode(DIRECTORY_SEPARATOR, $parts);
244
            if ($realpaths = realpath($attempt))
245
            {
246
                $path = $realpaths.substr($path, strlen($attempt));
247
                break;
248
            }
249
        }
250
        return $path;
251
    }
252
	  /**
253
     * @param array $options
254
     * @return mixed
255
     */
256
    private function parseConfiguration($options=[])
257
    {
258
259
        try
260
        {  $this->targetFile = $this->normalize($options['directory'].DIRECTORY_SEPARATOR.$options['filename']);
261
            if(!file_exists($this->targetFile))
262
                file_put_contents($this->targetFile,'',LOCK_EX);
263
            switch($this->Options['driver'])
264
            {
265
                case 'JSON':
266
                    $this->Config = unserialize(json_decode(file_get_contents($this->targetFile), true));
267
                    break;
268
                case 'INI':
269
                    $this->Config = parse_ini_file($this->targetFile, true);
270
                    break;
271
                case 'YML':
272
                    $ndocs=0;
273
                    $this->Config = yaml_parse_file($this->targetFile,0,$ndocs);
274
                    break;
275
                default:
276
                    if(!$this->Config = include $this->targetFile) $this->Config = [];
277
                    break;
278
            }
279
        }
280
        catch(Exception $b)
281
        {
282
            trigger_error($b->getMessage(),E_USER_ERROR);
283
        }
284
        return $this->Config;
285
    }
286
/**
287
     * @return bool
288
     */
289
     private function Save()
290
    {
291
	try {
292
		if( !is_writeable( $this->targetFile ) )
293
			if(@chmod($this->targetFile,0775))
294
				throw new Exception('Cant write to file: '.$this->targetFile);
295
		       $content = null;
296
        switch($this->Options['driver'])
297
        {
298
            case 'JSON':
299
                $content .= json_encode(serialize($this->Config));
300
                break;
301
            case 'INI':
302
                $content .= '; @file generator: Iriven France Php "'.get_class($this).'" Class'.PHP_EOL;
303
                $content .= '; @Last Update: '.date('Y-m-d H:i:s').PHP_EOL;
304
                $content .= PHP_EOL;
305
                foreach($this->Config as $section => $array)
306
                {
307
                    is_array($array) or $array = array($array);
308
                    $content .= '[' . $section . ']'.PHP_EOL;
309
                    foreach( $array as $key => $value )
310
                        $content .= $key.' = '.$value.PHP_EOL;
311
                    $content .= PHP_EOL;
312
                }
313
                break;
314
            case 'YML':
315
                $content .= yaml_emit ($this->Config, YAML_UTF8_ENCODING , YAML_LN_BREAK );
316
                break;
317
            default:
318
                $content .= '<?php'.PHP_EOL;
319
                $content .= 'return ';
320
                $content .= var_export($this->Config, true) . ';';
321
                $content = preg_replace('/array\s+\(/', '[', $content);
322
                $content = preg_replace('/,(\s+)\)/', '$1]', $content);
323
                break;
324
        }
325
        file_put_contents($this->targetFile, $content, LOCK_EX);
326
	if( is_writeable( $this->targetFile ) )
327
		if(@chmod($this->targetFile,0644))
328
			throw new Exception('Cant write to file: '.$this->targetFile);
329
	    } 
330
	     catch (Exception $e) 
331
	     {  trigger_error($e->getMessage(),E_USER_ERROR);}
332
        return true;
333
    }
334
    /**
335
     * fin de la classe
336
     */
337
338
}
339