Validar datos de campos personalizados en save_post

Contents

Validación de datos de campos personalizados en save_post

En el desarrollo de plugins y temas de WordPress, es frecuente añadir campos personalizados para enriquecer la información de las entradas y páginas. Sin embargo, almacenar datos sin validación ni saneamiento puede llevar a vulnerabilidades, errores de datos o problemas de compatibilidad. En este artículo, profundizaremos en cómo validar y sanear correctamente los datos de custom fields usando el hook save_post, siguiendo las mejores prácticas.

1. Fundamentos: saneamiento vs validación

Saneamiento (sanitization) consiste en limpiar los datos para que sean seguros: eliminar etiquetas no deseadas, caracteres maliciosos o inyecciones. Validación (validation) comprueba que el dato cumple un formato o rango esperado (por ejemplo, un correo electrónico válido o un número entero).

Ejemplo: Un campo de correo debe sanearse con sanitize_email() y validarse con is_email().

1.1. Funciones comunes de saneamiento

Función Uso
sanitize_text_field() Limpia texto plano
sanitize_email() Limpia correo electrónico
esc_url_raw() Limpia URLs para base de datos
intval() Convierte a entero

2. Hook save_post: estructura básica

El hook save_post se dispara cada vez que se guarda un post. Permite interceptar el proceso y ejecutar nuestra lógica de validación y guardado. Su firma más común es:

add_action(save_post, mi_validacion_campos_personalizados, 10, 2)

function mi_validacion_campos_personalizados(post_id, post) {
    // Lógica aquí
}
  

Los parámetros post_id y post facilitan acceso al ID y a los datos completos del post.

2.1. ¡Importante! Verificaciones previas

  • Revisar nonce: usaremos check_admin_referer() para evitar CSRF.
  • Permisos: current_user_can( edit_post, post_id ) para controlar roles.
  • Autoguardado: descartar DOING_AUTOSAVE para no duplicar ejecuciones.

3. Ejemplo completo de validación y guardado

add_action(save_post, guardar_campos_personalizados_seguro, 10, 2)
function guardar_campos_personalizados_seguro(post_id, post) {
    // 1. Evitar auto-saves
    if ( defined(DOING_AUTOSAVE)  DOING_AUTOSAVE ) {
        return
    }
    // 2. Verificar nonce
    if ( ! isset(_POST[mi_nonce])  ! wp_verify_nonce(_POST[mi_nonce], guardar_campos) ) {
        return
    }
    // 3. Comprobar permisos
    if ( ! current_user_can(edit_post, post_id) ) {
        return
    }

    // 4. Obtener y sanear datos
    email_raw = isset(_POST[email_usuario])  _POST[email_usuario] : 
    email = sanitize_email(email_raw)

    url_raw = isset(_POST[sitio_web])  _POST[sitio_web] : 
    url = esc_url_raw(url_raw)

    edad_raw = isset(_POST[edad])  _POST[edad] : 
    edad = intval(edad_raw)

    // 5. Validar
    if ( ! is_email(email) ) {
        // Manejar error: email inválido
        return
    }
    if ( edad < 0  edad > 120 ) {
        // Edad fuera de rango
        return
    }

    // 6. Guardar
    update_post_meta(post_id, email_usuario, email)
    update_post_meta(post_id, sitio_web, url)
    update_post_meta(post_id, edad, edad)
}
  

4. Gestión de errores y notificaciones

Al detectar errores en la validación, es recomendable informar al usuario mediante notices. Una forma sencilla:

// En la función de save_post, al detectar error:
add_filter(redirect_post_location, function(location) {
    return add_query_arg(mi_error, email_invalido, location)
})

// Luego, en admin_notices
add_action(admin_notices, function() {
    if ( isset(_GET[mi_error])  _GET[mi_error] === email_invalido ) {
        echo 
echo

Error: El correo ingresado no es válido.

echo
} })

5. Buenas prácticas y recursos

Checklist final:

  • ¿Se verifica DOING_AUTOSAVE
  • ¿Se comprueba el nonce
  • ¿Se validan los permisos de usuario
  • ¿Se limpia y luego se valida cada campo
  • ¿Se informa adecuadamente al usuario en caso de error

Implementar validaciones robustas no solo mejora la seguridad, sino también la calidad de datos y la experiencia de usuario en el administrador de WordPress.



Acepto donaciones de BAT's mediante el navegador Brave 🙂



Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *