Вопрос или проблема
Версия WP: 4.7.2
Я создаю плагин и использую wp_handle_upload_prefilter
и wp_handle_sideload_prefilter
для фильтрации размера файла и возврата ошибок.
Когда они добавлены в functions.php
темы, оба работают. Но когда они добавлены в функционал плагина, wp_handle_sideload_prefilter
перестает работать.
Кто-нибудь знает, как заставить этот хук работать внутри плагина?
Вот моя функция:
function validate_user_storage_space( $file ) {
$storage_limits = array(
"administrator" => 1, //размер в МБ
"editor" => 0,
"author" => 0,
"contributor" => 0,
"subscriber" => 0,
"client" => 0,
"vendor-basic" => 1,
"pending_user" => 0,
"suspended" => 0,
);
//$storage_limits = get_option( $this->plugin_name );
$user_id = get_current_user_id();
$user_data = get_userdata( $user_id );
$user_roles = $user_data->roles;
$user_limits = array();
// Если у пользователя несколько ролей
foreach ( $user_roles as $role ) {
array_push( $user_limits, $storage_limits[ $role ] );
}
// Сортирует лимиты в порядке возрастания
sort( $user_limits );
// Лимит 9999 означает неограниченное хранилище
if ( end( $user_limits ) === 9999 ) {
return $file;
}
else {
// Возвращает наивысший лимит
$size_limit = end( $user_limits );
}
// Конвертирует МБ в байты
$size_limit_bytes = $size_limit * pow( 1024, 2 );
$used_storage_space = get_user_meta( $user_id, 'rbsl_used_storage_space', $single = true );
$file_size = $file[ 'size' ];
if ( ( $file_size + $used_storage_space ) > $size_limit_bytes ) {
$storage_limit_reached = true;
}
else {
$storage_limit_reached = false;
}
if ( $file[ 'size' ] > 1 ) {
$file['error'] = apply_filters( 'rbsl_sl_error_message', __( 'Вы достигли лимита в', $this->plugin_name ) . ' ' . $size_limit . 'МБ', $size_limit );
}
return $file;
}
add_filter('wp_handle_upload_prefilter', 'validate_user_storage_space', 1);
add_filter('wp_handle_sideload_prefilter', 'validate_user_storage_space', 1);
возможно, validate_user_storage_space
запускается слишком рано или слишком поздно. попробуйте обернуть эту функцию в другую функцию, затем подключите вторую функцию с одним из следующих хуков действий
init
или after_setup_theme
или plugins_loaded
как ниже.
add_action( 'init', 'validate_user_init' ); //after_setup_theme plugins_loaded
function validate_user_init(){
add_filter('wp_handle_upload_prefilter', 'validate_user_storage_space', 1);
add_filter('wp_handle_sideload_prefilter', 'validate_user_storage_space', 1);
}
function validate_user_storage_space( $file ) {
//ваши действия
}
Ответ или решение
Когда дело касается разработки плагинов для WordPress, разработчики могут столкнуться с проблемой того, что определенные хуки работают в файлах темы, но не работают в самом плагине. Один из таких случаев — это проблема с хуками wp_handle_upload_prefilter
и wp_handle_sideload_prefilter
, как описано в вашем вопросе. Разберем, почему это может происходить и как решить данную проблему.
Теория
В WordPress хуки выполняются в определённом порядке во время процесса загрузки, и плагин может загружаться в разное время по отношению к другим компонентам, таким как темы. Из-за этого порядка выполнения, функция, подключаемая к хуку, возможно, активируется слишком рано или слишком поздно. Поэтому становится необходимым убедиться, что привязывание вашей функции к нужному хуку происходит в нужное время.
Пример
В вашей ситуации возникает проблема только с хуком wp_handle_sideload_prefilter
. Это указывает на возможную проблему с моментом выполнения, потому что в темах это решение работает корректно.
Применение
Поскольку проблема может быть связана с тем, когда именно подключаются ваши фильтры в плагине, можно использовать различные методы, чтобы регулировать этот порядок. Вот один из подходов:
-
Оборачивайте подключение в другую функцию: Это поможет контролировать, когда именно вызываются ваши фильтры. Ваша функция
validate_user_storage_space
должна быть подключена в конкретный момент выполнения через другой хук, такой какinit
,after_setup_theme
илиplugins_loaded
. -
Правильно выбирайте момент подключения: Используйте
plugins_loaded
илиinit
, чтобы быть уверенным, что ваши фильтры будут распределены в нужное время.
Пример кода:
add_action('plugins_loaded', 'init_validate_user_filters');
function init_validate_user_filters(){
add_filter('wp_handle_upload_prefilter', 'validate_user_storage_space', 1);
add_filter('wp_handle_sideload_prefilter', 'validate_user_storage_space', 1);
}
function validate_user_storage_space( $file ) {
// Ваш код обработки загрузки файлов
}
Заключение
Внедрение функции через plugins_loaded
/hooks, которые гарантируют, что она выполняется после загрузки всех плагинов, помогает устранить проблему с несвоевременной активацией хука. Это не только решает вашу текущую задачу, но и является хорошей практикой в разработке WordPress, способствующей расширяемости и поддерживаемости вашего кода.