Completed
Push — master ( 00ced4...d3edd8 )
by
unknown
07:54
created

ClassDefinition   B

Complexity

Total Complexity 39

Size/Duplication

Total Lines 355
Duplicated Lines 0 %

Coupling/Cohesion

Components 5
Dependencies 11

Test Coverage

Coverage 94.62%

Importance

Changes 0
Metric Value
wmc 39
lcom 5
cbo 11
dl 0
loc 355
ccs 88
cts 93
cp 0.9462
rs 8.2857
c 0
b 0
f 0

28 Methods

Rating   Name   Duplication   Size   Complexity  
A defineConstructor() 0 5 1
A defineMethod() 0 13 2
A defineProperty() 0 13 2
A defineIsPrototype() 0 6 1
A defineIsSingleton() 0 6 1
A getNameSpace() 0 4 1
A setNameSpace() 0 6 1
A addScope() 0 10 2
A removeScope() 0 10 2
A hasScope() 0 4 1
A getScope() 0 7 2
A getScopes() 0 4 1
A getClassName() 0 4 1
A setClassName() 0 12 3
A getServiceName() 0 4 1
A setServiceName() 0 6 1
A isSingleton() 0 4 1
A setIsSingleton() 0 6 1
A getPropertiesCollection() 0 4 1
A getMethodsCollection() 0 4 1
A setupMethod() 0 9 2
A setupProperty() 0 9 2
A hasProperty() 0 4 1
A getProperty() 0 7 2
A hasMethod() 0 4 1
A getMethod() 0 7 2
A isAnalyzed() 0 4 1
A setIsAnalyzed() 0 6 1
1
<?php declare(strict_types = 1);
2
/**
3
 * Created by PhpStorm.
4
 * User: root
5
 * Date: 02.08.16
6
 * Time: 0:46.
7
 */
8
namespace samsonframework\container\definition;
9
10
use samsonframework\container\definition\exception\MethodDefinitionNotFoundException;
11
use samsonframework\container\definition\exception\PropertyDefinitionNotFoundException;
12
use samsonframework\container\definition\reference\ClassReference;
13
use samsonframework\container\definition\reference\ReferenceInterface;
14
use samsonframework\container\definition\scope\AbstractScope;
15
use samsonframework\container\definition\exception\MethodDefinitionAlreadyExistsException;
16
use samsonframework\container\definition\exception\PropertyDefinitionAlreadyExistsException;
17
use samsonframework\container\definition\exception\ScopeAlreadyExistsException;
18
use samsonframework\container\definition\exception\ScopeNotFoundException;
19
20
/**
21
 * Class ClassDefinition
22
 *
23
 * @author Ruslan Molodyko <[email protected]>
24
 */
25
class ClassDefinition extends AbstractDefinition implements ClassBuilderInterface
26
{
27
    /** @var string Class name with namespace */
28
    protected $className;
29
    /** @var string Class name space */
30
    protected $nameSpace;
31
    /** @var string Service name */
32
    protected $serviceName;
33
    /** @var array Class container scopes */
34
    protected $scopes = [];
35
    /** @var bool Is singleton */
36
    protected $isSingleton = false;
37
    /** @var bool Is class definition was analyzed */
38
    protected $isAnalyzed = false;
39
40
    /** @var MethodDefinition[] Methods collection */
41
    protected $methodsCollection = [];
42
    /** @var PropertyDefinition[] Property collection */
43
    protected $propertiesCollection = [];
44
45
    /** {@inheritdoc} */
46 9
    public function defineConstructor(): MethodBuilderInterface
47
    {
48
        /** Add constructor method manually */
49 9
        return $this->defineMethod('__construct');
50
    }
51
52
    /** {@inheritdoc} */
53 13
    public function defineMethod(string $methodName): MethodBuilderInterface
54
    {
55 13
        if (array_key_exists($methodName, $this->methodsCollection)) {
56 2
            throw new MethodDefinitionAlreadyExistsException();
57
        }
58
59 13
        $methodDefinition = new MethodDefinition($this, $methodName);
0 ignored issues
show
Unused Code introduced by
The call to MethodDefinition::__construct() has too many arguments starting with $methodName.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
60 13
        $methodDefinition->setMethodName($methodName);
61
62 13
        $this->methodsCollection[$methodName] = $methodDefinition;
63
64 13
        return $methodDefinition;
65
    }
66
67
    /** {@inheritdoc} */
68 9
    public function defineProperty(string $propertyName): PropertyBuilderInterface
69
    {
70 9
        if (array_key_exists($propertyName, $this->propertiesCollection)) {
71 1
            throw new PropertyDefinitionAlreadyExistsException();
72
        }
73
74 9
        $propertyDefinition = new PropertyDefinition($this);
75 9
        $propertyDefinition->setPropertyName($propertyName);
76
77 9
        $this->propertiesCollection[$propertyName] = $propertyDefinition;
78
79 9
        return $propertyDefinition;
80
    }
81
82
    /** {@inheritdoc} */
83 2
    public function defineIsPrototype(): ClassBuilderInterface
84
    {
85 2
        $this->isSingleton = false;
86
87 2
        return $this;
88
    }
89
90
    /** {@inheritdoc} */
91 2
    public function defineIsSingleton(): ClassBuilderInterface
92
    {
93 2
        $this->isSingleton = true;
94
95 2
        return $this;
96
    }
97
98
    /**
99
     * Get namespace
100
     *
101
     * @return string
102
     */
103 2
    public function getNameSpace(): string
104
    {
105 2
        return $this->nameSpace;
106
    }
107
108
    /**
109
     * @param string $nameSpace
110
     * @return ClassDefinition
111
     */
112 6
    public function setNameSpace(string $nameSpace): ClassDefinition
113
    {
114 6
        $this->nameSpace = $nameSpace;
115
116 6
        return $this;
117
    }
118
119
    /**
120
     * Add scope to definition
121
     *
122
     * @param AbstractScope $scope
123
     * @return ClassDefinition
124
     * @throws ScopeAlreadyExistsException
125
     */
126 4
    public function addScope(AbstractScope $scope): ClassDefinition
127
    {
128 4
        if ($this->hasScope($scope::getId())) {
129 1
            throw new ScopeAlreadyExistsException();
130
        }
131
132 4
        $this->scopes[$scope::getId()] = $scope;
133
134 4
        return $this;
135
    }
136
137
    /**
138
     * Remove scope from definition
139
     *
140
     * @param string $id
141
     * @return ClassDefinition
142
     * @throws ScopeNotFoundException
143
     */
144 2
    public function removeScope(string $id): ClassDefinition
145
    {
146 2
        if (!$this->hasScope($id)) {
147 1
            throw new ScopeNotFoundException();
148
        }
149
150 1
        unset($this->scopes[$id]);
151
152 1
        return $this;
153
    }
154
155
    /**
156
     * Check if scope exists in definition
157
     *
158
     * @param string $id
159
     * @return bool
160
     */
161 4
    public function hasScope(string $id): bool
162
    {
163 4
        return array_key_exists($id, $this->scopes);
164
    }
165
166
    /**
167
     * Get scope from definition
168
     *
169
     * @param string $id
170
     * @return mixed
171
     * @throws ScopeNotFoundException
172
     */
173 2
    public function getScope(string $id): AbstractScope
174
    {
175 2
        if (!$this->hasScope($id)) {
176 1
            throw new ScopeNotFoundException();
177
        }
178 1
        return $this->scopes[$id];
179
    }
180
181
    /**
182
     * Get all scopes
183
     *
184
     * @return AbstractScope[]
185
     */
186 3
    public function getScopes(): array
187
    {
188 3
        return $this->scopes;
189
    }
190
191
    /**
192
     * Get class name
193
     *
194
     * @return string
195
     */
196 8
    public function getClassName(): string
197
    {
198 8
        return $this->className;
199
    }
200
201
    /**
202
     * @param string|ClassReference $className
203
     * @return ClassDefinition
204
     * @throws \InvalidArgumentException
205
     */
206 28
    public function setClassName($className): ClassDefinition
207
    {
208 28
        if ($className instanceof ClassReference) {
209 16
            $this->className = $className->getClassName();
210 12
        } elseif (is_string($className)) {
211 12
            $this->className = $className;
212
        } else {
213
            throw new \InvalidArgumentException();
214
        }
215
216 28
        return $this;
217
    }
218
219
    /**
220
     * @return string|null
221
     */
222 3
    public function getServiceName()
223
    {
224 3
        return $this->serviceName;
225
    }
226
227
    /**
228
     * @param string $serviceName
229
     * @return ClassDefinition
230
     */
231 2
    public function setServiceName(string $serviceName): ClassDefinition
232
    {
233 2
        $this->serviceName = $serviceName;
234
235 2
        return $this;
236
    }
237
238
    /**
239
     * @return boolean
240
     */
241 4
    public function isSingleton(): bool
242
    {
243 4
        return $this->isSingleton;
244
    }
245
246
    /**
247
     * @param boolean $isSingleton
248
     * @return ClassDefinition
249
     */
250 1
    public function setIsSingleton(bool $isSingleton): ClassDefinition
251
    {
252 1
        $this->isSingleton = $isSingleton;
253
254 1
        return $this;
255
    }
256
257
    /**
258
     * @return PropertyDefinition[]
259
     */
260 4
    public function getPropertiesCollection(): array
261
    {
262 4
        return $this->propertiesCollection;
263
    }
264
265
    /**
266
     * @return MethodDefinition[]
267
     */
268 4
    public function getMethodsCollection(): array
269
    {
270 4
        return $this->methodsCollection;
271
    }
272
273
    /**
274
     * Get existing or define new method
275
     *
276
     * @param string $methodName
277
     * @return MethodDefinition
278
     * @throws MethodDefinitionAlreadyExistsException
279
     * @throws MethodDefinitionNotFoundException
280
     */
281 2
    public function setupMethod(string $methodName): MethodDefinition
282
    {
283
        // Get existing method
284 2
        if ($this->hasMethod($methodName)) {
285 2
            return $this->getMethod($methodName);
286
        } else { // Or define new method
287
            return $this->defineMethod($methodName);
288
        }
289
    }
290
291
    /**
292
     * Get existing or define new property
293
     *
294
     * @param string $propertyName
295
     * @return PropertyDefinition
296
     * @throws PropertyDefinitionNotFoundException
297
     * @throws PropertyDefinitionAlreadyExistsException
298
     */
299 2
    public function setupProperty(string $propertyName): PropertyDefinition
300
    {
301
        // Get existing property
302 2
        if ($this->hasProperty($propertyName)) {
303 2
            return $this->getProperty($propertyName);
304
        } else { // Or define new property
305
            return $this->defineProperty($propertyName);
306
        }
307
    }
308
309
    /**
310
     * Has property definition
311
     *
312
     * @param string $propertyName
313
     * @return bool
314
     */
315 4
    public function hasProperty(string $propertyName): bool
316
    {
317 4
        return array_key_exists($propertyName, $this->propertiesCollection);
318
    }
319
320
    /**
321
     * Get property definition
322
     *
323
     * @param $propertyName
324
     * @return PropertyDefinition
325
     * @throws PropertyDefinitionNotFoundException
326
     */
327 3
    public function getProperty($propertyName): PropertyDefinition
328
    {
329 3
        if (!$this->hasProperty($propertyName)) {
330
            throw new PropertyDefinitionNotFoundException();
331
        }
332 3
        return $this->propertiesCollection[$propertyName];
333
    }
334
335
    /**
336
     * Has method definition
337
     *
338
     * @param string $methodName
339
     * @return bool
340
     */
341 4
    public function hasMethod(string $methodName): bool
342
    {
343 4
        return array_key_exists($methodName, $this->methodsCollection);
344
    }
345
346
    /**
347
     * Get method definition
348
     *
349
     * @param $methodName
350
     * @return MethodDefinition
351
     * @throws MethodDefinitionNotFoundException
352
     */
353 4
    public function getMethod($methodName): MethodDefinition
354
    {
355 4
        if (!$this->hasMethod($methodName)) {
356
            throw new MethodDefinitionNotFoundException();
357
        }
358 4
        return $this->methodsCollection[$methodName];
359
    }
360
361
    /**
362
     * @return boolean
363
     */
364 7
    public function isAnalyzed(): bool
365
    {
366 7
        return $this->isAnalyzed;
367
    }
368
369
    /**
370
     * @param boolean $isAnalyzed
371
     * @return ClassDefinition
372
     */
373 6
    public function setIsAnalyzed(bool $isAnalyzed): ClassDefinition
374
    {
375 6
        $this->isAnalyzed = $isAnalyzed;
376
377 6
        return $this;
378
    }
379
}
380