getFromDB($entities_id) || !$entity->can($entities_id, UPDATE)) { Html::displayRightError(); } global $DB; if ($action === 'sync') { $metadata = PluginRedmineRedmineapi::syncMetadata(); if ($metadata !== false) { $DB->update('glpi_plugin_redmine_configs', [ 'metadata_cache' => json_encode($metadata) ], ['id' => 1]); PluginRedmineRedmineapi::syncUsers(); Session::addMessageAfterRedirect(__('Metadados sincronizados com sucesso!', 'redmine')); } else { Session::addMessageAfterRedirect(__('Erro ao sincronizar com o Redmine.', 'redmine'), false, ERROR); } } elseif ($action === 'set_category') { $DB->update('glpi_plugin_redmine_entities', [ 'default_category_id' => (int) ($_POST['default_category_id'] ?? 0) ], [ 'entities_id' => $entities_id ]); Session::addMessageAfterRedirect(__('Categoria padrão salva com sucesso!', 'redmine')); } elseif ($action === 'unlink') { $DB->delete('glpi_plugin_redmine_entities', ['entities_id' => $entities_id]); Session::addMessageAfterRedirect(__('Entidade desvinculada do Redmine.', 'redmine')); } elseif ($action === 'process') { $redmine_project_id = $_POST['redmine_project_id'] ?? ''; if (!empty($redmine_project_id)) { // LINK OPERATION $DB->insert('glpi_plugin_redmine_entities', [ 'entities_id' => $entities_id, 'redmine_project_id' => $redmine_project_id ]); Session::addMessageAfterRedirect(__('Entidade vinculada com sucesso!', 'redmine')); } else { // CREATE OPERATION $new_redmine_id = false; // Motor 2.0: template ativo tem precedência; erro de RENDER cai no 1.x. $tpl = PluginRedmineTemplateengine::getActive('create_project'); if ($tpl) { try { $ctx = PluginRedmineTemplateengine::buildFormContext($_POST); $rendered = PluginRedmineTemplateengine::render($tpl['template'], $ctx); if (!empty($rendered['project'])) { $new_redmine_id = PluginRedmineRedmineapi::createProjectFull($rendered['project']); } } catch (\Throwable $e) { Toolbox::logInFile('redmine', "Template create_project falhou no render (" . $e->getMessage() . ") — usando motor 1.x.\n"); $tpl = null; } } if (!$tpl) { $payload = [ 'name' => $_POST['name'], 'identifier' => $_POST['identifier'], 'description' => $_POST['description'], 'is_public' => !empty($_POST['is_public']) ]; if (!empty($_POST['parent_id'])) { $payload['parent_id'] = $_POST['parent_id']; } if (!empty($_POST['enabled_module_names'])) { $payload['enabled_module_names'] = $_POST['enabled_module_names']; } // Trackers do projeto: sem eles o Redmine recusa criar issues. if (!empty($_POST['tracker_ids']) && is_array($_POST['tracker_ids'])) { $tids = array_values(array_filter(array_map('intval', $_POST['tracker_ids']))); if (!empty($tids)) { $payload['tracker_ids'] = $tids; } } if (empty($payload['tracker_ids'])) { $cfg = PluginRedmineConfig::getConfigRow(); if (!empty($cfg['default_tracker_id'])) { $payload['tracker_ids'] = [(int) $cfg['default_tracker_id']]; } } // Custom fields de projeto (obrigatórios em alguns Redmine). // O empty-choice do dropdown envia '0' — descartar junto com vazios. if (!empty($_POST['custom_field_values']) && is_array($_POST['custom_field_values'])) { $cfv = []; foreach ($_POST['custom_field_values'] as $cfid => $cfval) { if ($cfval !== '' && $cfval !== null && $cfval !== '0' && $cfval !== 0) { $cfv[(string) (int) $cfid] = $cfval; } } if (!empty($cfv)) { $payload['custom_field_values'] = $cfv; } } $new_redmine_id = PluginRedmineRedmineapi::createProjectFull($payload); } // fim do motor 1.x if ($new_redmine_id) { $DB->insert('glpi_plugin_redmine_entities', [ 'entities_id' => $entities_id, 'redmine_project_id' => $new_redmine_id ]); Session::addMessageAfterRedirect(__('Projeto criado e vinculado à entidade com sucesso!', 'redmine')); } else { Session::addMessageAfterRedirect(__('Erro ao criar projeto no Redmine.', 'redmine'), false, ERROR); } } } Html::redirect($CFG_GLPI["root_doc"] . "/front/entity.form.php?id=" . $entities_id); } Html::displayErrorAndDie("Lost");