obs
obs

Reputation: 807

wordpress get_posts ordered by custom field which is a custom date

i have a custom post type for members and the birth date is saved like 01.01.2013

$args = array(
    'numberposts'   => -1,
    'post_type'       => 'mitglied',
    'post_status'     => 'publish',
    'meta_key'      => 'geburtsdatum',
    'meta_value'    => date("d.m.Y"),
    'meta_compare' => '>',
    'orderby' => 'meta_value',
    'order' => 'ASC'
);
$geburtstage = get_posts ( $args );

i want a list with the birthdays of the members ordered by month and day like this

with the code above the list is ordered by day

also important is, that the ordering is not influenced by the year of birth

Upvotes: 0

Views: 3431

Answers (2)

obs
obs

Reputation: 807

I think my task is not solveable with get_posts only, so i did it in 3 steps.

First, i used get_posts to get all members

$args = array(
    'numberposts'   => -1,
    'post_type'       => 'mitglied',
);
$geburtstage = get_posts ( $args );

Then filled an array with the data. For sorting I made a timestamp with the day and month of the birthday, but the actual year. Although with this solution it would not have been necessary, I changed the date format to yyyy-mm-dd. @barakadam explained in his answer to my question how to do this. I use the wordpress plugin Advanced Custom Fields, so I fetch the custom fields with get_field()

$mitglieder = array( array() );
$i = 0;
foreach($geburtstage as $post){
    setup_postdata( $post );

    $datum = explode( "-",get_field('geburtsdatum') );

    $mitglieder[$i]['orderby'] = mktime(0, 0, 0, (int)$datum[1], (int)$datum[2], date('Y'));
    $mitglieder[$i]['name'] = get_field( 'name' );
    $i++;
}

The last step is using array_multisort to get the intended order

foreach ($mitglieder as $key => $row) {
    $dates[$key] = $row['orderby'];
}
array_multisort($dates, SORT_ASC, $mitglieder);

Thanks to @barakadam and @Christopher for participating.

Upvotes: 0

barakadam
barakadam

Reputation: 2249

You have stored the date in the wrong format in your custom field. You should have used a UNIX stamp or else a format like Y-m-d, which allows to sort chronologically. The only solution you have now is to retrieve your results without sorting them (forget 'order' => 'ASC') but also without limiting them (because your date limit is not working even if it looks like it does), create an array with all that, convert the date time as a UNIX timestamp (using strtotime) and sort by date... But my real advice would be to refactor your site using timestamps or properly formated dates (Y-m-d). You could create a loop that goes through every post and replaces the value of your custom field with the equivalent value in UNIX, using this :

$oldvalue = get_post_meta($post_id, 'geburtsdatum', true);  
update_post_meta($post_id, 'geburtsdatum', strtotime($old_value));  

Please backup your database before this or at least make a test on ore or two posts, but this should solve it. Then you will be able to later use :

date("d.m.Y", $yourunixstamp)

to get formated dates.

And then, also, your previous code will just become :

$args = array(
'numberposts'   => -1,
'post_type'       => 'mitglied',
'post_status'     => 'publish',
'meta_key'      => 'geburtsdatum',
'meta_value'    => time(),
'meta_compare' => '>',
'orderby' => 'meta_value',
'order' => 'ASC'
);
$geburtstage = get_posts ( $args );

Upvotes: 4

Related Questions