diff --git a/src/Fields/Spatie/Translatable.php b/src/Fields/Spatie/Translatable.php new file mode 100644 index 000000000..617103197 --- /dev/null +++ b/src/Fields/Spatie/Translatable.php @@ -0,0 +1,128 @@ +requiredLanguagesCodes = $languages; + + return $this; + } + + /** + * @param array $languages Массив кодов языков, которые которые будут вверху select языков + * @return $this + */ + public function priorityLanguages(array $languages): static + { + sort($languages); + $this->priorityLanguagesCodes = $languages; + + return $this; + } + + protected function getLanguagesCodes(): array + { + sort($this->languagesCodes); + + return collect(array_combine($this->requiredLanguagesCodes, $this->requiredLanguagesCodes)) + ->merge(array_combine($this->priorityLanguagesCodes, $this->priorityLanguagesCodes)) + ->merge(array_combine($this->languagesCodes, $this->languagesCodes)) + ->toArray(); + } + + public function keyValue(string $key = 'Language', string $value = 'Value'): static + { + $this->fields([ + Select::make($key, 'key') + ->options($this->getLanguagesCodes()) + ->nullable(), + Text::make($value, 'value'), + ]); + + return $this; + } + + public function getFields(): array + { + + if (empty($this->fields)) { + $this->fields([ + Select::make('Language', 'key') + ->options(array_combine($this->getLanguagesCodes(), array_map(fn($code) => Str::upper($code), $this->getLanguagesCodes()))) + ->nullable(), + Text::make('Value', 'value'), + ]); + } + + return parent::getFields(); + } + + public function hasFields(): bool + { + return true; + } + + public function indexViewValue(Model $item, bool $container = false): string + { + return $item->{$this->field()}; + } + + public function exportViewValue(Model $item): string + { + return $item->{$this->field()}; + } + + public function formViewValue(Model $item): mixed + { + return $item->getTranslations($this->field()); + } + + public function save(Model $item): Model + { + if ($this->requestValue() !== false) { + $array = collect($this->requestValue()) + ->filter(fn($data) => !empty($data['key']) && !empty($data['value'])) + ->mapWithKeys(fn($data) => [$data['key'] => $data['value']]) + ->toArray(); + + $notSetLanguages = array_diff($this->requiredLanguagesCodes, array_keys($array)); + + if (!empty($notSetLanguages)) { + throw ValidationException::withMessages( + [$this->field() => + sprintf('Для поля %s не заданы значения переводов на языки: %s', $this->label(), implode(', ', $notSetLanguages))]); + } + + $item->{$this->field()} = $array(); + } + + return $item; + } + +}