Permission.php 4.3 KB

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