fix: envia tracker_ids na criação de projeto (sem tracker, Redmine recusa issues) (1.5.7)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Gemini 2026-07-02 11:18:27 -03:00
parent 27ee6addeb
commit 1b790354a3
7 changed files with 68 additions and 1 deletions

View file

@ -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/) 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/). 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] ## [1.5.6]
### Corrigido ### Corrigido

View file

@ -64,6 +64,20 @@ if (isset($_POST["action"])) {
$payload['enabled_module_names'] = $_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). // Custom fields de projeto (obrigatórios em alguns Redmine).
// O empty-choice do dropdown envia '0' — descartar junto com vazios. // O empty-choice do dropdown envia '0' — descartar junto com vazios.
if (!empty($_POST['custom_field_values']) && is_array($_POST['custom_field_values'])) { if (!empty($_POST['custom_field_values']) && is_array($_POST['custom_field_values'])) {

View file

@ -71,6 +71,20 @@ if (isset($_POST["action"])) {
$payload['enabled_module_names'] = $_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). // Custom fields de projeto (obrigatórios em alguns Redmine).
// O empty-choice do dropdown envia '0' — descartar junto com vazios. // O empty-choice do dropdown envia '0' — descartar junto com vazios.
if (!empty($_POST['custom_field_values']) && is_array($_POST['custom_field_values'])) { if (!empty($_POST['custom_field_values']) && is_array($_POST['custom_field_values'])) {

View file

@ -76,6 +76,8 @@ class PluginRedmineEntity extends CommonDBTM {
'owner_id' => $entities_id, 'owner_id' => $entities_id,
'project_options' => PluginRedmineProject::getRedmineProjectOptions(true), 'project_options' => PluginRedmineProject::getRedmineProjectOptions(true),
'custom_fields' => PluginRedmineProject::getProjectCustomFieldDefs(), '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_name' => $entity->fields['name'],
'project_description' => $description, 'project_description' => $description,
'project_identifier' => 'glpi-ent-' . $entities_id, 'project_identifier' => 'glpi-ent-' . $entities_id,

View file

@ -76,6 +76,8 @@ class PluginRedmineProject extends CommonDBTM {
'owner_id' => $projects_id, 'owner_id' => $projects_id,
'project_options' => self::getRedmineProjectOptions(true), 'project_options' => self::getRedmineProjectOptions(true),
'custom_fields' => self::getProjectCustomFieldDefs(), '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_name' => $project->fields['name'],
'project_description' => $description, 'project_description' => $description,
'project_identifier' => 'glpi-proj-' . $projects_id, 'project_identifier' => 'glpi-proj-' . $projects_id,
@ -108,6 +110,24 @@ class PluginRedmineProject extends CommonDBTM {
return $opts; 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). * Project custom field definitions for the create form (from metadata cache).
* Some Redmine setups make these mandatory on project creation. * Some Redmine setups make these mandatory on project creation.

View file

@ -1,6 +1,6 @@
<?php <?php
define('PLUGIN_REDMINE_VERSION', '1.5.6'); define('PLUGIN_REDMINE_VERSION', '1.5.7');
/** /**
* Load the Mindplace License class if the autoloader has not run yet. * Load the Mindplace License class if the autoloader has not run yet.

View file

@ -59,6 +59,13 @@
'full_width': true 'full_width': true
}) }} }) }}
{{ fields.dropdownArrayField('tracker_ids', '', tracker_options|default({}), __('Tipos de tarefa (Trackers)', 'redmine'), {
'multiple': true,
'values': default_tracker_ids|default([]),
'full_width': true,
'helper': __('Sem tracker habilitado o Redmine não permite criar tarefas no projeto.', 'redmine')
}) }}
{# Campos personalizados de projeto do Redmine (alguns são obrigatórios na criação) #} {# Campos personalizados de projeto do Redmine (alguns são obrigatórios na criação) #}
{% for cf in custom_fields|default([]) %} {% for cf in custom_fields|default([]) %}
{% if cf.field_format == 'list' and cf.options is not empty %} {% if cf.field_format == 'list' and cf.options is not empty %}