1
0
Fork 0
mirror of https://github.com/archtechx/tenancy.git synced 2026-09-20 14:34:03 +00:00

Make force deleting central resources force delete already-trashed tenant resources

This commit is contained in:
lukinovec 2026-09-16 16:42:06 +02:00
parent 553f57a8ad
commit 735a2dd48b
2 changed files with 52 additions and 5 deletions

View file

@ -5,8 +5,8 @@ declare(strict_types=1);
namespace Stancl\Tenancy\ResourceSyncing\Listeners; namespace Stancl\Tenancy\ResourceSyncing\Listeners;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Stancl\Tenancy\ResourceSyncing\Syncable;
use Stancl\Tenancy\ResourceSyncing\SyncMaster; use Stancl\Tenancy\ResourceSyncing\SyncMaster;
use Illuminate\Contracts\Database\Eloquent\Builder;
trait DeletesSyncedResources trait DeletesSyncedResources
{ {
@ -14,16 +14,20 @@ trait DeletesSyncedResources
{ {
$tenantResourceClass = $centralResource->getTenantModelName(); $tenantResourceClass = $centralResource->getTenantModelName();
/** @var (Syncable&Model)|null $tenantResource */ /** @var Builder $query */
$tenantResource = $tenantResourceClass::firstWhere( $query = $tenantResourceClass::where(
$centralResource->getGlobalIdentifierKeyName(), $centralResource->getGlobalIdentifierKeyName(),
$centralResource->getGlobalIdentifierKey() $centralResource->getGlobalIdentifierKey()
); );
if ($force) { if ($force) {
$tenantResource?->forceDelete(); if ($query->hasMacro('withTrashed')) {
$query->withTrashed(); // @phpstan-ignore method.notFound
}
$query->first()?->forceDelete();
} else { } else {
$tenantResource?->delete(); $query->first()?->delete();
} }
} }
} }

View file

@ -1193,6 +1193,49 @@ test('using forceDelete on a central resource with soft deletes force deletes th
expect(TenantUserWithSoftDeletes::withTrashed()->firstWhere('global_id', 'user'))->toBeNull(); expect(TenantUserWithSoftDeletes::withTrashed()->firstWhere('global_id', 'user'))->toBeNull();
}); });
test('force deleting a central resource force deletes tenant resources that are already trashed', function () {
[$tenant1] = createTenantsAndRunMigrations();
migrateUsersTableForTenants();
addExtraColumns(true);
$centralUser = CentralUserWithSoftDeletes::create([
'global_id' => 'user',
'name' => 'Central user',
'email' => 'central@localhost',
'password' => 'password',
'role' => 'commenter',
'foo' => 'foo',
]);
$centralUser->tenants()->attach($tenant1);
tenancy()->initialize($tenant1);
// Trash the tenant resource a day in the past so that deleting it again would update deleted_at
$this->travelTo(now()->subDay());
TenantUserWithSoftDeletes::firstWhere('global_id', 'user')->delete();
$this->travelBack();
$tenantUserDeletedAt = TenantUserWithSoftDeletes::withTrashed()->firstWhere('global_id', 'user')->deleted_at;
expect($tenantUserDeletedAt)->not()->toBeNull();
// Trashing the central resource doesn't touch already trashed tenant resources
$centralUser->delete();
expect(TenantUserWithSoftDeletes::withTrashed()->firstWhere('global_id', 'user')->deleted_at)->toEqual($tenantUserDeletedAt);
tenancy()->end();
$centralUser->forceDelete();
tenancy()->initialize($tenant1);
expect(TenantUserWithSoftDeletes::withTrashed()->firstWhere('global_id', 'user'))->toBeNull();
});
test('resource creation works correctly when tenant resource provides defaults in the creation attributes', function () { test('resource creation works correctly when tenant resource provides defaults in the creation attributes', function () {
[$tenant1, $tenant2] = createTenantsAndRunMigrations(); [$tenant1, $tenant2] = createTenantsAndRunMigrations();