Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

250 lines
7.5KB

  1. <?php
  2. namespace App\Http\Controllers\Web;
  3. use App\Repositories\BaseRepository;
  4. use App\Util\DateUtil;
  5. use Exception;
  6. use Illuminate\Support\Arr;
  7. use Illuminate\Support\Carbon;
  8. use Illuminate\Support\Str;
  9. use Illuminate\Validation\Rules\Enum;
  10. use ReflectionClass;
  11. abstract class BaseParam implements IParam
  12. {
  13. const REQUIRED = 'required';
  14. const NULLABLE = 'nullable';
  15. const STR = 'string';
  16. const NUMERIC = 'numeric';
  17. const INTEGER = 'integer';
  18. const DATE = 'date';
  19. const BOOLEAN_ = 'boolean';
  20. const IMAGE = 'image';
  21. const FILE = 'file';
  22. const ARRAY = 'array';
  23. const PARAM_NAME_TIMESTAMP = 'timestamp';
  24. private array $param = [];
  25. abstract public function rules(): array;
  26. public function __set($name, $value)
  27. {
  28. $name = Str::snake($name);
  29. $rule = data_get($this->rules(), $name, null);
  30. if (!$rule) {
  31. throw new Exception('存在しないパラメータ ' . $name);
  32. }
  33. $this->param[$name] = $value;
  34. }
  35. public function __get($name)
  36. {
  37. return data_get($this->param, Str::snake($name), null);
  38. }
  39. public function toArray(bool $toCamelCase = false): array
  40. {
  41. if ($toCamelCase === false) {
  42. return $this->param;
  43. }
  44. $ret = [];
  45. foreach ($this->param as $key => $val) {
  46. $camelKey = Str::camel($key);
  47. $ret[$camelKey] = $val;
  48. }
  49. return $ret;
  50. }
  51. public function setData(array $data)
  52. {
  53. $dots = Arr::dot($data);
  54. $ruleRegExs = RuleAnalyzer::convertToRegEx($this->rules());
  55. // logger($ruleRegExs);
  56. foreach ($dots as $name => $value) {
  57. if ($value === null) {
  58. data_set($this->param, $name, null);
  59. continue;
  60. }
  61. $analyzer = new RuleAnalyzer($name, $ruleRegExs);
  62. if ($analyzer->isMathed()) {
  63. $content = $this->getSettableData($analyzer->getType(), $value);
  64. data_set($this->param, $name, $content);
  65. }
  66. }
  67. // logger($this->param);
  68. }
  69. private function getSettableData($rule, $value)
  70. {
  71. if (is_string($rule)) {
  72. if ($rule === self::STR) {
  73. return strval($value);
  74. }
  75. if ($rule === self::NUMERIC) {
  76. return intval($value);
  77. }
  78. if ($rule === self::BOOLEAN_) {
  79. return boolval($value);
  80. }
  81. if ($rule === self::DATE) {
  82. if (is_string($value)) {
  83. return DateUtil::parse($value);
  84. } else {
  85. return null;
  86. }
  87. }
  88. if ($rule === self::IMAGE || $rule === self::FILE) {
  89. return $value;
  90. }
  91. if ($rule === self::ARRAY) {
  92. return $value;
  93. }
  94. } elseif ($rule instanceof Enum) {
  95. // リフレクションを使ってEnumの型を取得する
  96. $ref = new ReflectionClass((get_class($rule)));
  97. $type = $ref->getProperty('type');
  98. $type->setAccessible(true);
  99. $enum = $type->getValue($rule);
  100. try {
  101. return $enum::tryFrom($value);
  102. } catch (Exception $e) {
  103. logs()->error('Enum パース失敗', ['rule' => $rule, 'value' => $value, 'exception' => $e->getMessage()]);
  104. throw $e;
  105. }
  106. }
  107. throw new Exception(sprintf("不正な変換 ",));
  108. }
  109. /**
  110. * 排他チェック
  111. *
  112. * @param Carbon|null $timestamp
  113. * @return boolean
  114. */
  115. public function checkTimestamp(Carbon|null $timestamp): bool
  116. {
  117. if ($timestamp === null) return true;
  118. $param = $this->__get(self::PARAM_NAME_TIMESTAMP);
  119. if ($param === null || !$param instanceof Carbon) {
  120. logger("無効なタイムスタンプ確認");
  121. logger($param);
  122. return false;
  123. }
  124. return $param->eq($timestamp);
  125. }
  126. private function isNullable(array|bool $condition, bool $nullable): bool
  127. {
  128. if (is_array($condition)) {
  129. return $nullable;
  130. } else {
  131. return $condition;
  132. }
  133. }
  134. protected function str(array|bool $condition = [], $nullable = false): array
  135. {
  136. $conditionEx = array_merge(is_array($condition) ? $condition : [], ['max:250']);
  137. return array_merge([
  138. $this->isNullable($condition, $nullable) ? self::NULLABLE : self::REQUIRED,
  139. self::STR
  140. ], $conditionEx);
  141. }
  142. protected function text(array|bool $condition = [], $nullable = false): array
  143. {
  144. return array_merge([
  145. $this->isNullable($condition, $nullable) ? self::NULLABLE : self::REQUIRED,
  146. self::STR
  147. ], is_array($condition) ? $condition : []);
  148. }
  149. protected function numeric(array|bool $condition = [], $nullable = false): array
  150. {
  151. return array_merge([
  152. $this->isNullable($condition, $nullable) ? self::NULLABLE : self::REQUIRED,
  153. self::NUMERIC,
  154. self::INTEGER,
  155. ], is_array($condition) ? $condition : []);
  156. }
  157. protected function boolean(array|bool $condition = [], $nullable = false): array
  158. {
  159. return array_merge([
  160. $this->isNullable($condition, $nullable) ? self::NULLABLE : self::REQUIRED,
  161. self::BOOLEAN_
  162. ], is_array($condition) ? $condition : []);
  163. }
  164. protected function array(array|bool $condition = [], $nullable = false): array
  165. {
  166. return array_merge([
  167. $this->isNullable($condition, $nullable) ? self::NULLABLE : self::REQUIRED,
  168. self::ARRAY
  169. ], is_array($condition) ? $condition : []);
  170. }
  171. protected function date(array|bool $condition = [], $nullable = false): array
  172. {
  173. return array_merge([
  174. $this->isNullable($condition, $nullable) ? self::NULLABLE : self::REQUIRED,
  175. self::DATE
  176. ], is_array($condition) ? $condition : []);
  177. }
  178. protected function enum(array|bool $condition = [], $nullable = false): array
  179. {
  180. return array_merge([
  181. $this->isNullable($condition, $nullable) ? self::NULLABLE : self::REQUIRED,
  182. ], is_array($condition) ? $condition : []);
  183. }
  184. protected function image(array|bool $condition = [], $nullable = false): array
  185. {
  186. return array_merge([
  187. $this->isNullable($condition, $nullable) ? self::NULLABLE : self::REQUIRED,
  188. self::IMAGE
  189. ], is_array($condition) ? $condition : []);
  190. }
  191. protected function images(string $name, $nullable = false): array
  192. {
  193. $need = $nullable ? self::NULLABLE : self::REQUIRED;
  194. return [
  195. $name => [$need, self::ARRAY],
  196. sprintf("%s.*", $name) => [$need, self::IMAGE]
  197. ];
  198. }
  199. protected function file(array|bool $condition = [], $nullable = false): array
  200. {
  201. return array_merge([
  202. $this->isNullable($condition, $nullable) ? self::NULLABLE : self::REQUIRED,
  203. self::FILE
  204. ], is_array($condition) ? $condition : []);
  205. }
  206. protected function sortableRules()
  207. {
  208. return [
  209. BaseRepository::CONDITION_SORT_TARGET => $this->str(true),
  210. BaseRepository::CONDITION_SORT_ORDER => $this->str(true),
  211. BaseRepository::CONDITION_LIMIT => $this->numeric(true),
  212. ];
  213. }
  214. protected function timestamp(bool $nullable = false)
  215. {
  216. return [self::PARAM_NAME_TIMESTAMP => $this->date($nullable)];
  217. }
  218. }