WordPress как на ладони
wordpress jino

wp_update_term() WP 2.3

Обновляет термин (элемент таксономии), используя указанные данные.

Используется в: wp_insert_category().
Хуки из функции:
Возвращает

ID термина и ID таксономии (в массиве) или объект WP_Error.

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

wp_update_term( $term_id, $taxonomy, $args );
$term_id(число) (обязательный)
ID термина, который нужно обновить.
По умолчанию: нет
$taxonomy(строка) (обязательный)
Название таксономии к которой принадлежит термин. Например: category, post_tag.
По умолчанию: нет
$args(массив)
Новые значение полей у термина.
По умолчанию: по умолчанию

Примеры

#1. Обновим термин 1 в таксономии category

Пример показывает, как обновить термин 1 в таксономии category (т.е. как обновить рубрику с ID=1).

<?php
wp_update_term(1, 'category', array(
  'name' => 'Non Categorise',
  'slug' => 'non-categorise'
));
?>

Поля термина, которые можно обновить. Поля в $args:

  • term_id

  • name

  • slug

  • term_group

  • term_taxonomy_id

  • taxonomy

  • description

  • parent

  • count

Заметки

Все имена полей в $args будут без разбора переписаны. Внимательно проверьте обновляемые данные, чтобы обновление не вызвало ошибку.

По умолчанию будут установлены alias_of, description, parent и slug, если они не определены в $args.

Если аргумент slug в $agrs не указан, то для его создания будет использован аргумент name. WP создаст новый уникальный слаг для термина. Также важно учитывать, что если мы установим slug и он окажется не уникальным, то функция вернет ошибку WP_Error.

Код wp update term: wp-includes/taxonomy.php VER 4.9.1

<?php
function wp_update_term( $term_id, $taxonomy, $args = array() ) {
	global $wpdb;

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

	$term_id = (int) $term_id;

	// First, get all of the original args
	$term = get_term( $term_id, $taxonomy );

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

	if ( ! $term ) {
		return new WP_Error( 'invalid_term', __( 'Empty Term.' ) );
	}

	$term = (array) $term->data;

	// Escape data pulled from DB.
	$term = wp_slash( $term );

	// Merge old and new args with new args overwriting old ones.
	$args = array_merge($term, $args);

	$defaults = array( 'alias_of' => '', 'description' => '', 'parent' => 0, 'slug' => '');
	$args = wp_parse_args($args, $defaults);
	$args = sanitize_term($args, $taxonomy, 'db');
	$parsed_args = $args;

	// expected_slashed ($name)
	$name = wp_unslash( $args['name'] );
	$description = wp_unslash( $args['description'] );

	$parsed_args['name'] = $name;
	$parsed_args['description'] = $description;

	if ( '' == trim( $name ) ) {
		return new WP_Error( 'empty_term_name', __( 'A name is required for this term.' ) );
	}

	if ( $parsed_args['parent'] > 0 && ! term_exists( (int) $parsed_args['parent'] ) ) {
		return new WP_Error( 'missing_parent', __( 'Parent term does not exist.' ) );
	}

	$empty_slug = false;
	if ( empty( $args['slug'] ) ) {
		$empty_slug = true;
		$slug = sanitize_title($name);
	} else {
		$slug = $args['slug'];
	}

	$parsed_args['slug'] = $slug;

	$term_group = isset( $parsed_args['term_group'] ) ? $parsed_args['term_group'] : 0;
	if ( $args['alias_of'] ) {
		$alias = get_term_by( 'slug', $args['alias_of'], $taxonomy );
		if ( ! empty( $alias->term_group ) ) {
			// The alias we want is already in a group, so let's use that one.
			$term_group = $alias->term_group;
		} elseif ( ! empty( $alias->term_id ) ) {
			/*
			 * The alias is not in a group, so we create a new one
			 * and add the alias to it.
			 */
			$term_group = $wpdb->get_var("SELECT MAX(term_group) FROM $wpdb->terms") + 1;

			wp_update_term( $alias->term_id, $taxonomy, array(
				'term_group' => $term_group,
			) );
		}

		$parsed_args['term_group'] = $term_group;
	}

	/**
	 * Filters the term parent.
	 *
	 * Hook to this filter to see if it will cause a hierarchy loop.
	 *
	 * @since 3.1.0
	 *
	 * @param int    $parent      ID of the parent term.
	 * @param int    $term_id     Term ID.
	 * @param string $taxonomy    Taxonomy slug.
	 * @param array  $parsed_args An array of potentially altered update arguments for the given term.
	 * @param array  $args        An array of update arguments for the given term.
	 */
	$parent = apply_filters( 'wp_update_term_parent', $args['parent'], $term_id, $taxonomy, $parsed_args, $args );

	// Check for duplicate slug
	$duplicate = get_term_by( 'slug', $slug, $taxonomy );
	if ( $duplicate && $duplicate->term_id != $term_id ) {
		// If an empty slug was passed or the parent changed, reset the slug to something unique.
		// Otherwise, bail.
		if ( $empty_slug || ( $parent != $term['parent']) ) {
			$slug = wp_unique_term_slug($slug, (object) $args);
		} else {
			/* translators: 1: Taxonomy term slug */
			return new WP_Error( 'duplicate_term_slug', sprintf( __( 'The slug &#8220;%s&#8221; is already in use by another term.' ), $slug ) );
		}
	}

	$tt_id = (int) $wpdb->get_var( $wpdb->prepare( "SELECT tt.term_taxonomy_id FROM $wpdb->term_taxonomy AS tt INNER JOIN $wpdb->terms AS t ON tt.term_id = t.term_id WHERE tt.taxonomy = %s AND t.term_id = %d", $taxonomy, $term_id) );

	// Check whether this is a shared term that needs splitting.
	$_term_id = _split_shared_term( $term_id, $tt_id );
	if ( ! is_wp_error( $_term_id ) ) {
		$term_id = $_term_id;
	}

	/**
	 * Fires immediately before the given terms are edited.
	 *
	 * @since 2.9.0
	 *
	 * @param int    $term_id  Term ID.
	 * @param string $taxonomy Taxonomy slug.
	 */
	do_action( 'edit_terms', $term_id, $taxonomy );

	$data = compact( 'name', 'slug', 'term_group' );

	/**
	 * Filters term data before it is updated in the database.
	 *
	 * @since 4.7.0
	 *
	 * @param array  $data     Term data to be updated.
	 * @param int    $term_id  Term ID.
	 * @param string $taxonomy Taxonomy slug.
	 * @param array  $args     Arguments passed to wp_update_term().
	 */
	$data = apply_filters( 'wp_update_term_data', $data, $term_id, $taxonomy, $args );

	$wpdb->update( $wpdb->terms, $data, compact( 'term_id' ) );
	if ( empty($slug) ) {
		$slug = sanitize_title($name, $term_id);
		$wpdb->update( $wpdb->terms, compact( 'slug' ), compact( 'term_id' ) );
	}

	/**
	 * Fires immediately after the given terms are edited.
	 *
	 * @since 2.9.0
	 *
	 * @param int    $term_id  Term ID
	 * @param string $taxonomy Taxonomy slug.
	 */
	do_action( 'edited_terms', $term_id, $taxonomy );

	/**
	 * Fires immediate before a term-taxonomy relationship is updated.
	 *
	 * @since 2.9.0
	 *
	 * @param int    $tt_id    Term taxonomy ID.
	 * @param string $taxonomy Taxonomy slug.
	 */
	do_action( 'edit_term_taxonomy', $tt_id, $taxonomy );

	$wpdb->update( $wpdb->term_taxonomy, compact( 'term_id', 'taxonomy', 'description', 'parent' ), array( 'term_taxonomy_id' => $tt_id ) );

	/**
	 * Fires immediately after a term-taxonomy relationship is updated.
	 *
	 * @since 2.9.0
	 *
	 * @param int    $tt_id    Term taxonomy ID.
	 * @param string $taxonomy Taxonomy slug.
	 */
	do_action( 'edited_term_taxonomy', $tt_id, $taxonomy );

	/**
	 * Fires after a term has been updated, but before the term cache has been cleaned.
	 *
	 * @since 2.3.0
	 *
	 * @param int    $term_id  Term ID.
	 * @param int    $tt_id    Term taxonomy ID.
	 * @param string $taxonomy Taxonomy slug.
	 */
	do_action( "edit_term", $term_id, $tt_id, $taxonomy );

	/**
	 * Fires after a term in a specific taxonomy has been updated, but before the term
	 * cache has been cleaned.
	 *
	 * The dynamic portion of the hook name, `$taxonomy`, refers to the taxonomy slug.
	 *
	 * @since 2.3.0
	 *
	 * @param int $term_id Term ID.
	 * @param int $tt_id   Term taxonomy ID.
	 */
	do_action( "edit_{$taxonomy}", $term_id, $tt_id );

	/** This filter is documented in wp-includes/taxonomy.php */
	$term_id = apply_filters( 'term_id_filter', $term_id, $tt_id );

	clean_term_cache($term_id, $taxonomy);

	/**
	 * Fires after a term has been updated, and the term cache has been cleaned.
	 *
	 * @since 2.3.0
	 *
	 * @param int    $term_id  Term ID.
	 * @param int    $tt_id    Term taxonomy ID.
	 * @param string $taxonomy Taxonomy slug.
	 */
	do_action( "edited_term", $term_id, $tt_id, $taxonomy );

	/**
	 * Fires after a term for a specific taxonomy has been updated, and the term
	 * cache has been cleaned.
	 *
	 * The dynamic portion of the hook name, `$taxonomy`, refers to the taxonomy slug.
	 *
	 * @since 2.3.0
	 *
	 * @param int $term_id Term ID.
	 * @param int $tt_id   Term taxonomy ID.
	 */
	do_action( "edited_{$taxonomy}", $term_id, $tt_id );

	return array('term_id' => $term_id, 'term_taxonomy_id' => $tt_id);
}

Cвязанные функции

Из метки: term (термины таксономий)

Еще из раздела: Любые таксономии

wp_update_term 24 комментария
  • Kama, добрый день!
    Подскажите пожалуйста по следующему вопросу:

    При наличии значения у метаполя, у определенного термина таксономии (иерархической) должен появиться чек в чекбоксе в админке в метабоксе таксономии, а пост сохраниться.

    Я пробую так:

    do_action( "save_post_{$post->my_custom_post_name}", $post_ID, $post, true );
    
    add_action( 'save_post', 'function_name', 10, 3 );
    
    function function_name( $post_ID, $post, $update ) {
    	if (get_post_meta($post->ID, 'my_meta_key', true)) .... //дальше не знаю 
    что использовать, чтобы прописать условия для чека у термина,
    наверное, через wp_update_term?
    }

    Попробовал еще вот так:

    add_action( 'wp_insert_post', 'update_post_terms' );
    function update_post_terms( $post_id ) {
    	if ( $the_post = wp_is_post_revision( $post_id ) )
    		$post_id = $the_post;   
    
    	$post = get_post( $post_id );   
    
    	if ( $post->post_type != 'post' )
    		return;
    
    	if (get_post_meta($post->ID, 'my_meta_key', true))
    
    	wp_set_post_terms( $post_id, 'my_term_name', 'my_taxonomy_name', true );
    }

    Безрезультатно.

    • Мысли может будут у кого-нибудь?

    • Kama4697

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

        1. Есть метаполе с названием 1.
        2. Есть термин таксономии с таким же названием 1 (но название может быть и другое).
        3. Эти метаполе и термин принадлежат посту произвольного типа записи.
        4. Нужно их связать, чтобы автоматически у термина таксономии ставился чек, если метаполе заполнено в посте в админке.
          Т.е. я в посте в админке заполняю это метаполе, таксономию не трогаю.
          Обновляю пост, захожу снова и там уже у термина стоит чек.
        • Kama4697

          Логика такая. Вешаешь событие на хук current_screen или wp. В нем проверяешь что ты находишься на странице редактирования тип записи. Далее, проверяешь, есть ли у этого типа записи нужное метаполе. Далее находишь термин по указанному метаполю. Если все нашлось, связываешь запись с термином через wp_set_object_terms()

          Тут не понятно, что ты указываешь в метаполе: ID, ярлык или название термина... И еще не понятно, зачем это нужно, как-то не логично, не проще руками выбрать термин, чем указывать что-то в метаполе?

          • Спасибо, буду пробовать.

            Поясню немного:
            Есть большая таблица с числовыми значениями в метаполях.
            Таблица продублирована в таксономии, чтобы поиск и фильтрация работала по терминам.

            Сейчас сделано так, что нужно вручную проходить большую таблицу и проставлять чек у терминов по каждому посту.

            Вот поэтому возникла необходимость это как-то упростить.
            Если заполнено метаполе 1, то поставить чек у такого-то термина таксономии.
            В метаполях числовые значения.

          • Вот такой код получился у меня, но не могу правильно вызвать ID записи, пробовал через get_the_ID, $post->ID, не получается.

            Но, если я укажу в коде конкретный ID записи, то все работает (при наличии meta_key чекается термин таксономии):

            function сurrent_screen_hook( $current_screen ) {
            	if ( 'my_post_type' == $current_screen->post_type && 'post' == $current_screen->base ) {
            
            		$post_id = get_the_ID();
            		if (get_post_meta($post_id, 'my_meta_key', true) != "") 
            			wp_set_object_terms( $post_id, 'my_term', 'my_taxonomy', true );    
            	}
            }
            add_action( 'current_screen', 'сurrent_screen_hook' );

            Тимур, подскажите пожалуйста, где я ошибся?

            • campusboy1951 cайт: www.youtube.com/c/wpplus

              Попробуй так:

              function сurrent_screen_hook( $current_screen ) {
              	if ( 'my_post_type' == $current_screen->post_type && 'post' == $current_screen->base ) {
              		global $post;
              
              		if (get_post_meta($post->ID, 'my_meta_key', true) != "") 
              			wp_set_object_terms( $post->ID, 'my_term', 'my_taxonomy', true );    
              	}
              }
              add_action( 'current_screen', 'сurrent_screen_hook' );
              1
            • campusboy1951 cайт: www.youtube.com/c/wpplus

              А если вот так?

              function сurrent_screen_hook( $current_screen ) {
              	$post_id = (int) $_GET['post'];
              
              	if ( 'my_post_type' == $current_screen->post_type && 'post' == $current_screen->base ) {
              
              		if (get_post_meta( $post_id, 'my_meta_key', true) != "") 
              			wp_set_object_terms( $post_id, 'my_term', 'my_taxonomy', true );    
              	}
              }
              add_action( 'current_screen', 'сurrent_screen_hook' );

              Где post тип поста из $_GET['post'], то есть берется из адресной строки. У меня это что-то типа:

              http://test-wp.ru/wp-admin/post.php?post=41&action=edit
              1
              • campusboy, благодарю. заработало!

                • campusboy1951 cайт: www.youtube.com/c/wpplus

                  Разобрался, почему $post->ID не работало. Потому что хук current_screen срабатывает до того, как вообще запрос о записи формируется. Надо посадить на другой хук, к примеру, что-то типа такого сделать:

                  function add_post_to_my_term() {
                  	global $post;
                  
                  	if ( 'my_post_type' == get_current_screen()->post_type && 'post' == get_current_screen()->base ) {
                  
                  		if (get_post_meta( $post-ID, 'my_meta_key', true) != ""){
                  
                  			wp_set_object_terms( $post-ID, 'my_term', 'my_taxonomy', true );  
                  
                  		}
                  
                  	}
                  }
                  add_action( 'pre_get_posts', 'add_post_to_my_term' );

                  В этот момент определены все данные, который возвращает функция get_post (там список этих всех значений).

                  1
                  • Спасибо, что уделили время моему вопросу!
                    Этот код тоже работает.

                  • Протестировал код.

                    Код в таком исполнении дико вешает сайт, у меня около 200 таких позиций, по которым нужно сделать увязку между метаполем и таксономией:

                    function add_post_to_my_term() {
                    	global $post;   
                    
                    		if (get_post_meta( $post->ID, 'my_meta_key', true) != "") {
                    			wp_set_object_terms( $post->ID, 'my_term', 'my_taxonomy', true ); }  
                    		else {wp_remove_object_terms( $post->ID, 'my_term', 'my_taxonomy', true ); }
                    }
                    add_action( 'pre_get_posts', 'add_post_to_my_term' );
                    

                    Код, который был до этого (через current_screen) полностью не тестировал, но на нескольких позициях тормозов не заметил:

                    function сurrent_screen_hook( $current_screen ) {
                    	$post_id = (int) $_GET['post'];
                    		if ( 'my_post_type' == $current_screen->post_type && 'post' == $current_screen->base ) {
                    
                    			if (get_post_meta( $post_id, 'my_meta_key1', true) != "") wp_set_object_terms( $post_id, 'my_term1', 'my_taxonomy1', true );
                    			if (!get_post_meta( $post_id, 'my_meta_key1', true)) wp_remove_object_terms( $post_id, 'my_term1', 'my_taxonomy1', true );
                    
                    			if (get_post_meta( $post_id, 'my_meta_key2', true) != "") wp_set_object_terms( $post_id, 'my_term2', 'my_taxonomy2', true );
                    			if (!get_post_meta( $post_id, 'my_meta_key2', true)) wp_remove_object_terms( $post_id, 'my_term2', 'my_taxonomy2', true );
                    	}
                    }
                    add_action( 'current_screen', 'сurrent_screen_hook' );

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

                    Увязка через pre_get_posts работает и там и там, но вызывает тормоза на сайте (сайт на локальном сервере).

                    Может есть еще какие-либо функции мне в помощь?

                    • Kama4697

                      Во первых, вместо pre_get_posts используй хук wp - он логичнее тут.

                      Во вторых, делай проверку что ты там, где нужно в админке или фронте, чтобы код хука срабатывал только в нужных местах. А то сейчас получается, что он срабатывает при абсолютно любом запросе, т.е. всегда срабатывает функция wp_set_object_terms() или wp_remove_object_terms() - независимо от того на какой странице фронта или админки мы находимся... Да еще и с хуком pre_get_posts скорее всего срабатывает по нескольку раз за генерацию страницы... Поэтому и тормоза...

                    • Тимур, спасибо.
                      Так и сделал: перевел на хук WP, сделал проверку для фронтенда и админки. Тормозов нет.

  • А куда пропал блок выражения благодарности Тимуру?

    • Kama4697

      Убрал за ненадобностью, никто не выражает никакой благодарности. Только на словах smile

      • Верните, пусть будет. Хочу попросить Вас уделить время моему вопросу и поблагодарить)

        • campusboy1951 cайт: www.youtube.com/c/wpplus

          На странице "О сайте" есть все реквизиты, чтобы сказать не просто спасибо, но и поблагодарить материально.

          1
  • Ярослав

    Также важно учитывать, что если мы установим slug и он окажется не уникальным, то функция вернет ошибку WP_Error.

    а если мне нужно обновить на существующий термин?

    Ответитьмесяц назад #

Здравствуйте, !

Ваш комментарий