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

daycry / auth / 22527357078

28 Feb 2026 07:22PM UTC coverage: 63.267% (+0.7%) from 62.568%
22527357078

push

github

daycry
Remove PHP 8.1 from PHPUnit CI matrix

Update .github/workflows/phpunit.yml to drop PHP 8.1 from the test matrix. CI will now run PHPUnit only on PHP 8.2 and 8.3, reducing the matrix to current supported versions.

3064 of 4843 relevant lines covered (63.27%)

41.52 hits per line

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

0.0
/src/Controllers/Admin/UsersController.php
1
<?php
2

3
declare(strict_types=1);
4

5
/**
6
 * This file is part of Daycry Auth.
7
 *
8
 * (c) Daycry <daycry9@proton.me>
9
 *
10
 * For the full copyright and license information, please view
11
 * the LICENSE file that was distributed with this source code.
12
 */
13

14
namespace Daycry\Auth\Controllers\Admin;
15

16
use CodeIgniter\HTTP\RedirectResponse;
17
use Daycry\Auth\Entities\User;
18
use Daycry\Auth\Exceptions\AuthorizationException;
19
use Daycry\Auth\Models\DeviceSessionModel;
20
use Daycry\Auth\Models\GroupModel;
21
use Daycry\Auth\Models\PermissionModel;
22
use Daycry\Auth\Models\UserModel;
23

24
/**
25
 * Admin Users Controller — full CRUD for user accounts.
26
 */
27
class UsersController extends BaseAdminController
28
{
29
    /**
30
     * Paginated list of users with optional keyword search.
31
     */
32
    public function index(): string
×
33
    {
34
        /** @var UserModel $userModel */
35
        $userModel = model(UserModel::class);
×
36

37
        $search = (string) $this->request->getGet('q');
×
38

39
        if ($search !== '') {
×
40
            $userModel->groupStart()
×
41
                ->like('username', $search)
×
42
                ->orLike('status', $search)
×
43
                ->groupEnd();
×
44
        }
45

46
        $users = $userModel
×
47
            ->orderBy('id', 'DESC')
×
48
            ->paginate(20, 'default');
×
49

50
        return $this->view('Daycry\\Auth\\Views\\admin\\users\\index', [
×
51
            'users'  => $users,
×
52
            'pager'  => $userModel->pager,
×
53
            'search' => $search,
×
54
        ]);
×
55
    }
56

57
    /**
58
     * Show a single user's detail: info, groups, permissions, device sessions.
59
     *
60
     * @param int|string $id
61
     */
62
    public function show($id): RedirectResponse|string
×
63
    {
64
        $user = $this->findUserOr404((int) $id);
×
65

66
        if ($user instanceof RedirectResponse) {
×
67
            return $user;
×
68
        }
69

70
        /** @var DeviceSessionModel $deviceModel */
71
        $deviceModel = model(DeviceSessionModel::class);
×
72

73
        return $this->view('Daycry\\Auth\\Views\\admin\\users\\show', [
×
74
            'user'     => $user,
×
75
            'sessions' => $deviceModel->getAllForUser($user),
×
76
        ]);
×
77
    }
78

79
    /**
80
     * Show the edit form for a user.
81
     *
82
     * @param int|string $id
83
     */
84
    public function edit($id): RedirectResponse|string
×
85
    {
86
        $user = $this->findUserOr404((int) $id);
×
87

88
        if ($user instanceof RedirectResponse) {
×
89
            return $user;
×
90
        }
91

92
        /** @var GroupModel $groupModel */
93
        $groupModel = model(GroupModel::class);
×
94

95
        /** @var PermissionModel $permissionModel */
96
        $permissionModel = model(PermissionModel::class);
×
97

98
        return $this->view('Daycry\\Auth\\Views\\admin\\users\\edit', [
×
99
            'user'      => $user,
×
100
            'allGroups' => $groupModel->findAll(),
×
101
            'allPerms'  => $permissionModel->findAll(),
×
102
        ]);
×
103
    }
104

105
    /**
106
     * Process the edit form.
107
     *
108
     * @param int|string $id
109
     */
110
    public function update($id): RedirectResponse
×
111
    {
112
        $user = $this->findUserOr404((int) $id);
×
113

114
        if ($user instanceof RedirectResponse) {
×
115
            return $user;
×
116
        }
117

118
        /** @var UserModel $userModel */
119
        $userModel = model(UserModel::class);
×
120

121
        $username = trim((string) $this->request->getPost('username'));
×
122
        $email    = trim((string) $this->request->getPost('email'));
×
123
        $active   = (bool) $this->request->getPost('active');
×
124

125
        if ($username !== '') {
×
126
            $user->username = $username;
×
127
        }
128

129
        if ($email !== '') {
×
130
            $user->email = $email;
×
131
        }
132

133
        $user->active = $active;
×
134

135
        $userModel->save($user);
×
136

137
        try {
138
            // Sync groups
139
            $newGroups = array_filter((array) $this->request->getPost('groups'));
×
140
            $user->syncGroups(...$newGroups);
×
141

142
            // Sync permissions
143
            $newPerms = array_filter((array) $this->request->getPost('permissions'));
×
144
            $user->syncPermissions(...$newPerms);
×
145
        } catch (AuthorizationException $e) {
×
146
            return redirect()->route('admin-user-edit', [$id])
×
147
                ->with('error', $e->getMessage());
×
148
        }
149

150
        return redirect()->route('admin-user-show', [$id])
×
151
            ->with('message', 'User updated successfully.');
×
152
    }
153

154
    /**
155
     * Ban a user.
156
     *
157
     * @param int|string $id
158
     */
159
    public function ban($id): RedirectResponse
×
160
    {
161
        $user = $this->findUserOr404((int) $id);
×
162

163
        if ($user instanceof RedirectResponse) {
×
164
            return $user;
×
165
        }
166

167
        $user->ban((string) $this->request->getPost('reason'));
×
168

169
        return redirect()->route('admin-user-show', [$id])
×
170
            ->with('message', 'User has been banned.');
×
171
    }
172

173
    /**
174
     * Remove ban from a user.
175
     *
176
     * @param int|string $id
177
     */
178
    public function unban($id): RedirectResponse
×
179
    {
180
        $user = $this->findUserOr404((int) $id);
×
181

182
        if ($user instanceof RedirectResponse) {
×
183
            return $user;
×
184
        }
185

186
        $user->unBan();
×
187

188
        return redirect()->route('admin-user-show', [$id])
×
189
            ->with('message', 'User has been unbanned.');
×
190
    }
191

192
    /**
193
     * Manually activate a user.
194
     *
195
     * @param int|string $id
196
     */
197
    public function activate($id): RedirectResponse
×
198
    {
199
        $user = $this->findUserOr404((int) $id);
×
200

201
        if ($user instanceof RedirectResponse) {
×
202
            return $user;
×
203
        }
204

205
        /** @var UserModel $userModel */
206
        $userModel = model(UserModel::class);
×
207
        $userModel->activate($user);
×
208

209
        return redirect()->route('admin-user-show', [$id])
×
210
            ->with('message', 'User has been activated.');
×
211
    }
212

213
    /**
214
     * Delete a user (hard delete).
215
     *
216
     * @param int|string $id
217
     */
218
    public function delete($id): RedirectResponse
×
219
    {
220
        $user = $this->findUserOr404((int) $id);
×
221

222
        if ($user instanceof RedirectResponse) {
×
223
            return $user;
×
224
        }
225

226
        /** @var UserModel $userModel */
227
        $userModel = model(UserModel::class);
×
228
        $userModel->delete($user->id, true);
×
229

230
        return redirect()->route('admin-users')
×
231
            ->with('message', 'User deleted permanently.');
×
232
    }
233

234
    // ── Private helpers ───────────────────────────────────────────
235

236
    /**
237
     * Find a user by ID or redirect with error.
238
     */
239
    private function findUserOr404(int $id): RedirectResponse|User
×
240
    {
241
        /** @var UserModel $userModel */
242
        $userModel = model(UserModel::class);
×
243
        $user      = $userModel->withIdentities()->findById($id);
×
244

245
        if ($user === null) {
×
246
            return redirect()->route('admin-users')->with('error', 'User not found.');
×
247
        }
248

249
        return $user;
×
250
    }
251
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc