Definition::arguments()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
1
<?php namespace nyx\console\input;
2
3
// Internal dependencies
4
use nyx\console\input\parameter\definitions;
5
6
/**
7
 * Input Definition
8
 *
9
 * This class represents a master Input Definition, eg. one that contains definitions for all parameters
10
 * allowed to be present in the Input.
11
 *
12
 * @version     0.1.0
13
 * @author      Michal Chojnacki <[email protected]>
14
 * @copyright   2012-2017 Nyx Dev Team
15
 * @link        https://github.com/unyx/nyx
16
 */
17
class Definition
18
{
19
    /**
20
     * @var definitions\Arguments   The Definitions of the Arguments that can be present in the Input.
21
     */
22
    private $arguments;
23
24
    /**
25
     * @var definitions\Options     The Definitions of the Options that can be present in the Input.
26
     */
27
    private $options;
28
29
    /**
30
     * Constructs a new Input Definition instance.
31
     *
32
     * @param   definitions\Arguments|array     $arguments  The defined Arguments.
33
     * @param   definitions\Options|array       $options    The defined Options.
34
     */
35
    public function __construct($arguments = null, $options = null)
36
    {
37
        $this->arguments = $arguments instanceof definitions\Arguments ? $arguments : new definitions\Arguments($arguments);
38
        $this->options   = $arguments instanceof definitions\Options   ? $options   : new definitions\Options($options);
0 ignored issues
show
Documentation Bug introduced by
It seems like $arguments instanceof \n...tions\Options($options) can also be of type array. However, the property $options is declared as type object<nyx\console\input...er\definitions\Options>. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
39
    }
40
41
    /**
42
     * Returns the Definitions of the Arguments that can be present in the Input.
43
     *
44
     * @return  definitions\Arguments
45
     */
46
    public function arguments() : definitions\Arguments
47
    {
48
        return $this->arguments;
49
    }
50
51
    /**
52
     * Returns the Definitions of the Options that can be present in the Input.
53
     *
54
     * @return  definitions\Options
55
     */
56
    public function options() : definitions\Options
57
    {
58
        return $this->options;
59
    }
60
61
    /**
62
     * Merges this Definition with other Definition(s) and returns the result as a new instance, meaning this one,
63
     * even though used as base for the merger, will be left unscathed.
64
     *
65
     * The merge order works just like array_merge(). Since all parameters are named, duplicates will be overwritten.
66
     * The method creates two new Parameters collections for the merged Arguments and Options. If you use customized bags
67
     * you will need to override the method, as they are not injected for simplicity's sake.
68
     *
69
     * @param   bool|Definition[]   $mergeArguments     Whether to merge the arguments. Can be omitted (ie. you may
70
     *                                                  pass a Definition as the first argument to this method right
71
     *                                                  away, in which case the default of "true" will be used).
72
     * @param   Definition          ...$definitions     The Definitions to merge with this one.
73
     * @return  Definition                              The merged Definition as a new instance.
74
     * @throws  \InvalidArgumentException               When one or more of the parameters is not a Definition
75
     *                                                  instance (not including the $mergeArguments bool).
76
     */
77
    public function merge($mergeArguments = true, Definition ...$definitions) : Definition
78
    {
79
        // Whether to merge the arguments. When the first argument is a Definition already, we will use the default
80
        // of true. Otherwise, strip the first argument out of what we assume to be just an array of Definitions
81
        // after the func_get_args() call.
82
        if ($mergeArguments instanceof Definition) {
83
            array_unshift($definitions, $mergeArguments);
84
            $mergeArguments = true;
85
        } else {
86
            $mergeArguments = (bool) $mergeArguments;
87
        }
88
89
        // We are not simply going to merge the arrays. We'll let the collections do their work and report
90
        // any duplicates etc. as necessary.
91
        $arguments = clone $this->arguments;
92
        $options   = clone $this->options;
93
94
        foreach ($definitions as $definition) {
95
            // Arguments are merged by default but don't necessarily have to be (for instance, help descriptions
96
            // only display the argument for the command itself, not for the whole command chain).
97
            if ($mergeArguments) {
98
                foreach ($definition->arguments as $argument) {
99
                    $arguments->add($argument);
100
                }
101
            }
102
103
            // Options are always merged.
104
            foreach ($definition->options as $option) {
105
                $options->add($option);
106
            }
107
        }
108
109
        return new static($arguments, $options);
110
    }
111
}
112