web-dev-qa-db-ja.com

ユーザーに最大アップロード容量を与えます。ユーザーがアップロードできるファイル数を制限する OR アップロードごとのファイル数を制限する

私は私のウェブサイトのフロントエンドにあるメディアライブラリを使っていて、無制限の数のファイルをアップロードすることによってユーザーが私のサーバーをスパムすることができないようにしたいです。

そういうものとして、私は以下のうちの1つまたは多分すべてをしたいです。

  1. ユーザーに最大アップロード容量を与えます。つまり、ユーザーは最大10メガバイトのファイルをアップロードできます。
  2. ユーザーが投稿ごとにアップロードできるファイルの数を制限する
  3. ユーザーが[挿入]ボタンをクリックしたときにアップロードできるファイルの数を制限します。つまり、Flashアップローダとクラシックアップローダでは、一度に2ファイルまでしかアップロードできません。

これらのどれも防弾ではありませんが、うまくいけば、そのような「スパム」を困難にするでしょう。

前もって感謝します、

9
dunc

あなたがWordPressのネイティブ関数、lik wp_handle_upload またはもっと高レベルなものを介してアップロード機能を提供していると仮定すると、いくつかのフックが引っ張られることになるという結論に至ります。

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

wp_handle_upload関数は、おそらくファイルに触れる最後のネイティブ関数であり、追跡するために必要なすべての情報を知っているでしょう。

この関数内の2つのフック、wp_handle_uploadwp_handle_upload_prefilterが重要です。後者が最初に来ます、これは現在の制限に対してチェックし、ファイルがアップロードされるのを妨げる可能性があります。前者はファイルサイズを追跡してカウントします。情報を保存することは 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;
}

理論的には、これはうまくいきます。事実上 - テストされていません。それがどのようになるのか教えてください。

投稿ごとのアップロード制限は、おそらく{$user_id}_upload_countなどのように、投稿メタに保持されます。それがうまくいかない理由はわからないでください。

アップロードを処理するためにカスタムコードを使用している場合(私はこれを使用します)、wp_handle_uploadsと同じように独自のアクションとフィルタを実装できます。

11
soulseekah

apply_filter変数が機能していなかったため、Soulseekahのコードを多少修正しました。おそらく理解できないからでしょう。

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

私はそれのためのインターフェースを開発したとき、これはプラグインを作るのが本当に簡単であるので私は将来のある時点でそれをリリースするかもしれません。

1
dunc