Ofereça aos usuários uma capacidade máxima de upload; limitar o número de arquivos que um usuário pode carregar OU limitar o número de arquivos por upload

9

Estou usando a Biblioteca de mídia no front-end do meu site e gostaria de impedir que os usuários enviem spam para o meu servidor enviando um número ilimitado de arquivos.

Como tal, gostaria de fazer um ou talvez todos os itens abaixo:

  1. Ofereça aos usuários uma capacidade máxima de upload; ou seja, os usuários podem fazer upload de até 10 megabytes de arquivos.
  2. Limitar o número de arquivos que um usuário pode enviar por postagem
  3. Limite o número de arquivos que um usuário pode enviar ao clicar no botão "Inserir", ou seja, o remetente Flash e o remetente Classic apenas permitirão o upload, por exemplo, de 2 arquivos por vez.

Nada disso é à prova de balas, mas, com sorte, eles dificultariam esse tipo de "spam".

Desde já, obrigado,

dunc
fonte

Respostas:

11

Supondo que você esteja fornecendo a funcionalidade de upload por meio das funções nativas do WordPress, lik wp_handle_uploadou algo mais de alto nível, chegamos à conclusão de que vários ganchos serão puxados.

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

A wp_handle_uploadfunção provavelmente seria a última função nativa a tocar no arquivo e conheceria todas as informações necessárias para acompanhar.

Dois ganchos dentro desta função são interessantes: wp_handle_uploade wp_handle_upload_prefilter. O último vem primeiro, isso pode verificar os limites atuais e impedir que o arquivo seja carregado. O primeiro rastreava o tamanho dos arquivos e conta. O armazenamento das informações seria tratado por ninguém 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;
}

Teoricamente, isso funciona; praticamente - não testado. Deixe-nos saber como vai.

Os limites de upload por postagem seriam mantidos na meta meta, provavelmente como {$user_id}_upload_countetc. Não veja por que isso não funcionaria.

Se você estiver usando um código personalizado para gerenciar envios (que eu dupliquei), poderá implementar suas próprias ações e filtros da mesma forma que wp_handle_uploadsfaz.

soulseekah
fonte
Oi Alma - excelente post, muito obrigado. Estou fazendo isso funcionar agora. Você poderia explicar o que essas linhas fazem? $upload_bytes_limit_reached = apply_filters( 'wpse47580_upload_bytes_limit_reached', 1024*1024*10 ) > ( $filesize + $upload_bytes );
Dunc
Atualizei o código para alterar as linhas que acabei de mencionar, pois estavam me causando problemas - acho que estou perdendo uma função de filtro, mas não tenho certeza do que precisava fazer com ela! Eu publiquei meu código como resposta, você pode criticá-lo?
Dunc
O apply_filterscódigo permitiria que outros plugins se conectassem a ele, pensando que seria útil. Você poderia descrever a natureza dos problemas?
soulseekah
11
Você deve retornar $ args em wp_handle_upload ou a imagem não será salva!
Skylarkcob
Além disso, deve haver algum código que manipule a exclusão de anexos e diminua os meta-campos upload_count e upload_bytes.
Svetoslav Marinov
1

Eu alterei o código de Soulseekah um pouco, pois as apply_filtervariáveis ​​não estavam funcionando para mim - provavelmente porque eu não as entendo!

# [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;
}

Seria muito simples criar um plug-in para poder lançá-lo em algum momento no futuro, quando desenvolvi uma interface para ele.

dunc
fonte