Permission.php 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. <?php
  2. namespace Dcat\Admin\Models;
  3. use Dcat\Admin\Support\Helper;
  4. use Dcat\Admin\Traits\HasDateTimeFormatter;
  5. use Dcat\Admin\Traits\ModelTree;
  6. use Illuminate\Database\Eloquent\Model;
  7. use Illuminate\Database\Eloquent\Relations\BelongsToMany;
  8. use Illuminate\Http\Request;
  9. use Illuminate\Support\Str;
  10. use Spatie\EloquentSortable\Sortable;
  11. class Permission extends Model implements Sortable
  12. {
  13. use HasDateTimeFormatter,
  14. ModelTree {
  15. ModelTree::boot as treeBoot;
  16. }
  17. /**
  18. * @var array
  19. */
  20. protected $fillable = ['parent_id', 'name', 'slug', 'http_method', 'http_path'];
  21. /**
  22. * @var array
  23. */
  24. public static $httpMethods = [
  25. 'GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS', 'HEAD',
  26. ];
  27. protected $titleColumn = 'name';
  28. /**
  29. * Create a new Eloquent model instance.
  30. *
  31. * @param array $attributes
  32. */
  33. public function __construct(array $attributes = [])
  34. {
  35. $connection = config('admin.database.connection') ?: config('database.default');
  36. $this->setConnection($connection);
  37. $this->setTable(config('admin.database.permissions_table'));
  38. parent::__construct($attributes);
  39. }
  40. /**
  41. * Permission belongs to many roles.
  42. *
  43. * @return BelongsToMany
  44. */
  45. public function roles(): BelongsToMany
  46. {
  47. $pivotTable = config('admin.database.role_permissions_table');
  48. $relatedModel = config('admin.database.roles_model');
  49. return $this->belongsToMany($relatedModel, $pivotTable, 'permission_id', 'role_id');
  50. }
  51. /**
  52. * If request should pass through the current permission.
  53. *
  54. * @param Request $request
  55. *
  56. * @return bool
  57. */
  58. public function shouldPassThrough(Request $request): bool
  59. {
  60. if (! $this->http_path) {
  61. return false;
  62. }
  63. $method = $this->http_method;
  64. $matches = array_map(function ($path) use ($method) {
  65. if (Str::contains($path, ':')) {
  66. [$method, $path] = explode(':', $path);
  67. $method = explode(',', $method);
  68. }
  69. $path = Str::contains($path, '.') ? $path : ltrim(admin_base_path($path), '/');
  70. return compact('method', 'path');
  71. }, $this->http_path);
  72. foreach ($matches as $match) {
  73. if ($this->matchRequest($match, $request)) {
  74. return true;
  75. }
  76. }
  77. return false;
  78. }
  79. /**
  80. * Get options for Select field in form.
  81. *
  82. * @param \Closure|null $closure
  83. *
  84. * @return array
  85. */
  86. public static function selectOptions(\Closure $closure = null)
  87. {
  88. $options = (new static())->withQuery($closure)->buildSelectOptions();
  89. return collect($options)->all();
  90. }
  91. /**
  92. * @param string $path
  93. *
  94. * @return mixed
  95. */
  96. public function getHttpPathAttribute($path)
  97. {
  98. return explode(',', $path);
  99. }
  100. /**
  101. * @param $path
  102. */
  103. public function setHttpPathAttribute($path)
  104. {
  105. if (is_array($path)) {
  106. $path = implode(',', $path);
  107. }
  108. return $this->attributes['http_path'] = $path;
  109. }
  110. /**
  111. * If a request match the specific HTTP method and path.
  112. *
  113. * @param array $match
  114. * @param Request $request
  115. *
  116. * @return bool
  117. */
  118. protected function matchRequest(array $match, Request $request): bool
  119. {
  120. if (! $path = trim($match['path'], '/')) {
  121. return false;
  122. }
  123. if (! Helper::matchRequestPath($path)) {
  124. return false;
  125. }
  126. $method = collect($match['method'])->filter()->map(function ($method) {
  127. return strtoupper($method);
  128. });
  129. return $method->isEmpty() || $method->contains($request->method());
  130. }
  131. /**
  132. * @param $method
  133. */
  134. public function setHttpMethodAttribute($method)
  135. {
  136. if (is_array($method)) {
  137. $this->attributes['http_method'] = implode(',', $method);
  138. }
  139. }
  140. /**
  141. * @param $method
  142. *
  143. * @return array
  144. */
  145. public function getHttpMethodAttribute($method)
  146. {
  147. if (is_string($method)) {
  148. return array_filter(explode(',', $method));
  149. }
  150. return $method;
  151. }
  152. /**
  153. * Detach models from the relationship.
  154. *
  155. * @return void
  156. */
  157. protected static function boot()
  158. {
  159. static::treeBoot();
  160. parent::boot();
  161. static::deleting(function ($model) {
  162. $model->roles()->detach();
  163. });
  164. }
  165. }