public static function configureServices(\Pimple $app, array $config) { foreach ($config as $service_name => $service) { $setup = function ($service_name, $service) use($app) { $arguments = ''; $deps = array(); if (isset($service['dependencies']) && is_array($service['dependencies']) && count($service['dependencies']) > 0) { $deps = $service['dependencies']; } $class = $service['class']; $sets = isset($service['set']) ? $service['set'] : array(); if (!is_array($sets)) { throw new \Exception('Service with a `sets` parameter must be a hash array of paramerter => service, where parameter is the un-camelised key and service is the key identifier of the dependant service.'); } $service_closure = function (\Pimple $app) use($class, $deps, $sets, $service_name) { // instantiate // $object = eval( $string ); $class = new \ReflectionClass($class); $arguments = array(); foreach ($deps as $key) { $arguments[] = Utils::getArrayValue($app, $key); } $instance = $class->newInstanceArgs($arguments); if ($instance instanceof \Skip\ServiceContainerInterface) { $instance->setContainer($app); } // handle any sets try { Utils::setParametersOn($instance, $sets, $app); } catch (\Exception $e) { // make it clearer throw new \Exception('Web Application initialisation of \'' . $service_name . '\' service: ' . $e->getMessage()); } return $instance; }; $type = isset($service['type']) ? $service['type'] : null; switch ($type) { case 'protect': $app[$service_name] = $app->protect($service_closure); break; case 'factory': $app[$service_name] = $service_closure; break; case 'share': default: $app[$service_name] = $app->share($service_closure); break; } }; $setup($service_name, $service); } }
public static function setParametersOn($object, $mappings, $hash_stack) { $reflect = new \ReflectionClass($object); $props = $reflect->getProperties(\ReflectionProperty::IS_PUBLIC); foreach ($mappings as $param => $dep_key) { // check if $dep_key actually exists! // check if its a public parameter try { $prop = $reflect->getProperty($param); } catch (\ReflectionException $e) { $prop = null; } try { $magic_prop = $reflect->getMethod('__set'); } catch (\ReflectionException $e) { $magic_prop = null; } if ($prop && $prop->isPublic() || $magic_prop && $magic_prop->isPublic()) { $object->{$param} = Utils::getArrayValue($hash_stack, $dep_key); continue; } // check if its a public set* or magic __call method $call = 'set' . ucwords(preg_replace('/_+/', ' ', strtolower($param))); $call = preg_replace('/\\s+/', '', $call); try { $method = $reflect->getMethod($call); } catch (\ReflectionException $e) { $method = null; } try { $magic_method = $reflect->getMethod('__call'); } catch (\ReflectionException $e) { $magic_method = null; } if ($method && $method->isPublic() || $magic_method && $magic_method->isPublic()) { $object->{$call}(Utils::getArrayValue($hash_stack, $dep_key)); continue; } // else throw error! throw new \Exception(sprintf('Unable to set param %s on object of type `%s`', $param, get_class($object))); } }