Completed
Push — master ( 308b6a...f69d44 )
by Antonio
02:29 queued 46s
created

src/User/Bootstrap.php (1 issue)

Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
/*
4
 * This file is part of the 2amigos/yii2-usuario project.
5
 *
6
 * (c) 2amigOS! <http://2amigos.us/>
7
 *
8
 * For the full copyright and license information, please view
9
 * the LICENSE file that was distributed with this source code.
10
 */
11
12
namespace Da\User;
13
14
use Da\User\Component\AuthDbManagerComponent;
15
use Da\User\Contracts\AuthManagerInterface;
16
use Da\User\Helper\ClassMapHelper;
17
use Da\User\Model\User;
18
use Yii;
19
use yii\authclient\Collection;
20
use yii\base\Application;
21
use yii\base\BootstrapInterface;
22
use yii\base\Exception;
23
use yii\console\Application as ConsoleApplication;
24
use yii\i18n\PhpMessageSource;
25
use yii\web\Application as WebApplication;
26
27
/**
28
 * Bootstrap class of the yii2-usuario extension. Configures container services, initializes translations,
29
 * builds class map, and does the other setup actions participating in the application bootstrap process.
30
 */
31
class Bootstrap implements BootstrapInterface
32
{
33
    /**
34
     * {@inheritdoc}
35
     */
36
    public function bootstrap($app)
37
    {
38
        if ($app->hasModule('user') && $app->getModule('user') instanceof Module) {
39
            $map = $this->buildClassMap($app->getModule('user')->classMap);
40
            $this->initContainer($app, $map);
41
            $this->initTranslations($app);
42
            $this->initMailServiceConfiguration($app, $app->getModule('user'));
43
44
            if ($app instanceof WebApplication) {
45
                $this->initControllerNamespace($app);
46
                $this->initUrlRoutes($app);
47
                $this->initAuthCollection($app);
48
                $this->initAuthManager($app);
49
            } else {
50
                /* @var $app ConsoleApplication */
51
                $this->initConsoleCommands($app);
52
                $this->initAuthManager($app);
53
            }
54
        }
55
    }
56
57
    /**
58
     * Initialize container with module classes.
59
     *
60
     * @param \yii\base\Application $app
61
     * @param array                 $map the previously built class map list
62
     */
63 10
    protected function initContainer($app, $map)
64
    {
65
        $di = Yii::$container;
66
        try {
67
            // events
68
            $di->set(Event\FormEvent::class);
69
            $di->set(Event\ProfileEvent::class);
70
            $di->set(Event\ResetPasswordEvent::class);
71
            $di->set(Event\SocialNetworkAuthEvent::class);
72
            $di->set(Event\SocialNetworkConnectEvent::class);
73
            $di->set(Event\UserEvent::class);
74
75
            // forms
76
            $di->set(Form\LoginForm::class);
77
            $di->set(Form\RecoveryForm::class);
78
            $di->set(Form\RegistrationForm::class);
79
            $di->set(Form\ResendForm::class);
80
            $di->set(Form\SettingsForm::class);
81
82
            // helpers
83
            $di->set(Helper\AuthHelper::class);
84
            $di->set(Helper\GravatarHelper::class);
85
            $di->set(Helper\SecurityHelper::class);
86
            $di->set(Helper\TimezoneHelper::class);
87
88
            // services
89
            $di->set(Service\AccountConfirmationService::class);
90
            $di->set(Service\EmailChangeService::class);
91
            $di->set(Service\PasswordRecoveryService::class);
92
            $di->set(Service\ResendConfirmationService::class);
93
            $di->set(Service\ResetPasswordService::class);
94
            $di->set(Service\SocialNetworkAccountConnectService::class);
95
            $di->set(Service\SocialNetworkAuthenticateService::class);
96
            $di->set(Service\UserBlockService::class);
97
            $di->set(Service\UserCreateService::class);
98
            $di->set(Service\UserRegisterService::class);
99
            $di->set(Service\UserConfirmationService::class);
100
            $di->set(Service\AuthItemEditionService::class);
101
            $di->set(Service\UpdateAuthAssignmentsService::class);
102
            $di->set(Service\SwitchIdentityService::class);
103
            $di->set(Service\TwoFactorQrCodeUriGeneratorService::class);
104
105
            // email change strategy
106
            $di->set(Strategy\DefaultEmailChangeStrategy::class);
107
            $di->set(Strategy\InsecureEmailChangeStrategy::class);
108
            $di->set(Strategy\SecureEmailChangeStrategy::class);
109
110
            // validators
111
            $di->set(Validator\AjaxRequestModelValidator::class);
112
            $di->set(Validator\TimeZoneValidator::class);
113
            $di->set(Validator\TwoFactorCodeValidator::class);
114
115
            // class map models + query classes
116
            $modelClassMap = [];
117
            foreach ($map as $class => $definition) {
118
                $di->set($class, $definition);
119
                $model = is_array($definition) ? $definition['class'] : $definition;
120
                $name = (substr($class, strrpos($class, '\\') + 1));
121
                $modelClassMap[$class] = $model;
122
                if (in_array($name, ['User', 'Profile', 'Token', 'SocialNetworkAccount'])) {
123
                    $di->set(
124
                        "Da\\User\\Query\\{$name}Query",
125 10
                        function () use ($model) {
126 10
                            return $model::find();
127
                        }
128
                    );
129
                }
130
            }
131
            $di->setSingleton(ClassMapHelper::class, ClassMapHelper::class, [$modelClassMap]);
132
133
            // search classes
134
            if (!$di->has(Search\UserSearch::class)) {
135
                $di->set(Search\UserSearch::class, [$di->get(Query\UserQuery::class)]);
136
            }
137
            if (!$di->has(Search\PermissionSearch::class)) {
138
                $di->set(Search\PermissionSearch::class);
139
            }
140
            if (!$di->has(Search\RoleSearch::class)) {
141
                $di->set(Search\RoleSearch::class);
142
            }
143
144
            if ($app instanceof WebApplication) {
145
                // override Yii
146
                $di->set(
147
                    'yii\web\User',
148
                    [
149
                        'enableAutoLogin' => true,
150
                        'loginUrl' => ['/user/security/login'],
151
                        'identityClass' => $di->get(ClassMapHelper::class)->get(User::class),
152
                    ]
153
                );
154
            }
155
        } catch (Exception $e) {
156
            die($e);
157
        }
158
    }
159
160
    /**
161
     * Registers module translation messages.
162
     *
163
     * @param Application $app
164
     */
165
    protected function initTranslations(Application $app)
166
    {
167
        if (!isset($app->get('i18n')->translations['usuario*'])) {
168
            $app->get('i18n')->translations['usuario*'] = [
169
                'class' => PhpMessageSource::class,
170
                'basePath' => __DIR__ . '/resources/i18n',
171
                'sourceLanguage' => 'en-US',
172
            ];
173
        }
174
    }
175
176
    /**
177
     * Ensures the auth manager is the one provided by the library.
178
     *
179
     * @param Application $app
180
     */
181
    protected function initAuthManager(Application $app)
182
    {
183
        if (!($app->getAuthManager() instanceof AuthManagerInterface)) {
184
            $app->set(
185
                'authManager',
186
                [
187
                    'class' => AuthDbManagerComponent::class,
188
                ]
189
            );
190
        }
191
    }
192
193
    /**
194
     * Initializes web url routes (rules in Yii2).
195
     *
196
     * @param WebApplication $app
197
     */
198
    protected function initUrlRoutes(WebApplication $app)
199
    {
200
        /** @var $module Module */
201
        $module = $app->getModule('user');
202
        $config = [
203
            'class' => 'yii\web\GroupUrlRule',
204
            'prefix' => $module->prefix,
205
            'rules' => $module->routes,
206
        ];
207
208
        if ($module->prefix !== 'user') {
209
            $config['routePrefix'] = 'user';
210
        }
211
212
        $rule = Yii::createObject($config);
213
        $app->getUrlManager()->addRules([$rule], false);
214
    }
215
216
    /**
217
     * Ensures required mail parameters needed for the mail service.
218
     *
219
     * @param Application             $app
220
     * @param Module|\yii\base\Module $module
221
     */
222
    protected function initMailServiceConfiguration(Application $app, Module $module)
223
    {
224
        $defaults = [
225
            'fromEmail' => '[email protected]',
226
            'welcomeMailSubject' => Yii::t('usuario', 'Welcome to {0}', $app->name),
227
            'confirmationMailSubject' => Yii::t('usuario', 'Confirm account on {0}', $app->name),
228
            'reconfirmationMailSubject' => Yii::t('usuario', 'Confirm email change on {0}', $app->name),
0 ignored issues
show
$app->name is of type string, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
229
            'recoveryMailSubject' => Yii::t('usuario', 'Complete password reset on {0}', $app->name),
230
        ];
231
232
        $module->mailParams = array_merge($defaults, $module->mailParams);
233
    }
234
235
    /**
236
     * Ensures the authCollection component is configured.
237
     *
238
     * @param WebApplication $app
239
     */
240
    protected function initAuthCollection(WebApplication $app)
241
    {
242
        if (!$app->has('authClientCollection')) {
243
            $app->set('authClientCollection', Collection::class);
244
        }
245
    }
246
247
    /**
248
     * Registers console commands to main app.
249
     *
250
     * @param ConsoleApplication $app
251
     */
252
    protected function initConsoleCommands(ConsoleApplication $app)
253
    {
254
        $app->getModule('user')->controllerNamespace = 'Da\User\Command';
255
    }
256
257
    /**
258
     * Registers controllers.
259
     *
260
     * @param WebApplication $app
261
     */
262
    protected function initControllerNamespace(WebApplication $app)
263
    {
264
        $app->getModule('user')->controllerNamespace = 'Da\User\Controller';
265
        $app->getModule('user')->setViewPath('@Da/User/resources/views');
266
    }
267
268
    /**
269
     * Builds class map according to user configuration.
270
     *
271
     * @param array $userClassMap user configuration on the module
272
     *
273
     * @return array
274
     */
275
    protected function buildClassMap(array $userClassMap)
276
    {
277
        $map = [];
278
279
        $defaults = [
280
            // --- models
281
            'User' => 'Da\User\Model\User',
282
            'SocialNetworkAccount' => 'Da\User\Model\SocialNetworkAccount',
283
            'Profile' => 'Da\User\Model\Profile',
284
            'Token' => 'Da\User\Model\Token',
285
            'Assignment' => 'Da\User\Model\Assignment',
286
            'Permission' => 'Da\User\Model\Permission',
287
            'Role' => 'Da\User\Model\Role',
288
            // --- search
289
            'UserSearch' => 'Da\User\Search\UserSearch',
290
            'PermissionSearch' => 'Da\User\Search\PermissionSearch',
291
            'RoleSearch' => 'Da\User\Search\RoleSearch',
292
            // --- forms
293
            'RegistrationForm' => 'Da\User\Form\RegistrationForm',
294
            'ResendForm' => 'Da\User\Form\ResendForm',
295
            'LoginForm' => 'Da\User\Form\LoginForm',
296
            'SettingsForm' => 'Da\User\Form\SettingsForm',
297
            'RecoveryForm' => 'Da\User\Form\RecoveryForm',
298
        ];
299
300
        $routes = [
301
            'Da\User\Model' => [
302
                'User',
303
                'SocialNetworkAccount',
304
                'Profile',
305
                'Token',
306
                'Assignment',
307
                'Permission',
308
                'Role',
309
            ],
310
            'Da\User\Search' => [
311
                'UserSearch',
312
                'PermissionSearch',
313
                'RoleSearch',
314
            ],
315
            'Da\User\Form' => [
316
                'RegistrationForm',
317
                'ResendForm',
318
                'LoginForm',
319
                'SettingsForm',
320
                'RecoveryForm',
321
            ],
322
        ];
323
324
        $mapping = array_merge($defaults, $userClassMap);
325
326
        foreach ($mapping as $name => $definition) {
327
            $map[$this->getRoute($routes, $name) . "\\$name"] = $definition;
328
        }
329
330
        return $map;
331
    }
332
333
    /**
334
     * Returns the parent class name route of a short class name.
335
     *
336
     * @param array  $routes class name routes
337
     * @param string $name
338
     *
339
     * @throws Exception
340
     * @return int|string
341
     *
342
     */
343
    protected function getRoute(array $routes, $name)
344
    {
345
        foreach ($routes as $route => $names) {
346
            if (in_array($name, $names)) {
347
                return $route;
348
            }
349
        }
350
        throw new Exception("Unknown configuration class name '{$name}'");
351
    }
352
}
353