Skip to content

Commit 99738f3

Browse files
committed
auto-save events with User
1 parent 1c877ad commit 99738f3

7 files changed

Lines changed: 108 additions & 71 deletions

File tree

userfrosting/controllers/AccountController.php

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -436,18 +436,16 @@ public function register(){
436436
foreach ($defaultGroups as $group_id => $group)
437437
$user->addGroup($group_id);
438438

439-
// Store new user to database
440-
$user->save();
441-
442439
// Create sign-up event
443-
$sign_up_event = $user->newEventSignUp();
444-
$sign_up_event->save();
440+
$user->newEventSignUp();
441+
442+
// Store new user to database
443+
$user->save();
445444

446445
if ($this->_app->site->require_activation) {
447446
// Create verification request event
448-
$verification_request = $user->newEventVerificationRequest();
449-
$user->save(); // Re-save is needed to update user's secret token
450-
$verification_request->save();
447+
$user->newEventVerificationRequest();
448+
$user->save(); // Re-save with verification event
451449

452450
// Create and send verification email
453451
$twig = $this->_app->view()->getEnvironment();
@@ -557,7 +555,7 @@ public function forgotPassword(){
557555
// TODO: rate-limit the number of password reset requests for a given user
558556

559557
// Generate a new password reset request. This will also generate a new secret token for the user.
560-
$event = $user->newEventPasswordReset();
558+
$user->newEventPasswordReset();
561559

562560
// Email the user asking to confirm this change password request
563561
$twig = $this->_app->view()->getEnvironment();
@@ -577,8 +575,7 @@ public function forgotPassword(){
577575
$this->_app->halt(500);
578576
}
579577

580-
$user->store();
581-
$event->save();
578+
$user->save();
582579
$ms->addMessageTranslated("success", "FORGOTPASS_REQUEST_SUCCESS");
583580
}
584581

@@ -740,7 +737,8 @@ public function denyResetPassword(){
740737
* 4. A request to resend the activation link wasn't already processed in the last X seconds (specified in site settings)
741738
* 5. The submitted data is valid.
742739
* This route is "public access".
743-
* Request type: POST
740+
* Request type: POST
741+
* @todo Again, just like with password reset - do we really need to get the user's user_name to do this?
744742
*/
745743
public function resendActivation(){
746744
$data = $this->_app->request->post();
@@ -796,7 +794,7 @@ public function resendActivation(){
796794
}
797795

798796
// We're good to go - create a new verification request and send the email
799-
$event = $user->newEventVerificationRequest();
797+
$user->newEventVerificationRequest();
800798

801799
// Email the user
802800
$twig = $this->_app->view()->getEnvironment();
@@ -816,8 +814,7 @@ public function resendActivation(){
816814
$this->_app->halt(500);
817815
}
818816

819-
$user->store();
820-
$event->save();
817+
$user->save();
821818
$ms->addMessageTranslated("success", "ACCOUNT_NEW_ACTIVATION_SENT");
822819
}
823820

userfrosting/controllers/InstallController.php

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -231,13 +231,12 @@ public function setupMasterAccount(){
231231
foreach ($defaultGroups as $group_id => $group)
232232
$user->addGroup($group_id);
233233

234+
// Add sign-up event
235+
$user->newEventSignUp();
236+
234237
// Store new user to database
235238
$user->save();
236239

237-
// Add sign-up event
238-
$event = $user->newEventSignUp();
239-
$event->save();
240-
241240
// No activation required
242241
$ms->addMessageTranslated("success", "ACCOUNT_REGISTRATION_COMPLETE_TYPE1");
243242

userfrosting/controllers/UserController.php

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -445,19 +445,12 @@ public function createUser(){
445445
}
446446
}
447447

448-
// Store new user to database so that we have a user_id
449-
$user->save();
450-
451448
// Create events - account creation and password reset
452-
$event_sign_up = $user->newEventSignUp($this->_app->user);
453-
$event_password_reset_request = $user->newEventPasswordReset();
454-
455-
// Save user again after creating reset event
456-
$user->save();
449+
$user->newEventSignUp($this->_app->user);
450+
$user->newEventPasswordReset();
457451

458-
// Save user events
459-
$event_sign_up->save();
460-
$event_password_reset_request->save();
452+
// Save user again after creating events
453+
$user->save();
461454

462455
// Send an email to the user's email address to set up password
463456
$twig = $this->_app->view()->getEnvironment();

userfrosting/initialize.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@
190190
$app->site->register('userfrosting', 'email_login', "Email Login", "toggle", [0 => "Off", 1 => "On"]);
191191
$app->site->register('userfrosting', 'resend_activation_threshold', "Resend Activation Email Cooloff (s)");
192192
$app->site->register('userfrosting', 'reset_password_timeout', "Password Recovery Timeout (s)");
193+
$app->site->register('userfrosting', 'create_password_expiration', "Create Password for New Users Timeout (s)");
193194
$app->site->register('userfrosting', 'minify_css', "Minify CSS", "toggle", [0 => "Off", 1 => "On"]);
194195
$app->site->register('userfrosting', 'minify_js', "Minify JS", "toggle", [0 => "Off", 1 => "On"]);
195196
}, 1);

userfrosting/models/database/User.php

Lines changed: 40 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ class User extends UFModel {
4343
*/
4444
protected $_primary_group;
4545

46+
/**
47+
* @var UserEvent[] An array of events to be inserted for this User when save is called.
48+
*/
49+
protected $new_events = [];
50+
4651
/**
4752
* @var bool Enable timestamps for Users.
4853
*/
@@ -149,6 +154,7 @@ public function newCollection(array $models = Array()) {
149154

150155
/**
151156
* Get all events for this user.
157+
* @todo save events in $new_events as well?
152158
*/
153159
public function events(){
154160
return $this->hasMany('UserFrosting\UserEvent');
@@ -329,20 +335,6 @@ private function fetchPrimaryGroup() {
329335
}
330336
return $this->belongsTo('UserFrosting\Group', 'primary_group_id')->getEager()->first();
331337
}
332-
333-
/**
334-
* Store the User to the database, along with any group associations, updating as necessary.
335-
*
336-
*/
337-
public function save(array $options = []){
338-
// Update the user record itself
339-
$result = parent::save($options);
340-
341-
// Synchronize model's group relations with database
342-
$this->syncCachedGroups();
343-
344-
return $result;
345-
}
346338

347339
/**
348340
* Create an event saying that this user registered their account, or an account was created for them.
@@ -356,10 +348,10 @@ public function newEventSignUp($creator = null){
356348
else
357349
$description = "User {$this->user_name} successfully registered on " . date("Y-m-d H:i:s") . ".";
358350
$event = new UserEvent([
359-
"user_id" => $this->id,
360351
"event_type" => "sign_up",
361352
"description" => $description
362353
]);
354+
$this->new_events[] = $event;
363355
return $event;
364356
}
365357

@@ -369,11 +361,12 @@ public function newEventSignUp($creator = null){
369361
* @return UserEvent
370362
*/
371363
public function newEventSignIn(){
372-
return new UserEvent([
373-
"user_id" => $this->id,
364+
$event = new UserEvent([
374365
"event_type" => "sign_in",
375366
"description" => "User {$this->user_name} signed in at " . date("Y-m-d H:i:s") . "."
376367
]);
368+
$this->new_events[] = $event;
369+
return $event;
377370
}
378371

379372
/**
@@ -384,10 +377,10 @@ public function newEventSignIn(){
384377
public function newEventVerificationRequest(){
385378
$this->secret_token = User::generateActivationToken();
386379
$event = new UserEvent([
387-
"user_id" => $this->id,
388380
"event_type" => "verification_request",
389381
"description" => "User {$this->user_name} requested verification on " . date("Y-m-d H:i:s") . "."
390382
]);
383+
$this->new_events[] = $event;
391384
return $event;
392385
}
393386

@@ -400,13 +393,32 @@ public function newEventPasswordReset(){
400393
$this->secret_token = User::generateActivationToken();
401394
$this->flag_password_reset = "1";
402395
$event = new UserEvent([
403-
"user_id" => $this->id,
404396
"event_type" => "password_reset_request",
405397
"description" => "User {$this->user_name} requested a password reset on " . date("Y-m-d H:i:s") . "."
406398
]);
399+
$this->new_events[] = $event;
407400
return $event;
408401
}
409402

403+
/**
404+
* Store the User to the database, along with any group associations and new events, updating as necessary.
405+
*
406+
*/
407+
public function save(array $options = []){
408+
// Update the user record itself
409+
$result = parent::save($options);
410+
411+
// Synchronize model's group relations with database
412+
$this->syncCachedGroups();
413+
414+
// Save any new events for this user
415+
foreach ($this->new_events as $event){
416+
$this->events()->save($event);
417+
}
418+
419+
return $result;
420+
}
421+
410422
/**
411423
* Delete this user from the database, along with any linked groups and authorization rules
412424
*
@@ -513,8 +525,7 @@ public function verifyPassword($password){
513525
*/
514526
public function login(){
515527
// Add a sign in event (time is automatically set by database)
516-
$event = $this->newEventSignIn();
517-
$event->save();
528+
$this->newEventSignIn();
518529

519530
// Update password if we had encountered an outdated hash
520531
if (Authentication::getPasswordHashType($this->password) != "modern"){
@@ -528,12 +539,18 @@ public function login(){
528539
}
529540
}
530541

531-
// Store changes
532-
$this->store();
542+
// Save changes
543+
$this->save();
533544

534545
return $this;
535546
}
536547

548+
/**
549+
* Log this user out.
550+
*
551+
* Destroys the PHP session as well.
552+
* @param bool $complete If set to true, will also clear out any persistent sessions.
553+
*/
537554
public function logout($complete = false) {
538555
if ($complete){
539556
$storage = new \Birke\Rememberme\Storage\PDO(static::$app->remember_me_table);

userfrosting/templates/themes/default/account/reset-password.twig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
</p>
2121
{% include 'components/common/alerts.twig' %}
2222
<form class="form-horizontal" role="form" name="reset_password" action="{{site.uri.public}}/account/set-password" method="post">
23+
<!-- Prevent browsers from trying to autofill the password field. See http://stackoverflow.com/a/23234498/2970321 -->
24+
<input type="text" style="display:none">
25+
<input type="password" style="display:none">
2326
<div class="form-group">
2427
<label for="input_password" class="control-label col-sm-4">New Password</label>
2528
<div class="col-sm-8">
Lines changed: 45 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,49 @@
1-
{% if 'password' not in fields.hidden %}
2-
<div class="col-sm-6">
3-
<div class="form-group">
4-
<label>Password</label>
5-
<div class="input-group">
6-
<span class="input-group-addon"><i class="fa fa-key"></i></span>
7-
<input type="password" class="form-control" name="password" autocomplete="off" value="" placeholder="8-50 characters">
8-
</div>
1+
<div id='{{box_id}}' class='modal fade' data-width="760">
2+
<div class='modal-header'>
3+
<button type='button' class='close' data-dismiss='modal' aria-hidden='true'>&times;</button>
4+
<h4 class='modal-title'>{{box_title}}</h4>
5+
</div>
6+
<div class='modal-body'>
7+
<form name="user_password" method="post" action="{{form_action}}">
8+
<div id="form-alerts">
99
</div>
10-
<div class="form-group">
11-
<label>Confirm password</label>
12-
<div class="input-group">
13-
<span class="input-group-addon"><i class="fa fa-key"></i></span>
14-
<input type="password" class="form-control" name="passwordc" autocomplete="off" value="" placeholder="Confirm password">
10+
<div class="row">
11+
<div class="col-sm-6">
12+
<div class="form-group">
13+
<label>Password</label>
14+
<div class="input-group">
15+
<span class="input-group-addon"><i class="fa fa-key"></i></span>
16+
<input type="password" class="form-control" name="password" autocomplete="off" value="" placeholder="8-50 characters">
17+
</div>
18+
</div>
19+
<div class="form-group">
20+
<label>Confirm password</label>
21+
<div class="input-group">
22+
<span class="input-group-addon"><i class="fa fa-key"></i></span>
23+
<input type="password" class="form-control" name="passwordc" autocomplete="off" value="" placeholder="Confirm password">
24+
</div>
25+
</div>
26+
</div>
27+
</div><br>
28+
<div class="row">
29+
<div class="col-xs-8 col-sm-4">
30+
<div class="vert-pad">
31+
<button type="submit" class="btn btn-block btn-lg btn-success">
32+
{{submit_button}}
33+
</button>
34+
</div>
35+
</div>
36+
<div class="col-xs-4 col-sm-3 pull-right">
37+
<div class="vert-pad">
38+
<button type="button" class="btn btn-block btn-lg btn-link" data-dismiss="modal">Cancel</button>
39+
</div>
1540
</div>
1641
</div>
17-
</div>
18-
{% endif %}
19-
42+
</form>
43+
</div>
44+
</div>
2045

21-
22-
46+
<script>
47+
// Load the validator rules for this form
48+
var validators = {{validators | raw}};
49+
</script>

0 commit comments

Comments
 (0)