根据月份ACF日期选择器字段获取用户

时间:2020-11-10 作者:fanatic21221

我有一个ACF字段“date\\u of\\u birth”,用于存储用户的生日,例如:20201226、20151225、19980701

Goal: 获取本月或下个月所有过生日的用户。

我目前有:

    $users_start_date_boundary = gmdate( \'Ymd\', strtotime( \'-1 month\' ) );
    $users_end_date_boundary   = gmdate( \'Ymd\', strtotime( \'+2 month\' ) );

    $wp_user_query = new WP_User_Query(
        [
            \'fields\'     => \'all_with_meta\',
            \'orderby\'    => \'date_of_birth\',
            \'order\'      => \'ASC\',
            \'meta_query\' => [
                [
                    \'key\'     => \'date_of_birth\',
                    \'value\'   => [ $users_start_date_boundary, $users_end_date_boundary ],
                    \'compare\' => \'BETWEEN\',
                    \'type\'    => \'DATE\',
                ],
            ],
        ]
    );

    return $wp_user_query->get_results();
然而,问题是,它只能让用户的出生年份为2020年。

如何根据给定的月份边界获取所有用户,同时忽略用户出生的年份/日期?

2 个回复
SO网友:Ivan Shatsky

Here is the code based on custom SQL query as suggested by @Rup that should work for you:

// get \'-1 month\' and \'+2 month\' dates as an array(\'YYYY\', \'MMDD\')
$before = str_split( gmdate( \'Ymd\', strtotime( \'-1 month\' ) ), 4 );
$after = str_split( gmdate( \'Ymd\', strtotime( \'+2 month\' ) ), 4 );
// if the before/after years are the same, should search for date >= before AND <= after
// if the before/after years are different, should search for date >= before OR <= after
$cmp = ( $before[0] == $after[0] ) ? \'AND\' : \'OR\';
// SQL query
$users = $wpdb->get_col( $wpdb->prepare(
    "SELECT user_id FROM {$wpdb->usermeta} WHERE meta_key = %s AND (SUBSTRING(meta_value, 5, 4) >= \'%s\' %s SUBSTRING(meta_value, 5, 4) <= \'%s\')",
    \'date_of_birth\', $before[1], $cmp, $after[1]
));

Update

Maybe I misunderstand your question looking at your code. The above code would give the list of users whose birthday passed no more than month ago or will happen no more than two months after the current date. To get the list of all users which have their birthday this month or next month, use the following code:

$current = gmdate( \'m\' );
$next = sprintf( "%02d", $current % 12 + 1 );
$users = $wpdb->get_col( $wpdb->prepare(
    "SELECT user_id FROM {$wpdb->usermeta} WHERE meta_key = %s AND (SUBSTRING(meta_value, 5, 2) = \'%s\' OR SUBSTRING(meta_value, 5, 2) = \'%s\')",
    \'date_of_birth\', $current, $next
));
SO网友:kero

我相信,由于ACF将这些值存储为Ymd 你必须写一些变通方法。一种可能的解决方案是,您连接到保存字段,并在另一个元字段中额外存储月份。这将允许查询=><= 使用元查询。

另一种解决方案是不以任意格式存储日期,而是以数据库能够理解的格式存储日期,然后使用数据库的现有功能。

\\add_filter(\'acf/update_value/type=date_picker\', function($value) {
    if (empty($value)) {
        return $value;
    }

    $dt = \\DateTime::createFromFormat(\'Ymd\', $value);
    return $dt->format(\\DateTime::ATOM);
});

\\add_filter(\'acf/load_value/type=date_picker\', function($value) {
    if (empty($value)) {
        return $value;
    }

    $dt = new \\DateTime($value);
    return $dt->format(\'Ymd\');
});
这两个过滤器将更改任何日期选择器,以将日期存储在格式良好的日期字符串中(如2005-08-15T15:52:01+00:00) 数据库很容易理解。你也可以针对这个特定的领域,阅读更多关于它的信息(doc for acf/update_valuedoc for acf/load_value). (Attention! 如果数据库中已经保存了日期,则应在应用此代码更改之前手动将其转换为新格式!)

检索可以使用的用户ID$wpdb 使用这样的自定义查询

$month = date(\'m\');
$userIds = $wpdb->get_col($wpdb->prepare(
    "SELECT user_id FROM {$wpdb->usermeta} WHERE meta_key = %s AND (MONTH(meta_value) = %d OR MONTH(meta_value) = %d)",
    \'date_of_birth\',
    $month,
    ($month % 12) + 1
));
(($month % 12) + 1 将在下个月获得,请参见this explanation)

看来WP_User_Query 无法按ID检索用户列表,因此您需要调用get_userdata() 对于每个用户ID,这可能不是最佳的,但这取决于您的用例。

相关推荐

ACF Date Based wp_query

我一直在尝试根据使用高级自定义字段创建的end\\u date自定义字段订购这些展览。我无法正常工作。我首先需要最近的约会。我也只需要在exhibition_status 属于past. 对于我的生活,我不能让这个工作,下面的代码只是最新的非工作互动。$args = array ( \'post_type\' => \'exhibitions\', \'meta_query\' => array( \'rel