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

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