Commit inicial con archivos existentes
This commit is contained in:
210
includes/translation_helper.php
Executable file
210
includes/translation_helper.php
Executable file
@@ -0,0 +1,210 @@
|
||||
<?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;
|
||||
}
|
||||
Reference in New Issue
Block a user