Passed
Push — master ( a5203b...48c4ea )
by Tom
04:36
created

Args::mapOption()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 7
nc 3
nop 2
dl 0
loc 12
ccs 8
cts 8
cp 1
crap 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
/* this file is part of pipelines */
4
5
namespace Ktomk\Pipelines\Cli;
6
7
use InvalidArgumentException;
8
use Ktomk\Pipelines\Cli\Args\Args as ArgsArgs;
9
use Ktomk\Pipelines\Cli\Args\OptionFilterIterator;
10
use Ktomk\Pipelines\Cli\Args\OptionIterator;
11
12
/**
13
 * Class Args
14
 *
15
 * Facade class to access arguments related functionality
16
 *
17
 * @package Ktomk\Pipelines\Cli
18
 */
19
class Args extends ArgsArgs
20
{
21
    /**
22
     * @var string $utility name
23
     */
24
    private $utility = '';
25
26
    /**
27
     * create from $argv
28
     *
29
     * @param array $argv
30
     *
31
     * @throws InvalidArgumentException
32
     *
33
     * @return Args
34
     */
35 5
    public static function create(array $argv)
36
    {
37 5
        if (0 === count($argv)) {
38 1
            throw new InvalidArgumentException('There must be at least one argument (the command name)');
39
        }
40
41 4
        $command = (string)array_shift($argv);
42 4
        $args = new self($argv);
43 4
        $args->utility = $command;
44
45 4
        return $args;
46
    }
47
48 20
    public function __construct(array $arguments)
49
    {
50 20
        $this->arguments = $arguments;
51 20
    }
52
53
    /**
54
     * test for option and consume any of them. these options
55
     * are all w/o option argument. e.g. check for -v/--verbose.
56
     *
57
     * @param string|string[] $option
58
     *
59
     * @throws InvalidArgumentException
60
     *
61
     * @return bool
62
     */
63 3
    public function hasOption($option)
64
    {
65 3
        $options = new OptionFilterIterator($this, $option);
66
67
        # consume arguments
68 3
        foreach ($options as $index => $argument) {
69 3
            unset($this->arguments[$index]);
70
        }
71
72 3
        return isset($index);
73
    }
74
75
    /**
76
     * map options on array keyed with options to parameters
77
     *
78
     * both provided to callback, options as first, parameter as
79
     * second parameter.
80
     *
81
     * @param array $map
82
     * @param callable $callback
83
     *
84
     * @return array results
85
     */
86 1
    public function mapOption(array $map, $callback)
87
    {
88 1
        $results = array();
89 1
        foreach ($map as $option => $parameter) {
90 1
            $result = array(false, null);
91 1
            if ($this->hasOption($option)) {
92 1
                $result = array(true, call_user_func($callback, $option, $parameter));
93
            }
94 1
            $results[$option] = $result;
95
        }
96
97 1
        return $results;
98
    }
99
100
    /**
101
     * @return null|string
102
     */
103 8
    public function getFirstRemainingOption()
104
    {
105
        /** @noinspection LoopWhichDoesNotLoopInspection */
106 8
        foreach (new OptionIterator($this) as $option) {
107 3
            return $option;
108
        }
109
110 5
        return null;
111
    }
112
113
    /**
114
     * Get the argument of an option.
115
     *
116
     * NOTE: returns only the first option value if multiple options would match
117
     *
118
     * @param string|string[] $option
119
     * @param null|bool|string $default [optional]
120
     * @param bool $required [optional]
121
     *
122
     * @throws InvalidArgumentException
123
     * @throws ArgsException
124
     *
125
     * @return null|bool|string
126
     */
127 7
    public function getOptionArgument($option, $default = null, $required = false)
128
    {
129 7
        $result = null;
130
131
        /** @var OptionFilterIterator|OptionIterator $options */
132 7
        $options = new OptionFilterIterator($this, $option);
133
        /** @noinspection LoopWhichDoesNotLoopInspection */
134 7
        foreach ($options as $index => $argument) {
135
            /** @scrutinizer ignore-call */
136 3
            $result = $options->getArgument();
137 1
            unset($this->arguments[$index], $this->arguments[$index + 1]);
138
139 1
            break; # first match
140
        }
141
142 5
        if (null === $result) {
143 4
            if ($required) {
144 1
                ArgsException::__(sprintf(
145 1
                    'option %s is not optional',
146
                    $options->/** @scrutinizer ignore-call */
147 1
                    getOptionDescription()
148
                ));
149
            }
150
151 3
            $result = $default;
152
        }
153
154 4
        return $result;
155
    }
156
157
    /**
158
     * Get the argument of an option.
159
     *
160
     * NOTE: returns only the first option value if multiple options would match
161
     *
162
     * @param string|string[] $option
163
     * @param string $default
164
     * @param bool $required [optional]
165
     *
166
     * @throws InvalidArgumentException
167
     * @throws ArgsException
168
     *
169
     * @return string
170
     */
171 1
    public function getStringOptionArgument($option, $default, $required = false)
172
    {
173 1
        if (!is_string($default)) {
0 ignored issues
show
introduced by
The condition is_string($default) is always true.
Loading history...
174 1
            throw new InvalidArgumentException(sprintf('default value must be string, %s given', gettype($default)));
175
        }
176
177 1
        return (string)$this->getOptionArgument($option, $default, $required);
178
    }
179
180
    /**
181
     * @return string
182
     */
183 1
    public function getUtility()
184
    {
185 1
        return $this->utility;
186
    }
187
188
    /**
189
     * @return array
190
     */
191 1
    public function getRemaining()
192
    {
193 1
        return $this->arguments;
194
    }
195
}
196