用户创建自定义帖子类型后,删除旧帖子类型

时间:2020-08-04 作者:Zaesar

我创建了一个表单,用户可以在其中更新他们的个人资料。创建或更新概要文件时,它会创建一个称为“课程”的CPT。url为the permalink + /course/ + the title of the course

/*  CREATING COURSE PAGES FROM USER PROFILES */

function create_course_page( $user_id = \'\' ) {
   $user = new WP_User($user_id);
   if ( ! $user->ID ) return \'\';

   // check if the user whose profile is updating has already a post
   global $wpdb;
   $course_post_exists = $wpdb->get_var( $wpdb->prepare(
   "SELECT ID FROM $wpdb->posts WHERE post_name = %s AND post_type = \'course\' and post_status = \'publish\'", $user->course_name
   ) );

  if ( ! in_array(\'instructor\', $user->roles) ) return \'\';

  $user_info = array_map( function( $a ){ return $a[0]; }, get_user_meta( $user->ID ) );
  $title = $user_info[\'course_name\'];
  // of course create the content as you want
  $content = \'This is the page for: \';
  $content .= $user_info[\'description_course\'];
  $post = array(
    \'post_title\' => $title,
    \'post_name\' => $user->course_name,
    \'post_content\' => $content,
    \'post_status\' => \'publish\',
    \'post_type\' => \'course\'
  );
  if ( $course_post_exists ) {
    $post[\'ID\'] = $course_post_exists;
    wp_update_post( $post );
  } else {
    wp_insert_post( $post );
  }
}

add_action( \'personal_options_update\', \'create_course_page\' );
add_action( \'edit_user_profile_update\', \'create_course_page\' );
我面临的问题是,当有人更改课程标题时,它会使用此url创建一个新帖子。

因此,我想在课程标题更改后删除旧帖子。

注意:当更改课程标题时,它会更改URL,这就是为什么我认为它需要像一篇新帖子一样。

为了完成这项工作,我定制了一些代码:

/* REMOVE OLD COURSES WHEN UPDATE */
add_action( \'admin_init\', \'removing_older_posts\' );
function removing_older_posts() {
    $args = array (
        \'post_type\'         => \'course\',
        \'author\'            => get_current_user_id(),
        \'orderby\'           => \'date\',
        );
    $query = new WP_Query( $args );

    if ( $query->have_posts() ) { //if the current user has posts under his/her name
        $i = 0; //create post counter
        while ( $query->have_posts() ) { //loop through each post
            $query->the_post(); //get the current post
            if ($i > 0) { //if you\'re not on the first post
                wp_delete_post( $query->post->ID, true ); //delete the post
            }
            $i++; //increment the post counter
        }
        wp_reset_postdata();
    }
}
但它不起作用。

感谢您的建议:)

2 个回复
SO网友:Oliver Gehrmann

我想如果你能解释一下为什么你要用用户在个人资料上所做的编辑来生成课程,那会很有帮助。最简单的解决方案似乎是一个前端表单,它只允许用户创建新帖子或编辑现有帖子,而不是使用此替代解决方案,即使用配置文件页面中的数据创建新帖子。


如果您想坚持当前的实施,我相信您可以研究状态转换:https://developer.wordpress.org/reference/hooks/transition_post_status/

下面是一些示例代码,我用来在创建自定义帖子类型后,在ID为1(=新闻)的类别中创建帖子:

// Automatically create a news when a wiki post has been published
function nxt_create_news($new_status, $old_status, $nxt_wiki_post) {
    if(\'publish\' === $new_status && \'publish\' !== $old_status && $nxt_wiki_post->post_type === \'wiki\') {
        $nxt_post_author = $nxt_wiki_post->post_author;
        $nxt_wiki_permalink = get_post_permalink($nxt_wiki_id);
        $nxt_wiki_title = $nxt_wiki_post->post_title;
        $nxt_postarr = array(
            \'post_author\' => $nxt_post_author,
            \'post_content\' => \'The wiki entry \' . $nxt_wiki_title . \' has just been published.<br /><br /><a href="\' . $nxt_wiki_permalink . \'" title="\' . $nxt_wiki_title . \'">Check out wiki entry</a>.\',
            \'post_title\' => \'The wiki entry \' . $nxt_wiki_title . \' has been published\',
            \'post_status\' => \'publish\',
            \'post_category\' => array(1),
        );
        $nxt_post_id = wp_insert_post($nxt_postarr);
        set_post_thumbnail(get_post($nxt_post_id), \'1518\');
    }
}
add_action( \'transition_post_status\', \'nxt_create_news\', 10, 3 );
在您的特定情况下,您可以将部分保存的帖子与将要创建的新帖子进行比较,然后防止发生默认操作(创建新帖子),而只需编辑旧帖子。

主要的问题是,系统如何知道有人试图编辑哪个帖子?我真的无法回答这个问题,因为我不明白你为什么要使用个人资料编辑来创建新帖子,但我希望这对你有所帮助。:-)

SO网友:Tom J Nowell

您无需执行任何操作,并且可以完全回避问题,使代码更快、更简单!

这就是我们要做的:

我们将使用课程文章作者,而不是名称,它更可靠,我们将避免原始SQL查询,以便使用缓存和WP_Querywp_insert_post 为了更新和创建帖子,请删除无用的array_map 打电话检查一下wp_insert_post 无论成功与否,我们将应用WP编码标准,以使其更易于阅读和更好地使用,例如现代PHP数组[] 而不是array(), 严格的in_array 检查,无全局变量

  • 计算课程ID的代码将移动到其自己的函数
    • 这样,当课程名称更改时,原始course 帖子的标题和URL已更新/更改,而不是创建全新的course 这需要清理旧球场。

      以下是一些接近实际情况的建议:

      function get_course_by_author( $user_id ) : int {
          // if we don\'t find anything then a value of 0 will create a new post rather than update an existing post.
          $course_id = 0;
          $args = [
              \'post_type\'      => \'course\',
              \'posts_per_page\' => 1,
              \'post_author\'    => $user_id,
          ];
          $query     = new WP_Query( $args );
          if ( $query->have_posts() ) {
              while ( $query->have_posts() ) {
                  $query->the_post();
                  $course_id = get_the_ID();
                  // we only want a single post ID
                  break;
              }
              // cleanup after the query
              wp_reset_postdata();
          } else {
              // perhaps the course was created before post authors were set? Fall back to looking for the post by its slug/name
              return 0;
          }
          return $course_id;
      }
      
      function get_course_by_slug( string $slug ) : int {
          $course_id = 0;
          $args = [
              \'post_type\'      => \'course\',
              \'posts_per_page\' => 1,
              \'post_name\'      => $slug,
          ];
          ... etc etc see get_course_by_author ...
          return $course_id;
      }
      
      function handle_course_post( $user_id = \'\' ) {
          // First, is this user an instructor?
          $user = get_user_by( \'ID\', $user_id );
          if ( ! $user || ! in_array( \'instructor\', $user->roles, true ) ) {
              return;
          }
      
          // get the course name
          $course_name = get_user_meta( $user_id, \'course_name\', true );
          if ( empty( $course_name ) {
              error_log( "the user does not have a course_name!" );
          }
      
          // Then lets find this users course if it exists.
          // if we don\'t find anything then a value of 0 will create a new post rather than update an existing post.
          $course_id = get_course_by_author( $user_id );
          if ( $course_id === 0 ) {
              // we didn\'t find a course with that author, try the course name.
              $course_id = get_course_by_slug( $course_name );
          }
      
          // Finally, save/update the course!
          $content  = \'This is the page for: \';
          $content .= get_user_meta( $user_id, \'description_course\', true );
          $args     = [
              \'ID\'           => $course_id,
              \'post_title\'   => $course_name,
              \'post_name\'    => $course_name, // set the slug/permalink
              \'post_content\' => $content,
              \'post_status\'  => \'publish\',
              \'post_type\'    => \'course\',
          ];
          $post_id  = wp_insert_post( $args );
      
          // check if we were succesful.
          if ( is_wp_error( $post_id ) ) {
              // it didn\'t work!
              error_log( $post_id->get_error_message() );
          } else if ( empty( $post_id ) ) {
              // it didn\'t work!
              error_log( "post_id is empty/false" );
          }
      
      }
      
      add_action( \'personal_options_update\', \'handle_course_post\' );
      add_action( \'edit_user_profile_update\', \'handle_course_post\' );
      
      请记住,这是未经测试的,需要一些理解,它不能按原样复制粘贴(尽管如果它按原样工作,那就好了!)。

      请注意,在结束时,我们检查wp_insert_post 是否工作。我们不能假设它是成功的,如果另一个用户已经选择了该课程名称怎么办?如果用户不再是讲师怎么办?

      还要记住,您现有的course 帖子没有合适的作者,需要重新保存。一旦完成,所有案件都将得到处理。如果上面的代码无法通过作者找到课程帖子,那么它将尝试通过slug获取课程帖子,允许部分迁移路径。

      这确实意味着你原来的问题仍然会发生,但只会发生在那些从未更新过个人资料并立即更改课程名称的用户身上。那些保存个人资料然后更改名称的人将被处理,所有未来的用户也将被处理。

    相关推荐

    在PHP中删除ECHO输出中的重复项

    现在,下面的函数输出产品的所有变体图像。E、 g.3倍蓝色(S、M、L号),3倍红色(S、M、L号)我想下面的功能只输出唯一的彩色图像。E、 g.1个蓝色,1个红色尝试在回显字符串中使用array\\u unique,但无法使其正常工作。谢谢你的帮助。function loop_display_variation_attribute_and_thumbnail() { global $product; if( $product->is_type(\'variable\