ChainConfig   A
last analyzed

Complexity

Total Complexity 16

Size/Duplication

Total Lines 72
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 0
Metric Value
wmc 16
lcom 1
cbo 1
dl 0
loc 72
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 16 4
B doGetAll() 0 30 9
A doSetAll() 0 10 3
1
<?php
2
3
/**
4
 * This file is part of Fabrica.
5
 *
6
 * (c) Alexandre Salomé <[email protected]>
7
 * (c) Julien DIDIER <[email protected]>
8
 *
9
 * This source file is subject to the GPL license that is bundled
10
 * with this source code in the file LICENSE.
11
 */
12
13
namespace Fabrica\Component\Config;
14
15
/**
16
 * ChainConfig is used to group different configs with an order.
17
 *
18
 * This order is useful because of the reading operation: it stops when a value is found.
19
 *
20
 * If a config fails, exception will be caught and ignored by chain-config.
21
 *
22
 * Writing operations are propagated to all sub-configs.
23
 *
24
 * @author Alexandre Salomé <[email protected]>
25
 */
26
class ChainConfig extends AbstractConfig
27
{
28
    protected $configs;
29
30
    /**
31
     * @param array $configs An array of ConfigInterface objects
32
     */
33
    public function __construct(array $configs)
34
    {
35
        if (count($configs) < 2) {
36
            throw new \LogicException(sprintf('You don\'t need a chain if you only have %s element(s)', count($configs)));
37
        }
38
39
        $this->configs = array();
40
        foreach ($configs as $config)
41
        {
42
            if (!$config instanceof ConfigInterface) {
43
                throw new \InvalidArgumentException(sprintf('Expected a ConfigInterface to be provided, given a %s', get_class($config)));
44
            }
45
46
            $this->configs[] = $config;
47
        }
48
    }
49
50
    /**
51
     * {@inheritDoc}
52
     */
53
    public function doGetAll()
54
    {
55
        $max = count($this->configs);
56
        for ($i = 0; $i < $max; $i++) {
57
58
            // If error occurs on reading, ignore and pass to next
59
            try {
60
                $current = $this->configs[$i]->all();
61
            } catch (\Exception $e) {
62
                continue;
63
            }
64
65
            if ($i === 0 && count($current)) {
66
                return $current;
67
            } elseif (count($current)) {
68
                break;
69
            }
70
        }
71
72
        while ($i > 0 && count($current)) {
0 ignored issues
show
Bug introduced by
The variable $current does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
73
            $i--;
74
            try {
75
                $this->configs[$i]->setAll($current);
76
            } catch (\Exception $e) {
77
                continue;
78
            }
79
        }
80
81
        return $current;
82
    }
83
84
    /**
85
     * {@inheritDoc}
86
     */
87
    public function doSetAll(array $values)
88
    {
89
        foreach ($this->configs as $config) {
90
            try {
91
                $config->setAll($values);
92
            } catch (\Exception $e) {
93
                continue;
94
            }
95
        }
96
    }
97
}
98