2

I have Radio with programs and they are associated to day of the weak.

Example:

1-Program Disco Nights plays at Monday and Friday

2-Pragram Crazy weekends play only at Sunday

3-etc

4-etc

Objective: List All the programs without repeating the ones are associated to multiple days based on current day and the next ones.

If today is Saturday have to list Saturday programs them sunday, monday etc etc but can't only be listed once the same program. (THE CLOSEST ONE)

How to achieve this?

On the back-office I have a multi select option which allow user to select multiple days based on plugin framework it stores the meta_value in a serialized array and can not be changed so I have to work with it.

a:3:{i:0;s:1:"3";i:1;s:1:"4";i:2;s:1:"6";}

Each day correspond to a value.

0 - Sunday

1 - Monday

2 - Tuesday

3 - Wednesday

4 - Thursday

5 - Friday

6 - Saturday

Now the hardest part to list it on-front office.

$today = date('w'); 
$args = array(
  'post_type' => 'programas',
  'meta_key' => 'audio_date',
  'orderby' => '  ?? closest one ??',

 $the_query = new WP_Query( $args );

);

Remember meta key returns a serialized array like this

    a:3:{i:0;s:1:"3";i:1;s:1:"4";i:2;s:1:"6";} 

I don't know how to compare the most closest programs to that day

while ( $the_query->have_posts() ) {
 $the_query->the_post();
 $items = get_post_meta( $post->ID, 'audio_date', true );

the_title();

if ( is_array($items) ) {  
  foreach ( $items as $item) :
    echo $item;
  endforeach; 
 }
}

Any ideas???? I tried also use post_type categories and make one category for each day but its not working also.

  • Do you have a save event for your plugin? Can you convert the days to post metadata / categories on that event? – jgraup Jan 11 '16 at 4:24
0

What about using just get_posts (removing the order_by argument), then looping through to create and array of programs, then building the output from that:

$posts = get_posts(array('post_type'=>'programas','meta_key'=>'audio_date'));

$programs = array();
foreach ($posts as $post) {
    $days = get_post_meta( $post->ID, 'audio_date', true );
    // $time = get_post_meta( $post->ID, 'audio_time', true);
    $found = false;
    foreach ($days as $day) {
         if (!$found) {$programs[$day][] = $post; $found = true;}
    }
    // foreach ($days as $day) {$programs[$day][$time] = $post;}
}

// start at today, loop for 7 days
$today = date('w'); 
for ($i = $today; $i < ($today + 7); $i++) {
    // fix to the actual day if value is over 6
    if ($i > 6) {$day = $i - 7;} else {$day = $i;}

    // could do this bit programmatically too
    if ($day == 0) {$daytitle = "<b>Sunday</b><br>";}
    if ($day == 1) {$daytitle = "<b>Monday</b><br>";}
    if ($day == 2) {$daytitle = "<b>Tuesday</b><br>";}
    if ($day == 3) {$daytitle = "<b>Wednesday</b><br>";}
    if ($day == 4) {$daytitle = "<b>Thursday</b><br>";}
    if ($day == 5) {$daytitle = "<b>Friday</b><br>";}
    if ($day == 6) {$daytitle = "<b>Saturday</b><br>";}

    if (isset($programs[$day])) {
        $output .= $daytitle;
        foreach ($programs[$day] as $time => $post) {
            $output .= $post->post_title;
            // $output .= " (".$time.");
            $output .= "<br>";
        }
    }
}

echo $output;

Of course, there may be another level of sorting complexity needed if you wanted to display the program times also, for now I have added some commented lines for that too.

  • Almost done! the problem is he is repeating more them once the same program. imgur.com/rbuhL1Y – Rodrigo Borba Jan 11 '16 at 5:03
  • not sure why you only want the first occurrence? but okay you can just change: foreach ($days as $day) {$programs[$day][] = $post;} to $found = false; foreach ($days as $day) {if (!$found) {$programs[$day][] = $post; $found = true;} } – majick Jan 11 '16 at 5:08
  • There is something wrong with the code Warning: Invalid argument supplied for foreach() Refer to this: foreach ($programs[$day] as $time => $post) i.imgur.com/4UQHTXV.jpg It gives the error my he keeps listing. Sorry if I'm bothering you but arrays is very confused to me. – Rodrigo Borba Jan 11 '16 at 5:55
  • ok yeah did not account for empty days, see edits... also changed it to only display the day if there is something on that day... – majick Jan 11 '16 at 6:06
  • AMAZING!!!!!! working like a charm. Thanks alot men. And I'm only want the first ocurrence because Will be listed in a slider. I got the tools to make the rest myself. Thanks alot :D – Rodrigo Borba Jan 11 '16 at 6:19
0

QUERY ALL PROGRAMAS - SORTED BY DAYS IN THE FUTURE

Loop for one week into the future and store the values to reduce calcs later.

$now = date('w');
$today = intval($now);
$futures = array();
for($offset = 0; $offset < 7; $offset ++) {
    if(($next = $today + $offset) > 6) $next -= 7; // day offset
    $futures[] = $next;
}

Do the query and collect data which will be stored into a multi-dimensional array for sorting later.

$programs = array();
$posts = get_posts(array('post_type'=>'programas','meta_key' => 'audio_date'));

foreach($posts as $post) {

    // deserialize our data for date checks
    $dates = maybe_unserialize(get_post_meta($post->ID, 'audio_date', true));

    // check for the next closest date
    foreach($futures as $offset => $next) {

        // we've found the next closest date
        if(in_array($next, $dates)) {

            // gather data
            $info = array(
                'post'   => $post,
                'ID'     => $post->ID,
                'next'   => $next,
                'offset' => $offset,
                'dates'  => $dates,
            );

            // store for later
            if( ! isset($programs[ $offset ])) $programs[ $offset ] = array();
            $programs[ $offset ][] = $info;

            // next date found -- onto the next program
            break; 
        }
    }

    // (optional) set tags based on dates for future queries
    //
    // foreach($dates as $day) wp_set_post_tags($post->ID, "day_$day", true);  
}

Sort the programs based on their day offset

ksort($programs);

Now loop through our sorted data and show each day

foreach($programs as $offset => $line_up) {

    // Name of the day
    $day = date('l', strtotime("+{$offset} days"));
    echo "<div>$day</div></ul>";

    foreach($line_up as $program) {

        // prep vars
        $title = $program[ 'post' ]->post_title;

        // output visuals
        echo "<li>$title</li>";
    }

    echo "</ul>";
}

QUERY DATES BY TAG

If you set tags, either in the loop above or elsewhere, then you have the option to query based on days.

// get today and tomorrow

$now = date('w');
$today = intval($now);
$today_tag = "day_$today";
$tomorrow = $today === 6 ? 0 : $today + 1;
$tomorrow_tag = "day_$today";

// do a query for those two days

$posts = get_posts(array('post_type'=>'programas','meta_key' => 'audio_date','tag'=>"$today_tag,$tomorrow_tag"));

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.