ExtensionCollection   A
last analyzed

Complexity

Total Complexity 19

Size/Duplication

Total Lines 139
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 19
lcom 1
cbo 3
dl 0
loc 139
ccs 43
cts 43
cp 1
rs 10
c 0
b 0
f 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A collection() 0 4 1
A createCollection() 0 9 2
A convertToArray() 0 8 2
A validateExtension() 0 5 1
A validateClassExists() 0 6 3
A validateClassImplementation() 0 12 3
A getKey() 0 11 4
A getType() 0 8 2
1
<?php
2
3
namespace League\CLImate\TerminalObject\Router;
4
5
use League\CLImate\Exceptions\InvalidArgumentException;
6
use League\CLImate\Exceptions\UnexpectedValueException;
7
use League\CLImate\Util\Helper;
8
9
class ExtensionCollection
10
{
11
    /**
12
     * @var array collection
13
     */
14
    protected $collection = ['basic' => [], 'dynamic' => []];
15
16
    /**
17
     * @var string $basic_interface
18
     */
19
    protected $basic_interface = 'League\CLImate\TerminalObject\Basic\BasicTerminalObjectInterface';
20
21
    /**
22
     * @var string $dynamic_interface
23
     */
24 36
    protected $dynamic_interface = 'League\CLImate\TerminalObject\Dynamic\DynamicTerminalObjectInterface';
25
26 36
    public function __construct($key, $class)
27 28
    {
28
        $this->createCollection($key, $class);
29 28
    }
30
31 28
    public function collection()
32
    {
33
        return $this->collection;
34
    }
35
36
    /**
37
     * Create the collection from the key/class
38
     *
39
     * @param string $original_key
40
     * @param string|object|array $original_class
41
     *
42 36
     * @return void
43
     */
44 36
    protected function createCollection($original_key, $original_class)
45
    {
46 36
        $collection = $this->convertToArray($original_key, $original_class);
47 36
48 28
        foreach ($collection as $key => $class) {
49 28
            $this->validateExtension($class);
50 28
            $this->collection[$this->getType($class)][$this->getKey($key, $class)] = $class;
51
        }
52
    }
53
54
    /**
55
     * Convert the given class and key to an array of classes
56
     *
57
     * @param string|object|array $class
58
     * @param string $key Optional custom key instead of class name
59
     *
60 36
     * @return array
61
     */
62 36
    protected function convertToArray($key, $class)
63 8
    {
64
        if (is_array($class)) {
65
            return $class;
66 28
        }
67
68
        return [$this->getKey($key, $class) => $class];
69
    }
70
71
    /**
72
     * Ensure that the extension is valid
73
     *
74 36
     * @param string|object|array $class
75
     */
76 36
    protected function validateExtension($class)
77 32
    {
78 28
        $this->validateClassExists($class);
0 ignored issues
show
Bug introduced by Joe Tannenbaum
It seems like $class defined by parameter $class on line 76 can also be of type array; however, League\CLImate\TerminalO...::validateClassExists() does only seem to accept string|object, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
79
        $this->validateClassImplementation($class);
0 ignored issues
show
Bug introduced by Joe Tannenbaum
It seems like $class defined by parameter $class on line 76 can also be of type array; however, League\CLImate\TerminalO...teClassImplementation() does only seem to accept string|object, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
80
    }
81
82
    /**
83
     * @param string|object $class
84
     *
85 36
     * @throws UnexpectedValueException if extension class does not exist
86
     */
87 36
    protected function validateClassExists($class)
88 4
    {
89
        if (is_string($class) && !class_exists($class)) {
90 32
            throw new UnexpectedValueException('Class does not exist: ' . $class);
91
        }
92
    }
93
94
    /**
95
     * @param string|object $class
96
     *
97 32
     * @throws InvalidArgumentException if extension class does not implement either Dynamic or Basic interface
98
     */
99 32
    protected function validateClassImplementation($class)
100
    {
101 32
        $str_class = is_string($class);
102 32
103
        $valid_implementation = (is_a($class, $this->basic_interface, $str_class)
104 32
                                    || is_a($class, $this->dynamic_interface, $str_class));
105 4
106 4
        if (!$valid_implementation) {
107
            throw new InvalidArgumentException('Class must implement either '
108 28
                                    . $this->basic_interface . ' or ' . $this->dynamic_interface);
109
        }
110
    }
111
112
    /**
113
     * Determine the extension key based on the class
114
     *
115
     * @param string|null $key
116
     * @param string|object $class
117
     *
118 36
     * @return string
119
     */
120 36
    protected function getKey($key, $class)
121 28
    {
122
        if ($key === null || !is_string($key)) {
123 28
            $class_path = (is_string($class)) ? $class : get_class($class);
124 28
125 28
            $key = explode('\\', $class_path);
126
            $key = end($key);
127 36
        }
128
129
        return Helper::snakeCase($key);
130
    }
131
132
    /**
133
     * Get the type of class the extension implements
134
     *
135
     * @param string|object $class
136
     *
137 28
     * @return string 'basic' or 'dynamic'
138
     */
139 28
    protected function getType($class)
140 24
    {
141
        if (is_a($class, $this->basic_interface, is_string($class))) {
142
            return 'basic';
143 12
        }
144
145
        return 'dynamic';
146
    }
147
}
148