Completed
Push — master ( 68fe25...8e1e8c )
by Woody
11s
created

Configuration::__construct()   D

Complexity

Conditions 9
Paths 19

Size

Total Lines 26
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 9

Importance

Changes 0
Metric Value
cc 9
eloc 17
nc 19
nop 1
dl 0
loc 26
ccs 18
cts 18
cp 1
crap 9
rs 4.909
c 0
b 0
f 0
1
<?php
2
3
namespace Northwoods\Config;
4
5
use Dotenv\Dotenv;
6
use Northwoods\Config\Path\PathCollection;
7
8
class Configuration
9
{
10
    /**
11
     * @var array
12
     */
13
    public static $env;
14
15
    /**
16
     * @var PathCollection
17
     */
18
    protected $paths;
19
20
    /**
21
     * @var Dotenv
22
     */
23
    protected $dotenv;
24
25
    /**
26
     * @var string
27
     */
28
    protected $environment;
29
30
    /**
31
     * @param array|Configuration $config
32
     */
33 24
    public function __construct($config)
34
    {
35 24
        $this->paths = new PathCollection();
36 24
        if (is_array($config)) {
37 24
            if (isset($config['path'])) {
38 22
                $this->paths->add($config['path']);
39
            }
40 24
            if (isset($config['paths'])) {
41 11
                foreach ($config['paths'] as $path) {
42 11
                    $this->paths->add($path);
43
                }
44
            }
45 24
            if (isset($config['environment'])) {
46 10
                $this->setEnvironment($config['environment']);
47
            }
48 24
            if (isset($config['dotenv'])) {
49 3
                $this->setDotenv(new Dotenv($config['dotenv']));
50
            }
51 21
        } elseif ($config instanceof Configuration) {
52 21
            $this->setPaths($config->getPaths());
53 21
            $this->setEnvironment($config->getEnvironment());
54 21
            if ($config->getDotenv()) {
55 2
                $this->setDotenv($config->getDotenv());
56
            }
57
        }
58 24
    }
59
60
    /**
61
     * @return PathCollection
62
     */
63 24
    public function getPaths()
64
    {
65 24
        return $this->paths;
66
    }
67
68
    /**
69
     * @param PathCollection $pathCollection
70
     * @return $this
71
     */
72 21
    public function setPaths(PathCollection $pathCollection)
73
    {
74 21
        $this->paths = $pathCollection;
75 21
        return $this;
76
    }
77
78
    /**
79
     * @param null|string $environment
80
     * @return $this
81
     */
82 22
    public function setEnvironment($environment)
83
    {
84 22
        if ($this->environment !== $environment) {
85 10
            if (method_exists($this, 'reset')) {
86 8
                $this->reset();
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Northwoods\Config\Configuration as the method reset() does only exist in the following sub-classes of Northwoods\Config\Configuration: Northwoods\Config\Collection. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
87
            }
88
        }
89 22
        $this->environment = $environment;
90 22
        return $this;
91
    }
92
93
    /**
94
     * @return $this
95
     */
96
    public function removeEnvironment()
97
    {
98
        if ($this->environment !== null) {
99
            if (method_exists($this, 'reset')) {
100
                $this->reset();
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Northwoods\Config\Configuration as the method reset() does only exist in the following sub-classes of Northwoods\Config\Configuration: Northwoods\Config\Collection. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
101
            }
102
        }
103
        $this->environment = null;
104
        return $this;
105
    }
106
107
    /**
108
     * @return null|string
109
     */
110 22
    public function getEnvironment()
111
    {
112 22
        return $this->environment;
113
    }
114
115
    /**
116
     * @return Dotenv
117
     */
118 22
    public function getDotenv()
119
    {
120 22
        return $this->dotenv;
121
    }
122
123
    /**
124
     * @param Dotenv $dotenv
125
     * @return $this
126
     */
127 3
    public function setDotenv(Dotenv $dotenv)
128
    {
129 3
        $this->dotenv = $dotenv;
130 3
        $this->loadDotenv();
131 3
        return $this;
132
    }
133
134 3
    private function loadDotenv()
135
    {
136 3
        $retval = [];
137 3
        $values = $this->dotenv->load();
138 3
        foreach ($values as $value) {
139 3
            $parts = explode("=", $value, 2);
140 3
            $retval[$parts[0]] = getenv($parts[0]);
141
        }
142 3
        return self::$env = $retval;
143
    }
144
}
145