Issues (3877)

PermissionExecutor/PermissionExecutor.php (1 issue)

Severity
1
<?php
2
3
/**
4
 * Copyright © 2016-present Spryker Systems GmbH. All rights reserved.
5
 * Use of this software requires acceptance of the Evaluation License Agreement. See LICENSE file.
6
 */
7
8
namespace Spryker\Client\Permission\PermissionExecutor;
9
10
use Generated\Shared\Transfer\PermissionCollectionTransfer;
11
use Generated\Shared\Transfer\PermissionTransfer;
12
use Spryker\Client\Permission\Exception\NotFoundPermissionCollectionTransferCacheException;
13
use Spryker\Client\Permission\PermissionFinder\PermissionFinderInterface;
14
use Spryker\Shared\PermissionExtension\Dependency\Plugin\ExecutablePermissionPluginInterface;
15
16
class PermissionExecutor implements PermissionExecutorInterface
17
{
18
    /**
19
     * @var array<\Spryker\Client\PermissionExtension\Dependency\Plugin\PermissionStoragePluginInterface>
20
     */
21
    protected $permissionStoragePlugins;
22
23
    /**
24
     * @var \Spryker\Client\Permission\PermissionFinder\PermissionFinderInterface
25
     */
26
    protected $permissionFinder;
27
28
    /**
29
     * @var array<\Generated\Shared\Transfer\PermissionCollectionTransfer>
30
     */
31
    protected static $permissionCollectionTransfersCache = [];
32
33
    /**
34
     * @param array<\Spryker\Client\PermissionExtension\Dependency\Plugin\PermissionStoragePluginInterface> $permissionStoragePlugins
35
     * @param \Spryker\Client\Permission\PermissionFinder\PermissionFinderInterface $permissionConfigurator
36
     */
37
    public function __construct(
38
        array $permissionStoragePlugins,
39
        PermissionFinderInterface $permissionConfigurator
40
    ) {
41
        $this->permissionFinder = $permissionConfigurator;
42
        $this->permissionStoragePlugins = $permissionStoragePlugins;
43
    }
44
45
    /**
46
     * @param string $permissionKey
47
     * @param array|string|int|null $context
48
     *
49
     * @return bool
50
     */
51
    public function can($permissionKey, $context = null): bool
52
    {
53
        $permissionPlugin = $this->permissionFinder->findPermissionPlugin($permissionKey);
54
        if (!$permissionPlugin) {
55
            return true;
56
        }
57
58
        $permissionCollectionTransfer = $this->findPermissions($permissionKey);
59
60
        if ($permissionCollectionTransfer->getPermissions()->count() <= 0) {
61
            return false;
62
        }
63
64
        if (!($permissionPlugin instanceof ExecutablePermissionPluginInterface)) {
0 ignored issues
show
$permissionPlugin is always a sub-type of Spryker\Shared\Permissio...rmissionPluginInterface.
Loading history...
65
            return true;
66
        }
67
68
        return $this->executePermissionCollection($permissionPlugin, $permissionCollectionTransfer, $context);
69
    }
70
71
    /**
72
     * If one of the permission configurations wins, then a subject has the permission
73
     *
74
     * @example A junior sales manager could place an order up to 1000 and
75
     *  a senior sales manager up to 2000. A user has both roles assigned, then he/she has
76
     *  the permission to place an order up to 2000.
77
     *
78
     * @param \Spryker\Shared\PermissionExtension\Dependency\Plugin\ExecutablePermissionPluginInterface $permissionPlugin
79
     * @param \Generated\Shared\Transfer\PermissionCollectionTransfer $permissionCollectionTransfer
80
     * @param array|string|int|null $context
81
     *
82
     * @return bool
83
     */
84
    protected function executePermissionCollection(
85
        ExecutablePermissionPluginInterface $permissionPlugin,
86
        PermissionCollectionTransfer $permissionCollectionTransfer,
87
        $context = null
88
    ): bool {
89
        foreach ($permissionCollectionTransfer->getPermissions() as $permissionTransfer) {
90
            if ($this->executePermission($permissionPlugin, $permissionTransfer, $context)) {
91
                return true;
92
            }
93
        }
94
95
        return false;
96
    }
97
98
    /**
99
     * @param \Spryker\Shared\PermissionExtension\Dependency\Plugin\ExecutablePermissionPluginInterface $permissionPlugin
100
     * @param \Generated\Shared\Transfer\PermissionTransfer $permissionTransfer
101
     * @param array|string|int|null $context
102
     *
103
     * @return bool
104
     */
105
    protected function executePermission(ExecutablePermissionPluginInterface $permissionPlugin, PermissionTransfer $permissionTransfer, $context = null): bool
106
    {
107
        return $permissionPlugin->can($permissionTransfer->getConfiguration(), $context);
108
    }
109
110
    /**
111
     * @param string $permissionKey
112
     *
113
     * @return \Generated\Shared\Transfer\PermissionCollectionTransfer
114
     */
115
    protected function findPermissions($permissionKey): PermissionCollectionTransfer
116
    {
117
        if ($this->hasPermissionCollectionTransferCacheByKey($permissionKey)) {
118
            return $this->getPermissionCollectionTransferCacheByKey($permissionKey);
119
        }
120
121
        $permissionCollectionTransfer = new PermissionCollectionTransfer();
122
123
        foreach ($this->permissionStoragePlugins as $permissionStoragePlugin) {
124
            foreach ($permissionStoragePlugin->getPermissionCollection()->getPermissions() as $permission) {
125
                if ($permission->getKey() === $permissionKey) {
126
                    $permissionCollectionTransfer->addPermission($permission);
127
                }
128
            }
129
        }
130
131
        $this->cachePermissionCollectionTransferByKey($permissionKey, $permissionCollectionTransfer);
132
133
        return $permissionCollectionTransfer;
134
    }
135
136
    /**
137
     * @param string $permissionKey
138
     *
139
     * @return bool
140
     */
141
    protected function hasPermissionCollectionTransferCacheByKey(string $permissionKey): bool
142
    {
143
        return isset(static::$permissionCollectionTransfersCache[$permissionKey]);
144
    }
145
146
    /**
147
     * @param string $permissionKey
148
     *
149
     * @throws \Spryker\Client\Permission\Exception\NotFoundPermissionCollectionTransferCacheException
150
     *
151
     * @return \Generated\Shared\Transfer\PermissionCollectionTransfer
152
     */
153
    protected function getPermissionCollectionTransferCacheByKey(string $permissionKey): PermissionCollectionTransfer
154
    {
155
        if (!$this->hasPermissionCollectionTransferCacheByKey($permissionKey)) {
156
            throw new NotFoundPermissionCollectionTransferCacheException();
157
        }
158
159
        return static::$permissionCollectionTransfersCache[$permissionKey];
160
    }
161
162
    /**
163
     * @param string $permissionKey
164
     * @param \Generated\Shared\Transfer\PermissionCollectionTransfer $permissionCollectionTransfer
165
     *
166
     * @return void
167
     */
168
    protected function cachePermissionCollectionTransferByKey(string $permissionKey, PermissionCollectionTransfer $permissionCollectionTransfer): void
169
    {
170
        static::$permissionCollectionTransfersCache[$permissionKey] = $permissionCollectionTransfer;
171
    }
172
}
173