Completed
Push — ezp-30229-alternative ( 33cbfb...37c73f )
by
unknown
26:25
created

UserHandler   A

Complexity

Total Complexity 38

Size/Duplication

Total Lines 518
Duplicated Lines 17.37 %

Coupling/Cohesion

Components 1
Dependencies 12

Importance

Changes 0
Metric Value
dl 90
loc 518
rs 9.36
c 0
b 0
f 0
wmc 38
lcom 1
cbo 12

30 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 40 1
A create() 0 15 1
A load() 0 12 1
A loadByLogin() 13 13 1
A loadByEmail() 12 12 1
A loadUserByToken() 0 27 1
A update() 10 10 1
A expireUserToken() 0 8 1
A delete() 0 10 1
A createRole() 0 6 1
A createRoleDraft() 0 6 1
A loadRole() 18 18 2
A loadRoleByIdentifier() 19 19 2
A loadRoleDraftByRoleId() 0 6 1
A loadRoles() 0 6 1
A loadRoleAssignment() 0 12 1
A updateUserToken() 0 11 1
A loadRoleAssignmentsByRoleId() 0 16 1
A loadRoleAssignmentsByGroupId() 0 32 4
A updateRole() 0 7 1
A deleteRole() 0 11 2
A publishRoleDraft() 0 14 2
A addPolicyByRoleDraft() 0 6 1
A addPolicy() 0 9 1
A updatePolicy() 9 9 1
A deletePolicy() 0 7 1
A loadPoliciesByUserId() 0 6 1
A assignRole() 0 15 2
A unassignRole() 9 9 1
A removeRoleAssignment() 0 9 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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, also need list tag in case of empty result */
355
            static function () use ($roleId) {
356
                return ['role-assignment-role-list-' . $roleId, 'role-' . $roleId];
357
            },
358
            [$roleId]
359
        );
360
    }
361
362
    /**
363
     * {@inheritdoc}
364
     */
365
    public function loadRoleAssignmentsByGroupId($groupId, $inherit = false)
366
    {
367
        $innerHandler = $this->persistenceHandler;
368
        if ($inherit) {
369
            $key = "ez-role-assignment-${groupId}-by-group-inherited";
370
        } else {
371
            $key = "ez-role-assignment-${groupId}-by-group";
372
        }
373
374
        return $this->getListCacheValue(
375
            $key,
376
            function () use ($groupId, $inherit) {
377
                return $this->persistenceHandler->userHandler()->loadRoleAssignmentsByGroupId($groupId, $inherit);
378
            },
379
            $this->getRoleAssignmentTags,
380
            $this->getRoleAssignmentKeys,
381
            static function () use ($groupId, $innerHandler) {
382
                // Tag needed for empty results, if not empty will alse be added by getRoleAssignmentTags().
383
                $cacheTags = ['role-assignment-group-list-' . $groupId];
384
                // To make sure tree operations affecting this can clear the permission cache
385
                $locations = $innerHandler->locationHandler()->loadLocationsByContent($groupId);
386
                foreach ($locations as $location) {
387
                    foreach (explode('/', trim($location->pathString, '/')) as $pathId) {
388
                        $cacheTags[] = 'location-path-' . $pathId;
389
                    }
390
                }
391
392
                return $cacheTags;
393
            },
394
            [$groupId, $inherit]
395
        );
396
    }
397
398
    /**
399
     * {@inheritdoc}
400
     */
401
    public function updateRole(RoleUpdateStruct $struct)
402
    {
403
        $this->logger->logCall(__METHOD__, array('struct' => $struct));
404
        $this->persistenceHandler->userHandler()->updateRole($struct);
405
406
        $this->invalidateCache(['role-' . $struct->id]);
407
    }
408
409
    /**
410
     * {@inheritdoc}
411
     */
412
    public function deleteRole($roleId, $status = Role::STATUS_DEFINED)
413
    {
414
        $this->logger->logCall(__METHOD__, array('role' => $roleId));
415
        $return = $this->persistenceHandler->userHandler()->deleteRole($roleId, $status);
416
417
        if ($status === Role::STATUS_DEFINED) {
418
            $this->invalidateCache(['role-' . $roleId, 'role-assignment-role-list-' . $roleId]);
419
        }
420
421
        return $return;
422
    }
423
424
    /**
425
     * {@inheritdoc}
426
     */
427
    public function publishRoleDraft($roleDraftId)
428
    {
429
        $this->logger->logCall(__METHOD__, array('role' => $roleDraftId));
430
        $userHandler = $this->persistenceHandler->userHandler();
431
        $roleDraft = $userHandler->loadRole($roleDraftId, Role::STATUS_DRAFT);
432
        $return = $userHandler->publishRoleDraft($roleDraftId);
433
434
        // If there was a original role for the draft, then we clean cache for it
435
        if ($roleDraft->originalId > -1) {
436
            $this->invalidateCache(['role-' . $roleDraft->originalId]);
437
        }
438
439
        return $return;
440
    }
441
442
    /**
443
     * {@inheritdoc}
444
     */
445
    public function addPolicyByRoleDraft($roleId, Policy $policy)
446
    {
447
        $this->logger->logCall(__METHOD__, array('role' => $roleId, 'struct' => $policy));
448
449
        return $this->persistenceHandler->userHandler()->addPolicyByRoleDraft($roleId, $policy);
450
    }
451
452
    /**
453
     * {@inheritdoc}
454
     */
455
    public function addPolicy($roleId, Policy $policy)
456
    {
457
        $this->logger->logCall(__METHOD__, array('role' => $roleId, 'struct' => $policy));
458
        $return = $this->persistenceHandler->userHandler()->addPolicy($roleId, $policy);
459
460
        $this->invalidateCache(['role-' . $roleId]);
461
462
        return $return;
463
    }
464
465
    /**
466
     * {@inheritdoc}
467
     */
468 View Code Duplication
    public function updatePolicy(Policy $policy)
469
    {
470
        $this->logger->logCall(__METHOD__, array('struct' => $policy));
471
        $return = $this->persistenceHandler->userHandler()->updatePolicy($policy);
472
473
        $this->invalidateCache(['policy-' . $policy->id, 'role-' . $policy->roleId]);
474
475
        return $return;
476
    }
477
478
    /**
479
     * {@inheritdoc}
480
     */
481
    public function deletePolicy($policyId, $roleId)
482
    {
483
        $this->logger->logCall(__METHOD__, array('policy' => $policyId));
484
        $this->persistenceHandler->userHandler()->deletePolicy($policyId, $roleId);
485
486
        $this->invalidateCache(['policy-' . $policyId, 'role-' . $roleId]);
487
    }
488
489
    /**
490
     * {@inheritdoc}
491
     */
492
    public function loadPoliciesByUserId($userId)
493
    {
494
        $this->logger->logCall(__METHOD__, array('user' => $userId));
495
496
        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...
497
    }
498
499
    /**
500
     * {@inheritdoc}
501
     */
502
    public function assignRole($contentId, $roleId, array $limitation = null)
503
    {
504
        $this->logger->logCall(__METHOD__, array('group' => $contentId, 'role' => $roleId, 'limitation' => $limitation));
505
        $return = $this->persistenceHandler->userHandler()->assignRole($contentId, $roleId, $limitation);
506
507
        $tags = ['role-assignment-group-list-' . $contentId, 'role-assignment-role-list-' . $roleId];
508
        $locations = $this->persistenceHandler->locationHandler()->loadLocationsByContent($contentId);
509
        foreach ($locations as $location) {
510
            $tags[] = 'location-path-' . $location->id;
511
        }
512
513
        $this->invalidateCache($tags);
514
515
        return $return;
516
    }
517
518
    /**
519
     * {@inheritdoc}
520
     */
521 View Code Duplication
    public function unassignRole($contentId, $roleId)
522
    {
523
        $this->logger->logCall(__METHOD__, array('group' => $contentId, 'role' => $roleId));
524
        $return = $this->persistenceHandler->userHandler()->unassignRole($contentId, $roleId);
525
526
        $this->invalidateCache(['role-assignment-group-list-' . $contentId, 'role-assignment-role-list-' . $roleId]);
527
528
        return $return;
529
    }
530
531
    /**
532
     * {@inheritdoc}
533
     */
534
    public function removeRoleAssignment($roleAssignmentId)
535
    {
536
        $this->logger->logCall(__METHOD__, array('assignment' => $roleAssignmentId));
537
        $return = $this->persistenceHandler->userHandler()->removeRoleAssignment($roleAssignmentId);
538
539
        $this->invalidateCache(['role-assignment-' . $roleAssignmentId]);
540
541
        return $return;
542
    }
543
}
544