Completed
Push — cached_permision_criterion ( 018fb5 )
by André
13:02
created

CachedPermissionService::hasAccess()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 3
rs 10
1
<?php
2
3
/**
4
 * @copyright Copyright (C) eZ Systems AS. All rights reserved.
5
 * @license For full copyright and license information view LICENSE file distributed with this source code.
6
 */
7
namespace eZ\Publish\Core\Repository\Permission;
8
9
use eZ\Publish\API\Repository\PermissionResolver;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, eZ\Publish\Core\Reposito...sion\PermissionResolver.

Let’s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let’s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
10
use eZ\Publish\API\Repository\PermissionCriterionResolver;
11
use eZ\Publish\API\Repository\Values\User\UserReference;
12
use eZ\Publish\API\Repository\Values\ValueObject;
13
14
/**
15
 * Cache implementation of PermissionResolver and PermissionCriterionResolver interface.
16
 *
17
 * Implements both interfaces as the cached permission criterion lookup needs to be
18
 * expired when a different user is set as current users in the system.
19
 *
20
 * The logic here uses a cache TTL of a few seconds, as this is in-memory cache we are not
21
 * able to know if any other concurrent user might be changing permissions.
22
 */
23
class CachedPermissionService implements PermissionResolver, PermissionCriterionResolver
24
{
25
    /**
26
     * @var \eZ\Publish\API\Repository\PermissionResolver
27
     */
28
    private $permissionResolver;
29
30
    /**
31
     * @var \eZ\Publish\API\Repository\PermissionCriterionResolver
32
     */
33
    private $permissionCriterionResolver;
34
35
    /**
36
     * @var int
37
     */
38
    private $cacheTTL;
39
40
    /**
41
     * Cached value for current user's getCriterion() result.
42
     *
43
     * Value is null if not yet set or cleared.
44
     *
45
     * @var bool|\eZ\Publish\API\Repository\Values\Content\Query\Criterion
46
     */
47
    private $permissionCriterion;
48
49
    /**
50
     * Cache time stamp.
51
     *
52
     * @var int
53
     */
54
    private $permissionCriterionTimeStamp;
55
56
    public function __construct(
57
        PermissionResolver $permissionResolver,
58
        PermissionCriterionResolver $permissionCriterionResolver,
59
        $cacheTTL = 5
60
    ) {
61
        $this->permissionResolver = $permissionResolver;
62
        $this->permissionCriterionResolver = $permissionCriterionResolver;
63
        $this->cacheTTL = $cacheTTL;
64
    }
65
66
    public function getCurrentUserReference()
67
    {
68
        return $this->permissionResolver->getCurrentUserReference();
69
    }
70
71
    public function setCurrentUserReference(UserReference $userReference)
72
    {
73
        $this->permissionCriterion = null;
74
        return $this->permissionResolver->setCurrentUserReference($userReference);
75
    }
76
77
    public function hasAccess($module, $function, UserReference $userReference = null)
78
    {
79
        return $this->permissionResolver->hasAccess($module, $function, $userReference);
80
    }
81
82
    public function canUser($module, $function, ValueObject $object, array $targets = [])
83
    {
84
        return $this->permissionResolver->canUser($module, $function, $object, $targets);
85
    }
86
87
    public function getPermissionsCriterion($module = 'content', $function = 'read')
88
    {
89
        if ($this->permissionCriterion !== null) {
90
            // If we are still within the cache TTL, then return the cached value
91
            if ((time() - $this->permissionCriterionTimeStamp) < $this->cacheTTL) {
92
                return $this->permissionCriterion;
93
            }
94
        }
95
96
        $this->permissionCriterionTimeStamp = time();
97
        $this->permissionCriterion = $this->permissionCriterionResolver->getPermissionsCriterion($module, $function);
98
99
        return $this->permissionCriterion;
100
    }
101
}