Skip to content

Base de Datos

Esta sección documenta la estructura de base de datos utilizada por el Conector NewBytes, incluyendo tablas, metadatos y optimizaciones implementadas.

🗄️ Estructura General

El plugin utiliza principalmente las tablas estándar de WordPress y WooCommerce, añadiendo metadatos específicos y opciones de configuración.

Tablas Utilizadas

TablaPropósitoTipo
wp_optionsConfiguración del pluginWordPress Core
wp_postsProductos WooCommerceWordPress Core
wp_postmetaMetadatos de productosWordPress Core
wp_termsCategorías de productosWordPress Core
wp_term_taxonomyTaxonomíasWordPress Core
wp_term_relationshipsRelaciones producto-categoríaWordPress Core
Archivos JSONLogs de sincronizaciónSistema de archivos

⚙️ Configuración del Plugin (wp_options)

Opciones Principales

sql
SELECT option_name, option_value 
FROM wp_options 
WHERE option_name LIKE 'nb_%';
SELECT option_name, option_value 
FROM wp_options 
WHERE option_name LIKE 'nb_%';

Configuración de Autenticación

OpciónDescripciónTipoEjemplo
nb_userUsuario NewBytesVARCHAR(255)"mi-usuario-nb"
nb_passwordContraseña NewBytesVARCHAR(255)"mi-password-segura"
nb_tokenToken JWT actualTEXT"eyJ0eXAiOiJKV1Q..."
php
// Obtener configuración de autenticación
$user = get_option('nb_user');
$password = get_option('nb_password');
$token = get_option('nb_token');
// Obtener configuración de autenticación
$user = get_option('nb_user');
$password = get_option('nb_password');
$token = get_option('nb_token');

Configuración de Productos

OpciónDescripciónTipoEjemplo
nb_prefixPrefijo SKUVARCHAR(50)"NB-"
nb_sync_no_ivaSincronizar sin IVABOOLEAN"1"
nb_sync_usdSincronizar en USDBOOLEAN"0"
nb_descriptionDescripción personalizadaTEXT"Producto NewBytes - Envío 24hs"
php
// Configuración de productos
$prefix = get_option('nb_prefix', 'NB-');
$no_iva = get_option('nb_sync_no_iva', false);
$usd = get_option('nb_sync_usd', false);
$description = get_option('nb_description', '');
// Configuración de productos
$prefix = get_option('nb_prefix', 'NB-');
$no_iva = get_option('nb_sync_no_iva', false);
$usd = get_option('nb_sync_usd', false);
$description = get_option('nb_description', '');

Configuración de Sincronización

OpciónDescripciónTipoEjemplo
nb_sync_intervalIntervalo en segundosINT1800
nb_last_updateÚltima sincronizaciónDATETIME"2024-01-15 14:30:25"
nb_last_sync_statsEstadísticas última syncJSON{"products": 150, "duration": "2m34s"}
php
// Configuración de sincronización
$interval = get_option('nb_sync_interval', 3600);
$last_update = get_option('nb_last_update');
$last_stats = json_decode(get_option('nb_last_sync_stats', '{}'), true);
// Configuración de sincronización
$interval = get_option('nb_sync_interval', 3600);
$last_update = get_option('nb_last_update');
$last_stats = json_decode(get_option('nb_last_sync_stats', '{}'), true);

📦 Productos y Metadatos (wp_posts & wp_postmeta)

Estructura de Productos

Los productos sincronizados se almacenan como posts de tipo product:

sql
SELECT p.ID, p.post_title, p.post_status, p.post_date
FROM wp_posts p
WHERE p.post_type = 'product'
AND EXISTS (
    SELECT 1 FROM wp_postmeta pm 
    WHERE pm.post_id = p.ID 
    AND pm.meta_key = '_sku' 
    AND pm.meta_value LIKE 'NB-%'
);
SELECT p.ID, p.post_title, p.post_status, p.post_date
FROM wp_posts p
WHERE p.post_type = 'product'
AND EXISTS (
    SELECT 1 FROM wp_postmeta pm 
    WHERE pm.post_id = p.ID 
    AND pm.meta_key = '_sku' 
    AND pm.meta_value LIKE 'NB-%'
);

Metadatos Estándar de WooCommerce

Meta KeyDescripciónEjemplo
_skuCódigo único del producto"NB-12345"
_pricePrecio actual"299.99"
_regular_pricePrecio regular"299.99"
_sale_pricePrecio de oferta""
_stockCantidad en stock"15"
_manage_stockGestionar stock"yes"
_stock_statusEstado del stock"instock"
_visibilityVisibilidad del producto"visible"
_featuredProducto destacado"no"
php
// Obtener metadatos estándar
$sku = get_post_meta($product_id, '_sku', true);
$price = get_post_meta($product_id, '_price', true);
$stock = get_post_meta($product_id, '_stock', true);
// Obtener metadatos estándar
$sku = get_post_meta($product_id, '_sku', true);
$price = get_post_meta($product_id, '_price', true);
$stock = get_post_meta($product_id, '_stock', true);

Metadatos Específicos del Plugin

Meta KeyDescripciónEjemplo
_nb_product_idID original en NewBytes"12345"
_nb_last_syncÚltima sincronización"2024-01-15 14:30:25"
_nb_original_pricePrecio original sin modificar"299.99"
_nb_sync_statusEstado de sincronización"synced"
_nb_category_idID categoría NewBytes"electronics"
_nb_attributesAtributos del producto'{"brand":"Samsung","color":"Negro"}'
php
// Metadatos específicos del plugin
update_post_meta($product_id, '_nb_product_id', $nb_product_id);
update_post_meta($product_id, '_nb_last_sync', current_time('mysql'));
update_post_meta($product_id, '_nb_original_price', $original_price);
update_post_meta($product_id, '_nb_sync_status', 'synced');
// Metadatos específicos del plugin
update_post_meta($product_id, '_nb_product_id', $nb_product_id);
update_post_meta($product_id, '_nb_last_sync', current_time('mysql'));
update_post_meta($product_id, '_nb_original_price', $original_price);
update_post_meta($product_id, '_nb_sync_status', 'synced');

Consultas Optimizadas

Obtener Productos de NewBytes

sql
SELECT p.ID, p.post_title, pm1.meta_value as sku, pm2.meta_value as nb_id
FROM wp_posts p
INNER JOIN wp_postmeta pm1 ON p.ID = pm1.post_id AND pm1.meta_key = '_sku'
INNER JOIN wp_postmeta pm2 ON p.ID = pm2.post_id AND pm2.meta_key = '_nb_product_id'
WHERE p.post_type = 'product'
AND p.post_status = 'publish'
AND pm1.meta_value LIKE 'NB-%';
SELECT p.ID, p.post_title, pm1.meta_value as sku, pm2.meta_value as nb_id
FROM wp_posts p
INNER JOIN wp_postmeta pm1 ON p.ID = pm1.post_id AND pm1.meta_key = '_sku'
INNER JOIN wp_postmeta pm2 ON p.ID = pm2.post_id AND pm2.meta_key = '_nb_product_id'
WHERE p.post_type = 'product'
AND p.post_status = 'publish'
AND pm1.meta_value LIKE 'NB-%';

Productos Pendientes de Sincronización

sql
SELECT p.ID, pm1.meta_value as sku
FROM wp_posts p
INNER JOIN wp_postmeta pm1 ON p.ID = pm1.post_id AND pm1.meta_key = '_sku'
LEFT JOIN wp_postmeta pm2 ON p.ID = pm2.post_id AND pm2.meta_key = '_nb_last_sync'
WHERE p.post_type = 'product'
AND pm1.meta_value LIKE 'NB-%'
AND (pm2.meta_value IS NULL OR pm2.meta_value < DATE_SUB(NOW(), INTERVAL 1 HOUR));
SELECT p.ID, pm1.meta_value as sku
FROM wp_posts p
INNER JOIN wp_postmeta pm1 ON p.ID = pm1.post_id AND pm1.meta_key = '_sku'
LEFT JOIN wp_postmeta pm2 ON p.ID = pm2.post_id AND pm2.meta_key = '_nb_last_sync'
WHERE p.post_type = 'product'
AND pm1.meta_value LIKE 'NB-%'
AND (pm2.meta_value IS NULL OR pm2.meta_value < DATE_SUB(NOW(), INTERVAL 1 HOUR));

🏷️ Categorías y Taxonomías

Estructura de Categorías

Las categorías se manejan usando el sistema de taxonomías de WordPress:

sql
SELECT t.term_id, t.name, t.slug, tt.taxonomy
FROM wp_terms t
INNER JOIN wp_term_taxonomy tt ON t.term_id = tt.term_id
WHERE tt.taxonomy = 'product_cat';
SELECT t.term_id, t.name, t.slug, tt.taxonomy
FROM wp_terms t
INNER JOIN wp_term_taxonomy tt ON t.term_id = tt.term_id
WHERE tt.taxonomy = 'product_cat';

Metadatos de Categorías

php
// Guardar ID de categoría NewBytes
update_term_meta($term_id, '_nb_category_id', $nb_category_id);
update_term_meta($term_id, '_nb_last_sync', current_time('mysql'));

// Obtener categoría por ID NewBytes
$term_query = new WP_Term_Query(array(
    'taxonomy' => 'product_cat',
    'meta_query' => array(
        array(
            'key' => '_nb_category_id',
            'value' => $nb_category_id,
            'compare' => '='
        )
    )
));
// Guardar ID de categoría NewBytes
update_term_meta($term_id, '_nb_category_id', $nb_category_id);
update_term_meta($term_id, '_nb_last_sync', current_time('mysql'));

// Obtener categoría por ID NewBytes
$term_query = new WP_Term_Query(array(
    'taxonomy' => 'product_cat',
    'meta_query' => array(
        array(
            'key' => '_nb_category_id',
            'value' => $nb_category_id,
            'compare' => '='
        )
    )
));

📊 Sistema de Logs (Archivos JSON)

Estructura de Directorio

wp-content/plugins/woocommerce-newbytes/logs-sync-nb/
├── sync_20240115_143025.json
├── sync_20240115_150025.json
├── sync_20240115_153025.json
└── api-requests.log
wp-content/plugins/woocommerce-newbytes/logs-sync-nb/
├── sync_20240115_143025.json
├── sync_20240115_150025.json
├── sync_20240115_153025.json
└── api-requests.log

Formato de Log JSON

json
{
  "log_id": "sync_20240115_143025",
  "timestamp": "2024-01-15 14:30:25",
  "sync_type": "automatic",
  "status": "success",
  "duration": {
    "start": "2024-01-15 14:30:25",
    "end": "2024-01-15 14:32:59",
    "total_seconds": 154,
    "formatted": "2m 34s"
  },
  "api_data": {
    "total_products": 150,
    "api_response_time": 1.23,
    "token_valid": true
  },
  "sync_stats": {
    "products_processed": 150,
    "products_created": 12,
    "products_updated": 138,
    "products_deleted": 3,
    "errors": 0,
    "warnings": 2
  },
  "products_detail": [
    {
      "nb_id": "12345",
      "sku": "NB-12345",
      "action": "updated",
      "changes": ["price", "stock"],
      "wp_product_id": 567
    }
  ],
  "errors": [],
  "warnings": [
    "Producto 12346: imagen no disponible",
    "Producto 12347: precio cero detectado"
  ],
  "system_info": {
    "memory_usage": "45MB",
    "peak_memory": "52MB",
    "wp_version": "6.4.2",
    "wc_version": "8.5.1",
    "plugin_version": "0.1.8",
    "php_version": "8.1.0"
  }
}
{
  "log_id": "sync_20240115_143025",
  "timestamp": "2024-01-15 14:30:25",
  "sync_type": "automatic",
  "status": "success",
  "duration": {
    "start": "2024-01-15 14:30:25",
    "end": "2024-01-15 14:32:59",
    "total_seconds": 154,
    "formatted": "2m 34s"
  },
  "api_data": {
    "total_products": 150,
    "api_response_time": 1.23,
    "token_valid": true
  },
  "sync_stats": {
    "products_processed": 150,
    "products_created": 12,
    "products_updated": 138,
    "products_deleted": 3,
    "errors": 0,
    "warnings": 2
  },
  "products_detail": [
    {
      "nb_id": "12345",
      "sku": "NB-12345",
      "action": "updated",
      "changes": ["price", "stock"],
      "wp_product_id": 567
    }
  ],
  "errors": [],
  "warnings": [
    "Producto 12346: imagen no disponible",
    "Producto 12347: precio cero detectado"
  ],
  "system_info": {
    "memory_usage": "45MB",
    "peak_memory": "52MB",
    "wp_version": "6.4.2",
    "wc_version": "8.5.1",
    "plugin_version": "0.1.8",
    "php_version": "8.1.0"
  }
}

Consultas de Logs

php
// Obtener logs por fecha
function nb_get_logs_by_date($date_from, $date_to) {
    $logs_dir = plugin_dir_path(__FILE__) . '../logs-sync-nb/';
    $logs = array();
    
    $files = glob($logs_dir . 'sync_*.json');
    
    foreach ($files as $file) {
        $log_data = json_decode(file_get_contents($file), true);
        $log_date = strtotime($log_data['timestamp']);
        
        if ($log_date >= strtotime($date_from) && $log_date <= strtotime($date_to)) {
            $logs[] = $log_data;
        }
    }
    
    return $logs;
}

// Obtener estadísticas agregadas
function nb_get_sync_statistics($days = 30) {
    $logs = nb_get_logs_by_date(
        date('Y-m-d', strtotime("-{$days} days")),
        date('Y-m-d')
    );
    
    $stats = array(
        'total_syncs' => count($logs),
        'successful_syncs' => 0,
        'failed_syncs' => 0,
        'total_products_processed' => 0,
        'average_duration' => 0
    );
    
    foreach ($logs as $log) {
        if ($log['status'] === 'success') {
            $stats['successful_syncs']++;
        } else {
            $stats['failed_syncs']++;
        }
        
        $stats['total_products_processed'] += $log['sync_stats']['products_processed'];
        $stats['average_duration'] += $log['duration']['total_seconds'];
    }
    
    if ($stats['total_syncs'] > 0) {
        $stats['average_duration'] = $stats['average_duration'] / $stats['total_syncs'];
        $stats['success_rate'] = ($stats['successful_syncs'] / $stats['total_syncs']) * 100;
    }
    
    return $stats;
}
// Obtener logs por fecha
function nb_get_logs_by_date($date_from, $date_to) {
    $logs_dir = plugin_dir_path(__FILE__) . '../logs-sync-nb/';
    $logs = array();
    
    $files = glob($logs_dir . 'sync_*.json');
    
    foreach ($files as $file) {
        $log_data = json_decode(file_get_contents($file), true);
        $log_date = strtotime($log_data['timestamp']);
        
        if ($log_date >= strtotime($date_from) && $log_date <= strtotime($date_to)) {
            $logs[] = $log_data;
        }
    }
    
    return $logs;
}

// Obtener estadísticas agregadas
function nb_get_sync_statistics($days = 30) {
    $logs = nb_get_logs_by_date(
        date('Y-m-d', strtotime("-{$days} days")),
        date('Y-m-d')
    );
    
    $stats = array(
        'total_syncs' => count($logs),
        'successful_syncs' => 0,
        'failed_syncs' => 0,
        'total_products_processed' => 0,
        'average_duration' => 0
    );
    
    foreach ($logs as $log) {
        if ($log['status'] === 'success') {
            $stats['successful_syncs']++;
        } else {
            $stats['failed_syncs']++;
        }
        
        $stats['total_products_processed'] += $log['sync_stats']['products_processed'];
        $stats['average_duration'] += $log['duration']['total_seconds'];
    }
    
    if ($stats['total_syncs'] > 0) {
        $stats['average_duration'] = $stats['average_duration'] / $stats['total_syncs'];
        $stats['success_rate'] = ($stats['successful_syncs'] / $stats['total_syncs']) * 100;
    }
    
    return $stats;
}

🔍 Consultas de Diagnóstico

Verificar Integridad de Datos

sql
-- Productos sin SKU
SELECT p.ID, p.post_title
FROM wp_posts p
LEFT JOIN wp_postmeta pm ON p.ID = pm.post_id AND pm.meta_key = '_sku'
WHERE p.post_type = 'product'
AND p.post_status = 'publish'
AND pm.meta_value IS NULL;

-- Productos NewBytes sin ID original
SELECT p.ID, p.post_title, pm1.meta_value as sku
FROM wp_posts p
INNER JOIN wp_postmeta pm1 ON p.ID = pm1.post_id AND pm1.meta_key = '_sku'
LEFT JOIN wp_postmeta pm2 ON p.ID = pm2.post_id AND pm2.meta_key = '_nb_product_id'
WHERE p.post_type = 'product'
AND pm1.meta_value LIKE 'NB-%'
AND pm2.meta_value IS NULL;

-- Productos duplicados por SKU
SELECT pm.meta_value as sku, COUNT(*) as count
FROM wp_postmeta pm
INNER JOIN wp_posts p ON pm.post_id = p.ID
WHERE pm.meta_key = '_sku'
AND p.post_type = 'product'
AND pm.meta_value LIKE 'NB-%'
GROUP BY pm.meta_value
HAVING COUNT(*) > 1;
-- Productos sin SKU
SELECT p.ID, p.post_title
FROM wp_posts p
LEFT JOIN wp_postmeta pm ON p.ID = pm.post_id AND pm.meta_key = '_sku'
WHERE p.post_type = 'product'
AND p.post_status = 'publish'
AND pm.meta_value IS NULL;

-- Productos NewBytes sin ID original
SELECT p.ID, p.post_title, pm1.meta_value as sku
FROM wp_posts p
INNER JOIN wp_postmeta pm1 ON p.ID = pm1.post_id AND pm1.meta_key = '_sku'
LEFT JOIN wp_postmeta pm2 ON p.ID = pm2.post_id AND pm2.meta_key = '_nb_product_id'
WHERE p.post_type = 'product'
AND pm1.meta_value LIKE 'NB-%'
AND pm2.meta_value IS NULL;

-- Productos duplicados por SKU
SELECT pm.meta_value as sku, COUNT(*) as count
FROM wp_postmeta pm
INNER JOIN wp_posts p ON pm.post_id = p.ID
WHERE pm.meta_key = '_sku'
AND p.post_type = 'product'
AND pm.meta_value LIKE 'NB-%'
GROUP BY pm.meta_value
HAVING COUNT(*) > 1;

Estadísticas de Rendimiento

sql
-- Productos por estado de stock
SELECT pm.meta_value as stock_status, COUNT(*) as count
FROM wp_postmeta pm
INNER JOIN wp_posts p ON pm.post_id = p.ID
INNER JOIN wp_postmeta pm2 ON p.ID = pm2.post_id AND pm2.meta_key = '_sku'
WHERE pm.meta_key = '_stock_status'
AND p.post_type = 'product'
AND pm2.meta_value LIKE 'NB-%'
GROUP BY pm.meta_value;

-- Distribución de precios
SELECT 
    CASE 
        WHEN CAST(pm.meta_value AS DECIMAL(10,2)) < 50 THEN '0-50'
        WHEN CAST(pm.meta_value AS DECIMAL(10,2)) < 100 THEN '50-100'
        WHEN CAST(pm.meta_value AS DECIMAL(10,2)) < 500 THEN '100-500'
        ELSE '500+'
    END as price_range,
    COUNT(*) as count
FROM wp_postmeta pm
INNER JOIN wp_posts p ON pm.post_id = p.ID
INNER JOIN wp_postmeta pm2 ON p.ID = pm2.post_id AND pm2.meta_key = '_sku'
WHERE pm.meta_key = '_price'
AND p.post_type = 'product'
AND pm2.meta_value LIKE 'NB-%'
AND pm.meta_value != ''
GROUP BY price_range;
-- Productos por estado de stock
SELECT pm.meta_value as stock_status, COUNT(*) as count
FROM wp_postmeta pm
INNER JOIN wp_posts p ON pm.post_id = p.ID
INNER JOIN wp_postmeta pm2 ON p.ID = pm2.post_id AND pm2.meta_key = '_sku'
WHERE pm.meta_key = '_stock_status'
AND p.post_type = 'product'
AND pm2.meta_value LIKE 'NB-%'
GROUP BY pm.meta_value;

-- Distribución de precios
SELECT 
    CASE 
        WHEN CAST(pm.meta_value AS DECIMAL(10,2)) < 50 THEN '0-50'
        WHEN CAST(pm.meta_value AS DECIMAL(10,2)) < 100 THEN '50-100'
        WHEN CAST(pm.meta_value AS DECIMAL(10,2)) < 500 THEN '100-500'
        ELSE '500+'
    END as price_range,
    COUNT(*) as count
FROM wp_postmeta pm
INNER JOIN wp_posts p ON pm.post_id = p.ID
INNER JOIN wp_postmeta pm2 ON p.ID = pm2.post_id AND pm2.meta_key = '_sku'
WHERE pm.meta_key = '_price'
AND p.post_type = 'product'
AND pm2.meta_value LIKE 'NB-%'
AND pm.meta_value != ''
GROUP BY price_range;

🛠️ Optimizaciones de Base de Datos

Índices Recomendados

sql
-- Índice para búsquedas por SKU
CREATE INDEX idx_postmeta_sku ON wp_postmeta (meta_key, meta_value(20));

-- Índice para productos NewBytes
CREATE INDEX idx_postmeta_nb_id ON wp_postmeta (meta_key, meta_value(50));

-- Índice compuesto para consultas de productos
CREATE INDEX idx_posts_type_status ON wp_posts (post_type, post_status);
-- Índice para búsquedas por SKU
CREATE INDEX idx_postmeta_sku ON wp_postmeta (meta_key, meta_value(20));

-- Índice para productos NewBytes
CREATE INDEX idx_postmeta_nb_id ON wp_postmeta (meta_key, meta_value(50));

-- Índice compuesto para consultas de productos
CREATE INDEX idx_posts_type_status ON wp_posts (post_type, post_status);

Limpieza de Datos

php
// Limpiar metadatos huérfanos
function nb_cleanup_orphaned_meta() {
    global $wpdb;
    
    $wpdb->query("
        DELETE pm FROM wp_postmeta pm
        LEFT JOIN wp_posts p ON pm.post_id = p.ID
        WHERE p.ID IS NULL
        AND pm.meta_key LIKE '_nb_%'
    ");
}

// Limpiar logs antiguos
function nb_cleanup_old_logs($days = 30) {
    $logs_dir = plugin_dir_path(__FILE__) . '../logs-sync-nb/';
    $cutoff_date = strtotime("-{$days} days");
    
    $files = glob($logs_dir . 'sync_*.json');
    
    foreach ($files as $file) {
        $file_date = filemtime($file);
        if ($file_date < $cutoff_date) {
            unlink($file);
        }
    }
}
// Limpiar metadatos huérfanos
function nb_cleanup_orphaned_meta() {
    global $wpdb;
    
    $wpdb->query("
        DELETE pm FROM wp_postmeta pm
        LEFT JOIN wp_posts p ON pm.post_id = p.ID
        WHERE p.ID IS NULL
        AND pm.meta_key LIKE '_nb_%'
    ");
}

// Limpiar logs antiguos
function nb_cleanup_old_logs($days = 30) {
    $logs_dir = plugin_dir_path(__FILE__) . '../logs-sync-nb/';
    $cutoff_date = strtotime("-{$days} days");
    
    $files = glob($logs_dir . 'sync_*.json');
    
    foreach ($files as $file) {
        $file_date = filemtime($file);
        if ($file_date < $cutoff_date) {
            unlink($file);
        }
    }
}

Backup de Configuración

php
// Exportar configuración del plugin
function nb_export_configuration() {
    $config = array();
    
    $options = array(
        'nb_user', 'nb_prefix', 'nb_sync_no_iva', 
        'nb_sync_usd', 'nb_description', 'nb_sync_interval'
    );
    
    foreach ($options as $option) {
        $config[$option] = get_option($option);
    }
    
    return json_encode($config, JSON_PRETTY_PRINT);
}

// Importar configuración
function nb_import_configuration($json_config) {
    $config = json_decode($json_config, true);
    
    if (!$config) {
        return false;
    }
    
    foreach ($config as $option => $value) {
        if (strpos($option, 'nb_') === 0 && $option !== 'nb_password' && $option !== 'nb_token') {
            update_option($option, $value);
        }
    }
    
    return true;
}
// Exportar configuración del plugin
function nb_export_configuration() {
    $config = array();
    
    $options = array(
        'nb_user', 'nb_prefix', 'nb_sync_no_iva', 
        'nb_sync_usd', 'nb_description', 'nb_sync_interval'
    );
    
    foreach ($options as $option) {
        $config[$option] = get_option($option);
    }
    
    return json_encode($config, JSON_PRETTY_PRINT);
}

// Importar configuración
function nb_import_configuration($json_config) {
    $config = json_decode($json_config, true);
    
    if (!$config) {
        return false;
    }
    
    foreach ($config as $option => $value) {
        if (strpos($option, 'nb_') === 0 && $option !== 'nb_password' && $option !== 'nb_token') {
            update_option($option, $value);
        }
    }
    
    return true;
}

📈 Monitoreo de Base de Datos

Métricas de Rendimiento

php
// Obtener estadísticas de la base de datos
function nb_get_db_stats() {
    global $wpdb;
    
    // Contar productos NewBytes
    $nb_products = $wpdb->get_var("
        SELECT COUNT(DISTINCT p.ID)
        FROM {$wpdb->posts} p
        INNER JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id
        WHERE p.post_type = 'product'
        AND pm.meta_key = '_sku'
        AND pm.meta_value LIKE 'NB-%'
    ");
    
    // Tamaño de logs
    $logs_dir = plugin_dir_path(__FILE__) . '../logs-sync-nb/';
    $logs_size = 0;
    $logs_count = 0;
    
    if (is_dir($logs_dir)) {
        $files = glob($logs_dir . '*.json');
        $logs_count = count($files);
        
        foreach ($files as $file) {
            $logs_size += filesize($file);
        }
    }
    
    return array(
        'nb_products_count' => $nb_products,
        'logs_count' => $logs_count,
        'logs_size_mb' => round($logs_size / 1024 / 1024, 2),
        'last_sync' => get_option('nb_last_update'),
        'db_version' => $wpdb->db_version()
    );
}
// Obtener estadísticas de la base de datos
function nb_get_db_stats() {
    global $wpdb;
    
    // Contar productos NewBytes
    $nb_products = $wpdb->get_var("
        SELECT COUNT(DISTINCT p.ID)
        FROM {$wpdb->posts} p
        INNER JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id
        WHERE p.post_type = 'product'
        AND pm.meta_key = '_sku'
        AND pm.meta_value LIKE 'NB-%'
    ");
    
    // Tamaño de logs
    $logs_dir = plugin_dir_path(__FILE__) . '../logs-sync-nb/';
    $logs_size = 0;
    $logs_count = 0;
    
    if (is_dir($logs_dir)) {
        $files = glob($logs_dir . '*.json');
        $logs_count = count($files);
        
        foreach ($files as $file) {
            $logs_size += filesize($file);
        }
    }
    
    return array(
        'nb_products_count' => $nb_products,
        'logs_count' => $logs_count,
        'logs_size_mb' => round($logs_size / 1024 / 1024, 2),
        'last_sync' => get_option('nb_last_update'),
        'db_version' => $wpdb->db_version()
    );
}

Esta documentación de base de datos proporciona una comprensión completa de cómo el plugin almacena y gestiona los datos, facilitando el mantenimiento, debugging y optimización del sistema.


💡 Optimización

Para mejor rendimiento, considera implementar los índices recomendados y ejecutar las rutinas de limpieza regularmente, especialmente en sitios con alto volumen de productos.

⚠️ Backup

Siempre haz backup de la base de datos antes de ejecutar consultas de limpieza o modificaciones masivas de datos.