Events Manager - Version 5.10

Version Description

  • fixed a minor PHPMailer PHP warning tiggered when mailing errors occur
  • fixed date validation errors restting available from/until times to 12AM for tickets
  • fixed WP Fullcalendar style tweak for tip image
  • removed loading of EM_Person upon construct of EM_Booking to prevent unecessary pre-loading
  • fixed bookings closed text not being translatable by ML plugins
  • fixed multilingual translation failures when triggering actions like ML booking emails as an admin
  • added em_ml_swiitch_locale and em_ml_restore_locale actions for ML plugins that don't hook into WP's switch_locale
  • fixed potential ML translation issues when switching translated event objects in a booking
  • optimized translated event switching in booking objects
  • added em_pre_taxonomy_template, em_pre_{taxonomy_name}taxonomy_template and emtaxonomy_template
  • added temporary fix for compatibility issue with/caused by BuddyBoss
  • fixed PHP warnings caused by dev version update checks, also removed em_org_dev_version_slugs filter in place of em_org_dev_versions
  • added em_bookings_single_details_footer filter
  • added extra email trimming to prevent mail errors due to errant whitespaces
  • added em_ticket_get_price_without_tax filter
  • fixed #@_{...} placeholders still showing if end date is the same
  • fixed email fatal errors when password reset is disabled by other plugins or custom code
  • fixed caching issues with custom code hooking into em_event by firing the action before caching occurs
  • fixed reported issues with Elementor by writing $content into event and location object post_content properties (kudos to @martinneumannat)
  • fixed CZY currency symbols not being included
  • fixed dbem_maps_text_format and potentially other formats retrieved via AJAX not being overridable using our em_formats_filter filter
  • fixed bookings="0" not returning non-bookable events in shortcodes
  • fixed google ical link using http://
  • fixed EM_Person::get_summary() returning mixed up array key/values (props @duisterdenhaag)
  • removed outline style rules from CSS to help with WCAG compliance
Download this release

Release Info

Developer netweblogic
Plugin Icon 128x128 Events Manager
Version 5.10
Comparing to
See all releases

Code changes from version 5.9.11.3 to 5.10

admin/em-admin.php CHANGED
@@ -256,35 +256,44 @@ function em_updates_check( $transient ) {
256
 
257
  //only bother if we're checking for dev versions
258
  if( get_option('em_check_dev_version') || get_option('dbem_pro_dev_updates') ){
259
- //check WP repo for trunk version
260
- $plugin_slugs = apply_filters('em_org_dev_version_slugs', array('events-manager'=> EM_SLUG));
261
- foreach( $plugin_slugs as $org_slug => $wp_slug ) {
 
 
 
 
 
262
  $request = wp_remote_get('https://plugins.svn.wordpress.org/'.$org_slug.'/trunk/'.$org_slug.'.php');
263
-
 
 
 
264
  if (!is_wp_error($request)) {
265
  preg_match('/Version: ([0-9a-z\.]+)/', $request['body'], $matches);
266
 
267
  if (!empty($matches[1])) {
268
  //we have a version number!
269
- if (version_compare($transient->checked[$wp_slug], $matches[1]) < 0) {
270
- $response = new stdClass();
271
- $response->slug = $wp_slug;
272
- $response->new_version = $matches[1];
273
- $response->url = 'http://wordpress.org/extend/plugins/'.$org_slug.'/';
274
- $response->package = 'http://downloads.wordpress.org/plugin/'.$org_slug.'.zip';
275
- $icon_test = wp_remote_get('https://ps.w.org/'.$org_slug.'/assets/icon-128x128.png');
276
- if( !is_wp_error($icon_test) && $icon_test['response']['code'] == 200 ){
277
- $response->icons = array(
278
- '1x' => 'https://ps.w.org/'.$org_slug.'/assets/icon-128x128.png',
279
- '2x' => 'https://ps.w.org/'.$org_slug.'/assets/icon-256x256.png'
280
- );
281
- }
282
  $transient->response[$wp_slug] = $response;
 
 
283
  }
284
  }
285
  }
286
  }
287
-
288
  delete_option('em_check_dev_version');
289
  }
290
 
256
 
257
  //only bother if we're checking for dev versions
258
  if( get_option('em_check_dev_version') || get_option('dbem_pro_dev_updates') ){
259
+ //check WP repo for trunk version, other EM-related plugins on .org can hook here to make the best of our admin setting option
260
+ $plugins = apply_filters('em_org_dev_versions', array(
261
+ 'events-manager'=> array(
262
+ 'slug' => EM_SLUG,
263
+ 'version' => EM_VERSION
264
+ )
265
+ ));
266
+ foreach( $plugins as $org_slug => $plugin_info ) {
267
  $request = wp_remote_get('https://plugins.svn.wordpress.org/'.$org_slug.'/trunk/'.$org_slug.'.php');
268
+ $wp_slug = $plugin_info['slug'];
269
+ if( empty($transient->checked[$wp_slug]) ){
270
+ $transient->checked[$wp_slug] = !empty($plugin_info['version']) ? $plugin_info['version'] : 0;
271
+ }
272
  if (!is_wp_error($request)) {
273
  preg_match('/Version: ([0-9a-z\.]+)/', $request['body'], $matches);
274
 
275
  if (!empty($matches[1])) {
276
  //we have a version number!
277
+ $response = new stdClass();
278
+ $response->slug = $wp_slug;
279
+ $response->new_version = $matches[1];
280
+ $response->url = 'http://wordpress.org/extend/plugins/'.$org_slug.'/';
281
+ $response->package = 'http://downloads.wordpress.org/plugin/'.$org_slug.'.zip';
282
+ $icon_test = wp_remote_get('https://ps.w.org/'.$org_slug.'/assets/icon-128x128.png');
283
+ if( !is_wp_error($icon_test) && $icon_test['response']['code'] == 200 ){
284
+ $response->icons = array(
285
+ '1x' => 'https://ps.w.org/'.$org_slug.'/assets/icon-128x128.png',
286
+ '2x' => 'https://ps.w.org/'.$org_slug.'/assets/icon-256x256.png'
287
+ );
288
+ }
289
+ if ( version_compare($transient->checked[$wp_slug], $matches[1]) < 0) {
290
  $transient->response[$wp_slug] = $response;
291
+ }else{
292
+ $transient->no_update[$wp_slug] = $response;
293
  }
294
  }
295
  }
296
  }
 
297
  delete_option('em_check_dev_version');
298
  }
299
 
admin/em-bookings.php CHANGED
@@ -448,6 +448,7 @@ function em_bookings_single(){
448
  $('.em-booking-single-status-edit').hide();
449
  });
450
  </script>
 
451
  </div>
452
  </div>
453
  <div id="em-booking-notes" class="postbox">
448
  $('.em-booking-single-status-edit').hide();
449
  });
450
  </script>
451
+ <?php do_action('em_bookings_single_details_footer', $EM_Booking); ?>
452
  </div>
453
  </div>
454
  <div id="em-booking-notes" class="postbox">
admin/em-docs.php CHANGED
@@ -169,7 +169,7 @@ function em_docs_init($force_init = false){
169
  'desc' => 'These placeholders will only show if bookings are enabled for the given event and in the events manager settings page. Spaces placeholders will default to 0',
170
  'placeholders' => array(
171
  '#_BOOKINGFORM' => array( 'desc' => 'Adds a booking forms for this event.' ),
172
- '#_BOOKINGBUTTON' => array( 'desc' => 'A single button that will appear to logged in users, if they click on it, they apply for a booking. This button will only display if there is one ticket.' ),
173
  '#_AVAILABLESPACES' => array( 'desc' => 'Shows available spaces for the event.' ),
174
  '#_BOOKEDSPACES' => array( 'desc' => 'Shows the amount of currently booked spaces for the event.' ),
175
  '#_PENDINGSPACES' => array( 'desc' => 'Shows the amount of pending spaces for the event.' ),
169
  'desc' => 'These placeholders will only show if bookings are enabled for the given event and in the events manager settings page. Spaces placeholders will default to 0',
170
  'placeholders' => array(
171
  '#_BOOKINGFORM' => array( 'desc' => 'Adds a booking forms for this event.' ),
172
+ '#_BOOKINGBUTTON' => array( 'desc' => 'A single button that will appear to logged in users, if they click on it a booking will be made. This button will automatically book the first aailable ticket if more than one ticket exists for the event, and will also circumvent any payment requirements. Use in combination with conditional placeholders such as is_free to avoid unpaid bookings.' ),
173
  '#_AVAILABLESPACES' => array( 'desc' => 'Shows available spaces for the event.' ),
174
  '#_BOOKEDSPACES' => array( 'desc' => 'Shows the amount of currently booked spaces for the event.' ),
175
  '#_PENDINGSPACES' => array( 'desc' => 'Shows the amount of pending spaces for the event.' ),
admin/settings/wpfc-admin.php CHANGED
@@ -42,7 +42,7 @@ function wpfc_em_install(){
42
  //check for updates - try adding one option, if it works then it's a first time install so add more
43
  if( current_user_can('manage_options') && get_option('dbem_emfc_full_calendar_event_format', false) ){
44
  add_option('dbem_emfc_full_calendar_event_format','#_EVENTTIMES - #_EVENTNAME');
45
- add_option('dbem_emfc_qtips_format', '{has_image}<div style="float:left; margin:0px 5px 5px 0px;">#_EVENTIMAGE{75,75}</div>{/has_image}#_EVENTEXCERPT');
46
  }
47
  }
48
  add_action('init', 'wpfc_em_install');
42
  //check for updates - try adding one option, if it works then it's a first time install so add more
43
  if( current_user_can('manage_options') && get_option('dbem_emfc_full_calendar_event_format', false) ){
44
  add_option('dbem_emfc_full_calendar_event_format','#_EVENTTIMES - #_EVENTNAME');
45
+ add_option('dbem_emfc_qtips_format', '{has_image}<div style="float:left; margin:5px 10px 5px 0px;">#_EVENTIMAGE{75,75}</div>{/has_image}#_EVENTEXCERPT');
46
  }
47
  }
48
  add_action('init', 'wpfc_em_install');
classes/em-booking.php CHANGED
@@ -143,7 +143,6 @@ class EM_Booking extends EM_Object{
143
  //Save into the object
144
  $this->to_object($booking);
145
  $this->previous_status = $this->booking_status;
146
- $this->get_person();
147
  $this->booking_date = !empty($booking['booking_date']) ? $booking['booking_date']:false;
148
  }
149
  //Do it here so things appear in the po file.
@@ -741,7 +740,7 @@ class EM_Booking extends EM_Object{
741
  */
742
  function get_event(){
743
  global $EM_Event;
744
- if( is_object($this->event) && get_class($this->event)=='EM_Event' && $this->event->event_id == $this->event_id ){
745
  return $this->event;
746
  }elseif( is_object($EM_Event) && $EM_Event->event_id == $this->event_id ){
747
  $this->event = $EM_Event;
143
  //Save into the object
144
  $this->to_object($booking);
145
  $this->previous_status = $this->booking_status;
 
146
  $this->booking_date = !empty($booking['booking_date']) ? $booking['booking_date']:false;
147
  }
148
  //Do it here so things appear in the po file.
740
  */
741
  function get_event(){
742
  global $EM_Event;
743
+ if( is_object($this->event) && get_class($this->event)=='EM_Event' && ($this->event->event_id == $this->event_id || (EM_ML::$is_ml && $this->event->event_parent == $this->event_id)) ){
744
  return $this->event;
745
  }elseif( is_object($EM_Event) && $EM_Event->event_id == $this->event_id ){
746
  $this->event = $EM_Event;
classes/em-event-post.php CHANGED
@@ -142,6 +142,8 @@ class EM_Event_Post {
142
  //we don't do extra checks here because WP will have already done the work for us here...
143
  $EM_Event->post_content = $post->post_content;
144
  $EM_Event->post_content_filtered = $post->post_content_filtered;
 
 
145
  }
146
  ob_start();
147
  em_locate_template('templates/event-single.php',true);
142
  //we don't do extra checks here because WP will have already done the work for us here...
143
  $EM_Event->post_content = $post->post_content;
144
  $EM_Event->post_content_filtered = $post->post_content_filtered;
145
+ }else{
146
+ $EM_Event->post_content = $content;
147
  }
148
  ob_start();
149
  em_locate_template('templates/event-single.php',true);
classes/em-event.php CHANGED
@@ -423,12 +423,13 @@ class EM_Event extends EM_Object{
423
  0 => __('Pending','events-manager'),
424
  1 => __('Approved','events-manager')
425
  );
 
 
426
  //add this event to the cache
427
  if( $this->event_id && $this->post_id ){
428
  wp_cache_set($this->event_id, $this, 'em_events');
429
  wp_cache_set($this->post_id, $this->event_id, 'em_events_ids');
430
  }
431
- do_action('em_event', $this, $id, $search_by);
432
  }
433
 
434
  function __get( $var ){
@@ -1928,8 +1929,8 @@ class EM_Event extends EM_Object{
1928
  $offset = 3;
1929
  }
1930
  }
1931
- if( $date == 'end' && $this->event_end == $this->event_start ){
1932
- $replace = __( apply_filters('em_event_output_placeholder', '', $this, $result, $target, array($result)) );
1933
  }else{
1934
  $date_format = substr( $result, $offset, (strlen($result)-($offset+1)) );
1935
  if( !empty($show_site_timezone) ){
@@ -2605,7 +2606,7 @@ class EM_Event extends EM_Object{
2605
  $dateEnd = $this->end()->format('Ymd\THis');
2606
  }
2607
  //build url
2608
- $gcal_url = 'http://www.google.com/calendar/event?action=TEMPLATE&text=event_name&dates=start_date/end_date&details=post_content&location=location_name&trp=false&sprop=event_url&sprop=name:blog_name&ctz=event_timezone';
2609
  $gcal_url = str_replace('event_name', urlencode($this->event_name), $gcal_url);
2610
  $gcal_url = str_replace('start_date', urlencode($dateStart), $gcal_url);
2611
  $gcal_url = str_replace('end_date', urlencode($dateEnd), $gcal_url);
@@ -2628,8 +2629,7 @@ class EM_Event extends EM_Object{
2628
  //get the final url
2629
  $replace = $gcal_url;
2630
  if( $result == '#_EVENTGCALLINK' ){
2631
- $img_url = 'www.google.com/calendar/images/ext/gc_button2.gif';
2632
- $img_url = is_ssl() ? 'https://'.$img_url:'http://'.$img_url;
2633
  $replace = '<a href="'.esc_url($replace).'" target="_blank"><img src="'.esc_url($img_url).'" alt="0" border="0"></a>';
2634
  }
2635
  break;
423
  0 => __('Pending','events-manager'),
424
  1 => __('Approved','events-manager')
425
  );
426
+ // fire hook to add any extra info to an event
427
+ do_action('em_event', $this, $id, $search_by);
428
  //add this event to the cache
429
  if( $this->event_id && $this->post_id ){
430
  wp_cache_set($this->event_id, $this, 'em_events');
431
  wp_cache_set($this->post_id, $this->event_id, 'em_events_ids');
432
  }
 
433
  }
434
 
435
  function __get( $var ){
1929
  $offset = 3;
1930
  }
1931
  }
1932
+ if( $date == 'end' && $this->event_start_date == $this->event_end_date ){
1933
+ $replace = apply_filters('em_event_output_placeholder', '', $this, $result, $target, array($result));
1934
  }else{
1935
  $date_format = substr( $result, $offset, (strlen($result)-($offset+1)) );
1936
  if( !empty($show_site_timezone) ){
2606
  $dateEnd = $this->end()->format('Ymd\THis');
2607
  }
2608
  //build url
2609
+ $gcal_url = 'https://www.google.com/calendar/event?action=TEMPLATE&text=event_name&dates=start_date/end_date&details=post_content&location=location_name&trp=false&sprop=event_url&sprop=name:blog_name&ctz=event_timezone';
2610
  $gcal_url = str_replace('event_name', urlencode($this->event_name), $gcal_url);
2611
  $gcal_url = str_replace('start_date', urlencode($dateStart), $gcal_url);
2612
  $gcal_url = str_replace('end_date', urlencode($dateEnd), $gcal_url);
2629
  //get the final url
2630
  $replace = $gcal_url;
2631
  if( $result == '#_EVENTGCALLINK' ){
2632
+ $img_url = 'https://www.google.com/calendar/images/ext/gc_button2.gif';
 
2633
  $replace = '<a href="'.esc_url($replace).'" target="_blank"><img src="'.esc_url($img_url).'" alt="0" border="0"></a>';
2634
  }
2635
  break;
classes/em-location-post.php CHANGED
@@ -102,6 +102,13 @@ class EM_Location_Post {
102
  }else{
103
  if( get_option('dbem_cp_locations_formats') && !post_password_required() ){
104
  $EM_Location = em_get_location($post);
 
 
 
 
 
 
 
105
  ob_start();
106
  em_locate_template('templates/location-single.php',true);
107
  $content = ob_get_clean();
102
  }else{
103
  if( get_option('dbem_cp_locations_formats') && !post_password_required() ){
104
  $EM_Location = em_get_location($post);
105
+ if( !empty($_REQUEST['preview']) ){
106
+ //we don't do extra checks here because WP will have already done the work for us here...
107
+ $EM_Location->post_content = $post->post_content;
108
+ $EM_Location->post_content_filtered = $post->post_content_filtered;
109
+ }else{
110
+ $EM_Location->post_content = $content;
111
+ }
112
  ob_start();
113
  em_locate_template('templates/location-single.php',true);
114
  $content = ob_get_clean();
classes/em-mailer.php CHANGED
@@ -29,11 +29,14 @@ class EM_Mailer {
29
  $subject = html_entity_decode(wp_kses_data($subject)); //decode entities, but run kses first just in case users use placeholders containing html
30
  if( is_array($receiver) ){
31
  $receiver_emails = array();
32
- foreach($receiver as $receiver_email){
 
 
33
  $receiver_emails[] = is_email($receiver_email);
34
  }
35
  $emails_ok = !in_array(false, $receiver_emails);
36
  }else{
 
37
  $emails_ok = is_email($receiver);
38
  }
39
  if( get_option('dbem_smtp_html') && get_option('dbem_smtp_html_br') ){
@@ -56,8 +59,10 @@ class EM_Mailer {
56
  remove_action('phpmailer_init', 'EM_Mailer::add_attachments_to_mailer', 9999);
57
  //send email
58
  if(!$send){
59
- global $phpmailer;
60
- $this->errors[] = $phpmailer->ErrorInfo;
 
 
61
  }
62
  //cleanup
63
  self::delete_email_attachments($attachments);
29
  $subject = html_entity_decode(wp_kses_data($subject)); //decode entities, but run kses first just in case users use placeholders containing html
30
  if( is_array($receiver) ){
31
  $receiver_emails = array();
32
+ foreach($receiver as $k => $receiver_email){
33
+ $receiver_email = trim($receiver_email);
34
+ $receiver[$k] = $receiver_email;
35
  $receiver_emails[] = is_email($receiver_email);
36
  }
37
  $emails_ok = !in_array(false, $receiver_emails);
38
  }else{
39
+ $receiver = trim($receiver);
40
  $emails_ok = is_email($receiver);
41
  }
42
  if( get_option('dbem_smtp_html') && get_option('dbem_smtp_html_br') ){
59
  remove_action('phpmailer_init', 'EM_Mailer::add_attachments_to_mailer', 9999);
60
  //send email
61
  if(!$send){
62
+ global $phpmailer; /* @var PHPMailer $phpmailer */
63
+ if( !empty($phpmailer->ErrorInfo) ) {
64
+ $this->errors[] = $phpmailer->ErrorInfo;
65
+ }
66
  }
67
  //cleanup
68
  self::delete_email_attachments($attachments);
classes/em-object.php CHANGED
@@ -231,7 +231,7 @@ class EM_Object {
231
  $tag = $args['tag'];// - not used anymore, accesses the $args directly
232
  $location = $args['location'];
233
  $bookings = $args['rsvp'];
234
- $bookings = !empty($args['bookings']) ? $args['bookings']:$bookings;
235
  $owner = $args['owner'];
236
  $event = $args['event'];
237
  $month = $args['month'];
@@ -590,6 +590,8 @@ class EM_Object {
590
  }else{
591
  $conditions['bookings'] = "(event_id = 0)";
592
  }
 
 
593
  }
594
  //Default ownership belongs to an event, child objects can just overwrite this if needed.
595
  if( is_numeric($owner) ){
@@ -1688,7 +1690,7 @@ class EM_Object {
1688
  }
1689
 
1690
  function sanitize_time( $time ){
1691
- if( !empty($time) && preg_match ( '/^([01]\d|2[0-3]):([0-5]\d) ?(AM|PM)?$/', $time, $match ) ){
1692
  if( !empty($match[3]) && $match[3] == 'PM' && $match[1] != 12 ){
1693
  $match[1] = 12+$match[1];
1694
  }elseif( !empty($match[3]) && $match[3] == 'AM' && $match[1] == 12 ){
231
  $tag = $args['tag'];// - not used anymore, accesses the $args directly
232
  $location = $args['location'];
233
  $bookings = $args['rsvp'];
234
+ $bookings = $args['bookings'] !== false ? absint($args['bookings']):$bookings;
235
  $owner = $args['owner'];
236
  $event = $args['event'];
237
  $month = $args['month'];
590
  }else{
591
  $conditions['bookings'] = "(event_id = 0)";
592
  }
593
+ }elseif( $bookings == 0 && $bookings !== false ){
594
+ $conditions['bookings'] = 'event_rsvp=0';
595
  }
596
  //Default ownership belongs to an event, child objects can just overwrite this if needed.
597
  if( is_numeric($owner) ){
1690
  }
1691
 
1692
  function sanitize_time( $time ){
1693
+ if( !empty($time) && preg_match ( '/^([01]?\d|2[0-3]):([0-5]\d) ?(AM|PM)?$/', $time, $match ) ){
1694
  if( !empty($match[3]) && $match[3] == 'PM' && $match[1] != 12 ){
1695
  $match[1] = 12+$match[1];
1696
  }elseif( !empty($match[3]) && $match[3] == 'AM' && $match[1] == 12 ){
classes/em-person.php CHANGED
@@ -109,9 +109,9 @@ class EM_Person extends WP_User{
109
 
110
  function get_summary(){
111
  $summary = array(
112
- 'dbem_phone' => array('name' => __('Name','events-manager'), 'value' => $this->get_name()),
113
- 'user_name' => array('name' => __('Email','events-manager'), 'value' => $this->user_email),
114
- 'user_email' => array('name' => __('Phone','events-manager'), 'value' => $this->phone),
115
  );
116
  $summary = array_merge( $summary, $this->custom_user_fields );
117
  return apply_filters('em_person_get_summary', $summary, $this);
109
 
110
  function get_summary(){
111
  $summary = array(
112
+ 'user_name' => array('name' => __('Name','events-manager'), 'value' => $this->get_name()),
113
+ 'user_email' => array('name' => __('Email','events-manager'), 'value' => $this->user_email),
114
+ 'dbem_phone' => array('name' => __('Phone','events-manager'), 'value' => $this->phone),
115
  );
116
  $summary = array_merge( $summary, $this->custom_user_fields );
117
  return apply_filters('em_person_get_summary', $summary, $this);
classes/em-taxonomy-frontend.php CHANGED
@@ -40,6 +40,8 @@ class EM_Taxonomy_Frontend {
40
  public static function template($template = ''){
41
  global $wp_query, $wp_the_query, $em_the_query, $post;
42
  if( is_tax(self::$taxonomy_name) && !locate_template('taxonomy-'.self::$taxonomy_name.'.php') && get_option('dbem_cp_'. self::$option_name_plural .'_formats', true) ){
 
 
43
  $em_the_query = $wp_the_query; //use this for situations where other plugins need to access 'original' query data, which you can switch back/forth.
44
  $EM_Taxonomy = $GLOBALS[self::$tax_class] = EM_Taxonomy_Term::get($wp_query->queried_object->term_id, self::$tax_class);
45
  if( self::get_page_id() ){
@@ -88,6 +90,7 @@ class EM_Taxonomy_Frontend {
88
  add_filter('wpseo_head', array(self::$this_class,'flip_the_query'), 1000000);
89
  }
90
  do_action('em_'. self::$option_name .'_taxonomy_template');
 
91
  }
92
  return $template;
93
  }
40
  public static function template($template = ''){
41
  global $wp_query, $wp_the_query, $em_the_query, $post;
42
  if( is_tax(self::$taxonomy_name) && !locate_template('taxonomy-'.self::$taxonomy_name.'.php') && get_option('dbem_cp_'. self::$option_name_plural .'_formats', true) ){
43
+ do_action('em_pre_'. self::$option_name .'_taxonomy_template');
44
+ do_action('em_pre_taxonomy_template', get_called_class(), static::$tax_class);
45
  $em_the_query = $wp_the_query; //use this for situations where other plugins need to access 'original' query data, which you can switch back/forth.
46
  $EM_Taxonomy = $GLOBALS[self::$tax_class] = EM_Taxonomy_Term::get($wp_query->queried_object->term_id, self::$tax_class);
47
  if( self::get_page_id() ){
90
  add_filter('wpseo_head', array(self::$this_class,'flip_the_query'), 1000000);
91
  }
92
  do_action('em_'. self::$option_name .'_taxonomy_template');
93
+ do_action('em_taxonomy_template', get_called_class(), static::$tax_class);
94
  }
95
  return $template;
96
  }
classes/em-ticket.php CHANGED
@@ -430,7 +430,7 @@ class EM_Ticket extends EM_Object{
430
  */
431
  function get_price_without_tax( $format = false ){
432
  if( $format ) return $this->format_price($this->ticket_price);
433
- return $this->ticket_price;
434
  }
435
 
436
  /**
430
  */
431
  function get_price_without_tax( $format = false ){
432
  if( $format ) return $this->format_price($this->ticket_price);
433
+ return apply_filters('em_ticket_get_price_without_tax', $this->ticket_price, $this);
434
  }
435
 
436
  /**
classes/em-tickets-bookings.php CHANGED
@@ -89,6 +89,7 @@ class EM_Tickets_Bookings extends EM_Object implements Iterator, Countable {
89
  /**
90
  * Add a booking into this event object, checking that there's enough space for the event
91
  * @param EM_Ticket_Booking $EM_Ticket_Booking
 
92
  * @return boolean
93
  */
94
  function add( $EM_Ticket_Booking, $override = false ){ //note, $override was a quick fix, not necessarily permanent, so don't depend on it just yet
89
  /**
90
  * Add a booking into this event object, checking that there's enough space for the event
91
  * @param EM_Ticket_Booking $EM_Ticket_Booking
92
+ * @param boolean $override
93
  * @return boolean
94
  */
95
  function add( $EM_Ticket_Booking, $override = false ){ //note, $override was a quick fix, not necessarily permanent, so don't depend on it just yet
em-data-privacy.php CHANGED
@@ -6,14 +6,20 @@
6
  function em_data_privacy_consent_checkbox( $EM_Object = false ){
7
  if( !empty($EM_Object) && (!empty($EM_Object->booking_id) || !empty($EM_Object->post_id)) ) return; //already saved so consent was given at one point
8
  $label = get_option('dbem_data_privacy_consent_text');
 
 
 
9
  if( function_exists('get_the_privacy_policy_link') ) $label = sprintf($label, get_the_privacy_policy_link());
 
 
 
10
  if( is_user_logged_in() ){
11
- //check if consent was previously given and check box if true
12
  $consent_given_already = get_user_meta( get_current_user_id(), 'em_data_privacy_consent', true );
13
  if( !empty($consent_given_already) && get_option('dbem_data_privacy_consent_remember') == 1 ) return; //ignore if consent given as per settings
14
  if( !empty($consent_given_already) && get_option('dbem_data_privacy_consent_remember') == 2 ) $checked = true;
15
  }
16
  if( empty($checked) && !empty($_REQUEST['data_privacy_consent']) ) $checked = true;
 
17
  ?>
18
  <p class="input-group input-checkbox input-field-data_privacy_consent">
19
  <label>
6
  function em_data_privacy_consent_checkbox( $EM_Object = false ){
7
  if( !empty($EM_Object) && (!empty($EM_Object->booking_id) || !empty($EM_Object->post_id)) ) return; //already saved so consent was given at one point
8
  $label = get_option('dbem_data_privacy_consent_text');
9
+ // buddyboss fix since bb v1.6.0
10
+ if( has_filter( 'the_privacy_policy_link', 'bp_core_change_privacy_policy_link_on_private_network') ) $bb_fix = remove_filter('the_privacy_policy_link', 'bp_core_change_privacy_policy_link_on_private_network', 999999);
11
+ // replace privacy policy text %s with link to policy page
12
  if( function_exists('get_the_privacy_policy_link') ) $label = sprintf($label, get_the_privacy_policy_link());
13
+ // buddyboss unfix since bb v1.6.0
14
+ if( !empty($bb_fix) ) add_filter( 'the_privacy_policy_link', 'bp_core_change_privacy_policy_link_on_private_network', 999999, 2 );
15
+ // check if consent was previously given and check box if true
16
  if( is_user_logged_in() ){
 
17
  $consent_given_already = get_user_meta( get_current_user_id(), 'em_data_privacy_consent', true );
18
  if( !empty($consent_given_already) && get_option('dbem_data_privacy_consent_remember') == 1 ) return; //ignore if consent given as per settings
19
  if( !empty($consent_given_already) && get_option('dbem_data_privacy_consent_remember') == 2 ) $checked = true;
20
  }
21
  if( empty($checked) && !empty($_REQUEST['data_privacy_consent']) ) $checked = true;
22
+ // output checkbox
23
  ?>
24
  <p class="input-group input-checkbox input-field-data_privacy_consent">
25
  <label>
em-functions.php CHANGED
@@ -220,9 +220,9 @@ function em_get_scopes(){
220
 
221
  function em_get_currencies(){
222
  $currencies = new stdClass();
223
- $currencies->names = array('EUR' => 'EUR - Euros','USD' => 'USD - U.S. Dollars','GBP' => 'GBP - British Pounds','CAD' => 'CAD - Canadian Dollars','AUD' => 'AUD - Australian Dollars','BRL' => 'BRL - Brazilian Reais','CZK' => 'CZK - Czech Koruny','DKK' => 'DKK - Danish Kroner','HKD' => 'HKD - Hong Kong Dollars','HUF' => 'HUF - Hungarian Forints','ILS' => 'ILS - Israeli New Shekels','JPY' => 'JPY - Japanese Yen','MYR' => 'MYR - Malaysian Ringgit','MXN' => 'MXN - Mexican Pesos','TWD' => 'TWD - New Taiwan Dollars','NZD' => 'NZD - New Zealand Dollars','NOK' => 'NOK - Norwegian Kroner','PHP' => 'PHP - Philippine Pesos','PLN' => 'PLN - Polish Zlotys','SGD' => 'SGD - Singapore Dollars','SEK' => 'SEK - Swedish Kronor','CHF' => 'CHF - Swiss Francs','THB' => 'THB - Thai Baht','TRY' => 'TRY - Turkish Liras', 'RUB'=>'RUB - Russian Ruble');
224
- $currencies->symbols = array( 'EUR' => '&euro;','USD' => '$','GBP' => '&pound;','CAD' => '$','AUD' => '$','BRL' => 'R$','DKK' => 'kr','HKD' => '$','HUF' => 'Ft','JPY' => '&#165;','MYR' => 'RM','MXN' => '$','TWD' => '$','NZD' => '$','NOK' => 'kr','PHP' => 'Php', 'PLN' => '&#122;&#322;','SGD' => '$','SEK' => 'kr','CHF' => 'CHF','TRY' => 'TL','RUB'=>'&#8381;');
225
- $currencies->true_symbols = array( 'EUR' => '€','USD' => '$','GBP' => '£','CAD' => '$','AUD' => '$','BRL' => 'R$','DKK' => 'kr','HKD' => '$','HUF' => 'Ft','JPY' => '¥','MYR' => 'RM','MXN' => '$','TWD' => '$','NZD' => '$','NOK' => 'kr','PHP' => 'Php','PLN' => 'zł','SGD' => '$','SEK' => 'kr','CHF' => 'CHF','TRY' => 'TL', 'RUB'=>'₽');
226
  return apply_filters('em_get_currencies',$currencies);
227
  }
228
 
@@ -513,7 +513,11 @@ function em_new_user_notification() {
513
  $set_password_url = '';
514
  if( function_exists('get_password_reset_key')){
515
  $key = get_password_reset_key( $user );
516
- $set_password_url = network_site_url("wp-login.php?action=rp&key=$key&login=" . rawurlencode($user_login), 'login');
 
 
 
 
517
  }
518
  $message = str_replace(array('%password%','%username%','%passwordurl%'), array($plaintext_pass, $user_login, $set_password_url), $message);
519
  global $EM_Mailer;
220
 
221
  function em_get_currencies(){
222
  $currencies = new stdClass();
223
+ $currencies->names = array('EUR' => 'EUR - Euros','USD' => 'USD - U.S. Dollars','GBP' => 'GBP - British Pounds','CAD' => 'CAD - Canadian Dollars','AUD' => 'AUD - Australian Dollars','BRL' => 'BRL - Brazilian Reais','CZK' => 'CZK - Czech koruna','DKK' => 'DKK - Danish Kroner','HKD' => 'HKD - Hong Kong Dollars','HUF' => 'HUF - Hungarian Forints','ILS' => 'ILS - Israeli New Shekels','JPY' => 'JPY - Japanese Yen','MYR' => 'MYR - Malaysian Ringgit','MXN' => 'MXN - Mexican Pesos','TWD' => 'TWD - New Taiwan Dollars','NZD' => 'NZD - New Zealand Dollars','NOK' => 'NOK - Norwegian Kroner','PHP' => 'PHP - Philippine Pesos','PLN' => 'PLN - Polish Zlotys','SGD' => 'SGD - Singapore Dollars','SEK' => 'SEK - Swedish Kronor','CHF' => 'CHF - Swiss Francs','THB' => 'THB - Thai Baht','TRY' => 'TRY - Turkish Liras', 'RUB'=>'RUB - Russian Ruble');
224
+ $currencies->symbols = array( 'EUR' => '&euro;','USD' => '$','GBP' => '&pound;','CAD' => '$','AUD' => '$','BRL' => 'R$','CZK' => 'K&#269;','DKK' => 'kr','HKD' => '$','HUF' => 'Ft','JPY' => '&#165;','MYR' => 'RM','MXN' => '$','TWD' => '$','NZD' => '$','NOK' => 'kr','PHP' => 'Php', 'PLN' => '&#122;&#322;','SGD' => '$','SEK' => 'kr','CHF' => 'CHF','TRY' => 'TL','RUB'=>'&#8381;');
225
+ $currencies->true_symbols = array( 'EUR' => '€','USD' => '$','GBP' => '£','CAD' => '$','AUD' => '$','BRL' => 'R$','CZK' => 'Kč','DKK' => 'kr','HKD' => '$','HUF' => 'Ft','JPY' => '¥','MYR' => 'RM','MXN' => '$','TWD' => '$','NZD' => '$','NOK' => 'kr','PHP' => 'Php','PLN' => 'zł','SGD' => '$','SEK' => 'kr','CHF' => 'CHF','TRY' => 'TL', 'RUB'=>'₽');
226
  return apply_filters('em_get_currencies',$currencies);
227
  }
228
 
513
  $set_password_url = '';
514
  if( function_exists('get_password_reset_key')){
515
  $key = get_password_reset_key( $user );
516
+ if( is_wp_error($key) ){
517
+ $set_password_url = __('Contact a site administrator for your password.', 'events-manager');
518
+ }else{
519
+ $set_password_url = network_site_url("wp-login.php?action=rp&key=$key&login=" . rawurlencode($user_login), 'login');
520
+ }
521
  }
522
  $message = str_replace(array('%password%','%username%','%passwordurl%'), array($plaintext_pass, $user_login, $set_password_url), $message);
523
  global $EM_Mailer;
events-manager.php CHANGED
@@ -1,7 +1,7 @@
1
  <?php
2
  /*
3
  Plugin Name: Events Manager
4
- Version: 5.9.11.3
5
  Plugin URI: http://wp-events-plugin.com
6
  Description: Event registration and booking management for WordPress. Recurring events, locations, webinars, google maps, rss, ical, booking registration and more!
7
  Author: Marcus Sykes
@@ -28,7 +28,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
28
  */
29
 
30
  // Setting constants
31
- define('EM_VERSION', 5.9942); //self expanatory, although version currently may not correspond directly with published version number
32
  define('EM_PRO_MIN_VERSION', 2.6712); //self expanatory
33
  define('EM_PRO_MIN_VERSION_CRITICAL', 2.377); //self expanatory
34
  define('EM_DIR', dirname( __FILE__ )); //an absolute path to this directory
@@ -678,7 +678,7 @@ function em_locate_template( $template_name, $load=false, $the_args = array() )
678
  * Since the options filter doesn't have a catchall filter, we send all filters to the __call function and figure out the option that way.
679
  */
680
  class EM_Formats {
681
- function __construct(){ add_action( 'template_redirect', array(&$this, 'add_filters')); }
682
  function add_filters(){
683
  //you can hook into this filter and activate the format options you want to override by supplying the wp option names in an array, just like in the database.
684
  $formats = apply_filters('em_formats_filter', array());
1
  <?php
2
  /*
3
  Plugin Name: Events Manager
4
+ Version: 5.10
5
  Plugin URI: http://wp-events-plugin.com
6
  Description: Event registration and booking management for WordPress. Recurring events, locations, webinars, google maps, rss, ical, booking registration and more!
7
  Author: Marcus Sykes
28
  */
29
 
30
  // Setting constants
31
+ define('EM_VERSION', 5.99910); //self expanatory, although version currently may not correspond directly with published version number. until 6.0 we're stuck updating 5.999.x
32
  define('EM_PRO_MIN_VERSION', 2.6712); //self expanatory
33
  define('EM_PRO_MIN_VERSION_CRITICAL', 2.377); //self expanatory
34
  define('EM_DIR', dirname( __FILE__ )); //an absolute path to this directory
678
  * Since the options filter doesn't have a catchall filter, we send all filters to the __call function and figure out the option that way.
679
  */
680
  class EM_Formats {
681
+ function __construct(){ add_action( 'events_manager_loaded', array(&$this, 'add_filters')); }
682
  function add_filters(){
683
  //you can hook into this filter and activate the format options you want to override by supplying the wp option names in an array, just like in the database.
684
  $formats = apply_filters('em_formats_filter', array());
includes/css/events_manager.css CHANGED
@@ -26,14 +26,14 @@ div#em-loading { position:absolute; width:100%; height:100%; background:#FFFFFF
26
  div.css-search.has-advanced div.em-search-main { padding-bottom:8px; border-bottom:1px solid #dedede; }
27
  div.css-search div.em-search-main div { display:inline; }
28
  div.css-search div.em-search-field { padding:5px 0px; }
29
- div.css-search input.em-search-text, div.css-search input.em-search-geo { width:90%; font-size:16px; line-height:16px; padding:8px; border:none; outline:none !important; color:#666; text-overflow: ellipsis; display:inline-block; }
30
  div.css-search div.em-search-geo { margin:0px 0px 0px 5px; padding-left:20px; background:url(../images/search-geo.png) 0px 3px no-repeat; }
31
  div.css-search div.em-search-text { margin:0px 0px 0px 5px; padding-left:20px; background:url(../images/search-mag-ico.png) 0px 4px no-repeat; }
32
  /* Placeholder text in main section */
33
- div.css-search div.em-search-main div.em-search-field input::-webkit-input-placeholder { /* WebKit browsers */ font-size:16px; line-height:16px; padding:3px 0px; border:none; outline:none; color:#666; }
34
- div.css-search div.em-search-main div.em-search-field input:-moz-placeholder { /* Mozilla Firefox 4 to 18 */ font-size:16px; line-height:16px; padding:8px; border:none; outline:none; color:#666; }
35
- div.css-search div.em-search-main div.em-search-field input::-moz-placeholder { /* Mozilla Firefox 19+ */ font-size:16px; line-height:16px; padding:8px; border:none; outline:none; color:#666; }
36
- div.css-search div.em-search-main div.em-search-field input:-ms-input-placeholder { /* Internet Explorer 10+ */ font-size:16px; line-height:16px; padding:8px; border:none; outline:none; color:#666; }
37
  /* Geo field specifics */
38
  div.css-search.has-search-geo.has-search-term input.em-search-text, div.css-search.has-search-geo.has-search-term input.em-search-geo { width:40%; }
39
  .pac-container .pac-item { padding:4px 4px !important; }
@@ -264,4 +264,4 @@ Please edit your theme's CSS to override this
264
  /* Time Picker */
265
  .em-time-input { width:7em;}
266
  .em-time-range .em-time-input.error, .em-time-input.error { border:#cc0000 1px solid; }
267
- .ui-em_timepicker-wrapper{overflow-y:auto;max-height:150px;width:6.5em;background:#fff;border:1px solid #ddd;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);outline:0;z-index:10052;margin:0}.ui-em_timepicker-wrapper.ui-em_timepicker-with-duration{width:13em}.ui-em_timepicker-wrapper.ui-em_timepicker-with-duration.ui-em_timepicker-step-30,.ui-em_timepicker-wrapper.ui-em_timepicker-with-duration.ui-em_timepicker-step-60{width:11em}.ui-em_timepicker-list,.ui-em_timepicker-list li{margin:0;padding:0;list-style:none}.ui-em_timepicker-duration{margin-left:5px;color:#888}.ui-em_timepicker-list:hover .ui-em_timepicker-duration{color:#888}.ui-em_timepicker-list li{padding:3px 0 3px 5px;cursor:pointer;white-space:nowrap;color:#000}.ui-em_timepicker-list:hover .ui-em_timepicker-selected{background:#fff;color:#000}.ui-em_timepicker-list .ui-em_timepicker-selected:hover,.ui-em_timepicker-list li:hover,li.ui-em_timepicker-selected{background:#1980ec;color:#fff}.ui-em_timepicker-list li:hover .ui-em_timepicker-duration,li.ui-em_timepicker-selected .ui-em_timepicker-duration{color:#ccc}.ui-em_timepicker-list li.ui-em_timepicker-disabled,.ui-em_timepicker-list li.ui-em_timepicker-disabled:hover,.ui-em_timepicker-list li.ui-em_timepicker-selected.ui-em_timepicker-disabled{color:#888;cursor:default}.ui-em_timepicker-list li.ui-em_timepicker-disabled:hover,.ui-em_timepicker-list li.ui-em_timepicker-selected.ui-em_timepicker-disabled{background:#f2f2f2}
26
  div.css-search.has-advanced div.em-search-main { padding-bottom:8px; border-bottom:1px solid #dedede; }
27
  div.css-search div.em-search-main div { display:inline; }
28
  div.css-search div.em-search-field { padding:5px 0px; }
29
+ div.css-search input.em-search-text, div.css-search input.em-search-geo { width:90%; font-size:16px; line-height:16px; padding:8px; border:none; color:#666; text-overflow: ellipsis; display:inline-block; }
30
  div.css-search div.em-search-geo { margin:0px 0px 0px 5px; padding-left:20px; background:url(../images/search-geo.png) 0px 3px no-repeat; }
31
  div.css-search div.em-search-text { margin:0px 0px 0px 5px; padding-left:20px; background:url(../images/search-mag-ico.png) 0px 4px no-repeat; }
32
  /* Placeholder text in main section */
33
+ div.css-search div.em-search-main div.em-search-field input::-webkit-input-placeholder { /* WebKit browsers */ font-size:16px; line-height:16px; padding:3px 0px; border:none; color:#666; }
34
+ div.css-search div.em-search-main div.em-search-field input:-moz-placeholder { /* Mozilla Firefox 4 to 18 */ font-size:16px; line-height:16px; padding:8px; border:none; color:#666; }
35
+ div.css-search div.em-search-main div.em-search-field input::-moz-placeholder { /* Mozilla Firefox 19+ */ font-size:16px; line-height:16px; padding:8px; border:none; color:#666; }
36
+ div.css-search div.em-search-main div.em-search-field input:-ms-input-placeholder { /* Internet Explorer 10+ */ font-size:16px; line-height:16px; padding:8px; border:none; color:#666; }
37
  /* Geo field specifics */
38
  div.css-search.has-search-geo.has-search-term input.em-search-text, div.css-search.has-search-geo.has-search-term input.em-search-geo { width:40%; }
39
  .pac-container .pac-item { padding:4px 4px !important; }
264
  /* Time Picker */
265
  .em-time-input { width:7em;}
266
  .em-time-range .em-time-input.error, .em-time-input.error { border:#cc0000 1px solid; }
267
+ .ui-em_timepicker-wrapper{overflow-y:auto;max-height:150px;width:6.5em;background:#fff;border:1px solid #ddd;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);z-index:10052;margin:0}.ui-em_timepicker-wrapper.ui-em_timepicker-with-duration{width:13em}.ui-em_timepicker-wrapper.ui-em_timepicker-with-duration.ui-em_timepicker-step-30,.ui-em_timepicker-wrapper.ui-em_timepicker-with-duration.ui-em_timepicker-step-60{width:11em}.ui-em_timepicker-list,.ui-em_timepicker-list li{margin:0;padding:0;list-style:none}.ui-em_timepicker-duration{margin-left:5px;color:#888}.ui-em_timepicker-list:hover .ui-em_timepicker-duration{color:#888}.ui-em_timepicker-list li{padding:3px 0 3px 5px;cursor:pointer;white-space:nowrap;color:#000}.ui-em_timepicker-list:hover .ui-em_timepicker-selected{background:#fff;color:#000}.ui-em_timepicker-list .ui-em_timepicker-selected:hover,.ui-em_timepicker-list li:hover,li.ui-em_timepicker-selected{background:#1980ec;color:#fff}.ui-em_timepicker-list li:hover .ui-em_timepicker-duration,li.ui-em_timepicker-selected .ui-em_timepicker-duration{color:#ccc}.ui-em_timepicker-list li.ui-em_timepicker-disabled,.ui-em_timepicker-list li.ui-em_timepicker-disabled:hover,.ui-em_timepicker-list li.ui-em_timepicker-selected.ui-em_timepicker-disabled{color:#888;cursor:default}.ui-em_timepicker-list li.ui-em_timepicker-disabled:hover,.ui-em_timepicker-list li.ui-em_timepicker-selected.ui-em_timepicker-disabled{background:#f2f2f2}
multilingual/em-ml-bookings.php CHANGED
@@ -24,7 +24,10 @@ class EM_ML_Bookings {
24
  EM_ML_Bookings::$ignore_post_ids[] = $post_id;
25
  });
26
  }
27
-
 
 
 
28
  public static function em_booking_email_before_send( $EM_Booking ){
29
  if( $EM_Booking->language && get_locale() !== $EM_Booking->language ){
30
  static::$displaying_locale = EM_ML::$current_language;
@@ -115,8 +118,8 @@ class EM_ML_Bookings {
115
  * @return EM_Event
116
  */
117
  public static function em_booking_get_event($EM_Event, $EM_Booking){
118
- if( EM_ML::get_the_language($EM_Event) != get_locale() ){
119
- $EM_Event = EM_ML::get_translation($EM_Event, get_locale());
120
  $EM_Booking->event = $EM_Event; // so that we always fire this filter each time get_event() is called
121
  }
122
  return $EM_Event;
24
  EM_ML_Bookings::$ignore_post_ids[] = $post_id;
25
  });
26
  }
27
+
28
+ /**
29
+ * @param EM_Booking $EM_Booking
30
+ */
31
  public static function em_booking_email_before_send( $EM_Booking ){
32
  if( $EM_Booking->language && get_locale() !== $EM_Booking->language ){
33
  static::$displaying_locale = EM_ML::$current_language;
118
  * @return EM_Event
119
  */
120
  public static function em_booking_get_event($EM_Event, $EM_Booking){
121
+ if( EM_ML::get_the_language($EM_Event) != $EM_Booking->language ){
122
+ $EM_Event = EM_ML::get_translation($EM_Event, $EM_Booking->language);
123
  $EM_Booking->event = $EM_Event; // so that we always fire this filter each time get_event() is called
124
  }
125
  return $EM_Event;
multilingual/em-ml-options.php CHANGED
@@ -139,6 +139,7 @@ class EM_ML_Options {
139
  'dbem_booking_button_msg_already_booked',
140
  'dbem_booking_button_msg_error',
141
  'dbem_booking_button_msg_full',
 
142
  'dbem_booking_button_msg_cancel',
143
  'dbem_booking_button_msg_canceling',
144
  'dbem_booking_button_msg_cancelled',
139
  'dbem_booking_button_msg_already_booked',
140
  'dbem_booking_button_msg_error',
141
  'dbem_booking_button_msg_full',
142
+ 'dbem_booking_button_msg_closed',
143
  'dbem_booking_button_msg_cancel',
144
  'dbem_booking_button_msg_canceling',
145
  'dbem_booking_button_msg_cancelled',
multilingual/em-ml.php CHANGED
@@ -111,6 +111,9 @@ class EM_ML{
111
  public static function switch_locale( $locale ){
112
  self::$current_language_restore = self::$current_language;
113
  switch_to_locale($locale);
 
 
 
114
  }
115
 
116
  public static function restore_locale(){
@@ -127,6 +130,23 @@ class EM_ML{
127
  }
128
  }
129
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130
  }
131
 
132
  /**
111
  public static function switch_locale( $locale ){
112
  self::$current_language_restore = self::$current_language;
113
  switch_to_locale($locale);
114
+ do_action('em_ml_switch_locale', $locale);
115
+ // short-circuit determininig the locale for EM-specific purposes
116
+ add_filter('pre_determine_locale', 'EM_ML::pre_determine_locale', 999999, 1);
117
  }
118
 
119
  public static function restore_locale(){
130
  }
131
  }
132
  }
133
+ do_action('em_ml_restore_locale', self::$current_language);
134
+ // short-circuit determininig the locale for EM-specific purposes
135
+ remove_filter('pre_determine_locale', 'EM_ML::pre_determine_locale', 999999);
136
+ }
137
+
138
+ /**
139
+ * Quirky fix for situations where admins are triggering something requiring translations in the backend whilst EM_ML has switched locales temporarily.
140
+ * For example, triggering an email booking resend in a translated language; In this case the loaded translation file will always be that of the admin
141
+ * preferred locale rather than the get_locale() which is not what we'd want in these situations. Therefore when switching language this hook is active.
142
+ * @param $locale
143
+ * @return mixed|string
144
+ */
145
+ public static function pre_determine_locale( $locale ){
146
+ if( is_admin() && EM_ML::$current_language_restore !== null ){
147
+ return self::$current_language;
148
+ }
149
+ return $locale;
150
  }
151
 
152
  /**
readme.txt CHANGED
@@ -4,8 +4,8 @@ Donate link: http://wp-events-plugin.com
4
  Tags: bookings, calendar, tickets, events, buddypress, event management, google maps, maps, locations, registration, zoom
5
  Text Domain: events-manager
6
  Requires at least: 5.2
7
- Tested up to: 5.7
8
- Stable tag: 5.9.11.3
9
  Requires PHP: 5.3
10
 
11
  Fully featured event registration management including recurring events, locations management, calendar, Google map integration, booking management
@@ -119,6 +119,33 @@ See our [FAQ](http://wp-events-plugin.com/documentation/faq/) page, which is upd
119
  6. Manage attendees with various booking reports
120
 
121
  == Changelog ==
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
122
  = 5.9.11.3 =
123
  * fixed issues with WooCommerce add-on circumventing currency formatting
124
  * changed various AJAX/Admin actions to fire on wp_loaded rather than init action to allow better plugin compatibility
4
  Tags: bookings, calendar, tickets, events, buddypress, event management, google maps, maps, locations, registration, zoom
5
  Text Domain: events-manager
6
  Requires at least: 5.2
7
+ Tested up to: 5.8
8
+ Stable tag: 5.10
9
  Requires PHP: 5.3
10
 
11
  Fully featured event registration management including recurring events, locations management, calendar, Google map integration, booking management
119
  6. Manage attendees with various booking reports
120
 
121
  == Changelog ==
122
+ = 5.10 =
123
+ * fixed a minor PHPMailer PHP warning tiggered when mailing errors occur
124
+ * fixed date validation errors restting available from/until times to 12AM for tickets
125
+ * fixed WP Fullcalendar style tweak for tip image
126
+ * removed loading of EM_Person upon construct of EM_Booking to prevent unecessary pre-loading
127
+ * fixed bookings closed text not being translatable by ML plugins
128
+ * fixed multilingual translation failures when triggering actions like ML booking emails as an admin
129
+ * added em_ml_swiitch_locale and em_ml_restore_locale actions for ML plugins that don't hook into WP's switch_locale
130
+ * fixed potential ML translation issues when switching translated event objects in a booking
131
+ * optimized translated event switching in booking objects
132
+ * added em_pre_taxonomy_template, em_pre_{taxonomy_name}_taxonomy_template and em_taxonomy_template
133
+ * added temporary fix for compatibility issue with/caused by BuddyBoss
134
+ * fixed PHP warnings caused by dev version update checks, also removed em_org_dev_version_slugs filter in place of em_org_dev_versions
135
+ * added em_bookings_single_details_footer filter
136
+ * added extra email trimming to prevent mail errors due to errant whitespaces
137
+ * added em_ticket_get_price_without_tax filter
138
+ * fixed #@_{...} placeholders still showing if end date is the same
139
+ * fixed email fatal errors when password reset is disabled by other plugins or custom code
140
+ * fixed caching issues with custom code hooking into em_event by firing the action before caching occurs
141
+ * fixed reported issues with Elementor by writing $content into event and location object post_content properties (kudos to @martinneumannat)
142
+ * fixed CZY currency symbols not being included
143
+ * fixed dbem_maps_text_format and potentially other formats retrieved via AJAX not being overridable using our em_formats_filter filter
144
+ * fixed bookings="0" not returning non-bookable events in shortcodes
145
+ * fixed google ical link using http://
146
+ * fixed EM_Person::get_summary() returning mixed up array key/values (props @duisterdenhaag)
147
+ * removed outline style rules from CSS to help with WCAG compliance
148
+
149
  = 5.9.11.3 =
150
  * fixed issues with WooCommerce add-on circumventing currency formatting
151
  * changed various AJAX/Admin actions to fire on wp_loaded rather than init action to allow better plugin compatibility