forked from amnah/yii2-user
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Module.php
288 lines (252 loc) · 9.79 KB
/
Module.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
<?php
namespace amnah\yii2\user;
use Yii;
use yii\base\InvalidConfigException;
use yii\db\ActiveRecord;
/**
* User module
*
* @author amnah <[email protected]>
*/
class Module extends \yii\base\Module
{
/**
* @var string Module version
*/
protected $version = "5.0.8";
/**
* @var string Alias for module
*/
public $alias = "@user";
/**
* @var bool If true, users are required to enter an email
*/
public $requireEmail = true;
/**
* @var bool If true, users are required to enter a username
*/
public $requireUsername = false;
/**
* @var bool If true, users can enter an email. This is automatically set to true if $requireEmail = true
*/
public $useEmail = true;
/**
* @var bool If true, users can enter a username. This is automatically set to true if $requireUsername = true
*/
public $useUsername = true;
/**
* @var bool If true, users can log in using their email
*/
public $loginEmail = true;
/**
* @var bool If true, users can log in using their username
*/
public $loginUsername = true;
/**
* @var int Login duration
*/
public $loginDuration = 2592000; // 1 month
/**
* @var array|string|null Url to redirect to after logging in. If null, will redirect to home page. Note that
* AccessControl takes precedence over this (see [[yii\web\User::loginRequired()]])
*/
public $loginRedirect = null;
/**
* @var array|string|null Url to redirect to after logging out. If null, will redirect to home page
*/
public $logoutRedirect = null;
/**
* @var bool If true, users will have to confirm their email address after registering (= email activation)
*/
public $emailConfirmation = true;
/**
* @var bool If true, users will have to confirm their email address after changing it on the account page
*/
public $emailChangeConfirmation = true;
/**
* @var string Reset password token expiration (passed to strtotime())
*/
public $resetExpireTime = "2 days";
/**
* @var string Login via email token expiration (passed to strtotime())
*/
public $loginExpireTime = "15 minutes";
/**
* @var string Email view path
*/
public $emailViewPath = "@user/mail";
/**
* @var string Force translation
*/
public $forceTranslation = false;
/**
* @var array Model classes, e.g., ["User" => "amnah\yii2\user\models\User"]
* Usage:
* $user = Yii::$app->getModule("user")->model("User", $config);
* (equivalent to)
* $user = new \amnah\yii2\user\models\User($config);
*
* The model classes here will be merged with/override the [[getDefaultModelClasses()|default ones]]
*/
public $modelClasses = [];
/**
* Get module version
* @return string
*/
public function getVersion()
{
return $this->version;
}
/**
* @inheritdoc
*/
public function init()
{
parent::init();
// check for valid email/username properties
$this->checkModuleProperties();
// set up i8n
if (empty(Yii::$app->i18n->translations['user'])) {
Yii::$app->i18n->translations['user'] = [
'class' => 'yii\i18n\PhpMessageSource',
'basePath' => __DIR__ . '/messages',
'forceTranslation' => $this->forceTranslation,
];
}
// override modelClasses
$this->modelClasses = array_merge($this->getDefaultModelClasses(), $this->modelClasses);
// set alias
$this->setAliases([
$this->alias => __DIR__,
]);
}
/**
* Check for valid email/username properties
*/
protected function checkModuleProperties()
{
// set use fields based on required fields
if ($this->requireEmail) {
$this->useEmail = true;
}
if ($this->requireUsername) {
$this->useUsername = true;
}
// get class name for error messages
$className = get_called_class();
// check required fields
if (!$this->requireEmail && !$this->requireUsername) {
throw new InvalidConfigException("{$className}: \$requireEmail and/or \$requireUsername must be true");
}
// check login fields
if (!$this->loginEmail && !$this->loginUsername) {
throw new InvalidConfigException("{$className}: \$loginEmail and/or \$loginUsername must be true");
}
// check email fields with emailConfirmation/emailChangeConfirmation is true
if (!$this->useEmail && ($this->emailConfirmation || $this->emailChangeConfirmation)) {
$msg = "{$className}: \$useEmail must be true if \$email(Change)Confirmation is true";
throw new InvalidConfigException($msg);
}
// ensure that the "user" component is set properly
// this typically causes problems in the yii2-advanced app when people set it in
// "common/config" instead of "frontend/config" and/or "backend/config"
// -> this results in users failing to login without any feedback/error message
$userComponent = Yii::$app->get('user', false);
if ($userComponent && !$userComponent instanceof \amnah\yii2\user\components\User) {
throw new InvalidConfigException('Yii::$app->user is not set properly. It needs to extend \amnah\yii2\user\components\User');
}
}
/**
* Get default model classes
*/
protected function getDefaultModelClasses()
{
// attempt to calculate user class based on user component
// (we do this because yii console does not have a user component)
if (Yii::$app->get('user', false)) {
$userClass = Yii::$app->user->identityClass;
} elseif (class_exists('app\models\User')) {
$userClass = 'app\models\User';
} else {
$userClass = 'amnah\yii2\user\models\User';
}
return [
'User' => $userClass,
'Profile' => 'amnah\yii2\user\models\Profile',
'Role' => 'amnah\yii2\user\models\Role',
'UserToken' => 'amnah\yii2\user\models\UserToken',
'UserAuth' => 'amnah\yii2\user\models\UserAuth',
'ForgotForm' => 'amnah\yii2\user\models\forms\ForgotForm',
'LoginForm' => 'amnah\yii2\user\models\forms\LoginForm',
'ResendForm' => 'amnah\yii2\user\models\forms\ResendForm',
'UserSearch' => 'amnah\yii2\user\models\search\UserSearch',
'LoginEmailForm' => 'amnah\yii2\user\models\forms\LoginEmailForm',
];
}
/**
* Get object instance of model
* @param string $name
* @param array $config
* @return ActiveRecord
*/
public function model($name, $config = [])
{
$config["class"] = $this->modelClasses[ucfirst($name)];
return Yii::createObject($config);
}
/**
* Modify createController() to handle routes in the default controller
*
* This is needed because of the way we map actions to "user/default/<action>".
* We can't use module bootstrapping because that doesn't work when
* `urlManager.enablePrettyUrl` = false.
* Additionally, this requires one less step during installation
*
* @link https://github.com/amnah/yii2-user/issues/94
*
* "user", "user/default", "user/admin", "user/copy", and "user/auth" work like normal
* any other "user/xxx" gets changed to "user/default/xxx"
*
* @inheritdoc
*/
public function createController($route)
{
// check valid routes
$validRoutes = [$this->defaultRoute, "admin", "copy", "auth"];
$isValidRoute = false;
foreach ($validRoutes as $validRoute) {
if (strpos($route, $validRoute) === 0) {
$isValidRoute = true;
break;
}
}
return (empty($route) or $isValidRoute)
? parent::createController($route)
: parent::createController("{$this->defaultRoute}/{$route}");
}
/**
* Get a list of actions for this module. Used for debugging/initial installations
*/
public function getActions()
{
return [
"/{$this->id}" => "This 'actions' list. Appears only when <strong>YII_DEBUG</strong>=true, otherwise redirects to /login or /account",
"/{$this->id}/admin" => "Admin CRUD",
"/{$this->id}/login" => "Login page",
"/{$this->id}/logout" => "Logout page",
"/{$this->id}/register" => "Register page",
"/{$this->id}/login-email" => "Login page v2 (login/register via email link)",
"/{$this->id}/login-callback?token=zzzzz" => "Login page v2 callback (after user clicks link in email)",
"/{$this->id}/auth/login?authclient=facebook" => "Register/login via social account",
"/{$this->id}/auth/connect?authclient=facebook" => "Connect social account to currently logged in user",
"/{$this->id}/account" => "User account page (email, username, password)",
"/{$this->id}/profile" => "Profile page",
"/{$this->id}/forgot" => "Forgot password page",
"/{$this->id}/reset?token=zzzzz" => "Reset password page. Automatically generated from forgot password page",
"/{$this->id}/resend" => "Resend email confirmation (for both activation and change of email)",
"/{$this->id}/resend-change" => "Resend email change confirmation (quick link on the 'Account' page)",
"/{$this->id}/cancel" => "Cancel email change confirmation (quick link on the 'Account' page)",
"/{$this->id}/confirm?token=zzzzz" => "Confirm email address. Automatically generated upon registration/email change",
];
}
}