Passed
Push — main ( c9aeaf...8f791a )
by Iain
06:03
created

User::handleDefaultParameters()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 16
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 14
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 16
rs 9.7998
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * Copyright Humbly Arrogant Software Limited 2020-2024
7
 *
8
 * Use of this software is governed by the Business Source License included in the LICENSE file and at https://getparthenon.com/docs/next/license.
9
 *
10
 * Change Date: 26.06.2026 ( 3 years after 2.2.0 release )
11
 *
12
 * On the date above, in accordance with the Business Source License, use of this software will be governed by the open source license specified in the LICENSE file.
13
 */
14
15
namespace Parthenon\DependencyInjection\Modules;
16
17
use Parthenon\Common\Exception\NonExistentClass;
18
use Parthenon\Common\Exception\ParameterNotSetException;
19
use Parthenon\User\Entity\TeamInterface;
20
use Parthenon\User\Entity\UserInterface;
21
use Parthenon\User\Gdpr\Deletion\DeleterInterface;
22
use Parthenon\User\Gdpr\Deletion\VoterInterface;
23
use Parthenon\User\Gdpr\Export\ExporterInterface;
24
use Parthenon\User\Gdpr\Export\FormatterInterface;
25
use Symfony\Component\Config\Definition\Builder\NodeBuilder;
26
use Symfony\Component\Config\FileLocator;
27
use Symfony\Component\DependencyInjection\ContainerBuilder;
28
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
29
30
final class User implements ModuleConfigurationInterface
31
{
32
    public function addConfig(NodeBuilder $nodeBuilder): void
33
    {
34
        $nodeBuilder
35
            ->arrayNode('user')
36
                ->children()
37
                    ->booleanNode('enabled')->defaultValue(false)->end()
38
                    ->scalarNode('user_class')->end()
0 ignored issues
show
Bug introduced by
The method scalarNode() does not exist on Symfony\Component\Config...der\NodeParentInterface. It seems like you code against a sub-type of Symfony\Component\Config...der\NodeParentInterface such as Symfony\Component\Config...ion\Builder\NodeBuilder. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

38
                    ->/** @scrutinizer ignore-call */ scalarNode('user_class')->end()
Loading history...
39
                    ->booleanNode('email_confirmation')->defaultValue(true)->end()
40
                    ->booleanNode('signed_in_after_signup')->defaultValue(false)->end()
41
                    ->booleanNode('user_invites_enabled')->defaultValue(false)->end()
42
                    ->scalarNode('login_route')->defaultValue('parthenon_user_login')->end()
43
                    ->scalarNode('login_redirect_route')->defaultValue('parthenon_user_profile')->end()
44
                    ->scalarNode('signup_success_route')->defaultValue('parthenon_user_signed_up')->end()
45
                    ->booleanNode('teams_enabled')->defaultValue(false)->end()
46
                    ->booleanNode('teams_invites_enabled')->defaultValue(false)->end()
47
                    ->booleanNode('self_signup_enabled')->defaultValue(true)->end()
48
                    ->scalarNode('team_class')->end()
49
                    ->scalarNode('firewall_name')->end()
50
                    ->arrayNode('roles')
51
                        ->children()
52
                            ->scalarNode('default_role')->defaultValue('ROLE_USER')->end()
53
                            ->arrayNode('user_assignable')
54
                                 ->useAttributeAsKey('name')
55
                                ->scalarPrototype()->end()
56
                            ->end()
57
                            ->arrayNode('athena_assignable')
58
                                ->useAttributeAsKey('name')
59
                                ->scalarPrototype()->end()
60
                            ->end()
61
                        ->end()
62
                    ->end()
63
                    ->arrayNode('gdpr')
64
                        ->children()
65
                            ->arrayNode('export')
66
                                ->children()
67
                                ->scalarNode('export_format')->end()
68
                                ->end()
69
                            ->end()
70
                        ->end()
71
                    ->end()
72
                ->end()
73
            ->end();
74
    }
75
76
    public function handleDefaultParameters(ContainerBuilder $container): void
77
    {
78
        $container->setParameter('parthenon_user_login_route', 'parthenon_user_login');
79
        $container->setParameter('parthenon_user_signup_success_route', 'parthenon_user_signed_up');
80
        $container->setParameter('parthenon_user_users_invites_enabled', false);
81
        $container->setParameter('parthenon_user_teams_enabled', false);
82
        $container->setParameter('parthenon_user_team_class', null);
83
        $container->setParameter('parthenon_user_teams_invites_enabled', false);
84
        $container->setParameter('parthenon_user_gdpr_formatter_type', 'json');
85
        $container->setParameter('parthenon_user_roles_default_role', 'ROLE_USER');
86
        $container->setParameter('parthenon_user_roles_user_assignable_roles', []);
87
        $container->setParameter('parthenon_user_roles_athena_assignable_roles', []);
88
        $container->setParameter('parthenon_user_self_signup_enabled', true);
89
        $container->setParameter('parthenon_user_email_confirmation', true);
90
        $container->setParameter('parthenon_user_signed_in_after_signup', false);
91
        $container->setParameter('parthenon_user_firewall_name', 'main');
92
    }
93
94
    public function handleConfiguration(array $config, ContainerBuilder $container): void
95
    {
96
        if (!isset($config['user']) || !isset($config['user']['enabled']) || false == $config['user']['enabled']) {
97
            return;
98
        }
99
        $container->setParameter('parthenon_user_enabled', true);
100
101
        $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../../Resources/config'));
102
        $bundles = $container->getParameter('kernel.bundles');
103
104
        $this->configureMongoDb($bundles, $loader);
105
        $this->configureDoctrine($bundles, $loader);
106
107
        $loader->load('services/user.xml');
108
109
        $this->configureAutotagging($container);
110
        $config = $this->configureUserClass($config, $container);
111
        $config = $this->configureSignupSuccessRoute($config, $container);
112
        $config = $this->configureLoginRoute($config, $container);
113
        $config = $this->configureUserInvitesEnabled($config, $container);
114
        $config = $this->configureTeamsInviteEnabled($config, $container);
115
        $config = $this->configureGdprFormatterType($config, $container);
116
        $config = $this->configureRoles($config, $container);
117
        $config = $this->configureSelfSignup($config, $container);
118
        $config = $this->configureEmailConfirmation($config, $container);
119
        $config = $this->configureSignedInAfterSignup($config, $container);
120
        $config = $this->configureFirewall($config, $container);
121
122
        $this->configureTeams($config, $container);
123
    }
124
125
    /**
126
     * @throws NonExistentClass
127
     * @throws ParameterNotSetException
128
     */
129
    private function configureTeams(array $config, ContainerBuilder $container): void
130
    {
131
        if (isset($config['user']['teams_enabled']) && $config['user']['teams_enabled']) {
132
            $container->setParameter('parthenon_user_teams_enabled_flag', true);
133
            $container->setParameter('parthenon_user_teams_enabled', $config['user']['teams_enabled']);
134
            if (!isset($config['user']['team_class']) || empty($config['user']['team_class'])) {
135
                throw new ParameterNotSetException('When the user module is enabled and teams are enabled the team_class must be defined');
136
            }
137
138
            if (!class_exists($config['user']['team_class'])) {
139
                throw new NonExistentClass(sprintf("The class '%s' does not exist.", $config['user']['team_class']));
140
            }
141
142
            $teamDdfinition = $container->getDefinition(TeamInterface::class);
143
            $teamDdfinition->setClass($config['user']['team_class']);
144
            $container->setDefinition(TeamInterface::class, $teamDdfinition);
145
        }
146
    }
147
148
    private function configureGdprFormatterType(array $config, ContainerBuilder $container): array
149
    {
150
        if (isset($config['user']['gdpr']['export']['formatter_type']) && !empty($config['user']['gdpr']['export']['formatter_type'])) {
151
            $container->setParameter('parthenon_user_gdpr_formatter_type', $config['user']['gdpr']['export']['formatter_type']);
152
        }
153
154
        return $config;
155
    }
156
157
    private function configureTeamsInviteEnabled(array $config, ContainerBuilder $container): array
158
    {
159
        if (isset($config['user']['teams_invites_enabled'])) {
160
            $container->setParameter('parthenon_user_teams_invites_enabled', $config['user']['teams_invites_enabled']);
161
        }
162
163
        return $config;
164
    }
165
166
    private function configureUserInvitesEnabled(array $config, ContainerBuilder $container): array
167
    {
168
        if (isset($config['user']['user_invites_enabled'])) {
169
            $container->setParameter('parthenon_user_users_invites_enabled', $config['user']['user_invites_enabled']);
170
        }
171
172
        return $config;
173
    }
174
175
    private function configureRoles(array $config, ContainerBuilder $containerBuilder): array
176
    {
177
        if (!isset($config['user']['roles'])) {
178
            return $config;
179
        }
180
181
        $containerBuilder->setParameter('parthenon_user_roles_default_role', $config['user']['roles']['default_role'] ?? 'ROLE_USER');
182
        $containerBuilder->setParameter('parthenon_user_roles_user_assignable_roles', $config['user']['roles']['user_assignable'] ?? []);
183
        $containerBuilder->setParameter('parthenon_user_roles_athena_assignable_roles', $config['user']['roles']['athena_assignable'] ?? []);
184
185
        return $config;
186
    }
187
188
    private function configureLoginRoute(array $config, ContainerBuilder $container): array
189
    {
190
        if (isset($config['user']['login_route'])) {
191
            $container->setParameter('parthenon_user_login_route', $config['user']['login_route']);
192
        }
193
194
        return $config;
195
    }
196
197
    private function configureSignupSuccessRoute(array $config, ContainerBuilder $container): array
198
    {
199
        if (isset($config['user']['signup_success_route'])) {
200
            $container->setParameter('parthenon_user_signup_success_route', $config['user']['signup_success_route']);
201
        }
202
203
        return $config;
204
    }
205
206
    private function configureEmailConfirmation(array $config, ContainerBuilder $container): array
207
    {
208
        if (isset($config['user']['email_confirmation'])) {
209
            $container->setParameter('parthenon_user_email_confirmation', $config['user']['email_confirmation']);
210
        }
211
212
        return $config;
213
    }
214
215
    private function configureFirewall(array $config, ContainerBuilder $container): array
216
    {
217
        if (isset($config['user']['firewall_name'])) {
218
            $container->setParameter('parthenon_user_firewall_name', $config['user']['firewall_name']);
219
        }
220
221
        return $config;
222
    }
223
224
    private function configureSignedInAfterSignup(array $config, ContainerBuilder $container): array
225
    {
226
        if (isset($config['user']['signed_in_after_signup'])) {
227
            $container->setParameter('parthenon_user_signed_in_after_signup', $config['user']['signed_in_after_signup']);
228
        }
229
230
        return $config;
231
    }
232
233
    private function configureSelfSignup(array $config, ContainerBuilder $container): array
234
    {
235
        if (isset($config['user']['self_signup_enabled'])) {
236
            $container->setParameter('parthenon_user_self_signup_enabled', $config['user']['self_signup_enabled']);
237
        }
238
239
        return $config;
240
    }
241
242
    private function configureAutotagging(ContainerBuilder $container): void
243
    {
244
        $container->registerForAutoconfiguration(ExporterInterface::class)->addTag('parthenon.user.gdpr.export.exporter');
245
        $container->registerForAutoconfiguration(FormatterInterface::class)->addTag('parthenon.user.gdpr.export.formatter');
246
        $container->registerForAutoconfiguration(DeleterInterface::class)->addTag('parthenon.user.gdpr.delete.deleter');
247
        $container->registerForAutoconfiguration(VoterInterface::class)->addTag('parthenon.user.gdpr.delete.voter');
248
    }
249
250
    /**
251
     * @throws \Exception
252
     */
253
    private function configureDoctrine(float|array|bool|int|string|null $bundles, XmlFileLoader $loader): string|int|bool|array|float|null
254
    {
255
        if (isset($bundles['DoctrineBundle'])) {
256
            $loader->load('services/orm/user.xml');
257
        }
258
259
        return $bundles;
260
    }
261
262
    /**
263
     * @throws \Exception
264
     */
265
    private function configureMongoDb(float|int|bool|array|string|null $bundles, XmlFileLoader $loader): void
266
    {
267
        if (isset($bundles['DoctrineMongoDBBundle'])) {
268
            $loader->load('services/odm/user.xml');
269
        }
270
    }
271
272
    /**
273
     * @throws NonExistentClass
274
     * @throws ParameterNotSetException
275
     */
276
    private function configureUserClass(array $config, ContainerBuilder $container): array
277
    {
278
        if (!isset($config['user']['user_class']) || empty($config['user']['user_class'])) {
279
            throw new ParameterNotSetException('When the user module is enabled the user_class must be defined');
280
        }
281
282
        if (!class_exists($config['user']['user_class'])) {
283
            throw new NonExistentClass(sprintf("The class '%s' does not exist.", $config['user']['user_class']));
284
        }
285
286
        $userDefintion = $container->getDefinition(UserInterface::class);
287
        $userDefintion->setClass($config['user']['user_class']);
288
        $container->setDefinition(UserInterface::class, $userDefintion);
289
290
        return $config;
291
    }
292
}
293