1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/* |
4
|
|
|
* This file is part of the puli/manager 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\Manager\Api\Php; |
13
|
|
|
|
14
|
|
|
use OutOfBoundsException; |
15
|
|
|
use RuntimeException; |
16
|
|
|
use Webmozart\Assert\Assert; |
17
|
|
|
use Webmozart\PathUtil\Path; |
18
|
|
|
|
19
|
|
|
/** |
20
|
|
|
* A model of a class. |
21
|
|
|
* |
22
|
|
|
* @since 1.0 |
23
|
|
|
* |
24
|
|
|
* @author Bernhard Schussek <[email protected]> |
25
|
|
|
*/ |
26
|
|
|
class Clazz |
27
|
|
|
{ |
28
|
|
|
/** |
29
|
|
|
* @var string |
30
|
|
|
*/ |
31
|
|
|
private $namespaceName; |
32
|
|
|
|
33
|
|
|
/** |
34
|
|
|
* @var string |
35
|
|
|
*/ |
36
|
|
|
private $shortClassName; |
37
|
|
|
|
38
|
|
|
/** |
39
|
|
|
* @var string |
40
|
|
|
*/ |
41
|
|
|
private $directory; |
42
|
|
|
|
43
|
|
|
/** |
44
|
|
|
* @var string |
45
|
|
|
*/ |
46
|
|
|
private $fileName; |
47
|
|
|
|
48
|
|
|
/** |
49
|
|
|
* @var string |
50
|
|
|
*/ |
51
|
|
|
private $parentClass; |
52
|
|
|
|
53
|
|
|
/** |
54
|
|
|
* @var bool[] |
55
|
|
|
*/ |
56
|
|
|
private $implementedInterfaces = array(); |
57
|
|
|
|
58
|
|
|
/** |
59
|
|
|
* @var Import[] |
60
|
|
|
*/ |
61
|
|
|
private $imports = array(); |
62
|
|
|
|
63
|
|
|
/** |
64
|
|
|
* @var string[] |
65
|
|
|
*/ |
66
|
|
|
private $importedSymbols = array(); |
67
|
|
|
|
68
|
|
|
/** |
69
|
|
|
* @var Method[] |
70
|
|
|
*/ |
71
|
|
|
private $methods = array(); |
72
|
|
|
|
73
|
|
|
/** |
74
|
|
|
* @var string |
75
|
|
|
*/ |
76
|
|
|
private $description; |
77
|
|
|
|
78
|
|
|
/** |
79
|
|
|
* Creates a new factory class. |
80
|
|
|
* |
81
|
|
|
* @param string $className The fully-qualified class name. |
82
|
|
|
*/ |
83
|
208 |
|
public function __construct($className) |
84
|
|
|
{ |
85
|
208 |
|
$this->setClassName($className); |
86
|
208 |
|
} |
87
|
|
|
|
88
|
|
|
/** |
89
|
|
|
* Sets the fully-qualified name of the factory class. |
90
|
|
|
* |
91
|
|
|
* @param string $className The fully-qualified class name. |
92
|
|
|
* |
93
|
|
|
* @return static The current instance. |
94
|
|
|
*/ |
95
|
208 |
|
public function setClassName($className) |
96
|
|
|
{ |
97
|
208 |
|
Assert::stringNotEmpty($className, 'The class name must be a non-empty string. Got: %s'); |
98
|
|
|
|
99
|
208 |
|
$pos = strrpos($className, '\\'); |
100
|
|
|
|
101
|
208 |
View Code Duplication |
if (false === $pos) { |
|
|
|
|
102
|
67 |
|
$this->namespaceName = ''; |
103
|
67 |
|
$this->shortClassName = $className; |
104
|
|
|
} else { |
105
|
144 |
|
$this->namespaceName = substr($className, 0, $pos); |
106
|
144 |
|
$this->shortClassName = substr($className, $pos + 1); |
107
|
|
|
} |
108
|
|
|
|
109
|
208 |
|
return $this; |
110
|
|
|
} |
111
|
|
|
|
112
|
|
|
/** |
113
|
|
|
* Returns the fully-qualified name of the factory class. |
114
|
|
|
* |
115
|
|
|
* @return string The fully-qualified class name. |
116
|
|
|
*/ |
117
|
9 |
|
public function getClassName() |
118
|
|
|
{ |
119
|
9 |
|
return $this->namespaceName |
120
|
5 |
|
? $this->namespaceName.'\\'.$this->shortClassName |
121
|
9 |
|
: $this->shortClassName; |
122
|
|
|
} |
123
|
|
|
|
124
|
|
|
/** |
125
|
|
|
* Returns the namespace of the factory class. |
126
|
|
|
* |
127
|
|
|
* @return string The namespace or an empty string if the class is in the |
128
|
|
|
* global namespace. |
129
|
|
|
*/ |
130
|
53 |
|
public function getNamespaceName() |
131
|
|
|
{ |
132
|
53 |
|
return $this->namespaceName; |
133
|
|
|
} |
134
|
|
|
|
135
|
|
|
/** |
136
|
|
|
* Returns the short class name. |
137
|
|
|
* |
138
|
|
|
* @return string The short name of the factory class. |
139
|
|
|
*/ |
140
|
53 |
|
public function getShortClassName() |
141
|
|
|
{ |
142
|
53 |
|
return $this->shortClassName; |
143
|
|
|
} |
144
|
|
|
|
145
|
|
|
/** |
146
|
|
|
* Returns the path to the directory holding the factory class file. |
147
|
|
|
* |
148
|
|
|
* @return string The absolute directory path. |
149
|
|
|
*/ |
150
|
91 |
|
public function getDirectory() |
151
|
|
|
{ |
152
|
91 |
|
return $this->directory; |
153
|
|
|
} |
154
|
|
|
|
155
|
|
|
/** |
156
|
|
|
* Sets the path to the directory holding the factory class file. |
157
|
|
|
* |
158
|
|
|
* @param string $directory The absolute directory path. |
159
|
|
|
* |
160
|
|
|
* @return static The current instance. |
161
|
|
|
*/ |
162
|
118 |
|
public function setDirectory($directory) |
163
|
|
|
{ |
164
|
118 |
|
Assert::stringNotEmpty($directory, 'The factory directory must be a non-empty string. Got: %s'); |
165
|
|
|
|
166
|
115 |
|
$this->directory = Path::canonicalize($directory); |
167
|
|
|
|
168
|
115 |
|
return $this; |
169
|
|
|
} |
170
|
|
|
|
171
|
|
|
/** |
172
|
|
|
* Returns the name of the factory class file. |
173
|
|
|
* |
174
|
|
|
* If no file name was set, the file is named after the short class name |
175
|
|
|
* suffixed with ".php". |
176
|
|
|
* |
177
|
|
|
* @return string The file name. |
178
|
|
|
*/ |
179
|
60 |
|
public function getFileName() |
180
|
|
|
{ |
181
|
60 |
|
if (!$this->fileName) { |
182
|
30 |
|
return $this->shortClassName.'.php'; |
183
|
|
|
} |
184
|
|
|
|
185
|
30 |
|
return $this->fileName; |
186
|
|
|
} |
187
|
|
|
|
188
|
|
|
/** |
189
|
|
|
* Sets the name of the factory class file. |
190
|
|
|
* |
191
|
|
|
* @param string $fileName The file name. |
192
|
|
|
* |
193
|
|
|
* @return static The current instance. |
194
|
|
|
*/ |
195
|
90 |
|
public function setFileName($fileName) |
196
|
|
|
{ |
197
|
90 |
|
Assert::stringNotEmpty($fileName, 'The factory file name must be a non-empty string. Got: %s'); |
198
|
|
|
|
199
|
87 |
|
$this->fileName = $fileName; |
200
|
|
|
|
201
|
87 |
|
return $this; |
202
|
|
|
} |
203
|
|
|
|
204
|
|
|
/** |
205
|
|
|
* Resets the name of the factory class file to the default value. |
206
|
|
|
* |
207
|
|
|
* By default, the file is named after the short class name suffixed with |
208
|
|
|
* ".php". |
209
|
|
|
* |
210
|
|
|
* @return static The current instance. |
211
|
|
|
*/ |
212
|
1 |
|
public function resetFileName() |
213
|
|
|
{ |
214
|
1 |
|
$this->fileName = null; |
215
|
|
|
|
216
|
1 |
|
return $this; |
217
|
|
|
} |
218
|
|
|
|
219
|
|
|
/** |
220
|
|
|
* Returns the absolute file path of the factory class file. |
221
|
|
|
* |
222
|
|
|
* @return string The absolute file path. |
223
|
|
|
*/ |
224
|
51 |
|
public function getFilePath() |
225
|
|
|
{ |
226
|
51 |
|
return $this->directory.'/'.$this->getFileName(); |
227
|
|
|
} |
228
|
|
|
|
229
|
|
|
/** |
230
|
|
|
* Sets the absolute file path of the factory class file. |
231
|
|
|
* |
232
|
|
|
* @param string $filePath The absolute file path. |
233
|
|
|
* |
234
|
|
|
* @return static The current instance. |
235
|
|
|
*/ |
236
|
86 |
|
public function setFilePath($filePath) |
237
|
|
|
{ |
238
|
86 |
|
Assert::stringNotEmpty($filePath, 'The factory file path must be a non-empty string. Got: %s'); |
239
|
|
|
|
240
|
83 |
|
$this->setDirectory(Path::getDirectory($filePath)); |
241
|
83 |
|
$this->setFileName(Path::getFilename($filePath)); |
242
|
|
|
|
243
|
83 |
|
return $this; |
244
|
|
|
} |
245
|
|
|
|
246
|
|
|
/** |
247
|
|
|
* Returns the parent class name. |
248
|
|
|
* |
249
|
|
|
* @return string|null The parent class name or `null` if the class has no |
250
|
|
|
* parent class. |
251
|
|
|
*/ |
252
|
4 |
|
public function getParentClass() |
253
|
|
|
{ |
254
|
4 |
|
return $this->parentClass; |
255
|
|
|
} |
256
|
|
|
|
257
|
|
|
/** |
258
|
|
|
* Sets the parent class name. |
259
|
|
|
* |
260
|
|
|
* If you don't pass a fully-qualified name, make sure to import the name |
261
|
|
|
* with {@link addImport()}. |
262
|
|
|
* |
263
|
|
|
* @param string $parentClass The parent class name. |
264
|
|
|
* |
265
|
|
|
* @return static The current instance. |
266
|
|
|
*/ |
267
|
8 |
|
public function setParentClass($parentClass) |
268
|
|
|
{ |
269
|
8 |
|
Assert::stringNotEmpty($parentClass, 'The parent class name must be a non-empty string. Got: %s'); |
270
|
|
|
|
271
|
5 |
|
$this->parentClass = $parentClass; |
272
|
|
|
|
273
|
5 |
|
return $this; |
274
|
|
|
} |
275
|
|
|
|
276
|
|
|
/** |
277
|
|
|
* Returns whether the class extends another class. |
278
|
|
|
* |
279
|
|
|
* @return bool Returns `true` if the class has a parent class and `false` |
280
|
|
|
* otherwise. |
281
|
|
|
*/ |
282
|
51 |
|
public function hasParentClass() |
283
|
|
|
{ |
284
|
51 |
|
return null !== $this->parentClass; |
285
|
|
|
} |
286
|
|
|
|
287
|
|
|
/** |
288
|
|
|
* Removes the parent class. |
289
|
|
|
* |
290
|
|
|
* @return static The current instance. |
291
|
|
|
*/ |
292
|
2 |
|
public function removeParentClass() |
293
|
|
|
{ |
294
|
2 |
|
$this->parentClass = null; |
295
|
|
|
|
296
|
2 |
|
return $this; |
297
|
|
|
} |
298
|
|
|
|
299
|
|
|
/** |
300
|
|
|
* Returns the interfaces that the class implements. |
301
|
|
|
* |
302
|
|
|
* @return string[] The names of the implemented interfaces. |
|
|
|
|
303
|
|
|
*/ |
304
|
8 |
|
public function getImplementedInterfaces() |
305
|
|
|
{ |
306
|
8 |
|
return array_keys($this->implementedInterfaces); |
307
|
|
|
} |
308
|
|
|
|
309
|
|
|
/** |
310
|
|
|
* Returns whether the class implements any interfaces. |
311
|
|
|
* |
312
|
|
|
* @return bool Returns `true` if the class implements any interfaces and |
313
|
|
|
* `false` otherwise. |
314
|
|
|
*/ |
315
|
51 |
|
public function hasImplementedInterfaces() |
316
|
|
|
{ |
317
|
51 |
|
return count($this->implementedInterfaces) > 0; |
318
|
|
|
} |
319
|
|
|
|
320
|
|
|
/** |
321
|
|
|
* Sets the interfaces that the class implements. |
322
|
|
|
* |
323
|
|
|
* Previously added interfaces are overwritten. |
324
|
|
|
* |
325
|
|
|
* If you don't pass fully-qualified names, make sure to import the names |
326
|
|
|
* with {@link addImport()}. |
327
|
|
|
* |
328
|
|
|
* @param string[] $interfaceNames The names of the implemented interfaces. |
329
|
|
|
* |
330
|
|
|
* @return static The current instance. |
331
|
|
|
*/ |
332
|
1 |
|
public function setImplementedInterfaces(array $interfaceNames) |
333
|
|
|
{ |
334
|
1 |
|
$this->implementedInterfaces = array(); |
335
|
|
|
|
336
|
1 |
|
$this->addImplementedInterfaces($interfaceNames); |
337
|
|
|
|
338
|
1 |
|
return $this; |
339
|
|
|
} |
340
|
|
|
|
341
|
|
|
/** |
342
|
|
|
* Adds implemented interfaces to the class definition. |
343
|
|
|
* |
344
|
|
|
* Previously added interfaces are kept. |
345
|
|
|
* |
346
|
|
|
* If you don't pass fully-qualified names, make sure to import the names |
347
|
|
|
* with {@link addImport()}. |
348
|
|
|
* |
349
|
|
|
* @param string[] $interfaceNames The names of the added interfaces. |
350
|
|
|
* |
351
|
|
|
* @return static The current instance. |
352
|
|
|
*/ |
353
|
2 |
|
public function addImplementedInterfaces(array $interfaceNames) |
354
|
|
|
{ |
355
|
2 |
|
foreach ($interfaceNames as $interfaceName) { |
356
|
2 |
|
$this->addImplementedInterface($interfaceName); |
357
|
|
|
} |
358
|
|
|
|
359
|
2 |
|
return $this; |
360
|
|
|
} |
361
|
|
|
|
362
|
|
|
/** |
363
|
|
|
* Adds an implemented interface to the class definition. |
364
|
|
|
* |
365
|
|
|
* If you don't pass a fully-qualified name, make sure to import the name |
366
|
|
|
* with {@link addImport()}. |
367
|
|
|
* |
368
|
|
|
* @param string $interfaceName The name of the added interfaces. |
369
|
|
|
* |
370
|
|
|
* @return static The current instance. |
371
|
|
|
*/ |
372
|
12 |
|
public function addImplementedInterface($interfaceName) |
373
|
|
|
{ |
374
|
12 |
|
Assert::stringNotEmpty($interfaceName, 'The interface name must be a non-empty string. Got: %s'); |
375
|
|
|
|
376
|
9 |
|
$this->implementedInterfaces[$interfaceName] = true; |
377
|
|
|
|
378
|
9 |
|
return $this; |
379
|
|
|
} |
380
|
|
|
|
381
|
|
|
/** |
382
|
|
|
* Removes an implemented interface from the class definition. |
383
|
|
|
* |
384
|
|
|
* @param string $interfaceName The name of the removed interfaces. |
385
|
|
|
* |
386
|
|
|
* @return static The current instance. |
387
|
|
|
*/ |
388
|
3 |
|
public function removeImplementedInterface($interfaceName) |
389
|
|
|
{ |
390
|
3 |
|
unset($this->implementedInterfaces[$interfaceName]); |
391
|
|
|
|
392
|
3 |
|
return $this; |
393
|
|
|
} |
394
|
|
|
|
395
|
|
|
/** |
396
|
|
|
* Removes all implemented interfaces from the class definition. |
397
|
|
|
* |
398
|
|
|
* @return static The current instance. |
399
|
|
|
*/ |
400
|
1 |
|
public function clearImplementedInterfaces() |
401
|
|
|
{ |
402
|
1 |
|
$this->implementedInterfaces = array(); |
403
|
|
|
|
404
|
1 |
|
return $this; |
405
|
|
|
} |
406
|
|
|
|
407
|
|
|
/** |
408
|
|
|
* Returns the import statements of the class file. |
409
|
|
|
* |
410
|
|
|
* @return Import[] The imported fully-qualified class names. |
411
|
|
|
*/ |
412
|
40 |
|
public function getImports() |
413
|
|
|
{ |
414
|
40 |
|
return $this->imports; |
415
|
|
|
} |
416
|
|
|
|
417
|
|
|
/** |
418
|
|
|
* Returns whether the class file imports any class name. |
419
|
|
|
* |
420
|
|
|
* @return bool Returns `true` if the class file imports class names and |
421
|
|
|
* `false` otherwise. |
422
|
|
|
*/ |
423
|
51 |
|
public function hasImports() |
424
|
|
|
{ |
425
|
51 |
|
return count($this->imports) > 0; |
426
|
|
|
} |
427
|
|
|
|
428
|
|
|
/** |
429
|
|
|
* Sets the import statements of the class file. |
430
|
|
|
* |
431
|
|
|
* Previously added imports are overwritten. |
432
|
|
|
* |
433
|
|
|
* @param Import[] $imports The imported fully-qualified class names. |
434
|
|
|
* |
435
|
|
|
* @return static The current instance. |
436
|
|
|
*/ |
437
|
1 |
|
public function setImports(array $imports) |
438
|
|
|
{ |
439
|
1 |
|
$this->imports = array(); |
440
|
|
|
|
441
|
1 |
|
$this->addImports($imports); |
442
|
|
|
|
443
|
1 |
|
return $this; |
444
|
|
|
} |
445
|
|
|
|
446
|
|
|
/** |
447
|
|
|
* Adds import statements to the class file. |
448
|
|
|
* |
449
|
|
|
* Previously added imports are kept. |
450
|
|
|
* |
451
|
|
|
* @param Import[] $imports The imported fully-qualified class names. |
452
|
|
|
* |
453
|
|
|
* @return static The current instance. |
454
|
|
|
*/ |
455
|
2 |
|
public function addImports(array $imports) |
456
|
|
|
{ |
457
|
2 |
|
foreach ($imports as $import) { |
458
|
2 |
|
$this->addImport($import); |
459
|
|
|
} |
460
|
|
|
|
461
|
2 |
|
return $this; |
462
|
|
|
} |
463
|
|
|
|
464
|
|
|
/** |
465
|
|
|
* Adds an import statement to the class file. |
466
|
|
|
* |
467
|
|
|
* @param Import $import The imported fully-qualified class name. |
468
|
|
|
* |
469
|
|
|
* @return static The current instance. |
470
|
|
|
*/ |
471
|
72 |
|
public function addImport(Import $import) |
472
|
|
|
{ |
473
|
72 |
|
if (isset($this->imports[$import->getClassName()])) { |
474
|
29 |
|
return $this; |
475
|
|
|
} |
476
|
|
|
|
477
|
72 |
|
$symbol = $import->getAlias() ?: $import->getShortClassName(); |
478
|
|
|
|
479
|
72 |
|
if (isset($this->importedSymbols[$symbol])) { |
480
|
3 |
|
throw new RuntimeException(sprintf( |
481
|
3 |
|
'The symbol "%s" was imported already.', |
482
|
3 |
|
$import->getShortClassName() |
483
|
|
|
)); |
484
|
|
|
} |
485
|
|
|
|
486
|
72 |
|
$this->imports[$import->getClassName()] = $import; |
487
|
72 |
|
$this->importedSymbols[$symbol] = true; |
488
|
|
|
|
489
|
72 |
|
ksort($this->imports); |
490
|
|
|
|
491
|
72 |
|
return $this; |
492
|
|
|
} |
493
|
|
|
|
494
|
|
|
/** |
495
|
|
|
* Removes an import statement from the class file. |
496
|
|
|
* |
497
|
|
|
* If the import statement is not found, this method does nothing. |
498
|
|
|
* |
499
|
|
|
* @param string $className The removed imported class name. |
500
|
|
|
* |
501
|
|
|
* @return static The current instance. |
502
|
|
|
*/ |
503
|
2 |
|
public function removeImport($className) |
504
|
|
|
{ |
505
|
2 |
|
if (isset($this->imports[$className])) { |
506
|
2 |
|
$import = $this->imports[$className]; |
507
|
2 |
|
$symbol = $import->getAlias() ?: $import->getShortClassName(); |
508
|
|
|
|
509
|
2 |
|
unset($this->imports[$className]); |
510
|
2 |
|
unset($this->importedSymbols[$symbol]); |
511
|
|
|
} |
512
|
|
|
|
513
|
2 |
|
return $this; |
514
|
|
|
} |
515
|
|
|
|
516
|
|
|
/** |
517
|
|
|
* Removes all import statements from the class file. |
518
|
|
|
* |
519
|
|
|
* @return static The current instance. |
520
|
|
|
*/ |
521
|
1 |
|
public function clearImports() |
522
|
|
|
{ |
523
|
1 |
|
$this->imports = array(); |
524
|
|
|
|
525
|
1 |
|
return $this; |
526
|
|
|
} |
527
|
|
|
|
528
|
|
|
/** |
529
|
|
|
* Returns the methods of the factory class. |
530
|
|
|
* |
531
|
|
|
* @return Method[] The methods indexed by their names. |
532
|
|
|
*/ |
533
|
56 |
|
public function getMethods() |
534
|
|
|
{ |
535
|
56 |
|
return $this->methods; |
536
|
|
|
} |
537
|
|
|
|
538
|
|
|
/** |
539
|
|
|
* Returns the method with the given name. |
540
|
|
|
* |
541
|
|
|
* @param string $name The name of the method. |
542
|
|
|
* |
543
|
|
|
* @return Method The method. |
544
|
|
|
* |
545
|
|
|
* @throws OutOfBoundsException If the method with the given name does not |
546
|
|
|
* exist. |
547
|
|
|
*/ |
548
|
2 |
|
public function getMethod($name) |
549
|
|
|
{ |
550
|
2 |
|
if (!isset($this->methods[$name])) { |
551
|
1 |
|
throw new OutOfBoundsException(sprintf( |
552
|
1 |
|
'The method "%s" does not exist.', |
553
|
|
|
$name |
554
|
|
|
)); |
555
|
|
|
} |
556
|
|
|
|
557
|
1 |
|
return $this->methods[$name]; |
558
|
|
|
} |
559
|
|
|
|
560
|
|
|
/** |
561
|
|
|
* Returns whether the class contains any methods. |
562
|
|
|
* |
563
|
|
|
* @return bool Returns `true` if the class contains methods and `false` |
564
|
|
|
* otherwise. |
565
|
|
|
*/ |
566
|
1 |
|
public function hasMethods() |
567
|
|
|
{ |
568
|
1 |
|
return count($this->methods) > 0; |
569
|
|
|
} |
570
|
|
|
|
571
|
|
|
/** |
572
|
|
|
* Returns whether the class contains a method with the given name. |
573
|
|
|
* |
574
|
|
|
* @param string $name The name of the method. |
575
|
|
|
* |
576
|
|
|
* @return bool Returns `true` if the method with the given name exists and |
577
|
|
|
* `false` otherwise. |
578
|
|
|
*/ |
579
|
2 |
|
public function hasMethod($name) |
580
|
|
|
{ |
581
|
2 |
|
return isset($this->methods[$name]); |
582
|
|
|
} |
583
|
|
|
|
584
|
|
|
/** |
585
|
|
|
* Sets the methods of the class. |
586
|
|
|
* |
587
|
|
|
* Previously added methods are overwritten. |
588
|
|
|
* |
589
|
|
|
* @param Method[] $methods The methods of the class. |
590
|
|
|
* |
591
|
|
|
* @return static The current instance. |
592
|
|
|
*/ |
593
|
1 |
|
public function setMethods(array $methods) |
594
|
|
|
{ |
595
|
1 |
|
$this->methods = array(); |
596
|
|
|
|
597
|
1 |
|
$this->addMethods($methods); |
598
|
|
|
|
599
|
1 |
|
return $this; |
600
|
|
|
} |
601
|
|
|
|
602
|
|
|
/** |
603
|
|
|
* Adds methods to the class. |
604
|
|
|
* |
605
|
|
|
* Previously added methods are kept. |
606
|
|
|
* |
607
|
|
|
* @param Method[] $methods The methods to add to the class. |
608
|
|
|
* |
609
|
|
|
* @return static The current instance. |
610
|
|
|
*/ |
611
|
2 |
|
public function addMethods(array $methods) |
612
|
|
|
{ |
613
|
2 |
|
foreach ($methods as $method) { |
614
|
2 |
|
$this->addMethod($method); |
615
|
|
|
} |
616
|
|
|
|
617
|
2 |
|
return $this; |
618
|
|
|
} |
619
|
|
|
|
620
|
|
|
/** |
621
|
|
|
* Adds a method to the class. |
622
|
|
|
* |
623
|
|
|
* @param Method $method The method to add to the class. |
624
|
|
|
* |
625
|
|
|
* @return static The current instance. |
626
|
|
|
*/ |
627
|
110 |
|
public function addMethod(Method $method) |
628
|
|
|
{ |
629
|
110 |
|
if (isset($this->methods[$method->getName()])) { |
630
|
1 |
|
throw new RuntimeException(sprintf( |
631
|
1 |
|
'The method "%s" exists already.', |
632
|
1 |
|
$method->getName() |
633
|
|
|
)); |
634
|
|
|
} |
635
|
|
|
|
636
|
110 |
|
$this->methods[$method->getName()] = $method; |
637
|
|
|
|
638
|
110 |
|
$method->setClass($this); |
639
|
|
|
|
640
|
110 |
|
return $this; |
641
|
|
|
} |
642
|
|
|
|
643
|
|
|
/** |
644
|
|
|
* Removes a method from the class. |
645
|
|
|
* |
646
|
|
|
* @param string $name The name of the removed method. |
647
|
|
|
* |
648
|
|
|
* @return static The current instance. |
649
|
|
|
*/ |
650
|
4 |
|
public function removeMethod($name) |
651
|
|
|
{ |
652
|
4 |
|
unset($this->methods[$name]); |
653
|
|
|
|
654
|
4 |
|
return $this; |
655
|
|
|
} |
656
|
|
|
|
657
|
|
|
/** |
658
|
|
|
* Removes all methods from the class. |
659
|
|
|
* |
660
|
|
|
* @return static The current instance. |
661
|
|
|
*/ |
662
|
1 |
|
public function clearMethods() |
663
|
|
|
{ |
664
|
1 |
|
$this->methods = array(); |
665
|
|
|
|
666
|
1 |
|
return $this; |
667
|
|
|
} |
668
|
|
|
|
669
|
|
|
/** |
670
|
|
|
* Returns the description of the class. |
671
|
|
|
* |
672
|
|
|
* @return string The class description. |
673
|
|
|
*/ |
674
|
51 |
|
public function getDescription() |
675
|
|
|
{ |
676
|
51 |
|
return $this->description; |
677
|
|
|
} |
678
|
|
|
|
679
|
|
|
/** |
680
|
|
|
* Sets the description of the class. |
681
|
|
|
* |
682
|
|
|
* @param string $description The class description. |
683
|
|
|
* |
684
|
|
|
* @return static The current instance. |
685
|
|
|
*/ |
686
|
33 |
|
public function setDescription($description) |
687
|
|
|
{ |
688
|
33 |
|
Assert::stringNotEmpty($description, 'The class description must be a non-empty string. Got: %s'); |
689
|
|
|
|
690
|
30 |
|
$this->description = $description; |
691
|
|
|
|
692
|
30 |
|
return $this; |
693
|
|
|
} |
694
|
|
|
} |
695
|
|
|
|
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.