PluginProbe
Polylang / 3.2.2
Polylang v3.2.2
3.8.9 3.8.8 3.8.7 3.8.6 3.8.5 3.8.4 3.8.3 2.7 2.7.0.1 2.7.1 2.7.2 2.7.3 2.7.4 2.8 2.8.1 2.8.2 2.8.3 2.8.4 2.9 2.9.1 2.9.2 3.0 3.0.1 3.0.2 3.0.3 All 233 releases
polylang / include / widget-calendar.php

widget-calendar.php in Polylang 3.2.2, at include/widget-calendar.php

283 lines 9.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * @package Polylang
4 */
5
6 if ( ! class_exists( 'WP_Widget_Calendar' ) ) {
7 require_once ABSPATH . '/wp-includes/default-widgets.php';
8 }
9
10 /**
11 * This classes rewrite the whole Calendar widget functionality as there is no filter on sql queries and only a filter on final output.
12 * Code last checked: WP 5.5.
13 *
14 * A request to add filters on sql queries exists: http://core.trac.wordpress.org/ticket/15202.
15 * Method used in 0.4.x: use of the get_calendar filter and overwrite the output of get_calendar function -> not very efficient (add 4 to 5 sql queries).
16 * Method used since 0.5: remove the WP widget and replace it by our own -> our language filter will not work if get_calendar is called directly by a theme.
17 *
18 * @since 0.5
19 */
20 class PLL_Widget_Calendar extends WP_Widget_Calendar {
21 protected static $pll_instance = 0; // Can't use $instance of WP_Widget_Calendar as it's private :/.
22
23 /**
24 * Outputs the content for the current Calendar widget instance.
25 * Modified version of the parent function to call our own get_calendar() method.
26 *
27 * @since 0.5
28 *
29 * @param array $args Display arguments including 'before_title', 'after_title',
30 * 'before_widget', and 'after_widget'.
31 * @param array $instance The settings for the particular instance of the widget.
32 */
33 public function widget( $args, $instance ) {
34 $title = ! empty( $instance['title'] ) ? $instance['title'] : '';
35
36 /** This filter is documented in wp-includes/widgets/class-wp-widget-pages.php */
37 $title = apply_filters( 'widget_title', $title, $instance, $this->id_base );
38
39 echo $args['before_widget'];
40 if ( $title ) {
41 echo $args['before_title'] . $title . $args['after_title'];
42 }
43 if ( 0 === self::$pll_instance ) { #modified#
44 echo '<div id="calendar_wrap" class="calendar_wrap">';
45 } else {
46 echo '<div class="calendar_wrap">';
47 }
48 empty( PLL()->curlang ) ? get_calendar() : self::get_calendar(); #modified#
49 echo '</div>';
50 echo $args['after_widget'];
51
52 self::$pll_instance++; #modified#
53 }
54
55 /**
56 * Modified version of the WP get_calendar() function to filter the queries.
57 *
58 * @since 0.5
59 *
60 * @param bool $initial Optional, default is true. Use initial calendar names.
61 * @param bool $echo Optional, default is true. Set to false for return.
62 * @return void|string Void if `$echo` argument is true, calendar HTML if `$echo` is false.
63 */
64 static public function get_calendar( $initial = true, $echo = true ) {
65 global $wpdb, $m, $monthnum, $year, $wp_locale, $posts;
66
67 $join_clause = PLL()->model->post->join_clause(); #added#
68 $where_clause = PLL()->model->post->where_clause( PLL()->curlang ); #added#
69
70 $key = md5( PLL()->curlang->slug . $m . $monthnum . $year ); #modified#
71 $cache = wp_cache_get( 'get_calendar', 'calendar' );
72
73 if ( $cache && is_array( $cache ) && isset( $cache[ $key ] ) ) {
74 /** This filter is documented in wp-includes/general-template.php */
75 $output = apply_filters( 'get_calendar', $cache[ $key ] );
76
77 if ( $echo ) {
78 echo $output;
79 return;
80 }
81
82 return $output;
83 }
84
85 if ( ! is_array( $cache ) ) {
86 $cache = array();
87 }
88
89 // Quick check. If we have no posts at all, abort!
90 if ( ! $posts ) {
91 $gotsome = $wpdb->get_var( "SELECT 1 as test FROM $wpdb->posts WHERE post_type = 'post' AND post_status = 'publish' LIMIT 1" );
92 if ( ! $gotsome ) {
93 $cache[ $key ] = '';
94 wp_cache_set( 'get_calendar', $cache, 'calendar' );
95 return;
96 }
97 }
98
99 if ( isset( $_GET['w'] ) ) {
100 $w = (int) $_GET['w'];
101 }
102 // week_begins = 0 stands for Sunday.
103 $week_begins = (int) get_option( 'start_of_week' );
104
105 // Let's figure out when we are.
106 if ( ! empty( $monthnum ) && ! empty( $year ) ) {
107 $thismonth = zeroise( (int) $monthnum, 2 );
108 $thisyear = (int) $year;
109 } elseif ( ! empty( $w ) ) {
110 // We need to get the month from MySQL.
111 $thisyear = (int) substr( $m, 0, 4 );
112 // It seems MySQL's weeks disagree with PHP's.
113 $d = ( ( $w - 1 ) * 7 ) + 6;
114 $thismonth = $wpdb->get_var( "SELECT DATE_FORMAT((DATE_ADD('{$thisyear}0101', INTERVAL $d DAY) ), '%m')" );
115 } elseif ( ! empty( $m ) ) {
116 $thisyear = (int) substr( $m, 0, 4 );
117 if ( strlen( $m ) < 6 ) {
118 $thismonth = '01';
119 } else {
120 $thismonth = zeroise( (int) substr( $m, 4, 2 ), 2 );
121 }
122 } else {
123 $thisyear = current_time( 'Y' );
124 $thismonth = current_time( 'm' );
125 }
126
127 $unixmonth = mktime( 0, 0, 0, $thismonth, 1, $thisyear );
128 $last_day = gmdate( 't', $unixmonth );
129
130 // Get the next and previous month and year with at least one post.
131 $previous = $wpdb->get_row(
132 "SELECT MONTH(post_date) AS month, YEAR(post_date) AS year
133 FROM $wpdb->posts $join_clause
134 WHERE post_date < '$thisyear-$thismonth-01'
135 AND post_type = 'post' AND post_status = 'publish' $where_clause
136 ORDER BY post_date DESC
137 LIMIT 1"
138 ); #modified#
139 $next = $wpdb->get_row(
140 "SELECT MONTH(post_date) AS month, YEAR(post_date) AS year
141 FROM $wpdb->posts $join_clause
142 WHERE post_date > '$thisyear-$thismonth-{$last_day} 23:59:59'
143 AND post_type = 'post' AND post_status = 'publish' $where_clause
144 ORDER BY post_date ASC
145 LIMIT 1"
146 ); #modified#
147
148 /* translators: Calendar caption: 1: Month name, 2: 4-digit year. */
149 $calendar_caption = _x( '%1$s %2$s', 'calendar caption' );
150 $calendar_output = '<table id="wp-calendar" class="wp-calendar-table">
151 <caption>' . sprintf(
152 $calendar_caption,
153 $wp_locale->get_month( $thismonth ),
154 gmdate( 'Y', $unixmonth )
155 ) . '</caption>
156 <thead>
157 <tr>';
158
159 $myweek = array();
160
161 for ( $wdcount = 0; $wdcount <= 6; $wdcount++ ) {
162 $myweek[] = $wp_locale->get_weekday( ( $wdcount + $week_begins ) % 7 );
163 }
164
165 foreach ( $myweek as $wd ) {
166 $day_name = $initial ? $wp_locale->get_weekday_initial( $wd ) : $wp_locale->get_weekday_abbrev( $wd );
167 $wd = esc_attr( $wd );
168 $calendar_output .= "\n\t\t<th scope=\"col\" title=\"$wd\">$day_name</th>";
169 }
170
171 $calendar_output .= '
172 </tr>
173 </thead>
174 <tbody>
175 <tr>';
176
177 $daywithpost = array();
178
179 // Get days with posts.
180 $dayswithposts = $wpdb->get_results(
181 "SELECT DISTINCT DAYOFMONTH(post_date)
182 FROM $wpdb->posts $join_clause WHERE post_date >= '{$thisyear}-{$thismonth}-01 00:00:00'
183 AND post_type = 'post' AND post_status = 'publish'
184 AND post_date <= '{$thisyear}-{$thismonth}-{$last_day} 23:59:59' $where_clause",
185 ARRAY_N
186 ); #modified#
187
188 if ( $dayswithposts ) {
189 foreach ( (array) $dayswithposts as $daywith ) {
190 $daywithpost[] = (int) $daywith[0];
191 }
192 }
193
194 // See how much we should pad in the beginning.
195 $pad = calendar_week_mod( gmdate( 'w', $unixmonth ) - $week_begins );
196 if ( 0 != $pad ) {
197 $calendar_output .= "\n\t\t" . '<td colspan="' . esc_attr( $pad ) . '" class="pad">&nbsp;</td>';
198 }
199
200 $newrow = false;
201 $daysinmonth = (int) gmdate( 't', $unixmonth );
202
203 for ( $day = 1; $day <= $daysinmonth; ++$day ) {
204 if ( isset( $newrow ) && $newrow ) {
205 $calendar_output .= "\n\t</tr>\n\t<tr>\n\t\t";
206 }
207 $newrow = false;
208
209 if ( current_time( 'j' ) == $day &&
210 current_time( 'm' ) == $thismonth &&
211 current_time( 'Y' ) == $thisyear ) {
212 $calendar_output .= '<td id="today">';
213 } else {
214 $calendar_output .= '<td>';
215 }
216
217 if ( in_array( $day, $daywithpost, true ) ) {
218 // Any posts today?
219 $date_format = gmdate( _x( 'F j, Y', 'daily archives date format' ), strtotime( "{$thisyear}-{$thismonth}-{$day}" ) );
220 /* translators: Post calendar label. %s: Date. */
221 $label = sprintf( __( 'Posts published on %s' ), $date_format );
222 $calendar_output .= sprintf(
223 '<a href="%s" aria-label="%s">%s</a>',
224 get_day_link( $thisyear, $thismonth, $day ),
225 esc_attr( $label ),
226 $day
227 );
228 } else {
229 $calendar_output .= $day;
230 }
231
232 $calendar_output .= '</td>';
233
234 if ( 6 == calendar_week_mod( gmdate( 'w', mktime( 0, 0, 0, $thismonth, $day, $thisyear ) ) - $week_begins ) ) {
235 $newrow = true;
236 }
237 }
238
239 $pad = 7 - calendar_week_mod( gmdate( 'w', mktime( 0, 0, 0, $thismonth, $day, $thisyear ) ) - $week_begins );
240 if ( 0 != $pad && 7 != $pad ) {
241 $calendar_output .= "\n\t\t" . '<td class="pad" colspan="' . esc_attr( $pad ) . '">&nbsp;</td>';
242 }
243
244 $calendar_output .= "\n\t</tr>\n\t</tbody>";
245
246 $calendar_output .= "\n\t</table>";
247
248 $calendar_output .= '<nav aria-label="' . __( 'Previous and next months' ) . '" class="wp-calendar-nav">';
249
250 if ( $previous ) {
251 $calendar_output .= "\n\t\t" . '<span class="wp-calendar-nav-prev"><a href="' . get_month_link( $previous->year, $previous->month ) . '">&laquo; ' .
252 $wp_locale->get_month_abbrev( $wp_locale->get_month( $previous->month ) ) .
253 '</a></span>';
254 } else {
255 $calendar_output .= "\n\t\t" . '<span class="wp-calendar-nav-prev">&nbsp;</span>';
256 }
257
258 $calendar_output .= "\n\t\t" . '<span class="pad">&nbsp;</span>';
259
260 if ( $next ) {
261 $calendar_output .= "\n\t\t" . '<span class="wp-calendar-nav-next"><a href="' . get_month_link( $next->year, $next->month ) . '">' .
262 $wp_locale->get_month_abbrev( $wp_locale->get_month( $next->month ) ) .
263 ' &raquo;</a></span>';
264 } else {
265 $calendar_output .= "\n\t\t" . '<span class="wp-calendar-nav-next">&nbsp;</span>';
266 }
267
268 $calendar_output .= '
269 </nav>';
270
271 $cache[ $key ] = $calendar_output;
272 wp_cache_set( 'get_calendar', $cache, 'calendar' );
273
274 if ( $echo ) {
275 /** This filter is documented in wp-includes/general-template.php */
276 echo apply_filters( 'get_calendar', $calendar_output );
277 return;
278 }
279 /** This filter is documented in wp-includes/general-template.php */
280 return apply_filters( 'get_calendar', $calendar_output );
281 }
282 }
283