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

daycry / auth / 25518434194

07 May 2026 07:49PM UTC coverage: 58.608% (-6.4%) from 64.989%
25518434194

push

github

web-flow
Merge pull request #47 from daycry/development

Implement security enhancements and new account features

277 of 1030 new or added lines in 55 files covered. (26.89%)

11 existing lines in 6 files now uncovered.

3544 of 6047 relevant lines covered (58.61%)

47.97 hits per line

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

0.0
/src/Controllers/Admin/GroupsController.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\Group;
18
use Daycry\Auth\Models\GroupModel;
19
use Daycry\Auth\Models\GroupUserModel;
20
use Daycry\Auth\Models\PermissionGroupModel;
21
use Daycry\Auth\Models\PermissionModel;
22

23
/**
24
 * Admin Groups Controller — CRUD for groups (roles).
25
 */
26
class GroupsController extends BaseAdminController
27
{
28
    /**
29
     * List all groups with member counts.
30
     */
31
    public function index(): string
×
32
    {
33
        /** @var GroupModel $groupModel */
34
        $groupModel = model(GroupModel::class);
×
35

36
        /** @var GroupUserModel $groupUserModel */
37
        $groupUserModel = model(GroupUserModel::class);
×
38

39
        $groups = $groupModel->orderBy('name')->findAll();
×
40

41
        // Attach member counts using group_id
42
        $counts = [];
×
43

44
        foreach ($groups as $group) {
×
45
            $counts[$group->id] = $groupUserModel->where('group_id', $group->id)->countAllResults();
×
46
        }
47

48
        return $this->view('Daycry\\Auth\\Views\\admin\\groups\\index', [
×
49
            'groups' => $groups,
×
50
            'counts' => $counts,
×
51
        ]);
×
52
    }
53

54
    /**
55
     * Show the create-group form.
56
     */
57
    public function create(): string
×
58
    {
59
        /** @var PermissionModel $permissionModel */
60
        $permissionModel = model(PermissionModel::class);
×
61

62
        return $this->view('Daycry\\Auth\\Views\\admin\\groups\\form', [
×
63
            'group'    => null,
×
64
            'allPerms' => $permissionModel->findAll(),
×
65
            'assigned' => [],
×
66
        ]);
×
67
    }
68

69
    /**
70
     * Persist a new group.
71
     */
72
    public function store(): RedirectResponse
×
73
    {
74
        /** @var GroupModel $groupModel */
75
        $groupModel = model(GroupModel::class);
×
76

77
        $name        = trim((string) $this->request->getPost('name'));
×
78
        $description = trim((string) $this->request->getPost('description'));
×
79

80
        if ($name === '') {
×
81
            return redirect()->route('admin-group-create')->with('error', 'Group name is required.');
×
82
        }
83

84
        $group              = new Group();
×
85
        $group->name        = $name;
×
86
        $group->description = $description !== '' ? $description : null;
×
87

88
        if (! $groupModel->save($group)) {
×
89
            return redirect()->route('admin-group-create')
×
90
                ->with('errors', $groupModel->errors());
×
91
        }
92

93
        return redirect()->route('admin-groups')
×
94
            ->with('message', "Group \"{$name}\" created.");
×
95
    }
96

97
    /**
98
     * Show the edit form for an existing group.
99
     *
100
     * @param int|string $id
101
     */
102
    public function edit($id): RedirectResponse|string
×
103
    {
104
        $group = $this->findGroupOr404((int) $id);
×
105

106
        if ($group instanceof RedirectResponse) {
×
107
            return $group;
×
108
        }
109

110
        /** @var PermissionModel $permissionModel */
111
        $permissionModel = model(PermissionModel::class);
×
112

113
        /** @var PermissionGroupModel $pgModel */
114
        $pgModel = model(PermissionGroupModel::class);
×
115

116
        // Collect IDs of permissions already assigned to this group
117
        $assigned = array_column(
×
118
            $pgModel->where('group_id', $group->id)->findAll(),
×
119
            'permission_id',
×
120
        );
×
121

122
        return $this->view('Daycry\\Auth\\Views\\admin\\groups\\form', [
×
123
            'group'    => $group,
×
124
            'allPerms' => $permissionModel->findAll(),
×
125
            'assigned' => $assigned,
×
126
        ]);
×
127
    }
128

129
    /**
130
     * Persist edits to an existing group.
131
     *
132
     * @param int|string $id
133
     */
134
    public function update($id): RedirectResponse
×
135
    {
136
        $group = $this->findGroupOr404((int) $id);
×
137

138
        if ($group instanceof RedirectResponse) {
×
139
            return $group;
×
140
        }
141

142
        /** @var GroupModel $groupModel */
143
        $groupModel = model(GroupModel::class);
×
144

145
        $description = trim((string) $this->request->getPost('description'));
×
146

147
        $group->description = $description !== '' ? $description : null;
×
148
        $groupModel->save($group);
×
149

150
        // Sync permissions for the group via PermissionGroupModel
151
        /** @var PermissionGroupModel $pgModel */
152
        $pgModel = model(PermissionGroupModel::class);
×
153

154
        // The form sends permission IDs (from the checkbox values)
NEW
155
        $newPermIds = array_filter(array_map(intval(...), (array) $this->request->getPost('permissions')));
×
156

157
        $pgModel->deleteAll($group->id);
×
158

159
        if ($newPermIds !== []) {
×
160
            $inserts = [];
×
161

162
            foreach ($newPermIds as $permId) {
×
163
                $inserts[] = ['group_id' => $group->id, 'permission_id' => $permId];
×
164
            }
165

166
            $pgModel->insertBatch($inserts);
×
167
        }
168

169
        return redirect()->route('admin-groups')
×
170
            ->with('message', "Group \"{$group->name}\" updated.");
×
171
    }
172

173
    /**
174
     * Delete a group.
175
     *
176
     * @param int|string $id
177
     */
178
    public function delete($id): RedirectResponse
×
179
    {
180
        $group = $this->findGroupOr404((int) $id);
×
181

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

186
        /** @var GroupModel $groupModel */
187
        $groupModel = model(GroupModel::class);
×
188
        $groupModel->delete($group->id, true);
×
189

190
        return redirect()->route('admin-groups')
×
191
            ->with('message', "Group \"{$group->name}\" deleted.");
×
192
    }
193

194
    // ── Private helpers ───────────────────────────────────────────
195

196
    private function findGroupOr404(int $id): Group|RedirectResponse
×
197
    {
198
        /** @var GroupModel $groupModel */
199
        $groupModel = model(GroupModel::class);
×
200
        $group      = $groupModel->find($id);
×
201

202
        if ($group === null) {
×
203
            return redirect()->route('admin-groups')->with('error', 'Group not found.');
×
204
        }
205

206
        return $group;
×
207
    }
208
}
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