diff --git a/modules/edw_document/src/Plugin/Field/FieldWidget/FileMultiLanguageWidget.php b/modules/edw_document/src/Plugin/Field/FieldWidget/FileMultiLanguageWidget.php index cf572b8..f80b364 100755 --- a/modules/edw_document/src/Plugin/Field/FieldWidget/FileMultiLanguageWidget.php +++ b/modules/edw_document/src/Plugin/Field/FieldWidget/FileMultiLanguageWidget.php @@ -98,14 +98,15 @@ public static function create(ContainerInterface $container, array $configuratio protected function formMultipleElements(FieldItemListInterface $items, array &$form, FormStateInterface $form_state) { $fieldName = $this->fieldDefinition->getName(); $languages = $this->languageManager->getLanguages(); + $selectedValues = $form_state->getValue($fieldName); $currentLangcode = $this->languageManager->getCurrentLanguage()->getId(); - /** @var \Drupal\Core\Entity\ContentEntityBase $entity */ $entity = $items->getEntity(); $elements = []; $elements['#type'] = 'details'; $elements['#open'] = TRUE; $elements['#title'] = $this->fieldDefinition->getLabel(); + $elements['#element_validate'] = [[$this, 'validate']]; $elements['languages'] = [ '#type' => 'horizontal_tabs', @@ -126,17 +127,49 @@ protected function formMultipleElements(FieldItemListInterface $items, array &$f $this->singleFieldIsRequired = $this->fieldDefinition->isRequired() && $language->isDefault(); if ($entity->hasTranslation($language->getId())) { - $translatedField = $entity->getTranslation($language->getId())->get($fieldName); + $translatedField = $entity->getTranslation($language->getId()) + ->get($fieldName); $elements['languages'][$language->getId()]['data'] = parent::formMultipleElements($translatedField, $form, $form_state); + $this->fixWidgetFileItems($elements, $selectedValues, $language->getId()); continue; } $elements['languages'][$language->getId()]['data'] = parent::formMultipleElements($this->getEmptyField($items), $form, $form_state); + $this->fixWidgetFileItems($elements, $selectedValues, $language->getId()); } + return $elements; } + public function fixWidgetFileItems(array &$element, ?array $selectedValues, $langCode) { + if (empty($selectedValues) || array_key_exists($langCode, $selectedValues['languages'])) { + return; + } + + foreach ($element['languages'][$langCode]['data'] as $key => $item) { + if (!is_array($item) || !isset($item['#default_value']['fids'])) { + continue; + } + + $foundFile = FALSE; + foreach ($selectedValues['languages'] as $languageFile) { + if ($foundFile) { + break; + } + + foreach ($languageFile['data'] as $selectedItem) { + $commonFids = array_intersect($selectedItem['fids'], $item['#default_value']['fids']); + if (!empty($commonFids)) { + unset($element['languages'][$langCode]['data'][$key]); + $foundFile = TRUE; + break; + } + } + } + } + } + /** * {@inheritdoc} * @@ -185,7 +218,8 @@ public function extractFormValues(FieldItemListInterface $items, array $form, Fo $entity->getTranslation($langcode) : $entity->addTranslation($langcode, $values); - $translationValues = array_column($translation->get($field_name)->getValue(), 'target_id'); + $translationValues = array_column($translation->get($field_name) + ->getValue(), 'target_id'); if (in_array($item['target_id'], $translationValues)) { continue; } @@ -282,6 +316,66 @@ public function extractFormValuesMultiLanguage(FieldItemListInterface $items, ar } } + /** + * Validates if the same file is added on different languages. + * + * @param array $element + * The widget form element. + * @param \Drupal\Core\Form\FormStateInterface $formState + * The form state. + * + * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException + * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException + */ + public function validate(array $element, FormStateInterface $formState) { + $fileStorage = $this->entityTypeManager->getStorage('file'); + $value = $formState->getValue($this->fieldDefinition->getName()); + $userInput = $formState->getUserInput(); + // Check if there is not an AJAX request. + if (!$formState->isSubmitted() || !empty($userInput['_drupal_ajax'])) { + return; + } + + if (empty($value) || !isset($value['languages'])) { + return; + } + + $fileLangMap = []; + foreach ($value['languages'] as $langCode => $items) { + if (!isset($items['data'])) { + continue; + } + + foreach ($items['data'] as $item) { + foreach ($item['fids'] as $fid) { + /** @var \Drupal\file\Entity\File $file */ + $file = $fileStorage->load($fid); + $sha = hash_file('sha256', $file->getFileUri()); + if (!isset($fileLangMap[$sha])) { + $fileLangMap[$sha] = [$langCode]; + continue; + } + + if (!in_array($langCode, $fileLangMap[$sha])) { + $languages = [ + $this->languageManager->getLanguage($fileLangMap[$sha][0]) + ->getName(), + ]; + $languages[] = $this->languageManager->getLanguage($langCode) + ->getName(); + + $formState->setError($element, $this->t('Same file, %fileName, appears multiple times for different languages: %languages.', [ + '%fileName' => $file->getFilename(), + '%languages' => implode(', ', $languages), + ])); + return; + } + } + } + } + + } + /** * {@inheritdoc} */