Скрипт для дублирования категорий как тегов

У меня есть сайт с более чем 900 сообщениями, каждый из которых содержит около 3-5 категорий. Я хотел бы скопировать каждую из категорий в тег, и я ищу код SQL для этого. Я не хочу удалять или перезаписывать категории. (Я предполагаю, что это лучшее, что можно сделать для целей SEO?)

Мне сложно определить, что именно должно быть INSERTED.

Что я до сих пор … Это комментарии в конце мне нужна помощь.

global $wpdb; $query = " SELECT $wpdb->posts.ID, $wpdb->term_relationships.object_id, $wpdb->term_relationships.term_taxonomy_id, $wpdb->term_taxonomy.term_taxonomy_id, $wpdb->terms.term_id, $wpdb->terms.name, $wpdb->terms.slug FROM $wpdb->posts LEFT JOIN $wpdb->term_relationships ON ($wpdb_posts.ID = $wpdb->term_relationships.object_id) LEFT JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id) LEFT JOIN $wpdb->terms ON ($wpdb->term_taxonomy.term_taxonomy_id = $wpdb->terms.term_id) WHERE $wpdb->posts.post_status = 'publish' AND $wpdb->posts.post_type = 'post' AND $wpdb->term_taxonomy.taxonomy = 'category' AND $wpdb->terms.name NOT LIKE '*%' ORDER BY post_date DESC "; $results = $wpdb->get_results($query); $insert = ""; $wpdb->query($insert); -- Next steps: -- LOOP? { -- INSERT INTO $wpdb->terms (name, slug) -- VALUES (terms.name, terms.slug) -- } -- SELECT new term_id's for the above inserted names and slugs -- LOOP? { -- INSERT INTO $wpdb->term_taxonomy (term_id, taxonomy) -- VALUES (terms.term_id, post_tag) -- } -- SELECT new term_taxonomy_id's for the above inserted term_id's -- LOOP? { -- INSERT INTO $wpdb->term_relationships (term_taxonomy_id, object_id) -- VALUES (term_taxonomy.term_taxonomy_id, post_id) -- } 

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

Здесь также неправильный рабочий процесс. Сначала я создаю все теги, а после этого вставляю теги в сообщения. Вы пытаетесь сделать все сразу.

Позволяет нам сначала захватить все категории и использовать эту информацию для создания тегов. Просто отметьте:

  • post_tag являющийся не иерархической таксономией, не может иметь никаких повторяющихся имен, иерархические таксономии, такие как category могут иметь повторяющиеся имена терминов в разных иерархиях. Если у вас есть категории с одинаковыми именами, вы получите объект WP_Error если вы попытаетесь вставить теги с повторяющимися именами. Чтобы этого избежать, мы просто проверим, существует ли тег, прежде чем мы попытаемся его вставить

  • Теги не могут иметь отношения родительские / дочерние, могут быть категории. Поэтому, когда мы дублируем категорию как термин, мы должны явно указать всем родителям 0

Вот код: ( ПРИМЕЧАНИЕ : нам потребуется PHP 5.4+)

 // Lets create our tags. We will use wp_insert_term hooked to init add_action( 'init', function () { // Get all categories $categories = get_categories( ['hide_empty' => 0] ); // Probably totally unnecessary, but check for empty $categories if ( !$categories ) return; // Loop through the categories and create our tags foreach ( $categories as $category ) { // First make sure that there is no tag that exist with the same name if ( term_exists( $category->name, 'post_tag' ) ) continue; // Set our arguments for our terms from $category $args = [ 'description' => $category->description, 'parent' => 0, // We can drop this, default is 0 'slug' => $category->slug, ]; wp_insert_term( $category->name, 'post_tag', $args ); } //endforeach }, PHP_INT_MAX ); 

Теперь вы должны увидеть эти теги на своей странице администратора Tag . Вы также можете удалить код, поскольку он больше не нужен.

Теперь, когда мы создали наши теги, нам нужно добавить их в наши сообщения. Здесь нам нужно быть осторожным, поскольку вы говорите о 900+ сообщениях, поэтому мы не хотим разорвать банк.

Что мы будем делать, мы будем запрашивать все эти сообщения, но только идентификаторы сообщений, которые экономит много ресурсов. Кроме того, мы будем использовать get_the_category которые кэшируются, поэтому для него не требуются дополнительные вызовы db, wp_get_post_categories не кэшируются, поэтому это действительно дорого

Из-за wp_set_post_terms что wp_set_post_terms дорого, вам, возможно, потребуется разделить следующее на пару запросов, но я считаю, что одного запроса должно быть достаточно

Позволяет прикреплять теги к нашим сообщениям

 add_action( 'template_redirect', function () { // Get all our posts $args = [ 'posts_per_page' => -1, 'fields' => 'ids', // Make the query lean // Add any additional query args here ]; $q = new WP_Query( $args ); if ( !$q->have_posts() ) return; while ( $q->have_posts() ) { $q->the_post(); // Get all the categories attached to the post $categories = get_the_category(); if ( !$categories ) continue; // Get the names from the categories into an array $names = wp_list_pluck( $categories, 'name' ); // Loop through the names and make sure that the post does not already has the tag attached foreach ( $names as $key=>$name ) { if ( has_tag( $name ) ) unset ( $names[$key] ); } // Make sure we still have a valid $names array if ( !$names ) continue; // Finally, attach our tags to the posts wp_set_post_terms( get_the_ID(), // Post ID $names, // Array of tag names to attach 'post_tag', true // Only add the tags, do not override ); } wp_reset_postdata(); }); 

Теперь ваши сообщения должны иметь прикрепленные к ним теги, соответствующие категориям. Вы также можете удалить функцию, как мы это сделали

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

Я не рекомендую запускать это более одного раза, если вы удаляете комментарии с конца кода. Вы поймете, когда вы доберетесь туда.

Этот код «копирует» все категории всех ваших сообщений и сохраняет их как теги. Он не удаляет категории, а также не устанавливает новые теги для сообщений. Если вы также хотите установить теги на сообщения, дайте мне знать.

PS! Он работает только правильно, если категории не являются иерархическими aka без родителей!

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


 <?php global $post; //Get ALL the posts with query $args = array( 'post_type' => 'post', 'post_status' => 'any' //Change to 'publish', 'draft' or 'pending' if you don't want to get ALL post STATUSES ); $post_query = new WP_Query( $args ); //Declare new array of our categories which eventually become tags $new_tags = array(); while ($post_query->have_posts()) : $post_query->the_post(); //Get all the categories names of the post and save as an array variable $post_categories = wp_get_post_categories($post->ID, array('fields' => 'names') ); //Loop through all categories foreach ( $post_categories as $category ) { //Check if category is already in array if ( ! in_array($category , $new_tags ) ) { //Push category to array if it isn't in array yet array_push( $new_tags, $category ); } } endwhile; wp_reset_postdata(); //VERY IMPORTANT - test first without making new tags and check if everything seems to be correct //PS! Compare the count of items in array (starts with 0 - it's 1 less because of that) with category count in WP admin area print_r($new_tags); //Add new tags programmatically - don't do it if you're sure that array is correct!! /* foreach ( $new_tags as $tag ) { wp_insert_term( $tag, 'post_tag' ); } */ ?>