0

Im using cpt for events and i need to display them in a calendar. most of the events are future. i managed to query the right ones by post_status at the archive, but I need to do the same at the calendar. i'm using plugin called "Custom Post Type Calendar Widget" - very simple plugin that creates calendar for cpt as widget by query straight from mysql. i hacked it for my needs:

<?php
/*
Plugin Name: Custom Post Type Calendar Widget
Plugin URI: http://pippinsplugins.com/
Description: Provides a calendar widget that can display custom post types
Version: 1.0
Author: Pippin Williamson
Author URI: http://pippinsplugins.com
*/

/**
 * CPT Calendar Widget Class
 */
  class pippin_cpt_calendar extends WP_Widget {


  /** constructor */
  function pippin_cpt_calendar() {
      parent::WP_Widget(false, $name = 'CPT Calendar'); 
  }

  /** @see WP_Widget::widget */
  function widget($args, $instance) {   
      extract( $args );
      $title            = apply_filters('widget_title', $instance['title']);
        $posttype_enabled = $instance['posttype_enabled'];
      $posttype         = $instance['posttype'];
      ?>
        <?php echo $before_widget; ?>
            <?php if ( $title )
                echo $before_title . $title . $after_title; ?>
                <div class="widget_calendar">
                    <div id="calendar_wrap">
                        <?php if($posttype_enabled == true) {
                            ucc_get_calendar(array($posttype));
                        } else {
                            ucc_get_calendar();
                        } ?>
                    </div>
                </div>
        <?php echo $after_widget; ?>
      <?php
  }

  /** @see WP_Widget::update */
  function update($new_instance, $old_instance) {       
    $instance = $old_instance;
    $instance['title'] = strip_tags($new_instance['title']);
    $instance['posttype_enabled'] = $new_instance['posttype_enabled'];
    $instance['posttype'] = $new_instance['posttype'];
      return $instance;
  }

  /** @see WP_Widget::form */
  function form($instance) {    

        $posttypes = get_post_types('', 'objects');

    $title = esc_attr($instance['title']);
        $posttype_enabled   = esc_attr($instance['posttype_enabled']);
        $posttype   = esc_attr($instance['posttype']);
      ?>
      <p>
        <label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('Title:'); ?></label> 
        <input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo $title; ?>" />
      </p>
    <p>
        <input id="<?php echo $this->get_field_id('posttype_enabled'); ?>" name="<?php echo $this->get_field_name('posttype_enabled'); ?>" type="checkbox" value="1" <?php checked( '1', $posttype_enabled ); ?>/>
        <label for="<?php echo $this->get_field_id('posttype_enabled'); ?>"><?php _e('Show only one post type?'); ?></label> 
      </p>
    <p> 
        <label for="<?php echo $this->get_field_id('posttype'); ?>"><?php _e('Choose the Post Type to display'); ?></label> 
        <select name="<?php echo $this->get_field_name('posttype'); ?>" id="<?php echo $this->get_field_id('posttype'); ?>" class="widefat">
            <?php
            foreach ($posttypes as $option) {
                echo '<option value="' . $option->name . '" id="' . $option->name . '"', $posttype == $option->name ? ' selected="selected"' : '', '>', $option->name, '</option>';
            }
            ?>
        </select>       
    </p>
      <?php 
  }
 } 

       // register CPT Calendar widget

     add_action('widgets_init', create_function('', 'return  register_widget("pippin_cpt_calendar");'));



  /* ucc_get_calendar() :: Extends get_calendar() by including custom post  types.
  * Derived from get_calendar() code in /wp-includes/general-template.php.
  */

  function ucc_get_calendar( $post_types = '' , $initial = true , $echo = true ) {
global $wpdb, $m, $monthnum, $year, $wp_locale, $posts;

if ( empty( $post_types ) || !is_array( $post_types ) ) {
  $args = array(
    'public' => true ,
    '_builtin' => false
  );
  $output = 'names';
  $operator = 'and';

  $post_types = get_post_types( $args , $output , $operator );
  $post_types = array_merge( $post_types , array( 'post' ) );
} else {
  /* Trust but verify. */
  $my_post_types = array();
  foreach ( $post_types as $post_type ) {
    if ( post_type_exists( $post_type ) )
      $my_post_types[] = $post_type;
  }
  $post_types = $my_post_types;
}
$post_types_key = implode( '' , $post_types );
$post_types = "'" . implode( "' , '" , $post_types ) . "'";

$cache = array();
$key = md5( $m . $monthnum . $year . $post_types_key );
if ( $cache = wp_cache_get( 'get_calendar' , 'calendar' ) ) {
  if ( is_array( $cache ) && isset( $cache[$key] ) ) {
    remove_filter( 'get_calendar' , 'ucc_get_calendar_filter' );
    $output = apply_filters( 'get_calendar',  $cache[$key] );
    add_filter( 'get_calendar' , 'ucc_get_calendar_filter' );
    if ( $echo ) {
      echo $output;
      return;
    } else {
      return $output;
    }
  }
}

if ( !is_array( $cache ) )
  $cache = array();

// Quick check. If we have no posts at all, abort!
if ( !$posts ) {
  $sql = "SELECT 1 as test FROM $wpdb->posts WHERE post_type IN ( $post_types ) AND post_status IN ( 'publish','future' ) LIMIT 1";
  $gotsome = $wpdb->get_var( $sql );
  if ( !$gotsome ) {
    $cache[$key] = '';
    wp_cache_set( 'get_calendar' , $cache , 'calendar' );
    return;
  }
}

if ( isset( $_GET['w'] ) )
  $w = '' . intval( $_GET['w'] );

// week_begins = 0 stands for Sunday
$week_begins = intval( get_option( 'start_of_week' ) );

// Let's figure out when we are
if ( !empty( $monthnum ) && !empty( $year ) ) {
  $thismonth = '' . zeroise( intval( $monthnum ) , 2 );
  $thisyear = ''.intval($year);
} elseif ( !empty( $w ) ) {
  // We need to get the month from MySQL
  $thisyear = '' . intval( substr( $m , 0 , 4 ) );
  $d = ( ( $w - 1 ) * 7 ) + 6; //it seems MySQL's weeks disagree with PHP's
  $thismonth = $wpdb->get_var( "SELECT DATE_FORMAT( ( DATE_ADD( '${thisyear}0101' , INTERVAL $d DAY ) ) , '%m' ) " );
} elseif ( !empty( $m ) ) {
  $thisyear = '' . intval( substr( $m , 0 , 4 ) );
  if ( strlen( $m ) < 6 )
      $thismonth = '01';
  else
      $thismonth = '' . zeroise( intval( substr( $m , 4 , 2 ) ) , 2 );
} else {
  $thisyear = gmdate( 'Y' , current_time( 'timestamp' ) );
  $thismonth = gmdate( 'm' , current_time( 'timestamp' ) );
}

$unixmonth = mktime( 0 , 0 , 0 , $thismonth , 1 , $thisyear);

// Get the next and previous month and year with at least one post
$previous = $wpdb->get_row( "SELECT DISTINCT MONTH( post_date ) AS month , YEAR( post_date ) AS year
  FROM $wpdb->posts
  WHERE post_date < '$thisyear-$thismonth-01'
  AND post_type IN ( $post_types ) AND post_status IN ( 'publish','future' )
    ORDER BY post_date DESC
    LIMIT 1" );
$next = $wpdb->get_row( "SELECT DISTINCT MONTH( post_date ) AS month, YEAR( post_date ) AS year
  FROM $wpdb->posts
  WHERE post_date > '$thisyear-$thismonth-01'
  AND MONTH( post_date ) != MONTH( '$thisyear-$thismonth-01' )
  AND post_type IN ( $post_types ) AND post_status IN ( 'publish','future' )
    ORDER  BY post_date ASC
    LIMIT 1" );

/* translators: Calendar caption: 1: month name, 2: 4-digit year */
$calendar_caption = _x( '%1$s %2$s' , 'calendar caption' );
$calendar_output = '<table id="wp-calendar" summary="' . esc_attr__( 'Calendar' ) . '">
<caption>' . sprintf( $calendar_caption , $wp_locale->get_month( $thismonth ) , date( 'Y' , $unixmonth ) ) . '</caption>
<thead>
<tr>';

$myweek = array();

for ( $wdcount = 0 ; $wdcount <= 6 ; $wdcount++ ) {
  $myweek[] = $wp_locale->get_weekday( ( $wdcount + $week_begins ) % 7 );
}

foreach ( $myweek as $wd ) {
  $day_name = ( true == $initial ) ? $wp_locale->get_weekday_initial( $wd ) : $wp_locale->get_weekday_abbrev( $wd );
  $wd = esc_attr( $wd );
  $calendar_output .= "\n\t\t<th scope=\"col\" title=\"$wd\">$day_name</th>";
}

$calendar_output .= '
</tr>
</thead>

<tfoot>
<tr>';
// print_r(cptda_get_month_link( $previous->year , $previous->month , 'events'));
// if ( $previous ) {    $calendar_output .= "\n\t\t" . '<td colspan="3" id="prev"><a href="' . cptda_get_month_link( $previous->year , $previous->month , 'events') . '" title="' . sprintf( __( 'View posts for %1$s %2$s' ) , $wp_locale->get_month( $previous->month ) , date( 'Y' , mktime( 0 , 0 , 0 , $previous->month , 1 , $previous->year ) ) ) . '">&laquo; ' . $wp_locale->get_month_abbrev( $wp_locale->get_month( $previous->month ) ) . '</a></td>';
if ( $previous ) {    $calendar_output .= "\n\t\t" . '<td colspan="3" id="prev"><a href="' . get_month_link( $previous->year , $previous->month ) . '" title="' . sprintf( __( 'View posts for %1$s %2$s' ) , $wp_locale->get_month( $previous->month ) , date( 'Y' , mktime( 0 , 0 , 0 , $previous->month , 1 , $previous->year ) ) ) . '">&laquo; ' . $wp_locale->get_month_abbrev( $wp_locale->get_month( $previous->month ) ) . '</a></td>';
} else {
  $calendar_output .= "\n\t\t" . '<td colspan="3" id="prev" class="pad">&nbsp;</td>';
}

$calendar_output .= "\n\t\t" . '<td class="pad">&nbsp;</td>';

// if ( $next ) {    $calendar_output .= "\n\t\t" . '<td colspan="3" id="next"><a href="' . cptda_get_month_link( $next->year , $next->month , 'events') . '" title="' . esc_attr( sprintf( __( 'View posts for %1$s %2$s' ) , $wp_locale->get_month( $next->month ) , date( 'Y' , mktime( 0 , 0 , 0 , $next->month , 1 , $next->year ) ) ) ) . '">' . $wp_locale->get_month_abbrev( $wp_locale->get_month( $next->month ) ) . ' &raquo;</a></td>';
if ( $next ) {    $calendar_output .= "\n\t\t" . '<td colspan="3" id="next"><a href="' . get_month_link( $next->year , $next->month ) . '" title="' . esc_attr( sprintf( __( 'View posts for %1$s %2$s' ) , $wp_locale->get_month( $next->month ) , date( 'Y' , mktime( 0 , 0 , 0 , $next->month , 1 , $next->year ) ) ) ) . '">' . $wp_locale->get_month_abbrev( $wp_locale->get_month( $next->month ) ) . ' &raquo;</a></td>';
} else {
  $calendar_output .= "\n\t\t" . '<td colspan="3" id="next" class="pad">&nbsp;</td>';
}

$calendar_output .= '
</tr>
</tfoot>

<tbody>
<tr>';

// Get days with posts
$dayswithposts = $wpdb->get_results( "SELECT DISTINCT DAYOFMONTH( post_date )
  FROM $wpdb->posts WHERE MONTH( post_date ) = '$thismonth'
  AND YEAR( post_date ) = '$thisyear'
  AND post_type IN ( $post_types ) 
  AND post_status IN ( 'publish','future' )");
if ( $dayswithposts ) {
  foreach ($dayswithposts as $key => $daywith) {
    if (is_object($daywith)) {
      foreach ($daywith as $key => $value) {
        $daywithpost[] = $value;
      }
    }else{
        $daywithpost[] = $daywith[0];
      }
  }
} else {
  $daywithpost = array();
}

if ( strpos( $_SERVER['HTTP_USER_AGENT'] , 'MSIE' ) !== false || stripos( $_SERVER['HTTP_USER_AGENT'] , 'camino' ) !== false || stripos( $_SERVER['HTTP_USER_AGENT'] , 'safari' ) !== false )
  $ak_title_separator = "\n";
else
  $ak_title_separator = ', ';

$ak_titles_for_day = array();
$ak_post_titles = $wpdb->get_results( 
  "SELECT ID, post_title, DAYOFMONTH( post_date ) as dom "
  . "FROM $wpdb->posts "
  . "WHERE YEAR( post_date ) = '$thisyear' "
  . "AND MONTH( post_date ) = '$thismonth' "
  . "AND post_type IN ( $post_types ) AND post_status IN ( 'publish','future' )"
);

if ( $ak_post_titles ) {
  $links = array();
  foreach ( $ak_post_titles as $ak_post_title ) {
      if (count($ak_post_titles) > 1) {
        $links[] = get_post_permalink($ak_post_title->ID);
      }else{
        $link = array(get_post_permalink($ak_post_title->ID));
      }
      $post_title = esc_attr( apply_filters( 'the_title' , $ak_post_title->post_title , $ak_post_title->ID ) );

      if ( empty( $ak_titles_for_day['day_' . $ak_post_title->dom] ) )
        $ak_titles_for_day['day_'.$ak_post_title->dom] = '';
      if ( empty( $ak_titles_for_day["$ak_post_title->dom"] ) ) // first one
        $ak_titles_for_day["$ak_post_title->dom"] = $post_title;
      else
        $ak_titles_for_day["$ak_post_title->dom"] .= $ak_title_separator . $post_title;
  }
}

// See how much we should pad in the beginning
$pad = calendar_week_mod( date( 'w' , $unixmonth ) - $week_begins );
if ( 0 != $pad )
  $calendar_output .= "\n\t\t" . '<td colspan="' . esc_attr( $pad ) . '" class="pad">&nbsp;</td>';

$daysinmonth = intval( date( 't' , $unixmonth ) );
for ( $day = 1 ; $day <= $daysinmonth ; ++$day ) {
  if ( isset( $newrow ) && $newrow )
    $calendar_output .= "\n\t</tr>\n\t<tr>\n\t\t";
  $newrow = false;

  if ( $day == gmdate( 'j' , current_time( 'timestamp' ) ) && $thismonth == gmdate( 'm' , current_time( 'timestamp' ) ) && $thisyear == gmdate( 'Y' , current_time( 'timestamp' ) ) )
    $calendar_output .= '<td id="today">';
  else
    $calendar_output .= '<td>';

  if ( in_array( $day , $daywithpost ) ){ // any posts today?
      if(isset($link)){
        $calendar_output .= '<a href="';
        foreach ($link as $key => $onelink) {
          $calendar_output .= $onelink;
          if ($key == count($link)) {
            $calendar_output .= ' , ';
          }
        }
        $calendar_output .= '\" ';

      }else{
          $calendar_output .= '<button';
          $model = true;
      }

      $calendar_output .= " title=\"" . esc_attr( $ak_titles_for_day[$day] ). "\"";
      if(isset($model) && $model){
        $model =' ';
        $calendar_output .= " type='button' class='btn' data-toggle='modal' data-target='#".$thismonth."_".$day."'>";
        $calendar_output .= $day;
        $calendar_output .= "</button>";
         $model .= "<div class='modal fade' id='".$thismonth."_".$day."' tabindex='-1' role='dialog' aria-labelledby='myModalLabel'>
            <div class='modal-dialog modal-lg'>
              <div class='modal-content'>
                <div class='modal-header'>
                  <button type='button' class='close' data-dismiss='modal' aria-label='Close'><span aria-hidden='true'>&times;</span></button>
                  <h4 class='modal-title'>$day/$thismonth/$thisyear</h4>
                  </div>
                    <div class='modal-body'>";
                    foreach ( $ak_post_titles as $ak_post_title ) {
                      if($ak_post_title->dom == $day): 
                        $img = wp_get_attachment_image_src( get_post_thumbnail_id( $ak_post_title->ID ));
                        $model .= "
                          <div class='row'>
                            <div class='col-md-3'>
                             <div class='frame small' style='background-image:url(\"" . $img[0] ."\");>
                                 <a href='". get_permalink( $ak_post_title->ID ) . "'>
                                      <span class='shadow'></span>
                                  </a>
                              </div>
                            </div>
                            <div class='col-md-9'>
                             <a href='". get_permalink( $ak_post_title->ID ). "'>
                                <h5>"
                                . $ak_post_title->post_title .
                                "</h5>
                              </a>
                              <address title='date'>"
                                .get_the_date('l, d/m/Y H:i', $ak_post_title->ID ).
                              "</address>
                            </div>
                          </div>";
                    endif; }
                $model .= "
                </div>
              </div><!-- /.modal-content -->
            </div><!-- /.modal-dialog -->
          </div><!-- /.modal -->";
        $calendar_output .= '</td>';
        $calendar_output .= $model;
      }else{
        $calendar_output .= ">$day</a>";
        $calendar_output .= '</td>';
      }
  }else{
    $calendar_output .= $day;
    $calendar_output .= '</td>';
  }

  if ( 6 == calendar_week_mod( date( 'w' , mktime( 0 , 0 , 0 , $thismonth , $day , $thisyear ) ) - $week_begins ) )
    $newrow = true;
}

$pad = 7 - calendar_week_mod( date( 'w' , mktime( 0 , 0 , 0 , $thismonth , $day , $thisyear ) ) - $week_begins );
if ( $pad != 0 && $pad != 7 )
  $calendar_output .= "\n\t\t" . '<td class="pad" colspan="' . esc_attr( $pad ) . '">&nbsp;</td>';

$calendar_output .= "\n\t</tr>\n\t</tbody>\n\t</table>";

$cache[$key] = $calendar_output;
wp_cache_set( 'get_calendar' , $cache, 'calendar' );

remove_filter( 'get_calendar' , 'ucc_get_calendar_filter' );
$output = apply_filters( 'get_calendar',  $calendar_output );
add_filter( 'get_calendar' , 'ucc_get_calendar_filter' );

if ( $echo )
  echo $output;
else
  return $output;
}

function ucc_get_calendar_filter( $content ) {
  $output = ucc_get_calendar( '' , '' , false );
  return $output;
}
add_filter( 'get_calendar' , 'ucc_get_calendar_filter' , 10 , 2 );
  • mainly i changed the post status from 'publish' to an array of publish and future.

it works well - all the future posts of this month are shown but as i try to load the next month date archive I get 404.

I tried using this plugin: https://github.com/keesiemeijer/custom-post-type-date-archives which works, but its rewrite rules made a lot of trouble on some other rewrite i did.

so i think the problem of the next month may be solved with some rewriting rules. any ideas or experience at the subject?

  • Don't use publish date for event dates, store the event date in post meta in the form yyyy-mm-dd. – Milo Sep 17 '15 at 17:29
  • can not - I use it for displaying calendar by post date. cant find simple mysql query by meta type isoDate – Amit Rahav Sep 18 '15 at 22:01
  • You can query a meta date range with WP_Query and order by meta, you don't need to write any SQL. – Milo Sep 19 '15 at 4:32
  • can you explain it on the code rip attached above? – Amit Rahav Sep 20 '15 at 11:10
  • There are answers here dealing with using post meta for dates if you look around. This is one I wrote a while ago. – Milo Sep 20 '15 at 15:26

Your Answer

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

Browse other questions tagged or ask your own question.