Completed
Push — master ( 360824...c62b77 )
by Bernhard
02:24
created

BindingType::acceptsBinding()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 3

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 6
ccs 4
cts 4
cp 1
rs 9.4285
cc 3
eloc 4
nc 3
nop 1
crap 3
1
<?php
2
3
/*
4
 * This file is part of the puli/discovery package.
5
 *
6
 * (c) Bernhard Schussek <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Puli\Discovery\Api\Type;
13
14
use InvalidArgumentException;
15
use Puli\Discovery\Api\Binding\Binding;
16
use Webmozart\Assert\Assert;
17
18
/**
19
 * A type that a binding can be bound to.
20
 *
21
 * @since  1.0
22
 *
23
 * @author Bernhard Schussek <[email protected]>
24
 */
25
class BindingType
26
{
27
    /**
28
     * @var string
29
     */
30
    private $name;
31
32
    /**
33
     * @var string
34
     */
35
    private $acceptedBindingClass;
36
37
    /**
38
     * @var BindingParameter[]
39
     */
40
    private $parameters = array();
41
42
    /**
43
     * Creates a new type.
44
     *
45
     * @param string             $name         The name of the type.
46
     * @param string             $bindingClass The class name of the accepted
47
     *                                         bindings.
48
     * @param BindingParameter[] $parameters   The parameters that can be set
49
     *                                         for a binding.
50
     */
51 190
    public function __construct($name, $bindingClass, array $parameters = array())
52
    {
53 190
        Assert::stringNotEmpty($name, 'The type name must be a non-empty string. Got: %s');
54 189
        Assert::allIsInstanceOf($parameters, 'Puli\Discovery\Api\Type\BindingParameter');
55
56 188
        if (!class_exists($bindingClass) && !interface_exists($bindingClass)) {
57 1
            throw new InvalidArgumentException(sprintf(
58
                'The binding class "%s" is neither a class nor an '.
59 1
                'interface name. Is there a typo?',
60
                $bindingClass
61
            ));
62
        }
63
64 187
        $this->name = $name;
65 187
        $this->acceptedBindingClass = $bindingClass;
66
67 187
        foreach ($parameters as $parameter) {
68 44
            $this->parameters[$parameter->getName()] = $parameter;
69
        }
70
71
        // Sort to facilitate comparison
72 187
        ksort($this->parameters);
73 187
    }
74
75
    /**
76
     * Returns the type's name.
77
     *
78
     * @return string The name of the type.
79
     */
80 166
    public function getName()
81
    {
82 166
        return $this->name;
83
    }
84
85
    /**
86
     * Returns the parameters.
87
     *
88
     * @return BindingParameter[] The type parameters.
89
     */
90 96
    public function getParameters()
91
    {
92 96
        return $this->parameters;
93
    }
94
95
    /**
96
     * Returns whether the type has parameters.
97
     *
98
     * @return bool Returns `true` if the type has parameters and `false`
99
     *              otherwise.
100
     */
101 2
    public function hasParameters()
102
    {
103 2
        return count($this->parameters) > 0;
104
    }
105
106
    /**
107
     * Returns whether the type has any required parameters.
108
     *
109
     * @return bool Returns `true` if the type has at least one required
110
     *              parameter.
111
     */
112 2
    public function hasRequiredParameters()
113
    {
114 2
        foreach ($this->parameters as $parameter) {
115 2
            if ($parameter->isRequired()) {
116 2
                return true;
117
            }
118
        }
119
120 1
        return false;
121
    }
122
123
    /**
124
     * Returns whether the type has any optional parameters.
125
     *
126
     * @return bool Returns `true` if the type has at least one optional
127
     *              parameter.
128
     */
129 2
    public function hasOptionalParameters()
130
    {
131 2
        foreach ($this->parameters as $parameter) {
132 2
            if (!$parameter->isRequired()) {
133 2
                return true;
134
            }
135
        }
136
137 1
        return false;
138
    }
139
140
    /**
141
     * Returns a parameter by name.
142
     *
143
     * @param string $name The parameter name.
144
     *
145
     * @return BindingParameter The parameter.
146
     *
147
     * @throws NoSuchParameterException If the parameter was not found.
148
     */
149 7
    public function getParameter($name)
150
    {
151 7
        if (!isset($this->parameters[$name])) {
152 3
            throw new NoSuchParameterException(sprintf(
153 3
                'The parameter "%s" does not exist on type "%s".',
154
                $name,
155 3
                $this->name
156
            ));
157
        }
158
159 4
        return $this->parameters[$name];
160
    }
161
162
    /**
163
     * Returns whether a parameter exists.
164
     *
165
     * @param string $name The parameter name.
166
     *
167
     * @return bool Returns `true` if a parameter with that name exists.
168
     */
169 33
    public function hasParameter($name)
170
    {
171 33
        return isset($this->parameters[$name]);
172
    }
173
174
    /**
175
     * Returns the default values of the parameters.
176
     *
177
     * @return array The default values of the parameters.
178
     */
179 95
    public function getParameterValues()
180
    {
181 95
        $values = array();
182
183 95
        foreach ($this->parameters as $name => $parameter) {
184 32
            if (!$parameter->isRequired()) {
185 32
                $values[$name] = $parameter->getDefaultValue();
186
            }
187
        }
188
189 95
        return $values;
190
    }
191
192
    /**
193
     * Returns whether the type has parameters with default values.
194
     *
195
     * @return bool Returns `true` if at least one parameter has a default value
196
     *              and `false` otherwise.
197
     */
198 2
    public function hasParameterValues()
199
    {
200 2
        foreach ($this->parameters as $name => $parameter) {
201 2
            if (!$parameter->isRequired()) {
202 2
                return true;
203
            }
204
        }
205
206 1
        return false;
207
    }
208
209
    /**
210
     * Returns the default value of a parameter.
211
     *
212
     * @param string $name The parameter name.
213
     *
214
     * @return mixed The default value.
215
     *
216
     * @throws NoSuchParameterException If the parameter was not found.
217
     */
218 3
    public function getParameterValue($name)
219
    {
220 3
        return $this->getParameter($name)->getDefaultValue();
221
    }
222
223
    /**
224
     * Returns whether a parameter has a default value set.
225
     *
226
     * @param string $name The parameter name.
227
     *
228
     * @return bool Returns `true` if the parameter has a default value set and
229
     *              `false` otherwise.
230
     *
231
     * @throws NoSuchParameterException If the parameter was not found.
232
     */
233 2
    public function hasParameterValue($name)
234
    {
235 2
        return !$this->getParameter($name)->isRequired();
236
    }
237
238
    /**
239
     * Returns whether the type accepts a binding class.
240
     *
241
     * @param Binding|string $binding The binding or the fully-qualified name of
242
     *                                the binding class.
243
     *
244
     * @return bool Returns `true` if the binding can be bound to this type and
245
     *              `false` otherwise.
246
     */
247 105
    public function acceptsBinding($binding)
248
    {
249 105
        return $binding instanceof $this->acceptedBindingClass
250 8
            || $binding === $this->acceptedBindingClass
251 105
            || is_subclass_of($binding, $this->acceptedBindingClass);
252
    }
253
254
    /**
255
     * Returns the binding class names that can be bound to this type.
256
     *
257
     * Returns an empty array if any binding can be bound to the type.
258
     *
259
     * @return string[] An array of class names or an empty array.
0 ignored issues
show
Documentation introduced by
Should the return type not be string?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
260
     */
261 1
    public function getAcceptedBindingClass()
262
    {
263 1
        return $this->acceptedBindingClass;
264
    }
265
}
266