Ofrezca a los usuarios una capacidad de carga máxima; limitar la cantidad de archivos que puede cargar un usuario O limitar la cantidad de archivos por carga

9

Estoy usando la Biblioteca de medios en la parte frontal de mi sitio web y me gustaría evitar que los usuarios puedan enviar spam a mi servidor cargando una cantidad ilimitada de archivos.

Como tal, me gustaría hacer uno o tal vez todo lo siguiente:

  1. Ofrezca a los usuarios una capacidad de carga máxima; es decir, los usuarios pueden cargar hasta 10 megabytes de archivos.
  2. Limite la cantidad de archivos que un usuario puede cargar por publicación
  3. Limite la cantidad de archivos que un usuario puede cargar cuando hace clic en el botón "Insertar", es decir, el cargador de Flash y el cargador clásico solo le permitirán cargar, por ejemplo, 2 archivos a la vez.

Ninguno de estos es a prueba de balas, pero con suerte haría que tal "spam" sea una dificultad.

Gracias por adelantado,

dunc
fuente

Respuestas:

11

Suponiendo que está proporcionando funcionalidad de carga a través de las funciones nativas de WordPress, lik wp_handle_uploado algo más de alto nivel, llegamos a la conclusión de que se van a tirar varios ganchos.

http://core.trac.wordpress.org/browser/tags/3.3/wp-admin/includes/file.php#L212

La wp_handle_uploadfunción probablemente sería la última función nativa en tocar el archivo y conocería toda la información necesaria para realizar un seguimiento.

Dos ganchos dentro de esta función son de interés: wp_handle_uploady wp_handle_upload_prefilter. Lo último es lo primero, esto podría verificar los límites actuales y evitar que el archivo se cargue. El primero rastrearía el tamaño de los archivos y contaría. El almacenamiento de la información sería manejado por nada menos que update_user_meta.

add_filter( 'wp_handle_upload', 'wpse47580_update_upload_stats' );
function wpse47580_update_upload_stats( $args ) {
    $file = $args['file'];
    $size = filesize( $file ); // bytes

    $user_id = get_current_user_id();

    $upload_count = get_user_meta( $user_id, 'upload_count', $single = true );
    $upload_bytes = get_user_meta( $user_id, 'upload_bytes', $single = true );

    update_user_meta( $user_id, 'upload_count', $upload_count + 1 );
    update_user_meta( $user_id, 'upload_bytes', $upload_bytes + $size );
}

add_filter( 'wp_handle_upload_prefilter', 'wpse47580_check_upload_limits' );
function wpse47580_check_upload_limits( $file ) {
    $user_id = get_current_user_id();

    $upload_count = get_user_meta( $user_id, 'upload_count', $single = true );
    $upload_bytes = get_user_meta( $user_id, 'upload_bytes', $single = true );

    $filesize = /* get filesize from $file array */;
    $upload_bytes_limit_reached = apply_filters( 'wpse47580_upload_bytes_limit_reached', 1024*1024*10 ) > ( $filesize + $upload_bytes );
    $upload_count_limit_reached = apply_filters( 'wpse47580_upload_count_limit_reached', 100 ) > ( $upload_count + 1 );

    if ( $upload_count_limit_reached || $upload_bytes_limit_reached )
        $file['error'] = 'Upload limit has been reached for this account!';

    return $file;
}

Teóricamente, esto funciona; prácticamente no probado. Háganos saber cómo va.

Los límites de carga por publicación se mantendrían en la meta de publicación, probablemente como {$user_id}_upload_countetc. No veo por qué eso no funcionaría.

Si está utilizando un código personalizado para manejar cargas (lo cual dudo), entonces puede implementar sus propias acciones y filtros como lo wp_handle_uploadshace.

soulseekah
fuente
Hola alma - excelente publicación, muchas gracias. Estoy haciendo que esto funcione ahora. ¿Podría explicar qué hacen estas líneas? $upload_bytes_limit_reached = apply_filters( 'wpse47580_upload_bytes_limit_reached', 1024*1024*10 ) > ( $filesize + $upload_bytes );
dunc
He actualizado el código para cambiar las líneas que acabo de mencionar, ya que me estaban causando problemas. ¡Supongo que me falta una función de filtro, pero no estoy seguro de lo que tenía que hacer con ella! He publicado mi código como respuesta, ¿podrías criticarlo?
dunc
El apply_filterscódigo permitiría que otros complementos se conectaran allí, pensé que sería útil. ¿Podría describir la naturaleza de los problemas?
soulseekah
1
¡Debe devolver $ args en wp_handle_upload o la imagen no se guardará!
skylarkcob
Además, debe haber algún código que controle la eliminación de archivos adjuntos y disminuya los metacampos upload_count y upload_bytes.
Svetoslav Marinov
1

Modifiqué un poco el código de Soulseekah porque las apply_filtervariables no me funcionaban, ¡probablemente porque no las entiendo!

# [File Upload]
#
# Two filters to give users a maximum upload limit of 10Mb and 100 files.
# This function runs after the file has been uploaded.
add_filter( 'wp_handle_upload', 'wpse47580_update_upload_stats' );
function wpse47580_update_upload_stats( $args ) {
    $size = filesize( $args['file'] );

    $user_id = get_current_user_id();

    $upload_count = get_user_meta( $user_id, 'upload_count', true );
    $upload_bytes = get_user_meta( $user_id, 'upload_bytes', true );

    update_user_meta( $user_id, 'upload_count', $upload_count + 1 );
    update_user_meta( $user_id, 'upload_bytes', $upload_bytes + $size );
}

# This function runs before the file is uploaded.
add_filter( 'wp_handle_upload_prefilter', 'wpse47580_check_upload_limits' );
function wpse47580_check_upload_limits( $file ) {
    $user_id = get_current_user_id();

    $upload_count = get_user_meta( $user_id, 'upload_count', true );
    $upload_bytes = get_user_meta( $user_id, 'upload_bytes', true );

    $filesize = $file['size']; // bytes

    $upload_bytes_limit_reached = ( ( $filesize + $upload_bytes ) > ( 1024 * 1024 * 10 ) );

    $upload_count_limit_reached = ( $upload_count + 1 ) > 100;

    if ( $upload_count_limit_reached || $upload_bytes_limit_reached )
        $file['error'] = 'Upload limit has been reached for this account!';

    return $file;
}

Sería realmente sencillo crear un complemento para poder lanzarlo en algún momento en el futuro, cuando haya desarrollado una interfaz para él.

dunc
fuente