PluginProbe
Timed Content / 2.71
Timed Content v2.71
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
← All changes | timed-content.php +2211 -1320 2.5.12.71 View file →
@@ -4,1474 +4,2365 @@
4 4 Text Domain: timed-content
5 5 Domain Path: /lang
6 6 Plugin URI: http://wordpress.org/plugins/timed-content/
7 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.1
8 +Author: K. Tough, Arno Welzel, Enrico Bacis
9 +Version: 2.71
10 10 Author URI: http://wordpress.org/plugins/timed-content/
11 11 */
12 -if ( !class_exists( "timedContentPlugin" ) ) {
12 +defined('ABSPATH') or die();
13 13
14 - define( "TIMED_CONTENT_VERSION", "2.5.1" );
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" );
14 +include 'lib/customFieldsInterface.php';
29 15
16 +define('TIMED_CONTENT_VERSION', '2.70');
17 +define('TIMED_CONTENT_SLUG', 'timed-content');
18 +define('TIMED_CONTENT_PLUGIN_URL', plugins_url() . '/' . TIMED_CONTENT_SLUG);
19 +define('TIMED_CONTENT_SHORTCODE_CLIENT', 'timed-content-client');
20 +define('TIMED_CONTENT_SHORTCODE_SERVER', 'timed-content-server');
21 +define('TIMED_CONTENT_SHORTCODE_RULE', 'timed-content-rule');
22 +define('TIMED_CONTENT_TIME_ZERO', '1970-01-01 00:00:00 +000'); // Start of Unix Epoch (32 bit)
23 +define('TIMED_CONTENT_TIME_END', '2038-01-19 03:14:06 +000'); // End of Unix Epoch (32 bit)
24 +define('TIMED_CONTENT_RULE_TYPE', 'timed_content_rule');
25 +define('TIMED_CONTENT_RULE_POSTMETA_PREFIX', TIMED_CONTENT_RULE_TYPE . '_');
26 +define('TIMED_CONTENT_CSS', TIMED_CONTENT_PLUGIN_URL . '/css/timed-content.css');
27 +define('TIMED_CONTENT_CSS_DASHICONS', TIMED_CONTENT_PLUGIN_URL . '/css/dashicons/style.css');
28 +define('TIMED_CONTENT_JQUERY_UI_CSS', TIMED_CONTENT_PLUGIN_URL . '/css/jqueryui/1.10.3/themes/smoothness/jquery-ui.css');
29 +define('TIMED_CONTENT_JQUERY_UI_TIMEPICKER_JS', TIMED_CONTENT_PLUGIN_URL . '/js/jquery-ui-timepicker-0.3.3/jquery.ui.timepicker.js');
30 +define('TIMED_CONTENT_JQUERY_UI_TIMEPICKER_CSS', TIMED_CONTENT_PLUGIN_URL . '/js/jquery-ui-timepicker-0.3.3/jquery.ui.timepicker.css');
31 +define('TIMED_CONTENT_DATE_FORMAT_OUTPUT', 'Y-m-d H:i O');
32 +define('TIMED_CONTENT_FREQ_HOURLY', 0);
33 +define('TIMED_CONTENT_FREQ_DAILY', 1);
34 +define('TIMED_CONTENT_FREQ_WEEKLY', 2);
35 +define('TIMED_CONTENT_FREQ_MONTHLY', 3);
36 +define('TIMED_CONTENT_FREQ_YEARLY', 4);
30 37
38 +
39 +/**
40 + * Class timedContentPlugin
41 + *
42 + * @package TimedContent
43 + */
44 +class timedContentPlugin
45 +{
46 + var $rule_freq_array;
47 + var $rule_days_array;
48 + var $rule_ordinal_array;
49 + var $rule_ordinal_days_array;
50 + var $rule_occurrence_custom_fields;
51 + var $rule_pattern_custom_fields;
52 + var $rule_recurrence_custom_fields;
53 + var $rule_exceptions_custom_fields;
54 +
55 + var $meridiem;
56 + var $show_period;
57 + var $show_period_labels;
58 + var $show_leading_zero;
59 +
60 + var $jquery_ui_datetime_datepicker_i18n;
61 + var $jquery_ui_datetime_timepicker_i18n;
62 +
31 63 /**
32 - * Class timedContentPlugin
64 + * Constructor
65 + */
66 + function __construct()
67 + {
68 + add_filter('timed_content_filter', 'convert_smilies');
69 + add_filter('timed_content_filter', 'convert_chars');
70 + add_filter('timed_content_filter', 'prepend_attachment');
71 + add_filter('timed_content_filter', 'do_shortcode');
72 + add_filter('manage_' . TIMED_CONTENT_RULE_TYPE . '_posts_columns', array($this, 'addDescColumnHead'));
73 + add_filter('pre_get_posts', array($this, 'timedContentPreGetPosts'));
74 + add_filter('post_updated_messages', array($this, 'timedContentRuleUpdatedMessages'), 1);
75 +
76 + add_action('init', array($this, 'init'), 2);
77 + add_action('wp_head', array($this, 'addHeaderCode'), 1);
78 + add_action('manage_' . TIMED_CONTENT_RULE_TYPE . '_posts_custom_column', array($this, 'addDescColumnContent'), 10, 2);
79 + add_action('admin_enqueue_scripts', array($this, 'addAdminHeaderCode'), 1);
80 + add_action('admin_init', array($this, 'setTinyMCEPluginVars'), 1);
81 + add_action('admin_init', array($this, 'initTinyMCEPlugin'), 2);
82 + add_action('wp_ajax_timedContentPluginGetTinyMCEDialog', array($this, 'timedContentPluginGetTinyMCEDialog'), 1);
83 + add_action('wp_ajax_timedContentPluginGetRulePeriodsAjax', array($this, 'timedContentPluginGetRulePeriodsAjax'), 1);
84 + add_action('wp_ajax_timedContentPluginGetScheduleDescriptionAjax', array($this, 'timedContentPluginGetScheduleDescriptionAjax'), 1);
85 + add_action('dashboard_glance_items', array($this, 'addRulesCount'));
86 + add_action('admin_head', array($this, 'addPostTypeIcons'), 1);
87 +
88 + add_shortcode(TIMED_CONTENT_SHORTCODE_CLIENT, array($this, 'clientShowHTML'));
89 + add_shortcode(TIMED_CONTENT_SHORTCODE_SERVER, array($this, 'serverShowHTML'));
90 + add_shortcode(TIMED_CONTENT_SHORTCODE_RULE, array($this, 'rulesShowHTML'));
91 + }
92 +
93 + /**
94 + * Initialise plugin
95 + */
96 + function init()
97 + {
98 + global $wp_locale;
99 +
100 + load_plugin_textdomain('timed-content', false, basename(dirname(__FILE__)) . '/lang/');
101 +
102 + $this->rule_freq_array = array(
103 + 0 => __('hourly', 'timed-content'),
104 + 1 => __('daily', 'timed-content'),
105 + 2 => __('weekly', 'timed-content'),
106 + 3 => __('monthly', 'timed-content'),
107 + 4 => __('yearly', 'timed-content')
108 + );
109 +
110 + $this->rule_days_array = array(
111 + 0 => __('Sunday', 'timed-content'),
112 + 1 => __('Monday', 'timed-content'),
113 + 2 => __('Tuesday', 'timed-content'),
114 + 3 => __('Wednesday', 'timed-content'),
115 + 4 => __('Thursday', 'timed-content'),
116 + 5 => __('Friday', 'timed-content'),
117 + 6 => __('Saturday', 'timed-content')
118 + );
119 +
120 + $this->rule_ordinal_array = array(
121 + 0 => __('first', 'timed-content'),
122 + 1 => __('second', 'timed-content'),
123 + 2 => __('third', 'timed-content'),
124 + 3 => __('fourth', 'timed-content'),
125 + 4 => __('last', 'timed-content')
126 + );
127 +
128 + $this->rule_ordinal_days_array = array(
129 + 0 => __('Sunday', 'timed-content'),
130 + 1 => __('Monday', 'timed-content'),
131 + 2 => __('Tuesday', 'timed-content'),
132 + 3 => __('Wednesday', 'timed-content'),
133 + 4 => __('Thursday', 'timed-content'),
134 + 5 => __('Friday', 'timed-content'),
135 + 6 => __('Saturday', 'timed-content'),
136 + 7 => __('day', 'timed-content')
137 + );
138 +
139 + $this->jquery_ui_datetime_datepicker_i18n = array(
140 + "closeText" => _x("Done", "jQuery UI Datepicker Close label", "timed-content"), // Display text for close link
141 + "prevText" => _x("Prev", "jQuery UI Datepicker Previous label", "timed-content"), // Display text for previous month link
142 + "nextText" => _x("Next", "jQuery UI Datepicker Next label", "timed-content"), // Display text for next month link
143 + "currentText" => _x("Today", "jQuery UI Datepicker Today label", "timed-content"), // Display text for current month link
144 + "weekHeader" => _x("Wk", "jQuery UI Datepicker Week label", "timed-content"), // Column header for week of the year
145 + // Replace the text indices for the following arrays with 0-based arrays
146 + "monthNames" => $this->stripArrayIndices($wp_locale->month), // Names of months for drop-down and formatting
147 + "monthNamesShort" => $this->stripArrayIndices($wp_locale->month_abbrev), // For formatting
148 + "dayNames" => $this->stripArrayIndices($wp_locale->weekday), // For formatting
149 + "dayNamesShort" => $this->stripArrayIndices($wp_locale->weekday_abbrev), // For formatting
150 + "dayNamesMin" => $this->stripArrayIndices($wp_locale->weekday_initial), // Column headings for days starting at Sunday
151 + "dateFormat" => 'yy-mm-dd',
152 + "firstDay" => get_option('start_of_week'),
153 + "isRTL" => $wp_locale->is_rtl(),
154 + "showMonthAfterYear" => false, // True if the year select precedes month, false for month then year
155 + "yearSuffix" => '' // Additional text to append to the year in the month headers
156 + );
157 +
158 + $tf = get_option('time_format');
159 + if (false !== strpos($tf, "A")) {
160 + $this->meridiem = array($wp_locale->meridiem['AM'], $wp_locale->meridiem['PM']);
161 + $this->show_period = true;
162 + $this->show_period_labels = true;
163 + $this->show_leading_zero = false;
164 + } elseif (false !== strpos($tf, "a")) {
165 + $this->meridiem = array($wp_locale->meridiem['am'], $wp_locale->meridiem['pm']);
166 + $this->show_period = true;
167 + $this->show_period_labels = true;
168 + $this->show_leading_zero = false;
169 + } else {
170 + $this->meridiem = array('', '');
171 + $this->show_period = false;
172 + $this->show_period_labels = false;
173 + $this->show_leading_zero = true;
174 + }
175 +
176 + $this->jquery_ui_datetime_timepicker_i18n = array(
177 + "hourText" => _x("Hour", "jQuery UI Timepicker 'Hour' label", "timed-content"),
178 + "minuteText" => _x("Minute", "jQuery UI Timepicker 'Minute' label", "timed-content"),
179 + "timeSeparator" => _x(":", "jQuery UI Datepicker: Character used to separate hours and minutes in translated language", 'timed-content'),
180 + "closeButtonText" => _x("Done", "jQuery UI Timepicker 'Done' label", "timed-content"),
181 + "nowButtonText" => _x("Now", "jQuery UI Timepicker 'Now' label", "timed-content"),
182 + "deselectButtonText" => _x("Deselect", "jQuery UI Timepicker 'Deselect' label", "timed-content"),
183 + "amPmText" => array('', ''),
184 + "showPeriod" => false,
185 + "showPeriodLabels" => false,
186 + "showLeadingZero" => false,
187 + "timeFormat" => 'G:i'
188 + );
189 +
190 + $this->timedContentRuleTypeInit();
191 + $this->setupCustomFields();
192 + }
193 +
194 + /**
195 + * Creates the Timed Content Rule post type and registers it with Wordpress
196 + */
197 + function timedContentRuleTypeInit()
198 + {
199 + $labels = array(
200 + 'name' => _x('Timed Content rules', 'post type general name', 'timed-content'),
201 + 'singular_name' => _x('Timed Content rule', 'post type singular name', 'timed-content'),
202 + 'add_new' => _x('Add new', 'Menu item/button label on Timed Content Rules admin page',
203 + '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.',
217 + 'timed-content'),
218 + 'public' => false,
219 + 'publicly_queryable' => false,
220 + 'exclude_from_search' => false,
221 + 'show_ui' => true,
222 + 'show_in_menu' => true,
223 + 'show_in_nav_menus' => true,
224 + 'show_in_admin_bar' => true,
225 + 'query_var' => false,
226 + 'rewrite' => false,
227 + 'capability_type' => 'post',
228 + 'has_archive' => false,
229 + 'hierarchical' => false,
230 + 'menu_position' => 5,
231 + 'supports' => array('title')
232 + );
233 + register_post_type(TIMED_CONTENT_RULE_TYPE, $args);
234 + }
235 +
236 +
237 + /**
238 + * Fix for date_i18n() as suggested in https://core.trac.wordpress.org/ticket/25768
33 239 *
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.
240 + * Modified from the original patch to use the currently set timezone from PHP,
241 + * like PHP's date(), and to make the code more readable.
242 + *
243 + * @param $j
244 + * @param $req_format
245 + * @param bool $i
246 + * @param bool $gmt
247 + *
248 + * @return bool|string
36 249 */
37 - class timedContentPlugin {
38 -
39 - function timedContentPlugin() {
40 - //constructor
250 + function fix_date_i18n($j, $req_format, $i = false, $gmt = false)
251 + {
252 + global $wp_locale;
253 + global $post;
41 254
42 - }
255 + $timestamp = $i;
43 256
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;
257 + // get current timestamp if $i is false
258 + if (false === $timestamp) {
259 + if ($gmt) {
260 + $timestamp = time();
261 + } else {
262 + $timestamp = current_time('timestamp');
263 + }
61 264
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 - }
265 + // use debug parameter if current user is allowed to edit the post
266 + if (isset($_GET['tctest']) && !empty($post) && current_user_can("edit_post", $post->post_id)) {
267 + $dt = DateTime::createFromFormat('Y-m-d H:i:s', $_GET['tctest']);
268 + if ($dt != false) {
269 + $timestamp = $dt->getTimestamp();
270 + }
271 + }
272 + }
70 273
274 + // get components of the date (timestamp) as array
275 + $date_components = getdate($timestamp);
71 276
72 - // get components of the date (timestamp) as array
73 - $date_components = getdate($timestamp);
277 + // numeric representation of a month, with leading zeros
278 + $date_month = $wp_locale->get_month($date_components['mon']);
279 + $date_month_abbrev = $wp_locale->get_month_abbrev($date_month);
280 + // numeric representation of the day of the week
281 + $date_weekday = $wp_locale->get_weekday($date_components['wday']);
282 + $date_weekday_abbrev = $wp_locale->get_weekday_abbrev($date_weekday);
283 + // get if hour is Ante meridiem or Post meridiem
284 + $meridiem = $date_components['hours'] >= 12 ? 'pm' : 'am';
285 + // lowercase Ante meridiem and Post meridiem hours
286 + $date_meridiem = $wp_locale->get_meridiem($meridiem);
287 + // uppercase Ante meridiem and Post meridiem
288 + $date_meridiem_capital = $wp_locale->get_meridiem(strtoupper($meridiem));
74 289
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));
290 + // escape literals
291 + $date_weekday_abbrev = backslashit($date_weekday_abbrev);
292 + $date_month = backslashit($date_month);
293 + $date_weekday = backslashit($date_weekday);
294 + $date_month_abbrev = backslashit($date_month_abbrev);
295 + $date_meridiem = backslashit($date_meridiem);
296 + $date_meridiem_capital = backslashit($date_meridiem_capital);
87 297
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);
298 + // the translated format string
299 + $translated_date_format_string = '';
300 + // the 2 arrays map a format literal to its translation (e. g. 'F' to the escaped month translation)
301 + $translate_formats = array('D', 'F', 'l', 'M', 'a', 'A', 'c', 'r');
302 + $translations = array(
303 + $date_weekday_abbrev, // D
304 + $date_month, // F
305 + $date_weekday, // l
306 + $date_month_abbrev, // M
307 + $date_meridiem, // a
308 + $date_meridiem_capital, // A
309 + 'Y-m-d\TH:i:sP', // c
310 + sprintf('%s, d %s Y H:i:s O', $date_weekday_abbrev, $date_month_abbrev), // r
311 + );
95 312
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 - );
313 + // find each format literal that needs translation and replace it by its translation
314 + // respects the escaping
315 + // iterate $req_format from ending to beginning
316 + for ($i = strlen($req_format) - 1; $i > - 1; $i --) {
317 + // test if current char is format literal that needs translation
318 + $translate_formats_index = array_search($req_format[ $i ], $translate_formats);
110 319
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);
320 + if ($translate_formats_index !== false) {
321 + // counts the slashes (the escape char) in front of the current char
322 + $slashes_counter = 0;
118 323
119 - if ($translate_formats_index !== false)
120 - {
121 - // counts the slashes (the escape char) in front of the current char
122 - $slashes_counter = 0;
324 + // count all slashes left-hand side of the current char
325 + for ($j = $i - 1; $j > - 1; $j --) {
326 + if ($req_format[ $j ] == '\\') {
327 + $slashes_counter ++;
328 + } else {
329 + break;
330 + }
331 + }
123 332
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 - }
333 + // number of slashes is even
334 + if ($slashes_counter % 2 == 0) // current char is not escaped, therefore it is a format literal
335 + {
336 + $translated_date_format_string = $translations[ $translate_formats_index ] . $translated_date_format_string;
337 + } else // current char is escaped, therefore it is not a format literal, just add it unchanged
338 + {
339 + $translated_date_format_string = $req_format[ $i ] . $translated_date_format_string;
340 + }
341 + } else // current char is no a format literal, just add it unchanged
342 + {
343 + $translated_date_format_string = $req_format[ $i ] . $translated_date_format_string;
344 + }
345 + }
132 346
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 - }
347 + $req_format = $translated_date_format_string;
145 348
146 - $req_format = $translated_date_format_string;
349 + if ($gmt) {
350 + // get GMT date string
351 + $date_formatted = gmdate($req_format, $timestamp);
352 + } else {
353 + // get Wordpress time zone
354 + // $timezone_string = get_option('timezone_string');
355 + // Haha, just kidding. Let's get the currently set timezone, as God and Rasmus intended
356 + $timezone_string = date_default_timezone_get();
147 357
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();
358 + if ($timezone_string) {
359 + // create time zone object
360 + $timezone_object = timezone_open($timezone_string);
361 + // create date object from time zone object
362 + $local_date_object = date_create(null, $timezone_object);
363 + // set time and date of $local_date_object to $timestamp
364 + $date_components = isset($date_components) ? $date_components : getdate($timestamp);
365 + date_date_set($local_date_object, $date_components['year'], $date_components['mon'],
366 + $date_components['mday']);
367 + date_time_set($local_date_object, $date_components['hours'], $date_components['minutes'],
368 + $date_components['seconds']);
369 + // format date according to the Wordpress time zone
370 + $date_formatted = date_format($local_date_object, $req_format);
371 + } else {
372 + // fall back if no Wordpress time zone set
373 + $date_formatted = date($req_format, $i);
374 + }
375 + }
157 376
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 - }
377 + return $date_formatted;
378 + }
177 379
178 - return $date_formatted;
179 - }
380 + /**
381 + * Filter to change sort order to title
382 + *
383 + * @param array $messages Array of currently defined messages for post types
384 + *
385 + * @return mixed Array of messages with appropriate messages for Timed Content Rules added in
386 + */
387 + function timedContentPreGetPosts($query)
388 + {
389 + if ($query->is_admin) {
390 + if ($query->get('post_type') == TIMED_CONTENT_RULE_TYPE) {
391 + $query->set('orderby', 'title');
392 + $query->set('order', 'ASC');
393 + }
394 + }
180 395
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 - }
396 + return $query;
397 + }
221 398
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;
399 + /**
400 + * Filter to customize CRUD messages for Timed Content Rules
401 + *
402 + * @param array $messages Array of currently defined messages for post types
403 + *
404 + * @return mixed Array of messages with appropriate messages for Timed Content Rules added in
405 + */
406 + function timedContentRuleUpdatedMessages($messages)
407 + {
408 + global $post;
230 409
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 ) );
410 + if (!empty($post)) {
411 + /* translators: date and time format to activate rule. http://ca2.php.net/manual/en/function.date.php*/
412 + $post_date = date_i18n(__('M j, Y @ G:i', 'timed-content'), strtotime($post->post_date));
413 + } else {
414 + $post_date = '';
415 + }
233 416
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 - }
417 + $messages[ TIMED_CONTENT_RULE_TYPE ] = array(
418 + 0 => '', // Unused. Messages start at index 1.
419 + 1 => __('Timed Content Rule updated.', 'timed-content'),
420 + 2 => __('Custom field updated.', 'timed-content'),
421 + 3 => __('Custom field deleted.', 'timed-content'),
422 + 4 => __('Timed Content Rule updated.', 'timed-content'),
423 + /* translators: %s: date and time of the revision */
424 + 5 => isset($_GET['revision']) ? sprintf(__('Timed Content Rule restored to revision from %s',
425 + 'timed-content'), wp_post_revision_title((int) $_GET['revision'], false)) : false,
426 + 6 => __('Timed Content Rule published.', 'timed-content'),
427 + 7 => __('Timed Content Rule saved.', 'timed-content'),
428 + 8 => __('Timed Content Rule submitted.', 'timed-content'),
429 + /* translators: %s: date and time to activate rule. */
430 + 9 => sprintf(__('Timed Content Rule scheduled for: %s.', 'timed-content'),
431 + "<strong>" . $post_date . "</strong>"),
432 + 10 => __('Timed Content Rule draft updated.', 'timed-content')
433 + );
252 434
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;
435 + return $messages;
436 + }
437 +
438 + function datetimeToEnglish($date, $time = "")
439 + {
440 + $months = array(
441 + "January",
442 + "February",
443 + "March",
444 + "April",
445 + "May",
446 + "June",
447 + "July",
448 + "August",
449 + "September",
450 + "October",
451 + "November",
452 + "December"
453 + );
454 + $monthsI18N = array(
455 + __("January", 'timed-content'),
456 + __("February", 'timed-content'),
457 + __("March", 'timed-content'),
458 + __("April", 'timed-content'),
459 + __("May", 'timed-content'),
460 + __("June", 'timed-content'),
461 + __("July", 'timed-content'),
462 + __("August", 'timed-content'),
463 + __("September", 'timed-content'),
464 + __("October", 'timed-content'),
465 + __("November", 'timed-content'),
466 + __("December", 'timed-content')
467 + );
468 + $english_date = str_replace($monthsI18N, $months, $date);
469 +
470 + return $english_date . " " . $time;
471 + }
472 +
473 + /**
474 + * Advances a date by a set number of days
475 + *
476 + * @param int $current UNIX timestamp of the date before incrementing
477 + * @param int $interval_multiplier Number of days to advance
478 + *
479 + * @return int Unix timestamp of the new date
480 + */
481 + function getNextDay($current, $interval_multiplier)
482 + {
483 + return strtotime($interval_multiplier . " day", $current);
484 + }
485 +
486 + /**
487 + * Advances a date/time by a set number of hours
488 + *
489 + * @param int $current UNIX timestamp of the date/time before incrementing
490 + * @param int $interval_multiplier Number of hours to advance
491 + *
492 + * @return int Unix timestamp of the new date/time
493 + */
494 + function getNextHour($current, $interval_multiplier)
495 + {
496 + return strtotime($interval_multiplier . " hour", $current);
497 + }
498 +
499 + /**
500 + * Advances a date/time by a set number of weeks
501 + *
502 + * Advances a date/time by a set number of weeks. If given an array of days of the week, this function will
503 + * advance the date/time to the next day in that array in the jumped-to week. Use this function if you're
504 + * repeating an action on specific days of the week (i.e., on Weekdays, Tuesdays and Thursdays, etc.).
505 + *
506 + * @param int $current UNIX timestamp of the date before incrementing
507 + * @param int $interval_multiplier Number of weeks to advance
508 + * @param array $days Array of integers symbolizing the days of the week to
509 + * repeat on (0 - Sunday, 1 - Monday, ..., 6 - Saturday).
510 + *
511 + * @return int Unix timestamp of the new date
512 + */
513 + function getNextWeek($current, $interval_multiplier, $days = array())
514 + {
515 + // If $days is empty, advance $interval_multiplier weeks from $current and return the timestamp
516 + if (empty($days)) {
517 + return strtotime($interval_multiplier . " week", $current);
280 518 }
281 519
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 - }
520 + // Otherwise, set up an array combining the days of the week to repeat on and the current day
521 + // (keys and values of the array will be the same, and the array is sorted)
522 + $currentDayOfWeekIndex = date("w", $current);
523 + $days = array_merge(array($currentDayOfWeekIndex), $days);
524 + $days = array_unique($days);
525 + $days = array_values($days);
526 + sort($days);
527 + $daysOfWeek = array_combine($days, $days);
292 528
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 - }
529 + // If the current day is the last one of the days of the week to repeat on, jump ahead to
530 + // the next week to be repeating on and get the earliest day in the array
531 + if ($currentDayOfWeekIndex == max($daysOfWeek)) {
532 + $pattern = ((7 - $currentDayOfWeekIndex) + (7 * ($interval_multiplier - 1)) + (min(array_keys($daysOfWeek)))) . " day";
533 + } // Otherwise, cycle through the array until we find the next day to repeat on
534 + else {
535 + $nextDayOfWeekIndex = $currentDayOfWeekIndex;
536 + do {
537 + } while (!isset($daysOfWeek[ ++ $nextDayOfWeekIndex ]));
538 + $pattern = ($nextDayOfWeekIndex - $currentDayOfWeekIndex) . " day";
539 + }
303 540
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 );
541 + return strtotime($pattern, $current);
542 + }
320 543
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 );
544 + /**
545 + * Advances a date by a set number of months
546 + *
547 + * Advances a date by a set number of months. When the date of the first active period lies
548 + * on the 29th, 30th, or 31st of the month, this function will return a date on the the last day
549 + * of the month for those months not containing those days.
550 + *
551 + * @param int $current UNIX timestamp of the date before incrementing
552 + * @param int $start UNIX timestamp of the first active period's date
553 + * @param int $interval_multiplier Number of months to advance
554 + *
555 + * @return int Unix timestamp of the new date
556 + */
557 + function getNextMonth($current, $start, $interval_multiplier)
558 + {
559 + // For most days in the month, it's pretty easy. Get the day of month of the starting date.
560 + $startDay = date("j", $start);
329 561
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 - }
562 + // If it's before or on the 28th, just jump the number of months and be done with it.
563 + if ($startDay <= 28) {
564 + return strtotime($interval_multiplier . " month", $current);
565 + }
342 566
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 ) {
567 + // If it's on the 29th, 30th, or 31st, it gets tricky. Some months don't have those days - so on those
568 + // months we need to repeat on the last day of the month instead, but we also need to jump back to the
569 + // correct day the following month. Let's say we want to repeat something on the 31st every month: this
570 + // is what we expect to see for a pattern:
571 + //
572 + // .
573 + // .
574 + // .
575 + // December 31st
576 + // January 31st
577 + // February 28th
578 + // March 31st
579 + // April 30th
580 + // .
581 + // .
582 + // .
583 + //
584 + // Unfortunately, PHP relative date handling isn't that smart (add "+1 month" to January 31st, and you
585 + // end up in March), so we'll have to figure it out ourselves by figuring out how many days to jump instead.
356 586
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.
587 + // We'll need to calculate this for each interval and return the timestamp after the last jump.
588 + $temp_current = $current;
589 + for ($i = 0; $i < $interval_multiplier; $i ++) {
590 + // The pattern for jumping will be different in each interval.
591 + /** @noinspection PhpUnusedLocalVariableInspection */
592 + $temp_pattern = "";
383 593
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;
594 + // Get the month number of the current date.
595 + //$currentMonth = date("n", $temp_current);
434 596
435 - }
597 + // Get the number of days in the month of the current date.
598 + $lastDayThisMonth = date("t", strtotime("this month", $temp_current));
436 599
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 ) {
600 + // Get the number of days for the next month relative to the current date .
601 + // Subtract 3 days from the next month to counter known month skipping bugs in PHP's relative date
602 + // handling, that being the difference between the shortest possible month (non-leap February - 28 days)
603 + // and the longest (Jan., Mar., May, Jul., Aug., Oct., Dec. - 31 days). This may be fixed in PHP 5.3.x
604 + // but this should be backwards-compatible anyway.
605 + $lastDayNextMonth = date("t", strtotime("-3 day next month", $temp_current));
449 606
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 - }
607 + // If the current month is longer than next month, follow this block
608 + if ($lastDayThisMonth > $lastDayNextMonth) {
609 + // If we're repeating on the last day of this month, jump the number of days next month
610 + if ($startDay == $lastDayThisMonth) {
611 + $temp_pattern = $lastDayNextMonth . " days";
612 + }
613 + // If the start day doesn't exist in the next month (i.e., no "31st" in June), jump the
614 + // number of days next month plus the difference between the start day and the number of days this month
615 + elseif ($startDay > $lastDayNextMonth) {
616 + $temp_pattern = ($lastDayThisMonth + $lastDayNextMonth - $startDay) . " days";
617 + } // Otherwise, jump ahead the number of days in this month
618 + else {
619 + $temp_pattern = $lastDayThisMonth . " days";
620 + }
621 + } // Or, if the current month is shorter than next month
622 + elseif ($lastDayThisMonth < $lastDayNextMonth) {
623 + // If the start day doesn't exist in this month (i.e., no "31st" in June), jump the
624 + // number of days next month plus the difference between the start day and the number of days this month
625 + if ($startDay >= $lastDayThisMonth) {
626 + $temp_pattern = $startDay . " days";
627 + } // Otherwise, jump ahead the number of days in this month
628 + else {
629 + $temp_pattern = $lastDayThisMonth . " days";
630 + }
631 + } // If the current month and next month are equally long, jumping by "1 month" is fine
632 + else {
633 + $temp_pattern = "1 month";
634 + }
491 635
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 - }
636 + $temp_current = strtotime($temp_pattern, $temp_current);
637 + }
502 638
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 - }
639 + return $temp_current;
545 640
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;
641 + }
558 642
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);
643 + /**
644 + * Advances a date to the 'n'th weekday of the next month (eg., first Wednesday, third Monday, last Friday, etc.).
645 + *
646 + * NB: if $ordinal is set to '4' and $day is set to '7', it wil return the last day of the month.
647 + *
648 + * @param int $current UNIX timestamp of the date before incrementing
649 + * @param int $ordinal Integer symbolizing the ordinal (0 - first, 1 - second, 2 - third, 3 - fourth, 4 - last)
650 + * @param int $day Integers symbolizing the days of the week to repeat on
651 + * (0 - Sunday, 1 - Monday, ..., 6 - Saturday, 7 - day).
652 + *
653 + * @return int Unix timestamp of the new date
654 + */
655 + function getNthWeekdayOfMonth($current, $ordinal, $day)
656 + {
657 + // First, get the month/year we need to work with
658 + $the_month = date("F", $current);
659 + $the_year = date("Y", $current);
660 + $lastDayThisMonth = date("t", $current);
576 661
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 );
662 + // Get the time for the $current timestamp
663 + $current_time = date("g:i A", $current);
664 + $the_day = "";
581 665
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;
666 + if ($day == 7) { // If $day is "day of the month", get the day of month based on the ordinal
667 + switch ($ordinal) {
668 + case 0 :
669 + $the_day = "1";
670 + break; // First day of the month //
671 + case 1 :
672 + $the_day = "2";
673 + break; // Second day of the month //
674 + case 2 :
675 + $the_day = "3";
676 + break; // Third day of the month //
677 + case 3 :
678 + $the_day = "4";
679 + break; // Fourth day of the month //
680 + case 4 :
681 + $the_day = $lastDayThisMonth;
682 + break; // Last day of the month //
683 + default :
684 + $the_day = "1";
685 + break;
686 + }
687 + } else { // If $day is one of the days of the week...
688 + $day_range = array();
689 + switch ($ordinal) { // ...get a 7-day range based on the ordinal...
690 + case 0 :
691 + $day_range = range(1, 7);
692 + break; // First 7 days of the month //
693 + case 1 :
694 + $day_range = range(8, 14);
695 + break; // Second 7 days of the month //
696 + case 2 :
697 + $day_range = range(15, 21);
698 + break; // Third 7 days of the month //
699 + case 3 :
700 + $day_range = range(22, 28);
701 + break; // Fourth 7 days of the month //
702 + case 4 :
703 + $day_range = range($lastDayThisMonth - 6, $lastDayThisMonth);
704 + break; // Last 7 days of the month //
705 + default :
706 + $day_range = range(1, 7);
707 + break;
708 + }
709 + foreach ($day_range as $a_day) { // ...and find the matching weekday in that range.
710 + if ($day == date("w", strtotime($the_month . " " . $a_day . ", " . $the_year))) {
711 + $the_day = $a_day;
712 + break;
713 + }
714 + }
715 + }
586 716
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 );
717 + // Build the date string for the correct day and return its timestamp
718 + $pattern = $the_month . " " . $the_day . ", " . $the_year . ", " . $current_time;
591 719
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++;
720 + return strtotime($pattern);
610 721
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 );
722 + }
633 723
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 - }
724 + /**
725 + * Advances a date by a set number of years
726 + *
727 + * @param int $current UNIX timestamp of the date before incrementing
728 + * @param int $interval_multiplier Number of years to advance
729 + *
730 + * @return int Unix timestamp of the new date
731 + */
732 + function getNextYear($current, $interval_multiplier)
733 + {
734 + return strtotime($interval_multiplier . " year", $current);
735 + }
643 736
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 - }
737 + /**
738 + * Validates the various Timed Content Rule parameters and returns a series of error messages.
739 + *
740 + * @param $args Array of Timed Content Rule parameters
741 + *
742 + * @return array Array of error messages
743 + */
744 + function validate($args)
745 + {
746 + $errors = array();
666 747
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 - }
748 + $instance_start = DateTime::createFromFormat('Y-m-d', $args['instance_start']['date']);
749 + if($instance_start != false) {
750 + $instance_start = $instance_start->getTimestamp();
751 + }
752 + $instance_end= DateTime::createFromFormat('Y-m-d', $args['instance_end']['date']);
753 + if($instance_end != false) {
754 + $instance_end = $instance_end->getTimestamp();
755 + }
756 + $end_date = DateTime::createFromFormat('Y-m-d', $args['end_date']);
757 + if($end_date != false) {
758 + $end_date = $end_date->getTimestamp();
759 + }
672 760
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();
761 + if ($args['instance_start']['date'] == "") {
762 + $errors[] = __("Starting date must not be empty.", 'timed-content');
763 + }
764 + if ($args['instance_start']['time'] == "") {
765 + $errors[] = __("Starting time must not be empty.", 'timed-content');
766 + }
767 + if ($args['instance_end']['date'] == "") {
768 + $errors[] = __("Ending date must not be empty.", 'timed-content');
769 + }
770 + if ($args['instance_end']['time'] == "") {
771 + $errors[] = __("Ending time must not be empty.", 'timed-content');
772 + }
773 + if ($args['interval_multiplier'] == "") {
774 + $errors[] = __("Interval must not be empty.", 'timed-content');
775 + }
776 + if (!is_numeric($args['interval_multiplier'])) {
777 + $errors[] = __("Number of recurrences must be a number.", 'timed-content');
778 + }
779 + if (($args['num_repeat'] == "") && ($args['recurr_type'] == "recurrence_duration_num_repeat")) {
780 + $errors[] = __("Number of repetitions must not be empty.", 'timed-content');
781 + }
782 + if ((!is_numeric($args['num_repeat'])) && ($args['recurr_type'] == "recurrence_duration_num_repeat")) {
783 + $errors[] = __("Number of repetitions must be a number.", 'timed-content');
784 + }
785 + if (($args['end_date'] == "") && ($args['recurr_type'] == "recurrence_duration_end_date")) {
786 + $errors[] = __("End date must not be empty.", 'timed-content');
787 + }
788 + if (false === $args['instance_start']) {
789 + $errors[] = __("Starting date/time must be valid.", 'timed-content');
790 + }
791 + if (false === $args['instance_end']) {
792 + $errors[] = __("Ending date/time must be valid.", 'timed-content');
793 + }
794 + if ($instance_start > $instance_end) {
795 + $errors[] = __("Starting date/time must be before ending date/time.", 'timed-content');
796 + }
797 + if (($instance_end > $end_date) && ($args['recurr_type'] == "recurrence_duration_end_date")) {
798 + $errors[] = __("Recurrence end date must be after ending date/time.", 'timed-content');
799 + }
685 800
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 );
801 + return $errors;
802 + }
707 803
708 - return $this->__getRulePeriods( $args );
804 + /**
805 + * Calculates the active periods for a Timed Content Rule
806 + *
807 + * @param $args Array of Timed Content Rule parameters
808 + *
809 + * @return array Array of active periods. Each value in the array describes an active period as an array itself
810 + * with "start" and "end" keys and values that are either UNIX timestamps or human-readable dates,
811 + * based on whether $args['human_readable'] is set to true or false.
812 + */
813 + function getRulePeriods($args)
814 + {
815 + global $post;
709 816
710 - }
817 + $active_periods = array();
818 + $period_count = 0;
711 819
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() );
820 + $human_readable = $args['human_readable'];
821 + $freq = $args['freq'];
822 + $timezone = $args['timezone'];
823 + $recurr_type = $args['recurr_type'];
824 + $num_repeat = intval($args['num_repeat']);
825 + $end_date = $args['end_date'];
826 + $days_of_week = $args['days_of_week'];
827 + $interval_multiplier = $args['interval_multiplier'];
828 + $instance_start_date = $args['instance_start']['date'];
829 + $instance_start_time = $args['instance_start']['time'];
830 + $instance_end_date = $args['instance_end']['date'];
831 + $instance_end_time = $args['instance_end']['time'];
832 + $monthly_pattern = $args['monthly_pattern'];
833 + $monthly_pattern_ord = $args['monthly_pattern_ord'];
834 + $monthly_pattern_day = $args['monthly_pattern_day'];
835 + $exceptions_dates = $args['exceptions_dates'];
735 836
736 - $response = json_encode( $this->__getRulePeriods( $args ) );
737 -
738 - // response output
739 - header( "Content-Type: application/json" );
740 - echo $response;
741 - }
742 - die();
837 + add_filter('date_i18n', array(&$this, "fix_date_i18n"), 10, 4);
838 + $temp_tz = date_default_timezone_get();
839 + date_default_timezone_set($timezone);
840 + $right_now_t = current_time('timestamp', 1);
743 841
744 - }
842 + // use debug parameter if current user is allowed to edit the post
843 + if (isset($_GET['tctest']) && !empty($post) && current_user_can("edit_post", $post->post_id)) {
844 + $dt = DateTime::createFromFormat('Y-m-d H:i:s', $_GET['tctest']);
845 + if ($dt != false) {
846 + $right_now_t = $dt->getTimestamp();
847 + }
848 + }
745 849
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");
850 + $instance_start = strtotime($this->datetimeToEnglish($instance_start_date,
851 + $instance_start_time) . " " . $timezone); // Beginning of first occurrence
852 + $instance_end = strtotime($this->datetimeToEnglish($instance_end_date,
853 + $instance_end_time) . " " . $timezone); // End of first occurrence
854 + $current = $instance_start;
855 + $end_current = $instance_end;
754 856
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'];
857 + if ($recurr_type == "recurrence_duration_num_repeat") {
858 + $last_occurrence_start = strtotime(TIMED_CONTENT_TIME_END);
859 + } else {
860 + $last_occurrence_start = strtotime($this->datetimeToEnglish($end_date,
861 + $instance_start_time) . " " . $timezone);
862 + }
791 863
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 );
864 + if ($recurr_type == "recurrence_duration_end_date") {
865 + $loop_test = "return (\$current <= \$last_occurrence_start);";
866 + } else {
867 + $loop_test = "return (\$period_count < \$num_repeat);";
868 + }
829 869
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 );
870 + $day_limit = 0;
871 + switch($freq) {
872 + case TIMED_CONTENT_FREQ_HOURLY:
873 + $day_limit = 1;
874 + break;
875 + case TIMED_CONTENT_FREQ_DAILY:
876 + $day_limit = 7;
877 + break;
878 + case TIMED_CONTENT_FREQ_WEEKLY:
879 + $day_limit = 21;
880 + break;
881 + case TIMED_CONTENT_FREQ_MONTHLY:
882 + $day_limit = 80;
883 + break;
884 + default: // TIMED_CONTENT_FREQ_YEARLY:
885 + $day_limit = 380;
886 + break;
887 + }
888 + $future_repeats = 0;
889 + while (eval ($loop_test) && ($current < $right_now_t || $future_repeats<20)) {
890 + $exception_period = false;
891 + $current_date = date('Y-m-d', $current);
892 + if (is_array($exceptions_dates)) {
893 + foreach ($exceptions_dates as $exceptions_date) {
894 + if (is_numeric($exceptions_date)) {
895 + $exceptions_date = date('Y-m-d', $exceptions_date);
896 + }
897 + if ($current_date === $exceptions_date) {
898 + $exception_period = true;
899 + break;
900 + }
901 + }
902 + }
834 903
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 - }
904 + if ((eval ($loop_test)) && (!($exception_period)) && $current > $right_now_t-$day_limit*86400) {
905 + if ($current > $right_now_t) {
906 + $future_repeats++;
907 + }
908 + $end_current = $current + ($instance_end - $instance_start);
909 + if ($human_readable == true) {
910 + $active_periods[ $period_count ]["start"] = date_i18n(TIMED_CONTENT_DATE_FORMAT_OUTPUT, $current);
911 + $active_periods[ $period_count ]["end"] = date_i18n(TIMED_CONTENT_DATE_FORMAT_OUTPUT, $end_current);
912 + if ($right_now_t < $current) {
913 + $active_periods[ $period_count ]["status"] = "upcoming";
914 + $active_periods[ $period_count ]["time"] = sprintf(_x('%s from now.',
915 + 'Human readable time difference', 'timed-content'),
916 + human_time_diff($current, $right_now_t));
917 + } elseif (($current <= $right_now_t) && ($right_now_t <= $end_current)) {
918 + $active_periods[ $period_count ]["status"] = "active";
919 + $active_periods[ $period_count ]["time"] = __("Right now!", 'timed-content');
920 + } else {
921 + $active_periods[$period_count]["status"] = "expired";
922 + $active_periods[$period_count]["time"] = sprintf(
923 + _x(
924 + '%s ago.',
925 + 'Human readable time difference',
926 + 'timed-content'
927 + ),
928 + human_time_diff($end_current, $right_now_t)
929 + );
930 + }
931 + } else {
932 + $active_periods[$period_count]["start"] = $current;
933 + $active_periods[$period_count]["end"] = $end_current;
934 + }
935 + if (!($exception_period)) {
936 + $period_count ++;
937 + }
938 + }
847 939
848 - $desc .= "&nbsp;" . sprintf( __( 'All times are in the %s timezone.', 'timed-content' ), $timezone );
849 - return $desc;
850 - }
940 + switch ($freq) {
941 + case TIMED_CONTENT_FREQ_HOURLY:
942 + $current = $this->getNextHour($current, $interval_multiplier);
943 + break;
944 + case TIMED_CONTENT_FREQ_DAILY:
945 + $current = $this->getNextDay($current, $interval_multiplier);
946 + break;
947 + case TIMED_CONTENT_FREQ_WEEKLY:
948 + $current = $this->getNextWeek($current, $interval_multiplier, $days_of_week);
949 + break;
950 + case TIMED_CONTENT_FREQ_MONTHLY:
951 + $current = $this->getNextMonth($current, $instance_start, $interval_multiplier);
952 + $temp_current = $current;
953 + if ($monthly_pattern == "yes") {
954 + $current = $this->getNthWeekdayOfMonth($current, $monthly_pattern_ord,
955 + $monthly_pattern_day);
956 + } else {
957 + $current = $temp_current;
958 + }
959 + break;
960 + default: // TIMED_CONTENT_FREQ_YEARLY:
961 + $current = $this->getNextYear($current, $interval_multiplier);
962 + break;
963 + }
964 + }
965 + date_default_timezone_set($temp_tz);
966 + remove_filter('date_i18n', array(&$this, "fix_date_i18n"), 10, 4);
851 967
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();
968 + return $active_periods;
969 + }
864 970
865 - foreach ( $timed_content_rule_occurrence_custom_fields as $field ) {
866 - $defaults[$field['name']] = $field['default'];
971 + /**
972 + * Wrapper for calling timedContentPlugin::__getRulePeriods() by the ID of a Timed Content Rule
973 + *
974 + * @param int $ID ID of the Timed Content Rule
975 + * @param bool $human_readable If true, the active periods are returned as a human-readable date
976 + * as defined by the constant TIMED_CONTENT_DT_FORMAT_OUTPUT otherwise,
977 + * they are returned as UNIX timestamps.
978 + *
979 + * @return array Array of active periods
980 + */
981 + function getRulePeriodsById($ID, $human_readable = false)
982 + {
983 + if (TIMED_CONTENT_RULE_TYPE != get_post_type($ID)) {
984 + return array();
985 + }
986 +
987 + $prefix = TIMED_CONTENT_RULE_POSTMETA_PREFIX;
988 + $args = array();
989 +
990 + $args['human_readable'] = (bool) $human_readable;
991 + $args['freq'] = get_post_meta($ID, $prefix . 'frequency', true);
992 + $args['timezone'] = get_post_meta($ID, $prefix . 'timezone', true);
993 + $args['recurr_type'] = get_post_meta($ID, $prefix . 'recurrence_duration', true);
994 + $args['num_repeat'] = get_post_meta($ID, $prefix . 'recurrence_duration_num_repeat', true);
995 + $args['end_date'] = get_post_meta($ID, $prefix . 'recurrence_duration_end_date', true);
996 + $args['days_of_week'] = get_post_meta($ID, $prefix . 'weekly_days_of_week_to_repeat', true);
997 + if ($args['freq'] == 0) {
998 + $args['interval_multiplier'] = get_post_meta($ID, $prefix . 'hourly_num_of_hours', true);
999 + }
1000 + if ($args['freq'] == 1) {
1001 + $args['interval_multiplier'] = get_post_meta($ID, $prefix . 'daily_num_of_days', true);
1002 + }
1003 + if ($args['freq'] == 2) {
1004 + $args['interval_multiplier'] = get_post_meta($ID, $prefix . 'weekly_num_of_weeks', true);
1005 + }
1006 + if ($args['freq'] == 3) {
1007 + $args['interval_multiplier'] = get_post_meta($ID, $prefix . 'monthly_num_of_months', true);
1008 + }
1009 + if ($args['freq'] == 4) {
1010 + $args['interval_multiplier'] = get_post_meta($ID, $prefix . 'yearly_num_of_years', true);
1011 + }
1012 + $args['instance_start'] = get_post_meta($ID, $prefix . 'instance_start', true);
1013 + $args['instance_end'] = get_post_meta($ID, $prefix . 'instance_end', true);
1014 + $args['monthly_pattern'] = get_post_meta($ID, $prefix . 'monthly_nth_weekday_of_month', true);
1015 + $args['monthly_pattern_ord'] = get_post_meta($ID, $prefix . 'monthly_nth_weekday_of_month_nth', true);
1016 + $args['monthly_pattern_day'] = get_post_meta($ID, $prefix . 'monthly_nth_weekday_of_month_weekday', true);
1017 +
1018 + $exceptions_dates = get_post_meta($ID, $prefix . 'exceptions_dates');
1019 + if (false !== $exceptions_dates && isset($exceptions_dates[0]) && is_array($exceptions_dates[0])) {
1020 + $args['exceptions_dates'] = $exceptions_dates[0];
1021 + } else {
1022 + $args['exceptions_dates'] = false;
1023 + }
1024 +
1025 + $args = $this->convertDateTimeParametersToISO($args);
1026 +
1027 + return $this->getRulePeriods($args);
1028 + }
1029 +
1030 + /**
1031 + * Wrapper for calling timedContentPlugin::__getRulePeriods() based on the contents of the form fields
1032 + * of the Add Timed Content Rule and Edit Timed Content Rule screens. Output is sent to output as JSON
1033 + */
1034 + function timedContentPluginGetRulePeriodsAjax()
1035 + {
1036 + if (current_user_can('edit_posts') || current_user_can('edit_pages')) {
1037 + $prefix = TIMED_CONTENT_RULE_POSTMETA_PREFIX;
1038 + $args = array();
1039 +
1040 + $args['human_readable'] = (((isset($_POST[ $prefix . 'human_readable' ])) && ($_POST[ $prefix . 'human_readable' ] == 'true')) ? (bool) $_POST[ $prefix . 'human_readable' ] : false);
1041 + $args['freq'] = $_POST[ $prefix . 'frequency' ];
1042 + $args['timezone'] = $_POST[ $prefix . 'timezone' ];
1043 + $args['recurr_type'] = $_POST[ $prefix . 'recurrence_duration' ];
1044 + $args['num_repeat'] = $_POST[ $prefix . 'recurrence_duration_num_repeat' ];
1045 + $args['end_date'] = $_POST[ $prefix . 'recurrence_duration_end_date' ];
1046 + $args['days_of_week'] = (isset($_POST[ $prefix . 'weekly_days_of_week_to_repeat' ]) ? $_POST[ $prefix . 'weekly_days_of_week_to_repeat' ] : array());
1047 + $args['interval_multiplier'] = $_POST[ $prefix . 'interval_multiplier' ];
1048 + $args['instance_start'] = $_POST[ $prefix . 'instance_start' ];
1049 + $args['instance_end'] = $_POST[ $prefix . 'instance_end' ];
1050 + $args['monthly_pattern'] = $_POST[ $prefix . 'monthly_nth_weekday_of_month' ];
1051 + $args['monthly_pattern_ord'] = $_POST[ $prefix . 'monthly_nth_weekday_of_month_nth' ];
1052 + $args['monthly_pattern_day'] = $_POST[ $prefix . 'monthly_nth_weekday_of_month_weekday' ];
1053 + $args['exceptions_dates'] = (isset($_POST[ $prefix . 'exceptions_dates' ]) ? $_POST[ $prefix . 'exceptions_dates' ] : array());
1054 +
1055 + $response = json_encode($this->getRulePeriods($args));
1056 +
1057 + // response output
1058 + header("Content-Type: application/json");
1059 + echo $response;
1060 + }
1061 + die();
1062 +
1063 + }
1064 +
1065 + /**
1066 + * Returns a human-readable description of a Timed Content Rule
1067 + *
1068 + * @param $args Array of Timed Content Rule parameters
1069 + *
1070 + * @return string Schedule description or warning, if the rule may not work properly
1071 + */
1072 + function getScheduleDescription($args)
1073 + {
1074 + $interval_multiplier = 1;
1075 + $desc = "";
1076 +
1077 + $errors = $this->validate($args);
1078 + if ($errors) {
1079 + $messages = "<div class=\"tcr-warning\">\n";
1080 + $messages .= "<p class=\"heading\">" . __("Warning!", 'timed-content') . "</p>\n";
1081 + $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";
1082 + $messages .= "<ul>\n";
1083 + foreach ($errors as $error) {
1084 + $messages .= " <li>" . $error . "</li>\n";
867 1085 }
868 - foreach ( $timed_content_rule_pattern_custom_fields as $field ) {
869 - $defaults[$field['name']] = $field['default'];
1086 + $messages .= "</ul>\n";
1087 + $messages .= "<p>" . __("Check that all of the conditions for this rule are correct, and use <b>Show projected dates/times</b> to ensure your rule is working properly.", 'timed-content') . "</p>\n";
1088 + $messages .= "</div>\n";
1089 +
1090 + return $messages;
1091 + }
1092 +
1093 + if ($args['action']) {
1094 + $action = __("Show the content", 'timed-content');
1095 + } else {
1096 + $action = __("Hide the content", 'timed-content');
1097 + }
1098 + $freq = $args['freq'];
1099 + $timezone = $args['timezone'];
1100 + $recurr_type = $args['recurr_type'];
1101 + $num_repeat = intval($args['num_repeat']);
1102 + $end_date = $args['end_date'];
1103 + $days_of_week = $args['days_of_week'];
1104 + $interval_multiplier = $args['interval_multiplier'];
1105 + $instance_start_date = $args['instance_start']['date'];
1106 + $instance_start_time = $args['instance_start']['time'];
1107 + $instance_end_date = $args['instance_end']['date'];
1108 + $instance_end_time = $args['instance_end']['time'];
1109 + $monthly_pattern = $args['monthly_pattern'];
1110 + $monthly_pattern_ord = $args['monthly_pattern_ord'];
1111 + $monthly_pattern_day = $args['monthly_pattern_day'];
1112 + $exceptions_dates = $args['exceptions_dates'];
1113 +
1114 + $desc = sprintf(_x('%1$s on %2$s @ %3$s until %4$s @ %5$s.',
1115 + '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).',
1116 + 'timed-content'), $action, $instance_start_date, $instance_start_time, $instance_end_date,
1117 + $instance_end_time);
1118 +
1119 + if ($freq == 0) {
1120 + $desc .= "<br />" . sprintf(_n('Repeat this action every hour.', 'Repeat this action every %d hours.',
1121 + $interval_multiplier, 'timed-content'), $interval_multiplier);
1122 + } elseif ($freq == 1) {
1123 + $desc .= "<br />" . sprintf(_n('Repeat this action every day.', 'Repeat this action every %d days.',
1124 + $interval_multiplier, 'timed-content'), $interval_multiplier);
1125 + } elseif ($freq == 2) {
1126 + if (($days_of_week) && (is_array($days_of_week))) {
1127 + $days = array();
1128 + $days_list = "";
1129 + foreach ($days_of_week as $v) {
1130 + $days[] = $this->rule_days_array[ $v ];
1131 + }
1132 + switch (count($days)) {
1133 + case 1:
1134 + $days_list = sprintf(_x('%1$s', 'List of one weekday', 'timed-content'), $days[0]);
1135 + break;
1136 + case 2:
1137 + $days_list = sprintf(_x('%1$s and %2$s', 'List of two weekdays', 'timed-content'),
1138 + $days[0], $days[1]);
1139 + break;
1140 + case 3:
1141 + $days_list = sprintf(_x('%1$s, %2$s and %3$s', 'List of three weekdays',
1142 + 'timed-content'), $days[0], $days[1], $days[2]);
1143 + break;
1144 + case 4:
1145 + $days_list = sprintf(_x('%1$s, %2$s, %3$s and %4$s', 'List of four weekdays',
1146 + 'timed-content'), $days[0], $days[1], $days[2], $days[3]);
1147 + break;
1148 + case 5:
1149 + $days_list = sprintf(_x('%1$s, %2$s, %3$s, %4$s and %5$s', 'List of five weekdays',
1150 + 'timed-content'), $days[0], $days[1], $days[2], $days[3], $days[4]);
1151 + break;
1152 + case 6:
1153 + $days_list = sprintf(_x('%1$s, %2$s, %3$s, %4$s, %5$s and %6$s', 'List of six weekdays',
1154 + 'timed-content'), $days[0], $days[1], $days[2], $days[3], $days[4], $days[5]);
1155 + break;
1156 + case 7:
1157 + $days_list = sprintf(_x('%1$s, %2$s, %3$s, %4$s, %5$s, %6$s and %7$s',
1158 + 'List of all weekdays', 'timed-content'), $days[0], $days[1], $days[2], $days[3],
1159 + $days[4], $days[5], $days[6]);
1160 + break;
1161 + }
1162 + if ($interval_multiplier == 1) {
1163 + $desc .= "<br />" . sprintf(_x('Repeat this action every week on %s.',
1164 + 'List the weekdays to repeat the rule when frequency is every week. %s is the list of weekdays.',
1165 + 'timed-content'), $days_list);
1166 + } else {
1167 + $desc .= "<br />" . sprintf(_x('Repeat this action every %1$d weeks on %2$s.',
1168 + 'List the weekdays to repeat the rule when frequency is every %1$d weeks. %2$s is the list of weekdays.',
1169 + 'timed-content'), $interval_multiplier, $days_list);
1170 + }
1171 + } else {
1172 + $desc .= "<br />" . sprintf(_n('Repeat this action every week.',
1173 + 'Repeat this action every %d weeks.', $interval_multiplier, 'timed-content'),
1174 + $interval_multiplier);
870 1175 }
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 1176
1177 + } elseif ($freq == 3) {
1178 + if ($monthly_pattern == "yes") {
1179 + if ($interval_multiplier == 1) {
1180 + $desc .= "<br />" . sprintf(_x('Repeat this action every month on the %1$s %2$s of the month.',
1181 + "Example: 'Repeat this action every month on the second Friday of the month.'",
1182 + 'timed-content'), $this->rule_ordinal_array[ $monthly_pattern_ord ],
1183 + $this->rule_ordinal_days_array[ $monthly_pattern_day ]);
1184 + } else {
1185 + $desc .= "<br />" . sprintf(_x('Repeat this action every %1$d months on the %2$s %3$s of the month.',
1186 + "Example: 'Repeat this action every 2 months on the second Friday of the month.'",
1187 + 'timed-content'), $interval_multiplier,
1188 + $this->rule_ordinal_array[ $monthly_pattern_ord ],
1189 + $this->rule_ordinal_days_array[ $monthly_pattern_day ]);
1190 + }
1191 + } else {
1192 + $desc .= "<br />" . sprintf(_n('Repeat this action every month.',
1193 + 'Repeat this action every %d months.', $interval_multiplier, 'timed-content'),
1194 + $interval_multiplier);
1195 + }
1196 + } elseif ($freq == 4) {
1197 + $desc .= "<br />" . sprintf(_n('Repeat this action every year.', 'Repeat this action every %d years.',
1198 + $interval_multiplier, 'timed-content'), $interval_multiplier);
1199 + }
1200 +
1201 + if ($recurr_type == "recurrence_duration_num_repeat") {
1202 + $desc .= "<br />" . sprintf(_n('This rule will be active for one recurrence.',
1203 + 'This rule will be active for %d recurrences.', $num_repeat, 'timed-content'), $num_repeat);
1204 + } elseif ($recurr_type == "recurrence_duration_end_date") {
1205 + $desc .= "<br />" . sprintf(__('This rule will be active until %s.', 'timed-content'), $end_date);
1206 + }
1207 +
1208 + if (($exceptions_dates) && (is_array($exceptions_dates))) {
1209 + sort($exceptions_dates, SORT_NUMERIC);
1210 + $exceptions_dates = array_unique($exceptions_dates);
1211 + if ($exceptions_dates[0] == 0) {
1212 + array_shift($exceptions_dates);
1213 + }
1214 + if (!empty($exceptions_dates)) {
1215 + $desc .= "<br />" . sprintf(__('This rule will be inactive on the following dates: %s.',
1216 + 'timed-content'), join(", ", $exceptions_dates));
1217 + }
1218 + }
1219 +
1220 + $desc .= "<br />" . sprintf(__('All times are in the %s timezone.', 'timed-content'), $timezone);
1221 +
1222 + return $desc;
1223 + }
1224 +
1225 + /**
1226 + * Wrapper for calling timedContentPlugin::__getScheduleDescription() by the ID of a Timed Content Rule
1227 + *
1228 + * @param int $ID ID of the Timed Content Rule
1229 + *
1230 + * @return string
1231 + */
1232 + function getScheduleDescriptionById($ID)
1233 + {
1234 + $defaults = array();
1235 +
1236 + foreach ($this->rule_occurrence_custom_fields as $field) {
1237 + $defaults[ $field['name'] ] = $field['default'];
1238 + }
1239 + foreach ($this->rule_pattern_custom_fields as $field) {
1240 + $defaults[ $field['name'] ] = $field['default'];
1241 + }
1242 + foreach ($this->rule_recurrence_custom_fields as $field) {
1243 + $defaults[ $field['name'] ] = $field['default'];
1244 + }
1245 + foreach ($this->rule_exceptions_custom_fields as $field) {
1246 + $defaults[ $field['name'] ] = $field['default'];
1247 + }
1248 +
1249 + $prefix = TIMED_CONTENT_RULE_POSTMETA_PREFIX;
1250 + $args = array();
1251 +
1252 + $args['action'] = (false === get_post_meta($ID, $prefix . 'action',
1253 + true) ? $defaults['action'] : get_post_meta($ID, $prefix . 'action', true));
1254 + $args['freq'] = (false === get_post_meta($ID, $prefix . 'frequency',
1255 + true) ? $defaults['frequency'] : get_post_meta($ID, $prefix . 'frequency', true));
1256 + $args['timezone'] = (false === get_post_meta($ID, $prefix . 'timezone',
1257 + true) ? $defaults['timezone'] : get_post_meta($ID, $prefix . 'timezone', true));
1258 + $args['recurr_type'] = (false === get_post_meta($ID, $prefix . 'recurrence_duration',
1259 + true) ? $defaults['recurrence_duration'] : get_post_meta($ID, $prefix . 'recurrence_duration',
1260 + true));
1261 + $args['num_repeat'] = (false === get_post_meta($ID, $prefix . 'recurrence_duration_num_repeat',
1262 + true) ? $defaults['recurrence_duration_num_repeat'] : get_post_meta($ID,
1263 + $prefix . 'recurrence_duration_num_repeat', true));
1264 + $args['end_date'] = (false === get_post_meta($ID, $prefix . 'recurrence_duration_end_date',
1265 + true) ? $defaults['recurrence_duration_end_date'] : get_post_meta($ID,
1266 + $prefix . 'recurrence_duration_end_date', true));
1267 + $args['days_of_week'] = (false === get_post_meta($ID, $prefix . 'weekly_days_of_week_to_repeat',
1268 + true) ? $defaults['weekly_days_of_week_to_repeat'] : get_post_meta($ID,
1269 + $prefix . 'weekly_days_of_week_to_repeat', true));
1270 + if ($args['freq'] == 0) {
1271 + $args['interval_multiplier'] = (false === get_post_meta($ID, $prefix . 'hourly_num_of_hours',
1272 + true) ? $defaults['hourly_num_of_hours'] : get_post_meta($ID, $prefix . 'hourly_num_of_hours',
1273 + true));
1274 + }
1275 + if ($args['freq'] == 1) {
1276 + $args['interval_multiplier'] = (false === get_post_meta($ID, $prefix . 'daily_num_of_days',
1277 + true) ? $defaults['daily_num_of_days'] : get_post_meta($ID, $prefix . 'daily_num_of_days',
1278 + true));
1279 + }
1280 + if ($args['freq'] == 2) {
1281 + $args['interval_multiplier'] = (false === get_post_meta($ID, $prefix . 'weekly_num_of_weeks',
1282 + true) ? $defaults['weekly_num_of_weeks'] : get_post_meta($ID, $prefix . 'weekly_num_of_weeks',
1283 + true));
1284 + }
1285 + if ($args['freq'] == 3) {
1286 + $args['interval_multiplier'] = (false === get_post_meta($ID, $prefix . 'monthly_num_of_months',
1287 + true) ? $defaults['monthly_num_of_months'] : get_post_meta($ID, $prefix . 'monthly_num_of_months',
1288 + true));
1289 + }
1290 + if ($args['freq'] == 4) {
1291 + $args['interval_multiplier'] = (false === get_post_meta($ID, $prefix . 'yearly_num_of_years',
1292 + true) ? $defaults['yearly_num_of_years'] : get_post_meta($ID, $prefix . 'yearly_num_of_years',
1293 + true));
1294 + }
1295 + $args['instance_start'] = (false === get_post_meta($ID, $prefix . 'instance_start',
1296 + true) ? $defaults['instance_start'] : get_post_meta($ID, $prefix . 'instance_start', true));
1297 + $args['instance_end'] = (false === get_post_meta($ID, $prefix . 'instance_end',
1298 + true) ? $defaults['instance_end'] : get_post_meta($ID, $prefix . 'instance_end', true));
1299 + $args['monthly_pattern'] = (false === get_post_meta($ID, $prefix . 'monthly_nth_weekday_of_month',
1300 + true) ? $defaults['monthly_nth_weekday_of_month'] : get_post_meta($ID,
1301 + $prefix . 'monthly_nth_weekday_of_month', true));
1302 + $args['monthly_pattern_ord'] = (false === get_post_meta($ID, $prefix . 'monthly_nth_weekday_of_month_nth',
1303 + true) ? $defaults['monthly_nth_weekday_of_month_nth'] : get_post_meta($ID,
1304 + $prefix . 'monthly_nth_weekday_of_month_nth', true));
1305 + $args['monthly_pattern_day'] = (false === get_post_meta($ID,
1306 + $prefix . 'monthly_nth_weekday_of_month_weekday',
1307 + true) ? $defaults['monthly_nth_weekday_of_month_weekday'] : get_post_meta($ID,
1308 + $prefix . 'monthly_nth_weekday_of_month_weekday', true));
1309 + $exceptions_dates = get_post_meta($ID, $prefix . 'exceptions_dates');
1310 + if (false !== $exceptions_dates && isset($exceptions_dates[0]) && is_array($exceptions_dates[0])) {
1311 + $args['exceptions_dates'] = $exceptions_dates[0];
1312 + } else {
1313 + $args['exceptions_dates'] = $defaults['exceptions_dates'];
1314 + }
1315 +
1316 + $args = $this->convertDateTimeParametersToISO($args);
1317 +
1318 + return $this->getScheduleDescription($args);
1319 + }
1320 +
1321 + /**
1322 + * Wrapper for calling timedContentPlugin::__getRulePeriods() based on the contents of the form fields
1323 + * of the Add Timed Content Rule and Edit Timed Content Rule screens. Output is sent to output as plain text
1324 + */
1325 + function timedContentPluginGetScheduleDescriptionAjax()
1326 + {
1327 + if (current_user_can('edit_posts') || current_user_can('edit_pages')) {
878 1328 $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 ) );
1329 + $args = array();
899 1330
900 - return $this->__getScheduleDescription( $args );
1331 + $args['action'] = $_POST[ $prefix . 'action' ];
1332 + $args['freq'] = $_POST[ $prefix . 'frequency' ];
1333 + $args['timezone'] = $_POST[ $prefix . 'timezone' ];
1334 + $args['recurr_type'] = $_POST[ $prefix . 'recurrence_duration' ];
1335 + $args['num_repeat'] = $_POST[ $prefix . 'recurrence_duration_num_repeat' ];
1336 + $args['end_date'] = $_POST[ $prefix . 'recurrence_duration_end_date' ];
1337 + $args['days_of_week'] = (isset($_POST[ $prefix . 'weekly_days_of_week_to_repeat' ]) ? $_POST[ $prefix . 'weekly_days_of_week_to_repeat' ] : array());
1338 + $args['interval_multiplier'] = $_POST[ $prefix . 'interval_multiplier' ];
1339 + $args['instance_start'] = $_POST[ $prefix . 'instance_start' ];
1340 + $args['instance_end'] = $_POST[ $prefix . 'instance_end' ];
1341 + $args['monthly_pattern'] = $_POST[ $prefix . 'monthly_nth_weekday_of_month' ];
1342 + $args['monthly_pattern_ord'] = $_POST[ $prefix . 'monthly_nth_weekday_of_month_nth' ];
1343 + $args['monthly_pattern_day'] = $_POST[ $prefix . 'monthly_nth_weekday_of_month_weekday' ];
1344 + $args['exceptions_dates'] = (isset($_POST[ $prefix . 'exceptions_dates' ]) ? $_POST[ $prefix . 'exceptions_dates' ] : array());
901 1345
902 - }
1346 + $response = $this->getScheduleDescription($args);
903 1347
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() );
1348 + // response output
1349 + header("Content-Type: text/plain");
1350 + echo $response;
1351 + }
1352 + die();
1353 + }
927 1354
928 - $response = $this->__getScheduleDescription( $args );
929 -
930 - // response output
931 - header( "Content-Type: text/plain" );
932 - echo $response;
933 - }
934 - die();
935 - }
1355 + /**
1356 + * Processes the [timed-content-client] shortcode.
1357 + *
1358 + * @param array $atts Shortcode attributes
1359 + * @param null $content Content inside the shortcode
1360 + *
1361 + * @return string Processed output
1362 + */
1363 + function clientShowHTML($atts, $content = null)
1364 + {
1365 + $show_attr = "";
1366 + $hide_attr = "";
1367 + extract(shortcode_atts(array('show' => '0:00:000', 'hide' => '0:00:000', 'display' => 'div'), $atts));
936 1368
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 );
1369 + // Initialize show/hide arguments
1370 + $s_min = 0;
1371 + $s_sec = 0;
1372 + $s_fade = 0;
1373 + $h_min = 0;
1374 + $h_sec = 0;
1375 + $h_fade = 0;
1376 + @list($s_min, $s_sec, $s_fade) = explode(":", $show);
1377 + @list($h_min, $h_sec, $h_fade) = explode(":", $hide);
954 1378
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" );
1379 + if (((int) $s_min + (int) $s_sec) > 0) {
1380 + $show_attr = "_show_" . $s_min . "_" . $s_sec . "_" . $s_fade;
1381 + }
1382 + if (((int) $h_min + (int) $h_sec) > 0) {
1383 + $hide_attr = "_hide_" . $h_min . "_" . $h_sec . "_" . $h_fade;
1384 + }
962 1385
963 - $the_filter = "timed_content_filter";
964 - $the_filter = apply_filters( "timed_content_filter_override", $the_filter );
1386 + $the_class = TIMED_CONTENT_SHORTCODE_CLIENT . $show_attr . $hide_attr;
1387 + $the_tag = ($display == "div" ? "div" : "span");
965 1388
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 . ">";
1389 + $the_filter = "timed_content_filter";
1390 + $the_filter = apply_filters("timed_content_filter_override", $the_filter);
974 1391
975 - return $the_HTML;
976 - }
1392 + $the_HTML = "<"
1393 + . $the_tag
1394 + . " class='"
1395 + . $the_class
1396 + . "'"
1397 + . (($show_attr != "") ? " style='display: none;'" : "") . ">"
1398 + . str_replace(']]>', ']]&gt;', apply_filters($the_filter, $content))
1399 + . "</" . $the_tag . ">";
977 1400
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 = "";
1401 + return $the_HTML;
1402 + }
992 1403
993 - $the_filter = "timed_content_filter";
994 - $the_filter = apply_filters( "timed_content_filter_override", $the_filter );
1404 + /**
1405 + * Processes the [timed-content-server] shortcode.
1406 + *
1407 + * @param array $atts Shortcode attributes
1408 + * @param null $content Content inside the shortcode
1409 + *
1410 + * @return string Processed output
1411 + */
1412 + function serverShowHTML($atts, $content = null)
1413 + {
1414 + global $post;
995 1415
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' ) );
1416 + extract(shortcode_atts(array(
1417 + 'show' => 0,
1418 + 'hide' => 0,
1419 + 'debug' => 'false'
1420 + ), $atts));
1000 1421
1001 - $right_now = date_i18n( TIMED_CONTENT_DT_FORMAT, $right_now_t );
1422 + // Get time and timezone object for "show" time
1423 + $pos = strrpos($show, ' ');
1424 + if ($pos !== false) {
1425 + $show_time = substr($show, 0, $pos);
1426 + $show_tzname = substr($show, $pos + 1);
1427 + } else {
1428 + $show_time = $show;
1429 + $show_tzname = date_default_timezone_get();
1430 + }
1431 + try {
1432 + $show_tz = new DateTimeZone($show_tzname);
1433 + } catch(Exception $e) {
1434 + $show_tz = new DateTimeZone('UTC');
1435 + }
1002 1436
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 ) );
1437 + // Create time and timezone object for "hide" time
1438 + $pos = strrpos($hide, ' ');
1439 + if ($pos !== false) {
1440 + $hide_time = substr($hide, 0, $pos);
1441 + $hide_tzname = substr($hide, $pos + 1);
1442 + } else {
1443 + $hide_time = $hide;
1444 + $hide_tzname = date_default_timezone_get();
1445 + }
1446 + try {
1447 + $hide_tz = new DateTimeZone($hide_tzname);
1448 + } catch(Exception $e) {
1449 + $hide_tz = new DateTimeZone('UTC');
1450 + }
1011 1451
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";
1452 + // Try to parse date as ISO first
1453 + $show_dt = DateTime::createFromFormat('Y-m-d G:i', $show_time, $show_tz);
1454 + // Fallback to American format
1455 + if ($show_dt === false) {
1456 + $show_dt = DateTime::createFromFormat('m/d/Y G:i', $show_time, $show_tz);
1457 + }
1015 1458
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";
1459 + if ($show_dt !== false) {
1460 + $show_t = $show_dt->getTimeStamp();
1461 + } else {
1462 + // If nothing else worked so far, try strtotime()
1463 + // as it was before version 2.50
1464 + $show_t = strtotime($show);
1465 + if($show_t === false) $show_t = 0;
1466 + $show_dt = new DateTime();
1467 + $show_dt->setTimeStamp($show_t);
1468 + $show_dt->setTimezone($show_tz);
1469 + }
1022 1470
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";
1471 + // Try to parse date as ISO first
1472 + $hide_dt = DateTime::createFromFormat('Y-m-d G:i', $hide_time, $hide_tz);
1473 + if ($hide_dt === false) {
1474 + $hide_dt = DateTime::createFromFormat('m/d/Y G:i', $hide_time, $hide_tz);
1475 + }
1476 + if ($hide_dt !== false) {
1477 + $hide_t = $hide_dt->getTimeStamp();
1478 + } else {
1479 + // If nothing else worked so far, try strtotime()
1480 + // as it was before version 2.50
1481 + $hide_t = strtotime($hide);
1482 + if($hide_t === false) $hide_t = 0;
1483 + $hide_dt = new DateTime();
1484 + $hide_dt->setTimeStamp($hide_t);
1485 + $hide_dt->setTimezone($hide_tz);
1486 + }
1029 1487
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";
1488 + $right_now_t = current_time('timestamp', 1);
1489 + $debug_message = "";
1033 1490
1034 - $debug_message .= "</div>\n";
1491 + // use debug parameter if current user is allowed to edit the post
1492 + if (isset($_GET['tctest']) && !empty($post) && current_user_can("edit_post", $post->post_id)) {
1493 + $dt = DateTime::createFromFormat('Y-m-d H:i:s', $_GET['tctest']);
1494 + if ($dt != false) {
1495 + $right_now_t = $dt->getTimestamp();
1496 + }
1497 + }
1035 1498
1036 - date_default_timezone_set( $temp_tz );
1037 - remove_filter('date_i18n', array( &$this, "fix_date_i18n" ), 10, 4);
1038 - }
1499 + $the_filter = "timed_content_filter";
1500 + $the_filter = apply_filters("timed_content_filter_override", $the_filter);
1039 1501
1502 + $show_content = false;
1503 + if (($show_t <= $right_now_t) && ($right_now_t <= $hide_t || $hide_t == 0)) {
1504 + $show_content = true;
1505 + }
1040 1506
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";
1507 + if ((($debug == "true") || ((!$show_content) && ($debug == "when_hidden"))) && (!empty($post) && current_user_can("edit_post", $post->post_id))) {
1508 + add_filter('date_i18n', array(&$this, "fix_date_i18n"), 10, 4);
1509 + $temp_tz = date_default_timezone_get();
1510 + date_default_timezone_set(get_option('timezone_string'));
1045 1511
1046 - }
1512 + $right_now = date_i18n(TIMED_CONTENT_DATE_FORMAT_OUTPUT, $right_now_t);
1047 1513
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;
1514 + if ($show_t > $right_now_t) {
1515 + $show_diff_str = sprintf(_x('%s from now.', 'Human readable time difference', 'timed-content'),
1516 + human_time_diff($show_t, $right_now_t));
1517 + } else {
1518 + $show_diff_str = sprintf(_x('%s ago.', 'Human readable time difference', 'timed-content'),
1519 + human_time_diff($show_t, $right_now_t));
1520 + }
1521 + if ($hide_t > $right_now_t) {
1522 + $hide_diff_str = sprintf(_x('%s from now.', 'Human readable time difference', 'timed-content'),
1523 + human_time_diff($hide_t, $right_now_t));
1524 + } else {
1525 + $hide_diff_str = sprintf(_x('%s ago.', 'Human readable time difference', 'timed-content'),
1526 + human_time_diff($hide_t, $right_now_t));
1527 + }
1058 1528
1059 - $prefix = TIMED_CONTENT_RULE_POSTMETA_PREFIX;
1060 - $right_now_t = current_time( 'timestamp', 1 );
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 - }
1529 + $debug_message = "<div class=\"tcr-warning\">\n";
1530 + $debug_message .= "<p class=\"heading\">" . _x("Notice", "Noun", 'timed-content') . "</p>\n";
1531 + $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.',
1532 + 'timed-content'), "<code>[timed-content-server]</code>", "<code>debug</code>") . "</p>\n";
1072 1533
1073 - $the_filter = "timed_content_filter";
1074 - $the_filter = apply_filters( "timed_content_filter_override", $the_filter );
1534 + if ($show_t === 0) {
1535 + $debug_message .= "<p>" . sprintf(__('The %s attribute is not set or invalid.', 'timed-content'),
1536 + "<code>show</code>") . "</p>\n";
1537 + } else {
1538 + $debug_message .= "<p>" . sprintf(__('The %s attribute is currently set to', 'timed-content'),
1539 + "<code>show</code>") . ": " . $show . ",<br />\n "
1540 + . __('The Timed Content plugin thinks the intended date/time is',
1541 + 'timed-content') . ": " . $show_dt->format(TIMED_CONTENT_DATE_FORMAT_OUTPUT)
1542 + . " (" . $show_diff_str . ")</p>\n";
1543 + }
1075 1544
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 - }
1545 + if ($hide === 0) {
1546 + $debug_message .= "<p>" . sprintf(__('The %s attribute is not set or invalid.', 'timed-content'),
1547 + "<code>hide</code>") . "</p>\n";
1548 + } else {
1549 + $debug_message .= "<p>" . sprintf(__('The %s attribute is currently set to', 'timed-content'),
1550 + "<code>hide</code>") . ": " . $hide . ",<br />\n"
1551 + . __('The Timed Content plugin thinks the intended date/time is',
1552 + 'timed-content') . ": " . $hide_dt->format(TIMED_CONTENT_DATE_FORMAT_OUTPUT)
1553 + . " (" . $hide_diff_str . ").</p>\n";
1554 + }
1081 1555
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 - }
1556 + $debug_message .= "<p>" . __('Current date:',
1557 + 'timed-content') . "&nbsp;" . $right_now . "</p>\n";
1558 + $debug_message .= "<p>" . __('Content filter:', 'timed-content') . "&nbsp;" . $the_filter . "</p>\n";
1559 + $debug_message .= "<p>" . _x('Content:', "Noun", 'timed-content') . "</p><p>" . $content . "</p>\n";
1091 1560
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
1561 + if ($show_content === true) {
1562 + $debug_message .= "<p>" . __('The plugin will show the content.', 'timed-content') . "</p>";
1563 + } else {
1564 + $debug_message .= "<p>" . __('The plugin will hide the content.', 'timed-content'). "</p>";
1565 + }
1566 +
1567 + $debug_message .= "</div>\n";
1568 +
1569 + date_default_timezone_set($temp_tz);
1570 + remove_filter('date_i18n', array(&$this, "fix_date_i18n"), 10, 4);
1107 1571 }
1108 1572
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 );
1573 + if ($show_content === true) {
1574 + if (!empty($post)) {
1575 + do_action("timed_content_server_show", $post->ID, $show, $hide, $content);
1576 + } else {
1577 + do_action("timed_content_server_show", null, $show, $hide, $content);
1578 + }
1150 1579
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' ) ) );
1580 + return $debug_message . str_replace(']]>', ']]&gt;', apply_filters($the_filter, $content)) . "\n";
1581 + } else {
1582 + if (!empty($post)) {
1583 + do_action("timed_content_server_hide", $post->ID, $show, $hide, $content);
1584 + } else {
1585 + do_action("timed_content_server_show", null, $show, $hide, $content);
1586 + }
1154 1587
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 - }
1588 + return $debug_message . "\n";
1589 + }
1168 1590
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 - }
1591 + }
1182 1592
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' ) ) )
1593 + /**
1594 + * Processes the [timed-content-rule] shortcode.
1595 + *
1596 + * @param array $atts Shortcode attributes
1597 + * @param null $content Content inside the shortcode
1598 + *
1599 + * @return string Processed output
1600 + */
1601 + function rulesShowHTML($atts, $content = null)
1602 + {
1603 + global $post;
1604 +
1605 + extract(shortcode_atts(array('id' => 0), $atts));
1606 + if (!is_numeric($id)) {
1607 + $page = get_page_by_title($id, OBJECT, TIMED_CONTENT_RULE_TYPE);
1608 + if ($page == null) {
1190 1609 return;
1610 + }
1611 + $id = $page->ID;
1612 + }
1613 + if (TIMED_CONTENT_RULE_TYPE != get_post_type($id)) {
1614 + return;
1615 + }
1191 1616
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 ) );
1617 + $prefix = TIMED_CONTENT_RULE_POSTMETA_PREFIX;
1618 + $right_now_t = current_time('timestamp', 1);
1619 + $rule_is_active = false;
1620 +
1621 + // use debug parameter if current user is allowed to edit the post
1622 + if (isset($_GET['tctest']) && current_user_can("edit_post", $post->post_id)) {
1623 + $dt = DateTime::createFromFormat('Y-m-d H:i:s', $_GET['tctest']);
1624 + if ($dt != false) {
1625 + $right_now_t = $dt->getTimestamp();
1203 1626 }
1204 1627 }
1205 1628
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 - }
1629 + $active_periods = $this->getRulePeriodsById($id, false);
1630 + $action_is_show = (bool) get_post_meta($id, $prefix . 'action', true);
1215 1631
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 - }
1632 + foreach ($active_periods as $period) {
1633 + if (($period['start'] <= $right_now_t) && ($right_now_t <= $period['end'])) {
1634 + $rule_is_active = true;
1635 + break;
1636 + }
1637 + }
1226 1638
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";
1639 + $the_filter = "timed_content_filter";
1640 + $the_filter = apply_filters("timed_content_filter_override", $the_filter);
1641 +
1642 + if ((($rule_is_active == true) && ($action_is_show == true)) || (($rule_is_active == false) && ($action_is_show == false))) {
1643 + if (!empty($post)) {
1644 + do_action("timed_content_rule_show", $post->ID, $id, $content);
1645 + } else {
1646 + do_action("timed_content_rule_show", null, $id, $content);
1242 1647 }
1243 - if ( empty( $the_rules ) )
1244 - $the_js .= " { 'ID': -999, 'title': ' ---- ', 'desc': '" . __( 'No Timed Content Rules found', 'timed-content' ) . "' }\n";
1245 1648
1246 - $the_js .= "];\n";
1247 - return $the_js;
1649 + return str_replace(']]>', ']]&gt;', apply_filters($the_filter, $content));
1650 + } else {
1651 + if (!empty($post)) {
1652 + do_action("timed_content_rule_hide", $post->ID, $id, $content);
1653 + } else {
1654 + do_action("timed_content_rule_hide", null, $id, $content);
1655 + }
1656 +
1657 + return "";
1248 1658 }
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" );
1659 + }
1255 1660
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 );
1661 + /**
1662 + * Enqueues the JavaScript code necessary for the functionality of the [timed-content-client] shortcode.
1663 + */
1664 + function addHeaderCode()
1665 + {
1666 + if (!is_admin()) {
1667 + wp_enqueue_style('timed-content-css', TIMED_CONTENT_CSS, false, TIMED_CONTENT_VERSION);
1668 + wp_enqueue_script('timed-content_js', TIMED_CONTENT_PLUGIN_URL . '/js/timed-content.js',
1669 + array('jquery'), TIMED_CONTENT_VERSION);
1670 + }
1671 + }
1672 +
1673 + /**
1674 + * Enqueues the CSS code necessary for custom icons for the Timed Content Rules management screens
1675 + * and the TinyMCE editor. Echo'd to output.
1676 + */
1677 + function addPostTypeIcons()
1678 + {
1679 + wp_enqueue_style('timed-content-dashicons', TIMED_CONTENT_CSS_DASHICONS, false, TIMED_CONTENT_VERSION);
1680 + ?>
1681 + <style type="text/css" media="screen">
1682 + #adminmenu #menu-posts-<?php echo TIMED_CONTENT_RULE_TYPE; ?>.menu-icon-post div.wp-menu-image:before {
1683 + font-family: 'timed-content-dashicons' !important;
1684 + content: '\e601';
1262 1685 }
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 );
1686 +
1687 + #dashboard_right_now li.<?php echo TIMED_CONTENT_RULE_TYPE; ?>-count a:before {
1688 + font-family: 'timed-content-dashicons' !important;
1689 + content: '\e601';
1271 1690 }
1272 1691
1273 - ob_start();
1274 - include( "tinymce_plugin/dialog.php" );
1275 - $content = ob_get_contents();
1276 - ob_end_clean();
1277 - echo $content;
1278 - die();
1279 - }
1692 + .mce-i-timed_content:before {
1693 + font: 400 24px/1 'timed-content-dashicons' !important;
1694 + padding: 0;
1695 + vertical-align: top;
1696 + margin-left: -2px;
1697 + padding-right: 2px;
1698 + content: '\e601';
1699 + }
1700 + </style>
1701 + <?php
1702 + }
1280 1703
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 - }
1704 + /**
1705 + * Enqueues the JavaScript code necessary for the functionality of the Timed Content Rules management screens.
1706 + */
1707 + function addAdminHeaderCode()
1708 + {
1709 + if ((isset($_GET['post_type']) && $_GET['post_type'] == TIMED_CONTENT_RULE_TYPE)
1710 + || (isset($post_type) && $post_type == TIMED_CONTENT_RULE_TYPE)
1711 + || (isset($_GET['post']) && get_post_type($_GET['post']) == TIMED_CONTENT_RULE_TYPE)) {
1712 + wp_enqueue_style('thickbox');
1713 + wp_enqueue_style('timed-content-css', TIMED_CONTENT_CSS, false, TIMED_CONTENT_VERSION);
1714 + // Enqueue the JavaScript file that manages the meta box UI
1715 + wp_enqueue_script('timed-content-admin_js', TIMED_CONTENT_PLUGIN_URL . '/js/timed-content-admin.js',
1716 + array('jquery'), TIMED_CONTENT_VERSION);
1717 + // Enqueue the JavaScript file that makes AJAX requests
1718 + wp_enqueue_script('timed-content-ajax_js', TIMED_CONTENT_PLUGIN_URL . '/js/timed-content-ajax.js',
1719 + array('jquery', 'thickbox'), TIMED_CONTENT_VERSION);
1300 1720
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>';
1721 + // Set up local variables used in the Admin JavaScript file
1722 + wp_localize_script('timed-content-admin_js', 'timedContentRuleAdmin', array(
1723 + 'no_exceptions_label' => __("- No exceptions set -", 'timed-content')
1724 + ));
1725 +
1726 + // Set up local variables used in the AJAX JavaScript file
1727 + wp_localize_script('timed-content-ajax_js', 'timedContentRuleAjax', array(
1728 + 'ajaxurl' => admin_url('admin-ajax.php'),
1729 + 'start_label' => _x('Start',
1730 + 'Scheduled Dates/Times dialog - Beginning of active period table header', 'timed-content'),
1731 + 'end_label' => _x('End',
1732 + 'Scheduled Dates/Times dialog - End of active period table header', 'timed-content'),
1733 + 'dialog_label' => _x('Scheduled dates/times',
1734 + 'Scheduled Dates/Times dialog - dialog header', 'timed-content'),
1735 + 'button_loading_label' => __('Calculating dates/times', 'timed-content'),
1736 + 'button_finished_label' => __('Show projected dates/times', 'timed-content'),
1737 + 'dialog_width' => 800,
1738 + 'dialog_height' => 500,
1739 + 'error' => __("Error", 'timed-content'),
1740 + 'error_desc' => __("Something unexpected has happened along the way. The specific details are below:",
1741 + 'timed-content')
1742 + ));
1743 + }
1744 + }
1745 +
1746 + /**
1747 + * Initializes the TinyMCE plugin bundled with this Wordpress plugin
1748 + *
1749 + * @return void
1750 + */
1751 + function initTinyMCEPlugin()
1752 + {
1753 + if ((!current_user_can('edit_posts')) && (!current_user_can('edit_pages'))) {
1754 + return;
1755 + }
1756 +
1757 + // Add only in Rich Editor mode
1758 + if (get_user_option('rich_editing') == 'true') {
1759 + add_filter("mce_external_plugins", array(&$this, "addTimedContentTinyMCEPlugin"));
1760 + add_filter("mce_buttons", array(&$this, "registerTinyMCEButton"));
1761 + }
1762 + }
1763 +
1764 + /**
1765 + * Sets up variables to use in the TinyMCE plugin's plugin.js.
1766 + *
1767 + * @return void
1768 + */
1769 + function setTinyMCEPluginVars()
1770 + {
1771 + global $wp_version;
1772 + if ((!current_user_can('edit_posts')) && (!current_user_can('edit_pages'))) {
1773 + return;
1774 + }
1775 +
1776 + // Add only in Rich Editor mode
1777 + if (get_user_option('rich_editing') == 'true') {
1778 + if (version_compare($wp_version, "3.8", "<")) {
1779 + $image = "/clock.gif";
1780 + } else {
1781 + $image = "";
1310 1782 }
1311 - if ( $column_name == 'description' ) {
1312 - $desc = $this->getScheduleDescriptionById( $post_ID );
1313 - if ( $desc ) {
1314 - echo '<em>' . $desc . '</em>';
1315 - }
1783 + wp_localize_script('editor',
1784 + 'timedContentAdminTinyMCEOptions',
1785 + array(
1786 + 'version' => TIMED_CONTENT_VERSION,
1787 + 'desc' => __("Add Timed Content shortcodes", 'timed-content'),
1788 + 'image' => $image
1789 + ));
1790 + }
1791 + }
1792 +
1793 + /**
1794 + * Sets up the button for the associated TinyMCE plugin for use in the editor menubar.
1795 + *
1796 + * @param array $buttons Array of menu buttons already registered with TinyMCE
1797 + *
1798 + * @return array The array of TinyMCE menu buttons with ours now loaded in as well
1799 + */
1800 + function registerTinyMCEButton($buttons)
1801 + {
1802 + array_push($buttons, "|", "timed_content");
1803 +
1804 + return $buttons;
1805 + }
1806 +
1807 + /**
1808 + * Loads the associated TinyMCE plugin into TinyMCE's plugin array
1809 + *
1810 + * @param array $plugin_array Array of plugins already registered with TinyMCE
1811 + *
1812 + * @return array The array of TinyMCE plugins with ours now loaded in as well
1813 + */
1814 + function addTimedContentTinyMCEPlugin($plugin_array)
1815 + {
1816 + $plugin_array['timed_content'] = TIMED_CONTENT_PLUGIN_URL . "/tinymce_plugin/plugin.js";
1817 +
1818 + return $plugin_array;
1819 + }
1820 +
1821 + /**
1822 + * Generates JavaScript array of objects describing Timed Content rules. Used in the dialog box created by
1823 + * timedContentPlugin::timedContentPluginGetTinyMCEDialog().
1824 + *
1825 + * @return string JavaScript array describing the Timed Content rules
1826 + */
1827 + function getRulesJS()
1828 + {
1829 + $the_js = "var rules = [\n";
1830 + $args = array(
1831 + 'post_type' => TIMED_CONTENT_RULE_TYPE,
1832 + 'posts_per_page' => - 1,
1833 + 'post_status' => 'publish'
1834 + );
1835 + $the_rules = get_posts($args);
1836 + foreach ($the_rules as $rule) {
1837 + $desc = $this->getScheduleDescriptionById($rule->ID);
1838 + $desc = str_replace('<br />', ' ', $desc);
1839 + // Only add a rule if there's no errors or warnings
1840 + if (false === strpos($desc, "tcr-warning")) {
1841 + $the_js .= " { 'ID': " . $rule->ID . ", 'title': '" . esc_js(((strlen($rule->post_title) > 0) ? $rule->post_title : _x("(no title)",
1842 + "No Timed Content Rule title",
1843 + "timed-content"))) . "', 'desc': '" . esc_js($desc) . "' },\n";
1316 1844 }
1317 - }
1845 + }
1846 + if (empty($the_rules)) {
1847 + $the_js .= " { 'ID': -999, 'title': ' ---- ', 'desc': '" . __('No Timed Content Rules found',
1848 + 'timed-content') . "' }\n";
1849 + }
1318 1850
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;
1851 + $the_js .= "];\n";
1852 +
1853 + return $the_js;
1854 + }
1855 +
1856 + /**
1857 + * Display a dialog box for this plugin's associated TinyMCE plugin. Called from TinyMCE via AJAX.
1858 + *
1859 + * @return void
1860 + */
1861 + function timedContentPluginGetTinyMCEDialog()
1862 + {
1863 + wp_enqueue_style(TIMED_CONTENT_SLUG . '-jquery-ui-css', TIMED_CONTENT_JQUERY_UI_CSS);
1864 + wp_enqueue_script('jquery-ui-datepicker');
1865 + wp_register_style(TIMED_CONTENT_SLUG . '-jquery-ui-timepicker-css',
1866 + TIMED_CONTENT_JQUERY_UI_TIMEPICKER_CSS);
1867 + wp_enqueue_style(TIMED_CONTENT_SLUG . '-jquery-ui-timepicker-css');
1868 + wp_register_script(TIMED_CONTENT_SLUG . '-jquery-ui-timepicker-js', TIMED_CONTENT_JQUERY_UI_TIMEPICKER_JS,
1869 + array('jquery', 'jquery-ui-datepicker'), TIMED_CONTENT_VERSION);
1870 + wp_enqueue_script(TIMED_CONTENT_SLUG . '-jquery-ui-timepicker-js');
1871 + if (!(wp_script_is(TIMED_CONTENT_SLUG . '-jquery-ui-datetime-i18n-js', 'registered'))) {
1872 + wp_register_script(TIMED_CONTENT_SLUG . '-jquery-ui-datetime-i18n-js',
1873 + TIMED_CONTENT_PLUGIN_URL . "/js/timed-content-datetime-i18n.js",
1874 + array('jquery', 'jquery-ui-datepicker', TIMED_CONTENT_SLUG . '-jquery-ui-timepicker-js'),
1875 + TIMED_CONTENT_VERSION);
1876 + wp_enqueue_script(TIMED_CONTENT_SLUG . '-jquery-ui-datetime-i18n-js');
1877 + wp_localize_script(TIMED_CONTENT_SLUG . '-jquery-ui-datetime-i18n-js', 'TimedContentJQDatepickerI18n',
1878 + $this->jquery_ui_datetime_datepicker_i18n);
1879 + wp_localize_script(TIMED_CONTENT_SLUG . '-jquery-ui-datetime-i18n-js', 'TimedContentJQTimepickerI18n',
1880 + $this->jquery_ui_datetime_timepicker_i18n);
1881 + }
1882 +
1883 + ob_start();
1884 + include("tinymce_plugin/dialog.php");
1885 + $content = ob_get_contents();
1886 + ob_end_clean();
1887 + echo $content;
1888 + die();
1889 + }
1890 +
1891 + /**
1892 + * Add custom columns to the Timed Content Rules overview page
1893 + *
1894 + * @return void
1895 + */
1896 + function addDescColumnHead($defaults)
1897 + {
1898 + unset($defaults['date']);
1899 + $defaults['description'] = __('Description', 'timed-content');
1900 + $defaults['shortcode'] = __('Shortcode', 'timed-content');
1901 +
1902 + return $defaults;
1903 + }
1904 +
1905 + /**
1906 + * Display content associated with custom columns on the Timed Content rules overview page
1907 + *
1908 + * @param $column_name Name of the column to be displayed
1909 + * @param $post_ID ID of the Timed Content Rule being listed
1910 + */
1911 + function addDescColumnContent($column_name, $post_ID)
1912 + {
1913 + if ($column_name == 'shortcode') {
1914 + echo '<code>[' . TIMED_CONTENT_SHORTCODE_RULE . ' id="' . $post_ID . '"]...[/' . TIMED_CONTENT_SHORTCODE_RULE . ']</code>';
1915 + }
1916 + if ($column_name == 'description') {
1917 + $desc = $this->getScheduleDescriptionById($post_ID);
1918 + if ($desc) {
1919 + echo '<em>' . $desc . '</em>';
1326 1920 }
1921 + }
1922 + }
1327 1923
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>";
1924 + /**
1925 + * Display a count of Timed Content rules in the Dashboard's Right Now widget
1926 + *
1927 + * @return void
1928 + */
1929 + function addRulesCount() {
1930 + if (!post_type_exists(TIMED_CONTENT_RULE_TYPE)) {
1931 + return;
1932 + }
1933 +
1934 + $num_posts = wp_count_posts(TIMED_CONTENT_RULE_TYPE);
1935 + $num = number_format_i18n($num_posts->publish);
1936 + $text = _n('Timed Content rule', 'Timed Content rules', intval($num_posts->publish),
1937 + 'timed-content');
1938 + if (current_user_can('edit_posts') || current_user_can('edit_pages')) {
1939 + echo "<a href='edit.php?post_type=" . TIMED_CONTENT_RULE_TYPE . "'>"
1940 + . '<li class="' . TIMED_CONTENT_RULE_TYPE . '-count">'
1941 + . $num
1942 + . ' '
1943 + . $text
1944 + . '</a></li>';
1945 + }
1946 +
1947 + if ($num_posts->pending > 0) {
1948 + $num = number_format_i18n($num_posts->pending);
1949 + $text = _n('Timed Content rule pending', 'Timed Content rules pending', intval($num_posts->pending),
1950 + 'timed-content');
1951 + if (current_user_can('edit_posts') || current_user_can('edit_pages')) {
1952 + echo "<a href='edit.php?post_status=pending&post_type=" . TIMED_CONTENT_RULE_TYPE . "'>"
1953 + . '<li class="' . TIMED_CONTENT_RULE_TYPE . '-count">'
1954 + . $num
1955 + . ' '
1956 + . $text
1957 + . '</a></li>';
1334 1958 }
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>';
1959 + }
1960 + }
1339 1961
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>";
1962 + /**
1963 + * Setup custom fields for Timed Content rules
1964 + *
1965 + * @return void
1966 + */
1967 + function setupCustomFields()
1968 + {
1969 + global $post;
1970 +
1971 + $now_ts = current_time('timestamp');
1972 + $now_plus1h_dt = new DateTime();
1973 + $now_plus2h_dt = new DateTime();
1974 + $now_plus1y_dt = new DateTime();
1975 + $now_plus1h_dt->setTimeStamp($now_ts);
1976 + $now_plus2h_dt->setTimeStamp($now_ts);
1977 + $now_plus1y_dt->setTimeStamp($now_ts);
1978 + $now_plus1h_dt->add(new DateInterval('PT1H'));
1979 + $now_plus2h_dt->add(new DateInterval('PT2H'));
1980 + $now_plus1y_dt->add(new DateInterval('P1Y'));
1981 +
1982 + $post_id = (isset($_GET['post']) && (TIMED_CONTENT_RULE_TYPE === get_post_type($_GET['post'])) ? intval($_GET['post']) : intval(0));
1983 + $exceptions_dates = get_post_meta($post_id, TIMED_CONTENT_RULE_POSTMETA_PREFIX . "exceptions_dates");
1984 + if (false !== $exceptions_dates && isset($exceptions_dates[0]) && is_array($exceptions_dates[0])) {
1985 + $timed_content_rules_exceptions_dates = $exceptions_dates[0];
1986 + sort($timed_content_rules_exceptions_dates, SORT_NUMERIC);
1987 + $timed_content_rules_exceptions_dates = array_unique($timed_content_rules_exceptions_dates);
1988 +
1989 + // If the exceptions are stored as timestamps, convert them to ISO first
1990 + $num = 0;
1991 + while ($num<count($timed_content_rules_exceptions_dates)) {
1992 + if (is_numeric($timed_content_rules_exceptions_dates[$num])) {
1993 + $timed_content_rules_exceptions_dates[$num] = date('Y-m-d', $timed_content_rules_exceptions_dates[$num]);
1346 1994 }
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>';
1995 + $num++;
1351 1996 }
1997 +
1998 + $timed_content_rules_exceptions_dates_array = array_combine($timed_content_rules_exceptions_dates, $timed_content_rules_exceptions_dates);
1999 + } else {
2000 + $timed_content_rules_exceptions_dates_array = array("0" => __("- No exceptions set -", 'timed-content'));
1352 2001 }
1353 2002
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 - }
2003 + $this->rule_occurrence_custom_fields = array(
2004 + array(
2005 + "name" => "action",
2006 + "display" => "block",
2007 + "title" => __("Action", 'timed-content'),
2008 + "description" => __("Sets the action to be performed when the rule is active.", 'timed-content'),
2009 + "type" => "radio",
2010 + "values" => array(1 => __("Show the content", 'timed-content'),
2011 + 0 => __("Hide the content", 'timed-content')),
2012 + "default" => 1,
2013 + "scope" => array(TIMED_CONTENT_RULE_TYPE),
2014 + "capability" => "edit_posts"
2015 + ),
2016 + array(
2017 + "name" => "instance_start",
2018 + "display" => "block",
2019 + "title" => __("Starting date/time", 'timed-content'),
2020 + "description" => __("Sets the date and time for the beginning of the first active period for this rule.", 'timed-content'),
2021 + "type" => "datetime",
2022 + "default" => array("date" => strftime('%Y-%m-%d', $now_plus1h_dt->getTimeStamp()),
2023 + "time" => strftime('%H:%M', $now_plus1h_dt->getTimeStamp())),
2024 + "scope" => array(TIMED_CONTENT_RULE_TYPE),
2025 + "capability" => "edit_posts"
2026 + ),
2027 + array(
2028 + "name" => "instance_end",
2029 + "display" => "block",
2030 + "title" => __("Ending date/time", 'timed-content'),
2031 + "description" => __("Sets the date and time for the end of the first active period for this rule.", 'timed-content'),
2032 + "type" => "datetime",
2033 + "default" => array("date" => strftime('%Y-%m-%d', $now_plus2h_dt->getTimeStamp()),
2034 + "time" => strftime('%H:%M', $now_plus2h_dt->getTimeStamp())),
2035 + "scope" => array(TIMED_CONTENT_RULE_TYPE),
2036 + "capability" => "edit_posts"
2037 + ),
2038 + array(
2039 + "name" => "timezone",
2040 + "display" => "block",
2041 + "title" => __("Timezone", 'timed-content'),
2042 + "description" => __("Select the timezone you wish to use for this rule.", 'timed-content'),
2043 + "type" => "timezone-list",
2044 + "default" => get_option('timezone_string'),
2045 + "scope" => array(TIMED_CONTENT_RULE_TYPE),
2046 + "capability" => "edit_posts"
2047 + )
2048 + );
1362 2049
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>';
2050 + $this->rule_pattern_custom_fields = array(
2051 + array(
2052 + "name" => "frequency",
2053 + "display" => "block",
2054 + "title" => __("Frequency", 'timed-content'),
2055 + "description" => __("Sets the frequency at which the action should be repeated.", 'timed-content'),
2056 + "type" => "list",
2057 + "default" => "1",
2058 + "values" => $this->rule_freq_array,
2059 + "scope" => array(TIMED_CONTENT_RULE_TYPE),
2060 + "capability" => "edit_posts"
2061 + ),
2062 + array(
2063 + "name" => "hourly_num_of_hours",
2064 + "display" => "none",
2065 + "title" => __("Interval of recurrences", 'timed-content'),
2066 + "description" => __("Repeat this action every X hours.", 'timed-content'),
2067 + "type" => "number",
2068 + "default" => "1",
2069 + "min" => "1",
2070 + "scope" => array(TIMED_CONTENT_RULE_TYPE),
2071 + "capability" => "edit_posts"
2072 + ),
2073 + array(
2074 + "name" => "daily_num_of_days",
2075 + "display" => "none",
2076 + "title" => __("Interval of recurrences", 'timed-content'),
2077 + "description" => __("Repeat this action every X days.", 'timed-content'),
2078 + "type" => "number",
2079 + "default" => "1",
2080 + "min" => "1",
2081 + "scope" => array(TIMED_CONTENT_RULE_TYPE),
2082 + "capability" => "edit_posts"
2083 + ),
2084 + array(
2085 + "name" => "weekly_num_of_weeks",
2086 + "display" => "none",
2087 + "title" => __("Interval of recurrences", 'timed-content'),
2088 + "description" => __("Repeat this action every X weeks.", 'timed-content'),
2089 + "type" => "number",
2090 + "default" => "1",
2091 + "min" => "1",
2092 + "scope" => array(TIMED_CONTENT_RULE_TYPE),
2093 + "capability" => "edit_posts"
2094 + ),
2095 + array(
2096 + "name" => "weekly_days_of_week_to_repeat",
2097 + "display" => "none",
2098 + "title" => __("Repeat on the following days", 'timed-content'),
2099 + "description" => __("Repeat this action on these days of the week <strong>instead</strong> of the day of week the starting date/time falls on.", 'timed-content'),
2100 + "type" => "checkbox-list",
2101 + "default" => array(),
2102 + "values" => $this->rule_days_array,
2103 + "scope" => array(TIMED_CONTENT_RULE_TYPE),
2104 + "capability" => "edit_posts"
2105 + ),
2106 + array(
2107 + "name" => "monthly_num_of_months",
2108 + "display" => "none",
2109 + "title" => __("Interval of recurrences", 'timed-content'),
2110 + "description" => __("Repeat this action every X months.", 'timed-content'),
2111 + "type" => "number",
2112 + "default" => "1",
2113 + "min" => "1",
2114 + "scope" => array(TIMED_CONTENT_RULE_TYPE),
2115 + "capability" => "edit_posts"
2116 + ),
2117 + array(
2118 + "name" => "monthly_nth_weekday_of_month",
2119 + "display" => "none",
2120 + "title" => __("Repeat on a specific weekday of the month", 'timed-content'),
2121 + "description" => __("Repeat this action on a specific weekday of the month (for example, \"every third Tuesday\"). Check this box to select a pattern below.", 'timed-content'),
2122 + "type" => "checkbox",
2123 + "default" => "no",
2124 + "scope" => array(TIMED_CONTENT_RULE_TYPE),
2125 + "capability" => "edit_posts"
2126 + ),
2127 + array(
2128 + "name" => "monthly_nth_weekday_of_month_nth",
2129 + "display" => "none",
2130 + "title" => __("Weekday ordinal", 'timed-content'),
2131 + "description" => __("Select a value for week of the month (for example \"first\", \"second\", etc.).", 'timed-content'),
2132 + "type" => "list",
2133 + "default" => 0,
2134 + "values" => $this->rule_ordinal_array,
2135 + "scope" => array(TIMED_CONTENT_RULE_TYPE),
2136 + "capability" => "edit_posts"
2137 + ),
2138 + array(
2139 + "name" => "monthly_nth_weekday_of_month_weekday",
2140 + "display" => "none",
2141 + "title" => __("Day of the week", 'timed-content'),
2142 + "description" => __("Select the day of week.", 'timed-content'),
2143 + "type" => "list",
2144 + "default" => 0,
2145 + "values" => $this->rule_ordinal_days_array,
2146 + "scope" => array(TIMED_CONTENT_RULE_TYPE),
2147 + "capability" => "edit_posts"
2148 + ),
2149 + array(
2150 + "name" => "yearly_num_of_years",
2151 + "display" => "none",
2152 + "title" => __("Interval of recurrences", 'timed-content'),
2153 + "description" => __("Repeat this action every X years.", 'timed-content'),
2154 + "type" => "number",
2155 + "default" => "1",
2156 + "min" => "1",
2157 + "scope" => array(TIMED_CONTENT_RULE_TYPE),
2158 + "capability" => "edit_posts"
2159 + )
2160 + );
1373 2161
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" );
2162 + $this->rule_recurrence_custom_fields = array(
2163 + array(
2164 + "name" => "recurrence_duration",
2165 + "display" => "block",
2166 + "title" => __("How often to repeat this action", 'timed-content'),
2167 + "description" => "",
2168 + "type" => "radio",
2169 + "values" => array("recurrence_duration_end_date" => __("Keep repeating until a given date", 'timed-content'),
2170 + "recurrence_duration_num_repeat" => __("Repeat a set number of times", 'timed-content')),
2171 + "default" => "recurrence_duration_end_date",
2172 + "scope" => array(TIMED_CONTENT_RULE_TYPE),
2173 + "capability" => "edit_posts"
2174 + ),
2175 + array(
2176 + "name" => "recurrence_duration_end_date",
2177 + "display" => "none",
2178 + "title" => __("End Date", 'timed-content'),
2179 + "description" => __("Using the settings above, repeat this action until this date.", 'timed-content'),
2180 + "type" => "date",
2181 + "default" => strftime('%Y-%m-%d', $now_plus1y_dt->getTimeStamp()),
2182 + "scope" => array(TIMED_CONTENT_RULE_TYPE),
2183 + "capability" => "edit_posts"
2184 + ),
2185 + array(
2186 + "name" => "recurrence_duration_num_repeat",
2187 + "display" => "none",
2188 + "title" => __("Number of repetitions", 'timed-content'),
2189 + "description" => __("Using the settings above, repeat this action this many times.", 'timed-content'),
2190 + "type" => "number",
2191 + "default" => "1",
2192 + "min" => "1",
2193 + "scope" => array(TIMED_CONTENT_RULE_TYPE),
2194 + "capability" => "edit_posts"
2195 + )
2196 + );
1390 2197
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 );
2198 + $exceptions_dates_picker_on_select = <<<FUNC
2199 +onSelect: function (dateText, inst) {
2200 + jQuery("#timed_content_rule_exceptions_dates option[value='0']").remove();
2201 + jQuery("#timed_content_rule_exceptions_dates").append('<option value="' + dateText + '">' + dateText + '</option>');
2202 + jQuery(this).val("");
2203 + jQuery(this).trigger("change");
2204 + },
2205 +FUNC;
1425 2206
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' ) );
2207 + $this->rule_exceptions_custom_fields = array(
2208 + array(
2209 + "name" => "exceptions_dates_picker",
2210 + "display" => "block",
2211 + "title" => __("Add exception date:", 'timed-content'),
2212 + "description" => __("Select a date to add to the exception dates list.", 'timed-content'),
2213 + "type" => "date",
2214 + "default" => "",
2215 + "scope" => array(TIMED_CONTENT_RULE_TYPE),
2216 + "capability" => "edit_posts",
2217 + "custom_functions" => $exceptions_dates_picker_on_select
2218 + ),
2219 + array(
2220 + "name" => "exceptions_dates",
2221 + "display" => "block",
2222 + "title" => __("Exception dates list", 'timed-content'),
2223 + "description" => __("Dates that this Timed Content rule will not be active. Double-click on a date to remove it from the list.", 'timed-content'),
2224 + "type" => "menu",
2225 + "values" => $timed_content_rules_exceptions_dates_array,
2226 + "size" => "10",
2227 + "default" => array(),
2228 + "scope" => array(TIMED_CONTENT_RULE_TYPE),
2229 + "capability" => "edit_posts"
2230 + )
2231 + );
1429 2232
2233 + $scf = new customFieldsInterface("timed_content_rule_schedule",
2234 + __('Rule description/schedule', 'timed-content'),
2235 + "<div id=\"schedule_desc\" style=\"font-style: italic; overflow-y: auto;\">"
2236 + . (isset($_GET['post']) && (TIMED_CONTENT_RULE_TYPE === get_post_type($_GET['post'])) ? $this->getScheduleDescriptionById(intval($_GET['post'])) : $this->getScheduleDescriptionById(intval(0)))
2237 + . "</div>"
2238 + . "<div id=\"tcr-dialogHolder\" style=\"display:none;\"></div>"
2239 + . "<div style=\"padding-top: 10px;\"><input type=\"button\" class=\"button button-primary\" id=\"timed_content_rule_test\" value=\"" . __('Show projected dates/times',
2240 + 'timed-content') . "\" /></div>",
2241 + TIMED_CONTENT_RULE_POSTMETA_PREFIX,
2242 + array(TIMED_CONTENT_RULE_TYPE),
2243 + array(),
2244 + $this->jquery_ui_datetime_datepicker_i18n,
2245 + $this->jquery_ui_datetime_timepicker_i18n);
2246 + $ocf = new customFieldsInterface("timed_content_rule_initial_event",
2247 + __('Action/Initial Event', 'timed-content'),
2248 + __('Set the action to be taken and when it should first run.', 'timed-content'),
2249 + TIMED_CONTENT_RULE_POSTMETA_PREFIX,
2250 + array(TIMED_CONTENT_RULE_TYPE),
2251 + $this->rule_occurrence_custom_fields,
2252 + $this->jquery_ui_datetime_datepicker_i18n,
2253 + $this->jquery_ui_datetime_timepicker_i18n);
2254 + $pcf = new customFieldsInterface("timed_content_rule_recurrence",
2255 + __('Repeating Pattern', 'timed-content'),
2256 + __('Set how often the action should repeat.', 'timed-content'),
2257 + TIMED_CONTENT_RULE_POSTMETA_PREFIX,
2258 + array(TIMED_CONTENT_RULE_TYPE),
2259 + $this->rule_pattern_custom_fields,
2260 + $this->jquery_ui_datetime_datepicker_i18n,
2261 + $this->jquery_ui_datetime_timepicker_i18n);
2262 + $rcf = new customFieldsInterface("timed_content_rule_stop_condition",
2263 + __('Stopping Condition', 'timed-content'),
2264 + __('Set how long or how many times the action should occur.', 'timed-content'),
2265 + TIMED_CONTENT_RULE_POSTMETA_PREFIX,
2266 + array(TIMED_CONTENT_RULE_TYPE),
2267 + $this->rule_recurrence_custom_fields,
2268 + $this->jquery_ui_datetime_datepicker_i18n,
2269 + $this->jquery_ui_datetime_timepicker_i18n);
2270 + $ecf = new customFieldsInterface("timed_content_rule_exceptions",
2271 + __('Exceptions', 'timed-content'),
2272 + __('Set up any exceptions to this Timed Content Rule.', 'timed-content'),
2273 + TIMED_CONTENT_RULE_POSTMETA_PREFIX,
2274 + array(TIMED_CONTENT_RULE_TYPE),
2275 + $this->rule_exceptions_custom_fields,
2276 + $this->jquery_ui_datetime_datepicker_i18n,
2277 + $this->jquery_ui_datetime_timepicker_i18n);
2278 + }
2279 +
2280 + /**
2281 + * Strips indices from an array
2282 + *
2283 + * @param $ArrayToStrip
2284 + *
2285 + * @return array Processed array
2286 + */
2287 + function stripArrayIndices($ArrayToStrip)
2288 + {
2289 + foreach ($ArrayToStrip as $objArrayItem) {
2290 + $NewArray[] = $objArrayItem;
1430 2291 }
1431 2292
1432 - }
2293 + return $NewArray;
2294 + }
1433 2295
1434 -} //End Class timedContentPlugin
2296 + /**
2297 + * Convert dates and times to ISO format if needed
2298 + *
2299 + * @param array $args Existing date and time values
2300 + *
2301 + * @return array Converted date values in ISO format
2302 + */
2303 + function convertDateTimeParametersToISO($args)
2304 + {
2305 + $date_parsed = date_create_from_format('Y-m-d', $args['instance_start']['date']);
2306 + if ($date_parsed === false) {
2307 + $date_source = strtotime($this->datetimeToEnglish($args['instance_start']['date']));
2308 + $args['instance_start']['date'] = strftime('%Y-%m-%d', $date_source);
2309 + }
1435 2310
1436 -// Initialize plugin
1437 -if ( class_exists( "timedContentPlugin" ) ) {
1438 - $timedContentPluginInstance = new timedContentPlugin();
1439 -}
2311 + $date_parsed = date_create_from_format('Y-m-d', $args['instance_end']['date']);
2312 + if ($date_parsed === false) {
2313 + $date_source = strtotime($this->datetimeToEnglish($args['instance_end']['date']));
2314 + $args['instance_end']['date'] = strftime('%Y-%m-%d', $date_source);
2315 + }
1440 2316
1441 -// Actions and Filters
1442 -if ( isset( $timedContentPluginInstance ) ) {
1443 - global $wp_version;
2317 + $args['instance_start']['time'] = $this->convertTimeToISO($args['instance_start']['time']);
1444 2318
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');
2319 + $args['instance_end']['time'] = $this->convertTimeToISO($args['instance_end']['time']);
1451 2320
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 );
2321 + $date_parsed = date_create_from_format('Y-m-d', $args['end_date']);
2322 + if ($date_parsed === false) {
2323 + $date_source = strtotime($this->datetimeToEnglish($args['end_date']));
2324 + $args['end_date'] = strftime('%Y-%m-%d', $date_source);
2325 + }
2326 +
2327 + if(is_array($args['exceptions_dates'])) {
2328 + foreach ($args['exceptions_dates'] as $key => $value) {
2329 + $date_parsed = date_create_from_format('Y-m-d', $value);
2330 + if ($date_parsed === false) {
2331 + $date_source = strtotime($this->datetimeToEnglish($args['end_date']));
2332 + $args['exceptions_dates'][$key] = strftime('%Y-%m-%d', $date_source);
2333 + }
2334 + }
2335 + }
2336 +
2337 + return $args;
1471 2338 }
1472 2339
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 );
2340 + /**
2341 + * Convert time to ISO format if needed
2342 + *
2343 + * @param string $time Existing time value
2344 + *
2345 + * @return string Converted time values in ISO format
2346 + */
2347 + function convertTimeToISO($time) {
2348 + if (strpos($time, 'AM') !== false) {
2349 + $time_base = trim(substr($time, 0, strlen($time)-2));
2350 + $time_dt = date_create_from_format('G:i', $time_base);
2351 + if($time_dt !== false) {
2352 + $time = strftime('%H:%M', $time_dt->getTimestamp());
2353 + }
2354 + } else if (strpos($time, 'PM') !== false) {
2355 + $time_base = trim(substr($time, 0, strlen($time)-2));
2356 + $time_dt = date_create_from_format('G:i', $time_base);
2357 + if($time_dt !== false) {
2358 + $time = strftime('%H:%M', $time_dt->getTimestamp() + 43200);
2359 + }
2360 + }
2361 +
2362 + return $time;
2363 + }
1476 2364 }
2365 +
2366 +// Initialize plugin
2367 +$timedContentPluginInstance = new timedContentPlugin();
1477 2368 ?>