Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
2 / 2
CRAP
100.00% covered (success)
100.00%
1 / 1
DeleteUserByAdminHandler
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
2 / 2
4
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 handle
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
3
1<?php
2
3declare(strict_types=1);
4
5namespace App\Identity\Application\Command;
6
7use App\Identity\Application\AuthenticatedUserFinder;
8use App\Identity\Application\Port\PreUserDeletion;
9use App\Identity\Domain\Exceptions\AdminSelfAction;
10use App\Identity\Domain\UserRepository;
11use App\Identity\Domain\ValueObject\UserId;
12use Symfony\Component\DependencyInjection\Attribute\AutowireIterator;
13
14final readonly class DeleteUserByAdminHandler
15{
16    /** @param iterable<PreUserDeletion> $preDeletionReactors */
17    public function __construct(
18        private AuthenticatedUserFinder $finder,
19        private UserRepository $users,
20        #[AutowireIterator('app.pre_user_deletion')]
21        private iterable $preDeletionReactors,
22    ) {
23    }
24
25    public function handle(DeleteUserByAdminCommand $command): void
26    {
27        // An admin deletes their own account through /users/me, not the admin API —
28        // blocking it here avoids a surprise self-deletion from the user table.
29        if ($command->callerId === $command->targetId) {
30            throw AdminSelfAction::cannotDeleteSelf();
31        }
32
33        $user = $this->finder->getOrFail(new UserId($command->targetId));
34
35        // Let other contexts react (Trip reassigns shared trips) before the row —
36        // and its FK cascade to trips -> expenses — is removed.
37        foreach ($this->preDeletionReactors as $reactor) {
38            $reactor->onUserDeletion($command->targetId);
39        }
40
41        $this->users->remove($user);
42    }
43}