Completed
Push — 15.x ( 1a3897...0b1d63 )
by Tim
02:57
created

ConfigurationValueLoader   A

Complexity

Total Complexity 7

Size/Duplication

Total Lines 67
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 7
lcom 1
cbo 3
dl 0
loc 67
ccs 0
cts 25
cp 0
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A getConfigurationKey() 0 4 1
A load() 0 29 5
1
<?php
2
3
/**
4
 * TechDivision\Import\Loaders\ConfigurationValueLoader
5
 *
6
 * NOTICE OF LICENSE
7
 *
8
 * This source file is subject to the Open Software License (OSL 3.0)
9
 * that is available through the world-wide-web at this URL:
10
 * http://opensource.org/licenses/osl-3.0.php
11
 *
12
 * PHP version 5
13
 *
14
 * @author    Tim Wagner <[email protected]>
15
 * @copyright 2019 TechDivision GmbH <[email protected]>
16
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
 * @link      https://github.com/techdivision/import
18
 * @link      http://www.techdivision.com
19
 */
20
21
namespace TechDivision\Import\Loaders;
22
23
use TechDivision\Import\Configuration\ParamsConfigurationInterface;
24
use TechDivision\Import\Configuration\PluginConfigurationInterface;
25
use TechDivision\Import\Configuration\SubjectConfigurationInterface;
26
27
/**
28
 * Generic loader implementation for configuration values.
29
 *
30
 * @author    Tim Wagner <[email protected]>
31
 * @copyright 2019 TechDivision GmbH <[email protected]>
32
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
33
 * @link      https://github.com/techdivision/import
34
 * @link      http://www.techdivision.com
35
 */
36
class ConfigurationValueLoader implements LoaderInterface
37
{
38
39
    /**
40
     * The configuration key to load the value with.
41
     *
42
     * @var string
43
     */
44
    protected $configurationKey;
45
46
    /**
47
     * Initializes the loader with the configuration key to load the value with.
48
     *
49
     * @param string $configurationKey The configuration key
50
     */
51
    public function __construct($configurationKey)
52
    {
53
        $this->configurationKey = $configurationKey;
54
    }
55
56
    /**
57
     * Return's the configuration key to load the value with.
58
     *
59
     * @return string The configuration key
60
     */
61
    protected function getConfigurationKey()
62
    {
63
        return $this->configurationKey;
64
    }
65
66
    /**
67
     * Loads and returns the configuration value for the key the instance has been initialized with.
68
     *
69
     * @param \TechDivision\Import\Configuration\ParamsConfigurationInterface $configuration The configuration instance to load the value from
70
     *
71
     * @return \ArrayAccess The array with the configuration value
72
     */
73
    public function load(ParamsConfigurationInterface $configuration = null)
74
    {
75
76
        // return an empty array if the param has NOT been set
77
        $values = array();
78
79
        // query whether or not an instance has been passed
80
        if ($configuration === null) {
81
            return $values;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $values; (array) is incompatible with the return type declared by the interface TechDivision\Import\Loaders\LoaderInterface::load of type ArrayAccess.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
82
        }
83
84
        // load the values from the plugin configuration recursively
85
        if ($configuration instanceof PluginConfigurationInterface) {
86
            $values = array_merge($values, $this->load($configuration->getConfiguration()));
87
        }
88
89
        // load the values from the subject configuration recursively
90
        if ($configuration instanceof SubjectConfigurationInterface) {
91
            $values = array_merge($values, $this->load($configuration->getPluginConfiguration()));
92
        }
93
94
        // finally load the values from the actual configuration
95
        if ($configuration->hasParam($configurationKey = $this->getConfigurationKey())) {
96
            $values = array_merge($configuration->getParam($configurationKey));
97
        }
98
99
        // return the values
100
        return $values;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $values; (array) is incompatible with the return type declared by the interface TechDivision\Import\Loaders\LoaderInterface::load of type ArrayAccess.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
101
    }
102
}
103