Completed
Push — interactive-mode ( 898eaf...bec884 )
by Craig
01:33
created

src/TerminalObject/Router/ExtensionCollection.php (2 issues)

Labels
Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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
    protected $dynamic_interface = 'League\CLImate\TerminalObject\Dynamic\DynamicTerminalObjectInterface';
25
26
    public function __construct($key, $class)
27
    {
28
        $this->createCollection($key, $class);
29
    }
30
31
    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
     * @return void
43
     */
44
    protected function createCollection($original_key, $original_class)
45
    {
46
        $collection = $this->convertToArray($original_key, $original_class);
47
48
        foreach ($collection as $key => $class) {
49
            $this->validateExtension($class);
50
            $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
     * @return array
61
     */
62
    protected function convertToArray($key, $class)
63
    {
64
        if (is_array($class)) {
65
            return $class;
66
        }
67
68
        return [$this->getKey($key, $class) => $class];
69
    }
70
71
    /**
72
     * Ensure that the extension is valid
73
     *
74
     * @param string|object|array $class
75
     */
76
    protected function validateExtension($class)
77
    {
78
        $this->validateClassExists($class);
0 ignored issues
show
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
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
     * @throws UnexpectedValueException if extension class does not exist
86
     */
87
    protected function validateClassExists($class)
88
    {
89
        if (is_string($class) && !class_exists($class)) {
90
            throw new UnexpectedValueException('Class does not exist: ' . $class);
91
        }
92
    }
93
94
    /**
95
     * @param string|object $class
96
     *
97
     * @throws InvalidArgumentException if extension class does not implement either Dynamic or Basic interface
98
     */
99
    protected function validateClassImplementation($class)
100
    {
101
        $str_class = is_string($class);
102
103
        $valid_implementation = (is_a($class, $this->basic_interface, $str_class)
104
                                    || is_a($class, $this->dynamic_interface, $str_class));
105
106
        if (!$valid_implementation) {
107
            throw new InvalidArgumentException('Class must implement either '
108
                                    . $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
     * @return string
119
     */
120
    protected function getKey($key, $class)
121
    {
122
        if ($key === null || !is_string($key)) {
123
            $class_path = (is_string($class)) ? $class : get_class($class);
124
125
            $key = explode('\\', $class_path);
126
            $key = end($key);
127
        }
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
     * @return string 'basic' or 'dynamic'
138
     */
139
    protected function getType($class)
140
    {
141
        if (is_a($class, $this->basic_interface, is_string($class))) {
142
            return 'basic';
143
        }
144
145
        return 'dynamic';
146
    }
147
}
148