Version Description
- added Data Privacy and GDPR features
- fixed user deletion not properly deleting events and not deleting locations if content is set to be deleted not reassigned
- added location attributes array to em_get_attributes filter
- fixed EM_MB_ICAL_WORDWRAP incorrectly not applying multibyte wordwraps if set to true
- added 'not_all_day' conditional placeholder
- made EM_Taxonomy_Terms objects countable
- fixed tag placeholders not getting parsed in event format such as #_TAGIMAGE
Download this release
Release Info
Developer | netweblogic |
Plugin | Events Manager |
Version | 5.9.3 |
Comparing to | |
See all releases |
Code changes from version 5.9.2 to 5.9.3
- admin/em-data-privacy.php +528 -0
- admin/em-options.php +79 -5
- admin/settings/tabs/general.php +2 -1
- classes/em-admin-notices.php +8 -2
- classes/em-booking.php +3 -0
- classes/em-datetime.php +5 -4
- classes/em-event.php +14 -3
- classes/em-notices.php +5 -1
- classes/em-people.php +6 -2
- classes/em-person.php +14 -2
- classes/em-taxonomy-terms.php +4 -1
- em-data-privacy.php +170 -0
- em-events.php +1 -1
- em-functions.php +1 -1
- em-ical.php +1 -1
- em-install.php +23 -5
- events-manager.php +4 -2
- includes/css/events_manager.css +2 -1
- readme.txt +24 -5
- templates/forms/event-editor.php +2 -2
- templates/forms/location-editor.php +2 -2
admin/em-data-privacy.php
ADDED
@@ -0,0 +1,528 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
* This file deals with new privacy tools included in WP 4.9.6 and in line with aiding users with conforming to the GPDR rules.
|
4 |
+
* Note that consent mechanisms are not included here and will be baked directly into the templates or Pro booking forms.
|
5 |
+
*/
|
6 |
+
class EM_Data_Privacy {
|
7 |
+
|
8 |
+
public static function init(){
|
9 |
+
add_action( 'admin_init', 'EM_Data_Privacy::privacy_policy_content' );
|
10 |
+
add_filter( 'wp_privacy_personal_data_erasers', 'EM_Data_Privacy::register_eraser', 10 );
|
11 |
+
add_filter( 'wp_privacy_personal_data_exporters', 'EM_Data_Privacy::register_exporter', 10 );
|
12 |
+
add_action( 'wp_privacy_personal_data_export_file_created', 'EM_Data_Privacy::export_cleanup');
|
13 |
+
}
|
14 |
+
|
15 |
+
public static function privacy_policy_content() {
|
16 |
+
if ( ! function_exists( 'wp_add_privacy_policy_content' ) ) {
|
17 |
+
return;
|
18 |
+
}
|
19 |
+
|
20 |
+
$content = array();
|
21 |
+
$content[] = sprintf(
|
22 |
+
__('We use Google services to generate maps and provide autocompletion when searching for events by location, which may collect data via your browser in accordance to Google\'s <a href="%s">privacy policy</a>.', 'events-manager' ),
|
23 |
+
'https://policies.google.com/privacy'
|
24 |
+
);
|
25 |
+
$content[] = __('We collect and store information you submit to us when making a booking, for the purpose of reserving your requested spaces at our event and maintaining a record of attendance.', 'events-manager' );
|
26 |
+
$content[] = __('We collect and store information you submit to us about events (and corresponding locations) you would like to publish on our site.', 'events-manager' );
|
27 |
+
$content[] = __('We may use cookies to temporarily store information about a booking in progress as well as any error/confirmation messages whilst submitting or managing your events and locations.', 'events-manager' );
|
28 |
+
|
29 |
+
wp_add_privacy_policy_content(
|
30 |
+
__('Events Manager', 'events-manager'),
|
31 |
+
wp_kses_post( '<p>'. implode('</p><p>', $content) .'</p>' )
|
32 |
+
);
|
33 |
+
}
|
34 |
+
|
35 |
+
public static function register_eraser( $erasers ) {
|
36 |
+
if( get_option('dbem_data_privacy_erase_bookings') ){
|
37 |
+
$erasers['events-manager-bookings'] = array(
|
38 |
+
'eraser_friendly_name' => __( 'Events Manager', 'events-manager' ) . ' - ' . __('Bookings', 'events-manager'),
|
39 |
+
'callback' => 'EM_Data_Privacy::erase_bookings',
|
40 |
+
);
|
41 |
+
}
|
42 |
+
if( get_option('dbem_data_privacy_erase_events') ){
|
43 |
+
$erasers['events-manager-recurring-events'] = array(
|
44 |
+
'eraser_friendly_name' => __( 'Events Manager', 'events-manager' ) . ' - ' . __('Recurring Events', 'events-manager'),
|
45 |
+
'callback' => 'EM_Data_Privacy::erase_recurring_events',
|
46 |
+
);
|
47 |
+
$erasers['events-manager-events'] = array(
|
48 |
+
'eraser_friendly_name' => __( 'Events Manager', 'events-manager' ) . ' - ' . __('Events', 'events-manager'),
|
49 |
+
'callback' => 'EM_Data_Privacy::erase_events',
|
50 |
+
);
|
51 |
+
}
|
52 |
+
if( get_option('dbem_data_privacy_erase_locations') ){
|
53 |
+
$erasers['events-manager-locations'] = array(
|
54 |
+
'eraser_friendly_name' => __( 'Events Manager', 'events-manager' ) . ' - ' . __('Locations', 'events-manager'),
|
55 |
+
'callback' => 'EM_Data_Privacy::erase_locations',
|
56 |
+
);
|
57 |
+
}
|
58 |
+
//in this case we don't register location deletion because we only need to handle anonymous events, locations submitted anonymously shouldn't have any personal data associated with it (unless a user submitted their home address anonymously!)
|
59 |
+
return $erasers;
|
60 |
+
}
|
61 |
+
|
62 |
+
public static function erase_bookings( $email_address, $page = 1 ) {
|
63 |
+
$page = (int) $page;
|
64 |
+
$limit = apply_filters('em_data_privacy_export_limit', 100);
|
65 |
+
$messages = array();
|
66 |
+
$user = get_user_by('email', $email_address); //is user or no-user?
|
67 |
+
|
68 |
+
if( $user !== false && get_option('dbem_data_privacy_erase_bookings') == 2 ){
|
69 |
+
//we're only deleting anonymous bookings, and letting WP handle user/booking deletion the traditional way for registered accounts
|
70 |
+
$done = true;
|
71 |
+
}else{
|
72 |
+
//get items to erase
|
73 |
+
$booking_ids = self::get_bookings($email_address, $page);
|
74 |
+
|
75 |
+
$items_removed = $items_retained = false;
|
76 |
+
foreach ( $booking_ids as $booking_id ) {
|
77 |
+
$EM_Booking = em_get_booking($booking_id);
|
78 |
+
if( $EM_Booking->delete() ){
|
79 |
+
$items_removed = true;
|
80 |
+
}else{
|
81 |
+
$items_retained = true;
|
82 |
+
$messages = array_merge($messages, $EM_Booking->get_errors());
|
83 |
+
}
|
84 |
+
}
|
85 |
+
if( $items_removed ) add_action('em_data_privacy_bookings_deleted', $booking_ids);
|
86 |
+
|
87 |
+
// Tell core if we have more comments to work on still
|
88 |
+
$done = count( $booking_ids ) < $limit;
|
89 |
+
}
|
90 |
+
return array(
|
91 |
+
'items_removed' => $items_removed,
|
92 |
+
'items_retained' => $items_retained, // always false in this example
|
93 |
+
'messages' => $messages, // no messages in this example
|
94 |
+
'done' => $done,
|
95 |
+
);
|
96 |
+
}
|
97 |
+
|
98 |
+
public static function erase_recurring_events( $email_address, $page = 1 ) {
|
99 |
+
return self::erase_events( $email_address, $page, 'event-recurring');
|
100 |
+
}
|
101 |
+
|
102 |
+
public static function erase_events( $email_address, $page = 1, $post_type = false ) {
|
103 |
+
$user = get_user_by('email', $email_address); //is user or no-user?
|
104 |
+
if( !$post_type ) $post_type = EM_POST_TYPE_EVENT; //default to event
|
105 |
+
$page = (int) $page;
|
106 |
+
$limit = apply_filters('em_data_privacy_erase_limit', 100);
|
107 |
+
$items_removed = $items_retained = false;
|
108 |
+
$messages = array();
|
109 |
+
|
110 |
+
if( $user !== false && get_option('dbem_data_privacy_erase_events') == 2 ){
|
111 |
+
//we're only deleting anonymous events, and letting WP handle CPT deletion the traditional way for registered accounts
|
112 |
+
$done = true;
|
113 |
+
}else{
|
114 |
+
//get event IDs submitted by user or "anonymously" by email
|
115 |
+
$events = self::get_events($email_address, $page, $post_type);
|
116 |
+
|
117 |
+
foreach( $events as $post_id ){
|
118 |
+
$EM_Event = em_get_event($post_id, 'post_id');
|
119 |
+
//erase the location first
|
120 |
+
$EM_Location = $EM_Event->get_location();
|
121 |
+
if( $EM_Location->location_id && get_option('dbem_data_privacy_erase_locations', 2) ){
|
122 |
+
if( ($user !== false && $EM_Location->location_owner == $user->ID) || ($user === false && $EM_Location->location_owner == get_option('dbem_events_anonymous_user')) ){
|
123 |
+
//depending on settings delete location only if it has no other events (eventually if we're deleting the last event of this user with the same location, it'll only have one event)
|
124 |
+
if( get_option('dbem_data_privacy_erase_locations', 2) == 1 || EM_Events::count(array('location_id' => $EM_Location->location_id, 'status' => 'all')) <= 1 ){
|
125 |
+
if( $EM_Location->delete(true) ){
|
126 |
+
$items_removed = true;
|
127 |
+
}else{
|
128 |
+
$items_retained = true;
|
129 |
+
}
|
130 |
+
}
|
131 |
+
}
|
132 |
+
}
|
133 |
+
//now erase the event
|
134 |
+
if( $EM_Event->delete(true) ){
|
135 |
+
$items_removed = true;
|
136 |
+
}else{
|
137 |
+
$items_retained = true;
|
138 |
+
$messages = array_merge($messages, $EM_Event->get_errors());
|
139 |
+
}
|
140 |
+
}
|
141 |
+
// Tell core if we have more comments to work on still
|
142 |
+
$done = count( $events ) < $limit;
|
143 |
+
}
|
144 |
+
return array(
|
145 |
+
'items_removed' => $items_removed,
|
146 |
+
'items_retained' => $items_retained, // always false in this example
|
147 |
+
'messages' => $messages, // no messages in this example
|
148 |
+
'done' => $done,
|
149 |
+
);
|
150 |
+
}
|
151 |
+
|
152 |
+
public static function erase_locations( $email_address, $page = 1 ) {
|
153 |
+
$user = get_user_by('email', $email_address); //is user or no-user?
|
154 |
+
$page = (int) $page;
|
155 |
+
$limit = apply_filters('em_data_privacy_erase_limit', 100);
|
156 |
+
$offset = ($page -1) * $limit;
|
157 |
+
$items_removed = $items_retained = false;
|
158 |
+
$messages = array();
|
159 |
+
|
160 |
+
if( get_option('dbem_data_privacy_erase_locations') == 2 ){ //for locations, we currently don't store anon info about locations
|
161 |
+
//we're only deleting anonymous events, and letting WP handle CPT deletion the traditional way for registered accounts
|
162 |
+
$done = true;
|
163 |
+
}elseif( $user !== false ){
|
164 |
+
$locations_count = 0;
|
165 |
+
foreach( EM_Locations::get(array('owner' => $user->ID, 'limit' => $limit, 'offset' => $offset, 'status'=>'everything')) as $EM_Location ){ /* @var EM_Location $EM_Location */
|
166 |
+
if( $EM_Location->delete(true) ){
|
167 |
+
$items_removed = true;
|
168 |
+
}else{
|
169 |
+
$items_retained = true;
|
170 |
+
$messages = array_merge($messages, $EM_Location->get_errors());
|
171 |
+
}
|
172 |
+
$locations_count++;
|
173 |
+
}
|
174 |
+
// Tell core if we have more comments to work on still
|
175 |
+
$done = $locations_count < $limit;
|
176 |
+
}
|
177 |
+
return array(
|
178 |
+
'items_removed' => $items_removed,
|
179 |
+
'items_retained' => $items_retained, // always false in this example
|
180 |
+
'messages' => $messages, // no messages in this example
|
181 |
+
'done' => $done,
|
182 |
+
);
|
183 |
+
}
|
184 |
+
|
185 |
+
public static function register_exporter( $exporters ) {
|
186 |
+
$exporters['events-manager-user'] = array(
|
187 |
+
'exporter_friendly_name' => __( 'Events Manager', 'events-manager' ) . ' - ' .__( 'Further Information', 'events-manager' ),
|
188 |
+
'callback' => 'EM_Data_Privacy::export_user',
|
189 |
+
);
|
190 |
+
if( get_option('dbem_data_privacy_export_bookings') ){
|
191 |
+
$exporters['events-manager-bookings'] = array(
|
192 |
+
'exporter_friendly_name' => __( 'Events Manager', 'events-manager' ) . ' - ' . __('Bookings', 'events-manager'),
|
193 |
+
'callback' => 'EM_Data_Privacy::export_bookings',
|
194 |
+
);
|
195 |
+
}
|
196 |
+
if( get_option('dbem_data_privacy_export_events') ){
|
197 |
+
$exporters['events-manager-recurring-events'] = array(
|
198 |
+
'exporter_friendly_name' => __( 'Events Manager', 'events-manager' ) . ' - ' . __('Recurring Events', 'events-manager'),
|
199 |
+
'callback' => 'EM_Data_Privacy::export_recurring_events',
|
200 |
+
);
|
201 |
+
$exporters['events-manager-events'] = array(
|
202 |
+
'exporter_friendly_name' => __( 'Events Manager', 'events-manager' ) . ' - ' . __('Events', 'events-manager'),
|
203 |
+
'callback' => 'EM_Data_Privacy::export_events',
|
204 |
+
);
|
205 |
+
}
|
206 |
+
if( get_option('dbem_data_privacy_export_locations') ){
|
207 |
+
$exporters['events-manager-locations'] = array(
|
208 |
+
'exporter_friendly_name' => __( 'Events Manager', 'events-manager' ) . ' - ' . __('Locations', 'events-manager'),
|
209 |
+
'callback' => 'EM_Data_Privacy::export_locations',
|
210 |
+
);
|
211 |
+
}
|
212 |
+
return $exporters;
|
213 |
+
}
|
214 |
+
|
215 |
+
public static function export_cleanup(){
|
216 |
+
delete_post_meta($_REQUEST['id'], '_em_locations_exported');
|
217 |
+
delete_post_meta($_REQUEST['id'], '_em_bookings_exported');
|
218 |
+
}
|
219 |
+
|
220 |
+
public static function export_user( $email_address ){
|
221 |
+
$user = get_user_by('email', $email_address); //is user or no-user?
|
222 |
+
$export_items = array();
|
223 |
+
if( $user !== false ){
|
224 |
+
//we add to the WP User section
|
225 |
+
$data_to_export[] = array(
|
226 |
+
'group_id' => 'user',
|
227 |
+
'group_label' => __( 'User' ),
|
228 |
+
'item_id' => "user-{$user->ID}",
|
229 |
+
'data' => array(),
|
230 |
+
);
|
231 |
+
$dbem_phone = get_user_meta($user->ID, 'dbem_phone', true);
|
232 |
+
if( !empty($dbem_phone) ){
|
233 |
+
$export_item['data'][] = array( 'name' => __('Phone', 'events-manager'), 'value' => $dbem_phone );
|
234 |
+
}
|
235 |
+
$export_item = apply_filters('em_data_privacy_export_user', $export_item, $user);
|
236 |
+
if( !empty($export_item['data']) ){
|
237 |
+
$export_items[] = $export_item;
|
238 |
+
}
|
239 |
+
}
|
240 |
+
return array(
|
241 |
+
'data' => $export_items,
|
242 |
+
'done' => true,
|
243 |
+
);
|
244 |
+
}
|
245 |
+
|
246 |
+
public static function export_bookings( $email_address, $page = 1 ) {
|
247 |
+
$page = (int) $page;
|
248 |
+
$limit = apply_filters('em_data_privacy_export_limit', 100);
|
249 |
+
|
250 |
+
$export_items = array();
|
251 |
+
$items_count = 0;
|
252 |
+
|
253 |
+
//check if we're only exporting bookings to those who made anonymous bookings
|
254 |
+
$user = get_user_by('email', $email_address); //is user or no-user?
|
255 |
+
if( $user !== false && get_option('dbem_data_privacy_export_bookings') == 2 ) return array( 'data' => $export_items, 'done' => true ); //return if user is registered and we're only exporting anon bookings
|
256 |
+
|
257 |
+
$bookings = self::get_bookings($email_address, $page);
|
258 |
+
|
259 |
+
$booking_export_default = array(
|
260 |
+
'group_id' => 'events-manager-bookings',
|
261 |
+
'group_label' => __('Bookings', 'events-manager'),
|
262 |
+
'item_id' => 'booking-ID', //replace ID with booking ID
|
263 |
+
'data' => array() // replace this with assoc array of name/value key arrays
|
264 |
+
);
|
265 |
+
$booking_price_adjustments = array(
|
266 |
+
'discounts_pre_tax' => __('Discounts Before Taxes','events-manager'),
|
267 |
+
'surcharges_pre_tax' => __('Surcharges Before Taxes','events-manager'),
|
268 |
+
'discounts_post_tax' => __('Discounts (After Taxes)','events-manager'),
|
269 |
+
'surcharges_post_tax' => __('Surcharges (After Taxes)','events-manager')
|
270 |
+
);
|
271 |
+
|
272 |
+
foreach ( $bookings as $booking_id ) {
|
273 |
+
$EM_Booking = em_get_booking($booking_id);
|
274 |
+
$export_item = $booking_export_default;
|
275 |
+
$export_item['item_id'] = 'booking-'.$EM_Booking->booking_id;
|
276 |
+
$export_item['data']['status'] = array('name' => __('Status','events-manager'), 'value' => $EM_Booking->get_status() );
|
277 |
+
$export_item['data']['date'] = array('name' => __('Date','events-manager'), 'value' => $EM_Booking->date()->getDateTime() . ' ' . $EM_Booking->date()->getTimezone()->getName() );
|
278 |
+
$export_item['data']['event'] = array('name' => __('Event','events-manager'), 'value' => $EM_Booking->get_event()->output('#_EVENTLINK - #_EVENTDATES @ #_EVENTTIMES') );
|
279 |
+
if( $EM_Booking->person_id == 0 ){
|
280 |
+
foreach( $EM_Booking->get_person()->get_summary() as $key => $info ){
|
281 |
+
$export_item['data']['field-'.$key] = $info;
|
282 |
+
}
|
283 |
+
}
|
284 |
+
$booking_tickets = array();
|
285 |
+
foreach($EM_Booking->get_tickets_bookings()->tickets_bookings as $EM_Ticket_Booking){ /* @var EM_Ticket_Booking $EM_Ticket_Booking */
|
286 |
+
$booking_tickets[] = $EM_Ticket_Booking->get_ticket()->ticket_name . ' x '. $EM_Ticket_Booking->get_spaces() . ' @ ' . $EM_Ticket_Booking->get_price(true);
|
287 |
+
}
|
288 |
+
$export_item['data']['tickets'] = array('name' => __('Tickets', 'events-manager-pro'), 'value' => implode('<br>', $booking_tickets));
|
289 |
+
$export_item['data']['sub-total'] = array('name' => __('Sub Total','events-manager'), 'value' => $EM_Booking->get_price_base(true));
|
290 |
+
$price_summary = $EM_Booking->get_price_summary_array();
|
291 |
+
foreach( $booking_price_adjustments as $adjustment_key => $adjustment_title ){
|
292 |
+
if( count($price_summary[$adjustment_key]) > 0 ){
|
293 |
+
$adjustments = array();
|
294 |
+
foreach( $price_summary[$adjustment_key] as $adjustment ){
|
295 |
+
$adjustments[] = "{$adjustment['name']} @ {$adjustment['amount']}";
|
296 |
+
}
|
297 |
+
$export_item['data'][$adjustment_key] = array('name' => $adjustment_title, 'value' => implode('<br>', $adjustments));
|
298 |
+
}
|
299 |
+
}
|
300 |
+
if( !empty($price_summary['taxes']['amount']) ){
|
301 |
+
$export_item['data']['taxes'] = array('name' => __('Taxes','events-manager'), 'value' => "({$price_summary['taxes']['rate']}) {$price_summary['taxes']['amount']}");
|
302 |
+
}
|
303 |
+
$export_item['data']['total'] = array('name' => __('Total Price','events-manager'), 'value' => $price_summary['total']);
|
304 |
+
//booking notes - can be exempt with a filter since maybe notes have private info
|
305 |
+
if( apply_filters('em_data_privacy_export_bookings_include_notes', true, $EM_Booking) ){
|
306 |
+
$booking_notes = $EM_Booking->get_notes();
|
307 |
+
if( !empty($booking_notes) ){
|
308 |
+
$booking_notes_data = array();
|
309 |
+
foreach( $booking_notes as $booking_note ){
|
310 |
+
$booking_notes_data[] = date(get_option('date_format'), $booking_note['timestamp']) .' - '. $booking_note['note'];
|
311 |
+
}
|
312 |
+
$export_item['data']['notes'] = array('name' => __( 'Booking Notes', 'events-manager'), 'value' => implode('<br><br>', $booking_notes_data));
|
313 |
+
}
|
314 |
+
}
|
315 |
+
$export_item = apply_filters('em_data_privacy_export_bookings_item', $export_item, $EM_Booking);
|
316 |
+
$export_items[] = $export_item;
|
317 |
+
$export_items = apply_filters('em_data_privacy_export_bookings_items_after_item', $export_items, $export_item, $EM_Booking); //could be used for cross-referencing and add-ing other groups e.g. Multiple Bookings in Pro
|
318 |
+
$items_count++;
|
319 |
+
if( $items_count == $limit ) break;
|
320 |
+
}
|
321 |
+
|
322 |
+
$done = $items_count < $limit; //if we didn't reach limit of bookings then we must be done
|
323 |
+
return array(
|
324 |
+
'data' => $export_items,
|
325 |
+
'done' => $done,
|
326 |
+
);
|
327 |
+
}
|
328 |
+
|
329 |
+
public static function export_recurring_events( $email_address, $page = 1){
|
330 |
+
return self::export_events( $email_address, $page, 'event-recurring' );
|
331 |
+
}
|
332 |
+
|
333 |
+
public static function export_events( $email_address, $page = 1, $post_type = false ) {
|
334 |
+
if( !$post_type ) $post_type = EM_POST_TYPE_EVENT; //default to event
|
335 |
+
$page = (int) $page;
|
336 |
+
$limit = apply_filters('em_data_privacy_export_limit', 100);
|
337 |
+
$user = get_user_by('email', $email_address); //is user or no-user?
|
338 |
+
$export_items = array();
|
339 |
+
$items_count = 0;
|
340 |
+
|
341 |
+
//check if we're only exporting events to those who submitted anonymously
|
342 |
+
if( $user !== false && get_option('dbem_data_privacy_export_events') == 2 ) return array( 'data' => $export_items, 'done' => true ); //return if user is registered and we're only exporting anon events
|
343 |
+
|
344 |
+
//prepare some location stuff for use within events
|
345 |
+
$locations_export_default = array(
|
346 |
+
'group_id' => 'events-manager-'.EM_POST_TYPE_LOCATION,
|
347 |
+
'group_label' => __('Locations', 'events-manager'),
|
348 |
+
'item_id' => 'location-post-ID', //replace ID with booking ID
|
349 |
+
'data' => array() // replace this with assoc array of name/value key arrays
|
350 |
+
);
|
351 |
+
$locations_exported = get_post_meta( $_REQUEST['id'], '_em_locations_exported', true);
|
352 |
+
if( empty($locations_exported) ) $locations_exported = array();
|
353 |
+
|
354 |
+
//EVENTS
|
355 |
+
$event_export_default = array(
|
356 |
+
'group_id' => 'events-manager-'.$post_type,
|
357 |
+
'item_id' => 'event-post-ID', //replace ID with booking ID
|
358 |
+
'data' => array() // replace this with assoc array of name/value key arrays
|
359 |
+
);
|
360 |
+
$event_export_default['group_label'] = $post_type == 'event-recurring' ? __('Recurring Events', 'events-manager'):__('Events', 'events-manager');
|
361 |
+
|
362 |
+
//get event IDs submitted by user or "anonymously" by email
|
363 |
+
$events = self::get_events($email_address, $page, $post_type);
|
364 |
+
|
365 |
+
foreach( $events as $post_id ){
|
366 |
+
$EM_Event = em_get_event($post_id, 'post_id');
|
367 |
+
$export_item = $event_export_default;
|
368 |
+
$export_item['item_id'] = 'event-post-'.$EM_Event->post_id;
|
369 |
+
$export_item['data'][] = array('name' => __('Event Name','events-manager'), 'value' => $EM_Event->event_name );
|
370 |
+
$export_item['data'][] = array('name' => sprintf(__('%s Status','events-manager'), __('Event','events-manager')), 'value' => $EM_Event->post_status );
|
371 |
+
if( $post_type == EM_POST_TYPE_EVENT && $EM_Event->event_status == 1 ){
|
372 |
+
$export_item['data'][] = array('name' => sprintf(__('%s URL','events-manager'), __('Event','events-manager')), 'value' => $EM_Event->get_permalink() );
|
373 |
+
}
|
374 |
+
if( $post_type == 'event-recurring' ){
|
375 |
+
$export_item['data'][] = array('name' => __('When','events-manager'), 'value' => $EM_Event->output('#_EVENTDATES @ #_EVENTTIMES').'<br>'.$EM_Event->get_recurrence_description() );
|
376 |
+
}else{
|
377 |
+
$export_item['data'][] = array('name' => __('When','events-manager'), 'value' => $EM_Event->output('#_EVENTDATES @ #_EVENTTIMES') );
|
378 |
+
}
|
379 |
+
$export_item['data'][] = array('name' => __('Timezone','events-manager'), 'value' => $EM_Event->start()->getTimezone()->getName() );
|
380 |
+
if( !empty($EM_Event->event_owner_name) ) $export_item['data'][] = array('name' => __('Name','events-manager'), 'value' => $EM_Event->event_owner_name );
|
381 |
+
if( $EM_Event->get_location()->location_id ){
|
382 |
+
$EM_Location = $EM_Event->get_location();
|
383 |
+
$export_item['data'][] = array('name' => __('Location','events-manager'), 'value' => $EM_Location->location_name . ', '. $EM_Location->get_full_address() .', '. $EM_Location->location_country);
|
384 |
+
//put this location as a new export item
|
385 |
+
$already_exported = in_array($EM_Location->location_id, $locations_exported);
|
386 |
+
$user_owns_location = ($user !== false && $EM_Location->location_owner == $user->ID) || ($user === false && $EM_Location->location_owner == get_option('dbem_events_anonymous_user'));
|
387 |
+
if( !$already_exported && $user_owns_location ){
|
388 |
+
$location_export_item = $locations_export_default;
|
389 |
+
$location_export_item['item_id'] = 'location-post-'.$EM_Location->post_id;
|
390 |
+
$location_export_item['data'][] = array('name' => __('Name','events-manager'), 'value' => $EM_Location->location_name );
|
391 |
+
$location_export_item['data'][] = array('name' => __('Address','events-manager'), 'value' => $EM_Location->get_full_address() .', '. $EM_Location->location_country );
|
392 |
+
$location_export_item['data'][] = array('name' => __('Coordinates','events-manager'), 'value' => $EM_Location->location_latitude .', '. $EM_Location->location_longitude );
|
393 |
+
$location_export_item['data'][] = array('name' => sprintf(__('%s Status','events-manager'), __('Location','events-manager')), 'value' => $EM_Location->post_status );
|
394 |
+
if( $EM_Location->post_status == 'publish' ){
|
395 |
+
$location_export_item['data'][] = array('name' => sprintf(__('%s URL','events-manager'), __('Location','events-manager')), 'value' => $EM_Location->get_permalink() );
|
396 |
+
}
|
397 |
+
foreach( $EM_Location->location_attributes as $k => $v ){
|
398 |
+
$location_export_item['data'][] = array('name' => $k, 'value' => $v);
|
399 |
+
}
|
400 |
+
$location_export_item = apply_filters('em_data_privacy_export_locations_item', $location_export_item, $EM_Location);
|
401 |
+
$export_items[] = $location_export_item;
|
402 |
+
$export_items = apply_filters('em_data_privacy_export_locations_items_after_item', $export_items, $location_export_item, $EM_Location); //could be used for cross-referencing and add-ing other groups e.g. Multiple Bookings in Pro
|
403 |
+
$items_count++;
|
404 |
+
$locations_exported[] = $EM_Location->location_id;
|
405 |
+
}
|
406 |
+
}
|
407 |
+
if( $EM_Event->event_rsvp ){
|
408 |
+
$tickets = array();
|
409 |
+
foreach( $EM_Event->get_tickets() as $EM_Ticket ){ /* @var EM_Ticket $EM_Ticket */
|
410 |
+
$ticket = array($EM_Ticket->ticket_name, $EM_Ticket->ticket_description, $EM_Ticket->get_price(true));
|
411 |
+
if( empty($EM_Ticket->ticket_description) ) unset($ticket[1]);
|
412 |
+
$tickets[] = implode( ' - ', $ticket);
|
413 |
+
}
|
414 |
+
$export_item['data'][] = array('name' => __('Tickets','events-manager'), 'value' => implode('<br>', $tickets) );
|
415 |
+
}
|
416 |
+
foreach( $EM_Event->event_attributes as $k => $v ){
|
417 |
+
$export_item['data'][] = array('name' => $k, 'value' => $v);
|
418 |
+
}
|
419 |
+
$export_item = apply_filters('em_data_privacy_export_events_item', $export_item, $EM_Event);
|
420 |
+
$export_items[] = $export_item;
|
421 |
+
$export_items = apply_filters('em_data_privacy_export_events_items_after_item', $export_items, $export_item, $EM_Event); //could be used for cross-referencing and add-ing other groups e.g. Multiple Bookings in Pro
|
422 |
+
$items_count++;
|
423 |
+
if( $items_count >= $limit ) break;
|
424 |
+
}
|
425 |
+
|
426 |
+
$done = $items_count < $limit; //if we didn't reach limit of bookings then we must be done
|
427 |
+
update_post_meta( $_REQUEST['id'], '_em_locations_exported', $locations_exported);
|
428 |
+
return array(
|
429 |
+
'data' => $export_items,
|
430 |
+
'done' => $done,
|
431 |
+
);
|
432 |
+
}
|
433 |
+
|
434 |
+
public static function export_locations( $email_address, $page = 1 ) {
|
435 |
+
$page = (int) $page;
|
436 |
+
$limit = apply_filters('em_data_privacy_export_limit', 100);
|
437 |
+
$offset = ($page -1) * $limit;
|
438 |
+
$user = get_user_by('email', $email_address); //is user or no-user?
|
439 |
+
$export_items = array();
|
440 |
+
$items_count = 0;
|
441 |
+
|
442 |
+
//check if we're only exporting locations to those who submitted anonymously - eventual since currently it's not possible to submit anonymously
|
443 |
+
if( $user !== false && get_option('dbem_data_privacy_export_locations') == 2 ) return array( 'data' => $export_items, 'done' => true ); //return if user is registered and we're only exporting anon events
|
444 |
+
|
445 |
+
$locations_export_default = array(
|
446 |
+
'group_id' => 'events-manager-'.EM_POST_TYPE_LOCATION,
|
447 |
+
'group_label' => __('Locations', 'events-manager'),
|
448 |
+
'item_id' => 'location-post-ID', //replace ID with booking ID
|
449 |
+
'data' => array() // replace this with assoc array of name/value key arrays
|
450 |
+
);
|
451 |
+
|
452 |
+
//Locations - here we only get event-less events submitted by registered users. Anonymous submissions would have been handled above as event/locations come in pairs.
|
453 |
+
if( $user !== false ){
|
454 |
+
foreach( EM_Locations::get(array('eventless' => get_option('dbem_data_privacy_export_events') != 0, 'owner' => $user->ID, 'limit' => $limit, 'offset' => $offset, 'status'=>'everything')) as $EM_Location ){ /* @var EM_Location $EM_Location */
|
455 |
+
$location_export_item = $locations_export_default;
|
456 |
+
$location_export_item['item_id'] = 'event-post-'.$EM_Location->post_id;
|
457 |
+
$location_export_item['data'][] = array('name' => __('Name','events-manager'), 'value' => $EM_Location->location_name );
|
458 |
+
$location_export_item['data'][] = array('name' => sprintf(__('%s Status','events-manager'), __('Location','events-manager')), 'value' => $EM_Location->post_status );
|
459 |
+
if( $EM_Location->post_status == 'publish' ){
|
460 |
+
$location_export_item['data'][] = array('name' => sprintf(__('%s URL','events-manager'), __('Location','events-manager')), 'value' => $EM_Location->get_permalink() );
|
461 |
+
}
|
462 |
+
$location_export_item['data'][] = array('name' => __('Address','events-manager'), 'value' => $EM_Location->get_full_address() .', '. $EM_Location->location_country );
|
463 |
+
$location_export_item['data'][] = array('name' => __('Coordinates','events-manager'), 'value' => $EM_Location->location_latitude .', '. $EM_Location->location_longitude );
|
464 |
+
foreach( $EM_Location->location_attributes as $k => $v ){
|
465 |
+
$location_export_item['data'][] = array('name' => $k, 'value' => $v);
|
466 |
+
}
|
467 |
+
$location_export_item = apply_filters('em_data_privacy_export_locations_item', $location_export_item, $EM_Location);
|
468 |
+
$export_items[] = $location_export_item;
|
469 |
+
$export_items = apply_filters('em_data_privacy_export_locations_items_after_item', $export_items, $location_export_item, $EM_Location); //could be used for cross-referencing and add-ing other groups e.g. Multiple Bookings in Pro
|
470 |
+
$items_count++;
|
471 |
+
if( $items_count == $limit ) break;
|
472 |
+
}
|
473 |
+
}
|
474 |
+
|
475 |
+
$done = $items_count < $limit; //if we didn't reach limit of bookings then we must be done
|
476 |
+
return array(
|
477 |
+
'data' => $export_items,
|
478 |
+
'done' => $done,
|
479 |
+
);
|
480 |
+
}
|
481 |
+
|
482 |
+
public static function get_events( $email_address, $page, $post_type ){
|
483 |
+
global $wpdb;
|
484 |
+
$page = (int) $page;
|
485 |
+
$limit = apply_filters('em_data_privacy_export_limit', 100);
|
486 |
+
$offset = ($page -1) * $limit;
|
487 |
+
$user = get_user_by('email', $email_address); //is user or no-user?
|
488 |
+
//get event IDs submitted by user or "anonymously" by email
|
489 |
+
$events = array();
|
490 |
+
if( $user !== false ){
|
491 |
+
$sql = $wpdb->prepare("SELECT ID FROM {$wpdb->posts} WHERE post_author = %d AND post_type = %s LIMIT %d OFFSET %d", $user->ID, $post_type, $limit, $offset);
|
492 |
+
$events = $wpdb->get_col($sql);
|
493 |
+
}
|
494 |
+
//if user ever submitted anonymous events with same email, we also process these
|
495 |
+
$sql = $wpdb->prepare("SELECT ID FROM {$wpdb->posts} WHERE ID IN (SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key='_event_owner_email' AND meta_value=%s) AND post_type = %s LIMIT %d OFFSET %d", $email_address, $post_type, $limit, $offset);
|
496 |
+
$events = array_merge($events, $wpdb->get_col($sql));
|
497 |
+
return $events;
|
498 |
+
}
|
499 |
+
|
500 |
+
public static function get_bookings( $email_address, $page ){
|
501 |
+
global $wpdb;
|
502 |
+
$page = (int) $page;
|
503 |
+
$limit = apply_filters('em_data_privacy_export_limit', 100);
|
504 |
+
$offset = ($page -1) * $limit;
|
505 |
+
$user = get_user_by('email', $email_address); //is user or no-user?
|
506 |
+
|
507 |
+
$conditions = array();
|
508 |
+
if( $user !== false ){
|
509 |
+
$conditions[] = $wpdb->prepare('person_id = %d', $user->ID);
|
510 |
+
}
|
511 |
+
$conditions[] = $wpdb->prepare('person_id=0 AND booking_meta LIKE %s', "%\"user_email\";s:".strlen($email_address).":\"$email_address\"%"); //find any booking that may have their email, anonymous or previous email address.
|
512 |
+
$bookings = $wpdb->get_col('SELECT booking_id FROM '.EM_BOOKINGS_TABLE.' WHERE '. implode(' OR ', $conditions) .' LIMIT '.$limit . ' OFFSET '.$offset);
|
513 |
+
|
514 |
+
return $bookings;
|
515 |
+
|
516 |
+
}
|
517 |
+
}
|
518 |
+
EM_Data_Privacy::init();
|
519 |
+
/*
|
520 |
+
add_action('admin_init', function(){
|
521 |
+
$data = EM_Data_Privacy::exporter('subscriber@netweblogic.com');
|
522 |
+
echo "<table>";
|
523 |
+
foreach( $data['data'] as $items ){
|
524 |
+
foreach($items['data'] as $item) echo "<tr><th>{$item['name']}</th><td>{$item['value']}</td>";
|
525 |
+
}
|
526 |
+
echo "</table>";
|
527 |
+
die();
|
528 |
+
}); //*/
|
admin/em-options.php
CHANGED
@@ -316,12 +316,15 @@ function em_options_save(){
|
|
316 |
|
317 |
//update scripts that may need to run
|
318 |
$blog_updates = is_multisite() ? array_merge(EM_Options::get('updates'), EM_Options::site_get('updates')) : EM_Options::get('updates');
|
319 |
-
|
320 |
-
$
|
321 |
-
|
322 |
-
|
|
|
|
|
|
|
|
|
323 |
}
|
324 |
-
|
325 |
}
|
326 |
add_action('admin_init', 'em_options_save');
|
327 |
|
@@ -921,4 +924,75 @@ function em_admin_option_box_uninstall(){
|
|
921 |
</div>
|
922 |
<?php
|
923 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
924 |
?>
|
316 |
|
317 |
//update scripts that may need to run
|
318 |
$blog_updates = is_multisite() ? array_merge(EM_Options::get('updates'), EM_Options::site_get('updates')) : EM_Options::get('updates');
|
319 |
+
if( is_array($blog_updates) ) {
|
320 |
+
foreach ( $blog_updates as $update => $update_data ) {
|
321 |
+
$filename = EM_DIR . '/admin/settings/updates/' . $update . '.php';
|
322 |
+
if ( file_exists( $filename ) ) {
|
323 |
+
include_once( $filename );
|
324 |
+
}
|
325 |
+
do_action( 'em_admin_update_' . $update, $update_data );
|
326 |
+
}
|
327 |
}
|
|
|
328 |
}
|
329 |
add_action('admin_init', 'em_options_save');
|
330 |
|
924 |
</div>
|
925 |
<?php
|
926 |
}
|
927 |
+
|
928 |
+
/**
|
929 |
+
* Meta options box for privacy and data protection rules for GDPR (and other dp laws) compliancy
|
930 |
+
*/
|
931 |
+
function em_admin_option_box_data_privacy(){
|
932 |
+
global $save_button;
|
933 |
+
$privacy_options = array(
|
934 |
+
0 => __('Do not include', 'events-manager'),
|
935 |
+
1 => __('Include all', 'events-manager'),
|
936 |
+
2 => __('Include only guest submissions', 'events-manager')
|
937 |
+
);
|
938 |
+
?>
|
939 |
+
<div class="postbox " id="em-opt-data-privacy" >
|
940 |
+
<div class="handlediv" title="<?php __('Click to toggle', 'events-manager'); ?>"><br /></div><h3><span><?php _e ( 'Privacy', 'events-manager'); ?> </span></h3>
|
941 |
+
<div class="inside">
|
942 |
+
<p class="em-boxheader"><?php echo sprintf(__('Depending on the nature of your site, you will be subject to one or more national and international privacy/data protection laws such as the %s. Below are some options that you can use to tailor how Events Manager interacts with WordPress privacy tools.','events-manager'), '<a href=http://ec.europa.eu/justice/smedataprotect/index_en.htm">GDPR</a>'); ?></p>
|
943 |
+
<p class="em-boxheader"><?php echo sprintf(__('For more information see our <a href="%s">data privacy documentation</a>.','events-manager'), 'http://wp-events-plugin.com/documentation/data-privacy-gdpr-compliance/'); ?></p>
|
944 |
+
<p class="em-boxheader"><?php echo __('All options below relate to data that may have been submitted by or collected from the user requesting their personal data, which would also include events and locations where they are the author.', 'events-manager'); ?></p>
|
945 |
+
<table class='form-table'>
|
946 |
+
<thead>
|
947 |
+
<tr class="em-header">
|
948 |
+
<th colspan="2"><h4><?php esc_html_e('Export Personal Data'); ?></h4></th>
|
949 |
+
</tr>
|
950 |
+
</thead>
|
951 |
+
<?php
|
952 |
+
em_options_select ( __( 'Events', 'events-manager'), 'dbem_data_privacy_export_events', $privacy_options );
|
953 |
+
em_options_select ( __( 'Locations', 'events-manager'), 'dbem_data_privacy_export_locations', $privacy_options, __('Locations submitted by guest users are not included, unless they are linked to events also submitted by them.', 'events-manager') );
|
954 |
+
em_options_select ( __( 'Bookings', 'events-manager'), 'dbem_data_privacy_export_bookings', $privacy_options, __('This is specific to bookings made by the user, not bookings that may have been made to events they own.', 'events-manager'), $privacy_options );
|
955 |
+
?>
|
956 |
+
<thead>
|
957 |
+
<tr class="em-header">
|
958 |
+
<th colspan="2"><h4><?php esc_html_e('Erase Personal Data'); ?></h4></th>
|
959 |
+
</tr>
|
960 |
+
</thead>
|
961 |
+
<?php
|
962 |
+
em_options_select ( __( 'Events', 'events-manager'), 'dbem_data_privacy_erase_events', $privacy_options );
|
963 |
+
em_options_select ( __( 'Locations', 'events-manager'), 'dbem_data_privacy_erase_locations', $privacy_options, __('Locations submitted by guest users are not included, unless they are linked to events also submitted by them.', 'events-manager') );
|
964 |
+
em_options_select ( __( 'Bookings', 'events-manager'), 'dbem_data_privacy_erase_bookings', $privacy_options, __('This is specific to bookings made by the user, not bookings that may have been made to events they own.', 'events-manager'), $privacy_options );
|
965 |
+
?>
|
966 |
+
<thead>
|
967 |
+
<tr class="em-header">
|
968 |
+
<th colspan="2">
|
969 |
+
<h4><?php esc_html_e('Consent', 'events-manager'); ?></h4>
|
970 |
+
<p><?php esc_html_e('If you collect personal data, you may want to request their consent. The options below will automatically add checkboxes requesting this consent.', 'events-manager'); ?></p>
|
971 |
+
</th>
|
972 |
+
</tr>
|
973 |
+
</thead>
|
974 |
+
<?php
|
975 |
+
$consent_options = array(
|
976 |
+
0 => __('Do not show', 'events-manager'),
|
977 |
+
1 => __('Show to all', 'events-manager'),
|
978 |
+
2 => __('Only show to guests', 'events-manager')
|
979 |
+
);
|
980 |
+
$consent_remember = array(
|
981 |
+
0 => __('Always show and ask for consent', 'events-manager'),
|
982 |
+
1 => __('Remember and hide checkbox', 'events-manager'),
|
983 |
+
2 => __('Remember and show checkbox', 'events-manager')
|
984 |
+
);
|
985 |
+
em_options_input_text( __('Consent Text', 'events-manager'), 'dbem_data_privacy_consent_text', __('%s will be replaced by a link to your site privacy policy page.', 'events-manager') );
|
986 |
+
em_options_select( __('Remembering Consent', 'events-manager'), 'dbem_data_privacy_consent_remember', $consent_remember, __('You can hide or leave the consent box checked for registered users who have provided consent previously.', 'events-manager') );
|
987 |
+
em_options_select( __( 'Event Submission Forms', 'events-manager'), 'dbem_data_privacy_consent_events', $privacy_options );
|
988 |
+
em_options_select( __( 'Location Submission Forms', 'events-manager'), 'dbem_data_privacy_consent_locations', $privacy_options );
|
989 |
+
em_options_select( __( 'Bookings Forms', 'events-manager'), 'dbem_data_privacy_consent_bookings', $privacy_options );
|
990 |
+
|
991 |
+
echo $save_button;
|
992 |
+
?>
|
993 |
+
</table>
|
994 |
+
</div> <!-- . inside -->
|
995 |
+
</div> <!-- .postbox -->
|
996 |
+
<?php
|
997 |
+
}
|
998 |
?>
|
admin/settings/tabs/general.php
CHANGED
@@ -262,7 +262,8 @@
|
|
262 |
</table>
|
263 |
</div> <!-- . inside -->
|
264 |
</div> <!-- .postbox -->
|
265 |
-
|
|
|
266 |
<?php if ( !is_multisite() ) { em_admin_option_box_uninstall(); } ?>
|
267 |
|
268 |
<?php if( get_option('dbem_migrate_images') ): ?>
|
262 |
</table>
|
263 |
</div> <!-- . inside -->
|
264 |
</div> <!-- .postbox -->
|
265 |
+
|
266 |
+
<?php em_admin_option_box_data_privacy(); ?>
|
267 |
<?php if ( !is_multisite() ) { em_admin_option_box_uninstall(); } ?>
|
268 |
|
269 |
<?php if( get_option('dbem_migrate_images') ): ?>
|
classes/em-admin-notices.php
CHANGED
@@ -37,9 +37,15 @@ class EM_Admin_Notices {
|
|
37 |
$network = $network && is_multisite(); //make sure we are actually in multisite!
|
38 |
if( is_string($EM_Admin_Notice) ) $EM_Admin_Notice = new EM_Admin_Notice( $EM_Admin_Notice );
|
39 |
if( !$EM_Admin_Notice->name ) return false;
|
|
|
40 |
$data = $network ? get_site_option('dbem_data') : get_option('dbem_data');
|
41 |
-
$
|
|
|
42 |
$notices_data = $network ? get_site_option('dbem_admin_notices') : get_option('dbem_admin_notices');
|
|
|
|
|
|
|
|
|
43 |
$notices[$EM_Admin_Notice->name] = !empty($EM_Admin_Notice->when) ? $EM_Admin_Notice->when : 0;
|
44 |
//if no message supplied, we assume it's a hook, possibly with a time-to-show assigned above
|
45 |
if( !empty($EM_Admin_Notice->message) ){
|
@@ -103,7 +109,7 @@ class EM_Admin_Notices {
|
|
103 |
public static function admin_notices( $network = false ){
|
104 |
$notices = array();
|
105 |
$data = $network ? get_site_option('dbem_data') : get_option('dbem_data');
|
106 |
-
$possible_notices = !empty($data['admin_notices']) ? $data['admin_notices'] : array();
|
107 |
//we may have something to show, so we make sure that there's something to show right now
|
108 |
foreach( $possible_notices as $key => $val ){
|
109 |
//to avoid extra loading etc. we weed out time-based notices that aren't triggered right now
|
37 |
$network = $network && is_multisite(); //make sure we are actually in multisite!
|
38 |
if( is_string($EM_Admin_Notice) ) $EM_Admin_Notice = new EM_Admin_Notice( $EM_Admin_Notice );
|
39 |
if( !$EM_Admin_Notice->name ) return false;
|
40 |
+
//get options data
|
41 |
$data = $network ? get_site_option('dbem_data') : get_option('dbem_data');
|
42 |
+
$data = empty($data) ? array() : maybe_unserialize($data);
|
43 |
+
if( !is_array($data)) $data = array();
|
44 |
$notices_data = $network ? get_site_option('dbem_admin_notices') : get_option('dbem_admin_notices');
|
45 |
+
$notices_data = empty($notices_data) ? array() : maybe_unserialize($notices_data);
|
46 |
+
if( !is_array($notices_data)) $notices_data = array();
|
47 |
+
//start building data
|
48 |
+
$notices = !empty($data['admin_notices']) ? $data['admin_notices'] : array();
|
49 |
$notices[$EM_Admin_Notice->name] = !empty($EM_Admin_Notice->when) ? $EM_Admin_Notice->when : 0;
|
50 |
//if no message supplied, we assume it's a hook, possibly with a time-to-show assigned above
|
51 |
if( !empty($EM_Admin_Notice->message) ){
|
109 |
public static function admin_notices( $network = false ){
|
110 |
$notices = array();
|
111 |
$data = $network ? get_site_option('dbem_data') : get_option('dbem_data');
|
112 |
+
$possible_notices = is_array($data) && !empty($data['admin_notices']) ? $data['admin_notices'] : array();
|
113 |
//we may have something to show, so we make sure that there's something to show right now
|
114 |
foreach( $possible_notices as $key => $val ){
|
115 |
//to avoid extra loading etc. we weed out time-based notices that aren't triggered right now
|
classes/em-booking.php
CHANGED
@@ -73,6 +73,9 @@ class EM_Booking extends EM_Object{
|
|
73 |
* @var EM_DateTime
|
74 |
*/
|
75 |
protected $date;
|
|
|
|
|
|
|
76 |
var $person;
|
77 |
var $required_fields = array('booking_id', 'event_id', 'person_id', 'booking_spaces');
|
78 |
var $feedback_message = "";
|
73 |
* @var EM_DateTime
|
74 |
*/
|
75 |
protected $date;
|
76 |
+
/**
|
77 |
+
* @var EM_Person
|
78 |
+
*/
|
79 |
var $person;
|
80 |
var $required_fields = array('booking_id', 'event_id', 'person_id', 'booking_spaces');
|
81 |
var $feedback_message = "";
|
classes/em-datetime.php
CHANGED
@@ -34,11 +34,15 @@ class EM_DateTime extends DateTime {
|
|
34 |
public function __construct( $time = null, $timezone = null ){
|
35 |
//get our EM_DateTimeZone
|
36 |
$timezone = EM_DateTimeZone::create($timezone);
|
|
|
|
|
|
|
37 |
//fix DateTime error if a regular timestamp is supplied without prepended @ symbol
|
38 |
if( is_numeric($time) ) $time = '@'.$time;
|
39 |
//finally, run parent function with our custom timezone
|
40 |
try{
|
41 |
@parent::__construct($time, $timezone);
|
|
|
42 |
$this->valid = true; //if we get this far, supplied time is valid
|
43 |
}catch( Exception $e ){
|
44 |
//get current date/time in relevant timezone and set valid flag to false
|
@@ -48,11 +52,8 @@ class EM_DateTime extends DateTime {
|
|
48 |
$this->setTime(0,0,0);
|
49 |
$this->valid = false;
|
50 |
}
|
51 |
-
//save timezone name for use in getTimezone()
|
52 |
-
$this->timezone_name = $timezone->getName();
|
53 |
-
$this->timezone_manual_offset = $timezone->manual_offset;
|
54 |
//deal with manual UTC offsets, but only if we haven't defaulted to the current timestamp since that would already be a correct relative value
|
55 |
-
if( $time !== null && $time != 'now' ) $this->handleOffsets($timezone);
|
56 |
}
|
57 |
|
58 |
/**
|
34 |
public function __construct( $time = null, $timezone = null ){
|
35 |
//get our EM_DateTimeZone
|
36 |
$timezone = EM_DateTimeZone::create($timezone);
|
37 |
+
//save timezone name for use in getTimezone()
|
38 |
+
$this->timezone_name = $timezone->getName();
|
39 |
+
$this->timezone_manual_offset = $timezone->manual_offset;
|
40 |
//fix DateTime error if a regular timestamp is supplied without prepended @ symbol
|
41 |
if( is_numeric($time) ) $time = '@'.$time;
|
42 |
//finally, run parent function with our custom timezone
|
43 |
try{
|
44 |
@parent::__construct($time, $timezone);
|
45 |
+
if( substr($time,0,1) == '@' || $time == 'now' ) $this->setTimezone($timezone);
|
46 |
$this->valid = true; //if we get this far, supplied time is valid
|
47 |
}catch( Exception $e ){
|
48 |
//get current date/time in relevant timezone and set valid flag to false
|
52 |
$this->setTime(0,0,0);
|
53 |
$this->valid = false;
|
54 |
}
|
|
|
|
|
|
|
55 |
//deal with manual UTC offsets, but only if we haven't defaulted to the current timestamp since that would already be a correct relative value
|
56 |
+
if( $time !== null && $time != 'now' && substr($time,0,1) != '@' ) $this->handleOffsets($timezone);
|
57 |
}
|
58 |
|
59 |
/**
|
classes/em-event.php
CHANGED
@@ -1795,6 +1795,9 @@ class EM_Event extends EM_Object{
|
|
1795 |
}elseif ($condition == 'all_day'){
|
1796 |
//is it an all day event
|
1797 |
$show_condition = !empty($this->event_all_day);
|
|
|
|
|
|
|
1798 |
}elseif ($condition == 'logged_in'){
|
1799 |
//user is logged in
|
1800 |
$show_condition = is_user_logged_in();
|
@@ -2335,14 +2338,22 @@ class EM_Event extends EM_Object{
|
|
2335 |
|
2336 |
if( get_option('dbem_categories_enabled') ){
|
2337 |
//for backwards compat and easy use, take over the individual category placeholders with the frirst cat in th elist.
|
2338 |
-
|
2339 |
-
|
2340 |
-
$EM_Category = $EM_Categories->get_first();
|
2341 |
}
|
2342 |
if( empty($EM_Category) ) $EM_Category = new EM_Category();
|
2343 |
$event_string = $EM_Category->output($event_string, $target);
|
2344 |
}
|
2345 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2346 |
//Finally, do the event notes, so that previous placeholders don't get replaced within the content, which may use shortcodes
|
2347 |
if( !empty($desc_replace) ){
|
2348 |
foreach($desc_replace as $full_result => $replacement){
|
1795 |
}elseif ($condition == 'all_day'){
|
1796 |
//is it an all day event
|
1797 |
$show_condition = !empty($this->event_all_day);
|
1798 |
+
}elseif ($condition == 'not_all_day'){
|
1799 |
+
//is not an all day event
|
1800 |
+
$show_condition = !empty($this->event_all_day);
|
1801 |
}elseif ($condition == 'logged_in'){
|
1802 |
//user is logged in
|
1803 |
$show_condition = is_user_logged_in();
|
2338 |
|
2339 |
if( get_option('dbem_categories_enabled') ){
|
2340 |
//for backwards compat and easy use, take over the individual category placeholders with the frirst cat in th elist.
|
2341 |
+
if( count($this->get_categories()) > 0 ){
|
2342 |
+
$EM_Category = $this->get_categories()->get_first();
|
|
|
2343 |
}
|
2344 |
if( empty($EM_Category) ) $EM_Category = new EM_Category();
|
2345 |
$event_string = $EM_Category->output($event_string, $target);
|
2346 |
}
|
2347 |
|
2348 |
+
if( get_option('dbem_tags_enabled') ){
|
2349 |
+
$EM_Tags = new EM_Tags($this);
|
2350 |
+
if( count($EM_Tags) > 0 ){
|
2351 |
+
$EM_Tag = $EM_Tags->get_first();
|
2352 |
+
}
|
2353 |
+
if( empty($EM_Tag) ) $EM_Tag = new EM_Tag();
|
2354 |
+
$event_string = $EM_Tag->output($event_string, $target);
|
2355 |
+
}
|
2356 |
+
|
2357 |
//Finally, do the event notes, so that previous placeholders don't get replaced within the content, which may use shortcodes
|
2358 |
if( !empty($desc_replace) ){
|
2359 |
foreach($desc_replace as $full_result => $replacement){
|
classes/em-notices.php
CHANGED
@@ -141,7 +141,11 @@
|
|
141 |
$string = '';
|
142 |
foreach ($this->notices[$type] as $message){
|
143 |
if( !is_array($message['string']) ){
|
144 |
-
|
|
|
|
|
|
|
|
|
145 |
}else{
|
146 |
$string .= "<p><strong>".$message['title']."</strong><ul>";
|
147 |
foreach($message['string'] as $msg){
|
141 |
$string = '';
|
142 |
foreach ($this->notices[$type] as $message){
|
143 |
if( !is_array($message['string']) ){
|
144 |
+
if( preg_match('/<p>/', $message['string']) ){
|
145 |
+
$string .= $message['string'];
|
146 |
+
}else{
|
147 |
+
$string .= "<p>{$message['string']}</p>";
|
148 |
+
}
|
149 |
}else{
|
150 |
$string .= "<p><strong>".$message['title']."</strong><ul>";
|
151 |
foreach($message['string'] as $msg){
|
classes/em-people.php
CHANGED
@@ -13,13 +13,17 @@ class EM_People extends EM_Object {
|
|
13 |
*/
|
14 |
public static function delete_user( $id ){
|
15 |
global $wpdb;
|
|
|
16 |
if( $_REQUEST['delete_option'] == 'reassign' && is_numeric($_REQUEST['reassign_user']) ){
|
17 |
$wpdb->update(EM_EVENTS_TABLE, array('event_owner'=>$_REQUEST['reassign_user']), array('event_owner'=>$id));
|
|
|
18 |
}else{
|
19 |
-
//
|
20 |
-
|
|
|
21 |
}
|
22 |
//delete their bookings completely
|
|
|
23 |
$EM_Person = new EM_Person();
|
24 |
$EM_Person->ID = $EM_Person->person_id = $id;
|
25 |
foreach( $EM_Person->get_bookings() as $EM_Booking){
|
13 |
*/
|
14 |
public static function delete_user( $id ){
|
15 |
global $wpdb;
|
16 |
+
//if events are set to be deleted, we hook in correctly already, if they're meant to be reassigned, we only need to update our tables as WP updated theirs
|
17 |
if( $_REQUEST['delete_option'] == 'reassign' && is_numeric($_REQUEST['reassign_user']) ){
|
18 |
$wpdb->update(EM_EVENTS_TABLE, array('event_owner'=>$_REQUEST['reassign_user']), array('event_owner'=>$id));
|
19 |
+
$wpdb->update(EM_LOCATIONS_TABLE, array('location_owner'=>$_REQUEST['reassign_user']), array('location_owner'=>$id));
|
20 |
}else{
|
21 |
+
//We delete all the events and locations owned by this user
|
22 |
+
foreach( EM_Events::get( array('owner'=>$id, 'status'=>'everything') ) as $EM_Event ) $EM_Event->delete();
|
23 |
+
foreach( EM_Locations::get( array('owner'=>$id, 'status'=>'everything', 'ids_only'=>true) ) as $EM_Location ) $EM_Location->delete();
|
24 |
}
|
25 |
//delete their bookings completely
|
26 |
+
//@TODO allow option to reassign bookings in a sensible way (i.e. handle personal data being transferred)
|
27 |
$EM_Person = new EM_Person();
|
28 |
$EM_Person->ID = $EM_Person->person_id = $id;
|
29 |
foreach( $EM_Person->get_bookings() as $EM_Booking){
|
classes/em-person.php
CHANGED
@@ -1,7 +1,9 @@
|
|
1 |
<?php
|
2 |
// TODO make person details more secure and integrate with WP user data
|
3 |
class EM_Person extends WP_User{
|
4 |
-
|
|
|
|
|
5 |
function __construct( $person_id = false, $username = '', $blog_id='' ){
|
6 |
if( is_array($person_id) ){
|
7 |
if( array_key_exists('person_id',$person_id) ){
|
@@ -104,7 +106,17 @@ class EM_Person extends WP_User{
|
|
104 |
<?php
|
105 |
return apply_filters('em_person_display_summary', ob_get_clean(), $this);
|
106 |
}
|
107 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
108 |
function get_name(){
|
109 |
$full_name = $this->first_name . " " . $this->last_name ;
|
110 |
$full_name = wp_kses_data(trim($full_name));
|
1 |
<?php
|
2 |
// TODO make person details more secure and integrate with WP user data
|
3 |
class EM_Person extends WP_User{
|
4 |
+
|
5 |
+
public $custom_user_fields = array();
|
6 |
+
|
7 |
function __construct( $person_id = false, $username = '', $blog_id='' ){
|
8 |
if( is_array($person_id) ){
|
9 |
if( array_key_exists('person_id',$person_id) ){
|
106 |
<?php
|
107 |
return apply_filters('em_person_display_summary', ob_get_clean(), $this);
|
108 |
}
|
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);
|
118 |
+
}
|
119 |
+
|
120 |
function get_name(){
|
121 |
$full_name = $this->first_name . " " . $this->last_name ;
|
122 |
$full_name = wp_kses_data(trim($full_name));
|
classes/em-taxonomy-terms.php
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
<?php
|
2 |
-
class EM_Taxonomy_Terms extends EM_Object implements Iterator{
|
3 |
|
4 |
protected $is_ms_global = false;
|
5 |
protected $meta_key = 'event-taxonomy';
|
@@ -326,4 +326,7 @@ class EM_Taxonomy_Terms extends EM_Object implements Iterator{
|
|
326 |
$var = ($key !== NULL && $key !== FALSE);
|
327 |
return $var;
|
328 |
}
|
|
|
|
|
|
|
329 |
}
|
1 |
<?php
|
2 |
+
class EM_Taxonomy_Terms extends EM_Object implements Iterator, Countable{
|
3 |
|
4 |
protected $is_ms_global = false;
|
5 |
protected $meta_key = 'event-taxonomy';
|
326 |
$var = ($key !== NULL && $key !== FALSE);
|
327 |
return $var;
|
328 |
}
|
329 |
+
public function count(){
|
330 |
+
return count($this->terms);
|
331 |
+
}
|
332 |
}
|
em-data-privacy.php
ADDED
@@ -0,0 +1,170 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Outputs a checkbox that can be used to obtain consent.
|
4 |
+
* @param EM_Event|EM_Location|EM_Booking|bool $EM_Object
|
5 |
+
*/
|
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 = sprintf(get_option('dbem_data_privacy_consent_text'), get_the_privacy_policy_link());
|
9 |
+
if( is_user_logged_in() ){
|
10 |
+
//check if consent was previously given and check box if true
|
11 |
+
$consent_given_already = get_user_meta( get_current_user_id(), 'em_data_privacy_consent', true );
|
12 |
+
if( !empty($consent_given_already) && get_option('dbem_data_privacy_consent_remember') == 1 ) return; //ignore if consent given as per settings
|
13 |
+
if( !empty($consent_given_already) && get_option('dbem_data_privacy_consent_remember') == 2 ) $checked = true;
|
14 |
+
}
|
15 |
+
if( empty($checked) && !empty($_REQUEST['data_privacy_consent']) ) $checked = true;
|
16 |
+
?>
|
17 |
+
<p class="input-group input-checkbox input-field-data_privacy_consent">
|
18 |
+
<label>
|
19 |
+
<input type="checkbox" name="data_privacy_consent" value="1" <?php if( !empty($checked) ) echo 'checked="checked"'; ?>>
|
20 |
+
<?php echo $label; ?>
|
21 |
+
</label>
|
22 |
+
<br style="clear:both;">
|
23 |
+
</p>
|
24 |
+
<?php
|
25 |
+
}
|
26 |
+
|
27 |
+
function em_data_privacy_consent_hooks(){
|
28 |
+
//BOOKINGS
|
29 |
+
if( get_option('dbem_data_privacy_consent_bookings') == 1 || ( get_option('dbem_data_privacy_consent_bookings') == 2 && !is_user_logged_in() ) ){
|
30 |
+
add_action('em_booking_form_footer', 'em_data_privacy_bookings_consent_checkbox', 9, 1);
|
31 |
+
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
|
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);
|
35 |
+
}
|
36 |
+
//EVENTS
|
37 |
+
if( get_option('dbem_data_privacy_consent_events') == 1 || ( get_option('dbem_data_privacy_consent_events') == 2 && !is_user_logged_in() ) ){
|
38 |
+
add_action('em_front_event_form_footer', 'em_data_privacy_consent_event_checkbox', 9, 1);
|
39 |
+
/**
|
40 |
+
* Wrapper function in case old overriden templates didn't pass the EM_Event object and depended on global value
|
41 |
+
* @param EM_Event $event
|
42 |
+
*/
|
43 |
+
function em_data_privacy_consent_event_checkbox( $event ){
|
44 |
+
if( empty($event) ){ global $EM_Event; }
|
45 |
+
else{ $EM_Event = $event ; }
|
46 |
+
em_data_privacy_consent_checkbox($EM_Event);
|
47 |
+
}
|
48 |
+
add_action('em_event_get_post_meta', 'em_data_privacy_cpt_get_post', 10, 2);
|
49 |
+
add_action('em_event_validate', 'em_data_privacy_cpt_validate', 10, 2);
|
50 |
+
add_action('em_event_save', 'em_data_privacy_cpt_save', 10, 2);
|
51 |
+
}
|
52 |
+
//LOCATIONS
|
53 |
+
if( get_option('dbem_data_privacy_consent_locations') == 1 || ( get_option('dbem_data_privacy_consent_events') == 2 && !is_user_logged_in() ) ){
|
54 |
+
add_action('em_front_location_form_footer', 'em_data_privacy_consent_location_checkbox', 9, 1); /**
|
55 |
+
* Wrapper function in case old overriden templates didn't pass the EM_Location object and depended on global value
|
56 |
+
* @param EM_Location $location
|
57 |
+
*/
|
58 |
+
function em_data_privacy_consent_location_checkbox( $location ){
|
59 |
+
if( empty($location) ){ global $EM_Location; }
|
60 |
+
else{ $EM_Location = $location ; }
|
61 |
+
em_data_privacy_consent_checkbox($EM_Location);
|
62 |
+
}
|
63 |
+
add_action('em_location_get_post_meta', 'em_data_privacy_cpt_get_post', 10, 2);
|
64 |
+
add_action('em_location_validate', 'em_data_privacy_cpt_validate', 10, 2);
|
65 |
+
add_action('em_location_save', 'em_data_privacy_cpt_save', 10, 2);
|
66 |
+
}
|
67 |
+
}
|
68 |
+
add_action('init', 'em_data_privacy_consent_hooks');
|
69 |
+
|
70 |
+
/**
|
71 |
+
* Gets consent information for the submitted booking and and add it to the booking object for saving later.
|
72 |
+
* @param bool $result
|
73 |
+
* @param EM_Booking $EM_Booking
|
74 |
+
* @return bool
|
75 |
+
*/
|
76 |
+
function em_data_privacy_consent_booking_get_post( $result, $EM_Booking ){
|
77 |
+
if( !empty($_REQUEST['data_privacy_consent']) ){
|
78 |
+
$EM_Booking->booking_meta['consent'] = true;
|
79 |
+
}
|
80 |
+
return $result;
|
81 |
+
}
|
82 |
+
|
83 |
+
/**
|
84 |
+
* Validates a bookng to ensure consent is/was given.
|
85 |
+
* @param bool $result
|
86 |
+
* @param EM_Booking $EM_Booking
|
87 |
+
* @return bool
|
88 |
+
*/
|
89 |
+
function em_data_privacy_consent_booking_validate( $result, $EM_Booking ){
|
90 |
+
if( is_user_logged_in() ){
|
91 |
+
//check if consent was previously given and ignore if settings dictate so
|
92 |
+
$consent_given_already = get_user_meta( get_current_user_id(), 'em_data_privacy_consent', true );
|
93 |
+
if( !empty($consent_given_already) && get_option('dbem_data_privacy_consent_remember') == 1 ) return $result; //ignore if consent given as per settings
|
94 |
+
}
|
95 |
+
if( empty($EM_Booking->booking_meta['consent']) ){
|
96 |
+
$EM_Booking->add_error( sprintf(__('You must allow us to collect and store your data in order for us to process your booking.', 'events-manager')) );
|
97 |
+
$result = false;
|
98 |
+
}
|
99 |
+
return $result;
|
100 |
+
}
|
101 |
+
|
102 |
+
/**
|
103 |
+
* Updates or adds the consent date of user account meta if booking was submitted by a user and consent was given.
|
104 |
+
* @param bool $result
|
105 |
+
* @param EM_Booking $EM_Booking
|
106 |
+
* @return bool
|
107 |
+
*/
|
108 |
+
function em_data_privacy_consent_booking_save( $result, $EM_Booking ){
|
109 |
+
if( $result ){
|
110 |
+
if( $EM_Booking->person_id != 0 ){
|
111 |
+
update_user_meta( $EM_Booking->person_id, 'em_data_privacy_consent', current_time('mysql') );
|
112 |
+
}
|
113 |
+
}
|
114 |
+
return $result;
|
115 |
+
}
|
116 |
+
|
117 |
+
/**
|
118 |
+
* Save consent to event or location object
|
119 |
+
* @param bool $result
|
120 |
+
* @param EM_Event|EM_Location $EM_Object
|
121 |
+
* @return bool
|
122 |
+
*/
|
123 |
+
function em_data_privacy_cpt_get_post($result, $EM_Object ){
|
124 |
+
if( !empty($_REQUEST['data_privacy_consent']) ){
|
125 |
+
if( get_class($EM_Object) == 'EM_Event' ){
|
126 |
+
$EM_Object->event_attributes['_consent_given'] = 1;
|
127 |
+
$EM_Object->get_location()->location_attributes['_consent_given'] = 1;
|
128 |
+
}else{
|
129 |
+
$EM_Object->location_attributes['_consent_given'] = 1;
|
130 |
+
}
|
131 |
+
}
|
132 |
+
return $result;
|
133 |
+
}
|
134 |
+
|
135 |
+
/**
|
136 |
+
* Validate the consent provided to events and locations.
|
137 |
+
* @param bool $result
|
138 |
+
* @param EM_Event|EM_Location $EM_Object
|
139 |
+
* @return bool
|
140 |
+
*/
|
141 |
+
function em_data_privacy_cpt_validate( $result, $EM_Object ){
|
142 |
+
if( !empty($EM_Object->post_id) ) return $result;
|
143 |
+
if( is_user_logged_in() ){
|
144 |
+
//check if consent was previously given and ignore if settings dictate so
|
145 |
+
$consent_given_already = get_user_meta( get_current_user_id(), 'em_data_privacy_consent', true );
|
146 |
+
if( !empty($consent_given_already) && get_option('dbem_data_privacy_consent_remember') == 1 ) return $result; //ignore if consent given as per settings
|
147 |
+
}
|
148 |
+
$attributes = get_class($EM_Object) == 'EM_Event' ? 'event_attributes':'location_attributes';
|
149 |
+
if( empty($EM_Object->{$attributes}['_consent_given']) ){
|
150 |
+
$EM_Object->add_error( sprintf(__('Please check the consent box so we can collect and store your submitted information.', 'events-manager')) );
|
151 |
+
$result = false;
|
152 |
+
}
|
153 |
+
return $result;
|
154 |
+
}
|
155 |
+
|
156 |
+
/**
|
157 |
+
* When an event or location is saved and consent is given or supplied again, update user account with latest consent date IF the object isn't associated with an anonymous user.
|
158 |
+
* @param bool $result
|
159 |
+
* @param EM_Event|EM_Location $EM_Object
|
160 |
+
* @return bool
|
161 |
+
*/
|
162 |
+
function em_data_privacy_cpt_save( $result, $EM_Object ){
|
163 |
+
$attributes = get_class($EM_Object) == 'EM_Event' ? 'event_attributes':'location_attributes';
|
164 |
+
if( $result && !empty($EM_Object->{$attributes}['_consent_given'])){
|
165 |
+
if( !get_option('dbem_events_anonymous_submissions') || $EM_Object->post_author != get_option('dbem_events_anonymous_user') ){
|
166 |
+
update_user_meta( $EM_Object->post_author, 'em_data_privacy_consent', current_time('mysql') );
|
167 |
+
}
|
168 |
+
}
|
169 |
+
return $result;
|
170 |
+
}
|
em-events.php
CHANGED
@@ -119,7 +119,7 @@ function em_content($page_content) {
|
|
119 |
$content = str_replace('CONTENTS',$content,$page_content);
|
120 |
}
|
121 |
if(get_option('dbem_credits')){
|
122 |
-
$content .= '<p style="color:#999; font-size:11px;">Powered by <a href="
|
123 |
}
|
124 |
}
|
125 |
return apply_filters('em_content', '<div id="em-wrapper">'.$content.'</div>');
|
119 |
$content = str_replace('CONTENTS',$content,$page_content);
|
120 |
}
|
121 |
if(get_option('dbem_credits')){
|
122 |
+
$content .= '<p style="color:#999; font-size:11px;">Powered by <a href="https://wp-events-plugin.com" style="color:#999;" target="_blank">Events Manager</a></p>';
|
123 |
}
|
124 |
}
|
125 |
return apply_filters('em_content', '<div id="em-wrapper">'.$content.'</div>');
|
em-functions.php
CHANGED
@@ -343,7 +343,7 @@ function em_get_attributes($lattributes = false){
|
|
343 |
}
|
344 |
}
|
345 |
}
|
346 |
-
return apply_filters('em_get_attributes', $attributes, $matches);
|
347 |
}
|
348 |
|
349 |
/**
|
343 |
}
|
344 |
}
|
345 |
}
|
346 |
+
return apply_filters('em_get_attributes', $attributes, $matches, $lattributes);
|
347 |
}
|
348 |
|
349 |
/**
|
em-ical.php
CHANGED
@@ -73,7 +73,7 @@
|
|
73 |
* @return string
|
74 |
*/
|
75 |
function em_mb_ical_wordwrap($string){
|
76 |
-
if( !defined('EM_MB_ICAL_WORDWRAP') ||
|
77 |
/*
|
78 |
// Match anything 1 to $width chars long followed by whitespace or EOS, otherwise match anything $width chars long
|
79 |
$search = '/(.{1,74})(?:\s|$)|(.{74})/uS';
|
73 |
* @return string
|
74 |
*/
|
75 |
function em_mb_ical_wordwrap($string){
|
76 |
+
if( !defined('EM_MB_ICAL_WORDWRAP') || EM_MB_ICAL_WORDWRAP ){
|
77 |
/*
|
78 |
// Match anything 1 to $width chars long followed by whitespace or EOS, otherwise match anything $width chars long
|
79 |
$search = '/(.{1,74})(?:\s|$)|(.{74})/uS';
|
em-install.php
CHANGED
@@ -496,23 +496,23 @@ function em_add_options() {
|
|
496 |
'dbem_display_calendar_in_events_page' => 0,
|
497 |
'dbem_single_event_format' => '<div style="float:right; margin:0px 0px 15px 15px;">#_LOCATIONMAP</div>
|
498 |
<p>
|
499 |
-
<strong>'.
|
500 |
Date(s) - #_EVENTDATES<br /><i>#_EVENTTIMES</i>
|
501 |
</p>
|
502 |
{has_location}
|
503 |
<p>
|
504 |
-
<strong>'.
|
505 |
#_LOCATIONLINK
|
506 |
</p>
|
507 |
{/has_location}
|
508 |
<p>
|
509 |
-
<strong>'.
|
510 |
#_CATEGORIES
|
511 |
</p>
|
512 |
<br style="clear:both" />
|
513 |
#_EVENTNOTES
|
514 |
{has_bookings}
|
515 |
-
<h3>Bookings</h3>
|
516 |
#_BOOKINGFORM
|
517 |
{/has_bookings}',
|
518 |
'dbem_event_excerpt_format' => '#_EVENTDATES @ #_EVENTTIMES - #_EVENTEXCERPT',
|
@@ -823,7 +823,19 @@ function em_add_options() {
|
|
823 |
//feedback reminder
|
824 |
'dbem_feedback_reminder' => time(),
|
825 |
'dbem_events_page_ajax' => 0,
|
826 |
-
'dbem_conditional_recursions' => 1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
827 |
);
|
828 |
|
829 |
//do date js according to locale:
|
@@ -1067,6 +1079,12 @@ function em_upgrade_current_installation(){
|
|
1067 |
));
|
1068 |
EM_Admin_Notices::add($EM_Admin_Notice, is_multisite());
|
1069 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
1070 |
}
|
1071 |
|
1072 |
function em_set_mass_caps( $roles, $caps ){
|
496 |
'dbem_display_calendar_in_events_page' => 0,
|
497 |
'dbem_single_event_format' => '<div style="float:right; margin:0px 0px 15px 15px;">#_LOCATIONMAP</div>
|
498 |
<p>
|
499 |
+
<strong>'.esc_html__('Date/Time','events-manager').'</strong><br/>
|
500 |
Date(s) - #_EVENTDATES<br /><i>#_EVENTTIMES</i>
|
501 |
</p>
|
502 |
{has_location}
|
503 |
<p>
|
504 |
+
<strong>'.esc_html__('Location','events-manager').'</strong><br/>
|
505 |
#_LOCATIONLINK
|
506 |
</p>
|
507 |
{/has_location}
|
508 |
<p>
|
509 |
+
<strong>'.esc_html__('Categories','events-manager').'</strong>
|
510 |
#_CATEGORIES
|
511 |
</p>
|
512 |
<br style="clear:both" />
|
513 |
#_EVENTNOTES
|
514 |
{has_bookings}
|
515 |
+
<h3>'.esc_html__('Bookings','events-manager').'</h3>
|
516 |
#_BOOKINGFORM
|
517 |
{/has_bookings}',
|
518 |
'dbem_event_excerpt_format' => '#_EVENTDATES @ #_EVENTTIMES - #_EVENTEXCERPT',
|
823 |
//feedback reminder
|
824 |
'dbem_feedback_reminder' => time(),
|
825 |
'dbem_events_page_ajax' => 0,
|
826 |
+
'dbem_conditional_recursions' => 1,
|
827 |
+
//data privacy/protection
|
828 |
+
'dbem_data_privacy_consent_text' => esc_html__('I consent to my submitted data being collected and stored as outlined by the site %s.','events-manager'),
|
829 |
+
'dbem_data_privacy_consent_remember' => 1,
|
830 |
+
'dbem_data_privacy_consent_events' => 1,
|
831 |
+
'dbem_data_privacy_consent_locations' => 1,
|
832 |
+
'dbem_data_privacy_consent_bookings' => 1,
|
833 |
+
'dbem_data_privacy_export_events' => 1,
|
834 |
+
'dbem_data_privacy_export_locations' => 1,
|
835 |
+
'dbem_data_privacy_export_bookings' => 1,
|
836 |
+
'dbem_data_privacy_erase_events' => 1,
|
837 |
+
'dbem_data_privacy_erase_locations' => 1,
|
838 |
+
'dbem_data_privacy_erase_bookings' => 1
|
839 |
);
|
840 |
|
841 |
//do date js according to locale:
|
1079 |
));
|
1080 |
EM_Admin_Notices::add($EM_Admin_Notice, is_multisite());
|
1081 |
}
|
1082 |
+
if( get_option('dbem_version') != '' && get_option('dbem_version') < 5.93 ){
|
1083 |
+
$message = __('Events Manager has introduced new privacy tools to help you comply with international laws such as the GDPR, <a href="%s">see our documentation</a> for more information.','events-manager');
|
1084 |
+
$message = sprintf( $message, 'https://wp-events-plugin.com/documentation/data-privacy-protection/?utm_source=plugin&utm_campaign=gdpr_update');
|
1085 |
+
$EM_Admin_Notice = new EM_Admin_Notice(array( 'name' => 'gdpr_update', 'who' => 'admin', 'where' => 'all', 'message' => $message ));
|
1086 |
+
EM_Admin_Notices::add($EM_Admin_Notice, is_multisite());
|
1087 |
+
}
|
1088 |
}
|
1089 |
|
1090 |
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.
|
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,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.
|
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
|
@@ -82,6 +82,7 @@ include("em-functions.php");
|
|
82 |
include("em-ical.php");
|
83 |
include("em-shortcode.php");
|
84 |
include("em-template-tags.php");
|
|
|
85 |
include("multilingual/em-ml.php");
|
86 |
//Widgets
|
87 |
include("widgets/em-events.php");
|
@@ -124,6 +125,7 @@ if( is_admin() ){
|
|
124 |
include('admin/em-docs.php');
|
125 |
include('admin/em-help.php');
|
126 |
include('admin/em-options.php');
|
|
|
127 |
if( is_multisite() ){
|
128 |
include('admin/em-ms-options.php');
|
129 |
}
|
1 |
<?php
|
2 |
/*
|
3 |
Plugin Name: Events Manager
|
4 |
+
Version: 5.9.3
|
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.93); //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
|
82 |
include("em-ical.php");
|
83 |
include("em-shortcode.php");
|
84 |
include("em-template-tags.php");
|
85 |
+
include("em-data-privacy.php");
|
86 |
include("multilingual/em-ml.php");
|
87 |
//Widgets
|
88 |
include("widgets/em-events.php");
|
125 |
include('admin/em-docs.php');
|
126 |
include('admin/em-help.php');
|
127 |
include('admin/em-options.php');
|
128 |
+
include('admin/em-data-privacy.php');
|
129 |
if( is_multisite() ){
|
130 |
include('admin/em-ms-options.php');
|
131 |
}
|
includes/css/events_manager.css
CHANGED
@@ -94,7 +94,8 @@ div#em-loading { position:absolute; width:100%; height:100%; background:#FFFFFF
|
|
94 |
.em-booking-form label { display:block; float:left; }
|
95 |
.em-booking-form span.input-group input { margin-left:-20px; }
|
96 |
.em-booking-form span.input-group { display:block; margin-left:120px; }
|
97 |
-
.em-booking-form label { display:inline-block; width:100px; }
|
|
|
98 |
.em-booking-form-details .em-booking-submit { width:auto; }
|
99 |
/* Tickets */
|
100 |
.em-tickets { margin-bottom:20px; }
|
94 |
.em-booking-form label { display:block; float:left; }
|
95 |
.em-booking-form span.input-group input { margin-left:-20px; }
|
96 |
.em-booking-form span.input-group { display:block; margin-left:120px; }
|
97 |
+
.em-booking-form label { display:inline-block; width:100px; }
|
98 |
+
.em-booking-form p.input-field-data_privacy_consent label { display:block; width:100%; }
|
99 |
.em-booking-form-details .em-booking-submit { width:auto; }
|
100 |
/* Tickets */
|
101 |
.em-tickets { margin-bottom:20px; }
|
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
|
5 |
Text Domain: events-manager
|
6 |
Requires at least: 3.5
|
7 |
-
Tested up to: 4.9
|
8 |
-
Stable tag: 5.9.
|
9 |
|
10 |
Fully featured event registration management including recurring events, locations management, calendar, Google map integration, booking management
|
11 |
|
@@ -50,13 +50,23 @@ Version 5 now makes events and locations WordPress Custom Post Types, allowing f
|
|
50 |
* Lots of documentation and tutorials
|
51 |
* And much more!
|
52 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
53 |
= Go Pro =
|
54 |
-
We have
|
55 |
|
56 |
* PayPal, Authorize.net and Offline Payments
|
57 |
* Custom booking forms
|
|
|
58 |
* Coupon Codes
|
59 |
-
*
|
|
|
60 |
|
61 |
For more information or to go pro, [visit our plugin website](http://wp-events-plugin.com/features/).
|
62 |
|
@@ -100,6 +110,15 @@ See our [FAQ](http://wp-events-plugin.com/documentation/faq/) page, which is upd
|
|
100 |
6. Manage attendees with various booking reports
|
101 |
|
102 |
== Changelog ==
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
103 |
= 5.9.2 =
|
104 |
* fixed some instances where PHP 5.2 outputs incorrect times due to other plugins changing server timezones
|
105 |
* fixed scope issues with PHP 5.2 when calculating start/end of month dates
|
@@ -109,7 +128,7 @@ See our [FAQ](http://wp-events-plugin.com/documentation/faq/) page, which is upd
|
|
109 |
* added notice when viewing bookings made in another language
|
110 |
* added booking admin table column for language used in booking
|
111 |
* fixed some minor PHP notices preventing event submissions/edits with a new location if display_errors are enabled
|
112 |
-
* updated EM_Notices to use new class names for notices output in WP
|
113 |
* added filters for all post type and custom taxonomy arrays used in initial post type and custom taxonomy registration functions (see em-posts.php)
|
114 |
|
115 |
= 5.9.1 =
|
4 |
Tags: bookings, calendar, tickets, events, buddypress, event management, google maps, maps, locations, registration
|
5 |
Text Domain: events-manager
|
6 |
Requires at least: 3.5
|
7 |
+
Tested up to: 4.9.6
|
8 |
+
Stable tag: 5.9.3
|
9 |
|
10 |
Fully featured event registration management including recurring events, locations management, calendar, Google map integration, booking management
|
11 |
|
50 |
* Lots of documentation and tutorials
|
51 |
* And much more!
|
52 |
|
53 |
+
= Data Privacy and GDPR Compliance =
|
54 |
+
We provide the tools to [help you be GDPR compliant](http://wp-events-plugin.com/documentation/data-privacy-gdpr-compliance/), including:
|
55 |
+
|
56 |
+
* export/erasure of data via the WordPress Privacy Tools, including booking, event and location data
|
57 |
+
* consent checkboxes on our booking, event and location forms on the frontend
|
58 |
+
* settings to control what can be exported/erased as well as where/when to place consent requests
|
59 |
+
* privacy policy sample describing what Events Manager does with personal data
|
60 |
+
|
61 |
= Go Pro =
|
62 |
+
We have a premium "Pro" add-on for Events Manager which not only demonstrates the flexibility of Events Manager, but also adds some important features including but not limited to:
|
63 |
|
64 |
* PayPal, Authorize.net and Offline Payments
|
65 |
* Custom booking forms
|
66 |
+
* Individual Attendee custom forms
|
67 |
* Coupon Codes
|
68 |
+
* Custom booking email per event and gateway
|
69 |
+
* Faster support via private Pro forums
|
70 |
|
71 |
For more information or to go pro, [visit our plugin website](http://wp-events-plugin.com/features/).
|
72 |
|
110 |
6. Manage attendees with various booking reports
|
111 |
|
112 |
== Changelog ==
|
113 |
+
= 5.9.3 =
|
114 |
+
* added Data Privacy and GDPR features
|
115 |
+
* fixed user deletion not properly deleting events and not deleting locations if content is set to be deleted not reassigned
|
116 |
+
* added location attributes array to em_get_attributes filter
|
117 |
+
* fixed EM_MB_ICAL_WORDWRAP incorrectly not applying multibyte wordwraps if set to true
|
118 |
+
* added 'not_all_day' conditional placeholder
|
119 |
+
* made EM_Taxonomy_Terms objects countable
|
120 |
+
* fixed tag placeholders not getting parsed in event format such as #_TAGIMAGE
|
121 |
+
|
122 |
= 5.9.2 =
|
123 |
* fixed some instances where PHP 5.2 outputs incorrect times due to other plugins changing server timezones
|
124 |
* fixed scope issues with PHP 5.2 when calculating start/end of month dates
|
128 |
* added notice when viewing bookings made in another language
|
129 |
* added booking admin table column for language used in booking
|
130 |
* fixed some minor PHP notices preventing event submissions/edits with a new location if display_errors are enabled
|
131 |
+
* updated EM_Notices to use new class names for notices output in WP Dashboard
|
132 |
* added filters for all post type and custom taxonomy arrays used in initial post type and custom taxonomy registration functions (see em-posts.php)
|
133 |
|
134 |
= 5.9.1 =
|
templates/forms/event-editor.php
CHANGED
@@ -25,7 +25,7 @@ if( !empty($_REQUEST['success']) ){
|
|
25 |
?>
|
26 |
<form enctype='multipart/form-data' id="event-form" class="em-event-admin-editor <?php if( $EM_Event->is_recurring() ) echo 'em-event-admin-recurring' ?>" method="post" action="<?php echo esc_url(add_query_arg(array('success'=>null))); ?>">
|
27 |
<div class="wrap">
|
28 |
-
<?php do_action('em_front_event_form_header'); ?>
|
29 |
<?php if(get_option('dbem_events_anonymous_submissions') && !is_user_logged_in()): ?>
|
30 |
<h3 class="event-form-submitter"><?php esc_html_e( 'Your Details', 'events-manager'); ?></h3>
|
31 |
<div class="inside event-form-submitter">
|
@@ -102,7 +102,7 @@ if( !empty($_REQUEST['success']) ){
|
|
102 |
<!-- END Bookings -->
|
103 |
<?php endif; ?>
|
104 |
|
105 |
-
<?php do_action('em_front_event_form_footer'); ?>
|
106 |
</div>
|
107 |
<p class="submit">
|
108 |
<?php if( empty($EM_Event->event_id) ): ?>
|
25 |
?>
|
26 |
<form enctype='multipart/form-data' id="event-form" class="em-event-admin-editor <?php if( $EM_Event->is_recurring() ) echo 'em-event-admin-recurring' ?>" method="post" action="<?php echo esc_url(add_query_arg(array('success'=>null))); ?>">
|
27 |
<div class="wrap">
|
28 |
+
<?php do_action('em_front_event_form_header', $EM_Event); ?>
|
29 |
<?php if(get_option('dbem_events_anonymous_submissions') && !is_user_logged_in()): ?>
|
30 |
<h3 class="event-form-submitter"><?php esc_html_e( 'Your Details', 'events-manager'); ?></h3>
|
31 |
<div class="inside event-form-submitter">
|
102 |
<!-- END Bookings -->
|
103 |
<?php endif; ?>
|
104 |
|
105 |
+
<?php do_action('em_front_event_form_footer', $EM_Event); ?>
|
106 |
</div>
|
107 |
<p class="submit">
|
108 |
<?php if( empty($EM_Event->event_id) ): ?>
|
templates/forms/location-editor.php
CHANGED
@@ -21,7 +21,7 @@ if(!is_admin()) echo $EM_Notices;
|
|
21 |
<input type='hidden' name='_wpnonce' value='<?php echo wp_create_nonce('location_save'); ?>' />
|
22 |
<input type='hidden' name='location_id' value='<?php echo $EM_Location->location_id ?>'/>
|
23 |
|
24 |
-
<?php do_action('em_front_location_form_header'); ?>
|
25 |
<h3 class="location-form-name"><?php esc_html_e( 'Location Name', 'events-manager'); ?></h3>
|
26 |
<div class="inside location-form-name">
|
27 |
<input name='location_name' id='location-name' type='text' value='<?php echo esc_attr($EM_Location->location_name, ENT_QUOTES); ?>' size='40' />
|
@@ -55,7 +55,7 @@ if(!is_admin()) echo $EM_Notices;
|
|
55 |
</div>
|
56 |
<?php endif; ?>
|
57 |
|
58 |
-
<?php do_action('em_front_location_form_footer'); ?>
|
59 |
|
60 |
<?php if( !empty($_REQUEST['redirect_to']) ): ?>
|
61 |
<input type="hidden" name="redirect_to" value="<?php echo esc_attr($_REQUEST['redirect_to']); ?>" />
|
21 |
<input type='hidden' name='_wpnonce' value='<?php echo wp_create_nonce('location_save'); ?>' />
|
22 |
<input type='hidden' name='location_id' value='<?php echo $EM_Location->location_id ?>'/>
|
23 |
|
24 |
+
<?php do_action('em_front_location_form_header', $EM_Location); ?>
|
25 |
<h3 class="location-form-name"><?php esc_html_e( 'Location Name', 'events-manager'); ?></h3>
|
26 |
<div class="inside location-form-name">
|
27 |
<input name='location_name' id='location-name' type='text' value='<?php echo esc_attr($EM_Location->location_name, ENT_QUOTES); ?>' size='40' />
|
55 |
</div>
|
56 |
<?php endif; ?>
|
57 |
|
58 |
+
<?php do_action('em_front_location_form_footer', $EM_Location); ?>
|
59 |
|
60 |
<?php if( !empty($_REQUEST['redirect_to']) ): ?>
|
61 |
<input type="hidden" name="redirect_to" value="<?php echo esc_attr($_REQUEST['redirect_to']); ?>" />
|