Definition   F
last analyzed

Complexity

Total Complexity 71

Size/Duplication

Total Lines 784
Duplicated Lines 4.59 %

Coupling/Cohesion

Components 10
Dependencies 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 71
c 1
b 0
f 0
lcom 10
cbo 2
dl 36
loc 784
rs 1.8461

49 Methods

Rating   Name   Duplication   Size   Complexity  
A getFactory() 0 4 1
A setDecoratedService() 0 14 4
A getDecoratedService() 0 4 1
A getClass() 0 4 1
A getProperties() 0 4 1
A getArguments() 0 4 1
A getMethodCalls() 0 4 1
A getTags() 0 4 1
A getTag() 0 4 2
A hasTag() 0 4 1
A getFile() 0 4 1
A getScope() 0 4 1
A isPublic() 0 4 1
A isLazy() 0 4 1
A isSynthetic() 0 4 1
A isAbstract() 0 4 1
A getConfigurator() 0 4 1
A __construct() 0 5 1
A setFactory() 0 10 3
A setFactoryClass() 0 8 1
A getFactoryClass() 0 8 2
A setFactoryMethod() 0 8 1
A getFactoryMethod() 0 8 2
A setFactoryService() 0 8 1
A getFactoryService() 0 8 2
A setClass() 0 6 1
A setArguments() 0 6 1
A setProperties() 0 6 1
A setProperty() 0 6 1
A addArgument() 0 6 1
A replaceArgument() 10 10 3
A getArgument() 8 8 3
A setMethodCalls() 0 9 2
A addMethodCall() 0 9 2
A removeMethodCall() 0 11 3
A hasMethodCall() 0 10 3
A setTags() 0 6 1
A addTag() 0 6 1
A clearTag() 0 8 2
A clearTags() 0 6 1
A setFile() 0 6 1
A setScope() 0 6 1
A setPublic() 0 6 1
A setSynchronized() 10 10 2
A isSynchronized() 8 8 2
A setLazy() 0 6 1
A setSynthetic() 0 6 1
A setAbstract() 0 6 1
A setConfigurator() 0 6 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Definition often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Definition, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/*
4
 * This file is part of the Symfony package.
5
 *
6
 * (c) Fabien Potencier <[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 Symfony\Component\DependencyInjection;
13
14
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
15
use Symfony\Component\DependencyInjection\Exception\OutOfBoundsException;
16
17
/**
18
 * Definition represents a service definition.
19
 *
20
 * @author Fabien Potencier <[email protected]>
21
 *
22
 * @api
23
 */
24
class Definition
25
{
26
    private $class;
27
    private $file;
28
    private $factory;
29
    private $factoryClass;
30
    private $factoryMethod;
31
    private $factoryService;
32
    private $scope = ContainerInterface::SCOPE_CONTAINER;
33
    private $properties = array();
34
    private $calls = array();
35
    private $configurator;
36
    private $tags = array();
37
    private $public = true;
38
    private $synthetic = false;
39
    private $abstract = false;
40
    private $synchronized = false;
41
    private $lazy = false;
42
    private $decoratedService;
43
44
    protected $arguments;
45
46
    /**
47
     * Constructor.
48
     *
49
     * @param string|null $class     The service class
50
     * @param array       $arguments An array of arguments to pass to the service constructor
51
     *
52
     * @api
53
     */
54
    public function __construct($class = null, array $arguments = array())
55
    {
56
        $this->class = $class;
57
        $this->arguments = $arguments;
58
    }
59
60
    /**
61
     * Sets a factory.
62
     *
63
     * @param string|array $factory A PHP function or an array containing a class/Reference and a method to call
64
     *
65
     * @return Definition The current instance
66
     */
67
    public function setFactory($factory)
68
    {
69
        if (is_string($factory) && strpos($factory, '::') !== false) {
70
            $factory = explode('::', $factory, 2);
71
        }
72
73
        $this->factory = $factory;
74
75
        return $this;
76
    }
77
78
    /**
79
     * Gets the factory.
80
     *
81
     * @return string|array The PHP function or an array containing a class/Reference and a method to call
82
     */
83
    public function getFactory()
84
    {
85
        return $this->factory;
86
    }
87
88
    /**
89
     * Sets the name of the class that acts as a factory using the factory method,
90
     * which will be invoked statically.
91
     *
92
     * @param string $factoryClass The factory class name
93
     *
94
     * @return Definition The current instance
95
     *
96
     * @api
97
     * @deprecated since version 2.6, to be removed in 3.0.
98
     */
99
    public function setFactoryClass($factoryClass)
100
    {
101
        trigger_error(sprintf('%s(%s) is deprecated since version 2.6 and will be removed in 3.0. Use Definition::setFactory() instead.', __METHOD__, $factoryClass), E_USER_DEPRECATED);
102
103
        $this->factoryClass = $factoryClass;
104
105
        return $this;
106
    }
107
108
    /**
109
     * Gets the factory class.
110
     *
111
     * @return string|null The factory class name
112
     *
113
     * @api
114
     * @deprecated since version 2.6, to be removed in 3.0.
115
     */
116
    public function getFactoryClass($triggerDeprecationError = true)
117
    {
118
        if ($triggerDeprecationError) {
119
            trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0.', E_USER_DEPRECATED);
120
        }
121
122
        return $this->factoryClass;
123
    }
124
125
    /**
126
     * Sets the factory method able to create an instance of this class.
127
     *
128
     * @param string $factoryMethod The factory method name
129
     *
130
     * @return Definition The current instance
131
     *
132
     * @api
133
     * @deprecated since version 2.6, to be removed in 3.0.
134
     */
135
    public function setFactoryMethod($factoryMethod)
136
    {
137
        trigger_error(sprintf('%s(%s) is deprecated since version 2.6 and will be removed in 3.0. Use Definition::setFactory() instead.', __METHOD__, $factoryMethod), E_USER_DEPRECATED);
138
139
        $this->factoryMethod = $factoryMethod;
140
141
        return $this;
142
    }
143
144
    /**
145
     * Sets the service that this service is decorating.
146
     *
147
     * @param null|string $id        The decorated service id, use null to remove decoration
148
     * @param null|string $renamedId The new decorated service id
149
     *
150
     * @return Definition The current instance
151
     *
152
     * @throws InvalidArgumentException In case the decorated service id and the new decorated service id are equals.
153
     */
154
    public function setDecoratedService($id, $renamedId = null)
155
    {
156
        if ($renamedId && $id == $renamedId) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $renamedId of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
157
            throw new \InvalidArgumentException(sprintf('The decorated service inner name for "%s" must be different than the service name itself.', $id));
158
        }
159
160
        if (null === $id) {
161
            $this->decoratedService = null;
162
        } else {
163
            $this->decoratedService = array($id, $renamedId);
164
        }
165
166
        return $this;
167
    }
168
169
    /**
170
     * Gets the service that decorates this service.
171
     *
172
     * @return null|array An array composed of the decorated service id and the new id for it, null if no service is decorated
173
     */
174
    public function getDecoratedService()
175
    {
176
        return $this->decoratedService;
177
    }
178
179
    /**
180
     * Gets the factory method.
181
     *
182
     * @return string|null The factory method name
183
     *
184
     * @api
185
     * @deprecated since version 2.6, to be removed in 3.0.
186
     */
187
    public function getFactoryMethod($triggerDeprecationError = true)
188
    {
189
        if ($triggerDeprecationError) {
190
            trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0.', E_USER_DEPRECATED);
191
        }
192
193
        return $this->factoryMethod;
194
    }
195
196
    /**
197
     * Sets the name of the service that acts as a factory using the factory method.
198
     *
199
     * @param string $factoryService The factory service id
200
     *
201
     * @return Definition The current instance
202
     *
203
     * @api
204
     * @deprecated since version 2.6, to be removed in 3.0.
205
     */
206
    public function setFactoryService($factoryService)
207
    {
208
        trigger_error(sprintf('%s(%s) is deprecated since version 2.6 and will be removed in 3.0. Use Definition::setFactory() instead.', __METHOD__, $factoryService), E_USER_DEPRECATED);
209
210
        $this->factoryService = $factoryService;
211
212
        return $this;
213
    }
214
215
    /**
216
     * Gets the factory service id.
217
     *
218
     * @return string|null The factory service id
219
     *
220
     * @api
221
     * @deprecated since version 2.6, to be removed in 3.0.
222
     */
223
    public function getFactoryService($triggerDeprecationError = true)
224
    {
225
        if ($triggerDeprecationError) {
226
            trigger_error('The '.__METHOD__.' method is deprecated since version 2.6 and will be removed in 3.0.', E_USER_DEPRECATED);
227
        }
228
229
        return $this->factoryService;
230
    }
231
232
    /**
233
     * Sets the service class.
234
     *
235
     * @param string $class The service class
236
     *
237
     * @return Definition The current instance
238
     *
239
     * @api
240
     */
241
    public function setClass($class)
242
    {
243
        $this->class = $class;
244
245
        return $this;
246
    }
247
248
    /**
249
     * Gets the service class.
250
     *
251
     * @return string|null The service class
252
     *
253
     * @api
254
     */
255
    public function getClass()
256
    {
257
        return $this->class;
258
    }
259
260
    /**
261
     * Sets the arguments to pass to the service constructor/factory method.
262
     *
263
     * @param array $arguments An array of arguments
264
     *
265
     * @return Definition The current instance
266
     *
267
     * @api
268
     */
269
    public function setArguments(array $arguments)
270
    {
271
        $this->arguments = $arguments;
272
273
        return $this;
274
    }
275
276
    /**
277
     * @api
278
     */
279
    public function setProperties(array $properties)
280
    {
281
        $this->properties = $properties;
282
283
        return $this;
284
    }
285
286
    /**
287
     * @api
288
     */
289
    public function getProperties()
290
    {
291
        return $this->properties;
292
    }
293
294
    /**
295
     * @api
296
     */
297
    public function setProperty($name, $value)
298
    {
299
        $this->properties[$name] = $value;
300
301
        return $this;
302
    }
303
304
    /**
305
     * Adds an argument to pass to the service constructor/factory method.
306
     *
307
     * @param mixed $argument An argument
308
     *
309
     * @return Definition The current instance
310
     *
311
     * @api
312
     */
313
    public function addArgument($argument)
314
    {
315
        $this->arguments[] = $argument;
316
317
        return $this;
318
    }
319
320
    /**
321
     * Sets a specific argument.
322
     *
323
     * @param int   $index
324
     * @param mixed $argument
325
     *
326
     * @return Definition The current instance
327
     *
328
     * @throws OutOfBoundsException When the replaced argument does not exist
329
     *
330
     * @api
331
     */
332 View Code Duplication
    public function replaceArgument($index, $argument)
333
    {
334
        if ($index < 0 || $index > count($this->arguments) - 1) {
335
            throw new OutOfBoundsException(sprintf('The index "%d" is not in the range [0, %d].', $index, count($this->arguments) - 1));
336
        }
337
338
        $this->arguments[$index] = $argument;
339
340
        return $this;
341
    }
342
343
    /**
344
     * Gets the arguments to pass to the service constructor/factory method.
345
     *
346
     * @return array The array of arguments
347
     *
348
     * @api
349
     */
350
    public function getArguments()
351
    {
352
        return $this->arguments;
353
    }
354
355
    /**
356
     * Gets an argument to pass to the service constructor/factory method.
357
     *
358
     * @param int $index
359
     *
360
     * @return mixed The argument value
361
     *
362
     * @throws OutOfBoundsException When the argument does not exist
363
     *
364
     * @api
365
     */
366 View Code Duplication
    public function getArgument($index)
367
    {
368
        if ($index < 0 || $index > count($this->arguments) - 1) {
369
            throw new OutOfBoundsException(sprintf('The index "%d" is not in the range [0, %d].', $index, count($this->arguments) - 1));
370
        }
371
372
        return $this->arguments[$index];
373
    }
374
375
    /**
376
     * Sets the methods to call after service initialization.
377
     *
378
     * @param array $calls An array of method calls
379
     *
380
     * @return Definition The current instance
381
     *
382
     * @api
383
     */
384
    public function setMethodCalls(array $calls = array())
385
    {
386
        $this->calls = array();
387
        foreach ($calls as $call) {
388
            $this->addMethodCall($call[0], $call[1]);
389
        }
390
391
        return $this;
392
    }
393
394
    /**
395
     * Adds a method to call after service initialization.
396
     *
397
     * @param string $method    The method name to call
398
     * @param array  $arguments An array of arguments to pass to the method call
399
     *
400
     * @return Definition The current instance
401
     *
402
     * @throws InvalidArgumentException on empty $method param
403
     *
404
     * @api
405
     */
406
    public function addMethodCall($method, array $arguments = array())
407
    {
408
        if (empty($method)) {
409
            throw new InvalidArgumentException(sprintf('Method name cannot be empty.'));
410
        }
411
        $this->calls[] = array($method, $arguments);
412
413
        return $this;
414
    }
415
416
    /**
417
     * Removes a method to call after service initialization.
418
     *
419
     * @param string $method The method name to remove
420
     *
421
     * @return Definition The current instance
422
     *
423
     * @api
424
     */
425
    public function removeMethodCall($method)
426
    {
427
        foreach ($this->calls as $i => $call) {
428
            if ($call[0] === $method) {
429
                unset($this->calls[$i]);
430
                break;
431
            }
432
        }
433
434
        return $this;
435
    }
436
437
    /**
438
     * Check if the current definition has a given method to call after service initialization.
439
     *
440
     * @param string $method The method name to search for
441
     *
442
     * @return bool
443
     *
444
     * @api
445
     */
446
    public function hasMethodCall($method)
447
    {
448
        foreach ($this->calls as $call) {
449
            if ($call[0] === $method) {
450
                return true;
451
            }
452
        }
453
454
        return false;
455
    }
456
457
    /**
458
     * Gets the methods to call after service initialization.
459
     *
460
     * @return array An array of method calls
461
     *
462
     * @api
463
     */
464
    public function getMethodCalls()
465
    {
466
        return $this->calls;
467
    }
468
469
    /**
470
     * Sets tags for this definition.
471
     *
472
     * @param array $tags
473
     *
474
     * @return Definition the current instance
475
     *
476
     * @api
477
     */
478
    public function setTags(array $tags)
479
    {
480
        $this->tags = $tags;
481
482
        return $this;
483
    }
484
485
    /**
486
     * Returns all tags.
487
     *
488
     * @return array An array of tags
489
     *
490
     * @api
491
     */
492
    public function getTags()
493
    {
494
        return $this->tags;
495
    }
496
497
    /**
498
     * Gets a tag by name.
499
     *
500
     * @param string $name The tag name
501
     *
502
     * @return array An array of attributes
503
     *
504
     * @api
505
     */
506
    public function getTag($name)
507
    {
508
        return isset($this->tags[$name]) ? $this->tags[$name] : array();
509
    }
510
511
    /**
512
     * Adds a tag for this definition.
513
     *
514
     * @param string $name       The tag name
515
     * @param array  $attributes An array of attributes
516
     *
517
     * @return Definition The current instance
518
     *
519
     * @api
520
     */
521
    public function addTag($name, array $attributes = array())
522
    {
523
        $this->tags[$name][] = $attributes;
524
525
        return $this;
526
    }
527
528
    /**
529
     * Whether this definition has a tag with the given name.
530
     *
531
     * @param string $name
532
     *
533
     * @return bool
534
     *
535
     * @api
536
     */
537
    public function hasTag($name)
538
    {
539
        return isset($this->tags[$name]);
540
    }
541
542
    /**
543
     * Clears all tags for a given name.
544
     *
545
     * @param string $name The tag name
546
     *
547
     * @return Definition
548
     */
549
    public function clearTag($name)
550
    {
551
        if (isset($this->tags[$name])) {
552
            unset($this->tags[$name]);
553
        }
554
555
        return $this;
556
    }
557
558
    /**
559
     * Clears the tags for this definition.
560
     *
561
     * @return Definition The current instance
562
     *
563
     * @api
564
     */
565
    public function clearTags()
566
    {
567
        $this->tags = array();
568
569
        return $this;
570
    }
571
572
    /**
573
     * Sets a file to require before creating the service.
574
     *
575
     * @param string $file A full pathname to include
576
     *
577
     * @return Definition The current instance
578
     *
579
     * @api
580
     */
581
    public function setFile($file)
582
    {
583
        $this->file = $file;
584
585
        return $this;
586
    }
587
588
    /**
589
     * Gets the file to require before creating the service.
590
     *
591
     * @return string|null The full pathname to include
592
     *
593
     * @api
594
     */
595
    public function getFile()
596
    {
597
        return $this->file;
598
    }
599
600
    /**
601
     * Sets the scope of the service.
602
     *
603
     * @param string $scope Whether the service must be shared or not
604
     *
605
     * @return Definition The current instance
606
     *
607
     * @api
608
     */
609
    public function setScope($scope)
610
    {
611
        $this->scope = $scope;
612
613
        return $this;
614
    }
615
616
    /**
617
     * Returns the scope of the service.
618
     *
619
     * @return string
620
     *
621
     * @api
622
     */
623
    public function getScope()
624
    {
625
        return $this->scope;
626
    }
627
628
    /**
629
     * Sets the visibility of this service.
630
     *
631
     * @param bool $boolean
632
     *
633
     * @return Definition The current instance
634
     *
635
     * @api
636
     */
637
    public function setPublic($boolean)
638
    {
639
        $this->public = (bool) $boolean;
640
641
        return $this;
642
    }
643
644
    /**
645
     * Whether this service is public facing.
646
     *
647
     * @return bool
648
     *
649
     * @api
650
     */
651
    public function isPublic()
652
    {
653
        return $this->public;
654
    }
655
656
    /**
657
     * Sets the synchronized flag of this service.
658
     *
659
     * @param bool $boolean
660
     *
661
     * @return Definition The current instance
662
     *
663
     * @api
664
     *
665
     * @deprecated since version 2.7, will be removed in 3.0.
666
     */
667 View Code Duplication
    public function setSynchronized($boolean, $triggerDeprecationError = true)
668
    {
669
        if ($triggerDeprecationError) {
670
            trigger_error('The '.__METHOD__.' method is deprecated since version 2.7 and will be removed in 3.0.', E_USER_DEPRECATED);
671
        }
672
673
        $this->synchronized = (bool) $boolean;
674
675
        return $this;
676
    }
677
678
    /**
679
     * Whether this service is synchronized.
680
     *
681
     * @return bool
682
     *
683
     * @api
684
     *
685
     * @deprecated since version 2.7, will be removed in 3.0.
686
     */
687 View Code Duplication
    public function isSynchronized($triggerDeprecationError = true)
688
    {
689
        if ($triggerDeprecationError) {
690
            trigger_error('The '.__METHOD__.' method is deprecated since version 2.7 and will be removed in 3.0.', E_USER_DEPRECATED);
691
        }
692
693
        return $this->synchronized;
694
    }
695
696
    /**
697
     * Sets the lazy flag of this service.
698
     *
699
     * @param bool $lazy
700
     *
701
     * @return Definition The current instance
702
     */
703
    public function setLazy($lazy)
704
    {
705
        $this->lazy = (bool) $lazy;
706
707
        return $this;
708
    }
709
710
    /**
711
     * Whether this service is lazy.
712
     *
713
     * @return bool
714
     */
715
    public function isLazy()
716
    {
717
        return $this->lazy;
718
    }
719
720
    /**
721
     * Sets whether this definition is synthetic, that is not constructed by the
722
     * container, but dynamically injected.
723
     *
724
     * @param bool $boolean
725
     *
726
     * @return Definition the current instance
727
     *
728
     * @api
729
     */
730
    public function setSynthetic($boolean)
731
    {
732
        $this->synthetic = (bool) $boolean;
733
734
        return $this;
735
    }
736
737
    /**
738
     * Whether this definition is synthetic, that is not constructed by the
739
     * container, but dynamically injected.
740
     *
741
     * @return bool
742
     *
743
     * @api
744
     */
745
    public function isSynthetic()
746
    {
747
        return $this->synthetic;
748
    }
749
750
    /**
751
     * Whether this definition is abstract, that means it merely serves as a
752
     * template for other definitions.
753
     *
754
     * @param bool $boolean
755
     *
756
     * @return Definition the current instance
757
     *
758
     * @api
759
     */
760
    public function setAbstract($boolean)
761
    {
762
        $this->abstract = (bool) $boolean;
763
764
        return $this;
765
    }
766
767
    /**
768
     * Whether this definition is abstract, that means it merely serves as a
769
     * template for other definitions.
770
     *
771
     * @return bool
772
     *
773
     * @api
774
     */
775
    public function isAbstract()
776
    {
777
        return $this->abstract;
778
    }
779
780
    /**
781
     * Sets a configurator to call after the service is fully initialized.
782
     *
783
     * @param callable $callable A PHP callable
784
     *
785
     * @return Definition The current instance
786
     *
787
     * @api
788
     */
789
    public function setConfigurator($callable)
790
    {
791
        $this->configurator = $callable;
792
793
        return $this;
794
    }
795
796
    /**
797
     * Gets the configurator to call after the service is fully initialized.
798
     *
799
     * @return callable|null The PHP callable to call
800
     *
801
     * @api
802
     */
803
    public function getConfigurator()
804
    {
805
        return $this->configurator;
806
    }
807
}
808