NamingRuleCheck.php 3.9 KB

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