You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

58 lines
1.5 KiB

2 years ago
  1. <?php
  2. namespace App\Utilities\Polices;
  3. use App\Documents\PolicyDocument;
  4. use Illuminate\Database\Eloquent\Model;
  5. use Illuminate\Http\Response;
  6. class BasePolicy
  7. {
  8. use PolicyConditions;
  9. public function __construct(PolicyDocument|null $policy = null, Model|null $model = null)
  10. {
  11. $this->policy = $policy;
  12. $this->model = $model;
  13. }
  14. public static function allow(PolicyDocument $policy, Model|null $model = null)
  15. {
  16. (new static($policy, $model))->applyCheck();
  17. }
  18. public static function when(PolicyDocument $policy, Model|null $model = null): bool
  19. {
  20. return (new static($policy, $model))->applyCheck(false);
  21. }
  22. public function applyCheck($throwException = true): bool
  23. {
  24. $pass = false;
  25. foreach ($this->policy?->needs ?? [] as $condition) {
  26. $pass = $this->checkCondition($condition);
  27. if ($pass) break;
  28. }
  29. if (!$pass && $throwException) {
  30. abort(Response::HTTP_FORBIDDEN, 'this action is forbidden.');
  31. }
  32. return $pass;
  33. }
  34. public function checkCondition($conditions): bool
  35. {
  36. $conditionsMatch = true;
  37. foreach ($conditions as $condition) {
  38. [$function, $param] = str_contains($condition, ":") ? explode(':', $condition) : [$condition, null];
  39. $conditionsMatch = $conditionsMatch &&
  40. call_user_func_array([static::class, $function], (empty($param) ? [] : [$param]));
  41. if (!$conditionsMatch) break;
  42. }
  43. return $conditionsMatch;
  44. }
  45. }