• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

lonnieezell / Bonfire2 / 37835748787

08 Oct 2026 07:56PM UTC coverage: 48.83% (+3.7%) from 45.132%
37835748787

push

github

web-flow
refactor(#583): concentrate Users admin access rules in one module (#589)

Add UserAccess (who may touch whom), AvatarStorage (avatar path, store,
delete) and SaveUser (the save orchestration moved out of the HTTP
method). The controller and the form, permissions and table views now
ask UserAccess instead of repeating the rules.

Purging several users now removes every user's avatar and meta, not only
the first. Nobody with users.edit can ban themselves any more, whether
or not they have me.edit. Re-enable testCanEditUser.

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>

100 of 118 new or added lines in 5 files covered. (84.75%)

6 existing lines in 1 file now uncovered.

1732 of 3547 relevant lines covered (48.83%)

14.06 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.15
/src/Users/Models/UserModel.php
1
<?php
2

3
namespace Bonfire\Users\Models;
4

5
use Bonfire\Users\Libraries\AvatarStorage;
6
use Bonfire\Users\User;
7
use CodeIgniter\Shield\Models\UserModel as ShieldUsers;
8
use Faker\Generator;
9

10
/**
11
 * This User model is ready for your customization.
12
 * It extends Shield's UserModel, providing many auth
13
 * features built right in.
14
 */
15
class UserModel extends ShieldUsers
16
{
17
    protected $returnType    = User::class;
18
    protected $allowedFields = [
19
        'username', 'status', 'status_message', 'active', 'last_active', 'deleted_at',
20
        'avatar', 'first_name', 'last_name',
21
    ];
22
    protected $allowCallbacks = true;
23
    protected $beforeDelete   = ['deleteAvatar', 'deleteMeta'];
24

25
    /**
26
     * Performs additional setup when finding objects
27
     * for the recycler. This might pull in additional
28
     * fields.
29
     */
30
    public function setupRecycler()
31
    {
32
        $dbPrefix = $this->db->getPrefix();
1 ✔
33

34
        return $this->select("{$dbPrefix}users.*,
1 ✔
35
            (SELECT secret
36
                from {$dbPrefix}auth_identities
1 ✔
37
                where user_id = {$dbPrefix}users.id
1 ✔
38
                    and type = 'email_password'
39
                order by last_used_at desc
40
                limit 1
41
            ) as email
42
        ");
1 ✔
43
    }
44

45
    public function fake(Generator &$faker): User
46
    {
47
        return new User([
50 ✔
48
            'username'   => $faker->userName(),
50 ✔
49
            'first_name' => $faker->firstName(),
50 ✔
50
            'last_name'  => $faker->lastName(),
50 ✔
51
            'active'     => true,
50 ✔
52
        ]);
50 ✔
53
    }
54

55
    /**
56
     * Event-triggered method to delete user avatars if the users are being purged
57
     * from the system
58
     */
59
    public function deleteAvatar(array $data): array
60
    {
61
        // if it is a soft delete, return at once
62
        if (! $data['purge']) {
6 ✔
63
            return $data;
4 ✔
64
        }
65

66
        $storage = new AvatarStorage();
3 ✔
67

68
        foreach ($this->purgedUsers($data) as $user) {
3 ✔
69
            /** @phpstan-ignore-next-line  TODO: any better way of accessing $avatar on user objet? It works, but phpstan complains */
70
            $storage->delete($user->avatar);
3 ✔
71
        }
72

73
        return $data;
3 ✔
74
    }
75

76
    /**
77
     * Event-triggered method to delete user meta info if the users are being purged
78
     * from the system
79
     */
80
    public function deleteMeta(array $data): array
81
    {
82
        // if it is a soft delete, return at once
83
        if (! $data['purge']) {
6 ✔
84
            return $data;
4 ✔
85
        }
86

87
        foreach ($this->purgedUsers($data) as $user) {
3 ✔
88
            if (! empty($user->allMeta())) {
3 ✔
89
                $user->deleteResourceMeta();
1 ✔
90
            }
91
        }
92

93
        return $data;
3 ✔
94
    }
95

96
    /**
97
     * @return list<User>
98
     */
99
    private function purgedUsers(array $data): array
100
    {
101
        if (empty($data['id'])) {
3 ✔
NEW
102
            return [];
×
103
        }
104

105
        return $this->withDeleted()->find($data['id']);
3 ✔
106
    }
107
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc