protected function findBestNextTask($branches, $taskList, ProcessConfiguration $process)
    {
        // Get resolvable tasks
        $taskCandidates = [];
        foreach ($taskList as $taskCode) {
            $task = $process->getTaskConfiguration($taskCode);
            if (empty($task->getPreviousTasksConfigurations())) {
                return $taskCode;
            }

            // Check if task has all necessary ancestors in branches
            $hasAllAncestors = array_reduce($task->getPreviousTasksConfigurations(), function ($result, TaskConfiguration $prevTask) use ($branches) {
                return $result && \in_array($prevTask->getCode(), $branches);
            }, true);

            if ($hasAllAncestors) {
                $taskCandidates[] = $taskCode;
            }
        }

        if (empty($taskCandidates)) {
            throw new \UnexpectedValueException('Cannot find a task to output');
        }

        // Try to find the task the most on the right
        $taskWeights = [];
        foreach ($taskCandidates as $taskCandidate) {
            $weight = 0;
            $task = $process->getTaskConfiguration($taskCandidate);
            foreach ($task->getPreviousTasksConfigurations() as $prevTask) {
                $key = array_search($prevTask->getCode(), $branches);

                // Should never be non-numeric...
                if (!is_numeric($key)) {
                    throw new \UnexpectedValueException('Invalid key type');
                }
                $weight += $key;
            }

            if (!empty($task->getPreviousTasksConfigurations())) {
                $weight = $weight / \count($task->getPreviousTasksConfigurations());
            }

            $taskWeights[$taskCandidate] = $weight;
        }

        arsort($taskWeights);
        $bestCandidate = key($taskWeights);
        $bestWeight = $taskWeights[$bestCandidate];

        $equalWeights = array_filter($taskWeights, function ($item) use ($bestWeight) {
            return $item == $bestWeight;
        });

        if (count($equalWeights) == 1) {
            return $bestCandidate;
        }

        // If a few tasks have the same weight, return the tasks with the lowest number of children
        $childCounts = [];
        foreach ($equalWeights as $taskCode => $weight) {
            $task = $process->getTaskConfiguration($taskCode);
            $childCounts[$taskCode] = $this->getTaskChildrenCount($task);
        }
        asort($childCounts);

        return key($childCounts);
    }
protected function findBestNextTask($branches, $taskList, ProcessConfiguration $process)
    {
        // Get resolvable tasks
        $taskCandidates = [];
        foreach ($taskList as $taskCode) {
            $task = $process->getTaskConfiguration($taskCode);
            if (empty($task->getPreviousTasksConfigurations())) {
                return $taskCode;
            }

            // Check if task has all necessary ancestors in branches
            $hasAllAncestors = array_reduce($task->getPreviousTasksConfigurations(), function ($result, TaskConfiguration $prevTask) use ($branches) {
                return $result && \in_array($prevTask->getCode(), $branches);
            }, true);

            if ($hasAllAncestors) {
                $taskCandidates[] = $taskCode;
            }
        }

        if (empty($taskCandidates)) {
            throw new \UnexpectedValueException('Cannot find a task to output');
        }

        // Try to find the task the most on the right
        $taskWeights = [];
        foreach ($taskCandidates as $taskCandidate) {
            $weight = 0;
            $task = $process->getTaskConfiguration($taskCandidate);
            foreach ($task->getPreviousTasksConfigurations() as $prevTask) {
                $key = array_search($prevTask->getCode(), $branches);

                // Should never be non-numeric...
                if (!is_numeric($key)) {
                    throw new \UnexpectedValueException('Invalid key type');
                }
                $weight += $key;
            }

            if (!empty($task->getPreviousTasksConfigurations())) {
                $weight = $weight / \count($task->getPreviousTasksConfigurations());
            }

            $taskWeights[$taskCandidate] = $weight;
        }

        arsort($taskWeights);
        $bestCandidate = key($taskWeights);
        $bestWeight = $taskWeights[$bestCandidate];

        $equalWeights = array_filter($taskWeights, function ($item) use ($bestWeight) {
            return $item == $bestWeight;
        });

        if (count($equalWeights) == 1) {
            return $bestCandidate;
        }

        // If a few tasks have the same weight, return the tasks with the lowest number of children
        $childCounts = [];
        foreach ($equalWeights as $taskCode => $weight) {
            $task = $process->getTaskConfiguration($taskCode);
            $childCounts[$taskCode] = $this->getTaskChildrenCount($task);
        }
        asort($childCounts);

        return key($childCounts);
    }
protected function findBestNextTask ( $ branches , $ taskList , ProcessConfiguration $ process ) { // Get resolvable tasks $ taskCandidates = [ ] ; foreach ( $ taskList as $ taskCode ) { $ task = $ process -> getTaskConfiguration ( $ taskCode ) ; if ( empty ( $ task -> getPreviousTasksConfigurations ( ) ) ) { return $ taskCode ; } // Check if task has all necessary ancestors in branches $ hasAllAncestors = array_reduce ( $ task -> getPreviousTasksConfigurations ( ) , function ( $ result , TaskConfiguration $ prevTask ) use ( $ branches ) { return $ result && \ in_array ( $ prevTask -> getCode ( ) , $ branches ) ; } , true ) ; if ( $ hasAllAncestors ) { $ taskCandidates [ ] = $ taskCode ; } } if ( empty ( $ taskCandidates ) ) { throw new \ UnexpectedValueException ( 'Cannot find a task to output' ) ; } // Try to find the task the most on the right $ taskWeights = [ ] ; foreach ( $ taskCandidates as $ taskCandidate ) { $ weight = 0 ; $ task = $ process -> getTaskConfiguration ( $ taskCandidate ) ; foreach ( $ task -> getPreviousTasksConfigurations ( ) as $ prevTask ) { $ key = array_search ( $ prevTask -> getCode ( ) , $ branches ) ; // Should never be non-numeric... if ( ! is_numeric ( $ key ) ) { throw new \ UnexpectedValueException ( 'Invalid key type' ) ; } $ weight += $ key ; } if ( ! empty ( $ task -> getPreviousTasksConfigurations ( ) ) ) { $ weight = $ weight / \ count ( $ task -> getPreviousTasksConfigurations ( ) ) ; } $ taskWeights [ $ taskCandidate ] = $ weight ; } arsort ( $ taskWeights ) ; $ bestCandidate = key ( $ taskWeights ) ; $ bestWeight = $ taskWeights [ $ bestCandidate ] ; $ equalWeights = array_filter ( $ taskWeights , function ( $ item ) use ( $ bestWeight ) { return $ item == $ bestWeight ; } ) ; if ( count ( $ equalWeights ) == 1 ) { return $ bestCandidate ; } // If a few tasks have the same weight, return the tasks with the lowest number of children $ childCounts = [ ] ; foreach ( $ equalWeights as $ taskCode => $ weight ) { $ task = $ process -> getTaskConfiguration ( $ taskCode ) ; $ childCounts [ $ taskCode ] = $ this -> getTaskChildrenCount ( $ task ) ; } asort ( $ childCounts ) ; return key ( $ childCounts ) ; }
Try to find a best candidate for next display

@param                      $branches
@param                      $taskList
@param ProcessConfiguration $process

@return int|null|string
Try to find a best candidate for next display