Вопрос или проблема
Я создаю ограничение для загрузки изображений на основе @brasofilo отличного кода. Короче говоря, он ограничивает пользователя загрузкой изображений только с минимальными размерами.
Однако я хочу применить это только тогда, когда пользователь загружает изображение миниатюры. Я пытался использовать $pagenow
в качестве условия,
global $pagenow;
if ($pagenow == 'media-upload.php')
add_filter( 'wp_handle_upload_prefilter', 'wpse_28359_block_small_images_upload' );
Но это не сработало. Есть идеи?
Определить, является ли вложение изображением миниатюры, довольно просто:
get_post_thumbnail_id( get_post() );
что является удобной функцией вокруг
get_post_meta( get_post()->ID, '_thumbnail_id', true );
Сложнее, если вы знаете только имя файла или URL.
add_filter( 'wp_handle_upload_prefilter', function( $file ) {
$url = wp_get_attachment_image_src(
get_post_thumbnail_id( get_post() ),
'post-thumbnail'
);
// Вывод возможных ошибок
if ( false !== strpos( $url, $file ) ) {
$file['error'] = 'Извините, но мы разрешаем загрузку только изображений миниатюры';
}
return $file;
} );
Как видите, я просто сравниваю текущую строку файла с URL изображения миниатюры поста. Обратите внимание, что я не знаю, сработает ли это, так как это не протестировано, и wp_handle_upload_prefilter
может быть слишком ранним этапом.
Другим вариантом может быть использование последнего фильтра внутри _wp_handle_upload()
:
apply_filters( 'wp_handle_upload', array(
'file' => $new_file,
'url' => $url,
'type' => $type
), 'wp_handle_sideload' === $action ? 'sideload' : 'upload' );
который также обрабатывает sideload.
Теоретически, я предполагаю, что слишком рано проверять, является ли изображение миниатюры на самом деле изображением миниатюры, прежде чем оно будет установлено. Вы можете отменить загрузку после её завершения (удалить файл, сбросить метаданные поста), но это далеко от изящного.
Сам мета-бокс регистрируется с помощью add_meta_box()
, а колбэк бокса – это post_thumbnail_meta_box
, который вызывает _wp_post_thumbnail_html()
для рендеринга содержимого. Когда вы заглянете внутрь, вы увидите, что там на самом деле есть скрытое поле:
$content .= '<input type="hidden" id="_thumbnail_id" name="_thumbnail_id" value="' . esc_attr( $thumbnail_id ? $thumbnail_id : '-1' ) . '" />';
Теперь name
– это _thumbnail_id
, который вы должны иметь возможность получить с помощью filter_input()
(хорошо) или с помощью $_POST['_thumbnail_id']
(плохо) внутри колбэка, такого как wp_handle_upload_prefilter
, чтобы определить, было ли это действительно изображением миниатюры:
$featID = filter_input( INPUT_POST, '_thumbnail_id', … filters … );
Добавьте приведенный ниже код в файл functions.php вашей текущей темы, и он ограничит минимальные размеры изображения:
add_filter('wp_handle_upload_prefilter','tc_handle_upload_prefilter');
function tc_handle_upload_prefilter($file)
{
$img=getimagesize($file['tmp_name']);
$minimum = array('width' => '250', 'height' => '200');
$width= $img[0];
$height =$img[1];
if ($width < $minimum['width'] )
return array("error"=>"Размеры изображения слишком малы. Минимальная ширина - {$minimum['width']}px. Загруженное изображение имеет ширину $width px");
elseif ($height < $minimum['height'])
return array("error"=>"Размеры изображения слишком малы. Минимальная высота - {$minimum['height']}px. Загруженное изображение имеет высоту $height px");
else
return $file;
}
Затем просто измените числа минимальных размеров, которые вы хотите (в моем примере это 250 и 200)
Ответ или решение
Чтобы ограничить загрузку изображений на основе минимальных размеров только для тех изображений, которые устанавливаются в качестве выбранного изображения (featured image), вы можете использовать фильтры WordPress, такие как wp_handle_upload_prefilter
. Ваша задача заключается в том, чтобы определить, происходит ли загрузка изображения с целью установки его в качестве выбранного изображения.
Вот шаги, которые вы должны выполнить:
-
Проверка, является ли изображение выбранным: Для этого вы можете использовать скрытое поле в форме, которое содержит ID выбранного изображения. Его можно получить, используя функцию
filter_input()
или массив$_POST
. -
Применение фильтра для проверки: Вам нужно будет добавить свой фильтр к функции
wp_handle_upload_prefilter
, чтобы проверить загруженный файл и его размеры только в том случае, если он предназначен для выбранного изображения.
Ниже приведен пример кода, который решает вашу задачу:
add_filter('wp_handle_upload_prefilter', 'tc_handle_upload_prefilter');
function tc_handle_upload_prefilter($file) {
// Получаем ID избранного изображения
$featured_id = filter_input(INPUT_POST, '_thumbnail_id', FILTER_SANITIZE_NUMBER_INT);
// Проверяем, указан ли ID
if ($featured_id) {
// Получаем размеры изображения
$img = getimagesize($file['tmp_name']);
$minimum = array('width' => 250, 'height' => 200);
$width = $img[0];
$height = $img[1];
// Проверяем минимальные размеры
if ($width < $minimum['width']) {
$file['error'] = "Ширина изображения слишком мала. Минимальная ширина: {$minimum['width']}px. Загруженная ширина: $width px.";
return $file;
} elseif ($height < $minimum['height']) {
$file['error'] = "Высота изображения слишком мала. Минимальная высота: {$minimum['height']}px. Загруженная высота: $height px.";
return $file;
}
}
return $file;
}
Пояснения:
-
Получение ID выбранного изображения: С помощью
filter_input(INPUT_POST, '_thumbnail_id')
мы получаем ID, если он установлен. Мы используем фильтрFILTER_SANITIZE_NUMBER_INT
, чтобы убедиться, что мы получаем только номер. -
Проверка изображений: Затем мы получаем размеры загружаемого изображения с помощью
getimagesize($file['tmp_name'])
. Мы сравниваем эти размеры с установленными минимальными размерами. -
Возврат ошибок: Если размеры недостаточные, мы присваиваем
error
элементу$file
и возвращаем его. Это предотвратит загрузку изображения, если оно не соответствует требованиям.
Эта реализация обеспечит проверку изображений только при установке их в качестве выбранных изображений, и не будет влиять на другие виды загрузок. Вы можете изменить минимальные размеры в массиве $minimum
, чтобы соответствовать вашим требованиям.
Не забудьте добавить этот код в файл functions.php
вашей текущей темы для его активации.