Groups   A
last analyzed

Complexity

Total Complexity 36

Size/Duplication

Total Lines 280
Duplicated Lines 0 %

Test Coverage

Coverage 98.39%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 141
c 1
b 0
f 0
dl 0
loc 280
ccs 122
cts 124
cp 0.9839
rs 9.52
wmc 36

11 Methods

Rating   Name   Duplication   Size   Complexity  
A getGroupClass() 0 13 1
B updateGroup() 0 34 6
A readGroup() 0 15 3
B createGroup() 0 52 7
A noDirectoryDelimiterSet() 0 3 1
A saveGroups() 0 3 1
A getGroupDataOnly() 0 19 5
B deleteGroup() 0 37 7
A openGroups() 0 3 1
A __construct() 0 15 1
A checkRest() 0 6 3
1
<?php
2
3
namespace kalanis\kw_auth_sources\Sources\Files;
4
5
6
use kalanis\kw_accounts\AccountsException;
7
use kalanis\kw_accounts\Data\FileGroup;
8
use kalanis\kw_accounts\Interfaces as acc_interfaces;
9
use kalanis\kw_auth_sources\AuthSourcesException;
10
use kalanis\kw_auth_sources\Interfaces;
11
use kalanis\kw_auth_sources\Traits;
12
use kalanis\kw_locks\Interfaces\ILock;
13
use kalanis\kw_locks\LockException;
14
15
16
/**
17
 * Class Groups
18
 * @package kalanis\kw_auth_sources\Sources\Files
19
 * Work with groups of users
20
 */
21
class Groups implements acc_interfaces\IProcessGroups
22
{
23
    use Traits\TAuthLock;
24
    use Traits\TLines;
25
    use Traits\TSeparated;
26
    use Traits\TStatusTransform;
27
28
    // default positions
29
    protected const GRP_ID = 0;
30
    protected const GRP_NAME = 1;
31
    protected const GRP_AUTHOR = 2;
32
    protected const GRP_DESC = 3;
33
    protected const GRP_STATUS = 4;
34
    protected const GRP_PARENTS = 5;
35
    protected const GRP_EXTRA = 6;
36
    protected const GRP_FEED = 7;
37
38
    protected Storages\AStorage $storage;
39
    protected acc_interfaces\IProcessAccounts $accounts;
40
    protected Interfaces\IExtraParser $extraParser;
41
    /** @var string[] */
42
    protected array $path = [];
43
44
    /**
45
     * @param Storages\AStorage $storage
46
     * @param acc_interfaces\IProcessAccounts $accounts
47
     * @param Interfaces\IExtraParser $parser
48
     * @param ILock $lock
49
     * @param string[] $path
50
     * @param Interfaces\IKAusTranslations|null $lang
51
     */
52 36
    public function __construct(
53
        Storages\AStorage $storage,
54
        acc_interfaces\IProcessAccounts $accounts,
55
        Interfaces\IExtraParser $parser,
56
        ILock $lock,
57
        array $path,
58
        ?Interfaces\IKAusTranslations $lang = null
59
    )
60
    {
61 36
        $this->setAusLang($lang);
62 36
        $this->initAuthLock($lock);
63 36
        $this->storage = $storage;
64 36
        $this->path = $path;
65 36
        $this->accounts = $accounts;
66 36
        $this->extraParser = $parser;
67 36
    }
68
69 4
    public function createGroup(acc_interfaces\IGroup $group): bool
70
    {
71 4
        $userId = $group->getGroupAuthorId();
72 4
        $groupName = $this->stripChars($group->getGroupName());
73 4
        $groupDesc = $this->stripChars($group->getGroupDesc());
74
75
        // not everything necessary is set
76 4
        if (empty($userId) || empty($groupName)) {
77 1
            throw new AccountsException($this->getAusLang()->kauGroupMissParam());
78
        }
79
80
        try {
81 3
            $this->checkLock();
82
83 2
            $gid = 0;
84 2
            $this->getLock()->create();
85
86
            // read groups
87
            try {
88 2
                $groupLines = $this->openGroups();
89 1
            } catch (AuthSourcesException $ex) {
90
                // silence the problems on storage
91 1
                $groupLines = [];
92
            }
93 2
            foreach ($groupLines as &$line) {
94 1
                $gid = max($gid, $line[static::GRP_ID]);
95
            }
96 2
            $gid++;
97
98
            $newGroup = [
99 2
                static::GRP_ID => $gid,
100 2
                static::GRP_NAME => $groupName,
101 2
                static::GRP_AUTHOR => $userId,
102 2
                static::GRP_DESC => !empty($groupDesc) ? $groupDesc : $groupName,
103 2
                static::GRP_STATUS => $group->getGroupStatus(),
104 2
                static::GRP_PARENTS => $this->compactStr($group->getGroupParents()),
105 2
                static::GRP_EXTRA => $this->extraParser->compact($group->getGroupExtra()),
106 2
                static::GRP_FEED => '',
107
            ];
108 2
            ksort($newGroup);
109 2
            $groupLines[] = $newGroup;
110
111
            try {
112
                // now save it
113 2
                $result = $this->saveGroups($groupLines);
114 2
            } finally {
115 2
                $this->getLock()->delete();
116
            }
117 2
            return $result;
118
119 1
        } catch (AuthSourcesException | LockException $ex) {
120 1
            throw new AccountsException($ex->getMessage(), $ex->getCode(), $ex);
121
        }
122
    }
123
124 3
    public function getGroupDataOnly(string $groupId): ?acc_interfaces\IGroup
125
    {
126
        try {
127 3
            $this->checkLock();
128
            try {
129 2
                $groupLines = $this->openGroups();
130 1
            } catch (AuthSourcesException $ex) {
131
                // silence the problems on storage
132 1
                return null;
133
            }
134 1
            foreach ($groupLines as &$line) {
135 1
                if ($line[static::GRP_ID] == $groupId) {
136 1
                    return $this->getGroupClass($line);
137
                }
138
            }
139 1
            return null;
140
141 1
        } catch (AuthSourcesException | LockException $ex) {
142 1
            throw new AccountsException($ex->getMessage(), $ex->getCode(), $ex);
143
        }
144
    }
145
146 2
    public function readGroup(): array
147
    {
148
        try {
149 2
            $this->checkLock();
150
151 1
            $groupLines = $this->openGroups();
152 1
            $result = [];
153 1
            foreach ($groupLines as &$line) {
154 1
                $result[] = $this->getGroupClass($line);
155
            }
156
157 1
            return $result;
158
159 1
        } catch (AuthSourcesException | LockException $ex) {
160 1
            throw new AccountsException($ex->getMessage(), $ex->getCode(), $ex);
161
        }
162
    }
163
164
    /**
165
     * @param array<int, string> $line
166
     * @throws AuthSourcesException
167
     * @return acc_interfaces\IGroup
168
     */
169 2
    protected function getGroupClass(array &$line): acc_interfaces\IGroup
170
    {
171 2
        $group = new FileGroup();
172 2
        $group->setGroupData(
173 2
            strval($line[static::GRP_ID]),
174 2
            strval($line[static::GRP_NAME]),
175 2
            strval($line[static::GRP_DESC]),
176 2
            strval($line[static::GRP_AUTHOR]),
177 2
            intval($line[static::GRP_STATUS]),
178 2
            $this->separateStr($line[static::GRP_PARENTS]),
179 2
            $this->extraParser->expand($line[static::GRP_EXTRA])
180
        );
181 2
        return $group;
182
    }
183
184 2
    public function updateGroup(acc_interfaces\IGroup $group): bool
185
    {
186 2
        $groupName = $this->stripChars($group->getGroupName());
187 2
        $groupDesc = $this->stripChars($group->getGroupDesc());
188
189
        try {
190 2
            $this->checkLock();
191
192 1
            $this->getLock()->create();
193
            try {
194 1
                $groupLines = $this->openGroups();
195 1
            } finally {
196 1
                $this->getLock()->delete();
197
            }
198 1
            foreach ($groupLines as &$line) {
199 1
                if ($line[static::GRP_ID] == $group->getGroupId()) {
200
                    // REFILL
201 1
                    $line[static::GRP_NAME] = !empty($groupName) ? $groupName : $line[static::GRP_NAME] ;
202 1
                    $line[static::GRP_DESC] = !empty($groupDesc) ? $groupDesc : $line[static::GRP_DESC] ;
203 1
                    $line[static::GRP_STATUS] = $group->getGroupStatus();
204 1
                    $line[static::GRP_PARENTS] = $this->compactStr($group->getGroupParents());
205 1
                    $line[static::GRP_EXTRA] = $this->extraParser->compact($group->getGroupExtra());
206
                }
207
            }
208
209
            try {
210 1
                $result = $this->saveGroups($groupLines);
211 1
            } finally {
212 1
                $this->getLock()->delete();
213
            }
214 1
            return $result;
215
216 1
        } catch (AuthSourcesException | LockException $ex) {
217 1
            throw new AccountsException($ex->getMessage(), $ex->getCode(), $ex);
218
        }
219
    }
220
221 4
    public function deleteGroup(string $groupId): bool
222
    {
223
        try {
224 4
            $this->checkLock();
225 3
            $this->checkRest($groupId);
226
227 2
            $changed = false;
228 2
            $this->getLock()->create();
229
230
            // update groups
231
            try {
232 2
                $openGroups = $this->openGroups();
233 1
            } catch (AuthSourcesException $ex) {
234
                // silence the problems on storage
235 1
                $this->getLock()->delete();
236 1
                return false;
237
            }
238 1
            foreach ($openGroups as $index => &$line) {
239 1
                if ($line[static::GRP_ID] == $groupId) {
240 1
                    unset($openGroups[$index]);
241 1
                    $changed = true;
242
                }
243
            }
244
245 1
            $result = true;
246
            try {
247
                // now save it
248 1
                if ($changed) {
249 1
                    $result = $this->saveGroups($openGroups);
250
                }
251 1
            } finally {
252 1
                $this->getLock()->delete();
253
            }
254 1
            return $changed && $result;
255
256 2
        } catch (AuthSourcesException | LockException $ex) {
257 1
            throw new AccountsException($ex->getMessage(), $ex->getCode(), $ex);
258
        }
259
    }
260
261
    /**
262
     * @param string $groupId
263
     * @throws AccountsException
264
     */
265 3
    protected function checkRest(string $groupId): void
266
    {
267 3
        $passLines = $this->accounts->readAccounts();
268 3
        foreach ($passLines as &$line) {
269 3
            if ($line->getGroup() == $groupId) {
270 1
                throw new AccountsException($this->getAusLang()->kauGroupHasMembers());
271
            }
272
        }
273 2
    }
274
275
    /**
276
     * @throws AuthSourcesException
277
     * @return array<int, array<int, string|int>>
278
     */
279 5
    protected function openGroups(): array
280
    {
281 5
        return $this->storage->read(array_merge($this->path, [Interfaces\IFile::GROUP_FILE]));
282
    }
283
284
    /**
285
     * @param array<int, array<int, string|int>> $lines
286
     * @throws AuthSourcesException
287
     * @return bool
288
     */
289 2
    protected function saveGroups(array $lines): bool
290
    {
291 2
        return $this->storage->write(array_merge($this->path, [Interfaces\IFile::GROUP_FILE]), $lines);
292
    }
293
294
    /**
295
     * @return string
296
     * @codeCoverageIgnore translation
297
     */
298
    protected function noDirectoryDelimiterSet(): string
299
    {
300
        return $this->getAusLang()->kauNoDelimiterSet();
301
    }
302
}
303