Completed
Push — master ( cb6b70...4e63d8 )
by Nikola
04:46
created

AbstractBuilder::offsetUnset()   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 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
crap 1
1
<?php
2
/*
3
 * This file is part of the Abstract builder package, an RunOpenCode project.
4
 *
5
 * (c) 2017 RunOpenCode
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
namespace RunOpenCode\AbstractBuilder;
11
12
use RunOpenCode\AbstractBuilder\Exception\BadMethodCallException;
13
use RunOpenCode\AbstractBuilder\Exception\InvalidArgumentException;
14
use RunOpenCode\AbstractBuilder\Exception\RuntimeException;
15
16
/**
17
 * Class AbstractBuilder
18
 *
19
 * Prototype implementation of class builder pattern.
20
 *
21
 * @package RunOpenCode\AbstractBuilder
22
 */
23
abstract class AbstractBuilder implements \ArrayAccess
24
{
25
    /**
26
     * A placeholder for constructor arguments.
27
     *
28
     * @var array
29
     */
30
    protected $_builder_placeholder_data_87cd3fb3_4fde_49d1_a91f_6411e0862c32;
31
32
    /**
33
     * AbstractBuilder constructor.
34
     *
35
     * @throws \RunOpenCode\AbstractBuilder\Exception\RuntimeException
36
     */
37 14
    public function __construct()
38
    {
39 14
        $this->_builder_placeholder_data_87cd3fb3_4fde_49d1_a91f_6411e0862c32 = $this->configureParameters();
40
41 14
        if (0 === count($this->_builder_placeholder_data_87cd3fb3_4fde_49d1_a91f_6411e0862c32)) {
42 1
            throw new RuntimeException('Builder expects at least one parameter to be defined.');
43
        }
44 13
    }
45
46
    /**
47
     * Builds new building class from provided arguments.
48
     *
49
     * @return object
50
     */
51 5
    public function build()
52
    {
53 5
        $reflector = new \ReflectionClass($this->getObjectFqcn());
54 5
        return $reflector->newInstanceArgs(array_values($this->_builder_placeholder_data_87cd3fb3_4fde_49d1_a91f_6411e0862c32));
55
    }
56
57
    /**
58
     * Set building class constructor arguments from array.
59
     *
60
     * @param array $values Values for constructor arguments of building class.
61
     * @return AbstractBuilder $this Fluent interface
62
     */
63 3
    public function fromArray(array $values)
64
    {
65 3
        foreach ($values as $key => $value) {
66 3
            $this->{$key} = $value;
67
        }
68
69 3
        return $this;
70
    }
71
72
    /**
73
     * Get all building class constructor arguments as array.
74
     *
75
     * @return array
76
     */
77 1
    public function toArray(array $keys = array())
78
    {
79 1
        if (0 === count($keys)) {
80
            return $this->_builder_placeholder_data_87cd3fb3_4fde_49d1_a91f_6411e0862c32;
81
        }
82
83 1
        return array_intersect_key($this->_builder_placeholder_data_87cd3fb3_4fde_49d1_a91f_6411e0862c32, array_flip($keys));
84
    }
85
86
    /**
87
     * Set building class constructor argument.
88
     *
89
     * @param string $name Argument name.
90
     * @param mixed $value Argument value.
91
     *
92
     * @throws \RunOpenCode\AbstractBuilder\Exception\InvalidArgumentException
93
     */
94 5 View Code Duplication
    public function __set($name, $value)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
95
    {
96 5
        if (!array_key_exists($name, $this->_builder_placeholder_data_87cd3fb3_4fde_49d1_a91f_6411e0862c32)) {
97 1
            throw new InvalidArgumentException(sprintf('Unknown property "%s" in "%s".', $name, get_class($this)));
98
        }
99
100 4
        $this->_builder_placeholder_data_87cd3fb3_4fde_49d1_a91f_6411e0862c32[$name] = $value;
101 4
    }
102
103
    /**
104
     * Get building class constructor argument.
105
     *
106
     * @param string $name Argument name.
107
     * @return mixed Argument value.
108
     *
109
     * @throws \RunOpenCode\AbstractBuilder\Exception\InvalidArgumentException
110
     */
111 1 View Code Duplication
    public function __get($name)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
112
    {
113 1
        if (!array_key_exists($name, $this->_builder_placeholder_data_87cd3fb3_4fde_49d1_a91f_6411e0862c32)) {
114
            throw new InvalidArgumentException(sprintf('Unknown property "%s" in "%s".', $name, get_class($this)));
115
        }
116
117 1
        return $this->_builder_placeholder_data_87cd3fb3_4fde_49d1_a91f_6411e0862c32[$name];
118
    }
119
120
    /**
121
     * Check if building class constructor argument is defined.
122
     *
123
     * @param string $name Argument name.
124
     * @return bool TRUE if argument is defined.
125
     */
126 1
    public function __isset($name)
127
    {
128 1
        return array_key_exists($name, $this->_builder_placeholder_data_87cd3fb3_4fde_49d1_a91f_6411e0862c32);
129
    }
130
131
    /**
132
     * Get/set building class constructor argument.
133
     *
134
     * @param string $name A method name.
135
     * @param array $arguments A method arguments.
136
     * @return $this|mixed Fluent interface or argument value, depending on method name.
137
     *
138
     * @throws \RunOpenCode\AbstractBuilder\Exception\BadMethodCallException
139
     */
140 5
    public function __call($name, array $arguments)
141
    {
142 5
        $property = lcfirst(substr($name, 3));
143
144
        if (
145 5
            !array_key_exists($property, $this->_builder_placeholder_data_87cd3fb3_4fde_49d1_a91f_6411e0862c32)
146
            ||
147 5
            (strpos($name, 'set') !== 0 && strpos($name, 'get') !== 0)
148
        ) {
149 1
            throw new BadMethodCallException(sprintf('Unknown method "%s" in "%s".', $name, get_class($this)));
150
        }
151
152 4 View Code Duplication
        if (count($arguments) !== 1 && strpos($name, 'set') === 0) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
153
            throw new BadMethodCallException(sprintf('Method "%s" in "%s" expects exactly one parameter.', $name, get_class($this)));
154
        }
155
156 4 View Code Duplication
        if (count($arguments) !== 0 && strpos($name, 'get') === 0) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
157
            throw new BadMethodCallException(sprintf('Method "%s" in "%s" does not use any parameter.', $name, get_class($this)));
158
        }
159
160 4
        if (strpos($name, 'get') === 0) {
161 1
            return $this->_builder_placeholder_data_87cd3fb3_4fde_49d1_a91f_6411e0862c32[$property];
162
        }
163
164 4
        $this->_builder_placeholder_data_87cd3fb3_4fde_49d1_a91f_6411e0862c32[$property] = $arguments[0];
165
166 4
        return $this;
167
    }
168
169
    /**
170
     * Function call to builder object instance will produce building class.
171
     *
172
     * @return object
173
     */
174 1
    public function __invoke()
175
    {
176 1
        return $this->build();
177
    }
178
179
    /**
180
     * {@inheritdoc}
181
     */
182 2
    public function offsetExists($offset)
183
    {
184 2
        return array_key_exists($offset, $this->_builder_placeholder_data_87cd3fb3_4fde_49d1_a91f_6411e0862c32);
185
    }
186
187
    /**
188
     * {@inheritdoc}
189
     */
190 1
    public function offsetGet($offset)
191
    {
192 1
        return $this->_builder_placeholder_data_87cd3fb3_4fde_49d1_a91f_6411e0862c32[$offset];
193
    }
194
195
    /**
196
     * {@inheritdoc}
197
     *
198
     * @throws \RunOpenCode\AbstractBuilder\Exception\BadMethodCallException
199
     */
200 2
    public function offsetSet($offset, $value)
201
    {
202 2
        if (!$this->offsetExists($offset)) {
203 1
            throw new RuntimeException(sprintf('Undefined property "%s" provided.', $offset));
204
        }
205
206 1
        $this->_builder_placeholder_data_87cd3fb3_4fde_49d1_a91f_6411e0862c32[$offset] = $value;
207 1
    }
208
209
    /**
210
     * Unused, throws an exception.
211
     *
212
     * @param mixed $offset
213
     *
214
     * @throws \RunOpenCode\AbstractBuilder\Exception\BadMethodCallException
215
     */
216 1
    public function offsetUnset($offset)
217
    {
218 1
        throw new BadMethodCallException('It is not allowed to unset builder property.');
219
    }
220
221
    /**
222
     * Produces new builder.
223
     *
224
     * @return static
225
     *
226
     * @throws \RunOpenCode\AbstractBuilder\Exception\RuntimeException
227
     */
228 13
    public static function createBuilder()
229
    {
230 13
        return new static();
231
    }
232
233
    /**
234
     * Configure builder parameters that will be passed to building class constructor.
235
     *
236
     * @return array
237
     */
238
    abstract protected function configureParameters();
239
240
    /**
241
     * Get full qualified class name of class which instance ought to be constructed.
242
     *
243
     * @return string
244
     */
245
    abstract protected function getObjectFqcn();
246
}
247