WordPress как на ладони
Недорогой хостинг для сайтов на WordPress: wordpress.jino.ru

Разрешаем/запрещаем загрузку типов файлов

WordPress не позволяет загружать в медиатеку что попало - защищается. Файлы нестандартных (не разрешенных) типов загрузить невозможно, потому что в WP есть список допустимых форматов файлов, т.е. белый список mime-типов.

Иногда такая защита мешает, и несмотря на потенциальную опасность все же нужно иметь возможность загружать файлы нужных нам типов.

Ниже рассмотрим, как добавить тип загружаемого файла в белый список.

Вот так выглядит ошибка, если, например, попытаться загрузить файл в расширением .svg:

Процесс загрузки файла и проверка его типа

Разрешаем/запрещаем типы файлов для загрузки

Для управления белым списком расширений файлов есть два хука:

  • upload_mimes - срабатывает раньше чем wp_check_filetype_and_ext.

  • wp_check_filetype_and_ext - срабатывает в конце всех базовых хуков для проверок.

Пример ниже показывает как разрешить загрузку одних типов файлов (.doc, .djvu) и как запретить другие (.mp4a) - удалить из белого списка.

add_filter( 'upload_mimes', 'upload_allow_types' );
function upload_allow_types( $mimes ) {

	// разрешаем новые типы
	$mimes['doc']  = 'application/msword'; 
	$mimes['woff'] = 'font/woff';
	$mimes['psd']  = 'image/vnd.adobe.photoshop'; 
	$mimes['djv']  = 'image/vnd.djvu';
	$mimes['djvu'] = 'image/vnd.djvu';
	$mimes['webp'] = 'image/webp';

	// запрещаем (отключаем) имеющиеся
	unset( $mimes['mp4a'] );

	return $mimes;
}

По аналогии можно разрешать или запрещать любые другие типы файлов. Список MIME типов смотрите здесь.

меню

Как загружать SVG файлы

Тип SVG файла может меняться в зависимости от файла, поэтому с ним не все так просто. Подробнее смотрите в отдельной статье.

Там же можно увидеть какие могут нестандартные ситуации могут возникнуть при разрешении загрузки запрещенных типов файлов и как их решать.

Загрузка картинок с неправильным расширением

В WP предусмотрен механизм исправления расширения файла, когда оно указано неправильно. Например, мы загружаем картинку img.png реальный формат которой JPG. В этом случае проверка на соответствие реального MIME типа файла и его расширения не проходит и WP, на основе списка подобных соответствий, пытается установить правильное расширение и пройти проверку снова (см: wp_check_filetype_and_ext()). Если проверка проходит, то название файла изменяется на правильное.

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

Например, мы добавили WEBP формат в фильтр upload_mimes, нам также нужно учесть и этот механизм проверки соответствия расширения и mime типа, иначе мы просто не сможем загрузить картинку WEBP формата, если в названии у неё указано отличное от .webp расширение.

Сделать это можно с помощью фильтра getimagesize_mimes_to_exts, подробнее про то как все это работает, читайте в описании фильтра.

# Добавляем соответствие миме-типа и расширения
add_filter( 'getimagesize_mimes_to_exts', 'more_mimes_to_exts' );
function more_mimes_to_exts( $mime_to_ext ){
	$mime_to_ext['image/webp'] = 'webp';

	return $mime_to_ext;
}

После этого хука, вы сможете загружать картинки WEBP формата, даже если в их названии указано другое расширение, например image.jpg.

меню

Включение права unfiltered_upload

Право unfiltered_upload позволяет пользователям (ролям) загружать любые файлы, без проверки их типа.

Это право по умолчанию есть у ролей:

  • В обычном режиме: Редактор, Админ
  • В режиме мультисайт: Супер-админ

Однако это право по умолчанию заблокировано, т.е. указанные роли не пройдут проверку if( current_user_can('unfiltered_upload') ), несмотря на наличие у них такого права.

Чтобы право unfiltered_upload начало работать как ожидается, нужно в файле wp-config.php «включить» константу:

define( 'ALLOW_UNFILTERED_UPLOADS', true );
10 комментов
  • Liza

    Подскажите пожалуйста как в медиазагрузчики запретить загрузку видео, если пользователям разрешена загрузка файлов из сайта, оставить только для фото и все

    А может есть плагин медиазагрузчика который на для пользователей отдельно, честно скажу, искала везде не могу найти такой плагин для сайта

    Ответить2.5 года назад #
    • В примере показано же:

      unset( $mimes['mp4a'] ); // отключаем mp4a

      Пишем это в той самой функции

      1
      Ответить2 года назад #
  • Мне кажется что-то изменилось с приходом гуттенберга. Код не срабаывает.

    1
    Ответить1.5 года назад #
    • Kama7773

      MIME Тип файла правильно укажи (они разные бывают). Код рабочий!

      1
      Ответить1.5 года назад #
      • Мне нужно было разрешить к загрузке SVG, поэтому сделал копи-паст вашего образца - не сработало. Поэтому дал временное разрешение:

        define('ALLOW_UNFILTERED_UPLOADS', true);

        Возможно, я должен был заменить "text/plain" на "image/svg+xml" в строке $mimes['svg'] = 'text/plain'; // image/svg+xml, но тогда зачем в образце именно так указано?

        Ответить1.5 года назад #
        • Kama7773

          Для CVG раньше работал image/svg+xml, теперь работает text/plain. Вообще, миме тип svg image/svg+xml. Смотри также wp_check_filetype_and_ext.

          ALLOW_UNFILTERED_UPLOADS = true - это опасно!

          2
          Ответить1.5 года назад #
          • Максим

            Столкнулся с подобной проблемой. Как оказалось причина может быть и в самом файле svg. Пересохранил свои svg-изображения через сервис https://jakearchibald.github.io/svgomg/ и все загрузилось. Может кому будет полезно smile

            2
            Ответитьгод назад #
  • Dalim

    Проделал всё как указано в статье, не помогло. В чем может быть причина? Инфа ещё актуальНа? мб код уже не рабочий...

    1
    Ответить1.1 года назад #
  • РЕСПЕКТ АВТОРУ ЗА ТРУД

    1
    Ответить7 мес назад #
  • Мне нужно было добавление файла с расширением .stl
    Добавил такой код:

    add_filter( 'upload_mimes', 'upload_allow_types' );
    function upload_allow_types( $mimes ) {
    	$mimes['stl']  = 'application/vnd.ms-pki.stl';
    	return $mimes;
    }

    Но результат был такой же, как и до внесения изменения. Подскажите, как все таки добавить?

    Ответитьмесяц назад #