Completed
Push — master ( b8ee64...bf1b53 )
by Nikola
04:04
created

Configuration::getRateTypeTypeDefinition()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 15
Code Lines 11

Duplication

Lines 15
Ratio 100 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 15
loc 15
ccs 0
cts 0
cp 0
rs 9.4285
cc 1
eloc 11
nc 1
nop 0
crap 2
1
<?php
2
/*
3
 * This file is part of the Exchange Rate Bundle, an RunOpenCode project.
4
 *
5
 * (c) 2016 RunOpenCode
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
namespace RunOpenCode\Bundle\ExchangeRate\DependencyInjection;
11
12
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
13
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
14
use Symfony\Component\Config\Definition\ConfigurationInterface;
15
16
/**
17
 * Class Configuration
18
 *
19
 * Configuration tree.
20
 *
21
 * @package RunOpenCode\Bundle\ExchangeRate\DependencyInjection
22
 */
23
class Configuration implements ConfigurationInterface
24
{
25
    /**
26
     * {@inheritdoc}
27
     */
28 4
    public function getConfigTreeBuilder()
29
    {
30 4
        $treeBuilder = new TreeBuilder();
31
32 4
        $rootNode = $treeBuilder->root('run_open_code_exchange_rate');
33
34
        $rootNode
35 4
            ->children()
36 4
                ->scalarNode('base_currency')
37 4
                    ->isRequired()
38 4
                    ->info('Set base currency in which you are doing your business activities.')
39 4
                ->end()
40 4
                ->scalarNode('repository')
41 4
                    ->defaultValue('file')
42 4
                    ->info('Service ID which is in charge for rates persistence.')
43 4
                ->end()
44 4
                ->append($this->getRatesDefinition())
45 4
                ->append($this->getFileRepositoryDefinition())
46 4
                ->append($this->getSourcesDefinition())
47 4
                ->append($this->getViewDefinition())
48 4
                ->append($this->getNotificationDefinition())
49 4
                ->arrayNode('form_types')
50 4
                    ->addDefaultsIfNotSet()
51
                    ->children()
52 4
                        ->append($this->getSourceTypeDefinition())
53
                        ->append($this->getRateTypeTypeDefinition())
54
                        ->append($this->getCurrencyCodeTypeDefinition())
55
                        ->append($this->getRateTypeDefinition())
56
                    ->end()
57
                ->end()
58
            ->end()
59
        ->end();
60 4
61
        return $treeBuilder;
62 4
    }
63
64 4
    /**
65 4
     * Build configuration tree for rates.
66 4
     *
67 4
     * @return ArrayNodeDefinition
68 4
     */
69 4
    protected function getRatesDefinition()
70 4
    {
71 4
        $node = new ArrayNodeDefinition('rates');
72 4
        $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 requiresAtLeastOneElement() 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...
73 4
            ->info('Configuration of each individual rate with which you intend to work with.')
74 4
            ->requiresAtLeastOneElement()
75
                ->prototype('array')
76 4
                    ->children()
77
                        ->scalarNode('currency_code')->isRequired()->end()
78
                        ->scalarNode('rate_type')->isRequired()->end()
79
                        ->scalarNode('source')->isRequired()->end()
80
                        ->arrayNode('extra')->end()
81
                    ->end()
82
                ->end()
83
            ->end();
84 4
85
        return $node;
86 4
    }
87
88
    /**
89 4
     * Build configuration tree for repository.
90 4
     *
91 4
     * @return ArrayNodeDefinition
92 4
     */
93 4
    protected function getFileRepositoryDefinition()
94 4
    {
95 4
        $node = new ArrayNodeDefinition('file_repository');
96 4
97 4
        $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 addDefaultsIfNotSet() 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...
98
            ->info('Configuration for file repository (if used).')
99 4
            ->addDefaultsIfNotSet()
100
            ->children()
101
                ->scalarNode('path')
102
                ->info('Absolute path to file where database file will be stored.')
103
                ->defaultValue('%kernel.root_dir%/db/exchange_rates.dat')
104
                ->end()
105
            ->end()
106
        ->end();
107 4
108
        return $node;
109 4
    }
110
111
    /**
112 4
     * Build configuration tree for simple sources.
113 4
     *
114 4
     * @return ArrayNodeDefinition
115 4
     */
116
    protected function getSourcesDefinition()
117 4
    {
118
        $node = new ArrayNodeDefinition('sources');
119
120
        $node
0 ignored issues
show
Bug introduced by
The method useAttributeAsKey() does not exist on Symfony\Component\Config...\Builder\NodeDefinition. Did you maybe mean attribute()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
121
            ->info('Add sources to sources registry without registering them into service container.')
122
            ->useAttributeAsKey('name')
123
            ->prototype('scalar')->end()
124
        ->end();
125 4
126
        return $node;
127 4
    }
128
129
    /**
130 4
     * Build configuration tree for view (controller).
131 4
     *
132 4
     * @return ArrayNodeDefinition
133 4
     */
134 4
    protected function getViewDefinition()
135 4
    {
136 4
        $node = new ArrayNodeDefinition('view');
137 4
138 4
        $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 addDefaultsIfNotSet() 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...
139 4
            ->info('Configuration of administration interface.')
140 4
            ->addDefaultsIfNotSet()
141 4
            ->children()
142 4
                ->scalarNode('base_template')
143 4
                    ->info('Base decorator template.')
144 4
                    ->defaultValue('@ExchangeRate/admin/base.html.twig')
145 4
                ->end()
146 4
                ->scalarNode('list')
147 4
                    ->info('Template for list view.')
148 4
                    ->defaultValue('@ExchangeRate/admin/list.html.twig')
149 4
                ->end()
150 4
                ->scalarNode('new')
151 4
                    ->info('Template for create new exchange rate view.')
152 4
                    ->defaultValue('@ExchangeRate/admin/new.html.twig')
153 4
                ->end()
154 4
                ->scalarNode('edit')
155 4
                    ->info('Template for edit exchange rate view.')
156 4
                    ->defaultValue('@ExchangeRate/admin/edit.html.twig')
157 4
                ->end()
158 4
                ->scalarNode('date_format')
159 4
                    ->info('Date format in list view.')
160
                    ->defaultValue('Y-m-d')
161 4
                ->end()
162
                ->scalarNode('time_format')
163
                    ->info('Date/time format in list view.')
164
                    ->defaultValue('H:i')
165
                ->end()
166
                ->booleanNode('secure')->defaultValue(true)->end()
167
            ->end()
168
        ->end();
169 4
170
        return $node;
171 4
    }
172
173
    /**
174 4
     * Build configuration tree for e-mail notifications.
175 4
     *
176 4
     * @return ArrayNodeDefinition
177 4
     */
178 4
    protected function getNotificationDefinition()
179 4
    {
180 4
        $node = new ArrayNodeDefinition('notifications');
181 4
182 4
        $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 children() 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...
183 4
            ->info('Notification settings.')
184 4
            ->children()
185 4
                ->arrayNode('fetch')
186 4
                    ->children()
187 4
                        ->booleanNode('enabled')
188 4
                            ->info('Send e-mail report about fetch result and fetched rates.')
189 4
                            ->defaultFalse()
190 4
                        ->end()
191 4
                        ->arrayNode('to')
192 4
                            ->info('Recipients e-mail addresses.')
193 4
                        ->end()
194 4
                        ->arrayNode('cc')
195 4
                            ->info('Recipients e-mail addresses.')
196 4
                        ->end()
197 4
                        ->arrayNode('bcc')
198 4
                            ->info('Blank carbon copy recipients e-mail addresses.')
199 4
                        ->end()
200 4
                        ->arrayNode('templates')
201 4
                            ->children()
202 4
                                ->scalarNode('success')
203 4
                                    ->isRequired()
204
                                    ->defaultValue('@ExchangeRate/mail/success.html.twig')
205 4
                                ->end()
206
                                ->scalarNode('error')
207
                                    ->isRequired()
208
                                    ->defaultValue('@ExchangeRate/mail/error.html.twig')
209
                                ->end()
210
                            ->end()
211
                        ->end()
212
                    ->end()
213
                ->end()
214
            ->end()
215
        ->end();
216
217
        return $node;
218
    }
219
220
    /**
221
     * Build configuration tree for "RunOpenCode\\Bundle\\ExchangeRate\\Form\\Type\\SourceType" default settings.
222
     *
223
     * @return ArrayNodeDefinition
224
     */
225 View Code Duplication
    protected function getSourceTypeDefinition()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
226
    {
227
        $node = new ArrayNodeDefinition('source_type');
228
229
        $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 addDefaultsIfNotSet() 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...
230
            ->info('Modify default "RunOpenCode\\Bundle\\ExchangeRate\\Form\\Type\\SourceType" settings.')
231
            ->addDefaultsIfNotSet()
232
            ->children()
233
                ->scalarNode('choice_translation_domain')->defaultValue('roc_exchange_rate')->end()
234
                ->arrayNode('preferred_choices')->end()
235
            ->end()
236
        ->end();
237
238
        return $node;
239
    }
240
241
    /**
242
     * Build configuration tree for "RunOpenCode\\Bundle\\ExchangeRate\\Form\\Type\\RateTypeType" default settings.
243
     *
244
     * @return ArrayNodeDefinition
245
     */
246 View Code Duplication
    protected function getRateTypeTypeDefinition()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
247
    {
248
        $node = new ArrayNodeDefinition('rate_type_type');
249
250
        $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 addDefaultsIfNotSet() 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...
251
            ->info('Modify default "RunOpenCode\\Bundle\\ExchangeRate\\Form\\Type\\RateTypeType" settings.')
252
            ->addDefaultsIfNotSet()
253
            ->children()
254
                ->scalarNode('choice_translation_domain')->defaultValue('roc_exchange_rate')->end()
255
                ->arrayNode('preferred_choices')->end()
256
            ->end()
257
        ->end();
258
259
        return $node;
260
    }
261
262
    /**
263
     * Build configuration tree for "RunOpenCode\\Bundle\\ExchangeRate\\Form\\Type\\CurrencyCodeType" default settings.
264
     *
265
     * @return ArrayNodeDefinition
266
     */
267 View Code Duplication
    protected function getCurrencyCodeTypeDefinition()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
268
    {
269
        $node = new ArrayNodeDefinition('currency_code_type');
270
271
        $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 addDefaultsIfNotSet() 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...
272
            ->info('Modify default "RunOpenCode\\Bundle\\ExchangeRate\\Form\\Type\\CurrencyCodeType" settings.')
273
            ->addDefaultsIfNotSet()
274
            ->children()
275
                ->scalarNode('choice_translation_domain')->defaultValue('roc_exchange_rate')->end()
276
                ->arrayNode('preferred_choices')->end()
277
            ->end()
278
        ->end();
279
280
        return $node;
281
    }
282
283
    /**
284
     * Build configuration tree for "RunOpenCode\\Bundle\\ExchangeRate\\Form\\Type\\RateType" default settings.
285
     *
286
     * @return ArrayNodeDefinition
287
     */
288
    protected function getRateTypeDefinition()
289
    {
290
        $node = new ArrayNodeDefinition('rate_type');
291
292
        $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 addDefaultsIfNotSet() 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...
293
            ->info('Modify default "RunOpenCode\\Bundle\\ExchangeRate\\Form\\Type\\RateType" settings.')
294
            ->addDefaultsIfNotSet()
295
            ->children()
296
                ->scalarNode('choice_translation_domain')->defaultValue('roc_exchange_rate')->end()
297
                ->scalarNode('label_format')->defaultValue('{{currency-code}}, {{rate-type}} ({{source}})')->end()
298
                ->arrayNode('preferred_choices')->end()
299
            ->end()
300
        ->end();
301
302
        return $node;
303
    }
304
}
305