PluginProbe
Timed Content / 2.0
Timed Content v2.0
2.99 trunk 1.0 1.1 1.2 2.0 2.1 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.10 2.11 2.12 2.15 2.2 2.3 2.3.1 2.4 2.5 2.5.1 2.50 2.51 2.52 All 67 releases
timed-content / timed-content.php

timed-content.php in Timed Content 2.0, at timed-content.php

1,118 lines 60.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 Plugin Name: Timed Content
4 Text Domain: timed-content
5 Plugin URI: http://wordpress.org/plugins/timed-content/
6 Description: Plugin to show or hide portions of a Page or Post based on specific date/time characteristics. These actions can either be processed either server-side or client-side, depending on the desired effect.
7 Author: K. Tough
8 Version: 2.0
9 Author URI: http://wordpress.org/plugins/timed-content/
10 */
11 if ( !class_exists( "timedContentPlugin" ) ) {
12
13 define( "TIMED_CONTENT_VERSION", 2.0 );
14 define( "TIMED_CONTENT_PLUGIN_URL", plugins_url() . '/timed-content' );
15 define( "TIMED_CONTENT_CLIENT_TAG", "timed-content-client" );
16 define( "TIMED_CONTENT_SERVER_TAG", "timed-content-server" );
17 define( "TIMED_CONTENT_RULE_TAG", "timed-content-rule" );
18 define( "TIMED_CONTENT_ZERO_TIME", "1970-Jan-01 00:00:00 +000" ); // Start of Unix Epoch
19 define( "TIMED_CONTENT_END_TIME", "2038-Jan-19 03:14:07 +000" ); // End of Unix Epoch
20 /* translators: date/time format for debugging messages. */
21 define( "TIMED_CONTENT_DT_FORMAT", __( "l, F jS, Y, g:i A T" , 'timed-content' ) );
22 define( "TIMED_CONTENT_RULE_TYPE", "timed_content_rule" );
23 define( "TIMED_CONTENT_RULE_POSTMETA_PREFIX", TIMED_CONTENT_RULE_TYPE . "_" );
24 // Required for styling the JQuery UI Datepicker and JQuery UI Timepicker
25 define( "TIMED_CONTENT_JQUERY_UI_CSS", "http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/themes/smoothness/jquery-ui.css" );
26 define( "TIMED_CONTENT_JQUERY_UI_TIMEPICKER_JS", TIMED_CONTENT_PLUGIN_URL."/js/jquery-ui-timepicker-0.3.3/jquery.ui.timepicker.js" );
27 define( "TIMED_CONTENT_JQUERY_UI_TIMEPICKER_CSS", TIMED_CONTENT_PLUGIN_URL."/js/jquery-ui-timepicker-0.3.3/jquery.ui.timepicker.css" );
28 require_once( "lib/customFields-settings.php" );
29 require_once( "lib/customFieldsInterface.php" );
30
31
32 /**
33 * Class timedContentPlugin
34 *
35 * Class that contains all of the functions required to run the plugin. This cuts down on
36 * the possibility of name collisions with other plugins.
37 */
38 class timedContentPlugin {
39
40 function timedContentPlugin() {
41 //constructor
42
43 }
44
45 /**
46 * Creates the Timed Content Rule post type and registers it with Wordpress
47 *
48 */
49 function timedContentRuleTypeInit()
50 {
51 $labels = array(
52 'name' => _x( 'Timed Content Rules', 'post type general name', 'timed-content' ),
53 'singular_name' => _x( 'Timed Content Rule', 'post type singular name', 'timed-content' ),
54 'add_new' => _x( 'Add New', TIMED_CONTENT_RULE_TYPE, 'timed-content' ),
55 'add_new_item' => __( 'Add New Timed Content Rule', 'timed-content' ),
56 'edit_item' => __( 'Edit Timed Content Rule', 'timed-content' ),
57 'new_item' => __( 'New Timed Content Rule', 'timed-content' ),
58 'view_item' => __( 'View Timed Content Rule', 'timed-content' ),
59 'search_items' => __( 'Search Timed Content Rules', 'timed-content' ),
60 'not_found' => __( 'No Timed Content Rules found', 'timed-content' ),
61 'not_found_in_trash' => __( 'No Timed Content Rules found in Trash', 'timed-content' ),
62 'parent_item_colon' => '',
63 'menu_name' =>_x( 'Timed Content Rules', 'post type general name', 'timed-content' )
64 );
65 $args = array(
66 'labels' => $labels,
67 'description' => __( 'Create regular schedules to show or hide selected content in a Page or Post.', 'timed-content' ),
68 'public' => false,
69 'publicly_queryable' => false,
70 'exclude_from_search' => false,
71 'show_ui' => true,
72 'show_in_menu' => true,
73 'show_in_nav_menus' => true,
74 'show_in_admin_bar' => true,
75 'query_var' => false,
76 'rewrite' => false,
77 'capability_type' => 'post',
78 'has_archive' => false,
79 'hierarchical' => false,
80 'menu_position' => 5,
81 'supports' => array( 'title' )
82 );
83 register_post_type( TIMED_CONTENT_RULE_TYPE, $args );
84 }
85
86
87 /**
88 * Filter to customize CRUD messages for Timed Content Rules
89 *
90 * @param array $messages Array of currently defined messages for post types
91 * @return mixed Array of messages with appropriate messages for Timed Content Rules added in
92 */
93 function timedContentRuleUpdatedMessages( $messages ) {
94 global $post;
95 // global $post_ID;
96
97 $messages[TIMED_CONTENT_RULE_TYPE] = array(
98 0 => '', // Unused. Messages start at index 1.
99 1 => __( 'Timed Content Rule updated.', 'timed-content' ),
100 2 => __( 'Custom field updated.', 'timed-content' ),
101 3 => __( 'Custom field deleted.', 'timed-content' ),
102 4 => __( 'Timed Content Rule updated.', 'timed-content' ),
103 /* translators: %s: date and time of the revision */
104 5 => isset( $_GET['revision'] ) ? sprintf( __( 'Timed Content Rule restored to revision from %s', 'timed-content' ), wp_post_revision_title( (int) $_GET['revision'], false ) ) : false,
105 6 => __( 'Timed Content Rule published.', 'timed-content' ),
106 7 => __( 'Timed Content Rule saved.', 'timed-content' ),
107 8 => __( 'Timed Content Rule submitted.', 'timed-content' ),
108 /* translators: %s: date and time to activate rule */
109 9 => sprintf( __('Timed Content Rule scheduled for: <strong>%1$s</strong>.', 'timed-content' ), date_i18n( __( 'M j, Y @ G:i' ), strtotime( $post->post_date ) ) ),
110 10 => __( 'Timed Content Rule draft updated.', 'timed-content' )
111 );
112
113 return $messages;
114 }
115
116 /**
117 * Advances a date/time by a set number of days
118 *
119 * @param int $current UNIX timestamp of the date/time before incrementing
120 * @param int $interval_multiplier Number of days to advance
121 * @return int Unix timestamp of the new date/time
122 */
123 function __getNextDay( $current, $interval_multiplier ) {
124 return strtotime( $interval_multiplier . " day", $current );
125 }
126
127 /**
128 * Advances a date/time by a set number of hours
129 *
130 * @param int $current UNIX timestamp of the date/time before incrementing
131 * @param int $interval_multiplier Number of hours to advance
132 * @return int Unix timestamp of the new date/time
133 */
134 function __getNextHour( $current, $interval_multiplier ) {
135 return strtotime( $interval_multiplier . " hour", $current );
136 }
137
138 /**
139 * Advances a date/time by a set number of weeks
140 *
141 * Advances a date/time by a set number of weeks. If given an array of days of the week, this function will
142 * advance the date/time to the next day in that array in the jumped-to week. Use this function if you're
143 * repeating an action on specific days of the week (i.e., on Weekdays, Tuesdays and Thursdays, etc.).
144 *
145 * @param int $current UNIX timestamp of the date/time before incrementing
146 * @param int $interval_multiplier Number of weeks to advance
147 * @param array $days Array of integers symbolizing the days of the week to
148 * repeat on (0 - Sunday, 1 - Monday, ..., 6 - Saturday).
149 * @return int Unix timestamp of the new date/time
150 */
151 function __getNextWeek( $current, $interval_multiplier, $days = array() ) {
152 if ( empty( $days ) ) return strtotime( $interval_multiplier . " week", $current );
153
154 $currentDayOfWeekIndex = date( "w", $current );
155 $days[] = $currentDayOfWeekIndex;
156 $daysOfWeek = array_values( $days );
157 if ( $currentDayOfWeekIndex == max( $daysOfWeek ) )
158 $pattern = ( ( 7 - $currentDayOfWeekIndex ) + ( 7 * ( $interval_multiplier - 1 ) ) + ( min( array_keys( $days ) ) ) ) . " day";
159 else {
160 $nextDayOfWeekIndex = $currentDayOfWeekIndex;
161 do {} while ( !isset( $days[++$nextDayOfWeekIndex] ) );
162 $pattern = ( $nextDayOfWeekIndex - $currentDayOfWeekIndex ) . " day";
163 }
164 return strtotime( $pattern, $current );
165 }
166
167 /**
168 * Advances a date/time by a set number of months
169 *
170 * Advances a date/time by a set number of months. When the date/time of the first active period lies
171 * on the 29th, 30th, or 31st of the month, this function will return a date/time on the the last day
172 * of the month for those months not containing those days.
173 *
174 * @param int $current UNIX timestamp of the date/time before incrementing
175 * @param int $start UNIX timestamp of the first active period's date/time
176 * @param int $interval_multiplier Number of months to advance
177 * @return int Unix timestamp of the new date/time
178 */
179 function __getNextMonth( $current, $start, $interval_multiplier ) {
180
181 // For most days in the month, it's pretty easy. Get the day of month of the starting date.
182 $startDay = date( "j", $start );
183
184 // If it's before or on the 28th, just jump the number of months and be done with it.
185 if ( $startDay <= 28 )
186 return strtotime( $interval_multiplier . " month", $current );
187
188 // If it's on the 29th, 30th, or 31st, it gets tricky. Some months don't have those days - so on those
189 // months we need to repeat on the last day of the month instead, but we also need to jump back to the
190 // correct day the following month. Let's say we want to repeat something on the 31st every month: this
191 // is what we expect to see for a pattern:
192 //
193 // .
194 // .
195 // .
196 // December 31st
197 // January 31st
198 // February 28th
199 // March 31st
200 // April 30th
201 // .
202 // .
203 // .
204 //
205 // Unfortunately, PHP relative date handling isn't that smart (add "+1 month" to January 31st, and you
206 // end up in March), so we'll have to figure it out ourselves by figuring out how many days to jump instead.
207
208 // We'll need to calculate this for each interval and return the timestamp after the last jump.
209 $temp_current = $current;
210 for ( $i = 0; $i < $interval_multiplier; $i++ ) {
211 // The pattern for jumping will be different in each interval.
212 /** @noinspection PhpUnusedLocalVariableInspection */
213 $temp_pattern = "";
214
215 // Get the month number of the current date.
216 //$currentMonth = date( "n", $temp_current );
217
218 // Get the number of days in the month of the current date.
219 $lastDayThisMonth = date( "t", strtotime( "this month", $temp_current ) );
220
221 // Get the number of days for the next month relative to the current date .
222 // Subtract 3 days from the next month to counter known month skipping bugs in PHP's relative date
223 // handling, that being the difference between the shortest possible month (non-leap February - 28 days)
224 // and the longest (Jan., Mar., May, Jul., Aug., Oct., Dec. - 31 days). This may be fixed in PHP 5.3.x
225 // but this should be backwards-compatible anyway.
226 $lastDayNextMonth = date( "t", strtotime( "-3 day next month", $temp_current ) );
227
228 // If the current month is longer than next month, follow this block
229 if ( $lastDayThisMonth > $lastDayNextMonth ) {
230 // If we're repeating on the last day of this month, jump the number of days next month
231 if ( $startDay == $lastDayThisMonth )
232 $temp_pattern = $lastDayNextMonth . " days";
233 // If the start day doesn't exist in the next month (i.e., no "31st" in June), jump the
234 // number of days next month plus the difference between the start day and the number of days this month
235 elseif ( $startDay > $lastDayNextMonth )
236 $temp_pattern = ( $lastDayThisMonth + $lastDayNextMonth - $startDay ). " days";
237 // Otherwise, jump ahead the number of days in this month
238 else
239 $temp_pattern = $lastDayThisMonth . " days";
240 }
241 // Or, if the current month is shorter than next month
242 elseif ( $lastDayThisMonth < $lastDayNextMonth ) {
243 // If the start day doesn't exist in this month (i.e., no "31st" in June), jump the
244 // number of days next month plus the difference between the start day and the number of days this month
245 if ( $startDay >= $lastDayThisMonth )
246 $temp_pattern = $startDay . " days";
247 // Otherwise, jump ahead the number of days in this month
248 else
249 $temp_pattern = $lastDayThisMonth . " days";
250 }
251 // If the current month and next month are equally long, jumping by "1 month" is fine
252 else
253 $temp_pattern = "1 month";
254
255 $temp_current = strtotime( $temp_pattern, $temp_current );
256 }
257 return $temp_current;
258
259 }
260
261 /**
262 * Advances a date/time to the 'n'th weekday of the next month (eg., first Wednesday, third Monday, last Friday, etc.).
263 *
264 * NB: if $ordinal is set to '4' and $day is set to '7', it wil return the last day of the month.
265 *
266 * @param int $current UNIX timestamp of the date/time before incrementing
267 * @param int $ordinal Integer symbolizing the ordinal (0 - first, 1 - second, 2 - third, 3 - fourth, 4 - last)
268 * @param int $day integers symbolizing the days of the week to
269 * repeat on (0 - Sunday, 1 - Monday, ..., 6 - Saturday, 7 - day).
270 * @return int Unix timestamp of the new date/time
271 */
272 function __getNthWeekdayOfMonth( $current, $ordinal, $day ) {
273
274 // First, get the month/year we need to work with
275 $the_month = date( "F", $current );
276 $the_year = date( "Y", $current );
277 $lastDayThisMonth = date( "t", $current );
278
279 // Get the time for the $current timestamp
280 $current_time = date( "g:i A", $current );
281 $the_day = "";
282
283 if ( $day == 7 ) { // If $day is "day of the month", get the day of month based on the ordinal
284 switch ( $ordinal ) {
285 case 1 : $the_day = "1"; break; // First day of the month //
286 case 2 : $the_day = "2"; break; // Second day of the month //
287 case 3 : $the_day = "3"; break; // Third day of the month //
288 case 4 : $the_day = "4"; break; // Fourth day of the month //
289 case 5 : $the_day = $lastDayThisMonth; break; // Last day of the month //
290 default : $the_day = "1"; break;
291 }
292 } else { // If $day is one of the days of the week...
293 $day_range = array();
294 switch ( $ordinal ) { // ...get a 7-day range based on the ordinal...
295 case 1 : $day_range = range( 1, 7 ); break; // First 7 days of the month //
296 case 2 : $day_range = range( 8, 14 ); break; // Second 7 days of the month //
297 case 3 : $day_range = range( 15, 21 ); break; // Third 7 days of the month //
298 case 4 : $day_range = range( 22, 28 ); break; // Fourth 7 days of the month //
299 case 5 : $day_range = range( $lastDayThisMonth - 6, $lastDayThisMonth ); break; // Last 7 days of the month //
300 default : $day_range = range( 1, 7 ); break;
301 }
302 foreach ( $day_range as $a_day ) { // ...and find the matching weekday in that range.
303 if ( $day == date( "l", strtotime( $the_month . " " . $a_day . ", " . $the_year ) ) ) {
304 $the_day = $a_day;
305 break;
306 }
307 }
308 }
309
310 // Build the date/time string for the correct day and return its timestamp
311 $pattern = $the_month . " " . $the_day . ", " . $the_year . ", " . $current_time;
312 return strtotime( $pattern );
313
314 }
315
316 /**
317 * Advances a date/time by a set number of years
318 *
319 * @param int $current UNIX timestamp of the date/time before incrementing
320 * @param int $interval_multiplier Number of years to advance
321 * @return int Unix timestamp of the new date/time
322 */
323 function __getNextYear( $current, $interval_multiplier ) {
324 return strtotime( $interval_multiplier . " year", $current );
325 }
326
327 /**
328 * Validates the various Timed Content Rule parameters and returns a series of error messages.
329 *
330 * @param $args Array of Timed Content Rule parameters
331 * @return array Array of error messages
332 */
333 function __validate( $args ) {
334 $errors = array();
335
336 $instance_start = strtotime( $args['instance_start']['date'] . '' . $args['instance_start']['time'] . ' ' . $args['timezone'] );
337 $instance_end = strtotime( $args['instance_end']['date'] . '' . $args['instance_end']['time'] . ' ' . $args['timezone'] );
338 $end_date = strtotime( $args['end_date'] . '' . $args['instance_start']['time'] . ' ' . $args['timezone'] );
339
340 if ( $args['instance_start']['date'] == "" )
341 $errors[] = __( "Date in Starting Date/Time must not be empty.", 'timed-content' );
342 if ( $args['instance_start']['time'] == "" )
343 $errors[] = __( "Time in Starting Date/Time must not be empty.", 'timed-content' );
344 if ( $args['instance_end']['date'] == "" )
345 $errors[] = __( "Date in Ending Date/Time must not be empty.", 'timed-content' );
346 if ( $args['instance_end']['time'] == "" )
347 $errors[] = __( "Time in Ending Date/Time must not be empty.", 'timed-content' );
348 if ( $args['interval_multiplier'] == "" )
349 $errors[] = __( "Repeat How Often? must not be empty.", 'timed-content' );
350 if ( !is_numeric( $args['interval_multiplier'] ) )
351 $errors[] = __( "Repeat How Often? must be a number.", 'timed-content' );
352 if ( ( $args['num_repeat'] == "" ) && ( $args['recurr_type'] == "recurrence_duration_num_repeat" ) )
353 $errors[] = __( "Repeat How Many Times? must not be empty.", 'timed-content' );
354 if ( ( !is_numeric( $args['num_repeat'] ) ) && ( $args['recurr_type'] == "recurrence_duration_num_repeat" ) )
355 $errors[] = __( "Repeat How Many Times? must be a number.", 'timed-content' );
356 if ( ( $args['end_date'] == "" ) && ( $args['recurr_type'] == "recurrence_duration_end_date" ) )
357 $errors[] = __( "End Date must not be empty.", 'timed-content' );
358 if ( false === $instance_start )
359 $errors[] = __( "Starting Date/Time must be valid.", 'timed-content' );
360 if ( false === $instance_end )
361 $errors[] = __( "Ending Date/Time must be valid.", 'timed-content' );
362 if ( $instance_start > $instance_end )
363 $errors[] = __( "Starting Date/Time must be before Ending Date/Time.", 'timed-content' );
364 if ( ( $instance_end > $end_date ) && ( $args['recurr_type'] == "recurrence_duration_end_date" ) )
365 $errors[] = __( "End Date must be after Ending Date/Time.", 'timed-content' );
366
367 return $errors;
368 }
369
370 /**
371 * Calculates the active periods for a Timed Content Rule
372 *
373 * @param $args Array of Timed Content Rule parameters
374 * @return array Array of active periods. Each value in the array describes an active period as
375 * an array itself with "start" and "end" keys and values that are either UNIX
376 * timestamps or human-readable dates, based on whether $args['human_readable']
377 * is set to true or false.
378 */
379 function __getRulePeriods( $args ) {
380 $active_periods = array();
381 $period_count = 0;
382
383 $human_readable = $args['human_readable'];
384 $freq = $args['freq'];
385 $timezone = $args['timezone'];
386 $recurr_type = $args['recurr_type'];
387 $num_repeat = intval( $args['num_repeat'] );
388 $end_date = $args['end_date'];
389 $days_of_week = $args['days_of_week'];
390 $interval_multiplier = $args['interval_multiplier'];
391 $instance_start_date = $args['instance_start']['date'];
392 $instance_start_time = $args['instance_start']['time'];
393 $instance_end_date = $args['instance_end']['date'];
394 $instance_end_time = $args['instance_end']['time'];
395 $monthly_pattern = $args['monthly_pattern'];
396 $monthly_pattern_ord = $args['monthly_pattern_ord'];
397 $monthly_pattern_day = $args['monthly_pattern_day'];
398
399 $temp_tz = date_default_timezone_get();
400 date_default_timezone_set( $timezone );
401 $right_now_t = time();
402
403 $instance_start = strtotime( $instance_start_date . " " . $instance_start_time . " " . $timezone ); // Beginning of first occurrence
404 $instance_end = strtotime( $instance_end_date . " " . $instance_end_time . " " . $timezone ); // End of first occurrence
405 $current = $instance_start;
406 $end_current = $instance_end;
407
408 if ( $recurr_type == "recurrence_duration_num_repeat" )
409 $last_occurrence_start = strtotime( TIMED_CONTENT_END_TIME );
410 else
411 $last_occurrence_start = strtotime( $end_date . " " . $instance_start_time . " " . $timezone );
412
413 if ( $human_readable == true ) {
414 $active_periods[$period_count]["start"] = date( TIMED_CONTENT_DT_FORMAT, $current );
415 $active_periods[$period_count]["end"] = date( TIMED_CONTENT_DT_FORMAT, $end_current );
416 } else {
417 $active_periods[$period_count]["start"] = $current;
418 $active_periods[$period_count]["end"] = $end_current;
419 }
420 if ( $right_now_t < $current ) {
421 $active_periods[$period_count]["status"] = "upcoming";
422 $active_periods[$period_count]["time"] = sprintf( __( '%s from now.', 'timed-content' ), human_time_diff( $current, $right_now_t ) );
423 } elseif ( ( $current <= $right_now_t ) && ( $right_now_t <= $end_current ) ) {
424 $active_periods[$period_count]["status"] = "active";
425 $active_periods[$period_count]["time"] = __( "Right now!", 'timed-content' );
426 } else {
427 $active_periods[$period_count]["status"] = "expired";
428 $active_periods[$period_count]["time"] = sprintf( __( '%s ago.', 'timed-content' ), human_time_diff( $end_current, $right_now_t ) );
429 }
430 $period_count++;
431
432 if ( $recurr_type == "recurrence_duration_end_date" )
433 $loop_test = "return ( \$current < \$last_occurrence_start );";
434 else
435 $loop_test = "return ( \$period_count <= \$num_repeat );";
436
437 while ( eval ( $loop_test ) ) {
438 $temp_current = "";
439 if ( $freq == 0 )
440 $current = $this->__getNextHour( $current, $interval_multiplier );
441 elseif ( $freq == 1 )
442 $current = $this->__getNextDay( $current, $interval_multiplier );
443 elseif ( $freq == 2 )
444 $current = $this->__getNextWeek( $current, $interval_multiplier, $days_of_week );
445 elseif ( $freq == 3 ) {
446 $current = $this->__getNextMonth( $current, $instance_start, $interval_multiplier );
447 $temp_current = $current;
448 if ( $monthly_pattern == "yes" ) $current = $this->__getNthWeekdayOfMonth( $current, $monthly_pattern_ord, $monthly_pattern_day );
449 } elseif ( $freq == 4 )
450 $current = $this->__getNextYear( $current, $interval_multiplier );
451
452 if ( eval ( $loop_test ) ) {
453 $end_current = $current + ( $instance_end - $instance_start );
454 if ( $human_readable == true ) {
455 $active_periods[$period_count]["start"] = date( TIMED_CONTENT_DT_FORMAT, $current );
456 $active_periods[$period_count]["end"] = date( TIMED_CONTENT_DT_FORMAT, $end_current );
457 } else {
458 $active_periods[$period_count]["start"] = $current;
459 $active_periods[$period_count]["end"] = $end_current;
460 }
461 if ( $right_now_t < $current ) {
462 $active_periods[$period_count]["status"] = "upcoming";
463 $active_periods[$period_count]["time"] = sprintf( _x( '%s from now.', 'Human readable time difference', 'timed-content' ), human_time_diff( $current, $right_now_t ) );
464 } elseif ( ( $current <= $right_now_t ) && ( $right_now_t <= $end_current ) ) {
465 $active_periods[$period_count]["status"] = "active";
466 $active_periods[$period_count]["time"] = __( "Right now!", 'timed-content' );
467 } else {
468 $active_periods[$period_count]["status"] = "expired";
469 $active_periods[$period_count]["time"] = sprintf( _x( '%s ago.', 'Human readable time difference', 'timed-content' ), human_time_diff( $end_current, $right_now_t ) );
470 }
471 $period_count++;
472 }
473
474 if ( ( $freq == 3 ) && ( $monthly_pattern == "yes" ) ) $current = $temp_current;
475 }
476 date_default_timezone_set( $temp_tz );
477 return $active_periods;
478 }
479
480 /**
481 * Wrapper for calling timedContentPlugin::__getRulePeriods() by the ID of a Timed Content Rule
482 *
483 * @param int $ID ID of the Timed Content Rule
484 * @param bool $human_readable If true, the active periods are returned as a human-readable date/time
485 * as defined by the constant TIMED_CONTENT_DT_FORMAT; otherwise, they are
486 * returned as UNIX timestamps.
487 * @return array Array of active periods
488 */
489 function getRulePeriodsById( $ID, $human_readable = false ) {
490 if ( TIMED_CONTENT_RULE_TYPE != get_post_type( $ID ) )
491 return array();;
492
493 $prefix = TIMED_CONTENT_RULE_POSTMETA_PREFIX;
494 $args = array();
495
496 $args['human_readable'] = (bool) $human_readable;
497 $args['freq'] = get_post_meta( $ID, $prefix . 'frequency', true );
498 $args['timezone'] = get_post_meta( $ID, $prefix . 'timezone', true );
499 $args['recurr_type'] = get_post_meta( $ID, $prefix . 'recurrence_duration', true );
500 $args['num_repeat'] = get_post_meta( $ID, $prefix . 'recurrence_duration_num_repeat', true );
501 $args['end_date'] = get_post_meta( $ID, $prefix . 'recurrence_duration_end_date', true );
502 $args['days_of_week'] = get_post_meta( $ID, $prefix . 'weekly_days_of_week_to_repeat', true );
503 if ( $args['freq'] == 0 ) $args['interval_multiplier'] = get_post_meta( $ID, $prefix . 'hourly_num_of_hours', true );
504 if ( $args['freq'] == 1 ) $args['interval_multiplier'] = get_post_meta( $ID, $prefix . 'daily_num_of_days', true );
505 if ( $args['freq'] == 2 ) $args['interval_multiplier'] = get_post_meta( $ID, $prefix . 'weekly_num_of_weeks', true );
506 if ( $args['freq'] == 3 ) $args['interval_multiplier'] = get_post_meta( $ID, $prefix . 'monthly_num_of_months', true );
507 if ( $args['freq'] == 4 ) $args['interval_multiplier'] = get_post_meta( $ID, $prefix . 'yearly_num_of_years', true );
508 $args['instance_start'] = get_post_meta( $ID, $prefix . 'instance_start', true );
509 $args['instance_end'] = get_post_meta( $ID, $prefix . 'instance_end', true );
510 $args['monthly_pattern'] = get_post_meta( $ID, $prefix . 'monthly_nth_weekday_of_month', true );
511 $args['monthly_pattern_ord'] = get_post_meta( $ID, $prefix . 'monthly_nth_weekday_of_month_nth', true );
512 $args['monthly_pattern_day'] = get_post_meta( $ID, $prefix . 'monthly_nth_weekday_of_month_weekday', true );
513
514 return $this->__getRulePeriods( $args );
515
516 }
517
518 /**
519 * Wrapper for calling timedContentPlugin::__getRulePeriods() based on the contents of the form fields
520 * of the Add Timed Content Rule and Edit Timed Content Rule screens. Output is sent to output as JSON
521 */
522 function timedContentPluginGetRulePeriodsAjax() {
523 if ( current_user_can( 'edit_posts' ) || current_user_can( 'edit_pages' ) ) {
524 $prefix = TIMED_CONTENT_RULE_POSTMETA_PREFIX;
525 $args = array();
526
527 $args['human_readable'] = ( ( ( isset( $_POST[$prefix . 'human_readable'] ) ) && ( $_POST[$prefix . 'human_readable'] == 'true' ) ) ? (bool)$_POST[$prefix . 'human_readable'] : false );
528 $args['freq'] = $_POST[$prefix . 'frequency'];
529 $args['timezone'] = $_POST[$prefix . 'timezone'];
530 $args['recurr_type'] = $_POST[$prefix . 'recurrence_duration'];
531 $args['num_repeat'] = $_POST[$prefix . 'recurrence_duration_num_repeat'];
532 $args['end_date'] = $_POST[$prefix . 'recurrence_duration_end_date'];
533 $args['days_of_week'] = ( isset( $_POST[$prefix . 'weekly_days_of_week_to_repeat'] ) ? $_POST[$prefix . 'weekly_days_of_week_to_repeat'] : array() );
534 $args['interval_multiplier'] = $_POST[$prefix . 'interval_multiplier'];
535 $args['instance_start'] = $_POST[$prefix . 'instance_start'];
536 $args['instance_end'] = $_POST[$prefix . 'instance_end'];
537 $args['monthly_pattern'] = $_POST[$prefix . 'monthly_nth_weekday_of_month'];
538 $args['monthly_pattern_ord'] = $_POST[$prefix . 'monthly_nth_weekday_of_month_nth'];
539 $args['monthly_pattern_day'] = $_POST[$prefix . 'monthly_nth_weekday_of_month_weekday'];
540
541 $response = json_encode( $this->__getRulePeriods( $args ) );
542
543 // response output
544 header( "Content-Type: application/json" );
545 echo $response;
546 }
547 die();
548
549 }
550
551 /**
552 * Returns a human-readable description of a Timed Content Rule
553 *
554 * @param $args Array of Timed Content Rule parameters
555 * @return string
556 */
557 function __getScheduleDescription( $args ) {
558 require("lib/Arrays_Definitions.php");
559
560 $interval_multiplier = 1;
561 $desc = "";
562
563 $errors = $this->__validate( $args );
564 if ( $errors ) {
565 $messages = "<div class=\"tcr-warning\">\n";
566 $messages .= "<p class=\"heading\">" . __( "Warning!", 'timed-content' ) . "</p>\n";
567 $messages .= "<p>" . __( "Some problems have been detected. Although you can still publish this rule, it may not work the way you expect.", 'timed-content' ) . "</p>\n";
568 $messages .= "<ul>\n";
569 foreach ( $errors as $error )
570 $messages .= " <li>" . $error . "</li>\n";
571 $messages .= "</ul>\n";
572 $messages .= "<p>" . __( "Check that all of the conditions for this rule are correct, and use Show Projected Dates/Times to ensure your rule is working properly.", 'timed-content' ) . "</p>\n";
573 $messages .= "</div>\n";
574 return $messages;
575 }
576
577 if ( $args['action'] )
578 $action = __( "Show the content", 'timed-content' );
579 else
580 $action = __( "Hide the content", 'timed-content' );
581 $freq = $args['freq'];
582 $timezone = $args['timezone'];
583 $recurr_type = $args['recurr_type'];
584 $num_repeat = intval( $args['num_repeat'] );
585 $end_date = $args['end_date'];
586 $days_of_week = $args['days_of_week'];
587 $interval_multiplier = $args['interval_multiplier'];
588 $instance_start_date = $args['instance_start']['date'];
589 $instance_start_time = $args['instance_start']['time'];
590 $instance_end_date = $args['instance_end']['date'];
591 $instance_end_time = $args['instance_end']['time'];
592 $monthly_pattern = $args['monthly_pattern'];
593 $monthly_pattern_ord = $args['monthly_pattern_ord'];
594 $monthly_pattern_day = $args['monthly_pattern_day'];
595
596 $desc = sprintf( _x( '%1$s on %2$s @ %3$s until %4$s @ %5$s.', 'Dates/times of first active period', 'timed-content' ), $action, $instance_start_date, $instance_start_time, $instance_end_date, $instance_end_time );
597
598 if ( $freq == 0 )
599 $desc .= "&nbsp;" . sprintf( _n( 'Repeat this action every hour.', 'Repeat this action every %d hours.', $interval_multiplier, 'timed-content' ), $interval_multiplier );
600 elseif ( $freq == 1 )
601 $desc .= "&nbsp;" . sprintf( _n( 'Repeat this action every day.', 'Repeat this action every %d days.', $interval_multiplier, 'timed-content' ), $interval_multiplier );
602 elseif ( $freq == 2 ) {
603 if ( ( $days_of_week ) && ( is_array( $days_of_week ) ) ) {
604 $days = array(); $days_list = "";
605 foreach ( $days_of_week as $v )
606 $days[] = $timed_content_rule_days_array[$v];
607 switch ( count( $days ) ) {
608 case 1: $days_list = sprintf( _x( '%1$s', 'List of one weekday', 'timed-content' ), $days[0] ); break;
609 case 2: $days_list = sprintf( _x( '%1$s and %2$s', 'List of two weekdays', 'timed-content' ), $days[0], $days[1] ); break;
610 case 3: $days_list = sprintf( _x( '%1$s, %2$s, and %3$s', 'List of three weekdays', 'timed-content' ), $days[0], $days[1], $days[2] ); break;
611 case 4: $days_list = sprintf( _x( '%1$s, %2$s, %3$s, and %4$s', 'List of four weekdays', 'timed-content' ), $days[0], $days[1], $days[2], $days[3] ); break;
612 case 5: $days_list = sprintf( _x( '%1$s, %2$s, %3$s, %4$s, and %5$s', 'List of five weekdays', 'timed-content' ), $days[0], $days[1], $days[2], $days[3], $days[4] ); break;
613 case 6: $days_list = sprintf( _x( '%1$s, %2$s, %3$s, %4$s, %5$s, and %6$s', 'List of six weekdays', 'timed-content' ), $days[0], $days[1], $days[2], $days[3], $days[4], $days[5] ); break;
614 case 7: $days_list = sprintf( _x( '%1$s, %2$s, %3$s, %4$s, %5$s, %6$s, and %7$s', 'List of all weekdays', 'timed-content' ), $days[0], $days[1], $days[2], $days[3], $days[4], $days[5], $days[6] ); break;
615 }
616 if ( $interval_multiplier == 1 )
617 $desc .= "&nbsp;" . sprintf( _x( 'Repeat this action every week on %s.', 'List the weekdays to repeat the rule when frequency is every week. %s is the list of weekdays.', 'timed-content' ), $days_list );
618 else
619 $desc .= "&nbsp;" . sprintf( _x( 'Repeat this action every %1$d weeks on %2$s.', 'List the weekdays to repeat the rule when frequency is every %1$d weeks. %2$s is the list of weekdays.', 'timed-content' ), $interval_multiplier, $days_list );
620 } else
621 $desc .= "&nbsp;" . sprintf( _n( 'Repeat this action every week.', 'Repeat this action every %d weeks.', $interval_multiplier, 'timed-content' ), $interval_multiplier );
622
623 } elseif ( $freq == 3 ) {
624 if ( $monthly_pattern == "yes" ) {
625 if ( $interval_multiplier == 1 )
626 $desc .= "&nbsp;" . sprintf( __( 'Repeat this action every month on the %1$s %2$s of the month.', 'timed-content' ), $timed_content_rule_ordinal_array[$monthly_pattern_ord], $timed_content_rule_ordinal_days_array[$monthly_pattern_day] );
627 else
628 $desc .= "&nbsp;" . sprintf( __( 'Repeat this action every %1$d months on the %2$s %3$s of the month.', 'timed-content' ), $interval_multiplier, $timed_content_rule_ordinal_array[$monthly_pattern_ord], $timed_content_rule_ordinal_days_array[$monthly_pattern_day] );
629 } else
630 $desc .= "&nbsp;" . sprintf( _n( 'Repeat this action every month.', 'Repeat this action every %d months.', $interval_multiplier, 'timed-content' ), $interval_multiplier );
631 } elseif ( $freq == 4 )
632 $desc .= "&nbsp;" . sprintf( _n( 'Repeat this action every year.', 'Repeat this action every %d years.', $interval_multiplier, 'timed-content' ), $interval_multiplier );
633
634 if ( $recurr_type == "recurrence_duration_num_repeat" )
635 $desc .= "&nbsp;" . sprintf( _n( 'This rule will be active for 1 repetition.', 'This rule will be active for %d repetitions.', $num_repeat, 'timed-content' ), $num_repeat );
636 elseif ( $recurr_type == "recurrence_duration_end_date" )
637 $desc .= "&nbsp;" . sprintf( __( 'This rule will be active until %s.', 'timed-content' ), $end_date );
638
639 $desc .= "&nbsp;" . sprintf( __( 'All times are in the %s timezone.', 'timed-content' ), $timezone );
640 return $desc;
641 }
642
643 /**
644 * Wrapper for calling timedContentPlugin::__getScheduleDescription() by the ID of a Timed Content Rule
645 *
646 * @param int $ID ID of the Timed Content Rule
647 * @return string
648 */
649 function getScheduleDescriptionById( $ID ) {
650 $defaults = array();
651
652 foreach ( array( "timed_content_rule_occurrence_custom_fields",
653 "timed_content_rule_pattern_custom_fields",
654 "timed_content_rule_recurrence_custom_fields" ) as $fields ) {
655 global $$fields;
656 foreach ( $$fields as $field ) {
657 $defaults[$field['name']] = $field['default'];
658 }
659 }
660
661 $prefix = TIMED_CONTENT_RULE_POSTMETA_PREFIX;
662 $args = array();
663
664 $args['action'] = ( false === get_post_meta( $ID, $prefix . 'action', true ) ? $defaults['action'] : get_post_meta( $ID, $prefix . 'action', true ) );
665 $args['freq'] = ( false === get_post_meta( $ID, $prefix . 'frequency', true ) ? $defaults['frequency'] : get_post_meta( $ID, $prefix . 'frequency', true ) );
666 $args['timezone'] = ( false === get_post_meta( $ID, $prefix . 'timezone', true ) ? $defaults['timezone'] : get_post_meta( $ID, $prefix . 'timezone', true ) );
667 $args['recurr_type'] = ( false === get_post_meta( $ID, $prefix . 'recurrence_duration', true ) ? $defaults['recurrence_duration'] : get_post_meta( $ID, $prefix . 'recurrence_duration', true ) );
668 $args['num_repeat'] = ( false === get_post_meta( $ID, $prefix . 'recurrence_duration_num_repeat', true ) ? $defaults['recurrence_duration_num_repeat'] : get_post_meta( $ID, $prefix . 'recurrence_duration_num_repeat', true ) );
669 $args['end_date'] = ( false === get_post_meta( $ID, $prefix . 'recurrence_duration_end_date', true ) ? $defaults['recurrence_duration_end_date'] : get_post_meta( $ID, $prefix . 'recurrence_duration_end_date', true ) );
670 $args['days_of_week'] = ( false === get_post_meta( $ID, $prefix . 'weekly_days_of_week_to_repeat', true ) ? $defaults['weekly_days_of_week_to_repeat'] : get_post_meta( $ID, $prefix . 'weekly_days_of_week_to_repeat', true ) );
671 if ( $args['freq'] == 0 ) $args['interval_multiplier'] = ( false === get_post_meta( $ID, $prefix . 'hourly_num_of_hours', true ) ? $defaults['hourly_num_of_hours'] : get_post_meta( $ID, $prefix . 'hourly_num_of_hours', true ) );
672 if ( $args['freq'] == 1 ) $args['interval_multiplier'] = ( false === get_post_meta( $ID, $prefix . 'daily_num_of_days', true ) ? $defaults['daily_num_of_days'] : get_post_meta( $ID, $prefix . 'daily_num_of_days', true ) );
673 if ( $args['freq'] == 2 ) $args['interval_multiplier'] = ( false === get_post_meta( $ID, $prefix . 'weekly_num_of_weeks', true ) ? $defaults['weekly_num_of_weeks'] : get_post_meta( $ID, $prefix . 'weekly_num_of_weeks', true ) );
674 if ( $args['freq'] == 3 ) $args['interval_multiplier'] = ( false === get_post_meta( $ID, $prefix . 'monthly_num_of_months', true ) ? $defaults['monthly_num_of_months'] : get_post_meta( $ID, $prefix . 'monthly_num_of_months', true ) );
675 if ( $args['freq'] == 4 ) $args['interval_multiplier'] = ( false === get_post_meta( $ID, $prefix . 'yearly_num_of_years', true ) ? $defaults['yearly_num_of_years'] : get_post_meta( $ID, $prefix . 'yearly_num_of_years', true ) );
676 $args['instance_start'] = ( false === get_post_meta( $ID, $prefix . 'instance_start', true ) ? $defaults['instance_start'] : get_post_meta( $ID, $prefix . 'instance_start', true ) );
677 $args['instance_end'] = ( false === get_post_meta( $ID, $prefix . 'instance_end', true ) ? $defaults['instance_end'] : get_post_meta( $ID, $prefix . 'instance_end', true ) );
678 $args['monthly_pattern'] = ( false === get_post_meta( $ID, $prefix . 'monthly_nth_weekday_of_month', true ) ? $defaults['monthly_nth_weekday_of_month'] : get_post_meta( $ID, $prefix . 'monthly_nth_weekday_of_month', true ) );
679 $args['monthly_pattern_ord'] = ( false === get_post_meta( $ID, $prefix . 'monthly_nth_weekday_of_month_nth', true ) ? $defaults['monthly_nth_weekday_of_month_nth'] : get_post_meta( $ID, $prefix . 'monthly_nth_weekday_of_month_nth', true ) );
680 $args['monthly_pattern_day'] = ( false === get_post_meta( $ID, $prefix . 'monthly_nth_weekday_of_month_weekday', true ) ? $defaults['monthly_nth_weekday_of_month_weekday'] : get_post_meta( $ID, $prefix . 'monthly_nth_weekday_of_month_weekday', true ) );
681
682 return $this->__getScheduleDescription( $args );
683
684 }
685
686 /**
687 * Wrapper for calling timedContentPlugin::__getRulePeriods() based on the contents of the form fields
688 * of the Add Timed Content Rule and Edit Timed Content Rule screens. Output is sent to output as plain text
689 */
690 function timedContentPluginGetScheduleDescriptionAjax() {
691 if ( current_user_can( 'edit_posts' ) || current_user_can( 'edit_pages' ) ) {
692 $prefix = TIMED_CONTENT_RULE_POSTMETA_PREFIX;
693 $args = array();
694
695 $args['action'] = $_POST[$prefix . 'action'];
696 $args['freq'] = $_POST[$prefix . 'frequency'];
697 $args['timezone'] = $_POST[$prefix . 'timezone'];
698 $args['recurr_type'] = $_POST[$prefix . 'recurrence_duration'];
699 $args['num_repeat'] = $_POST[$prefix . 'recurrence_duration_num_repeat'];
700 $args['end_date'] = $_POST[$prefix . 'recurrence_duration_end_date'];
701 $args['days_of_week'] = ( isset( $_POST[$prefix . 'weekly_days_of_week_to_repeat'] ) ? $_POST[$prefix . 'weekly_days_of_week_to_repeat'] : array() );
702 $args['interval_multiplier'] = $_POST[$prefix . 'interval_multiplier'];
703 $args['instance_start'] = $_POST[$prefix . 'instance_start'];
704 $args['instance_end'] = $_POST[$prefix . 'instance_end'];
705 $args['monthly_pattern'] = $_POST[$prefix . 'monthly_nth_weekday_of_month'];
706 $args['monthly_pattern_ord'] = $_POST[$prefix . 'monthly_nth_weekday_of_month_nth'];
707 $args['monthly_pattern_day'] = $_POST[$prefix . 'monthly_nth_weekday_of_month_weekday'];
708
709 $response = $this->__getScheduleDescription( $args );
710
711 // response output
712 header( "Content-Type: text/plain" );
713 echo $response;
714 }
715 die();
716 }
717
718 /**
719 * Processes the [timed-content-client] shortcode.
720 *
721 * @param array $atts
722 * @param null $content
723 * @return string
724 */
725 function clientShowHTML( $atts, $content = null ) {
726 $show_attr = "";
727 $hide_attr = "";
728 extract( shortcode_atts( array( 'show' => '0:00:000' , 'hide' => '0:00:000' , 'display' => 'div' ), $atts ) );
729
730 // Initialize show/hide arguments
731 $s_min = 0; $s_sec = 0; $s_fade = 0;
732 $h_min = 0; $h_sec = 0; $h_fade = 0;
733 @list( $s_min, $s_sec, $s_fade ) = explode( ":", $show );
734 @list( $h_min, $h_sec, $h_fade ) = explode( ":", $hide );
735
736 if ( ( (int)$s_min + (int)$s_sec ) > 0 )
737 $show_attr = "_show_" . $s_min . "_" . $s_sec . "_" . $s_fade;
738 if ( ( (int)$h_min + (int)$h_sec ) > 0 )
739 $hide_attr = "_hide_" . $h_min . "_" . $h_sec . "_" . $h_fade;
740
741 $the_class = TIMED_CONTENT_CLIENT_TAG . $show_attr . $hide_attr ;
742 $the_tag = ( $display == "div" ? "div" : "span" );
743
744 $the_HTML = "<" . $the_tag . " class='" . $the_class . "'" . ( ( $show_attr != "" ) ? " style='display: none;'" : "" ) .">" . do_shortcode( $content ) . "</" . $the_tag . ">";
745
746 return $the_HTML;
747 }
748
749 /**
750 * Processes the [timed-content-server] shortcode.
751 *
752 * @param array $atts
753 * @param null $content
754 * @return string
755 */
756 function serverShowHTML( $atts, $content = null ) {
757 global $post;
758 extract( shortcode_atts( array( 'show' => TIMED_CONTENT_ZERO_TIME , 'hide' => TIMED_CONTENT_END_TIME, 'debug' => 'false' ), $atts ) );
759 $show_t = strtotime( $show );
760 $hide_t = strtotime( $hide );
761 $right_now_t = time();
762 $debug_message = "";
763
764 if ( ( $debug == "true" ) && ( current_user_can( "edit_post", $post->post_id ) ) ) {
765 $temp_tz = date_default_timezone_get();
766 date_default_timezone_set( get_option( 'timezone_string' ) );
767
768 $right_now = date_i18n( TIMED_CONTENT_DT_FORMAT, $right_now_t );
769
770 if ( $show_t > $right_now_t )
771 $show_diff_str = sprintf( _x( '%s from now.', 'Human readable time difference', 'timed-content' ), human_time_diff( $show_t, $right_now_t ) );
772 else
773 $show_diff_str = sprintf( _x( '%s ago.', 'Human readable time difference', 'timed-content' ), human_time_diff( $show_t, $right_now_t ) );
774 if ( $hide_t > $right_now_t )
775 $hide_diff_str = sprintf( _x( '%s from now.', 'Human readable time difference', 'timed-content' ), human_time_diff( $hide_t, $right_now_t ) );
776 else
777 $hide_diff_str = sprintf( _x( '%s ago.', 'Human readable time difference', 'timed-content' ), human_time_diff( $hide_t, $right_now_t ) );
778
779 $debug_message = "<div class=\"tcr-warning\">\n";
780 $debug_message .= "<p class=\"heading\">" . _x( "Notice", "Noun", 'timed-content' ) . "</p>\n";
781 $debug_message .= "<p>" . __( "Debugging has been turned on for a <code>[timed-content-server]</code> shortcode on this Post/Page. Only website users who are currently logged in and can edit this Post/Page will see this. To turn off this message, remove the <code>debug</code> attribute from the shortcode.", 'timed-content' ) . "</p>\n";
782
783 if ( $show == TIMED_CONTENT_ZERO_TIME )
784 $debug_message .= "<p>" . __( 'The <code>show</code> attribute is not set.', 'timed-content') . "</p>\n";
785 else
786 $debug_message .= "<p>" . __( 'The <code>show</code> attribute is currently set to', 'timed-content') . ": " . $show . ",<br />\n "
787 . __( 'The Timed Content plugin thinks the intended date/time is', 'timed-content') . ": " . date_i18n( TIMED_CONTENT_DT_FORMAT, $show_t )
788 . " (" . $show_diff_str . ")</p>\n";
789
790 if ( $hide == TIMED_CONTENT_END_TIME )
791 $debug_message .= "<p>" . __( 'The <code>hide</code> attribute is not set.' , 'timed-content') . "</p>\n";
792 else
793 $debug_message .= "<p>" . __( 'The <code>hide</code> attribute is currently set to', 'timed-content') . ": " . $hide . ",<br />\n"
794 . __( 'The Timed Content plugin thinks the intended date/time is', 'timed-content') . ": " . date_i18n( TIMED_CONTENT_DT_FORMAT, $hide_t )
795 . " (" . $hide_diff_str . ").</p>\n";
796
797 $debug_message .= "<p>" . __( 'Current time', 'timed-content') . " : " . $right_now . "</p>\n";
798 $debug_message .= "<p>" . __( 'Content', "Noun", 'timed-content') . " : " . $content . "</p>\n";
799
800 $debug_message .= "</div>\n";
801
802 date_default_timezone_set( $temp_tz );
803 }
804
805 if ( ( $show_t <= $right_now_t ) && ( $right_now_t <= $hide_t ) )
806 return $debug_message . do_shortcode( $content ) . "\n";
807 else
808 return $debug_message . "\n";
809
810 }
811
812 /**
813 * Processes the [timed-content-rule] shortcode.
814 *
815 * @param array $atts
816 * @param null $content
817 * @return string
818 */
819 function rulesShowHTML( $atts, $content = null ) {
820 extract( shortcode_atts( array( 'id' => '0' ), $atts ) );
821 if ( TIMED_CONTENT_RULE_TYPE != get_post_type( $id ) ) return;
822
823 $prefix = TIMED_CONTENT_RULE_POSTMETA_PREFIX;
824 $right_now_t = time();
825 $rule_is_active = false;
826
827 $active_periods = $this->getRulePeriodsById( $id, false );
828 $action_is_show = (bool) get_post_meta( $id, $prefix . 'action', true );
829
830 foreach ( $active_periods as $period ) {
831 if ( ( $period['start'] <= $right_now_t ) && ( $right_now_t <= $period['end'] ) ) {
832 $rule_is_active = true;
833 break;
834 }
835 }
836
837 if ( ( ( $rule_is_active == true ) && ( $action_is_show == true ) ) || ( ( $rule_is_active == false ) && ( $action_is_show == false ) ) )
838 return do_shortcode( $content );
839 else
840 return "";
841 }
842
843 /**
844 * Enqueues the JavaScript code necessary for the functionality of the [timed-content-client] shortcode.
845 */
846 function addHeaderCode() {
847 if ( ! is_admin() ) {
848 wp_enqueue_style( 'timed-content-css', TIMED_CONTENT_PLUGIN_URL . '/timed-content.css' );
849 wp_enqueue_script( 'timed-content_js', TIMED_CONTENT_PLUGIN_URL . '/js/timed-content.js', array( 'jquery' ), TIMED_CONTENT_VERSION );
850 }
851 }
852
853 /**
854 * Enqueues the CSS code necessary for custom icons for the Timed Content Rules management screens. Echo'd to output.
855 */
856 function addPostTypeIcons() {
857 ?>
858 <style type="text/css" media="screen">
859 #menu-posts-<?php echo TIMED_CONTENT_RULE_TYPE; ?> .wp-menu-image {
860 background: url(<?php echo TIMED_CONTENT_PLUGIN_URL; ?>/img/clock_icon.png) no-repeat 6px 6px !important;
861 }
862 #menu-posts-<?php echo TIMED_CONTENT_RULE_TYPE; ?>:hover .wp-menu-image, #menu-posts-<?php echo TIMED_CONTENT_RULE_TYPE; ?>.wp-has-current-submenu .wp-menu-image {
863 background-position: -22px 6px !important;
864 }
865 #icon-edit.icon32-posts-<?php echo TIMED_CONTENT_RULE_TYPE; ?> {background: url(<?php echo TIMED_CONTENT_PLUGIN_URL; ?>/img/clock_32x32.png) no-repeat;}
866 </style>
867 <?php
868 }
869
870 /**
871 * Enqueues the JavaScript code necessary for the functionality of the Timed Content Rules management screens.
872 */
873 function addAdminHeaderCode() {
874 if ( ( isset( $_GET['post_type'] ) && $_GET['post_type'] == TIMED_CONTENT_RULE_TYPE )
875 || ( isset( $post_type ) && $post_type == TIMED_CONTENT_RULE_TYPE )
876 || ( isset( $_GET['post'] ) && get_post_type( $_GET['post'] ) == TIMED_CONTENT_RULE_TYPE ) ) {
877 wp_enqueue_style( 'timed-content-css', TIMED_CONTENT_PLUGIN_URL . '/timed-content.css' );
878 // Enqueue the JavaScript file that manages the meta box UI
879 wp_enqueue_script( 'timed-content-admin_js', TIMED_CONTENT_PLUGIN_URL . '/js/timed-content-admin.js', array( 'jquery' ), TIMED_CONTENT_VERSION );
880 // Enqueue the JavaScript file that makes AJAX requests
881 wp_enqueue_script( 'timed-content-ajax_js', TIMED_CONTENT_PLUGIN_URL . '/js/timed-content-ajax.js', array( 'jquery', 'jquery-ui-dialog' ), TIMED_CONTENT_VERSION );
882
883 // Set up local variables used in the AJAX JavaScript file
884 wp_localize_script( 'timed-content-ajax_js', 'timedContentRuleAjax', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ),
885 'start_label' => _x( 'Start', 'Scheduled Dates/Times dialog - Beginning of active period table header', 'timed-content' ),
886 'end_label' => _x( 'End', 'Scheduled Dates/Times dialog - End of active period table header', 'timed-content' ),
887 'dialog_label' => _x( 'Scheduled Dates/Times', 'Scheduled Dates/Times dialog - dialog header', 'timed-content' ),
888 'dialog_width' => 800,
889 'dialog_height' => 500,
890 'close_label' => _x( 'Close', 'Scheduled Dates/Times dialog - Close button HTML label', 'timed-content' ),
891 'loadingimg' => TIMED_CONTENT_PLUGIN_URL . '/img/wpspin.gif',
892 'error' => __( "Error", 'timed-content' ),
893 'error_desc' => __( "Something unexpected has happened along the way. The specific details are below:", 'timed-content' ) ) );
894 }
895 }
896
897 /**
898 * Initializes the TinyMCE plugin bundled with this Wordpress plugin
899 */
900 function initTinyMCEPlugin() {
901 if ( ( ! current_user_can( 'edit_posts' ) ) && ( ! current_user_can( 'edit_pages' ) ) )
902 return;
903
904 // Add only in Rich Editor mode
905 if ( get_user_option( 'rich_editing' ) == 'true' ) {
906 add_filter( "mce_external_plugins", array( &$this, "addTimedContentTinyMCEPlugin" ) );
907 add_filter( "mce_buttons", array( &$this, "registerTinyMCEButton" ) );
908 }
909 }
910
911 /**
912 * Sets up variables to use in the TinyMCE plugin's editor_plugin_src.js.
913 *
914 */
915 function setTinyMCEPluginVars() {
916 if ( ( ! current_user_can( 'edit_posts' ) ) && ( ! current_user_can( 'edit_pages' ) ) )
917 return;
918
919 // Add only in Rich Editor mode
920 if ( get_user_option( 'rich_editing' ) == 'true' ) {
921 wp_enqueue_script( 'timed-content-admin_tinymce_js', TIMED_CONTENT_PLUGIN_URL . '/js/timed-content-admin-tinymce.js', array(), TIMED_CONTENT_VERSION );
922 wp_localize_script( 'timed-content-admin_tinymce_js',
923 'timedContentAdminTinyMCEOptionsVars',
924 array( 'version' => TIMED_CONTENT_VERSION,
925 'desc' => __( "Add Timed Content shortcodes", 'timed-content' ) ) );
926 }
927 }
928
929 /**
930 * Sets up the button for the associated TinyMCE plugin for use in the editor menubar.
931 * @param array $buttons Array of menu buttons already registered with TinyMCE
932 * @return array The array of TinyMCE menu buttons with ours now loaded in as well
933 */
934 function registerTinyMCEButton( $buttons ) {
935 array_push( $buttons, "|", "timed_content" );
936 return $buttons;
937 }
938
939 /**
940 * Loads the associated TinyMCE plugin into TinyMCE's plugin array
941 *
942 * @param array $plugin_array Array of plugins already registered with TinyMCE
943 * @return array The array of TinyMCE plugins with ours now loaded in as well
944 */
945 function addTimedContentTinyMCEPlugin( $plugin_array ) {
946 $plugin_array['timed_content'] = TIMED_CONTENT_PLUGIN_URL . "/tinymce_plugin/editor_plugin.js";
947 return $plugin_array;
948 }
949
950 /**
951 * Generates JavaScript array of objects describing Timed Content Rules. Used in the dialog box created by
952 * timedContentPlugin::timedContentPluginGetTinyMCEDialog().
953 *
954 * @return string
955 */
956 function __getRulesJS() {
957 $the_js = "var rules = [\n";
958 $args = array( 'post_type' => TIMED_CONTENT_RULE_TYPE, 'posts_per_page' => -1, 'post_status' => 'publish' );
959 $the_rules = get_posts( $args );
960 foreach ( $the_rules as $rule ) {
961 $desc = $this->getScheduleDescriptionById( $rule->ID );
962 // Only add a rule if there's no errors or warnings
963 if ( false === strpos( $desc, "tcr-warning" ) )
964 $the_js .= " { 'ID': " . $rule->ID . ", 'title': '" . esc_js( $rule->post_title ) . "', 'desc': '" . esc_js( $desc ) . "' },\n";
965 }
966 $the_js .= "];\n";
967 return $the_js;
968 }
969 /**
970 * Display a dialog box for this plugin's associated TinyMCE plugin. Called from TinyMCE via AJAX.
971 *
972 */
973 function timedContentPluginGetTinyMCEDialog() {
974 wp_enqueue_style( 'timed-content-jquery-ui-css', TIMED_CONTENT_JQUERY_UI_CSS );
975 wp_enqueue_script( 'jquery-ui-datepicker' );
976 wp_register_style( 'timed-content-jquery-ui-timepicker-css', TIMED_CONTENT_JQUERY_UI_TIMEPICKER_CSS );
977 wp_enqueue_style( 'timed-content-jquery-ui-timepicker-css' );
978 wp_register_script( 'timed-content-jquery-ui-timepicker-js', TIMED_CONTENT_JQUERY_UI_TIMEPICKER_JS, array('jquery', 'jquery-ui-datepicker'), TIMED_CONTENT_VERSION );
979 wp_enqueue_script( 'timed-content-jquery-ui-timepicker-js' );
980
981 ob_start();
982 include("tinymce_plugin/dialog.php");
983 $content = ob_get_contents();
984 ob_end_clean();
985 echo $content;
986 die();
987 }
988
989 /**
990 * Displays a count of Timed Content Rules of the Dashboard's Right now widget
991 *
992 */
993 function i18nInit() {
994 $plugin_dir = basename( dirname( __FILE__ ) ) . "/lang/";
995 load_plugin_textdomain( 'timed-content', null, $plugin_dir );
996 }
997
998 /**
999 * Add custom columns to the Timed Content Rules overview page
1000 *
1001 */
1002 function addDescColumnHead( $defaults ) {
1003 unset( $defaults['date'] );
1004 $defaults['description'] = __( 'Description', 'timed-content' );
1005 $defaults['shortcode'] = __( 'Shortcode', 'timed-content' );
1006 return $defaults;
1007 }
1008
1009 /**
1010 * Display content associated with custom columns on the Timed Content Rules overview page
1011 *
1012 * @param $column_name Name of the column to be displayed
1013 * @param $post_ID ID of the Timed Content Rule being listed
1014 */
1015 function addDescColumnContent( $column_name, $post_ID ) {
1016 if ( $column_name == 'shortcode' ) {
1017 echo '<code>[' . TIMED_CONTENT_RULE_TAG . ' id="' . $post_ID . '"]...[/' . TIMED_CONTENT_RULE_TAG . ']</code>';
1018 }
1019 if ( $column_name == 'description' ) {
1020 $desc = $this->getScheduleDescriptionById( $post_ID );
1021 if ( $desc ) {
1022 echo '<em>' . $desc . '</em>';
1023 }
1024 }
1025 }
1026
1027
1028 /**
1029 * Display a count of Timed Content Rules of the Dashboard's Right now widget
1030 *
1031 */
1032 function addRulesCount() {
1033 if ( !post_type_exists( TIMED_CONTENT_RULE_TYPE ) ) {
1034 return;
1035 }
1036
1037 $num_posts = wp_count_posts( TIMED_CONTENT_RULE_TYPE );
1038 $num = number_format_i18n( $num_posts->publish );
1039 $text = _n( 'Timed Content Rule', 'Timed Content Rules', intval( $num_posts->publish ) );
1040 if ( current_user_can( 'edit_posts' ) || current_user_can( 'edit_pages' ) ) {
1041 $num = "<a href='edit.php?post_type=" . TIMED_CONTENT_RULE_TYPE . "'>$num</a>";
1042 $text = "<a href='edit.php?post_type=" . TIMED_CONTENT_RULE_TYPE . "'>$text</a>";
1043 }
1044 echo '<tr>';
1045 echo '<td class="first b b-' . TIMED_CONTENT_RULE_TYPE . '">' . $num . '</td>';
1046 echo '<td class="t ' . TIMED_CONTENT_RULE_TYPE . '">' . $text . '</td>';
1047 echo '</tr>';
1048
1049 if ( $num_posts->pending > 0 ) {
1050 $num = number_format_i18n( $num_posts->pending );
1051 $text = _n( 'Timed Content Rule Pending', 'Timed Content Rules Pending', intval( $num_posts->pending ) );
1052 if ( current_user_can( 'edit_posts' ) || current_user_can( 'edit_pages' ) ) {
1053 $num = "<a href='edit.php?post_status=pending&post_type=" . TIMED_CONTENT_RULE_TYPE . "'>$num</a>";
1054 $text = "<a href='edit.php?post_status=pending&post_type=" . TIMED_CONTENT_RULE_TYPE . "'>$text</a>";
1055 }
1056 echo '<tr>';
1057 echo '<td class="first b b-' . TIMED_CONTENT_RULE_TYPE . '">' . $num . '</td>';
1058 echo '<td class="t ' . TIMED_CONTENT_RULE_TYPE . '">' . $text . '</td>';
1059 echo '</tr>';
1060 }
1061 }
1062 }
1063
1064 } //End Class timedContentPlugin
1065
1066 // Initialize plugin
1067 if ( class_exists( "timedContentPlugin" ) ) {
1068 $timedContentPluginInstance = new timedContentPlugin();
1069 }
1070
1071 // Actions and Filters
1072 if ( isset( $timedContentPluginInstance ) ) {
1073 $scf = new customFieldsInterface( "cfi_s",
1074 __( 'Rule Description/Schedule', 'timed-content' ),
1075 "<div id=\"schedule_desc\" style=\"font-style: italic;\">"
1076 . ( isset( $_GET['post'] ) && ( TIMED_CONTENT_RULE_TYPE === get_post_type( $_GET['post'] ) ) ? $timedContentPluginInstance->getScheduleDescriptionById( intval( $_GET['post'] ) ) : $timedContentPluginInstance->getScheduleDescriptionById( intval( 0 ) ) )
1077 . "</div>"
1078 . "<div style=\"padding-top: 10px;\"><input type=\"button\" class=\"button-primary\" id=\"timed_content_rule_test\" value=\"Show Projected Dates/Times\" /></div>",
1079 TIMED_CONTENT_RULE_POSTMETA_PREFIX,
1080 array( TIMED_CONTENT_RULE_TYPE ),
1081 array() );
1082 $ocf = new customFieldsInterface( "cfi_o",
1083 __( 'Action/Initial Event', 'timed-content' ),
1084 __( 'Set the action to be taken and when it should first run.', 'timed-content' ),
1085 TIMED_CONTENT_RULE_POSTMETA_PREFIX,
1086 array( TIMED_CONTENT_RULE_TYPE ),
1087 $timed_content_rule_occurrence_custom_fields );
1088 $pcf = new customFieldsInterface( "cfi_p",
1089 __( 'Repeating Pattern', 'timed-content' ),
1090 __( 'Set how often the action should repeat.', 'timed-content' ),
1091 TIMED_CONTENT_RULE_POSTMETA_PREFIX,
1092 array( TIMED_CONTENT_RULE_TYPE ),
1093 $timed_content_rule_pattern_custom_fields );
1094 $rcf = new customFieldsInterface( "cfi_r",
1095 __( 'Stopping Condition', 'timed-content' ),
1096 __( 'Set how long or how many times the action should occur.', 'timed-content' ),
1097 TIMED_CONTENT_RULE_POSTMETA_PREFIX,
1098 array( TIMED_CONTENT_RULE_TYPE ),
1099 $timed_content_rule_recurrence_custom_fields );
1100 add_action( "init", array( &$timedContentPluginInstance, "i18nInit" ), 1 );
1101 add_action( "init", array( &$timedContentPluginInstance, "timedContentRuleTypeInit" ), 2 );
1102 add_action( "right_now_content_table_end", array( &$timedContentPluginInstance, "addRulesCount" ) );
1103 add_action( "wp_head", array( &$timedContentPluginInstance, "addHeaderCode" ), 1 );
1104 add_filter( "manage_" . TIMED_CONTENT_RULE_TYPE . "_posts_columns", array( &$timedContentPluginInstance, "addDescColumnHead" ) );
1105 add_action( "manage_" . TIMED_CONTENT_RULE_TYPE . "_posts_custom_column", array( &$timedContentPluginInstance, "addDescColumnContent" ), 10, 2);
1106 add_action( "admin_enqueue_scripts", array( &$timedContentPluginInstance, "addAdminHeaderCode" ), 1 );
1107 add_action( "admin_init", array( &$timedContentPluginInstance, "setTinyMCEPluginVars" ), 1 );
1108 add_action( "admin_init", array( &$timedContentPluginInstance, "initTinyMCEPlugin" ), 2 );
1109 add_action( "admin_head", array( &$timedContentPluginInstance, "addPostTypeIcons" ), 1 );
1110 add_action( 'wp_ajax_timedContentPluginGetTinyMCEDialog', array( &$timedContentPluginInstance, "timedContentPluginGetTinyMCEDialog" ), 1 );
1111 add_action( 'wp_ajax_timedContentPluginGetRulePeriodsAjax', array( &$timedContentPluginInstance, "timedContentPluginGetRulePeriodsAjax" ), 1 );
1112 add_action( 'wp_ajax_timedContentPluginGetScheduleDescriptionAjax', array( &$timedContentPluginInstance, "timedContentPluginGetScheduleDescriptionAjax" ), 1 );
1113 add_filter( "post_updated_messages", array( &$timedContentPluginInstance, "timedContentRuleUpdatedMessages" ), 1 );
1114 add_shortcode( TIMED_CONTENT_CLIENT_TAG, array( &$timedContentPluginInstance, "clientShowHTML" ), 1 );
1115 add_shortcode( TIMED_CONTENT_SERVER_TAG, array( &$timedContentPluginInstance, "serverShowHTML" ), 1 );
1116 add_shortcode( TIMED_CONTENT_RULE_TAG, array( &$timedContentPluginInstance, "rulesShowHTML" ), 1 );
1117 }
1118 ?>