PluginProbe
Timed Content / 2.7
Timed Content v2.7
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.7, at timed-content.php

1,491 lines 78.3 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 Domain Path: /lang
6 Plugin URI: http://wordpress.org/plugins/timed-content/
7 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.
8 Author: K. Tough, Arno Welzel
9 Version: 2.7
10 Author URI: http://wordpress.org/plugins/timed-content/
11 */
12 if ( !class_exists( "timedContentPlugin" ) ) {
13
14 define( "TIMED_CONTENT_VERSION", "2.7" );
15 define( "TIMED_CONTENT_SLUG", "timed-content" );
16 define( "TIMED_CONTENT_PLUGIN_URL", plugins_url() . '/' . TIMED_CONTENT_SLUG );
17 define( "TIMED_CONTENT_CLIENT_TAG", "timed-content-client" );
18 define( "TIMED_CONTENT_SERVER_TAG", "timed-content-server" );
19 define( "TIMED_CONTENT_RULE_TAG", "timed-content-rule" );
20 define( "TIMED_CONTENT_ZERO_TIME", "1970-Jan-01 00:00:00 +000" ); // Start of Unix Epoch
21 define( "TIMED_CONTENT_END_TIME", "2038-Jan-19 03:14:07 +000" ); // End of Unix Epoch
22 define( "TIMED_CONTENT_RULE_TYPE", "timed_content_rule" );
23 define( "TIMED_CONTENT_RULE_POSTMETA_PREFIX", TIMED_CONTENT_RULE_TYPE . "_" );
24 define( "TIMED_CONTENT_CSS", TIMED_CONTENT_PLUGIN_URL . "/css/timed-content.css" );
25 define( "TIMED_CONTENT_CSS_DASHICONS", TIMED_CONTENT_PLUGIN_URL . "/css/ca-aliencyborg-dashicons/style.css" );
26 // Required for styling the jQuery UI Datepicker and jQuery UI Timepicker
27 define( "TIMED_CONTENT_JQUERY_UI_CSS", TIMED_CONTENT_PLUGIN_URL . "/css/jqueryui/1.10.3/themes/smoothness/jquery-ui.css" );
28 define( "TIMED_CONTENT_JQUERY_UI_TIMEPICKER_JS", TIMED_CONTENT_PLUGIN_URL . "/js/jquery-ui-timepicker-0.3.3/jquery.ui.timepicker.js" );
29 define( "TIMED_CONTENT_JQUERY_UI_TIMEPICKER_CSS", TIMED_CONTENT_PLUGIN_URL . "/js/jquery-ui-timepicker-0.3.3/jquery.ui.timepicker.css" );
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 __construct() {
41 //constructor
42
43 }
44
45 function timedContentPlugin() {
46 self::__construct();
47
48 }
49
50 /** https://core.trac.wordpress.org/ticket/25768
51 *
52 * Modified from the original patch to use the currently set
53 * timezone from PHP, like PHP's date(), and to make the code
54 * more readable.
55 *
56 * @param $j
57 * @param $req_format
58 * @param bool $i
59 * @param bool $gmt
60 * @return bool|string
61 */
62 function fix_date_i18n($j, $req_format, $i = false, $gmt = false)
63 {
64 /* @var $wp_locale WP_Locale */
65 global $wp_locale;
66 $timestamp = $i;
67
68 // get current timestamp if $i is false
69 if (false === $timestamp)
70 {
71 if ($gmt)
72 $timestamp = time();
73 else
74 $timestamp = current_time('timestamp');
75 }
76
77
78 // get components of the date (timestamp) as array
79 $date_components = getdate($timestamp);
80
81 // numeric representation of a month, with leading zeros
82 $date_month = $wp_locale->get_month($date_components['mon']);
83 $date_month_abbrev = $wp_locale->get_month_abbrev($date_month);
84 // numeric representation of the day of the week
85 $date_weekday = $wp_locale->get_weekday($date_components['wday']);
86 $date_weekday_abbrev = $wp_locale->get_weekday_abbrev($date_weekday);
87 // get if hour is Ante meridiem or Post meridiem
88 $meridiem = $date_components['hours'] >= 12 ? 'pm' : 'am';
89 // lowercase Ante meridiem and Post meridiem hours
90 $date_meridiem = $wp_locale->get_meridiem($meridiem);
91 // uppercase Ante meridiem and Post meridiem
92 $date_meridiem_capital = $wp_locale->get_meridiem(strtoupper($meridiem));
93
94 // escape literals
95 $date_weekday_abbrev = backslashit($date_weekday_abbrev);
96 $date_month = backslashit($date_month);
97 $date_weekday = backslashit($date_weekday);
98 $date_month_abbrev = backslashit($date_month_abbrev);
99 $date_meridiem = backslashit($date_meridiem);
100 $date_meridiem_capital = backslashit($date_meridiem_capital);
101
102 // the translated format string
103 $translated_date_format_string = '';
104 // the 2 arrays map a format literal to its translation (e. g. 'F' to the escaped month translation)
105 $translate_formats = array('D', 'F', 'l', 'M', 'a', 'A', 'c', 'r');
106 $translations = array(
107 $date_weekday_abbrev, // D
108 $date_month, // F
109 $date_weekday, // l
110 $date_month_abbrev, // M
111 $date_meridiem, // a
112 $date_meridiem_capital, // A
113 'Y-m-d\TH:i:sP', // c
114 sprintf('%s, d %s Y H:i:s O', $date_weekday_abbrev, $date_month_abbrev), // r
115 );
116
117 // find each format literal that needs translation and replace it by its translation
118 // respects the escaping
119 // iterate $req_format from ending to beginning
120 for ($i = strlen($req_format) - 1; $i > -1; $i--)
121 {
122 // test if current char is format literal that needs translation
123 $translate_formats_index = array_search($req_format[$i], $translate_formats);
124
125 if ($translate_formats_index !== false)
126 {
127 // counts the slashes (the escape char) in front of the current char
128 $slashes_counter = 0;
129
130 // count all slashes left-hand side of the current char
131 for ($j = $i - 1; $j > -1; $j--)
132 {
133 if ($req_format[$j] == '\\')
134 $slashes_counter++;
135 else
136 break;
137 }
138
139 // number of slashes is even
140 if ($slashes_counter % 2 == 0)
141 // current char is not escaped, therefore it is a format literal
142 $translated_date_format_string = $translations[$translate_formats_index] . $translated_date_format_string;
143 else
144 // current char is escaped, therefore it is not a format literal, just add it unchanged
145 $translated_date_format_string = $req_format[$i] . $translated_date_format_string;
146 }
147 else
148 // current char is no a format literal, just add it unchanged
149 $translated_date_format_string = $req_format[$i] . $translated_date_format_string;
150 }
151
152 $req_format = $translated_date_format_string;
153
154 if ($gmt)
155 // get GMT date string
156 $date_formatted = gmdate($req_format, $timestamp);
157 else
158 {
159 // get Wordpress time zone
160 // $timezone_string = get_option('timezone_string');
161 // Haha, just kidding. Let's get the currently set timezone, as God and Rasmus intended
162 $timezone_string = date_default_timezone_get();
163
164 if ($timezone_string)
165 {
166 // create time zone object
167 $timezone_object = timezone_open($timezone_string);
168 // create date object from time zone object
169 $local_date_object = date_create(null, $timezone_object);
170 // set time and date of $local_date_object to $timestamp
171 $date_components = isset($date_components) ? $date_components : getdate($timestamp);
172 date_date_set($local_date_object, $date_components['year'], $date_components['mon'], $date_components['mday']);
173 date_time_set($local_date_object, $date_components['hours'], $date_components['minutes'], $date_components['seconds']);
174 // format date according to the Wordpress time zone
175 $date_formatted = date_format($local_date_object, $req_format);
176 }
177 else
178 {
179 // fall back if no Wordpress time zone set
180 $date_formatted = date($req_format, $i);
181 }
182 }
183
184 return $date_formatted;
185 }
186
187 /**
188 * Creates the Timed Content Rule post type and registers it with Wordpress
189 *
190 */
191 function timedContentRuleTypeInit()
192 {
193 $labels = array(
194 'name' => _x( 'Timed Content Rules', 'post type general name', 'timed-content' ),
195 'singular_name' => _x( 'Timed Content Rule', 'post type singular name', 'timed-content' ),
196 'add_new' => _x( 'Add New', 'Menu item/button label on Timed Content Rules admin page', 'timed-content' ),
197 'add_new_item' => __( 'Add New Timed Content Rule', 'timed-content' ),
198 'edit_item' => __( 'Edit Timed Content Rule', 'timed-content' ),
199 'new_item' => __( 'New Timed Content Rule', 'timed-content' ),
200 'view_item' => __( 'View Timed Content Rule', 'timed-content' ),
201 'search_items' => __( 'Search Timed Content Rules', 'timed-content' ),
202 'not_found' => __( 'No Timed Content Rules found', 'timed-content' ),
203 'not_found_in_trash' => __( 'No Timed Content Rules found in Trash', 'timed-content' ),
204 'parent_item_colon' => '',
205 'menu_name' => _x( 'Timed Content Rules', 'post type general name', 'timed-content' )
206 );
207 $args = array(
208 'labels' => $labels,
209 'description' => __( 'Create regular schedules to show or hide selected content in a Page or Post.', 'timed-content' ),
210 'public' => false,
211 'publicly_queryable' => false,
212 'exclude_from_search' => false,
213 'show_ui' => true,
214 'show_in_menu' => true,
215 'show_in_nav_menus' => true,
216 'show_in_admin_bar' => true,
217 'query_var' => false,
218 'rewrite' => false,
219 'capability_type' => 'post',
220 'has_archive' => false,
221 'hierarchical' => false,
222 'menu_position' => 5,
223 'supports' => array( 'title' )
224 );
225 register_post_type( TIMED_CONTENT_RULE_TYPE, $args );
226 }
227
228 /**
229 * Filter to customize CRUD messages for Timed Content Rules
230 *
231 * @param array $messages Array of currently defined messages for post types
232 * @return mixed Array of messages with appropriate messages for Timed Content Rules added in
233 */
234 function timedContentRuleUpdatedMessages( $messages ) {
235 global $post;
236
237 /* translators: date and time format to activate rule. http://ca2.php.net/manual/en/function.date.php*/
238 $post_date = date_i18n( __( 'M j, Y @ G:i', 'timed-content' ), strtotime( $post->post_date ) );
239
240 $messages[TIMED_CONTENT_RULE_TYPE] = array(
241 0 => '', // Unused. Messages start at index 1.
242 1 => __( 'Timed Content Rule updated.', 'timed-content' ),
243 2 => __( 'Custom field updated.', 'timed-content' ),
244 3 => __( 'Custom field deleted.', 'timed-content' ),
245 4 => __( 'Timed Content Rule updated.', 'timed-content' ),
246 /* translators: %s: date and time of the revision */
247 5 => isset( $_GET['revision'] ) ? sprintf( __( 'Timed Content Rule restored to revision from %s', 'timed-content' ), wp_post_revision_title( (int) $_GET['revision'], false ) ) : false,
248 6 => __( 'Timed Content Rule published.', 'timed-content' ),
249 7 => __( 'Timed Content Rule saved.', 'timed-content' ),
250 8 => __( 'Timed Content Rule submitted.', 'timed-content' ),
251 /* translators: %s: date and time to activate rule. */
252 9 => sprintf( __( 'Timed Content Rule scheduled for: %s.' , 'timed-content' ), "<strong>" . $post_date . "</strong>" ),
253 10 => __( 'Timed Content Rule draft updated.', 'timed-content' )
254 );
255
256 return $messages;
257 }
258
259 function __datetimeToEnglish( $date, $time = "" ) {
260 $months = array( "January",
261 "February",
262 "March",
263 "April",
264 "May",
265 "June",
266 "July",
267 "August",
268 "September",
269 "October",
270 "November",
271 "December" );
272 $monthsI18N = array( __( "January", 'timed-content' ),
273 __( "February", 'timed-content' ),
274 __( "March", 'timed-content' ),
275 __( "April", 'timed-content' ),
276 __( "May", 'timed-content' ),
277 __( "June", 'timed-content' ),
278 __( "July", 'timed-content' ),
279 __( "August", 'timed-content' ),
280 __( "September", 'timed-content' ),
281 __( "October", 'timed-content' ),
282 __( "November", 'timed-content' ),
283 __( "December", 'timed-content' ) );
284 $english_date = str_replace( $monthsI18N, $months, $date );
285 return $english_date . " " . $time;
286 }
287
288 /**
289 * Advances a date/time by a set number of days
290 *
291 * @param int $current UNIX timestamp of the date/time before incrementing
292 * @param int $interval_multiplier Number of days to advance
293 * @return int Unix timestamp of the new date/time
294 */
295 function __getNextDay( $current, $interval_multiplier ) {
296 return strtotime( $interval_multiplier . " day", $current );
297 }
298
299 /**
300 * Advances a date/time by a set number of hours
301 *
302 * @param int $current UNIX timestamp of the date/time before incrementing
303 * @param int $interval_multiplier Number of hours to advance
304 * @return int Unix timestamp of the new date/time
305 */
306 function __getNextHour( $current, $interval_multiplier ) {
307 return strtotime( $interval_multiplier . " hour", $current );
308 }
309
310 /**
311 * Advances a date/time by a set number of weeks
312 *
313 * Advances a date/time by a set number of weeks. If given an array of days of the week, this function will
314 * advance the date/time to the next day in that array in the jumped-to week. Use this function if you're
315 * repeating an action on specific days of the week (i.e., on Weekdays, Tuesdays and Thursdays, etc.).
316 *
317 * @param int $current UNIX timestamp of the date/time before incrementing
318 * @param int $interval_multiplier Number of weeks to advance
319 * @param array $days Array of integers symbolizing the days of the week to
320 * repeat on (0 - Sunday, 1 - Monday, ..., 6 - Saturday).
321 * @return int Unix timestamp of the new date/time
322 */
323 function __getNextWeek( $current, $interval_multiplier, $days = array() ) {
324 // If $days is empty, advance $interval_multiplier weeks from $current and return the timestamp
325 if ( empty( $days ) ) return strtotime( $interval_multiplier . " week", $current );
326
327 // Otherwise, set up an array combining the days of the week to repeat on and the current day
328 // (keys and values of the array will be the same, and the array is sorted)
329 $currentDayOfWeekIndex = date( "w", $current );
330 $days = array_merge( array( $currentDayOfWeekIndex ), $days );
331 $days = array_unique( $days );
332 $days = array_values( $days );
333 sort( $days );
334 $daysOfWeek = array_combine( $days, $days );
335
336 // If the current day is the last one of the days of the week to repeat on, jump ahead to
337 // the next week to be repeating on and get the earliest day in the array
338 if ( $currentDayOfWeekIndex == max( $daysOfWeek ) )
339 $pattern = ( ( 7 - $currentDayOfWeekIndex ) + ( 7 * ( $interval_multiplier - 1 ) ) + ( min( array_keys( $daysOfWeek ) ) ) ) . " day";
340 // Otherwise, cycle through the array until we find the next day to repeat on
341 else {
342 $nextDayOfWeekIndex = $currentDayOfWeekIndex;
343 do {} while ( !isset( $daysOfWeek[++$nextDayOfWeekIndex] ) );
344 $pattern = ( $nextDayOfWeekIndex - $currentDayOfWeekIndex ) . " day";
345 }
346 return strtotime( $pattern, $current );
347 }
348
349 /**
350 * Advances a date/time by a set number of months
351 *
352 * Advances a date/time by a set number of months. When the date/time of the first active period lies
353 * on the 29th, 30th, or 31st of the month, this function will return a date/time on the the last day
354 * of the month for those months not containing those days.
355 *
356 * @param int $current UNIX timestamp of the date/time before incrementing
357 * @param int $start UNIX timestamp of the first active period's date/time
358 * @param int $interval_multiplier Number of months to advance
359 * @return int Unix timestamp of the new date/time
360 */
361 function __getNextMonth( $current, $start, $interval_multiplier ) {
362
363 // For most days in the month, it's pretty easy. Get the day of month of the starting date.
364 $startDay = date( "j", $start );
365
366 // If it's before or on the 28th, just jump the number of months and be done with it.
367 if ( $startDay <= 28 )
368 return strtotime( $interval_multiplier . " month", $current );
369
370 // If it's on the 29th, 30th, or 31st, it gets tricky. Some months don't have those days - so on those
371 // months we need to repeat on the last day of the month instead, but we also need to jump back to the
372 // correct day the following month. Let's say we want to repeat something on the 31st every month: this
373 // is what we expect to see for a pattern:
374 //
375 // .
376 // .
377 // .
378 // December 31st
379 // January 31st
380 // February 28th
381 // March 31st
382 // April 30th
383 // .
384 // .
385 // .
386 //
387 // Unfortunately, PHP relative date handling isn't that smart (add "+1 month" to January 31st, and you
388 // end up in March), so we'll have to figure it out ourselves by figuring out how many days to jump instead.
389
390 // We'll need to calculate this for each interval and return the timestamp after the last jump.
391 $temp_current = $current;
392 for ( $i = 0; $i < $interval_multiplier; $i++ ) {
393 // The pattern for jumping will be different in each interval.
394 /** @noinspection PhpUnusedLocalVariableInspection */
395 $temp_pattern = "";
396
397 // Get the month number of the current date.
398 //$currentMonth = date( "n", $temp_current );
399
400 // Get the number of days in the month of the current date.
401 $lastDayThisMonth = date( "t", strtotime( "this month", $temp_current ) );
402
403 // Get the number of days for the next month relative to the current date .
404 // Subtract 3 days from the next month to counter known month skipping bugs in PHP's relative date
405 // handling, that being the difference between the shortest possible month (non-leap February - 28 days)
406 // and the longest (Jan., Mar., May, Jul., Aug., Oct., Dec. - 31 days). This may be fixed in PHP 5.3.x
407 // but this should be backwards-compatible anyway.
408 $lastDayNextMonth = date( "t", strtotime( "-3 day next month", $temp_current ) );
409
410 // If the current month is longer than next month, follow this block
411 if ( $lastDayThisMonth > $lastDayNextMonth ) {
412 // If we're repeating on the last day of this month, jump the number of days next month
413 if ( $startDay == $lastDayThisMonth )
414 $temp_pattern = $lastDayNextMonth . " days";
415 // If the start day doesn't exist in the next month (i.e., no "31st" in June), jump the
416 // number of days next month plus the difference between the start day and the number of days this month
417 elseif ( $startDay > $lastDayNextMonth )
418 $temp_pattern = ( $lastDayThisMonth + $lastDayNextMonth - $startDay ). " days";
419 // Otherwise, jump ahead the number of days in this month
420 else
421 $temp_pattern = $lastDayThisMonth . " days";
422 }
423 // Or, if the current month is shorter than next month
424 elseif ( $lastDayThisMonth < $lastDayNextMonth ) {
425 // If the start day doesn't exist in this month (i.e., no "31st" in June), jump the
426 // number of days next month plus the difference between the start day and the number of days this month
427 if ( $startDay >= $lastDayThisMonth )
428 $temp_pattern = $startDay . " days";
429 // Otherwise, jump ahead the number of days in this month
430 else
431 $temp_pattern = $lastDayThisMonth . " days";
432 }
433 // If the current month and next month are equally long, jumping by "1 month" is fine
434 else
435 $temp_pattern = "1 month";
436
437 $temp_current = strtotime( $temp_pattern, $temp_current );
438 }
439 return $temp_current;
440
441 }
442
443 /**
444 * Advances a date/time to the 'n'th weekday of the next month (eg., first Wednesday, third Monday, last Friday, etc.).
445 *
446 * NB: if $ordinal is set to '4' and $day is set to '7', it wil return the last day of the month.
447 *
448 * @param int $current UNIX timestamp of the date/time before incrementing
449 * @param int $ordinal Integer symbolizing the ordinal (0 - first, 1 - second, 2 - third, 3 - fourth, 4 - last)
450 * @param int $day integers symbolizing the days of the week to
451 * repeat on (0 - Sunday, 1 - Monday, ..., 6 - Saturday, 7 - day).
452 * @return int Unix timestamp of the new date/time
453 */
454 function __getNthWeekdayOfMonth( $current, $ordinal, $day ) {
455
456 // First, get the month/year we need to work with
457 $the_month = date( "F", $current );
458 $the_year = date( "Y", $current );
459 $lastDayThisMonth = date( "t", $current );
460
461 // Get the time for the $current timestamp
462 $current_time = date( "g:i A", $current );
463 $the_day = "";
464
465 if ( $day == 7 ) { // If $day is "day of the month", get the day of month based on the ordinal
466 switch ( $ordinal ) {
467 case 0 : $the_day = "1"; break; // First day of the month //
468 case 1 : $the_day = "2"; break; // Second day of the month //
469 case 2 : $the_day = "3"; break; // Third day of the month //
470 case 3 : $the_day = "4"; break; // Fourth day of the month //
471 case 4 : $the_day = $lastDayThisMonth; break; // Last day of the month //
472 default : $the_day = "1"; break;
473 }
474 } else { // If $day is one of the days of the week...
475 $day_range = array();
476 switch ( $ordinal ) { // ...get a 7-day range based on the ordinal...
477 case 0 : $day_range = range( 1, 7 ); break; // First 7 days of the month //
478 case 1 : $day_range = range( 8, 14 ); break; // Second 7 days of the month //
479 case 2 : $day_range = range( 15, 21 ); break; // Third 7 days of the month //
480 case 3 : $day_range = range( 22, 28 ); break; // Fourth 7 days of the month //
481 case 4 : $day_range = range( $lastDayThisMonth - 6, $lastDayThisMonth ); break; // Last 7 days of the month //
482 default : $day_range = range( 1, 7 ); break;
483 }
484 foreach ( $day_range as $a_day ) { // ...and find the matching weekday in that range.
485 if ( $day == date( "w", strtotime( $the_month . " " . $a_day . ", " . $the_year ) ) ) {
486 $the_day = $a_day;
487 break;
488 }
489 }
490 }
491
492 // Build the date/time string for the correct day and return its timestamp
493 $pattern = $the_month . " " . $the_day . ", " . $the_year . ", " . $current_time;
494 return strtotime( $pattern );
495
496 }
497
498 /**
499 * Advances a date/time by a set number of years
500 *
501 * @param int $current UNIX timestamp of the date/time before incrementing
502 * @param int $interval_multiplier Number of years to advance
503 * @return int Unix timestamp of the new date/time
504 */
505 function __getNextYear( $current, $interval_multiplier ) {
506 return strtotime( $interval_multiplier . " year", $current );
507 }
508
509 /**
510 * Validates the various Timed Content Rule parameters and returns a series of error messages.
511 *
512 * @param $args Array of Timed Content Rule parameters
513 * @return array Array of error messages
514 */
515 function __validate( $args ) {
516 $errors = array();
517
518 $instance_start = strtotime( $this->__datetimeToEnglish( $args['instance_start']['date'], $args['instance_start']['time'] ) . ' ' . $args['timezone'] );
519 $instance_end = strtotime( $this->__datetimeToEnglish( $args['instance_end']['date'], $args['instance_end']['time'] ) . ' ' . $args['timezone'] );
520 $end_date = strtotime( $this->__datetimeToEnglish( $args['end_date'], $args['instance_start']['time'] ) . ' ' . $args['timezone'] );
521
522 if ( $args['instance_start']['date'] == "" )
523 $errors[] = __( "Date in Starting Date/Time must not be empty.", 'timed-content' );
524 if ( $args['instance_start']['time'] == "" )
525 $errors[] = __( "Time in Starting Date/Time must not be empty.", 'timed-content' );
526 if ( $args['instance_end']['date'] == "" )
527 $errors[] = __( "Date in Ending Date/Time must not be empty.", 'timed-content' );
528 if ( $args['instance_end']['time'] == "" )
529 $errors[] = __( "Time in Ending Date/Time must not be empty.", 'timed-content' );
530 if ( $args['interval_multiplier'] == "" )
531 $errors[] = __( "Repeat How Often? must not be empty.", 'timed-content' );
532 if ( !is_numeric( $args['interval_multiplier'] ) )
533 $errors[] = __( "Repeat How Often? must be a number.", 'timed-content' );
534 if ( ( $args['num_repeat'] == "" ) && ( $args['recurr_type'] == "recurrence_duration_num_repeat" ) )
535 $errors[] = __( "Repeat How Many Times? must not be empty.", 'timed-content' );
536 if ( ( !is_numeric( $args['num_repeat'] ) ) && ( $args['recurr_type'] == "recurrence_duration_num_repeat" ) )
537 $errors[] = __( "Repeat How Many Times? must be a number.", 'timed-content' );
538 if ( ( $args['end_date'] == "" ) && ( $args['recurr_type'] == "recurrence_duration_end_date" ) )
539 $errors[] = __( "End Date must not be empty.", 'timed-content' );
540 if ( false === $instance_start )
541 $errors[] = __( "Starting Date/Time must be valid.", 'timed-content' );
542 if ( false === $instance_end )
543 $errors[] = __( "Ending Date/Time must be valid.", 'timed-content' );
544 if ( $instance_start > $instance_end )
545 $errors[] = __( "Starting Date/Time must be before Ending Date/Time.", 'timed-content' );
546 if ( ( $instance_end > $end_date ) && ( $args['recurr_type'] == "recurrence_duration_end_date" ) )
547 $errors[] = __( "End Date must be after Ending Date/Time.", 'timed-content' );
548
549 return $errors;
550 }
551
552 /**
553 * Calculates the active periods for a Timed Content Rule
554 *
555 * @param $args Array of Timed Content Rule parameters
556 * @return array Array of active periods. Each value in the array describes an active period as
557 * an array itself with "start" and "end" keys and values that are either UNIX
558 * timestamps or human-readable dates, based on whether $args['human_readable']
559 * is set to true or false.
560 */
561 function __getRulePeriods( $args ) {
562 $active_periods = array();
563 $period_count = 0;
564
565 $human_readable = $args['human_readable'];
566 $freq = $args['freq'];
567 $timezone = $args['timezone'];
568 $recurr_type = $args['recurr_type'];
569 $num_repeat = intval( $args['num_repeat'] );
570 $end_date = $args['end_date'];
571 $days_of_week = $args['days_of_week'];
572 $interval_multiplier = $args['interval_multiplier'];
573 $instance_start_date = $args['instance_start']['date'];
574 $instance_start_time = $args['instance_start']['time'];
575 $instance_end_date = $args['instance_end']['date'];
576 $instance_end_time = $args['instance_end']['time'];
577 $monthly_pattern = $args['monthly_pattern'];
578 $monthly_pattern_ord = $args['monthly_pattern_ord'];
579 $monthly_pattern_day = $args['monthly_pattern_day'];
580 $exceptions_dates = $args['exceptions_dates'];
581 //print_r($days_of_week);
582
583 add_filter('date_i18n', array( &$this, "fix_date_i18n" ), 10, 4);
584 $temp_tz = date_default_timezone_get();
585 date_default_timezone_set( $timezone );
586 $right_now_t = current_time( 'timestamp', 1 );
587
588 $instance_start = strtotime( $this->__datetimeToEnglish( $instance_start_date, $instance_start_time ) . " " . $timezone ); // Beginning of first occurrence
589 $instance_end = strtotime( $this->__datetimeToEnglish( $instance_end_date, $instance_end_time ) . " " . $timezone ); // End of first occurrence
590 $current = $instance_start;
591 $end_current = $instance_end;
592
593 if ( $recurr_type == "recurrence_duration_num_repeat" )
594 $last_occurrence_start = strtotime( TIMED_CONTENT_END_TIME );
595 else
596 $last_occurrence_start = strtotime( $this->__datetimeToEnglish( $end_date, $instance_start_time ) . " " . $timezone );
597
598 if ( $human_readable == true ) {
599 $active_periods[$period_count]["start"] = date_i18n( TIMED_CONTENT_DT_FORMAT, $current );
600 $active_periods[$period_count]["end"] = date_i18n( TIMED_CONTENT_DT_FORMAT, $end_current );
601 if ( $right_now_t < $current ) {
602 $active_periods[$period_count]["status"] = "upcoming";
603 $active_periods[$period_count]["time"] = sprintf( _x( '%s from now.', 'Human readable time difference', 'timed-content' ), human_time_diff( $right_now_t, $current ) );
604 } elseif ( ( $current <= $right_now_t ) && ( $right_now_t <= $end_current ) ) {
605 $active_periods[$period_count]["status"] = "active";
606 $active_periods[$period_count]["time"] = __( "Right now!", 'timed-content' );
607 } else {
608 $active_periods[$period_count]["status"] = "expired";
609 $active_periods[$period_count]["time"] = sprintf( _x( '%s ago.', 'Human readable time difference', 'timed-content' ), human_time_diff( $end_current, $right_now_t ) );
610 }
611 } else {
612 $active_periods[$period_count]["start"] = $current;
613 $active_periods[$period_count]["end"] = $end_current;
614 }
615 $period_count++;
616
617 if ( $recurr_type == "recurrence_duration_end_date" )
618 $loop_test = "return ( \$current < \$last_occurrence_start );";
619 else
620 $loop_test = "return ( \$period_count <= \$num_repeat );";
621
622 while ( eval ( $loop_test ) ) {
623 $temp_current = "";
624 if ( $freq == 0 )
625 $current = $this->__getNextHour( $current, $interval_multiplier );
626 elseif ( $freq == 1 )
627 $current = $this->__getNextDay( $current, $interval_multiplier );
628 elseif ( $freq == 2 )
629 $current = $this->__getNextWeek( $current, $interval_multiplier, $days_of_week );
630 elseif ( $freq == 3 ) {
631 $current = $this->__getNextMonth( $current, $instance_start, $interval_multiplier );
632 $temp_current = $current;
633 if ( $monthly_pattern == "yes" )
634 $current = $this->__getNthWeekdayOfMonth( $current, $monthly_pattern_ord, $monthly_pattern_day );
635 else
636 $current = $temp_current;
637 } elseif ( $freq == 4 )
638 $current = $this->__getNextYear( $current, $interval_multiplier );
639
640 $exception_period = false;
641 if ( is_array( $exceptions_dates ) ) {
642 foreach ($exceptions_dates as $date) {
643 if (($current >= $date) && ($current < strtotime("+1 day", $date))) {
644 $exception_period = true;
645 break;
646 }
647 }
648 }
649
650 if ( ( eval ( $loop_test ) ) && ( !($exception_period) ) ) {
651 $end_current = $current + ( $instance_end - $instance_start );
652 if ( $human_readable == true ) {
653 $active_periods[$period_count]["start"] = date_i18n( TIMED_CONTENT_DT_FORMAT, $current );
654 $active_periods[$period_count]["end"] = date_i18n( TIMED_CONTENT_DT_FORMAT, $end_current );
655 if ( $right_now_t < $current ) {
656 $active_periods[$period_count]["status"] = "upcoming";
657 $active_periods[$period_count]["time"] = sprintf( _x( '%s from now.', 'Human readable time difference', 'timed-content' ), human_time_diff( $current, $right_now_t ) );
658 } elseif ( ( $current <= $right_now_t ) && ( $right_now_t <= $end_current ) ) {
659 $active_periods[$period_count]["status"] = "active";
660 $active_periods[$period_count]["time"] = __( "Right now!", 'timed-content' );
661 } else {
662 $active_periods[$period_count]["status"] = "expired";
663 $active_periods[$period_count]["time"] = sprintf( _x( '%s ago.', 'Human readable time difference', 'timed-content' ), human_time_diff( $end_current, $right_now_t ) );
664 }
665 } else {
666 $active_periods[$period_count]["start"] = $current;
667 $active_periods[$period_count]["end"] = $end_current;
668 }
669 if ( !($exception_period) )
670 $period_count++;
671 }
672
673 }
674 date_default_timezone_set( $temp_tz );
675 remove_filter('date_i18n', array( &$this, "fix_date_i18n" ), 10, 4);
676 return $active_periods;
677 }
678
679 /**
680 * Wrapper for calling timedContentPlugin::__getRulePeriods() by the ID of a Timed Content Rule
681 *
682 * @param int $ID ID of the Timed Content Rule
683 * @param bool $human_readable If true, the active periods are returned as a human-readable date/time
684 * as defined by the constant TIMED_CONTENT_DT_FORMAT; otherwise, they are
685 * returned as UNIX timestamps.
686 * @return array Array of active periods
687 */
688 function getRulePeriodsById( $ID, $human_readable = false ) {
689 if ( TIMED_CONTENT_RULE_TYPE != get_post_type( $ID ) )
690 return array();
691
692 $prefix = TIMED_CONTENT_RULE_POSTMETA_PREFIX;
693 $args = array();
694
695 $args['human_readable'] = (bool) $human_readable;
696 $args['freq'] = get_post_meta( $ID, $prefix . 'frequency', true );
697 $args['timezone'] = get_post_meta( $ID, $prefix . 'timezone', true );
698 $args['recurr_type'] = get_post_meta( $ID, $prefix . 'recurrence_duration', true );
699 $args['num_repeat'] = get_post_meta( $ID, $prefix . 'recurrence_duration_num_repeat', true );
700 $args['end_date'] = get_post_meta( $ID, $prefix . 'recurrence_duration_end_date', true );
701 $args['days_of_week'] = get_post_meta( $ID, $prefix . 'weekly_days_of_week_to_repeat', true );
702 if ( $args['freq'] == 0 ) $args['interval_multiplier'] = get_post_meta( $ID, $prefix . 'hourly_num_of_hours', true );
703 if ( $args['freq'] == 1 ) $args['interval_multiplier'] = get_post_meta( $ID, $prefix . 'daily_num_of_days', true );
704 if ( $args['freq'] == 2 ) $args['interval_multiplier'] = get_post_meta( $ID, $prefix . 'weekly_num_of_weeks', true );
705 if ( $args['freq'] == 3 ) $args['interval_multiplier'] = get_post_meta( $ID, $prefix . 'monthly_num_of_months', true );
706 if ( $args['freq'] == 4 ) $args['interval_multiplier'] = get_post_meta( $ID, $prefix . 'yearly_num_of_years', true );
707 $args['instance_start'] = get_post_meta( $ID, $prefix . 'instance_start', true );
708 $args['instance_end'] = get_post_meta( $ID, $prefix . 'instance_end', true );
709 $args['monthly_pattern'] = get_post_meta( $ID, $prefix . 'monthly_nth_weekday_of_month', true );
710 $args['monthly_pattern_ord'] = get_post_meta( $ID, $prefix . 'monthly_nth_weekday_of_month_nth', true );
711 $args['monthly_pattern_day'] = get_post_meta( $ID, $prefix . 'monthly_nth_weekday_of_month_weekday', true );
712 $args['exceptions_dates'] = get_post_meta( $ID, $prefix . 'exceptions_dates', true );
713
714 return $this->__getRulePeriods( $args );
715
716 }
717
718 /**
719 * Wrapper for calling timedContentPlugin::__getRulePeriods() based on the contents of the form fields
720 * of the Add Timed Content Rule and Edit Timed Content Rule screens. Output is sent to output as JSON
721 */
722 function timedContentPluginGetRulePeriodsAjax() {
723 if ( current_user_can( 'edit_posts' ) || current_user_can( 'edit_pages' ) ) {
724 $prefix = TIMED_CONTENT_RULE_POSTMETA_PREFIX;
725 $args = array();
726
727 $args['human_readable'] = ( ( ( isset( $_POST[$prefix . 'human_readable'] ) ) && ( $_POST[$prefix . 'human_readable'] == 'true' ) ) ? (bool)$_POST[$prefix . 'human_readable'] : false );
728 $args['freq'] = $_POST[$prefix . 'frequency'];
729 $args['timezone'] = $_POST[$prefix . 'timezone'];
730 $args['recurr_type'] = $_POST[$prefix . 'recurrence_duration'];
731 $args['num_repeat'] = $_POST[$prefix . 'recurrence_duration_num_repeat'];
732 $args['end_date'] = $_POST[$prefix . 'recurrence_duration_end_date'];
733 $args['days_of_week'] = ( isset( $_POST[$prefix . 'weekly_days_of_week_to_repeat'] ) ? $_POST[$prefix . 'weekly_days_of_week_to_repeat'] : array() );
734 $args['interval_multiplier'] = $_POST[$prefix . 'interval_multiplier'];
735 $args['instance_start'] = $_POST[$prefix . 'instance_start'];
736 $args['instance_end'] = $_POST[$prefix . 'instance_end'];
737 $args['monthly_pattern'] = $_POST[$prefix . 'monthly_nth_weekday_of_month'];
738 $args['monthly_pattern_ord'] = $_POST[$prefix . 'monthly_nth_weekday_of_month_nth'];
739 $args['monthly_pattern_day'] = $_POST[$prefix . 'monthly_nth_weekday_of_month_weekday'];
740 $args['exceptions_dates'] = ( isset( $_POST[$prefix . 'exceptions_dates'] ) ? $_POST[$prefix . 'exceptions_dates'] : array() );
741
742 $response = json_encode( $this->__getRulePeriods( $args ) );
743
744 // response output
745 header( "Content-Type: application/json" );
746 echo $response;
747 }
748 die();
749
750 }
751
752 /**
753 * Returns a human-readable description of a Timed Content Rule
754 *
755 * @param $args Array of Timed Content Rule parameters
756 * @return string
757 */
758 function __getScheduleDescription( $args ) {
759 include("lib/Arrays_Definitions.php");
760
761 $interval_multiplier = 1;
762 $desc = "";
763
764 $errors = $this->__validate( $args );
765 if ( $errors ) {
766 $messages = "<div class=\"tcr-warning\">\n";
767 $messages .= "<p class=\"heading\">" . __( "Warning!", 'timed-content' ) . "</p>\n";
768 $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";
769 $messages .= "<ul>\n";
770 foreach ( $errors as $error )
771 $messages .= " <li>" . $error . "</li>\n";
772 $messages .= "</ul>\n";
773 $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";
774 $messages .= "</div>\n";
775 return $messages;
776 }
777
778 if ( $args['action'] )
779 $action = __( "Show the content", 'timed-content' );
780 else
781 $action = __( "Hide the content", 'timed-content' );
782 $freq = $args['freq'];
783 $timezone = $args['timezone'];
784 $recurr_type = $args['recurr_type'];
785 $num_repeat = intval( $args['num_repeat'] );
786 $end_date = $args['end_date'];
787 $days_of_week = $args['days_of_week'];
788 $interval_multiplier = $args['interval_multiplier'];
789 $instance_start_date = $args['instance_start']['date'];
790 $instance_start_time = $args['instance_start']['time'];
791 $instance_end_date = $args['instance_end']['date'];
792 $instance_end_time = $args['instance_end']['time'];
793 $monthly_pattern = $args['monthly_pattern'];
794 $monthly_pattern_ord = $args['monthly_pattern_ord'];
795 $monthly_pattern_day = $args['monthly_pattern_day'];
796 $exceptions_dates = $args['exceptions_dates'];
797
798 $desc = sprintf( _x( '%1$s on %2$s @ %3$s until %4$s @ %5$s.', 'Perform action (%1$s) from date/time of first active period (%2$s @ %3$s) until date/time of last active period (%4$s @ %5$s).', 'timed-content' ), $action, $instance_start_date, $instance_start_time, $instance_end_date, $instance_end_time );
799
800 if ( $freq == 0 )
801 $desc .= "&nbsp;" . sprintf( _n( 'Repeat this action every hour.', 'Repeat this action every %d hours.', $interval_multiplier, 'timed-content' ), $interval_multiplier );
802 elseif ( $freq == 1 )
803 $desc .= "&nbsp;" . sprintf( _n( 'Repeat this action every day.', 'Repeat this action every %d days.', $interval_multiplier, 'timed-content' ), $interval_multiplier );
804 elseif ( $freq == 2 ) {
805 if ( ( $days_of_week ) && ( is_array( $days_of_week ) ) ) {
806 $days = array(); $days_list = "";
807 foreach ( $days_of_week as $v )
808 $days[] = $timed_content_rule_days_array[$v];
809 switch ( count( $days ) ) {
810 case 1: $days_list = sprintf( _x( '%1$s', 'List of one weekday', 'timed-content' ), $days[0] ); break;
811 case 2: $days_list = sprintf( _x( '%1$s and %2$s', 'List of two weekdays', 'timed-content' ), $days[0], $days[1] ); break;
812 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;
813 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;
814 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;
815 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;
816 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;
817 }
818 if ( $interval_multiplier == 1 )
819 $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 );
820 else
821 $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 );
822 } else
823 $desc .= "&nbsp;" . sprintf( _n( 'Repeat this action every week.', 'Repeat this action every %d weeks.', $interval_multiplier, 'timed-content' ), $interval_multiplier );
824
825 } elseif ( $freq == 3 ) {
826 if ( $monthly_pattern == "yes" ) {
827 if ( $interval_multiplier == 1 )
828 $desc .= "&nbsp;" . sprintf( _x( 'Repeat this action every month on the %1$s %2$s of the month.', "Example: 'Repeat this action every month on the second Friday of the month.'", 'timed-content' ), $timed_content_rule_ordinal_array[$monthly_pattern_ord], $timed_content_rule_ordinal_days_array[$monthly_pattern_day] );
829 else
830 $desc .= "&nbsp;" . sprintf( _x( 'Repeat this action every %1$d months on the %2$s %3$s of the month.', "Example: 'Repeat this action every 2 months on the second Friday of the month.'", 'timed-content' ), $interval_multiplier, $timed_content_rule_ordinal_array[$monthly_pattern_ord], $timed_content_rule_ordinal_days_array[$monthly_pattern_day] );
831 } else
832 $desc .= "&nbsp;" . sprintf( _n( 'Repeat this action every month.', 'Repeat this action every %d months.', $interval_multiplier, 'timed-content' ), $interval_multiplier );
833 } elseif ( $freq == 4 )
834 $desc .= "&nbsp;" . sprintf( _n( 'Repeat this action every year.', 'Repeat this action every %d years.', $interval_multiplier, 'timed-content' ), $interval_multiplier );
835
836 if ( $recurr_type == "recurrence_duration_num_repeat" )
837 $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 );
838 elseif ( $recurr_type == "recurrence_duration_end_date" )
839 $desc .= "&nbsp;" . sprintf( __( 'This rule will be active until %s.', 'timed-content' ), $end_date );
840
841 if ( ( $exceptions_dates ) && ( is_array( $exceptions_dates ) ) ) {
842 sort( $exceptions_dates, SORT_NUMERIC );
843 $exceptions_dates = array_unique( $exceptions_dates );
844 if ( $exceptions_dates[0] == 0 )
845 array_shift( $exceptions_dates );
846 if ( !empty( $exceptions_dates ) ) {
847 $formatted_dates = array();
848 foreach ( $exceptions_dates as $a_date )
849 $formatted_dates[] = date( _x( "F j, Y" , "Date format for schedule description", 'timed-content' ), $a_date );
850 $desc .= "&nbsp;" . sprintf( __( 'This rule will be inactive on the following dates: %s.', 'timed-content' ), join( ", ", $formatted_dates ) );
851 }
852 }
853
854 $desc .= "&nbsp;" . sprintf( __( 'All times are in the %s timezone.', 'timed-content' ), $timezone );
855 return $desc;
856 }
857
858 /**
859 * Wrapper for calling timedContentPlugin::__getScheduleDescription() by the ID of a Timed Content Rule
860 *
861 * @param int $ID ID of the Timed Content Rule
862 * @return string
863 */
864 function getScheduleDescriptionById( $ID ) {
865 global $timed_content_rule_occurrence_custom_fields,
866 $timed_content_rule_pattern_custom_fields,
867 $timed_content_rule_recurrence_custom_fields,
868 $timed_content_rule_exceptions_custom_fields;
869 $defaults = array();
870
871 foreach ( $timed_content_rule_occurrence_custom_fields as $field ) {
872 $defaults[$field['name']] = $field['default'];
873 }
874 foreach ( $timed_content_rule_pattern_custom_fields as $field ) {
875 $defaults[$field['name']] = $field['default'];
876 }
877 foreach ( $timed_content_rule_recurrence_custom_fields as $field ) {
878 $defaults[$field['name']] = $field['default'];
879 }
880 foreach ( $timed_content_rule_exceptions_custom_fields as $field ) {
881 $defaults[$field['name']] = $field['default'];
882 }
883
884 $prefix = TIMED_CONTENT_RULE_POSTMETA_PREFIX;
885 $args = array();
886
887 $args['action'] = ( false === get_post_meta( $ID, $prefix . 'action', true ) ? $defaults['action'] : get_post_meta( $ID, $prefix . 'action', true ) );
888 $args['freq'] = ( false === get_post_meta( $ID, $prefix . 'frequency', true ) ? $defaults['frequency'] : get_post_meta( $ID, $prefix . 'frequency', true ) );
889 $args['timezone'] = ( false === get_post_meta( $ID, $prefix . 'timezone', true ) ? $defaults['timezone'] : get_post_meta( $ID, $prefix . 'timezone', true ) );
890 $args['recurr_type'] = ( false === get_post_meta( $ID, $prefix . 'recurrence_duration', true ) ? $defaults['recurrence_duration'] : get_post_meta( $ID, $prefix . 'recurrence_duration', true ) );
891 $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 ) );
892 $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 ) );
893 $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 ) );
894 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 ) );
895 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 ) );
896 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 ) );
897 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 ) );
898 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 ) );
899 $args['instance_start'] = ( false === get_post_meta( $ID, $prefix . 'instance_start', true ) ? $defaults['instance_start'] : get_post_meta( $ID, $prefix . 'instance_start', true ) );
900 $args['instance_end'] = ( false === get_post_meta( $ID, $prefix . 'instance_end', true ) ? $defaults['instance_end'] : get_post_meta( $ID, $prefix . 'instance_end', true ) );
901 $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 ) );
902 $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 ) );
903 $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 ) );
904 $args['exceptions_dates'] = ( false === get_post_meta( $ID, $prefix . 'exceptions_dates', true ) ? $defaults['exceptions_dates'] : get_post_meta( $ID, $prefix . 'exceptions_dates', true ) );
905
906 return $this->__getScheduleDescription( $args );
907
908 }
909
910 /**
911 * Wrapper for calling timedContentPlugin::__getRulePeriods() based on the contents of the form fields
912 * of the Add Timed Content Rule and Edit Timed Content Rule screens. Output is sent to output as plain text
913 */
914 function timedContentPluginGetScheduleDescriptionAjax() {
915 if ( current_user_can( 'edit_posts' ) || current_user_can( 'edit_pages' ) ) {
916 $prefix = TIMED_CONTENT_RULE_POSTMETA_PREFIX;
917 $args = array();
918
919 $args['action'] = $_POST[$prefix . 'action'];
920 $args['freq'] = $_POST[$prefix . 'frequency'];
921 $args['timezone'] = $_POST[$prefix . 'timezone'];
922 $args['recurr_type'] = $_POST[$prefix . 'recurrence_duration'];
923 $args['num_repeat'] = $_POST[$prefix . 'recurrence_duration_num_repeat'];
924 $args['end_date'] = $_POST[$prefix . 'recurrence_duration_end_date'];
925 $args['days_of_week'] = ( isset( $_POST[$prefix . 'weekly_days_of_week_to_repeat'] ) ? $_POST[$prefix . 'weekly_days_of_week_to_repeat'] : array() );
926 $args['interval_multiplier'] = $_POST[$prefix . 'interval_multiplier'];
927 $args['instance_start'] = $_POST[$prefix . 'instance_start'];
928 $args['instance_end'] = $_POST[$prefix . 'instance_end'];
929 $args['monthly_pattern'] = $_POST[$prefix . 'monthly_nth_weekday_of_month'];
930 $args['monthly_pattern_ord'] = $_POST[$prefix . 'monthly_nth_weekday_of_month_nth'];
931 $args['monthly_pattern_day'] = $_POST[$prefix . 'monthly_nth_weekday_of_month_weekday'];
932 $args['exceptions_dates'] = ( isset( $_POST[$prefix . 'exceptions_dates'] ) ? $_POST[$prefix . 'exceptions_dates'] : array() );
933
934 $response = $this->__getScheduleDescription( $args );
935
936 // response output
937 header( "Content-Type: text/plain" );
938 echo $response;
939 }
940 die();
941 }
942
943 /**
944 * Processes the [timed-content-client] shortcode.
945 *
946 * @param array $atts
947 * @param null $content
948 * @return string
949 */
950 function clientShowHTML( $atts, $content = null ) {
951 $show_attr = "";
952 $hide_attr = "";
953 extract( shortcode_atts( array( 'show' => '0:00:000' , 'hide' => '0:00:000' , 'display' => 'div' ), $atts ) );
954
955 // Initialize show/hide arguments
956 $s_min = 0; $s_sec = 0; $s_fade = 0;
957 $h_min = 0; $h_sec = 0; $h_fade = 0;
958 @list( $s_min, $s_sec, $s_fade ) = explode( ":", $show );
959 @list( $h_min, $h_sec, $h_fade ) = explode( ":", $hide );
960
961 if ( ( (int)$s_min + (int)$s_sec ) > 0 )
962 $show_attr = "_show_" . $s_min . "_" . $s_sec . "_" . $s_fade;
963 if ( ( (int)$h_min + (int)$h_sec ) > 0 )
964 $hide_attr = "_hide_" . $h_min . "_" . $h_sec . "_" . $h_fade;
965
966 $the_class = TIMED_CONTENT_CLIENT_TAG . $show_attr . $hide_attr ;
967 $the_tag = ( $display == "div" ? "div" : "span" );
968
969 $the_filter = "timed_content_filter";
970 $the_filter = apply_filters( "timed_content_filter_override", $the_filter );
971
972 $the_HTML = "<"
973 . $the_tag
974 . " class='"
975 . $the_class
976 . "'"
977 . ( ( $show_attr != "" ) ? " style='display: none;'" : "" ) .">"
978 . str_replace( ']]>', ']]&gt;', apply_filters( $the_filter, $content ) )
979 . "</" . $the_tag . ">";
980
981 return $the_HTML;
982 }
983
984 /**
985 * Processes the [timed-content-server] shortcode.
986 *
987 * @param array $atts
988 * @param null $content
989 * @return string
990 */
991 function serverShowHTML( $atts, $content = null ) {
992 global $post;
993 extract( shortcode_atts( array( 'show' => TIMED_CONTENT_ZERO_TIME , 'hide' => TIMED_CONTENT_END_TIME, 'debug' => 'false' ), $atts ) );
994 $show_t = strtotime( $this->__datetimeToEnglish( $show ) );
995 $hide_t = strtotime( $this->__datetimeToEnglish( $hide ) );
996 $right_now_t = current_time( 'timestamp', 1 );
997 $debug_message = "";
998
999 $the_filter = "timed_content_filter";
1000 $the_filter = apply_filters( "timed_content_filter_override", $the_filter );
1001
1002 if ( ( $debug == "true" ) && ( current_user_can( "edit_post", $post->post_id ) ) ) {
1003 add_filter('date_i18n', array( &$this, "fix_date_i18n" ), 10, 4);
1004 $temp_tz = date_default_timezone_get();
1005 date_default_timezone_set( get_option( 'timezone_string' ) );
1006
1007 $right_now = date_i18n( TIMED_CONTENT_DT_FORMAT, $right_now_t );
1008
1009 if ( $show_t > $right_now_t )
1010 $show_diff_str = sprintf( _x( '%s from now.', 'Human readable time difference', 'timed-content' ), human_time_diff( $show_t, $right_now_t ) );
1011 else
1012 $show_diff_str = sprintf( _x( '%s ago.', 'Human readable time difference', 'timed-content' ), human_time_diff( $show_t, $right_now_t ) );
1013 if ( $hide_t > $right_now_t )
1014 $hide_diff_str = sprintf( _x( '%s from now.', 'Human readable time difference', 'timed-content' ), human_time_diff( $hide_t, $right_now_t ) );
1015 else
1016 $hide_diff_str = sprintf( _x( '%s ago.', 'Human readable time difference', 'timed-content' ), human_time_diff( $hide_t, $right_now_t ) );
1017
1018 $debug_message = "<div class=\"tcr-warning\">\n";
1019 $debug_message .= "<p class=\"heading\">" . _x( "Notice", "Noun", 'timed-content' ) . "</p>\n";
1020 $debug_message .= "<p>" . sprintf( __( 'Debugging has been turned on for a %1$s 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 %2$s attribute from the shortcode.', 'timed-content' ), "<code>[timed-content-server]</code>" , "<code>debug</code>" ) . "</p>\n";
1021
1022 if ( $show == TIMED_CONTENT_ZERO_TIME )
1023 $debug_message .= "<p>" . sprintf( __( 'The %s attribute is not set.', 'timed-content' ), "<code>show</code>" ) . "</p>\n";
1024 else
1025 $debug_message .= "<p>" . sprintf( __( 'The %s attribute is currently set to', 'timed-content' ), "<code>show</code>" ) . ": " . $show . ",<br />\n "
1026 . __( 'The Timed Content plugin thinks the intended date/time is', 'timed-content') . ": " . date_i18n( TIMED_CONTENT_DT_FORMAT, $show_t )
1027 . " (" . $show_diff_str . ")</p>\n";
1028
1029 if ( $hide == TIMED_CONTENT_END_TIME )
1030 $debug_message .= "<p>" . sprintf( __( 'The %s attribute is not set.' , 'timed-content' ), "<code>hide</code>" ) . "</p>\n";
1031 else
1032 $debug_message .= "<p>" . sprintf( __( 'The %s attribute is currently set to', 'timed-content' ), "<code>hide</code>" ) . ": " . $hide . ",<br />\n"
1033 . __( 'The Timed Content plugin thinks the intended date/time is', 'timed-content') . ": " . date_i18n( TIMED_CONTENT_DT_FORMAT, $hide_t )
1034 . " (" . $hide_diff_str . ").</p>\n";
1035
1036 $debug_message .= "<p>" . __( 'Current Date/Time:', 'timed-content') . "&nbsp;" . $right_now . "<br />\n";
1037 $debug_message .= __( 'Content Filter:', 'timed-content') . "&nbsp;" . $the_filter . "</p>\n";
1038 $debug_message .= "<p>" . _x( 'Content:', "Noun", 'timed-content') . "&nbsp;" . $content . "</p>\n";
1039
1040 $debug_message .= "</div>\n";
1041
1042 date_default_timezone_set( $temp_tz );
1043 remove_filter('date_i18n', array( &$this, "fix_date_i18n" ), 10, 4);
1044 }
1045
1046
1047 if ( ( $show_t <= $right_now_t ) && ( $right_now_t <= $hide_t ) ) {
1048 do_action("timed_content_server_show", $post->ID, $show, $hide, $content);
1049 return $debug_message . str_replace(']]>', ']]&gt;', apply_filters($the_filter, $content)) . "\n";
1050 } else {
1051 do_action("timed_content_server_hide", $post->ID, $show, $hide, $content);
1052 return $debug_message . "\n";
1053 }
1054
1055 }
1056
1057 /**
1058 * Processes the [timed-content-rule] shortcode.
1059 *
1060 * @param array $atts
1061 * @param null $content
1062 * @return string
1063 */
1064 function rulesShowHTML( $atts, $content = null ) {
1065 global $post;
1066 extract( shortcode_atts( array( 'id' => 0 ), $atts ) );
1067 if ( !is_numeric( $id ) ) {
1068 $page = get_page_by_title( $id, OBJECT, TIMED_CONTENT_RULE_TYPE );
1069 if ( $page == null ) return;
1070 $id = $page->ID;
1071 }
1072 if ( TIMED_CONTENT_RULE_TYPE != get_post_type( $id ) ) return;
1073
1074 $prefix = TIMED_CONTENT_RULE_POSTMETA_PREFIX;
1075 $right_now_t = current_time( 'timestamp', 1 );
1076 $rule_is_active = false;
1077
1078 $active_periods = $this->getRulePeriodsById( $id, false );
1079 $action_is_show = (bool) get_post_meta( $id, $prefix . 'action', true );
1080
1081 foreach ( $active_periods as $period ) {
1082 if ( ( $period['start'] <= $right_now_t ) && ( $right_now_t <= $period['end'] ) ) {
1083 $rule_is_active = true;
1084 break;
1085 }
1086 }
1087
1088 $the_filter = "timed_content_filter";
1089 $the_filter = apply_filters( "timed_content_filter_override", $the_filter );
1090
1091 if ( ( ( $rule_is_active == true ) && ( $action_is_show == true ) ) || ( ( $rule_is_active == false ) && ( $action_is_show == false ) ) ) {
1092 do_action("timed_content_rule_show", $post->ID, $id, $content);
1093 return str_replace(']]>', ']]&gt;', apply_filters($the_filter, $content));
1094 } else {
1095 do_action("timed_content_rule_hide", $post->ID, $id, $content);
1096 return "";
1097 }
1098 }
1099
1100 /**
1101 * Enqueues the JavaScript code necessary for the functionality of the [timed-content-client] shortcode.
1102 */
1103 function addHeaderCode() {
1104 if ( ! is_admin() ) {
1105 wp_enqueue_style( 'timed-content-css', TIMED_CONTENT_CSS, false, TIMED_CONTENT_VERSION );
1106 wp_enqueue_script( 'timed-content_js', TIMED_CONTENT_PLUGIN_URL . '/js/timed-content.js', array( 'jquery' ), TIMED_CONTENT_VERSION );
1107 }
1108 }
1109
1110 /**
1111 * Enqueues the CSS code necessary for custom icons for the Timed Content Rules management screens for WP 3.7.1 and under. Echo'd to output.
1112 */
1113 function addPostTypeIcons37() {
1114 ?>
1115 <style type="text/css" media="screen">
1116 #menu-posts-<?php echo TIMED_CONTENT_RULE_TYPE; ?> .wp-menu-image {
1117 background: url(<?php echo TIMED_CONTENT_PLUGIN_URL; ?>/img/clock_icon.png) no-repeat 6px 6px !important;
1118 }
1119 #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 {
1120 background-position: -22px 6px !important;
1121 }
1122 #icon-edit.icon32-posts-<?php echo TIMED_CONTENT_RULE_TYPE; ?> {background: url(<?php echo TIMED_CONTENT_PLUGIN_URL; ?>/img/clock_32x32.png) no-repeat;}
1123 </style>
1124 <?php
1125 }
1126
1127 /**
1128 * Enqueues the CSS code necessary for custom icons for the Timed Content Rules management screens
1129 * and the TinyMCE editor. Echo'd to output.
1130 */
1131 function addPostTypeIcons() {
1132 wp_enqueue_style( 'ca-aliencyborg-dashicons', TIMED_CONTENT_CSS_DASHICONS, false, TIMED_CONTENT_VERSION );
1133 ?>
1134 <style type="text/css" media="screen">
1135 #adminmenu #menu-posts-<?php echo TIMED_CONTENT_RULE_TYPE; ?>.menu-icon-post div.wp-menu-image:before {
1136 font-family: 'ca-aliencyborg-dashicons' !important;
1137 content: '\e601';
1138 }
1139 #dashboard_right_now li.<?php echo TIMED_CONTENT_RULE_TYPE; ?>-count a:before {
1140 font-family: 'ca-aliencyborg-dashicons' !important;
1141 content: '\e601';
1142 }
1143 .mce-i-timed_content:before {
1144 font: 400 24px/1 'ca-aliencyborg-dashicons' !important;
1145 padding: 0;
1146 vertical-align: top;
1147 margin-left: -2px;
1148 padding-right: 2px;
1149 content: '\e601';
1150 }
1151 </style>
1152 <?php
1153 }
1154
1155 /**
1156 * Enqueues the JavaScript code necessary for the functionality of the Timed Content Rules management screens.
1157 */
1158 function addAdminHeaderCode() {
1159 if ( ( isset( $_GET['post_type'] ) && $_GET['post_type'] == TIMED_CONTENT_RULE_TYPE )
1160 || ( isset( $post_type ) && $post_type == TIMED_CONTENT_RULE_TYPE )
1161 || ( isset( $_GET['post'] ) && get_post_type( $_GET['post'] ) == TIMED_CONTENT_RULE_TYPE ) ) {
1162 wp_enqueue_style( 'thickbox' );
1163 wp_enqueue_style( 'timed-content-css', TIMED_CONTENT_CSS, false, TIMED_CONTENT_VERSION );
1164 // Enqueue the JavaScript file that manages the meta box UI
1165 wp_enqueue_script( 'timed-content-admin_js', TIMED_CONTENT_PLUGIN_URL . '/js/timed-content-admin.js', array( 'jquery' ), TIMED_CONTENT_VERSION );
1166 // Enqueue the JavaScript file that makes AJAX requests
1167 wp_enqueue_script( 'timed-content-ajax_js', TIMED_CONTENT_PLUGIN_URL . '/js/timed-content-ajax.js', array( 'jquery', 'thickbox' ), TIMED_CONTENT_VERSION );
1168
1169 // Set up local variables used in the Admin JavaScript file
1170 wp_localize_script( 'timed-content-admin_js', 'timedContentRuleAdmin', array(
1171 'no_exceptions_label' => __( "- No exceptions set -", 'timed-content' ) ) );
1172
1173 // Set up local variables used in the AJAX JavaScript file
1174 wp_localize_script( 'timed-content-ajax_js', 'timedContentRuleAjax', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ),
1175 'start_label' => _x( 'Start', 'Scheduled Dates/Times dialog - Beginning of active period table header', 'timed-content' ),
1176 'end_label' => _x( 'End', 'Scheduled Dates/Times dialog - End of active period table header', 'timed-content' ),
1177 'dialog_label' => _x( 'Scheduled Dates/Times', 'Scheduled Dates/Times dialog - dialog header', 'timed-content' ),
1178 'button_loading_label' => __( 'Calculating Dates/Times', 'timed-content' ),
1179 'button_finished_label' => __( 'Show Projected Dates/Times', 'timed-content' ),
1180 'dialog_width' => 800,
1181 'dialog_height' => 500,
1182 'error' => __( "Error", 'timed-content' ),
1183 'error_desc' => __( "Something unexpected has happened along the way. The specific details are below:", 'timed-content' ) ) );
1184 }
1185 }
1186
1187 /**
1188 * Initializes the TinyMCE plugin bundled with this Wordpress plugin
1189 */
1190 function initTinyMCEPlugin() {
1191 if ( ( ! current_user_can( 'edit_posts' ) ) && ( ! current_user_can( 'edit_pages' ) ) )
1192 return;
1193
1194 // Add only in Rich Editor mode
1195 if ( get_user_option( 'rich_editing' ) == 'true' ) {
1196 add_filter( "mce_external_plugins", array( &$this, "addTimedContentTinyMCEPlugin" ) );
1197 add_filter( "mce_buttons", array( &$this, "registerTinyMCEButton" ) );
1198 }
1199 }
1200
1201 /**
1202 * Sets up variables to use in the TinyMCE plugin's plugin.js.
1203 *
1204 */
1205 function setTinyMCEPluginVars() {
1206 global $wp_version;
1207 if ( ( ! current_user_can( 'edit_posts' ) ) && ( ! current_user_can( 'edit_pages' ) ) )
1208 return;
1209
1210 // Add only in Rich Editor mode
1211 if ( get_user_option( 'rich_editing' ) == 'true' ) {
1212 if ( version_compare( $wp_version, "3.8", "<" ) )
1213 $image = "/clock.gif";
1214 else
1215 $image = "";
1216 wp_localize_script( 'editor',
1217 'timedContentAdminTinyMCEOptions',
1218 array( 'version' => TIMED_CONTENT_VERSION,
1219 'desc' => __( "Add Timed Content shortcodes", 'timed-content' ),
1220 'image' => $image ) );
1221 }
1222 }
1223
1224 /**
1225 * Sets up the button for the associated TinyMCE plugin for use in the editor menubar.
1226 * @param array $buttons Array of menu buttons already registered with TinyMCE
1227 * @return array The array of TinyMCE menu buttons with ours now loaded in as well
1228 */
1229 function registerTinyMCEButton( $buttons ) {
1230 array_push( $buttons, "|", "timed_content" );
1231 return $buttons;
1232 }
1233
1234 /**
1235 * Loads the associated TinyMCE plugin into TinyMCE's plugin array
1236 *
1237 * @param array $plugin_array Array of plugins already registered with TinyMCE
1238 * @return array The array of TinyMCE plugins with ours now loaded in as well
1239 */
1240 function addTimedContentTinyMCEPlugin( $plugin_array ) {
1241 $plugin_array['timed_content'] = TIMED_CONTENT_PLUGIN_URL . "/tinymce_plugin/plugin.js";
1242 return $plugin_array;
1243 }
1244
1245 /**
1246 * Generates JavaScript array of objects describing Timed Content Rules. Used in the dialog box created by
1247 * timedContentPlugin::timedContentPluginGetTinyMCEDialog().
1248 *
1249 * @return string
1250 */
1251 function __getRulesJS() {
1252 $the_js = "var rules = [\n";
1253 $args = array( 'post_type' => TIMED_CONTENT_RULE_TYPE, 'posts_per_page' => -1, 'post_status' => 'publish' );
1254 $the_rules = get_posts( $args );
1255 foreach ( $the_rules as $rule ) {
1256 $desc = $this->getScheduleDescriptionById( $rule->ID );
1257 // Only add a rule if there's no errors or warnings
1258 if ( false === strpos( $desc, "tcr-warning" ) )
1259 $the_js .= " { 'ID': " . $rule->ID . ", 'title': '" . esc_js( ( ( strlen( $rule->post_title ) > 0 ) ? $rule->post_title : _x( "(no title)", "No Timed Content Rule title", "timed-content" ) ) ) . "', 'desc': '" . esc_js( $desc ) . "' },\n";
1260 }
1261 if ( empty( $the_rules ) )
1262 $the_js .= " { 'ID': -999, 'title': ' ---- ', 'desc': '" . __( 'No Timed Content Rules found', 'timed-content' ) . "' }\n";
1263
1264 $the_js .= "];\n";
1265 return $the_js;
1266 }
1267 /**
1268 * Display a dialog box for this plugin's associated TinyMCE plugin. Called from TinyMCE via AJAX.
1269 *
1270 */
1271 function timedContentPluginGetTinyMCEDialog() {
1272 include("lib/jquery-ui-datetime-i18n.php");
1273
1274 wp_enqueue_style(TIMED_CONTENT_SLUG . '-jquery-ui-css', TIMED_CONTENT_JQUERY_UI_CSS);
1275 wp_enqueue_script('jquery-ui-datepicker');
1276 wp_register_style(TIMED_CONTENT_SLUG . '-jquery-ui-timepicker-css', TIMED_CONTENT_JQUERY_UI_TIMEPICKER_CSS);
1277 wp_enqueue_style(TIMED_CONTENT_SLUG . '-jquery-ui-timepicker-css');
1278 wp_register_script(TIMED_CONTENT_SLUG . '-jquery-ui-timepicker-js', TIMED_CONTENT_JQUERY_UI_TIMEPICKER_JS, array('jquery', 'jquery-ui-datepicker'), TIMED_CONTENT_VERSION);
1279 wp_enqueue_script(TIMED_CONTENT_SLUG . '-jquery-ui-timepicker-js');
1280 if (!(wp_script_is(TIMED_CONTENT_SLUG . '-jquery-ui-datetime-i18n-js', 'registered'))) {
1281 wp_register_script(TIMED_CONTENT_SLUG . '-jquery-ui-datetime-i18n-js', TIMED_CONTENT_PLUGIN_URL . "/js/content-protector-datetime-i18n.js", array('jquery', 'jquery-ui-datepicker', TIMED_CONTENT_SLUG . '-jquery-ui-timepicker-js'), TIMED_CONTENT_VERSION);
1282 wp_enqueue_script(TIMED_CONTENT_SLUG . '-jquery-ui-datetime-i18n-js');
1283 wp_localize_script(TIMED_CONTENT_SLUG . '-jquery-ui-datetime-i18n-js', 'TimedContentJQDatepickerI18n', $jquery_ui_datetime_datepicker_i18n);
1284 wp_localize_script(TIMED_CONTENT_SLUG . '-jquery-ui-datetime-i18n-js', 'TimedContentJQTimepickerI18n', $jquery_ui_datetime_timepicker_i18n);
1285 }
1286
1287 ob_start();
1288 include( "tinymce_plugin/dialog.php" );
1289 $content = ob_get_contents();
1290 ob_end_clean();
1291 echo $content;
1292 die();
1293 }
1294
1295 /**
1296 * Adds support for i18n (internationalization)
1297 *
1298 */
1299 function i18nInit() {
1300 $plugin_dir = basename( dirname( __FILE__ ) ) . "/lang/";
1301 load_plugin_textdomain( 'timed-content', false, $plugin_dir );
1302 }
1303
1304 /**
1305 * Add custom columns to the Timed Content Rules overview page
1306 *
1307 */
1308 function addDescColumnHead( $defaults ) {
1309 unset( $defaults['date'] );
1310 $defaults['description'] = __( 'Description', 'timed-content' );
1311 $defaults['shortcode'] = __( 'Shortcode', 'timed-content' );
1312 return $defaults;
1313 }
1314
1315 /**
1316 * Display content associated with custom columns on the Timed Content Rules overview page
1317 *
1318 * @param $column_name Name of the column to be displayed
1319 * @param $post_ID ID of the Timed Content Rule being listed
1320 */
1321 function addDescColumnContent( $column_name, $post_ID ) {
1322 if ( $column_name == 'shortcode' ) {
1323 echo '<code>[' . TIMED_CONTENT_RULE_TAG . ' id="' . $post_ID . '"]...[/' . TIMED_CONTENT_RULE_TAG . ']</code>';
1324 }
1325 if ( $column_name == 'description' ) {
1326 $desc = $this->getScheduleDescriptionById( $post_ID );
1327 if ( $desc ) {
1328 echo '<em>' . $desc . '</em>';
1329 }
1330 }
1331 }
1332
1333 /**
1334 * Display a count of Timed Content Rules in the Dashboard's Right Now widget for Wordpress versions 3.7.1 and below
1335 *
1336 */
1337 function addRulesCount37() {
1338 if ( !post_type_exists( TIMED_CONTENT_RULE_TYPE ) ) {
1339 return;
1340 }
1341
1342 $num_posts = wp_count_posts( TIMED_CONTENT_RULE_TYPE );
1343 $num = number_format_i18n( $num_posts->publish );
1344 $text = _n( 'Timed Content Rule', 'Timed Content Rules', intval( $num_posts->publish ), 'timed-content' );
1345 if ( current_user_can( 'edit_posts' ) || current_user_can( 'edit_pages' ) ) {
1346 $num = "<a href='edit.php?post_type=" . TIMED_CONTENT_RULE_TYPE . "'>" . $num . "</a>";
1347 $text = "<a href='edit.php?post_type=" . TIMED_CONTENT_RULE_TYPE . "'>" . $text . "</a>";
1348 }
1349 echo '<tr>';
1350 echo '<td class="first b b-' . TIMED_CONTENT_RULE_TYPE . '">' . $num . '</td>';
1351 echo '<td class="t ' . TIMED_CONTENT_RULE_TYPE . '">' . $text . '</td>';
1352 echo '</tr>';
1353
1354 if ( $num_posts->pending > 0 ) {
1355 $num = number_format_i18n( $num_posts->pending );
1356 $text = _n( 'Timed Content Rule Pending', 'Timed Content Rules Pending', intval( $num_posts->pending ), 'timed-content' );
1357 if ( current_user_can( 'edit_posts' ) || current_user_can( 'edit_pages' ) ) {
1358 $num = "<a href='edit.php?post_status=pending&post_type=" . TIMED_CONTENT_RULE_TYPE . "'>" . $num . "</a>";
1359 $text = "<a href='edit.php?post_status=pending&post_type=" . TIMED_CONTENT_RULE_TYPE . "'>" . $text . "</a>";
1360 }
1361 echo '<tr>';
1362 echo '<td class="first b b-' . TIMED_CONTENT_RULE_TYPE . '">' . $num . '</td>';
1363 echo '<td class="t ' . TIMED_CONTENT_RULE_TYPE . '">' . $text . '</td>';
1364 echo '</tr>';
1365 }
1366 }
1367
1368 /**
1369 * Display a count of Timed Content Rules in the Dashboard's Right Now widget
1370 *
1371 */
1372 function addRulesCount() {
1373 if ( !post_type_exists( TIMED_CONTENT_RULE_TYPE ) ) {
1374 return;
1375 }
1376
1377 $num_posts = wp_count_posts( TIMED_CONTENT_RULE_TYPE );
1378 $num = number_format_i18n( $num_posts->publish );
1379 $text = _n( 'Timed Content Rule', 'Timed Content Rules', intval( $num_posts->publish ), 'timed-content' );
1380 if ( current_user_can( 'edit_posts' ) || current_user_can( 'edit_pages' ) )
1381 echo "<a href='edit.php?post_type=" . TIMED_CONTENT_RULE_TYPE . "'>"
1382 . '<li class="' . TIMED_CONTENT_RULE_TYPE . '-count">'
1383 . $num
1384 . ' '
1385 . $text
1386 . '</a></li>';
1387
1388 if ( $num_posts->pending > 0 ) {
1389 $num = number_format_i18n( $num_posts->pending );
1390 $text = _n( 'Timed Content Rule Pending', 'Timed Content Rules Pending', intval( $num_posts->pending ), 'timed-content' );
1391 if ( current_user_can( 'edit_posts' ) || current_user_can( 'edit_pages' ) )
1392 echo "<a href='edit.php?post_status=pending&post_type=" . TIMED_CONTENT_RULE_TYPE . "'>"
1393 . '<li class="' . TIMED_CONTENT_RULE_TYPE . '-count">'
1394 . $num
1395 . ' '
1396 . $text
1397 . '</a></li>';
1398 }
1399 }
1400
1401 function setUpCustomFields() {
1402 require_once( "lib/customFields-settings.php" );
1403 require_once( "lib/customFieldsInterface.php" );
1404
1405 $scf = new customFieldsInterface( "timed_content_rule_schedule",
1406 __( 'Rule Description/Schedule', 'timed-content' ),
1407 "<div id=\"schedule_desc\" style=\"font-style: italic;\">"
1408 . ( isset( $_GET['post'] ) && ( TIMED_CONTENT_RULE_TYPE === get_post_type( $_GET['post'] ) ) ? $this->getScheduleDescriptionById( intval( $_GET['post'] ) ) : $this->getScheduleDescriptionById( intval( 0 ) ) )
1409 . "</div>"
1410 . "<div id=\"tcr-dialogHolder\" style=\"display:none;\"></div>"
1411 . "<div style=\"padding-top: 10px;\"><input type=\"button\" class=\"button button-primary\" id=\"timed_content_rule_test\" value=\"" . __( 'Show Projected Dates/Times', 'timed-content' ) . "\" /></div>",
1412 TIMED_CONTENT_RULE_POSTMETA_PREFIX,
1413 array( TIMED_CONTENT_RULE_TYPE ),
1414 array() );
1415 $ocf = new customFieldsInterface( "timed_content_rule_initial_event",
1416 __( 'Action/Initial Event', 'timed-content' ),
1417 __( 'Set the action to be taken and when it should first run.', 'timed-content' ),
1418 TIMED_CONTENT_RULE_POSTMETA_PREFIX,
1419 array( TIMED_CONTENT_RULE_TYPE ),
1420 $timed_content_rule_occurrence_custom_fields );
1421 $pcf = new customFieldsInterface( "timed_content_rule_recurrence",
1422 __( 'Repeating Pattern', 'timed-content' ),
1423 __( 'Set how often the action should repeat.', 'timed-content' ),
1424 TIMED_CONTENT_RULE_POSTMETA_PREFIX,
1425 array( TIMED_CONTENT_RULE_TYPE ),
1426 $timed_content_rule_pattern_custom_fields );
1427 $rcf = new customFieldsInterface( "timed_content_rule_stop_condition",
1428 __( 'Stopping Condition', 'timed-content' ),
1429 __( 'Set how long or how many times the action should occur.', 'timed-content' ),
1430 TIMED_CONTENT_RULE_POSTMETA_PREFIX,
1431 array( TIMED_CONTENT_RULE_TYPE ),
1432 $timed_content_rule_recurrence_custom_fields );
1433 $ecf = new customFieldsInterface( "timed_content_rule_exceptions",
1434 __( 'Exceptions', 'timed-content' ),
1435 __( 'Set up any exceptions to this Timed Content Rule.', 'timed-content' ),
1436 TIMED_CONTENT_RULE_POSTMETA_PREFIX,
1437 array( TIMED_CONTENT_RULE_TYPE ),
1438 $timed_content_rule_exceptions_custom_fields );
1439
1440 // Initially loaded at the top; defining this constant here means it can get i18n'd
1441 /* translators: date/time format for debugging messages. http://ca2.php.net/manual/en/function.date.php */
1442 define( "TIMED_CONTENT_DT_FORMAT", __( "l, F jS, Y, g:i A T" , 'timed-content' ) );
1443
1444 }
1445
1446 }
1447
1448 } //End Class timedContentPlugin
1449
1450 // Initialize plugin
1451 if ( class_exists( "timedContentPlugin" ) ) {
1452 $timedContentPluginInstance = new timedContentPlugin();
1453 }
1454
1455 // Actions and Filters
1456 if ( isset( $timedContentPluginInstance ) ) {
1457 global $wp_version;
1458
1459 add_filter('timed_content_filter', 'wptexturize');
1460 add_filter('timed_content_filter', 'convert_smilies');
1461 add_filter('timed_content_filter', 'convert_chars');
1462 add_filter('timed_content_filter', 'wpautop');
1463 add_filter('timed_content_filter', 'prepend_attachment');
1464 add_filter('timed_content_filter', 'do_shortcode');
1465
1466 add_action( "plugins_loaded", array( &$timedContentPluginInstance, "i18nInit" ), 1 );
1467 add_action( "init", array( &$timedContentPluginInstance, "timedContentRuleTypeInit" ), 2 );
1468 add_action( "init", array( &$timedContentPluginInstance, "setUpCustomFields" ), 2 );
1469 add_action( "wp_head", array( &$timedContentPluginInstance, "addHeaderCode" ), 1 );
1470 add_filter( "manage_" . TIMED_CONTENT_RULE_TYPE . "_posts_columns", array( &$timedContentPluginInstance, "addDescColumnHead" ) );
1471 add_action( "manage_" . TIMED_CONTENT_RULE_TYPE . "_posts_custom_column", array( &$timedContentPluginInstance, "addDescColumnContent" ), 10, 2);
1472 add_action( "admin_enqueue_scripts", array( &$timedContentPluginInstance, "addAdminHeaderCode" ), 1 );
1473 add_action( "admin_init", array( &$timedContentPluginInstance, "setTinyMCEPluginVars" ), 1 );
1474 add_action( "admin_init", array( &$timedContentPluginInstance, "initTinyMCEPlugin" ), 2 );
1475 add_action( 'wp_ajax_timedContentPluginGetTinyMCEDialog', array( &$timedContentPluginInstance, "timedContentPluginGetTinyMCEDialog" ), 1 );
1476 add_action( 'wp_ajax_timedContentPluginGetRulePeriodsAjax', array( &$timedContentPluginInstance, "timedContentPluginGetRulePeriodsAjax" ), 1 );
1477 add_action( 'wp_ajax_timedContentPluginGetScheduleDescriptionAjax', array( &$timedContentPluginInstance, "timedContentPluginGetScheduleDescriptionAjax" ), 1 );
1478 add_filter( "post_updated_messages", array( &$timedContentPluginInstance, "timedContentRuleUpdatedMessages" ), 1 );
1479 if ( version_compare( $wp_version, "3.8", ">=" ) ) {
1480 add_action( "dashboard_glance_items", array( &$timedContentPluginInstance, "addRulesCount" ) );
1481 add_action( "admin_head", array( &$timedContentPluginInstance, "addPostTypeIcons" ), 1 );
1482 } else {
1483 add_action( "right_now_content_table_end", array( &$timedContentPluginInstance, "addRulesCount37" ) );
1484 add_action( "admin_head", array( &$timedContentPluginInstance, "addPostTypeIcons37" ), 1 );
1485 }
1486
1487 add_shortcode( TIMED_CONTENT_CLIENT_TAG, array( &$timedContentPluginInstance, "clientShowHTML" ), 1 );
1488 add_shortcode( TIMED_CONTENT_SERVER_TAG, array( &$timedContentPluginInstance, "serverShowHTML" ), 1 );
1489 add_shortcode( TIMED_CONTENT_RULE_TAG, array( &$timedContentPluginInstance, "rulesShowHTML" ), 1 );
1490 }
1491 ?>