20. Creating a method to update the file

 

20. Creación de un método para actualizar archivos en la base de datos

¡Hola y bienvenido de nuevo!

En esta lección vamos a crear un método crucial para la funcionalidad de traducción - el método update(). Este método nos permitirá guardar las traducciones generadas por ChatGPT directamente en nuestra base de datos. ¡Es como añadir notas adicionales a un archivo existente!


🎯 ¿Qué vamos a crear?

Vamos a crear el método update() que:

  1. Recibe un ID de archivo, contenido traducido e idioma destino

  2. Ejecuta una consulta UPDATE en la base de datos

  3. Actualiza las columnas translated y lang del registro específico

  4. Permite guardar traducciones para su reutilización futura


🔍 Contexto: ¿Por qué necesitamos este método?

Imagina que ya tienes un archivo con texto en español. Quieres traducirlo a inglés:

  1. Archivo original en BD:

  2. text

ID: 25

content: "Hola mundo"

translated: NULL

  1. lang: NULL

  2. Después de traducción:

  3. text

ID: 25

content: "Hola mundo"

translated: "Hello world"

  1. lang: "English"

El método update() es el que hace esta transformación en la base de datos.


🛠️ Método update()

php

/**

 * Actualiza un archivo con su traducción e idioma

 * 

 * @param int $fileID ID del archivo a actualizar

 * @param string $content Texto traducido

 * @param string $lang Idioma de la traducción

 * @return void

 */

public function update($fileID, $content, $lang)

{

    // 1. Preparamos la consulta UPDATE

    $stmt = $this->DB->prepare("

        UPDATE `files` 

        SET `translated` = :content, 

            `lang` = :lang 

        WHERE `ID` = :fileID

    ");

    

    // 2. Vinculamos los parámetros (seguridad contra SQL injection)

    $stmt->bindParam(":content", $content, PDO::PARAM_STR);

    $stmt->bindParam(":lang", $lang, PDO::PARAM_STR);

    $stmt->bindParam(":fileID", $fileID, PDO::PARAM_INT);

    

    // 3. Ejecutamos la consulta

    $stmt->execute();

}


📝 Explicación detallada de la consulta UPDATE

Sintaxis SQL UPDATE:

sql

UPDATE nombre_tabla

SET columna1 = valor1, columna2 = valor2

WHERE condición;

Nuestra consulta desglosada:

sql

UPDATE `files`                    -- Tabla a actualizar

SET `translated` = :content,      -- Nueva columna 1 (contenido traducido)

    `lang` = :lang                -- Nueva columna 2 (idioma destino)

WHERE `ID` = :fileID;             -- Condición: solo el archivo con este ID

¡IMPORTANTE! Sin el WHERE, actualizarías TODOS los registros de la tabla.


🔍 Diferencia entre INSERT y UPDATE

Operación

¿Qué hace?

Sintaxis SQL

Ejemplo

INSERT

Crea NUEVO registro

INSERT INTO tabla VALUES (...)

Agregar archivo nuevo

UPDATE

MODIFICA registro existente

UPDATE tabla SET ... WHERE id=X

Agregar traducción a archivo existente

Analogía:

  • INSERT → Escribir en una página nueva del cuaderno

  • UPDATE → Corregir o añadir información en una página ya escrita


🎨 Diagrama del flujo de traducción

text

┌─────────────────────────────────────────────────────────────┐

│                PROCESO COMPLETO DE TRADUCCIÓN               │

├─────────────────────────────────────────────────────────────┤

│ 1. USUARIO en view.php?file=25                              │

│    • Ve texto: "Hola mundo"                                 │

│    • Selecciona: Language → "English"                       │

│    • Click: "Translate"                                     │

│                                                             │

│ 2. PHP procesa:                                             │

│    • Configura: dataType = 'translation'                    │

│    • Configura: content = "Hola mundo"                      │

│    • Configura: lang = "English"                            │

│    • Llama: convert() → ChatGPT traduce                     │

│    • Recibe: "Hello world"                                  │

│                                                             │

│ 3. update() se ejecuta:                                     │

│    • Parámetros: (25, "Hello world", "English")             │

│    • SQL: UPDATE files SET translated='Hello world',        │

│           lang='English' WHERE ID=25                        │

│                                                             │

│ 4. BASE DE DATOS ANTES:                                     │

│    ┌─────┬──────────────┬──────────────┬────────┬────────┐  │

│    │ ID  │ content      │ translated   │ lang   │ type   │  │

│    ├─────┼──────────────┼──────────────┼────────┼────────┤  │

│    │ 25  │ Hola mundo   │ NULL         │ NULL   │ audio  │  │

│    └─────┴──────────────┴──────────────┴────────┴────────┘  │

│                                                             │

│ 5. BASE DE DATOS DESPUÉS:                                   │

│    ┌─────┬──────────────┬──────────────┬────────┬────────┐  │

│    │ ID  │ content      │ translated   │ lang   │ type   │  │

│    ├─────┼──────────────┼──────────────┼────────┼────────┤  │

│    │ 25  │ Hola mundo   │ Hello world  │ English│ audio  │  │

│    └─────┴──────────────┴──────────────┴────────┴────────┘  │

│                                                             │

│ 6. USUARIO ve resultado:                                    │

│    • Texto original: "Hola mundo"                           │

│    • Traducción: "Hello world"                              │

│    • Guardado para futuras consultas                        │

└─────────────────────────────────────────────────────────────┘


🔧 Ejemplo práctico paso a paso

Paso 1: Estado inicial de la BD

sql

SELECT * FROM files WHERE ID = 25;

-- Resultado:

-- ID: 25, content: 'Hola mundo', translated: NULL, lang: NULL

Paso 2: Llamada al método update()

php

// Después de obtener traducción de ChatGPT

$fileID = 25;

$translatedText = "Hello world";

$language = "English";


$whisperObj->update($fileID, $translatedText, $language);

Paso 3: Consulta SQL generada

sql

-- PHP/PDO ejecuta esta consulta (con valores seguros):

UPDATE `files` 

SET `translated` = 'Hello world', 

    `lang` = 'English' 

WHERE `ID` = 25;

Paso 4: Estado final de la BD

sql

SELECT * FROM files WHERE ID = 25;

-- Resultado:

-- ID: 25, content: 'Hola mundo', translated: 'Hello world', lang: 'English'

Paso 5: Visualización en view.php

php

<?php if($file->translated !== NULL): ?>

    <li id="translateContent" class="flex flex-col my-5 w-full">

        <h3 class="text-2xl"><?php echo $file->lang; ?></h3>

        <div><?php echo $file->translated; ?></div>

    </li>

<?php endif; ?>


💡 Importancia de los tipos de datos en bindParam()

Corrección importante:

php

// ERROR en el código original:

$stmt->bindParam(":fileID", $fileID, PDO::PARAM_STR);  // ← STR para ID?


// CORRECTO:

$stmt->bindParam(":fileID", $fileID, PDO::PARAM_INT);  // ← INT para ID

¿Por qué es importante?

  • PDO::PARAM_INT → Trata el valor como número entero

  • PDO::PARAM_STR → Trata el valor como texto (string)

  • Los IDs son números, no texto

  • Mejora el rendimiento y seguridad


📊 Estructura completa de la tabla files

sql

-- Estructura óptima de la tabla:

CREATE TABLE files (

    ID INT AUTO_INCREMENT PRIMARY KEY,

    fileUrl VARCHAR(255) NOT NULL,           -- Ruta del archivo

    content TEXT NOT NULL,                   -- Texto original

    type ENUM('audio', 'video') NOT NULL,   -- Tipo de archivo

    translated TEXT NULL,                    -- Texto traducido (puede ser NULL)

    lang VARCHAR(50) NULL,                   -- Idioma de traducción (puede ser NULL)

    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP

);

Campos importantes:

  1. translated → TEXT que permite NULL (inicialmente vacío)

  2. lang → VARCHAR que permite NULL (inicialmente vacío)

  3. NULL vs vacío ('') → NULL significa "aún no traducido"


🎯 Ventajas de guardar traducciones en BD

1. Evita reprocesamiento costoso:

php

// SIN guardar en BD:

// Cada vez que usuario pide traducción → llama a ChatGPT → paga por API


// CON guardado en BD:

// Primera vez: ChatGPT → paga

// Segunda vez: Lee de BD → GRATIS

2. Historial completo:

  • Usuario puede ver todas las traducciones previas

  • Puede comparar traducciones en diferentes idiomas

  • Puede revertir a versiones anteriores

3. Rendimiento mejorado:

  • Lectura desde BD: ~10ms

  • Llamada a ChatGPT API: ~500-2000ms

  • 50-200 veces más rápido después de la primera traducción


🔍 Mejoras potenciales al método

Versión mejorada con validación:

php

public function update($fileID, $content, $lang)

{

    // Validar que el archivo existe antes de actualizar

    $existingFile = $this->getFileById($fileID);

    

    if(!$existingFile) {

        $this->error = "Archivo no encontrado";

        return false;

    }

    

    // Validar que el contenido no esté vacío

    if(empty(trim($content))) {

        $this->error = "El contenido traducido no puede estar vacío";

        return false;

    }

    

    // Preparar y ejecutar consulta

    $stmt = $this->DB->prepare("

        UPDATE `files` 

        SET `translated` = :content, 

            `lang` = :lang,

            `updated_at` = NOW()  -- Registrar fecha de actualización

        WHERE `ID` = :fileID

    ");

    

    $stmt->bindParam(":content", $content, PDO::PARAM_STR);

    $stmt->bindParam(":lang", $lang, PDO::PARAM_STR);

    $stmt->bindParam(":fileID", $fileID, PDO::PARAM_INT);

    

    return $stmt->execute(); // Retorna true/false

}

Ventajas de la versión mejorada:

  1. ✅ Validación de existencia del archivo

  2. ✅ Validación de contenido no vacío

  3. ✅ Registro de fecha de actualización

  4. ✅ Retorno de estado (éxito/fracaso)

  5. ✅ Manejo de errores apropiado


⚠️ Consideraciones de seguridad

1. SQL Injection (ya prevenido):

php

// SEGURO gracias a bindParam()

$stmt->bindParam(":fileID", $fileID, PDO::PARAM_INT);


// INSECURO (nunca hacer esto):

$query = "UPDATE files SET translated='$content' WHERE ID=$fileID";

2. XSS (Cross-Site Scripting):

php

// Al mostrar contenido, siempre escapar:

echo htmlspecialchars($file->translated, ENT_QUOTES, 'UTF-8');

3. Validación de permisos (futuro):

php

// Si implementas usuarios:

if($file->user_id !== $_SESSION['user_id']) {

    die("No tienes permiso para actualizar este archivo");

}


📊 Comparación: save() vs update()

Aspecto

save()

update()

Propósito

Crear nuevo registro

Modificar registro existente

SQL

INSERT INTO ...

UPDATE ... SET ... WHERE

ID

Lo genera la BD (auto_increment)

Se proporciona como parámetro

Cuando se usa

Subir nuevo archivo

Traducir archivo existente

Columnas afectadas

fileUrl, content, type

translated, lang

Retorno

Nuevo ID

Nada (void) o éxito/fracaso


💡 Casos de uso adicionales para update()

1. Corregir transcripción:

php

// Si el usuario encuentra un error en el texto transcrito

$whisperObj->update($fileID, $textoCorregido, NULL);

// Solo actualiza contenido, no idioma

2. Multiples traducciones (futuro):

php

// Tabla separada para múltiples traducciones

public function addTranslation($fileID, $content, $lang, $translationType = 'chatgpt')

{

    $stmt = $this->DB->prepare("

        INSERT INTO translations (file_id, content, lang, type)

        VALUES (:fileID, :content, :lang, :type)

    ");

    // ...

}

3. Metadatos adicionales:

php

// Agregar información sobre la traducción

public function updateWithMetadata($fileID, $translated, $lang, $translator = 'chatgpt', $confidence = 0.95)

{

    $stmt = $this->DB->prepare("

        UPDATE files 

        SET translated = :translated,

            lang = :lang,

            translator = :translator,

            confidence_score = :confidence,

            translated_at = NOW()

        WHERE ID = :fileID

    ");

    // ...

}


🎯 Puntos Clave para Recordar

  1. UPDATE modifica, INSERT crea nuevo

  2. WHERE es CRÍTICO → Sin él, actualizas TODA la tabla

  3. bindParam() con tipo correcto → PARAM_INT para IDs

  4. NULL vs vacío → NULL significa "no traducido aún"

  5. Ventaja principal → Evita llamadas repetidas a API costosas

  6. Siempre validar → Que archivo exista, que contenido no esté vacío


📋 Cuestionario de Repaso

Pregunta 1:

¿Qué pasa si ejecutamos UPDATE files SET translated='hola' SIN cláusula WHERE?
a) Solo se actualiza el primer registro
b) Se actualizan TODOS los registros de la tabla
c) La consulta falla con error
d) Solo se actualizan los registros con translated=NULL

Pregunta 2:

¿Por qué usamos PDO::PARAM_INT para fileID en bindParam()?
a) Porque los IDs siempre son números enteros
b) Para seguridad y optimización (tratarlo como número, no texto)
c) Porque UPDATE solo acepta parámetros enteros
d) Porque es requerido por la cláusula WHERE

Pregunta 3:

¿Qué ventaja principal tiene guardar traducciones en la BD?
a) Hace que la página se vea más bonita
b) Evita llamadas repetidas y costosas a la API de ChatGPT
c) Permite traducir a más idiomas
d) Mejora la calidad de las traducciones

Pregunta 4:

¿Qué diferencia hay entre translated = NULL y translated = ''?
a) NULL es lo mismo que cadena vacía
b) NULL significa "no existe valor", '' significa "valor vacío"
c) NULL ocupa más espacio en la BD
d) Solo se puede usar NULL con números

Pregunta 5:

¿Qué método usarías para agregar una nueva traducción a un archivo existente?
a) save()
b) update()
c) insert()
d) modify()


📝 Respuestas del Cuestionario

  1. b) Sin cláusula WHERE, la consulta UPDATE afecta a TODAS las filas de la tabla. Esto es un error grave que podría corromper todos los datos. Siempre usar WHERE con UPDATE.

  2. b) PDO::PARAM_INT le dice a PDO que el valor debe tratarse como número entero, lo que previene ciertos tipos de inyección SQL y permite optimizaciones internas de la base de datos.

  3. b) La principal ventaja es económica y de rendimiento: evitar pagar y esperar por la API de OpenAI cada vez que un usuario solicita la misma traducción. Una vez traducido, se sirve desde BD.

  4. b) NULL significa "ausencia de valor" o "desconocido", mientras que '' (cadena vacía) es un valor conocido que simplemente está vacío. En nuestra lógica, NULL = "no traducido aún".

  5. b) update() es para modificar registros existentes. save() es para crear nuevos registros (nuevos archivos subidos). Cada uno tiene su propósito específico.


🚀 Lo que viene después

¡Perfecto! Ahora tenemos:
✅ Método update() completo y seguro
✅ Capacidad para guardar traducciones
✅ Estructura de BD preparada para traducciones

En la próxima lección vamos a:

  1. Implementar el formulario de traducción en view.php

  2. Procesar solicitudes POST de traducción

  3. Integrar ChatGPT para generar traducciones

  4. Llamar a update() para guardar resultados

  5. Mostrar traducciones en tiempo real

✨ ¡Excelente trabajo! Has creado la infraestructura necesaria para que las traducciones sean persistentes. Ahora los usuarios pueden traducir una vez y disfrutar para siempre.


Comentarios

Entradas más populares de este blog

1-7. Transforma tu audio a texto

10. Haz que tu asistente hable

8. NUEVO - Solución si tu micrófono no está captando tu audio