Geben Sie den Benutzern eine maximale Upload-Kapazität. Begrenzen Sie die Anzahl der Dateien, die ein Benutzer hochladen kann, ODER begrenzen Sie die Anzahl der Dateien pro Upload

9

Ich verwende die Medienbibliothek am vorderen Ende meiner Website und möchte verhindern, dass Benutzer meinen Server durch Hochladen einer unbegrenzten Anzahl von Dateien spammen können.

Als solches möchte ich einen oder alle der folgenden Schritte ausführen:

  1. Geben Sie den Benutzern eine maximale Upload-Kapazität. Das heißt, Benutzer können bis zu 10 Megabyte Dateien hochladen.
  2. Begrenzen Sie die Anzahl der Dateien, die ein Benutzer pro Post hochladen kann
  3. Begrenzen Sie die Anzahl der Dateien, die ein Benutzer hochladen kann, wenn er auf die Schaltfläche "Einfügen" klickt. Mit dem Flash-Uploader und dem Classic-Uploader können Sie beispielsweise nur 2 Dateien gleichzeitig hochladen.

Keines davon ist kugelsicher, aber sie würden hoffentlich ein solches "Spam" zu einer Schwierigkeit machen.

Danke im Voraus,

dunc
quelle

Antworten:

11

Unter der Annahme, dass Sie Upload-Funktionen über die nativen Funktionen von WordPress bereitstellen, wie z. B. über wp_handle_uploadetwas höheres , kommen wir zu dem Schluss, dass mehrere Hooks gezogen werden.

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

Die wp_handle_uploadFunktion wäre wahrscheinlich die letzte native Funktion, die die Datei berührt, und würde alle Informationen kennen, die erforderlich sind, um den Überblick zu behalten.

Zwei Haken innerhalb dieser Funktion sind von Interesse: wp_handle_uploadund wp_handle_upload_prefilter. Letzteres steht an erster Stelle. Dies könnte die aktuellen Grenzwerte überprüfen und verhindern, dass die Datei hochgeladen wird. Ersteres würde Dateigrößen verfolgen und zählen. Das Speichern der Informationen würde von niemand anderem als verwaltet 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;
}

Theoretisch funktioniert das; praktisch - ungetestet. Lassen Sie uns wissen, wie es geht.

Die Upload-Limits pro Post würden im Post-Meta beibehalten, wahrscheinlich wie {$user_id}_upload_countusw. Ich verstehe nicht, warum das nicht funktionieren würde.

Wenn Sie benutzerdefinierten Code verwenden, um Uploads zu verarbeiten (was ich verdopple), können Sie Ihre eigenen Aktionen und Filter genauso implementieren wie dies der wp_handle_uploadsFall ist.

Soulseekah
quelle
Hi Soul - exzellenter Beitrag, vielen Dank. Ich bringe das jetzt zum Laufen. Können Sie erklären, was diese Zeilen tun? $upload_bytes_limit_reached = apply_filters( 'wpse47580_upload_bytes_limit_reached', 1024*1024*10 ) > ( $filesize + $upload_bytes );
Dunc
Ich habe den Code aktualisiert, um die gerade erwähnten Zeilen zu ändern, da sie mir Probleme bereiteten. Ich glaube, ich vermisse eine Filterfunktion, bin mir aber nicht sicher, was ich damit machen soll! Ich habe meinen Code als Antwort gepostet. Können Sie ihn kritisieren?
Dunc
Der apply_filtersCode würde es anderen Plugins ermöglichen, sich dort anzuschließen, was nützlich wäre. Können Sie die Art der Probleme beschreiben?
Soulseekah
1
Sie müssen $ args in wp_handle_upload zurückgeben, sonst wird das Bild nicht gespeichert!
Skylarkcob
Außerdem muss Code vorhanden sein, der das Löschen von Anhängen übernimmt und die Metafelder upload_count und upload_bytes verringert.
Svetoslav Marinov
1

Ich habe Soulseekahs Code etwas geändert, da die apply_filterVariablen für mich nicht funktionierten - wahrscheinlich, weil ich sie nicht verstehe!

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

Es wäre wirklich einfach, ein Plugin daraus zu machen, damit ich es möglicherweise irgendwann in der Zukunft veröffentlichen kann, wenn ich eine Schnittstelle dafür entwickelt habe.

dunc
quelle