База данных wordpress, описание, структура, таблицы

Описание и предназначение таблиц базы данных

Работая с базой данных в целях администрирования я использую панель phpMyAdmin. На вашем хостинге или сервере может быть установлено другое программное обеспечение.


Таблица wp_commentmeta

Каждый комментарий, оставленный на сайте, содержит метаданные — эта информация хранится в этой таблице. Например, если установлен плагин Akismet для защиты от спама, то он будет записывать в неё свои данные: одобрен комментарий или нет, имеется ли пометка о спаме.

Таблица wp_comments

Название этой таблицы говорит само за себя — здесь хранятся оставленные к записям комментарии. Именно в этой таблице я переносил комментарий с одной страницы на другую, о чём писал в начале статьи.

Помимо текста комментария в таблице хранится дополнительная информация, включая имя, электронную почту и сайт автора, IP-адрес с которого бы отправлен комментарий, дату, время и многое другое.

Таблица wp_links

Эта таблица раньше хранила ссылки блогролла на Кодекс, wordpress.org и другие ресурсы. На блоге у меня были удалены все ссылки из консоли, поэтому на скриншоте ниже есть надпись «Ссылок не найдено», а таблица пуста.

Теперь эта функция устарела, но при необходимости её можно включить с помощью плагина Links Manager.

Таблица wp_options

Хранит основные настройки WordPress, в том числе параметры, доступные для изменения в консоли администрирования. Кстати, таблица wp_options очень интересна для изучения, но зачастую после установки и последующего удаления плагинов содержит лишние строки. У меня есть отличное руководство по чистке базы данных от «мусора».

Таблица wp_postmeta

Хранит огромное количество данных о записях и страницах сайта: информацию о прикреплённых файлах (изображения, документы, видео), данные заполняемых полей при создании или редактировании записей. Некоторые плагины могут добавлять свою собственную информацию в эту таблицу. Например, плагин All in One SEO Pack хранит здесь Title, Description и Keywords.

Таблица wp_posts

Самое ценное — контент — сосредоточено в таблице wp_posts. В ней хранятся сведения об авторе статьи, дата и время публикации, дата и время последнего изменения, непосредственно тексты, статус записи (опубликовано, черновик, на утверждении) и ещё очень много информации.

Таблица wp_termmeta

Каждый термин (категории, метки и термины пользовательских таксономий) содержит информацию, называемую метаданными, и хранится в этой таблице. Скриншот не прилагаю, так как у меня эта таблица оказалась пустой. Метки и пользовательские таксономии при этом не использую.

Таблица содержит категории, метки и термины пользовательских таксономий.

Таблица wp_term_relationships

Сообщения связаны с категориями и метками из таблицы wp_terms и эта связь здесь поддерживается. Ассоциация ссылок на соответствующие категории также хранится в этой таблице.

Таблица wp_term_taxonomy

В этой таблице описаны таксономии (категории, теги) для записей в таблице wp_terms. Устанавливается очередность и вложенность категорий, которые могут быть родительскими и дочерними, вот таблица wp_term_taxonomy и отслеживает иерархию между ними.

Таблица wp_usermeta

Эта таблица хранит метаданные зарегистрированных пользователей, их персональные настройки и данные профиля, такие как цветовая схема, контактные данные, биография, никнейм и другие.

Таблица wp_users


Таким вот образом организована структура базы данных WordPress, все таблицы взаимосвязаны между собой, содержат сериализированные массивы, поэтому изменение данных вручную может привести к сбою, помните об этом и соблюдайте осторожность при редактировании

Source #Source

File: wp-includes/taxonomy.php

function wp_get_object_terms( $object_ids, $taxonomies, $args = array() ) {
	if ( empty( $object_ids ) || empty( $taxonomies ) ) {
		return array();
	}

	if ( ! is_array( $taxonomies ) ) {
		$taxonomies = array( $taxonomies );
	}

	foreach ( $taxonomies as $taxonomy ) {
		if ( ! taxonomy_exists( $taxonomy ) ) {
			return new WP_Error( 'invalid_taxonomy', __( 'Invalid taxonomy.' ) );
		}
	}

	if ( ! is_array( $object_ids ) ) {
		$object_ids = array( $object_ids );
	}
	$object_ids = array_map( 'intval', $object_ids );

	$args = wp_parse_args( $args );

	/**
	 * Filter arguments for retrieving object terms.
	 *
	 * @since 4.9.0
	 *
	 * @param array    $args       An array of arguments for retrieving terms for the given object(s).
	 *                             See {@see wp_get_object_terms()} for details.
	 * @param int[]    $object_ids Array of object IDs.
	 * @param string[] $taxonomies Array of taxonomy names to retrieve terms from.
	 */
	$args = apply_filters( 'wp_get_object_terms_args', $args, $object_ids, $taxonomies );

	/*
	 * When one or more queried taxonomies is registered with an 'args' array,
	 * those params override the `$args` passed to this function.
	 */
	$terms = array();
	if ( count( $taxonomies ) > 1 ) {
		foreach ( $taxonomies as $index => $taxonomy ) {
			$t = get_taxonomy( $taxonomy );
			if ( isset( $t->args ) && is_array( $t->args ) && array_merge( $args, $t->args ) != $args ) {
				unset( $taxonomies );
				$terms = array_merge( $terms, wp_get_object_terms( $object_ids, $taxonomy, array_merge( $args, $t->args ) ) );
			}
		}
	} else {
		$t = get_taxonomy( $taxonomies );
		if ( isset( $t->args ) && is_array( $t->args ) ) {
			$args = array_merge( $args, $t->args );
		}
	}

	$args   = $taxonomies;
	$args = $object_ids;

	// Taxonomies registered without an 'args' param are handled here.
	if ( ! empty( $taxonomies ) ) {
		$terms_from_remaining_taxonomies = get_terms( $args );

		// Array keys should be preserved for values of $fields that use term_id for keys.
		if ( ! empty( $args ) && 0 === strpos( $args, 'id=>' ) ) {
			$terms = $terms + $terms_from_remaining_taxonomies;
		} else {
			$terms = array_merge( $terms, $terms_from_remaining_taxonomies );
		}
	}

	/**
	 * Filters the terms for a given object or objects.
	 *
	 * @since 4.2.0
	 *
	 * @param array    $terms      Array of terms for the given object or objects.
	 * @param int[]    $object_ids Array of object IDs for which terms were retrieved.
	 * @param string[] $taxonomies Array of taxonomy names from which terms were retrieved.
	 * @param array    $args       Array of arguments for retrieving terms for the given
	 *                             object(s). See wp_get_object_terms() for details.
	 */
	$terms = apply_filters( 'get_object_terms', $terms, $object_ids, $taxonomies, $args );

	$object_ids = implode( ',', $object_ids );
	$taxonomies = "'" . implode( "', '", array_map( 'esc_sql', $taxonomies ) ) . "'";

	/**
	 * Filters the terms for a given object or objects.
	 *
	 * The `$taxonomies` parameter passed to this filter is formatted as a SQL fragment. The
	 * {@see 'get_object_terms'} filter is recommended as an alternative.
	 *
	 * @since 2.8.0
	 *
	 * @param array    $terms      Array of terms for the given object or objects.
	 * @param int[]    $object_ids Array of object IDs for which terms were retrieved.
	 * @param string[] $taxonomies Array of taxonomy names from which terms were retrieved.
	 * @param array    $args       Array of arguments for retrieving terms for the given
	 *                             object(s). See wp_get_object_terms() for details.
	 */
	return apply_filters( 'wp_get_object_terms', $terms, $object_ids, $taxonomies, $args );
}

Changelog

3.3.0

  • New feature: Custom title tag added for external links
  • Bug fix: in SCO_TD_Long_Terms_First_Parser::compare_terms method
  • WP 4.9.5 support

3.1.9

  • New feature: “Convert in custom posts types” options added
  • New feature: shortcodes support added
  • New feature: wptexturize support added
  • New feature: word forms support added to CSV export
  • Bug fix: edit term with post_id link type bug fixed

3.1.5

  • Interface updated in accordance to WP 3.8 requirements
  • New feature: batch terms removal added
  • New feature: nofollow attribute support added
  • New feature: noindex tag support added

3.0.5

  • Additional checks added for external links to prevent self-linking
  • Quotation marks are not included in the links when using the Simple quotes parser

3.0.3

  • New feature: two additional quotes types added to “Simple parser with quotes support”
  • Bug fix: number of post titles in autocomplete list increased

3.0.1

  • New option: wrap links with arbitrary text
  • Bug fix: the plugin now uses default database charset and collation during table creation
  • The plugin version updated according with very old releases

1.2.2

  • New feature: disable plugin for individual post
  • New option: maximum transformations number
  • New option: add title attribute to links
  • Bug fix: “Link to itself” in posts with non-latin URLs

1.2.0

  • Administration interface updated
  • Database structure updated
  • Export / import functions are added
  • Packet terms upload function is added
  • Different parsers support is added
  • Simple parser is added
  • Simple parser with quotes support is added
  • Permalinks update function is added
  • Bug fixes
  • “Convert terms only on single pages” option is added.
  • Custom posts types partial support is added.
  • Bug fix: Convert first “-1” term occurrences means “no limit”.

Custom permalinks structure support added. Now when you change permalinks structure all links will be updated automatically.

Related #Related

Uses

Uses
Uses
wp-includes/taxonomy.php: saved_term
wp-includes/taxonomy.php: saved_{$taxonomy}
wp-includes/taxonomy.php: wp_update_term_data
wp-includes/taxonomy.php: edit_terms
wp-includes/taxonomy.php: edited_terms
wp-includes/l10n.php: __()
wp-includes/formatting.php: wp_slash()
wp-includes/formatting.php: wp_unslash()
wp-includes/formatting.php: sanitize_title()
wp-includes/functions.php: wp_parse_args()
wp-includes/taxonomy.php: clean_term_cache()
wp-includes/taxonomy.php: wp_update_term()
wp-includes/taxonomy.php: wp_unique_term_slug()
wp-includes/taxonomy.php: wp_update_term_parent
wp-includes/taxonomy.php: edit_term_taxonomy
wp-includes/taxonomy.php: edited_term_taxonomy
wp-includes/taxonomy.php: edit_term
wp-includes/taxonomy.php: edit_{$taxonomy}
wp-includes/taxonomy.php: edited_term
wp-includes/taxonomy.php: edited_{$taxonomy}
wp-includes/taxonomy.php: term_id_filter
wp-includes/taxonomy.php: sanitize_term()
wp-includes/taxonomy.php: term_exists()
wp-includes/taxonomy.php: get_term_by()
wp-includes/taxonomy.php: taxonomy_exists()
wp-includes/taxonomy.php: get_term()
wp-includes/plugin.php: apply_filters()
wp-includes/plugin.php: do_action()
wp-includes/wp-db.php: wpdb::get_var()
wp-includes/wp-db.php: wpdb::update()
wp-includes/wp-db.php: wpdb::prepare()
wp-includes/load.php: is_wp_error()
wp-includes/class-wp-error.php: WP_Error::__construct()

Avis

http-equiv=»Content-Type» content=»text/html;charset=UTF-8″>lass=»plugin-reviews»>

All I can do with this pulgin is review the plugin. There is no option for creating legal pages, just an empty page with a review option so here is my review can I please make some legal pages now?

Love this Plugin. So easy to use and customize. Only thing I didn’t like was that it loads in the form of a post rather than a page, but I managed to get around that and am very happy with the outcome.

Will definitely be using this plugin on other websites that I design and will be recommending it.

Big thanks to the creators — You Rock!

saved me a ton of time.

Thanks for the plugin. It’s a basic document and ideal to add in a rush until a detailed doc is arranged. Their pro package may look more professional.

I needed some privacy info for my site and was a little unsure about purchasing a plug in because sometimes what is promised is not what you get.

I am happy with this plug in though. Easy enough to use although it could use some directions to help you.

After I got lucky and clicked on the correct link to get started it was WAY easy and the information/privacy page was super thorough.

If you purchase and I advise you to do so if you need this on your site (and truly…everyone does) gather your information beforehand to make the process easier (facebook business link, company name, do you want/need Euro Specs, etc. It will make your life a little easier.

Again. It is a good purchase and gives you everything you need for a complete privacy/affiliate links page protection.

I installed and created the privacy and terms pages. Thing is, it doesn’t a page in my WP Pages section. I changed my EasyCart to point to the WP AutoTerms «pages» but it could not find them. So where are they? If I don’t get it sorted out, I will be removing the Plugin.

wp term get

Получает сведения о термине.

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

wp term get {taxonomy} {term}    

Можно указать Глобальные параметры и следующие:

Taxonomy of the term to get
ID or slug of the term to get

Explicitly handle the term value as a slug or id. По умолчанию: id Может быть:

  • slug
  • id
Instead of returning the whole term, returns the value of a single field.
Limit the output to specific fields. Defaults to all fields.

Render output in a particular format. По умолчанию: table Может быть:

  • table
  • csv
  • json
  • yaml

Примеры

# Get details about a category with id 199.
$ wp term get category 199 --format=json
{"term_id":199,"name":"Apple","slug":"apple","term_group":0,"term_taxonomy_id":199,"taxonomy":"category","description":"A type of fruit","parent":0,"count":0,"filter":"raw"}
# Get details about a category with slug apple.
$ wp term get category apple --by=slug --format=json
{"term_id":199,"name":"Apple","slug":"apple","term_group":0,"term_taxonomy_id":199,"taxonomy":"category","description":"A type of fruit","parent":0,"count":0,"filter":"raw"}

Описание

База данных WordPress это набор таблиц (в коробочной версии этих таблиц 12 штук). Каждая таблица имеет уникальное название, которое начинается с префикса базы данных. По молчанию префикс БД — wp. На этапе установки, целях безопасности от взлома, префикс wp меняют произвольные 4 буквы-цифры латинского алфавита.

Каждая таблица БД имеет столбцы и строки. Столбец БД называется «поле», строка БД называется «запись», пересечение поля и записи называется «ячейка».

Приложение phpmyadmin позволяет редактировать таблицы БД при помощи визуально понятных кнопок или через язык инъекций, называемый SQL. Для использования языка SQL есть вкладка-кнопка «SQL».


Все операции с базой данных сделанные через кнопки управления, дублируются показом исполняемого запроса SQL к БД.

wp term recount

Пересчитывает количество записей в каждом термине.

In instances where manual updates are made to the terms assigned to posts in the database, the number of posts associated with a term can become out-of-sync with the actual number of posts.

This command runs wp_update_term_count() on the taxonomy’s terms to bring the count back to the correct value.

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

wp term recount {taxonomy}...

Можно указать Глобальные параметры и следующие:

One or more taxonomies to recalculate.

Примеры

# Recount posts assigned to each categories and tags
$ wp term recount category post_tag
Success: Updated category term count.
Success: Updated post_tag term count.
# Recount all listed taxonomies
$ wp taxonomy list --field=name | xargs wp term recount
Success: Updated category term count.
Success: Updated post_tag term count.
Success: Updated nav_menu term count.
Success: Updated link_category term count.
Success: Updated post_format term count.

wp term list

Получает термины таксономии.

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

wp term list {taxonomy}...    

Можно указать Глобальные параметры и следующие:

List terms of one or more taxonomies
Filter by one or more fields (see get_terms() $args parameter for a list of fields).
Prints the value of a single field for each term.
Limit the output to specific object fields.

Render output in a particular format. По умолчанию: table Может быть:

  • table
  • csv
  • ids
  • json
  • count
  • yaml

Доступные поля

These fields will be displayed by default for each term:

  • term_id
  • term_taxonomy_id
  • name
  • slug
  • description
  • parent
  • count

These fields are optionally available:

url

Примеры

# List post categories
$ wp term list category --format=csv
term_id,term_taxonomy_id,name,slug,description,parent,count
2,2,aciform,aciform,,0,1
3,3,antiquarianism,antiquarianism,,0,1
4,4,arrangement,arrangement,,0,1
5,5,asmodeus,asmodeus,,0,1
# List post tags
$ wp term list post_tag --fields=name,slug
+-----------+-------------+
| name      | slug        |
+-----------+-------------+
| 8BIT      | 8bit        |
| alignment | alignment-2 |
| Articles  | articles    |
| aside     | aside       |
+-----------+-------------+

wp term delete

Удаляет существующий термин.

Errors if the term doesn’t exist, or there was a problem in deleting it.

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

wp term delete {taxonomy} {term}... 

Можно указать Глобальные параметры и следующие:

Taxonomy of the term to delete.
One or more IDs or slugs of terms to delete.

Explicitly handle the term value as a slug or id. По умолчанию: id Может быть:

  • slug
  • id

Примеры

# Delete post category by id
$ wp term delete category 15
Deleted category 15.
Success: Deleted 1 of 1 terms.
# Delete post category by slug
$ wp term delete category apple --by=slug
Deleted category 15.
Success: Deleted 1 of 1 terms.
# Delete all post tags
$ wp term list post_tag --field=term_id | xargs wp term delete post_tag
Deleted post_tag 159.
Deleted post_tag 160.
Deleted post_tag 161.
Success: Deleted 3 of 3 terms.

network_get_terms()

This multisite plugin has become more popular than I expected, so I decided to make it even better. One of the first improvements I made was the function similar to — .


The main difference between these two functions is that works only within a single site and in the entire multisite network.

network_get_terms( $network_taxonomies, $network_args )

Parameters

Most parameters of the functions and are the same, but not all. So, I think I should describe them in details.

$network_taxonomies
Taxonomy name or an array of taxonomies, e.g. .
$network_args
An array of additional arguments.
number
The number of terms to get.
offset
The number of elements you want to offset from the beginning of the query. Works only if parameter is also passed.
include, exclude

These parameters accept only local term ID or an array of IDs.

// in this examplle we exclude the categories with ID = 1 or ID = 2 on each network sites
$network_category = network_get_terms('category', array('exclude' => array( 1, 2 ) ) );

If you pass both of these parameters, will be ignored.

parent
Local term ID whose direct children you want the function to return.

It works for all network blogs. For example if you set the value of this parameter equal to 11, and you have the category with ID = 11 on the blog 1 and on the blog 2 too, then the function returns the direct children of these both categories.

If is passed, function returns only top-level terms with no children.

$slug
Returns the terms from the whole network whose slugs match this value. You can also specify the array of slugs.
$name
Returns the terms from the whole network whose names match this value. The array of names is also supported.
$name__like, $description__like
Specify the part of the name or the part of the description (case-insensitive). It uses query in database agains term names or descriptions.
$search
Function will search the given string in term names and slugs all over the network.
orderby
How to order the results, — by the number of posts in terms, (default), , — by term description, — order as in parameter, — by local term ID value.
order
ascending (default) or descending.
fields
How to return the results:
  • — array of objects (default),
  • — array of term names,
  • — array of local IDs.

Filters

The has the same filters, as , but with prefix.

get_terms() network_get_terms()
get_terms_args network_get_terms_args
get_terms network_get_terms
get_terms_orderby network_get_terms_orderby
list_terms_exclusions network_list_terms_exclusions
get_terms_fields network_get_terms_fields
terms_clauses network_terms_clauses

I don’t want to spend time describing each of these filters — you can find and learn them in the plugin code or just ask me in comments.

And now let’s look at the examples (the following code will work only if my plugin is installed on your network).

1. Get Post Tags from all Blogs in WP Multisite

$network_tags = network_get_terms('post_tag', 'orderby=name&hide_empty=0');
 
if( $network_tags ){
	echo '<select>';
	foreach ( $network_tags as $network_tag ){
		echo "<option value='{$network_tag->term_id}'>{$network_tag->name}</option>";
	}
	echo '</select>';
}
/*
in this example is obvious that
$network_tag->name - tag name,
$network_tag->term_id - tag global unique ID across the network
 
the other parameters:
$network_tag->term_local_id - the local tag ID inside the blog, which the tag belong to
$network_tag->parent - local ID of tag parent
$network_tag->taxonomy - taxonomy name, in this case: post_tag
$network_tag->slug
$network_tag->blog_id - ID of the blog, the tag belong to
$network_tag->description
$network_tag->count - the number of tagged posts
*/

You may notice that this example doesn’t describe one important thing. So, we have tag names, tag ids, but we dont’t have tag links.

Don’t worry, for these purposes I created a function — , which is similar to default , but works with WordPress Multisite.

2. Get all Category Links across the WordPress Multisite Network

network_get_term_link( $term, $taxonomy='', $blog_id=null )
$term
You can pass term local ID, or its slug or the whole object (result of function). If you pass the object, you can leave the second and the third parameters empty.
$taxonomy
Taxonomy name.
$blog_id
Blog ID.
$network_categories = network_get_terms('category');
 
if( $network_categories ){
	echo '<ul>';
	foreach ( $network_categories as $network_category ){
		echo '<li><a href="' . network_get_term_link( $network_category ) . '">' . $network_category->name . '</a></li>';
	}
	echo '</ul>';
}

If you have a question, please leave it in comments.

Misha Rudrastyh

I love WordPress, WooCommerce and Gutenberg so much. 11 yrs of experience.

Need some custom developer help? Get in touch

Valores devueltos

(array|string|WP_Error) 
Array of term objects or an empty array if no terms were found. WP_Error if any of $taxonomies does not exist. If the 'fields' argument was 'count', the number of terms found will be returned as a string.

The fields returned are:

  • term_id
  • name
  • slug
  • term_group
  • term_taxonomy_id
  • taxonomy
  • description
  • parent
  • count

Warning: string vs integer confusion! Field values, including term_id are returned in string format. Before further use, typecast numeric values to actual integers, otherwise WordPress will mix up term_ids and slugs which happen to have only numeric characters

Source #Source

File: wp-includes/taxonomy.php

function wp_set_object_terms( $object_id, $terms, $taxonomy, $append = false ) {
	global $wpdb;

	$object_id = (int) $object_id;

	if ( ! taxonomy_exists( $taxonomy ) ) {
		return new WP_Error( 'invalid_taxonomy', __( 'Invalid taxonomy.' ) );
	}

	if ( ! is_array( $terms ) ) {
		$terms = array( $terms );
	}

	if ( ! $append ) {
		$old_tt_ids = wp_get_object_terms(
			$object_id,
			$taxonomy,
			array(
				'fields'                 => 'tt_ids',
				'orderby'                => 'none',
				'update_term_meta_cache' => false,
			)
		);
	} else {
		$old_tt_ids = array();
	}

	$tt_ids     = array();
	$term_ids   = array();
	$new_tt_ids = array();

	foreach ( (array) $terms as $term ) {
		if ( '' === trim( $term ) ) {
			continue;
		}

		$term_info = term_exists( $term, $taxonomy );

		if ( ! $term_info ) {
			// Skip if a non-existent term ID is passed.
			if ( is_int( $term ) ) {
				continue;
			}

			$term_info = wp_insert_term( $term, $taxonomy );
		}

		if ( is_wp_error( $term_info ) ) {
			return $term_info;
		}

		$term_ids[] = $term_info;
		$tt_id      = $term_info;
		$tt_ids[]   = $tt_id;

		if ( $wpdb->get_var( $wpdb->prepare( "SELECT term_taxonomy_id FROM $wpdb->term_relationships WHERE object_id = %d AND term_taxonomy_id = %d", $object_id, $tt_id ) ) ) {
			continue;
		}

		/**
		 * Fires immediately before an object-term relationship is added.
		 *
		 * @since 2.9.0
		 * @since 4.7.0 Added the `$taxonomy` parameter.
		 *
		 * @param int    $object_id Object ID.
		 * @param int    $tt_id     Term taxonomy ID.
		 * @param string $taxonomy  Taxonomy slug.
		 */
		do_action( 'add_term_relationship', $object_id, $tt_id, $taxonomy );

		$wpdb->insert(
			$wpdb->term_relationships,
			array(
				'object_id'        => $object_id,
				'term_taxonomy_id' => $tt_id,
			)
		);

		/**
		 * Fires immediately after an object-term relationship is added.
		 *
		 * @since 2.9.0
		 * @since 4.7.0 Added the `$taxonomy` parameter.
		 *
		 * @param int    $object_id Object ID.
		 * @param int    $tt_id     Term taxonomy ID.
		 * @param string $taxonomy  Taxonomy slug.
		 */
		do_action( 'added_term_relationship', $object_id, $tt_id, $taxonomy );

		$new_tt_ids[] = $tt_id;
	}

	if ( $new_tt_ids ) {
		wp_update_term_count( $new_tt_ids, $taxonomy );
	}

	if ( ! $append ) {
		$delete_tt_ids = array_diff( $old_tt_ids, $tt_ids );

		if ( $delete_tt_ids ) {
			$in_delete_tt_ids = "'" . implode( "', '", $delete_tt_ids ) . "'";
			$delete_term_ids  = $wpdb->get_col( $wpdb->prepare( "SELECT tt.term_id FROM $wpdb->term_taxonomy AS tt WHERE tt.taxonomy = %s AND tt.term_taxonomy_id IN ($in_delete_tt_ids)", $taxonomy ) );
			$delete_term_ids  = array_map( 'intval', $delete_term_ids );

			$remove = wp_remove_object_terms( $object_id, $delete_term_ids, $taxonomy );
			if ( is_wp_error( $remove ) ) {
				return $remove;
			}
		}
	}

	$t = get_taxonomy( $taxonomy );

	if ( ! $append && isset( $t->sort ) && $t->sort ) {
		$values     = array();
		$term_order = 0;

		$final_tt_ids = wp_get_object_terms(
			$object_id,
			$taxonomy,
			array(
				'fields'                 => 'tt_ids',
				'update_term_meta_cache' => false,
			)
		);

		foreach ( $tt_ids as $tt_id ) {
			if ( in_array( (int) $tt_id, $final_tt_ids, true ) ) {
				$values[] = $wpdb->prepare( '(%d, %d, %d)', $object_id, $tt_id, ++$term_order );
			}
		}

		if ( $values ) {
			if ( false === $wpdb->query( "INSERT INTO $wpdb->term_relationships (object_id, term_taxonomy_id, term_order) VALUES " . join( ',', $values ) . ' ON DUPLICATE KEY UPDATE term_order = VALUES(term_order)' ) ) {
				return new WP_Error( 'db_insert_error', __( 'Could not insert term relationship into the database.' ), $wpdb->last_error );
			}
		}
	}

	wp_cache_delete( $object_id, $taxonomy . '_relationships' );
	wp_cache_delete( 'last_changed', 'terms' );

	/**
	 * Fires after an object's terms have been set.
	 *
	 * @since 2.8.0
	 *
	 * @param int    $object_id  Object ID.
	 * @param array  $terms      An array of object terms.
	 * @param array  $tt_ids     An array of term taxonomy IDs.
	 * @param string $taxonomy   Taxonomy slug.
	 * @param bool   $append     Whether to append new terms to the old terms.
	 * @param array  $old_tt_ids Old array of term taxonomy IDs.
	 */
	do_action( 'set_object_terms', $object_id, $terms, $tt_ids, $taxonomy, $append, $old_tt_ids );

	return $tt_ids;
}

С этим читают