|
@@ -0,0 +1,107 @@
|
|
|
+<?php
|
|
|
+
|
|
|
+namespace App\Services\NamingRule;
|
|
|
+
|
|
|
+use App\Models\Asset;
|
|
|
+use App\Models\CustomField;
|
|
|
+use App\Models\Enums\CustomFieldType;
|
|
|
+use App\Models\Enums\FileObjectType;
|
|
|
+use App\Models\Enums\LibraryType;
|
|
|
+use App\Models\Project;
|
|
|
+use Illuminate\Database\Eloquent\Collection;
|
|
|
+
|
|
|
+class NamingRuleCheck
|
|
|
+{
|
|
|
+ protected ?Collection $customFieldsKeyBy = null;
|
|
|
+
|
|
|
+ public function __construct(
|
|
|
+ protected FileObjectType $fileObjectType,
|
|
|
+ protected ?object $object = null
|
|
|
+ )
|
|
|
+ {
|
|
|
+ if ($this->object) {
|
|
|
+ $this->customFieldsKeyBy = CustomField::query()
|
|
|
+ ->where("group", $this->object->naming_rule_id)
|
|
|
+ ->get()
|
|
|
+ ->keyBy("key");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public function check(string $name)
|
|
|
+ {
|
|
|
+ if (! $this->object || ! $this->object->namingRule) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ $fileName = pathinfo($name)['filename'];
|
|
|
+
|
|
|
+ $result = $this->parse($fileName, $this->getNamingRuleCode(), $this->object->namingRule->combination_rules);
|
|
|
+
|
|
|
+ throw_validation_if(! $result, sprintf("'%s' does not conform to the naming rules", $fileName));
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ protected function parse(string $name, string $code, array $rules): bool|array
|
|
|
+ {
|
|
|
+ if (!str_starts_with($name, $code)) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ $remainingString = substr($name, strlen($code));
|
|
|
+
|
|
|
+ $items = [];
|
|
|
+ foreach ($rules as $rule) {
|
|
|
+ $expectedLink = $rule['link']; // 期望的连接符
|
|
|
+
|
|
|
+ if (!str_starts_with($remainingString, $expectedLink)) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ $remainingString = substr($remainingString, strlen($expectedLink));
|
|
|
+
|
|
|
+ $nextLinkPos = false;
|
|
|
+ foreach ($rules as $r) {
|
|
|
+ $pos = strpos($remainingString, $r['link']);
|
|
|
+ if ($pos !== false && $pos > 0) {
|
|
|
+ $nextLinkPos = $pos;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if ($nextLinkPos !== false) {
|
|
|
+ $fieldValue = substr($remainingString, 0, $nextLinkPos);
|
|
|
+ $remainingString = substr($remainingString, $nextLinkPos);
|
|
|
+ } else {
|
|
|
+ $fieldValue = $remainingString;
|
|
|
+ $remainingString = '';
|
|
|
+ }
|
|
|
+
|
|
|
+ $customField = $this->customFieldsKeyBy[$rule['field']];
|
|
|
+ if ($customField->type == CustomFieldType::SELECT->value) {
|
|
|
+ if (! in_array($fieldValue, array_column($customField->options, "value"))) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ $items[$customField->key] = $fieldValue;
|
|
|
+ }
|
|
|
+
|
|
|
+ return $items;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ protected function getNamingRuleCode()
|
|
|
+ {
|
|
|
+ $library = $this->object->library;
|
|
|
+
|
|
|
+ $code = match (LibraryType::tryFrom($library->type)) {
|
|
|
+ LibraryType::PROJECT => Project::query()->find($library->project_id)?->code,
|
|
|
+ LibraryType::ASSET => Asset::query()->find($library->asset_id)?->code,
|
|
|
+ LibraryType::CUSTOM => "custom"
|
|
|
+ };
|
|
|
+
|
|
|
+ throw_validation_if(! $code, "The supported type or selected item does not exist");
|
|
|
+
|
|
|
+ return $code;
|
|
|
+ }
|
|
|
+}
|