ClassDefinition   B
last analyzed

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