Changeset View
Changeset View
Standalone View
Standalone View
src/app/Observers/UserObserver.php
Show First 20 Lines • Show All 183 Lines • ▼ Show 20 Lines | public function restored(User $user) | ||||
$chain = [ | $chain = [ | ||||
new \App\Jobs\User\VerifyJob($user->id), | new \App\Jobs\User\VerifyJob($user->id), | ||||
]; | ]; | ||||
\App\Jobs\User\CreateJob::withChain($chain)->dispatch($user->id); | \App\Jobs\User\CreateJob::withChain($chain)->dispatch($user->id); | ||||
} | } | ||||
/** | /** | ||||
* Handle the "updating" event. | * Handle the "updated" event. | ||||
* | * | ||||
* @param User $user The user that is being updated. | * @param \App\User $user The user that is being updated. | ||||
* | * | ||||
* @return void | * @return void | ||||
*/ | */ | ||||
public function updating(User $user) | public function updated(User $user) | ||||
{ | { | ||||
\App\Jobs\User\UpdateJob::dispatch($user->id); | \App\Jobs\User\UpdateJob::dispatch($user->id); | ||||
$oldStatus = $user->getOriginal('status'); | |||||
$newStatus = $user->status; | |||||
if (($oldStatus & User::STATUS_DEGRADED) !== ($newStatus & User::STATUS_DEGRADED)) { | |||||
$wallets = []; | |||||
$isDegraded = $user->isDegraded(); | |||||
// Charge all entitlements as if they were being deleted, | |||||
// but don't delete them. Just debit the wallet and update | |||||
// entitlements' updated_at timestamp. On un-degrade we still | |||||
// update updated_at, but with no debit (the cost is 0 on a degraded account). | |||||
foreach ($user->wallets as $wallet) { | |||||
$wallet->updateEntitlements($isDegraded); | |||||
// Remember time of the degradation for sending periodic reminders | |||||
// and reset it on un-degradation | |||||
$val = $isDegraded ? \Carbon\Carbon::now()->toDateTimeString() : null; | |||||
$wallet->setSetting('degraded_last_reminder', $val); | |||||
$wallets[] = $wallet->id; | |||||
} | |||||
// (Un-)degrade users by invoking an update job. | |||||
// LDAP backend will read the wallet owner's degraded status and | |||||
// set LDAP attributes accordingly. | |||||
// We do not change their status as their wallets have its own state | |||||
\App\Entitlement::whereIn('wallet_id', $wallets) | |||||
->where('entitleable_id', '!=', $user->id) | |||||
->where('entitleable_type', User::class) | |||||
->pluck('entitleable_id') | |||||
->unique() | |||||
->each(function ($user_id) { | |||||
\App\Jobs\User\UpdateJob::dispatch($user_id); | |||||
}); | |||||
} | |||||
} | } | ||||
/** | /** | ||||
* Remove entitleables/transactions related to the user (in user's wallets) | * Remove entitleables/transactions related to the user (in user's wallets) | ||||
* | * | ||||
* @param \App\User $user The user | * @param \App\User $user The user | ||||
* @param bool $force Force-delete mode | * @param bool $force Force-delete mode | ||||
*/ | */ | ||||
private static function removeRelatedObjects(User $user, $force = false): void | private static function removeRelatedObjects(User $user, $force = false): void | ||||
{ | { | ||||
$wallets = $user->wallets->pluck('id')->all(); | $wallets = $user->wallets->pluck('id')->all(); | ||||
\App\Entitlement::withTrashed() | \App\Entitlement::withTrashed() | ||||
->select('entitleable_id', 'entitleable_type') | ->select('entitleable_id', 'entitleable_type') | ||||
->distinct() | ->distinct() | ||||
->whereIn('wallet_id', $wallets) | ->whereIn('wallet_id', $wallets) | ||||
->get() | ->get() | ||||
->each(function ($entitlement) use ($user, $force) { | ->each(function ($entitlement) use ($user, $force) { | ||||
// Skip the current user (infinite recursion loop) | // Skip the current user (infinite recursion loop) | ||||
if ($entitlement->entitleable_type == User::class && $entitlement->entitleable_id == $user->id) { | if ($entitlement->entitleable_type == User::class && $entitlement->entitleable_id == $user->id) { | ||||
return; | return; | ||||
} | } | ||||
// Objects need to be deleted one by one to make sure observers can do the proper cleanup | // Objects need to be deleted one by one to make sure observers can do the proper cleanup | ||||
if ($entitlement->entitleable) { | |||||
if ($force) { | if ($force) { | ||||
$entitlement->entitleable->forceDelete(); | $entitlement->entitleable->forceDelete(); | ||||
} elseif (!$entitlement->entitleable->trashed()) { | } elseif (!$entitlement->entitleable->trashed()) { | ||||
$entitlement->entitleable->delete(); | $entitlement->entitleable->delete(); | ||||
} | } | ||||
} | |||||
}); | }); | ||||
if ($force) { | if ($force) { | ||||
// Remove "wallet" transactions, they have no foreign key constraint | // Remove "wallet" transactions, they have no foreign key constraint | ||||
\App\Transaction::where('object_type', Wallet::class) | \App\Transaction::where('object_type', Wallet::class) | ||||
->whereIn('object_id', $wallets) | ->whereIn('object_id', $wallets) | ||||
->delete(); | ->delete(); | ||||
} | } | ||||
} | } | ||||
} | } |