/**
  * Substitute all references to services in a param set
  *
  * @param Collection $params
  *
  * @return Collection
  */
 protected function substituteReferences(Collection $params)
 {
     $params->each(function (&$value) {
         if ($value instanceof ServiceReference) {
             $value = $this->getServicesFactory()->get($value->getId());
         }
     });
 }
 /**
  * ServicesFactory constructor.
  */
 public function __construct()
 {
     // init collections
     $this->services = (new Collection())->restrictTo(ServiceSpecsInterface::class);
     $this->builders = (new Collection())->restrictTo(ServiceBuilderInterface::class);
     $this->injectors = new Collection();
     $this->instances = new Collection();
     // register annotations
     AnnotationRegistry::registerFile(__DIR__ . '/Annotation/Inject.php');
     $this->annotationsReader = new AnnotationReader();
     // load default builders
     $this->builders->append(new ClassServiceBuilder(), new PrefabServiceBuilder());
 }
 public function testCallbacksAreSetUsingAnArrayAsConstructorParam()
 {
     $aggregate = new CallbacksAggregate('aggreagate', [$lambda = function () {
     }, $otherLambda = function () {
     }]);
     $this->assertEquals(Collection::cast([$lambda, $otherLambda]), $aggregate->getCallbacks());
 }
 /**
  * @param array $filters
  *
  * @return $this
  */
 public function setFilters($filters)
 {
     Collection::cast($filters)->each(function ($filter) {
         $this->addFilter($filter);
     });
     return $this;
 }
Beispiel #5
0
 /**
  * @param $options
  *
  * @return $this
  * @throws \ObjectivePHP\Primitives\Exception
  */
 public function addOptions($options)
 {
     Collection::cast($options)->each(function ($value, $key) {
         $this->addOption($key, $value);
     });
     return $this;
 }
 /**
  * @param ApplicationInterface $app
  *
  * @throws \Doctrine\ORM\ORMException
  * @throws \ObjectivePHP\Primitives\Exception
  * @throws \ObjectivePHP\ServicesFactory\Exception
  */
 public function buildEntityManagers(ApplicationInterface $app)
 {
     $entityManagers = $app->getConfig()->subset(Config\EntityManager::class);
     foreach ($entityManagers as $connection => $params) {
         if (isset($params['db'])) {
             $params = $params['db'];
         }
         // normalize if needed
         $entitiesPaths = $params['entities.locations'];
         Collection::cast($entitiesPaths)->each(function (&$path) {
             if (strpos($path, '/') !== 0) {
                 $path = getcwd() . '/' . $path;
             }
         });
         // TODO: handle isDev depending on app config
         $emConfig = Setup::createAnnotationMetadataConfiguration((array) $entitiesPaths, true);
         $emConfig->setNamingStrategy(new UnderscoreNamingStrategy());
         $em = EntityManager::create($params, $emConfig);
         if (!empty($params['mapping_types']) && is_array($params['mapping_types'])) {
             $platform = $em->getConnection()->getDatabasePlatform();
             foreach ($params['mapping_types'] as $type => $mapping) {
                 if (!Type::hasType($type) && class_exists($mapping)) {
                     Type::addType($type, $mapping);
                     $mapping = $type;
                 }
                 $platform->registerDoctrineTypeMapping($type, $mapping);
             }
         }
         // register entity manager as a service
         $emServiceId = 'doctrine.em.' . Str::cast($connection)->lower();
         $app->getServicesFactory()->registerService(['id' => $emServiceId, 'instance' => $em]);
         $app->getServicesFactory()->registerService(['id' => 'db.connection.' . $connection, 'instance' => $em->getConnection()->getWrappedConnection()]);
     }
 }
 /**
  * @param ClassServiceSpecs $serviceSpecs
  * @param array $params
  * @return mixed
  * @throws Exception
  */
 public function build(ServiceSpecsInterface $serviceSpecs, $params = [])
 {
     // check compatibility with the service definition
     if (!$this->doesHandle($serviceSpecs)) {
         throw new Exception(sprintf('"%s" service definition is not handled by this builder.', get_class($serviceSpecs)), Exception::INCOMPATIBLE_SERVICE_DEFINITION);
     }
     $serviceClassName = $serviceSpecs->getClass();
     // check class existence
     if (!class_exists($serviceClassName)) {
         throw new Exception(sprintf('Unable to build service: class "%s" is unknown', $serviceClassName), Exception::INVALID_SERVICE_SPECS);
     }
     // merge service defined and runtime params
     $constructorParams = clone Collection::cast($params);
     $constructorParams->add($serviceSpecs->getParams());
     // substitute params with referenced services
     $this->substituteReferences($constructorParams);
     $service = new $serviceClassName(...$constructorParams->values());
     // call setters if any
     if ($setters = $serviceSpecs->getSetters()) {
         foreach ($setters as $setter => $setterParams) {
             $instanceSetterParams = clone Collection::cast($setterParams);
             $this->substituteReferences($instanceSetterParams);
             $service->{$setter}(...$instanceSetterParams->values());
         }
     }
     return $service;
 }
Beispiel #8
0
 /**
  * MatchedRoute constructor.
  * @param RouterInterface $router
  * @param string $name
  * @param $action
  * @param array $params
  */
 public function __construct(RouterInterface $router, string $name, $action, $params = [])
 {
     $this->router = $router;
     $this->name = $name;
     $this->action = $action;
     $this->params = Collection::cast($params);
 }
 /**
  * @param $value
  */
 public function __invoke(&$value)
 {
     $className = $this->className;
     if (!$value instanceof $className) {
         $value = new $className(...Collection::cast($value)->values()->getInternalValue());
     }
 }
 public function testNativeMerging()
 {
     $merger = new ValueMerger(MergePolicy::NATIVE);
     $firstCollection = new Collection(['x' => 'a', 'y' => 'b']);
     $secondCollection = new Collection(['x' => 'a was replaced', 'z' => 'c']);
     $mergedValue = $merger->merge($firstCollection, $secondCollection);
     $this->assertEquals(Collection::cast(['x' => 'a was replaced', 'y' => 'b', 'z' => 'c']), $mergedValue);
 }
 public static function factory($rawDefinition)
 {
     $rawDefinition = Collection::cast($rawDefinition);
     if (!$rawDefinition->has('instance')) {
         throw new Exception('Missing \'instance\' parameter', Exception::INCOMPLETE_SERVICE_SPECS);
     }
     $serviceDefinition = new PrefabServiceSpecs($rawDefinition['id'], $rawDefinition['instance']);
     return $serviceDefinition;
 }
 /**
  * BeanstalkServer constructor.
  *
  * @param $identifier
  * @param $value array Server configuration
  *
  * @throws Exception
  */
 public function __construct($identifier, $value)
 {
     // check value
     $value = Collection::cast($value)->toArray() + ['port' => PheanstalkInterface::DEFAULT_PORT, 'timeout' => null, 'persistent' => false];
     $mandatory = ['host', 'tube'];
     $missing = array_diff($mandatory, array_keys($value));
     if ($missing) {
         throw new Exception(sprintf('Missing %s keys in beanstalk configuration', implode(', ', $missing)));
     }
     parent::__construct($identifier, $value);
 }
 /**
  * @param ApplicationInterface $app
  * @return mixed
  * @throws \ObjectivePHP\Primitives\Exception
  * @internal param ApplicationInterface $application
  *
  */
 public function run(ApplicationInterface $app)
 {
     $result = parent::run($app);
     if ($result instanceof Response) {
         $app->setResponse($result);
     } else {
         // set default content type
         $app->setResponse((new HttpResponse())->withHeader('Content-Type', 'text/html'));
         Collection::cast($result)->each(function ($value, $var) {
             Vars::set($var, $value);
         });
     }
 }
 public function render(Tag $tag)
 {
     if ($tag->isClosingTag()) {
         $tag->close(false);
         return '</' . $tag->getTag() . '>';
     } else {
         $html = '<' . trim(implode(' ', [$tag->getTag(), $tag->getAttributes()])) . '>';
         if (!$tag->getContent()->isEmpty()) {
             $chunks = new Collection();
             $tag->getContent()->each(function ($chunk) use(&$chunks) {
                 $content = (string) $chunk;
                 if ($content) {
                     $chunks[] = $content;
                 }
             });
             $html .= $chunks->join($tag->getSeparator())->trim();
             $html .= '</' . $tag->getTag() . '>';
         } elseif ($tag->isAlwaysClosed()) {
             $html .= '</' . $tag->getTag() . '>';
         }
         return $html;
     }
 }
Beispiel #15
0
 /**
  * @param null $type
  *
  * @return int
  * @throws \ObjectivePHP\Primitives\Exception
  */
 public function count($type = null)
 {
     if (is_null($type)) {
         $count = parent::count();
     } else {
         $count = 0;
         $this->each(function (MessageInterface $message) use(&$count, $type) {
             if ($type == $message->getType()) {
                 $count++;
             }
         });
     }
     return $count;
 }
Beispiel #16
0
 public function run(ApplicationInterface $app)
 {
     $matchedRoute = $app->getRequest()->getMatchedRoute();
     $action = Invokable::cast($matchedRoute->getAction());
     $app->getServicesFactory()->injectDependencies($action->getCallable());
     $app->setParam('runtime.action.middleware', $action);
     $result = $action->getCallable()($app);
     if ($result instanceof Response) {
         $app->setResponse($result);
     } else {
         // set default content type
         $app->setResponse((new HttpResponse())->withHeader('Content-Type', 'text/html'));
         Collection::cast($result)->each(function ($value, $var) {
             Vars::set($var, $value);
         });
     }
 }
 public function testContextCanBeReplacedByAnArray()
 {
     $event = new Event();
     $event->setContext(['a' => 'value']);
     $event->setContext(['b' => 'other value']);
     $this->assertEquals(Collection::cast(['b' => 'other value']), $event->getContext());
     $this->expectsException(function () use($event) {
         $event->setContext('wrong type - should be an array or an ArrayObject');
     }, Exception::class, null, Exception::EVENT_INVALID_CONTEXT);
     $this->expectsException(function () use($event) {
         $event->setContext($this);
     }, Exception::class, null, Exception::EVENT_INVALID_CONTEXT);
     $this->expectsException(function () use($event) {
         $newContext = new \stdClass();
         $newContext->property = 'wrong type - should be an array or an ArrayObject';
         $event->setContext($newContext);
     }, Exception::class, null, Exception::EVENT_INVALID_CONTEXT);
 }
Beispiel #18
0
 public function __toString()
 {
     $flattenedAttributes = [];
     $this->each(function ($value, $attribute) use(&$flattenedAttributes) {
         // skip empty collections
         if ($value instanceof Collection && $value->isEmpty()) {
             return;
         }
         if (is_int($attribute)) {
             $flattenedAttributes[] = $value;
         } else {
             if (is_bool($value)) {
                 if ($value === true) {
                     $flattenedAttributes[] = $attribute;
                 }
             } else {
                 $flattenedAttributes[] = $attribute . '="' . Collection::cast($value)->join(' ') . '"';
             }
         }
     });
     return trim(implode(' ', $flattenedAttributes));
 }
Beispiel #19
0
 /**
  * Merge two values according to the defined policy
  *
  * @param $first
  * @param $second
  *
  * @return mixed
  */
 public function merge($first, $second)
 {
     switch ($this->policy) {
         case MergePolicy::COMBINE:
             if ($first instanceof Collection) {
                 // Modify the first collection
                 return $first->append($second);
             } else {
                 return new Collection([$first, $second]);
             }
             break;
         case MergePolicy::REPLACE:
             return $second;
             break;
         case MergePolicy::ADD:
             return Collection::cast($first)->add(Collection::cast($second));
             break;
         case MergePolicy::NATIVE:
             return Collection::cast($first)->merge(Collection::cast($second));
             break;
         default:
             throw new Exception(sprintf('Policy "%s" does not exist', $this->policy), Exception::INVALID_PARAMETER);
     }
 }
 /**
  * Trigger an event
  *
  * @param string $eventName
  * @param mixed $origin
  * @param mixed $context
  *
  * @param EventInterface $event
  * @return EventInterface
  * @throws Exception
  * @throws \ObjectivePHP\Primitives\Exception
  * @throws \ObjectivePHP\ServicesFactory\Exception\ServiceNotFoundException
  */
 public function trigger($eventName, $origin = null, $context = [], EventInterface $event = null)
 {
     if (is_null($origin)) {
         $origin = $this;
     }
     // cast context to Collection
     $context = Collection::cast($context);
     // cannot get event from factory
     // because of injection process
     // which triggers an event causing
     // an infinite loop...
     if (is_null($event)) {
         $event = new Event();
     }
     $event->setName($eventName)->setOrigin($origin)->setContext($context);
     // add reference to previous event if any
     if ($previous = \current($this->currentEventsQueue)) {
         $event->setPrevious($previous);
     }
     $this->currentEventsQueue[(string) $event->getName()] = $event;
     $listeners = $this->getListeners($eventName);
     // TODO sort listeners according to their priority or other mechanism
     $i = 0;
     foreach ($listeners as $listenersGroup) {
         $callbacks = [];
         // handle callbacks aggregate
         foreach ($listenersGroup as $alias => $callback) {
             if ($callback instanceof CallbacksAggregate) {
                 $callback->getCallbacks()->each(function ($callback, $callbackAlias) use(&$callbacks, $alias) {
                     $callbackAlias = implode('.', [$alias, $callbackAlias]);
                     $callbacks[$callbackAlias] = $callback;
                 });
             } else {
                 $callbacks[$alias] = $callback;
             }
         }
         foreach ($callbacks as $alias => $callback) {
             // handle service references
             if ($callback instanceof ServiceReference) {
                 $callback = $this->getServicesFactory()->get($callback->getId());
             }
             // if listener is a class name, instantiate it
             if (!is_callable($callback) && class_exists($callback)) {
                 $className = $callback;
                 $callback = new $className();
                 if (!is_callable($callback)) {
                     throw new Exception(sprintf('Class "%s" does not implement __invoke(), thus cannot be used as a callback', $className), Exception::EVENT_INVALID_CALLBACK);
                 }
             }
             $result = $callback($event);
             // gather exceptions
             if ($result instanceof \Exception) {
                 $event->setException($i, $result);
             }
             $event->setResult(is_string($alias) ? $alias : $i, $result);
             if ($event->isHalted()) {
                 // yes, this is a goto...
                 // I know that it was not absolutely needed, but it's a quite long story
                 // so please keep it as is.
                 // ping @EmmanuelJacoby :)
                 //
                 // @gdelamarre
                 goto shunt;
             }
             if (!is_string($alias)) {
                 $i++;
             }
         }
     }
     // target reached from within the triggering loop
     // if the event was halted by a listener
     shunt:
     // event has been triggered, it is now removed from events queue
     array_pop($this->currentEventsQueue);
     end($this->currentEventsQueue);
     return $event;
 }
Beispiel #21
0
 /**
  * @param RouterInterface $router
  */
 public function register(RouterInterface $router)
 {
     $this->routers->prepend($router);
 }
 public function __construct($arg1 = null, $arg2 = null)
 {
     $this->args = Collection::cast($this->args);
     $this->args['arg1'] = $arg1;
     $this->args['arg2'] = $arg2;
 }
Beispiel #23
0
 /**
  * @param string $name
  * @param array  $input
  */
 public function __construct($name, array $input = [])
 {
     parent::__construct($input);
     $this->setName($name);
     $this->restrictTo(Hook::class, false);
 }
 static function factory($rawDefinition)
 {
     $rawDefinition = Collection::cast($rawDefinition);
     // first check an id has been provided
     if ($rawDefinition->lacks('id')) {
         throw new Exception('Missing mandatory \'id\' parameter in service definition', Exception::INCOMPLETE_SERVICE_SPECS);
     }
     // try to guess service type if not provided
     if ($rawDefinition->lacks('type')) {
         $matchingTypes = [];
         foreach (['instance' => PrefabServiceSpecs::class, 'class' => ClassServiceSpecs::class] as $key => $type) {
             if ($rawDefinition->has($key)) {
                 $matchingTypes[] = $type;
             }
         }
         if (!$matchingTypes) {
             // throw new Exception('The service specs factory has not been able to guess what type of service has been passed. Please check your syntax, or explicitly define the "type" key in your service specifications', Exception::INCOMPLETE_SERVICE_SPECS);
             // default to UndefinedService
             $matchingTypes[] = UndefinedServiceSpecs::class;
         }
         if (count($matchingTypes) > 1) {
             throw new Exception('Service specifications are ambiguous: they contain both "instance" and "class" key. Please remove the unneeded oneor explicitly define the "type" key in your service specifications ', Exception::AMBIGUOUS_SERVICE_SPECS);
         }
         // only one match
         $rawDefinition['type'] = array_pop($matchingTypes);
     }
     $serviceDefinition = call_user_func([$rawDefinition['type'], 'factory'], $rawDefinition);
     // static
     if ($rawDefinition->has('static')) {
         $serviceDefinition->setStatic($rawDefinition['static']);
     }
     // aliases
     if ($rawDefinition->has('alias') || $rawDefinition->has('aliases')) {
         $aliases = new Collection();
         if ($rawDefinition->has('alias')) {
             $aliases[] = $rawDefinition['alias'];
         }
         if ($rawDefinition->has('aliases')) {
             $aliases->merge($rawDefinition['aliases']);
         }
         $serviceDefinition->setAliases($aliases);
     }
     return $serviceDefinition;
 }
 /**
  * Return all defined messages
  *
  * @return Collection
  */
 public function getMessages()
 {
     return Collection::cast($this->messages);
 }
 public function get($param, $default = null, $origin = 'cli')
 {
     return $this->params->get($origin)->get($param, $default);
 }
Beispiel #27
0
 /**
  * @param $key
  *
  * @return $this
  */
 public function remove($reference)
 {
     $reference = $this->computeKeyFQN($reference);
     $matcher = $this->getMatcher();
     Collection::cast(self::$data)->each(function (&$value, $key) use($matcher, $reference) {
         if ($matcher->match($reference, $key)) {
             unset(self::$data[$key]);
         }
     });
     return $this;
 }
Beispiel #28
0
 /**
  * @param MessageStack $errors
  */
 public static function setErrors(Collection $errors)
 {
     // check errors content
     $errors->restrictTo(MessageStack::class);
     self::$errors = $errors;
 }
Beispiel #29
0
 public function getMergers()
 {
     return Collection::cast($this->mergers);
 }
 /**
  * @param $params
  *
  * @return $this
  */
 public function setParams($params)
 {
     $this->params = Collection::cast($params);
     return $this;
 }