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

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