Configuration::getConfigTreeBuilder()   B
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 132

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 132
rs 8
c 0
b 0
f 0
cc 1
nc 1
nop 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Admingenerator\GeneratorBundle\DependencyInjection;
4
5
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
6
use Symfony\Component\Config\Definition\ConfigurationInterface;
7
8
/**
9
 * This class contains the configuration information for the bundle
10
 *
11
 * @author clombardot
12
 */
13
class Configuration implements ConfigurationInterface
14
{
15
    /**
16
     * @var string
17
     */
18
    protected $rootName;
19
20
    /**
21
     * @param string $rootName
22
     */
23
    public function __construct($rootName)
24
    {
25
        $this->rootName = $rootName;
26
    }
27
28
    private $defaultFormTypes = array(
29
        'doctrine_orm' => array(
30
            // datetime types
31
            'datetime'    => 'Symfony\Component\Form\Extension\Core\Type\DateTimeType',
32
            'vardatetime' => 'Symfony\Component\Form\Extension\Core\Type\DateTimeType',
33
            'datetimetz'  => 'Symfony\Component\Form\Extension\Core\Type\DateTimeType',
34
            'date'        => 'Symfony\Component\Form\Extension\Core\Type\DateType',
35
            // time types
36
            'time'        => 'Symfony\Component\Form\Extension\Core\Type\TimeType',
37
            // number types
38
            'decimal'     => 'Symfony\Component\Form\Extension\Core\Type\NumberType',
39
            'float'       => 'Symfony\Component\Form\Extension\Core\Type\NumberType',
40
            // integer types
41
            'integer'     => 'Symfony\Component\Form\Extension\Core\Type\IntegerType',
42
            'bigint'      => 'Symfony\Component\Form\Extension\Core\Type\IntegerType',
43
            'smallint'    => 'Symfony\Component\Form\Extension\Core\Type\IntegerType',
44
            // text types
45
            'string'      => 'Symfony\Component\Form\Extension\Core\Type\TextType',
46
            // textarea types
47
            'text'        => 'Symfony\Component\Form\Extension\Core\Type\TextareaType',
48
            // association types
49
            'entity'      => 'Symfony\Bridge\Doctrine\Form\Type\EntityType',
50
            'collection'  => 'Symfony\Component\Form\Extension\Core\Type\CollectionType',
51
            // array types
52
            'array'       => 'Symfony\Component\Form\Extension\Core\Type\CollectionType',
53
            // boolean types
54
            'boolean'     => 'Symfony\Component\Form\Extension\Core\Type\CheckboxType',
55
        ),
56
        'doctrine_odm' => array(
57
            // datetime types
58
            'datetime'    => 'Symfony\Component\Form\Extension\Core\Type\DateTimeType',
59
            'timestamp'   => 'Symfony\Component\Form\Extension\Core\Type\DateTimeType',
60
            'vardatetime' => 'Symfony\Component\Form\Extension\Core\Type\DateTimeType',
61
            'datetimetz'  => 'Symfony\Component\Form\Extension\Core\Type\DateTimeType',
62
            'date'        => 'Symfony\Component\Form\Extension\Core\Type\DateType',
63
            // time types
64
            'time'        => 'Symfony\Component\Form\Extension\Core\Type\TimeType',
65
            // number types
66
            'decimal'     => 'Symfony\Component\Form\Extension\Core\Type\NumberType',
67
            'float'       => 'Symfony\Component\Form\Extension\Core\Type\NumberType',
68
            // integer types
69
            'int'         => 'Symfony\Component\Form\Extension\Core\Type\IntegerType',
70
            'integer'     => 'Symfony\Component\Form\Extension\Core\Type\IntegerType',
71
            'int_id'      => 'Symfony\Component\Form\Extension\Core\Type\IntegerType',
72
            'bigint'      => 'Symfony\Component\Form\Extension\Core\Type\IntegerType',
73
            'smallint'    => 'Symfony\Component\Form\Extension\Core\Type\IntegerType',
74
            // text types
75
            'id'          => 'Symfony\Component\Form\Extension\Core\Type\TextType',
76
            'custom_id'   => 'Symfony\Component\Form\Extension\Core\Type\TextType',
77
            'string'      => 'Symfony\Component\Form\Extension\Core\Type\TextType',
78
            // textarea types
79
            'text'        => 'Symfony\Component\Form\Extension\Core\Type\TextareaType',
80
            // association types
81
            'document'    => 'Doctrine\Bundle\MongoDBBundle\Form\Type\DocumentType',
82
            'collection'  => 'Symfony\Component\Form\Extension\Core\Type\CollectionType',
83
            // hash types
84
            'hash'        => 'Symfony\Component\Form\Extension\Core\Type\CollectionType',
85
            // boolean types
86
            'boolean'     => 'Symfony\Component\Form\Extension\Core\Type\CheckboxType',
87
        ),
88
        'propel'       => array(
89
            // datetime types
90
            'TIMESTAMP'    => 'Symfony\Component\Form\Extension\Core\Type\DateTimeType',
91
            'BU_TIMESTAMP' => 'Symfony\Component\Form\Extension\Core\Type\DateTimeType',
92
            // date types
93
            'DATE'         => 'Symfony\Component\Form\Extension\Core\Type\DateType',
94
            'BU_DATE'      => 'Symfony\Component\Form\Extension\Core\Type\DateType',
95
            // time types
96
            'TIME'         => 'Symfony\Component\Form\Extension\Core\Type\TimeType',
97
            // number types
98
            'FLOAT'        => 'Symfony\Component\Form\Extension\Core\Type\NumberType',
99
            'REAL'         => 'Symfony\Component\Form\Extension\Core\Type\NumberType',
100
            'DOUBLE'       => 'Symfony\Component\Form\Extension\Core\Type\NumberType',
101
            'DECIMAL'      => 'Symfony\Component\Form\Extension\Core\Type\NumberType',
102
            // integer types
103
            'TINYINT'      => 'Symfony\Component\Form\Extension\Core\Type\IntegerType',
104
            'SMALLINT'     => 'Symfony\Component\Form\Extension\Core\Type\IntegerType',
105
            'INTEGER'      => 'Symfony\Component\Form\Extension\Core\Type\IntegerType',
106
            'BIGINT'       => 'Symfony\Component\Form\Extension\Core\Type\IntegerType',
107
            'NUMERIC'      => 'Symfony\Component\Form\Extension\Core\Type\IntegerType',
108
            // text types
109
            'CHAR'         => 'Symfony\Component\Form\Extension\Core\Type\TextType',
110
            'VARCHAR'      => 'Symfony\Component\Form\Extension\Core\Type\TextType',
111
            // textarea types
112
            'LONGVARCHAR'  => 'Symfony\Component\Form\Extension\Core\Type\TextareaType',
113
            'BLOB'         => 'Symfony\Component\Form\Extension\Core\Type\TextareaType',
114
            'CLOB'         => 'Symfony\Component\Form\Extension\Core\Type\TextareaType',
115
            'CLOB_EMU'     => 'Symfony\Component\Form\Extension\Core\Type\TextareaType',
116
            // association types
117
            'model'        => 'Symfony\Bridge\Propel1\Form\Type\ModelType',
118
            'collection'   => 'Symfony\Component\Form\Extension\Core\Type\CollectionType',
119
            // array types
120
            'PHP_ARRAY'    => 'Symfony\Component\Form\Extension\Core\Type\CollectionType',
121
            // choice types
122
            'ENUM'         => 'Symfony\Component\Form\Extension\Core\Type\ChoiceType',
123
            // boolean types
124
            'BOOLEAN'      => 'Symfony\Component\Form\Extension\Core\Type\CheckboxType',
125
            'BOOLEAN_EMU'  => 'Symfony\Component\Form\Extension\Core\Type\CheckboxType',
126
        ));
127
128
    private $defaultFilterTypes = array(
129
        'doctrine_orm' => array(
130
            // datetime types
131
            'datetime'    => 'Symfony\Component\Form\Extension\Core\Type\DateTimeType',
132
            'vardatetime' => 'Symfony\Component\Form\Extension\Core\Type\DateTimeType',
133
            'datetimetz'  => 'Symfony\Component\Form\Extension\Core\Type\DateTimeType',
134
            'date'        => 'Symfony\Component\Form\Extension\Core\Type\DateType',
135
            // time types
136
            'time'        => 'Symfony\Component\Form\Extension\Core\Type\TimeType',
137
            // number types
138
            'decimal'     => 'Symfony\Component\Form\Extension\Core\Type\NumberType',
139
            'float'       => 'Symfony\Component\Form\Extension\Core\Type\NumberType',
140
            // integer types
141
            'integer'     => 'Symfony\Component\Form\Extension\Core\Type\NumberType',
142
            'bigint'      => 'Symfony\Component\Form\Extension\Core\Type\NumberType',
143
            'smallint'    => 'Symfony\Component\Form\Extension\Core\Type\NumberType',
144
            // text types
145
            'string'      => 'Symfony\Component\Form\Extension\Core\Type\TextType',
146
            // textarea types
147
            'text'        => 'Symfony\Component\Form\Extension\Core\Type\TextType',
148
            // association types
149
            'entity'      => 'Symfony\Bridge\Doctrine\Form\Type\EntityType',
150
            'collection'  => 'Symfony\Component\Form\Extension\Core\Type\CollectionType',
151
            // array types
152
            'array'       => 'Symfony\Component\Form\Extension\Core\Type\TextType',
153
            // boolean types
154
            'boolean'     => 'Symfony\Component\Form\Extension\Core\Type\ChoiceType',
155
        ),
156
        'doctrine_odm' => array(
157
            // datetime types
158
            'datetime'    => 'Symfony\Component\Form\Extension\Core\Type\DateTimeType',
159
            'timestamp'   => 'Symfony\Component\Form\Extension\Core\Type\DateTimeType',
160
            'vardatetime' => 'Symfony\Component\Form\Extension\Core\Type\DateTimeType',
161
            'datetimetz'  => 'Symfony\Component\Form\Extension\Core\Type\DateTimeType',
162
            'date'        => 'Symfony\Component\Form\Extension\Core\Type\DateType',
163
            // time types
164
            'time'        => 'Symfony\Component\Form\Extension\Core\Type\TimeType',
165
            // number types
166
            'decimal'     => 'Symfony\Component\Form\Extension\Core\Type\NumberType',
167
            'float'       => 'Symfony\Component\Form\Extension\Core\Type\NumberType',
168
            // integer types
169
            'int'         => 'Symfony\Component\Form\Extension\Core\Type\NumberType',
170
            'integer'     => 'Symfony\Component\Form\Extension\Core\Type\NumberType',
171
            'int_id'      => 'Symfony\Component\Form\Extension\Core\Type\NumberType',
172
            'bigint'      => 'Symfony\Component\Form\Extension\Core\Type\NumberType',
173
            'smallint'    => 'Symfony\Component\Form\Extension\Core\Type\NumberType',
174
            // text types
175
            'id'          => 'Symfony\Component\Form\Extension\Core\Type\TextType',
176
            'custom_id'   => 'Symfony\Component\Form\Extension\Core\Type\TextType',
177
            'string'      => 'Symfony\Component\Form\Extension\Core\Type\TextType',
178
            // textarea types
179
            'text'        => 'Symfony\Component\Form\Extension\Core\Type\TextType',
180
            // association types
181
            'document'    => 'Doctrine\Bundle\MongoDBBundle\Form\Type\DocumentType',
182
            'collection'  => 'Symfony\Component\Form\Extension\Core\Type\CollectionType',
183
            // hash types
184
            'hash'        => 'Symfony\Component\Form\Extension\Core\Type\TextType',
185
            // boolean types
186
            'boolean'     => 'Symfony\Component\Form\Extension\Core\Type\ChoiceType',
187
        ),
188
        'propel' => array(
189
            // datetime types
190
            'TIMESTAMP'    => 'Symfony\Component\Form\Extension\Core\Type\DateTimeType',
191
            'BU_TIMESTAMP' => 'Symfony\Component\Form\Extension\Core\Type\DateTimeType',
192
            // date types
193
            'DATE'         => 'Symfony\Component\Form\Extension\Core\Type\DateType',
194
            'BU_DATE'      => 'Symfony\Component\Form\Extension\Core\Type\DateType',
195
            // time types
196
            'TIME'         => 'Symfony\Component\Form\Extension\Core\Type\TimeType',
197
            // number types
198
            'FLOAT'        => 'Symfony\Component\Form\Extension\Core\Type\NumberType',
199
            'REAL'         => 'Symfony\Component\Form\Extension\Core\Type\NumberType',
200
            'DOUBLE'       => 'Symfony\Component\Form\Extension\Core\Type\NumberType',
201
            'DECIMAL'      => 'Symfony\Component\Form\Extension\Core\Type\NumberType',
202
            // integer types
203
            'TINYINT'      => 'Symfony\Component\Form\Extension\Core\Type\IntegerType',
204
            'SMALLINT'     => 'Symfony\Component\Form\Extension\Core\Type\IntegerType',
205
            'INTEGER'      => 'Symfony\Component\Form\Extension\Core\Type\IntegerType',
206
            'BIGINT'       => 'Symfony\Component\Form\Extension\Core\Type\IntegerType',
207
            'NUMERIC'      => 'Symfony\Component\Form\Extension\Core\Type\NumberType',
208
            // text types
209
            'CHAR'         => 'Symfony\Component\Form\Extension\Core\Type\TextType',
210
            'VARCHAR'      => 'Symfony\Component\Form\Extension\Core\Type\TextType',
211
            // textarea types
212
            'LONGVARCHAR'  => 'Symfony\Component\Form\Extension\Core\Type\TextType',
213
            'BLOB'         => 'Symfony\Component\Form\Extension\Core\Type\TextType',
214
            'CLOB'         => 'Symfony\Component\Form\Extension\Core\Type\TextType',
215
            'CLOB_EMU'     => 'Symfony\Component\Form\Extension\Core\Type\TextType',
216
            // association types
217
            'model'        => 'Symfony\Bridge\Propel1\Form\Type\ModelType',
218
            'collection'   => 'Symfony\Component\Form\Extension\Core\Type\CollectionType',
219
            // array types
220
            'PHP_ARRAY'    => 'Symfony\Component\Form\Extension\Core\Type\TextType',
221
            // choice types
222
            'ENUM'         => 'Symfony\Component\Form\Extension\Core\Type\TextType',
223
            // boolean types
224
            'BOOLEAN'      => 'Symfony\Component\Form\Extension\Core\Type\ChoiceType',
225
            'BOOLEAN_EMU'  => 'Symfony\Component\Form\Extension\Core\Type\ChoiceType',
226
        ));
227
228
    /**
229
     * Generates the configuration tree builder.
230
     *
231
     *
232
     * @return \Symfony\Component\Config\Definition\Builder\TreeBuilder The tree builder
233
     */
234
    public function getConfigTreeBuilder()
235
    {
236
        $treeBuilder = new TreeBuilder();
237
        $rootNode    = $treeBuilder->root($this->rootName);
238
239
        $rootNode
240
            ->children()
241
                ->booleanNode('use_doctrine_orm')->defaultFalse()->end()
242
                ->booleanNode('use_doctrine_odm')->defaultFalse()->end()
243
                ->booleanNode('use_propel')->defaultFalse()->end()
244
                ->booleanNode('use_jms_security')->defaultFalse()->end()
245
                ->booleanNode('guess_required')->defaultTrue()->end()
246
                ->booleanNode('default_required')->defaultTrue()->end()
247
                ->booleanNode('overwrite_if_exists')->defaultFalse()->end()
248
                ->booleanNode('throw_exceptions')->defaultFalse()->end()
249
                ->scalarNode('base_admin_template')
250
                    ->defaultValue("AdmingeneratorGeneratorBundle::base.html.twig")
251
                ->end()
252
                ->scalarNode('dashboard_route')->defaultNull()->end()
253
                ->scalarNode('login_route')->defaultNull()->end()
254
                ->scalarNode('logout_route')->defaultNull()->end()
255
                ->scalarNode('exit_route')->defaultNull()->end()
256
                ->scalarNode('generator_cache')->defaultNull()->end()
257
                ->scalarNode('default_action_after_save')->defaultValue('edit')->end()
258
                ->scalarNode('knp_menu_alias')->defaultNull()->end()
259
                ->booleanNode('use_doctrine_orm_batch_remove')->defaultFalse()->end()
260
                ->booleanNode('use_doctrine_odm_batch_remove')->defaultFalse()->end()
261
                ->booleanNode('use_propel_batch_remove')->defaultFalse()->end()
262
                ->arrayNode('twig')
263
                    ->addDefaultsIfNotSet()
264
                    ->children()
265
                        ->booleanNode('use_form_resources')->defaultTrue()->end()
266
                        ->booleanNode('use_localized_date')->defaultFalse()->end()
267
                        ->scalarNode('date_format')->defaultValue('Y-m-d')->end()
268
                        ->scalarNode('datetime_format')->defaultValue('Y-m-d H:i:s')->end()
269
                        ->scalarNode('localized_date_format')->defaultValue('medium')->end()
270
                        ->scalarNode('localized_datetime_format')->defaultValue('medium')->end()
271
                        ->arrayNode('number_format')
272
                            ->addDefaultsIfNotSet()
273
                            ->children()
274
                                ->scalarNode('decimal')->defaultValue(0)->end()
275
                                ->scalarNode('decimal_point')->defaultValue('.')->end()
276
                                ->scalarNode('thousand_separator')->defaultValue(',')->end()
277
                            ->end()
278
                        ->end()
279
                    ->end()
280
                ->end()
281
                ->arrayNode('templates_dirs')
282
                    ->prototype('scalar')->end()
283
                ->end()
284
                ->arrayNode('form_types')
285
                    ->addDefaultsIfNotSet()
286
                    ->children()
287
                        ->arrayNode('doctrine_orm')
288
                            ->useAttributeAsKey('name')
289
                            ->prototype('scalar')->end()
290
                            ->defaultValue($this->defaultFormTypes['doctrine_orm'])
291
                            ->validate()
292
                            ->ifNotInArray(array_keys($this->defaultFormTypes['doctrine_orm']))
293
                                ->then(function($v) {
294
                                    return array_merge($this->defaultFormTypes['doctrine_orm'], $v);
295
                                })
296
                            ->end()
297
                        ->end()
298
                        ->arrayNode('doctrine_odm')
299
                            ->useAttributeAsKey('name')
300
                            ->prototype('scalar')->end()
301
                            ->defaultValue($this->defaultFormTypes['doctrine_odm'])
302
                            ->validate()
303
                            ->ifNotInArray(array_values($this->defaultFormTypes['doctrine_odm']))
304
                                ->then(function ($v){
305
                                    return array_merge($this->defaultFormTypes['doctrine_odm'], $v);
306
                                })
307
                            ->end()
308
                        ->end()
309
                        ->arrayNode('propel')
310
                            ->useAttributeAsKey('name')
311
                            ->prototype('scalar')->end()
312
                            ->defaultValue($this->defaultFormTypes['propel'])
313
                            ->validate()
314
                            ->ifNotInArray(array_values($this->defaultFormTypes['propel']))
315
                                ->then(function ($v){
316
                                    return array_merge($this->defaultFormTypes['propel'], $v);
317
                                })
318
                            ->end()
319
                        ->end()
320
                    ->end()
321
                ->end()
322
                ->arrayNode('filter_types')
323
                    ->addDefaultsIfNotSet()
324
                    ->children()
325
                        ->arrayNode('doctrine_orm')
326
                            ->useAttributeAsKey('name')
327
                            ->prototype('scalar')->end()
328
                            ->defaultValue($this->defaultFilterTypes['doctrine_orm'])
329
                            ->validate()
330
                            ->ifNotInArray(array_values($this->defaultFilterTypes['doctrine_orm']))
331
                                ->then(function ($v){
332
                                    return array_merge($this->defaultFilterTypes['doctrine_orm'], $v);
333
                                })
334
                            ->end()
335
                        ->end()
336
                        ->arrayNode('doctrine_odm')
337
                            ->useAttributeAsKey('name')
338
                            ->prototype('scalar')->end()
339
                            ->defaultValue($this->defaultFilterTypes['doctrine_odm'])
340
                            ->validate()
341
                            ->ifNotInArray(array_keys($this->defaultFilterTypes['doctrine_odm']))
342
                                ->then(function ($v){
343
                                    return array_merge($this->defaultFilterTypes['doctrine_odm'], $v);
344
                                })
345
                            ->end()
346
                        ->end()
347
                        ->arrayNode('propel')
348
                            ->useAttributeAsKey('name')
349
                            ->prototype('scalar')->end()
350
                            ->defaultValue($this->defaultFilterTypes['propel'])
351
                            ->validate()
352
                            ->ifNotInArray(array_values($this->defaultFilterTypes['propel']))
353
                                ->then(function ($v){
354
                                    return array_merge($this->defaultFilterTypes['propel'], $v);
355
                                })
356
                            ->end()
357
                        ->end()
358
                    ->end()
359
                ->end()
360
                ->append($this->getStylesheetNode())
361
                ->append($this->getJavascriptsNode())
362
            ->end();
363
364
        return $treeBuilder;
365
    }
366
367
    private function getStylesheetNode()
368
    {
369
        $treeBuilder = new TreeBuilder();
370
        $node = $treeBuilder->root('stylesheets');
371
372
        $node
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Symfony\Component\Config...\Builder\NodeDefinition as the method fixXmlConfig() does only exist in the following sub-classes of Symfony\Component\Config...\Builder\NodeDefinition: Symfony\Component\Config...der\ArrayNodeDefinition. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
373
            ->prototype('array')
374
            ->fixXmlConfig('stylesheets')
375
                ->children()
376
                    ->scalarNode('path')->end()
377
                    ->scalarNode('media')->defaultValue('all')->end()
378
                ->end()
379
            ->end();
380
381
        return $node;
382
    }
383
384
    private function getJavascriptsNode()
385
    {
386
        $treeBuilder = new TreeBuilder();
387
        $node = $treeBuilder->root('javascripts');
388
389
        $node
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Symfony\Component\Config...\Builder\NodeDefinition as the method fixXmlConfig() does only exist in the following sub-classes of Symfony\Component\Config...\Builder\NodeDefinition: Symfony\Component\Config...der\ArrayNodeDefinition. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
390
            ->prototype('array')
391
            ->fixXmlConfig('javascripts')
392
                ->children()
393
                    ->scalarNode('path')->end()
394
                    ->scalarNode('route')->end()
395
                    ->arrayNode('routeparams')
396
                        ->useAttributeAsKey('key')
397
                        ->prototype('scalar')
398
                        ->end()
399
                    ->end()
400
                ->end()
401
            ->end();
402
403
        return $node;
404
    }
405
}