Validator   A
last analyzed

Complexity

Total Complexity 23

Size/Duplication

Total Lines 85
Duplicated Lines 0 %

Test Coverage

Coverage 78.13%

Importance

Changes 4
Bugs 2 Features 1
Metric Value
wmc 23
eloc 31
c 4
b 2
f 1
dl 0
loc 85
ccs 25
cts 32
cp 0.7813
rs 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
A validateCommand() 0 10 4
B validateOption() 0 18 11
B validateArguments() 0 14 8
1
<?php
2
3
namespace clearice\argparser;
4
5
6
/**
7
 * An implementation of the validator interface for validating parsed arguments and their definitions.
8
 *
9
 * @package clearice\argparser
10
 */
11
class Validator implements ValidatorInterface
12
{
13
    /**
14
     * Supported keys expected in the option array. This is used for validation./
15
     */
16
    const VALID_OPTION_KEYS = [
17
        'name', 'short_name', 'type', 'help', 'repeats',
18
        'default', 'value', 'required', 'command'
19
    ];
20
21
    /**
22
     * Validates the actual arguments passed to the shell to ensure they meet all the requirements of their definitions.
23
     *
24
     * @param $options
25
     * @param $parsed
26
     * @throws InvalidArgumentException
27
     */
28 5
    public function validateArguments($options, $parsed)
29
    {
30 5
        $required = [];
31 5
        foreach($options as $option) {
32 5
            if(isset($option['required']) && $option['required'] && !isset($parsed[$option['name']]) && $option['command'] == ($parsed['__command'] ?? '')) {
33
                $required[] = $option['name'];
34
            }
35
        }
36
37 5
        if(!empty(($required))) {
38
            throw new InvalidArgumentException(
39
                sprintf(
40
                    "Values for the following options are required%s: %s.\nPass the --help option for more information about possible options.",
41
                    isset($parsed['__command']) ? " for the {$parsed['__command']} command" : "", implode(",", $required)
42
                )
43
            );
44
        }
45 5
    }
46
47
    /**
48
     * Validates option definitions and throws exceptions for poorly defined options.
49
     *
50
     * @param $option
51
     * @param $commands
52
     * @throws InvalidArgumentDescriptionException
53
     * @throws UnknownCommandException
54
     */
55 16
    public function validateOption($option, $commands)
56
    {
57 16
        if (!(isset($option['name']) || isset($option['short_name']))) {
58 1
            throw new InvalidArgumentDescriptionException("An option must have either a name, a short_name or both.");
59
        }
60 15
        $name = $option['name'] ?? $option['short_name'];
61 15
        if(isset($option['default']) && isset($option['required'])) {
62
            throw new InvalidArgumentDescriptionException("A required option, {$name} cannot have a default value.");
63
        }
64 15
        foreach($option as $key => $value) {
65 15
            if(!in_array($key, self::VALID_OPTION_KEYS)) {
66
                throw new InvalidArgumentDescriptionException("Invalid key [$key] in option description for [{$name}]");
67
            }
68
        }
69 15
        if (isset($option['command'])) {
70 7
            foreach(is_array($option['command']) ? $option['command'] : [$option['command']] as $command) {
71 7
                if(!isset($commands[$command])) {
72 1
                    throw new UnknownCommandException("The command '{$command}' for option '{$option['name']}' has not been added to this parser.");
73
                }
74
            }
75
        }
76 15
    }
77
78
    /**
79
     * Validates command definitions and throws exceptions poorly defined commands.
80
     *
81
     * @param $command
82
     * @param $commands
83
     * @throws CommandExistsException
84
     * @throws InvalidArgumentDescriptionException
85
     */
86 7
    public function validateCommand($command, $commands)
87
    {
88 7
        if (!isset($command['name'])) {
89 1
            throw new InvalidArgumentDescriptionException("Command description must contain a name");
90
        }
91 7
        if(!isset($command['help'])) {
92 1
            throw new InvalidArgumentDescriptionException("Please add a brief help message to your command description");
93
        }
94 7
        if (isset($commands[$command['name']])) {
95 1
            throw new CommandExistsException("Command ${command['name']} already exists.");
96
        }
97
    }
98
}