diff --git a/modules/site_tools_msc_2020/src/Plugin/Field/FieldFormatter/MscTermListFormatter.php b/modules/site_tools_msc_2020/src/Plugin/Field/FieldFormatter/MscTermListFormatter.php new file mode 100644 index 0000000..3323d01 --- /dev/null +++ b/modules/site_tools_msc_2020/src/Plugin/Field/FieldFormatter/MscTermListFormatter.php @@ -0,0 +1,212 @@ +get('entity_type.manager'), + ); + } + + public static function isApplicable(FieldDefinitionInterface $field_definition): bool { + $storage = $field_definition->getFieldStorageDefinition(); + if ($storage->getSetting('target_type') !== 'taxonomy_term') { + return FALSE; + } + $handler_settings = $field_definition->getSetting('handler_settings'); + return !empty($handler_settings['target_bundles']['msc_2020']); + } + + public static function defaultSettings(): array { + return ['link_to_entity' => FALSE] + parent::defaultSettings(); + } + + public function settingsForm(array $form, FormStateInterface $form_state): array { + $elements = parent::settingsForm($form, $form_state); + $elements['link_to_entity'] = [ + '#type' => 'checkbox', + '#title' => $this->t('Link para a entidade referenciada'), + '#default_value' => $this->getSetting('link_to_entity'), + ]; + return $elements; + } + + public function settingsSummary(): array { + $summary = parent::settingsSummary(); + $summary[] = $this->getSetting('link_to_entity') + ? $this->t('Link para a entidade referenciada') + : $this->t('Sem link para a entidade referenciada'); + return $summary; + } + + public function viewElements(FieldItemListInterface $items, $langcode): array { + $tids = []; + foreach ($items as $item) { + if ($item instanceof EntityReferenceItem && !empty($item->target_id)) { + $tids[] = (int) $item->target_id; + } + } + + if (empty($tids)) { + return []; + } + + $link = (bool) $this->getSetting('link_to_entity'); + $storage = $this->entityTypeManager->getStorage('taxonomy_term'); + $terms = $storage->loadMultiple($tids); + + // Separa pais e filhos; coleta códigos de pais ausentes. + $parents_by_code = []; + $children_by_code = []; + $missing_codes = []; + + foreach ($terms as $term) { + $code = $term->get('field_msc_code')->value; + if (strlen($code) === 2) { + $parents_by_code[$code] = $term; + } + else { + $parent_code = substr($code, 0, 2); + $children_by_code[$parent_code][] = $term; + if (!isset($parents_by_code[$parent_code])) { + $missing_codes[$parent_code] = $parent_code; + } + } + } + + // Carrega pais que não foram selecionados mas são necessários para agrupar. + if (!empty($missing_codes)) { + $parent_tids = $storage->getQuery() + ->condition('vid', 'msc_2020') + ->condition('field_msc_code', array_values($missing_codes), 'IN') + ->accessCheck(FALSE) + ->execute(); + foreach ($storage->loadMultiple($parent_tids) as $term) { + $code = $term->get('field_msc_code')->value; + $parents_by_code[$code] = $term; + } + } + + // Ordena grupos por código. + $all_codes = array_unique( + array_merge(array_keys($parents_by_code), array_keys($children_by_code)) + ); + sort($all_codes); + + // Monta o render array como lista aninhada. + $build = [ + '#prefix' => '