Skip to content

Commit bf858b1

Browse files
Dispatcher refactored.
1 parent 365eaa6 commit bf858b1

2 files changed

Lines changed: 67 additions & 35 deletions

File tree

src/Magic/Dispatcher.php

Lines changed: 49 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ public static function invoke(
5757
array $prioritizedCallHandlerClassNames
5858
)
5959
{
60-
return self::doInvocation($object, $methodName, $arguments, $prioritizedCallHandlerClassNames, false);
60+
return self::instance()
61+
->doInvocation($object, $methodName, $arguments, $prioritizedCallHandlerClassNames, false);
6162
}
6263

6364
public static function invokeStatically(
@@ -67,59 +68,41 @@ public static function invokeStatically(
6768
array $prioritizedCallHandlerClassNames
6869
)
6970
{
70-
return self::doInvocation($className, $methodName, $arguments, $prioritizedCallHandlerClassNames, true);
71+
return self::instance()
72+
->doInvocation($className, $methodName, $arguments, $prioritizedCallHandlerClassNames, true);
7173
}
7274

7375
/**
7476
* @param object|string $objectOrClassName
7577
*/
76-
private static function doInvocation(
78+
private function doInvocation(
7779
$objectOrClassName,
7880
string $methodName,
7981
array $arguments,
80-
array $prioritizedCallHandlerClassNames,
82+
array $prioritizedCallHandlers,
8183
bool $isStatic
8284
)
8385
{
84-
$instance = self::instance();
85-
8686
$className = $isStatic ? $objectOrClassName : get_class($objectOrClassName);
87-
$classMetadata = $instance->classMetadata($className);
87+
$classMetadata = $this->classMetadata($className);
8888

89-
foreach ($prioritizedCallHandlerClassNames as $callHandlerData) {
90-
// prepare $callHandlerClassName and $options
91-
if (is_array($callHandlerData)) {
92-
$callHandlerClassName = $callHandlerData[0];
93-
$options = $callHandlerData[1];
94-
} else {
95-
$callHandlerClassName = $callHandlerData;
96-
$options = [];
97-
}
89+
$callHandler = $this->determineCallHandler($methodName, $classMetadata, $prioritizedCallHandlers);
9890

99-
// retrieve $callHandler
100-
if (! array_key_exists($callHandlerClassName, $instance->callHandlers)) {
101-
$instance->callHandlers[$callHandlerClassName] = new $callHandlerClassName();
91+
if (! is_null($callHandler)) {
92+
if (
93+
$isStatic &&
94+
$callHandler->requiresObjectContext()
95+
) {
96+
throw new \Error("Calling a non-static method when not in object context.");
10297
}
10398

104-
$callHandler = $instance->callHandlers[$callHandlerClassName];
105-
106-
// execute
107-
if ($callHandler->canHandle($methodName, $classMetadata, $options)) {
108-
$instance->assertGivenParametersMatchMethodSignature($methodName, $arguments, $classMetadata);
109-
110-
if (
111-
$isStatic &&
112-
$callHandler->requiresObjectContext()
113-
) {
114-
throw new \Error("Calling a non-static method when not in object context.");
115-
}
99+
$this->assertGivenParametersMatchMethodSignature($methodName, $arguments, $classMetadata);
116100

117-
$return = $callHandler->execute($objectOrClassName, $methodName, $arguments, $classMetadata);
101+
$return = $callHandler->execute($objectOrClassName, $methodName, $arguments, $classMetadata);
118102

119-
$instance->assertCorrectReturnType($objectOrClassName, $methodName, $return, $classMetadata);
103+
$this->assertCorrectReturnType($objectOrClassName, $methodName, $return, $classMetadata);
120104

121-
return $return;
122-
}
105+
return $return;
123106
}
124107

125108
if (
@@ -144,6 +127,37 @@ private function classMetadata(string $className) : ClassMetadata
144127
->classMetadata[$className];
145128
}
146129

130+
private function determineCallHandler(
131+
string $methodName,
132+
ClassMetadata $classMetadata,
133+
array $prioritizedCallHandlers
134+
) : ?CallHandler
135+
{
136+
foreach ($prioritizedCallHandlers as $callHandlerData) {
137+
// prepare $callHandlerClassName and $options
138+
if (is_array($callHandlerData)) {
139+
$callHandlerClassName = $callHandlerData[0];
140+
$options = $callHandlerData[1];
141+
} else {
142+
$callHandlerClassName = $callHandlerData;
143+
$options = [];
144+
}
145+
146+
// retrieve $callHandler
147+
if (! array_key_exists($callHandlerClassName, $this->callHandlers)) {
148+
$this->callHandlers[$callHandlerClassName] = new $callHandlerClassName();
149+
}
150+
$callHandler = $this->callHandlers[$callHandlerClassName];
151+
152+
// check if it can handle the method
153+
if ($callHandler->canHandle($methodName, $classMetadata, $options)) {
154+
return $callHandler;
155+
}
156+
}
157+
158+
return null;
159+
}
160+
147161
private function assertGivenParametersMatchMethodSignature(
148162
string $methodName,
149163
array $parameters,

tests/PhpUnit/Magic/DispatcherTest.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ final class DispatcherTest extends TestCase
3232
* @covers ::classMetadata()
3333
* @covers ::invoke()
3434
* @covers ::doInvocation()
35+
* @covers ::determineCallHandler()
3536
* @covers ::assertGivenParametersMatchMethodSignature()
3637
* @covers ::assertCorrectReturnType()
3738
*/
@@ -91,6 +92,22 @@ public function it_invokes_a_virtual_static_method_on_some_object_via_some_call_
9192
);
9293
}
9394

95+
/**
96+
* @test
97+
* @covers ::determineCallHandler()
98+
*/
99+
public function it_accepts_call_handlers_with_options()
100+
{
101+
// given a ClassName with a CallHandler that has options (like the NamedConstructor in
102+
// ClassForNamedConstructorTesting)
103+
104+
// when determining the CallHandler
105+
$newObject = ClassForNamedConstructorTesting::create('some other string', 11);
106+
107+
// then the relevant options have been used
108+
$this->assertInstanceOf(ClassForNamedConstructorTesting::class, $newObject);
109+
}
110+
94111
/**
95112
* @test
96113
* @covers ::doInvocation()
@@ -203,6 +220,7 @@ public function it_throws_an_exception_when_the_return_type_is_invalid()
203220
/**
204221
* @test
205222
* @covers ::doInvocation()
223+
* @covers ::determineCallHandler()
206224
*/
207225
public function it_throws_an_exception_if_no_call_handler_can_handle_the_method()
208226
{

0 commit comments

Comments
 (0)