From 1b790354a3acd25590206643d7a9fed672613fc7 Mon Sep 17 00:00:00 2001 From: Gemini Date: Thu, 2 Jul 2026 11:18:27 -0300 Subject: [PATCH] =?UTF-8?q?fix:=20envia=20tracker=5Fids=20na=20cria=C3=A7?= =?UTF-8?q?=C3=A3o=20de=20projeto=20(sem=20tracker,=20Redmine=20recusa=20i?= =?UTF-8?q?ssues)=20(1.5.7)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5 --- CHANGELOG.md | 10 ++++++++++ front/entity.form.php | 14 ++++++++++++++ front/project.form.php | 14 ++++++++++++++ inc/entity.class.php | 2 ++ inc/project.class.php | 20 ++++++++++++++++++++ setup.php | 2 +- templates/project_form.html.twig | 7 +++++++ 7 files changed, 68 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 09516f3..62fd7cc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,16 @@ Todas as mudanças relevantes deste plugin são documentadas aqui. O formato segue [Keep a Changelog](https://keepachangelog.com/pt-BR/1.0.0/) e o versionamento segue [SemVer](https://semver.org/lang/pt-BR/). +## [1.5.7] + +### Corrigido +- **Projetos criados pelo plugin nasciam SEM trackers** quando a instância Redmine + não tem "trackers padrão para novos projetos" — e sem tracker o Redmine recusa + criar issues (integração silenciosamente inoperante no projeto novo). O form de + criação agora tem o multiselect **"Tipos de tarefa (Trackers)"** (pré-selecionado + com o tracker padrão da config) e envia `tracker_ids`; sem seleção, usa o tracker + padrão como fallback. + ## [1.5.6] ### Corrigido diff --git a/front/entity.form.php b/front/entity.form.php index 335b1c7..8b0afe5 100644 --- a/front/entity.form.php +++ b/front/entity.form.php @@ -64,6 +64,20 @@ if (isset($_POST["action"])) { $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'])) { diff --git a/front/project.form.php b/front/project.form.php index 2a59303..b7446fa 100644 --- a/front/project.form.php +++ b/front/project.form.php @@ -71,6 +71,20 @@ if (isset($_POST["action"])) { $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'])) { diff --git a/inc/entity.class.php b/inc/entity.class.php index 5ea7dd5..fe191d4 100644 --- a/inc/entity.class.php +++ b/inc/entity.class.php @@ -76,6 +76,8 @@ class PluginRedmineEntity extends CommonDBTM { 'owner_id' => $entities_id, 'project_options' => PluginRedmineProject::getRedmineProjectOptions(true), 'custom_fields' => PluginRedmineProject::getProjectCustomFieldDefs(), + 'tracker_options' => PluginRedmineProject::getTrackerOptions(), + 'default_tracker_ids' => ($dt = (int) (PluginRedmineConfig::getConfigRow()['default_tracker_id'] ?? 0)) ? [$dt] : [], 'project_name' => $entity->fields['name'], 'project_description' => $description, 'project_identifier' => 'glpi-ent-' . $entities_id, diff --git a/inc/project.class.php b/inc/project.class.php index a5a4ded..0c69b44 100644 --- a/inc/project.class.php +++ b/inc/project.class.php @@ -76,6 +76,8 @@ class PluginRedmineProject extends CommonDBTM { 'owner_id' => $projects_id, 'project_options' => self::getRedmineProjectOptions(true), 'custom_fields' => self::getProjectCustomFieldDefs(), + 'tracker_options' => self::getTrackerOptions(), + 'default_tracker_ids' => ($dt = (int) (PluginRedmineConfig::getConfigRow()['default_tracker_id'] ?? 0)) ? [$dt] : [], 'project_name' => $project->fields['name'], 'project_description' => $description, 'project_identifier' => 'glpi-proj-' . $projects_id, @@ -108,6 +110,24 @@ class PluginRedmineProject extends CommonDBTM { return $opts; } + /** + * {id: name} map of the cached Redmine trackers (for the create form). + * @return array + */ + static function getTrackerOptions() { + global $DB; + $it = $DB->request(['FROM' => 'glpi_plugin_redmine_configs', 'WHERE' => ['id' => 1]]); + $config = count($it) > 0 ? $it->current() : []; + $metadata = !empty($config['metadata_cache']) ? json_decode($config['metadata_cache'], true) : []; + $opts = []; + foreach (($metadata['trackers'] ?? []) as $t) { + if (isset($t['id'], $t['name'])) { + $opts[$t['id']] = $t['name']; + } + } + return $opts; + } + /** * Project custom field definitions for the create form (from metadata cache). * Some Redmine setups make these mandatory on project creation. diff --git a/setup.php b/setup.php index 657c9a5..4ec09c0 100644 --- a/setup.php +++ b/setup.php @@ -1,6 +1,6 @@