Offrez aux utilisateurs une capacité de téléchargement maximale; limiter le nombre de fichiers qu'un utilisateur peut télécharger OU limiter le nombre de fichiers par téléchargement

9

J'utilise la médiathèque à l'avant de mon site Web et j'aimerais empêcher les utilisateurs de pouvoir envoyer du spam à mon serveur en téléchargeant un nombre illimité de fichiers.

En tant que tel, je voudrais faire une ou peut-être toutes les opérations ci-dessous:

  1. Offrez aux utilisateurs une capacité de téléchargement maximale; les utilisateurs peuvent télécharger jusqu'à 10 mégaoctets de fichiers.
  2. Limitez le nombre de fichiers qu'un utilisateur peut télécharger par poste
  3. Limitez le nombre de fichiers qu'un utilisateur peut télécharger lorsqu'il clique sur le bouton "Insérer", c'est-à-dire que le téléchargeur Flash et le téléchargeur classique ne vous permettront de télécharger, par exemple, que 2 fichiers à la fois.

Aucun de ceux-ci n'est à l'épreuve des balles mais ils feraient, espérons-le, un tel "spamming" une difficulté.

Merci d'avance,

dunc
la source

Réponses:

11

En supposant que vous fournissez une fonctionnalité de téléchargement via les fonctions natives de WordPress, lik wp_handle_uploadou quelque chose de plus haut niveau, nous arrivons à la conclusion que plusieurs crochets vont être tirés.

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

La wp_handle_uploadfonction serait probablement la dernière fonction native à toucher le fichier et connaîtrait toutes les informations nécessaires pour garder une trace.

Deux crochets à l'intérieur de cette fonction sont intéressants: wp_handle_uploadet wp_handle_upload_prefilter. Ce dernier vient en premier, cela pourrait vérifier les limites actuelles et empêcher le téléchargement du fichier. Le premier suivrait la taille des fichiers et compterait. Le stockage des informations serait géré par nul autre 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;
}

Théoriquement, cela fonctionne; pratiquement - non testé. Tiens nous au courant de comment ça se passe.

Les limites de téléchargement par publication seraient conservées dans la méta-publication, probablement comme {$user_id}_upload_countetc. Ne voyez pas pourquoi cela ne fonctionnerait pas.

Si vous utilisez du code personnalisé pour gérer les téléchargements (que je double), vous pouvez implémenter vos propres actions et filtres comme vous le faites wp_handle_uploads.

soulseekah
la source
Salut l'âme - excellent post, merci beaucoup. Je fais fonctionner ça maintenant. Pourriez-vous expliquer ce que font ces lignes? $upload_bytes_limit_reached = apply_filters( 'wpse47580_upload_bytes_limit_reached', 1024*1024*10 ) > ( $filesize + $upload_bytes );
Dunc
J'ai mis à jour le code pour changer les lignes que je viens de mentionner, car elles me posaient des problèmes - je suppose qu'il me manque une fonction de filtrage mais je ne suis pas sûr de ce que je devais faire avec! J'ai publié mon code comme réponse, pourriez-vous le critiquer?
Dunc
Le apply_filterscode permettrait à d'autres plugins de s'y connecter, pensant que cela serait utile. Pourriez-vous décrire la nature des problèmes?
soulseekah
1
Vous devez retourner $ args dans wp_handle_upload ou l'image ne sera pas enregistrée!
skylarkcob
En outre, il doit y avoir du code qui gérera la suppression des pièces jointes et réduira les champs méta upload_count et upload_bytes.
Svetoslav Marinov
1

J'ai quelque peu modifié le code de Soulseekah car les apply_filtervariables ne fonctionnaient pas pour moi - probablement parce que je ne les comprends pas!

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

Ce serait vraiment simple de créer un plugin, donc je pourrais le publier à un moment donné dans le futur, quand j'aurai développé une interface pour cela.

dunc
la source