Completed
Pull Request — master (#1039)
by Matthew
01:59
created

PermissionRegistrar::getRoleClass()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Spatie\Permission;
4
5
use Illuminate\Cache\CacheManager;
6
use Illuminate\Support\Collection;
7
use Spatie\Permission\Contracts\Role;
8
use Illuminate\Contracts\Auth\Access\Gate;
9
use Spatie\Permission\Contracts\Permission;
10
use Illuminate\Contracts\Auth\Access\Authorizable;
11
use Spatie\Permission\Exceptions\PermissionDoesNotExist;
12
13
class PermissionRegistrar
14
{
15
    /** @var \Illuminate\Contracts\Auth\Access\Gate */
16
    protected $gate;
17
18
    /** @var \Illuminate\Contracts\Cache\Repository */
19
    protected $cache;
20
21
    /** @var \Illuminate\Cache\CacheManager */
22
    protected $cacheManager;
23
24
    /** @var string */
25
    protected $permissionClass;
26
27
    /** @var string */
28
    protected $roleClass;
29
30
    /** @var \Illuminate\Support\Collection */
31
    protected $permissions;
32
33
    /** @var DateInterval|int */
34
    public static $cacheExpirationTime;
35
36
    /** @var string */
37
    public static $cacheKey;
38
39
    /** @var string */
40
    public static $cacheModelKey;
41
42
    /**
43
     * PermissionRegistrar constructor.
44
     *
45
     * @param \Illuminate\Contracts\Auth\Access\Gate $gate
46
     * @param \Illuminate\Cache\CacheManager $cacheManager
47
     */
48
    public function __construct(Gate $gate, CacheManager $cacheManager)
49
    {
50
        $this->gate = $gate;
51
        $this->permissionClass = config('permission.models.permission');
52
        $this->roleClass = config('permission.models.role');
53
54
        $this->cacheManager = $cacheManager;
55
        $this->initializeCache();
56
    }
57
58
    protected function initializeCache()
59
    {
60
        self::$cacheExpirationTime = config('permission.cache.expiration_time', config('permission.cache_expiration_time'));
61
62
        if (app()->version() <= '5.5') {
63
            if (self::$cacheExpirationTime instanceof \DateInterval) {
64
                $interval = self::$cacheExpirationTime;
65
                self::$cacheExpirationTime = $interval->m * 30 * 60 * 24 + $interval->d * 60 * 24 + $interval->h * 60 + $interval->i;
66
            }
67
        }
68
69
        self::$cacheKey = config('permission.cache.key');
70
        self::$cacheModelKey = config('permission.cache.model_key');
71
72
        $this->cache = $this->getCacheStoreFromConfig();
73
    }
74
75
    protected function getCacheStoreFromConfig(): \Illuminate\Contracts\Cache\Repository
76
    {
77
        // the 'default' fallback here is from the permission.php config file, where 'default' means to use config(cache.default)
78
        $cacheDriver = config('permission.cache.store', 'default');
79
80
        // when 'default' is specified, no action is required since we already have the default instance
81
        if ($cacheDriver === 'default') {
82
            return $this->cacheManager->store();
83
        }
84
85
        // if an undefined cache store is specified, fallback to 'array' which is Laravel's closest equiv to 'none'
86
        if (! \array_key_exists($cacheDriver, config('cache.stores'))) {
87
            $cacheDriver = 'array';
88
        }
89
90
        return $this->cacheManager->store($cacheDriver);
91
    }
92
93
    /**
94
     * Register the permission check method on the gate.
95
     *
96
     * @return bool
97
     */
98
    public function registerPermissions(): bool
99
    {
100
        $this->gate->before(function (Authorizable $user, string $ability) {
101
            try {
102
                if (method_exists($user, 'hasPermissionTo')) {
103
                    return $user->hasPermissionTo($ability) ?: null;
0 ignored issues
show
Bug introduced by
The method hasPermissionTo() does not seem to exist on object<Illuminate\Contra...th\Access\Authorizable>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
104
                }
105
            } catch (PermissionDoesNotExist $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
106
            }
107
        });
108
109
        return true;
110
    }
111
112
    /**
113
     * Flush the cache.
114
     */
115
    public function forgetCachedPermissions()
116
    {
117
        $this->permissions = null;
118
        $this->cache->forget(self::$cacheKey);
119
    }
120
121
    /**
122
     * Get the permissions based on the passed params.
123
     *
124
     * @param array $params
125
     *
126
     * @return \Illuminate\Support\Collection
127
     */
128
    public function getPermissions(array $params = []): Collection
129
    {
130
        if ($this->permissions === null) {
131
            $this->permissions = $this->cache->remember(self::$cacheKey, self::$cacheExpirationTime, function () {
132
                return $this->getPermissionClass()
133
                    ->with('roles')
134
                    ->get();
135
            });
136
        }
137
138
        $permissions = clone $this->permissions;
139
140
        foreach ($params as $attr => $value) {
141
            $permissions = $permissions->where($attr, $value);
142
        }
143
144
        return $permissions;
145
    }
146
147
    /**
148
     * Get an instance of the permission class.
149
     *
150
     * @return \Spatie\Permission\Contracts\Permission
151
     */
152
    public function getPermissionClass(): Permission
153
    {
154
        return app($this->permissionClass);
155
    }
156
157
    /**
158
     * Get an instance of the role class.
159
     *
160
     * @return \Spatie\Permission\Contracts\Role
161
     */
162
    public function getRoleClass(): Role
163
    {
164
        return app($this->roleClass);
165
    }
166
167
    /**
168
     * Get the instance of the Cache Store.
169
     *
170
     * @return \Illuminate\Contracts\Cache\Store
171
     */
172
    public function getCacheStore(): \Illuminate\Contracts\Cache\Store
173
    {
174
        return $this->cache->getStore();
175
    }
176
}
177