Passed
Push — master ( 5d2f4a...4ba7a2 )
by Petr
07:39
created

Groups::updateGroup()   B

Complexity

Conditions 6
Paths 110

Size

Total Lines 34
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 21
CRAP Score 6

Importance

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