em = $em; $this->id = $id; $this->converter = $converter; $this->handlers = $handlers; $this->handlers->loadConfiguration(array_merge([ IdFilter::class => IdFilterDatabaseHandler::class, Limit::class => LimitDatabaseHandler::class, FieldFilter::class => FieldFilterDatabaseHandler::class, RelatedFilter::class => RelatedFilterDatabaseGenericHandler::class, With::class => GenericWithDatabaseHandler::class, ], static::getHandlers())); } /** @return static */ public function withProvider(ProviderEntity $provider) { $result = clone $this; $result->provider = $provider; return $result; } protected function convert($entity) { return $this->converter->convert($entity); } protected function reference($class, Referable $referable) { $id = $this->id->generate($this->provider, $referable->getId()); return $this->em->getReference($class, $id); } protected function processQueryBuilder(QueryBuilder $builder, iterable $modifiers, array $meta = []) { $reducers = []; foreach ($modifiers as $modifier) { $handler = $this->handlers->get($modifier); if ($handler instanceof ModifierHandler) { $event = new HandleDatabaseModifierEvent($modifier, $this, $builder, array_merge([ 'provider' => $this->provider, ], $meta)); $handler->process($event); } if ($handler instanceof PostProcessingHandler) { $reducers[] = function ($result) use ($meta, $modifier, $handler) { $event = new PostProcessEvent($result, $modifier, $this, array_merge([ 'provider' => $this->provider, ], $meta)); $handler->postProcess($event); return $event->getData(); }; } } return collect($reducers); } protected function allFromQueryBuilder(QueryBuilder $builder, iterable $modifiers, array $meta = []) { $builder->setMaxResults(self::DEFAULT_LIMIT); $reducers = $this->processQueryBuilder($builder, $modifiers, $meta); $result = collect($builder->getQuery()->execute())->map(\Closure::fromCallable([$this, 'convert'])); return $reducers->reduce(function ($result, $reducer) { return $reducer($result); }, $result); } public function first(Modifier ...$modifiers) { return $this->all(Limit::count(1), ...$modifiers)->first(); } /** * Returns array describing handlers for each modifier type. Syntax is as follows: * [ IdFilter::class => IdFilterDatabaseHandler::class ] * * It is internally used as part of service subscriber. * * @return array */ protected static function getHandlers() { return []; } }