ContentInput.php 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. <?php
  2. declare(strict_types=1);
  3. namespace plugin\saiadmin\app\service\content;
  4. use plugin\saiadmin\exception\ApiException;
  5. /** Validated content configuration shared by every save entry point. */
  6. final class ContentInput
  7. {
  8. public static function text(array $input, string $key, int $max, string $default = ''): string
  9. {
  10. $value = $input[$key] ?? $default;
  11. if (!is_string($value) || mb_strlen($value) > $max) {
  12. throw new ApiException('内容字段格式或长度不正确:'.$key);
  13. }
  14. return trim($value);
  15. }
  16. public static function integer(array $input, string $key, int $default, int $min, int $max): int
  17. {
  18. $value = $input[$key] ?? $default;
  19. if (filter_var($value, FILTER_VALIDATE_INT) === false || (int)$value < $min || (int)$value > $max) {
  20. throw new ApiException('内容数字字段不正确:'.$key);
  21. }
  22. return (int)$value;
  23. }
  24. public static function values(array $input): array
  25. {
  26. $values = [];
  27. foreach (['title' => 120, 'audience' => 30, 'region' => 80, 'image_url' => 500, 'target_url' => 500] as $key => $max) {
  28. $values[$key] = self::text($input, $key, $max);
  29. }
  30. if ($values['title'] === '') throw new ApiException('请填写内容标题');
  31. if (!in_array($values['audience'], ['all', 'new', 'purchased', 'enterprise_admin'], true)) {
  32. throw new ApiException('投放人群不支持');
  33. }
  34. if ($values['region'] === '全国') $values['region'] = '';
  35. foreach (['image_url', 'target_url'] as $key) {
  36. $url = $values[$key];
  37. if ($url !== '' && (!filter_var($url, FILTER_VALIDATE_URL) || !preg_match('#^https?://[^\s]+$#iD', $url))) {
  38. throw new ApiException('图片和活动链接必须是有效的 http 或 https 地址');
  39. }
  40. }
  41. foreach (['starts_at', 'ends_at'] as $key) {
  42. $value = self::text($input, $key, 19);
  43. if ($value !== '') {
  44. if (!preg_match('/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/D', $value)) {
  45. throw new ApiException('活动时间格式不正确');
  46. }
  47. $date = \DateTimeImmutable::createFromFormat('!Y-m-d H:i:s', $value, new \DateTimeZone('Asia/Shanghai'));
  48. if (!$date || $date->format('Y-m-d H:i:s') !== $value || $value < '2000-01-01 00:00:00') {
  49. throw new ApiException('活动时间不正确,请选择2000年之后的日期');
  50. }
  51. }
  52. $values[$key] = $value === '' ? null : $value;
  53. }
  54. if ($values['starts_at'] && $values['ends_at'] && $values['starts_at'] >= $values['ends_at']) {
  55. throw new ApiException('结束时间必须晚于开始时间');
  56. }
  57. $values['status'] = self::integer($input, 'status', 1, 1, 2);
  58. $values['sort'] = self::integer($input, 'sort', 0, 0, 10000000);
  59. return $values;
  60. }
  61. }