NamingRuleCheck.php 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. <?php
  2. namespace App\Services\NamingRule;
  3. use App\Models\Asset;
  4. use App\Models\CustomField;
  5. use App\Models\Enums\CustomFieldType;
  6. use App\Models\Enums\FileObjectType;
  7. use App\Models\Enums\LibraryType;
  8. use App\Models\Project;
  9. use Illuminate\Database\Eloquent\Collection;
  10. class NamingRuleCheck
  11. {
  12. protected ?Collection $customFieldsKeyBy = null;
  13. public function __construct(
  14. protected FileObjectType $fileObjectType,
  15. protected ?object $object = null
  16. )
  17. {
  18. if ($this->object) {
  19. $this->customFieldsKeyBy = CustomField::query()
  20. ->where("group", $this->object->naming_rule_id)
  21. ->get()
  22. ->keyBy("key");
  23. }
  24. }
  25. public function check(string $name)
  26. {
  27. if (! $this->object || ! $this->object->namingRule) {
  28. return;
  29. }
  30. $fileName = pathinfo($name)['filename'];
  31. $result = $this->parse($fileName, $this->getNamingRuleCode(), $this->object->namingRule->combination_rules);
  32. throw_validation_if(! $result, sprintf("'%s' does not conform to the naming rules", $fileName));
  33. }
  34. protected function parse(string $name, string $code, array $rules): bool|array
  35. {
  36. if (!str_starts_with($name, $code)) {
  37. return false;
  38. }
  39. $remainingString = substr($name, strlen($code));
  40. $items = [];
  41. foreach ($rules as $rule) {
  42. $expectedLink = $rule['link']; // 期望的连接符
  43. if (!str_starts_with($remainingString, $expectedLink)) {
  44. return false;
  45. }
  46. $remainingString = substr($remainingString, strlen($expectedLink));
  47. $nextLinkPos = false;
  48. foreach ($rules as $r) {
  49. $pos = strpos($remainingString, $r['link']);
  50. if ($pos !== false && $pos > 0) {
  51. $nextLinkPos = $pos;
  52. break;
  53. }
  54. }
  55. if ($nextLinkPos !== false) {
  56. $fieldValue = substr($remainingString, 0, $nextLinkPos);
  57. $remainingString = substr($remainingString, $nextLinkPos);
  58. } else {
  59. $fieldValue = $remainingString;
  60. $remainingString = '';
  61. }
  62. $customField = $this->customFieldsKeyBy[$rule['field']];
  63. if ($customField->type == CustomFieldType::SELECT->value) {
  64. if (! in_array($fieldValue, array_column($customField->options, "value"))) {
  65. return false;
  66. }
  67. }
  68. $items[$customField->key] = $fieldValue;
  69. }
  70. return $items;
  71. }
  72. protected function getNamingRuleCode()
  73. {
  74. $library = $this->object->library;
  75. $code = match (LibraryType::tryFrom($library->type)) {
  76. LibraryType::PROJECT => Project::query()->find($library->project_id)?->code,
  77. LibraryType::ASSET => Asset::query()->find($library->asset_id)?->code,
  78. LibraryType::CUSTOM => "custom"
  79. };
  80. throw_validation_if(! $code, "The supported type or selected item does not exist");
  81. return $code;
  82. }
  83. }