true,
'captura_elementor' => true,
'procesar_templates' => true,
'procesar_elementos' => true,
'modo_debug' => false,
'solo_admin' => true,
'captura_en_idioma_principal' => true,
'permitir_escaneo' => true // Nuevo: activado por defecto
]);
}
// Cargar opciones
$this->options = get_option('accessitrans_aria_options', [
'captura_total' => true,
'captura_elementor' => true,
'procesar_templates' => true,
'procesar_elementos' => true,
'modo_debug' => false,
'solo_admin' => true,
'captura_en_idioma_principal' => true,
'permitir_escaneo' => true // Nuevo: activado por defecto
]);
// Registrar hooks de activación y desactivación
register_activation_hook(ACCESSITRANS_PATH . 'accessitrans-aria.php', [$this, 'activate']);
register_deactivation_hook(ACCESSITRANS_PATH . 'accessitrans-aria.php', [$this, 'deactivate']);
// Verificar dependencias básicas
if (!did_action('elementor/loaded') || !defined('ICL_SITEPRESS_VERSION')) {
add_action('admin_notices', [$this, 'show_dependencies_notice']);
return;
}
// Inicializar componentes
$this->init_components();
// Borrar caché al guardar configuración de Elementor
add_action('elementor/editor/after_save', [$this, 'clear_cache_after_elementor_save']);
// Inicializar método específicos si existen dependencias
if (did_action('elementor/loaded') && defined('ICL_SITEPRESS_VERSION')) {
$this->init_translation_methods();
}
}
/**
* Inicializa los componentes del plugin
*/
private function init_components() {
// Inicializar componentes
$this->translator = new AccessiTrans_Translator($this);
$this->capture = new AccessiTrans_Capture($this);
$this->admin = new AccessiTrans_Admin($this);
$this->diagnostics = new AccessiTrans_Diagnostics($this);
}
/**
* Inicializa los métodos de traducción
*/
private function init_translation_methods() {
// Aplicar traducciones al contenido final
add_filter('elementor/frontend/the_content', [$this->translator, 'translate_aria_attributes'], 1000);
add_filter('the_content', [$this->translator, 'translate_aria_attributes'], 1000);
// Registro de debug (solo una vez)
if ($this->options['modo_debug'] && !self::$initialization_logged) {
$this->log_debug('Plugin inicializado - Versión ' . $this->version);
self::$initialization_logged = true;
}
}
/**
* Método singleton
*/
public static function get_instance() {
if (null === self::$instance) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Activación del plugin
*/
public function activate() {
// Asegurarse de que las opciones predeterminadas están configuradas
if (!get_option('accessitrans_aria_options')) {
update_option('accessitrans_aria_options', [
'captura_total' => true,
'captura_elementor' => true,
'procesar_templates' => true,
'procesar_elementos' => true,
'modo_debug' => false,
'solo_admin' => true,
'captura_en_idioma_principal' => true,
'permitir_escaneo' => true // Nuevo: activado por defecto
]);
}
// Reiniciar flags estáticos
self::$initialization_logged = false;
}
/**
* Desactivación del plugin
*/
public function deactivate() {
// Limpiar archivos temporales o caché si es necesario
}
/**
* Muestra notificación de dependencias faltantes
*/
public function show_dependencies_notice() {
$class = 'notice notice-error';
$message = __('AccessiTrans requires Elementor and WPML to be installed and activated.', 'accessitrans-aria');
printf('
', esc_attr($class), esc_html($message));
}
/**
* Borra la caché después de guardar en Elementor
*/
public function clear_cache_after_elementor_save() {
if ($this->translator) {
$this->translator->clear_cache();
}
if ($this->capture) {
$this->capture->clear_cache();
}
if ($this->options['modo_debug']) {
$this->log_debug("Caché limpiada después de guardar en Elementor");
}
}
/**
* Obtiene la lista de atributos traducibles
*/
public function get_traducible_attrs() {
return $this->traducible_attrs;
}
/**
* Obtiene el contexto de las traducciones
*/
public function get_context() {
return $this->context;
}
/**
* Obtiene la versión del plugin
*/
public function get_version() {
return $this->version;
}
/**
* Logger para debug optimizado y seguro
*
* @param mixed $message Mensaje o datos a registrar
* @return void
*/
public function log_debug($message) {
// Verificar primero si el modo debug está activo
if (empty($this->options['modo_debug'])) {
return;
}
// Obtener el directorio de uploads
$upload_dir = wp_upload_dir();
$log_directory = $upload_dir['basedir'] . '/accessitrans-logs';
// Crear directorio si no existe
if (!file_exists($log_directory)) {
wp_mkdir_p($log_directory);
}
$log_file = $log_directory . '/debug-aria-wpml.log';
$timestamp = gmdate('[Y-m-d H:i:s] ');
// Convertir arrays/objetos a string de forma segura sin usar funciones de depuración
if (is_array($message) || is_object($message)) {
// Usar json_encode como alternativa segura a var_export/print_r
$formatted_message = 'Array/Object data: ' . json_encode($message);
// Evitar error_log usando file_put_contents
@file_put_contents($log_file, $timestamp . $formatted_message . PHP_EOL, FILE_APPEND);
} else {
// Asegurar que el mensaje es una cadena
$safe_message = sanitize_text_field($message);
// Evitar error_log usando file_put_contents
@file_put_contents($log_file, $timestamp . $safe_message . PHP_EOL, FILE_APPEND);
}
}
/**
* Verifica si una cadena ya existe en WPML
* @param string $value Valor a verificar
* @param string $context Contexto de la cadena (opcional)
* @return bool True si existe, False si no
*/
public function exists_in_wpml($value, $context = null) {
if (empty($value)) {
return false;
}
$context = $context ?: $this->get_context();
global $wpdb;
// Buscar por valor exacto
$exists = $wpdb->get_var($wpdb->prepare(
"SELECT COUNT(*) FROM {$wpdb->prefix}icl_strings
WHERE value = %s AND context = %s",
$value,
$context
));
if ($exists) {
return true;
}
// También buscar por prefijo para cada atributo
foreach ($this->get_traducible_attrs() as $attr) {
$prefixed_name = "{$attr}_{$value}";
$exists = $wpdb->get_var($wpdb->prepare(
"SELECT COUNT(*) FROM {$wpdb->prefix}icl_strings
WHERE name = %s AND context = %s",
$prefixed_name,
$context
));
if ($exists) {
return true;
}
}
return false;
}
/**
* Verifica si debe capturar en el idioma actual (método mejorado)
* @return bool True si debe capturar, False si no
*/
public function should_capture_in_current_language() {
// Si la opción está desactivada, siempre permitir captura
if (!isset($this->options['captura_en_idioma_principal']) || !$this->options['captura_en_idioma_principal']) {
return true;
}
// Verificar si WPML está disponible antes de usar sus filtros
if (!function_exists('icl_object_id') || !function_exists('apply_filters')) {
if ($this->options['modo_debug']) {
$this->log_debug("WPML no está completamente inicializado - omitiendo captura por precaución");
}
return false;
}
// Obtener idioma actual y predeterminado con verificación
$current_language = apply_filters('wpml_current_language', null);
$default_language = apply_filters('wpml_default_language', null);
// Si alguno de los idiomas no está definido, ser cauteloso y no capturar
if (empty($current_language) || empty($default_language)) {
if ($this->options['modo_debug']) {
$this->log_debug("No se puede determinar idioma actual o predeterminado");
}
return false;
}
$result = ($current_language === $default_language);
if ($this->options['modo_debug'] && !$result) {
$this->log_debug("Captura omitida - Idioma actual ({$current_language}) no es el principal ({$default_language})");
}
return $result;
}
/**
* Verifica si debe realizar captura basado en opciones generales
* @return bool True si debe capturar, False si no
*/
public function should_capture() {
// Si la captura está globalmente desactivada, no realizar captura
if (!isset($this->options['permitir_escaneo']) || !$this->options['permitir_escaneo']) {
if ($this->options['modo_debug']) {
$this->log_debug("Captura omitida - Escaneo global desactivado");
}
return false;
}
// Verificación especial para entorno de administración
if (is_admin() && !wp_doing_ajax()) {
// En admin, ser extra cauteloso y verificar explícitamente idioma
$current_language = apply_filters('wpml_current_language', null);
$default_language = apply_filters('wpml_default_language', null);
if ($current_language !== $default_language) {
if ($this->options['modo_debug']) {
$this->log_debug("Captura omitida en admin - Idioma actual ({$current_language}) no es el principal ({$default_language})");
}
return false;
}
}
// Verificar idioma actual
return $this->should_capture_in_current_language();
}
}