register_custom_content_type($this);
add_filter('posts_where_request', array($this, 'filter_events_where'), 10, 1);
add_filter('posts_join_request', array($this, 'filter_events_join'), 10, 1);
$this->metadata = array(
'misc' => array(
new URL_Metadata('clickthru_url', 'Click-Thru URL'),
new URL_Metadata('ticket_purchase_url', 'Ticket Purchase URL'),
new Checkbox_Metadata('livenation_link', 'LiveNation Ticket Link'),
new Text_Metadata('ticket_price', 'Ticket Price'),
new Checkbox_Metadata('sold_out', 'Sold Out'),
)
);
}
public function get_content_type()
{
return 'calendar_event';
}
public function get_type_label()
{
return 'Event';
}
public function get_type_label_plural()
{
return 'Events';
}
public function get_type_publicly_queryable() {return true; }
public function get_type_icon_url()
{
return CP_BASE_URL.'/child-plugins/cp-calendar-events/menu-events.png';
}
public function get_type_permastructure()
{
return array('identifier' => 'events', 'structure' => '%identifier%/%year%/%monthnum%/%day%/%postname%/');
}
/**
* Returns an array of features the content type supports
*
* @return array
*/
public function get_type_supports()
{
//leaving out thumbnail until we can migrate featured images to use that instead.
return array('title', 'editor', 'excerpt', 'comments');
}
/**
* First fired on 'request' filter
* Sets order to 'asc' by default
* Sets month and year to current if not set and not a search
*
* @param array $query_vars
* @return array
*/
public function filter_request_query_vars($query_vars)
{
if(!is_admin() && (isset($query_vars['taxonomy']) && in_array( $query_vars['taxonomy'], get_object_taxonomies($this->get_content_type())) && $query_vars['post_type'] == $this->get_content_type()))
{
$query_vars['order'] = 'asc';
}
if(!is_admin() && isset($query_vars['post_type']) && $this->get_content_type() == $query_vars['post_type'])
{
if(!isset($query_vars['order']))
{
$query_vars['order'] = 'asc';
}
if(!isset($query_vars['monthnum']) && empty($query_vars['s']))
{
//set month to current
$query_vars['year'] = date('Y');
$query_vars['monthnum'] = date('m');
}
}
return $query_vars;
}
/**
* Replaces the submitdiv meta box with a custom one for events
* Adds metabox for remaining event data
*
* @param object $post
*/
public function add_meta_boxes($post)
{
global $wp_meta_boxes;
//replace the default submit metabox with the special one for events
$wp_meta_boxes[$this->get_content_type()]['side']['core']['submitdiv'] = array('id' => 'submitdiv', 'title' => 'Publish', 'callback' => array($this, 'submit_meta_box'), 'args' => null);
add_meta_box('eventmeta', "Misc Event Meta", array($this, 'misc_event_metabox'), $this->get_content_type(), 'normal', 'core');
}
/**
* Meta boxes for ticket price, ticket purchase url, clickthru url, etc
*
* @param unknown_type $post
*/
public function misc_event_metabox($post)
{
CP_Custom_Metadata_Base::display_all($this->metadata['misc'], $post->ID);
}
/**
* Save event for the data from the Misc Event Metabox
*
* @param int $post_id
*/
public function on_save_event($post_id, $post)
{
if(!((defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) || (defined('DOING_CRON') && DOING_CRON)))
{
if ( wp_is_post_revision($post_id) || wp_is_post_autosave($post_id))
{
return $post_id;
}
CP_Custom_Metadata_Base::save_all($this->metadata['misc'], $post_id);
}
}
/**
* Runs on 'wp_insert_post_data' filter to change the status from 'future' to 'publish'
* and validates and saves the end date in meta.
*
* @param array $data
* @param array $posted_data
* @return array
*/
public function filter_wp_insert_post_data($data, $posted_data)
{
if($data['post_type'] == $this->get_content_type())
{
if($posted_data['post_status'] == 'publish' || $data['post_status'] == 'future')
{
$data['post_status'] = 'publish';
}
if(isset($posted_data['update_event_nonce']) && wp_verify_nonce($posted_data['update_event_nonce'], 'update_event'))
{
//update the dates
$defaults = array(
'start_aa' => '',
'start_mm' => '',
'start_jj' => '',
'start_hh' => '',
'start_mn' => '',
'start_ss' => '',
'start_mr' => '',
'end_aa' => '',
'end_mm' => '',
'end_jj' => '',
'end_hh' => '',
'end_mn' => '',
'end_ss' => '',
'end_mr' => '',
);
$posted_data = array_merge($defaults, $posted_data);
$is_allday = isset($posted_data['event_is_allday']);
$start_aa = $posted_data['start_aa'];
$start_mm = $posted_data['start_mm'];
$start_jj = $posted_data['start_jj'];
$start_hh = $posted_data['start_hh'];
$start_mn = $posted_data['start_mn'];
$start_ss = $posted_data['start_ss'];
$start_mr = $posted_data['start_mr'];
$start_mr = ($start_mr == 'AM') ? 'AM' : 'PM';
$start_hh = (($start_mr == 'PM' && $start_hh != 12) || ($start_mr != 'PM' && $start_hh = 12)) ? $start_hh + 12 : $start_hh;
$start_aa = ($start_aa <= 0 ) ? date('Y') : $start_aa;
$start_mm = ($start_mm <= 0 ) ? date('n') : $start_mm;
$start_jj = ($start_jj > 31 ) ? 31 : $start_jj;
$start_jj = ($start_jj <= 0 ) ? date('j') : $start_jj;
if($is_allday)
{
$start_mn = $start_hh = '00';
}
else
{
$start_hh = ($start_hh > 23 ) ? $start_hh -24 : $start_hh;
$start_mn = ($start_mn > 59 ) ? $start_mn -60 : $start_mn;
}
$data['post_date'] = sprintf( "%04d-%02d-%02d %02d:%02d:00", $start_aa, $start_mm, $start_jj, $start_hh, $start_mn);
$end_aa = $posted_data['end_aa'];
$end_mm = $posted_data['end_mm'];
$end_jj = $posted_data['end_jj'];
$end_hh = $posted_data['end_hh'];
$end_mn = $posted_data['end_mn'];
$end_ss = $posted_data['end_ss'];
$end_mr = $posted_data['end_mr'];
$end_mr = ($end_mr == 'AM') ? 'AM' : 'PM';
$end_hh = (($end_mr == 'PM' && $end_hh != 12) || ($end_mr != 'PM' && $end_hh = 12)) ? $end_hh + 12 : $end_hh;
$end_aa = ($end_aa <= 0 ) ? date('Y') : $end_aa;
$end_mm = ($end_mm <= 0 ) ? date('n') : $end_mm;
$end_jj = ($end_jj > 31 ) ? 31 : $end_jj;
$end_jj = ($end_jj <= 0 ) ? date('j') : $end_jj;
if($is_allday)
{
$end_mn = $end_hh = '00';
}
else
{
$end_hh = ($end_hh > 23 ) ? $end_hh -24 : $end_hh;
$end_mn = ($end_mn > 59 ) ? $end_mn -60 : $end_mn;
}
$end_datetime = sprintf( "%04d-%02d-%02d %02d:%02d:00", $end_aa, $end_mm, $end_jj, $end_hh, $end_mn);
update_post_meta($posted_data['post_ID'], 'event_is_allday', $is_allday ? '1' : '0');
update_post_meta($posted_data['post_ID'], 'event_end_datetime', $end_datetime);
}
}
return $data;
}
/**
* Submit box for Events, replaces default submit box to add end date and all day option
*
* @param object $post
*/
public function submit_meta_box($post)
{
global $action, $wp_locale;
$post_type_obj = get_post_type_object($post->post_type);
$can_publish = current_user_can($post_type_obj->cap->publish_posts);
?>
post_status ) {
case 'private':
_e('Privately Published');
break;
case 'publish':
_e('Published');
break;
case 'future':
_e('Scheduled');
break;
case 'pending':
_e('Pending Review');
break;
case 'draft':
_e('Draft');
break;
}
?>
post_status || 'private' == $post->post_status || $can_publish ) : ?>
post_status ) { ?>style="display:none;" class="edit-post-status hide-if-no-js" tabindex='4'>
post_status )
{
$post->post_password = '';
$visibility = 'private';
$visibility_trans = __('Private');
}
elseif ( !empty( $post->post_password ) )
{
$visibility = 'password';
$visibility_trans = __('Password protected');
}
else
{
$visibility = 'public';
$visibility_trans = __('Public');
}
echo esc_html( $visibility_trans );
?>
ID )
{
$start_datetime = strtotime($post->post_date);
if(!$end_date_sql = get_post_meta($post->ID, 'event_end_datetime', true))
{
$end_datetime = $start_datetime;
}
else
{
$end_datetime = strtotime($end_date_sql);
}
$is_allday = (bool)get_post_meta($post->ID, 'event_is_allday', true);
}
else
{
$start_datetime = current_time('timestamp');
$end_datetime = current_time('timestamp');
$is_allday = false;
}
$start_jj = date( 'd', $start_datetime);
$start_mm = date( 'm', $start_datetime);
$start_aa = date( 'Y', $start_datetime);
$start_hh = date( 'g', $start_datetime);
$start_mn = date( 'i', $start_datetime);
$start_ss = date( 's', $start_datetime);
$start_mr = date( 'A', $start_datetime);
$end_jj = date( 'd', $end_datetime);
$end_mm = date( 'm', $end_datetime);
$end_aa = date( 'Y', $end_datetime);
$end_hh = date( 'g', $end_datetime);
$end_mn = date( 'i', $end_datetime);
$end_ss = date( 's', $end_datetime);
$end_mr = date( 'A', $end_datetime);
$start_month = "
';
$end_month = "
';
$start_day = '
';
$start_year = '
';
$start_hour = '
';
$start_minute = '
';
$start_meridian = '
';
$end_day = '
';
$end_year = '
';
$end_hour = '
';
$end_minute = '
';
$end_meridian = '
';
?>
/>
Start Date:
Start Time:
End Date:
End Time:
post_type == $this->get_content_type())
{
$where = str_replace("post_type = 'post'", "post_type = '".$this->get_content_type()."'", $where);
}
return $where;
}
/**
* Filters for handle_404 to allow months with no events not to 404
*
* @todo This is dependent on http://core.trac.wordpress.org/ticket/10722
*
* @param bool $handle_404
* @return bool
*/
public function should_handle_404($handle_404)
{
global $wp_query;
if($handle_404 && get_query_var('post_type') == $this->get_content_type())
{
$handle_404 = false;
}
return $handle_404;
}
/**
* The following 2 functions are a work around to keep empty months from 404ing
* until http://core.trac.wordpress.org/ticket/10722 is available.
*
*/
public function handle_404_workaround()
{
if(get_query_var('post_type') == $this->get_content_type() && is_date())
{
global $wp_query;
$wp_query->is_category = true;
$wp_query->queried_object = true;
}
}
public function reset_handle_404_workaround()
{
if(get_query_var('post_type') == $this->get_content_type() && is_date())
{
global $wp_query;
$wp_query->is_category = false;
unset($wp_query->queried_object);
}
}
/**
* Runs on 'posts_where_request' to exclude events that ended previous to today.
*
* @param string $where
* @return string
*/
public function filter_events_where($where)
{
global $wpdb;
if(!is_admin() && ($this->get_content_type() == get_query_var('post_type') || get_query_var('taxonomy') == 'venue'))
{
$gmt_time = current_time('timestamp');
$gmt_bod = mktime(0, 0, 0, date('m', $gmt_time), date('j', $gmt_time), date('Y', $gmt_time));
$where.= $wpdb->prepare(" AND (($wpdb->posts.post_date >= %s AND EndDate.meta_value is null) OR EndDate.meta_value >= %s)", gmdate('Y-m-d H:i:s', $gmt_bod), gmdate('Y-m-d H:i:s', $gmt_bod));
}
return $where;
}
/**
* Runs on 'posts_join_request' filter to add joins needed for filter_events_where method.
*
* @param string $join
* @return string
*/
public function filter_events_join($join)
{
global $wpdb;
if(!is_admin() && ($this->get_content_type() == get_query_var('post_type') || get_query_var('taxonomy') == 'venue'))
{
$join.= "LEFT JOIN $wpdb->postmeta EndDate ON EndDate.post_id = $wpdb->posts.ID AND EndDate.meta_key = 'event_end_datetime' ";
}
return $join;
}
/**
* Redirects the events home to the current month.
*
*/
public function redirect_event_landing()
{
if(in_array($_SERVER['REQUEST_URI'], array('/events', '/events/')))
{
wp_redirect(site_url('events'.date('/Y/m/')));
die();
}
if(function_exists('wpcom_is_vip') && (strpos($_SERVER['REQUEST_URI'], '/events?s=') !== false || strpos($_SERVER['REQUEST_URI'], '/events/?s=') !== false))
{
wp_redirect(site_url('events/search/'.urlencode($_REQUEST['s']).'/'));
die();
}
}
/**
* Adds a date based template for events
*
* @param string $template
* @return string
*/
public function filter_date_template($template)
{
if($this->get_content_type() == get_query_var('post_type'))
{
$date_template = locate_template(array('date-calendar_event.php'));
if($date_template) $template = $date_template;
}
return $date_template;
}
}
$cal_handler = new CP_Calendar_Event_Handler();
add_action('setup_custom_content', array($cal_handler, 'on_setup_custom_content'));
add_action('save_post', array($cal_handler, 'on_save_event'), 10, 2);
add_filter('request', array($cal_handler, 'filter_request_query_vars'));
//add_filter('posts_request', array($cal_handler, 'fix_request'), 10, 1); //added for debugging
add_action('init', array($cal_handler, 'redirect_event_landing'));
/**
* @todo the handle_404 filter requires ticket http://core.trac.wordpress.org/ticket/10722 to be available.
* the other two functions are a work around until then.
*/
//add_filter('handle_404', array($cal_handler, 'should_handle_404'), 10, 1);
add_action('posts_selection', array($cal_handler, 'handle_404_workaround'), 10, 1);
add_action('template_redirect', array($cal_handler, 'reset_handle_404_workaround'));
add_filter('date_template', array($cal_handler, 'filter_date_template'), 10, 1);
add_action('add_meta_boxes_'.$cal_handler->get_content_type(), array($cal_handler, 'add_meta_boxes'), 10, 1);
add_filter('wp_insert_post_data', array($cal_handler, 'filter_wp_insert_post_data'), 10, 2);