Дать пользователям максимальную емкость загрузки; ограничить количество файлов, которые пользователь может загрузить ИЛИ ограничить количество файлов на загрузку

9

Я использую библиотеку мультимедиа в интерфейсе своего веб-сайта и хочу, чтобы пользователи не могли спамить мой сервер, загружая неограниченное количество файлов.

Таким образом, я хотел бы сделать одно или, возможно, все ниже:

  1. Дать пользователям максимальную емкость загрузки; т.е. пользователи могут загружать до 10 мегабайт файлов.
  2. Ограничьте количество файлов, которые пользователь может загружать для каждого поста.
  3. Ограничьте количество файлов, которые пользователь может загрузить, нажав на кнопку «Вставить», т. Е. Flash Uploader и Classic Uploader позволяют загружать, например, только 2 файла одновременно.

Ничто из этого не является пуленепробиваемым, но они, надеюсь, затруднят такой «спам».

Заранее спасибо,

Dunc
источник

Ответы:

11

Предполагая, что вы предоставляете функцию загрузки с помощью собственных функций WordPress, например, lik wp_handle_uploadили чего-то более высокого уровня, мы пришли к выводу, что несколько хуков будут вытянуты.

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

Эта wp_handle_uploadфункция, вероятно, будет последней встроенной функцией, которая коснется файла, и будет знать всю информацию, необходимую для отслеживания.

Два хука внутри этой функции представляют интерес: wp_handle_uploadи wp_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делает.

soulseekah
источник
Привет Soul - отличный пост, большое спасибо. Я получаю это работает сейчас. Не могли бы вы объяснить, что делают эти строки? $upload_bytes_limit_reached = apply_filters( 'wpse47580_upload_bytes_limit_reached', 1024*1024*10 ) > ( $filesize + $upload_bytes );
Dunc
Я обновил код, чтобы изменить только что упомянутые строки, так как они вызывают у меня проблемы - наверное, мне не хватает функции фильтра, но я не уверен, что мне нужно с ней делать! Я отправил свой код в качестве ответа, можете ли вы его критиковать?
Dunc
apply_filtersКод позволит другому плагины вклиниться туда, подумал , что было бы полезно. Не могли бы вы описать природу проблем?
soulseekah
1
Вы должны вернуть $ args в wp_handle_upload, иначе изображение не будет сохранено!
skylarkcob
Кроме того, должен быть некоторый код, который будет обрабатывать удаление вложений и уменьшать мета-поля upload_count и upload_bytes.
Святослав Маринов
1

Я несколько исправил код Soulseekah, так как apply_filterпеременные у меня не работали - возможно, потому, что я их не понимаю!

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

Было бы очень просто создать плагин, чтобы я мог выпустить его в будущем, когда я разработал интерфейс для него.

Dunc
источник