I’m making use of the UserObserver to make sure everytime a user gets some experience points a new UserLevel is given to the user (in case of newly gained experience points are sufficient to level up / level down).
UserObserver:
public function updating(User $user){
//check if EXP amount was updated
if($user->isDirty('exp')){
//increased
if($user->experience_points > $user->getOriginal('experience_points')){
$nextLevel = $user->currentLevel->nextLevel();
while(!is_null($nextLevel) && $user->experience_points >= $nextLevel->experience_required) {
Log::info("current level: " . $user->current_level);
$user->current_level = $nextLevel->id;
Log::info("after edit level: " . $user->current_level);
$nextLevel = UserLevel::whereId($nextLevel->id + 1)->first();
}
}
//decreased
elseif($user->experience_points < $user->getOriginal('experience_points')){
$previousLevel = $user->currentLevel->previousLevel();
while(!is_null($previousLevel) && $user->experience_points <= $previousLevel->experience_required) {
Log::info("current level: " . $user->current_level);
$user->current_level = $previousLevel->id;
Log::info("after edit level: " . $user->current_level);
$previousLevel = UserLevel::whereId($previousLevel->id - 1)->first();
}
}
}
}
I’m able to follow the output of the observer:
[2023-03-11 18:53:36] local.INFO: current level: 1
[2023-03-11 18:53:36] local.INFO: after edit level: 2
[2023-03-11 18:53:36] local.INFO: current level: 2
[2023-03-11 18:53:36] local.INFO: after edit level: 3
[2023-03-11 18:53:36] local.INFO: current level: 3
[2023-03-11 18:53:36] local.INFO: after edit level: 4
[2023-03-11 18:53:36] local.INFO: current level: 4
[2023-03-11 18:53:36] local.INFO: after edit level: 5
Somehow the current_level field inside the database is not updated (still set to 1) after observer run is finished.
Any ideas to make the code more readable are welcome.