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

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