- docs/DESIGN-2.0.md: decisões fechadas (tags PT, editor linha-a-linha,
escopo global, dry-run com preview) e arquitetura Motor x Template
- PluginRedmineTemplateengine: render mustache-like ({{ var | filtro }}),
regra de tipos (tag inteira = tipo nativo), lookup indexado
(map.status[chamado.status]), filtros (truncar, sem_html, minusculo,
identificador, padrao), prune de nulls, seeds 1.x-equivalentes e
descoberta de custom fields obrigatórios
- tabela glpi_plugin_redmine_templates (operation único, is_active)
- wiring com precedência de template + fallback no render em
create_issue, log_time e update_status
- validado: 12/12 unit + E2E (template ativo cria issue/tempo; template
quebrado cai no motor 1.x sem perder lançamento)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
119 lines
3.4 KiB
PHP
119 lines
3.4 KiB
PHP
<?php
|
|
|
|
define('PLUGIN_REDMINE_VERSION', '2.0.0-dev');
|
|
|
|
/**
|
|
* Load the Mindplace License class if the autoloader has not run yet.
|
|
* Needed because this plugin may initialize before mindplace.
|
|
*/
|
|
function plugin_redmine_load_license() {
|
|
if (class_exists('\GlpiPlugin\Mindplace\License')) {
|
|
return;
|
|
}
|
|
foreach ([
|
|
GLPI_ROOT . '/plugins/mindplace/src/License.php',
|
|
GLPI_ROOT . '/marketplace/mindplace/src/License.php',
|
|
] as $path) {
|
|
if (file_exists($path)) {
|
|
include_once $path;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Init hooks of the plugin.
|
|
*/
|
|
function plugin_init_redmine() {
|
|
global $PLUGIN_HOOKS;
|
|
|
|
$PLUGIN_HOOKS['csrf_compliant']['redmine'] = true;
|
|
|
|
// ──────────────────────────────────────────────────────────────────
|
|
// KILL SWITCH — aborta silenciosamente se a licença Mindtek for inválida
|
|
// ──────────────────────────────────────────────────────────────────
|
|
plugin_redmine_load_license();
|
|
if (!class_exists('\GlpiPlugin\Mindplace\License') || !\GlpiPlugin\Mindplace\License::isValid()) {
|
|
return;
|
|
}
|
|
|
|
// Register classes
|
|
Plugin::registerClass('PluginRedmineConfig', [
|
|
'addtabon' => ['Config']
|
|
]);
|
|
Plugin::registerClass('PluginRedmineProject', [
|
|
'addtabon' => ['Project']
|
|
]);
|
|
Plugin::registerClass('PluginRedmineEntity', [
|
|
'addtabon' => ['Entity']
|
|
]);
|
|
|
|
// Set configuration page
|
|
$PLUGIN_HOOKS['config_page']['redmine'] = 'front/config.form.php';
|
|
|
|
// Hook to intercept item creation
|
|
$PLUGIN_HOOKS['item_add']['redmine'] = [
|
|
'TicketTask' => 'plugin_redmine_tickettask_add'
|
|
];
|
|
|
|
// Hook to intercept item updates
|
|
$PLUGIN_HOOKS['item_update']['redmine'] = [
|
|
'TicketTask' => 'plugin_redmine_tickettask_update',
|
|
'Ticket' => 'plugin_redmine_ticket_update'
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Get the name and the version of the plugin
|
|
*
|
|
* @return array
|
|
*/
|
|
function plugin_version_redmine() {
|
|
return [
|
|
'name' => 'Redmine Integration',
|
|
'version' => PLUGIN_REDMINE_VERSION,
|
|
'author' => 'Mindtek',
|
|
'license' => 'GPLv3+',
|
|
'homepage' => '',
|
|
'requirements' => [
|
|
'glpi' => [
|
|
'min' => '11.0.0',
|
|
'max' => '11.99.99'
|
|
]
|
|
]
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Check pre-requisites before install
|
|
*
|
|
* @return boolean
|
|
*/
|
|
function plugin_redmine_check_prerequisites() {
|
|
if (version_compare(GLPI_VERSION, '11.0.0', 'lt')) {
|
|
echo "This plugin requires GLPI >= 11.0.0";
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Check configuration process
|
|
*
|
|
* @param boolean $verbose Whether to display messages.
|
|
*
|
|
* @return boolean
|
|
*/
|
|
function plugin_redmine_check_config($verbose = false) {
|
|
plugin_redmine_load_license();
|
|
|
|
if (!class_exists('\GlpiPlugin\Mindplace\License') || !\GlpiPlugin\Mindplace\License::isValid()) {
|
|
if ($verbose && !isCommandLine()) {
|
|
echo "<div class='alert alert-danger'>"
|
|
. "Licença Mindtek inativa ou Mind Place ausente. O plugin foi desativado por segurança."
|
|
. "</div>";
|
|
}
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|