/** * Delivers a notification by calling the given object's method with given arguments. * * Returns `false` if notification couldn't be delivered, `true` otherwise. * * @param string $targetServiceName The target service name. * @param object $targetService The target service instance. * @param string $senderName Name of the service that sent this notification. * @param string $methodName Name of the method that should be called. * @param array $arguments The method arguments. Default: `array()`. * @return boolean */ public function deliverNotification($targetServiceName, $targetService, $senderName, $methodName, array $arguments = array()) { if (!is_object($targetService) || !method_exists($targetService, $methodName)) { throw new InvalidServiceException('Could not deliver notification to service "' . $targetServiceName . '" because the method "' . $methodName . '()" does not exist in it. Sender: "' . $senderName . '".'); } $args = $this->argumentsResolver->resolve($arguments, $senderName); switch (count($args)) { case 0: $targetService->{$methodName}(); break; case 1: $targetService->{$methodName}($args[0]); break; case 2: $targetService->{$methodName}($args[0], $args[1]); break; case 3: $targetService->{$methodName}($args[0], $args[1], $args[2]); break; case 4: $targetService->{$methodName}($args[0], $args[1], $args[2], $args[3]); break; case 5: $targetService->{$methodName}($args[0], $args[1], $args[2], $args[3], $args[4]); break; default: call_user_func_array(array($targetService, $methodName), $args); } // add this notification to the list of delivered notifications $this->deliveredNotifications[$targetServiceName][] = array('sender' => $senderName, 'target' => $targetServiceName, 'method' => $methodName, 'arguments' => $arguments); return true; }
/** * Call a method on a service. * * @param Service $service Service to call a method on. * @param string $methodName Name of the method to call on the service. * @param array $arguments [optional] Arguments to call the method with. Default: `array()`. * @param object $instance [optional] Service object instance. Should be passed for all non-singleton services. * @return mixed * * @throws RuntimeException When trying to call a method on a service that hasn't been instantiated yet. */ public function callMethod(Service $service, $methodName, array $arguments = array(), $instance = null) { if ($instance === null && !$service->isInstantiated()) { throw new RuntimeException('Cannot call a method of a service that has not been instantiated yet, when trying to call "::' . $methodName . '" on "' . $service->name . '".'); } $instance = $instance ? $instance : $service->getInstance(); $arguments = $this->argumentsResolver->resolve($arguments); switch (count($arguments)) { case 0: $result = $instance->{$methodName}(); break; case 1: $result = $instance->{$methodName}($arguments[0]); break; case 2: $result = $instance->{$methodName}($arguments[0], $arguments[1]); break; case 3: $result = $instance->{$methodName}($arguments[0], $arguments[1], $arguments[2]); break; case 4: $result = $instance->{$methodName}($arguments[0], $arguments[1], $arguments[2], $arguments[3]); break; case 5: $result = $instance->{$methodName}($arguments[0], $arguments[1], $arguments[2], $arguments[3], $arguments[4]); break; default: $result = call_user_func_array(array($instance, $methodName), $arguments); } return $result; }