Subir archivos programáticamente a campos media de JetEngine

Subir archivos programáticamente a campos media de JetEngine

Subir archivos programáticamente a campos media de JetEngine permite que los usuarios suban documentos a tu sitio WordPress y que estos se almacenen automáticamente en campos personalizados de JetEngine. Subir archivos programáticamente a campos media de JetEngine necesita saber dónde guardarlos, cómo registrarlos y qué hacer si llega algo sospechoso. En esta guía práctica, te mostraré exactamente cómo hacerlo paso a paso.

¿Por Qué Subir Archivos Programáticamente a JetEngine?

Imagina que tienes un portal de empleo donde los candidatos deben subir su hoja de vida. En lugar de usar el editor clásico de WordPress, quieres que ese PDF se guarde en un campo específico de JetEngine para procesarlo después. Aquí es donde la subida programática se vuelve esencial.

JetEngine almacena los archivos multimedia en un formato específico que incluye tanto el ID del adjunto como su URL. Si intentas guardar solo la URL o solo el ID, el campo aparecerá vacío en el administrador. Es como intentar abrir una puerta con solo la llave o solo la cerradura: necesitas ambas partes.

Requisitos Previos para la Subida Programática

Antes de empezar, asegúrate de tener:

  • WordPress 5.0 o superior instalado
  • El plugin JetEngine activo y configurado
  • Un tipo de contenido personalizado (CPT) con campo media de JetEngine
  • Acceso al archivo functions.php de tu tema o a un plugin personalizado

El Formato Correcto de Campos Media en JetEngine

JetEngine no almacena los archivos como texto simple. Usa un array con estructura específica:

array(
    'id'  => 123,  // ID del adjunto en WordPress
    'url' => 'https://tusitio.com/wp-content/uploads/documento.pdf'
)

Este formato permite que JetEngine muestre el archivo correctamente en la interfaz administrativa y genere los enlaces apropiados en el frontend. Si alguna vez has visto que subiste un archivo pero el campo aparece vacío, probablemente fue porque guardaste solo el ID o solo la URL.

Paso 1: Preparar el Terreno para la Subida

Primero, necesitas incluir las funciones de WordPress que manejan archivos. Es como preparar la cocina antes de cocinar:

// Funciones esenciales de WordPress para manejo de archivos
require_once ABSPATH . 'wp-admin/includes/file.php';
require_once ABSPATH . 'wp-admin/includes/media.php';
require_once ABSPATH . 'wp-admin/includes/image.php';

Paso 2: Validar el Archivo (Tu Primer Filtro de Seguridad)

Nunca confíes en los archivos que suben los usuarios. Imagina que eres el portero de un edificio: debes revisar cada paquete antes de dejarlo entrar. Aquí tienes una función de validación robusta:

function validar_archivo_subido($archivo) {
    // ¿Se subió realmente un archivo?
    if (empty($archivo['name']) || UPLOAD_ERR_NO_FILE === $archivo['error']) {
        return new WP_Error('sin_archivo', 'No se subió ningún archivo');
    }
    
    // ¿Hubo errores durante la subida?
    if (UPLOAD_ERR_OK !== $archivo['error']) {
        return new WP_Error('error_subida', 'Error al subir el archivo');
    }
    
    // Validar tipo de archivo (ejemplo: solo PDF)
    $tipo_archivo = wp_check_filetype($archivo['name']);
    if ('pdf' !== $tipo_archivo['ext']) {
        return new WP_Error('tipo_invalido', 'Solo se permiten archivos PDF');
    }
    
    // Validar tamaño máximo (ejemplo: 5MB)
    $tamano_maximo = 5 * 1024 * 1024; // 5MB en bytes
    if ($archivo['size'] > $tamano_maximo) {
        return new WP_Error('muy_grande', 'El archivo supera el límite de 5MB');
    }
    
    return true;
}

Paso 3: Subir el Archivo a WordPress

Usa la función wp_handle_upload() de WordPress. Es como el sistema de correo interno de tu sitio:

function subir_archivo_wordpress($archivo) {
    // Primero validar
    $validacion = validar_archivo_subido($archivo);
    if (is_wp_error($validacion)) {
        return $validacion;
    }
    
    // Configurar opciones de subida
    $opciones = array(
        'test_form' => false,
        'mimes'     => array('pdf' => 'application/pdf'),
    );
    
    // Subir el archivo
    $subida = wp_handle_upload($archivo, $opciones);
    
    if (isset($subida['error'])) {
        return new WP_Error('subida_fallida', $subida['error']);
    }
    
    return $subida;
}

Paso 4: Crear el Adjunto en la Biblioteca Multimedia

Subir el archivo no es suficiente. Necesitas registrarlo en la biblioteca de WordPress, como cuando registras un libro nuevo en una biblioteca:

function crear_adjunto_multimedia($subida, $post_id = 0) {
    $ruta_archivo = $subida['file'];
    $url_archivo = $subida['url'];
    $tipo_archivo = $subida['type'];
    
    // Preparar datos del adjunto
    $datos_adjunto = array(
        'guid'           => $url_archivo,
        'post_mime_type' => $tipo_archivo,
        'post_title'     => preg_replace('/\.[^.]+$/', '', basename($ruta_archivo)),
        'post_content'   => '',
        'post_status'    => 'inherit', // ¡IMPORTANTE!
    );
    
    // Insertar el adjunto
    $adjunto_id = wp_insert_attachment($datos_adjunto, $ruta_archivo, $post_id);
    
    if (is_wp_error($adjunto_id)) {
        return $adjunto_id;
    }
    
    // Generar metadatos (especialmente importante para imágenes)
    $metadatos = wp_generate_attachment_metadata($adjunto_id, $ruta_archivo);
    wp_update_attachment_metadata($adjunto_id, $metadatos);
    
    return $adjunto_id;
}

Paso 5: Guardar en el Campo Media de JetEngine

Finalmente, guardamos el archivo en el formato que JetEngine entiende. Es como poner la dirección correcta en el sobre:

function guardar_campo_media_jetengine($post_id, $meta_key, $adjunto_id) {
    // Obtener la URL del adjunto
    $url = wp_get_attachment_url($adjunto_id);
    
    if (!$url) {
        return false;
    }
    
    // Formato específico de JetEngine
    $valor_meta = array(
        'id'  => $adjunto_id,
        'url' => $url,
    );
    
    // Actualizar el meta del post
    update_post_meta($post_id, $meta_key, $valor_meta);
    
    return true;
}

Ejemplo Completo: Función Unificada

Aquí tienes una función que integra todos los pasos anteriores. Es como una receta completa para subir archivos:

function manejar_subida_jetengine($post_id, $meta_key, $archivo) {
    // Incluir funciones necesarias
    require_once ABSPATH . 'wp-admin/includes/file.php';
    require_once ABSPATH . 'wp-admin/includes/media.php';
    require_once ABSPATH . 'wp-admin/includes/image.php';
    
    // 1. Validar
    $validacion = validar_archivo_subido($archivo);
    if (is_wp_error($validacion)) {
        return array('exito' => false, 'mensaje' => $validacion->get_error_message());
    }
    
    // 2. Eliminar adjunto anterior si existe
    $meta_actual = get_post_meta($post_id, $meta_key, true);
    if (is_array($meta_actual) && !empty($meta_actual['id'])) {
        $adjunto_anterior_id = absint($meta_actual['id']);
        if ($adjunto_anterior_id && current_user_can('delete_post', $adjunto_anterior_id)) {
            wp_delete_attachment($adjunto_anterior_id, true);
        }
    }
    
    // 3. Subir archivo
    $subida = subir_archivo_wordpress($archivo);
    if (is_wp_error($subida)) {
        return array('exito' => false, 'mensaje' => $subida->get_error_message());
    }
    
    // 4. Crear adjunto
    $adjunto_id = crear_adjunto_multimedia($subida, $post_id);
    if (is_wp_error($adjunto_id)) {
        return array('exito' => false, 'mensaje' => $adjunto_id->get_error_message());
    }
    
    // 5. Guardar en JetEngine
    $guardado = guardar_campo_media_jetengine($post_id, $meta_key, $adjunto_id);
    if (!$guardado) {
        return array('exito' => false, 'mensaje' => 'Error al guardar en el campo de JetEngine');
    }
    
    return array(
        'exito'         => true,
        'mensaje'       => 'Archivo subido correctamente',
        'adjunto_id'    => $adjunto_id,
    );
}

Implementación con AJAX (Para Formularios Frontend)

Si quieres que los usuarios suban archivos desde el frontend, necesitas AJAX. Aquí tienes un ejemplo básico:

// En functions.php o tu plugin
add_action('wp_ajax_subir_documento', 'manejar_subida_documento_ajax');

function manejar_subida_documento_ajax() {
    // Verificar nonce de seguridad
    check_ajax_referer('nonce_subida', 'nonce');
    
    // Verificar permisos
    if (!is_user_logged_in()) {
        wp_send_json_error(array('mensaje' => 'Debes iniciar sesión'));
    }
    
    // Obtener ID del post
    $post_id = isset($_POST['post_id']) ? absint($_POST['post_id']) : 0;
    
    // Verificar que se subió un archivo
    if (empty($_FILES['documento'])) {
        wp_send_json_error(array('mensaje' => 'No se subió ningún archivo'));
    }
    
    // Manejar la subida
    $resultado = manejar_subida_jetengine(
        $post_id,
        'mi_campo_documentos', // Tu campo de JetEngine
        $_FILES['documento']
    );
    
    if ($resultado['exito']) {
        wp_send_json_success($resultado);
    } else {
        wp_send_json_error($resultado);
    }
}

Mejores Prácticas de Seguridad para Subida de Archivos

La seguridad es crucial cuando manejas archivos de usuarios. Sigue estas recomendaciones:

  • Valida tipos MIME: Usa wp_check_filetype() para verificar tipos de archivo reales, no solo extensiones
  • Limita tamaños: Define límites razonables según tus necesidades
  • Verifica permisos: Asegúrate que el usuario tenga permiso para subir archivos
  • Usa nonces: Protege tus formularios AJAX con nonces de WordPress
  • Limpia nombres: WordPress lo hace automáticamente, pero puedes usar sanitize_file_name() para mayor control

Problemas Comunes y Soluciones

Problema: El archivo se sube pero el campo de JetEngine aparece vacío.
Solución: Verifica que estás usando el formato correcto: array con ‘id’ (entero) y ‘url’ (string).

Problema: La subida falla sin mensaje de error.
Solución: Revisa los límites de PHP (upload_max_filesize, post_max_size) y los permisos del directorio uploads.

Problema: El adjunto no aparece en la biblioteca multimedia.
Solución: Asegúrate de establecer post_status como ‘inherit’ al crear el adjunto.

Optimización del Rendimiento

Para sitios con muchas subidas de archivos:

  • Elimina adjuntos antiguos: Siempre borra el archivo anterior antes de subir uno nuevo
  • Omite metadatos innecesarios: Para archivos PDF o documentos, no necesitas generar metadatos de imagen
  • Usa transients para subidas largas: Puedes mostrar el progreso al usuario

Conclusión

Subir archivos programáticamente a campos media de JetEngine requiere atención a tres aspectos clave: la validación de seguridad, el manejo correcto de archivos de WordPress, y el formato específico que JetEngine espera. Siguiendo esta guía, podrás implementar un sistema robusto para manejar documentos, imágenes u otros archivos en tus tipos de contenido personalizados.

Recuerda que cada sitio es diferente. Adapta los ejemplos a tus necesidades específicas, prueba exhaustivamente en un entorno de desarrollo antes de pasar a producción, y siempre prioriza la seguridad de tus usuarios y tu sitio.

Si necesitas profundizar en temas específicos de WordPress, consultar la documentación oficial de WordPress sobre subida de archivos.

Compartir esta información