Passed
Push — test ( 63bffd...9ffc6c )
by Tom
03:04
created

Args::getOptionOptionalArgument()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 17
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 4

Importance

Changes 0
Metric Value
cc 4
eloc 11
nc 3
nop 2
dl 0
loc 17
ccs 11
cts 11
cp 1
crap 4
rs 9.9
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 21
    public function __construct(array $arguments)
49
    {
50 21
        $this->arguments = $arguments;
51 21
    }
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 option w/ optional argument
115
     *
116
     * optional by equal sign (--option=argument)
117
     *
118
     * @param string|string[] $option
119
     * @param null|bool|string $default [optional] argument
120
     *
121
     * @return null|bool|string null when not found, default when found with no argument or the argument
122
     */
123 1
    public function getOptionOptionalArgument($option, $default = null)
124
    {
125 1
        $result = null;
126
127 1
        $options = new OptionIterator($this);
128 1
        if ($options->seekOption($option) || $options->currentMatchesOption($option)) {
0 ignored issues
show
Bug introduced by
Are you sure the usage of $options->seekOption($option) targeting Ktomk\Pipelines\Cli\Args...nIterator::seekOption() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
129 1
            $buffer = $options->current();
130 1
            $equalPos = strpos($buffer, '=');
131 1
            if (false === $equalPos) {
132 1
                $result = $default;
133
            } else {
134 1
                $result = (string)substr($buffer, $equalPos + 1);
135
            }
136 1
            unset($this->arguments[$options->key()]);
137
        }
138
139 1
        return $result;
140
    }
141
142
    /**
143
     * Get the argument of an option.
144
     *
145
     * NOTE: returns only the first option value if multiple options would match
146
     *
147
     * @param string|string[] $option
148
     * @param null|bool|string $default [optional]
149
     * @param bool $required [optional]
150
     *
151
     * @throws InvalidArgumentException
152
     * @throws ArgsException
153
     *
154
     * @return null|bool|string
155
     */
156 7
    public function getOptionArgument($option, $default = null, $required = false)
157
    {
158 7
        $result = null;
159
160
        /** @var OptionFilterIterator|OptionIterator $options */
161 7
        $options = new OptionFilterIterator($this, $option);
162
        /** @noinspection LoopWhichDoesNotLoopInspection */
163 7
        foreach ($options as $index => $argument) {
164
            /** @scrutinizer ignore-call */
165 3
            $result = $options->getArgument();
166 1
            unset($this->arguments[$index], $this->arguments[$index + 1]);
167
168 1
            break; # first match
169
        }
170
171 5
        if (null === $result) {
172 4
            if ($required) {
173 1
                throw new ArgsException(sprintf(
174 1
                    'option %s is not optional',
175
                    $options->/** @scrutinizer ignore-call */
176 1
                    getOptionDescription()
177
                ));
178
            }
179
180 3
            $result = $default;
181
        }
182
183 4
        return $result;
184
    }
185
186
    /**
187
     * Get the argument of an option.
188
     *
189
     * NOTE: returns only the first option value if multiple options would match
190
     *
191
     * @param string|string[] $option
192
     * @param string $default
193
     * @param bool $required [optional]
194
     *
195
     * @throws InvalidArgumentException
196
     * @throws ArgsException
197
     *
198
     * @return string
199
     */
200 1
    public function getStringOptionArgument($option, $default, $required = false)
201
    {
202 1
        if (!is_string($default)) {
0 ignored issues
show
introduced by
The condition is_string($default) is always true.
Loading history...
203 1
            throw new InvalidArgumentException(sprintf('default value must be string, %s given', gettype($default)));
204
        }
205
206 1
        return (string)$this->getOptionArgument($option, $default, $required);
207
    }
208
209
    /**
210
     * @return string
211
     */
212 1
    public function getUtility()
213
    {
214 1
        return $this->utility;
215
    }
216
217
    /**
218
     * @return array
219
     */
220 1
    public function getRemaining()
221
    {
222 1
        return $this->arguments;
223
    }
224
}
225