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.

68 lines
1.6 KiB

2 years ago
  1. <?php
  2. namespace App\Rules;
  3. use Illuminate\Contracts\Validation\Rule;
  4. use Illuminate\Database\Eloquent\Model as Model;
  5. use Jenssegers\Mongodb\Eloquent\Model as Document;
  6. class ExistsRule implements Rule
  7. {
  8. CONST FIELD = '_id';
  9. private Model|Document $model;
  10. private array $invalidItems;
  11. /**
  12. * Create a new rule instance.
  13. *
  14. * @param Model|Document $model
  15. * @param string $field
  16. */
  17. public function __construct(Model|Document $model)
  18. {
  19. $this->model = $model;
  20. }
  21. /**
  22. * Determine if the validation rule passes.
  23. *
  24. * @param string $attribute
  25. * @param mixed $value
  26. * @return bool
  27. */
  28. public function passes($attribute, $value)
  29. {
  30. $valid = true;
  31. $value = collect($value);
  32. // if value is empty do not validate
  33. if ($value->isEmpty()) {
  34. return $valid;
  35. }
  36. // query to fetch records base on field and value.
  37. $validCollection = $this->model->select(self::FIELD)
  38. ->whereIn(self::FIELD, $value->toArray())
  39. ->withoutTrash()
  40. ->get()->map(fn($m) => $m->{self::FIELD});
  41. // check if all values are existed.
  42. $valid = $value->count() === $validCollection->count();
  43. // extract invalid values.
  44. $this->invalidItems = $value->diff($validCollection)->toArray();
  45. return $valid;
  46. }
  47. /**
  48. * Get the validation error message.
  49. *
  50. * @return string
  51. */
  52. public function message()
  53. {
  54. return implode(',', $this->invalidItems) .
  55. (count($this->invalidItems) > 1 ? ' are ' : ' is ') .
  56. 'invalid!';
  57. }
  58. }