Configuration   A
last analyzed

Complexity

Total Complexity 1

Size/Duplication

Total Lines 116
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 1

Importance

Changes 0
Metric Value
wmc 1
lcom 0
cbo 1
dl 0
loc 116
rs 10
c 0
b 0
f 0

1 Method

Rating   Name   Duplication   Size   Complexity  
B getConfigTreeBuilder() 0 110 1
1
<?php
2
3
/*
4
 * This file is part of the Superdesk Web Publisher MultiTenancy Bundle.
5
 *
6
 * Copyright 2015 Sourcefabric z.u. and contributors.
7
 *
8
 * For the full copyright and license information, please see the
9
 * AUTHORS and LICENSE files distributed with this source code.
10
 *
11
 * @copyright 2015 Sourcefabric z.ú
12
 * @license http://www.superdesk.org/license
13
 */
14
15
namespace SWP\Bundle\MultiTenancyBundle\DependencyInjection;
16
17
use SWP\Bundle\MultiTenancyBundle\Doctrine\ORM\OrganizationRepository;
18
use SWP\Bundle\MultiTenancyBundle\Doctrine\ORM\TenantRepository;
19
use SWP\Bundle\MultiTenancyBundle\Doctrine\PHPCR\OrganizationRepository as PHPCROrganizationRepository;
20
use SWP\Bundle\MultiTenancyBundle\Doctrine\PHPCR\TenantRepository as PHPCRTenantRepository;
21
use SWP\Bundle\MultiTenancyBundle\Factory\OrganizationFactory;
22
use SWP\Bundle\MultiTenancyBundle\Routing\TenantAwareRouter;
23
use SWP\Component\MultiTenancy\Factory\TenantFactory;
24
use SWP\Component\MultiTenancy\Model\Organization;
25
use SWP\Component\MultiTenancy\Model\OrganizationInterface;
26
use SWP\Component\MultiTenancy\Model\Tenant;
27
use SWP\Component\MultiTenancy\Model\TenantInterface;
28
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
29
use Symfony\Component\Config\Definition\ConfigurationInterface;
30
31
/**
32
 * This is the class that validates and merges configuration from your app/config files.
33
 *
34
 * To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html#cookbook-bundles-extension-config-class}
35
 */
36
class Configuration implements ConfigurationInterface
37
{
38
    /**
39
     * {@inheritdoc}
40
     */
41
    public function getConfigTreeBuilder()
42
    {
43
        $treeBuilder = new TreeBuilder('swp_multi_tenancy');
44
        $treeBuilder->getRootNode()
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...
45
            ->children()
46
                ->booleanNode('use_orm_listeners')
47
                    ->defaultFalse()
48
                    ->info('Listeners which make sure that each entity is tenant aware (they append tenant code).')
49
                ->end()
50
                ->arrayNode('persistence')
51
                    ->validate()
52
                    ->ifTrue(function ($v) {
53
                        return count(array_filter($v, function ($persistence) {
54
                            return $persistence['enabled'];
55
                        })) > 1;
56
                    })
57
                    ->thenInvalid('Only one persistence layer can be enabled at the same time.')
58
                    ->end()
59
                    ->addDefaultsIfNotSet()
60
                    ->children()
61
                        ->arrayNode('phpcr')
62
                            ->addDefaultsIfNotSet()
63
                            ->canBeEnabled()
64
                            ->children()
65
                                ->scalarNode('basepath')->defaultValue('/swp')->end()
66
                                ->arrayNode('route_basepaths')
67
                                    ->prototype('scalar')->end()
68
                                    ->defaultValue(['routes'])
69
                                    ->info('Route base paths names')
70
                                ->end()
71
                                ->scalarNode('content_basepath')
72
                                    ->defaultValue('content')
73
                                    ->info('Content base path name')
74
                                ->end()
75
                                ->scalarNode('menu_basepath')
76
                                    ->defaultValue('menu')
77
                                    ->info('Menu base path name')
78
                                ->end()
79
                                ->scalarNode('media_basepath')
80
                                    ->defaultValue('media')
81
                                    ->info('Media base path name')
82
                                ->end()
83
                                ->scalarNode('tenant_aware_router_class')
84
                                    ->defaultValue(TenantAwareRouter::class)
85
                                    ->info('Tenant aware router FQCN')
86
                                ->end()
87
                                ->arrayNode('classes')
88
                                    ->addDefaultsIfNotSet()
89
                                    ->children()
90
                                        ->arrayNode('tenant')
91
                                            ->addDefaultsIfNotSet()
92
                                            ->children()
93
                                                ->scalarNode('model')->cannotBeEmpty()->defaultValue(Tenant::class)->end()
94
                                                ->scalarNode('interface')->cannotBeEmpty()->defaultValue(TenantInterface::class)->end()
95
                                                ->scalarNode('repository')->defaultValue(PHPCRTenantRepository::class)->end()
96
                                                ->scalarNode('factory')->defaultValue(TenantFactory::class)->end()
97
                                                ->scalarNode('object_manager_name')->defaultValue(null)->end()
98
                                            ->end()
99
                                        ->end()
100
                                        ->arrayNode('organization')
101
                                            ->addDefaultsIfNotSet()
102
                                            ->children()
103
                                                ->scalarNode('model')->cannotBeEmpty()->defaultValue(Organization::class)->end()
104
                                                ->scalarNode('interface')->cannotBeEmpty()->defaultValue(OrganizationInterface::class)->end()
105
                                                ->scalarNode('repository')->defaultValue(PHPCROrganizationRepository::class)->end()
106
                                                ->scalarNode('factory')->defaultValue(OrganizationFactory::class)->end()
107
                                                ->scalarNode('object_manager_name')->defaultValue(null)->end()
108
                                            ->end()
109
                                        ->end()
110
                                    ->end()
111
                                ->end()
112
                            ->end()
113
                        ->end() // phpcr
114
                        ->arrayNode('orm')
115
                            ->addDefaultsIfNotSet()
116
                            ->canBeEnabled()
117
                            ->children()
118
                                ->arrayNode('classes')
119
                                    ->addDefaultsIfNotSet()
120
                                    ->children()
121
                                        ->arrayNode('tenant')
122
                                            ->addDefaultsIfNotSet()
123
                                            ->children()
124
                                                ->scalarNode('model')->cannotBeEmpty()->defaultValue(Tenant::class)->end()
125
                                                ->scalarNode('interface')->cannotBeEmpty()->defaultValue(TenantInterface::class)->end()
126
                                                ->scalarNode('repository')->defaultValue(TenantRepository::class)->end()
127
                                                ->scalarNode('factory')->defaultValue(TenantFactory::class)->end()
128
                                                ->scalarNode('object_manager_name')->defaultValue(null)->end()
129
                                            ->end()
130
                                        ->end()
131
                                        ->arrayNode('organization')
132
                                            ->addDefaultsIfNotSet()
133
                                            ->children()
134
                                                ->scalarNode('model')->cannotBeEmpty()->defaultValue(Organization::class)->end()
135
                                                ->scalarNode('interface')->cannotBeEmpty()->defaultValue(OrganizationInterface::class)->end()
136
                                                ->scalarNode('repository')->defaultValue(OrganizationRepository::class)->end()
137
                                                ->scalarNode('factory')->defaultValue(OrganizationFactory::class)->end()
138
                                                ->scalarNode('object_manager_name')->defaultValue(null)->end()
139
                                            ->end()
140
                                        ->end()
141
                                    ->end()
142
                                ->end()
143
                            ->end()
144
                        ->end() // orm
145
                    ->end()
146
                ->end()
147
            ->end();
148
149
        return $treeBuilder;
150
    }
151
}
152