-
Notifications
You must be signed in to change notification settings - Fork 123
/
ExtensionCollection.php
147 lines (126 loc) · 3.83 KB
/
ExtensionCollection.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
<?php
namespace League\CLImate\TerminalObject\Router;
use League\CLImate\Exceptions\InvalidArgumentException;
use League\CLImate\Exceptions\UnexpectedValueException;
use League\CLImate\Util\Helper;
class ExtensionCollection
{
/**
* @var array collection
*/
protected $collection = ['basic' => [], 'dynamic' => []];
/**
* @var string $basic_interface
*/
protected $basic_interface = 'League\CLImate\TerminalObject\Basic\BasicTerminalObjectInterface';
/**
* @var string $dynamic_interface
*/
protected $dynamic_interface = 'League\CLImate\TerminalObject\Dynamic\DynamicTerminalObjectInterface';
public function __construct($key, $class)
{
$this->createCollection($key, $class);
}
public function collection()
{
return $this->collection;
}
/**
* Create the collection from the key/class
*
* @param string $original_key
* @param string|object|array $original_class
*
* @return void
*/
protected function createCollection($original_key, $original_class)
{
$collection = $this->convertToArray($original_key, $original_class);
foreach ($collection as $key => $class) {
$this->validateExtension($class);
$this->collection[$this->getType($class)][$this->getKey($key, $class)] = $class;
}
}
/**
* Convert the given class and key to an array of classes
*
* @param string|object|array $class
* @param string $key Optional custom key instead of class name
*
* @return array
*/
protected function convertToArray($key, $class)
{
if (is_array($class)) {
return $class;
}
return [$this->getKey($key, $class) => $class];
}
/**
* Ensure that the extension is valid
*
* @param string|object|array $class
*/
protected function validateExtension($class)
{
$this->validateClassExists($class);
$this->validateClassImplementation($class);
}
/**
* @param string|object $class
*
* @throws UnexpectedValueException if extension class does not exist
*/
protected function validateClassExists($class)
{
if (is_string($class) && !class_exists($class)) {
throw new UnexpectedValueException('Class does not exist: ' . $class);
}
}
/**
* @param string|object $class
*
* @throws InvalidArgumentException if extension class does not implement either Dynamic or Basic interface
*/
protected function validateClassImplementation($class)
{
$str_class = is_string($class);
$valid_implementation = (is_a($class, $this->basic_interface, $str_class)
|| is_a($class, $this->dynamic_interface, $str_class));
if (!$valid_implementation) {
throw new InvalidArgumentException('Class must implement either '
. $this->basic_interface . ' or ' . $this->dynamic_interface);
}
}
/**
* Determine the extension key based on the class
*
* @param string|null $key
* @param string|object $class
*
* @return string
*/
protected function getKey($key, $class)
{
if ($key === null || !is_string($key)) {
$class_path = (is_string($class)) ? $class : get_class($class);
$key = explode('\\', $class_path);
$key = end($key);
}
return Helper::snakeCase($key);
}
/**
* Get the type of class the extension implements
*
* @param string|object $class
*
* @return string 'basic' or 'dynamic'
*/
protected function getType($class)
{
if (is_a($class, $this->basic_interface, is_string($class))) {
return 'basic';
}
return 'dynamic';
}
}