@@ -24,6 +24,11 @@ class ConfigurableObject implements InterpreterInterface
24
24
*/
25
25
private $ classWhitelist = [];
26
26
27
+ /**
28
+ * @var array
29
+ */
30
+ private $ deniedClassList = [];
31
+
27
32
/**
28
33
* @var ObjectManagerInterface
29
34
*/
@@ -52,17 +57,20 @@ class ConfigurableObject implements InterpreterInterface
52
57
* @param array $classWhitelist
53
58
* @param ClassReader|null $classReader
54
59
* @param ConfigInterface|null $objectManagerConfig
60
+ * @param array $deniedClassList
55
61
*/
56
62
public function __construct (
57
63
ObjectManagerInterface $ objectManager ,
58
64
InterpreterInterface $ argumentInterpreter ,
59
65
array $ classWhitelist = [],
60
66
ClassReader $ classReader = null ,
61
- ConfigInterface $ objectManagerConfig = null
67
+ ConfigInterface $ objectManagerConfig = null ,
68
+ array $ deniedClassList = []
62
69
) {
63
70
$ this ->objectManager = $ objectManager ;
64
71
$ this ->argumentInterpreter = $ argumentInterpreter ;
65
72
$ this ->classWhitelist = $ classWhitelist ;
73
+ $ this ->deniedClassList = $ deniedClassList ;
66
74
$ this ->classReader = $ classReader ?? $ objectManager ->get (ClassReader::class);
67
75
$ this ->objectManagerConfig = $ objectManagerConfig ?? $ objectManager ->get (ConfigInterface::class);
68
76
}
@@ -85,25 +93,12 @@ public function evaluate(array $data)
85
93
if (!isset ($ arguments ['class ' ])) {
86
94
throw new \InvalidArgumentException ('Node "argument" with name "class" is required for this type. ' );
87
95
}
88
-
89
96
$ className = $ arguments ['class ' ];
90
97
unset($ arguments ['class ' ]);
91
-
92
- $ type = $ this ->objectManagerConfig ->getInstanceType (
93
- $ this ->objectManagerConfig ->getPreference ($ className )
94
- );
95
-
96
- $ classParents = $ this ->getParents ($ type );
97
-
98
- $ whitelistIntersection = array_intersect ($ classParents , $ this ->classWhitelist );
99
-
100
- if (empty ($ whitelistIntersection )) {
101
- throw new \InvalidArgumentException (
102
- sprintf ('Class argument is invalid: %s ' , $ className )
103
- );
104
- }
105
98
}
106
99
100
+ $ this ->isValid ($ className );
101
+
107
102
return $ this ->objectManager ->create ($ className , $ arguments );
108
103
}
109
104
@@ -115,7 +110,7 @@ public function evaluate(array $data)
115
110
*/
116
111
private function getParents (string $ type )
117
112
{
118
- $ classParents = $ this ->classReader ->getParents ($ type );
113
+ $ classParents = $ this ->classReader ->getParents ($ type ) ?? [] ;
119
114
foreach ($ classParents as $ parent ) {
120
115
if (empty ($ parent )) {
121
116
continue ;
@@ -125,4 +120,30 @@ private function getParents(string $type)
125
120
126
121
return $ classParents ;
127
122
}
123
+
124
+ /**
125
+ * Check that provided class could be evaluated like an argument.
126
+ *
127
+ * @param string $className
128
+ * @throws \InvalidArgumentException
129
+ */
130
+ private function isValid (string $ className ): void
131
+ {
132
+ $ type = $ this ->objectManagerConfig ->getInstanceType (
133
+ $ this ->objectManagerConfig ->getPreference ($ className )
134
+ );
135
+
136
+ $ classParents = $ this ->getParents ($ type );
137
+
138
+ if (!empty ($ classParents )) {
139
+ $ whitelistIntersection = array_intersect ($ classParents , $ this ->classWhitelist );
140
+ $ deniedIntersection = array_intersect ($ classParents , $ this ->deniedClassList );
141
+
142
+ if (empty ($ whitelistIntersection ) || !empty ($ deniedIntersection )) {
143
+ throw new \InvalidArgumentException (
144
+ sprintf ('Class argument is invalid: %s ' , $ className )
145
+ );
146
+ }
147
+ }
148
+ }
128
149
}
0 commit comments