| 5 |
5 |
*/
|
| 6 |
6 |
/**
|
| 7 |
7 |
* This functions updates a post of event type, with data given in the $post_data
|
| 8 |
|
* and event data given in $event_data. Returns the post_id.
|
|
8 |
* and event data given in $event_data. Returns the post_id.
|
| 9 |
9 |
*
|
| 10 |
10 |
* Triggers {@see `eventorganiser_save_event`} passing event (post) ID
|
| 11 |
11 |
*
|
| ... | ... | |
| 17 |
17 |
* * (string) BYMONTHDAY=XX to repeat on XXth day of month, e.g. BYMONTHDAY=01 to repeat on the first of every month.
|
| 18 |
18 |
* * (string) BYDAY=ND. N= 1|2|3|4|-1 (first, second, third, fourth, last). D is day of week SU|MO|TU|WE|TH|FR|SA. E.g. BYDAY=2TU (repeat on second tuesday)
|
| 19 |
19 |
* * For weekly schedules,
|
| 20 |
|
* * (array) Days to repeat on: (SU,MO,TU,WE,TH,FR,SA). e.g. set to array('SU','TU') to repeat on Tuesdays & Sundays.
|
|
20 |
* * (array) Days to repeat on: (SU,MO,TU,WE,TH,FR,SA). e.g. set to array('SU','TU') to repeat on Tuesdays & Sundays.
|
| 21 |
21 |
* * Can be left blank to repeat weekly from the start date.
|
| 22 |
22 |
* * `frequency` => (int) positive integer, sets frequency of recurrence (every 2 days, or every 3 days etc)
|
| 23 |
23 |
* * `all_day` => 1 if its an all day event, 0 if not
|
| ... | ... | |
| 25 |
25 |
* * `end` => end date (of first occurrence) as a datetime object
|
| 26 |
26 |
* * `until` => **START** date of last occurrence (or upper-bound thereof) as a datetime object
|
| 27 |
27 |
* * `schedule_last` => Alias of until. Deprecated 2.13.0, use until.
|
| 28 |
|
* * `number_occurrences` => Instead of specifying `until` you can specify the number of occurrence a recurring event should have.
|
|
28 |
* * `number_occurrences` => Instead of specifying `until` you can specify the number of occurrence a recurring event should have.
|
| 29 |
29 |
* This is only used if `until` is not, and for daily, weekly, monthly or yearly recurring events.
|
| 30 |
30 |
* * `include` => array of datetime objects to include in the schedule
|
| 31 |
31 |
* * `exclude` => array of datetime objects to exclude in the schedule
|
| ... | ... | |
| 41 |
41 |
function eo_update_event( $post_id, $event_data = array(), $post_data = array() ){
|
| 42 |
42 |
|
| 43 |
43 |
$post_id = (int) $post_id;
|
| 44 |
|
|
|
44 |
|
| 45 |
45 |
$input = array_merge( $post_data, $event_data );
|
| 46 |
|
|
|
46 |
|
| 47 |
47 |
//Backwards compat:
|
| 48 |
48 |
if( !empty( $input['venue'] ) ){
|
| 49 |
49 |
$input['tax_input']['event-venue'] = $input['venue'];
|
| ... | ... | |
| 51 |
51 |
if( !empty( $input['category'] ) ){
|
| 52 |
52 |
$input['tax_input']['event-category'] = $input['category'];
|
| 53 |
53 |
}
|
| 54 |
|
|
| 55 |
|
$event_keys = array_flip( array(
|
| 56 |
|
'start', 'end', 'schedule', 'schedule_meta', 'frequency',
|
|
54 |
|
|
55 |
$event_keys = array_flip( array(
|
|
56 |
'start', 'end', 'schedule', 'schedule_meta', 'frequency',
|
| 57 |
57 |
'all_day', 'until', 'schedule_last', 'include', 'exclude', 'occurs_by', 'number_occurrences',
|
| 58 |
58 |
) );
|
| 59 |
|
|
|
59 |
|
| 60 |
60 |
$post_keys = array_flip( array(
|
| 61 |
|
'post_title','post_content','post_status', 'post_type','post_author','ping_status','post_parent','menu_order',
|
|
61 |
'post_title','post_content','post_status', 'post_type','post_author','ping_status','post_parent','menu_order',
|
| 62 |
62 |
'to_ping', 'pinged', 'post_password', 'guid', 'post_content_filtered', 'post_excerpt', 'import_id', 'tax_input',
|
| 63 |
63 |
'comment_status', 'context', 'post_date', 'post_date_gmt',
|
| 64 |
64 |
) );
|
| 65 |
|
|
|
65 |
|
| 66 |
66 |
$event_data = array_intersect_key( $input, $event_keys );
|
| 67 |
67 |
$post_data = array_intersect_key( $input, $post_keys ) + $post_data;
|
| 68 |
|
|
|
68 |
|
| 69 |
69 |
if( empty( $post_id ) ){
|
| 70 |
70 |
return new WP_Error( 'eo_error', 'Empty post ID.' );
|
| 71 |
71 |
}
|
| 72 |
|
|
|
72 |
|
| 73 |
73 |
/**
|
| 74 |
74 |
*@ignore
|
| 75 |
75 |
*/
|
| ... | ... | |
| 80 |
80 |
$post_data = apply_filters( 'eventorganiser_update_event_post_data', $post_data, $post_id, $post_data, $event_data );
|
| 81 |
81 |
|
| 82 |
82 |
if( !empty($post_data) ){
|
| 83 |
|
$post_data['ID'] = $post_id;
|
|
83 |
$post_data['ID'] = $post_id;
|
| 84 |
84 |
wp_update_post( $post_data );
|
| 85 |
85 |
}
|
| 86 |
86 |
|
| ... | ... | |
| 94 |
94 |
}
|
| 95 |
95 |
unset( $event_data['schedule_last'] );
|
| 96 |
96 |
}
|
| 97 |
|
|
|
97 |
|
| 98 |
98 |
//Get previous data, parse with data to be updated
|
| 99 |
99 |
$prev = eo_get_event_schedule( $post_id );
|
| 100 |
100 |
$event_data = wp_parse_args( $event_data, $prev );
|
| ... | ... | |
| 103 |
103 |
if( ( empty($event_data['schedule']) || 'once' == $event_data['schedule'] ) && !empty($event_data['include']) ){
|
| 104 |
104 |
$event_data['schedule'] = 'custom';
|
| 105 |
105 |
}
|
| 106 |
|
|
|
106 |
|
| 107 |
107 |
$event_data = _eventorganiser_generate_occurrences( $event_data );
|
| 108 |
108 |
|
| 109 |
109 |
if( is_wp_error( $event_data ) ){
|
| ... | ... | |
| 145 |
145 |
* * (string) BYMONTHDAY=XX to repeat on XXth day of month, e.g. BYMONTHDAY=01 to repeat on the first of every month.
|
| 146 |
146 |
* * (string) BYDAY=ND. N= 1|2|3|4|-1 (first, second, third, fourth, last). D is day of week SU|MO|TU|WE|TH|FR|SA. E.g. BYDAY=2TU (repeat on second tuesday)
|
| 147 |
147 |
* * For weekly schedules,
|
| 148 |
|
* * (array) Days to repeat on: (SU,MO,TU,WE,TH,FR,SA). e.g. set to array('SU','TU') to repeat on Tuesdays & Sundays.
|
|
148 |
* * (array) Days to repeat on: (SU,MO,TU,WE,TH,FR,SA). e.g. set to array('SU','TU') to repeat on Tuesdays & Sundays.
|
| 149 |
149 |
* * Can be left blank to repeat weekly from the start date.
|
| 150 |
150 |
* * `frequency` => (int) positive integer, sets frequency of recurrence (every 2 days, or every 3 days etc)
|
| 151 |
151 |
* * `all_day` => 1 if its an all day event, 0 if not
|
| ... | ... | |
| 153 |
153 |
* * `end` => end date (of first occurrence) as a datetime object
|
| 154 |
154 |
* * `until` => **START** date of last occurrence (or upper-bound thereof) as a datetime object
|
| 155 |
155 |
* * `schedule_last` => Alias of until. Deprecated 2.13.0, use until.
|
| 156 |
|
* * `number_occurrences` => Instead of specifying `until` you can specify the number of occurrence a recurring event should have.
|
|
156 |
* * `number_occurrences` => Instead of specifying `until` you can specify the number of occurrence a recurring event should have.
|
| 157 |
157 |
* This is only used if `until` is not, and for daily, weekly, monthly or yearly recurring events.
|
| 158 |
158 |
* * `include` => array of datetime objects to include in the schedule
|
| 159 |
159 |
* * `exclude` => array of datetime objects to exclude in the schedule
|
| ... | ... | |
| 176 |
176 |
*
|
| 177 |
177 |
* $e = eo_insert_event($post_data,$event_data);
|
| 178 |
178 |
* </code>
|
| 179 |
|
*
|
|
179 |
*
|
| 180 |
180 |
* ### Tutorial
|
| 181 |
181 |
* See this <a href="http://www.stephenharris.info/2012/front-end-event-posting/">tutorial</a> or <a href="https://gist.github.com/3867194">this Gist</a> on front-end event posting.
|
| 182 |
182 |
*
|
| 183 |
183 |
* @since 1.5
|
| 184 |
184 |
* @link http://www.stephenharris.info/2012/front-end-event-posting/ Tutorial on front-end event posting
|
| 185 |
|
* @uses wp_insert_post()
|
|
185 |
* @uses wp_insert_post()
|
| 186 |
186 |
*
|
| 187 |
187 |
* @param array $post_data array of data to be used by wp_insert_post.
|
| 188 |
188 |
* @param array $event_data array of event data
|
| ... | ... | |
| 192 |
192 |
global $wpdb;
|
| 193 |
193 |
|
| 194 |
194 |
$input = array_merge( $post_data, $event_data );
|
| 195 |
|
|
|
195 |
|
| 196 |
196 |
//Backwards compat:
|
| 197 |
197 |
if( !empty( $input['venue'] ) ){
|
| 198 |
198 |
$input['tax_input']['event-venue'] = $input['venue'];
|
| ... | ... | |
| 200 |
200 |
if( !empty( $input['category'] ) ){
|
| 201 |
201 |
$input['tax_input']['event-category'] = $input['category'];
|
| 202 |
202 |
}
|
| 203 |
|
|
|
203 |
|
| 204 |
204 |
$event_keys = array_flip( array(
|
| 205 |
|
'start', 'end', 'schedule', 'schedule_meta', 'frequency', 'all_day',
|
| 206 |
|
'until', 'schedule_last', 'include', 'exclude', 'occurs_by', 'number_occurrences',
|
|
205 |
'start', 'end', 'schedule', 'schedule_meta', 'frequency', 'all_day',
|
|
206 |
'until', 'schedule_last', 'include', 'exclude', 'occurs_by', 'number_occurrences',
|
| 207 |
207 |
) );
|
| 208 |
|
|
|
208 |
|
| 209 |
209 |
$post_keys = array_flip( array(
|
| 210 |
|
'post_title','post_content','post_status', 'post_type','post_author','ping_status','post_parent','menu_order',
|
|
210 |
'post_title','post_content','post_status', 'post_type','post_author','ping_status','post_parent','menu_order',
|
| 211 |
211 |
'to_ping', 'pinged', 'post_password', 'guid', 'post_content_filtered', 'post_excerpt', 'import_id', 'tax_input',
|
| 212 |
212 |
'comment_status', 'context', 'post_date', 'post_date_gmt',
|
| 213 |
213 |
) );
|
| 214 |
|
|
|
214 |
|
| 215 |
215 |
$event_data = array_intersect_key( $input, $event_keys ) + $event_data;
|
| 216 |
216 |
$post_data = array_intersect_key( $input, $post_keys );
|
| 217 |
|
|
|
217 |
|
| 218 |
218 |
//If schedule is 'once' and dates are included - set to 'custom':
|
| 219 |
219 |
if( ( empty($event_data['schedule']) || 'once' == $event_data['schedule'] ) && !empty($event_data['include']) ){
|
| 220 |
220 |
$event_data['schedule'] = 'custom';
|
| 221 |
221 |
}
|
| 222 |
|
|
|
222 |
|
| 223 |
223 |
if( !empty( $event_data['schedule_last'] ) ){
|
| 224 |
224 |
if( !isset( $event_data['until'] ) ){
|
| 225 |
225 |
$event_data['until'] = clone $event_data['schedule_last'];
|
| ... | ... | |
| 228 |
228 |
}
|
| 229 |
229 |
|
| 230 |
230 |
$event_data = _eventorganiser_generate_occurrences( $event_data );
|
| 231 |
|
|
|
231 |
|
| 232 |
232 |
if( is_wp_error( $event_data ) ){
|
| 233 |
233 |
return $event_data;
|
| 234 |
234 |
}
|
| ... | ... | |
| 237 |
237 |
*@ignore
|
| 238 |
238 |
*/
|
| 239 |
239 |
$event_data = apply_filters( 'eventorganiser_insert_event_event_data', $event_data, $post_data, $event_data );
|
| 240 |
|
|
|
240 |
|
| 241 |
241 |
/**
|
| 242 |
242 |
*@ignore
|
| 243 |
243 |
*/
|
| 244 |
244 |
$post_data = apply_filters( 'eventorganiser_insert_event_post_data', $post_data, $post_data, $event_data );
|
| 245 |
|
|
|
245 |
|
| 246 |
246 |
//Finally we create event (first create the post in WP)
|
| 247 |
|
$post_input = array_merge(array('post_title'=>'untitled event'), $post_data, array('post_type'=>'event'));
|
|
247 |
$post_input = array_merge(array('post_title'=>'untitled event'), $post_data, array('post_type'=>'event'));
|
| 248 |
248 |
$post_id = wp_insert_post($post_input, true);
|
| 249 |
249 |
|
| 250 |
|
//Did the event insert correctly?
|
| 251 |
|
if ( is_wp_error( $post_id) )
|
|
250 |
//Did the event insert correctly?
|
|
251 |
if ( is_wp_error( $post_id) )
|
| 252 |
252 |
return $post_id;
|
| 253 |
253 |
|
| 254 |
254 |
_eventorganiser_insert_occurrences($post_id, $event_data);
|
| 255 |
|
|
|
255 |
|
| 256 |
256 |
//Action used to break cache & trigger Pro actions (& by other plug-ins?)
|
| 257 |
257 |
/**
|
| 258 |
258 |
* Triggered after an event has been updated.
|
| 259 |
|
*
|
| 260 |
|
* @param int $post_id The ID of the event
|
|
259 |
*
|
|
260 |
* @param int $post_id The ID of the event
|
| 261 |
261 |
*/
|
| 262 |
262 |
do_action( 'eventorganiser_save_event', $post_id );
|
| 263 |
263 |
|
| ... | ... | |
| 287 |
287 |
*
|
| 288 |
288 |
* This function does not update any of the event schedule details.
|
| 289 |
289 |
* **Don't call this unless you know what you're doing**.
|
| 290 |
|
*
|
|
290 |
*
|
| 291 |
291 |
* @since 1.5
|
| 292 |
292 |
* @access private
|
| 293 |
293 |
* @param int $post_id the event's (post) ID to be deleted
|
| 294 |
294 |
* @param int|array $occurrence_ids Occurrence ID (or array of IDs) for specificaly occurrences to delete. If empty/false, deletes all.
|
| 295 |
|
*
|
|
295 |
*
|
| 296 |
296 |
*/
|
| 297 |
297 |
function eo_delete_event_occurrences( $event_id, $occurrence_ids = false ){
|
| 298 |
298 |
global $wpdb;
|
| 299 |
299 |
//TODO use this in break/remove occurrence
|
| 300 |
|
|
|
300 |
|
| 301 |
301 |
//Let's just ensure empty is cast as false
|
| 302 |
302 |
$occurrence_ids = ( empty( $occurrence_ids ) ? false : $occurrence_ids );
|
| 303 |
|
|
|
303 |
|
| 304 |
304 |
if( $occurrence_ids !== false ){
|
| 305 |
305 |
$occurrence_ids = (array) $occurrence_ids;
|
| 306 |
306 |
$occurrence_ids = array_map( 'absint', $occurrence_ids );
|
| 307 |
307 |
$occurrence_ids_in = implode( ', ', $occurrence_ids );
|
| 308 |
|
|
|
308 |
|
| 309 |
309 |
$raw_sql = "DELETE FROM $wpdb->eo_events WHERE post_id=%d AND event_id IN( $occurrence_ids_in )";
|
| 310 |
310 |
|
| 311 |
311 |
}else{
|
| 312 |
312 |
$raw_sql = "DELETE FROM $wpdb->eo_events WHERE post_id=%d";
|
| 313 |
313 |
}
|
| 314 |
|
|
|
314 |
|
| 315 |
315 |
/**
|
| 316 |
316 |
* @ignore
|
| 317 |
317 |
*/
|
| 318 |
318 |
do_action( 'eventorganiser_delete_event', $event_id, $occurrence_ids ); //Deprecated - do not use!
|
| 319 |
|
|
|
319 |
|
| 320 |
320 |
/**
|
| 321 |
321 |
* Triggers just before the specified occurrences for the event are deleted.
|
| 322 |
|
*
|
|
322 |
*
|
| 323 |
323 |
* @param int $event_id The (post) ID of the event of which we're deleting occurrences.
|
| 324 |
324 |
* @param array|false $occurrence_ids An array of occurrences to be delete. If `false`, all occurrences are to be removed.
|
| 325 |
325 |
*/
|
| 326 |
326 |
do_action( 'eventorganiser_delete_event_occurrences', $event_id, $occurrence_ids );
|
| 327 |
|
|
|
327 |
|
| 328 |
328 |
$del = $wpdb->get_results( $wpdb->prepare( $raw_sql, $event_id ) );
|
| 329 |
|
|
|
329 |
|
| 330 |
330 |
}
|
| 331 |
331 |
add_action( 'delete_post', 'eo_delete_event_occurrences', 10 );
|
| 332 |
332 |
|
| ... | ... | |
| 340 |
340 |
* @return int $post_id
|
| 341 |
341 |
*/
|
| 342 |
342 |
function _eventorganiser_insert_occurrences( $post_id, $event_data ){
|
| 343 |
|
|
|
343 |
|
| 344 |
344 |
global $wpdb;
|
| 345 |
345 |
extract( $event_data );
|
| 346 |
346 |
$tz = eo_get_blog_timezone();
|
| ... | ... | |
| 349 |
349 |
//Also see https://github.com/stephenharris/Event-Organiser/issues/205
|
| 350 |
350 |
//And https://github.com/stephenharris/Event-Organiser/issues/224
|
| 351 |
351 |
$duration_str = eo_date_interval( $start, $end, '+%y year +%m month +%d days +%h hours +%i minutes +%s seconds' );
|
| 352 |
|
|
|
352 |
|
| 353 |
353 |
$event_data['duration_str'] = $duration_str;
|
| 354 |
354 |
|
| 355 |
355 |
$schedule_last_end = clone $schedule_last;
|
| ... | ... | |
| 358 |
358 |
//Get dates to be deleted / added
|
| 359 |
359 |
$current_occurrences = eo_get_the_occurrences( $post_id );
|
| 360 |
360 |
$current_occurrences = $current_occurrences ? $current_occurrences : array();
|
| 361 |
|
|
|
361 |
|
| 362 |
362 |
$delete = array_udiff( $current_occurrences, $occurrences, '_eventorganiser_compare_dates' );
|
| 363 |
363 |
$insert = array_udiff( $occurrences, $current_occurrences, '_eventorganiser_compare_dates' );
|
| 364 |
364 |
$update = array_uintersect( $occurrences, $current_occurrences, '_eventorganiser_compare_dates' );
|
| 365 |
365 |
$update_2 = array_uintersect( $current_occurrences, $update, '_eventorganiser_compare_dates' );
|
| 366 |
366 |
$keys = array_keys( $update_2 );
|
| 367 |
|
|
|
367 |
|
| 368 |
368 |
if( $delete ){
|
| 369 |
369 |
$delete_occurrence_ids = array_keys( $delete );
|
| 370 |
370 |
eo_delete_event_occurrences( $post_id, $delete_occurrence_ids );
|
| 371 |
371 |
}
|
| 372 |
|
|
|
372 |
|
| 373 |
373 |
$occurrence_cache = array();
|
| 374 |
374 |
$occurrence_array = array();
|
| 375 |
|
|
|
375 |
|
| 376 |
376 |
if( $update ){
|
| 377 |
377 |
$update = array_combine( $keys, $update );
|
| 378 |
|
|
|
378 |
|
| 379 |
379 |
foreach( $update as $occurrence_id => $occurrence ){
|
| 380 |
380 |
|
| 381 |
381 |
$occurrence_end = clone $occurrence;
|
| 382 |
382 |
$occurrence_end->modify($duration_str);
|
| 383 |
|
|
|
383 |
|
| 384 |
384 |
$occurrence_input = array(
|
| 385 |
385 |
'StartDate' => $occurrence->format('Y-m-d'),
|
| 386 |
386 |
'StartTime' => $occurrence->format('H:i:s'),
|
| ... | ... | |
| 389 |
389 |
);
|
| 390 |
390 |
|
| 391 |
391 |
$wpdb->update(
|
| 392 |
|
$wpdb->eo_events,
|
| 393 |
|
$occurrence_input,
|
|
392 |
$wpdb->eo_events,
|
|
393 |
$occurrence_input,
|
| 394 |
394 |
array( 'event_id' => $occurrence_id )
|
| 395 |
395 |
);
|
| 396 |
396 |
|
| ... | ... | |
| 402 |
402 |
);
|
| 403 |
403 |
}
|
| 404 |
404 |
}
|
| 405 |
|
|
|
405 |
|
| 406 |
406 |
if( $insert ){
|
| 407 |
407 |
foreach( $insert as $counter => $occurrence ):
|
| 408 |
408 |
$occurrence_end = clone $occurrence;
|
| ... | ... | |
| 418 |
418 |
);
|
| 419 |
419 |
|
| 420 |
420 |
$wpdb->insert( $wpdb->eo_events, $occurrence_input );
|
| 421 |
|
|
|
421 |
|
| 422 |
422 |
$occurrence_array[$wpdb->insert_id] = $occurrence->format('Y-m-d H:i:s');
|
| 423 |
423 |
|
| 424 |
424 |
//Add to occurrence cache: TODO use post meta
|
| ... | ... | |
| 429 |
429 |
|
| 430 |
430 |
endforeach;
|
| 431 |
431 |
}
|
| 432 |
|
|
|
432 |
|
| 433 |
433 |
//Set occurrence cache
|
| 434 |
434 |
wp_cache_set( 'eventorganiser_occurrences_'.$post_id, $occurrence_cache );
|
| 435 |
435 |
wp_cache_set( 'eventorganiser_all_occurrences_'.$post_id, $occurrence_cache );
|
| 436 |
436 |
|
| 437 |
437 |
unset( $event_data['occurrences'] );
|
| 438 |
438 |
//$event_data['_occurrences'] = $occurrence_array;
|
| 439 |
|
|
|
439 |
|
| 440 |
440 |
if( !empty($include) ){
|
| 441 |
441 |
$event_data['include'] = array_map('eo_format_datetime', $include, array_fill(0, count($include), 'Y-m-d H:i:s') );
|
| 442 |
442 |
}
|
| 443 |
|
|
|
443 |
|
| 444 |
444 |
if( !empty($exclude) ){
|
| 445 |
445 |
$event_data['exclude'] = array_map('eo_format_datetime', $exclude, array_fill(0, count($exclude), 'Y-m-d H:i:s') );
|
| 446 |
446 |
}
|
| ... | ... | |
| 450 |
450 |
unset( $event_data['schedule_start'] );
|
| 451 |
451 |
unset( $event_data['schedule_last'] );
|
| 452 |
452 |
unset( $event_data['until'] );
|
| 453 |
|
|
|
453 |
|
| 454 |
454 |
update_post_meta( $post_id, '_eventorganiser_event_schedule', $event_data );
|
| 455 |
455 |
update_post_meta( $post_id, '_eventorganiser_schedule_start_start', $start->format('Y-m-d H:i:s') );
|
| 456 |
456 |
update_post_meta( $post_id, '_eventorganiser_schedule_start_finish', $end->format('Y-m-d H:i:s') );
|
| 457 |
457 |
update_post_meta( $post_id, '_eventorganiser_schedule_until', $until->format('Y-m-d H:i:s') );
|
| 458 |
458 |
update_post_meta( $post_id, '_eventorganiser_schedule_last_start', $schedule_last->format('Y-m-d H:i:s') );
|
| 459 |
459 |
update_post_meta( $post_id, '_eventorganiser_schedule_last_finish', $schedule_last_end->format('Y-m-d H:i:s') );
|
| 460 |
|
|
|
460 |
|
| 461 |
461 |
return $post_id;
|
| 462 |
462 |
}
|
| 463 |
463 |
|
| ... | ... | |
| 474 |
474 |
* * (string) BYMONTHDAY=XX to repeat on XXth day of month, e.g. BYMONTHDAY=01 to repeat on the first of every month.
|
| 475 |
475 |
* * (string) BYDAY=ND. N= 1|2|3|4|-1 (first, second, third, fourth, last). D is day of week SU|MO|TU|WE|TH|FR|SA. E.g. BYDAY=2TU (repeat on second tuesday)
|
| 476 |
476 |
* * For weekly schedules,
|
| 477 |
|
* * (array) Days to repeat on: (SU,MO,TU,WE,TH,FR,SA). e.g. set to array('SU','TU') to repeat on Tuesdays & Sundays.
|
|
477 |
* * (array) Days to repeat on: (SU,MO,TU,WE,TH,FR,SA). e.g. set to array('SU','TU') to repeat on Tuesdays & Sundays.
|
| 478 |
478 |
* * `occurs_by` - For use with monthly schedules: how the event recurs: BYDAY or BYMONTHDAY
|
| 479 |
479 |
* * `frequency` => (int) positive integer, sets frequency of recurrence (every 2 days, or every 3 days etc)
|
| 480 |
480 |
* * `all_day` => 1 if its an all day event, 0 if not
|
| 481 |
481 |
* * `start` => start date (of first occurrence) as a datetime object
|
| 482 |
482 |
* * `end` => end date (of first occurrence) as a datetime object
|
| 483 |
483 |
* * `until` => For recurring events, the date they repeat until. Note that this may not be equal to `schedule_last` if
|
| 484 |
|
* dates are included/excluded.
|
|
484 |
* dates are included/excluded.
|
| 485 |
485 |
* * `schedule_last` => **START** date of last occurrence as a datetime object
|
| 486 |
486 |
* * `include` => array of datetime objects to include in the schedule
|
| 487 |
487 |
* * `exclude` => array of datetime objects to exclude in the schedule
|
| ... | ... | |
| 493 |
493 |
|
| 494 |
494 |
$post_id = (int) ( empty($post_id) ? get_the_ID() : $post_id);
|
| 495 |
495 |
|
| 496 |
|
if( empty( $post_id ) ){
|
|
496 |
if( empty( $post_id ) ){
|
| 497 |
497 |
return false;
|
| 498 |
498 |
}
|
| 499 |
499 |
|
| ... | ... | |
| 519 |
519 |
} else {
|
| 520 |
520 |
// No start time, so set a default start time to next half-hour
|
| 521 |
521 |
$now = new DateTime( 'now', $tz );
|
| 522 |
|
|
|
522 |
|
| 523 |
523 |
$minute = $now->format( 'i' ) > 30 ? 0 : 30;
|
| 524 |
|
|
|
524 |
|
| 525 |
525 |
$now->setTime( $now->format( 'G' ), $minute );
|
| 526 |
|
|
|
526 |
|
| 527 |
527 |
if( 0 === $minute ){
|
| 528 |
528 |
$now->modify( '+1 hour' );
|
| 529 |
529 |
}
|
| 530 |
|
|
| 531 |
|
$event_details['start'] = $now;
|
|
530 |
|
|
531 |
$event_details['start'] = $now;
|
| 532 |
532 |
}
|
| 533 |
533 |
|
| 534 |
534 |
// Get end time
|
| ... | ... | |
| 551 |
551 |
$event_details['until'] = clone $event_details['schedule_last'];
|
| 552 |
552 |
update_post_meta( $post_id, '_eventorganiser_schedule_until', $event_details['until']->format( 'Y-m-d H:i:s' ) );
|
| 553 |
553 |
}
|
| 554 |
|
|
|
554 |
|
| 555 |
555 |
if ( ! empty( $event_details['include'] ) ) {
|
| 556 |
556 |
$event_details['include'] = array_map( 'eventorganiser_date_create', $event_details['include'] );
|
| 557 |
557 |
}
|
| ... | ... | |
| 570 |
570 |
|
| 571 |
571 |
/**
|
| 572 |
572 |
* Filters the schedule metadata for an event (as returned by `eo_get_event_schedule()`.
|
| 573 |
|
*
|
|
573 |
*
|
| 574 |
574 |
* See documentation on `eo_get_event_schedule()` for more details.
|
| 575 |
575 |
*
|
| 576 |
576 |
* @param array $event_details Details of the event's dates and recurrence pattern
|
| ... | ... | |
| 593 |
593 |
|
| 594 |
594 |
$event_defaults = array(
|
| 595 |
595 |
'start' => '', 'end' => '', 'all_day' => 0,
|
| 596 |
|
'schedule' => 'once', 'schedule_meta' => '', 'frequency' => 1, 'schedule_last' => '',
|
|
596 |
'schedule' => 'once', 'schedule_meta' => '', 'frequency' => 1, 'schedule_last' => '',
|
| 597 |
597 |
'until' => '', 'number_occurrences' => 0, 'exclude' => array(), 'include' => array(),
|
| 598 |
598 |
);
|
| 599 |
599 |
|
| 600 |
600 |
extract( wp_parse_args( $event_data, $event_defaults ) );
|
| 601 |
|
|
| 602 |
|
$occurrences =array(); //occurrences array
|
|
601 |
|
|
602 |
$occurrences =array(); //occurrences array
|
| 603 |
603 |
|
| 604 |
604 |
$exclude = array_filter( (array) $exclude );
|
| 605 |
605 |
$include = array_filter( (array) $include );
|
| 606 |
|
|
|
606 |
|
| 607 |
607 |
$exclude = array_udiff($exclude, $include, '_eventorganiser_compare_datetime');
|
| 608 |
608 |
$include = array_udiff($include, $exclude, '_eventorganiser_compare_datetime');
|
| 609 |
|
|
|
609 |
|
| 610 |
610 |
//White list schedule
|
| 611 |
611 |
if( !in_array($schedule, array('once','daily','weekly','monthly','yearly','custom')) )
|
| 612 |
612 |
return new WP_Error('eo_error',__('Schedule not recognised.','eventorganiser'));
|
| 613 |
|
|
|
613 |
|
| 614 |
614 |
//Ensure event frequency is a positive integer. Else set to 1.
|
| 615 |
615 |
$frequency = max(absint($frequency),1);
|
| 616 |
616 |
$all_day = (int) $all_day;
|
| 617 |
617 |
$number_occurrences = absint( $number_occurrences );
|
| 618 |
|
|
|
618 |
|
| 619 |
619 |
//Check dates are supplied and are valid
|
| 620 |
620 |
if( !($start instanceof DateTime) )
|
| 621 |
621 |
return new WP_Error('eo_error',__('Start date not provided.','eventorganiser'));
|
| 622 |
622 |
|
| 623 |
623 |
if( !($end instanceof DateTime) )
|
| 624 |
624 |
$end = clone $start;
|
| 625 |
|
|
|
625 |
|
| 626 |
626 |
//If use 'number_occurrences' to limit recurring event, set dummy 'schedule_last' date.
|
| 627 |
627 |
if( !($until instanceof DateTime) && $number_occurrences && in_array( $schedule, array( 'daily','weekly','monthly','yearly' ) ) ){
|
| 628 |
628 |
//Set dummy "last occurrance" date.
|
| ... | ... | |
| 637 |
637 |
//Check dates are in chronological order
|
| 638 |
638 |
if($end < $start)
|
| 639 |
639 |
return new WP_Error('eo_error',__('Start date occurs after end date.','eventorganiser'));
|
| 640 |
|
|
|
640 |
|
| 641 |
641 |
if($until < $start)
|
| 642 |
642 |
return new WP_Error('eo_error',__('Schedule end date is before is before the start date.','eventorganiser'));
|
| 643 |
643 |
|
| ... | ... | |
| 652 |
652 |
$start_days =array();
|
| 653 |
653 |
$workaround='';
|
| 654 |
654 |
$icaldays = array('SU','MO','TU','WE','TH','FR','SA');
|
| 655 |
|
$weekdays = array('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday');
|
|
655 |
$weekdays = array('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday');
|
| 656 |
656 |
$ical2day = array('SU'=>'Sunday','MO'=>'Monday','TU'=>'Tuesday','WE'=>'Wednesday','TH'=>'Thursday','FR'=>'Friday','SA'=>'Saturday');
|
| 657 |
657 |
|
| 658 |
658 |
//Set up schedule
|
| ... | ... | |
| 670 |
670 |
case 'daily':
|
| 671 |
671 |
$interval = "+".$frequency."day";
|
| 672 |
672 |
$start_days[] = clone $start;
|
| 673 |
|
break;
|
|
673 |
break;
|
| 674 |
674 |
|
| 675 |
675 |
case 'weekly':
|
| 676 |
676 |
$schedule_meta = ( $schedule_meta ? array_filter($schedule_meta) : array() );
|
| ... | ... | |
| 694 |
694 |
$rule =$rule_value[0];
|
| 695 |
695 |
$values = !empty( $rule_value[1] ) ? explode(',',$rule_value[1]) : array();//Should only be one value, but may support more in future
|
| 696 |
696 |
$values = array_filter( $values );
|
| 697 |
|
|
|
697 |
|
| 698 |
698 |
if( $rule=='BYMONTHDAY' ):
|
| 699 |
699 |
$date = (int) $start_days[0]->format('d');
|
| 700 |
700 |
$interval = "+".$frequency."month";
|
| 701 |
|
|
|
701 |
|
| 702 |
702 |
if($date >= 29)
|
| 703 |
703 |
$workaround = 'short months'; //This case deals with 29/30/31 of month
|
| 704 |
704 |
|
| ... | ... | |
| 727 |
727 |
$day = $weekdays[$day_num];//Full day name from day_num (Sunday -Monday)
|
| 728 |
728 |
$schedule_meta = 'BYDAY='.$n.$ical_day; //E.g. BYDAY=2MO
|
| 729 |
729 |
$interval = $ordinal[$n].' '.$day.' of +'.$frequency.' month'; //E.g. second monday of +1 month
|
| 730 |
|
|
|
730 |
|
| 731 |
731 |
//Work around for PHP <5.3
|
| 732 |
732 |
if(!function_exists('date_diff')){
|
| 733 |
733 |
$workaround = 'php5.2';
|
| 734 |
734 |
}
|
| 735 |
735 |
endif;
|
| 736 |
736 |
break;
|
| 737 |
|
|
|
737 |
|
| 738 |
738 |
case 'yearly':
|
| 739 |
739 |
$start_days[] = clone $start;
|
| 740 |
740 |
if( '29-02' == $start_days[0]->format('d-m') )
|
| 741 |
741 |
$workaround = 'leap year';
|
| 742 |
|
|
|
742 |
|
| 743 |
743 |
$interval = "+".$frequency."year";
|
| 744 |
744 |
break;
|
| 745 |
745 |
endswitch; //End $schedule switch
|
| ... | ... | |
| 749 |
749 |
foreach($start_days as $index => $start_day):
|
| 750 |
750 |
$current = clone $start_day;
|
| 751 |
751 |
$occurrence_n = 0;
|
| 752 |
|
|
|
752 |
|
| 753 |
753 |
switch($workaround):
|
| 754 |
754 |
//Not really a workaround. Just add the occurrence and finish.
|
| 755 |
755 |
case 'once':
|
| 756 |
756 |
$current->setTime($H,$i );
|
| 757 |
757 |
$occurrences[] = clone $current;
|
| 758 |
758 |
break;
|
| 759 |
|
|
|
759 |
|
| 760 |
760 |
//Loops for monthly events that require php5.3 functionality
|
| 761 |
761 |
case 'php5.2':
|
| 762 |
762 |
while( $current <= $until || $occurrence_n < $number_occurrences ):
|
| 763 |
763 |
$current->setTime($H,$i );
|
| 764 |
|
$occurrences[] = clone $current;
|
|
764 |
$occurrences[] = clone $current;
|
| 765 |
765 |
$current = _eventorganiser_php52_modify($current,$interval);
|
| 766 |
766 |
$occurrence_n++;
|
| 767 |
|
endwhile;
|
|
767 |
endwhile;
|
| 768 |
768 |
break;
|
| 769 |
769 |
|
| 770 |
770 |
//Loops for monthly events on the 29th/30th/31st
|
| 771 |
771 |
case 'short months':
|
| 772 |
772 |
$day_int =intval($start_day->format('d'));
|
| 773 |
|
|
|
773 |
|
| 774 |
774 |
//Set the first month
|
| 775 |
775 |
$current_month= clone $start_day;
|
| 776 |
776 |
$current_month = date_create($current_month->format('Y-m-1'));
|
| 777 |
|
|
|
777 |
|
| 778 |
778 |
while( $current_month <= $until || $occurrence_n < $number_occurrences ):
|
| 779 |
|
$month_int = intval($current_month->format('m'));
|
| 780 |
|
$year_int = intval($current_month->format('Y'));
|
|
779 |
$month_int = intval($current_month->format('m'));
|
|
780 |
$year_int = intval($current_month->format('Y'));
|
| 781 |
781 |
|
| 782 |
782 |
if( checkdate($month_int , $day_int , $year_int) ){
|
| 783 |
783 |
$current = new DateTime($day_int.'-'.$month_int.'-'.$year_int, $timezone);
|
| ... | ... | |
| 786 |
786 |
$occurrence_n++;
|
| 787 |
787 |
}
|
| 788 |
788 |
$current_month->modify($interval);
|
| 789 |
|
endwhile;
|
|
789 |
endwhile;
|
| 790 |
790 |
break;
|
| 791 |
791 |
|
| 792 |
792 |
//To be used for yearly events occuring on Feb 29
|
| ... | ... | |
| 794 |
794 |
$current_year = clone $current;
|
| 795 |
795 |
$current_year->modify('-1 day');
|
| 796 |
796 |
|
| 797 |
|
while( $current_year <= $until || $occurrence_n < $number_occurrences ):
|
|
797 |
while( $current_year <= $until || $occurrence_n < $number_occurrences ):
|
| 798 |
798 |
$is_leap_year = (int) $current_year->format('L');
|
| 799 |
799 |
|
| 800 |
800 |
if( $is_leap_year ){
|
| ... | ... | |
| 808 |
808 |
$current_year->modify( $interval );
|
| 809 |
809 |
endwhile;
|
| 810 |
810 |
break;
|
| 811 |
|
|
|
811 |
|
| 812 |
812 |
default:
|
| 813 |
813 |
while( $current <= $until || $occurrence_n < $number_occurrences ):
|
| 814 |
814 |
$current->setTime($H,$i );
|
| 815 |
|
$occurrences[] = clone $current;
|
|
815 |
$occurrences[] = clone $current;
|
| 816 |
816 |
$current->modify( $interval );
|
| 817 |
817 |
$occurrence_n++;
|
| 818 |
818 |
endwhile;
|
| ... | ... | |
| 828 |
828 |
$occurrences = array_slice( $occurrences, 0, $number_occurrences );
|
| 829 |
829 |
$until = end( $occurrences );
|
| 830 |
830 |
}
|
| 831 |
|
|
|
831 |
|
| 832 |
832 |
//Cast includes/exclude to timezone
|
| 833 |
833 |
$tz = eo_get_blog_timezone();
|
| 834 |
834 |
if( $include ){
|
| ... | ... | |
| 841 |
841 |
$excluded_date->setTimezone( $tz );
|
| 842 |
842 |
}
|
| 843 |
843 |
}
|
| 844 |
|
|
|
844 |
|
| 845 |
845 |
//Add inclusions, removes exceptions and duplicates
|
| 846 |
846 |
if( defined( 'WP_DEBUG' ) && WP_DEBUG ){
|
| 847 |
847 |
//Make sure 'included' dates doesn't appear in generate date
|
| 848 |
848 |
$include = array_udiff( $include, $occurrences, '_eventorganiser_compare_datetime' );
|
| 849 |
849 |
}
|
| 850 |
|
$occurrences = array_merge($occurrences, $include);
|
|
850 |
$occurrences = array_merge($occurrences, $include);
|
| 851 |
851 |
$occurrences = array_udiff( $occurrences, $exclude, '_eventorganiser_compare_datetime') ;
|
| 852 |
852 |
$occurrences = _eventorganiser_remove_duplicates($occurrences);
|
| 853 |
853 |
|
| 854 |
854 |
//Sort occurrences
|
| 855 |
855 |
sort($occurrences);
|
| 856 |
|
|
|
856 |
|
| 857 |
857 |
if( empty( $occurrences ) || !$occurrences[0] || !( $occurrences[0] instanceof DateTime ) ){
|
| 858 |
858 |
return new WP_Error('eo_error',__('Event does not contain any dates.','eventorganiser'));
|
| 859 |
859 |
}
|
| ... | ... | |
| 874 |
874 |
'include' => $include,
|
| 875 |
875 |
'occurrences' => $occurrences,
|
| 876 |
876 |
);
|
| 877 |
|
|
|
877 |
|
| 878 |
878 |
/**
|
| 879 |
879 |
* Filters the event schedule after its dates has been generated by a given schedule.
|
| 880 |
|
*
|
| 881 |
|
* The filtered array is an array of occurrences generated from a
|
|
880 |
*
|
|
881 |
* The filtered array is an array of occurrences generated from a
|
| 882 |
882 |
* schedule which may include:
|
| 883 |
|
*
|
|
883 |
*
|
| 884 |
884 |
* * **start** (DateTime) - when the event starts
|
| 885 |
885 |
* * **end** (DateTime) - when the event ends
|
| 886 |
886 |
* * **all_day** (Bool) - If the event is all day or no
|
| ... | ... | |
| 894 |
894 |
* * **exclude** (array) - Array of DateTime objects to exclude from the schedule
|
| 895 |
895 |
* * **include** (array) - Array of DateTime objects to include in the schedule
|
| 896 |
896 |
* * **occurrences** (array) - Array of DateTime objects generated from the above schedule.
|
| 897 |
|
*
|
|
897 |
*
|
| 898 |
898 |
* @param array $_event_data The event schedule with generated occurrences.
|
| 899 |
|
* @param array $event_data The original event schedule (without occurrences).
|
|
899 |
* @param array $event_data The original event schedule (without occurrences).
|
| 900 |
900 |
*/
|
| 901 |
901 |
$_event_data = apply_filters( 'eventorganiser_generate_occurrences', $_event_data, $event_data );
|
| 902 |
902 |
return $_event_data;
|
| 903 |
903 |
}
|
| 904 |
904 |
|
| 905 |
905 |
/**
|
| 906 |
|
* Generates the ICS RRULE fromthe event schedule data.
|
|
906 |
* Generates the ICS RRULE fromthe event schedule data.
|
| 907 |
907 |
* @access private
|
| 908 |
908 |
* @ignore
|
| 909 |
909 |
* @since 1.0.0
|
| ... | ... | |
| 921 |
921 |
return false;
|
| 922 |
922 |
|
| 923 |
923 |
extract($rrule);
|
| 924 |
|
|
|
924 |
|
| 925 |
925 |
$schedule_last->setTimezone( new DateTimeZone('UTC') );
|
| 926 |
926 |
$schedule_last = $schedule_last->format( 'Ymd\THis\Z' );
|
| 927 |
927 |
|
| ... | ... | |
| 938 |
938 |
$recurrence_rule .=$schedule_meta.";";
|
| 939 |
939 |
$recurrence_rule .= "UNTIL=".$schedule_last;
|
| 940 |
940 |
return $recurrence_rule;
|
| 941 |
|
|
|
941 |
|
| 942 |
942 |
case 'weekly':
|
| 943 |
|
|
|
943 |
|
| 944 |
944 |
if( !eo_is_all_day( $post_id ) ){
|
| 945 |
945 |
//None all day event, setting event timezone to UTC may cause it to shift days.
|
| 946 |
946 |
//E.g. a 9pm Monday event in New York will a Tuesday event in UTC.
|
| 947 |
947 |
//We may need to correct the BYDAY attribute to be valid for UTC.
|
| 948 |
|
|
|
948 |
|
| 949 |
949 |
$days_of_week = array( 'SU', 'MO', 'TU', 'WE', 'TH', 'FR', 'SA' );
|
| 950 |
950 |
$UTC = new DateTimeZone('UTC');
|
| 951 |
|
|
|
951 |
|
| 952 |
952 |
//Get day shift upon timezone set to UTC
|
| 953 |
953 |
$start = eo_get_schedule_start( DATETIMEOBJ, $post_id );
|
| 954 |
954 |
$local_day = (int) $start->format( 'w' );
|
| 955 |
955 |
$start->setTimezone( $UTC );
|
| 956 |
956 |
$utc_day = (int) $start->format( 'w' );
|
| 957 |
957 |
$diff = $utc_day - $local_day + 7; //ensure difference is positive (should be 0, +1 or +6).
|
| 958 |
|
|
|
958 |
|
| 959 |
959 |
//If there is a shift correct BYDAY
|
| 960 |
960 |
if( $diff ){
|
| 961 |
961 |
$utc_days = array();
|
| 962 |
|
|
|
962 |
|
| 963 |
963 |
foreach( $schedule_meta as $day ){
|
| 964 |
964 |
$utc_day_index = ( array_search( $day, $days_of_week ) + $diff ) %7;
|
| 965 |
965 |
$utc_days[] = $days_of_week[$utc_day_index];
|
| 966 |
966 |
}
|
| 967 |
967 |
$schedule_meta = $utc_days;
|
| 968 |
968 |
}
|
| 969 |
|
|
|
969 |
|
| 970 |
970 |
}
|
| 971 |
|
|
|
971 |
|
| 972 |
972 |
return "FREQ=WEEKLY;INTERVAL=".$frequency.";BYDAY=".implode(',',$schedule_meta).";UNTIL=".$schedule_last;
|
| 973 |
973 |
|
| 974 |
974 |
case 'daily':
|
| ... | ... | |
| 980 |
980 |
}
|
| 981 |
981 |
|
| 982 |
982 |
function eventorganiser_ical_vtimezone( $timezone, $from, $to ) {
|
| 983 |
|
|
|
983 |
|
| 984 |
984 |
$vtimezone = "BEGIN:VTIMEZONE\r\n";
|
| 985 |
985 |
$vtimezone .= sprintf( "TZID:%s\r\n", $timezone->getName() );
|
| 986 |
|
|
|
986 |
|
| 987 |
987 |
//$timezone->getTransitions() doesn't accept any arguments in php 5.2, and would be ineffecient
|
| 988 |
988 |
if ( version_compare( PHP_VERSION, '5.3.0' ) < 0 ) {
|
| 989 |
989 |
return '';
|
| 990 |
990 |
}
|
| 991 |
|
|
|
991 |
|
| 992 |
992 |
// get all transitions, and (as an estimate) an early one which we skip
|
| 993 |
993 |
$transitions = $timezone->getTransitions( $from - YEAR_IN_SECONDS / 2, $to );
|
| 994 |
|
|
|
994 |
|
| 995 |
995 |
if ( ! $transitions ) {
|
| 996 |
996 |
return '';
|
| 997 |
997 |
}
|
| 998 |
998 |
|
| 999 |
999 |
foreach ( $transitions as $i => $trans ) {
|
| 1000 |
|
|
|
1000 |
|
| 1001 |
1001 |
$pm = $trans['offset'] >= 0 ? '+' : '-';
|
| 1002 |
1002 |
$hours = floor( absint( $trans['offset'] ) / HOUR_IN_SECONDS ) % 24;
|
| 1003 |
1003 |
$minutes = ( absint( $trans['offset'] ) - $hours * HOUR_IN_SECONDS ) / MINUTE_IN_SECONDS;
|
| 1004 |
|
|
|
1004 |
|
| 1005 |
1005 |
$tzto = $pm . str_pad( $hours, 2, '0', STR_PAD_LEFT ) . str_pad( $minutes, 2, '0', STR_PAD_LEFT );
|
| 1006 |
|
|
|
1006 |
|
| 1007 |
1007 |
// skip the first entry, we just want it for the TZOFFSETFROM value of the next one
|
| 1008 |
1008 |
if ( $i == 0 ) {
|
| 1009 |
1009 |
$tzfrom = $tzto;
|
| ... | ... | |
| 1011 |
1011 |
continue;
|
| 1012 |
1012 |
}
|
| 1013 |
1013 |
}
|
| 1014 |
|
|
| 1015 |
|
$type = $trans['isdst'] ? 'DAYLIGHT' : 'STANDARD';
|
|
1014 |
|
|
1015 |
$type = $trans['isdst'] ? 'DAYLIGHT' : 'STANDARD';
|
| 1016 |
1016 |
$dt = new DateTime( $trans['time'], $timezone );
|
| 1017 |
|
|
|
1017 |
|
| 1018 |
1018 |
$vtimezone .= sprintf( "BEGIN:%s\r\n", $type );
|
| 1019 |
1019 |
$vtimezone .= sprintf( "TZOFFSETFROM:%s\r\n", $tzfrom ); //needs formatting
|
| 1020 |
1020 |
$vtimezone .= sprintf( "TZOFFSETTO:%s\r\n", $tzto ); //needs formatting
|
| 1021 |
1021 |
$vtimezone .= sprintf( "DTSTART:%s\r\n", $dt->format('Ymd\THis') );
|
| 1022 |
|
$vtimezone .= sprintf( "TZNAME:%s\r\n", $trans['abbr'] );
|
|
1022 |
$vtimezone .= sprintf( "TZNAME:%s\r\n", $trans['abbr'] );
|
| 1023 |
1023 |
$vtimezone .= sprintf( "END:%s\r\n", $type );
|
| 1024 |
|
|
| 1025 |
|
$tzfrom = $tzto;
|
|
1024 |
|
|
1025 |
$tzfrom = $tzto;
|
| 1026 |
1026 |
}
|
| 1027 |
|
|
|
1027 |
|
| 1028 |
1028 |
$vtimezone .= 'END:VTIMEZONE';
|
| 1029 |
|
|
|
1029 |
|
| 1030 |
1030 |
return $vtimezone;
|
| 1031 |
1031 |
}
|
| 1032 |
1032 |
|
| ... | ... | |
| 1044 |
1044 |
global $wpdb;
|
| 1045 |
1045 |
|
| 1046 |
1046 |
$remove = $wpdb->get_row($wpdb->prepare(
|
| 1047 |
|
"SELECT {$wpdb->eo_events}.StartDate, {$wpdb->eo_events}.StartTime
|
| 1048 |
|
FROM {$wpdb->eo_events}
|
|
1047 |
"SELECT {$wpdb->eo_events}.StartDate, {$wpdb->eo_events}.StartTime
|
|
1048 |
FROM {$wpdb->eo_events}
|
| 1049 |
1049 |
WHERE post_id=%d AND event_id=%d",$post_id,$event_id));
|
| 1050 |
1050 |
|
| 1051 |
1051 |
if( !$remove )
|
| ... | ... | |
| 1064 |
1064 |
}
|
| 1065 |
1065 |
|
| 1066 |
1066 |
//Update post meta and delete date from events table
|
| 1067 |
|
update_post_meta( $post_id,'_eventorganiser_event_schedule',$event_details);
|
|
1067 |
update_post_meta( $post_id,'_eventorganiser_event_schedule',$event_details);
|
| 1068 |
1068 |
eo_delete_event_occurrences( $post_id, $event_id );
|
| 1069 |
1069 |
|
| 1070 |
1070 |
//Clear cache
|
| ... | ... | |
| 1073 |
1073 |
return true;
|
| 1074 |
1074 |
}
|
| 1075 |
1075 |
|
| 1076 |
|
|
|
1076 |
|
| 1077 |
1077 |
/**
|
| 1078 |
|
* Updates a specific occurrence, and preserves the occurrence ID.
|
| 1079 |
|
*
|
|
1078 |
* Updates a specific occurrence, and preserves the occurrence ID.
|
|
1079 |
*
|
| 1080 |
1080 |
* Currently two occurrences cannot occupy the same date.
|
| 1081 |
|
*
|
|
1081 |
*
|
| 1082 |
1082 |
* @ignore
|
| 1083 |
1083 |
* @access private
|
| 1084 |
1084 |
* @since 2.12.0
|
| 1085 |
|
*
|
|
1085 |
*
|
| 1086 |
1086 |
* @param int $event_id ID of the event whose occurrence we're moving
|
| 1087 |
1087 |
* @param int $occurrence_id ID of the occurrence we're moving
|
| 1088 |
1088 |
* @param DateTime $start New start DateTime of the occurrence
|
| ... | ... | |
| 1092 |
1092 |
function eventorganiser_move_occurrence( $event_id, $occurrence_id, $start, $end ){
|
| 1093 |
1093 |
|
| 1094 |
1094 |
global $wpdb;
|
| 1095 |
|
|
|
1095 |
|
| 1096 |
1096 |
$old_start = eo_get_the_start( DATETIMEOBJ, $event_id, null, $occurrence_id );
|
| 1097 |
1097 |
$schedule = eo_get_event_schedule( $event_id );
|
| 1098 |
|
|
|
1098 |
|
| 1099 |
1099 |
if( $start == $old_start ){
|
| 1100 |
1100 |
return true;
|
| 1101 |
1101 |
}
|
| 1102 |
|
|
|
1102 |
|
| 1103 |
1103 |
$current_occurrences = eo_get_the_occurrences( $event_id );
|
| 1104 |
1104 |
unset( $current_occurrences[$occurrence_id] );
|
| 1105 |
1105 |
$current_occurrences = array_map( 'eo_format_datetime', $current_occurrences );
|
| 1106 |
|
|
|
1106 |
|
| 1107 |
1107 |
if( in_array( $start->format( 'd-m-Y' ), $current_occurrences ) ){
|
| 1108 |
|
return new WP_Error( 'events-cannot-share-date', __( 'There is already an occurrence on this date', 'eventorganiser' ) );
|
|
1108 |
return new WP_Error( 'events-cannot-share-date', __( 'There is already an occurrence on this date', 'eventorganiser' ) );
|
| 1109 |
1109 |
}
|
| 1110 |
|
|
|
1110 |
|
| 1111 |
1111 |
//We update the date directly in the DB first so the occurrence is not deleted and recreated,
|
| 1112 |
|
//but simply updated.
|
| 1113 |
|
|
|
1112 |
//but simply updated.
|
|
1113 |
|
| 1114 |
1114 |
$wpdb->update(
|
| 1115 |
|
$wpdb->eo_events,
|
|
1115 |
$wpdb->eo_events,
|
| 1116 |
1116 |
array(
|
| 1117 |
1117 |
'StartDate' => $start->format( 'Y-m-d' ),
|
| 1118 |
1118 |
'StartTime' => $start->format( 'H:i:s' ),
|
| 1119 |
1119 |
'EndDate' => $end->format( 'Y-m-d' ),
|
| 1120 |
1120 |
'FinishTime' => $end->format( 'H:i:s' ),
|
| 1121 |
|
),
|
|
1121 |
),
|
| 1122 |
1122 |
array( 'event_id' => $occurrence_id )
|
| 1123 |
1123 |
);
|
| 1124 |
|
|
|
1124 |
|
| 1125 |
1125 |
wp_cache_delete( 'eventorganiser_occurrences_'.$event_id );//Important: update DB clear cache
|
| 1126 |
1126 |
wp_cache_delete( 'eventorganiser_all_occurrences_'.$event_id );//Important: update DB clear cache
|
| 1127 |
1127 |
|
| 1128 |
1128 |
//Now update event schedule...
|
| 1129 |
|
|
| 1130 |
|
//If date being removed was manually included remove it,
|
|
1129 |
|
|
1130 |
//If date being removed was manually included remove it,
|
| 1131 |
1131 |
//otherwise add it to exclude. Then add new date as include.
|
| 1132 |
1132 |
if( false === ( $index = array_search( $old_start, $schedule['include'] ) ) ){
|
| 1133 |
1133 |
$schedule['exclude'][] = $old_start;
|
| ... | ... | |
| 1137 |
1137 |
$schedule['include'][] = $start;
|
| 1138 |
1138 |
|
| 1139 |
1139 |
$re = eo_update_event( $event_id, $schedule );
|
| 1140 |
|
|
|
1140 |
|
| 1141 |
1141 |
if( $re && !is_wp_error( $re ) ){
|
| 1142 |
1142 |
return true;
|
| 1143 |
1143 |
}
|
| 1144 |
|
|
|
1144 |
|
| 1145 |
1145 |
return $re;
|
| 1146 |
1146 |
}
|
| 1147 |
1147 |
?>
|