Completed
Push — master ( 955b04...f00653 )
by André
38:12 queued 16:07
created

UserHandler::loadRoleAssignmentsByGroupId()   A

Complexity

Conditions 4
Paths 2

Size

Total Lines 31

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
nc 2
nop 2
dl 0
loc 31
rs 9.424
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * File containing a User Handler impl.
5
 *
6
 * @copyright Copyright (C) eZ Systems AS. All rights reserved.
7
 * @license For full copyright and license information view LICENSE file distributed with this source code.
8
 */
9
namespace eZ\Publish\Core\Persistence\Cache;
10
11
use eZ\Publish\Core\Persistence\Cache\InMemory\InMemoryCache;
12
use eZ\Publish\SPI\Persistence\Handler as PersistenceHandler;
13
use eZ\Publish\SPI\Persistence\User\UserTokenUpdateStruct;
14
use eZ\Publish\SPI\Persistence\User\Handler as UserHandlerInterface;
15
use eZ\Publish\SPI\Persistence\User;
16
use eZ\Publish\SPI\Persistence\User\Role;
17
use eZ\Publish\SPI\Persistence\User\RoleAssignment;
18
use eZ\Publish\SPI\Persistence\User\RoleCreateStruct;
19
use eZ\Publish\SPI\Persistence\User\RoleUpdateStruct;
20
use eZ\Publish\SPI\Persistence\User\Policy;
21
use Symfony\Component\Cache\Adapter\TagAwareAdapterInterface;
22
23
/**
24
 * Cache handler for user module.
25
 */
26
class UserHandler extends AbstractInMemoryHandler implements UserHandlerInterface
27
{
28
    /** @var callable */
29
    private $getUserTags;
30
31
    /** @var callable */
32
    private $getUserKeys;
33
34
    /** @var callable */
35
    private $getRoleTags;
36
37
    /** @var callable */
38
    private $getRoleKeys;
39
40
    /** @var callable */
41
    private $getRoleAssignmentTags;
42
43
    /** @var callable */
44
    private $getRoleAssignmentKeys;
45
46
    public function __construct(
47
        TagAwareAdapterInterface $cache,
48
        PersistenceHandler $persistenceHandler,
49
        PersistenceLogger $logger,
50
        InMemoryCache $inMemory
51
    ) {
52
        parent::__construct($cache, $persistenceHandler, $logger, $inMemory);
53
54
        $this->getUserTags = static function (User $user) {
55
            return ['content-' . $user->id, 'user-' . $user->id];
56
        };
57
        $this->getUserKeys = static function (User $user) {
58
            return [
59
                'ez-user-' . $user->id,
60
                'ez-user-' . \str_replace('@', '§', $user->login) . '-by-login',
61
                //'ez-user-' . $hash . '-by-account-key',
62
            ];
63
        };
64
        $this->getRoleTags = static function (Role $role) {
65
            return ['role-' . $role->id];
66
        };
67
        $this->getRoleKeys = static function (Role $role) {
68
            return [
69
                'ez-role-' . $role->id,
70
                'ez-role-' . $role->identifier . '-by-identifier',
71
            ];
72
        };
73
        $this->getRoleAssignmentTags = static function (RoleAssignment $roleAssignment) {
74
            return [
75
                'role-assignment-' . $roleAssignment->id,
76
                'role-assignment-group-list-' . $roleAssignment->contentId,
77
                'role-assignment-role-list-' . $roleAssignment->roleId,
78
            ];
79
        };
80
        $this->getRoleAssignmentKeys = static function (RoleAssignment $roleAssignment) {
81
            return [
82
                'ez-role-assignment-' . $roleAssignment->id,
83
            ];
84
        };
85
    }
86
87
    /**
88
     * {@inheritdoc}
89
     */
90
    public function create(User $user)
91
    {
92
        $this->logger->logCall(__METHOD__, array('struct' => $user));
93
        $return = $this->persistenceHandler->userHandler()->create($user);
94
95
        // Clear corresponding content cache as creation of the User changes it's external data
96
        $this->invalidateCache(['content-fields-' . $user->id]);
97
        $this->deleteCache([
98
            'ez-user-' . $user->id,
99
            'ez-user-' . str_replace('@', '§', $user->login) . '-by-login',
100
            'ez-user-' . str_replace('@', '§', $user->email) . '-by-email',
101
        ]);
102
103
        return $return;
104
    }
105
106
    /**
107
     * {@inheritdoc}
108
     */
109
    public function load($userId)
110
    {
111
        return $this->getCacheValue(
112
            $userId,
113
            'ez-user-',
114
            function ($userId) {
115
                return $this->persistenceHandler->userHandler()->load($userId);
116
            },
117
            $this->getUserTags,
118
            $this->getUserKeys
119
        );
120
    }
121
122
    /**
123
     * {@inheritdoc}
124
     */
125 View Code Duplication
    public function loadByLogin($login)
126
    {
127
        return $this->getCacheValue(
128
            str_replace('@', '§', $login),
129
            'ez-user-',
130
            function ($escapedLogin) use ($login) {
0 ignored issues
show
Unused Code introduced by
The parameter $escapedLogin is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
131
                return $this->persistenceHandler->userHandler()->loadByLogin($login);
132
            },
133
            $this->getUserTags,
134
            $this->getUserKeys,
135
            '-by-login'
136
        );
137
    }
138
139
    /**
140
     * {@inheritdoc}
141
     */
142 View Code Duplication
    public function loadByEmail($email)
143
    {
144
        // As load by email can return several items we threat it like a list here.
145
        return $this->getListCacheValue(
146
            'ez-user-' . str_replace('@', '§', $email) . '-by-email',
147
            function () use ($email) {
148
                return $this->persistenceHandler->userHandler()->loadByEmail($email);
149
            },
150
            $this->getUserTags,
151
            $this->getUserKeys
152
        );
153
    }
154
155
    /**
156
     * {@inheritdoc}
157
     */
158
    public function loadUserByToken($hash)
159
    {
160
        $getUserKeysFn = $this->getUserKeys;
161
        $getUserTagsFn = $this->getUserTags;
162
163
        return $this->getCacheValue(
164
            $hash,
165
            'ez-user-',
166
            function ($hash) {
167
                return $this->persistenceHandler->userHandler()->loadUserByToken($hash);
168
            },
169
            static function (User $user) use ($getUserTagsFn) {
170
                $tags = $getUserTagsFn($user);
171
                // See updateUserToken()
172
                $tags[] = 'user-' . $user->id . '-account-key';
173
174
                return $tags;
175
            },
176
            static function (User $user) use ($hash, $getUserKeysFn) {
177
                $keys = $getUserKeysFn($user);
178
                $keys[] = 'ez-user-' . $hash . '-by-account-key';
179
180
                return $keys;
181
            },
182
            '-by-account-key'
183
        );
184
    }
185
186
    /**
187
     * {@inheritdoc}
188
     */
189 View Code Duplication
    public function update(User $user)
190
    {
191
        $this->logger->logCall(__METHOD__, array('struct' => $user));
192
        $return = $this->persistenceHandler->userHandler()->update($user);
193
194
        // Clear corresponding content cache as update of the User changes it's external data
195
        $this->invalidateCache(['content-fields-' . $user->id, 'user-' . $user->id]);
196
197
        return $return;
198
    }
199
200
    /**
201
     * {@inheritdoc}
202
     */
203
    public function updateUserToken(UserTokenUpdateStruct $userTokenUpdateStruct)
204
    {
205
        $this->logger->logCall(__METHOD__, array('struct' => $userTokenUpdateStruct));
206
        $return = $this->persistenceHandler->userHandler()->updateUserToken($userTokenUpdateStruct);
207
208
        // As we 1. don't know original hash, and 2. hash is not guaranteed to be unique, we do it like this for now
209
        $this->invalidateCache(['user-' . $userTokenUpdateStruct->userId . '-account-key']);
210
        $this->deleteCache(['ez-user-' . $userTokenUpdateStruct->hashKey . '-by-account-key']);
211
212
        return $return;
213
    }
214
215
    /**
216
     * {@inheritdoc}
217
     */
218
    public function expireUserToken($hash)
219
    {
220
        $this->logger->logCall(__METHOD__, array('hash' => $hash));
221
        $return = $this->persistenceHandler->userHandler()->expireUserToken($hash);
222
        $this->deleteCache(['ez-user-' . $hash . '-by-account-key']);
223
224
        return $return;
225
    }
226
227
    /**
228
     * {@inheritdoc}
229
     */
230
    public function delete($userId)
231
    {
232
        $this->logger->logCall(__METHOD__, array('user' => $userId));
233
        $return = $this->persistenceHandler->userHandler()->delete($userId);
234
235
        // user id == content id == group id
236
        $this->invalidateCache(['content-fields-' . $userId, 'user-' . $userId]);
237
238
        return $return;
239
    }
240
241
    /**
242
     * {@inheritdoc}
243
     */
244
    public function createRole(RoleCreateStruct $createStruct)
245
    {
246
        $this->logger->logCall(__METHOD__, array('struct' => $createStruct));
247
248
        return $this->persistenceHandler->userHandler()->createRole($createStruct);
249
    }
250
251
    /**
252
     * {@inheritdoc}
253
     */
254
    public function createRoleDraft($roleId)
255
    {
256
        $this->logger->logCall(__METHOD__, array('role' => $roleId));
257
258
        return $this->persistenceHandler->userHandler()->createRoleDraft($roleId);
259
    }
260
261
    /**
262
     * {@inheritdoc}
263
     */
264 View Code Duplication
    public function loadRole($roleId, $status = Role::STATUS_DEFINED)
265
    {
266
        if ($status !== Role::STATUS_DEFINED) {
267
            $this->logger->logCall(__METHOD__, array('role' => $roleId));
268
269
            return $this->persistenceHandler->userHandler()->loadRole($roleId, $status);
270
        }
271
272
        return $this->getCacheValue(
273
            $roleId,
274
            'ez-role-',
275
            function ($roleId) {
276
                return $this->persistenceHandler->userHandler()->loadRole($roleId);
277
            },
278
            $this->getRoleTags,
279
            $this->getRoleKeys
280
        );
281
    }
282
283
    /**
284
     * {@inheritdoc}
285
     */
286 View Code Duplication
    public function loadRoleByIdentifier($identifier, $status = Role::STATUS_DEFINED)
287
    {
288
        if ($status !== Role::STATUS_DEFINED) {
289
            $this->logger->logCall(__METHOD__, array('role' => $identifier));
290
291
            return $this->persistenceHandler->userHandler()->loadRoleByIdentifier($identifier, $status);
292
        }
293
294
        return $this->getCacheValue(
295
            $identifier,
296
            'ez-role-',
297
            function ($identifier) {
298
                return $this->persistenceHandler->userHandler()->loadRoleByIdentifier($identifier);
299
            },
300
            $this->getRoleTags,
301
            $this->getRoleKeys,
302
            '-by-identifier'
303
        );
304
    }
305
306
    /**
307
     * {@inheritdoc}
308
     */
309
    public function loadRoleDraftByRoleId($roleId)
310
    {
311
        $this->logger->logCall(__METHOD__, array('role' => $roleId));
312
313
        return $this->persistenceHandler->userHandler()->loadRoleDraftByRoleId($roleId);
314
    }
315
316
    /**
317
     * {@inheritdoc}
318
     */
319
    public function loadRoles()
320
    {
321
        $this->logger->logCall(__METHOD__);
322
323
        return $this->persistenceHandler->userHandler()->loadRoles();
324
    }
325
326
    /**
327
     * {@inheritdoc}
328
     */
329
    public function loadRoleAssignment($roleAssignmentId)
330
    {
331
        return $this->getCacheValue(
332
            $roleAssignmentId,
333
            'ez-role-assignment-',
334
            function ($roleAssignmentId) {
335
                return $this->persistenceHandler->userHandler()->loadRoleAssignment($roleAssignmentId);
336
            },
337
            $this->getRoleAssignmentTags,
338
            $this->getRoleAssignmentKeys
339
        );
340
    }
341
342
    /**
343
     * {@inheritdoc}
344
     */
345
    public function loadRoleAssignmentsByRoleId($roleId)
346
    {
347
        return $this->getListCacheValue(
348
            "ez-role-assignment-${roleId}-by-role",
349
            function () use ($roleId) {
350
                return $this->persistenceHandler->userHandler()->loadRoleAssignmentsByRoleId($roleId);
351
            },
352
            $this->getRoleAssignmentTags,
353
            $this->getRoleAssignmentKeys,
354
            /* Role update (policies) changes role assignment id */
355
            static function () use ($roleId) { return ['role-' . $roleId]; },
356
            [$roleId]
357
        );
358
    }
359
360
    /**
361
     * {@inheritdoc}
362
     */
363
    public function loadRoleAssignmentsByGroupId($groupId, $inherit = false)
364
    {
365
        $innerHandler = $this->persistenceHandler;
366
        if ($inherit) {
367
            $key = "ez-role-assignment-${groupId}-by-group-inherited";
368
        } else {
369
            $key = "ez-role-assignment-${groupId}-by-group";
370
        }
371
372
        return $this->getListCacheValue(
373
            $key,
374
            function () use ($groupId, $inherit) {
375
                return $this->persistenceHandler->userHandler()->loadRoleAssignmentsByGroupId($groupId, $inherit);
376
            },
377
            $this->getRoleAssignmentTags,
378
            $this->getRoleAssignmentKeys,
379
            static function () use ($groupId, $innerHandler) {
380
                // To make sure tree operations affecting this can clear the permission cache
381
                $cacheTags = [];
382
                $locations = $innerHandler->locationHandler()->loadLocationsByContent($groupId);
383
                foreach ($locations as $location) {
384
                    foreach (explode('/', trim($location->pathString, '/')) as $pathId) {
385
                        $cacheTags[] = 'location-path-' . $pathId;
386
                    }
387
                }
388
389
                return $cacheTags;
390
            },
391
            [$groupId, $inherit]
392
        );
393
    }
394
395
    /**
396
     * {@inheritdoc}
397
     */
398
    public function updateRole(RoleUpdateStruct $struct)
399
    {
400
        $this->logger->logCall(__METHOD__, array('struct' => $struct));
401
        $this->persistenceHandler->userHandler()->updateRole($struct);
402
403
        $this->invalidateCache(['role-' . $struct->id]);
404
    }
405
406
    /**
407
     * {@inheritdoc}
408
     */
409
    public function deleteRole($roleId, $status = Role::STATUS_DEFINED)
410
    {
411
        $this->logger->logCall(__METHOD__, array('role' => $roleId));
412
        $return = $this->persistenceHandler->userHandler()->deleteRole($roleId, $status);
413
414
        if ($status === Role::STATUS_DEFINED) {
415
            $this->invalidateCache(['role-' . $roleId, 'role-assignment-role-list-' . $roleId]);
416
        }
417
418
        return $return;
419
    }
420
421
    /**
422
     * {@inheritdoc}
423
     */
424
    public function publishRoleDraft($roleDraftId)
425
    {
426
        $this->logger->logCall(__METHOD__, array('role' => $roleDraftId));
427
        $userHandler = $this->persistenceHandler->userHandler();
428
        $roleDraft = $userHandler->loadRole($roleDraftId, Role::STATUS_DRAFT);
429
        $return = $userHandler->publishRoleDraft($roleDraftId);
430
431
        // If there was a original role for the draft, then we clean cache for it
432
        if ($roleDraft->originalId > -1) {
433
            $this->invalidateCache(['role-' . $roleDraft->originalId]);
434
        }
435
436
        return $return;
437
    }
438
439
    /**
440
     * {@inheritdoc}
441
     */
442
    public function addPolicyByRoleDraft($roleId, Policy $policy)
443
    {
444
        $this->logger->logCall(__METHOD__, array('role' => $roleId, 'struct' => $policy));
445
446
        return $this->persistenceHandler->userHandler()->addPolicyByRoleDraft($roleId, $policy);
447
    }
448
449
    /**
450
     * {@inheritdoc}
451
     */
452
    public function addPolicy($roleId, Policy $policy)
453
    {
454
        $this->logger->logCall(__METHOD__, array('role' => $roleId, 'struct' => $policy));
455
        $return = $this->persistenceHandler->userHandler()->addPolicy($roleId, $policy);
456
457
        $this->invalidateCache(['role-' . $roleId]);
458
459
        return $return;
460
    }
461
462
    /**
463
     * {@inheritdoc}
464
     */
465 View Code Duplication
    public function updatePolicy(Policy $policy)
466
    {
467
        $this->logger->logCall(__METHOD__, array('struct' => $policy));
468
        $return = $this->persistenceHandler->userHandler()->updatePolicy($policy);
469
470
        $this->invalidateCache(['policy-' . $policy->id, 'role-' . $policy->roleId]);
471
472
        return $return;
473
    }
474
475
    /**
476
     * {@inheritdoc}
477
     */
478
    public function deletePolicy($policyId, $roleId)
479
    {
480
        $this->logger->logCall(__METHOD__, array('policy' => $policyId));
481
        $this->persistenceHandler->userHandler()->deletePolicy($policyId, $roleId);
482
483
        $this->invalidateCache(['policy-' . $policyId, 'role-' . $roleId]);
484
    }
485
486
    /**
487
     * {@inheritdoc}
488
     */
489
    public function loadPoliciesByUserId($userId)
490
    {
491
        $this->logger->logCall(__METHOD__, array('user' => $userId));
492
493
        return $this->persistenceHandler->userHandler()->loadPoliciesByUserId($userId);
0 ignored issues
show
Deprecated Code introduced by
The method eZ\Publish\SPI\Persisten...:loadPoliciesByUserId() has been deprecated with message: Since 6.8, not currently in use as permission system needs to know about role assignment limitations.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
494
    }
495
496
    /**
497
     * {@inheritdoc}
498
     */
499
    public function assignRole($contentId, $roleId, array $limitation = null)
500
    {
501
        $this->logger->logCall(__METHOD__, array('group' => $contentId, 'role' => $roleId, 'limitation' => $limitation));
502
        $return = $this->persistenceHandler->userHandler()->assignRole($contentId, $roleId, $limitation);
503
504
        $tags = ['role-assignment-group-list-' . $contentId, 'role-assignment-role-list-' . $roleId];
505
        $locations = $this->persistenceHandler->locationHandler()->loadLocationsByContent($contentId);
506
        foreach ($locations as $location) {
507
            $tags[] = 'location-path-' . $location->id;
508
        }
509
510
        $this->invalidateCache($tags);
511
512
        return $return;
513
    }
514
515
    /**
516
     * {@inheritdoc}
517
     */
518 View Code Duplication
    public function unassignRole($contentId, $roleId)
519
    {
520
        $this->logger->logCall(__METHOD__, array('group' => $contentId, 'role' => $roleId));
521
        $return = $this->persistenceHandler->userHandler()->unassignRole($contentId, $roleId);
522
523
        $this->invalidateCache(['role-assignment-group-list-' . $contentId, 'role-assignment-role-list-' . $roleId]);
524
525
        return $return;
526
    }
527
528
    /**
529
     * {@inheritdoc}
530
     */
531
    public function removeRoleAssignment($roleAssignmentId)
532
    {
533
        $this->logger->logCall(__METHOD__, array('assignment' => $roleAssignmentId));
534
        $return = $this->persistenceHandler->userHandler()->removeRoleAssignment($roleAssignmentId);
535
536
        $this->invalidateCache(['role-assignment-' . $roleAssignmentId]);
537
538
        return $return;
539
    }
540
}
541