Last active
June 11, 2018 02:43
-
-
Save munyagu/731eaa201262afcbce6a3979f06a81ed to your computer and use it in GitHub Desktop.
カスタム投稿タイプ用カレンダーウィジット
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
Plugin Name: Custom Post Type Calendar | |
Author: nagasawa@barbwire.co.jp | |
Plugin URI: https://munyagu.com/ | |
Description: Calendar for custom post type archive. | |
Version: 0.1 | |
License: GPLv2 or later | |
License URI: http://www.gnu.org/licenses/gpl-2.0.html | |
*/ | |
/** | |
* Widget API: WP_Widget_Custom_Post_Type_Calendar class | |
* | |
* @package WordPress | |
* @subpackage Widgets | |
* @since 4.4.0 | |
*/ | |
/** | |
* Core class used to implement the Calendar widget. | |
* | |
* @since 2.8.0 | |
* | |
* @see WP_Widget | |
*/ | |
class WP_Widget_Custom_Post_Type_Calendar extends WP_Widget { | |
/** | |
* Ensure that the ID attribute only appears in the markup once | |
* | |
* @since 4.4.0 | |
* | |
* @static | |
* @var int | |
*/ | |
private static $instance = 0; | |
/** | |
* Sets up a new Calendar widget instance. | |
* | |
* @since 2.8.0 | |
*/ | |
public function __construct() { | |
$widget_ops = array( | |
'classname' => 'widget_calendar', | |
'description' => __( 'A calendar of your site’s Posts.' ), | |
'customize_selective_refresh' => true, | |
); | |
parent::__construct( 'custom-post-type-calendar', __( 'Custom Post Type Calendar' ), $widget_ops ); | |
} | |
/** | |
* Outputs the content for the current Calendar widget instance. | |
* | |
* @since 2.8.0 | |
* | |
* @param array $args Display arguments including 'before_title', 'after_title', | |
* 'before_widget', and 'after_widget'. | |
* @param array $instance The settings for the particular instance of the widget. | |
*/ | |
public function widget( $args, $instance ) { | |
$title = ! empty( $instance['title'] ) ? $instance['title'] : ''; | |
$post_type = ! empty( $instance['post_type'] ) ? $instance['post_type'] : 'post'; | |
/** This filter is documented in wp-includes/widgets/class-wp-widget-pages.php */ | |
$title = apply_filters( 'widget_title', $title, $instance, $this->id_base ); | |
echo $args['before_widget']; | |
if ( $title ) { | |
echo $args['before_title'] . $title . $args['after_title']; | |
} | |
if ( 0 === self::$instance ) { | |
echo '<div id="calendar_wrap" class="calendar_wrap">'; | |
} else { | |
echo '<div class="calendar_wrap">'; | |
} | |
get_custom_post_type_calendar(true, true, $post_type); | |
echo '</div>'; | |
echo $args['after_widget']; | |
self::$instance++; | |
} | |
/** | |
* Handles updating settings for the current Calendar widget instance. | |
* | |
* @since 2.8.0 | |
* | |
* @param array $new_instance New settings for this instance as input by the user via | |
* WP_Widget::form(). | |
* @param array $old_instance Old settings for this instance. | |
* @return array Updated settings to save. | |
*/ | |
public function update( $new_instance, $old_instance ) { | |
$instance = $old_instance; | |
$instance['title'] = sanitize_text_field( $new_instance['title'] ); | |
$instance['post_type'] = sanitize_text_field( $new_instance['post_type'] ); | |
return $instance; | |
} | |
/** | |
* Outputs the settings form for the Calendar widget. | |
* | |
* @since 2.8.0 | |
* | |
* @param array $instance Current settings. | |
*/ | |
public function form( $instance ) { | |
$instance = wp_parse_args( (array) $instance, array( 'title' => '', 'post_type' => '' ) ); | |
$title = sanitize_text_field( $instance['title'] ); | |
$post_type = sanitize_text_field( $instance['post_type'] ); | |
?> | |
<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 esc_attr($title); ?>" /></p> | |
<p><label for="<?php echo $this->get_field_id('post_type'); ?>"><?php _e('Post Type:'); ?></label> | |
<input class="widefat" id="<?php echo $this->get_field_id('post_type'); ?>" name="<?php echo $this->get_field_name('post_type'); ?>" type="text" value="<?php echo esc_attr($post_type); ?>" /></p> | |
<?php | |
} | |
} | |
/** | |
* Display calendar with days that have posts as links for custom post type. | |
* | |
* The calendar is cached, which will be retrieved, if it exists. If there are | |
* no posts for the month, then it will not be displayed. | |
* | |
* | |
* @global wpdb $wpdb | |
* @global int $m | |
* @global int $monthnum | |
* @global int $year | |
* @global WP_Locale $wp_locale | |
* @global array $posts | |
* | |
* @param bool $initial Optional, default is true. Use initial calendar names. | |
* @param bool $echo Optional, default is true. Set to false for return. | |
* @param bool $echo Optional, default is 'post'. Set custom post type. | |
* @return string|void String when retrieving. | |
*/ | |
function get_custom_post_type_calendar( $initial = true, $echo = true, $post_type = 'post' ) { | |
global $wpdb, $m, $monthnum, $year, $wp_locale, $posts; | |
$key = md5( $m . $monthnum . $year ); | |
$cache = wp_cache_get( 'get_custom_post_type_calendar', 'custom_post_type_calendar' ); | |
if ( $cache && is_array( $cache ) && isset( $cache[ $key ] ) ) { | |
/** This filter is documented in wp-includes/general-template.php */ | |
$output = apply_filters( 'get_custom_post_type_calendar', $cache[ $key ] ); | |
if ( $echo ) { | |
echo $output; | |
return; | |
} | |
return $output; | |
} | |
if ( ! is_array( $cache ) ) { | |
$cache = array(); | |
} | |
// Quick check. If we have no posts at all, abort! | |
if ( ! $posts ) { | |
$gotsome = $wpdb->get_var("SELECT 1 as test FROM $wpdb->posts WHERE post_type = '{$post_type}' AND post_status = 'publish' LIMIT 1"); | |
if ( ! $gotsome ) { | |
$cache[ $key ] = ''; | |
wp_cache_set( 'get_custom_post_type_calendar', $cache, 'custom_post_type_calendar' ); | |
return; | |
} | |
} | |
if ( isset( $_GET['w'] ) ) { | |
$w = (int) $_GET['w']; | |
} | |
// week_begins = 0 stands for Sunday | |
$week_begins = (int) get_option( 'start_of_week' ); | |
$ts = current_time( 'timestamp' ); | |
// Let's figure out when we are | |
if ( ! empty( $monthnum ) && ! empty( $year ) ) { | |
$thismonth = zeroise( intval( $monthnum ), 2 ); | |
$thisyear = (int) $year; | |
} elseif ( ! empty( $w ) ) { | |
// We need to get the month from MySQL | |
$thisyear = (int) substr( $m, 0, 4 ); | |
//it seems MySQL's weeks disagree with PHP's | |
$d = ( ( $w - 1 ) * 7 ) + 6; | |
$thismonth = $wpdb->get_var("SELECT DATE_FORMAT((DATE_ADD('{$thisyear}0101', INTERVAL $d DAY) ), '%m')"); | |
} elseif ( ! empty( $m ) ) { | |
$thisyear = (int) substr( $m, 0, 4 ); | |
if ( strlen( $m ) < 6 ) { | |
$thismonth = '01'; | |
} else { | |
$thismonth = zeroise( (int) substr( $m, 4, 2 ), 2 ); | |
} | |
} else { | |
$thisyear = gmdate( 'Y', $ts ); | |
$thismonth = gmdate( 'm', $ts ); | |
} | |
$unixmonth = mktime( 0, 0 , 0, $thismonth, 1, $thisyear ); | |
$last_day = date( 't', $unixmonth ); | |
// Get the next and previous month and year with at least one post | |
$previous = $wpdb->get_row("SELECT MONTH(post_date) AS month, YEAR(post_date) AS year | |
FROM $wpdb->posts | |
WHERE post_date < '$thisyear-$thismonth-01' | |
AND post_type = '{$post_type}' AND post_status = 'publish' | |
ORDER BY post_date DESC | |
LIMIT 1"); | |
$next = $wpdb->get_row("SELECT MONTH(post_date) AS month, YEAR(post_date) AS year | |
FROM $wpdb->posts | |
WHERE post_date > '$thisyear-$thismonth-{$last_day} 23:59:59' | |
AND post_type = '{$post_type}' AND post_status = 'publish' | |
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"> | |
<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 = $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>'; | |
if ( $previous ) { | |
$calendar_output .= "\n\t\t".'<td colspan="3" id="prev"><a href="' . get_month_link( $previous->year, $previous->month ) . '">« ' . | |
$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"> </td>'; | |
} | |
$calendar_output .= "\n\t\t".'<td class="pad"> </td>'; | |
if ( $next ) { | |
$calendar_output .= "\n\t\t".'<td colspan="3" id="next"><a href="' . get_month_link( $next->year, $next->month ) . '">' . | |
$wp_locale->get_month_abbrev( $wp_locale->get_month( $next->month ) ) . | |
' »</a></td>'; | |
} else { | |
$calendar_output .= "\n\t\t".'<td colspan="3" id="next" class="pad"> </td>'; | |
} | |
$calendar_output .= ' | |
</tr> | |
</tfoot> | |
<tbody> | |
<tr>'; | |
$daywithpost = array(); | |
// Get days with posts | |
$dayswithposts = $wpdb->get_results("SELECT DISTINCT DAYOFMONTH(post_date) | |
FROM $wpdb->posts WHERE post_date >= '{$thisyear}-{$thismonth}-01 00:00:00' | |
AND post_type = '{$post_type}' AND post_status = 'publish' | |
AND post_date <= '{$thisyear}-{$thismonth}-{$last_day} 23:59:59'", ARRAY_N); | |
if ( $dayswithposts ) { | |
foreach ( (array) $dayswithposts as $daywith ) { | |
$daywithpost[] = $daywith[0]; | |
} | |
} | |
// 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"> </td>'; | |
} | |
$newrow = false; | |
$daysinmonth = (int) 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', $ts ) && | |
$thismonth == gmdate( 'm', $ts ) && | |
$thisyear == gmdate( 'Y', $ts ) ) { | |
$calendar_output .= '<td id="today">'; | |
} else { | |
$calendar_output .= '<td>'; | |
} | |
if ( in_array( $day, $daywithpost ) ) { | |
// any posts today? | |
$date_format = date( _x( 'F j, Y', 'daily archives date format' ), strtotime( "{$thisyear}-{$thismonth}-{$day}" ) ); | |
/* translators: Post calendar label. 1: Date */ | |
$label = sprintf( __( 'Posts published on %s' ), $date_format ); | |
$link = get_day_link( $thisyear, $thismonth, $day ); | |
if( 'post' !== $post_type ){ | |
$link .= '?post_type=' . $post_type; | |
} | |
$calendar_output .= sprintf( | |
'<a href="%s" aria-label="%s">%s</a>', | |
$link, | |
esc_attr( $label ), | |
$day | |
); | |
} 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 ) .'"> </td>'; | |
} | |
$calendar_output .= "\n\t</tr>\n\t</tbody>\n\t</table>"; | |
$cache[ $key ] = $calendar_output; | |
wp_cache_set( 'get_custom_post_type_calendar', $cache, 'custom_post_type_calendar' ); | |
if ( $echo ) { | |
/** | |
* Filters the HTML calendar output. | |
* | |
* @since 3.0.0 | |
* | |
* @param string $calendar_output HTML output of the calendar. | |
*/ | |
echo apply_filters( 'get_custom_post_type_calendar', $calendar_output ); | |
return; | |
} | |
/** This filter is documented in wp-includes/general-template.php */ | |
return apply_filters( 'get_custom_post_type_calendar', $calendar_output ); | |
} | |
add_action( 'widgets_init', function () { | |
register_widget( 'WP_Widget_Custom_Post_Type_Calendar' ); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Based WordPress4.6.9 wp-includes/general-template.php.