Permission.php 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  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. * {@inheritDoc}
  30. */
  31. public function __construct(array $attributes = [])
  32. {
  33. $this->init();
  34. parent::__construct($attributes);
  35. }
  36. protected function init()
  37. {
  38. $connection = config('admin.database.connection') ?: config('database.default');
  39. $this->setConnection($connection);
  40. $this->setTable(config('admin.database.permissions_table'));
  41. }
  42. /**
  43. * Permission belongs to many roles.
  44. *
  45. * @return BelongsToMany
  46. */
  47. public function roles(): BelongsToMany
  48. {
  49. $pivotTable = config('admin.database.role_permissions_table');
  50. $relatedModel = config('admin.database.roles_model');
  51. return $this->belongsToMany($relatedModel, $pivotTable, 'permission_id', 'role_id');
  52. }
  53. /**
  54. * If request should pass through the current permission.
  55. *
  56. * @param Request $request
  57. *
  58. * @return bool
  59. */
  60. public function shouldPassThrough(Request $request): bool
  61. {
  62. if (! $this->http_path) {
  63. return false;
  64. }
  65. $method = $this->http_method;
  66. $matches = array_map(function ($path) use ($method) {
  67. if (Str::contains($path, ':')) {
  68. [$method, $path] = explode(':', $path);
  69. $method = explode(',', $method);
  70. }
  71. $path = Str::contains($path, '.') ? $path : ltrim(admin_base_path($path), '/');
  72. return compact('method', 'path');
  73. }, $this->http_path);
  74. foreach ($matches as $match) {
  75. if ($this->matchRequest($match, $request)) {
  76. return true;
  77. }
  78. }
  79. return false;
  80. }
  81. /**
  82. * Get options for Select field in form.
  83. *
  84. * @param \Closure|null $closure
  85. *
  86. * @return array
  87. */
  88. public static function selectOptions(\Closure $closure = null)
  89. {
  90. $options = (new static())->withQuery($closure)->buildSelectOptions();
  91. return collect($options)->all();
  92. }
  93. /**
  94. * @param string $path
  95. *
  96. * @return mixed
  97. */
  98. public function getHttpPathAttribute($path)
  99. {
  100. return explode(',', $path);
  101. }
  102. /**
  103. * @param $path
  104. */
  105. public function setHttpPathAttribute($path)
  106. {
  107. if (is_array($path)) {
  108. $path = implode(',', $path);
  109. }
  110. return $this->attributes['http_path'] = $path;
  111. }
  112. /**
  113. * If a request match the specific HTTP method and path.
  114. *
  115. * @param array $match
  116. * @param Request $request
  117. *
  118. * @return bool
  119. */
  120. protected function matchRequest(array $match, Request $request): bool
  121. {
  122. if (! $path = trim($match['path'], '/')) {
  123. return false;
  124. }
  125. if (! Helper::matchRequestPath($path)) {
  126. return false;
  127. }
  128. $method = collect($match['method'])->filter()->map(function ($method) {
  129. return strtoupper($method);
  130. });
  131. return $method->isEmpty() || $method->contains($request->method());
  132. }
  133. /**
  134. * @param $method
  135. */
  136. public function setHttpMethodAttribute($method)
  137. {
  138. if (is_array($method)) {
  139. $this->attributes['http_method'] = implode(',', $method);
  140. }
  141. }
  142. /**
  143. * @param $method
  144. *
  145. * @return array
  146. */
  147. public function getHttpMethodAttribute($method)
  148. {
  149. if (is_string($method)) {
  150. return array_filter(explode(',', $method));
  151. }
  152. return $method;
  153. }
  154. /**
  155. * Detach models from the relationship.
  156. *
  157. * @return void
  158. */
  159. protected static function boot()
  160. {
  161. static::treeBoot();
  162. parent::boot();
  163. static::deleting(function ($model) {
  164. $model->roles()->detach();
  165. });
  166. }
  167. }