領収証発行サービス
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.

239 lines
7.1KB

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