Resolve an operation, taking runtime constraints into account.

@param string      $operationName
@param array|mixed $context
@throws FlowQueryException
@return OperationInterface the resolved operation
519146
public function resolveOperation($operationName, $context)
    {
        if (!isset($this->operations[$operationName])) {
            throw new FlowQueryException('Operation "' . $operationName . '" not found.', 1332491837);
        }

        foreach ($this->operations[$operationName] as $operationClassName) {
            /** @var OperationInterface $operation */
            $operation = $this->objectManager->get($operationClassName);
            if ($operation->canEvaluate($context)) {
                return $operation;
            }
        }
        throw new FlowQueryException('No operation which satisfies the runtime constraints found for "' . $operationName . '".', 1332491864);
    }
1007056
public function evaluate(FlowQuery $flowQuery, array $arguments)
    {
        $output = [];
        $outputNodePaths = [];

        $filter = isset($arguments[0]) ? $arguments[0] : null;

        /** @var NodeInterface $contextNode */
        foreach ($flowQuery->getContext() as $contextNode) {
            /** @var NodeInterface $childNode */
            foreach ($contextNode->getChildNodes($filter) as $childNode) {
                if (!isset($outputNodePaths[$childNode->getPath()])) {
                    $output[] = $childNode;
                    $outputNodePaths[$childNode->getPath()] = true;
                }
            }
        }
        $flowQuery->setContext($output);
    }
519658
public function evaluate(FlowQuery $flowQuery, array $arguments)
    {
        $output = [];
        $outputNodeAggregateIdentifiers = [];
        foreach ($flowQuery->getContext() as $contextNode) {
            /** @var TraversableNodeInterface $contextNode */
            $outputNodeAggregateIdentifiers[(string)$contextNode->getNodeAggregateIdentifier()] = true;
        }

        foreach ($flowQuery->getContext() as $contextNode) {
            try {
                $parentNode = $contextNode->findParentNode();
            } catch (NodeException $e) {
                continue;
            }

            foreach ($parentNode->findChildNodes() as $childNode) {
                if (!isset($outputNodeAggregateIdentifiers[(string)$childNode->getNodeAggregateIdentifier()])) {
                    $output[] = $childNode;
                    $outputNodeAggregateIdentifiers[(string)$childNode->getNodeAggregateIdentifier()] = true;
                }
            }
        }
        $flowQuery->setContext($output);

        if (isset($arguments[0]) && !empty($arguments[0])) {
            $flowQuery->pushOperation('filter', $arguments);
        }
    }
1304036
private function resolveContainer(): ContainerInterface
    {
        if ($this->container === null) {
            $container = $this->containerFactory->build($this);

            if (!$container instanceof ContainerInterface) {
                throw new \RuntimeException(
                    "Invalid factory result, expected ContainerInterface"
                );
            }

            $this->container = $container;
        }

        return $this->container;
    }
320644
public function getCollection(string $resourceClass, string $operationName = null, array $context = [])
    {
        /** @var ObjectManager $manager */
        $manager = $this->managerRegistry->getManagerForClass($resourceClass);

        $repository = $manager->getRepository($resourceClass);
        if (!method_exists($repository, 'createQueryBuilder')) {
            throw new RuntimeException('The repository class must have a "createQueryBuilder" method.');
        }

        $queryBuilder = $repository->createQueryBuilder('o');
        $queryNameGenerator = new QueryNameGenerator();
        foreach ($this->collectionExtensions as $extension) {
            $extension->applyToCollection($queryBuilder, $queryNameGenerator, $resourceClass, $operationName, $context);

            if ($extension instanceof QueryResultCollectionExtensionInterface && $extension->supportsResult($resourceClass, $operationName, $context)) {
                return $extension->getResult($queryBuilder, $resourceClass, $operationName, $context);
            }
        }

        return $queryBuilder->getQuery()->getResult();
    }
179272
public function evaluate(FlowQuery $flowQuery, array $arguments)
    {
        $context = $flowQuery->getContext();
        if (isset($arguments[0])) {
            $index = $arguments[0];
            if (isset($context[$index])) {
                return $context[$index];
            } else {
                return null;
            }
        } else {
            return $context;
        }
    }
515071
public function evaluate(FlowQuery $flowQuery, array $arguments)
    {
        $sortOrder = 'ASC';
        if (!empty($arguments[0]) && in_array($arguments[0], ['ASC', 'DESC'], true)) {
            $sortOrder = $arguments[0];
        }
        
        $nodes = $flowQuery->getContext();

        $indexPathCache = [];

        /** @var NodeInterface $node */
        foreach ($nodes as $node) {
            // Collect the list of sorting indices for all parents of the node and the node itself
            $nodeIdentifier = $node->getIdentifier();
            $indexPath = [$node->getIndex()];
            while ($node = $node->getParent()) {
                $indexPath[] = $node->getIndex();
            }
            $indexPathCache[$nodeIdentifier] = $indexPath;
        }

        $flip = $sortOrder === 'DESC' ? -1 : 1;

        usort($nodes, function (NodeInterface $a, NodeInterface $b) use ($indexPathCache, $flip) {
            if ($a === $b) {
                return 0;
            }

            // Compare index path starting from the site root until a difference is found
            $aIndexPath = $indexPathCache[$a->getIdentifier()];
            $bIndexPath = $indexPathCache[$b->getIdentifier()];
            while (count($aIndexPath) > 0 && count($bIndexPath) > 0) {
                $diff = (array_pop($aIndexPath) - array_pop($bIndexPath));
                if ($diff !== 0) {
                    return $flip * $diff < 0 ? -1 : 1;
                }
            }

            return 0;
        });

        $flowQuery->setContext($nodes);
    }
1308722
private function getEnabled(array $context, string $resourceClass = null, string $operationName = null, bool $partial = false): bool
    {
        $enabled = $this->options[$partial ? 'partial' : 'enabled'];
        $clientEnabled = $this->options[$partial ? 'client_partial' : 'client_enabled'];

        if (null !== $resourceClass) {
            $resourceMetadata = $this->resourceMetadataFactory->create($resourceClass);
            $enabled = $resourceMetadata->getCollectionOperationAttribute($operationName, $partial ? 'pagination_partial' : 'pagination_enabled', $enabled, true);

            $clientEnabled = $resourceMetadata->getCollectionOperationAttribute($operationName, $partial ? 'pagination_client_partial' : 'pagination_client_enabled', $clientEnabled, true);
        }

        if ($clientEnabled) {
            return filter_var($this->getParameterFromContext($context, $this->options[$partial ? 'partial_parameter_name' : 'enabled_parameter_name'], $enabled), FILTER_VALIDATE_BOOLEAN);
        }

        return $enabled;
    }
119911
public function getOperation($name)
    {
        if (!isset($this->operations[$name])) {
            if (!isset($this->definition['operations'][$name])) {
                throw new \InvalidArgumentException("Unknown operation: $name");
            }
            $this->operations[$name] = new Operation(
                $this->definition['operations'][$name],
                $this->shapeMap
            );
        }

        return $this->operations[$name];
    }
580128
public function resolve(object $message, ServiceBusContext $context, MessageHandlerArgument $argument): object
    {
        /** @var object $object */
        $object = $this->serviceLocator->get((string) $argument->typeClass);

        return $object;
    }
124027
public static function resolve(array $parameters, $context = null)
    {
        $params = [];
        foreach ($parameters as $key => $value) {
            if ($value instanceof Reference) {
                $val = $value->getValue();
                if (isset($context[$val])) {
                    $params[$key] = $context[$val];
                } else {
                    throw new RuntimeException('Reference invalid context key "' . $val . '"');
                }
            } else {
                $params[$key] = $value;
            }
        }

        return $params;
    }
908010
protected function execute(array $configuration, &$context)
    {
        $parameters = $this->confHelper->resolve($configuration[self::CONF_PARAMETERS], $context);
        $parameters = $this->prepareParameters($parameters);

        $sql = $this->confHelper->resolve($configuration[self::CONF_SQL], $context);

        return $this->performQuery($configuration, $context, $parameters, $sql);
    }
199370
public function evaluate(FlowQuery $flowQuery, array $arguments)
    {
        if (!isset($arguments[0]) || empty($arguments[0])) {
            return;
        }
        if (!is_string($arguments[0])) {
            throw new FizzleException('filter operation expects string argument', 1332489625);
        }
        $filter = $arguments[0];

        $parsedFilter = FizzleParser::parseFilterGroup($filter);

        $filteredContext = [];
        $context = $flowQuery->getContext();
        foreach ($context as $element) {
            if ($this->matchesFilterGroup($element, $parsedFilter)) {
                $filteredContext[] = $element;
            }
        }
        $flowQuery->setContext($filteredContext);
    }
985686
public function resolve($name)
    {
        return isset($this->services[$name]) ? $this->iteratorFactory->create($this->services[$name]) : null;
    }
212753
public function getCollection(string $resourceClass, string $operationName = null, array $context = [])
    {
        /** @var DocumentManager $manager */
        $manager = $this->managerRegistry->getManagerForClass($resourceClass);

        $repository = $manager->getRepository($resourceClass);
        if (!$repository instanceof DocumentRepository) {
            throw new RuntimeException(sprintf('The repository for "%s" must be an instance of "%s".', $resourceClass, DocumentRepository::class));
        }

        $aggregationBuilder = $repository->createAggregationBuilder();
        foreach ($this->collectionExtensions as $extension) {
            $extension->applyToCollection($aggregationBuilder, $resourceClass, $operationName, $context);

            if ($extension instanceof AggregationResultCollectionExtensionInterface && $extension->supportsResult($resourceClass, $operationName, $context)) {
                return $extension->getResult($aggregationBuilder, $resourceClass, $operationName, $context);
            }
        }

        return $aggregationBuilder->hydrate($resourceClass)->execute();
    }
420
public function evaluate(FlowQuery $flowQuery, array $arguments)
    {
        $subject = $arguments[0];
        if (!isset($subject) || empty($subject)) {
            $flowQuery->setContext([]);
            return;
        }

        $filteredContext = [];
        $context = $flowQuery->getContext();
        if (is_string($subject)) {
            foreach ($context as $contextElement) {
                $contextElementQuery = new FlowQuery([$contextElement]);
                $contextElementQuery->pushOperation('children', $arguments);
                if ($contextElementQuery->count() > 0) {
                    $filteredContext[] = $contextElement;
                }
            }
        } else {
            if ($subject instanceof FlowQuery) {
                $elements = $subject->get();
            } elseif ($subject instanceof \Traversable) {
                $elements = iterator_to_array($subject);
            } elseif (is_object($subject)) {
                $elements = [$subject];
            } elseif (is_array($subject)) {
                $elements = $subject;
            } else {
                throw new FizzleException('supplied argument for has operation not supported', 1332489625);
            }
            foreach ($elements as $element) {
                if ($element instanceof TraversableNodeInterface) {
                    $parentsQuery = new FlowQuery([$element]);
                    foreach ($parentsQuery->parents([])->get() as $parent) {
                        /** @var TraversableNodeInterface $parent */
                        foreach ($context as $contextElement) {
                            /** @var TraversableNodeInterface $contextElement */
                            if ($contextElement === $parent) {
                                $filteredContext[] = $contextElement;
                            }
                        }
                    }
                }
            }
            $filteredContext = array_unique($filteredContext);
        }

        $flowQuery->setContext($filteredContext);
    }
434096
public function resolveArguments($callable, array $context) {
        $resolve_arg = $this->resolve_arg;

        $rf = $this->callableToReflectionFunctionAbstract($callable);

        $args = [];
        foreach ($rf->getParameters() as $i => $arg_meta) {
            $arg = $resolve_arg($arg_meta, $context);
            if (!count($arg) && $arg_meta->isOptional()) {
                continue;
            } else if (!count($arg)) {
                throw new Exception\ResolutionException($arg_meta);
            }

            $args[] = $arg[0];
        }

        return $args;
    }