Events Manager - Version 5.9.5

Version Description

  • added new Google Maps display options to help prevent cost increases
  • fixed booking status emails getting resent when attempting to change status to same status
  • fixed potential consent issues with editing/validating bookings made by other registered users
  • fixed broken #_LATT custom field attributes for locations
  • fixed #_ATT placeholders with dropdown options not selecting default option if not defined
  • added em_locate_template_default filter to allow for further template overriding
  • fixed certain unsanitized permalink output on admin settings page
  • fixed weekly and daily recurrence creation inconsistencies when traversing DST change dates
Download this release

Release Info

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

Code changes from version 5.9.4 to 5.9.5

admin/settings/tabs/formats.php CHANGED
@@ -436,19 +436,10 @@
436
  <div class="handlediv" title="<?php __('Click to toggle', 'events-manager'); ?>"><br /></div><h3><span><?php _e ( 'Maps', 'events-manager'); ?> </span></h3>
437
  <div class="inside">
438
  <p class="em-boxheader"><?php echo sprintf(__('You can use Google Maps to show where your events are located. For more information on using maps, <a href="%s">see our documentation</a>.','events-manager'),'http://wp-events-plugin.com/documentation/google-maps/'); ?>
439
- <table class='form-table'>
440
- <?php $gmap_is_active = get_option ( 'dbem_gmap_is_active' ); ?>
441
  <tr valign="top">
442
- <th scope="row"><?php _e ( 'Enable Google Maps integration?', 'events-manager'); ?></th>
443
- <td>
444
- <?php _e ( 'Yes' ); ?> <input id="dbem_gmap_is_active_yes" name="dbem_gmap_is_active" type="radio" value="1" <?php echo ($gmap_is_active) ? "checked='checked'":''; ?> />
445
- <?php _e ( 'No' ); ?> <input name="dbem_gmap_is_active" type="radio" value="0" <?php echo ($gmap_is_active) ? '':"checked='checked'"; ?> /><br />
446
- <em><?php _e ( 'Check this option to enable Goggle Map integration.', 'events-manager')?></em>
447
- </td>
448
- <?php em_options_input_text(__('Google Maps API Browser Key','events-manager'), 'dbem_google_maps_browser_key', sprintf(__('Google Maps require an API key, please see our %s page for instructions on obtaining one.', 'events-manager'), sprintf('<a href="http://wp-events-plugin.com/documentation/google-maps/api-key/">%s</a>', __('documentation','events-manager')))); ?>
449
  <?php em_options_input_text(__('Default map width','events-manager'), 'dbem_map_default_width', sprintf(__('Can be in form of pixels or a percentage such as %s or %s.', 'events-manager'), '<code>100%</code>', '<code>100px</code>')); ?>
450
  <?php em_options_input_text(__('Default map height','events-manager'), 'dbem_map_default_height', sprintf(__('Can be in form of pixels or a percentage such as %s or %s.', 'events-manager'), '<code>100%</code>', '<code>100px</code>')); ?>
451
- <?php em_options_textarea(__('Google Maps Style', 'events-manager'), 'dbem_google_maps_styles', sprintf(__('You can add styles to your maps to give them a unique look. Build one using the %s or choose from the many free templates on %s paste the generated JSON code here.', 'events-manager'), '<a href="https://mapstyle.withgoogle.com/" target="_blank">'.__('Google Maps Styling Wizard', 'events-manager').'</a>', '<a href="https://snazzymaps.com/explore" target="_blank">Snazzy Maps</a>')); ?>
452
  </tr>
453
  <tr class="em-header"><td colspan="2">
454
  <h4><?php _e('Global Map Format','events-manager'); ?></h4>
436
  <div class="handlediv" title="<?php __('Click to toggle', 'events-manager'); ?>"><br /></div><h3><span><?php _e ( 'Maps', 'events-manager'); ?> </span></h3>
437
  <div class="inside">
438
  <p class="em-boxheader"><?php echo sprintf(__('You can use Google Maps to show where your events are located. For more information on using maps, <a href="%s">see our documentation</a>.','events-manager'),'http://wp-events-plugin.com/documentation/google-maps/'); ?>
439
+ <table class='form-table'>
 
440
  <tr valign="top">
 
 
 
 
 
 
 
441
  <?php em_options_input_text(__('Default map width','events-manager'), 'dbem_map_default_width', sprintf(__('Can be in form of pixels or a percentage such as %s or %s.', 'events-manager'), '<code>100%</code>', '<code>100px</code>')); ?>
442
  <?php em_options_input_text(__('Default map height','events-manager'), 'dbem_map_default_height', sprintf(__('Can be in form of pixels or a percentage such as %s or %s.', 'events-manager'), '<code>100%</code>', '<code>100px</code>')); ?>
 
443
  </tr>
444
  <tr class="em-header"><td colspan="2">
445
  <h4><?php _e('Global Map Format','events-manager'); ?></h4>
admin/settings/tabs/general.php CHANGED
@@ -96,12 +96,53 @@
96
  ?>
97
  </table>
98
 
99
- </div> <!-- . inside -->
100
  </div> <!-- .postbox -->
101
 
102
  <?php if ( !is_multisite() ){ em_admin_option_box_image_sizes(); } ?>
103
 
104
  <?php if ( !is_multisite() || (em_wp_is_super_admin() && !get_site_option('dbem_ms_global_caps')) ){ em_admin_option_box_caps(); } ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
 
106
  <div class="postbox" id="em-opt-event-submissions" >
107
  <div class="handlediv" title="<?php __('Click to toggle', 'events-manager'); ?>"><br /></div><h3><span><?php _e ( 'Event Submission Forms', 'events-manager'); ?></span></h3>
96
  ?>
97
  </table>
98
 
99
+ </div> <!-- . inside -->
100
  </div> <!-- .postbox -->
101
 
102
  <?php if ( !is_multisite() ){ em_admin_option_box_image_sizes(); } ?>
103
 
104
  <?php if ( !is_multisite() || (em_wp_is_super_admin() && !get_site_option('dbem_ms_global_caps')) ){ em_admin_option_box_caps(); } ?>
105
+
106
+ <div class="postbox" id="em-opt-google-maps" >
107
+ <div class="handlediv" title="<?php __('Click to toggle', 'events-manager'); ?>"><br /></div><h3><span><?php _e ( 'Google Maps and Location Services', 'events-manager'); ?></span></h3>
108
+ <div class="inside">
109
+ <div class="em-boxheader">
110
+ <p><?php esc_html_e('Google Maps API provides you with ways to display maps of your locations and help site visitors find events near their desired locations.','events-manager'); ?></p>
111
+ <p style="font-weight: bold; color:#ca4a1f;">
112
+ <?php
113
+ $msg = esc_html__('Google may charge you for usage, depending on how much traffic your site receives. For more information about how and where Events Manager uses the Google Maps API, and how to manage costs, please see our %s page.', 'events-manager');
114
+ echo sprintf($msg, '<a href="https://wp-events-plugin.com/documentation/google-maps/api-usage/?utm_source=plugin&utm_medium=settings&utm_campaign=gmaps-general">'.esc_html__('documentation', 'events-manager').'</a>');
115
+ ?>
116
+ </p>
117
+ </div>
118
+ <table class="form-table">
119
+ <?php
120
+ em_options_radio_binary( esc_html__( 'Enable Google Maps integration?', 'events-manager'), 'dbem_gmap_is_active', esc_html__( 'Check this option to enable Google Map integration.', 'events-manager'), '', '.em-google-maps-enabled' );
121
+ ?>
122
+ <tbody class="form-table em-google-maps-enabled">
123
+ <?php
124
+ em_options_input_text(__('Google Maps API Browser Key','events-manager'), 'dbem_google_maps_browser_key', sprintf(__('Google Maps require an API key, please see our %s page for instructions on obtaining one.', 'events-manager'), '<a href="https://wp-events-plugin.com/documentation/google-maps/api-key/?utm_source=plugin&utm_medium=settings&utm_campaign=gmaps-api-key">'.esc_html__('documentation','events-manager').'</a>'));
125
+ $google_map_options = apply_filters('em_settings_google_maps_options', array(
126
+ 'dynamic' => _x('Dynamic', 'Google Map Type', 'events-manager'),
127
+ 'embed' => _x('Embedded', 'Google Map Type', 'events-manager')
128
+ ));
129
+ $google_map_options_pro = !defined('EMP_VERSION') || EMP_VERSION < 2.64 ? '<strong>'.sprintf(__('Upgrade to %s for more options!', 'events-manager'), '<a target="_blank" href="https://wp-events-plugin.com/google-maps/static-maps/?utm_source=plugin&utm_medium=settings&utm_campaign=gmaps-types">Events Manager Pro</a>').'</strong>' : '';
130
+ $google_map_options_desc = sprintf(__('Google offers different map displays, each with varying prices and free usage allowance. See our %s page for more information on these display options.', 'events-manager'), '<a href="https://wp-events-plugin.com/google-maps/map-types/?utm_source=plugin&utm_medium=settings&utm_campaign=gmaps-types">'.__('documentation', 'events-manager').'</a>') .' '. $google_map_options_pro;
131
+ em_options_select(__('Google Map Type', 'events-manager'), 'dbem_gmap_type', $google_map_options, $google_map_options_desc);
132
+ $embed_options = array('place' => __('Location name and address', 'events-manager'), 'address' => __('Address only', 'events-manager'), 'coordinates' => __('Location coordinates', 'events-manager'));
133
+ em_options_select(__('Embed Display Type', 'events-manager'), 'dbem_gmap_embed_type', $embed_options, __('When displaying embedded maps for a location, choose what information Google will use to generate a map from, each producing varying results.', 'events-manager'));
134
+ em_options_textarea(__('Google Maps Style', 'events-manager'), 'dbem_google_maps_styles', sprintf(__('You can add styles to your maps to give them a unique look. Build one using the %s or choose from the many free templates on %s paste the generated JSON code here.', 'events-manager'), '<a href="https://mapstyle.withgoogle.com/" target="_blank">'.esc_html__('Google Maps Styling Wizard', 'events-manager').'</a>', '<a href="https://snazzymaps.com/explore" target="_blank">Snazzy Maps</a>'));
135
+ ?>
136
+ </tbody>
137
+ <tbody class="form-table em-google-maps-enabled em-google-maps-static">
138
+ <?php do_action('em_settings_google_maps_general'); ?>
139
+ </tbody>
140
+ <?php
141
+ echo $save_button;
142
+ ?>
143
+ </table>
144
+ </div> <!-- . inside -->
145
+ </div> <!-- .postbox -->
146
 
147
  <div class="postbox" id="em-opt-event-submissions" >
148
  <div class="handlediv" title="<?php __('Click to toggle', 'events-manager'); ?>"><br /></div><h3><span><?php _e ( 'Event Submission Forms', 'events-manager'); ?></span></h3>
admin/settings/tabs/pages.php CHANGED
@@ -16,15 +16,15 @@
16
  <p class="em-boxheader"><?php _e('You can change the permalink structure of your events, locations, categories and tags here. Be aware that you may want to set up redirects if you change your permalink structures to maintain SEO rankings.','events-manager'); ?></p>
17
  <table class="form-table">
18
  <?php
19
- em_options_input_text ( __( 'Events', 'events-manager'), 'dbem_cp_events_slug', sprintf(__('e.g. %s - you can use / Separators too', 'events-manager'), '<strong>'.home_url().'/<code>'.get_option('dbem_cp_events_slug',EM_POST_TYPE_EVENT_SLUG).'</code>/2012-olympics/</strong>'), EM_POST_TYPE_EVENT_SLUG );
20
  if( get_option('dbem_locations_enabled') && !(EM_MS_GLOBAL && get_site_option('dbem_ms_mainblog_locations') && !is_main_site()) ){
21
- em_options_input_text ( __( 'Locations', 'events-manager'), 'dbem_cp_locations_slug', sprintf(__('e.g. %s - you can use / Separators too', 'events-manager'), '<strong>'.home_url().'/<code>'.get_option('dbem_cp_locations_slug',EM_POST_TYPE_LOCATION_SLUG).'</code>/wembley-stadium/</strong>'), EM_POST_TYPE_LOCATION_SLUG );
22
  }
23
  if( get_option('dbem_categories_enabled') && !(EM_MS_GLOBAL && !is_main_site()) ){
24
- em_options_input_text ( __( 'Event Categories', 'events-manager'), 'dbem_taxonomy_category_slug', sprintf(__('e.g. %s - you can use / Separators too', 'events-manager'), '<strong>'.home_url().'/<code>'.get_option('dbem_taxonomy_category_slug',EM_TAXONOMY_CATEGORY_SLUG).'</code>/sports/</strong>'), EM_TAXONOMY_CATEGORY_SLUG );
25
  }
26
  if( get_option('dbem_tags_enabled') ){
27
- em_options_input_text ( __( 'Event Tags', 'events-manager'), 'dbem_taxonomy_tag_slug', sprintf(__('e.g. %s - you can use / Separators too', 'events-manager'), '<strong>'.home_url().'/<code>'.get_option('dbem_taxonomy_tag_slug',EM_TAXONOMY_TAG_SLUG).'</code>/running/</strong>'), EM_TAXONOMY_TAG_SLUG );
28
  }
29
  echo $save_button;
30
  ?>
@@ -72,7 +72,7 @@
72
  <tr class="em-header">
73
  <td colspan="2">
74
  <h4><?php echo sprintf(__('WordPress %s Archives','events-manager'), __('Event','events-manager')); ?></h4>
75
- <p><?php echo sprintf(__('%s custom post types can have archives, just like normal WordPress posts. If enabled, should you visit your base slug url %s and you will see an post-formatted archive of previous %s', 'events-manager'), __('Event','events-manager'), '<code>'.home_url().'/'.get_option('dbem_cp_events_slug',EM_POST_TYPE_EVENT_SLUG).'/</code>', __('events','events-manager')); ?></p>
76
  <p><?php echo sprintf(__('Note that assigning a %s page above will override this archive if the URLs collide (which is the default setting, and is recommended for maximum plugin compatibility). You can have both at the same time, but you must ensure that your page and %s slugs are different.','events-manager'), __('events','events-manager'), __('event','events-manager')); ?></p>
77
  </td>
78
  </tr>
@@ -256,7 +256,7 @@
256
  <tr class="em-header">
257
  <td colspan="2">
258
  <h4><?php echo sprintf(__('WordPress %s Archives','events-manager'), __('Location','events-manager')); ?></h4>
259
- <p><?php echo sprintf(__('%s custom post types can have archives, just like normal WordPress posts. If enabled, should you visit your base slug url %s and you will see an post-formatted archive of previous %s', 'events-manager'), __('Location','events-manager'), '<code>'.home_url().'/'.get_option('dbem_cp_locations_slug',EM_POST_TYPE_LOCATION_SLUG).'/</code>', __('locations','events-manager')); ?></p>
260
  <p><?php echo sprintf(__('Note that assigning a %s page above will override this archive if the URLs collide (which is the default settings, and is recommended for maximum plugin compatibility). You can have both at the same time, but you must ensure that your page and %s slugs are different.','events-manager'), __('locations','events-manager'), __('location','events-manager')); ?></p>
261
  </td>
262
  </tr>
16
  <p class="em-boxheader"><?php _e('You can change the permalink structure of your events, locations, categories and tags here. Be aware that you may want to set up redirects if you change your permalink structures to maintain SEO rankings.','events-manager'); ?></p>
17
  <table class="form-table">
18
  <?php
19
+ em_options_input_text ( __( 'Events', 'events-manager'), 'dbem_cp_events_slug', sprintf(__('e.g. %s - you can use / Separators too', 'events-manager'), '<strong>'.home_url().'/<code>'.esc_html(get_option('dbem_cp_events_slug',EM_POST_TYPE_EVENT_SLUG)).'</code>/2012-olympics/</strong>'), EM_POST_TYPE_EVENT_SLUG );
20
  if( get_option('dbem_locations_enabled') && !(EM_MS_GLOBAL && get_site_option('dbem_ms_mainblog_locations') && !is_main_site()) ){
21
+ em_options_input_text ( __( 'Locations', 'events-manager'), 'dbem_cp_locations_slug', sprintf(__('e.g. %s - you can use / Separators too', 'events-manager'), '<strong>'.home_url().'/<code>'.esc_html(get_option('dbem_cp_locations_slug',EM_POST_TYPE_LOCATION_SLUG)).'</code>/wembley-stadium/</strong>'), EM_POST_TYPE_LOCATION_SLUG );
22
  }
23
  if( get_option('dbem_categories_enabled') && !(EM_MS_GLOBAL && !is_main_site()) ){
24
+ em_options_input_text ( __( 'Event Categories', 'events-manager'), 'dbem_taxonomy_category_slug', sprintf(__('e.g. %s - you can use / Separators too', 'events-manager'), '<strong>'.home_url().'/<code>'.esc_html(get_option('dbem_taxonomy_category_slug',EM_TAXONOMY_CATEGORY_SLUG)).'</code>/sports/</strong>'), EM_TAXONOMY_CATEGORY_SLUG );
25
  }
26
  if( get_option('dbem_tags_enabled') ){
27
+ em_options_input_text ( __( 'Event Tags', 'events-manager'), 'dbem_taxonomy_tag_slug', sprintf(__('e.g. %s - you can use / Separators too', 'events-manager'), '<strong>'.home_url().'/<code>'.esc_html(get_option('dbem_taxonomy_tag_slug',EM_TAXONOMY_TAG_SLUG)).'</code>/running/</strong>'), EM_TAXONOMY_TAG_SLUG );
28
  }
29
  echo $save_button;
30
  ?>
72
  <tr class="em-header">
73
  <td colspan="2">
74
  <h4><?php echo sprintf(__('WordPress %s Archives','events-manager'), __('Event','events-manager')); ?></h4>
75
+ <p><?php echo sprintf(__('%s custom post types can have archives, just like normal WordPress posts. If enabled, should you visit your base slug url %s and you will see an post-formatted archive of previous %s', 'events-manager'), __('Event','events-manager'), '<code>'.home_url().'/'.esc_html(get_option('dbem_cp_events_slug',EM_POST_TYPE_EVENT_SLUG)).'/</code>', __('events','events-manager')); ?></p>
76
  <p><?php echo sprintf(__('Note that assigning a %s page above will override this archive if the URLs collide (which is the default setting, and is recommended for maximum plugin compatibility). You can have both at the same time, but you must ensure that your page and %s slugs are different.','events-manager'), __('events','events-manager'), __('event','events-manager')); ?></p>
77
  </td>
78
  </tr>
256
  <tr class="em-header">
257
  <td colspan="2">
258
  <h4><?php echo sprintf(__('WordPress %s Archives','events-manager'), __('Location','events-manager')); ?></h4>
259
+ <p><?php echo sprintf(__('%s custom post types can have archives, just like normal WordPress posts. If enabled, should you visit your base slug url %s and you will see an post-formatted archive of previous %s', 'events-manager'), __('Location','events-manager'), '<code>'.home_url().'/'.esc_html(get_option('dbem_cp_locations_slug',EM_POST_TYPE_LOCATION_SLUG)).'/</code>', __('locations','events-manager')); ?></p>
260
  <p><?php echo sprintf(__('Note that assigning a %s page above will override this archive if the URLs collide (which is the default settings, and is recommended for maximum plugin compatibility). You can have both at the same time, but you must ensure that your page and %s slugs are different.','events-manager'), __('locations','events-manager'), __('location','events-manager')); ?></p>
261
  </td>
262
  </tr>
classes/em-booking.php CHANGED
@@ -936,7 +936,7 @@ class EM_Booking extends EM_Object{
936
  $result = $wpdb->query($wpdb->prepare('UPDATE '.EM_BOOKINGS_TABLE.' SET booking_status=%d WHERE booking_id=%d', array($status, $this->booking_id)));
937
  if($result !== false){
938
  $this->feedback_message = sprintf(__('Booking %s.','events-manager'), $action_string);
939
- if( $email ){
940
  if( $this->email() ){
941
  if( $this->mails_sent > 0 ){
942
  $this->feedback_message .= " ".__('Email Sent.','events-manager');
936
  $result = $wpdb->query($wpdb->prepare('UPDATE '.EM_BOOKINGS_TABLE.' SET booking_status=%d WHERE booking_id=%d', array($status, $this->booking_id)));
937
  if($result !== false){
938
  $this->feedback_message = sprintf(__('Booking %s.','events-manager'), $action_string);
939
+ if( $email && $this->previous_status != $this->booking_status ){ //email if status has changed
940
  if( $this->email() ){
941
  if( $this->mails_sent > 0 ){
942
  $this->feedback_message .= " ".__('Email Sent.','events-manager');
classes/em-event.php CHANGED
@@ -1762,7 +1762,8 @@ class EM_Event extends EM_Object{
1762
  $attString = $this->event_attributes[$attRef];
1763
  }elseif( !empty($results[3][$resultKey]) ){
1764
  //Check to see if we have a second set of braces;
1765
- $attString = $results[3][$resultKey];
 
1766
  }elseif( !empty($attributes['values'][$attRef][0]) ){
1767
  $attString = $attributes['values'][$attRef][0];
1768
  }
@@ -2851,10 +2852,10 @@ class EM_Event extends EM_Object{
2851
  switch ( $this->recurrence_freq ){ /* @var EM_DateTime $current_date */
2852
  case 'daily':
2853
  //If daily, it's simple. Get start date, add interval timestamps to that and create matching day for each interval until end date.
2854
- $current_date = $start_date;
2855
- while( $current_date <= $end_date ){
2856
- $matching_days[] = $current_date;
2857
- $current_date = $current_date + (DAY_IN_SECONDS * $this->recurrence_interval);
2858
  }
2859
  break;
2860
  case 'weekly':
@@ -2872,11 +2873,12 @@ class EM_Event extends EM_Object{
2872
  //for each day of eventful days in week 1, add 7 days * weekly intervals
2873
  foreach ($start_weekday_dates as $weekday_date){
2874
  //Loop weeks by interval until we reach or surpass end date
2875
- while($weekday_date <= $end_date){
2876
- if( $weekday_date >= $start_date && $weekday_date <= $end_date ){
2877
- $matching_days[] = $weekday_date;
 
2878
  }
2879
- $weekday_date = $weekday_date + (WEEK_IN_SECONDS * $this->recurrence_interval);
2880
  }
2881
  }//done!
2882
  break;
1762
  $attString = $this->event_attributes[$attRef];
1763
  }elseif( !empty($results[3][$resultKey]) ){
1764
  //Check to see if we have a second set of braces;
1765
+ $attStringArray = explode('|', $results[3][$resultKey]);
1766
+ $attString = $attStringArray[0];
1767
  }elseif( !empty($attributes['values'][$attRef][0]) ){
1768
  $attString = $attributes['values'][$attRef][0];
1769
  }
2852
  switch ( $this->recurrence_freq ){ /* @var EM_DateTime $current_date */
2853
  case 'daily':
2854
  //If daily, it's simple. Get start date, add interval timestamps to that and create matching day for each interval until end date.
2855
+ $current_date = $this->start()->copy()->setTime(0,0,0);
2856
+ while( $current_date->getTimestamp() <= $end_date ){
2857
+ $matching_days[] = $current_date->getTimestamp();
2858
+ $current_date->add('P'. $this->recurrence_interval .'D');
2859
  }
2860
  break;
2861
  case 'weekly':
2873
  //for each day of eventful days in week 1, add 7 days * weekly intervals
2874
  foreach ($start_weekday_dates as $weekday_date){
2875
  //Loop weeks by interval until we reach or surpass end date
2876
+ $current_date->setTimestamp($weekday_date);
2877
+ while($current_date->getTimestamp() <= $end_date){
2878
+ if( $current_date->getTimestamp() >= $start_date && $current_date->getTimestamp() <= $end_date ){
2879
+ $matching_days[] = $current_date->getTimestamp();
2880
  }
2881
+ $current_date->add('P'. ($this->recurrence_interval * 7 ) .'D');
2882
  }
2883
  }//done!
2884
  break;
classes/em-location.php CHANGED
@@ -130,8 +130,8 @@ class EM_Location extends EM_Object {
130
 
131
  /**
132
  * Gets data from POST (default), supplied array, or from the database if an ID is supplied
133
- * @param $location_data
134
- * @param $search_by can be set to post_id or a number for a blog id if in ms mode with global tables, default is location_id
135
  * @return null
136
  */
137
  function __construct($id = false, $search_by = 'location_id' ) {
@@ -205,7 +205,7 @@ class EM_Location extends EM_Object {
205
  foreach($location_meta as $location_meta_key => $location_meta_val){
206
  $field_name = substr($location_meta_key, 1);
207
  if($location_meta_key[0] != '_'){
208
- $this->event_attributes[$location_meta_key] = ( is_array($location_meta_val) ) ? $location_meta_val[0]:$location_meta_val;
209
  }elseif( is_string($field_name) && !in_array($field_name, $this->post_fields) ){
210
  if( array_key_exists($field_name, $this->fields) ){
211
  $this->$field_name = $location_meta_val[0];
@@ -459,6 +459,7 @@ class EM_Location extends EM_Object {
459
  }
460
  }
461
  }
 
462
  $this->get_status();
463
  $this->location_status = (count($this->errors) == 0) ? $this->location_status:null; //set status at this point, it's either the current status, or if validation fails, null
464
  //Save to em_locations table
@@ -820,14 +821,22 @@ class EM_Location extends EM_Object {
820
  //This is for the custom attributes
821
  preg_match_all('/#_LATT\{([^}]+)\}(\{([^}]+)\})?/', $location_string, $results);
822
  foreach($results[0] as $resultKey => $result) {
 
 
 
 
 
823
  //Strip string of placeholder and just leave the reference
824
  $attRef = substr( substr($result, 0, strpos($result, '}')), 7 );
825
  $attString = '';
826
- if( is_array($this->location_attributes) && array_key_exists($attRef, $this->location_attributes) && !empty($this->location_attributes[$attRef]) ){
827
  $attString = $this->location_attributes[$attRef];
828
  }elseif( !empty($results[3][$resultKey]) ){
829
  //Check to see if we have a second set of braces;
830
- $attString = $results[3][$resultKey];
 
 
 
831
  }
832
  $attString = apply_filters('em_location_output_placeholder', $attString, $this, $result, $target);
833
  $location_string = str_replace($result, $attString ,$location_string );
@@ -1072,4 +1081,23 @@ class EM_Location extends EM_Object {
1072
  if( !empty($this->location_region) ) $location_array[] = $this->location_region;
1073
  return implode($glue, $location_array);
1074
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1075
  }
130
 
131
  /**
132
  * Gets data from POST (default), supplied array, or from the database if an ID is supplied
133
+ * @param WP_Post|int|false $id
134
+ * @param $search_by - Can be post_id or a number for a blog id if in ms mode with global tables, default is location_id
135
  * @return null
136
  */
137
  function __construct($id = false, $search_by = 'location_id' ) {
205
  foreach($location_meta as $location_meta_key => $location_meta_val){
206
  $field_name = substr($location_meta_key, 1);
207
  if($location_meta_key[0] != '_'){
208
+ $this->location_attributes[$location_meta_key] = ( is_array($location_meta_val) ) ? $location_meta_val[0]:$location_meta_val;
209
  }elseif( is_string($field_name) && !in_array($field_name, $this->post_fields) ){
210
  if( array_key_exists($field_name, $this->fields) ){
211
  $this->$field_name = $location_meta_val[0];
459
  }
460
  }
461
  }
462
+ //refresh status
463
  $this->get_status();
464
  $this->location_status = (count($this->errors) == 0) ? $this->location_status:null; //set status at this point, it's either the current status, or if validation fails, null
465
  //Save to em_locations table
821
  //This is for the custom attributes
822
  preg_match_all('/#_LATT\{([^}]+)\}(\{([^}]+)\})?/', $location_string, $results);
823
  foreach($results[0] as $resultKey => $result) {
824
+ //check that we haven't mistakenly captured a closing bracket in second bracket set
825
+ if( !empty($results[3][$resultKey]) && $results[3][$resultKey][0] == '/' ){
826
+ $result = $results[0][$resultKey] = str_replace($results[2][$resultKey], '', $result);
827
+ $results[3][$resultKey] = $results[2][$resultKey] = '';
828
+ }
829
  //Strip string of placeholder and just leave the reference
830
  $attRef = substr( substr($result, 0, strpos($result, '}')), 7 );
831
  $attString = '';
832
+ if( is_array($this->location_attributes) && array_key_exists($attRef, $this->location_attributes) ){
833
  $attString = $this->location_attributes[$attRef];
834
  }elseif( !empty($results[3][$resultKey]) ){
835
  //Check to see if we have a second set of braces;
836
+ $attStringArray = explode('|', $results[3][$resultKey]);
837
+ $attString = $attStringArray[0];
838
+ }elseif( !empty($attributes['values'][$attRef][0]) ){
839
+ $attString = $attributes['values'][$attRef][0];
840
  }
841
  $attString = apply_filters('em_location_output_placeholder', $attString, $this, $result, $target);
842
  $location_string = str_replace($result, $attString ,$location_string );
1081
  if( !empty($this->location_region) ) $location_array[] = $this->location_region;
1082
  return implode($glue, $location_array);
1083
  }
1084
+
1085
+ function get_google_maps_embed_url(){
1086
+ //generate the map url
1087
+ $latlng = $this->location_latitude.','.$this->location_longitude;
1088
+ $args = apply_filters('em_location_google_maps_embed_args', array(
1089
+ 'maptype' => 'roadmap',
1090
+ 'zoom' => 15,
1091
+ 'key' => get_option('dbem_google_maps_browser_key')
1092
+ ), $this);
1093
+ if( get_option('dbem_gmap_embed_type') == 'place' ){
1094
+ $args['q'] = $this->location_name.', '. $this->get_full_address();
1095
+ }elseif( get_option('dbem_gmap_embed_type') == 'address' ){
1096
+ $args['q'] = $this->get_full_address();
1097
+ }else{
1098
+ $args['q'] = $latlng;
1099
+ }
1100
+ $url = add_query_arg( $args, "https://www.google.com/maps/embed/v1/place");
1101
+ return apply_filters('em_location_get_google_maps_embed_url', $url, $this);
1102
+ }
1103
  }
em-data-privacy.php CHANGED
@@ -28,8 +28,7 @@ function em_data_privacy_consent_checkbox( $EM_Object = false ){
28
  function em_data_privacy_consent_hooks(){
29
  //BOOKINGS
30
  if( get_option('dbem_data_privacy_consent_bookings') == 1 || ( get_option('dbem_data_privacy_consent_bookings') == 2 && !is_user_logged_in() ) ){
31
- add_action('em_booking_form_footer', 'em_data_privacy_bookings_consent_checkbox', 9, 1);
32
- function em_data_privacy_bookings_consent_checkbox(){ em_data_privacy_consent_checkbox(); } //remove passed argument since it's an EM_Event and we'll confuse with submission form
33
  add_filter('em_booking_get_post', 'em_data_privacy_consent_booking_get_post', 10, 2);
34
  add_filter('em_booking_validate', 'em_data_privacy_consent_booking_validate', 10, 2);
35
  add_filter('em_booking_save', 'em_data_privacy_consent_booking_save', 10, 2);
@@ -90,9 +89,9 @@ function em_data_privacy_consent_booking_get_post( $result, $EM_Booking ){
90
  * @return bool
91
  */
92
  function em_data_privacy_consent_booking_validate( $result, $EM_Booking ){
93
- if( is_user_logged_in() ){
94
  //check if consent was previously given and ignore if settings dictate so
95
- $consent_given_already = get_user_meta( get_current_user_id(), 'em_data_privacy_consent', true );
96
  if( !empty($consent_given_already) && get_option('dbem_data_privacy_consent_remember') == 1 ) return $result; //ignore if consent given as per settings
97
  }
98
  if( empty($EM_Booking->booking_meta['consent']) ){
28
  function em_data_privacy_consent_hooks(){
29
  //BOOKINGS
30
  if( get_option('dbem_data_privacy_consent_bookings') == 1 || ( get_option('dbem_data_privacy_consent_bookings') == 2 && !is_user_logged_in() ) ){
31
+ add_action('em_booking_form_footer', 'em_data_privacy_consent_checkbox', 9, 0); //supply 0 args since arg is $EM_Event and callback will think it's an event submission form
 
32
  add_filter('em_booking_get_post', 'em_data_privacy_consent_booking_get_post', 10, 2);
33
  add_filter('em_booking_validate', 'em_data_privacy_consent_booking_validate', 10, 2);
34
  add_filter('em_booking_save', 'em_data_privacy_consent_booking_save', 10, 2);
89
  * @return bool
90
  */
91
  function em_data_privacy_consent_booking_validate( $result, $EM_Booking ){
92
+ if( is_user_logged_in() && $EM_Booking->person_id == get_current_user_id() ){
93
  //check if consent was previously given and ignore if settings dictate so
94
+ $consent_given_already = get_user_meta( $EM_Booking->person_id, 'em_data_privacy_consent', true );
95
  if( !empty($consent_given_already) && get_option('dbem_data_privacy_consent_remember') == 1 ) return $result; //ignore if consent given as per settings
96
  }
97
  if( empty($EM_Booking->booking_meta['consent']) ){
em-install.php CHANGED
@@ -1084,6 +1084,13 @@ function em_upgrade_current_installation(){
1084
  $EM_Admin_Notice = new EM_Admin_Notice(array( 'name' => 'gdpr_update', 'who' => 'admin', 'where' => 'all', 'message' => $message ));
1085
  EM_Admin_Notices::add($EM_Admin_Notice, is_multisite());
1086
  }
 
 
 
 
 
 
 
1087
  }
1088
 
1089
  function em_set_mass_caps( $roles, $caps ){
1084
  $EM_Admin_Notice = new EM_Admin_Notice(array( 'name' => 'gdpr_update', 'who' => 'admin', 'where' => 'all', 'message' => $message ));
1085
  EM_Admin_Notices::add($EM_Admin_Notice, is_multisite());
1086
  }
1087
+ if( get_option('dbem_version') != '' && get_option('dbem_version') < 5.95 ){
1088
+ $message = esc_html__('Google has introduced new pricing for displaying maps on your site. If you have moderate traffic levels, this may likely affect you with surprise and unexpected costs!', 'events-manager');
1089
+ $message2 = esc_html__('Events Manager has implemented multiple ways to help prevent or reduce these costs drastically, please check our %s page for more information.', 'events-manager');
1090
+ $message2 = sprintf($message2, '<a href="https://wp-events-plugin.com/documentation/google-maps/api-usage/?utm_source=plugin&utm_source=medium=settings&utm_campaign=gmaps-update">'.esc_html__('documentation', 'events-manager') .'</a>');
1091
+ $EM_Admin_Notice = new EM_Admin_Notice(array( 'name' => 'gdpr_update', 'who' => 'admin', 'where' => 'all', 'message' => "<p>$message</p><p>$message2</p>" ));
1092
+ EM_Admin_Notices::add($EM_Admin_Notice, is_multisite());
1093
+ }
1094
  }
1095
 
1096
  function em_set_mass_caps( $roles, $caps ){
events-manager.php CHANGED
@@ -1,7 +1,7 @@
1
  <?php
2
  /*
3
  Plugin Name: Events Manager
4
- Version: 5.9.4
5
  Plugin URI: http://wp-events-plugin.com
6
  Description: Event registration and booking management for WordPress. Recurring events, locations, google maps, rss, ical, booking registration and more!
7
  Author: Marcus Sykes
@@ -28,8 +28,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
28
  */
29
 
30
  // Setting constants
31
- define('EM_VERSION', 5.94); //self expanatory
32
- define('EM_PRO_MIN_VERSION', 2.392); //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
35
  define('EM_DIR_URI', trailingslashit(plugins_url('',__FILE__))); //an absolute path to this directory
@@ -639,7 +639,8 @@ function em_locate_template( $template_name, $load=false, $the_args = array() )
639
  //First we check if there are overriding tempates in the child or parent theme
640
  $located = locate_template(array('plugins/events-manager/'.$template_name));
641
  if( !$located ){
642
- if ( file_exists(EM_DIR.'/templates/'.$template_name) ) {
 
643
  $located = EM_DIR.'/templates/'.$template_name;
644
  }
645
  }
1
  <?php
2
  /*
3
  Plugin Name: Events Manager
4
+ Version: 5.9.5
5
  Plugin URI: http://wp-events-plugin.com
6
  Description: Event registration and booking management for WordPress. Recurring events, locations, google maps, rss, ical, booking registration and more!
7
  Author: Marcus Sykes
28
  */
29
 
30
  // Setting constants
31
+ define('EM_VERSION', 5.95); //self expanatory
32
+ define('EM_PRO_MIN_VERSION', 2.64); //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
35
  define('EM_DIR_URI', trailingslashit(plugins_url('',__FILE__))); //an absolute path to this directory
639
  //First we check if there are overriding tempates in the child or parent theme
640
  $located = locate_template(array('plugins/events-manager/'.$template_name));
641
  if( !$located ){
642
+ $located = apply_filters('em_locate_template_default', $located, $template_name, $load, $the_args);
643
+ if ( !$located && file_exists(EM_DIR.'/templates/'.$template_name) ) {
644
  $located = EM_DIR.'/templates/'.$template_name;
645
  }
646
  }
includes/css/events_manager_admin.css CHANGED
@@ -72,7 +72,8 @@ table.events-table .category { color:#888; }
72
  .em-booking-form label { display:block; float:left; }
73
  .em-booking-form span.input-group input { margin-left:-20px; }
74
  .em-booking-form span.input-group { display:block; margin-left:120px; }
75
- .em-booking-form label { display:inline-block; width:100px; }
 
76
  .em-booking-form-details .em-booking-submit { width:auto; }
77
  /* Tickets */
78
  .em-tickets { margin-bottom:20px; }
72
  .em-booking-form label { display:block; float:left; }
73
  .em-booking-form span.input-group input { margin-left:-20px; }
74
  .em-booking-form span.input-group { display:block; margin-left:120px; }
75
+ .em-booking-form label { display:inline-block; width:100px; }
76
+ .em-booking-form p.input-field-data_privacy_consent label { display:block; width:100%; }
77
  .em-booking-form-details .em-booking-submit { width:auto; }
78
  /* Tickets */
79
  .em-tickets { margin-bottom:20px; }
readme.txt CHANGED
@@ -5,7 +5,7 @@ Tags: bookings, calendar, tickets, events, buddypress, event management, google
5
  Text Domain: events-manager
6
  Requires at least: 3.5
7
  Tested up to: 4.9.6
8
- Stable tag: 5.9.4
9
 
10
  Fully featured event registration management including recurring events, locations management, calendar, Google map integration, booking management
11
 
@@ -36,7 +36,7 @@ Version 5 now makes events and locations WordPress Custom Post Types, allowing f
36
  * Assign event locations and view events by location
37
  * Event categories
38
  * Easily create custom event attributes (e.g. dress code)
39
- * Google Maps
40
  * Advanced permissions - restrict user management of events and locations.
41
  * Widgets for Events, Locations and Calendars
42
  * Fine grained control of how every aspect of your events are shown on your site, easily modify templates from the settings pages and template files
@@ -103,13 +103,23 @@ See our [FAQ](http://wp-events-plugin.com/documentation/faq/) page, which is upd
103
  == Screenshots ==
104
 
105
  1. Event registration and user submitted events pending approval
106
- 2. Event ticketing and bookings forms, easily styleable.
107
  3. Multiple tickets with constraints and prices
108
  4. Locations with google map integration
109
  5. Event registration page
110
  6. Manage attendees with various booking reports
111
 
112
  == Changelog ==
 
 
 
 
 
 
 
 
 
 
113
  = 5.9.4 =
114
  * added em_rewrite_rules_array filter for final permalink rule manipulation
115
  * fixed privacy consent blocking certain actions such as single booking button and admin-side submissions
5
  Text Domain: events-manager
6
  Requires at least: 3.5
7
  Tested up to: 4.9.6
8
+ Stable tag: 5.9.5
9
 
10
  Fully featured event registration management including recurring events, locations management, calendar, Google map integration, booking management
11
 
36
  * Assign event locations and view events by location
37
  * Event categories
38
  * Easily create custom event attributes (e.g. dress code)
39
+ * Google Maps [(see our API usage recommendations)](https://wp-events-plugin.com/documentation/google-maps/api-usage/?utm_source=repo&utm_medium=readme&utm_campaign=gmaps-api)
40
  * Advanced permissions - restrict user management of events and locations.
41
  * Widgets for Events, Locations and Calendars
42
  * Fine grained control of how every aspect of your events are shown on your site, easily modify templates from the settings pages and template files
103
  == Screenshots ==
104
 
105
  1. Event registration and user submitted events pending approval
106
+ 2. Event ticketing and bookings forms, can be easily styled.
107
  3. Multiple tickets with constraints and prices
108
  4. Locations with google map integration
109
  5. Event registration page
110
  6. Manage attendees with various booking reports
111
 
112
  == Changelog ==
113
+ = 5.9.5 =
114
+ * added new Google Maps display options to help prevent cost increases
115
+ * fixed booking status emails getting resent when attempting to change status to same status
116
+ * fixed potential consent issues with editing/validating bookings made by other registered users
117
+ * fixed broken #_LATT custom field attributes for locations
118
+ * fixed #_ATT placeholders with dropdown options not selecting default option if not defined
119
+ * added em_locate_template_default filter to allow for further template overriding
120
+ * fixed certain unsanitized permalink output on admin settings page
121
+ * fixed weekly and daily recurrence creation inconsistencies when traversing DST change dates
122
+
123
  = 5.9.4 =
124
  * added em_rewrite_rules_array filter for final permalink rule manipulation
125
  * fixed privacy consent blocking certain actions such as single booking button and admin-side submissions
templates/placeholders/locationmap.php CHANGED
@@ -8,29 +8,39 @@
8
  */
9
  /* @var $EM_Location EM_Location */
10
  if ( get_option('dbem_gmap_is_active') && ( is_object($EM_Location) && $EM_Location->location_latitude != 0 && $EM_Location->location_longitude != 0 ) ) {
11
- //get dimensions with px or % added in
 
 
12
  $width = (!empty($args['width'])) ? $args['width']:get_option('dbem_map_default_width','400px');
13
- $width = preg_match('/(px)|%/', $width) ? $width:$width.'px';
14
  $height = (!empty($args['height'])) ? $args['height']:get_option('dbem_map_default_height','300px');
 
15
  $height = preg_match('/(px)|%/', $height) ? $height:$height.'px';
16
- //assign random number for element id reference
17
- $rand = substr(md5(rand().rand()),0,5);
18
- ?>
19
- <div class="em-location-map-container" style='position:relative; background: #CDCDCD; width: <?php echo $width ?>; height: <?php echo $height ?>;'>
20
- <div class='em-location-map' id='em-location-map-<?php echo $rand ?>' style="width: 100%; height: 100%;">
21
- <?php _e('Loading Map....', 'events-manager'); ?>
22
- </div>
23
- </div>
24
- <div class='em-location-map-info' id='em-location-map-info-<?php echo $rand ?>' style="display:none; visibility:hidden;">
25
- <div class="em-map-balloon" style="font-size:12px;">
26
- <div class="em-map-balloon-content" ><?php echo $EM_Location->output(get_option('dbem_location_baloon_format')); ?></div>
27
- </div>
28
- </div>
29
- <div class='em-location-map-coords' id='em-location-map-coords-<?php echo $rand ?>' style="display:none; visibility:hidden;">
30
- <span class="lat"><?php echo $EM_Location->location_latitude; ?></span>
31
- <span class="lng"><?php echo $EM_Location->location_longitude; ?></span>
32
- </div>
33
- <?php
 
 
 
 
 
 
 
 
34
  }elseif( is_object($EM_Location) && $EM_Location->location_latitude == 0 && $EM_Location->location_longitude == 0 ){
35
  echo '<i>'. __('Map Unavailable', 'events-manager') .'</i>';
36
  }
8
  */
9
  /* @var $EM_Location EM_Location */
10
  if ( get_option('dbem_gmap_is_active') && ( is_object($EM_Location) && $EM_Location->location_latitude != 0 && $EM_Location->location_longitude != 0 ) ) {
11
+ //assign random number for element id reference
12
+ $rand = substr(md5(rand().rand()),0,5);
13
+ //get dimensions with px or % added in
14
  $width = (!empty($args['width'])) ? $args['width']:get_option('dbem_map_default_width','400px');
 
15
  $height = (!empty($args['height'])) ? $args['height']:get_option('dbem_map_default_height','300px');
16
+ $width = preg_match('/(px)|%/', $width) ? $width:$width.'px';
17
  $height = preg_match('/(px)|%/', $height) ? $height:$height.'px';
18
+ //generate map depending on type
19
+ if( get_option('dbem_gmap_type') == 'embed' ){
20
+ $map_url = $EM_Location->get_google_maps_embed_url();
21
+ ?>
22
+ <div class="em-location-map-container" style='position:relative; background: #CDCDCD; width: <?php echo $width ?>; height: <?php echo $height ?>;'>
23
+ <iframe style="width:100%; height:100%;" frameborder="0" style="border:0" src="<?php echo esc_attr($map_url); ?>" allowfullscreen></iframe>
24
+ </div>
25
+ <?php
26
+ }else{
27
+ ?>
28
+ <div class="em-location-map-container" style='position:relative; background: #CDCDCD; width: <?php echo $width ?>; height: <?php echo $height ?>;'>
29
+ <div class='em-location-map' id='em-location-map-<?php echo $rand ?>' style="width: 100%; height: 100%;">
30
+ <?php _e('Loading Map....', 'events-manager'); ?>
31
+ </div>
32
+ </div>
33
+ <div class='em-location-map-info' id='em-location-map-info-<?php echo $rand ?>' style="display:none; visibility:hidden;">
34
+ <div class="em-map-balloon" style="font-size:12px;">
35
+ <div class="em-map-balloon-content" ><?php echo $EM_Location->output(get_option('dbem_location_baloon_format')); ?></div>
36
+ </div>
37
+ </div>
38
+ <div class='em-location-map-coords' id='em-location-map-coords-<?php echo $rand ?>' style="display:none; visibility:hidden;">
39
+ <span class="lat"><?php echo $EM_Location->location_latitude; ?></span>
40
+ <span class="lng"><?php echo $EM_Location->location_longitude; ?></span>
41
+ </div>
42
+ <?php
43
+ }
44
  }elseif( is_object($EM_Location) && $EM_Location->location_latitude == 0 && $EM_Location->location_longitude == 0 ){
45
  echo '<i>'. __('Map Unavailable', 'events-manager') .'</i>';
46
  }