CommandFactory   A
last analyzed

Complexity

Total Complexity 14

Size/Duplication

Total Lines 95
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 45
dl 0
loc 95
rs 10
c 2
b 0
f 0
wmc 14

3 Methods

Rating   Name   Duplication   Size   Complexity  
A extractParametersFromPrompt() 0 11 2
B fromArray() 0 42 9
A createParameters() 0 16 3
1
<?php
2
3
namespace Startwind\Forrest\Command;
4
5
use Startwind\Forrest\Command\Parameters\Parameter;
6
use Startwind\Forrest\Command\Parameters\ParameterFactory;
7
8
class CommandFactory
9
{
10
    public const CONFIG_FIELD_PROMPT = 'prompt';
11
    public const CONFIG_FIELD_NAME = 'name';
12
    public const CONFIG_FIELD_DESCRIPTION = 'description';
13
    public const CONFIG_FIELD_EXPLANATION = 'explanation';
14
    public const CONFIG_FIELD_PARAMETERS = 'parameters';
15
    public const CONFIG_FIELD_SCORE = 'score';
16
    public const CONFIG_FIELD_ALLOWED_IN_HISTORY = 'allowed-in-history';
17
    public const CONFIG_FIELD_OUTPUT = 'output-format';
18
19
    /**
20
     * Create a Command object out of the given array.
21
     */
22
    public static function fromArray(array $commandConfig, $withParameters = true): Command
23
    {
24
        $prompt = $commandConfig[self::CONFIG_FIELD_PROMPT];
25
26
        if (array_key_exists(self::CONFIG_FIELD_EXPLANATION, $commandConfig)) {
27
            $explanation = $commandConfig[self::CONFIG_FIELD_EXPLANATION];
28
        } else {
29
            $explanation = '';
30
        }
31
32
        $command = new Command($commandConfig[self::CONFIG_FIELD_NAME], $commandConfig[self::CONFIG_FIELD_DESCRIPTION], $prompt, $explanation);
33
34
        $command->setPlainCommandArray($commandConfig);
35
36
        if (array_key_exists(self::CONFIG_FIELD_OUTPUT, $commandConfig)) {
37
            $command->setOutputFormat($commandConfig[self::CONFIG_FIELD_OUTPUT]);
38
        }
39
40
        if (array_key_exists(self::CONFIG_FIELD_ALLOWED_IN_HISTORY, $commandConfig) && $commandConfig[self::CONFIG_FIELD_ALLOWED_IN_HISTORY] === false) {
41
            $command->setAllowedInHistory(false);
42
        }
43
44
        if (array_key_exists(self::CONFIG_FIELD_PARAMETERS, $commandConfig)) {
45
            $parameterConfig = $commandConfig[self::CONFIG_FIELD_PARAMETERS];
46
        } else {
47
            $parameterConfig = [];
48
        }
49
50
51
        if (array_key_exists(self::CONFIG_FIELD_SCORE, $commandConfig)) {
52
            $command->setScore((float)$commandConfig[self::CONFIG_FIELD_SCORE]);
53
        }
54
55
        if (is_string($parameterConfig)) {
56
            throw new \RuntimeException('The configuration is malformed. Array expected but "' . $parameterConfig . '" found.');
57
        }
58
59
        if ($withParameters) {
60
            $command->setParameters(self::createParameters($prompt, $parameterConfig));
61
        }
62
63
        return $command;
64
    }
65
66
    /**
67
     * Create the parameter objects from the array.
68
     *
69
     * @return Parameter[]
70
     */
71
    private static function createParameters(string $prompt, array $parameterConfig): array
72
    {
73
        $parameterNames = self::extractParametersFromPrompt($prompt);
74
75
        $parameters = [];
76
77
        foreach ($parameterNames as $parameterName) {
78
            if (array_key_exists($parameterName, $parameterConfig)) {
79
                $config = $parameterConfig[$parameterName];
80
            } else {
81
                $config = [];
82
            }
83
            $parameters[$parameterName] = ParameterFactory::create($config);
84
        }
85
86
        return $parameters;
87
    }
88
89
    /**
90
     * Use regular expressions to extract the parameters from the prompt.
91
     */
92
    private static function extractParametersFromPrompt(string $prompt): array
93
    {
94
        preg_match_all('^\${[a-zA-Z_:\x7f-\xff][a-zA-Z0-9_:\x7f-\xff\/]*}^', $prompt, $matches);
95
96
        $parameters = [];
97
98
        foreach ($matches[0] as $match) {
99
            $parameters[] = str_replace(Parameter::PARAMETER_PREFIX, '', str_replace(Parameter::PARAMETER_POSTFIX, '', $match));
100
        }
101
102
        return $parameters;
103
    }
104
}
105