Files
structural_pages/imecc_menu_helper/imecc_menu_helper.module
Quintino A. G. Souza 276fd028f2 Add field_redirect_page to site_sections terms and fix root page hierarchy
- Add field_redirect_page to site_sections taxonomy terms, with a custom
  EntityReferenceSelection plugin that filters content_page nodes by section
- Redirect taxonomy term canonical URLs to the configured node (301)
- Fix root page detection in MenuBlock and views to also match nodes whose
  field_parent_page points to a taxonomy_term (not only empty parent)
- Move root taxonomy-term option to the top of the parent-page dropdown
- Add breadcrumb workaround for Gavias notech theme separator rendering
- Add imecc_menu_helper submodule
- Translate config labels and default terms from English to Portuguese

Co-Authored-By: Henrique Bauer <henrique@webcontent.com.br>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-05 07:52:49 -03:00

202 lines
6.4 KiB
Plaintext

<?php
use Drupal\node\NodeInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Menu\MenuTreeParameters;
use Drupal\Core\Routing\TrustedRedirectResponse;
use Drupal\Core\Url;
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
/**
* Implements hook_node_presave().
* (Mantido intacto)
*/
function imecc_menu_helper_node_presave(NodeInterface $node) {
if ($node->getType() != 'pagina') return;
$field_name = 'field_taxinomia_setor';
if (!$node->hasField($field_name) || $node->get($field_name)->isEmpty()) return;
$setor_tid = $node->get($field_name)->target_id;
$config = \Drupal::config('imecc_menu_helper.settings');
$parent_mapping_string = $config->get('mapping_' . $setor_tid);
if (empty($parent_mapping_string)) return;
$current_parent = $node->menu['menu_parent'] ?? 'main:';
if ($current_parent != 'main:') {
if ($current_parent != $parent_mapping_string) return;
}
if (!$node->isNew() && strpos($parent_mapping_string, $node->uuid()) !== false) return;
$node->menu['enabled'] = 1;
$node->menu['title'] = $node->getTitle();
$node->menu['menu_parent'] = $parent_mapping_string;
}
/**
* Implements hook_form_alter().
*/
function imecc_menu_helper_form_node_form_alter(&$form, FormStateInterface $form_state, $form_id) {
if (!in_array($form_id, ['node_pagina_form', 'node_pagina_edit_form'])) {
return;
}
// --- LÓGICA DO MENU (AJAX) ---
// REMOVIDO: O wrapper 'imecc-menu-wrapper' que causava erro.
// Agora atacamos direto o ID nativo 'edit-menu'.
if (isset($form['field_taxinomia_setor'])) {
$form['field_taxinomia_setor']['widget']['#ajax'] = [
'callback' => '_imecc_menu_helper_update_menu_options',
'wrapper' => 'edit-menu', // <--- CORREÇÃO: Volta para o ID nativo
'event' => 'change',
'progress' => [
'type' => 'throbber',
'message' => t('Carregando menu...'),
],
];
}
// --- LÓGICA DO REDIRECIONAMENTO (Barra Lateral) ---
$node = $form_state->getFormObject()->getEntity();
$should_open = FALSE;
if ($node->hasField('field_redirecionar_para') && !$node->get('field_redirecionar_para')->isEmpty()) {
$should_open = TRUE;
}
$form['redirection_settings'] = [
'#type' => 'details',
'#title' => t('Redirecionamento'),
'#group' => 'advanced',
'#open' => $should_open,
'#weight' => -10,
'#attributes' => [
'class' => ['node-form-redirection-settings'],
],
];
if (isset($form['field_redirecionar_para'])) {
$form['field_redirecionar_para']['#group'] = 'redirection_settings';
}
}
/**
* Callback AJAX (CORRIGIDO)
*/
function _imecc_menu_helper_update_menu_options(array &$form, FormStateInterface $form_state) {
$values = $form_state->getValue('field_taxinomia_setor');
$tid = 0;
if (is_array($values) && isset($values[0]['target_id'])) {
$tid = $values[0]['target_id'];
} elseif (is_array($values) && isset($values['target_id'])) {
$tid = $values['target_id'];
} elseif (is_numeric($values)) {
$tid = $values;
}
// CORREÇÃO: Garante que o ID do formulário se mantenha estável para não quebrar o AJAX
$form['menu']['#attributes']['id'] = 'edit-menu';
if (empty($tid)) return $form['menu'];
$config = \Drupal::config('imecc_menu_helper.settings');
$parent_mapping_string = $config->get('mapping_' . $tid);
if (empty($parent_mapping_string)) return $form['menu'];
list($menu_name, $root_plugin_id) = explode(':', $parent_mapping_string, 2);
/** @var \Drupal\Core\Menu\MenuLinkTreeInterface $menu_tree_service */
$menu_tree_service = \Drupal::service('menu.link_tree');
$parameters = new MenuTreeParameters();
$parameters->setRoot($root_plugin_id);
$parameters->excludeRoot();
$parameters->setMaxDepth(NULL);
$tree = $menu_tree_service->load($menu_name, $parameters);
$allowed_ids = [];
$allowed_ids[$parent_mapping_string] = true;
_imecc_menu_helper_extract_ids($tree, $menu_name, $allowed_ids);
if (isset($form['menu']['link']['menu_parent']['#options'])) {
$options = $form['menu']['link']['menu_parent']['#options'];
$filtered_options = [];
foreach ($options as $key => $label) {
if (isset($allowed_ids[$key])) {
$filtered_options[$key] = $label;
}
}
if (empty($filtered_options) && isset($options[$parent_mapping_string])) {
$filtered_options[$parent_mapping_string] = $options[$parent_mapping_string];
}
$form['menu']['link']['menu_parent']['#options'] = $filtered_options;
$current_val = $form_state->getValue(['menu', 'link', 'menu_parent']);
if (empty($current_val) || !isset($filtered_options[$current_val])) {
$form['menu']['link']['menu_parent']['#value'] = $parent_mapping_string;
}
}
$form['menu']['#open'] = TRUE;
if (isset($form['menu']['enabled'])) {
$form['menu']['enabled']['#value'] = 1;
}
// CORREÇÃO: Retorna o array direto, sem envelopar em arrays novos
return $form['menu'];
}
/**
* Função auxiliar recursiva (Mantida intacta)
*/
function _imecc_menu_helper_extract_ids(array $tree, $menu_name, array &$allowed_ids) {
foreach ($tree as $element) {
$plugin_id = $element->link->getPluginId();
$key = $menu_name . ':' . $plugin_id;
$allowed_ids[$key] = true;
if ($element->subtree) {
_imecc_menu_helper_extract_ids($element->subtree, $menu_name, $allowed_ids);
}
}
}
/**
* Implements hook_node_view().
* (Mantido intacto)
*/
function imecc_menu_helper_node_view(array &$build, NodeInterface $node, EntityViewDisplayInterface $display, $view_mode) {
if ($view_mode !== 'full') return;
$route_name = \Drupal::routeMatch()->getRouteName();
if ($route_name != 'entity.node.canonical') return;
$field_redirect = 'field_redirecionar_para';
if ($node->hasField($field_redirect) && !$node->get($field_redirect)->isEmpty()) {
$url_object = $node->get($field_redirect)->first()->getUrl();
$destination = $url_object->toString();
$current_url = Url::fromRoute('<current>')->toString();
if ($destination == $current_url) return;
$response = new TrustedRedirectResponse($destination, 302);
$response->addCacheableDependency($node);
$response->send();
exit;
}
}