Files
sistema_funcionando_lastwar/includes/translation_helper.php

211 lines
7.0 KiB
PHP
Executable File

<?php
/**
* Helper para manejar traducciones en la aplicación
*
* Este archivo proporciona funciones para manejar traducciones de manera consistente
* en toda la aplicación, incluyendo soporte para múltiples idiomas y caché de traducciones.
*/
// Evitar acceso directo
defined('ROOT_PATH') || define('ROOT_PATH', dirname(__DIR__));
// Inicializar el array de caché de traducciones
$GLOBALS['_translations_cache'] = [];
/**
* Obtiene una traducción para la clave dada en el idioma actual del usuario
*
* @param string $key Clave de traducción
* @param array $params Parámetros para reemplazar en la cadena de traducción
* @param string|null $language Código de idioma (opcional, por defecto usa el idioma de sesión)
* @return string Texto traducido o la clave si no se encuentra la traducción
*/
function __($key, $params = [], $language = null) {
global $pdo; // Asumiendo que $pdo está disponible globalmente
// Si no se proporciona un idioma, usar el de la sesión o el predeterminado
if ($language === null) {
$language = $_SESSION['language'] ?? 'es';
}
// Clave para el caché
$cache_key = $language . '_' . $key;
// Verificar si la traducción está en caché
if (isset($GLOBALS['_translations_cache'][$cache_key])) {
$translation = $GLOBALS['_translations_cache'][$cache_key];
} else {
// Si no está en caché, buscarla en la base de datos
try {
$stmt = $pdo->prepare(
"SELECT `value` FROM translations
WHERE `key` = :key AND language_code = :language
LIMIT 1"
);
$stmt->execute([
':key' => $key,
':language' => $language
]);
$result = $stmt->fetch(PDO::FETCH_ASSOC);
$translation = $result ? $result['value'] : '';
// Almacenar en caché para futuras solicitudes
$GLOBALS['_translations_cache'][$cache_key] = $translation;
} catch (PDOException $e) {
// En caso de error, devolver la clave como último recurso
error_log("Error al obtener traducción: " . $e->getMessage());
return $key;
}
}
// Si no se encontró la traducción, devolver la clave
if (empty($translation)) {
// Opcional: Registrar claves faltantes para facilitar la localización
log_missing_translation($key, $language);
return $key;
}
// Reemplazar parámetros si se proporcionan
if (!empty($params) && is_array($params)) {
foreach ($params as $param => $value) {
$translation = str_replace(":$param", $value, $translation);
}
}
return $translation;
}
/**
* Registra claves de traducción faltantes para facilitar la localización
*
* @param string $key Clave de traducción faltante
* @param string $language Código de idioma
*/
function log_missing_translation($key, $language) {
$log_file = ROOT_PATH . '/logs/missing_translations.log';
$log_entry = sprintf(
"[%s] Missing translation: %s (Language: %s)\n",
date('Y-m-d H:i:s'),
$key,
$language
);
// Asegurarse de que el directorio de logs existe
if (!is_dir(dirname($log_file))) {
@mkdir(dirname($log_file), 0755, true);
}
// Registrar en el archivo de log
@file_put_contents($log_file, $log_entry, FILE_APPEND);
}
/**
* Obtiene la lista de idiomas disponibles
*
* @param bool $only_active Si es true, solo devuelve los idiomas activos
* @return array Lista de idiomas
*/
function get_available_languages($only_active = true) {
global $pdo;
try {
$sql = "SELECT code, name, native_name, flag_emoji, is_active
FROM languages";
if ($only_active) {
$sql .= " WHERE is_active = 1";
}
$sql .= " ORDER BY name";
$stmt = $pdo->query($sql);
return $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
error_log("Error al obtener idiomas: " . $e->getMessage());
return [
['code' => 'es', 'name' => 'Spanish', 'native_name' => 'Español', 'flag_emoji' => '🇪🇸', 'is_active' => 1],
['code' => 'en', 'name' => 'English', 'native_name' => 'English', 'flag_emoji' => '🇬🇧', 'is_active' => 1]
];
}
}
/**
* Inicializa el sistema de traducciones en las plantillas
* Inyecta las traducciones necesarias para JavaScript
*
* @return string Código JavaScript con las traducciones (sin etiquetas <script>)
*/
function init_translations_for_js() {
global $pdo;
// Obtener el idioma actual
$language = $_SESSION['language'] ?? 'es';
// Obtener todas las traducciones para el idioma actual
try {
$stmt = $pdo->prepare(
"SELECT `key`, `value` FROM translations
WHERE language_code = :language"
);
$stmt->execute([':language' => $language]);
$translations = $stmt->fetchAll(PDO::FETCH_KEY_PAIR);
} catch (PDOException $e) {
error_log("Error al cargar traducciones para JS: " . $e->getMessage());
$translations = [];
}
// Devolver solo el código JavaScript (sin etiquetas <script>)
return "// Traducciones cargadas dinámicamente\n" .
"window.translations = " . json_encode($translations, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE) . ";\n";
}
/**
* Función para traducir texto en JavaScript
* Se debe llamar después de incluir el helper en el HTML
*/
function js_translation_function() {
echo <<<JS
<script>
/**
* Función para traducir texto en JavaScript
* @param {string} key - Clave de traducción
* @param {Object} params - Parámetros para reemplazar en la cadena
* @return {string} Texto traducido o la clave si no se encuentra
*/
function __(key, params = {}) {
let text = translations[key] || key;
// Reemplazar parámetros
Object.keys(params).forEach(param => {
text = text.replace(new RegExp(`:${param}`, 'g'), params[param]);
});
return text;
}
// Traducir elementos con el atributo data-translate
document.addEventListener('DOMContentLoaded', function() {
const elements = document.querySelectorAll('[data-translate]');
elements.forEach(element => {
const key = element.getAttribute('data-translate');
if (translations[key]) {
if (element.tagName === 'INPUT' || element.tagName === 'TEXTAREA') {
element.placeholder = translations[key];
} else if (element.tagName === 'BUTTON' || element.tagName === 'A') {
element.textContent = translations[key];
} else {
element.textContent = translations[key];
}
}
});
});
</script>
JS;
}