1
|
|
|
<?php |
2
|
|
|
declare(strict_types=1); |
3
|
|
|
|
4
|
|
|
namespace Maklad\Permission\Models; |
5
|
|
|
|
6
|
|
|
use Jenssegers\Mongodb\Eloquent\Model; |
7
|
|
|
use Jenssegers\Mongodb\Relations\BelongsToMany; |
8
|
|
|
use Maklad\Permission\Contracts\PermissionInterface; |
9
|
|
|
use Maklad\Permission\Contracts\RoleInterface; |
10
|
|
|
use Maklad\Permission\Exceptions\GuardDoesNotMatch; |
11
|
|
|
use Maklad\Permission\Exceptions\RoleAlreadyExists; |
12
|
|
|
use Maklad\Permission\Exceptions\RoleDoesNotExist; |
13
|
|
|
use Maklad\Permission\Helpers; |
14
|
|
|
use Maklad\Permission\Traits\HasPermissions; |
15
|
|
|
use Maklad\Permission\Traits\RefreshesPermissionCache; |
16
|
|
|
|
17
|
|
|
/** |
18
|
|
|
* Class Role |
19
|
|
|
* @package Maklad\Permission\Models |
20
|
|
|
*/ |
21
|
|
|
class Role extends Model implements RoleInterface |
22
|
|
|
{ |
23
|
|
|
use HasPermissions; |
24
|
|
|
use RefreshesPermissionCache; |
25
|
|
|
|
26
|
|
|
public $guarded = ['id']; |
27
|
|
|
protected $helpers; |
28
|
|
|
|
29
|
|
|
/** |
30
|
|
|
* Role constructor. |
31
|
|
|
* |
32
|
|
|
* @param array $attributes |
33
|
|
|
*/ |
34
|
119 |
View Code Duplication |
public function __construct(array $attributes = []) |
|
|
|
|
35
|
|
|
{ |
36
|
119 |
|
$attributes['guard_name'] = $attributes['guard_name'] ?? \config('auth.defaults.guard'); |
37
|
|
|
|
38
|
119 |
|
parent::__construct($attributes); |
39
|
|
|
|
40
|
119 |
|
$this->helpers = new Helpers(); |
41
|
|
|
|
42
|
119 |
|
$this->setTable(\config('permission.collection_names.roles')); |
43
|
119 |
|
} |
44
|
|
|
|
45
|
|
|
/** |
46
|
|
|
* @param array $attributes |
47
|
|
|
* |
48
|
|
|
* @return $this|Model |
49
|
|
|
* @throws RoleAlreadyExists |
50
|
|
|
* @internal param array $attributes§ |
51
|
|
|
* |
52
|
|
|
*/ |
53
|
119 |
View Code Duplication |
public static function create(array $attributes = []) |
|
|
|
|
54
|
|
|
{ |
55
|
119 |
|
$attributes['guard_name'] = $attributes['guard_name'] ?? \config('auth.defaults.guard'); |
56
|
119 |
|
$helpers = new Helpers(); |
57
|
|
|
|
58
|
119 |
|
if (static::where('name', $attributes['name'])->where('guard_name', $attributes['guard_name'])->first()) { |
59
|
1 |
|
$name = (string) $attributes['name']; |
60
|
1 |
|
$guardName = (string) $attributes['guard_name']; |
61
|
1 |
|
throw new RoleAlreadyExists($helpers->getRoleAlreadyExistsMessage($name, $guardName)); |
62
|
|
|
} |
63
|
|
|
|
64
|
119 |
|
if ($helpers->isNotLumen() && app()::VERSION < '5.4') { |
65
|
|
|
return parent::create($attributes); |
66
|
|
|
} |
67
|
|
|
|
68
|
119 |
|
return static::query()->create($attributes); |
69
|
|
|
} |
70
|
|
|
|
71
|
|
|
/** |
72
|
|
|
* Find or create role by its name (and optionally guardName). |
73
|
|
|
* |
74
|
|
|
* @param string $name |
75
|
|
|
* @param string|null $guardName |
76
|
|
|
* |
77
|
|
|
* @return RoleInterface |
78
|
|
|
* @throws \Maklad\Permission\Exceptions\RoleAlreadyExists |
79
|
|
|
*/ |
80
|
1 |
View Code Duplication |
public static function findOrCreate(string $name, $guardName = null): RoleInterface |
|
|
|
|
81
|
|
|
{ |
82
|
1 |
|
$guardName = $guardName ?? config('auth.defaults.guard'); |
83
|
|
|
|
84
|
1 |
|
$role = static::where('name', $name) |
85
|
1 |
|
->where('guard_name', $guardName) |
86
|
1 |
|
->first(); |
87
|
|
|
|
88
|
1 |
|
if (! $role) { |
89
|
1 |
|
$role = static::create(['name' => $name, 'guard_name' => $guardName]); |
90
|
|
|
} |
91
|
|
|
|
92
|
1 |
|
return $role; |
93
|
|
|
} |
94
|
|
|
|
95
|
|
|
/** |
96
|
|
|
* A role may be given various permissions. |
97
|
|
|
* @return BelongsToMany |
98
|
|
|
*/ |
99
|
29 |
|
public function permissions(): BelongsToMany |
100
|
|
|
{ |
101
|
29 |
|
return $this->belongsToMany( |
102
|
29 |
|
\config('permission.models.permission'), |
|
|
|
|
103
|
29 |
|
\config('permission.collection_names.role_has_permissions') |
104
|
|
|
); |
105
|
|
|
} |
106
|
|
|
|
107
|
|
|
/** |
108
|
|
|
* A role belongs to some users of the model associated with its guard. |
109
|
|
|
*/ |
110
|
2 |
|
public function users(): BelongsToMany |
111
|
|
|
{ |
112
|
2 |
|
return $this->belongsToMany($this->helpers->getModelForGuard($this->attributes['guard_name'])); |
|
|
|
|
113
|
|
|
} |
114
|
|
|
|
115
|
|
|
/** |
116
|
|
|
* Find a role by its name and guard name. |
117
|
|
|
* |
118
|
|
|
* @param string $name |
119
|
|
|
* @param string|null $guardName |
120
|
|
|
* |
121
|
|
|
* @return RoleInterface |
122
|
|
|
* @throws RoleDoesNotExist |
123
|
|
|
*/ |
124
|
47 |
View Code Duplication |
public static function findByName(string $name, $guardName = null): RoleInterface |
|
|
|
|
125
|
|
|
{ |
126
|
47 |
|
$guardName = $guardName ?? \config('auth.defaults.guard'); |
127
|
|
|
|
128
|
47 |
|
$role = static::where('name', $name) |
129
|
47 |
|
->where('guard_name', $guardName) |
130
|
47 |
|
->first(); |
131
|
|
|
|
132
|
47 |
|
if (! $role) { |
133
|
2 |
|
$helpers = new Helpers(); |
134
|
2 |
|
throw new RoleDoesNotExist($helpers->getRoleDoesNotExistMessage($name, $guardName)); |
135
|
|
|
} |
136
|
|
|
|
137
|
45 |
|
return $role; |
138
|
|
|
} |
139
|
|
|
|
140
|
|
|
/** |
141
|
|
|
* Determine if the user may perform the given permission. |
142
|
|
|
* |
143
|
|
|
* @param string|Permission $permission |
144
|
|
|
* |
145
|
|
|
* @return bool |
146
|
|
|
* |
147
|
|
|
* @throws GuardDoesNotMatch |
148
|
|
|
*/ |
149
|
12 |
|
public function hasPermissionTo($permission): bool |
150
|
|
|
{ |
151
|
12 |
|
if (\is_string($permission)) { |
152
|
9 |
|
$permission = \app(Permission::class)->findByName($permission, $this->getDefaultGuardName()); |
153
|
|
|
} |
154
|
|
|
|
155
|
11 |
View Code Duplication |
if (! $this->getGuardNames()->contains($permission->guard_name)) { |
|
|
|
|
156
|
1 |
|
$expected = $this->getGuardNames(); |
157
|
1 |
|
$given = $permission->guard_name; |
158
|
|
|
|
159
|
1 |
|
throw new GuardDoesNotMatch($this->helpers->getGuardDoesNotMatchMessage($expected, $given)); |
160
|
|
|
} |
161
|
|
|
|
162
|
10 |
|
return $this->permissions->contains('id', $permission->id); |
163
|
|
|
} |
164
|
|
|
} |
165
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.