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