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.

140 lines
4.0 KiB

2 years ago
  1. <?php
  2. namespace App\Models\Traits;
  3. use App\Rules\ExistsRule;
  4. use App\Rules\UniqueRule;
  5. use Illuminate\Database\Eloquent\Model;
  6. use Illuminate\Database\Eloquent\SoftDeletes;
  7. use Illuminate\Support\Str;
  8. use Jenssegers\Mongodb\Eloquent\Model as Document;
  9. trait ValidationMaker
  10. {
  11. private Model|Document|null $modelDocument;
  12. private array $field = [];
  13. private array $rules = [];
  14. protected function createValidations($prefix = 'fields'): array
  15. {
  16. $this->modelDocument = app('modelDocument');
  17. if (empty($this->modelDocument)) {
  18. return $this->rules;
  19. }
  20. foreach ($this->modelDocument->{$prefix} ?? [] as $field) {
  21. $this->field = $field;
  22. $this->field['request_name'] = $prefix . '.' . $this->field['name'];
  23. $this->required();
  24. $this->type();
  25. $this->primitiveType();
  26. $this->unique();
  27. $this->limit('min');
  28. $this->limit('max');
  29. $this->in();
  30. }
  31. return $this->rules;
  32. }
  33. private function isArray(): bool
  34. {
  35. return $this->field['info']['multi'] == true || $this->field['info']['multi'] == "true";
  36. }
  37. private function isResource(): bool
  38. {
  39. return str_contains($this->field['info']['type'], 'resource:');
  40. }
  41. private function isSetting(): bool
  42. {
  43. return str_contains($this->field['info']['type'], 'setting:');
  44. }
  45. private function complexName(): string
  46. {
  47. return $this->field['request_name'] . ($this->isArray() ? '.*' : '');
  48. }
  49. private function required()
  50. {
  51. $this->rules[$this->field['request_name']][] = $this->field['info']['required'] ? 'required' : 'sometimes';
  52. }
  53. private function unique()
  54. {
  55. if ($this->field['info']['unique'] == true || $this->field['info']['unique'] == "true") {
  56. $rule = new UniqueRule($this->getTable(), str_replace('.', '->', $this->field['request_name']));
  57. $rule = in_array(SoftDeletes::class, array_keys(class_uses($this))) ? $rule->withoutTrashed() : $rule;
  58. $rule = $this->getTable() === 'resources' ? $rule->where('model_id', $this->modelDocument->id) : $rule;
  59. $this->rules[$this->field['request_name']][] = $rule->ignore($this->id);
  60. }
  61. }
  62. private function type()
  63. {
  64. if ($this->isArray()) {
  65. $this->rules[$this->field['request_name']][] = 'array';
  66. }
  67. if ($this->isResource()) {
  68. $documentName = Str::studly(str_replace('resource:', '', $this->field['info']['type'])) . "Document";
  69. $this->rules[$this->field['request_name']][] = new ExistsRule(new ('App\Documents\\' . $documentName));
  70. }
  71. if ($this->isSetting()) {
  72. //todo:setting checking
  73. }
  74. }
  75. private function primitiveType()
  76. {
  77. if ($this->isResource() || $this->isSetting()) {
  78. return;
  79. }
  80. $name = $this->complexName();
  81. $this->rules[$name][] = match ($this->field['info']['type']) {
  82. 'int', 'float' => 'numeric',
  83. 'string' => 'string',
  84. 'email' => 'email',
  85. 'boolean' => 'boolean',
  86. 'date' => 'date',
  87. };
  88. }
  89. private function limit($rule)
  90. {
  91. $ruleValue = trim($this->field['info'][$rule]);
  92. $rule = !empty($ruleValue) && $ruleValue != "null" ? ($rule . ':' . $ruleValue) : null;
  93. if (empty($rule)) {
  94. return;
  95. }
  96. if ($this->field['info']['type'] == 'date') {
  97. $rule = str_replace(['min:', 'max:'], ['after_or_equal:', 'before_or_equal:'], $rule);
  98. }
  99. $name = $this->complexName();
  100. $this->rules[$name][] = $rule;
  101. }
  102. private function in()
  103. {
  104. $in = $this->field['info']['in'];
  105. if (empty($in) || $in == "null") {
  106. return;
  107. }
  108. $in = is_array($in) ? $in : explode(',', $in);
  109. $name = $this->complexName();
  110. $this->rules[$name][] = 'in:' . implode(',', $in);
  111. }
  112. }