按多个自定义元字段排序

时间:2014-10-26 作者:Michael

我的插件中有一个名为members, 以及两个自定义字段;first_namelast_name. 我正试着把我的名字排在最后,然后是名字。我找到的唯一解决方案是利用函数拉入前两个查询元字段并替换它们(我遵循了dotnordic.se的教程)。然而,每当我尝试这一点,我没有帖子返回。我已经在下面发布了我的代码。如果您能帮助我解决代码中的问题或建议其他方法,我将不胜感激。

  // Shortcode Function
  function mba_members_list_code() {

  // WP_Query arguments
  $args = array (
  \'post_type\'       => \'member_data\',
  \'post_status\'     => \'active\',
  \'fields\'          => \'ids\',
  \'posts_per_page\'  => -1,
  \'meta_key\'        => \'last_name\',
  \'orderby\'         => \'meta_value\',
  \'order\'           => \'ASC\',
  \'meta_query\'      => array(
    array(
      \'key\'         => \'first_name\',
    ),
    array(
      \'key\'         => \'last_name\',
    ),
    array(
      \'key\'         => \'publicly_listed\',
      \'value\'       => \'true\',
    ),
  ),
);

// The Query
$posts = get_posts( $args );

// The Loop
if( $posts ) {
   echo "Total Members Found: " . count($posts) . "<br>";

   foreach ( $posts as $post ) {
      $q = get_post_meta($post);
      echo "<b>" . $q[\'first_name\'][0] . " " . $q[\'last_name\'][0] . "</b><br>";
      echo $q[\'city\'][0] . ", " . $q[\'state\'][0] . " " . $q[\'zip\'][0] . "<br>";
      echo "<a href=\'mailto:" . $q[\'email\'][0] . "\'>" . $q[\'email\'][0] . "</a><br>";
      echo "<br>"; 
   }
   unset( $post );       
}else{
  echo "<b>Sorry, we found no active members. Please be sure to check back soon.</b>";
}
}

EDIT

function customorder($orderby) {
global $wpdb;
return \' {$wpdb->postmeta}.meta_value, mt1.meta_value\';
//return str_replace(\'menu_order\', \'mt1.meta_value, mt2.meta_value\', $orderby);
}
我知道还有其他问题需要解决,以实现同样的功能;然而,每当我实现它时no records/posts 已返回。

2 个回复
最合适的回答,由SO网友:Pieter Goosen 整理而成

EDIT有关代码的完整解释,请参阅原始答案)

我的原始答案中的代码按预期工作,但会触发一个已知的bugusort (检查此处的错误报告#50688)

警告错误:[2]usort():用户比较函数修改了数组

只有当fields 参数在中的参数中设置get_posts, 因此,我能找到的唯一可行的解决方法是删除fields 参数,并使用正在检索的完整帖子。

这是无bug的工作版本

<?php
$args = array (
  \'post_type\'              => \'member_data\',
  \'post_status\'            => \'active\',
  \'posts_per_page\'         => -1,
  \'meta_query\'             => array(
    array(
      \'key\'       => \'first_name\',
    ),
    array(
      \'key\'       => \'last_name\',
    ),
    array(
      \'key\'       => \'publicly_listed\',
      \'value\'     => \'true\',
    ),
  ),
);

$posts = get_posts( $args );

usort( $posts, function( $a, $b ){

    // sort first by last name
    $compare = strnatcmp(get_post_meta($a->ID, \'last_name\', true), get_post_meta($b->ID, \'last_name\', true));

    // if last names are identical, sort by first name
    if(!$compare) {
        return strnatcmp(get_post_meta($a->ID, \'first_name\', true), get_post_meta($b->ID, \'first_name\', true));
    }else{
        return $compare;
    }

});

if( $posts ) {
   echo "Total Members Found: " . count($posts) . "<br>";

   foreach ( $posts as $post ) {
      $q = get_post_meta($post->ID);
      echo "<b>" . $q[\'first_name\'][0] . " " . $q[\'last_name\'][0] . "</b><br>";
      echo $q[\'city\'][0] . ", " . $q[\'state\'][0] . " " . $q[\'zip\'][0] . "<br>";
      echo "<a href=\'mailto:" . $q[\'email\'][0] . "\'>" . $q[\'email\'][0] . "</a><br>";
      echo "<br>"; 
   }
   unset( $post );       
}else{
  echo "<b>Sorry, we found no active members. Please be sure to check back soon.</b>";
}
}

ORIGINAL ANSWER

不幸的是,没有办法以本机方式进行这种类型的排序,因此您需要在这里采用不同的方法。

使用WP_Query, 甚至更好get_posts 正常检索您的帖子。在此阶段无需应用任何排序。在我个人看来,这是无用的,因为您只能按一个进行排序meta_value 而不是两个。我宁愿只使用php排序来根据需要排序帖子。(如果要使用分页,请使用WP_Query).

您将使用usort 要对帖子进行排序,请首先按last_name, 如果两个或两个以上的人共享同一个last_name, 我们将根据first_name.

这是一个概念:在我开始之前,我想指出几件事

您的meta_query 不幸的是,这里一团糟。所有内容都在一个数组中的一个数组中的一个数组中,其中一个数组中应该有3个单独的数组

我宁愿使用get_posts 此处并仅检索post ID,因为您不会使用任何postdata或返回的任何其他数据WP_Query

这是一项相当繁重的操作,因为每个帖子都会访问db两次。你必须注意利用这里的瞬变。

Now for the solution

如上所述使用get_posts 使用构造查询。我们将检索与这三个匹配的帖子meta_key\'s

$args = array (
  \'post_type\'              => \'member_data\',
  \'fields\'                 => \'ids\',
  \'post_status\'            => \'active\',
  \'posts_per_page\'         => -1,
  \'meta_query\'             => array(
    array(
      \'key\'       => \'first_name\',
    ),
    array(
      \'key\'       => \'last_name\',
    ),
    array(
      \'key\'       => \'publicly_listed\',
      \'value\'     => \'true\',
    ),
  ),
);

$posts = get_posts( $args );
我们现在要排序$posts 通过last_name 然后first_name 使用usort

usort( $posts, function( $a, $b ){

    // sort first by last name
    $compare = strnatcmp(get_post_meta($a, \'last_name\', true), get_post_meta($b, \'last_name\', true));

    // if last names are identical, sort by first name
    if(!$compare) {
        return strnatcmp(get_post_meta($a, \'first_name\', true), get_post_meta($b, \'first_name\', true));
    }else{
        return $compare;
    }

});
$posts 现在应按字母顺序排序last_name, 如果last_name 对于两个或两个以上的人是相同的,他们将按字母顺序排序first_name.

您的循环将如下所示

if( $posts ) {
   echo "Total Members Found: " . count($posts) . "<br>";

   foreach ( $posts as $post ) {
      $q = get_post_meta($post);
      echo "<b>" . $q[\'first_name\'][0] . " " . $q[\'last_name\'][0] . "</b><br>";
      echo $q[\'city\'][0] . ", " . $q[\'state\'][0] . " " . $q[\'zip\'][0] . "<br>";
      echo "<a href=\'mailto:" . $q[\'email\'][0] . "\'>" . $q[\'email\'][0] . "</a><br>";
      echo "<br>"; 
   }
   unset( $post );       
}else{
  echo "<b>Sorry, we found no active members. Please be sure to check back soon.</b>";
}
}

SO网友:Tom Bangham

从另一篇帖子中尝试类似的内容:

query_posts(
    array( 
        \'post_type\'      => \'custompost\', 
        \'posts_per_page\' => 4, 
        \'meta_key\'       => \'mydate\', 
        \'orderby\'        => \'meta_value\', 
        \'order\'          => \'ASC\', 
        \'meta_query\'     => array( 
            array( 
                \'key\'        => \'mydate\', 
                \'meta-value\' => $value, 
                \'value\'      => $today, 
                \'compare\'    => \'>=\', 
                \'type\'       => \'CHAR\' 
            ) 
        ) 
    )
);
尽管您只需要按姓氏排序,因为名字将在循环中按您调用它的顺序找到。

结束

相关推荐

Orderby参数在自定义查询中不起作用

我有一个非常奇怪的问题,我正在更新的网站。。。我想做的就是让帖子按降序排列,而不是随机排列。我有下面的代码,但当您将其从“rand”更改为“desc”时,它只是默认按“asc”顺序拉入帖子。我不知道为什么。此外,如果将“orderby”更改为“order”,则默认为升序。。。我在主题中做了一个搜索,看看发生了什么,但根本没有列出的地方。。。有人能把我引向正确的方向吗? <?php $args= array( \'post_type\' => \'waiting-f