Daj użytkownikom maksymalną pojemność wysyłania; ogranicz liczbę plików, które użytkownik może przesłać LUB ogranicz liczbę plików na przesyłanie

9

Korzystam z Biblioteki multimediów na froncie mojej witryny i chciałbym uniemożliwić użytkownikom spamowanie mojego serwera przez przesłanie nieograniczonej liczby plików.

Jako taki chciałbym wykonać jedną, a może wszystkie poniższe czynności:

  1. Daj użytkownikom maksymalną pojemność wysyłania; tzn. użytkownicy mogą przesyłać do 10 megabajtów plików.
  2. Ogranicz liczbę plików, które użytkownik może przesłać osobno
  3. Ogranicz liczbę plików, które użytkownik może przesłać po kliknięciu przycisku „Wstaw”, tzn. Programy do przesyłania Flash i Classic do przesyłania umożliwiają na przykład przesyłanie tylko 2 plików na raz.

Żadne z nich nie jest kuloodporne, ale mam nadzieję, że utrudnią takie „spamowanie”.

Z góry dziękuję,

nie
źródło

Odpowiedzi:

11

Zakładając, że udostępniasz funkcję wysyłania za pośrednictwem natywnych funkcji WordPress, liku wp_handle_uploadlub czegoś bardziej wysokiego poziomu, doszliśmy do wniosku, że zostanie wyciągniętych kilka haczyków.

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

Ta wp_handle_uploadfunkcja prawdopodobnie byłaby ostatnią natywną funkcją, która dotknęła pliku i znała wszystkie informacje niezbędne do śledzenia.

Interesujące są dwa haczyki wewnątrz tej funkcji: wp_handle_uploadi wp_handle_upload_prefilter. Ten ostatni jest na pierwszym miejscu, co może sprawdzić aktualne limity i uniemożliwić przesłanie pliku. Ten pierwszy śledziłby rozmiary plików i liczył. Przechowywanie informacji byłoby obsługiwane przez nikogo innego 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;
}

Teoretycznie to działa; praktycznie - niesprawdzone. Poinformuj nas jak to idzie.

Limity wysyłania postów byłyby zachowane w meta postach, prawdopodobnie jak {$user_id}_upload_countitp. Nie rozumiem, dlaczego to nie zadziałałoby.

Jeśli używasz niestandardowego kodu do obsługi przesyłania (co dubluję), możesz zaimplementować własne akcje i filtry, tak jak wp_handle_uploadsrobi to.

soulseekah
źródło
Cześć Soul - doskonały post, wielkie dzięki. Teraz zaczynam działać. Czy możesz wyjaśnić, co robią te linie? $upload_bytes_limit_reached = apply_filters( 'wpse47580_upload_bytes_limit_reached', 1024*1024*10 ) > ( $filesize + $upload_bytes );
dunc
Zaktualizowałem kod, aby zmienić wiersze, które właśnie wspomniałem, ponieważ powodowały mi problemy - chyba brakuje mi funkcji filtrowania, ale nie jestem pewien, co musiałem z tym zrobić! Wysłałem swój kod jako odpowiedź, czy możesz go skrytykować?
dunc
apply_filtersKod pozwoliłoby inne wtyczki do podłączenia do tam, pomyślałem, że byłoby użyteczne. Czy mógłbyś opisać naturę problemów?
soulseekah
1
Musisz zwrócić $ args w wp_handle_upload, w przeciwnym razie obraz nie zostanie zapisany!
skylarkcob
Ponadto musi istnieć kod, który będzie obsługiwał usuwanie załączników i zmniejszył pola meta upload_count i upload_bytes.
Svetoslav Marinov,
1

Poprawiłem nieco kod Soulseekaha, ponieważ apply_filterzmienne nie działały dla mnie - prawdopodobnie dlatego, że ich nie rozumiem!

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

Utworzenie wtyczki byłoby bardzo proste, więc mógłbym ją wypuścić w przyszłości, kiedy opracuję dla niej interfejs.

nie
źródło