wp_insert_post() WP 1.0.0

Безпечно вставляє/оновлює запис у базі даних.

Функція очищає дані, що передаються; робить деякі перевірки; заповнює пропущені змінні (наприклад, якщо не передати дату посту, то дату буде отримано автоматично).

Чекає на екрановані дані. Це означає, якщо функцію передаються не POST дані, то перед відправкою потрібно обробити масив даних функцією wp_slash()

ВАЖЛИВО! Вказати 'post_author' => user_id, якщо код викликається не під користувача, наприклад, через CRON, REST і т.д. За замовчуванням туди вставляється ВД поточного користувача, і якщо поточного користувача немає, отримаємо 0 і купу багів.

Майте на увазі, що функції спрацьовують різні хуки, наприклад wp_insert_post . У колбеках цих хуків можуть бути використані $_POST/$_GET дані, але вони можуть бути відсутніми у фронті. Тому можуть бути помилки, коли функція використовується у фронті – шукайте помилки у функціях хуків.

Що конкретно розуміється під записами, читайте у статті: Записи в WordPress

Категорії

Категорії потрібно передавати у вигляді масиву чисел, що збігаються з ID категорій у базі даних. Це стосується і випадку, коли передається одна категорія.

Також дивіться: wp_set_post_terms()

Безпека (очищення заголовка посту)

Функція обробляє передані дані за допомогою функції sanitize_post() – вона перевіряє та очищує значення всіх полів. Тому можна не турбуватися про очищення даних, що передаються.

Однак, можливо, вам потрібно буде видалити HTML теги та інші нестандартні символи із заголовка запису. WordPress не робить це автоматично для заголовка. Це можна зробити, використовуючи sanitize_text_field() , особливо це актуально, коли пости можна публікувати з фронт-енду:

// Створюємо масив даних нового запису
$post_data = array(
	'post_title' => sanitize_text_field( $_POST['post_title'] ),
	'post_content' => $_POST['post_content'],
	'post_status' => 'publish',
	'post_author' => 1,
	'post_category' => array( 8,39 )
);

// Вставляємо запис до бази даних
$post_id = wp_insert_post($post_data);
emoji нотатка

C версії 4.2, із запровадженням смайликів эмодзи. Функція автоматично конвертує символи-смайликів у полях ‘post_title’, ‘post_content’, ‘post_excerpt’, якщо кодування таблиці utf8, а не utf8mb4. До цих полів застосовується функція wp_encode_emoji() .

Повертає

int|WP_Error.

  • ID запису – якщо вдалося вставити запис.
  • 0 – якщо параметр $wp_error вимкнений і є помилка під час вставки.
  • WP_Error об’єкт – якщо увімкнено параметр $wp_error і є помилка при вставці.

Шаблон використання

// вставляємо запис до бази даних
$post_id = wp_insert_post( wp_slash( array(
	'post_title' => 'POST TITLE',
	'post_content' => 'POST CONTENT',
	'post_name' => 'post_slug',
	'post_status' => 'draft',
	'post_type' => 'post',
	'post_author' => $user_ID,
	'ping_status' => get_option('default_ping_status'),
	'post_parent' => 0,
	'menu_order' => 0,
	'to_ping' => '',
	'pinged' => '',
	'post_password' => '',
	'post_excerpt' => '',
	'meta_input' => [ 'meta_key'=>'meta_value' ],
))));

Використання

$post_id = wp_insert_post( $postarr, $wp_error, $fire_after_hooks );
$postarr
(масив) (обов’язковий)

Масив даних, які потрібно вставити до Бази даних. Ключі масиву в точності рівні полям таблиці wp_posts, значення ключів, що передаються, будуть вставлені в значення полів таблиці.

Якщо передати параметр ID, то буде відредаговано вже існуючий запис із таким самим ID, тобто. при вказівці параметра ID ми оновлюємо запис, а не створюємо новий.

Параметри масиву, що передається:

$post = array(
	'ID' => <post id>, // Ви оновлюєте пост?
	'menu_order' => <order>, // Якщо запис "постійна сторінка", встановіть його порядок у меню.
	'comment_status' => 'closed' | 'open', // 'closed' означає, що коментарі закриті.
	'ping_status' => 'closed' | 'open', // 'closed' означає, що пінги та повідомлення вимкнені.
	'pinged' =>?, //?
	'post_author' => <user ID>, // ID автора запису
	'post_content' => <the text of the post>, // Повний текст запису.
	'post_date' => Ymd H:i:s, // Час, коли запис було створено.
	'post_date_gmt' => Ymd H:i:s, // Час, коли запис було створено GMT.
	'post_excerpt' => <an excerpt>, // Цитата (пояснювальний текст) запису.
	'post_name' => <the name>, // Альтернативна назва запису (slug) буде використана в УРЛі.
	'post_parent' => <post ID>, // ID батьківського запису, якщо потрібно.
	'post_password' => ?, // Пароль для перегляду запису.
	'post_status' => 'draft' | 'publish' | 'pending' | 'future' | 'private', // Статус створюваного запису.
	'post_title' => <the title>, // Заголовок (назва) запису.
	'post_type' => 'post' | 'page' | 'link' | 'nav_menu_item' | custom post type // Тип запису.
	'post_category' => array( <category id>, <...> ), // Категорія до якої належить пост (вказуємо ярлики, імена або ID).
	'tags_input' => array(<tag>, <tag>, <...>), // Мітки посту (вказуємо ярлики, імена або ID).
	'tax_input' => array( 'taxonomy_name' => array( 'term', 'term2', 'term3' ) ) // До яких таксів прикріпити запис (вказуємо ярлики, імена або ID).
	'to_ping' => ?, //?
	'meta_input' => [ 'meta_key'=>'meta_value' ], // додасть зазначені мета поля. За замовчуванням: ''. з версії 4.4.
);

Примітка: поле таблиці page_templateбуло видалено, тепер шаблон для постійної сторінки задається в метаполі _wp_page_template– там зберігається назва php файлу шаблону.

Примітка: якщо статус посту вказується як future, то обов’язково потрібно вказати дату посту post_dateщоб WordPress знав коли опублікувати запис.

Примітка: якщо користувач не має права працювати з таксономіями, то вказувати параметр tax_inputнемає сенсу — прикріпити запис до терміну все одно не вийде. Це можна зробити через функцію wp_set_object_terms() .

$wp_error
(логічний)
Встановіть у true, щоб функція повернула
об’єкт WP_Error при помилці.


Типово: false
$fire_after_hooks
(логічний) (WP 5.6)
Чи потрібно запускати функцію
wp_after_insert_post() , яка запускає хуки наприкінці роботи функції.


Типово: true

Приклади

У масиві даних, який передається функції, як мінімум потрібно вказати заголовок і текст запису (ключі масиву: post_title і post_content ) інакше запис не буде створено. Значення для інших важливих, але не зазначених полів, будуть автоматично згенеровані, наприклад поля post_date , post_author .

0

#1 Вставимо запис та перевіримо помилки

$post_id = wp_insert_post( $POST['post_data'], true);

if( is_wp_error($post_id) ){
	echo $post_id->get_error_message();
}
else {
	// тепер можна використовувати $post_id, щоб наприклад додати
	// довільні поля запису за допомогою add_post_meta() або update_post_meta()
}
0

#2 Простий приклад вставки нового запису в базу даних WordPress:

// Створюємо масив
$post_data = array(
	'post_title' => 'Заголовок запису',
	'post_content' => 'Тут має бути контент (текст) запису.',
	'post_status' => 'publish',
	'post_author' => 1,
	'post_category' => array(8,39)
);

// Вставляємо дані до БД
$post_id = wp_insert_post(wp_slash($post_data));

Категорії потрібно передавати у масиві, навіть якщо вказується одна категорія. Наприклад:'post_category' => array(8)

Дивіться також wp_set_post_terms() , коли потрібно встановити довільні таксономії для посту або типу запису.

0

#3 Вставка посту з таксономією та метаданими посту

$post_arr = array(
	'post_title' => 'Test post',
	'post_content' => 'Test post content',
	'post_status' => 'publish',
	'post_author' => get_current_user_id(),
	'tax_input' => array(
		'hierarchical_tax' => array( 13, 10 ),
		'non_hierarchical_tax' => 'tax name 1, tax name 2',
	),
	'meta_input' => array(
		'test_meta_key' => 'value of test_meta_key',
	),
);

нотатки

  • Використовує:wp_transition_post_status()
  • Використовує:_wp_put_post_revision()
  • Використовує: $user_ID
  • Використовує: $wpdb
  • Використовує: $wp_rewrite

  • Використовує: do_action() – edit_post, якщо виконується оновлення запису. Надсилаються ID та Дані.

  • Використовує: do_action() – save_postта wp_insert_post. Надсилаються ID та Дані.

  • Використовує: apply_filters() – wp_insert_post_dataпередає $data, $postarr для оновлення/вставки даних у БД.

нотатки

  • Дивіться: sanitize_post()
  • Global. wpdb. $wpdb WordPress database abstraction object.

список змін

З версії 1.0.0Введено.
З версії 2.6.0Added $wp_error parameter to allow a WP_Error для того, щоб відновити на failure.
З версії 4.2.0Support був added for encoding emoji в post title, content, and excerpt.
З версії 4.4.0A ‘meta_input’ array може бути passed до $postarr до add post meta data.
З версії 5.6.0Added the $fire_after_hooks parameter.

Код wp_insert_post() WP 6.0.2

function wp_insert_post( $postarr, $wp_error = false, $fire_after_hooks = true ) {
	Global $wpdb;

	// Capture original pre-sanitized array for passing in filters.
	$unsanitized_postarr = $postarr;

	$user_id = get_current_user_id();

	$defaults = array(
		'post_author' => $user_id,
		'post_content' => '',
		'post_content_filtered' => '',
		'post_title' => '',
		'post_excerpt' => '',
		'post_status' => 'draft',
		'post_type' => 'post',
		'comment_status' => '',
		'ping_status' => '',
		'post_password' => '',
		'to_ping' => '',
		'pinged' => '',
		'post_parent' => 0,
		'menu_order' => 0,
		'guid' => '',
		'import_id' => 0,
		'context' => '',
		'post_date' => '',
		'post_date_gmt' => '',
	);

	$postarr = wp_parse_args($postarr, $defaults);

	unset($postarr['filter']);

	$postarr = sanitize_post($postarr, 'db');

	// Are we updating or creating?
	$post_ID = 0;
	$update = false;
	$guid = $postarr['guid'];

	if ( ! empty( $postarr['ID'] ) ) {
		$update = true;

		// Get the post ID and GUID.
		$post_ID = $postarr['ID'];
		$post_before = get_post($post_ID);

		if ( is_null( $post_before ) ) {
			if ( $wp_error ) {
				return new WP_Error( 'invalid_post', __( 'Invalid post ID.' ) );
			}
			return 0;
		}

		$guid = get_post_field( 'guid', $post_ID );
		$previous_status = get_post_field( 'post_status', $post_ID );
	} else {
		$previous_status = 'new';
		$post_before = null;
	}

	$post_type = empty( $postarr['post_type'] ) ? 'post': $postarr['post_type'];

	$post_title = $postarr['post_title'];
	$post_content = $postarr['post_content'];
	$post_excerpt = $postarr['post_excerpt'];

	if ( isset( $postarr['post_name'] ) ) {
		$post_name = $postarr['post_name'];
	} elseif ($ update) {
		// Для update, не можна змінити post_name, якщо це не було виявлено як argument.
		$post_name = $post_before->post_name;
	}

	$maybe_empty = 'attachment' !== $post_type
		&&! $post_content && ! $post_title &&! $post_excerpt
		&& post_type_supports( $post_type, 'editor' )
		&& post_type_supports( $post_type, 'title' )
		&& post_type_supports( $post_type, 'excerpt');

	/**
	 * Filters whether the post should бути визнані "empty".
	 *
	 * The post is considered "empty" if both:
	 * 1. The post type supports the title, editor, and excerpt fields
	 * 2. The title, editor, і excerpt fields є all empty
	 *
	 * Returning a truthy value from the filter will effectively short-circuit
	 * New post being inserted and return 0. Якщо $wp_error is true, a WP_Error
	 * will be returned instead.
	 *
	 * @ Since 3.3.0
	 *
	 * @param bool $maybe_empty Whether the post should be considered "empty".
	 * @param array $postarr Array of post data.
	 */
	if ( apply_filters( 'wp_insert_post_empty_content', $maybe_empty, $postarr ) ) {
		if ( $wp_error ) {
			return new WP_Error( 'empty_content', __( 'Content, title, and excerpt are empty.' ) );
		} else {
			return 0;
		}
	}

	$post_status = empty( $postarr['post_status'] ) ? 'draft' : $postarr['post_status'];

	if ( 'attachment' === $post_type && ! in_array( $post_status, array( 'inherit', 'private', 'trash', 'auto-draft' ), true ) ) {
		$post_status = 'inherit';
	}

	if ( ! empty( $postarr['post_category'] ) ) {
		// Filter out empty terms.
		$post_category = array_filter( $postarr['post_category'] );
	}

	// Make sure we set a valid category.
	if ( empty( $post_category ) || 0 === count( $post_category ) || ! is_array( $post_category ) ) {
		// 'post' requires at least one category.
		if ( 'post' === $post_type && 'auto-draft' !== $post_status ) {
			$post_category = array( get_option( 'default_category' ) );
		} else {
			$post_category = array();
		}
	}

	/*
	 * Не дозволені contributors до набору post slug for pending review posts.
	 *
	 * Для нових posts check the primitive capability, for updates check the meta capability.
	 */
	$post_type_object = get_post_type_object( $post_type );

	if ( ! $update && 'pending' === $post_status && ! current_user_can( $post_type_object->cap->publish_posts ) ) {
		$post_name = '';
	} elseif ( $update && 'pending' === $post_status && ! current_user_can( 'publish_post', $post_ID ) ) {
		$post_name = '';
	}

	/*
	 * Create a valid post name. Drafts and pending posts allowed to have
	 * an empty post name.
	 */
	if (empty($post_name)) {
		if ( ! in_array( $post_status, array( 'draft', 'pending', 'auto-draft' ), true ) ) {
			$post_name = sanitize_title($post_title);
		} else {
			$post_name = '';
		}
	} else {
		// On updates, we need to check to see if it's using the old, fixed sanitization context.
		$check_name = sanitize_title( $post_name, '', 'old-save');

		if ( $update && strtolower( urlencode( $post_name ) ) == $check_name && get_post_field( 'post_name', $post_ID ) == $check_name ) {
			$post_name = $check_name;
		} else { // New post, або slug has changed.
			$post_name = sanitize_title($post_name);
		}
	}

	/*
	 * Resolve the post date from any provided post date or post date GMT strings;
	 * якщо не буде передбачено, час буде вибрано.
	 */
	$post_date = wp_resolve_post_date( $postarr['post_date'], $postarr['post_date_gmt'] );
	if (! $post_date) {
		if ( $wp_error ) {
			return new WP_Error( 'invalid_date', __( 'Invalid date.' ) );
		} else {
			return 0;
		}
	}

	if ( empty( $postarr['post_date_gmt'] ) || '0000-00-00 00:00:00' === $postarr['post_date_gmt'] ) {
		if ( ! in_array( $post_status, get_post_stati( array( 'date_floating' => true ) ), true ) ) {
			$post_date_gmt = get_gmt_from_date($post_date);
		} else {
			$post_date_gmt = '0000-00-00 00:00:00';
		}
	} else {
		$post_date_gmt = $postarr['post_date_gmt'];
	}

	if ( $update || '0000-00-00 00:00:00' === $post_date ) {
		$post_modified = current_time( 'mysql');
		$post_modified_gmt = current_time( 'mysql', 1);
	} else {
		$post_modified = $post_date;
		$post_modified_gmt = $post_date_gmt;
	}

	if ( 'attachment' !== $post_type ) {
		$now = gmdate( 'Ymd H:i:s');

		if ( 'publish' === $post_status ) {
			if ( strtotime( $post_date_gmt ) - strtotime( $now ) >= MINUTE_IN_SECONDS ) {
				$post_status = 'future';
			}
		} elseif ( 'future' === $post_status ) {
			if ( strtotime( $post_date_gmt ) - strtotime( $now ) < MINUTE_IN_SECONDS ) {
				$post_status = 'publish';
			}
		}
	}

	// Comment status.
	if ( empty( $postarr['comment_status'] ) ) {
		if ($update) {
			$comment_status = 'closed';
		} else {
			$ comment_status = get_default_comment_status ($ post_type);
		}
	} else {
		$comment_status = $postarr['comment_status'];
	}

	// Ці variables needed by compact() later.
	$post_content_filtered = $postarr['post_content_filtered'];
	$post_author = isset( $postarr['post_author'] ) ? $postarr['post_author'] : $user_id;
	$ping_status = empty($postarr['ping_status'])? get_default_comment_status( $post_type, 'pingback' ) : $postarr['ping_status'];
	$to_ping = isset($postarr['to_ping'])? sanitize_trackback_urls( $postarr['to_ping'] ) : '';
	$pinged = isset($postarr['pinged'])? $postarr['pinged'] : '';
	$import_id = isset($postarr['import_id'])? $postarr['import_id'] : 0;

	/*
	 * The 'wp_insert_post_parent' filter expects all variables to be present.
	 * Перш за все, ці вариації повинні бутиутворені, щоб бути extracted
	 */
	if ( isset( $postarr['menu_order'] ) ) {
		$menu_order = (int) $postarr['menu_order'];
	} else {
		$menu_order = 0;
	}

	$post_password = isset($postarr['post_password'])? $postarr['post_password'] : '';
	if ( 'private' === $post_status ) {
		$post_password = '';
	}

	if ( isset( $postarr['post_parent'] ) ) {
		$post_parent = (int) $postarr['post_parent'];
	} else {
		$post_parent = 0;
	}

	$new_postarr = array_merge(
		array(
			'ID' => $post_ID,
		),
		compact( array_diff( array_keys( $defaults ), array( 'context', 'filter' ) ) ))
	);

	/**
	 * Filters the post parent -- використовували для перевірки і керування hierarchy loops.
	 *
	 * @ Since 3.1.0
	 *
	 * @param int $post_parent Post parent ID.
	 * @param int $post_ID Post ID.
	 * @param array $new_postarr Array of parsed post data.
	 * @param array $postarr Array of sanitized, але іншіwise unmodified post data.
	 */
	$post_parent = apply_filters( 'wp_insert_post_parent', $post_parent, $post_ID, $new_postarr, $postarr);

	/*
	 * Якщо починається бути неперетравленим і він має захищений slug stored in post meta,
	 * Reassign it.
	 */
	if ( 'trash' === $previous_status && 'trash' !== $post_status ) {
		$desired_post_slug = get_post_meta( $post_ID, '_wp_desired_post_slug', true );

		if ( $desired_post_slug ) {
			delete_post_meta( $post_ID, '_wp_desired_post_slug' );
			$post_name = $desired_post_slug;
		}
	}

	// If a trashed post has desired slug, змінювати його і літ це повідомлення має бути.
	if ( 'trash' !== $post_status && $post_name ) {
		/**
		 * Filters whether or not to add a `__trashed` suffix to trashed posts, що дотримуються name of the updated post.
		 *
		 * @ Since 5.4.0
		 *
		 * @param bool $add_trashed_suffix Whether to attempt to add the suffix.
		 * @param string $post_name Назву електронної пошти post being updated.
		 * @param int $post_ID Post ID.
		 */
		$add_trashed_suffix = apply_filters( 'add_trashed_suffix_to_trashed_posts', true, $post_name, $post_ID );

		if ( $add_trashed_suffix ) {
			wp_add_trashed_suffix_to_post_name_for_trashed_posts( $post_name, $post_ID );
		}
	}

	// Якщо він постачає існуюче повідомлення, змінює його засобом для того, щоб запобігти неперетрашенню повідомлень для використання його.
	if ( 'trash' === $post_status && 'trash' !== $previous_status && 'new' !== $previous_status ) {
		$post_name = wp_add_trashed_suffix_to_post_name_for_post( $post_ID );
	}

	$post_name = wp_unique_post_slug( $post_name, $post_ID, $post_status, $post_type, $post_parent );

	// Don't unslash.
	$post_mime_type = isset( $postarr['post_mime_type'] ) ? $postarr['post_mime_type'] : '';

	// Expected_slashed (everything!).
	$data = compact( 'post_author', 'post_date', 'post_date_gmt', 'post_content', 'post_content_filtered', 'post_title', 'post_excerpt', 'post_status', 'post_type', 'comment_status', 'ping post_password', 'post_name', 'to_ping', 'pinged', 'post_modified', 'post_modified_gmt', 'post_parent', 'menu_order', 'post_mime_type', 'guid' );

	$emoji_fields = array( 'post_title', 'post_content', 'post_excerpt');

	foreach ( $emoji_fields as $emoji_field ) {
		if ( isset ( $ data [ $ emoji_field ) ) ) {
			$charset = $wpdb->get_col_charset( $wpdb->posts, $emoji_field );

			if ( 'utf8' === $charset ) {
				$ data [ $ emoji_field ] = wp_encode_emoji ( $ data [ $ emoji_field ] );
			}
		}
	}

	if ( 'attachment' === $post_type ) {
		/**
		 * Filters attachment post data before it is updated in or added to the database.
		 *
		 * @ Since 3.9.0
		 * @since 5.4.1 The `$unsanitized_postarr` parameter was added.
		 * @since 6.0.0 The `$update` parameter was added.
		 *
		 * @param array $data На array of slashed, sanitized, і procesed attachment post data.
		 * @param array $postarr На array of slashed and sanitized attachment post data, але не processed.
		 * @param array $unsanitized_postarr На array of slashed yet *unsanitized* and unprocessed attachment post data
		 * як originally passed to wp_insert_post().
		 * @param bool $update Wether this is existing attachment post being updated.
		 */
		$data = apply_filters( 'wp_insert_attachment_data', $data, $postarr, $unsanitized_postarr, $update);
	} else {
		/**
		 * Filters slashed post data just before it is inserted into database.
		 *
		 * @ Since 2.7.0
		 * @since 5.4.1 The `$unsanitized_postarr` parameter was added.
		 * @since 6.0.0 The `$update` parameter was added.
		 *
		 * @param array $data На array of slashed, sanitized, і processed post data.
		 * @param array $postarr На array of sanitized (and slashed) але іншіwise unmodified post data.
		 * @param array $unsanitized_postarr На array of slashed yet *unsanitized* and unprocessed post data as
		 * Оригінально passed to wp_insert_post().
		 * @param bool $update Whether this is existing post being updated.
		 */
		$data = apply_filters( 'wp_insert_post_data', $data, $postarr, $unsanitized_postarr, $update);
	}

	$ data = wp_unslash ($ data);
	$where = array( 'ID' => $post_ID );

	if ($update) {
		/**
		 * Fires immediately before an existing post is updated in the database.
		 *
		 * @ Since 2.5.0
		 *
		 * @param int $post_ID Post ID.
		 * @param array $data Array of unslashed post data.
		 */
		do_action( 'pre_post_update', $post_ID, $data );

		if ( false === $wpdb->update( $wpdb->posts, $data, $where ) ) {
			if ( $wp_error ) {
				if ( 'attachment' === $post_type ) {
					$message = __( 'Could not update attachment in the database.' );
				} else {
					$message = __( 'Could not update post in the database.' );
				}

				return new WP_Error( 'db_update_error', $message, $wpdb->last_error );
			} else {
				return 0;
			}
		}
	} else {
		// If there is a suggested ID, use it if not already present.
		if ( ! empty( $import_id ) ) {
			$import_id = (int) $import_id;

			if ( ! $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE ID = %d", $import_id ) ) ) {
				$data['ID'] = $import_id;
			}
		}

		if ( false === $wpdb->insert( $wpdb->posts, $data ) ) {
			if ( $wp_error ) {
				if ( 'attachment' === $post_type ) {
					$message = __( 'Could not insert attachment into database.' );
				} else {
					$message = __( 'Could not insert post into the database.' );
				}

				return new WP_Error( 'db_insert_error', $message, $wpdb->last_error );
			} else {
				return 0;
			}
		}

		$post_ID = (int) $wpdb->insert_id;

		// Use the newly generated $post_ID.
		$where = array( 'ID' => $post_ID );
	}

	if ( empty( $data['post_name'] ) && ! in_array( $data['post_status'], array( 'draft', 'pending', 'auto-draft' ), true ) ) {
		$data['post_name'] = wp_unique_post_slug( sanitize_title( $data['post_title'], $post_ID ), $post_ID, $data['post_status'], $post_type, $post_parent );

		$wpdb->update( $wpdb->posts, array( 'post_name' => $data['post_name'] ), $where );
		clean_post_cache( $post_ID );
	}

	if ( is_object_in_taxonomy( $post_type, 'category' ) ) {
		wp_set_post_categories( $post_ID, $post_category );
	}

	if ( isset( $postarr['tags_input'] ) && is_object_in_taxonomy( $post_type, 'post_tag' ) ) {
		wp_set_post_tags($post_ID, $postarr['tags_input']);
	}

	// Add default term for all associated custom taxonomies.
	if ( 'auto-draft' !== $post_status ) {
		foreach ( get_object_taxonomies( $post_type, 'object' ) as $taxonomy => $tax_object ) {

			if ( ! empty( $tax_object->default_term ) ) {

				// Filter out empty terms.
				if ( isset( $postarr['tax_input'][ $taxonomy ] ) && is_array( $postarr['tax_input'][ $taxonomy ] ) ) {
					$postarr['tax_input'][ $taxonomy ] = array_filter( $postarr['tax_input'][ $taxonomy ] );
				}

				// Відомий custom taxonomy list overwrites existing list if not empty.
				$terms = wp_get_object_terms( $post_ID, $taxonomy, array( 'fields' => 'ids' ) );
				if ( ! empty( $terms ) && empty( $postarr['tax_input'][ $taxonomy ] ) ) {
					$postarr['tax_input'][ $taxonomy ] = $terms;
				}

				if ( empty( $postarr['tax_input'][ $taxonomy ] ) ) {
					$default_term_id = get_option( 'default_term_' . $taxonomy );
					if ( ! empty( $default_term_id ) ) {
						$postarr['tax_input'][ $taxonomy ] = array( (int) $default_term_id );
					}
				}
			}
		}
	}

	// New-style support for all custom taxonomies.
	if ( ! empty( $postarr['tax_input'] ) ) {
		foreach ( $postarr['tax_input'] as $taxonomy => $tags ) {
			$taxonomy_obj = get_taxonomy( $taxonomy );

			if ( ! $taxonomy_obj ) {
				/* translators: %s: Taxonomy name. */
				_doing_it_wrong( __FUNCTION__, sprintf( __( 'Invalid taxonomy: %s.' ), $taxonomy ), '4.4.0' );
				continue;
			}

			// array = hierarchical, string = non-hierarchical.
			if ( is_array( $tags ) ) {
				$ tags = array_filter ($ tags);
			}

			if ( current_user_can( $taxonomy_obj->cap->assign_terms ) ) {
				wp_set_post_terms( $post_ID, $tags, $taxonomy );
			}
		}
	}

	if ( ! empty( $postarr['meta_input'] ) ) {
		foreach ( $postarr['meta_input'] as $field => $value ) {
			update_post_meta( $post_ID, $field, $value );
		}
	}

	$current_guid = get_post_field( 'guid', $post_ID );

	// Set GUID.
	if ( ! $update && '' === $current_guid ) {
		$wpdb->update( $wpdb->posts, array( 'guid' => get_permalink( $post_ID ) ), $where );
	}

	if ( 'attachment' === $postarr['post_type'] ) {
		if ( ! empty( $postarr['file'] ) ) {
			update_attached_file($post_ID, $postarr['file']);
		}

		if ( ! empty( $postarr['context'] ) ) {
			add_post_meta( $post_ID, '_wp_attachment_context', $postarr['context'], true );
		}
	}

	// Set or remove featured image.
	if ( isset( $postarr['_thumbnail_id'] ) ) {
		$thumbnail_support = current_theme_supports( 'post-thumbnails', $post_type ) && post_type_supports( $post_type, 'thumbnail' ) || 'revision' === $post_type;

		if ( ! $thumbnail_support && 'attachment' === $post_type && $post_mime_type ) {
			if ( wp_attachment_is( 'audio', $post_ID ) ) {
				$thumbnail_support = post_type_supports( 'attachment:audio', 'thumbnail' ) || current_theme_supports( 'post-thumbnails', 'attachment:audio');
			} elseif ( wp_attachment_is( 'video', $post_ID ) ) {
				$thumbnail_support = post_type_supports( 'attachment:video', 'thumbnail' ) || current_theme_supports( 'post-thumbnails', 'attachment:video');
			}
		}

		if ( $thumbnail_support ) {
			$thumbnail_id = (int) $postarr['_thumbnail_id'];
			if ( -1 === $thumbnail_id ) {
				delete_post_thumbnail( $post_ID );
			} else {
				set_post_thumbnail($post_ID, $thumbnail_id);
			}
		}
	}

	clean_post_cache( $post_ID );

	$post = get_post($post_ID);

	if ( ! empty( $postarr['page_template'] ) ) {
		$post->page_template = $postarr['page_template'];
		$page_templates = wp_get_theme()->get_page_templates( $post );

		if ( 'default' !== $postarr['page_template'] && ! isset( $page_templates[ $postarr['page_template'] ] ) ) {
			if ( $wp_error ) {
				return new WP_Error( 'invalid_page_template', __( 'Invalid page template.' ) );
			}

			update_post_meta( $post_ID, '_wp_page_template', 'default' );
		} else {
			update_post_meta( $post_ID, '_wp_page_template', $postarr['page_template'] );
		}
	}

	if ( 'attachment' !== $postarr['post_type'] ) {
		wp_transition_post_status($ data['post_status'], $previous_status, $post);
	} else {
		if ($update) {
			/**
			 * Fires once an existing attachment has been updated.
			 *
			 * @ Since 2.0.0
			 *
			 * @param int $post_ID Attachment ID.
			 */
			do_action( 'edit_attachment', $post_ID );

			$post_after = get_post($post_ID);

			/**
			 * Fires once an existing attachment has been updated.
			 *
			 * @ Since 4.4.0
			 *
			 * @param int $post_ID Post ID.
			 * @param WP_Post $post_after Post об'єкт слідує за оновленням.
			 * @param WP_Post $post_before Post object before the update.
			 */
			do_action( 'attachment_updated', $post_ID, $post_after, $post_before);
		} else {

			/**
			 * Fires once an attachment has been added.
			 *
			 * @ Since 2.0.0
			 *
			 * @param int $post_ID Attachment ID.
			 */
			do_action( 'add_attachment', $post_ID );
		}

		return $post_ID;
	}

	if ($update) {
		/**
		 * Fires once an existing post has been updated.
		 *
		 * The dynamic portion of hook name, `$post->post_type`, refers to
		 * the post type slug.
		 *
		 * Possible hook names include:
		 *
		 * - `edit_post_post`
		 * - `edit_post_page`
		 *
		 * @ Since 5.1.0
		 *
		 * @param int $post_ID Post ID.
		 * @param WP_Post $post Post об'єкт.
		 */
		do_action( "edit_post_{$post->post_type}", $post_ID, $post);

		/**
		 * Fires once an existing post has been updated.
		 *
		 * @ Since 1.2.0
		 *
		 * @param int $post_ID Post ID.
		 * @param WP_Post $post Post об'єкт.
		 */
		do_action( 'edit_post', $post_ID, $post );

		$post_after = get_post($post_ID);

		/**
		 * Fires once an existing post has been updated.
		 *
		 * @ Since 3.0.0
		 *
		 * @param int $post_ID Post ID.
		 * @param WP_Post $post_after Post об'єкт слідує за оновленням.
		 * @param WP_Post $post_before Post object before the update.
		 */
		do_action( 'post_updated', $post_ID, $post_after, $post_before);
	}

	/**
	 * Fires once a post has been saved.
	 *
	 * The dynamic portion of hook name, `$post->post_type`, refers to
	 * the post type slug.
	 *
	 * Possible hook names include:
	 *
	 * - `save_post_post`
	 * - `save_post_page`
	 *
	 * @ Since 3.7.0
	 *
	 * @param int $post_ID Post ID.
	 * @param WP_Post $post Post об'єкт.
	 * @param bool $update Whether this is existing post being updated.
	 */
	do_action( "save_post_{$post->post_type}", $post_ID, $post, $update);

	/**
	 * Fires once a post has been saved.
	 *
	 * @ Since 1.5.0
	 *
	 * @param int $post_ID Post ID.
	 * @param WP_Post $post Post об'єкт.
	 * @param bool $update Whether this is existing post being updated.
	 */
	do_action( 'save_post', $post_ID, $post, $update);

	/**
	 * Fires once a post has been saved.
	 *
	 * @ Since 2.0.0
	 *
	 * @param int $post_ID Post ID.
	 * @param WP_Post $post Post об'єкт.
	 * @param bool $update Whether this is existing post being updated.
	 */
	do_action( 'wp_insert_post', $post_ID, $post, $update);

	if ( $fire_after_hooks ) {
		wp_after_insert_post( $post, $update, $post_before );
	}

	return $post_ID;
}

Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *