up
This commit is contained in:
@@ -0,0 +1,151 @@
|
||||
# 🤖 WhatsApp Bot Manager - Guía de Instalación Rápida
|
||||
|
||||
## 🚀 Pasos para poner en funcionamiento:
|
||||
|
||||
### 1. 📊 Instalar Base de Datos
|
||||
- Abrir en navegador: `http://localhost/migrador/install.php`
|
||||
- Hacer clic en "Ejecutar Instalación"
|
||||
- Verificar que todas las tablas se crearon correctamente
|
||||
|
||||
### 2. 🔧 Verificar Sistema
|
||||
- Abrir: `http://localhost/migrador/test.php`
|
||||
- Revisar que todos los componentes estén en ✅
|
||||
|
||||
### 3. 🌐 Acceder al Panel
|
||||
- Abrir: `http://localhost/migrador/index.php`
|
||||
- Navegar por las diferentes secciones
|
||||
|
||||
### 4. ⚙️ Configurar WhatsApp (IMPORTANTE)
|
||||
1. Ir a **Configuración** en el panel
|
||||
2. Completar:
|
||||
- **Token de WhatsApp**: EAAWTKu1iZAGABP46c7GZAFvHremu9uvTLOlgZCAa4eKUlaCqszzsQjjLcgnqORzo2EBhB7LZAcAqJ7clpGvNCk3oXKnqo8Fl0K2o7eHYoeaqZBesqjBPRfsd4ZBOdY4kN1YBJnmRznegTD9wtJZByVrRcMXF8YXaAJjLCuIFZCK7QFUpId7i4eVkFvbqUYnUKA91rgPvaeGRNZCLHa5ZC1ZB2Skn0gFNgPTBx7bedAMULYZD
|
||||
- **Phone Number ID**: 938177732702718
|
||||
- **Webhook Token**: mi_token_secreto_123
|
||||
3. Guardar configuración
|
||||
|
||||
### 5. 🔗 Configurar Webhook en Facebook
|
||||
1. Ir a [Facebook for Developers](https://developers.facebook.com)
|
||||
2. Crear/configurar aplicación WhatsApp Business
|
||||
3. Webhook URL: `https://tudominio.com/migrador/api/webhook.php`
|
||||
4. Token de verificación: `mi_token_secreto_123`
|
||||
5. Suscribirse a eventos: `conversations`
|
||||
|
||||
## 🎯 Prueba Rápida del Bot
|
||||
|
||||
Envía estos mensajes por WhatsApp para probar:
|
||||
|
||||
```
|
||||
👤 Usuario: "Hola"
|
||||
🤖 Bot: Mensaje de bienvenida
|
||||
|
||||
👤 Usuario: "menu"
|
||||
🤖 Bot: Muestra menú principal
|
||||
|
||||
👤 Usuario: "1"
|
||||
🤖 Bot: Muestra submenú de servicios
|
||||
|
||||
👤 Usuario: "ayuda"
|
||||
🤖 Bot: Muestra información de ayuda
|
||||
```
|
||||
|
||||
## 📋 Funcionalidades Principales
|
||||
|
||||
### 🤖 Bot Automático
|
||||
- ✅ Menús navegables por números
|
||||
- ✅ Respuestas automáticas
|
||||
- ✅ Comandos especiales (menu, ayuda, salir)
|
||||
- ✅ Gestión de estados de usuario
|
||||
|
||||
### 🎛️ Panel de Control
|
||||
- ✅ Dashboard con estadísticas
|
||||
- ✅ Gestión de conversaciones
|
||||
- ✅ Administración de usuarios
|
||||
- ✅ Editor de menús
|
||||
- ✅ Envío de mensajes
|
||||
- ✅ Configuración del sistema
|
||||
|
||||
### 🔧 APIs Disponibles
|
||||
- ✅ Webhook para recibir mensajes
|
||||
- ✅ Envío de mensajes individuales
|
||||
- ✅ Envío masivo (broadcast)
|
||||
- ✅ Gestión de menús
|
||||
- ✅ Estadísticas y reportes
|
||||
|
||||
## 🛠️ Estructura de Archivos
|
||||
|
||||
```
|
||||
bot/
|
||||
├── 🏠 index.php # Panel principal
|
||||
├── 🔧 install.php # Instalador automático
|
||||
├── 🧪 test.php # Script de pruebas
|
||||
├── 📖 README.md # Documentación completa
|
||||
├── config/
|
||||
│ └── config.php # Configuración
|
||||
├── database/
|
||||
│ └── schema.sql # Esquema de BD
|
||||
├── api/ # APIs REST
|
||||
│ ├── webhook.php # Webhook principal
|
||||
│ ├── send_message.php # Envío de mensajes
|
||||
│ ├── get_stats.php # Estadísticas
|
||||
│ └── [más APIs...]
|
||||
├── classes/
|
||||
│ └── Database.php # Conexión BD
|
||||
├── services/
|
||||
│ ├── WhatsAppService.php # Servicio WhatsApp
|
||||
│ └── BotService.php # Lógica del bot
|
||||
└── assets/
|
||||
├── css/styles.css # Estilos
|
||||
└── js/app_simple.js # JavaScript
|
||||
```
|
||||
|
||||
## 🎨 Personalización
|
||||
|
||||
### Cambiar Menús
|
||||
1. Ir a **Menús** en el panel
|
||||
2. Editar menús existentes o crear nuevos
|
||||
3. Configurar opciones y acciones
|
||||
|
||||
### Agregar Respuestas Automáticas
|
||||
1. Ir a **Respuestas Auto**
|
||||
2. Agregar nuevas palabras clave
|
||||
3. Definir respuestas personalizadas
|
||||
|
||||
### Configurar Mensajes Masivos
|
||||
1. Ir a **Enviar Mensaje**
|
||||
2. Usar la sección "Mensaje Masivo"
|
||||
3. Seleccionar filtros de usuarios
|
||||
|
||||
## 🚨 Solución de Problemas
|
||||
|
||||
### ❌ Error de conexión BD
|
||||
- Verificar credenciales en `config/config.php`
|
||||
- Comprobar que MySQL esté funcionando
|
||||
- Revisar permisos del usuario
|
||||
|
||||
### ❌ Webhook no funciona
|
||||
- Verificar que la URL sea accesible públicamente
|
||||
- Comprobar SSL (debe ser HTTPS)
|
||||
- Revisar logs en el panel
|
||||
|
||||
### ❌ Bot no responde
|
||||
- Verificar token en configuración
|
||||
- Comprobar webhook en Facebook
|
||||
- Revisar logs de PHP
|
||||
|
||||
## 📞 URLs de Prueba
|
||||
|
||||
- **Panel**: http://localhost/bot/index.php
|
||||
- **Test**: http://localhost/bot/test.php
|
||||
- **API Stats**: http://localhost/bot/api/get_stats.php
|
||||
- **Webhook**: http://localhost/bot/api/webhook.php
|
||||
|
||||
## 🎯 ¡Sistema Listo!
|
||||
|
||||
Una vez completados todos los pasos, tendrás:
|
||||
|
||||
- 🤖 **Bot funcional** respondiendo mensajes automáticamente
|
||||
- 🎛️ **Panel web** para gestión completa
|
||||
- 📊 **Dashboard** con métricas en tiempo real
|
||||
- 🔧 **APIs** para integraciones personalizadas
|
||||
|
||||
¡Disfruta de tu nuevo sistema de WhatsApp Bot! 🚀
|
||||
@@ -0,0 +1,282 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="es">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>🚀 WhatsApp Bot - Instalación</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
|
||||
<style>
|
||||
:root {
|
||||
--primary-color: #25d366;
|
||||
--secondary-color: #075e54;
|
||||
--bg-gradient: linear-gradient(135deg, #25d366 0%, #075e54 100%);
|
||||
}
|
||||
body {
|
||||
background: var(--bg-gradient);
|
||||
min-height: 100vh;
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
}
|
||||
.install-card {
|
||||
background: rgba(255,255,255,0.95);
|
||||
border-radius: 20px;
|
||||
backdrop-filter: blur(10px);
|
||||
box-shadow: 0 20px 40px rgba(0,0,0,0.1);
|
||||
}
|
||||
.option-card {
|
||||
border: 2px solid transparent;
|
||||
border-radius: 15px;
|
||||
transition: all 0.3s ease;
|
||||
height: 100%;
|
||||
}
|
||||
.option-card:hover {
|
||||
border-color: var(--primary-color);
|
||||
transform: translateY(-5px);
|
||||
box-shadow: 0 10px 25px rgba(0,0,0,0.1);
|
||||
}
|
||||
.btn-install {
|
||||
background: var(--bg-gradient);
|
||||
border: none;
|
||||
color: white;
|
||||
padding: 12px 25px;
|
||||
border-radius: 10px;
|
||||
font-weight: 600;
|
||||
width: 100%;
|
||||
}
|
||||
.btn-install:hover {
|
||||
color: white;
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
.hosting-badge {
|
||||
position: absolute;
|
||||
top: -10px;
|
||||
right: 15px;
|
||||
font-size: 0.8rem;
|
||||
padding: 5px 10px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container mt-5">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-lg-10">
|
||||
<div class="install-card p-5">
|
||||
|
||||
<div class="text-center mb-5">
|
||||
<i class="fab fa-whatsapp text-success" style="font-size: 4rem;"></i>
|
||||
<h1 class="mt-3 fw-bold">WhatsApp Bot Manager</h1>
|
||||
<p class="text-muted">Elige el método de instalación según tu tipo de hosting</p>
|
||||
<div class="mt-3">
|
||||
<small class="text-muted">
|
||||
Desarrollado por <strong><a href="https://u-site.app" target="_blank" class="text-decoration-none">U-Site.app</a></strong>
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row g-3">
|
||||
<!-- Instalación Automática -->
|
||||
<div class="col-lg-2">
|
||||
<div class="option-card bg-light p-3 position-relative">
|
||||
<span class="hosting-badge badge bg-success">Local</span>
|
||||
<div class="text-center mb-2">
|
||||
<i class="fas fa-magic text-primary" style="font-size: 2rem;"></i>
|
||||
</div>
|
||||
<h6 class="text-center mb-2">🪄 Automática</h6>
|
||||
|
||||
<div class="mb-3">
|
||||
<ul class="list-unstyled small">
|
||||
<li>• Laragon/XAMPP</li>
|
||||
<li>• VPS con root</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<a href="install.php" class="btn btn-install btn-sm w-100">
|
||||
<i class="fas fa-play me-1"></i>Usar
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Instalación Manual -->
|
||||
<div class="col-lg-2">
|
||||
<div class="option-card bg-light p-3 position-relative">
|
||||
<span class="hosting-badge badge bg-warning">Hosting</span>
|
||||
<div class="text-center mb-2">
|
||||
<i class="fas fa-tools text-warning" style="font-size: 2rem;"></i>
|
||||
</div>
|
||||
<h6 class="text-center mb-2">🛠️ Manual</h6>
|
||||
|
||||
<div class="mb-3">
|
||||
<ul class="list-unstyled small">
|
||||
<li>• HestiaCP</li>
|
||||
<li>• Schema archivo</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<a href="install_manual.php" class="btn btn-install bg-warning text-dark btn-sm w-100">
|
||||
<i class="fas fa-wrench me-1"></i>Usar
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Instalación Integrada -->
|
||||
<div class="col-lg-2">
|
||||
<div class="option-card bg-light p-3 position-relative">
|
||||
<span class="hosting-badge badge bg-primary">Robusto</span>
|
||||
<div class="text-center mb-2">
|
||||
<i class="fas fa-cogs text-primary" style="font-size: 2rem;"></i>
|
||||
</div>
|
||||
<h6 class="text-center mb-2">🔧 Integrada</h6>
|
||||
|
||||
<div class="mb-3">
|
||||
<ul class="list-unstyled small">
|
||||
<li>• Schema interno</li>
|
||||
<li>• Muy confiable</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<a href="install_integrated.php" class="btn btn-install btn-sm w-100">
|
||||
<i class="fas fa-cog me-1"></i>Usar
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Instalación Ultra Básica -->
|
||||
<div class="col-lg-3">
|
||||
<div class="option-card bg-light p-3 position-relative border-danger">
|
||||
<span class="hosting-badge badge bg-danger">SOLUCIÓN</span>
|
||||
<div class="text-center mb-2">
|
||||
<i class="fas fa-medkit text-danger" style="font-size: 2rem;"></i>
|
||||
</div>
|
||||
<h6 class="text-center mb-2">⚡ Ultra Básico</h6>
|
||||
|
||||
<div class="mb-3">
|
||||
<ul class="list-unstyled small">
|
||||
<li><strong>• Para errores "Table doesn't exist"</strong></li>
|
||||
<li>• Solo tablas esenciales</li>
|
||||
<li>• Paso a paso verificado</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<a href="install_ultra_basic.php" class="btn btn-danger btn-sm w-100">
|
||||
<i class="fas fa-medkit me-1"></i>SOLUCIONAR
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Instalación Simplificada -->
|
||||
<div class="col-lg-3">
|
||||
<div class="option-card bg-light p-3 position-relative">
|
||||
<span class="hosting-badge badge bg-info">Rápido</span>
|
||||
<div class="text-center mb-2">
|
||||
<i class="fas fa-rocket text-info" style="font-size: 2rem;"></i>
|
||||
</div>
|
||||
<h6 class="text-center mb-2">📦 Simple</h6>
|
||||
|
||||
<div class="mb-3">
|
||||
<ul class="list-unstyled small">
|
||||
<li>• Solo lo esencial</li>
|
||||
<li>• Proceso rápido</li>
|
||||
<li>• Principiantes</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<a href="install_simple.php" class="btn btn-install btn-sm w-100" style="background: #17a2b8;">
|
||||
<i class="fas fa-bolt me-1"></i>Usar
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-5">
|
||||
<div class="alert alert-danger">
|
||||
<h5><i class="fas fa-exclamation-triangle me-2"></i>🚨 ¿Tienes errores de "Table doesn't exist"?</h5>
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<p><strong>Si ves errores como:</strong></p>
|
||||
<ul class="mb-2">
|
||||
<li>❌ "Table 'usite_whatsapp_bot.menus' doesn't exist"</li>
|
||||
<li>❌ "Table 'usite_whatsapp_bot.users' doesn't exist"</li>
|
||||
<li>❌ "0 tablas, 0 elementos procesados"</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-md-4 text-center">
|
||||
<a href="install_ultra_basic.php" class="btn btn-danger btn-lg">
|
||||
<i class="fas fa-medkit me-2"></i>SOLUCIÓN AQUÍ
|
||||
</a>
|
||||
<br><small class="text-muted">Instalador Ultra Básico</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="alert alert-warning">
|
||||
<h5><i class="fas fa-question-circle me-2"></i>¿Cuál elegir según tu situación?</h5>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<h6>🔥 <strong>Si tuviste errores con schema.sql:</strong></h6>
|
||||
<ul class="mb-2">
|
||||
<li>❌ "Table doesn't exist"</li>
|
||||
<li>❌ "0 tablas, 0 elementos"</li>
|
||||
<li>❌ Errores de parsing SQL</li>
|
||||
</ul>
|
||||
<p><strong>👉 USA:</strong> <span class="badge bg-danger">Ultra Básico</span> - Resuelve el problema</p>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<h6>💡 <strong>Recomendaciones generales:</strong></h6>
|
||||
<ul class="mb-2">
|
||||
<li><strong>Errores de tablas:</strong> Ultra Básico</li>
|
||||
<li><strong>Primera vez:</strong> Integrada</li>
|
||||
<li><strong>HestiaCP:</strong> Ultra Básico o Simple</li>
|
||||
<li><strong>Desarrollo:</strong> Automática</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row g-3 mt-4">
|
||||
<div class="col-md-3">
|
||||
<div class="text-center">
|
||||
<a href="GUIA_HESTIACP.md" target="_blank" class="btn btn-outline-primary">
|
||||
<i class="fas fa-book me-2"></i>Guía HestiaCP
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="text-center">
|
||||
<a href="debug_install.php" class="btn btn-outline-warning">
|
||||
<i class="fas fa-bug me-2"></i>Diagnóstico
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="text-center">
|
||||
<a href="INSTALACION.md" target="_blank" class="btn btn-outline-success">
|
||||
<i class="fas fa-file-alt me-2"></i>Documentación
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="text-center">
|
||||
<a href="test.php" class="btn btn-outline-info">
|
||||
<i class="fas fa-vial me-2"></i>Probar Sistema
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Footer -->
|
||||
<div class="mt-5 pt-4 border-top text-center">
|
||||
<small class="text-muted">
|
||||
WhatsApp Bot Manager v1.0 |
|
||||
Desarrollado por <strong>U-Site.app</strong> |
|
||||
<a href="https://u-site.app/support" target="_blank">Soporte técnico</a>
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,243 @@
|
||||
<?php
|
||||
/**
|
||||
* 🗄️ INSTALADOR DE BASE DE DATOS - WhatsApp Bot
|
||||
* Crea todas las tablas necesarias y corrige inconsistencias
|
||||
*/
|
||||
|
||||
// Headers para mostrar errores
|
||||
error_reporting(E_ALL);
|
||||
ini_set('display_errors', 1);
|
||||
set_time_limit(120); // 2 minutos máximo
|
||||
|
||||
echo "<!DOCTYPE html><html><head><meta charset='UTF-8'>";
|
||||
echo "<title>🗄️ Instalador BD</title>";
|
||||
echo "<style>body{font-family:monospace;margin:20px;background:#000;color:#00ff00}";
|
||||
echo ".ok{color:#00ff00}.error{color:#ff0040}.warning{color:#ffaa00}";
|
||||
echo ".section{background:#111;padding:15px;margin:10px 0;border:1px solid #333}";
|
||||
echo "pre{background:#222;padding:10px;color:#ccc;overflow:auto;max-height:200px}";
|
||||
echo "</style></head><body>";
|
||||
|
||||
echo "<h1>🗄️ INSTALADOR DE BASE DE DATOS</h1>";
|
||||
|
||||
// Cargar configuración
|
||||
try {
|
||||
require_once 'config/config.php';
|
||||
} catch (Exception $e) {
|
||||
echo "<div class='error'>❌ Error cargando configuración: " . htmlspecialchars($e->getMessage()) . "</div>";
|
||||
exit;
|
||||
}
|
||||
|
||||
// Verificar que existe el archivo schema.sql
|
||||
if (!file_exists('database/schema.sql')) {
|
||||
echo "<div class='error'>❌ CRÍTICO: database/schema.sql no encontrado</div>";
|
||||
exit;
|
||||
}
|
||||
|
||||
// Conectar a la base de datos
|
||||
try {
|
||||
$dsn = "mysql:host=" . DB_HOST . ";port=" . DB_PORT . ";dbname=" . DB_NAME . ";charset=" . DB_CHARSET;
|
||||
$pdo = new PDO($dsn, DB_USER, DB_PASS, [
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
|
||||
]);
|
||||
|
||||
echo "<div class='ok'>✅ Conectado a la base de datos</div>";
|
||||
|
||||
} catch (PDOException $e) {
|
||||
echo "<div class='error'>❌ Error de conexión: " . htmlspecialchars($e->getMessage()) . "</div>";
|
||||
exit;
|
||||
}
|
||||
|
||||
// Leer archivo SQL
|
||||
$sql_content = file_get_contents('database/schema.sql');
|
||||
if (!$sql_content) {
|
||||
echo "<div class='error'>❌ No se pudo leer database/schema.sql</div>";
|
||||
exit;
|
||||
}
|
||||
|
||||
echo "<div class='section'>";
|
||||
echo "<h2>📋 EJECUTANDO SCHEMA SQL...</h2>";
|
||||
|
||||
// Separar comandos SQL
|
||||
$commands = array_filter(
|
||||
array_map('trim', explode(';', $sql_content)),
|
||||
function($cmd) {
|
||||
return !empty($cmd) && !preg_match('/^\s*--/', $cmd);
|
||||
}
|
||||
);
|
||||
|
||||
$success_count = 0;
|
||||
$error_count = 0;
|
||||
|
||||
foreach ($commands as $i => $command) {
|
||||
if (empty(trim($command))) continue;
|
||||
|
||||
// Mostrar progreso cada 5 comandos
|
||||
if ($i % 5 === 0) {
|
||||
echo "<div class='warning'>Procesando comando " . ($i + 1) . "/" . count($commands) . "...</div>";
|
||||
flush();
|
||||
}
|
||||
|
||||
try {
|
||||
$pdo->exec($command);
|
||||
$success_count++;
|
||||
|
||||
// Solo mostrar detalles de CREATE TABLE y INSERT importantes
|
||||
if (preg_match('/CREATE TABLE (\w+)/', $command, $matches)) {
|
||||
echo "<div class='ok'>✅ Tabla '{$matches[1]}' creada</div>";
|
||||
} elseif (preg_match('/INSERT INTO (\w+)/', $command, $matches) && $i < 10) {
|
||||
echo "<div class='ok'>✅ Datos insertados en '{$matches[1]}'</div>";
|
||||
}
|
||||
|
||||
} catch (PDOException $e) {
|
||||
$error_count++;
|
||||
|
||||
// Si es error de tabla existente, es OK
|
||||
if (strpos($e->getMessage(), 'already exists') !== false) {
|
||||
if (preg_match('/CREATE TABLE (\w+)/', $command, $matches)) {
|
||||
echo "<div class='warning'>⚠️ Tabla '{$matches[1]}' ya existe</div>";
|
||||
}
|
||||
} else {
|
||||
echo "<div class='error'>❌ Error en comando " . ($i + 1) . ": " . htmlspecialchars($e->getMessage()) . "</div>";
|
||||
if (strlen($command) < 200) {
|
||||
echo "<pre>" . htmlspecialchars($command) . "</pre>";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
echo "<div class='ok'>📊 Comandos exitosos: $success_count</div>";
|
||||
echo "<div class='error'>📊 Errores: $error_count</div>";
|
||||
|
||||
echo "</div>";
|
||||
|
||||
// Ahora crear tablas adicionales que faltan
|
||||
echo "<div class='section'>";
|
||||
echo "<h2>🔧 CREANDO TABLAS FALTANTES...</h2>";
|
||||
|
||||
// Crear tabla 'conversations' como alias de conversations
|
||||
try {
|
||||
$pdo->exec("
|
||||
CREATE TABLE IF NOT EXISTS conversations (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
user_id INT NOT NULL,
|
||||
phone_number VARCHAR(20) NOT NULL,
|
||||
message_text TEXT,
|
||||
direction ENUM('incoming', 'outgoing') NOT NULL,
|
||||
message_type ENUM('text', 'image', 'audio', 'video', 'document', 'template') DEFAULT 'text',
|
||||
status ENUM('sent', 'delivered', 'read', 'failed') DEFAULT 'sent',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
INDEX idx_phone (phone_number),
|
||||
INDEX idx_direction (direction),
|
||||
INDEX idx_created (created_at)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
");
|
||||
echo "<div class='ok'>✅ Tabla 'conversations' creada</div>";
|
||||
} catch (PDOException $e) {
|
||||
if (strpos($e->getMessage(), 'already exists') === false) {
|
||||
echo "<div class='error'>❌ Error creando tabla conversations: " . htmlspecialchars($e->getMessage()) . "</div>";
|
||||
} else {
|
||||
echo "<div class='warning'>⚠️ Tabla 'conversations' ya existe</div>";
|
||||
}
|
||||
}
|
||||
|
||||
// Crear tabla 'system_config' como alias de system_config
|
||||
try {
|
||||
$pdo->exec("
|
||||
CREATE TABLE IF NOT EXISTS system_config (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
setting_key VARCHAR(100) UNIQUE NOT NULL,
|
||||
setting_value TEXT,
|
||||
description TEXT,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
");
|
||||
echo "<div class='ok'>✅ Tabla 'system_config' creada</div>";
|
||||
} catch (PDOException $e) {
|
||||
if (strpos($e->getMessage(), 'already exists') === false) {
|
||||
echo "<div class='error'>❌ Error creando tabla system_config: " . htmlspecialchars($e->getMessage()) . "</div>";
|
||||
} else {
|
||||
echo "<div class='warning'>⚠️ Tabla 'system_config' ya existe</div>";
|
||||
}
|
||||
}
|
||||
|
||||
echo "</div>";
|
||||
|
||||
// Copiar datos de system_config a system_config si no existen
|
||||
echo "<div class='section'>";
|
||||
echo "<h2>📊 SINCRONIZANDO CONFIGURACIÓN...</h2>";
|
||||
|
||||
try {
|
||||
// Copiar datos de system_config a system_config
|
||||
$pdo->exec("
|
||||
INSERT IGNORE INTO system_config (setting_key, setting_value, description, created_at)
|
||||
SELECT config_key, config_value, description, created_at
|
||||
FROM system_config
|
||||
WHERE config_key IS NOT NULL
|
||||
");
|
||||
|
||||
$affected = $pdo->lastInsertId();
|
||||
echo "<div class='ok'>✅ Configuraciones sincronizadas</div>";
|
||||
|
||||
} catch (PDOException $e) {
|
||||
echo "<div class='warning'>⚠️ Error sincronizando: " . htmlspecialchars($e->getMessage()) . "</div>";
|
||||
}
|
||||
|
||||
// Verificar que el SECRET_KEY esté definido
|
||||
try {
|
||||
if (!defined('SECRET_KEY') || empty(SECRET_KEY)) {
|
||||
$secret_key = bin2hex(random_bytes(32));
|
||||
$pdo->prepare("INSERT INTO system_config (setting_key, setting_value, description) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE setting_value = VALUES(setting_value)")
|
||||
->execute(['SECRET_KEY', $secret_key, 'Clave secreta para encriptación']);
|
||||
echo "<div class='ok'>✅ SECRET_KEY generada y guardada</div>";
|
||||
echo "<div class='warning'>🔑 IMPORTANTE: Agrega esta línea a config/config.php:</div>";
|
||||
echo "<pre>define('SECRET_KEY', '$secret_key');</pre>";
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
echo "<div class='error'>❌ Error generando SECRET_KEY: " . htmlspecialchars($e->getMessage()) . "</div>";
|
||||
}
|
||||
|
||||
echo "</div>";
|
||||
|
||||
// Verificación final
|
||||
echo "<div class='section'>";
|
||||
echo "<h2>✅ VERIFICACIÓN FINAL</h2>";
|
||||
|
||||
$required_tables = ['conversations', 'conversations', 'system_config', 'message_templates', 'users', 'menus'];
|
||||
$missing_tables = [];
|
||||
|
||||
foreach ($required_tables as $table) {
|
||||
try {
|
||||
$stmt = $pdo->query("SHOW TABLES LIKE '$table'");
|
||||
if ($stmt->rowCount() > 0) {
|
||||
// Contar registros
|
||||
$count_stmt = $pdo->query("SELECT COUNT(*) as count FROM $table");
|
||||
$count = $count_stmt->fetch()['count'];
|
||||
echo "<div class='ok'>✅ Tabla '$table' existe ($count registros)</div>";
|
||||
} else {
|
||||
$missing_tables[] = $table;
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
echo "<div class='error'>❌ Error verificando tabla '$table': " . htmlspecialchars($e->getMessage()) . "</div>";
|
||||
$missing_tables[] = $table;
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($missing_tables)) {
|
||||
echo "<div class='ok'>🎉 ¡TODAS LAS TABLAS ESTÁN LISTAS!</div>";
|
||||
echo "<div class='ok'>✅ Base de datos completamente configurada</div>";
|
||||
echo "<div class='ok'>✅ Sistema debería funcionar ahora</div>";
|
||||
|
||||
echo "<br><div class='warning'><strong>PRÓXIMO PASO:</strong></div>";
|
||||
echo "<div class='warning'>• Probar: <a href='login.php' style='color:#ffaa00'>login.php</a></div>";
|
||||
echo "<div class='warning'>• Si funciona, probar: <a href='index.php' style='color:#ffaa00'>index.php</a></div>";
|
||||
} else {
|
||||
echo "<div class='error'>❌ Faltan tablas: " . implode(', ', $missing_tables) . "</div>";
|
||||
echo "<div class='error'>❌ Sistema NO puede funcionar</div>";
|
||||
}
|
||||
|
||||
echo "</div>";
|
||||
|
||||
echo "</body></html>";
|
||||
?>
|
||||
@@ -0,0 +1,493 @@
|
||||
<?php
|
||||
/**
|
||||
* Instalador automático del sistema WhatsApp Bot
|
||||
* Desarrollado por U-Site.app - https://u-site.app
|
||||
* Genera contraseña aleatoria y configura la base de datos
|
||||
* Fecha: 13 de noviembre de 2025
|
||||
*/
|
||||
|
||||
// Verificar si la instalación ya está completada
|
||||
$installationLockFile = '.installation_completed';
|
||||
if (file_exists($installationLockFile)) {
|
||||
header('Location: login.php');
|
||||
exit('La instalación ya está completada. <a href="login.php">Iniciar sesión</a>');
|
||||
}
|
||||
|
||||
// Función para generar contraseña aleatoria segura
|
||||
function generateRandomPassword($length = 20) {
|
||||
$chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*-_=+';
|
||||
$password = '';
|
||||
for ($i = 0; $i < $length; $i++) {
|
||||
$password .= $chars[random_int(0, strlen($chars) - 1)];
|
||||
}
|
||||
return $password;
|
||||
}
|
||||
|
||||
// Configuración de la instalación (compatible con cPanel)
|
||||
$dbHost = 'localhost';
|
||||
$dbName = 'whatsapp_bot';
|
||||
$dbUser = 'whatsapp_user';
|
||||
$dbPass = generateRandomPassword(20);
|
||||
$dbRootUser = 'root';
|
||||
$dbRootPass = ''; // En cPanel puede requerir contraseña
|
||||
|
||||
// Generar contraseña para admin
|
||||
$adminPassword = generateRandomPassword(12);
|
||||
|
||||
$installStep = $_GET['step'] ?? 'welcome';
|
||||
$errors = [];
|
||||
$success = [];
|
||||
|
||||
// Procesar instalación
|
||||
if ($installStep === 'install' && $_POST) {
|
||||
try {
|
||||
// 1. Intentar conectar como root para crear base de datos y usuario
|
||||
try {
|
||||
$rootPdo = new PDO("mysql:host=$dbHost;charset=utf8mb4", $dbRootUser, $dbRootPass);
|
||||
$rootPdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
} catch (PDOException $e) {
|
||||
// Si no se puede conectar como root, es probable que sea hosting compartido
|
||||
throw new Exception("⚠️ HOSTING COMPARTIDO DETECTADO ⚠️<br><br>" .
|
||||
"No se pueden crear bases de datos automáticamente en este tipo de hosting.<br><br>" .
|
||||
"<strong>SOLUCIÓN:</strong><br>" .
|
||||
"1. Crea manualmente la base de datos y usuario en tu panel de control<br>" .
|
||||
"2. Usa <a href='install_manual.php' class='btn btn-warning btn-sm'>install_manual.php</a> en su lugar<br>" .
|
||||
"3. Lee la guía: <a href='GUIA_HESTIACP.md' target='_blank'>GUIA_HESTIACP.md</a><br><br>" .
|
||||
"Error técnico: " . $e->getMessage());
|
||||
}
|
||||
|
||||
// 2. Crear base de datos
|
||||
$rootPdo->exec("CREATE DATABASE IF NOT EXISTS `$dbName` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci");
|
||||
$success[] = "✅ Base de datos '$dbName' creada correctamente";
|
||||
|
||||
// 3. Crear usuario con permisos
|
||||
$rootPdo->exec("DROP USER IF EXISTS '$dbUser'@'localhost'");
|
||||
$rootPdo->exec("CREATE USER '$dbUser'@'localhost' IDENTIFIED BY '$dbPass'");
|
||||
$rootPdo->exec("GRANT ALL PRIVILEGES ON `$dbName`.* TO '$dbUser'@'localhost'");
|
||||
$rootPdo->exec("FLUSH PRIVILEGES");
|
||||
$success[] = "✅ Usuario '$dbUser' creado con contraseña aleatoria";
|
||||
|
||||
// 4. Conectar con nuevo usuario
|
||||
$pdo = new PDO("mysql:host=$dbHost;dbname=$dbName;charset=utf8mb4", $dbUser, $dbPass);
|
||||
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
|
||||
// 5. Crear tablas desde schema.sql
|
||||
$schema = file_get_contents('database/schema.sql');
|
||||
if (!$schema) {
|
||||
throw new Exception("No se pudo leer el archivo schema.sql");
|
||||
}
|
||||
|
||||
// Ejecutar comandos SQL uno por uno
|
||||
$statements = array_filter(array_map('trim', explode(';', $schema)));
|
||||
$tablesCreated = 0;
|
||||
|
||||
foreach ($statements as $statement) {
|
||||
if (!empty($statement) && !preg_match('/^--/', $statement)) {
|
||||
$pdo->exec($statement);
|
||||
if (preg_match('/CREATE TABLE|INSERT INTO/', $statement)) {
|
||||
$tablesCreated++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$success[] = "✅ $tablesCreated elementos de base de datos procesados";
|
||||
|
||||
// 6. Actualizar archivo de configuración
|
||||
$configFile = 'config/config.php';
|
||||
$configContent = file_get_contents($configFile);
|
||||
|
||||
$configContent = preg_replace("/define\('DB_HOST',\s*'[^']*'\);/", "define('DB_HOST', '$dbHost');", $configContent);
|
||||
$configContent = preg_replace("/define\('DB_NAME',\s*'[^']*'\);/", "define('DB_NAME', '$dbName');", $configContent);
|
||||
$configContent = preg_replace("/define\('DB_USER',\s*'[^']*'\);/", "define('DB_USER', '$dbUser');", $configContent);
|
||||
$configContent = preg_replace("/define\('DB_PASS',\s*'[^']*'\);/", "define('DB_PASS', '$dbPass');", $configContent);
|
||||
$configContent = preg_replace("/define\('ADMIN_PASSWORD',\s*'[^']*'\);/", "define('ADMIN_PASSWORD', '" . password_hash($adminPassword, PASSWORD_DEFAULT) . "');", $configContent);
|
||||
|
||||
// Auto-detectar URL del servidor
|
||||
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https://' : 'http://';
|
||||
$host = $_SERVER['HTTP_HOST'];
|
||||
$path = dirname($_SERVER['SCRIPT_NAME']);
|
||||
$autoUrl = $protocol . $host . $path;
|
||||
$configContent = preg_replace("/define\('APP_URL',\s*'[^']*'\);/", "define('APP_URL', '$autoUrl');", $configContent);
|
||||
|
||||
file_put_contents($configFile, $configContent);
|
||||
$success[] = "✅ Archivo config.php actualizado con nuevas credenciales";
|
||||
|
||||
// 7. Crear archivo de bloqueo de instalación
|
||||
$lockContent = "Instalación completada: " . date('Y-m-d H:i:s') . "\n";
|
||||
$lockContent .= "Desarrollado por: U-Site.app\n";
|
||||
$lockContent .= "URL: https://u-site.app\n";
|
||||
file_put_contents($installationLockFile, $lockContent);
|
||||
$success[] = "✅ Sistema bloqueado contra reinstalaciones";
|
||||
|
||||
// 8. Crear archivo de credenciales para referencia
|
||||
$credentialsFile = "CREDENCIALES_SISTEMA.txt";
|
||||
$credentialsContent = "=== CREDENCIALES DEL SISTEMA WHATSAPP BOT ===\n";
|
||||
$credentialsContent .= "Desarrollado por: U-Site.app (https://u-site.app)\n";
|
||||
$credentialsContent .= "Generado automáticamente: " . date('Y-m-d H:i:s') . "\n\n";
|
||||
$credentialsContent .= "=== BASE DE DATOS ===\n";
|
||||
$credentialsContent .= "Host: $dbHost\n";
|
||||
$credentialsContent .= "Base de datos: $dbName\n";
|
||||
$credentialsContent .= "Usuario: $dbUser\n";
|
||||
$credentialsContent .= "Contraseña: $dbPass\n\n";
|
||||
$credentialsContent .= "=== PANEL ADMINISTRATIVO ===\n";
|
||||
$credentialsContent .= "Usuario: admin\n";
|
||||
$credentialsContent .= "Contraseña: $adminPassword\n";
|
||||
$credentialsContent .= "URL Login: $autoUrl/login.php\n\n";
|
||||
$credentialsContent .= "⚠️ IMPORTANTE: Guarda estas credenciales en un lugar seguro.\n";
|
||||
$credentialsContent .= "⚠️ Elimina este archivo después de guardar las credenciales.\n";
|
||||
$credentialsContent .= "⚠️ El sistema está protegido contra reinstalaciones.\n\n";
|
||||
$credentialsContent .= "📞 Soporte técnico: support@u-site.app\n";
|
||||
|
||||
file_put_contents($credentialsFile, $credentialsContent);
|
||||
$success[] = "✅ Archivo de credenciales creado: $credentialsFile";
|
||||
|
||||
$installStep = 'completed';
|
||||
|
||||
} catch (PDOException $e) {
|
||||
$errors[] = "❌ Error de base de datos: " . $e->getMessage();
|
||||
} catch (Exception $e) {
|
||||
$errors[] = "❌ Error general: " . $e->getMessage();
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="es">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>🚀 Instalador WhatsApp Bot</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
|
||||
<style>
|
||||
:root {
|
||||
--primary-color: #25d366;
|
||||
--secondary-color: #075e54;
|
||||
--bg-gradient: linear-gradient(135deg, #25d366 0%, #075e54 100%);
|
||||
}
|
||||
body {
|
||||
background: var(--bg-gradient);
|
||||
min-height: 100vh;
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
}
|
||||
.install-card {
|
||||
background: rgba(255,255,255,0.95);
|
||||
border-radius: 20px;
|
||||
backdrop-filter: blur(10px);
|
||||
box-shadow: 0 20px 40px rgba(0,0,0,0.1);
|
||||
}
|
||||
.btn-install {
|
||||
background: var(--bg-gradient);
|
||||
border: none;
|
||||
color: white;
|
||||
padding: 15px 30px;
|
||||
border-radius: 10px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.btn-install:hover {
|
||||
transform: translateY(-2px);
|
||||
color: white;
|
||||
}
|
||||
.password-display {
|
||||
background: #f8f9fa;
|
||||
border: 2px dashed #28a745;
|
||||
border-radius: 10px;
|
||||
font-family: 'Courier New', monospace;
|
||||
font-size: 1.1rem;
|
||||
font-weight: bold;
|
||||
color: #155724;
|
||||
word-break: break-all;
|
||||
padding: 15px;
|
||||
}
|
||||
.step-indicator {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 50%;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-right: 15px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.step-active { background: var(--primary-color); color: white; }
|
||||
.step-completed { background: #28a745; color: white; }
|
||||
.step-pending { background: #e9ecef; color: #6c757d; }
|
||||
.console-output {
|
||||
background: #1e1e1e;
|
||||
color: #00ff00;
|
||||
border-radius: 10px;
|
||||
font-family: 'Courier New', monospace;
|
||||
font-size: 0.9rem;
|
||||
max-height: 300px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.blink {
|
||||
animation: blink 1s infinite;
|
||||
}
|
||||
@keyframes blink {
|
||||
0%, 50% { opacity: 1; }
|
||||
51%, 100% { opacity: 0; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container mt-5">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-lg-8">
|
||||
<div class="install-card p-5">
|
||||
|
||||
<?php if ($installStep === 'welcome'): ?>
|
||||
<!-- Pantalla de Bienvenida -->
|
||||
<div class="text-center mb-4">
|
||||
<i class="fas fa-database text-primary" style="font-size: 4rem;"></i>
|
||||
<h1 class="mt-3 fw-bold">Instalador WhatsApp Bot</h1>
|
||||
<p class="text-muted">Configuración automática con credenciales aleatorias</p>
|
||||
<div class="mt-3">
|
||||
<small class="text-muted">
|
||||
Desarrollado por <strong><a href="https://u-site.app" target="_blank" class="text-decoration-none">U-Site.app</a></strong> |
|
||||
<a href="https://u-site.app/support" target="_blank" class="text-decoration-none">Soporte técnico</a>
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row g-3 mb-4">
|
||||
<div class="col-md-4">
|
||||
<div class="d-flex align-items-center">
|
||||
<span class="step-indicator step-active">1</span>
|
||||
<div>
|
||||
<h6 class="mb-1">Crear BD</h6>
|
||||
<small class="text-muted">Base de datos: <strong>whatsapp_bot</strong></small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="d-flex align-items-center">
|
||||
<span class="step-indicator step-pending">2</span>
|
||||
<div>
|
||||
<h6 class="mb-1">Crear Usuario</h6>
|
||||
<small class="text-muted">Usuario: <strong>whatsapp_user</strong></small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="d-flex align-items-center">
|
||||
<span class="step-indicator step-pending">3</span>
|
||||
<div>
|
||||
<h6 class="mb-1">Configurar</h6>
|
||||
<small class="text-muted">Aplicar configuración</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="alert alert-info">
|
||||
<i class="fas fa-info-circle me-2"></i>
|
||||
<strong>Configuración automática para cPanel/hosting compartido:</strong>
|
||||
<ul class="mb-0 mt-2">
|
||||
<li><strong>Host:</strong> localhost (compatible con cualquier hosting)</li>
|
||||
<li><strong>Base de datos:</strong> whatsapp_bot (se creará automáticamente)</li>
|
||||
<li><strong>Usuario DB:</strong> whatsapp_user (se creará automáticamente)</li>
|
||||
<li><strong>Contraseña DB:</strong> Se generará aleatoriamente (20 caracteres)</li>
|
||||
<li><strong>Usuario Admin:</strong> admin</li>
|
||||
<li><strong>Contraseña Admin:</strong> Se generará aleatoriamente (12 caracteres)</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="alert alert-success">
|
||||
<i class="fas fa-shield-alt me-2"></i>
|
||||
<strong>Características de seguridad:</strong>
|
||||
<ul class="mb-0 mt-2">
|
||||
<li>✅ Protección contra reinstalaciones</li>
|
||||
<li>✅ Sistema de login con bloqueo por intentos</li>
|
||||
<li>✅ Contraseñas encriptadas</li>
|
||||
<li>✅ Auto-detección de URL del servidor</li>
|
||||
<li>✅ Compatible con cualquier hosting cPanel</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="alert alert-warning">
|
||||
<i class="fas fa-exclamation-triangle me-2"></i>
|
||||
<strong>Requisitos:</strong> Asegúrate de que MySQL esté funcionando en Laragon
|
||||
</div>
|
||||
|
||||
<div class="alert alert-danger">
|
||||
<i class="fas fa-server me-2"></i>
|
||||
<strong>⚠️ ¿Usas hosting compartido? (HestiaCP, cPanel, etc.)</strong><br>
|
||||
Este instalador automático <strong>NO funcionará</strong> en hosting compartido porque requiere privilegios de administrador.<br><br>
|
||||
<strong>👉 SOLUCIÓN:</strong>
|
||||
<a href="install_manual.php" class="btn btn-warning btn-sm me-2">
|
||||
<i class="fas fa-tools me-1"></i>Usar Instalador Manual
|
||||
</a>
|
||||
<a href="GUIA_HESTIACP.md" target="_blank" class="btn btn-info btn-sm">
|
||||
<i class="fas fa-book me-1"></i>Ver Guía
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="text-center mb-4">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<div class="password-display">
|
||||
🔐 CONTRASEÑA BD:<br>
|
||||
<strong><?= htmlspecialchars($dbPass) ?></strong>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="password-display">
|
||||
👤 CONTRASEÑA ADMIN:<br>
|
||||
<strong><?= htmlspecialchars($adminPassword) ?></strong>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="text-center">
|
||||
<a href="?step=install" class="btn btn-install btn-lg">
|
||||
<i class="fas fa-play me-2"></i>Iniciar Instalación
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<?php elseif ($installStep === 'install'): ?>
|
||||
<!-- Pantalla de Instalación -->
|
||||
<div class="text-center mb-4">
|
||||
<i class="fas fa-cog fa-spin text-warning" style="font-size: 3rem;"></i>
|
||||
<h2 class="mt-3">Instalando Sistema...</h2>
|
||||
<p class="text-muted">Configurando base de datos automáticamente</p>
|
||||
</div>
|
||||
|
||||
<form method="POST" id="installForm">
|
||||
<div class="console-output p-4 mb-4">
|
||||
<div>WhatsApp Bot Installer v1.0</div>
|
||||
<div>Connecting to MySQL server (localhost)...</div>
|
||||
<div>Generating secure random password...</div>
|
||||
<div class="mt-3">
|
||||
<strong style="color: #ffff00;">🔐 CONTRASEÑAS GENERADAS:</strong><br>
|
||||
<span style="color: #00ffff; font-size: 1.0rem;">DB: <?= htmlspecialchars($dbPass) ?></span><br>
|
||||
<span style="color: #00ff00; font-size: 1.0rem;">Admin: <?= htmlspecialchars($adminPassword) ?></span>
|
||||
</div>
|
||||
<div class="mt-2">Creating database 'whatsapp_bot'...</div>
|
||||
<div>Creating user 'whatsapp_user'@'localhost'...</div>
|
||||
<div>Granting privileges...</div>
|
||||
<div>Installing database schema...</div>
|
||||
<div>Updating configuration files...</div>
|
||||
<div class="text-success mt-2">Ready to execute installation <span class="blink">_</span></div>
|
||||
</div>
|
||||
|
||||
<div class="text-center">
|
||||
<button type="submit" class="btn btn-install btn-lg">
|
||||
<i class="fas fa-database me-2"></i>Ejecutar Instalación
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<script>
|
||||
// Auto-submit después de mostrar la información
|
||||
setTimeout(function() {
|
||||
document.getElementById('installForm').submit();
|
||||
}, 4000);
|
||||
</script>
|
||||
|
||||
<?php elseif ($installStep === 'completed'): ?>
|
||||
<!-- Pantalla de Completado -->
|
||||
<div class="text-center mb-4">
|
||||
<i class="fas fa-check-circle text-success" style="font-size: 4rem;"></i>
|
||||
<h1 class="mt-3 text-success fw-bold">¡Instalación Completada!</h1>
|
||||
<p class="text-muted">Tu sistema WhatsApp Bot está listo para usar</p>
|
||||
</div>
|
||||
|
||||
<!-- Mostrar errores si los hay -->
|
||||
<?php if (!empty($errors)): ?>
|
||||
<div class="alert alert-danger">
|
||||
<h5><i class="fas fa-exclamation-triangle me-2"></i>Errores encontrados:</h5>
|
||||
<?php foreach ($errors as $error): ?>
|
||||
<div><?= htmlspecialchars($error) ?></div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- Mostrar éxitos -->
|
||||
<?php if (!empty($success)): ?>
|
||||
<div class="alert alert-success">
|
||||
<h5><i class="fas fa-check-circle me-2"></i>Instalación exitosa:</h5>
|
||||
<?php foreach ($success as $msg): ?>
|
||||
<div><?= htmlspecialchars($msg) ?></div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- Mostrar credenciales -->
|
||||
<div class="row g-4 mb-4">
|
||||
<div class="col-md-6">
|
||||
<h5><i class="fas fa-database me-2 text-primary"></i>Credenciales de BD</h5>
|
||||
<div class="bg-light p-3 rounded">
|
||||
<div><strong>Host:</strong> <?= $dbHost ?></div>
|
||||
<div><strong>Base de datos:</strong> <?= $dbName ?></div>
|
||||
<div><strong>Usuario:</strong> <?= $dbUser ?></div>
|
||||
<div class="mt-2">
|
||||
<strong>Contraseña:</strong><br>
|
||||
<div class="password-display mt-1">
|
||||
<?= htmlspecialchars($dbPass) ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h5 class="mt-3"><i class="fas fa-user-shield me-2 text-success"></i>Credenciales Admin</h5>
|
||||
<div class="bg-light p-3 rounded">
|
||||
<div><strong>Usuario:</strong> admin</div>
|
||||
<div class="mt-2">
|
||||
<strong>Contraseña:</strong><br>
|
||||
<div class="password-display mt-1">
|
||||
<?= htmlspecialchars($adminPassword) ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-2"><strong>URL Login:</strong><br>
|
||||
<a href="login.php" target="_blank"><?= AUTO_DETECTED_URL ?? $autoUrl ?? '' ?>/login.php</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<h5><i class="fas fa-link me-2 text-success"></i>Próximos Pasos</h5>
|
||||
<div class="d-grid gap-2">
|
||||
<a href="login.php" class="btn btn-install">
|
||||
<i class="fas fa-sign-in-alt me-2"></i>Iniciar Sesión
|
||||
</a>
|
||||
<a href="test.php" class="btn btn-outline-primary">
|
||||
<i class="fas fa-check-circle me-2"></i>Probar Sistema
|
||||
</a>
|
||||
<a href="server_setup.php" class="btn btn-outline-warning">
|
||||
<i class="fab fa-whatsapp me-2"></i>Configurar WhatsApp
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="alert alert-warning">
|
||||
<i class="fas fa-exclamation-triangle me-2"></i>
|
||||
<strong>¡IMPORTANTE!</strong>
|
||||
<ul class="mb-0 mt-2">
|
||||
<li>Guarda las credenciales en un lugar seguro</li>
|
||||
<li>El archivo <code>CREDENCIALES_SISTEMA.txt</code> contiene toda la información</li>
|
||||
<li>Elimina este archivo después de guardar las credenciales</li>
|
||||
<li><strong>El sistema está protegido contra reinstalaciones</strong></li>
|
||||
<li>Configura tu token de WhatsApp después del login</li>
|
||||
<li>Soporte técnico: <a href="mailto:support@u-site.app">support@u-site.app</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- Footer -->
|
||||
<div class="mt-5 pt-4 border-top text-center">
|
||||
<small class="text-muted">
|
||||
WhatsApp Bot Manager v1.0 by <strong>U-Site.app</strong> |
|
||||
Instalación automática con credenciales seguras |
|
||||
<a href="https://u-site.app/support" target="_blank">Soporte</a>
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,438 @@
|
||||
<?php
|
||||
/**
|
||||
* Instalador con Schema Integrado
|
||||
* Evita problemas de parsing del archivo schema.sql
|
||||
* Desarrollado por U-Site.app
|
||||
* Fecha: 14 de noviembre de 2025
|
||||
*/
|
||||
|
||||
// Verificar si ya está instalado
|
||||
if (file_exists('.installation_completed')) {
|
||||
header('Location: login.php');
|
||||
exit('Sistema ya instalado');
|
||||
}
|
||||
|
||||
$step = $_GET['step'] ?? 'form';
|
||||
$errors = [];
|
||||
$success = [];
|
||||
|
||||
function generatePassword($length = 12) {
|
||||
return bin2hex(random_bytes($length / 2));
|
||||
}
|
||||
|
||||
$adminPassword = generatePassword(12);
|
||||
|
||||
// Schema SQL integrado (evita problemas de parsing)
|
||||
$integratedSchema = [
|
||||
// Crear tablas principales
|
||||
"CREATE TABLE IF NOT EXISTS users (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
phone_number VARCHAR(20) UNIQUE NOT NULL,
|
||||
name VARCHAR(100),
|
||||
email VARCHAR(100),
|
||||
status ENUM('active', 'inactive', 'blocked') DEFAULT 'active',
|
||||
current_menu_id INT NULL,
|
||||
current_step INT DEFAULT 0,
|
||||
session_data JSON,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
INDEX idx_phone (phone_number),
|
||||
INDEX idx_status (status)
|
||||
)",
|
||||
|
||||
"CREATE TABLE IF NOT EXISTS conversations (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
user_id INT NOT NULL,
|
||||
message_id VARCHAR(100),
|
||||
direction ENUM('incoming', 'outgoing') NOT NULL,
|
||||
message_type ENUM('text', 'image', 'audio', 'video', 'document', 'template') DEFAULT 'text',
|
||||
content TEXT,
|
||||
media_url VARCHAR(500),
|
||||
status ENUM('sent', 'delivered', 'read', 'failed') DEFAULT 'sent',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
|
||||
INDEX idx_user (user_id),
|
||||
INDEX idx_created (created_at)
|
||||
)",
|
||||
|
||||
"CREATE TABLE IF NOT EXISTS menus (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
name VARCHAR(100) NOT NULL,
|
||||
title VARCHAR(200) NOT NULL,
|
||||
description TEXT,
|
||||
parent_id INT NULL,
|
||||
is_root BOOLEAN DEFAULT FALSE,
|
||||
is_active BOOLEAN DEFAULT TRUE,
|
||||
order_position INT DEFAULT 0,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (parent_id) REFERENCES menus(id) ON DELETE CASCADE,
|
||||
INDEX idx_parent (parent_id),
|
||||
INDEX idx_active (is_active)
|
||||
)",
|
||||
|
||||
"CREATE TABLE IF NOT EXISTS menu_options (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
menu_id INT NOT NULL,
|
||||
option_number INT NOT NULL,
|
||||
text VARCHAR(200) NOT NULL,
|
||||
action_type ENUM('menu', 'message', 'api_call', 'end') NOT NULL,
|
||||
action_value VARCHAR(500),
|
||||
is_active BOOLEAN DEFAULT TRUE,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (menu_id) REFERENCES menus(id) ON DELETE CASCADE,
|
||||
UNIQUE KEY unique_menu_option (menu_id, option_number)
|
||||
)",
|
||||
|
||||
"CREATE TABLE IF NOT EXISTS system_config (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
config_key VARCHAR(100) UNIQUE NOT NULL,
|
||||
config_value TEXT,
|
||||
description TEXT,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
||||
)",
|
||||
|
||||
"CREATE TABLE IF NOT EXISTS autoresponses (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
trigger_type ENUM('keyword', 'menu_selection', 'welcome') NOT NULL,
|
||||
trigger_value VARCHAR(200),
|
||||
response_text TEXT NOT NULL,
|
||||
response_type ENUM('text', 'template') DEFAULT 'text',
|
||||
is_active BOOLEAN DEFAULT TRUE,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
)",
|
||||
|
||||
"CREATE TABLE IF NOT EXISTS webhook_logs (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
request_body TEXT,
|
||||
response_body TEXT,
|
||||
status_code INT,
|
||||
ip_address VARCHAR(45),
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
INDEX idx_created (created_at)
|
||||
)"
|
||||
];
|
||||
|
||||
$initialData = [
|
||||
// Configuración inicial
|
||||
"INSERT IGNORE INTO system_config (config_key, config_value, description) VALUES
|
||||
('whatsapp_token', 'TU_TOKEN_AQUI', 'Token de WhatsApp Business API'),
|
||||
('whatsapp_phone_number_id', 'TU_PHONE_ID_AQUI', 'ID del número de teléfono'),
|
||||
('webhook_verify_token', 'mi_token_secreto_123', 'Token de verificación del webhook'),
|
||||
('welcome_message', '¡Hola! 👋 Bienvenido. Escribe *menu* para ver opciones.', 'Mensaje de bienvenida'),
|
||||
('business_name', 'Mi Empresa', 'Nombre de la empresa'),
|
||||
('app_installed', '1', 'Marca de instalación completada'),
|
||||
('install_date', NOW(), 'Fecha de instalación')",
|
||||
|
||||
// Menú principal
|
||||
"INSERT IGNORE INTO menus (id, name, title, description, is_root, order_position) VALUES
|
||||
(1, 'main_menu', '🏠 Menú Principal', 'Menú principal del sistema', TRUE, 1)",
|
||||
|
||||
// Opciones del menú principal
|
||||
"INSERT IGNORE INTO menu_options (menu_id, option_number, text, action_type, action_value) VALUES
|
||||
(1, 1, '📋 Información', 'message', 'Gracias por contactarnos. Un representante te atenderá pronto.'),
|
||||
(1, 2, '📞 Soporte', 'message', 'Para soporte técnico, describe tu consulta y te ayudaremos.'),
|
||||
(1, 0, '❌ Salir', 'end', 'Gracias por contactarnos. ¡Hasta pronto!')",
|
||||
|
||||
// Respuestas automáticas
|
||||
"INSERT IGNORE INTO autoresponses (trigger_type, trigger_value, response_text) VALUES
|
||||
('keyword', 'menu', 'Aquí tienes nuestro menú principal:'),
|
||||
('keyword', 'hola', '¡Hola! 👋 Escribe *menu* para ver opciones.'),
|
||||
('welcome', '', '¡Bienvenido! 👋 Escribe *menu* para comenzar.')"
|
||||
];
|
||||
|
||||
if ($step === 'install' && $_POST) {
|
||||
$dbHost = trim($_POST['db_host'] ?? 'localhost');
|
||||
$dbPort = trim($_POST['db_port'] ?? '3306');
|
||||
$dbName = trim($_POST['db_name'] ?? '');
|
||||
$dbUser = trim($_POST['db_user'] ?? '');
|
||||
$dbPass = $_POST['db_pass'] ?? '';
|
||||
|
||||
// Validar
|
||||
if (empty($dbName)) $errors[] = "Nombre de BD requerido";
|
||||
if (empty($dbUser)) $errors[] = "Usuario requerido";
|
||||
if (empty($dbPass)) $errors[] = "Contraseña requerida";
|
||||
|
||||
if (empty($errors)) {
|
||||
try {
|
||||
// Conectar
|
||||
$dsn = "mysql:host={$dbHost};port={$dbPort};dbname={$dbName};charset=utf8mb4";
|
||||
$pdo = new PDO($dsn, $dbUser, $dbPass, [
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
|
||||
]);
|
||||
$success[] = "✅ Conexión exitosa a '{$dbName}'";
|
||||
|
||||
// Ejecutar schema - PASO 1: Crear solo las tablas
|
||||
$tablesCreated = 0;
|
||||
$creationErrors = [];
|
||||
|
||||
echo "<script>console.log('Iniciando creación de tablas...');</script>";
|
||||
|
||||
foreach ($integratedSchema as $index => $sql) {
|
||||
try {
|
||||
echo "<script>console.log('Ejecutando SQL: " . substr($sql, 0, 50) . "...');</script>";
|
||||
|
||||
$result = $pdo->exec($sql);
|
||||
$tablesCreated++;
|
||||
|
||||
// Extraer nombre de tabla para log
|
||||
if (preg_match('/CREATE TABLE IF NOT EXISTS (\w+)/', $sql, $matches)) {
|
||||
$tableName = $matches[1];
|
||||
$success[] = "✅ Tabla '{$tableName}' creada/verificada";
|
||||
|
||||
// Verificar que la tabla realmente existe
|
||||
try {
|
||||
$checkQuery = "DESCRIBE `{$tableName}`";
|
||||
$pdo->query($checkQuery);
|
||||
} catch (PDOException $e) {
|
||||
$creationErrors[] = "❌ Error verificando tabla '{$tableName}': " . $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
// Pequeña pausa para evitar problemas de timing
|
||||
usleep(100000); // 0.1 segundos
|
||||
|
||||
} catch (PDOException $e) {
|
||||
$errorMsg = $e->getMessage();
|
||||
if (strpos($errorMsg, 'already exists') === false) {
|
||||
$creationErrors[] = "❌ Error en tabla " . ($index + 1) . ": " . $errorMsg;
|
||||
} else {
|
||||
$tablesCreated++; // Contar como creada si ya existe
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Mostrar errores de creación si los hay
|
||||
if (!empty($creationErrors)) {
|
||||
foreach ($creationErrors as $error) {
|
||||
$errors[] = $error;
|
||||
}
|
||||
}
|
||||
|
||||
// Solo continuar si se crearon las tablas principales
|
||||
$essentialTables = ['users', 'conversations', 'menus', 'system_config'];
|
||||
$missingTables = [];
|
||||
|
||||
foreach ($essentialTables as $table) {
|
||||
try {
|
||||
$pdo->query("DESCRIBE `{$table}`");
|
||||
} catch (PDOException $e) {
|
||||
$missingTables[] = $table;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($missingTables)) {
|
||||
$errors[] = "❌ Tablas esenciales no creadas: " . implode(', ', $missingTables);
|
||||
$errors[] = "ℹ️ Intenta ejecutar el SQL manualmente en phpMyAdmin primero";
|
||||
} else {
|
||||
$success[] = "✅ Todas las tablas esenciales verificadas";
|
||||
|
||||
// PASO 2: Insertar datos solo si las tablas existen
|
||||
$dataInserted = 0;
|
||||
foreach ($initialData as $sql) {
|
||||
try {
|
||||
$pdo->exec($sql);
|
||||
$dataInserted++;
|
||||
} catch (PDOException $e) {
|
||||
$errorMsg = $e->getMessage();
|
||||
if (strpos($errorMsg, 'Duplicate entry') === false) {
|
||||
$errors[] = "⚠️ Error insertando datos: " . $errorMsg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$success[] = "✅ {$tablesCreated} tablas procesadas, {$dataInserted} conjuntos de datos insertados";
|
||||
}
|
||||
|
||||
// Actualizar config.php
|
||||
$configFile = 'config/config.php';
|
||||
if (file_exists($configFile)) {
|
||||
$config = file_get_contents($configFile);
|
||||
|
||||
$config = preg_replace("/define\('DB_HOST',\s*'[^']*'\);/", "define('DB_HOST', '$dbHost');", $config);
|
||||
$config = preg_replace("/define\('DB_PORT',\s*'[^']*'\);/", "define('DB_PORT', '$dbPort');", $config);
|
||||
$config = preg_replace("/define\('DB_NAME',\s*'[^']*'\);/", "define('DB_NAME', '$dbName');", $config);
|
||||
$config = preg_replace("/define\('DB_USER',\s*'[^']*'\);/", "define('DB_USER', '$dbUser');", $config);
|
||||
$config = preg_replace("/define\('DB_PASS',\s*'[^']*'\);/", "define('DB_PASS', '$dbPass');", $config);
|
||||
$config = preg_replace("/define\('ADMIN_PASSWORD',\s*'[^']*'\);/", "define('ADMIN_PASSWORD', '" . password_hash($adminPassword, PASSWORD_DEFAULT) . "');", $config);
|
||||
|
||||
// Auto-detectar URL
|
||||
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https://' : 'http://';
|
||||
$host = $_SERVER['HTTP_HOST'];
|
||||
$path = dirname($_SERVER['SCRIPT_NAME']);
|
||||
$autoUrl = $protocol . $host . $path;
|
||||
$config = preg_replace("/define\('APP_URL',\s*'[^']*'\);/", "define('APP_URL', '$autoUrl');", $config);
|
||||
|
||||
if (file_put_contents($configFile, $config)) {
|
||||
$success[] = "✅ Configuración actualizada";
|
||||
} else {
|
||||
$errors[] = "❌ No se pudo actualizar config.php";
|
||||
}
|
||||
}
|
||||
|
||||
// Verificar instalación
|
||||
if (empty($errors)) {
|
||||
try {
|
||||
$userCount = $pdo->query("SELECT COUNT(*) FROM users")->fetchColumn();
|
||||
$configCount = $pdo->query("SELECT COUNT(*) FROM system_config")->fetchColumn();
|
||||
$success[] = "✅ Verificación: {$userCount} usuarios, {$configCount} configuraciones";
|
||||
|
||||
// Marcar como instalado
|
||||
file_put_contents('.installation_completed', date('Y-m-d H:i:s'));
|
||||
|
||||
// Credenciales
|
||||
$credentials = "USUARIO: admin\nCONTRASEÑA: {$adminPassword}\nFECHA: " . date('Y-m-d H:i:s');
|
||||
file_put_contents('CREDENCIALES.txt', $credentials);
|
||||
|
||||
$success[] = "✅ Instalación completada exitosamente";
|
||||
$step = 'completed';
|
||||
|
||||
} catch (Exception $e) {
|
||||
$errors[] = "❌ Error en verificación: " . $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
} catch (PDOException $e) {
|
||||
$errors[] = "❌ Error de conexión: " . $e->getMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="es">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>🔧 Instalador Integrado</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
|
||||
<style>
|
||||
body { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); min-height: 100vh; }
|
||||
.install-card { background: rgba(255,255,255,0.95); border-radius: 15px; }
|
||||
.btn-primary { background: #667eea; border: none; }
|
||||
</style>
|
||||
</head>
|
||||
<body class="d-flex align-items-center">
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-lg-8">
|
||||
<div class="install-card shadow-lg p-4">
|
||||
|
||||
<?php if ($step === 'form'): ?>
|
||||
<div class="text-center mb-4">
|
||||
<h2><i class="fas fa-cogs me-2"></i>Instalador con Schema Integrado</h2>
|
||||
<p class="text-muted">Evita problemas de parsing del archivo schema.sql</p>
|
||||
</div>
|
||||
|
||||
<div class="alert alert-info">
|
||||
<i class="fas fa-info-circle me-2"></i>
|
||||
<strong>Ventajas de este instalador:</strong>
|
||||
<ul class="mb-0 mt-2">
|
||||
<li>✅ Schema SQL integrado en el código</li>
|
||||
<li>✅ No depende de archivos externos</li>
|
||||
<li>✅ Ejecución paso a paso controlada</li>
|
||||
<li>✅ Manejo de errores mejorado</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<form method="POST" action="?step=install">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label"><i class="fas fa-server me-2"></i>Host</label>
|
||||
<input type="text" class="form-control" name="db_host" value="localhost" required>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label"><i class="fas fa-plug me-2"></i>Puerto</label>
|
||||
<input type="text" class="form-control" name="db_port" value="3306" required>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label"><i class="fas fa-database me-2"></i>Base de datos</label>
|
||||
<input type="text" class="form-control" name="db_name" placeholder="usite_whatsapp_bot" required>
|
||||
<small class="text-muted">Debe existir previamente</small>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label"><i class="fas fa-user me-2"></i>Usuario</label>
|
||||
<input type="text" class="form-control" name="db_user" placeholder="usite_usuario" required>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<label class="form-label"><i class="fas fa-key me-2"></i>Contraseña</label>
|
||||
<input type="password" class="form-control" name="db_pass" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="text-center mt-4">
|
||||
<div class="alert alert-success">
|
||||
<strong><i class="fas fa-user-shield me-2"></i>Credenciales de Admin:</strong><br>
|
||||
<strong>Usuario:</strong> admin<br>
|
||||
<strong>Contraseña:</strong> <code><?= $adminPassword ?></code>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary btn-lg">
|
||||
<i class="fas fa-rocket me-2"></i>Instalar con Schema Integrado
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php elseif ($step === 'install'): ?>
|
||||
<div class="text-center mb-4">
|
||||
<h2><i class="fas fa-cog fa-spin me-2"></i>Instalando...</h2>
|
||||
</div>
|
||||
|
||||
<?php if (!empty($errors)): ?>
|
||||
<div class="alert alert-danger">
|
||||
<h5><i class="fas fa-exclamation-triangle me-2"></i>Errores:</h5>
|
||||
<?php foreach ($errors as $error): ?>
|
||||
<div><?= htmlspecialchars($error) ?></div>
|
||||
<?php endforeach; ?>
|
||||
<hr>
|
||||
<a href="?step=form" class="btn btn-outline-danger">Reintentar</a>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($success)): ?>
|
||||
<div class="alert alert-success">
|
||||
<h5><i class="fas fa-check-circle me-2"></i>Progreso:</h5>
|
||||
<?php foreach ($success as $msg): ?>
|
||||
<div><?= htmlspecialchars($msg) ?></div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php elseif ($step === 'completed'): ?>
|
||||
<div class="text-center mb-4">
|
||||
<h2 class="text-success"><i class="fas fa-check-circle me-2"></i>¡Instalación Exitosa!</h2>
|
||||
<p class="text-muted">Sistema WhatsApp Bot instalado correctamente</p>
|
||||
</div>
|
||||
|
||||
<div class="row g-4">
|
||||
<div class="col-md-6">
|
||||
<h5><i class="fas fa-key me-2 text-success"></i>Credenciales</h5>
|
||||
<div class="alert alert-success">
|
||||
<strong>Usuario:</strong> admin<br>
|
||||
<strong>Contraseña:</strong> <code><?= $adminPassword ?></code><br>
|
||||
<small>Guardadas en CREDENCIALES.txt</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<h5><i class="fas fa-rocket me-2 text-primary"></i>Acciones</h5>
|
||||
<div class="d-grid gap-2">
|
||||
<a href="index.php" class="btn btn-primary">Panel de Control</a>
|
||||
<a href="test.php" class="btn btn-outline-success">Probar Sistema</a>
|
||||
<a href="login.php" class="btn btn-outline-info">Iniciar Sesión</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="alert alert-info mt-4">
|
||||
<i class="fas fa-info-circle me-2"></i>
|
||||
<strong>Próximos pasos:</strong> Configura tu token de WhatsApp en el panel de administración.
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,544 @@
|
||||
<?php
|
||||
/**
|
||||
* Instalador manual para hostings compartidos (HestiaCP, cPanel, etc.)
|
||||
* Desarrollado por U-Site.app - https://u-site.app
|
||||
* Para cuando ya creaste la BD y usuario manualmente
|
||||
* Fecha: 13 de noviembre de 2025
|
||||
*/
|
||||
|
||||
// Verificar si la instalación ya está completada
|
||||
$installationLockFile = '.installation_completed';
|
||||
if (file_exists($installationLockFile)) {
|
||||
header('Location: login.php');
|
||||
exit('La instalación ya está completada. <a href="login.php">Iniciar sesión</a>');
|
||||
}
|
||||
|
||||
// Función para generar contraseña aleatoria segura
|
||||
function generateRandomPassword($length = 12) {
|
||||
$chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*-_=+';
|
||||
$password = '';
|
||||
for ($i = 0; $i < $length; $i++) {
|
||||
$password .= $chars[random_int(0, strlen($chars) - 1)];
|
||||
}
|
||||
return $password;
|
||||
}
|
||||
|
||||
$installStep = $_GET['step'] ?? 'config';
|
||||
$errors = [];
|
||||
$success = [];
|
||||
|
||||
// Generar contraseña para admin
|
||||
$adminPassword = generateRandomPassword(12);
|
||||
|
||||
// Procesar instalación manual
|
||||
if ($installStep === 'install' && $_POST) {
|
||||
$dbHost = trim($_POST['db_host'] ?? 'localhost');
|
||||
$dbName = trim($_POST['db_name'] ?? '');
|
||||
$dbUser = trim($_POST['db_user'] ?? '');
|
||||
$dbPass = trim($_POST['db_pass'] ?? '');
|
||||
$dbPort = trim($_POST['db_port'] ?? '3306');
|
||||
|
||||
// Validar campos requeridos
|
||||
if (empty($dbName)) {
|
||||
$errors[] = "❌ El nombre de la base de datos es obligatorio";
|
||||
}
|
||||
if (empty($dbUser)) {
|
||||
$errors[] = "❌ El usuario de la base de datos es obligatorio";
|
||||
}
|
||||
if (empty($dbPass)) {
|
||||
$errors[] = "❌ La contraseña de la base de datos es obligatoria";
|
||||
}
|
||||
|
||||
if (empty($errors)) {
|
||||
try {
|
||||
// 1. Probar conexión con las credenciales proporcionadas
|
||||
$dsn = "mysql:host={$dbHost};port={$dbPort};charset=utf8mb4";
|
||||
$testConnection = new PDO($dsn, $dbUser, $dbPass, [
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
PDO::ATTR_TIMEOUT => 5,
|
||||
]);
|
||||
$success[] = "✅ Conexión al servidor MySQL exitosa";
|
||||
|
||||
// Verificar que la base de datos existe
|
||||
$dsn = "mysql:host={$dbHost};port={$dbPort};dbname={$dbName};charset=utf8mb4";
|
||||
$pdo = new PDO($dsn, $dbUser, $dbPass, [
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||
PDO::ATTR_EMULATE_PREPARES => false,
|
||||
]);
|
||||
|
||||
$success[] = "✅ Conexión a base de datos '$dbName' exitosa";
|
||||
|
||||
// 2. Verificar si las tablas ya existen
|
||||
$existingTables = [];
|
||||
$stmt = $pdo->query("SHOW TABLES");
|
||||
while ($row = $stmt->fetch(PDO::FETCH_NUM)) {
|
||||
$existingTables[] = $row[0];
|
||||
}
|
||||
|
||||
if (!empty($existingTables)) {
|
||||
$success[] = "✅ Base de datos contiene " . count($existingTables) . " tablas existentes";
|
||||
}
|
||||
|
||||
// 3. Ejecutar schema.sql para crear/actualizar tablas
|
||||
$schemaFile = 'database/schema.sql';
|
||||
if (!file_exists($schemaFile)) {
|
||||
throw new Exception("No se encontró el archivo schema.sql");
|
||||
}
|
||||
|
||||
$schema = file_get_contents($schemaFile);
|
||||
if (!$schema) {
|
||||
throw new Exception("No se pudo leer el archivo schema.sql");
|
||||
}
|
||||
|
||||
// Ejecutar comandos SQL uno por uno
|
||||
$statements = preg_split('/;\s*$/m', $schema);
|
||||
$tablesCreated = 0;
|
||||
$tablesUpdated = 0;
|
||||
$errors_sql = [];
|
||||
|
||||
// Primero ejecutar solo CREATE TABLE
|
||||
foreach ($statements as $statement) {
|
||||
$statement = trim($statement);
|
||||
if (!empty($statement) &&
|
||||
!preg_match('/^--/', $statement) &&
|
||||
preg_match('/CREATE TABLE/i', $statement)) {
|
||||
try {
|
||||
$pdo->exec($statement);
|
||||
$tablesCreated++;
|
||||
|
||||
// Extraer nombre de tabla para log
|
||||
if (preg_match('/CREATE TABLE\s+(?:IF NOT EXISTS\s+)?`?(\w+)`?/i', $statement, $matches)) {
|
||||
$success[] = "✅ Tabla '{$matches[1]}' creada";
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
$errorMsg = $e->getMessage();
|
||||
if (strpos($errorMsg, 'already exists') === false) {
|
||||
$errors_sql[] = "Error creando tabla: " . $errorMsg;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Luego ejecutar INSERT y otras operaciones
|
||||
foreach ($statements as $statement) {
|
||||
$statement = trim($statement);
|
||||
if (!empty($statement) &&
|
||||
!preg_match('/^--/', $statement) &&
|
||||
!preg_match('/CREATE TABLE/i', $statement) &&
|
||||
(preg_match('/INSERT/i', $statement) || preg_match('/UPDATE/i', $statement) || preg_match('/SET/i', $statement))) {
|
||||
try {
|
||||
$pdo->exec($statement);
|
||||
if (preg_match('/INSERT INTO/i', $statement)) {
|
||||
$tablesUpdated++;
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
$errorMsg = $e->getMessage();
|
||||
if (strpos($errorMsg, 'Duplicate entry') === false) {
|
||||
$errors_sql[] = "Error insertando datos: " . $errorMsg;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($errors_sql)) {
|
||||
$success[] = "✅ Esquema aplicado: {$tablesCreated} tablas creadas, {$tablesUpdated} registros insertados";
|
||||
} else {
|
||||
$success[] = "⚠️ Esquema procesado: {$tablesCreated} tablas, {$tablesUpdated} registros";
|
||||
foreach ($errors_sql as $sqlError) {
|
||||
$errors[] = "⚠️ " . $sqlError;
|
||||
}
|
||||
}
|
||||
|
||||
// 4. Actualizar archivo de configuración
|
||||
$configFile = 'config/config.php';
|
||||
$configContent = file_get_contents($configFile);
|
||||
|
||||
$configContent = preg_replace("/define\('DB_HOST',\s*'[^']*'\);/", "define('DB_HOST', '$dbHost');", $configContent);
|
||||
$configContent = preg_replace("/define\('DB_PORT',\s*'[^']*'\);/", "define('DB_PORT', '$dbPort');", $configContent);
|
||||
$configContent = preg_replace("/define\('DB_NAME',\s*'[^']*'\);/", "define('DB_NAME', '$dbName');", $configContent);
|
||||
$configContent = preg_replace("/define\('DB_USER',\s*'[^']*'\);/", "define('DB_USER', '$dbUser');", $configContent);
|
||||
$configContent = preg_replace("/define\('DB_PASS',\s*'[^']*'\);/", "define('DB_PASS', '$dbPass');", $configContent);
|
||||
$configContent = preg_replace("/define\('ADMIN_PASSWORD',\s*'[^']*'\);/", "define('ADMIN_PASSWORD', '" . password_hash($adminPassword, PASSWORD_DEFAULT) . "');", $configContent);
|
||||
|
||||
// Auto-detectar URL del servidor
|
||||
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https://' : 'http://';
|
||||
$host = $_SERVER['HTTP_HOST'];
|
||||
$path = dirname($_SERVER['SCRIPT_NAME']);
|
||||
$autoUrl = $protocol . $host . $path;
|
||||
$configContent = preg_replace("/define\('APP_URL',\s*'[^']*'\);/", "define('APP_URL', '$autoUrl');", $configContent);
|
||||
|
||||
if (file_put_contents($configFile, $configContent)) {
|
||||
$success[] = "✅ Archivo config.php actualizado";
|
||||
} else {
|
||||
$errors[] = "❌ No se pudo actualizar config.php";
|
||||
}
|
||||
|
||||
// 5. Verificar que la configuración funcione
|
||||
try {
|
||||
// Probar directamente con PDO usando las nuevas credenciales
|
||||
$testPdo = new PDO("mysql:host={$dbHost};port={$dbPort};dbname={$dbName};charset=utf8mb4", $dbUser, $dbPass, [
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||
]);
|
||||
|
||||
$testQuery = $testPdo->query("SELECT COUNT(*) as count FROM users");
|
||||
$userCount = $testQuery->fetch()['count'];
|
||||
$success[] = "✅ Prueba de conexión exitosa: {$userCount} usuarios registrados";
|
||||
|
||||
// Verificar que las tablas principales existan
|
||||
$mainTables = ['users', 'conversations', 'menus', 'system_config'];
|
||||
foreach ($mainTables as $table) {
|
||||
$checkTable = $testPdo->query("SHOW TABLES LIKE '{$table}'");
|
||||
if ($checkTable->rowCount() > 0) {
|
||||
$success[] = "✅ Tabla '{$table}' verificada";
|
||||
} else {
|
||||
$errors[] = "❌ Tabla '{$table}' no encontrada";
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception $e) {
|
||||
$errors[] = "❌ Error probando la nueva configuración: " . $e->getMessage();
|
||||
}
|
||||
|
||||
if (empty($errors)) {
|
||||
// 6. Crear archivo de bloqueo de instalación
|
||||
$lockContent = "Instalación manual completada: " . date('Y-m-d H:i:s') . "\n";
|
||||
$lockContent .= "Host: $dbHost\n";
|
||||
$lockContent .= "Base de datos: $dbName\n";
|
||||
$lockContent .= "Usuario BD: $dbUser\n";
|
||||
$lockContent .= "Desarrollado por: U-Site.app\n";
|
||||
$lockContent .= "URL: https://u-site.app\n";
|
||||
file_put_contents($installationLockFile, $lockContent);
|
||||
$success[] = "✅ Sistema bloqueado contra reinstalaciones";
|
||||
|
||||
// 7. Crear archivo de credenciales
|
||||
$credentialsFile = "CREDENCIALES_SISTEMA.txt";
|
||||
$credentialsContent = "=== CREDENCIALES DEL SISTEMA WHATSAPP BOT ===\n";
|
||||
$credentialsContent .= "Instalación manual completada\n";
|
||||
$credentialsContent .= "Desarrollado por: U-Site.app (https://u-site.app)\n";
|
||||
$credentialsContent .= "Generado automáticamente: " . date('Y-m-d H:i:s') . "\n\n";
|
||||
$credentialsContent .= "=== BASE DE DATOS ===\n";
|
||||
$credentialsContent .= "Host: $dbHost\n";
|
||||
$credentialsContent .= "Puerto: $dbPort\n";
|
||||
$credentialsContent .= "Base de datos: $dbName\n";
|
||||
$credentialsContent .= "Usuario: $dbUser\n";
|
||||
$credentialsContent .= "Contraseña: [LA QUE CONFIGURASTE MANUALMENTE]\n\n";
|
||||
$credentialsContent .= "=== PANEL ADMINISTRATIVO ===\n";
|
||||
$credentialsContent .= "Usuario: admin\n";
|
||||
$credentialsContent .= "Contraseña: $adminPassword\n";
|
||||
$credentialsContent .= "URL Login: $autoUrl/login.php\n\n";
|
||||
$credentialsContent .= "⚠️ IMPORTANTE: Guarda estas credenciales en un lugar seguro.\n";
|
||||
$credentialsContent .= "⚠️ La contraseña de BD es la que TÚ configuraste manualmente.\n";
|
||||
$credentialsContent .= "⚠️ El sistema está protegido contra reinstalaciones.\n\n";
|
||||
$credentialsContent .= "📞 Soporte técnico: support@u-site.app\n";
|
||||
|
||||
file_put_contents($credentialsFile, $credentialsContent);
|
||||
$success[] = "✅ Archivo de credenciales creado: $credentialsFile";
|
||||
|
||||
$installStep = 'completed';
|
||||
}
|
||||
|
||||
} catch (PDOException $e) {
|
||||
$errors[] = "❌ Error de base de datos: " . $e->getMessage();
|
||||
} catch (Exception $e) {
|
||||
$errors[] = "❌ Error general: " . $e->getMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="es">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>🛠️ Instalación Manual - WhatsApp Bot</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
|
||||
<style>
|
||||
:root {
|
||||
--primary-color: #25d366;
|
||||
--secondary-color: #075e54;
|
||||
--bg-gradient: linear-gradient(135deg, #25d366 0%, #075e54 100%);
|
||||
}
|
||||
body {
|
||||
background: var(--bg-gradient);
|
||||
min-height: 100vh;
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
}
|
||||
.install-card {
|
||||
background: rgba(255,255,255,0.95);
|
||||
border-radius: 20px;
|
||||
backdrop-filter: blur(10px);
|
||||
box-shadow: 0 20px 40px rgba(0,0,0,0.1);
|
||||
}
|
||||
.btn-install {
|
||||
background: var(--bg-gradient);
|
||||
border: none;
|
||||
color: white;
|
||||
padding: 15px 30px;
|
||||
border-radius: 10px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.btn-install:hover {
|
||||
transform: translateY(-2px);
|
||||
color: white;
|
||||
}
|
||||
.password-display {
|
||||
background: #f8f9fa;
|
||||
border: 2px dashed #28a745;
|
||||
border-radius: 10px;
|
||||
font-family: 'Courier New', monospace;
|
||||
font-size: 1.1rem;
|
||||
font-weight: bold;
|
||||
color: #155724;
|
||||
word-break: break-all;
|
||||
padding: 15px;
|
||||
}
|
||||
.form-control:focus {
|
||||
border-color: var(--primary-color);
|
||||
box-shadow: 0 0 0 0.2rem rgba(37, 211, 102, 0.25);
|
||||
}
|
||||
.hosting-info {
|
||||
background: linear-gradient(45deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
border-radius: 15px;
|
||||
padding: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container mt-4">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-lg-10">
|
||||
<div class="install-card p-4">
|
||||
|
||||
<?php if ($installStep === 'config'): ?>
|
||||
<!-- Pantalla de Configuración Manual -->
|
||||
<div class="text-center mb-4">
|
||||
<i class="fas fa-tools text-warning" style="font-size: 3rem;"></i>
|
||||
<h1 class="mt-3 fw-bold">Instalación Manual</h1>
|
||||
<p class="text-muted">Para hostings compartidos (HestiaCP, cPanel, etc.)</p>
|
||||
</div>
|
||||
|
||||
<div class="hosting-info">
|
||||
<h5><i class="fas fa-server me-2"></i>Configuración para Hosting Compartido</h5>
|
||||
<p class="mb-2">Este instalador es para cuando ya creaste manualmente:</p>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<ul class="mb-0">
|
||||
<li>✅ Base de datos MySQL</li>
|
||||
<li>✅ Usuario de base de datos</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<ul class="mb-0">
|
||||
<li>✅ Permisos asignados</li>
|
||||
<li>✅ Acceso desde tu dominio</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="alert alert-info">
|
||||
<h6><i class="fas fa-info-circle me-2"></i>Pasos previos en HestiaCP/cPanel:</h6>
|
||||
<ol class="mb-0">
|
||||
<li><strong>Crear base de datos:</strong> Ve a MySQL Databases</li>
|
||||
<li><strong>Crear usuario:</strong> Asigna un usuario a la BD</li>
|
||||
<li><strong>Asignar permisos:</strong> Da ALL PRIVILEGES al usuario</li>
|
||||
<li><strong>Anotar credenciales:</strong> Host, nombre BD, usuario y contraseña</li>
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
<form action="?step=install" method="POST">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label"><i class="fas fa-server me-2"></i>Host de BD</label>
|
||||
<input type="text" class="form-control" name="db_host" value="localhost" required>
|
||||
<small class="text-muted">Generalmente 'localhost' en hosting compartido</small>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label"><i class="fas fa-plug me-2"></i>Puerto</label>
|
||||
<input type="text" class="form-control" name="db_port" value="3306">
|
||||
<small class="text-muted">Puerto estándar de MySQL</small>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label"><i class="fas fa-database me-2"></i>Nombre de BD <span class="text-danger">*</span></label>
|
||||
<input type="text" class="form-control" name="db_name" placeholder="mi_basedatos" required>
|
||||
<small class="text-muted">Nombre exacto de la base de datos creada</small>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label"><i class="fas fa-user me-2"></i>Usuario de BD <span class="text-danger">*</span></label>
|
||||
<input type="text" class="form-control" name="db_user" placeholder="mi_usuario" required>
|
||||
<small class="text-muted">Usuario asignado a la base de datos</small>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<label class="form-label"><i class="fas fa-key me-2"></i>Contraseña de BD <span class="text-danger">*</span></label>
|
||||
<input type="password" class="form-control" name="db_pass" required>
|
||||
<small class="text-muted">Contraseña del usuario de base de datos</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-4">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<h6><i class="fas fa-user-shield me-2 text-success"></i>Credenciales Admin</h6>
|
||||
<div class="alert alert-success">
|
||||
<strong>Usuario:</strong> admin<br>
|
||||
<strong>Contraseña:</strong> <span class="password-display d-inline p-2"><?= htmlspecialchars($adminPassword) ?></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<h6><i class="fas fa-shield-alt me-2 text-primary"></i>Que incluye</h6>
|
||||
<ul class="list-unstyled">
|
||||
<li>✅ Configuración automática</li>
|
||||
<li>✅ Creación de tablas</li>
|
||||
<li>✅ Datos iniciales</li>
|
||||
<li>✅ Protección contra reinstalación</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="text-center mt-4">
|
||||
<button type="submit" class="btn btn-install btn-lg">
|
||||
<i class="fas fa-cog me-2"></i>Configurar Sistema
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php elseif ($installStep === 'install'): ?>
|
||||
<!-- Pantalla de Procesamiento -->
|
||||
<div class="text-center mb-4">
|
||||
<i class="fas fa-cog fa-spin text-warning" style="font-size: 3rem;"></i>
|
||||
<h2 class="mt-3">Configurando Sistema...</h2>
|
||||
<p class="text-muted">Aplicando configuración con tus credenciales</p>
|
||||
</div>
|
||||
|
||||
<!-- Mostrar errores -->
|
||||
<?php if (!empty($errors)): ?>
|
||||
<div class="alert alert-danger">
|
||||
<h5><i class="fas fa-exclamation-triangle me-2"></i>Errores encontrados:</h5>
|
||||
<?php foreach ($errors as $error): ?>
|
||||
<div><?= htmlspecialchars($error) ?></div>
|
||||
<?php endforeach; ?>
|
||||
<hr>
|
||||
<a href="?step=config" class="btn btn-outline-danger">
|
||||
<i class="fas fa-arrow-left me-2"></i>Volver a intentar
|
||||
</a>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- Mostrar éxitos -->
|
||||
<?php if (!empty($success)): ?>
|
||||
<div class="alert alert-success">
|
||||
<h5><i class="fas fa-check-circle me-2"></i>Progreso de instalación:</h5>
|
||||
<?php foreach ($success as $msg): ?>
|
||||
<div><?= htmlspecialchars($msg) ?></div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($errors) && empty($success)): ?>
|
||||
<!-- Solo mostrar si hay errores sin éxitos -->
|
||||
<?php elseif ($installStep !== 'completed'): ?>
|
||||
<div class="text-center">
|
||||
<div class="spinner-border text-primary" role="status">
|
||||
<span class="visually-hidden">Procesando...</span>
|
||||
</div>
|
||||
<p class="mt-2">Procesando configuración...</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php elseif ($installStep === 'completed'): ?>
|
||||
<!-- Pantalla de Completado -->
|
||||
<div class="text-center mb-4">
|
||||
<i class="fas fa-check-circle text-success" style="font-size: 4rem;"></i>
|
||||
<h1 class="mt-3 text-success fw-bold">¡Instalación Completada!</h1>
|
||||
<p class="text-muted">Tu sistema WhatsApp Bot está configurado y listo</p>
|
||||
</div>
|
||||
|
||||
<!-- Mostrar errores si los hay -->
|
||||
<?php if (!empty($errors)): ?>
|
||||
<div class="alert alert-warning">
|
||||
<h5><i class="fas fa-exclamation-triangle me-2"></i>Advertencias:</h5>
|
||||
<?php foreach ($errors as $error): ?>
|
||||
<div><?= htmlspecialchars($error) ?></div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- Mostrar éxitos -->
|
||||
<?php if (!empty($success)): ?>
|
||||
<div class="alert alert-success">
|
||||
<h5><i class="fas fa-check-circle me-2"></i>Instalación exitosa:</h5>
|
||||
<?php foreach ($success as $msg): ?>
|
||||
<div><?= htmlspecialchars($msg) ?></div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="row g-4 mb-4">
|
||||
<div class="col-md-6">
|
||||
<h5><i class="fas fa-user-shield me-2 text-success"></i>Acceso al Sistema</h5>
|
||||
<div class="bg-light p-3 rounded">
|
||||
<div><strong>Usuario:</strong> admin</div>
|
||||
<div class="mt-2">
|
||||
<strong>Contraseña:</strong><br>
|
||||
<div class="password-display mt-1">
|
||||
<?= htmlspecialchars($adminPassword) ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-3">
|
||||
<a href="login.php" class="btn btn-install btn-sm">
|
||||
<i class="fas fa-sign-in-alt me-2"></i>Iniciar Sesión
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<h5><i class="fas fa-link me-2 text-primary"></i>Próximos Pasos</h5>
|
||||
<div class="d-grid gap-2">
|
||||
<a href="test.php" class="btn btn-outline-success">
|
||||
<i class="fas fa-check-circle me-2"></i>Probar Sistema
|
||||
</a>
|
||||
<a href="index.php" class="btn btn-outline-primary">
|
||||
<i class="fas fa-home me-2"></i>Ir al Panel
|
||||
</a>
|
||||
<a href="server_setup.php" class="btn btn-outline-warning">
|
||||
<i class="fab fa-whatsapp me-2"></i>Configurar WhatsApp
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="alert alert-info">
|
||||
<h6><i class="fas fa-info-circle me-2"></i>Información Importante:</h6>
|
||||
<ul class="mb-0">
|
||||
<li><strong>Credenciales guardadas:</strong> Revisa el archivo CREDENCIALES_SISTEMA.txt</li>
|
||||
<li><strong>Base de datos:</strong> Se conecta usando tus credenciales existentes</li>
|
||||
<li><strong>Sistema protegido:</strong> No se puede reinstalar accidentalmente</li>
|
||||
<li><strong>Soporte:</strong> <a href="mailto:support@u-site.app">support@u-site.app</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- Footer -->
|
||||
<div class="mt-4 pt-3 border-top text-center">
|
||||
<small class="text-muted">
|
||||
Instalación Manual WhatsApp Bot |
|
||||
Desarrollado por <strong><a href="https://u-site.app" target="_blank">U-Site.app</a></strong> |
|
||||
<a href="https://u-site.app/support" target="_blank">Soporte</a>
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,239 @@
|
||||
<?php
|
||||
/**
|
||||
* Instalador Simplificado para Hosting Compartido
|
||||
* Version mínima y robusta para HestiaCP/cPanel
|
||||
* Desarrollado por U-Site.app
|
||||
* Fecha: 13 de noviembre de 2025
|
||||
*/
|
||||
|
||||
// Configuración básica
|
||||
error_reporting(E_ALL);
|
||||
ini_set('display_errors', 1);
|
||||
|
||||
$step = $_GET['step'] ?? 'form';
|
||||
$errors = [];
|
||||
$success = [];
|
||||
|
||||
// Generar contraseña admin
|
||||
function generatePassword($length = 12) {
|
||||
return bin2hex(random_bytes($length / 2));
|
||||
}
|
||||
|
||||
$adminPassword = generatePassword(12);
|
||||
|
||||
if ($step === 'install' && $_POST) {
|
||||
$dbHost = trim($_POST['db_host'] ?? 'localhost');
|
||||
$dbPort = trim($_POST['db_port'] ?? '3306');
|
||||
$dbName = trim($_POST['db_name'] ?? '');
|
||||
$dbUser = trim($_POST['db_user'] ?? '');
|
||||
$dbPass = $_POST['db_pass'] ?? '';
|
||||
|
||||
// Validar campos
|
||||
if (empty($dbName)) $errors[] = "Nombre de BD requerido";
|
||||
if (empty($dbUser)) $errors[] = "Usuario de BD requerido";
|
||||
if (empty($dbPass)) $errors[] = "Contraseña de BD requerida";
|
||||
|
||||
if (empty($errors)) {
|
||||
try {
|
||||
// 1. Conectar a BD
|
||||
$dsn = "mysql:host={$dbHost};port={$dbPort};dbname={$dbName};charset=utf8mb4";
|
||||
$pdo = new PDO($dsn, $dbUser, $dbPass, [
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
|
||||
]);
|
||||
$success[] = "✅ Conexión exitosa";
|
||||
|
||||
// 2. Aplicar schema básico
|
||||
$basicSchema = "
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
phone_number VARCHAR(20) UNIQUE NOT NULL,
|
||||
name VARCHAR(100),
|
||||
status ENUM('active', 'inactive') DEFAULT 'active',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS conversations (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
user_id INT,
|
||||
direction ENUM('incoming', 'outgoing') NOT NULL,
|
||||
content TEXT,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (user_id) REFERENCES users(id)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS system_config (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
config_key VARCHAR(100) UNIQUE NOT NULL,
|
||||
config_value TEXT,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
INSERT IGNORE INTO system_config (config_key, config_value) VALUES
|
||||
('app_installed', '1'),
|
||||
('install_date', NOW()),
|
||||
('admin_user', 'admin');
|
||||
";
|
||||
|
||||
$statements = array_filter(explode(';', $basicSchema));
|
||||
foreach ($statements as $stmt) {
|
||||
if (trim($stmt)) {
|
||||
$pdo->exec(trim($stmt));
|
||||
}
|
||||
}
|
||||
$success[] = "✅ Tablas creadas";
|
||||
|
||||
// 3. Actualizar config.php
|
||||
$configFile = 'config/config.php';
|
||||
if (file_exists($configFile)) {
|
||||
$config = file_get_contents($configFile);
|
||||
|
||||
$config = preg_replace("/define\('DB_HOST',\s*'[^']*'\);/", "define('DB_HOST', '$dbHost');", $config);
|
||||
$config = preg_replace("/define\('DB_PORT',\s*'[^']*'\);/", "define('DB_PORT', '$dbPort');", $config);
|
||||
$config = preg_replace("/define\('DB_NAME',\s*'[^']*'\);/", "define('DB_NAME', '$dbName');", $config);
|
||||
$config = preg_replace("/define\('DB_USER',\s*'[^']*'\);/", "define('DB_USER', '$dbUser');", $config);
|
||||
$config = preg_replace("/define\('DB_PASS',\s*'[^']*'\);/", "define('DB_PASS', '$dbPass');", $config);
|
||||
$config = preg_replace("/define\('ADMIN_PASSWORD',\s*'[^']*'\);/", "define('ADMIN_PASSWORD', '" . password_hash($adminPassword, PASSWORD_DEFAULT) . "');", $config);
|
||||
|
||||
file_put_contents($configFile, $config);
|
||||
$success[] = "✅ Configuración actualizada";
|
||||
}
|
||||
|
||||
// 4. Crear archivo de instalación completada
|
||||
file_put_contents('.installation_completed', date('Y-m-d H:i:s'));
|
||||
$success[] = "✅ Instalación completada";
|
||||
|
||||
// 5. Crear credenciales
|
||||
$creds = "USUARIO ADMIN: admin\nCONTRASEÑA: $adminPassword\nFECHA: " . date('Y-m-d H:i:s');
|
||||
file_put_contents('CREDENCIALES.txt', $creds);
|
||||
$success[] = "✅ Credenciales guardadas en CREDENCIALES.txt";
|
||||
|
||||
$step = 'completed';
|
||||
|
||||
} catch (Exception $e) {
|
||||
$errors[] = "❌ Error: " . $e->getMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="es">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>📦 Instalador Simplificado</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<style>
|
||||
body { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); min-height: 100vh; }
|
||||
.card { background: rgba(255,255,255,0.95); border-radius: 15px; }
|
||||
.btn-primary { background: #667eea; border: none; }
|
||||
</style>
|
||||
</head>
|
||||
<body class="d-flex align-items-center">
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-lg-8">
|
||||
<div class="card shadow-lg p-4">
|
||||
|
||||
<?php if ($step === 'form'): ?>
|
||||
<div class="text-center mb-4">
|
||||
<h2>📦 Instalador Simplificado</h2>
|
||||
<p class="text-muted">Para hosting compartido (HestiaCP/cPanel)</p>
|
||||
</div>
|
||||
|
||||
<div class="alert alert-info">
|
||||
<strong>Antes de continuar:</strong> Asegúrate de haber creado la base de datos y usuario en tu panel de control.
|
||||
</div>
|
||||
|
||||
<form method="POST" action="?step=install">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Host</label>
|
||||
<input type="text" class="form-control" name="db_host" value="localhost" required>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Puerto</label>
|
||||
<input type="text" class="form-control" name="db_port" value="3306" required>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Base de datos</label>
|
||||
<input type="text" class="form-control" name="db_name" placeholder="mi_basedatos" required>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Usuario</label>
|
||||
<input type="text" class="form-control" name="db_user" placeholder="mi_usuario" required>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<label class="form-label">Contraseña</label>
|
||||
<input type="password" class="form-control" name="db_pass" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="text-center mt-4">
|
||||
<div class="alert alert-success">
|
||||
<strong>Contraseña de administrador:</strong><br>
|
||||
<code><?= $adminPassword ?></code>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary btn-lg">
|
||||
<i class="fas fa-play"></i> Instalar Sistema
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php elseif ($step === 'install'): ?>
|
||||
<div class="text-center mb-4">
|
||||
<h2>⚙️ Instalando...</h2>
|
||||
</div>
|
||||
|
||||
<?php if (!empty($errors)): ?>
|
||||
<div class="alert alert-danger">
|
||||
<h5>❌ Errores:</h5>
|
||||
<?php foreach ($errors as $error): ?>
|
||||
<div><?= htmlspecialchars($error) ?></div>
|
||||
<?php endforeach; ?>
|
||||
<hr>
|
||||
<a href="?step=form" class="btn btn-outline-danger">Reintentar</a>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($success)): ?>
|
||||
<div class="alert alert-success">
|
||||
<h5>✅ Progreso:</h5>
|
||||
<?php foreach ($success as $msg): ?>
|
||||
<div><?= htmlspecialchars($msg) ?></div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php elseif ($step === 'completed'): ?>
|
||||
<div class="text-center mb-4">
|
||||
<h2 class="text-success">🎉 ¡Instalación Exitosa!</h2>
|
||||
</div>
|
||||
|
||||
<div class="row g-4">
|
||||
<div class="col-md-6">
|
||||
<h5>🔐 Credenciales de Acceso</h5>
|
||||
<div class="alert alert-success">
|
||||
<strong>Usuario:</strong> admin<br>
|
||||
<strong>Contraseña:</strong> <code><?= $adminPassword ?></code>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<h5>🚀 Próximos Pasos</h5>
|
||||
<div class="d-grid gap-2">
|
||||
<a href="index.php" class="btn btn-primary">Panel de Control</a>
|
||||
<a href="test.php" class="btn btn-outline-success">Probar Sistema</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="alert alert-warning mt-4">
|
||||
<strong>Importante:</strong> Guarda las credenciales. El archivo CREDENCIALES.txt contiene toda la información.
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,282 @@
|
||||
<?php
|
||||
/**
|
||||
* Instalador Ultra Básico - Paso a Paso
|
||||
* Para resolver problemas de creación de tablas
|
||||
* Desarrollado por U-Site.app
|
||||
* Fecha: 14 de noviembre de 2025
|
||||
*/
|
||||
|
||||
error_reporting(E_ALL);
|
||||
ini_set('display_errors', 1);
|
||||
|
||||
if (file_exists('.installation_completed')) {
|
||||
header('Location: login.php');
|
||||
exit('Sistema ya instalado');
|
||||
}
|
||||
|
||||
$step = $_GET['step'] ?? 'form';
|
||||
$errors = [];
|
||||
$success = [];
|
||||
$adminPassword = bin2hex(random_bytes(6)); // 12 caracteres
|
||||
|
||||
if ($step === 'install' && $_POST) {
|
||||
$dbHost = trim($_POST['db_host'] ?? 'localhost');
|
||||
$dbPort = trim($_POST['db_port'] ?? '3306');
|
||||
$dbName = trim($_POST['db_name'] ?? '');
|
||||
$dbUser = trim($_POST['db_user'] ?? '');
|
||||
$dbPass = $_POST['db_pass'] ?? '';
|
||||
|
||||
if (empty($dbName)) $errors[] = "BD requerida";
|
||||
if (empty($dbUser)) $errors[] = "Usuario requerido";
|
||||
if (empty($dbPass)) $errors[] = "Contraseña requerida";
|
||||
|
||||
if (empty($errors)) {
|
||||
try {
|
||||
$dsn = "mysql:host={$dbHost};port={$dbPort};dbname={$dbName};charset=utf8mb4";
|
||||
$pdo = new PDO($dsn, $dbUser, $dbPass, [
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
|
||||
]);
|
||||
$success[] = "✅ Conectado a '{$dbName}'";
|
||||
|
||||
// Crear tabla users primero
|
||||
$sql = "CREATE TABLE IF NOT EXISTS users (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
phone_number VARCHAR(20) UNIQUE NOT NULL,
|
||||
name VARCHAR(100),
|
||||
status ENUM('active', 'inactive') DEFAULT 'active',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
)";
|
||||
|
||||
$pdo->exec($sql);
|
||||
|
||||
// Verificar que se creó
|
||||
try {
|
||||
$result = $pdo->query("SELECT COUNT(*) FROM users");
|
||||
$success[] = "✅ Tabla 'users' creada y funcional";
|
||||
} catch (Exception $e) {
|
||||
$errors[] = "❌ Tabla users no funciona: " . $e->getMessage();
|
||||
}
|
||||
|
||||
// Crear tabla system_config
|
||||
$sql = "CREATE TABLE IF NOT EXISTS system_config (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
config_key VARCHAR(100) UNIQUE NOT NULL,
|
||||
config_value TEXT,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
)";
|
||||
|
||||
$pdo->exec($sql);
|
||||
|
||||
// Verificar
|
||||
try {
|
||||
$result = $pdo->query("SELECT COUNT(*) FROM system_config");
|
||||
$success[] = "✅ Tabla 'system_config' creada y funcional";
|
||||
} catch (Exception $e) {
|
||||
$errors[] = "❌ Tabla system_config no funciona: " . $e->getMessage();
|
||||
}
|
||||
|
||||
// Solo insertar datos si no hay errores
|
||||
if (empty($errors)) {
|
||||
// Insertar configuración básica
|
||||
$configSql = "INSERT IGNORE INTO system_config (config_key, config_value) VALUES
|
||||
('app_installed', '1'),
|
||||
('install_date', NOW()),
|
||||
('business_name', 'Mi Empresa'),
|
||||
('admin_user', 'admin')";
|
||||
|
||||
try {
|
||||
$pdo->exec($configSql);
|
||||
$success[] = "✅ Configuración inicial insertada";
|
||||
} catch (Exception $e) {
|
||||
$errors[] = "⚠️ Error insertando config: " . $e->getMessage();
|
||||
}
|
||||
|
||||
// Actualizar config.php
|
||||
if (file_exists('config/config.php')) {
|
||||
$config = file_get_contents('config/config.php');
|
||||
|
||||
$config = preg_replace("/define\('DB_HOST',\s*'[^']*'\);/", "define('DB_HOST', '$dbHost');", $config);
|
||||
$config = preg_replace("/define\('DB_PORT',\s*'[^']*'\);/", "define('DB_PORT', '$dbPort');", $config);
|
||||
$config = preg_replace("/define\('DB_NAME',\s*'[^']*'\);/", "define('DB_NAME', '$dbName');", $config);
|
||||
$config = preg_replace("/define\('DB_USER',\s*'[^']*'\);/", "define('DB_USER', '$dbUser');", $config);
|
||||
$config = preg_replace("/define\('DB_PASS',\s*'[^']*'\);/", "define('DB_PASS', '$dbPass');", $config);
|
||||
$config = preg_replace("/define\('ADMIN_PASSWORD',\s*'[^']*'\);/", "define('ADMIN_PASSWORD', '" . password_hash($adminPassword, PASSWORD_DEFAULT) . "');", $config);
|
||||
|
||||
file_put_contents('config/config.php', $config);
|
||||
$success[] = "✅ config.php actualizado";
|
||||
}
|
||||
|
||||
// Verificar que todo funciona
|
||||
try {
|
||||
$userCount = $pdo->query("SELECT COUNT(*) FROM users")->fetchColumn();
|
||||
$configCount = $pdo->query("SELECT COUNT(*) FROM system_config")->fetchColumn();
|
||||
$success[] = "✅ Verificación final: {$userCount} usuarios, {$configCount} configs";
|
||||
|
||||
// Marcar como instalado
|
||||
file_put_contents('.installation_completed', date('Y-m-d H:i:s'));
|
||||
file_put_contents('CREDENCIALES_BASICO.txt', "USUARIO: admin\nCONTRASEÑA: {$adminPassword}\nFECHA: " . date('Y-m-d H:i:s'));
|
||||
|
||||
$success[] = "🎉 Instalación básica completada";
|
||||
$step = 'completed';
|
||||
|
||||
} catch (Exception $e) {
|
||||
$errors[] = "❌ Error en verificación final: " . $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
} catch (PDOException $e) {
|
||||
$errors[] = "❌ Error de conexión: " . $e->getMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="es">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>⚡ Instalador Ultra Básico</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<style>
|
||||
body { background: linear-gradient(45deg, #667eea, #764ba2); min-height: 100vh; }
|
||||
.card { background: rgba(255,255,255,0.95); border-radius: 15px; box-shadow: 0 10px 30px rgba(0,0,0,0.3); }
|
||||
</style>
|
||||
</head>
|
||||
<body class="d-flex align-items-center">
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-lg-8">
|
||||
<div class="card p-4">
|
||||
|
||||
<?php if ($step === 'form'): ?>
|
||||
<div class="text-center mb-4">
|
||||
<h2>⚡ Instalador Ultra Básico</h2>
|
||||
<p class="text-muted">Solo crea las tablas esenciales paso a paso</p>
|
||||
</div>
|
||||
|
||||
<div class="alert alert-info">
|
||||
<h6><i class="fas fa-info-circle me-2"></i>Este instalador:</h6>
|
||||
<ul class="mb-0">
|
||||
<li>✅ Crea solo 2 tablas esenciales: <code>users</code> y <code>system_config</code></li>
|
||||
<li>✅ Verifica cada paso antes de continuar</li>
|
||||
<li>✅ Proceso ultra simplificado</li>
|
||||
<li>✅ Ideal para resolver problemas de creación de tablas</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<form method="POST" action="?step=install">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Host</label>
|
||||
<input type="text" class="form-control" name="db_host" value="localhost" required>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Puerto</label>
|
||||
<input type="text" class="form-control" name="db_port" value="3306" required>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Base de datos</label>
|
||||
<input type="text" class="form-control" name="db_name" placeholder="usite_whatsapp_bot" required>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Usuario</label>
|
||||
<input type="text" class="form-control" name="db_user" required>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<label class="form-label">Contraseña</label>
|
||||
<input type="password" class="form-control" name="db_pass" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="text-center mt-4">
|
||||
<div class="alert alert-success">
|
||||
<strong>Contraseña de admin que se generará:</strong><br>
|
||||
<code><?= $adminPassword ?></code>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary btn-lg">
|
||||
⚡ Instalación Ultra Básica
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php elseif ($step === 'install'): ?>
|
||||
<div class="text-center mb-4">
|
||||
<h2>⚙️ Instalando paso a paso...</h2>
|
||||
</div>
|
||||
|
||||
<?php if (!empty($errors)): ?>
|
||||
<div class="alert alert-danger">
|
||||
<h5>❌ Errores:</h5>
|
||||
<?php foreach ($errors as $error): ?>
|
||||
<div><?= htmlspecialchars($error) ?></div>
|
||||
<?php endforeach; ?>
|
||||
<hr>
|
||||
<a href="?step=form" class="btn btn-outline-danger">Reintentar</a>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($success)): ?>
|
||||
<div class="alert alert-success">
|
||||
<h5>✅ Progreso:</h5>
|
||||
<?php foreach ($success as $msg): ?>
|
||||
<div><?= htmlspecialchars($msg) ?></div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($step !== 'completed' && !empty($errors)): ?>
|
||||
<div class="alert alert-warning">
|
||||
<h6>💡 Sugerencias para resolver errores:</h6>
|
||||
<ul class="mb-0">
|
||||
<li>Verifica que la base de datos existe</li>
|
||||
<li>Confirma que el usuario tiene permisos ALL en la BD</li>
|
||||
<li>Prueba conectarte manualmente con phpMyAdmin</li>
|
||||
<li>Si persiste, contacta soporte con estos mensajes</li>
|
||||
</ul>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php elseif ($step === 'completed'): ?>
|
||||
<div class="text-center mb-4">
|
||||
<h2 class="text-success">🎉 ¡Instalación Básica Exitosa!</h2>
|
||||
<p class="text-muted">Sistema mínimo funcional instalado</p>
|
||||
</div>
|
||||
|
||||
<div class="row g-4">
|
||||
<div class="col-md-6">
|
||||
<h5>🔑 Credenciales</h5>
|
||||
<div class="alert alert-success">
|
||||
<strong>Usuario:</strong> admin<br>
|
||||
<strong>Contraseña:</strong> <code><?= $adminPassword ?></code><br>
|
||||
<small>Guardadas en: CREDENCIALES_BASICO.txt</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<h5>🚀 Siguiente</h5>
|
||||
<div class="d-grid gap-2">
|
||||
<a href="test.php" class="btn btn-success">Probar Sistema</a>
|
||||
<a href="index.php" class="btn btn-primary">Panel Admin</a>
|
||||
<a href="login.php" class="btn btn-outline-info">Login</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="alert alert-info mt-4">
|
||||
<h6>📋 Lo que se instaló:</h6>
|
||||
<ul class="mb-0">
|
||||
<li>✅ Tabla <code>users</code> - Para gestión de usuarios</li>
|
||||
<li>✅ Tabla <code>system_config</code> - Para configuración</li>
|
||||
<li>✅ Configuración básica del sistema</li>
|
||||
<li>✅ Credenciales de administrador</li>
|
||||
</ul>
|
||||
<hr>
|
||||
<small><strong>Nota:</strong> Puedes agregar más funcionalidades desde el panel de administración.</small>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user