getFromDB($projects_id) || !$project->can($projects_id, UPDATE)) { Html::displayRightError(); } if ($action === 'sync') { // Full metadata sync (partial sync used to wipe trackers/statuses from the cache). $metadata = PluginRedmineRedmineapi::syncMetadata(); if ($metadata !== false) { global $DB; $DB->update('glpi_plugin_redmine_configs', [ 'metadata_cache' => json_encode($metadata) ], [ 'id' => 1 ]); PluginRedmineRedmineapi::syncUsers(); Session::addMessageAfterRedirect("Metadados sincronizados com sucesso!"); } else { Session::addMessageAfterRedirect("Erro ao sincronizar com Redmine.", false, ERROR); } } elseif ($action === 'set_category') { global $DB; $DB->update('glpi_plugin_redmine_projects', [ 'default_category_id' => (int) ($_POST['default_category_id'] ?? 0) ], [ 'projects_id' => $projects_id ]); Session::addMessageAfterRedirect("Categoria padrão salva com sucesso!"); } elseif ($action === 'unlink') { global $DB; $DB->delete('glpi_plugin_redmine_projects', ['projects_id' => $projects_id]); Session::addMessageAfterRedirect("Projeto desvinculado do Redmine."); } elseif ($action === 'process') { $redmine_project_id = $_POST['redmine_project_id'] ?? ''; if (!empty($redmine_project_id)) { // LINK OPERATION global $DB; $DB->insert('glpi_plugin_redmine_projects', [ 'projects_id' => $projects_id, 'redmine_project_id' => $redmine_project_id ]); Session::addMessageAfterRedirect("Projeto vinculado com sucesso!"); } else { // CREATE OPERATION $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); if ($new_redmine_id) { global $DB; $DB->insert('glpi_plugin_redmine_projects', [ 'projects_id' => $projects_id, 'redmine_project_id' => $new_redmine_id ]); Session::addMessageAfterRedirect("Projeto criado e vinculado com sucesso!"); } else { Session::addMessageAfterRedirect("Erro ao criar projeto no Redmine.", false, ERROR); } } } Html::redirect($CFG_GLPI["root_doc"] . "/front/project.form.php?id=" . $projects_id); } Html::displayErrorAndDie("Lost");