Completed
Push — master ( 7d1fce...9e821b )
by Nikola
05:43
created

Configuration::getAccessRolesDefinition()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 30
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 27
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 30
ccs 27
cts 27
cp 1
rs 8.8571
c 0
b 0
f 0
cc 1
eloc 25
nc 1
nop 0
crap 1
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->getAccessRolesDefinition())
49 4
                ->append($this->getNotificationDefinition())
50 4
                ->arrayNode('form_types')
51 4
                    ->addDefaultsIfNotSet()
52 4
                    ->children()
53 4
                        ->append($this->getSourceTypeDefinition())
54 4
                        ->append($this->getRateTypeTypeDefinition())
55 4
                        ->append($this->getCurrencyCodeTypeDefinition())
56 4
                        ->append($this->getRateTypeDefinition())
57 4
                    ->end()
58 4
                ->end()
59 4
            ->end()
60
        ->end();
61 4
62
        return $treeBuilder;
63
    }
64
65
    /**
66
     * Build configuration tree for rates.
67
     *
68
     * @return ArrayNodeDefinition
69 4
     */
70
    protected function getRatesDefinition()
71 4
    {
72
        $node = new ArrayNodeDefinition('rates');
73 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...
74 4
            ->info('Configuration of each individual rate with which you intend to work with.')
75 4
            ->requiresAtLeastOneElement()
76 4
                ->prototype('array')
77 4
                    ->children()
78 4
                        ->scalarNode('currency_code')->isRequired()->end()
79 4
                        ->scalarNode('rate_type')->isRequired()->end()
80 4
                        ->scalarNode('source')->isRequired()->end()
81 4
                        ->arrayNode('extra')->end()
82 4
                    ->end()
83 4
                ->end()
84
            ->end();
85 4
86
        return $node;
87
    }
88
89
    /**
90
     * Build configuration tree for repository.
91
     *
92
     * @return ArrayNodeDefinition
93 4
     */
94
    protected function getFileRepositoryDefinition()
95 4
    {
96
        $node = new ArrayNodeDefinition('file_repository');
97
98 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...
99 4
            ->info('Configuration for file repository (if used).')
100 4
            ->addDefaultsIfNotSet()
101 4
            ->children()
102 4
                ->scalarNode('path')
103 4
                ->info('Absolute path to file where database file will be stored.')
104 4
                ->defaultValue('%kernel.root_dir%/db/exchange_rates.dat')
105 4
                ->end()
106 4
            ->end()
107
        ->end();
108 4
109
        return $node;
110
    }
111
112
    /**
113
     * Build configuration tree for simple sources.
114
     *
115
     * @return ArrayNodeDefinition
116 4
     */
117
    protected function getSourcesDefinition()
118 4
    {
119
        $node = new ArrayNodeDefinition('sources');
120
121 4
        $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...
122 4
            ->info('Add sources to sources registry without registering them into service container.')
123 4
            ->useAttributeAsKey('name')
124 4
            ->prototype('scalar')->end()
125
        ->end();
126 4
127
        return $node;
128
    }
129
130
    /**
131
     * Build configuration tree for view (controller).
132
     *
133
     * @return ArrayNodeDefinition
134 4
     */
135
    protected function getViewDefinition()
136 4
    {
137
        $node = new ArrayNodeDefinition('view');
138
139 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...
140 4
            ->info('Configuration of administration interface.')
141 4
            ->addDefaultsIfNotSet()
142 4
            ->children()
143 4
                ->scalarNode('base_template')
144 4
                    ->info('Base decorator template.')
145 4
                    ->defaultValue('@ExchangeRate/admin/base.html.twig')
146 4
                ->end()
147 4
                ->scalarNode('list')
148 4
                    ->info('Template for list view.')
149 4
                    ->defaultValue('@ExchangeRate/admin/list.html.twig')
150 4
                ->end()
151 4
                ->scalarNode('new')
152 4
                    ->info('Template for create new exchange rate view.')
153 4
                    ->defaultValue('@ExchangeRate/admin/new.html.twig')
154 4
                ->end()
155 4
                ->scalarNode('edit')
156 4
                    ->info('Template for edit exchange rate view.')
157 4
                    ->defaultValue('@ExchangeRate/admin/edit.html.twig')
158 4
                ->end()
159 4
                ->scalarNode('date_format')
160 4
                    ->info('Date format in list view.')
161 4
                    ->defaultValue('Y-m-d')
162 4
                ->end()
163 4
                ->scalarNode('time_format')
164 4
                    ->info('Date/time format in list view.')
165 4
                    ->defaultValue('H:i')
166 4
                ->end()
167 4
                ->booleanNode('secure')->defaultValue(true)->end()
168 4
            ->end()
169
        ->end();
170 4
171
        return $node;
172
    }
173
174
    /**
175
     * Build configuration tree for access roles.
176
     *
177
     * @return ArrayNodeDefinition
178 4
     */
179
    protected function getAccessRolesDefinition()
180 4
    {
181
        $node = new ArrayNodeDefinition('access_roles');
182
183 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...
184 4
            ->info('Configuration of controller access roles.')
185 4
            ->addDefaultsIfNotSet()
186 4
            ->children()
187 4
                ->arrayNode('list')
188 4
                    ->defaultValue(array('ROLE_EXCHANGE_RATE_MANAGER', 'ROLE_EXCHANGE_RATE_LIST'))
189 4
                    ->prototype('scalar')->end()
190 4
                ->end()
191 4
                ->arrayNode('create')
192 4
                    ->defaultValue(array('ROLE_EXCHANGE_RATE_MANAGER', 'ROLE_EXCHANGE_RATE_CREATE'))
193 4
                    ->prototype('scalar')->end()
194 4
                ->end()
195 4
                ->arrayNode('edit')
196 4
                    ->defaultValue(array('ROLE_EXCHANGE_RATE_MANAGER', 'ROLE_EXCHANGE_RATE_EDIT'))
197 4
                    ->prototype('scalar')->end()
198 4
                ->end()
199 4
                ->arrayNode('delete')
200 4
                    ->defaultValue(array('ROLE_EXCHANGE_RATE_MANAGER', 'ROLE_EXCHANGE_RATE_DELETE'))
201 4
                    ->prototype('scalar')->end()
202 4
                ->end()
203 4
            ->end()
204 4
        ->end();
205 4
206 4
207 4
        return $node;
208 4
    }
209 4
210 4
    /**
211 4
     * Build configuration tree for e-mail notifications.
212 4
     *
213 4
     * @return ArrayNodeDefinition
214 4
     */
215 4
    protected function getNotificationDefinition()
216 4
    {
217 4
        $node = new ArrayNodeDefinition('notifications');
218 4
219 4
        $node
220 4
            ->info('Notification settings.')
221 4
            ->addDefaultsIfNotSet()
222 4
            ->children()
223 4
                ->arrayNode('fetch')
224 4
                    ->children()
225 4
                        ->booleanNode('enabled')
226 4
                            ->info('Send e-mail report about fetch result and fetched rates.')
227 4
                            ->defaultTrue()
228 4
                        ->end()
229 4
                        ->scalarNode('from')
230 4
                            ->info('Mail sender address.')
231 4
                            ->defaultNull()
232 4
                        ->end()
233 4
                        ->arrayNode('to')
234 4
                            ->info('Recipients e-mail addresses.')
235 4
                            ->prototype('scalar')->end()
236 4
                        ->end()
237 4
                        ->arrayNode('cc')
238 4
                            ->info('Recipients e-mail addresses.')
239 4
                            ->prototype('scalar')->end()
240 4
                        ->end()
241 4
                        ->arrayNode('bcc')
242 4
                            ->info('Blank carbon copy recipients e-mail addresses.')
243 4
                            ->prototype('scalar')->end()
244 4
                        ->end()
245 4
                        ->arrayNode('templates')
246 4
                            ->addDefaultsIfNotSet()
247 4
                            ->info('Enable/disable individual mail notifications.')
248 4
                            ->children()
249 4
                                ->arrayNode('success')
250 4
                                    ->addDefaultsIfNotSet()
251 4
                                    ->children()
252
                                        ->booleanNode('enabled')
253 4
                                            ->info('Enable/disable success notification.')
254
                                            ->defaultTrue()
255
                                        ->end()
256
                                        ->scalarNode('subject')
257
                                            ->info('Mail notification subject.')
258
                                            ->defaultValue('System notification: exchange rates successfully fetched.')
259
                                        ->end()
260
                                        ->scalarNode('template')
261 4
                                            ->info('Mail body template.')
262
                                            ->defaultValue('@ExchangeRate/mail/success.html.twig')
263 4
                                        ->end()
264
                                    ->end()
265
                                ->end()
266 4
                                ->arrayNode('error')
267 4
                                    ->addDefaultsIfNotSet()
268 4
                                    ->children()
269 4
                                        ->booleanNode('enabled')
270 4
                                            ->info('Enable/disable success notification.')
271 4
                                            ->defaultTrue()
272 4
                                        ->end()
273
                                        ->scalarNode('subject')
274 4
                                            ->info('Mail notification subject.')
275
                                            ->defaultValue('Error notification: exchange rates are not fetched.')
276
                                        ->end()
277
                                        ->scalarNode('template')
278
                                            ->info('Mail body template.')
279
                                            ->defaultValue('@ExchangeRate/mail/error.html.twig')
280
                                        ->end()
281
                                    ->end()
282 4
                                ->end()
283
                            ->end()
284 4
                        ->end()
285
                    ->end()
286
                ->end()
287 4
            ->end()
288 4
        ->end();
289 4
290 4
        return $node;
291 4
    }
292 4
293 4
    /**
294
     * Build configuration tree for "RunOpenCode\Bundle\ExchangeRate\Form\Type\SourceType" default settings.
295 4
     *
296
     * @return ArrayNodeDefinition
297
     */
298 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...
299
    {
300
        $node = new ArrayNodeDefinition('source_type');
301
302
        $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...
303 4
            ->info('Modify default "RunOpenCode\\Bundle\\ExchangeRate\\Form\\Type\\SourceType" settings.')
304
            ->addDefaultsIfNotSet()
305 4
            ->children()
306
                ->scalarNode('choice_translation_domain')->defaultValue('roc_exchange_rate')->end()
307
                ->arrayNode('preferred_choices')->end()
308 4
            ->end()
309 4
        ->end();
310 4
311 4
        return $node;
312 4
    }
313 4
314 4
    /**
315
     * Build configuration tree for "RunOpenCode\Bundle\ExchangeRate\Form\Type\RateTypeType" default settings.
316 4
     *
317
     * @return ArrayNodeDefinition
318
     */
319 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...
320
    {
321
        $node = new ArrayNodeDefinition('rate_type_type');
322
323
        $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...
324 4
            ->info('Modify default "RunOpenCode\\Bundle\\ExchangeRate\\Form\\Type\\RateTypeType" settings.')
325
            ->addDefaultsIfNotSet()
326 4
            ->children()
327
                ->scalarNode('choice_translation_domain')->defaultValue('roc_exchange_rate')->end()
328
                ->arrayNode('preferred_choices')->end()
329 4
            ->end()
330 4
        ->end();
331 4
332 4
        return $node;
333 4
    }
334 4
335 4
    /**
336 4
     * Build configuration tree for "RunOpenCode\Bundle\ExchangeRate\Form\Type\CurrencyCodeType" default settings.
337
     *
338 4
     * @return ArrayNodeDefinition
339
     */
340 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...
341
    {
342
        $node = new ArrayNodeDefinition('currency_code_type');
343
344
        $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...
345
            ->info('Modify default "RunOpenCode\\Bundle\\ExchangeRate\\Form\\Type\\CurrencyCodeType" settings.')
346
            ->addDefaultsIfNotSet()
347
            ->children()
348
                ->scalarNode('choice_translation_domain')->defaultValue('roc_exchange_rate')->end()
349
                ->arrayNode('preferred_choices')->end()
350
            ->end()
351
        ->end();
352
353
        return $node;
354
    }
355
356
    /**
357
     * Build configuration tree for "RunOpenCode\Bundle\ExchangeRate\Form\Type\RateType" default settings.
358
     *
359
     * @return ArrayNodeDefinition
360
     */
361
    protected function getRateTypeDefinition()
362
    {
363
        $node = new ArrayNodeDefinition('rate_type');
364
365
        $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...
366
            ->info('Modify default "RunOpenCode\\Bundle\\ExchangeRate\\Form\\Type\\RateType" settings.')
367
            ->addDefaultsIfNotSet()
368
            ->children()
369
                ->scalarNode('choice_translation_domain')->defaultValue('roc_exchange_rate')->end()
370
                ->scalarNode('label_format')->defaultValue('{{currency-code}}, {{rate-type}} ({{source}})')->end()
371
                ->arrayNode('preferred_choices')->end()
372
            ->end()
373
        ->end();
374
375
        return $node;
376
    }
377
}
378