Completed
Push — master ( 3ac92f...176d93 )
by Bernhard
02:21
created

AbstractBinding::getUuid()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 1
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\Binding;
13
14
use InvalidArgumentException;
15
use Puli\Discovery\Api\Binding\Binding;
16
use Puli\Discovery\Api\Binding\Initializer\NotInitializedException;
17
use Puli\Discovery\Api\Type\BindingNotAcceptedException;
18
use Puli\Discovery\Api\Type\BindingType;
19
use Puli\Discovery\Api\Type\MissingParameterException;
20
use Puli\Discovery\Api\Type\NoSuchParameterException;
21
use Rhumsaa\Uuid\Uuid;
22
use Webmozart\Assert\Assert;
23
24
/**
25
 * Base class for bindings.
26
 *
27
 * @since  1.0
28
 *
29
 * @author Bernhard Schussek <[email protected]>
30
 */
31
abstract class AbstractBinding implements Binding
32
{
33
    /**
34
     * @var Uuid
35
     */
36
    private $uuid;
37
38
    /**
39
     * @var string
40
     */
41
    private $typeName;
42
43
    /**
44
     * @var BindingType|null
45
     */
46
    private $type;
47
48
    /**
49
     * @var array
50
     */
51
    private $userParameterValues = array();
52
53
    /**
54
     * @var array
55
     */
56
    private $parameterValues = array();
57
58
    /**
59
     * Creates a new binding.
60
     *
61
     * You can pass parameters that have been defined for the type. If you pass
62
     * unknown parameters, or if a required parameter is missing, an exception
63
     * is thrown.
64
     *
65
     * All parameters that you do not set here will receive the default values
66
     * set for the parameter.
67
     *
68
     * @param string    $typeName        The name of the type to bind against.
69
     * @param array     $parameterValues The values of the parameters defined
70
     *                                   for the type.
71
     * @param Uuid|null $uuid            The UUID of the binding. A new one is
72
     *                                   generated if none is passed.
73
     *
74
     * @throws NoSuchParameterException  If an invalid parameter was passed.
75
     * @throws MissingParameterException If a required parameter was not passed.
76
     */
77 159
    public function __construct($typeName, array $parameterValues = array(), Uuid $uuid = null)
78
    {
79 159
        Assert::stringNotEmpty($typeName, 'The type name must be a non-empty string. Got: %s');
80
81 157
        ksort($parameterValues);
82
83 157
        $this->typeName = $typeName;
84 157
        $this->userParameterValues = $parameterValues;
85 157
        $this->parameterValues = $parameterValues;
86 157
        $this->uuid = $uuid ?: Uuid::uuid4();
87 157
    }
88
89
    /**
90
     * {@inheritdoc}
91
     */
92 130
    public function initialize(BindingType $type)
93
    {
94 130
        if ($this->typeName !== $type->getName()) {
95 2
            throw new InvalidArgumentException(sprintf(
96 2
                'The passed type "%s" does not match the configured type "%s".',
97 2
                $type->getName(),
98 2
                $this->typeName
99
            ));
100
        }
101
102 128
        if (!$type->acceptsBinding(get_class($this))) {
103 7
            throw BindingNotAcceptedException::forBindingClass($type->getName(), get_class($this));
104
        }
105
106
        // Merge default parameter values of the type
107 121
        $this->assertParameterValuesValid($this->userParameterValues, $type);
108
109 117
        $this->type = $type;
110 117
        $this->parameterValues = array_replace($type->getParameterValues(), $this->userParameterValues);
111
112 117
        ksort($this->parameterValues);
113 117
    }
114
115
    /**
116
     * {@inheritdoc}
117
     */
118 2
    public function isInitialized()
119
    {
120 2
        return null !== $this->type;
121
    }
122
123
    /**
124
     * {@inheritdoc}
125
     */
126 119
    public function getUuid()
127
    {
128 119
        return $this->uuid;
129
    }
130
131
    /**
132
     * {@inheritdoc}
133
     */
134 122
    public function getTypeName()
135
    {
136 122
        return $this->typeName;
137
    }
138
139
    /**
140
     * {@inheritdoc}
141
     */
142 4
    public function getType()
143
    {
144 4
        if (null === $this->type) {
145 2
            throw new NotInitializedException('The binding must be initialized before accessing the type.');
146
        }
147
148 2
        return $this->type;
149
    }
150
151
    /**
152
     * {@inheritdoc}
153
     */
154 10
    public function getParameterValues($includeDefault = true)
155
    {
156 10
        if ($includeDefault) {
157 10
            return $this->parameterValues;
158
        }
159
160 6
        return $this->userParameterValues;
161
    }
162
163
    /**
164
     * {@inheritdoc}
165
     */
166
    public function hasParameterValues($includeDefault = true)
167
    {
168
        if ($includeDefault) {
169
            return count($this->parameterValues) > 0;
170
        }
171
172
        return count($this->userParameterValues) > 0;
173
    }
174
175
    /**
176
     * {@inheritdoc}
177
     */
178 32
    public function getParameterValue($parameterName, $includeDefault = true)
179
    {
180 32
        $parameterValues = $includeDefault ? $this->parameterValues : $this->userParameterValues;
181
182 32
        if (!array_key_exists($parameterName, $parameterValues)) {
183 2
            throw NoSuchParameterException::forParameterName($parameterName, $this->typeName);
184
        }
185
186 30
        return $parameterValues[$parameterName];
187
    }
188
189
    /**
190
     * {@inheritdoc}
191
     */
192 10
    public function hasParameterValue($parameterName, $includeDefault = true)
193
    {
194 10
        if ($includeDefault) {
195 10
            return array_key_exists($parameterName, $this->parameterValues);
196
        }
197
198 6
        return array_key_exists($parameterName, $this->userParameterValues);
199
    }
200
201
    /**
202
     * {@inheritdoc}
203
     */
204 93
    public function serialize()
205
    {
206 93
        $data = array();
207
208 93
        $this->preSerialize($data);
209
210 93
        return serialize($data);
211
    }
212
213
    /**
214
     * {@inheritdoc}
215
     */
216 40
    public function unserialize($serialized)
217
    {
218 40
        $data = unserialize($serialized);
219
220 40
        $this->postUnserialize($data);
221 40
    }
222
223 93
    protected function preSerialize(array &$data)
224
    {
225 93
        $data[] = $this->typeName;
226 93
        $data[] = $this->userParameterValues;
227 93
        $data[] = $this->uuid->toString();
228 93
    }
229
230 40
    protected function postUnserialize(array &$data)
231
    {
232 40
        $this->uuid = Uuid::fromString(array_pop($data));
233 40
        $this->userParameterValues = array_pop($data);
234 40
        $this->parameterValues = $this->userParameterValues;
235 40
        $this->typeName = array_pop($data);
236 40
    }
237
238 121
    private function assertParameterValuesValid(array $parameterValues, BindingType $type)
239
    {
240 121
        foreach ($parameterValues as $name => $value) {
241 32
            if (!$type->hasParameter($name)) {
242 32
                throw NoSuchParameterException::forParameterName($name, $type->getName());
243
            }
244
        }
245
246 119
        foreach ($type->getParameters() as $parameter) {
247 32
            if (!isset($parameterValues[$parameter->getName()])) {
248 27
                if ($parameter->isRequired()) {
249 32
                    throw MissingParameterException::forParameterName($parameter->getName(), $type->getName());
250
                }
251
            }
252
        }
253 117
    }
254
}
255