Недавно был пост как добавить свои колонки на страницу с постами в WordPress. Его можно прочитать здесь. А сейчас будет продолжение.
Наша задача сегодня – сделать возможность быстрого редактирования кастомных мета-полей у большого количества постов в WordPress.
Задача будет реализована в 5 этапов:
- 1 этап – создадим кастомные колонки – те, кто это уже сделал раньше, можно смело пропускать.
- 2 этап – добавляем поля в блок быстрого редактирования
- 3 этап – добавляем скрипт в админку
- 4 этап – финал. Сохранение значений
В целом идея написать пост появилась после того, как меня попросили на одном сайте добавить такой функционал.
1 этап – создадим колонки
Сам этап описан вот в этой статье. Дублировать текст не буду и оставлю только код.
add_filter( 'manage_kuhni_posts_columns', 'rb_kuhni_price_columns' );
function rb_kuhni_price_columns( $column_array ) {
$column_array['price'] = 'Цена - Базовая';
$column_array['price_std'] = 'Цена - Стандартная';
$column_array['price_pr'] = 'Цена - Премиум';
return $column_array;
}
add_action( 'manage_posts_custom_column', 'rb_kuhni_price_columns_populate', 10, 2 );
function rb_kuhni_price_columns_populate( $columns, $post_id ) {
switch( $columns ) :
case 'price': {
echo number_format( get_post_meta( $post_id, 'price', true ), 0, '.', ' ');
break;
}
case 'price_std': {
echo number_format( get_post_meta( $post_id, 'price_std', true ), 0, '.', ' ');
break;
}
case 'price_pr': {
echo number_format( get_post_meta( $post_id, 'price_pr', true ), 0, '.', ' ');
break;
}
endswitch;
}Результат этого действия будет такой:

Наша главная задача данного этапа была – добавить наши поля в колонки. Если вам не нужно, чтобы колонки отображались, то вы можете просто отключить их в блоке настройки:

2 этап – добавляем поля в блок быстрого редактирования
add_action('bulk_edit_custom_box', 'rb_quick_edit_fields', 10, 2);
function rb_quick_edit_fields( $column_name, $post_type ) {
if ( 'kuhni' === $post_type ) {
switch( $column_name ) :
case 'price_std': {
wp_nonce_field( 'rb_kuhni_bulk_nonce', 'rb_kuhni_nonce' );
echo '<fieldset class="inline-edit-col-left">
<div class="inline-edit-col">
<div class="inline-edit-group wp-clearfix">
<label class="inline-edit-status alignleft">
<span class="title">Увеличить все цены на</span>
<span class="input-text-wrap"><input type="number" name="price-increase" autocomplete="off" value=""></span>
</label>
</div>
</div>
</fieldset>';
break;
}
case 'price_pr': {
echo '<fieldset class="inline-edit-col-left">
<div class="inline-edit-col">
<div class="inline-edit-group wp-clearfix">
<label class="inline-edit-status alignleft">
<span class="title">Увеличить все цены в процентах</span>
<span class="input-text-wrap"><input type="number" name="price-increase-percent" autocomplete="off" value=""></span>
</label>
</div>
</div>
</fieldset>';
break;
}
endswitch;
}
}Используем хук – bulk_edit_custom_box, но если нам нужно просто добавить в быстрое редактирование 1 поста, то можем использовать ту же функцию, что указана выше, но другой хук – quick_edit_custom_box.
Также я использую функцию wp_nonce_field(), чтобы добавить поле с дополнительной проверкой.
В итоге получаем вот такой результат:

Отлично. У нас появились поля – “Увеличить все цены на” и “Увеличить все цены в процентах”. Но этого пока мало, тк мы пока не добавили функционал позволяющий сохранять значения из этих полей в мета-полях постов.
3 этап – добавляем скрипт в админку
К сожалению, хука с сохранением информации из этих полей я не нашёл, зато нашёл много других способов как можно сохранять информацию, а именно посредством js и конкретно ajax.
Для того, чтобы у нас в админке выводились скрипты или стили – нужно использовать хук – admin_enqueue_scripts, – об этом написано здесь.
add_action( 'admin_enqueue_scripts', 'rb_add_scripts_to_admin' );
function rb_add_scripts_to_admin(){
//подключаем скрипты
wp_enqueue_script( 'admin-script', get_stylesheet_directory_uri() .'/js/admin-bulk.js' );
}Ниже будет приведён код скрипта, который мы подключаем в админке. Сам файл я назвал – admin-bulk.js:
jQuery(function($){
$( 'body' ).on( 'click', 'input[name="bulk_edit"]', function() {
let bulk_edit_row = $( 'tr#bulk-edit' ),
post_ids = new Array(),
priceIncrease = bulk_edit_row.find( 'input[name="price-increase"]' ).val(),
priceIncreasePercent = bulk_edit_row.find( 'input[name="price-increase-percent"]' ).val(),
featured = bulk_edit_row.find( 'input[name="featured"]' ).attr('checked') ? 1 : 0;
bulk_edit_row.find( '#bulk-titles' ).children().each( function() {
post_ids.push( $( this ).attr( 'id' ).replace( /^(ttle)/i, '' ) );
});
//формируем объект с данными, которые будут передаваться
let data = {
action: 'rb_kuhni_save_bulk',
post_ids: post_ids,
price_increase: priceIncrease,
price_increase_percent: priceIncreasePercent,
rb_nonce: $('#rb_kuhni_nonce').val()
};
//передаём данные в обработчик
$.ajax({
url: ajaxurl, // кстати тут повезло, тк в админке есть переменная со ссылкой на родной обработчик WordPress
type: 'POST',
data: data
});
});
});
4 этап – финал. Сохранение значений
Сейчас осталось последнее действие – нам нужно сделать обработчик ajax запроса.
add_action( 'wp_ajax_rb_kuhni_save_bulk', 'rb_save_bulk_edit_hook' );
function rb_save_bulk_edit_hook() {
//тут мы проверяем наш nonce
if ( ! wp_verify_nonce( $_POST['rb_nonce'], 'rb_kuhni_bulk_nonce' ) ) {
die();
}
// проверяем, что передаются id постов, иначе нет смысла что-то делать
if( empty( $_POST[ 'post_ids' ] ) ) {
die();
}
// запускаем цикл для каждого id поста, переданного ранее
foreach( $_POST[ 'post_ids' ] as $curr_post_id ) {
$price_increase = ! empty( $_POST[ 'price_increase' ] ) ? sanitize_text_field( $_POST['price_increase'] ) : '';
$price_increase_percent = ! empty( $_POST[ 'price_increase_percent' ] ) ? sanitize_text_field( $_POST['price_increase_percent'] ) : '';
// Тут мы просто прибавляем к одному значению - другое
if( $price_increase ) {
$final_price = $price_increase + get_post_meta( $curr_post_id, 'price', true );
$final_price_std = $price_increase + get_post_meta( $curr_post_id, 'price_std', true );
$final_price_pr = $price_increase + get_post_meta( $curr_post_id, 'price_pr', true );
update_post_meta( $curr_post_id, 'price', $final_price );
update_post_meta( $curr_post_id, 'price_std', $final_price_std );
update_post_meta( $curr_post_id, 'price_pr', $final_price_pr );
}
// Тут мы увеличиваем текущее число на количество проыентов
if( $price_increase_percent ) {
$final_price = get_post_meta( $curr_post_id, 'price', true ) + ( $price_increase_percent * get_post_meta( $curr_post_id, 'price', true ) / 100 );
$final_price_std = get_post_meta( $curr_post_id, 'price_std', true ) + ( $price_increase_percent * get_post_meta( $curr_post_id, 'price_std', true ) / 100 );
$final_price_pr = get_post_meta( $curr_post_id, 'price_pr', true ) + ( $price_increase_percent * get_post_meta( $curr_post_id, 'price_pr', true ) / 100 );
update_post_meta( $curr_post_id, 'price', $final_price );
update_post_meta( $curr_post_id, 'price_std', $final_price_std );
update_post_meta( $curr_post_id, 'price_pr', $final_price_pr );
}
}
die();
}
Также я использую функцию wp_verify_nonce(), чтобы проверить поле с дополнительной проверкой.
В целом мы тут просто получаем данные из файла admin-bulk.js и увеличиваем данные в мета-полях всех выбранных постов на указанное значение.