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

wp_insert_post_data хук-фильтр . WP 2.7

Фильтрует данные записи, прямо перед тем, как вставить или обновить их в БД через функцию wp_insert_post(). Все данные экранированы слэшами!

На этом этапе данные еще не очищены от экранированных слэшей \, см. wp_unslash().

Этот фильтр удобен, когда перед тем как записать/обновить данные поста их нужно изменить. Например заменить какие-либо строки в контенте, проверить дату, изменить другие поля: post_name, guid...

Использование

add_filter( 'wp_insert_post_data', 'filter_function_name_11', 10, 2 );
function filter_function_name_11( $data, $postarr ) {
	// фильтруем $data ...

	return $data;
}
$data(массив)
Данные поста. Данные содержат экранированные слэши \!
$postarr(массив)
Оригинальные данные поста переданные в wp_insert_post().

Примеры

#1 Удалим \r (возврат каретки) из контента записи

## Удаляет \r (возврат каретки) из контента записи
add_action( 'wp_insert_post_data', 'remove_r_carriage_return', 0 );
function remove_r_carriage_return( $data ){
	$data['post_content'] = str_replace( "\r", '', $data['post_content'] );
	return $data;
}

#2 Изменим данные записи перед обновлением

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

Этот пример показывает как в поле guid всегда записывать постоянную ссылку на запись:

add_action('wp_insert_post_data', 'who_book_save', 20, 2 );
function who_book_save( $data, $postarr ){
	if( ! isset($_POST['post_type']) || $_POST['post_type'] != 'book' ) return $data; // убедимся что мы редактируем нужный тип поста
	if( get_current_screen()->id != 'book' ) return $data; // убедимся что мы на нужной странице админки
	if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE  ) return $data; // пропустим если это автосохранение
	if ( ! current_user_can('edit_post', $postarr['ID'] ) ) return $data; // убедимся что пользователь может редактировать запись

	// Все ОК! обрабатываем
	$data['guid'] = get_permalink( $postarr['ID'] );

	return $data;
}

#3 Запретим сохранение записи со статусом publish

Пусть вы создали свой кастомный тип записи transaction и зарегистрировали свои кастомные статусы поста.

Эти записи не должны иметь статус, отличный от тех, что мы создали. Программно это легко контролируется, но при редактировании такой записи из админки WordPress при сохранении автоматически назначит ей статус publish (опубликовано). Код ниже решает проблему:

add_filter( 'wp_insert_post_data', 'restoring_status_saved_admin_panel' );

/**
 * При сохранении из админки восстанавливает оригинальный статус транзакции,
 * так как WordPress пытается назначить ей статус publish.
 *
 * @param array $data
 *
 * @return array
 */
function restoring_status_saved_admin_panel( $data ) {
	if ( 'transaction' === $data['post_type'] && 'publish' === $data['post_status'] ) {
		$data['post_status'] = sanitize_key( filter_input( INPUT_POST, 'original_post_status' ) );
	}

	return $data;
}

Заметки

В $data по умолчанию передаются следующие поля:

Array
(
	[post_author] => 1
	[post_date] => 2015-07-15 02:44:40
	[post_date_gmt] => 2015-07-14 23:44:40
	[post_content] = контент
	[post_content_filtered] => 
	[post_title] => supermy
	[post_excerpt] => 
	[post_status] => publish
	[post_type] => book
	[comment_status] => closed
	[ping_status] => closed
	[post_password] => 
	[post_name] => supermy__
	[to_ping] => 
	[pinged] => 
	[post_modified] => 2015-07-16 01:10:27
	[post_modified_gmt] => 2015-07-15 22:10:27
	[post_parent] => 0
	[menu_order] => 0
	[post_mime_type] => 
	[guid] => http://example.com/?post_type=book&p=19
)

Поля по умолчанию для параметра $postarr:

'post_status'           - 'draft'.
'post_type'             - 'post'.
'post_author'           - ID текущего пользователя или кто создал запись.
'ping_status'           - значение настройки 'default_ping_status'.
'post_parent'           - 0
'menu_order'            - 0
'to_ping'               - 
'pinged'                - пустая строка
'post_password'         - пустая строка
'guid'                  - уникальный ID
'post_content_filtered' - 
'post_excerpt'          - текст.

А так выглядит $postarr:

Array
(
	[post_status] => publish
	[post_type] => book
	[post_author] => 1
	[ping_status] => closed
	[post_parent] => 0
	[menu_order] => 0
	[to_ping] => 
	[pinged] => 
	[post_password] => 
	[guid] => http://example.com/?post_type=book&p=19
	[post_content_filtered] => 
	[post_excerpt] => 
	[import_id] => 0
	[post_content] = текст
	[post_title] => supermy
	[context] => 
	[ID] => 19
	[post_date] => 2015-07-15 02:44:40
	[post_date_gmt] => 2015-07-14 23:44:40
	[comment_status] => closed
	[post_name] => supermy__
	[post_modified] => 2015-07-16 00:48:42
	[post_modified_gmt] => 2015-07-15 21:48:42
	[post_mime_type] => 
	[comment_count] => 0
	[ancestors] => Array
		(
		)

	[post_category] => Array
		(
		)

	[tags_input] => Array
		(
		)

	[_wpnonce] => e296535396
	[_wp_http_referer] => /wp-admin/post.php?post=19&action=edit
	[user_ID] => 1
	[action] => editpost
	[originalaction] => editpost
	[original_post_status] => publish
	[referredby] => http://example.com/wp-admin/edit.php?post_type=book
	[_wp_original_http_referer] => http://example.com/wp-admin/edit.php?post_type=book
	[post_ID] => 19
	[meta-box-order-nonce] => ea65cc23d4
	[closedpostboxesnonce] => ca65bc8597
	[samplepermalinknonce] => f19941a639
	[hidden_post_status] => publish
	[hidden_post_password] => 
	[hidden_post_visibility] => public
	[visibility] => public
	[mm] => 07
	[jj] => 15
	[aa] => 2015
	[hh] => 02
	[mn] => 44
	[ss] => 40
	[hidden_mm] => 07
	[cur_mm] => 07
	[hidden_jj] => 15
	[cur_jj] => 16
	[hidden_aa] => 2015
	[cur_aa] => 2015
	[hidden_hh] => 02
	[cur_hh] => 00
	[hidden_mn] => 44
	[cur_mn] => 19
	[original_publish] => Обновить
	[save] => Обновить
	[filter] => db
)

Список изменений

С версии 2.7.0 Введена.
С версии 5.4.1 $unsanitized_postarr argument added.

Где вызывается хук

wp_insert_post()
wp_insert_post_data
wp-includes/post.php 3915
$data = apply_filters( 'wp_insert_post_data', $data, $postarr, $unsanitized_postarr );

Где используется хук в ядре WP

wp-admin/includes/ms-admin-filters.php 29
add_filter( 'wp_insert_post_data', 'avoid_blog_page_permalink_collision', 10, 2 );
wp-includes/class-wp-customize-manager.php 2930
add_filter( 'wp_insert_post_data', array( $this, 'preserve_insert_changeset_post_content' ), 5, 3 );
wp-includes/class-wp-customize-manager.php 2961
remove_filter( 'wp_insert_post_data', array( $this, 'preserve_insert_changeset_post_content' ), 5 );
wp-includes/default-filters.php 87
add_filter( 'wp_insert_post_data', '_wp_customize_changeset_filter_insert_post_data', 10, 2 );
2 коммента
  • Иван

    Большое спасибо за статью! Теперь я знаю, как сделать автоматически генерируемые тайтлы из кастомных полей. Не подскажете, как еще автоматически генерировать слаг? Дело в том,что, если не передать заголовок, то wp в слаг ставит id поста, и это совсем не то, чего бы мне хотелось. А эта функция работает на wp_insert_post_data, соответственно, срабатывает каждый раз, когда пост обновляется, что не нужно. Я понимаю, что надо хукать создание поста, но вот как это записать?

    Ответить2.8 года назад #
    • Kama7770

      Проверяй, если слаг это число или его нет, то указывай свой...

      if( is_numeric($data['post_name']) || ! $data['post_name'] )
      	$data['post_name'] = sanitize_title( $data['post_title'] );
      1
      Ответить1.8 года назад #