通过比较数组中的ID按特定顺序显示父子帖子

时间:2021-08-31 作者:aslamdoctor

我有一个为自定义帖子类型存储的ID数组;服务;。其中有些是父ID,有些是子ID。

So“;service"E;此处的帖子类型是分层的。

现在,从这个ID数组中,我想以如下格式列出页面:

它们按帖子标题升序排序。

它们列在父项中;子模式如下:

Service 1
    A Child
    B Child
Service 2
    X Child
    Y Child
Service 3
由于数组包含任何ID,如果数组中有子ID,但父ID不是,则show the parent post automatically.

到目前为止,我已经实现了以下代码:

$args = array(
    \'post_type\' => array( \'service\' ),
    \'posts_per_page\' => \'-1\',
    \'orderby\' => \'title\',
    \'order\' => \'ASC\',
    \'post__in\' => $service_ids_array,
);

$all_services = new WP_Query( $args );
但是,这只是从按标题排序的ID数组中获取所有服务。

这是我试图实现的逻辑,但如果有更好的解决方案,我很乐意使用它。

所以我的逻辑是,从根级别的数组中获取所有帖子。因此父ID=0。之后,我运行这些ID的循环,并在循环中检查它们的子ID是否存在于$service_ids_array 或者不是。并显示它们是否存在。

但是如果数组中只有子ID呢?在这种情况下,这种逻辑将不会成功。

1 个回复
SO网友:Antti Koskinen

我认为您只需要循环这个循环,首先构建一个助手数组来包含层次结构,然后使用它来打印出任何必要的html。将生成的助手数组缓存到瞬态可能是一个节省处理时间的好主意。

// is there a transient?
$transient = get_transient( "parent_children_ids_{$post_id}" );

if ( ! $transient ) {
  // initial query
  $all_services = new WP_Query( $args );
  
  // first sort found posts to a helper associative array
  $posts_by_id = array();
  foreach ($all_services->posts as $service) {
    $posts_by_id[$service->ID]$service;
  }
  
  // create hierarchy array
  $parent_children_ids = array();
  // track parents IDs that are not in found posts
  $missing_parent_ids = array();
  
  // WP_Query by default returns array of WP_Post objects
  // WP_Post has a property post_parent, which is the ID of the parent post, if such is set
  foreach ($all_services->posts as $service) {
    // add parents as top level keys
    if ( ! $service->post_parent ) {
      if ( ! isset($parent_children_ids[$service->ID]) ) {
        $parent_children_ids[$service->ID] = array();
      }
      continue;
    }
  
    // add the parent to the array, if it hasn\'t been added already
    if ( ! isset( $parent_children_ids[$service->post_parent] ) ) {
      $parent_children_ids[$service->post_parent] = array();
    }
  
    // should the parent be queried
    if ( ! isset( $posts_by_id[$service->post_parent] ) ) {
      $missing_parent_ids[] = $service->post_parent;
    }
  
    // append the post to the child array
    $parent_children_ids[$service->post_parent][] = $service->ID;
  }
  
  // query the missing parent posts
  if ( $missing_parent_ids ) {
    $missing_parents = new WP_Query(\'post__in\' => $missing_parent_ids);
    // push the found posts to the posts helper array
    foreach ($missing_parents->posts as $service) {
      $posts_by_id[$service->ID]$service;
    }
  }

  // do some further sorting, if needed..
  
  // perhaps save the $parent_children_ids to an transient
  // to skip the previous processing for a suitable length of time
  // remember to clear the transient when the source data changes to have the transient rebuilt
  set_transient( "parent_children_ids_{$post_id}", $parent_children_ids, DAY_IN_SECONDS );
} else {
  $parent_children_ids = $transient;
}

// loop the parents and chilrend array
foreach ($parent_children_ids as $parent_id => $child_ids) {
  $parent = $posts_by_id[$parent_id];
  // parent code..

  foreach ($child_ids as $child_id) {
    $child = $posts_by_id[$child_id];
    // child code...
  }
}