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

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