NamingRuleCheck.php 3.8 KB

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