Events Manager - Version 5.1.8

Version Description

  • important - Modified template files? See this http://em.cm/datetime
  • fixed jigoshop session_start conflict
  • removed some group metabox php warnings
  • fixed slashes added to location/event name in db table
  • fixed/improved multisite capability management (see network admin settings)
  • events with >1 ticket will show multi-ticket editor regardless of single ticket mode setting
  • updated Brazilian language, added Catalan and fixed a few language datepicker oddities
  • fixed RSS validation fails for some special characters
  • fixed cancellations being possible after event boookings close
  • fixed admin-side search-by-category
  • fixed manage_others_bookings not allowing access to bookings without other caps
  • fixed calendar widgets taking on day link search arguments from other parts of the page
  • fixed admin email problems when in auto-approve mode and using alternate status numbers e.g. 5
  • added force-approve booking flag in EM_Booking::set_status
  • fixed ical locations and apostrophes and single ical file time offsets
  • fixed gallery shortcode for recurring events
  • fixed guest event submission auto-complete
  • refactored booking form JS to allow multiple forms on one page
  • fixed some booking js ui animations
  • fixed booking table overlay issues
  • added more js vars for translation purposes
  • improved placeholder replacement logic
  • added em_event_submission_login filter
  • simplified timepicker and datepicker JS and html strucuture for re-use
  • EM_Notices behaviour changed so errors are printed and not deleted, only at start/end of script
Download this release

Release Info

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

Code changes from version 3.0.98 to 5.1.8

Files changed (56) hide show
  1. admin/bookings/em-cancelled.php +136 -132
  2. admin/bookings/em-confirmed.php +143 -139
  3. admin/bookings/em-events.php +171 -178
  4. admin/bookings/em-pending.php +158 -154
  5. admin/bookings/em-person.php +151 -149
  6. admin/bookings/em-rejected.php +136 -132
  7. admin/em-admin.php +241 -284
  8. admin/em-bookings.php +506 -287
  9. admin/em-categories.php +0 -177
  10. admin/em-docs.php +318 -192
  11. admin/em-event.php +0 -627
  12. admin/em-events.php +0 -242
  13. admin/em-help.php +68 -51
  14. admin/em-locations-search.php +8 -3
  15. admin/em-locations.php +0 -268
  16. admin/em-ms-locations.php +55 -0
  17. admin/em-ms-options.php +212 -0
  18. admin/em-options.php +1689 -443
  19. admin/em-people.php +0 -192
  20. buddypress/bp-em-activity.php +130 -0
  21. buddypress/bp-em-core.php +235 -0
  22. buddypress/bp-em-groups.php +140 -0
  23. buddypress/bp-em-notifications.php +82 -0
  24. buddypress/bp-em-templatetags.php +21 -0
  25. buddypress/screens/attending.php +29 -0
  26. buddypress/screens/group-events.php +30 -0
  27. buddypress/screens/my-bookings.php +35 -0
  28. buddypress/screens/my-events.php +55 -0
  29. buddypress/screens/my-group-events.php +27 -0
  30. buddypress/screens/my-locations.php +51 -0
  31. buddypress/screens/profile.php +32 -0
  32. classes/em-booking.php +695 -378
  33. classes/em-bookings-table.php +623 -0
  34. classes/em-bookings.php +620 -487
  35. classes/em-calendar.php +372 -366
  36. classes/em-categories-taxonomy.php +104 -0
  37. classes/em-categories.php +320 -156
  38. classes/em-category-taxonomy.php +121 -0
  39. classes/em-category.php +215 -151
  40. classes/em-event-post-admin.php +382 -0
  41. classes/em-event-post.php +259 -0
  42. classes/em-event-posts-admin.php +280 -0
  43. classes/em-event.php +2095 -1005
  44. classes/em-events.php +386 -253
  45. classes/em-location-post-admin.php +134 -0
  46. classes/em-location-post.php +69 -0
  47. classes/em-location-posts-admin.php +84 -0
  48. classes/em-location.php +727 -306
  49. classes/em-locations.php +305 -212
  50. classes/em-mailer.php +115 -79
  51. classes/em-map.php +0 -60
  52. classes/em-notices.php +201 -0
  53. classes/em-object.php +1214 -485
  54. classes/em-people.php +33 -128
  55. classes/em-permalinks.php +241 -0
  56. classes/em-person.php +83 -153
admin/bookings/em-cancelled.php CHANGED
@@ -1,133 +1,137 @@
1
- <?php
2
- /**
3
- * Generates a "widget" table of confirmed bookings for a specific event.
4
- *
5
- * @param int $event_id
6
- */
7
- function em_bookings_cancelled_table(){
8
- global $EM_Event, $wpdb, $current_user;
9
-
10
- $action_scope = ( !empty($_REQUEST['em_obj']) && $_REQUEST['em_obj'] == 'em_bookings_cancelled_table' );
11
- $action = ( $action_scope && !empty($_GET ['action']) ) ? $_GET ['action']:'';
12
- $order = ( $action_scope && !empty($_GET ['order']) ) ? $_GET ['order']:'ASC';
13
- $limit = ( $action_scope && !empty($_GET['limit']) ) ? $_GET['limit'] : 20;//Default limit
14
- $page = ( $action_scope && !empty($_GET['pno']) ) ? $_GET['pno']:1;
15
- $offset = ( $action_scope && $page > 1 ) ? ($page-1)*$limit : 0;
16
-
17
- if( is_object($EM_Event) ){
18
- $bookings = $EM_Event->get_bookings()->get_cancelled_bookings();
19
- }else{
20
- return false;
21
- }
22
- $bookings_count = (is_array($bookings)) ? count($bookings):0;
23
- ?>
24
- <div class='wrap em_bookings_pending_table em_obj'>
25
- <form id='bookings-filter' method='get' action='<?php bloginfo('wpurl') ?>/wp-admin/edit.php'>
26
- <input type="hidden" name="em_obj" value="em_bookings_pending_table" />
27
- <!--
28
- <ul class="subsubsub">
29
- <li>
30
- <a href='edit.php?post_type=post' class="current">All <span class="count">(1)</span></a> |
31
- </li>
32
- </ul>
33
- <p class="search-box">
34
- <label class="screen-reader-text" for="post-search-input"><?php _e('Search'); ?>:</label>
35
- <input type="text" id="post-search-input" name="em_search" value="<?php echo (!empty($_GET['em_search'])) ? $_GET['em_search']:''; ?>" />
36
- <input type="submit" value="<?php _e('Search'); ?>" class="button" />
37
- </p>
38
- -->
39
- <?php if ( $bookings_count >= $limit ) : ?>
40
- <div class='tablenav'>
41
- <!--
42
- <div class="alignleft actions">
43
- <select name="action">
44
- <option value="-1" selected="selected">
45
- <?php _e('Bulk Actions'); ?>
46
- </option>
47
- <option value="approve">
48
- <?php _e('Approve', 'dbem'); ?>
49
- </option>
50
- <option value="decline">
51
- <?php _e('Decline', 'dbem'); ?>
52
- </option>
53
- </select>
54
- <input type="submit" id="post-query-submit" value="Filter" class="button-secondary" />
55
- </div>
56
- -->
57
- <!--
58
- <div class="view-switch">
59
- <a href="/wp-admin/edit.php?mode=list"><img class="current" id="view-switch-list" src="http://wordpress.lan/wp-includes/images/blank.gif" width="20" height="20" title="List View" alt="List View" name="view-switch-list" /></a> <a href="/wp-admin/edit.php?mode=excerpt"><img id="view-switch-excerpt" src="http://wordpress.lan/wp-includes/images/blank.gif" width="20" height="20" title="Excerpt View" alt="Excerpt View" name="view-switch-excerpt" /></a>
60
- </div>
61
- -->
62
- <?php
63
- if ( $bookings_count >= $limit ) {
64
- $page_link_template = em_add_get_params($_SERVER['REQUEST_URI'], array('pno'=>'%PAGE%', 'em_ajax'=>0, 'em_obj'=>'em_bookings_confirmed_table'));
65
- $bookings_nav = em_admin_paginate( $page_link_template, $bookings_count, $limit, $page, 5);
66
- echo $bookings_nav;
67
- }
68
- ?>
69
- <div class="clear"></div>
70
- </div>
71
- <?php endif; ?>
72
- <div class="clear"></div>
73
- <?php if( $bookings_count > 0 ): ?>
74
- <div class='table-wrap'>
75
- <table id='dbem-bookings-table' class='widefat post fixed'>
76
- <thead>
77
- <tr>
78
- <th class='manage-column column-cb check-column' scope='col'>
79
- <input class='select-all' type="checkbox" value='1' />
80
- </th>
81
- <th class='manage-column' scope='col'>Booker</th>
82
- <th class='manage-column' scope='col'>E-mail</th>
83
- <th class='manage-column' scope='col'>Phone number</th>
84
- <th class='manage-column' scope='col'>Spaces</th>
85
- <th class='manage-column' scope='col'>&nbsp;</th>
86
- </tr>
87
- </thead>
88
- <tbody>
89
- <?php
90
- $rowno = 0;
91
- $event_count = 0;
92
- foreach ($bookings as $EM_Booking) {
93
- if( ($rowno < $limit || empty($limit)) && ($event_count >= $offset || $offset === 0) ) {
94
- $rowno++;
95
- ?>
96
- <tr>
97
- <th scope="row" class="check-column" style="padding:7px 0px 7px;"><input type='checkbox' value='<?php echo $EM_Booking->id ?>' name='bookings[]'/></th>
98
- <td><a href="<?php bloginfo ( 'wpurl' )?>/wp-admin/admin.php?page=events-manager-bookings&amp;person_id=<?php echo $EM_Booking->person->id; ?>"><?php echo $EM_Booking->person->name ?></a></td>
99
- <td><?php echo $EM_Booking->person->email ?></td>
100
- <td><?php echo $EM_Booking->person->phone ?></td>
101
- <td><?php echo $EM_Booking->seats ?></td>
102
- <td>
103
- <?php
104
- $approve_url = em_add_get_params($_SERVER['REQUEST_URI'], array('action'=>'bookings_approve', 'booking_id'=>$EM_Booking->id));
105
- $delete_url = em_add_get_params($_SERVER['REQUEST_URI'], array('action'=>'bookings_delete', 'booking_id'=>$EM_Booking->id));
106
- ?>
107
- <a class="em-bookings-approve" href="<?php echo $approve_url ?>"><?php _e('Restore','dbem'); ?></a> |
108
- <a class="em-bookings-edit" href="<?php bloginfo ( 'wpurl' )?>/wp-admin/admin.php?page=events-manager-bookings&amp;booking_id=<?php echo $EM_Booking->id; ?>"><?php _e('Edit'); ?></a> |
109
- <a class="em-bookings-delete" href="<?php echo $delete_url ?>"><?php _e('Delete','dbem'); ?></a>
110
- </td>
111
- </tr>
112
- <?php
113
- }
114
- $event_count++;
115
- }
116
- ?>
117
- </tbody>
118
- </table>
119
- </div>
120
- <?php else: ?>
121
- <?php _e('No cancelled bookings.', 'dbem'); ?>
122
- <?php endif; ?>
123
- </form>
124
- <?php if( !empty($bookings_nav) ) : ?>
125
- <div class='tablenav'>
126
- <?php echo $bookings_nav; ?>
127
- <div class="clear"></div>
128
- </div>
129
- <?php endif; ?>
130
- </div>
131
- <?php
132
- }
 
 
 
 
133
  ?>
1
+ <?php
2
+ /**
3
+ * Generates a "widget" table of confirmed bookings for a specific event.
4
+ *
5
+ * @param int $event_id
6
+ */
7
+ function em_bookings_cancelled_table(){
8
+ global $EM_Event, $EM_Ticket, $wpdb, $current_user;
9
+
10
+ $action_scope = ( !empty($_REQUEST['em_obj']) && $_REQUEST['em_obj'] == 'em_bookings_cancelled_table' );
11
+ $action = ( $action_scope && !empty($_GET ['action']) ) ? $_GET ['action']:'';
12
+ $order = ( $action_scope && !empty($_GET ['order']) ) ? $_GET ['order']:'ASC';
13
+ $limit = ( $action_scope && !empty($_GET['limit']) ) ? $_GET['limit'] : 20;//Default limit
14
+ $page = ( $action_scope && !empty($_GET['pno']) ) ? $_GET['pno']:1;
15
+ $offset = ( $action_scope && $page > 1 ) ? ($page-1)*$limit : 0;
16
+
17
+ if( is_object($EM_Ticket) ){
18
+ $EM_Bookings = $EM_Ticket->get_bookings()->get_cancelled_bookings();
19
+ }else{
20
+ if( is_object($EM_Event) ){
21
+ $EM_Bookings = $EM_Event->get_bookings()->get_cancelled_bookings();
22
+ }else{
23
+ return false;
24
+ }
25
+ }
26
+ $bookings_count = (is_array($EM_Bookings->bookings)) ? count($EM_Bookings->bookings):0;
27
+ ?>
28
+ <div class='wrap em_bookings_pending_table em_obj'>
29
+ <form id='bookings-filter' method='get' action='<?php bloginfo('wpurl') ?>/wp-admin/edit.php'>
30
+ <input type="hidden" name="em_obj" value="em_bookings_pending_table" />
31
+ <!--
32
+ <ul class="subsubsub">
33
+ <li>
34
+ <a href='edit.php?post_type=post' class="current">All <span class="count">(1)</span></a> |
35
+ </li>
36
+ </ul>
37
+ <p class="search-box">
38
+ <label class="screen-reader-text" for="post-search-input"><?php _e('Search', 'dbem'); ?>:</label>
39
+ <input type="text" id="post-search-input" name="em_search" value="<?php echo (!empty($_GET['em_search'])) ? $_GET['em_search']:''; ?>" />
40
+ <input type="submit" value="<?php _e('Search', 'dbem'); ?>" class="button" />
41
+ </p>
42
+ -->
43
+ <?php if ( $bookings_count >= $limit ) : ?>
44
+ <div class='tablenav'>
45
+ <!--
46
+ <div class="alignleft actions">
47
+ <select name="action">
48
+ <option value="-1" selected="selected">
49
+ <?php _e('Bulk Actions', 'dbem'); ?>
50
+ </option>
51
+ <option value="approve">
52
+ <?php _e('Approve', 'dbem'); ?>
53
+ </option>
54
+ <option value="decline">
55
+ <?php _e('Decline', 'dbem'); ?>
56
+ </option>
57
+ </select>
58
+ <input type="submit" id="post-query-submit" value="Filter" class="button-secondary" />
59
+ </div>
60
+ -->
61
+ <!--
62
+ <div class="view-switch">
63
+ <a href="/wp-admin/edit.php?mode=list"><img class="current" id="view-switch-list" src="http://wordpress.lan/wp-includes/images/blank.gif" width="20" height="20" title="List View" alt="List View" name="view-switch-list" /></a> <a href="/wp-admin/edit.php?mode=excerpt"><img id="view-switch-excerpt" src="http://wordpress.lan/wp-includes/images/blank.gif" width="20" height="20" title="Excerpt View" alt="Excerpt View" name="view-switch-excerpt" /></a>
64
+ </div>
65
+ -->
66
+ <?php
67
+ if ( $bookings_count >= $limit ) {
68
+ $bookings_nav = em_admin_paginate( $bookings_count, $limit, $page, array('em_ajax'=>0, 'em_obj'=>'em_bookings_confirmed_table'));
69
+ echo $bookings_nav;
70
+ }
71
+ ?>
72
+ <div class="clear"></div>
73
+ </div>
74
+ <?php endif; ?>
75
+ <div class="clear"></div>
76
+ <?php if( $bookings_count > 0 ): ?>
77
+ <div class='table-wrap'>
78
+ <table id='dbem-bookings-table' class='widefat post '>
79
+ <thead>
80
+ <tr>
81
+ <th class='manage-column column-cb check-column' scope='col'>
82
+ <input class='select-all' type="checkbox" value='1' />
83
+ </th>
84
+ <th class='manage-column' scope='col'><?php _e('Booker', 'dbem'); ?></th>
85
+ <th class='manage-column' scope='col'><?php _e('E-mail', 'dbem'); ?></th>
86
+ <th class='manage-column' scope='col'><?php _e('Phone number', 'dbem'); ?></th>
87
+ <th class='manage-column' scope='col'><?php _e('Spaces', 'dbem'); ?></th>
88
+ <th class='manage-column' scope='col'>&nbsp;</th>
89
+ </tr>
90
+ </thead>
91
+ <tbody>
92
+ <?php
93
+ $rowno = 0;
94
+ $event_count = 0;
95
+ foreach ($EM_Bookings->bookings as $EM_Booking) {
96
+ if( ($rowno < $limit || empty($limit)) && ($event_count >= $offset || $offset === 0) ) {
97
+ $rowno++;
98
+ ?>
99
+ <tr>
100
+ <th scope="row" class="check-column" style="padding:7px 0px 7px;"><input type='checkbox' value='<?php echo $EM_Booking->booking_id ?>' name='bookings[]'/></th>
101
+ <td><a href="<?php echo EM_ADMIN_URL; ?>&amp;page=events-manager-bookings&amp;person_id=<?php echo $EM_Booking->person->ID; ?>"><?php echo $EM_Booking->person->get_name() ?></a></td>
102
+ <td><?php echo $EM_Booking->person->user_email ?></td>
103
+ <td><?php echo $EM_Booking->person->phone ?></td>
104
+ <td><?php echo $EM_Booking->get_spaces() ?></td>
105
+ <td>
106
+ <?php
107
+ $approve_url = em_add_get_params($_SERVER['REQUEST_URI'], array('action'=>'bookings_approve', 'booking_id'=>$EM_Booking->booking_id));
108
+ $delete_url = em_add_get_params($_SERVER['REQUEST_URI'], array('action'=>'bookings_delete', 'booking_id'=>$EM_Booking->booking_id));
109
+ $edit_url = em_add_get_params($_SERVER['REQUEST_URI'], array('booking_id'=>$EM_Booking->booking_id, 'em_ajax'=>null, 'em_obj'=>null));
110
+ ?>
111
+ <a class="em-bookings-approve" href="<?php echo $approve_url ?>"><?php _e('Restore','dbem'); ?></a> |
112
+ <a class="em-bookings-edit" href="<?php echo $edit_url; ?>"><?php _e('Edit/View','dbem'); ?></a> |
113
+ <a class="em-bookings-delete" href="<?php echo $delete_url ?>"><?php _e('Delete','dbem'); ?></a>
114
+ </td>
115
+ </tr>
116
+ <?php
117
+ }
118
+ $event_count++;
119
+ }
120
+ ?>
121
+ </tbody>
122
+ </table>
123
+ </div>
124
+ <?php else: ?>
125
+ <?php _e('No cancelled bookings.', 'dbem'); ?>
126
+ <?php endif; ?>
127
+ </form>
128
+ <?php if( !empty($bookings_nav) && $EM_Bookings >= $limit ) : ?>
129
+ <div class='tablenav'>
130
+ <?php echo $bookings_nav; ?>
131
+ <div class="clear"></div>
132
+ </div>
133
+ <?php endif; ?>
134
+ </div>
135
+ <?php
136
+ }
137
  ?>
admin/bookings/em-confirmed.php CHANGED
@@ -1,140 +1,144 @@
1
- <?php
2
-
3
- /**
4
- * Generates a "widget" table of confirmed bookings for a specific event.
5
- *
6
- * @param int $event_id
7
- */
8
- function em_bookings_confirmed_table(){
9
- global $EM_Event, $wpdb, $current_user;
10
-
11
- $action_scope = ( !empty($_REQUEST['em_obj']) && $_REQUEST['em_obj'] == 'em_bookings_confirmed_table' );
12
- $action = ( $action_scope && !empty($_GET ['action']) ) ? $_GET ['action']:'';
13
- $order = ( $action_scope && !empty($_GET ['order']) ) ? $_GET ['order']:'ASC';
14
- $limit = ( $action_scope && !empty($_GET['limit']) ) ? $_GET['limit'] : 20;//Default limit
15
- $page = ( $action_scope && !empty($_GET['pno']) ) ? $_GET['pno']:1;
16
- $offset = ( $action_scope && $page > 1 ) ? ($page-1)*$limit : 0;
17
-
18
- if( is_object($EM_Event) ){
19
- $bookings = $EM_Event->get_bookings()->get_bookings();
20
- }else{
21
- return false;
22
- }
23
- $bookings_count = (is_array($bookings)) ? count($bookings):0;
24
- ?>
25
- <div class='wrap em_bookings_pending_table em_obj'>
26
- <form id='bookings-filter' method='get' action='<?php bloginfo('wpurl') ?>/wp-admin/edit.php'>
27
- <input type="hidden" name="em_obj" value="em_bookings_pending_table" />
28
- <!--
29
- <ul class="subsubsub">
30
- <li>
31
- <a href='edit.php?post_type=post' class="current">All <span class="count">(1)</span></a> |
32
- </li>
33
- </ul>
34
- <p class="search-box">
35
- <label class="screen-reader-text" for="post-search-input"><?php _e('Search'); ?>:</label>
36
- <input type="text" id="post-search-input" name="em_search" value="<?php echo (!empty($_GET['em_search'])) ? $_GET['em_search']:''; ?>" />
37
- <input type="submit" value="<?php _e('Search'); ?>" class="button" />
38
- </p>
39
- -->
40
- <?php if ( $bookings_count >= $limit ) : ?>
41
- <div class='tablenav'>
42
- <!--
43
- <div class="alignleft actions">
44
- <select name="action">
45
- <option value="-1" selected="selected">
46
- <?php _e('Bulk Actions'); ?>
47
- </option>
48
- <option value="approve">
49
- <?php _e('Approve', 'dbem'); ?>
50
- </option>
51
- <option value="decline">
52
- <?php _e('Decline', 'dbem'); ?>
53
- </option>
54
- </select>
55
- <input type="submit" id="post-query-submit" value="Filter" class="button-secondary" />
56
- </div>
57
- -->
58
- <!--
59
- <div class="view-switch">
60
- <a href="/wp-admin/edit.php?mode=list"><img class="current" id="view-switch-list" src="http://wordpress.lan/wp-includes/images/blank.gif" width="20" height="20" title="List View" alt="List View" name="view-switch-list" /></a> <a href="/wp-admin/edit.php?mode=excerpt"><img id="view-switch-excerpt" src="http://wordpress.lan/wp-includes/images/blank.gif" width="20" height="20" title="Excerpt View" alt="Excerpt View" name="view-switch-excerpt" /></a>
61
- </div>
62
- -->
63
- <?php
64
- if ( $bookings_count >= $limit ) {
65
- $page_link_template = em_add_get_params($_SERVER['REQUEST_URI'], array('pno'=>'%PAGE%', 'em_ajax'=>0, 'em_obj'=>'em_bookings_confirmed_table'));
66
- $bookings_nav = em_admin_paginate( $page_link_template, $bookings_count, $limit, $page, 5);
67
- echo $bookings_nav;
68
- }
69
- ?>
70
- <div class="clear"></div>
71
- </div>
72
- <?php endif; ?>
73
- <div class="clear"></div>
74
- <?php if( $bookings_count > 0 ): ?>
75
- <div class='table-wrap'>
76
- <table id='dbem-bookings-table' class='widefat post fixed'>
77
- <thead>
78
- <tr>
79
- <th class='manage-column column-cb check-column' scope='col'>
80
- <input class='select-all' type="checkbox" value='1' />
81
- </th>
82
- <th class='manage-column' scope='col'>Booker</th>
83
- <th class='manage-column' scope='col'>E-mail</th>
84
- <th class='manage-column' scope='col'>Phone number</th>
85
- <th class='manage-column' scope='col'>Spaces</th>
86
- <th class='manage-column' scope='col'>&nbsp;</th>
87
- </tr>
88
- </thead>
89
- <tbody>
90
- <?php
91
- $rowno = 0;
92
- $event_count = 0;
93
- foreach ($bookings as $EM_Booking) {
94
- if( ($rowno < $limit || empty($limit)) && ($event_count >= $offset || $offset === 0) ) {
95
- $rowno++;
96
- ?>
97
- <tr>
98
- <th scope="row" class="check-column" style="padding:7px 0px 7px;"><input type='checkbox' value='<?php echo $EM_Booking->id ?>' name='bookings[]'/></th>
99
- <td><a href="<?php bloginfo ( 'wpurl' )?>/wp-admin/admin.php?page=events-manager-bookings&amp;person_id=<?php echo $EM_Booking->person_id; ?>"><?php echo $EM_Booking->person->name ?></a></td>
100
- <td><?php echo $EM_Booking->person->email ?></td>
101
- <td><?php echo $EM_Booking->person->phone ?></td>
102
- <td><?php echo $EM_Booking->seats ?></td>
103
- <td>
104
- <?php
105
- $unapprove_url = em_add_get_params($_SERVER['REQUEST_URI'], array('action'=>'bookings_unapprove', 'booking_id'=>$EM_Booking->id));
106
- $reject_url = em_add_get_params($_SERVER['REQUEST_URI'], array('action'=>'bookings_reject', 'booking_id'=>$EM_Booking->id));
107
- $delete_url = em_add_get_params($_SERVER['REQUEST_URI'], array('action'=>'bookings_delete', 'booking_id'=>$EM_Booking->id));
108
- ?>
109
- <?php if( get_option('dbem_bookings_approval') ): ?>
110
- <a class="em-bookings-unapprove" href="<?php echo $unapprove_url ?>"><?php _e('Unapprove','dbem'); ?></a> |
111
- <?php else: ?>
112
- <a class="em-bookings-reject" href="<?php echo $reject_url ?>"><?php _e('Reject','dbem'); ?></a> |
113
- <?php endif; ?>
114
- <a class="em-bookings-delete" href="<?php echo $delete_url ?>"><?php _e('Delete','dbem'); ?></a> |
115
- <a class="em-bookings-edit" href="<?php bloginfo ( 'wpurl' )?>/wp-admin/admin.php?page=events-manager-bookings&amp;booking_id=<?php echo $EM_Booking->id; ?>"><?php _e('Edit'); ?></a>
116
- </td>
117
- </tr>
118
- <?php
119
- }
120
- $event_count++;
121
- }
122
- ?>
123
- </tbody>
124
- </table>
125
- </div>
126
- <?php else: ?>
127
- <?php _e('No confirmed bookings.', 'dbem'); ?>
128
- <?php endif; ?>
129
- </form>
130
- <?php if( !empty($bookings_nav) ) : ?>
131
- <div class='tablenav'>
132
- <?php echo $bookings_nav; ?>
133
- <div class="clear"></div>
134
- </div>
135
- <?php endif; ?>
136
- </div>
137
- <?php
138
-
139
- }
 
 
 
 
140
  ?>
1
+ <?php
2
+
3
+ /**
4
+ * Generates a "widget" table of confirmed bookings for a specific event.
5
+ *
6
+ * @param int $event_id
7
+ */
8
+ function em_bookings_confirmed_table(){
9
+ global $EM_Event, $EM_Ticket, $wpdb, $current_user;
10
+
11
+ $action_scope = ( !empty($_REQUEST['em_obj']) && $_REQUEST['em_obj'] == 'em_bookings_confirmed_table' );
12
+ $action = ( $action_scope && !empty($_GET ['action']) ) ? $_GET ['action']:'';
13
+ $order = ( $action_scope && !empty($_GET ['order']) ) ? $_GET ['order']:'ASC';
14
+ $limit = ( $action_scope && !empty($_GET['limit']) ) ? $_GET['limit'] : 20;//Default limit
15
+ $page = ( $action_scope && !empty($_GET['pno']) ) ? $_GET['pno']:1;
16
+ $offset = ( $action_scope && $page > 1 ) ? ($page-1)*$limit : 0;
17
+
18
+ if( is_object($EM_Ticket) ){
19
+ $EM_Bookings = $EM_Ticket->get_bookings()->get_bookings();
20
+ }else{
21
+ if( is_object($EM_Event) ){
22
+ $EM_Bookings = $EM_Event->get_bookings()->get_bookings();
23
+ }else{
24
+ return false;
25
+ }
26
+ }
27
+ $bookings_count = (is_array($EM_Bookings->bookings)) ? count($EM_Bookings->bookings):0;
28
+ ?>
29
+ <div class='wrap em_bookings_pending_table em_obj'>
30
+ <form id='bookings-filter' method='get' action='<?php bloginfo('wpurl') ?>/wp-admin/edit.php'>
31
+ <input type="hidden" name="em_obj" value="em_bookings_pending_table" />
32
+ <!--
33
+ <ul class="subsubsub">
34
+ <li>
35
+ <a href='edit.php?post_type=post' class="current">All <span class="count">(1)</span></a> |
36
+ </li>
37
+ </ul>
38
+ <p class="search-box">
39
+ <label class="screen-reader-text" for="post-search-input"><?php _e('Search', 'dbem'); ?>:</label>
40
+ <input type="text" id="post-search-input" name="em_search" value="<?php echo (!empty($_GET['em_search'])) ? $_GET['em_search']:''; ?>" />
41
+ <input type="submit" value="<?php _e('Search', 'dbem'); ?>" class="button" />
42
+ </p>
43
+ -->
44
+ <?php if ( $bookings_count >= $limit ) : ?>
45
+ <div class='tablenav'>
46
+ <!--
47
+ <div class="alignleft actions">
48
+ <select name="action">
49
+ <option value="-1" selected="selected">
50
+ <?php _e('Bulk Actions', 'dbem'); ?>
51
+ </option>
52
+ <option value="approve">
53
+ <?php _e('Approve', 'dbem'); ?>
54
+ </option>
55
+ <option value="decline">
56
+ <?php _e('Decline', 'dbem'); ?>
57
+ </option>
58
+ </select>
59
+ <input type="submit" id="post-query-submit" value="Filter" class="button-secondary" />
60
+ </div>
61
+ -->
62
+ <!--
63
+ <div class="view-switch">
64
+ <a href="/wp-admin/edit.php?mode=list"><img class="current" id="view-switch-list" src="http://wordpress.lan/wp-includes/images/blank.gif" width="20" height="20" title="List View" alt="List View" name="view-switch-list" /></a> <a href="/wp-admin/edit.php?mode=excerpt"><img id="view-switch-excerpt" src="http://wordpress.lan/wp-includes/images/blank.gif" width="20" height="20" title="Excerpt View" alt="Excerpt View" name="view-switch-excerpt" /></a>
65
+ </div>
66
+ -->
67
+ <?php
68
+ if ( $bookings_count >= $limit ) {
69
+ $bookings_nav = em_admin_paginate($bookings_count, $limit, $page, array('em_ajax'=>0, 'em_obj'=>'em_bookings_confirmed_table'));
70
+ echo $bookings_nav;
71
+ }
72
+ ?>
73
+ <div class="clear"></div>
74
+ </div>
75
+ <?php endif; ?>
76
+ <div class="clear"></div>
77
+ <?php if( $bookings_count > 0 ): ?>
78
+ <div class='table-wrap'>
79
+ <table id='dbem-bookings-table' class='widefat post '>
80
+ <thead>
81
+ <tr>
82
+ <th class='manage-column column-cb check-column' scope='col'>
83
+ <input class='select-all' type="checkbox" value='1' />
84
+ </th>
85
+ <th class='manage-column' scope='col'><?php _e('Booker', 'dbem'); ?></th>
86
+ <th class='manage-column' scope='col'><?php _e('E-mail', 'dbem'); ?></th>
87
+ <th class='manage-column' scope='col'><?php _e('Phone number', 'dbem'); ?></th>
88
+ <th class='manage-column' scope='col'><?php _e('Spaces', 'dbem'); ?></th>
89
+ <th class='manage-column' scope='col'>&nbsp;</th>
90
+ </tr>
91
+ </thead>
92
+ <tbody>
93
+ <?php
94
+ $rowno = 0;
95
+ $event_count = 0;
96
+ foreach ($EM_Bookings->bookings as $EM_Booking) {
97
+ if( ($rowno < $limit || empty($limit)) && ($event_count >= $offset || $offset === 0) ) {
98
+ $rowno++;
99
+ ?>
100
+ <tr>
101
+ <th scope="row" class="check-column" style="padding:7px 0px 7px;"><input type='checkbox' value='<?php echo $EM_Booking->booking_id ?>' name='bookings[]'/></th>
102
+ <td><a href="<?php echo EM_ADMIN_URL; ?>&amp;page=events-manager-bookings&amp;person_id=<?php echo $EM_Booking->person_id; ?>"><?php echo $EM_Booking->person->get_name() ?></a></td>
103
+ <td><?php echo $EM_Booking->person->user_email ?></td>
104
+ <td><?php echo $EM_Booking->person->phone ?></td>
105
+ <td><?php echo $EM_Booking->get_spaces() ?></td>
106
+ <td>
107
+ <?php
108
+ $unapprove_url = em_add_get_params($_SERVER['REQUEST_URI'], array('action'=>'bookings_unapprove', 'booking_id'=>$EM_Booking->booking_id));
109
+ $reject_url = em_add_get_params($_SERVER['REQUEST_URI'], array('action'=>'bookings_reject', 'booking_id'=>$EM_Booking->booking_id));
110
+ $delete_url = em_add_get_params($_SERVER['REQUEST_URI'], array('action'=>'bookings_delete', 'booking_id'=>$EM_Booking->booking_id));
111
+ $edit_url = em_add_get_params($_SERVER['REQUEST_URI'], array('booking_id'=>$EM_Booking->booking_id, 'em_ajax'=>null, 'em_obj'=>null));
112
+ ?>
113
+ <?php if( current_user_can('manage_bookings') && get_option('dbem_bookings_approval') ): ?>
114
+ <a class="em-bookings-unapprove" href="<?php echo $unapprove_url ?>"><?php _e('Unapprove','dbem'); ?></a> |
115
+ <?php else: ?>
116
+ <a class="em-bookings-reject" href="<?php echo $reject_url ?>"><?php _e('Reject','dbem'); ?></a> |
117
+ <?php endif; ?>
118
+ <span class="trash"><a class="em-bookings-delete" href="<?php echo $delete_url ?>"><?php _e('Delete','dbem'); ?></a></span> |
119
+ <a class="em-bookings-edit" href="<?php echo $edit_url; ?>"><?php _e('Edit/View','dbem'); ?></a>
120
+ </td>
121
+ </tr>
122
+ <?php
123
+ }
124
+ $event_count++;
125
+ }
126
+ ?>
127
+ </tbody>
128
+ </table>
129
+ </div>
130
+ <?php else: ?>
131
+ <?php _e('No confirmed bookings.', 'dbem'); ?>
132
+ <?php endif; ?>
133
+ </form>
134
+ <?php if( !empty($bookings_nav) && $EM_Bookings >= $limit ) : ?>
135
+ <div class='tablenav'>
136
+ <?php echo $bookings_nav; ?>
137
+ <div class="clear"></div>
138
+ </div>
139
+ <?php endif; ?>
140
+ </div>
141
+ <?php
142
+
143
+ }
144
  ?>
admin/bookings/em-events.php CHANGED
@@ -1,179 +1,172 @@
1
- <?php
2
-
3
- /**
4
- * Determines whether to show event page or events page, and saves any updates to the event or events
5
- * @return null
6
- */
7
- function em_bookings_events_table() {
8
- //TODO Simplify panel for events, use form flags to detect certain actions (e.g. submitted, etc)
9
- global $wpdb;
10
- global $EM_Event;
11
-
12
- $scope_names = array (
13
- 'past' => __ ( 'Past events', 'dbem' ),
14
- 'all' => __ ( 'All events', 'dbem' ),
15
- 'future' => __ ( 'Future events', 'dbem' )
16
- );
17
-
18
- $action_scope = ( !empty($_REQUEST['em_obj']) && $_REQUEST['em_obj'] == 'em_bookings_events_table' );
19
- $action = ( $action_scope && !empty($_GET ['action']) ) ? $_GET ['action']:'';
20
- $order = ( $action_scope && !empty($_GET ['order']) ) ? $_GET ['order']:'ASC';
21
- $limit = ( $action_scope && !empty($_GET['limit']) ) ? $_GET['limit'] : 20;//Default limit
22
- $page = ( $action_scope && !empty($_GET['pno']) ) ? $_GET['pno']:1;
23
- $offset = ( $action_scope && $page > 1 ) ? ($page-1)*$limit : 0;
24
- $scope = ( $action_scope && !empty($_GET ['scope']) && array_key_exists($_GET ['scope'], $scope_names) ) ? $_GET ['scope']:'future';
25
-
26
- // No action, only showing the events list
27
- switch ($scope) {
28
- case "past" :
29
- $title = __ ( 'Past Events', 'dbem' );
30
- break;
31
- case "all" :
32
- $title = __ ( 'All Events', 'dbem' );
33
- break;
34
- default :
35
- $title = __ ( 'Future Events', 'dbem' );
36
- $scope = "future";
37
- }
38
- $events = EM_Events::get( array('scope'=>$scope, 'limit'=>0, 'order'=>$order, 'rsvp'=>true ) );
39
- $events_count = count ( $events );
40
-
41
- $use_events_end = get_option ( 'dbem_use_event_end' );
42
- ?>
43
- <div class="wrap em_bookings_events_table em_obj">
44
- <form id="posts-filter" action="<?php echo $_SERVER['REQUEST_URI'] ?>" method="get">
45
- <input type="hidden" name="em_obj" value="em_bookings_events_table" />
46
- <?php if(!empty($_GET['page'])): ?>
47
- <input type='hidden' name='page' value='events-manager-bookings' />
48
- <?php endif; ?>
49
- <ul class="subsubsub">
50
- <li><a href='#' class="current"><?php _e ( 'Total', 'dbem' ); ?> <span class="count">(<?php echo (count ( $events )); ?>)</span></a></li>
51
- </ul>
52
- <div class="tablenav">
53
- <div class="alignleft actions">
54
- <!--
55
- <select name="action">
56
- <option value="-1" selected="selected"><?php _e ( 'Bulk Actions' ); ?></option>
57
- <option value="deleteEvents"><?php _e ( 'Delete selected','dbem' ); ?></option>
58
- </select>
59
- <input type="submit" value="<?php _e ( 'Apply' ); ?>" name="doaction2" id="doaction2" class="button-secondary action" />
60
- -->
61
- <select name="scope">
62
- <?php
63
- foreach ( $scope_names as $key => $value ) {
64
- $selected = "";
65
- if ($key == $scope)
66
- $selected = "selected='selected'";
67
- echo "<option value='$key' $selected>$value</option> ";
68
- }
69
- ?>
70
- </select>
71
- <input id="post-query-submit" class="button-secondary" type="submit" value="<?php _e ( 'Filter' )?>" />
72
- </div>
73
- <!--
74
- <div class="view-switch">
75
- <a href="/wp-admin/edit.php?mode=list"><img class="current" id="view-switch-list" src="http://wordpress.lan/wp-includes/images/blank.gif" width="20" height="20" title="List View" alt="List View" name="view-switch-list" /></a> <a href="/wp-admin/edit.php?mode=excerpt"><img id="view-switch-excerpt" src="http://wordpress.lan/wp-includes/images/blank.gif" width="20" height="20" title="Excerpt View" alt="Excerpt View" name="view-switch-excerpt" /></a>
76
- </div>
77
- -->
78
- <?php
79
- if ( $events_count >= $limit ) {
80
- $page_link_template = em_add_get_params($_SERVER['REQUEST_URI'], array('pno'=>'%PAGE%', 'em_ajax'=>0, 'em_obj'=>'em_bookings_events_table'));
81
- $events_nav = em_admin_paginate( $page_link_template, $events_count, $limit, $page, 5);
82
- echo $events_nav;
83
- }
84
- ?>
85
- <br class="clear" />
86
- </div>
87
-
88
- <?php
89
- if (empty ( $events )) {
90
- // TODO localize
91
- _e ( 'no events','dbem' );
92
- } else {
93
- ?>
94
- <div class='table-wrap'>
95
- <table class="widefat">
96
- <thead>
97
- <tr>
98
- <th class='manage-column column-cb check-column' scope='col'>
99
- <input class='select-all' type="checkbox" value='1' />
100
- </th>
101
- <th><?php _e ( 'Event', 'dbem' ); ?></th>
102
- <th><?php _e ( 'Date and time', 'dbem' ); ?></th>
103
- </tr>
104
- </thead>
105
- <tbody>
106
- <?php
107
- $rowno = 0;
108
- $event_count = 0;
109
- foreach ( $events as $event ) {
110
- /* @var $event EM_Event */
111
- if( ($rowno < $limit || empty($limit)) && ($event_count >= $offset || $offset === 0) ) {
112
- $rowno++;
113
- $class = ($rowno % 2) ? ' class="alternate"' : '';
114
- // FIXME set to american
115
- $localised_start_date = date_i18n('D d M Y', $event->start);
116
- $localised_end_date = date_i18n('D d M Y', $event->end);
117
- $style = "";
118
- $today = date ( "Y-m-d" );
119
-
120
- if ($event->start_date < $today && $event->end_date < $today){
121
- $style = "style ='background-color: #FADDB7;'";
122
- }
123
- ?>
124
- <tr <?php echo "$class $style"; ?>>
125
-
126
- <td>
127
- <input type='checkbox' class='row-selector' value='<?php echo $event->id; ?>' name='events[]' />
128
- </td>
129
- <td>
130
- <strong>
131
- <a class="row-title" href="<?php bloginfo ( 'wpurl' )?>/wp-admin/admin.php?page=events-manager-bookings&amp;event_id=<?php echo $event->id ?>"><?php echo ($event->name); ?></a>
132
- </strong>
133
- &ndash;
134
- <?php _e("Booked Seats",'dbem') ?>: <?php echo $event->get_bookings()->get_booked_seats()."/".$event->seats ?>
135
- <?php if( get_option('dbem_bookings_approval') == 1 ) : ?>
136
- | <?php _e("Pending",'dbem') ?>: <?php echo $event->get_bookings()->get_pending_seats(); ?>
137
- <?php endif; ?>
138
- </td>
139
-
140
- <td>
141
- <?php echo $localised_start_date; ?>
142
- <?php echo ($localised_end_date != $localised_start_date) ? " - $localised_end_date":'' ?>
143
- &ndash;
144
- <?php
145
- //TODO Should 00:00 - 00:00 be treated as an all day event?
146
- echo substr ( $event->start_time, 0, 5 ) . " - " . substr ( $event->end_time, 0, 5 );
147
- ?>
148
- </td>
149
- </tr>
150
- <?php
151
- }
152
- $event_count++;
153
- }
154
- ?>
155
- </tbody>
156
- </table>
157
- </div>
158
- <?php
159
- } // end of table
160
- ?>
161
- <div class='tablenav'>
162
- <div class="alignleft actions">
163
- <br class='clear' />
164
- </div>
165
- <?php if( !empty($events_nav) ) : ?>
166
- <div class="tablenav-pages">
167
- <?php
168
- echo $events_nav;
169
- ?>
170
- </div>
171
- <?php endif; ?>
172
- <br class='clear' />
173
- </div>
174
- </form>
175
- </div>
176
- <?php
177
- }
178
-
179
  ?>
1
+ <?php
2
+
3
+ /**
4
+ * Determines whether to show event page or events page, and saves any updates to the event or events
5
+ * @return null
6
+ */
7
+ function em_bookings_events_table() {
8
+ //TODO Simplify panel for events, use form flags to detect certain actions (e.g. submitted, etc)
9
+ global $wpdb;
10
+ global $EM_Event;
11
+
12
+ $scope_names = array (
13
+ 'past' => __ ( 'Past events', 'dbem' ),
14
+ 'all' => __ ( 'All events', 'dbem' ),
15
+ 'future' => __ ( 'Future events', 'dbem' )
16
+ );
17
+
18
+ $action_scope = ( !empty($_REQUEST['em_obj']) && $_REQUEST['em_obj'] == 'em_bookings_events_table' );
19
+ $action = ( $action_scope && !empty($_GET ['action']) ) ? $_GET ['action']:'';
20
+ $order = ( $action_scope && !empty($_GET ['order']) ) ? $_GET ['order']:'ASC';
21
+ $limit = ( $action_scope && !empty($_GET['limit']) ) ? $_GET['limit'] : 20;//Default limit
22
+ $page = ( $action_scope && !empty($_GET['pno']) ) ? $_GET['pno']:1;
23
+ $offset = ( $action_scope && $page > 1 ) ? ($page-1)*$limit : 0;
24
+ $scope = ( $action_scope && !empty($_GET ['scope']) && array_key_exists($_GET ['scope'], $scope_names) ) ? $_GET ['scope']:'future';
25
+
26
+ // No action, only showing the events list
27
+ switch ($scope) {
28
+ case "past" :
29
+ $title = __ ( 'Past Events', 'dbem' );
30
+ break;
31
+ case "all" :
32
+ $title = __ ( 'All Events', 'dbem' );
33
+ break;
34
+ default :
35
+ $title = __ ( 'Future Events', 'dbem' );
36
+ $scope = "future";
37
+ }
38
+ $owner = !current_user_can('manage_others_bookings') ? get_current_user_id() : false;
39
+ $events = EM_Events::get( array('scope'=>$scope, 'limit'=>$limit, 'offset' => $offset, 'order'=>$order, 'bookings'=>true, 'owner' => $owner ) );
40
+ $events_count = EM_Events::count( array('scope'=>$scope, 'limit'=>0, 'order'=>$order, 'bookings'=>true, 'owner' => $owner ) );
41
+
42
+ $use_events_end = get_option ( 'dbem_use_event_end' );
43
+ ?>
44
+ <div class="wrap em_bookings_events_table em_obj">
45
+ <form id="posts-filter" action="" method="get">
46
+ <input type="hidden" name="em_obj" value="em_bookings_events_table" />
47
+ <?php if(!empty($_GET['page'])): ?>
48
+ <input type='hidden' name='page' value='events-manager-bookings' />
49
+ <?php endif; ?>
50
+ <div class="tablenav">
51
+ <div class="alignleft actions">
52
+ <!--
53
+ <select name="action">
54
+ <option value="-1" selected="selected"><?php _e ( 'Bulk Actions' ); ?></option>
55
+ <option value="deleteEvents"><?php _e ( 'Delete selected','dbem' ); ?></option>
56
+ </select>
57
+ <input type="submit" value="<?php _e ( 'Apply' ); ?>" name="doaction2" id="doaction2" class="button-secondary action" />
58
+ -->
59
+ <select name="scope">
60
+ <?php
61
+ foreach ( $scope_names as $key => $value ) {
62
+ $selected = "";
63
+ if ($key == $scope)
64
+ $selected = "selected='selected'";
65
+ echo "<option value='$key' $selected>$value</option> ";
66
+ }
67
+ ?>
68
+ </select>
69
+ <input id="post-query-submit" class="button-secondary" type="submit" value="<?php _e ( 'Filter' )?>" />
70
+ </div>
71
+ <!--
72
+ <div class="view-switch">
73
+ <a href="/wp-admin/edit.php?mode=list"><img class="current" id="view-switch-list" src="http://wordpress.lan/wp-includes/images/blank.gif" width="20" height="20" title="List View" alt="List View" name="view-switch-list" /></a> <a href="/wp-admin/edit.php?mode=excerpt"><img id="view-switch-excerpt" src="http://wordpress.lan/wp-includes/images/blank.gif" width="20" height="20" title="Excerpt View" alt="Excerpt View" name="view-switch-excerpt" /></a>
74
+ </div>
75
+ -->
76
+ <?php
77
+ if ( $events_count >= $limit ) {
78
+ $events_nav = em_admin_paginate( $events_count, $limit, $page, array('em_ajax'=>0, 'em_obj'=>'em_bookings_events_table'));
79
+ echo $events_nav;
80
+ }
81
+ ?>
82
+ <br class="clear" />
83
+ </div>
84
+
85
+ <?php
86
+ if (empty ( $events )) {
87
+ // TODO localize
88
+ _e ( 'no events','dbem' );
89
+ } else {
90
+ ?>
91
+ <div class='table-wrap'>
92
+ <table class="widefat">
93
+ <thead>
94
+ <tr>
95
+ <th class='manage-column column-cb check-column' scope='col'>
96
+ <input class='select-all' type="checkbox" value='1' />
97
+ </th>
98
+ <th><?php _e ( 'Event', 'dbem' ); ?></th>
99
+ <th><?php _e ( 'Date and time', 'dbem' ); ?></th>
100
+ </tr>
101
+ </thead>
102
+ <tbody>
103
+ <?php
104
+ $rowno = 0;
105
+ foreach ( $events as $event ) {
106
+ /* @var $event EM_Event */
107
+ $rowno++;
108
+ $class = ($rowno % 2) ? ' class="alternate"' : '';
109
+ // FIXME set to american
110
+ $localised_start_date = date_i18n(get_option('date_format'), $event->start);
111
+ $localised_end_date = date_i18n(get_option('date_format'), $event->end);
112
+ $style = "";
113
+ $today = date ( "Y-m-d" );
114
+
115
+ if ($event->start_date < $today && $event->end_date < $today){
116
+ $style = "style ='background-color: #FADDB7;'";
117
+ }
118
+ ?>
119
+ <tr <?php echo "$class $style"; ?>>
120
+
121
+ <td>
122
+ <input type='checkbox' class='row-selector' value='<?php echo $event->event_id; ?>' name='events[]' />
123
+ </td>
124
+ <td>
125
+ <strong>
126
+ <?php echo $event->output('#_BOOKINGSLINK'); ?>
127
+ </strong>
128
+ &ndash;
129
+ <?php _e("Booked Spaces",'dbem') ?>: <?php echo $event->get_bookings()->get_booked_spaces()."/".$event->get_spaces() ?>
130
+ <?php if( get_option('dbem_bookings_approval') == 1 ) : ?>
131
+ | <?php _e("Pending",'dbem') ?>: <?php echo $event->get_bookings()->get_pending_spaces(); ?>
132
+ <?php endif; ?>
133
+ </td>
134
+
135
+ <td>
136
+ <?php echo $localised_start_date; ?>
137
+ <?php echo ($localised_end_date != $localised_start_date) ? " - $localised_end_date":'' ?>
138
+ &ndash;
139
+ <?php
140
+ //TODO Should 00:00 - 00:00 be treated as an all day event?
141
+ echo substr ( $event->start_time, 0, 5 ) . " - " . substr ( $event->end_time, 0, 5 );
142
+ ?>
143
+ </td>
144
+ </tr>
145
+ <?php
146
+ }
147
+ ?>
148
+ </tbody>
149
+ </table>
150
+ </div>
151
+ <?php
152
+ } // end of table
153
+ ?>
154
+ <div class='tablenav'>
155
+ <div class="alignleft actions">
156
+ <br class='clear' />
157
+ </div>
158
+ <?php if (!empty($events_nav) && $events_count >= $limit ) : ?>
159
+ <div class="tablenav-pages">
160
+ <?php
161
+ echo $events_nav;
162
+ ?>
163
+ </div>
164
+ <?php endif; ?>
165
+ <br class='clear' />
166
+ </div>
167
+ </form>
168
+ </div>
169
+ <?php
170
+ }
171
+
 
 
 
 
 
 
 
172
  ?>
admin/bookings/em-pending.php CHANGED
@@ -1,155 +1,159 @@
1
- <?php
2
-
3
- /**
4
- * Generates a "widget" table of pending bookings with some quick admin operation options.
5
- * If event id supplied then only pending bookings for that event will show.
6
- *
7
- * @param int $event_id
8
- */
9
- function em_bookings_pending_table($event_id = false){
10
- global $EM_Event, $wpdb, $current_user;
11
-
12
- if( get_option('dbem_bookings_approval') == 0 ){
13
- return false;
14
- }
15
-
16
- $action_scope = ( !empty($_REQUEST['em_obj']) && $_REQUEST['em_obj'] == 'em_bookings_pending_table' );
17
- $action = ( $action_scope && !empty($_GET ['action']) ) ? $_GET ['action']:'';
18
- $order = ( $action_scope && !empty($_GET ['order']) ) ? $_GET ['order']:'ASC';
19
- $limit = ( $action_scope && !empty($_GET['limit']) ) ? $_GET['limit'] : 20;//Default limit
20
- $page = ( $action_scope && !empty($_GET['pno']) ) ? $_GET['pno']:1;
21
- $offset = ( $action_scope && $page > 1 ) ? ($page-1)*$limit : 0;
22
-
23
- if( is_object($EM_Event) ){
24
- $bookings = $EM_Event->get_bookings()->get_pending();
25
- }else{
26
- //To optimize performance, we can do one query here for all pending bookings to show.
27
- $bookings = EM_Bookings::get(array('status'=>0));
28
- $events = array();
29
- //Now let's create events and bookings for this:
30
- foreach($bookings as $EM_Booking){
31
- //create event
32
- if( !array_key_exists($EM_Booking->event_id,$events) ){
33
- $events[$EM_Booking->event_id] = new EM_Event($EM_Booking->event_id);
34
- }
35
- }
36
- }
37
- $bookings_count = (is_array($bookings)) ? count($bookings):0;
38
- ?>
39
- <div class='wrap em_bookings_pending_table em_obj'>
40
- <form id='bookings-filter' method='get' action='<?php bloginfo('wpurl') ?>/wp-admin/edit.php'>
41
- <input type="hidden" name="em_obj" value="em_bookings_pending_table" />
42
- <!--
43
- <ul class="subsubsub">
44
- <li>
45
- <a href='edit.php?post_type=post' class="current">All <span class="count">(1)</span></a> |
46
- </li>
47
- </ul>
48
- <p class="search-box">
49
- <label class="screen-reader-text" for="post-search-input"><?php _e('Search'); ?>:</label>
50
- <input type="text" id="post-search-input" name="em_search" value="<?php echo (!empty($_GET['em_search'])) ? $_GET['em_search']:''; ?>" />
51
- <input type="submit" value="<?php _e('Search'); ?>" class="button" />
52
- </p>
53
- -->
54
- <?php if ( $bookings_count >= $limit ) : ?>
55
- <div class='tablenav'>
56
- <!--
57
- <div class="alignleft actions">
58
- <select name="action">
59
- <option value="-1" selected="selected">
60
- <?php _e('Bulk Actions'); ?>
61
- </option>
62
- <option value="approve">
63
- <?php _e('Approve', 'dbem'); ?>
64
- </option>
65
- <option value="decline">
66
- <?php _e('Decline', 'dbem'); ?>
67
- </option>
68
- </select>
69
- <input type="submit" id="post-query-submit" value="Filter" class="button-secondary" />
70
- </div>
71
- -->
72
- <!--
73
- <div class="view-switch">
74
- <a href="/wp-admin/edit.php?mode=list"><img class="current" id="view-switch-list" src="http://wordpress.lan/wp-includes/images/blank.gif" width="20" height="20" title="List View" alt="List View" name="view-switch-list" /></a> <a href="/wp-admin/edit.php?mode=excerpt"><img id="view-switch-excerpt" src="http://wordpress.lan/wp-includes/images/blank.gif" width="20" height="20" title="Excerpt View" alt="Excerpt View" name="view-switch-excerpt" /></a>
75
- </div>
76
- -->
77
- <?php
78
- if ( $bookings_count >= $limit ) {
79
- $page_link_template = em_add_get_params($_SERVER['REQUEST_URI'], array('pno'=>'%PAGE%', 'em_ajax'=>0, 'em_obj'=>'em_bookings_pending_table'));
80
- $bookings_nav = em_admin_paginate( $page_link_template, $bookings_count, $limit, $page, 5);
81
- echo $bookings_nav;
82
- }
83
- ?>
84
- <div class="clear"></div>
85
- </div>
86
- <?php endif; ?>
87
- <div class="clear"></div>
88
- <?php if( $bookings_count > 0 ): ?>
89
- <div class='table-wrap'>
90
- <table id='dbem-bookings-table' class='widefat post fixed'>
91
- <thead>
92
- <tr>
93
- <th class='manage-column column-cb check-column' scope='col'>
94
- <input class='select-all' type="checkbox" value='1' />
95
- </th>
96
- <th class='manage-column' scope='col'>Booker</th>
97
- <?php if( !is_object($EM_Event) ): ?>
98
- <th class='manage-column' scope="col">Event</th>
99
- <?php endif; ?>
100
- <th class='manage-column' scope='col'>E-mail</th>
101
- <th class='manage-column' scope='col'>Phone number</th>
102
- <th class='manage-column' scope='col'>Spaces</th>
103
- <th class='manage-column' scope='col'>&nbsp;</th>
104
- </tr>
105
- </thead>
106
- <tbody>
107
- <?php
108
- $rowno = 0;
109
- $event_count = 0;
110
- foreach ($bookings as $EM_Booking) {
111
- if( ($rowno < $limit || empty($limit)) && ($event_count >= $offset || $offset === 0) ) {
112
- $rowno++;
113
- ?>
114
- <tr>
115
- <th scope="row" class="check-column" style="padding:7px 0px 7px;"><input type='checkbox' value='<?php echo $EM_Booking->id ?>' name='bookings[]'/></th>
116
- <td><a href="<?php bloginfo ( 'wpurl' )?>/wp-admin/admin.php?page=events-manager-bookings&amp;person_id=<?php echo $EM_Booking->person->id; ?>"><?php echo $EM_Booking->person->name ?></a></td>
117
- <?php if( !is_object($EM_Event) ): ?>
118
- <td><a href="<?php bloginfo ( 'wpurl' )?>/wp-admin/admin.php?page=events-manager-bookings&amp;event_id=<?php echo $EM_Booking->event_id; ?>"><?php echo $events[$EM_Booking->event_id]->name ?></a></td>
119
- <?php endif; ?>
120
- <td><?php echo $EM_Booking->person->email ?></td>
121
- <td><?php echo $EM_Booking->person->phone ?></td>
122
- <td><?php echo $EM_Booking->seats ?></td>
123
- <td>
124
- <?php
125
- $approve_url = em_add_get_params($_SERVER['REQUEST_URI'], array('action'=>'bookings_approve', 'booking_id'=>$EM_Booking->id));
126
- $reject_url = em_add_get_params($_SERVER['REQUEST_URI'], array('action'=>'bookings_reject', 'booking_id'=>$EM_Booking->id));
127
- ?>
128
- <a class="em-bookings-approve" href="<?php echo $approve_url ?>"><?php _e('Approve','dbem'); ?></a> |
129
- <a class="em-bookings-reject" href="<?php echo $reject_url ?>"><?php _e('Reject','dbem'); ?></a> |
130
- <a class="em-bookings-edit" href="<?php bloginfo ( 'wpurl' )?>/wp-admin/admin.php?page=events-manager-bookings&amp;booking_id=<?php echo $EM_Booking->id; ?>"><?php _e('Edit'); ?></a>
131
- </td>
132
- </tr>
133
- <?php
134
- }
135
- $event_count++;
136
- }
137
- ?>
138
- </tbody>
139
- </table>
140
- </div>
141
- <?php else: ?>
142
- <?php _e('No pending bookings.', 'dbem'); ?>
143
- <?php endif; ?>
144
- </form>
145
- <?php if( !empty($bookings_nav) ) : ?>
146
- <div class='tablenav'>
147
- <?php echo $bookings_nav; ?>
148
- <div class="clear"></div>
149
- </div>
150
- <?php endif; ?>
151
- </div>
152
- <?php
153
-
154
- }
 
 
 
 
155
  ?>
1
+ <?php
2
+
3
+ /**
4
+ * Generates a "widget" table of pending bookings with some quick admin operation options.
5
+ * If event id supplied then only pending bookings for that event will show.
6
+ *
7
+ * @param int $event_id
8
+ */
9
+ function em_bookings_pending_table($event_id = false){
10
+ global $EM_Event, $EM_Ticket, $wpdb, $current_user;
11
+
12
+ if( get_option('dbem_bookings_approval') == 0 ){
13
+ return false;
14
+ }
15
+
16
+ $action_scope = ( !empty($_REQUEST['em_obj']) && $_REQUEST['em_obj'] == 'em_bookings_pending_table' );
17
+ $action = ( $action_scope && !empty($_GET ['action']) ) ? $_GET ['action']:'';
18
+ $order = ( $action_scope && !empty($_GET ['order']) ) ? $_GET ['order']:'ASC';
19
+ $limit = ( $action_scope && !empty($_GET['limit']) ) ? $_GET['limit'] : 20;//Default limit
20
+ $page = ( $action_scope && !empty($_GET['pno']) ) ? $_GET['pno']:1;
21
+ $offset = ( $action_scope && $page > 1 ) ? ($page-1)*$limit : 0;
22
+
23
+ if( is_object($EM_Ticket) ){
24
+ $EM_Bookings = $EM_Ticket->get_bookings()->get_pending_bookings();
25
+ }else{
26
+ if( is_object($EM_Event) ){
27
+ $EM_Bookings = $EM_Event->get_bookings()->get_pending_bookings();
28
+ }else{
29
+ //To optimize performance, we can do one query here for all pending bookings to show.
30
+ $EM_Bookings = EM_Bookings::get(array('status'=>0));
31
+ $events = array();
32
+ //Now let's create events and bookings for this:
33
+ foreach($EM_Bookings->bookings as $EM_Booking){
34
+ //create event
35
+ if( !array_key_exists($EM_Booking->event_id,$events) ){
36
+ $events[$EM_Booking->event_id] = new EM_Event($EM_Booking->event_id);
37
+ }
38
+ }
39
+ }
40
+ }
41
+ $bookings_count = (is_array($EM_Bookings->bookings)) ? count($EM_Bookings->bookings):0;
42
+ ?>
43
+ <div class='wrap em_bookings_pending_table em_obj'>
44
+ <form id='bookings-filter' method='get' action='<?php bloginfo('wpurl') ?>/wp-admin/edit.php'>
45
+ <input type="hidden" name="em_obj" value="em_bookings_pending_table" />
46
+ <!--
47
+ <ul class="subsubsub">
48
+ <li>
49
+ <a href='edit.php?post_type=post' class="current">All <span class="count">(1)</span></a> |
50
+ </li>
51
+ </ul>
52
+ <p class="search-box">
53
+ <label class="screen-reader-text" for="post-search-input"><?php _e('Search', 'dbem'); ?>:</label>
54
+ <input type="text" id="post-search-input" name="em_search" value="<?php echo (!empty($_GET['em_search'])) ? $_GET['em_search']:''; ?>" />
55
+ <input type="submit" value="<?php _e('Search', 'dbem'); ?>" class="button" />
56
+ </p>
57
+ -->
58
+ <?php if ( $bookings_count >= $limit ) : ?>
59
+ <div class='tablenav'>
60
+ <!--
61
+ <div class="alignleft actions">
62
+ <select name="action">
63
+ <option value="-1" selected="selected">
64
+ <?php _e('Bulk Actions', 'dbem'); ?>
65
+ </option>
66
+ <option value="approve">
67
+ <?php _e('Approve', 'dbem'); ?>
68
+ </option>
69
+ <option value="decline">
70
+ <?php _e('Decline', 'dbem'); ?>
71
+ </option>
72
+ </select>
73
+ <input type="submit" id="post-query-submit" value="Filter" class="button-secondary" />
74
+ </div>
75
+ -->
76
+ <!--
77
+ <div class="view-switch">
78
+ <a href="/wp-admin/edit.php?mode=list"><img class="current" id="view-switch-list" src="http://wordpress.lan/wp-includes/images/blank.gif" width="20" height="20" title="List View" alt="List View" name="view-switch-list" /></a> <a href="/wp-admin/edit.php?mode=excerpt"><img id="view-switch-excerpt" src="http://wordpress.lan/wp-includes/images/blank.gif" width="20" height="20" title="Excerpt View" alt="Excerpt View" name="view-switch-excerpt" /></a>
79
+ </div>
80
+ -->
81
+ <?php
82
+ if ( $bookings_count >= $limit ) {
83
+ $bookings_nav = em_admin_paginate( $bookings_count, $limit, $page, array('em_ajax'=>0, 'em_obj'=>'em_bookings_pending_table'));
84
+ echo $bookings_nav;
85
+ }
86
+ ?>
87
+ <div class="clear"></div>
88
+ </div>
89
+ <?php endif; ?>
90
+ <div class="clear"></div>
91
+ <?php if( $bookings_count > 0 ): ?>
92
+ <div class='table-wrap'>
93
+ <table id='dbem-bookings-table' class='widefat post '>
94
+ <thead>
95
+ <tr>
96
+ <th class='manage-column column-cb check-column' scope='col'>
97
+ <input class='select-all' type="checkbox" value='1' />
98
+ </th>
99
+ <th class='manage-column' scope='col'><?php _e('Booker', 'dbem'); ?></th>
100
+ <?php if( !is_object($EM_Event) && !is_object($EM_Ticket) ): ?>
101
+ <th class='manage-column' scope="col"><?php _e('Event', 'dbem'); ?></th>
102
+ <?php endif; ?>
103
+ <th class='manage-column' scope='col'><?php _e('E-mail', 'dbem'); ?></th>
104
+ <th class='manage-column' scope='col'><?php _e('Phone number', 'dbem'); ?></th>
105
+ <th class='manage-column' scope='col'><?php _e('Spaces', 'dbem'); ?></th>
106
+ <th class='manage-column' scope='col'>&nbsp;</th>
107
+ </tr>
108
+ </thead>
109
+ <tbody>
110
+ <?php
111
+ $rowno = 0;
112
+ $event_count = 0;
113
+ foreach ($EM_Bookings->bookings as $EM_Booking) {
114
+ if( ($rowno < $limit || empty($limit)) && ($event_count >= $offset || $offset === 0) ) {
115
+ $rowno++;
116
+ ?>
117
+ <tr>
118
+ <th scope="row" class="check-column" style="padding:7px 0px 7px;"><input type='checkbox' value='<?php echo $EM_Booking->booking_id ?>' name='bookings[]'/></th>
119
+ <td><a href="<?php echo EM_ADMIN_URL; ?>&amp;page=events-manager-bookings&amp;person_id=<?php echo $EM_Booking->person->ID; ?>"><?php echo $EM_Booking->person->get_name() ?></a></td>
120
+ <?php if( !is_object($EM_Event) && !is_object($EM_Ticket) ): ?>
121
+ <td><a href="<?php echo EM_ADMIN_URL; ?>&amp;page=events-manager-bookings&amp;event_id=<?php echo $EM_Booking->event_id; ?>"><?php echo $events[$EM_Booking->event_id]->name ?></a></td>
122
+ <?php endif; ?>
123
+ <td><?php echo $EM_Booking->person->user_email ?></td>
124
+ <td><?php echo $EM_Booking->person->phone ?></td>
125
+ <td><?php echo $EM_Booking->get_spaces() ?></td>
126
+ <td>
127
+ <?php
128
+ $approve_url = em_add_get_params($_SERVER['REQUEST_URI'], array('action'=>'bookings_approve', 'booking_id'=>$EM_Booking->booking_id));
129
+ $reject_url = em_add_get_params($_SERVER['REQUEST_URI'], array('action'=>'bookings_reject', 'booking_id'=>$EM_Booking->booking_id));
130
+ $delete_url = em_add_get_params($_SERVER['REQUEST_URI'], array('action'=>'bookings_delete', 'booking_id'=>$EM_Booking->booking_id));
131
+ ?>
132
+ <a class="em-bookings-approve" href="<?php echo $approve_url ?>"><?php _e('Approve','dbem'); ?></a> |
133
+ <a class="em-bookings-reject" href="<?php echo $reject_url ?>"><?php _e('Reject','dbem'); ?></a> |
134
+ <span class="trash"><a class="em-bookings-delete" href="<?php echo $delete_url ?>"><?php _e('Delete','dbem'); ?></a></span> |
135
+ <a class="em-bookings-edit" href="<?php echo EM_ADMIN_URL; ?>&amp;page=events-manager-bookings&amp;booking_id=<?php echo $EM_Booking->booking_id; ?>"><?php _e('Edit/View','dbem'); ?></a>
136
+ </td>
137
+ </tr>
138
+ <?php
139
+ }
140
+ $event_count++;
141
+ }
142
+ ?>
143
+ </tbody>
144
+ </table>
145
+ </div>
146
+ <?php else: ?>
147
+ <?php _e('No pending bookings.', 'dbem'); ?>
148
+ <?php endif; ?>
149
+ </form>
150
+ <?php if( !empty($bookings_nav) && $EM_Bookings >= $limit ) : ?>
151
+ <div class='tablenav'>
152
+ <?php echo $bookings_nav; ?>
153
+ <div class="clear"></div>
154
+ </div>
155
+ <?php endif; ?>
156
+ </div>
157
+ <?php
158
+ }
159
  ?>
admin/bookings/em-person.php CHANGED
@@ -1,150 +1,152 @@
1
- <?php
2
-
3
- /**
4
- * Generates a "widget" table of confirmed bookings for a specific event.
5
- *
6
- * @param int $event_id
7
- */
8
- function em_bookings_person_table(){
9
- global $wpdb, $current_user,$EM_Person;
10
- if(!is_object($EM_Person)){
11
- return false;
12
- }
13
- $action_scope = ( !empty($_REQUEST['em_obj']) && $_REQUEST['em_obj'] == 'em_bookings_confirmed_table' );
14
- $action = ( $action_scope && !empty($_GET ['action']) ) ? $_GET ['action']:'';
15
- $order = ( $action_scope && !empty($_GET ['order']) ) ? $_GET ['order']:'ASC';
16
- $limit = ( $action_scope && !empty($_GET['limit']) ) ? $_GET['limit'] : 20;//Default limit
17
- $page = ( $action_scope && !empty($_GET['pno']) ) ? $_GET['pno']:1;
18
- $offset = ( $action_scope && $page > 1 ) ? ($page-1)*$limit : 0;
19
-
20
- $bookings = $EM_Person->get_bookings();
21
- $bookings_count = (is_array($bookings)) ? count($bookings):0;
22
- if($bookings_count > 0){
23
- //Get events here in one query to speed things up
24
- foreach($bookings as $EM_Booking){
25
- $event_ids[] = $EM_Booking->event_id;
26
- }
27
- $events = EM_Events::get($event_ids);
28
- }
29
- ?>
30
- <div class='wrap em_bookings_pending_table em_obj'>
31
- <form id='bookings-filter' method='get' action='<?php bloginfo('wpurl') ?>/wp-admin/edit.php'>
32
- <input type="hidden" name="em_obj" value="em_bookings_pending_table" />
33
- <!--
34
- <ul class="subsubsub">
35
- <li>
36
- <a href='edit.php?post_type=post' class="current">All <span class="count">(1)</span></a> |
37
- </li>
38
- </ul>
39
- <p class="search-box">
40
- <label class="screen-reader-text" for="post-search-input"><?php _e('Search'); ?>:</label>
41
- <input type="text" id="post-search-input" name="em_search" value="<?php echo (!empty($_GET['em_search'])) ? $_GET['em_search']:''; ?>" />
42
- <input type="submit" value="<?php _e('Search'); ?>" class="button" />
43
- </p>
44
- -->
45
- <?php if ( $bookings_count >= $limit ) : ?>
46
- <div class='tablenav'>
47
- <!--
48
- <div class="alignleft actions">
49
- <select name="action">
50
- <option value="-1" selected="selected">
51
- <?php _e('Bulk Actions'); ?>
52
- </option>
53
- <option value="approve">
54
- <?php _e('Approve', 'dbem'); ?>
55
- </option>
56
- <option value="decline">
57
- <?php _e('Decline', 'dbem'); ?>
58
- </option>
59
- </select>
60
- <input type="submit" id="post-query-submit" value="Filter" class="button-secondary" />
61
- </div>
62
- -->
63
- <!--
64
- <div class="view-switch">
65
- <a href="/wp-admin/edit.php?mode=list"><img class="current" id="view-switch-list" src="http://wordpress.lan/wp-includes/images/blank.gif" width="20" height="20" title="List View" alt="List View" name="view-switch-list" /></a> <a href="/wp-admin/edit.php?mode=excerpt"><img id="view-switch-excerpt" src="http://wordpress.lan/wp-includes/images/blank.gif" width="20" height="20" title="Excerpt View" alt="Excerpt View" name="view-switch-excerpt" /></a>
66
- </div>
67
- -->
68
- <?php
69
- if ( $bookings_count >= $limit ) {
70
- $page_link_template = em_add_get_params($_SERVER['REQUEST_URI'], array('pno'=>'%PAGE%', 'em_ajax'=>0, 'em_obj'=>'em_bookings_confirmed_table'));
71
- $bookings_nav = em_admin_paginate( $page_link_template, $bookings_count, $limit, $page, 5);
72
- echo $bookings_nav;
73
- }
74
- ?>
75
- <div class="clear"></div>
76
- </div>
77
- <?php endif; ?>
78
- <div class="clear"></div>
79
- <?php if( $bookings_count > 0 ): ?>
80
- <div class='table-wrap'>
81
- <table id='dbem-bookings-table' class='widefat post fixed'>
82
- <thead>
83
- <tr>
84
- <th class='manage-column column-cb check-column' scope='col'>
85
- <input class='select-all' type="checkbox" value='1' />
86
- </th>
87
- <th class='manage-column' scope='col'>Event</th>
88
- <th class='manage-column' scope='col'>Spaces</th>
89
- <th class='manage-column' scope='col'>Status</th>
90
- <th class='manage-column' scope='col'>&nbsp;</th>
91
- </tr>
92
- </thead>
93
- <tbody>
94
- <?php
95
- $rowno = 0;
96
- $event_count = 0;
97
- foreach ($bookings as $EM_Booking) {
98
- $EM_Event = $events[$EM_Booking->event_id];
99
- if( $EM_Event->can_manage() && ($rowno < $limit || empty($limit)) && ($event_count >= $offset || $offset === 0) ) {
100
- $rowno++;
101
- ?>
102
- <tr>
103
- <th scope="row" class="check-column" style="padding:7px 0px 7px;"><input type='checkbox' value='<?php echo $EM_Booking->id ?>' name='bookings[]'/></th>
104
- <td><a class="row-title" href="<?php bloginfo ( 'wpurl' )?>/wp-admin/admin.php?page=events-manager-bookings&amp;event_id=<?php echo $EM_Event->id ?>"><?php echo ($EM_Event->name); ?></a></td>
105
- <td><?php echo $EM_Booking->seats ?></td>
106
- <td><?php echo $EM_Booking->status_array[$EM_Booking->status]; ?>
107
- </td>
108
- <td>
109
- <?php
110
- $unapprove_url = em_add_get_params($_SERVER['REQUEST_URI'], array('action'=>'bookings_unapprove', 'bookings'=>$EM_Booking->id));
111
- $approve_url = em_add_get_params($_SERVER['REQUEST_URI'], array('action'=>'bookings_approve', 'bookings'=>$EM_Booking->id));
112
- $reject_url = em_add_get_params($_SERVER['REQUEST_URI'], array('action'=>'bookings_reject', 'bookings'=>$EM_Booking->id));
113
- $delete_url = em_add_get_params($_SERVER['REQUEST_URI'], array('action'=>'bookings_delete', 'bookings'=>$EM_Booking->id));
114
- ?>
115
- <?php if( $EM_Booking->status == 0 || $EM_Booking->status == 2 ): ?>
116
- <a class="em-bookings-approve" href="<?php echo $approve_url ?>"><?php _e('Approve','dbem'); ?></a> |
117
- <?php endif; ?>
118
- <?php if( $EM_Booking->status == 2 ): ?>
119
- <a class="em-bookings-unapprove" href="<?php echo $unapprove_url ?>"><?php _e('Unapprove','dbem'); ?></a> |
120
- <?php endif; ?>
121
- <?php if( $EM_Booking->status == 0 || $EM_Booking->status == 1 ): ?>
122
- <a class="em-bookings-reject" href="<?php echo $reject_url ?>"><?php _e('Reject','dbem'); ?></a> |
123
- <?php endif; ?>
124
- <a class="em-bookings-edit" href="<?php bloginfo ( 'wpurl' )?>/wp-admin/admin.php?page=events-manager-bookings&amp;booking_id=<?php echo $EM_Booking->id; ?>"><?php _e('Edit'); ?></a> |
125
- <a class="em-bookings-delete" href="<?php echo $delete_url ?>"><?php _e('Delete','dbem'); ?></a>
126
- </td>
127
- </tr>
128
- <?php
129
- }
130
- $event_count++;
131
- }
132
- ?>
133
- </tbody>
134
- </table>
135
- </div>
136
- <?php else: ?>
137
- <?php _e('No confirmed bookings.', 'dbem'); ?>
138
- <?php endif; ?>
139
- </form>
140
- <?php if( !empty($bookings_nav) ) : ?>
141
- <div class='tablenav'>
142
- <?php echo $bookings_nav; ?>
143
- <div class="clear"></div>
144
- </div>
145
- <?php endif; ?>
146
- </div>
147
- <?php
148
-
149
- }
 
 
150
  ?>
1
+ <?php
2
+
3
+ /**
4
+ * Generates a "widget" table of confirmed bookings for a specific event.
5
+ *
6
+ * @param int $event_id
7
+ */
8
+ function em_bookings_person_table(){
9
+ global $wpdb, $current_user,$EM_Person;
10
+ if(!is_object($EM_Person)){
11
+ return false;
12
+ }
13
+ $action_scope = ( !empty($_REQUEST['em_obj']) && $_REQUEST['em_obj'] == 'em_bookings_confirmed_table' );
14
+ $action = ( $action_scope && !empty($_GET ['action']) ) ? $_GET ['action']:'';
15
+ $order = ( $action_scope && !empty($_GET ['order']) ) ? $_GET ['order']:'ASC';
16
+ $limit = ( $action_scope && !empty($_GET['limit']) ) ? $_GET['limit'] : 20;//Default limit
17
+ $page = ( $action_scope && !empty($_GET['pno']) ) ? $_GET['pno']:1;
18
+ $offset = ( $action_scope && $page > 1 ) ? ($page-1)*$limit : 0;
19
+
20
+ $bookings = $EM_Person->get_bookings();
21
+ $bookings_count = count($bookings);
22
+ if($bookings_count > 0){
23
+ //Get events here in one query to speed things up
24
+ foreach($bookings as $EM_Booking){
25
+ $event_ids[] = $EM_Booking->event_id;
26
+ }
27
+ $events = EM_Events::get($event_ids);
28
+ }
29
+ ?>
30
+ <div class='wrap em_bookings_pending_table em_obj'>
31
+ <form id='bookings-filter' method='get' action='<?php bloginfo('wpurl') ?>/wp-admin/edit.php'>
32
+ <input type="hidden" name="em_obj" value="em_bookings_pending_table" />
33
+ <!--
34
+ <ul class="subsubsub">
35
+ <li>
36
+ <a href='edit.php?post_type=post' class="current">All <span class="count">(1)</span></a> |
37
+ </li>
38
+ </ul>
39
+ <p class="search-box">
40
+ <label class="screen-reader-text" for="post-search-input"><?php _e('Search', 'dbem'); ?>:</label>
41
+ <input type="text" id="post-search-input" name="em_search" value="<?php echo (!empty($_GET['em_search'])) ? $_GET['em_search']:''; ?>" />
42
+ <input type="submit" value="<?php _e('Search', 'dbem'); ?>" class="button" />
43
+ </p>
44
+ -->
45
+ <?php if ( $bookings_count >= $limit ) : ?>
46
+ <div class='tablenav'>
47
+ <!--
48
+ <div class="alignleft actions">
49
+ <select name="action">
50
+ <option value="-1" selected="selected">
51
+ <?php _e('Bulk Actions', 'dbem'); ?>
52
+ </option>
53
+ <option value="approve">
54
+ <?php _e('Approve', 'dbem'); ?>
55
+ </option>
56
+ <option value="decline">
57
+ <?php _e('Decline', 'dbem'); ?>
58
+ </option>
59
+ </select>
60
+ <input type="submit" id="post-query-submit" value="Filter" class="button-secondary" />
61
+ </div>
62
+ -->
63
+ <!--
64
+ <div class="view-switch">
65
+ <a href="/wp-admin/edit.php?mode=list"><img class="current" id="view-switch-list" src="http://wordpress.lan/wp-includes/images/blank.gif" width="20" height="20" title="List View" alt="List View" name="view-switch-list" /></a> <a href="/wp-admin/edit.php?mode=excerpt"><img id="view-switch-excerpt" src="http://wordpress.lan/wp-includes/images/blank.gif" width="20" height="20" title="Excerpt View" alt="Excerpt View" name="view-switch-excerpt" /></a>
66
+ </div>
67
+ -->
68
+ <?php
69
+ if ( $bookings_count >= $limit ) {
70
+ $bookings_nav = em_admin_paginate( $bookings_count, $limit, $page, array('em_ajax'=>0, 'em_obj'=>'em_bookings_confirmed_table'));
71
+ echo $bookings_nav;
72
+ }
73
+ ?>
74
+ <div class="clear"></div>
75
+ </div>
76
+ <?php endif; ?>
77
+ <div class="clear"></div>
78
+ <?php if( $bookings_count > 0 ): ?>
79
+ <div class='table-wrap'>
80
+ <table id='dbem-bookings-table' class='widefat post '>
81
+ <thead>
82
+ <tr>
83
+ <th class='manage-column column-cb check-column' scope='col'>
84
+ <input class='select-all' type="checkbox" value='1' />
85
+ </th>
86
+ <th class='manage-column' scope='col'><?php _e('Event', 'dbem'); ?></th>
87
+ <th class='manage-column' scope='col'><?php _e('Spaces', 'dbem'); ?></th>
88
+ <th class='manage-column' scope='col'><?php _e('Status', 'dbem'); ?></th>
89
+ <th class='manage-column' scope='col'>&nbsp;</th>
90
+ </tr>
91
+ </thead>
92
+ <tbody>
93
+ <?php
94
+ $rowno = 0;
95
+ $event_count = 0;
96
+ foreach ($bookings as $EM_Booking) {
97
+ $EM_Event = $events[$EM_Booking->event_id];
98
+ if( $EM_Event->can_manage('edit_events','edit_others_events') && ($rowno < $limit || empty($limit)) && ($event_count >= $offset || $offset === 0) ) {
99
+ $rowno++;
100
+ ?>
101
+ <tr>
102
+ <th scope="row" class="check-column" style="padding:7px 0px 7px;"><input type='checkbox' value='<?php echo $EM_Booking->booking_id ?>' name='bookings[]'/></th>
103
+ <td><a class="row-title" href="<?php echo EM_ADMIN_URL; ?>&amp;page=events-manager-bookings&amp;event_id=<?php echo $EM_Event->event_id ?>"><?php echo ($EM_Event->event_name); ?></a></td>
104
+ <td><?php echo $EM_Booking->get_spaces() ?></td>
105
+ <td><?php echo $EM_Booking->status_array[$EM_Booking->booking_status]; ?>
106
+ </td>
107
+ <td>
108
+ <?php
109
+ $unapprove_url = em_add_get_params($_SERVER['REQUEST_URI'], array('action'=>'bookings_unapprove', 'booking_id'=>$EM_Booking->booking_id));
110
+ $approve_url = em_add_get_params($_SERVER['REQUEST_URI'], array('action'=>'bookings_approve', 'booking_id'=>$EM_Booking->booking_id));
111
+ $reject_url = em_add_get_params($_SERVER['REQUEST_URI'], array('action'=>'bookings_reject', 'booking_id'=>$EM_Booking->booking_id));
112
+ $delete_url = em_add_get_params($_SERVER['REQUEST_URI'], array('action'=>'bookings_delete', 'booking_id'=>$EM_Booking->booking_id));
113
+ ?>
114
+ <?php if( get_option('dbem_bookings_approval') && ($EM_Booking->booking_status == 0 ) ): ?>
115
+ <a class="em-bookings-approve" href="<?php echo $approve_url ?>"><?php _e('Approve','dbem'); ?></a> |
116
+ <?php endif; ?>
117
+ <?php if( get_option('dbem_bookings_approval') && $EM_Booking->booking_status == 1 ): ?>
118
+ <a class="em-bookings-unapprove" href="<?php echo $unapprove_url ?>"><?php _e('Unapprove','dbem'); ?></a> |
119
+ <?php endif; ?>
120
+ <?php if( $EM_Booking->booking_status == 2 ): ?>
121
+ <a class="em-bookings-approve" href="<?php echo $approve_url ?>"><?php _e('Restore','dbem'); ?></a> |
122
+ <?php endif; ?>
123
+ <?php if( $EM_Booking->booking_status == 0 || $EM_Booking->booking_status == 1 ): ?>
124
+ <a class="em-bookings-reject" href="<?php echo $reject_url ?>"><?php _e('Reject','dbem'); ?></a> |
125
+ <?php endif; ?>
126
+ <a class="em-bookings-edit" href="<?php echo EM_ADMIN_URL; ?>&amp;page=events-manager-bookings&amp;booking_id=<?php echo $EM_Booking->booking_id; ?>"><?php _e('Edit/View','dbem'); ?></a> |
127
+ <span class="trash"><a class="em-bookings-delete" href="<?php echo $delete_url ?>"><?php _e('Delete','dbem'); ?></a></span>
128
+ </td>
129
+ </tr>
130
+ <?php
131
+ }
132
+ $event_count++;
133
+ }
134
+ ?>
135
+ </tbody>
136
+ </table>
137
+ </div>
138
+ <?php else: ?>
139
+ <?php _e('No confirmed bookings.', 'dbem'); ?>
140
+ <?php endif; ?>
141
+ </form>
142
+ <?php if( !empty($bookings_nav) && $bookings >= $limit ) : ?>
143
+ <div class='tablenav'>
144
+ <?php echo $bookings_nav; ?>
145
+ <div class="clear"></div>
146
+ </div>
147
+ <?php endif; ?>
148
+ </div>
149
+ <?php
150
+
151
+ }
152
  ?>
admin/bookings/em-rejected.php CHANGED
@@ -1,133 +1,137 @@
1
- <?php
2
- /**
3
- * Generates a "widget" table of confirmed bookings for a specific event.
4
- *
5
- * @param int $event_id
6
- */
7
- function em_bookings_rejected_table(){
8
- global $EM_Event, $wpdb, $current_user;
9
-
10
- $action_scope = ( !empty($_REQUEST['em_obj']) && $_REQUEST['em_obj'] == 'em_bookings_confirmed_table' );
11
- $action = ( $action_scope && !empty($_GET ['action']) ) ? $_GET ['action']:'';
12
- $order = ( $action_scope && !empty($_GET ['order']) ) ? $_GET ['order']:'ASC';
13
- $limit = ( $action_scope && !empty($_GET['limit']) ) ? $_GET['limit'] : 20;//Default limit
14
- $page = ( $action_scope && !empty($_GET['pno']) ) ? $_GET['pno']:1;
15
- $offset = ( $action_scope && $page > 1 ) ? ($page-1)*$limit : 0;
16
-
17
- if( is_object($EM_Event) ){
18
- $bookings = $EM_Event->get_bookings()->get_rejected_bookings();
19
- }else{
20
- return false;
21
- }
22
- $bookings_count = (is_array($bookings)) ? count($bookings):0;
23
- ?>
24
- <div class='wrap em_bookings_pending_table em_obj'>
25
- <form id='bookings-filter' method='get' action='<?php bloginfo('wpurl') ?>/wp-admin/edit.php'>
26
- <input type="hidden" name="em_obj" value="em_bookings_pending_table" />
27
- <!--
28
- <ul class="subsubsub">
29
- <li>
30
- <a href='edit.php?post_type=post' class="current">All <span class="count">(1)</span></a> |
31
- </li>
32
- </ul>
33
- <p class="search-box">
34
- <label class="screen-reader-text" for="post-search-input"><?php _e('Search'); ?>:</label>
35
- <input type="text" id="post-search-input" name="em_search" value="<?php echo (!empty($_GET['em_search'])) ? $_GET['em_search']:''; ?>" />
36
- <input type="submit" value="<?php _e('Search'); ?>" class="button" />
37
- </p>
38
- -->
39
- <?php if ( $bookings_count >= $limit ) : ?>
40
- <div class='tablenav'>
41
- <!--
42
- <div class="alignleft actions">
43
- <select name="action">
44
- <option value="-1" selected="selected">
45
- <?php _e('Bulk Actions'); ?>
46
- </option>
47
- <option value="approve">
48
- <?php _e('Approve', 'dbem'); ?>
49
- </option>
50
- <option value="decline">
51
- <?php _e('Decline', 'dbem'); ?>
52
- </option>
53
- </select>
54
- <input type="submit" id="post-query-submit" value="Filter" class="button-secondary" />
55
- </div>
56
- -->
57
- <!--
58
- <div class="view-switch">
59
- <a href="/wp-admin/edit.php?mode=list"><img class="current" id="view-switch-list" src="http://wordpress.lan/wp-includes/images/blank.gif" width="20" height="20" title="List View" alt="List View" name="view-switch-list" /></a> <a href="/wp-admin/edit.php?mode=excerpt"><img id="view-switch-excerpt" src="http://wordpress.lan/wp-includes/images/blank.gif" width="20" height="20" title="Excerpt View" alt="Excerpt View" name="view-switch-excerpt" /></a>
60
- </div>
61
- -->
62
- <?php
63
- if ( $bookings_count >= $limit ) {
64
- $page_link_template = em_add_get_params($_SERVER['REQUEST_URI'], array('pno'=>'%PAGE%', 'em_ajax'=>0, 'em_obj'=>'em_bookings_confirmed_table'));
65
- $bookings_nav = em_admin_paginate( $page_link_template, $bookings_count, $limit, $page, 5);
66
- echo $bookings_nav;
67
- }
68
- ?>
69
- <div class="clear"></div>
70
- </div>
71
- <?php endif; ?>
72
- <div class="clear"></div>
73
- <?php if( $bookings_count > 0 ): ?>
74
- <div class='table-wrap'>
75
- <table id='dbem-bookings-table' class='widefat post fixed'>
76
- <thead>
77
- <tr>
78
- <th class='manage-column column-cb check-column' scope='col'>
79
- <input class='select-all' type="checkbox" value='1' />
80
- </th>
81
- <th class='manage-column' scope='col'>Booker</th>
82
- <th class='manage-column' scope='col'>E-mail</th>
83
- <th class='manage-column' scope='col'>Phone number</th>
84
- <th class='manage-column' scope='col'>Spaces</th>
85
- <th class='manage-column' scope='col'>&nbsp;</th>
86
- </tr>
87
- </thead>
88
- <tbody>
89
- <?php
90
- $rowno = 0;
91
- $event_count = 0;
92
- foreach ($bookings as $EM_Booking) {
93
- if( ($rowno < $limit || empty($limit)) && ($event_count >= $offset || $offset === 0) ) {
94
- $rowno++;
95
- ?>
96
- <tr>
97
- <th scope="row" class="check-column" style="padding:7px 0px 7px;"><input type='checkbox' value='<?php echo $EM_Booking->id ?>' name='bookings[]'/></th>
98
- <td><a href="<?php bloginfo ( 'wpurl' )?>/wp-admin/admin.php?page=events-manager-bookings&amp;person_id=<?php echo $EM_Booking->person->id; ?>"><?php echo $EM_Booking->person->name ?></a></td>
99
- <td><?php echo $EM_Booking->person->email ?></td>
100
- <td><?php echo $EM_Booking->person->phone ?></td>
101
- <td><?php echo $EM_Booking->seats ?></td>
102
- <td>
103
- <?php
104
- $approve_url = em_add_get_params($_SERVER['REQUEST_URI'], array('action'=>'bookings_approve', 'booking_id'=>$EM_Booking->id));
105
- $delete_url = em_add_get_params($_SERVER['REQUEST_URI'], array('action'=>'bookings_delete', 'booking_id'=>$EM_Booking->id));
106
- ?>
107
- <a class="em-bookings-approve" href="<?php echo $approve_url ?>"><?php _e('Approve','dbem'); ?></a> |
108
- <a class="em-bookings-edit" href="<?php bloginfo ( 'wpurl' )?>/wp-admin/admin.php?page=events-manager-bookings&amp;booking_id=<?php echo $EM_Booking->id; ?>"><?php _e('Edit'); ?></a> |
109
- <a class="em-bookings-delete" href="<?php echo $delete_url ?>"><?php _e('Delete','dbem'); ?></a>
110
- </td>
111
- </tr>
112
- <?php
113
- }
114
- $event_count++;
115
- }
116
- ?>
117
- </tbody>
118
- </table>
119
- </div>
120
- <?php else: ?>
121
- <?php _e('No rejected bookings.', 'dbem'); ?>
122
- <?php endif; ?>
123
- </form>
124
- <?php if( !empty($bookings_nav) ) : ?>
125
- <div class='tablenav'>
126
- <?php echo $bookings_nav; ?>
127
- <div class="clear"></div>
128
- </div>
129
- <?php endif; ?>
130
- </div>
131
- <?php
132
- }
 
 
 
 
133
  ?>
1
+ <?php
2
+ /**
3
+ * Generates a "widget" table of confirmed bookings for a specific event.
4
+ *
5
+ * @param int $event_id
6
+ */
7
+ function em_bookings_rejected_table(){
8
+ global $EM_Event, $EM_Ticket, $wpdb, $current_user;
9
+
10
+ $action_scope = ( !empty($_REQUEST['em_obj']) && $_REQUEST['em_obj'] == 'em_bookings_confirmed_table' );
11
+ $action = ( $action_scope && !empty($_GET ['action']) ) ? $_GET ['action']:'';
12
+ $order = ( $action_scope && !empty($_GET ['order']) ) ? $_GET ['order']:'ASC';
13
+ $limit = ( $action_scope && !empty($_GET['limit']) ) ? $_GET['limit'] : 20;//Default limit
14
+ $page = ( $action_scope && !empty($_GET['pno']) ) ? $_GET['pno']:1;
15
+ $offset = ( $action_scope && $page > 1 ) ? ($page-1)*$limit : 0;
16
+
17
+ if( is_object($EM_Ticket) ){
18
+ $EM_Bookings = $EM_Ticket->get_bookings()->get_rejected_bookings();
19
+ }else{
20
+ if( is_object($EM_Event) ){
21
+ $EM_Bookings = $EM_Event->get_bookings()->get_rejected_bookings();
22
+ }else{
23
+ return false;
24
+ }
25
+ }
26
+ $bookings_count = (is_array($EM_Bookings->bookings)) ? count($EM_Bookings->bookings):0;
27
+ ?>
28
+ <div class='wrap em_bookings_pending_table em_obj'>
29
+ <form id='bookings-filter' method='get' action='<?php bloginfo('wpurl') ?>/wp-admin/edit.php'>
30
+ <input type="hidden" name="em_obj" value="em_bookings_pending_table" />
31
+ <!--
32
+ <ul class="subsubsub">
33
+ <li>
34
+ <a href='edit.php?post_type=post' class="current">All <span class="count">(1)</span></a> |
35
+ </li>
36
+ </ul>
37
+ <p class="search-box">
38
+ <label class="screen-reader-text" for="post-search-input"><?php _e('Search', 'dbem'); ?>:</label>
39
+ <input type="text" id="post-search-input" name="em_search" value="<?php echo (!empty($_GET['em_search'])) ? $_GET['em_search']:''; ?>" />
40
+ <input type="submit" value="<?php _e('Search', 'dbem'); ?>" class="button" />
41
+ </p>
42
+ -->
43
+ <?php if ( $bookings_count >= $limit ) : ?>
44
+ <div class='tablenav'>
45
+ <!--
46
+ <div class="alignleft actions">
47
+ <select name="action">
48
+ <option value="-1" selected="selected">
49
+ <?php _e('Bulk Actions', 'dbem'); ?>
50
+ </option>
51
+ <option value="approve">
52
+ <?php _e('Approve', 'dbem'); ?>
53
+ </option>
54
+ <option value="decline">
55
+ <?php _e('Decline', 'dbem'); ?>
56
+ </option>
57
+ </select>
58
+ <input type="submit" id="post-query-submit" value="Filter" class="button-secondary" />
59
+ </div>
60
+ -->
61
+ <!--
62
+ <div class="view-switch">
63
+ <a href="/wp-admin/edit.php?mode=list"><img class="current" id="view-switch-list" src="http://wordpress.lan/wp-includes/images/blank.gif" width="20" height="20" title="List View" alt="List View" name="view-switch-list" /></a> <a href="/wp-admin/edit.php?mode=excerpt"><img id="view-switch-excerpt" src="http://wordpress.lan/wp-includes/images/blank.gif" width="20" height="20" title="Excerpt View" alt="Excerpt View" name="view-switch-excerpt" /></a>
64
+ </div>
65
+ -->
66
+ <?php
67
+ if ( $bookings_count >= $limit ) {
68
+ $bookings_nav = em_admin_paginate( $bookings_count, $limit, $page, array('em_ajax'=>0, 'em_obj'=>'em_bookings_confirmed_table'));
69
+ echo $bookings_nav;
70
+ }
71
+ ?>
72
+ <div class="clear"></div>
73
+ </div>
74
+ <?php endif; ?>
75
+ <div class="clear"></div>
76
+ <?php if( $bookings_count > 0 ): ?>
77
+ <div class='table-wrap'>
78
+ <table id='dbem-bookings-table' class='widefat post '>
79
+ <thead>
80
+ <tr>
81
+ <th class='manage-column column-cb check-column' scope='col'>
82
+ <input class='select-all' type="checkbox" value='1' />
83
+ </th>
84
+ <th class='manage-column' scope='col'><?php _e('Booker', 'dbem'); ?></th>
85
+ <th class='manage-column' scope='col'><?php _e('E-mail', 'dbem'); ?></th>
86
+ <th class='manage-column' scope='col'><?php _e('Phone number', 'dbem'); ?></th>
87
+ <th class='manage-column' scope='col'><?php _e('Spaces', 'dbem'); ?></th>
88
+ <th class='manage-column' scope='col'>&nbsp;</th>
89
+ </tr>
90
+ </thead>
91
+ <tbody>
92
+ <?php
93
+ $rowno = 0;
94
+ $event_count = 0;
95
+ foreach ($EM_Bookings->bookings as $EM_Booking) {
96
+ if( ($rowno < $limit || empty($limit)) && ($event_count >= $offset || $offset === 0) ) {
97
+ $rowno++;
98
+ ?>
99
+ <tr>
100
+ <th scope="row" class="check-column" style="padding:7px 0px 7px;"><input type='checkbox' value='<?php echo $EM_Booking->booking_id ?>' name='bookings[]'/></th>
101
+ <td><a href="<?php echo EM_ADMIN_URL; ?>&amp;page=events-manager-bookings&amp;person_id=<?php echo $EM_Booking->person->ID; ?>"><?php echo $EM_Booking->person->get_name() ?></a></td>
102
+ <td><?php echo $EM_Booking->person->user_email ?></td>
103
+ <td><?php echo $EM_Booking->person->phone ?></td>
104
+ <td><?php echo $EM_Booking->get_spaces() ?></td>
105
+ <td>
106
+ <?php
107
+ $approve_url = em_add_get_params($_SERVER['REQUEST_URI'], array('action'=>'bookings_approve', 'booking_id'=>$EM_Booking->booking_id));
108
+ $delete_url = em_add_get_params($_SERVER['REQUEST_URI'], array('action'=>'bookings_delete', 'booking_id'=>$EM_Booking->booking_id));
109
+ $edit_url = em_add_get_params($_SERVER['REQUEST_URI'], array('booking_id'=>$EM_Booking->booking_id, 'em_ajax'=>null, 'em_obj'=>null));
110
+ ?>
111
+ <a class="em-bookings-approve" href="<?php echo $approve_url ?>"><?php _e('Approve','dbem'); ?></a> |
112
+ <a class="em-bookings-edit" href="<?php echo $edit_url ?>"><?php _e('Edit/View','dbem'); ?></a> |
113
+ <span class="trash"><a class="em-bookings-delete" href="<?php echo $delete_url ?>"><?php _e('Delete','dbem'); ?></a></span>
114
+ </td>
115
+ </tr>
116
+ <?php
117
+ }
118
+ $event_count++;
119
+ }
120
+ ?>
121
+ </tbody>
122
+ </table>
123
+ </div>
124
+ <?php else: ?>
125
+ <?php _e('No rejected bookings.', 'dbem'); ?>
126
+ <?php endif; ?>
127
+ </form>
128
+ <?php if( !empty($bookings_nav) && $EM_Bookings >= $limit ) : ?>
129
+ <div class='tablenav'>
130
+ <?php echo $bookings_nav; ?>
131
+ <div class="clear"></div>
132
+ </div>
133
+ <?php endif; ?>
134
+ </div>
135
+ <?php
136
+ }
137
  ?>
admin/em-admin.php CHANGED
@@ -1,285 +1,242 @@
1
- <?php
2
- //Admin functions
3
-
4
- /**
5
- * Generate warnings and notices in the admin area
6
- */
7
- function em_admin_warnings() {
8
- //If we're editing the events page show hello to new user
9
- $events_page_id = get_option ( 'dbem_events_page' );
10
- $dismiss_link_joiner = ( count($_GET) > 0 ) ? '&amp;':'?';
11
-
12
- if( em_verify_admin() ){
13
- //New User Intro
14
- if (isset ( $_GET ['disable_hello_to_user'] ) && $_GET ['disable_hello_to_user'] == 'true'){
15
- // Disable Hello to new user if requested
16
- update_option ( 'dbem_hello_to_user', 0 );
17
- }elseif ( get_option ( 'dbem_hello_to_user' ) == 1 && !empty($_GET['page']) && $_GET['page'] == 'events-manager-events' ) {
18
- $current_user = wp_get_current_user ();
19
- //FIXME update welcome msg with good links
20
- $advice = sprintf ( __ ( "<p>Hey, <strong>%s</strong>, welcome to <strong>Events Manager</strong>! We hope you like it around here.</p>
21
- <p>Now it's time to insert events lists through <a href='%s' title='Widgets page'>widgets</a>, <a href='%s' title='Template tags documentation'>template tags</a> or <a href='%s' title='Shortcodes documentation'>shortcodes</a>.</p>
22
- <p>By the way, have you taken a look at the <a href='%s' title='Change settings'>Settings page</a>? That's where you customize the way events and locations are displayed.</p>
23
- <p>What? Tired of seeing this advice? I hear you, <a href='%s' title='Don't show this advice again'>click here</a> and you won't see this again!</p>", 'dbem' ), $current_user->display_name, get_bloginfo ( 'url' ) . '/wp-admin/widgets.php', 'http://wp-events-plugin.com/documentation/template-tags/', 'http://wp-events-plugin.com/documentation/shortcodes/', get_bloginfo ( 'url' ) . '/wp-admin/admin.php?page=events-manager-options', get_bloginfo ( 'url' ) . '/wp-admin/admin.php?page=events-manager&disable_hello_to_user=true' );
24
- ?>
25
- <div id="message" class="updated">
26
- <?php echo $advice; ?>
27
- </div>
28
- <?php
29
- }
30
-
31
- //If events page couldn't be created
32
- if( !empty($_GET['em_dismiss_admin_notice']) ){
33
- delete_option('dbem_admin_notice_'.$_GET['em_dismiss_admin_notice']);
34
- }else{
35
- if ( get_option('dbem_admin_notice_3.0.91') ){
36
- ?>
37
- <div class="updated">
38
- <p><?php echo sprintf ( __( '<strong>Events Manager has some new features!</strong><ul><li>Bookings can now be approved before they count towards your event\'s space allocations.</li><li>Events now have owners, and you can restrict users so they can only manage events/locations/categories they create.<br/><br/>These new permissions are enabled by default, but since you upgraded it has been disabled to maintain the previous plugin behaviour. You can re-enable it from the <a href="%s">settings page</a>. <a href="%s">Dismiss</a>', 'dbem'), get_bloginfo ( 'url' ) . '/wp-admin/admin.php?page=events-manager-options', $_SERVER['REQUEST_URI'].$dismiss_link_joiner.'em_dismiss_admin_notice=3.0.91' ); ?></p>
39
- </div>
40
- <?php
41
- }
42
- }
43
- //If events page couldn't be created
44
- if( !empty($_GET['em_dismiss_rc_notice']) ){
45
- delete_option('dbem_admin_notice_rc');
46
- }elseif( get_option('dbem_admin_notice_rc')){
47
- ?>
48
- <div class="updated">
49
- <p>
50
- <strong>Events Manager 4.0 on its way!</strong>
51
- We've just about finished with 4.0, which boasts TONS of long awaited features including advanced booking, permalinks, MultiSite and BuddPress integration, and much more!
52
- It is undergoing final testing to be released in the coming days, and the website has already had a documentation and tutorial overhaul in preparation.
53
- </p><p>
54
- To read up on the changes and get a hold of the Release Candidate
55
- <a href="http://wp-events-plugin.com/try-the-beta/?utm_source=plugin&utm_medium=html&utm_campaign=rc_notice">click here</a>.
56
- Please make sure to have a look at this page if you use EM for bookings or have made any mods to the plugin, as there are some considerations to make when upgrading.<br />
57
- <a href="http://wp-events-plugin.com/try-the-beta/?utm_source=plugin&utm_medium=html&utm_campaign=rc_notice">See what's new</a> | <a href="<?php echo $_SERVER['REQUEST_URI'].$dismiss_link_joiner.'em_dismiss_rc_notice=1' ?>">Dismiss this message.</a>
58
- </p>
59
- </div>
60
- <?php
61
- }
62
-
63
- //If events page couldn't be created
64
- if( !empty($_GET['em_dismiss_events_page']) ){
65
- update_option('dbem_dismiss_events_page',1);
66
- }else{
67
- if ( !get_page($events_page_id) && !get_option('dbem_dismiss_events_page') ){
68
- ?>
69
- <div id="em_page_error" class="updated">
70
- <p><?php echo sprintf ( __( 'Uh Oh! For some reason wordpress could not create an events page for you (or you just deleted it). Not to worry though, all you have to do is create an empty page, name it whatever you want, and select it as your events page in your <a href="%s">settings page</a>. Sorry for the extra step! If you know what you are doing, you may have done this on purpose, if so <a href="%s">ignore this message</a>', 'dbem'), get_bloginfo ( 'url' ) . '/wp-admin/admin.php?page=events-manager-options', $_SERVER['REQUEST_URI'].$dismiss_link_joiner.'em_dismiss_events_page=1' ); ?></p>
71
- </div>
72
- <?php
73
- }
74
- }
75
- }
76
- //Warn about EM page edit
77
- if ( preg_match( '/(post|page).php/', $_SERVER ['SCRIPT_NAME']) && isset ( $_GET ['action'] ) && $_GET ['action'] == 'edit' && isset ( $_GET ['post'] ) && $_GET ['post'] == "$events_page_id") {
78
- $message = sprintf ( __ ( "This page corresponds to <strong>Events Manager</strong> events page. Its content will be overriden by <strong>Events Manager</strong>. If you want to display your content, you can can assign another page to <strong>Events Manager</strong> in the the <a href='%s'>Settings</a>. ", 'dbem' ), 'admin.php?page=events-manager-options' );
79
- $notice = "<div class='error'><p>$message</p></div>";
80
- echo $notice;
81
- }
82
-
83
- }
84
- add_action ( 'admin_notices', 'em_admin_warnings' );
85
-
86
- /**
87
- * Creates a wp-admin style navigation. All this does is wrap some html around the em_paginate function result to make it style correctly in the admin area.
88
- * @param string $link
89
- * @param int $total
90
- * @param int $limit
91
- * @param int $page
92
- * @param int $pagesToShow
93
- * @return string
94
- * @uses em_paginate()
95
- */
96
- function em_admin_paginate($link, $total, $limit, $page=1, $pagesToShow=5){
97
- $return = '<div class="tablenav-pages">';
98
- $return .= sprintf( '<span class="displaying-num">' . __( 'Displaying %s&#8211;%s of %s' ) . '</span>',
99
- number_format_i18n( ( $page - 1 ) * $limit + 1 ),
100
- number_format_i18n( min( $page * $limit, $total ) ),
101
- number_format_i18n( $total )
102
- );
103
- $return .= em_paginate($link, $total, $limit, $page, $pagesToShow);
104
- $return .= '</div>';
105
- return $return;
106
- }
107
-
108
- /**
109
- * Called by admin_print_scripts-(hook|page) action, created when adding menu items in events-manager.php
110
- */
111
- function em_admin_load_scripts(){
112
- //Load the UI items, currently date picker and autocomplete plus dependencies
113
- //wp_enqueue_script('em-ui-js', WP_PLUGIN_URL.'/events-manager/includes/js/jquery-ui-1.8.5.custom.min.js', array('jquery', 'jquery-ui-core'));
114
- wp_enqueue_script('em-ui-js', WP_PLUGIN_URL.'/events-manager/includes/js/em_ui.js', array('jquery', 'jquery-ui-core'));
115
-
116
- //Add maps
117
- if( get_option('dbem_gmap_is_active') ){
118
- wp_enqueue_script('em-google-maps', 'http://maps.google.com/maps/api/js?sensor=false');
119
- }
120
- //Time Entry
121
- wp_enqueue_script('em-timeentry', WP_PLUGIN_URL.'/events-manager/includes/js/timeentry/jquery.timeentry.js', array('jquery'));
122
-
123
- //Date Picker Locale
124
- $locale_code = substr ( get_locale (), 0, 2 );
125
- $locale_file = "/events-manager/includes/js/i18n/jquery.ui.datepicker-$locale_code.js";
126
- if ( file_exists(WP_PLUGIN_DIR.$locale_file) ) {
127
- wp_enqueue_script("em-ui-datepicker-$locale_code", WP_PLUGIN_URL.$locale_file, array('em-ui-js'));
128
- }
129
- wp_enqueue_script('em-script', WP_PLUGIN_URL.'/events-manager/includes/js/em_admin.js', array('em-ui-js'));
130
-
131
- //TinyMCE Editor
132
- remove_filter('the_editor', 'qtrans_modifyRichEditor'); //qtranslate filter
133
- add_action( 'admin_print_footer_scripts', 'wp_tiny_mce', 25 );
134
- add_action( 'admin_print_footer_scripts', 'wp_tiny_mce_preload_dialogs', 30 );
135
- wp_enqueue_script('post');
136
- if ( user_can_richedit() )
137
- wp_enqueue_script('editor');
138
-
139
- add_thickbox();
140
- wp_enqueue_script('media-upload');
141
- wp_enqueue_script('word-count');
142
- wp_enqueue_script('quicktags');
143
- }
144
-
145
- /**
146
- * Called by admin_print_styles-(hook|page) action, created when adding menu items in events-manager.php
147
- */
148
- function em_admin_load_styles() {
149
- add_thickbox();
150
- wp_enqueue_style('em-ui-css', WP_PLUGIN_URL.'/events-manager/includes/css/jquery-ui-1.7.3.custom.css');
151
- wp_enqueue_style('events-manager-admin', WP_PLUGIN_URL.'/events-manager/includes/css/events_manager_admin.css');
152
- }
153
-
154
- /**
155
- * Loads script inline due to insertion of php values
156
- */
157
- function em_admin_general_script() {
158
- //TODO clean script up, remove dependency of php so it can be moved to js file.
159
- // Check if the locale is there and loads it
160
- $locale_code = substr ( get_locale (), 0, 2 );
161
- $show24Hours = 'true';
162
- // Setting 12 hours format for those countries using it
163
- if (preg_match ( "/en|sk|zh|us|uk/", $locale_code ))
164
- $show24Hours = 'false';
165
- ?>
166
- <script type="text/javascript">
167
- //<![CDATA[
168
- // TODO: make more general, to support also latitude and longitude (when added)
169
-
170
- jQuery(document).ready( function($) {
171
-
172
- function updateIntervalDescriptor () {
173
- $(".interval-desc").hide();
174
- var number = "-plural";
175
- if ($('input#recurrence-interval').val() == 1 || $('input#recurrence-interval').val() == "")
176
- number = "-singular"
177
- var descriptor = "span#interval-"+$("select#recurrence-frequency").val()+number;
178
- $(descriptor).show();
179
- }
180
- function updateIntervalSelectors () {
181
- $('p.alternate-selector').hide();
182
- $('p#'+ $('select#recurrence-frequency').val() + "-selector").show();
183
- }
184
- function updateShowHideRsvp () {
185
- if($('input#rsvp-checkbox').attr("checked")) {
186
- $("div#rsvp-data").fadeIn();
187
- } else {
188
- $("div#rsvp-data").hide();
189
- }
190
- }
191
- function updateShowHideRecurrence () {
192
- if( $('input#event-recurrence').attr("checked")) {
193
- $("#event_recurrence_pattern").fadeIn();
194
- $("#event-date-explanation").hide();
195
- $("#recurrence-dates-explanation").show();
196
- $("h3#recurrence-dates-title").show();
197
- $("h3#event-date-title").hide();
198
- } else {
199
- $("#event_recurrence_pattern").hide();
200
- $("#recurrence-dates-explanation").hide();
201
- $("#event-date-explanation").show();
202
- $("h3#recurrence-dates-title").hide();
203
- $("h3#event-date-title").show();
204
- }
205
- }
206
- $("#recurrence-dates-explanation").hide();
207
- $("#localised-date").show();
208
- $("#localised-end-date").show();
209
-
210
- $("#date-to-submit").hide();
211
- $("#end-date-to-submit").hide();
212
-
213
- $("#start-time").timeEntry({spinnerImage: '', show24Hours: <?php echo $show24Hours; ?> });
214
- $("#end-time").timeEntry({spinnerImage: '', show24Hours: <?php echo $show24Hours; ?>});
215
-
216
- $('input.select-all').change(function(){
217
- if($(this).is(':checked'))
218
- $('input.row-selector').attr('checked', true);
219
- else
220
- $('input.row-selector').attr('checked', false);
221
- });
222
-
223
- updateIntervalDescriptor();
224
- updateIntervalSelectors();
225
- updateShowHideRecurrence();
226
- updateShowHideRsvp();
227
- $('input#event-recurrence').change(updateShowHideRecurrence);
228
- $('input#rsvp-checkbox').change(updateShowHideRsvp);
229
-
230
- // recurrency elements
231
- $('input#recurrence-interval').keyup(updateIntervalDescriptor);
232
- $('select#recurrence-frequency').change(updateIntervalDescriptor);
233
- $('select#recurrence-frequency').change(updateIntervalSelectors);
234
-
235
- // hiding or showing notes according to their content
236
- $('.postbox h3').prepend('<a class="togbox">+</a> ');
237
- $('#event_notes h3').click( function() {
238
- $(this).parent().first().toggleClass('closed');
239
- });
240
-
241
- // users cannot submit the event form unless some fields are filled
242
- function validateEventForm(){
243
- errors = "";
244
- var recurring = $("input[@name=repeated_event]:checked").val();
245
- requiredFields= new Array('event_name', 'localised_event_date', 'location_name','location_address','location_town');
246
- var localisedRequiredFields = {
247
- 'event_name':"<?php _e ( 'Name', 'dbem' )?>",
248
- 'localised_event_date':"<?php _e ( 'Date', 'dbem' )?>",
249
- 'location_name':"<?php _e ( 'Location', 'dbem' )?>",
250
- 'location_address':"<?php _e ( 'Address', 'dbem' )?>",
251
- 'location_town':"<?php _e ( 'Town', 'dbem' )?>"
252
- };
253
- missingFields = new Array;
254
- for (var i in requiredFields) {
255
- if ($("input[@name=" + requiredFields[i]+ "]").val() == 0) {
256
- missingFields.push(localisedRequiredFields[requiredFields[i]]);
257
- $("input[@name=" + requiredFields[i]+ "]").css('border','2px solid red');
258
- } else {
259
- $("input[@name=" + requiredFields[i]+ "]").css('border','1px solid #DFDFDF');
260
- }
261
- }
262
-
263
- // alert('ciao ' + recurring+ " end: " + $("input[@name=localised_event_end_date]").val());
264
- if (missingFields.length > 0) {
265
- errors = "<?php _e ( 'Some required fields are missing:', 'dbem' )?> " + missingFields.join(", ") + ".\n";
266
- }
267
- if(recurring && $("input[@name=localised_event_end_date]").val() == "") {
268
- errors = errors + "<?php _e ( 'Since the event is repeated, you must specify an end date', 'dbem' )?>.";
269
- $("input[@name=localised_event_end_date]").css('border','2px solid red');
270
- } else {
271
- $("input[@name=localised_event_end_date]").css('border','1px solid #DFDFDF');
272
- }
273
- if(errors != "") {
274
- alert(errors);
275
- return false;
276
- }
277
- return true;
278
- }
279
- $('#event-form').bind("submit", validateEventForm);
280
- });
281
- //]]>
282
- </script>
283
- <?php
284
- }
285
  ?>
1
+ <?php
2
+ //Admin functions
3
+ function em_admin_menu(){
4
+ global $menu, $submenu, $pagenow;
5
+ //Count pending bookings
6
+ if( get_option('dbem_rsvp_enabled') ){
7
+ $bookings_num = '';
8
+ $bookings_pending_count = apply_filters('em_bookings_pending_count',0);
9
+ if( get_option('dbem_bookings_approval') == 1){
10
+ $bookings_pending_count += count(EM_Bookings::get(array('status'=>'0', 'blog'=>get_current_blog_id()))->bookings);
11
+ }
12
+ if($bookings_pending_count > 0){
13
+ $bookings_num = '<span class="update-plugins count-'.$bookings_pending_count.'"><span class="plugin-count">'.$bookings_pending_count.'</span></span>';
14
+ }
15
+ }else{
16
+ $bookings_num = '';
17
+ $bookings_pending_count = 0;
18
+ }
19
+ //Count pending events
20
+ $events_num = '';
21
+ $events_pending_count = EM_Events::count(array('status'=>0, 'scope'=>'all', 'blog'=>get_current_blog_id()));
22
+ //TODO Add flexible permissions
23
+ if($events_pending_count > 0){
24
+ $events_num = '<span class="update-plugins count-'.$events_pending_count.'"><span class="plugin-count">'.$events_pending_count.'</span></span>';
25
+ }
26
+ //Count pending recurring events
27
+ $events_recurring_num = '';
28
+ $events_recurring_pending_count = EM_Events::count(array('status'=>0, 'recurring'=>1, 'scope'=>'all', 'blog'=>get_current_blog_id()));
29
+ //TODO Add flexible permissions
30
+ if($events_recurring_pending_count > 0){
31
+ $events_recurring_num = '<span class="update-plugins count-'.$events_recurring_pending_count.'"><span class="plugin-count">'.$events_recurring_pending_count.'</span></span>';
32
+ }
33
+ $both_pending_count = apply_filters('em_items_pending_count', $events_pending_count + $bookings_pending_count + $events_recurring_pending_count);
34
+ $both_num = ($both_pending_count > 0) ? '<span class="update-plugins count-'.$both_pending_count.'"><span class="plugin-count">'.$both_pending_count.'</span></span>':'';
35
+ // Add a submenu to the custom top-level menu:
36
+ $plugin_pages = array();
37
+ if( get_option('dbem_rsvp_enabled') ){
38
+ $plugin_pages['bookings'] = add_submenu_page('edit.php?post_type='.EM_POST_TYPE_EVENT, __('Bookings', 'dbem'), __('Bookings', 'dbem').$bookings_num, 'manage_bookings', 'events-manager-bookings', "em_bookings_page");
39
+ }
40
+ $plugin_pages['options'] = add_submenu_page('edit.php?post_type='.EM_POST_TYPE_EVENT, __('Events Manager Settings','dbem'),__('Settings','dbem'), 'activate_plugins', "events-manager-options", 'em_admin_options_page');
41
+ $plugin_pages['help'] = add_submenu_page('edit.php?post_type='.EM_POST_TYPE_EVENT, __('Getting Help for Events Manager','dbem'),__('Help','dbem'), 'activate_plugins', "events-manager-help", 'em_admin_help_page');
42
+ //If multisite global with locations set to be saved in main blogs we can force locations to be created on the main blog only
43
+ if( EM_MS_GLOBAL && !is_main_site() && get_site_option('dbem_ms_mainblog_locations') ){
44
+ include( dirname(__FILE__)."/em-ms-locations.php" );
45
+ $plugin_pages['locations'] = add_submenu_page('edit.php?post_type='.EM_POST_TYPE_EVENT, __('Locations','dbem'),__('Locations','dbem'), 'read_others_locations', "locations", 'em_admin_ms_locations');
46
+ }
47
+ $plugin_pages = apply_filters('em_create_events_submenu',$plugin_pages);
48
+ //We have to modify the menus manually
49
+ if( !empty($both_num) ){ //Main Event Menu
50
+ //go through the menu array and modify the events menu if found
51
+ foreach ( (array)$menu as $key => $parent_menu ) {
52
+ if ( $parent_menu[2] == 'edit.php?post_type='.EM_POST_TYPE_EVENT ){
53
+ $menu[$key][0] = $menu[$key][0]. $both_num;
54
+ break;
55
+ }
56
+ }
57
+ }
58
+ if( !empty($events_num) && !empty($submenu['edit.php?post_type='.EM_POST_TYPE_EVENT]) ){ //Submenu Event Item
59
+ //go through the menu array and modify the events menu if found
60
+ foreach ( (array)$submenu['edit.php?post_type='.EM_POST_TYPE_EVENT] as $key => $submenu_item ) {
61
+ if ( $submenu_item[2] == 'edit.php?post_type='.EM_POST_TYPE_EVENT ){
62
+ $submenu['edit.php?post_type='.EM_POST_TYPE_EVENT][$key][0] = $submenu['edit.php?post_type='.EM_POST_TYPE_EVENT][$key][0]. $events_num;
63
+ break;
64
+ }
65
+ }
66
+ }
67
+ if( !empty($events_recurring_num) && !empty($submenu['edit.php?post_type='.EM_POST_TYPE_EVENT]) ){ //Submenu Recurring Event Item
68
+ //go through the menu array and modify the events menu if found
69
+ foreach ( (array)$submenu['edit.php?post_type='.EM_POST_TYPE_EVENT] as $key => $submenu_item ) {
70
+ if ( $submenu_item[2] == 'edit.php?post_type=event-recurring' ){
71
+ $submenu['edit.php?post_type='.EM_POST_TYPE_EVENT][$key][0] = $submenu['edit.php?post_type='.EM_POST_TYPE_EVENT][$key][0]. $events_recurring_num;
72
+ break;
73
+ }
74
+ }
75
+ }
76
+ /* Hack! Add location/recurrence isn't possible atm so this is a workaround */
77
+ global $_wp_submenu_nopriv;
78
+ if( $pagenow == 'post-new.php' && !empty($_REQUEST['post_type']) ){
79
+ if( $_REQUEST['post_type'] == EM_POST_TYPE_LOCATION && !empty($_wp_submenu_nopriv['edit.php']['post-new.php']) && current_user_can('edit_locations') ){
80
+ unset($_wp_submenu_nopriv['edit.php']['post-new.php']);
81
+ }
82
+ if( $_REQUEST['post_type'] == 'event-recurring' && !empty($_wp_submenu_nopriv['edit.php']['post-new.php']) && current_user_can('edit_recurring_events') ){
83
+ unset($_wp_submenu_nopriv['edit.php']['post-new.php']);
84
+ }
85
+ }
86
+ }
87
+ add_action('admin_menu','em_admin_menu');
88
+
89
+ function em_ms_admin_menu(){
90
+ add_menu_page( __('Events Manager','dbem'), __('Events Manager','dbem'), 'activate_plugins', 'events-manager-options', 'em_ms_admin_options_page', plugins_url('includes/images/calendar-16.png', dirname(dirname(__FILE__)).'/events-manager.php') );
91
+ add_submenu_page('events-manager-options', __('Update Blogs','dbem'),__('Update Blogs','dbem'), 'activate_plugins', "events-manager-update", 'em_ms_upgrade');
92
+ }
93
+ add_action('network_admin_menu','em_ms_admin_menu');
94
+
95
+ function em_admin_init(){
96
+ //in MS global mode
97
+ if( EM_MS_GLOBAL && is_user_logged_in() && !is_main_site() && get_site_option('dbem_ms_mainblog_locations') ){
98
+ EM_Object::ms_global_switch();
99
+ $user = new WP_User(get_current_user_id());
100
+ if( count($user->roles) == 0 ){
101
+ $user->set_role('subscriber');
102
+ }
103
+ EM_Object::ms_global_switch_back();
104
+ }
105
+ }
106
+ add_action('admin_init','em_admin_init');
107
+
108
+ /**
109
+ * Generate warnings and notices in the admin area
110
+ */
111
+ function em_admin_warnings() {
112
+ global $EM_Notices;
113
+ //If we're editing the events page show hello to new user
114
+ $events_page_id = get_option ( 'dbem_events_page' );
115
+ $dismiss_link_joiner = ( count($_GET) > 0 ) ? '&amp;':'?';
116
+
117
+ if( current_user_can('activate_plugins') ){
118
+ //New User Intro
119
+ if (isset ( $_GET ['disable_hello_to_user'] ) && $_GET ['disable_hello_to_user'] == 'true'){
120
+ // Disable Hello to new user if requested
121
+ update_option('dbem_hello_to_user',0);
122
+ }elseif ( get_option ( 'dbem_hello_to_user' ) ) {
123
+ //FIXME update welcome msg with good links
124
+ $advice = sprintf( __("<p>Events Manager is ready to go! It is highly recommended you read the <a href='%s'>Getting Started</a> guide on our site, as well as checking out the <a href='%s'>Settings Page</a>. <a href='%s' title='Don't show this advice again'>Dismiss</a></p>", 'dbem'), 'http://wp-events-plugin.com/documentation/getting-started/?utm_source=em&utm_medium=plugin&utm_content=installationlink&utm_campaign=plugin_links', EM_ADMIN_URL .'&amp;page=events-manager-options', $_SERVER['REQUEST_URI'].$dismiss_link_joiner.'disable_hello_to_user=true');
125
+ ?>
126
+ <div id="message" class="updated">
127
+ <?php echo $advice; ?>
128
+ </div>
129
+ <?php
130
+ }
131
+
132
+ //If events page couldn't be created or is missing
133
+ if( !empty($_GET['em_dismiss_events_page']) ){
134
+ update_option('dbem_dismiss_events_page',1);
135
+ }else{
136
+ if ( !get_page($events_page_id) && !get_option('dbem_dismiss_events_page') ){
137
+ ?>
138
+ <div id="em_page_error" class="updated">
139
+ <p><?php echo sprintf ( __( 'Uh Oh! For some reason WordPress could not create an events page for you (or you just deleted it). Not to worry though, all you have to do is create an empty page, name it whatever you want, and select it as your events page in your <a href="%s">settings page</a>. Sorry for the extra step! If you know what you are doing, you may have done this on purpose, if so <a href="%s">ignore this message</a>', 'dbem'), EM_ADMIN_URL .'&amp;page=events-manager-options', $_SERVER['REQUEST_URI'].$dismiss_link_joiner.'em_dismiss_events_page=1' ); ?></p>
140
+ </div>
141
+ <?php
142
+ }
143
+ }
144
+
145
+ if( defined('EMP_VERSION') && EMP_VERSION < EM_PRO_MIN_VERSION ){
146
+ ?>
147
+ <div id="em_page_error" class="updated">
148
+ <p><?php _e('There is a newer version of Events Manager Pro which is required for this current version of Events Manager. Please go to the plugin website and download the latest update.','dbem'); ?></p>
149
+ </div>
150
+ <?php
151
+ }
152
+
153
+ if( is_multisite() && !empty($_REQUEST['page']) && $_REQUEST['page']=='events-manager-options' && is_super_admin() && get_option('dbem_ms_update_nag') ){
154
+ if( !empty($_GET['disable_dbem_ms_update_nag']) ){
155
+ delete_site_option('dbem_ms_update_nag');
156
+ }else{
157
+ ?>
158
+ <div id="em_page_error" class="updated">
159
+ <p><?php echo sprintf(__('MultiSite options have moved <a href="%s">here</a>. <a href="%s">Dismiss message</a>','dbem'),admin_url().'network/admin.php?page=events-manager-options', $_SERVER['REQUEST_URI'].'&amp;disable_dbem_ms_update_nag=1'); ?></p>
160
+ </div>
161
+ <?php
162
+ }
163
+ }
164
+
165
+ if( is_super_admin() && get_option('dbem_migrate_images_nag') ){
166
+ if( !empty($_GET['disable_dbem_migrate_images_nag']) ){
167
+ delete_site_option('dbem_migrate_images_nag');
168
+ }else{
169
+ ?>
170
+ <div id="em_page_error" class="updated">
171
+ <p><?php echo sprintf(__('Whilst they will still appear using placeholders, you need to <a href="%s">migrate your location and event images</a> in order for them to appear in your edit forms and media library. <a href="%s">Dismiss message</a>','dbem'),admin_url().'edit.php?post_type=event&page=events-manager-options&em_migrate_images=1&_wpnonce='.wp_create_nonce('em_migrate_images'), em_add_get_params($_SERVER['REQUEST_URI'], array('disable_dbem_migrate_images_nag' => 1))); ?></p>
172
+ </div>
173
+ <?php
174
+ }
175
+ }
176
+ if( !empty($_REQUEST['page']) && 'events-manager-options' == $_REQUEST['page'] && get_option('dbem_pro_dev_updates') == 1 ){
177
+ ?>
178
+ <div id="message" class="updated">
179
+ <p><?php echo sprintf(__('Dev Mode active: Just a friendly reminder that you are updating to development versions. Only admins see this message, and it will go away when you disable this <a href="#pro-api">here</a> in your settings.','em-pro'),'<code>define(\'EMP_DEV_UPDATES\',true);</code>'); ?></p>
180
+ </div>
181
+ <?php
182
+ }
183
+ }
184
+ //Warn about EM page edit
185
+ if ( preg_match( '/(post|page).php/', $_SERVER ['SCRIPT_NAME']) && isset ( $_GET ['action'] ) && $_GET ['action'] == 'edit' && isset ( $_GET ['post'] ) && $_GET ['post'] == "$events_page_id") {
186
+ $message = sprintf ( __ ( "This page corresponds to <strong>Events Manager</strong> events page. Its content will be overriden by Events Manager, although if you include the word CONTENTS (exactly in capitals) and surround it with other text, only CONTENTS will be overwritten. If you want to change the way your events look, go to the <a href='%s'>settings</a> page. ", 'dbem' ), EM_ADMIN_URL .'&amp;page=events-manager-options' );
187
+ $notice = "<div class='error'><p>$message</p></div>";
188
+ echo $notice;
189
+ }
190
+ echo $EM_Notices;
191
+ }
192
+ add_action ( 'admin_notices', 'em_admin_warnings', 100 );
193
+
194
+ /**
195
+ * Settings link in the plugins page menu
196
+ * @param array $links
197
+ * @param string $file
198
+ * @return array
199
+ */
200
+ function em_plugin_action_links($actions, $file, $plugin_data) {
201
+ $actions['settings'] = sprintf( '<a href="'.EM_ADMIN_URL.'&amp;page=events-manager-options">%s</a>', __('Settings', 'dbem') );
202
+ if( is_multisite() ){
203
+ $uninstall_url = admin_url().'network/admin.php?page=events-manager-options&amp;action=uninstall&amp;_wpnonce='.wp_create_nonce('em_uninstall_'.get_current_user_id().'_wpnonce');
204
+ }else{
205
+ $uninstall_url = EM_ADMIN_URL.'&amp;page=events-manager-options&amp;action=uninstall&amp;_wpnonce='.wp_create_nonce('em_uninstall_'.get_current_user_id().'_wpnonce');
206
+ }
207
+ $actions['uninstall'] = '<span class="delete"><a href="'.$uninstall_url.'" class="delete">'.__('Uninstall','dbem').'</a></span>';
208
+ return $actions;
209
+ }
210
+ add_filter( 'plugin_action_links_events-manager/events-manager.php', 'em_plugin_action_links', 10, 3 );
211
+
212
+ //Updates and Dev versions
213
+ function em_updates_check( $transient ) {
214
+ // Check if the transient contains the 'checked' information
215
+ if( empty( $transient->checked ) )
216
+ return $transient;
217
+
218
+ //only bother if we're checking for dev versions
219
+ if( get_option('em_check_dev_version') || get_option('dbem_pro_dev_updates') ){
220
+ //check WP repo for trunk version
221
+ $request = wp_remote_get('http://plugins.svn.wordpress.org/events-manager/trunk/events-manager.php');
222
+
223
+ preg_match('/Version: ([0-9a-z\.]+)/', $request['body'], $matches);
224
+
225
+ if( !empty($matches[1]) ){
226
+ //we have a version number!
227
+ if( version_compare($transient->checked[EM_SLUG], $matches[1]) < 0) {
228
+ $response = new stdClass();
229
+ $response->slug = EM_SLUG;
230
+ $response->new_version = $matches[1] ;
231
+ $response->url = 'http://wordpress.org/extend/plugins/events-manager/';
232
+ $response->package = 'http://downloads.wordpress.org/plugin/events-manager.zip';
233
+ $transient->response[EM_SLUG] = $response;
234
+ }
235
+ }
236
+ delete_option('em_check_dev_version');
237
+ }
238
+
239
+ return $transient;
240
+ }
241
+ add_filter('pre_set_site_transient_update_plugins', 'em_updates_check'); // Hook into the plugin update check and mod for dev version
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
242
  ?>
admin/em-bookings.php CHANGED
@@ -1,288 +1,507 @@
1
- <?php
2
- /**
3
- * Check if there's any admin-related actions to take for bookings. All actions are caught here.
4
- * @return null
5
- */
6
- function em_admin_actions_bookings() {
7
- global $dbem_form_add_message;
8
- global $dbem_form_delete_message;
9
- global $wpdb, $EM_Booking, $EM_Event;
10
-
11
- if( current_user_can(EM_MIN_CAPABILITY) && is_object($EM_Booking) && !empty($_REQUEST['action']) ) {
12
- if( $_REQUEST['action'] == 'bookings_delete' ){
13
- //Delete
14
- if( isset($_POST['booking_id']) ){
15
- $EM_Booking = new EM_Booking($_POST['booking_id']);
16
- $EM_Booking->delete();
17
- }
18
- }elseif( $_REQUEST['action'] == 'bookings_edit' ){
19
- //Edit Booking
20
- $validation = $EM_Booking->get_post();
21
- if ( $validation ) { //EM_Event gets the event if submitted via POST and validates it (safer than to depend on JS)
22
- //Save
23
- if( $EM_Booking->save() ) {
24
- function em_booking_save_notification(){ global $EM_Booking; ?><div class="updated"><p><strong><?php echo $EM_Booking->feedback_message; ?></strong></p></div><?php }
25
- }else{
26
- function em_booking_save_notification(){ global $EM_Booking; ?><div class="error"><p><strong><?php echo $EM_Booking->feedback_message; ?></strong></p></div><?php }
27
- }
28
- }else{
29
- //TODO make errors clearer when saving person
30
- function em_booking_save_notification(){ global $EM_Booking; ?><div class="error"><p><strong><?php echo $EM_Booking->feedback_message; ?></strong></p></div><?php }
31
- }
32
- add_action ( 'admin_notices', 'em_booking_save_notification' );
33
- }elseif( $_REQUEST['action'] == 'bookings_approve' || $_REQUEST['action'] == 'bookings_reject' || $_REQUEST['action'] == 'bookings_unapprove' ){
34
- //Booking Approvals
35
- $status_array = array('bookings_unapprove' => 0,'bookings_approve' => 1,'bookings_reject' => 2, 'bookings_cancel' => 3);
36
- if( $EM_Booking->set_status( $status_array[$_REQUEST['action']] ) ) {
37
- function em_booking_save_notification(){ global $EM_Booking; ?><div class="updated"><p><strong><?php echo $EM_Booking->feedback_message; ?></strong></p></div><?php }
38
- }else{
39
- function em_booking_save_notification(){ global $EM_Booking; ?><div class="error"><p><strong><?php echo $EM_Booking->feedback_message; ?></strong></p></div><?php }
40
- }
41
- add_action ( 'admin_notices', 'em_booking_save_notification' );
42
- }elseif( $_REQUEST['action'] == 'bookings_add_note' ){
43
- $EM_Booking->add_note($_REQUEST['booking_note']);
44
- function em_booking_save_notification(){ global $EM_Booking; ?><div class="updated"><p><strong><?php echo $EM_Booking->feedback_message; ?></strong></p></div><?php }
45
- add_action ( 'admin_notices', 'em_booking_save_notification' );
46
- }
47
- }elseif( current_user_can(EM_MIN_CAPABILITY) && is_object($EM_Event) && !empty($_REQUEST['action']) ){
48
- if( $_REQUEST['action'] == 'export_csv' ){
49
- $EM_Event->get_bookings()->export_csv();
50
- exit();
51
- }
52
- }
53
- }
54
- add_action('admin_init','em_admin_actions_bookings',100);
55
-
56
- /**
57
- * Decide what content to show in the bookings section.
58
- */
59
- function em_bookings_page(){
60
- //First any actions take priority
61
- if( !empty($_REQUEST['booking_id']) ){
62
- em_bookings_single();
63
- }elseif( !empty($_REQUEST['person_id']) ){
64
- em_bookings_person();
65
- }elseif( !empty($_REQUEST['event_id']) ){
66
- em_bookings_event();
67
- }else{
68
- em_bookings_dashboard();
69
- }
70
- }
71
-
72
- /**
73
- * Generates the bookings dashboard, showing information on all events
74
- */
75
- function em_bookings_dashboard(){
76
- ?>
77
- <div class='wrap'>
78
- <div id='icon-users' class='icon32'>
79
- <br/>
80
- </div>
81
- <h2>
82
- <?php _e('Event Bookings Dashboard', 'dbem'); ?>
83
- </h2>
84
- <?php if( get_option('dbem_bookings_approval') ): ?>
85
- <h2><?php _e('Pending Bookings','dbem'); ?></h2>
86
- <?php em_bookings_pending_table(); ?>
87
- <?php endif; ?>
88
- <h2><?php _e('Events With Bookings Enabled','dbem'); ?></h2>
89
- <?php em_bookings_events_table(); ?>
90
- </div>
91
- <?php
92
- }
93
-
94
- /**
95
- * Shows all booking data for a single event
96
- */
97
- function em_bookings_event(){
98
- global $EM_Event,$EM_Person;
99
- //check that user can access this page
100
- if( is_object($EM_Event) && !$EM_Event->can_manage() ){
101
- ?>
102
- <div class="wrap"><h2><?php _e('Unauthorized Access','dbem'); ?></h2><p><?php _e('You do not have the rights to manage this event.','dbem'); ?></p></div>
103
- <?php
104
- return false;
105
- }
106
- $localised_start_date = date_i18n('D d M Y', $EM_Event->start);
107
- $localised_end_date = date_i18n('D d M Y', $EM_Event->end);
108
- ?>
109
- <div class='wrap'>
110
- <div id='icon-users' class='icon32'>
111
- <br/>
112
- </div>
113
- <h2>
114
- <?php echo sprintf(__('Manage %s Bookings', 'dbem'), "'{$EM_Event->name}'"); ?>
115
- <a href="admin.php?page=events-manager-event&event_id=<?php echo $EM_Event->id; ?>" class="button add-new-h2"><?php _e('View/Edit Event','dbem') ?></a>
116
- </h2>
117
- <div><a href='<?php echo get_bloginfo('wpurl') . "/wp-admin/admin.php?page=events-manager-bookings&action=export_csv&event_id=".$EM_Event->id ?>'><?php _e('export csv','dbem')?></a></div>
118
- <div>
119
- <p><strong><?php _e('Event Name','dbem'); ?></strong> : <?php echo ($EM_Event->name); ?></p>
120
- <p><strong>Availability :</strong> <?php echo $EM_Event->get_bookings()->get_booked_seats() . '/'. $EM_Event->seats ." ". __('Seats confirmed','dbem'); ?></p>
121
- <p>
122
- <strong><?php _e('Date','dbem'); ?></strong> :
123
- <?php echo $localised_start_date; ?>
124
- <?php echo ($localised_end_date != $localised_start_date) ? " - $localised_end_date":'' ?>
125
- <?php echo substr ( $EM_Event->start_time, 0, 5 ) . " - " . substr ( $EM_Event->end_time, 0, 5 ); ?>
126
- </p>
127
- <p>
128
- <strong><?php _e('Location','dbem'); ?></strong> :
129
- <a class="row-title" href="<?php bloginfo ( 'wpurl' )?>/wp-admin/admin.php?page=events-manager-locations&amp;location_id=<?php echo $EM_Event->location->id ?>"><?php echo ($EM_Event->location->name); ?></a>
130
- </p>
131
- </div>
132
- <?php if( get_option('dbem_bookings_approval') ): ?>
133
- <h2><?php _e('Pending Bookings','dbem'); ?></h2>
134
- <?php em_bookings_pending_table(); ?>
135
- <?php endif; ?>
136
- <h2><?php _e('Confirmed Bookings','dbem'); ?></h2>
137
- <?php em_bookings_confirmed_table(); ?>
138
- <h2><?php _e('Rejected Bookings','dbem'); ?></h2>
139
- <?php em_bookings_rejected_table(); ?>
140
- <h2><?php _e('Cancelled Bookings','dbem'); ?></h2>
141
- <?php em_bookings_cancelled_table(); ?>
142
- </div>
143
- <?php
144
- }
145
-
146
- /**
147
- * Shows a single booking for a single person.
148
- */
149
- function em_bookings_single(){
150
- global $EM_Booking;
151
- //check that user can access this page
152
- if( is_object($EM_Booking) && !$EM_Booking->can_manage() ){
153
- ?>
154
- <div class="wrap"><h2><?php _e('Unauthorized Access','dbem'); ?></h2><p><?php _e('You do not have the rights to manage this event.','dbem'); ?></p></div>
155
- <?php
156
- return false;
157
- }
158
- ?>
159
- <div class='wrap'>
160
- <div id='icon-users' class='icon32'>
161
- <br/>
162
- </div>
163
- <h2>
164
- <?php _e('Edit Booking', 'dbem'); ?>
165
- </h2>
166
- <div id="poststuff" class="metabox-holder has-right-sidebar">
167
- <div id="post-body">
168
- <div id="post-body-content">
169
- <div id="event_name" class="stuffbox">
170
- <h3>
171
- <?php _e ( 'Booking Details', 'dbem' ); ?>
172
- </h3>
173
- <div class="inside">
174
- <?php em_bookings_edit_form(); ?>
175
- </div>
176
- </div>
177
- </div>
178
- </div>
179
- </div>
180
- <br style="clear:both;" />
181
- <div id="poststuff" class="metabox-holder has-right-sidebar">
182
- <div id="post-body">
183
- <div id="post-body-content">
184
- <div id="event_name" class="stuffbox">
185
- <h3>
186
- <?php _e ( 'Booking Notes', 'dbem' ); ?>
187
- </h3>
188
- <div class="inside">
189
- <p><?php _e('You can add private notes below for internal reference that only event managers will see.','dbem'); ?></p>
190
- <?php foreach( $EM_Booking->notes as $note ):
191
- $user = get_userdata($note['author']);
192
- ?>
193
- <div>
194
- <?php echo date(get_option('date_format'), $note['timestamp']) .' - '. $user->display_name; ?> <?php _e('wrote','dbem'); ?>:
195
- <p style="background:#efefef; padding:5px;"><?php echo nl2br($note['note']); ?></p>
196
- </div>
197
- <?php endforeach; ?>
198
- <form method="post" action="" style="padding:5px;">
199
- <textarea class="widefat" rows="5" name="booking_note"></textarea>
200
- <input type="hidden" name="action" value="bookings_add_note" />
201
- <input type="submit" value="Add Note" />
202
- </form>
203
- </div>
204
- </div>
205
- </div>
206
- </div>
207
- </div>
208
- <br style="clear:both;" />
209
- <?php do_action('em_bookings_single_footer'); ?>
210
- </div>
211
- <?php
212
-
213
- }
214
-
215
- /**
216
- * Shows all bookings made by one person.
217
- */
218
- function em_bookings_person(){
219
- global $EM_Person;
220
- ?>
221
- <div class='wrap'>
222
- <div id='icon-users' class='icon32'>
223
- <br/>
224
- </div>
225
- <h2>
226
- <?php _e('Manage Person\'s Booking', 'dbem'); ?>
227
- <a href="admin.php?page=events-manager-bookings&action=person_delete&person_id=<?php echo $EM_Person->id; ?>" onclick="if( !confirm('<?php _e('Are you sure you want to delete this person? All bookings corresponding to this person will be deleted and this is not reversible.','dbem') ?>') ){ return false; }" class="button add-new-h2"><?php _e('Delete Person','dbem') ?></a>
228
- </h2>
229
- <div id="poststuff" class="metabox-holder has-right-sidebar">
230
- <div id="post-body">
231
- <div id="post-body-content">
232
- <div id="event_name" class="stuffbox">
233
- <h3>
234
- <?php _e ( 'Personal Details', 'dbem' ); ?>
235
- </h3>
236
- <div class="inside">
237
- <?php em_person_edit_form(); ?>
238
- </div>
239
- </div>
240
- </div>
241
- </div>
242
- </div>
243
- <br style="clear:both;" />
244
- <h3><?php _e('Past And Present Bookings','dbem'); ?></h3>
245
- <?php em_bookings_person_table(); ?>
246
- </div>
247
- <?php
248
- }
249
-
250
- function em_bookings_edit_form(){
251
- global $EM_Booking;
252
- $EM_Event = new EM_Event($EM_Booking->event_id);
253
- $localised_start_date = date_i18n('D d M Y', $EM_Event->start);
254
- $localised_end_date = date_i18n('D d M Y', $EM_Event->end);
255
- ?>
256
- <form action="" method="post" id="em-person-form">
257
- <h4>Event Details</h4>
258
- <table>
259
- <tr><td><strong><?php _e('Name','dbem'); ?></strong></td><td><a class="row-title" href="<?php bloginfo ( 'wpurl' )?>/wp-admin/admin.php?page=events-manager-bookings&amp;event_id=<?php echo $EM_Event->id ?>"><?php echo ($EM_Event->name); ?></a></td></tr>
260
- <tr>
261
- <td><strong><?php _e('Date/Time','dbem'); ?>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</strong></td>
262
- <td>
263
- <?php echo $localised_start_date; ?>
264
- <?php echo ($localised_end_date != $localised_start_date) ? " - $localised_end_date":'' ?>
265
- <?php echo substr ( $EM_Event->start_time, 0, 5 ) . " - " . substr ( $EM_Event->end_time, 0, 5 ); ?>
266
- </td>
267
- </tr>
268
- </table>
269
- <h4>Personal Details</h4>
270
- <table>
271
- <tr><td><strong><?php _e('Name','dbem'); ?> </strong></td><td><a href="<?php bloginfo ( 'wpurl' )?>/wp-admin/admin.php?page=events-manager-bookings&amp;person_id=<?php echo $EM_Booking->person_id; ?>"><?php echo $EM_Booking->person->name ?></a></td></tr>
272
- <tr><td><strong><?php _e('Phone','dbem'); ?> </strong></td><td><?php echo $EM_Booking->person->phone; ?></td></tr>
273
- <tr><td><strong><?php _e('E-mail','dbem'); ?>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</strong></td><td><?php echo $EM_Booking->person->email; ?></td></tr>
274
- </table>
275
- <h4>Booking Details</h4>
276
- <table>
277
- <tr><td><strong><?php _e('Spaces','dbem'); ?> </strong></td><td><input type="text" name="booking_seats" value="<?php echo $EM_Booking->seats; ?>" /></td></tr>
278
- <tr><td><strong><?php _e('Comment','dbem'); ?>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</strong></td><td><textarea name="booking_comment"><?php echo $EM_Booking->comment; ?></textarea></td></tr>
279
- </table>
280
- <p class="submit">
281
- <input type="submit" name="events_update" value="<?php _e ( 'Save' ); ?> &raquo;" />
282
- </p>
283
- <input type="hidden" name="action" value="bookings_edit" />
284
- <input type="hidden" name="booking_id" value="<?php echo $EM_Booking->id; ?>" />
285
- </form>
286
- <?php
287
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
288
  ?>
1
+ <?php
2
+ /**
3
+ * Check if there's any admin-related actions to take for bookings. All actions are caught here.
4
+ * @return null
5
+ */
6
+ function em_admin_actions_bookings() {
7
+ global $dbem_form_add_message;
8
+ global $dbem_form_delete_message;
9
+ global $wpdb, $EM_Booking, $EM_Event, $EM_Notices;
10
+
11
+ if( is_object($EM_Booking) && !empty($_REQUEST['action']) && $EM_Booking->can_manage('manage_bookings','manage_others_bookings') ) {
12
+ if( $_REQUEST['action'] == 'bookings_add_note' ){
13
+ $EM_Booking->add_note($_REQUEST['booking_note']);
14
+ function em_booking_save_notification(){ global $EM_Booking; ?><div class="updated"><p><strong><?php echo $EM_Booking->feedback_message; ?></strong></p></div><?php }
15
+ add_action ( 'admin_notices', 'em_booking_save_notification' );
16
+ }
17
+ }
18
+ if( is_object($EM_Event) && !empty($_REQUEST['action']) ){
19
+ if( $_REQUEST['action'] == 'bookings_export_csv' && wp_verify_nonce($_REQUEST['_wpnonce'],'bookings_export_csv') ){
20
+ $EM_Event->get_bookings()->export_csv();
21
+ exit();
22
+ }
23
+ }
24
+ }
25
+ add_action('admin_init','em_admin_actions_bookings',100);
26
+
27
+ /**
28
+ * Decide what content to show in the bookings section.
29
+ */
30
+ function em_bookings_page(){
31
+ //First any actions take priority
32
+ if( !empty($_REQUEST['action']) && substr($_REQUEST['action'],0,7) != 'booking' ){ //actions not starting with booking_
33
+ do_action('em_bookings_'.$_REQUEST['action']);
34
+ }elseif( !empty($_REQUEST['booking_id']) ){
35
+ em_bookings_single();
36
+ }elseif( !empty($_REQUEST['person_id']) ){
37
+ em_bookings_person();
38
+ }elseif( !empty($_REQUEST['event_id']) ){
39
+ em_bookings_event();
40
+ }elseif( !empty($_REQUEST['ticket_id']) ){
41
+ em_bookings_ticket();
42
+ }else{
43
+ em_bookings_dashboard();
44
+ }
45
+ }
46
+
47
+ /**
48
+ * Generates the bookings dashboard, showing information on all events
49
+ */
50
+ function em_bookings_dashboard(){
51
+ global $EM_Notices;
52
+ ?>
53
+ <div class='wrap'>
54
+ <?php if( is_admin() ): ?>
55
+ <div id='icon-users' class='icon32'>
56
+ <br/>
57
+ </div>
58
+ <h2>
59
+ <?php _e('Event Bookings Dashboard', 'dbem'); ?>
60
+ </h2>
61
+ <?php endif; ?>
62
+ <?php echo $EM_Notices; ?>
63
+ <?php if( is_admin() ): ?>
64
+ <div class="icon32" id="icon-bookings"><br></div>
65
+ <?php endif; ?>
66
+ <h2><?php _e('Recent Bookings','dbem'); ?></h2>
67
+ <?php
68
+ $EM_Bookings_Table = new EM_Bookings_Table();
69
+ $EM_Bookings_Table->status = get_option('dbem_bookings_approval') ? 'needs-attention':'confirmed';
70
+ $EM_Bookings_Table->output();
71
+ ?>
72
+ <br class="clear" />
73
+ <?php if( is_admin() ): ?>
74
+ <div class="icon32" id="events"><br></div>
75
+ <?php endif; ?>
76
+ <h2><?php _e('Events With Bookings Enabled','dbem'); ?></h2>
77
+ <?php em_bookings_events_table(); ?>
78
+ <?php do_action('em_bookings_dashboard'); ?>
79
+ </div>
80
+ <?php
81
+ }
82
+
83
+ /**
84
+ * Shows all booking data for a single event
85
+ */
86
+ function em_bookings_event(){
87
+ global $EM_Event,$EM_Person,$EM_Notices;
88
+ //check that user can access this page
89
+ if( is_object($EM_Event) && !$EM_Event->can_manage('manage_bookings','manage_others_bookings') ){
90
+ ?>
91
+ <div class="wrap"><h2><?php _e('Unauthorized Access','dbem'); ?></h2><p><?php _e('You do not have the rights to manage this event.','dbem'); ?></p></div>
92
+ <?php
93
+ return false;
94
+ }
95
+ $localised_start_date = date_i18n('D d M Y', $EM_Event->start);
96
+ $localised_end_date = date_i18n('D d M Y', $EM_Event->end);
97
+ ?>
98
+ <div class='wrap'>
99
+ <div id='icon-users' class='icon32'>
100
+ <br/>
101
+ </div>
102
+ <h2>
103
+ <?php echo sprintf(__('Manage %s Bookings', 'dbem'), "'{$EM_Event->event_name}'"); ?>
104
+ <a href="<?php echo $EM_Event->get_permalink(); ?>" class="button add-new-h2"><?php echo sprintf(__('View %s','dbem'), __('Event', 'dbem')) ?></a>
105
+ <a href="<?php echo $EM_Event->get_edit_url(); ?>" class="button add-new-h2"><?php echo sprintf(__('Edit %s','dbem'), __('Event', 'dbem')) ?></a>
106
+ <?php if( locate_template('plugins/events-manager/templates/csv-event-bookings.php', false) ): ?>
107
+ <a href='<?php echo EM_ADMIN_URL ."&amp;page=events-manager-bookings&action=bookings_export_csv&_wpnonce=".wp_create_nonce('bookings_export_csv')."&event_id=".$EM_Event->event_id ?>' class="button add-new-h2"><?php _e('Export CSV','dbem')?></a>
108
+ <?php endif; ?>
109
+ <?php do_action('em_admin_event_booking_options_buttons'); ?>
110
+ </h2>
111
+ <?php echo $EM_Notices; ?>
112
+ <div>
113
+ <p><strong><?php _e('Event Name','dbem'); ?></strong> : <?php echo ($EM_Event->event_name); ?></p>
114
+ <p>
115
+ <strong><?php _e('Availability','dbem'); ?></strong> :
116
+ <?php echo $EM_Event->get_bookings()->get_booked_spaces() . '/'. $EM_Event->get_spaces() ." ". __('Spaces confirmed','dbem'); ?>
117
+ <?php if( get_option('dbem_bookings_approval_reserved') ): ?>
118
+ , <?php echo $EM_Event->get_bookings()->get_available_spaces() . '/'. $EM_Event->get_spaces() ." ". __('Available spaces','dbem'); ?>
119
+ <?php endif; ?>
120
+ </p>
121
+ <p>
122
+ <strong><?php _e('Date','dbem'); ?></strong> :
123
+ <?php echo $localised_start_date; ?>
124
+ <?php echo ($localised_end_date != $localised_start_date) ? " - $localised_end_date":'' ?>
125
+ <?php echo substr ( $EM_Event->event_start_time, 0, 5 ) . " - " . substr ( $EM_Event->event_end_time, 0, 5 ); ?>
126
+ </p>
127
+ <p>
128
+ <strong><?php _e('Location','dbem'); ?></strong> :
129
+ <a class="row-title" href="<?php echo admin_url(); ?>post.php?action=edit&amp;post=<?php echo $EM_Event->get_location()->post_id ?>"><?php echo ($EM_Event->get_location()->location_name); ?></a>
130
+ </p>
131
+ </div>
132
+ <div class="icon32" id="icon-bookings"><br></div>
133
+ <h2><?php _e('Bookings','dbem'); ?></h2>
134
+ <?php
135
+ $EM_Bookings_Table = new EM_Bookings_Table();
136
+ $EM_Bookings_Table->status = 'all';
137
+ $EM_Bookings_Table->output();
138
+ ?>
139
+ <?php do_action('em_bookings_event_footer', $EM_Event); ?>
140
+ </div>
141
+ <?php
142
+ }
143
+
144
+ /**
145
+ * Shows a ticket view
146
+ */
147
+ function em_bookings_ticket(){
148
+ global $EM_Ticket,$EM_Notices;
149
+ $EM_Event = $EM_Ticket->get_event();
150
+ //check that user can access this page
151
+ if( is_object($EM_Ticket) && !$EM_Ticket->can_manage() ){
152
+ ?>
153
+ <div class="wrap"><h2><?php _e('Unauthorized Access','dbem'); ?></h2><p><?php _e('You do not have the rights to manage this ticket.','dbem'); ?></p></div>
154
+ <?php
155
+ return false;
156
+ }
157
+ ?>
158
+ <div class='wrap'>
159
+ <div id='icon-users' class='icon32'>
160
+ <br/>
161
+ </div>
162
+ <h2>
163
+ <?php echo sprintf(__('Ticket for %s', 'dbem'), "'{$EM_Event->name}'"); ?>
164
+ <a href="<?php echo $EM_Event->get_edit_url(); ?>" class="button add-new-h2"><?php _e('View/Edit Event','dbem') ?></a>
165
+ <a href="<?php echo $EM_Event->get_bookings_url(); ?>" class="button add-new-h2"><?php _e('View Event Bookings','dbem') ?></a>
166
+ </h2>
167
+ <?php echo $EM_Notices; ?>
168
+ <div>
169
+ <table>
170
+ <tr><td><?php echo __('Name','dbem'); ?></td><td></td><td><?php echo $EM_Ticket->ticket_name; ?></td></tr>
171
+ <tr><td><?php echo __('Description','dbem'); ?>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td><td></td><td><?php echo ($EM_Ticket->ticket_description) ? $EM_Ticket->ticket_description : '-'; ?></td></tr>
172
+ <tr><td><?php echo __('Price','dbem'); ?></td><td></td><td><?php echo ($EM_Ticket->ticket_price) ? $EM_Ticket->ticket_price : '-'; ?></td></tr>
173
+ <tr><td><?php echo __('Spaces','dbem'); ?></td><td></td><td><?php echo ($EM_Ticket->ticket_spaces) ? $EM_Ticket->ticket_spaces : '-'; ?></td></tr>
174
+ <tr><td><?php echo __('Min','dbem'); ?></td><td></td><td><?php echo ($EM_Ticket->ticket_min) ? $EM_Ticket->ticket_min : '-'; ?></td></tr>
175
+ <tr><td><?php echo __('Max','dbem'); ?></td><td></td><td><?php echo ($EM_Ticket->ticket_max) ? $EM_Ticket->ticket_max : '-'; ?></td></tr>
176
+ <tr><td><?php echo __('Start','dbem'); ?></td><td></td><td><?php echo ($EM_Ticket->ticket_start) ? $EM_Ticket->ticket_start : '-'; ?></td></tr>
177
+ <tr><td><?php echo __('End','dbem'); ?></td><td></td><td><?php echo ($EM_Ticket->ticket_end) ? $EM_Ticket->ticket_end : '-'; ?></td></tr>
178
+ <?php do_action('em_booking_admin_ticket_row', $EM_Ticket); ?>
179
+ </table>
180
+ </div>
181
+ <div class="icon32" id="icon-bookings"><br></div>
182
+ <h2><?php _e('Bookings','dbem'); ?></h2>
183
+ <?php
184
+ $EM_Bookings_Table = new EM_Bookings_Table();
185
+ $EM_Bookings_Table->status = get_option('dbem_bookings_approval') ? 'needs-attention':'confirmed';
186
+ $EM_Bookings_Table->output();
187
+ ?>
188
+ <?php do_action('em_bookings_ticket_footer', $EM_Ticket); ?>
189
+ </div>
190
+ <?php
191
+ }
192
+
193
+ /**
194
+ * Shows a single booking for a single person.
195
+ */
196
+ function em_bookings_single(){
197
+ global $EM_Booking, $EM_Notices;
198
+ //check that user can access this page
199
+ if( is_object($EM_Booking) && !$EM_Booking->can_manage() ){
200
+ ?>
201
+ <div class="wrap"><h2><?php _e('Unauthorized Access','dbem'); ?></h2><p><?php _e('You do not have the rights to manage this event.','dbem'); ?></p></div>
202
+ <?php
203
+ return false;
204
+ }
205
+ ?>
206
+ <div class='wrap' id="em-bookings-admin-booking">
207
+ <div class="icon32" id="icon-bookings"><br></div>
208
+ <h2>
209
+ <?php _e('Edit Booking', 'dbem'); ?>
210
+ </h2>
211
+ <?php echo $EM_Notices; ?>
212
+ <div id="poststuff" class="metabox-holder">
213
+ <div id="post-body">
214
+ <div id="post-body-content">
215
+ <div class="stuffbox">
216
+ <h3>
217
+ <?php _e ( 'Event Details', 'dbem' ); ?>
218
+ </h3>
219
+ <div class="inside">
220
+ <?php
221
+ $EM_Event = $EM_Booking->get_event();
222
+ $localised_start_date = date_i18n(get_option('dbem_date_format'), $EM_Event->start);
223
+ $localised_end_date = date_i18n(get_option('dbem_date_format'), $EM_Event->end);
224
+ ?>
225
+ <table>
226
+ <tr><td><strong><?php _e('Name','dbem'); ?></strong></td><td><a class="row-title" href="<?php echo $EM_Event->get_bookings_url(); ?>"><?php echo ($EM_Event->event_name); ?></a></td></tr>
227
+ <tr>
228
+ <td><strong><?php _e('Date/Time','dbem'); ?>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</strong></td>
229
+ <td>
230
+ <?php echo $localised_start_date; ?>
231
+ <?php echo ($localised_end_date != $localised_start_date) ? " - $localised_end_date":'' ?>
232
+ <?php echo substr ( $EM_Event->start_time, 0, 5 ) . " - " . substr ( $EM_Event->end_time, 0, 5 ); ?>
233
+ </td>
234
+ </tr>
235
+ </table>
236
+ <?php do_action('em_bookings_admin_booking_event', $EM_Event); ?>
237
+ </div>
238
+ </div>
239
+ <div class="stuffbox">
240
+ <h3>
241
+ <?php _e ( 'Personal Details', 'dbem' ); ?>
242
+ </h3>
243
+ <div class="inside">
244
+ <?php echo $EM_Booking->get_person()->display_summary(); ?>
245
+ <?php do_action('em_bookings_admin_booking_person', $EM_Booking); ?>
246
+ </div>
247
+ </div>
248
+ <div class="stuffbox">
249
+ <h3>
250
+ <?php _e ( 'Booking Details', 'dbem' ); ?>
251
+ </h3>
252
+ <div class="inside">
253
+ <?php
254
+ $EM_Event = $EM_Booking->get_event();
255
+ $localised_start_date = date_i18n(get_option('date_format'), $EM_Event->start);
256
+ $localised_end_date = date_i18n(get_option('date_format'), $EM_Event->end);
257
+ $shown_tickets = array();
258
+ ?>
259
+ <div>
260
+ <form action="" method="post" class="em-booking-single-status-info">
261
+ <strong><?php _e('Status','dbem'); ?> : </strong>
262
+ <?php echo $EM_Booking->get_status(); ?>
263
+ <input type="button" class="em-booking-submit-status-modify" id="em-booking-submit-status-modify" value="<?php _e('Change', 'dbem'); ?>" />
264
+ <input type="submit" class="em-booking-resend-email" id="em-booking-resend-email" value="<?php _e('Resend Email', 'dbem'); ?>" />
265
+ <input type='hidden' name='action' value='booking_resend_email'/>
266
+ <input type='hidden' name='booking_id' value='<?php echo $EM_Booking->booking_id; ?>'/>
267
+ <input type='hidden' name='event_id' value='<?php echo $EM_Event->event_id; ?>'/>
268
+ <input type='hidden' name='_wpnonce' value='<?php echo wp_create_nonce('booking_resend_email_'.$EM_Booking->booking_id); ?>'/>
269
+ </form>
270
+ <form action="" method="post" class="em-booking-single-status-edit">
271
+ <strong><?php _e('Status','dbem'); ?> : </strong>
272
+ <select name="booking_status">
273
+ <?php foreach($EM_Booking->status_array as $status => $status_name): ?>
274
+ <option value="<?php echo esc_attr($status); ?>" <?php if($status == $EM_Booking->booking_status){ echo 'selected="selected"'; } ?>><?php echo esc_html($status_name); ?></option>
275
+ <?php endforeach; ?>
276
+ </select>
277
+ <input type="checkbox" checked="checked" name="send_email" value="1" />
278
+ <?php _e('Send Email','dbem'); ?>
279
+ <input type="submit" class="em-booking-submit-status" id="em-booking-submit-status" value="<?php _e('Submit Changes', 'dbem'); ?>" />
280
+ <input type="button" class="em-booking-submit-status-cancel" id="em-booking-submit-status-cancel" value="<?php _e('Cancel', 'dbem'); ?>" />
281
+ <input type='hidden' name='action' value='booking_set_status'/>
282
+ <input type='hidden' name='booking_id' value='<?php echo $EM_Booking->booking_id; ?>'/>
283
+ <input type='hidden' name='event_id' value='<?php echo $EM_Event->event_id; ?>'/>
284
+ <input type='hidden' name='_wpnonce' value='<?php echo wp_create_nonce('booking_set_status_'.$EM_Booking->booking_id); ?>'/>
285
+ </form>
286
+ </div>
287
+ <form action="" method="post">
288
+ <table class="em-tickets-bookings-table" cellspacing="0" cellpadding="0">
289
+ <thead>
290
+ <tr>
291
+ <th><?php _e('Ticket Type','dbem'); ?></th>
292
+ <th><?php _e('Spaces','dbem'); ?></th>
293
+ <th><?php _e('Price','dbem'); ?></th>
294
+ </tr>
295
+ </thead>
296
+ <tbody>
297
+ <?php foreach($EM_Booking->get_tickets_bookings()->tickets_bookings as $EM_Ticket_Booking): ?>
298
+ <tr>
299
+ <td class="ticket-type"><a class="row-title" href="<?php echo em_add_get_params($EM_Event->get_bookings_url(), array('ticket_id'=>$EM_Ticket_Booking->get_ticket()->ticket_id)); ?>"><?php echo $EM_Ticket_Booking->get_ticket()->ticket_name ?></a></td>
300
+ <td>
301
+ <span class="em-booking-single-info"><?php echo $EM_Ticket_Booking->get_spaces(); ?></span>
302
+ <div class="em-booking-single-edit"><input name="em_tickets[<?php echo $EM_Ticket_Booking->get_ticket()->ticket_id; ?>][spaces]" class="em-ticket-select" value="<?php echo $EM_Ticket_Booking->get_spaces(); ?>" /></div>
303
+ </td>
304
+ <td><?php echo $EM_Ticket_Booking->get_price(true,true); ?></td>
305
+ </tr>
306
+ <?php $shown_tickets[] = $EM_Ticket_Booking->ticket_id; ?>
307
+ <?php endforeach; ?>
308
+ <?php if( count($shown_tickets) < count($EM_Event->get_bookings()->get_tickets()->tickets)): ?><tr>
309
+ <?php foreach($EM_Event->get_bookings()->get_tickets()->tickets as $EM_Ticket): ?>
310
+ <?php if( !in_array($EM_Ticket->ticket_id, $shown_tickets) ): ?>
311
+ <tr>
312
+ <td class="ticket-type"><a class="row-title" href="<?php echo em_add_get_params($EM_Event->get_bookings_url(), array('ticket_id'=>$EM_Ticket_Booking->get_ticket()->ticket_id)); ?>"><?php echo $EM_Ticket->ticket_name ?></a></td>
313
+ <td>
314
+ <span class="em-booking-single-info">0</span>
315
+ <div class="em-booking-single-edit"><input name="em_tickets[<?php echo $EM_Ticket->ticket_id; ?>][spaces]" class="em-ticket-select" value="0" /></div>
316
+ </td>
317
+ <td><?php echo em_get_currency_symbol() ?>0.00</td>
318
+ </tr>
319
+ <?php endif; ?>
320
+ <?php endforeach; ?>
321
+ <?php endif; ?>
322
+ </tbody>
323
+ <tfoot>
324
+ <?php do_action('em_bookings_admin_ticket_totals_header'); ?>
325
+ <tr>
326
+ <th><?php _e('Total Price','dbem'); ?></th>
327
+ <th><?php echo sprintf(__('%d Spaces','dbem'), $EM_Booking->get_spaces()); ?></th>
328
+ <th><?php echo $EM_Booking->get_price(true, true); ?></th>
329
+ </tr>
330
+ <?php if( !get_option('dbem_bookings_tax_auto_add') && is_numeric(get_option('dbem_bookings_tax')) && get_option('dbem_bookings_tax') > 0 ): ?>
331
+ <tr>
332
+ <th><?php _e('Tax','dbem'); ?></th>
333
+ <th><?php echo get_option('dbem_bookings_tax') ?>%</th>
334
+ <th><?php echo em_get_currency_formatted($EM_Booking->get_price() * (get_option('dbem_bookings_tax')/100),2); ?></th>
335
+ </tr>
336
+ <tr>
337
+ <th><?php _e('Total Price (inc. tax)','dbem'); ?></th>
338
+ <th>&nbsp;</th>
339
+ <th><?php echo $EM_Booking->get_price(false, true, true); ?></th>
340
+ </tr>
341
+ <?php endif; ?>
342
+ <?php do_action('em_bookings_admin_ticket_totals_footer'); ?>
343
+ </tfoot>
344
+ </table>
345
+ <table cellspacing="0" cellpadding="0">
346
+ <?php if( !has_action('em_bookings_single_custom') ): //default behaviour ?>
347
+ <tr>
348
+ <td>
349
+ <strong><?php _e('Comment','dbem'); ?>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</strong>
350
+ </td>
351
+ <td>
352
+ <span class="em-booking-single-info"><?php echo $EM_Booking->booking_comment; ?></span>
353
+ <div class="em-booking-single-edit"><textarea name="booking_comment"><?php echo $EM_Booking->booking_comment; ?></textarea></div>
354
+ </td>
355
+ </tr>
356
+ <?php else: do_action('em_bookings_single_custom',$EM_Booking); //do your own thing, e.g. pro ?>
357
+ <?php endif; ?>
358
+ </table>
359
+ <p class="em-booking-single-info">
360
+ <input type="button" class="em-booking-submit-modify" id="em-booking-submit-modify" value="<?php _e('Modify Booking', 'dbem'); ?>" />
361
+ </p>
362
+ <p class="em-booking-single-edit">
363
+ <em><?php _e('<strong>Notes:</strong> Ticket availability not taken into account (i.e. you can overbook). Emails are not resent automatically.','dbem'); ?></em>
364
+ <br /><br />
365
+ <input type="submit" class="em-booking-submit" id="em-booking-submit" value="<?php _e('Submit Changes', 'dbem'); ?>" />
366
+ <input type="button" class="em-booking-submit-cancel" id="em-booking-submit-cancel" value="<?php _e('Cancel', 'dbem'); ?>" />
367
+ <input type='hidden' name='action' value='booking_save'/>
368
+ <input type='hidden' name='booking_id' value='<?php echo $EM_Booking->booking_id; ?>'/>
369
+ <input type='hidden' name='event_id' value='<?php echo $EM_Event->event_id; ?>'/>
370
+ <input type='hidden' name='_wpnonce' value='<?php echo wp_create_nonce('booking_save_'.$EM_Booking->booking_id); ?>'/>
371
+ </p>
372
+ </form>
373
+ <script type="text/javascript">
374
+ jQuery(document).ready( function($){
375
+ $('#em-booking-submit-modify').click(function(){
376
+ $('.em-booking-single-info').hide();
377
+ $('.em-booking-single-edit').show();
378
+ });
379
+ $('#em-booking-submit-cancel').click(function(){
380
+ $('.em-booking-single-info').show();
381
+ $('.em-booking-single-edit').hide();
382
+ });
383
+ $('.em-booking-single-info').show();
384
+ $('.em-booking-single-edit').hide();
385
+
386
+ $('#em-booking-submit-status-modify').click(function(){
387
+ $('.em-booking-single-status-info').hide();
388
+ $('.em-booking-single-status-edit').show();
389
+ });
390
+ $('#em-booking-submit-status-cancel').click(function(){
391
+ $('.em-booking-single-status-info').show();
392
+ $('.em-booking-single-status-edit').hide();
393
+ });
394
+ $('.em-booking-single-status-info').show();
395
+ $('.em-booking-single-status-edit').hide();
396
+ });
397
+ </script>
398
+ </div>
399
+ </div>
400
+ <div id="em-booking-notes" class="stuffbox">
401
+ <h3>
402
+ <?php _e ( 'Booking Notes', 'dbem' ); ?>
403
+ </h3>
404
+ <div class="inside">
405
+ <p><?php _e('You can add private notes below for internal reference that only event managers will see.','dbem'); ?></p>
406
+ <?php foreach( $EM_Booking->get_notes() as $note ):
407
+ $user = new EM_Person($note['author']);
408
+ ?>
409
+ <div>
410
+ <?php echo date(get_option('date_format'), $note['timestamp']) .' - '. $user->get_name(); ?> <?php _e('wrote','dbem'); ?>:
411
+ <p style="background:#efefef; padding:5px;"><?php echo nl2br($note['note']); ?></p>
412
+ </div>
413
+ <?php endforeach; ?>
414
+ <form method="post" action="" style="padding:5px;">
415
+ <textarea class="widefat" rows="5" name="booking_note"></textarea>
416
+ <input type="hidden" name="action" value="bookings_add_note" />
417
+ <input type="submit" value="Add Note" />
418
+ </form>
419
+ </div>
420
+ </div>
421
+ <?php do_action('em_bookings_single_metabox_footer', $EM_Booking); ?>
422
+ </div>
423
+ </div>
424
+ </div>
425
+ <br style="clear:both;" />
426
+ <?php do_action('em_bookings_single_footer', $EM_Booking); ?>
427
+ </div>
428
+ <?php
429
+
430
+ }
431
+
432
+ /**
433
+ * Shows all bookings made by one person.
434
+ */
435
+ function em_bookings_person(){
436
+ global $EM_Person, $EM_Notices;
437
+ $EM_Person->get_bookings();
438
+ $has_booking = false;
439
+ foreach($EM_Person->get_bookings() as $EM_Booking){
440
+ if($EM_Booking->can_manage('manage_bookings','manage_others_bookings')){
441
+ $has_booking = true;
442
+ }
443
+ }
444
+ if( !$has_booking ){
445
+ ?>
446
+ <div class="wrap"><h2><?php _e('Unauthorized Access','dbem'); ?></h2><p><?php _e('You do not have the rights to manage this event.','dbem'); ?></p></div>
447
+ <?php
448
+ return false;
449
+ }
450
+ ?>
451
+ <div class='wrap'>
452
+ <div id='icon-users' class='icon32'>
453
+ <br/>
454
+ </div>
455
+ <h2>
456
+ <?php _e('Manage Person\'s Booking', 'dbem'); ?>
457
+ <?php if( current_user_can('edit_users') ) : ?>
458
+ <a href="<?php admin_url('user-edit.php?user_id='.$EM_Person->ID); ?>" class="button add-new-h2"><?php _e('Edit User','dbem') ?></a>
459
+ <?php endif; ?>
460
+ </h2>
461
+ <?php echo $EM_Notices; ?>
462
+ <?php do_action('em_bookings_person_header'); ?>
463
+ <div id="poststuff" class="metabox-holder has-right-sidebar">
464
+ <div id="post-body">
465
+ <div id="post-body-content">
466
+ <div id="event_name" class="stuffbox">
467
+ <h3>
468
+ <?php _e ( 'Personal Details', 'dbem' ); ?>
469
+ </h3>
470
+ <div class="inside">
471
+ <?php echo $EM_Person->display_summary(); ?>
472
+ </div>
473
+ </div>
474
+ </div>
475
+ </div>
476
+ </div>
477
+ <br style="clear:both;" />
478
+ <?php do_action('em_bookings_person_body_1'); ?>
479
+ <div class="icon32" id="icon-bookings"><br></div>
480
+ <h2><?php _e('Past And Present Bookings','dbem'); ?></h2>
481
+ <?php
482
+ $EM_Bookings_Table = new EM_Bookings_Table();
483
+ $EM_Bookings_Table->status = 'all';
484
+ $EM_Bookings_Table->scope = 'all';
485
+ $EM_Bookings_Table->output();
486
+ ?>
487
+ <?php do_action('em_bookings_person_footer', $EM_Person); ?>
488
+ </div>
489
+ <?php
490
+ }
491
+
492
+ function em_printable_booking_report() {
493
+ global $EM_Event;
494
+ //check that user can access this page
495
+ if( isset($_GET['page']) && $_GET['page']=='events-manager-bookings' && isset($_GET['action']) && $_GET['action'] == 'bookings_report' && is_object($EM_Event)){
496
+ if( is_object($EM_Event) && !$EM_Event->can_manage('edit_events','edit_others_events') ){
497
+ ?>
498
+ <div class="wrap"><h2><?php _e('Unauthorized Access','dbem'); ?></h2><p><?php _e('You do not have the rights to manage this event.','dbem'); ?></p></div>
499
+ <?php
500
+ return false;
501
+ }
502
+ em_locate_template('templates/bookings-event-printable.php', true);
503
+ die();
504
+ }
505
+ }
506
+ add_action('admin_init', 'em_printable_booking_report');
507
  ?>
admin/em-categories.php DELETED
@@ -1,177 +0,0 @@
1
- <?php
2
- function em_admin_categories_page() {
3
- global $wpdb, $EM_Category;
4
-
5
- if( !empty($_REQUEST['action']) ){
6
- if( $_REQUEST['action'] == "save") {
7
- // save (add/update) category
8
- if( empty($EM_Category) || !is_object($EM_Category) ){
9
- $EM_Category = new EM_Category(); //blank category
10
- $success_message = __('The category has been added.', 'dbem');
11
- }else{
12
- $success_message = __('The category has been updated.', 'dbem');
13
- }
14
- $EM_Category->get_post();
15
- if ( $EM_Category->validate() ) {
16
- $EM_Category->save(); //FIXME better handling of db write fails when saving category
17
- em_categories_table_layout($success_message);
18
- } else {
19
- ?>
20
- <div id='message' class='error '>
21
- <p>
22
- <strong><?php _e( "Ach, there's a problem here:", "dbem" ) ?></strong><br /><br /><?php echo implode('<br />', $EM_Category->errors); ?>
23
- </p>
24
- </div>
25
- <?php
26
- em_categories_edit_layout();
27
- }
28
- } elseif( $_REQUEST['action'] == "edit" ){
29
- em_categories_edit_layout();
30
- } elseif( $_REQUEST['action'] == "delete" ){
31
- //delelte category
32
- EM_Categories::delete($_REQUEST['categories']);
33
- //FIXME no result verification when deleting various categories
34
- $message = __('Categories Deleted', "dbem" );
35
- em_categories_table_layout($message);
36
- }
37
- }else{
38
- em_categories_table_layout($message);
39
- }
40
- }
41
-
42
- function em_categories_table_layout($message = "") {
43
- $categories = EM_Categories::get();
44
- $destination = get_bloginfo('url')."/wp-admin/admin.php";
45
- ?>
46
- <div class='wrap nosubsub'>
47
- <div id='icon-edit' class='icon32'>
48
- <br/>
49
- </div>
50
- <h2><?php echo __('Categories', 'dbem') ?></h2>
51
-
52
- <?php if($message != "") : ?>
53
- <div id='message' class='updated fade below-h2' style='background-color: rgb(255, 251, 204);'>
54
- <p><?php echo $message ?></p>
55
- </div>
56
- <?php endif; ?>
57
-
58
- <div id='col-container'>
59
- <!-- begin col-right -->
60
- <div id='col-right'>
61
- <div class='col-wrap'>
62
- <form id='bookings-filter' method='post' action='<?php echo get_bloginfo('wpurl') ?>/wp-admin/admin.php?page=events-manager-categories'>
63
- <input type='hidden' name='action' value='delete'/>
64
- <?php if (count($categories)>0) : ?>
65
- <table class='widefat'>
66
- <thead>
67
- <tr>
68
- <th class='manage-column column-cb check-column' scope='col'><input type='checkbox' class='select-all' value='1'/></th>
69
- <th><?php echo __('ID', 'dbem') ?></th>
70
- <th><?php echo __('Name', 'dbem') ?></th>
71
- </tr>
72
- </thead>
73
- <tfoot>
74
- <tr>
75
- <th class='manage-column column-cb check-column' scope='col'><input type='checkbox' class='select-all' value='1'/></th>
76
- <th><?php echo __('ID', 'dbem') ?></th>
77
- <th><?php echo __('Name', 'dbem') ?></th>
78
- </tr>
79
- </tfoot>
80
- <tbody>
81
- <?php foreach ($categories as $EM_Category) : ?>
82
- <tr>
83
- <td><input type='checkbox' class ='row-selector' value='<?php echo $EM_Category->id ?>' name='categories[]'/></td>
84
- <td><a href='<?php echo get_bloginfo('wpurl') ?>/wp-admin/admin.php?page=events-manager-categories&amp;action=edit&amp;category_id=<?php echo $EM_Category->id ?>'><?php echo htmlspecialchars($EM_Category->id, ENT_QUOTES); ?></a></td>
85
- <td><a href='<?php echo get_bloginfo('wpurl') ?>/wp-admin/admin.php?page=events-manager-categories&amp;action=edit&amp;category_id=<?php echo $EM_Category->id ?>'><?php echo htmlspecialchars($EM_Category->name, ENT_QUOTES); ?></a></td>
86
- </tr>
87
- <?php endforeach; ?>
88
- </tbody>
89
-
90
- </table>
91
-
92
- <div class='tablenav'>
93
- <div class='alignleft actions'>
94
- <input class='button-secondary action' type='submit' name='doaction2' value='Delete'/>
95
- <br class='clear'/>
96
- </div>
97
- <br class='clear'/>
98
- </div>
99
- <?php else: ?>
100
- <p><?php echo __('No categories have been inserted yet!', 'dbem'); ?></p>
101
- <?php endif; ?>
102
- </form>
103
- </div>
104
- </div>
105
- <!-- end col-right -->
106
-
107
- <!-- begin col-left -->
108
- <div id='col-left'>
109
- <div class='col-wrap'>
110
- <div class='form-wrap'>
111
- <div id='ajax-response'>
112
- <h3><?php echo __('Add category', 'dbem') ?></h3>
113
- <form name='add' id='add' method='post' action='admin.php?page=events-manager-categories' class='add:the-list: validate'>
114
- <input type='hidden' name='action' value='save' />
115
- <div class='form-field form-required'>
116
- <label for='category_name'><?php echo __('Category name', 'dbem') ?></label>
117
- <input id='category-name' name='category_name' id='category_name' type='text' size='40' />
118
- <p><?php echo __('The name of the category', 'dbem'); ?></p>
119
- </div>
120
- <p class='submit'><input type='submit' class='button' name='submit' value='<?php echo __('Add category', 'dbem') ?>' /></p>
121
- </form>
122
- </div>
123
- </div>
124
- </div>
125
- </div>
126
- <!-- end col-left -->
127
- </div>
128
- </div>
129
- <?php
130
- }
131
-
132
-
133
- function em_categories_edit_layout($message = "") {
134
- global $EM_Category;
135
- if( !is_object($EM_Category) ){
136
- $EM_Category = new EM_Category();
137
- }
138
- //check that user can access this page
139
- if( is_object($EM_Category) && !$EM_Category->can_manage() ){
140
- ?>
141
- <div class="wrap"><h2><?php _e('Unauthorized Access','dbem'); ?></h2><p><?php _e('You do not have the rights to manage this event.','dbem'); ?></p></div>
142
- <?php
143
- return;
144
- }
145
- ?>
146
- <div class='wrap'>
147
- <div id='icon-edit' class='icon32'>
148
- <br/>
149
- </div>
150
-
151
- <h2><?php echo __('Edit category', 'dbem') ?></h2>
152
-
153
- <?php if($message != "") : ?>
154
- <div id='message' class='updated fade below-h2' style='background-color: rgb(255, 251, 204);'>
155
- <p><?php echo $message ?></p>
156
- </div>
157
- <?php endif; ?>
158
-
159
- <div id='ajax-response'></div>
160
-
161
- <form name='editcat' id='editcat' method='post' action='admin.php?page=events-manager-categories' class='validate'>
162
- <input type='hidden' name='action' value='save' />
163
- <input type='hidden' name='category_id' value='<?php echo $EM_Category->id ?>'/>
164
-
165
- <table class='form-table'>
166
- <tr class='form-field form-required'>
167
- <th scope='row' valign='top'><label for='category_name'><?php echo __('Category name', 'dbem') ?></label></th>
168
- <td><input name='category_name' id='category-name' type='text' value='<?php echo $EM_Category->name ?>' size='40' /><br />
169
- <?php echo __('The name of the category', 'dbem') ?></td>
170
- </tr>
171
- </table>
172
- <p class='submit'><input type='submit' class='button-primary' name='submit' value='<?php echo __('Update category', 'dbem') ?>' /></p>
173
- </form>
174
- </div>
175
- <?php
176
- }
177
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/em-docs.php CHANGED
@@ -1,193 +1,319 @@
1
- <?php
2
-
3
- function em_docs_init(){
4
- if( class_exists('EM_Event') ){
5
- add_action('wp_head', 'emd_head');
6
- //Generate the docs
7
- global $EM_Documentation;
8
- $EM_Event = new EM_Event();
9
- $event_fields = $EM_Event->get_fields(true);
10
- $EM_Location = new EM_Location();
11
- $location_fields = $EM_Location->get_fields(true);
12
- $EM_Documentation = array(
13
- 'arguments' => array(
14
- 'events' => array(
15
- 'limit' => array( 'default'=>'See the events lists limit option on the settings page.' ),
16
- 'orderby' => array( 'desc'=>'Choose what fields to order your results by. You can supply a single field or multiple comma-seperated fields (e.g. "start_date,name").', 'default'=>'See the event lists ordering option on the settings page.', 'args'=>'name, start_date, start_time, end_date, end_time'),
17
- 'order' => array( 'default'=>'See the event lists ordering option on the settings page.' )
18
- ),
19
- 'locations' => array(
20
- 'eventful' => array( 'desc'=>'If set to 1 will only show locations that have at least one event occurring during the scope.', 'default' => 0),
21
- 'eventless' => array( 'desc'=>'If set to 1 will only show locations that have no events occurring during the scope.', 'default' => 0),
22
- 'orderby' => array('desc'=>'Choose what fields to order your results by. You can supply a single field or multiple comma-seperated fields (e.g. "start_date,name").', 'default'=>'name', 'args' => 'name, address, town'),
23
- 'scope' => array( 'default' => 'all')
24
- ),
25
- 'calendar' => array(
26
- 'full' => array( 'desc'=>'If set to 1 it will display a full calendar that shows event names.', 'default' => 0),
27
- 'long_events' => array( 'desc'=>'If set to 1, will show events that last longer than a day.', 'default' => 0),
28
- 'order' => array( 'desc'=>'Same as for events.' ),
29
- 'scope' => array( 'default' => 'future')
30
- ),
31
- //The object is commonly shared by all, so entries above overwrite entries here
32
- 'general' => array(
33
- 'limit' => array( 'desc'=>'Limits the amount of values returned to this number.', 'default'=>'0 (no limit)'),
34
- 'scope' => array( 'desc'=>'Choose the time frame of events to show. Accepted values are "future", "past" or "all" events. Additionally you can supply dates (in format of YYYY-MM-DD), either single for events on a specific date or two dates seperated by a comma (e.g. 2010-12-25,2010-12-31) for events ocurring between these dates.', 'default'=>'future'),
35
- 'order' => array( 'desc'=>'Indicates the order of the events. Choose between ASC (ascending) and DESC (descending).', 'default'=>'ASC'),
36
- 'orderby' => array( 'desc'=>'Choose what fields to order your results by. You can supply a single field or multiple comma-seperated fields (e.g. "start_date,name"). See specific instances (e.g. events, locations, etc.) for field names.', 'default'=>0),
37
- 'format' => array( 'desc'=>'If you are displaying some information with the shortcode or function (e.g. listing events), you can supply the html and placeholders here.', 'default'=>'The relevant default format will be taken from the settings page.'),
38
- 'event' => array( 'desc'=>'Supply a single id or comma-seperated ids (e.g. "1,2,3") to limit the search to events with these id(s).', 'default'=>0),
39
- 'category' => array( 'desc'=>'Supply a single id or comma-seperated ids (e.g. "1,2,3") to limit the search to events in these categories.', 'default'=>0),
40
- 'location' => array( 'desc'=>'Supply a single id or comma-seperated ids to limit the search to these locations (or events in these locations).', 'default'=>0),
41
- 'offset' => array( 'desc'=>'For example, if you have ten results, if you set this to 5, only the last 5 results will be returned. Useful for pagination.', 'default'=>0),
42
- 'recurrence' => array( 'desc'=>'If set to 1, will show only events that are recurring (i.e. events that are repeated over different dates).', 'default'=>0),
43
- 'recurring' => array( 'desc'=>'If set to 1, will only show recurring event templates. Only useful if you know what you\'re doing, use recurrence if you want events that are recurrences.', 'default'=>0),
44
- 'month' => array( 'desc'=>'If set to a month (1 to 12) only events that start or end during this month/year will be retured. Must be used in conjunction with year', 'default'=>''),
45
- 'year' => array( 'desc'=>'If set to a year (e.g. 2010) only events that start or end during this year/month will be returned. Must be used in conjunction with year', 'default'=>''),
46
- 'array' => array( 'desc'=>'If you supply this as an argument, the returned data will be in an array, no objects (only useful wen using PHP, not shortcodes)', 'default'=>0),
47
- 'pagination' => array('desc'=>'When using a function or shortcode that outputs items (e.g. [events_list] for events, [locations_list] for locations), if the number of items supercede the limit of items to show, setting this to 1 will show page links under the list.', 'default'=>0)
48
- )
49
- ),
50
- 'placeholders' => array(
51
- 'events' => array(
52
- 'Event Details' => array(
53
- 'placeholders' => array(
54
- '#_NAME' => array( 'desc' => 'Displays the name of the event.' ),
55
- '#_NOTES' => array( 'desc' => 'Shows the description of the event.' ),
56
- '#_EXCERPT' => array( 'desc' => 'If you added a <a href="http://en.support.wordpress.com/splitting-content/more-tag/">more tag</a> to your event description, only the content before this tag will show (currently, no read more link is added).' ),
57
- '#_EVENTID' => array( 'desc' => 'Shows the event\'s corresponding ID number in the database table.' )
58
- )
59
- ),
60
- 'Category Details' => array(
61
- 'placeholders' => array(
62
- '#_CATEGORYNAME' => array( 'desc' => 'Shows the category name of the event.' ),
63
- '#_CATEGORYID' => array( 'desc' => 'Shows the category ID of the event.' )
64
- )
65
- ),
66
- 'Time' => array(
67
- 'desc' => '',
68
- 'placeholders' => array(
69
- '#_24HSTARTTIME' => array( 'desc' => 'Displays the start time in a 24 hours format (e.g. 16:30).' ),
70
- '#_24HENDTIME' => array( 'desc' => 'Displays the end time in a 24 hours format (e.g. 18:30).' ),
71
- '#_12HSTARTTIME' => array( 'desc' => 'Displays the start time in a 12 hours format (e.g. 4:30 PM).' ),
72
- '#_12HENDTIME' => array( 'desc' => 'Displays the end time in a 12 hours format (e.g. 6:30 PM).' )
73
- )
74
- ),
75
- 'Custom Date/Time Formatting' => array(
76
- 'desc' => 'Events Manager allows extremely flexible date formatting by using <a href="http://www.php.net/manual/en/function.date.php">PHP date syntax format characters</a> along with placeholders.',
77
- 'placeholders' => array(
78
- '# or #@' => array( 'desc' => 'Prepend <code>#</code> or <code>#@</code> before a valid PHP date syntax format character to show start and end date/time information respectively (e.g. <code>#F</code> will show the starting month name like "January", #@h shows the end hour).' ),
79
- '#{x} or #@{x}' => array( 'desc' => 'You can also create a date format without prepending # to each character by wrapping a valid php date() format in <code>#{}</code> or <code>#@{}</code> (e.g. <code>#_{d/m/Y}</code>). If there is no end date (or is same as start date), the value is not shown. This is useful if you want to show event end dates only on events that are longer than on day, e.g. <code>#j #M #Y #@_{ \u\n\t\i\l j M Y}</code>.' ),
80
- )
81
- ),
82
- 'Links' => array(
83
- 'placeholders' => array(
84
- '#_EVENTURL' => array( 'desc' => 'Simply prints the event URL. You can use this placeholder to build your own customised links.' ),
85
- '#_EVENTLINK' => array( 'desc' => 'Displays the event name with a link to the event page.' ),
86
- '#_EDITEVENTLINK' => array( 'desc' => 'Inserts a link to the edit event page, only if a user is logged in and is allowed to edit the event.' )
87
- )
88
- ),
89
- 'Custom Attributes' => array(
90
- 'desc' => 'Events Manager allows you to create dynamic attributes to your events, which act as extra information fields for your events (e.g. "Dress Code"). For more information see <a href="http://wp-events-plugin.com/documentation/categories-and-attributes/">our online documentation</a> for more info on attributes.',
91
- 'placeholders' => array(
92
- '#_ATT{key}{alternative text}' => array('desc'=>'This key will appear as an option when adding attributes to your event. The second braces are optional and will appear if the attribute is not defined or left blank for that event.')
93
- )
94
- ),
95
- 'Bookings/RSVP' => array(
96
- 'desc' => 'These placeholders will only show if RSVP is enabled for the given event and in the events manager settings page. Spaces placeholders will default to 0',
97
- 'placeholders' => array(
98
- '#_ADDBOOKINGFORM' => array( 'desc' => 'Adds a form which allows the visitors to register for an event.' ),
99
- '#_REMOVEBOOKINGFORM' => array( 'desc' => 'Adds a form which allows the visitors to remove their booking.' ),
100
- '#_BOOKINGFORM' => array( 'desc' => 'Adds a both booking forms (add and remove).' ),
101
- '#_AVAILABLESPACES' => array( 'desc' => 'Shows available spaces for the event.' ),
102
- '#_BOOKEDSPACES' => array( 'desc' => 'Shows the amount of currently booked seats for the event.' ),
103
- '#_SPACES' => array( 'desc' => 'Shows the total spaces for the event.' )
104
- )
105
- ),
106
- 'Contact Details' => array(
107
- 'desc' => 'The values here are taken from the chosen contact for the specific event, or the default contact in the settings page.',
108
- 'placeholders' => array(
109
- '#_CONTACTNAME' => array( 'desc' => 'Name of the contact person for this event (as shown in the dropdown when adding an event).' ),
110
- '#_CONTACTUSERNAME' => array( 'desc' => 'Contact person\'s username.' ),
111
- '#_CONTACTEMAIL' => array( 'desc' => 'E-mail of the contact person for this event.' ),
112
- '#_CONTACTPHONE' => array( 'desc' => 'Phone number of the contact person for this event. Can be set in the user profile page.' ),
113
- '#_CONTACTAVATAR' => array( 'desc' => 'Contact person\'s avatar.' ),
114
- '#_CONTACTPROFILELINK' => array( 'desc' => 'Contact person\'s "Profile" link. Only works with BuddyPress enabled.' ),
115
- '#_CONTACTPROFILEURL' => array( 'desc' => 'Contact person\'s profile url. Only works with BuddyPress enabled.' ),
116
- '#_CONTACTID' => array( 'desc' => 'Contact person\'s wordpress user ID.')
117
- )
118
- ),
119
- ),
120
- 'locations' => array(
121
- 'Location Details' => array(
122
- 'desc' => '',
123
- 'placeholders' => array(
124
- '#_LOCATIONNAME' => array( 'desc' => 'Displays the location name.' ),
125
- '#_LOCATIONADDRESS' => array( 'desc' => 'Displays the address.' ),
126
- '#_LOCATIONTOWN' => array( 'desc' => 'Displays the town.' ),
127
- '#_LOCATIONMAP' => array( 'desc' => 'Displays a google map showing where the event is located (Will not show if maps are disabled in the settings page)' ),
128
- '#_LOCATIONNOTES' => array( 'desc' => 'Shows the location description.' ),
129
- '#_LOCATIONEXCERPT' => array( 'desc' => 'If you added a <a href="http://en.support.wordpress.com/splitting-content/more-tag/">more tag</a> to your location description, only the content before this tag will show (currently, no read more link is added).' ),
130
- '#_LOCATIONIMAGE' => array( 'desc' => 'Shows the location image.' ),
131
- '#_LOCATIONID' => array( 'desc' => 'Displays the location ID number.' )
132
- )
133
- ),
134
- 'Links' => array(
135
- 'placeholders' => array(
136
- '#_LOCATIONURL' => array( 'desc' => 'Simply prints the location URL. You can use this placeholder to build your own customised links.' ),
137
- '#_LOCATIONLINK' => array( 'desc' => 'Displays the location name with a link to the location page.' )
138
- )
139
- ),
140
- 'Related Events' => array(
141
- 'desc' => 'You can show lists of other events that are being held at this location. The formatting of the list is the same as a normal events list.',
142
- 'placeholders' => array(
143
- '#_LOCATIONPASTEVENTS' => array( 'desc' => 'Will show a list of all past events at this location.' ),
144
- '#_LOCATIONNEXTEVENTS' => array( 'desc' => 'Will show a list of all future events at this location.' ),
145
- '#_LOCATIONALLEVENTS' => array( 'desc' => 'Will show a list of all events at this location.' )
146
- )
147
- ),
148
- ),
149
- 'bookings' => array(
150
- 'Booking Person Information' => array(
151
- 'desc' => 'When a specific booking is displayed (on screen and on email), you can use these placeholders to show specific information about the booking. For contact details of the contact of this event, see the events placeholders.',
152
- 'placeholders' => array(
153
- '#_BOOKINGNAME' => array( 'desc' => 'Name of person who made the booking.' ),
154
- '#_BOOKINGEMAIL' => array( 'desc' => 'Email of person who made the booking.' ),
155
- '#_BOOKINGPHONE' => array( 'desc' => 'Phone number of person who made the booking.' ),
156
- '#_BOOKINGSPACES' => array( 'desc' => 'Number of spaces the person has booked.' ),
157
- '#_BOOKINGCOMMENT' => array( 'desc' => 'Any specific comments made by the person who made the booking.' )
158
- )
159
- )
160
- ),
161
- )
162
- );
163
- }
164
- }
165
- add_action('init', 'em_docs_init');
166
-
167
- function em_docs_placeholders($atts){
168
- ob_start();
169
- ?>
170
- <div class="em-docs">
171
- <?php
172
- global $EM_Documentation;
173
- $type = $atts['type'];
174
- $data = $EM_Documentation['placeholders'][$type];
175
- foreach($data as $sectionTitle => $details) : ?>
176
- <div>
177
- <h3><?php echo $sectionTitle; ?></h3>
178
- <?php if($details['desc'] != ''): ?>
179
- <p><?php echo $details['desc']; ?></p>
180
- <?php endif; ?>
181
- <dl>
182
- <?php foreach($details['placeholders'] as $placeholder => $desc ): ?>
183
- <dt><b><?php echo $placeholder; ?></b></dt>
184
- <dd><?php echo $desc['desc']; ?></dd>
185
- <?php endforeach; ?>
186
- </dl>
187
- </div>
188
- <?php endforeach; ?>
189
- </div>
190
- <?php
191
- return ob_get_clean();
192
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
193
  ?>
1
+ <?php
2
+
3
+ function em_docs_init($force_init = false){
4
+ global $pagenow;
5
+ if( ($pagenow == 'edit.php' && !empty($_GET['page']) && $_GET['page']=='events-manager-help' && class_exists('EM_Event')) || $force_init){
6
+ add_action('wp_head', 'emd_head');
7
+ //Generate the docs
8
+ global $EM_Documentation;
9
+ $EM_Event = new EM_Event();
10
+ $event_fields = $EM_Event->get_fields(true);
11
+ $EM_Location = new EM_Location();
12
+ $location_fields = $EM_Location->get_fields(true);
13
+ $EM_Documentation = array(
14
+ 'arguments' => array(
15
+ 'events' => array(
16
+ 'blog' => array( 'desc' => sprintf('Limit search to %s created in a specific blog id (MultiSite only)','events')),
17
+ 'bookings' => array( 'desc'=> 'Include only events with bookings enabled. Use \'user\' to show events a logged in user has booked.'.'1 = yes, 0 = no'),
18
+ 'category' => array( 'desc'=> sprintf('Supply a single id or comma-seperated ids (e.g. "1,2,3") to limit the search to events in these %s. You can also use negative numbers to exclude specific categories (e.g. -1,-2,-3).','categories'), 'default'=>0),
19
+ 'tag' => array( 'desc'=> sprintf('Supply a single id or comma-seperated ids (e.g. "music,theatre,sport") to limit the search to events in these %s.','tags'), 'default'=>0),
20
+ 'event' => array( 'desc'=> sprintf('Supply a single id or comma-seperated ids (e.g. "1,2,3") to limit the search to %s with the %s.','events', 'event_id(s)'), 'default'=>0),
21
+ 'group' => array( 'desc' => 'Limit search to events belonging to a specific group id (BuddyPress only). Using \'my\' will show events belonging to groups the logged in user is a member of.'),
22
+ 'post_id' => array( 'desc' => sprintf('Supply a single id or comma-seperated ids (e.g. "1,2,3") to limit the search to %s with the %s.','events', 'post_id(s)')),
23
+ 'private' => array( 'desc' => sprintf('Display private %s within your list?','events'), 'args' => '1 = yes, 0 = no', 'default' => 'If user can view private events, 1, otherwise 0.'),
24
+ 'private_only' => array( 'desc' =>sprintf('Display only private %s ?','events'), 'args' => '1 = yes, 0 = no', 'default' => '0'),
25
+ 'recurrence' => array( 'desc'=> 'If set to the event id of the recurring event, this will show only events this event recurrences.', 'default'=>0),
26
+ 'recurring' => array( 'desc'=> 'If set to 1, will only show recurring event templates. Only useful if you know what you\'re doing, use recurrence if you want events that are recurrences.', 'default'=>0),
27
+ 'search' => array( 'desc'=> 'Do a search for this string within event name, details and location address.' ),
28
+ 'status' => array( 'desc' => sprintf('Limit search to %s with a spefic status (1 is active, 0 is pending approval)','events'), 'default'=>1),
29
+ 'scope' => array( 'desc'=> 'Choose the time frame of events to show. Additionally you can supply dates (in format of YYYY-MM-DD), either single for events on a specific date or two dates seperated by a comma (e.g. 2010-12-25,2010-12-31) for events ocurring between these dates.', 'default'=>'future', 'args'=>array("future", "past", "today", "tomorrow", "month", "next-month", "1-months", "2-months", "3-months", "6-months", "12-months","all")),
30
+ 'category' => array( 'desc'=> sprintf('Supply a single id or comma-seperated ids (e.g. "1,2,3") to limit the search to events in these %s.','tags'), 'default'=>0),
31
+ 'year' => array( 'desc'=> 'If set to a year (e.g. 2010) only events that start or end during this year/month will be returned. Does not work as intended if used with scope.', 'default'=>''),
32
+ ),
33
+ 'locations' => array(
34
+ 'blog' => array( 'desc' => sprintf('Limit search to %s created in a specific blog id (MultiSite only)','locations')),
35
+ 'eventful' => array( 'desc'=> 'If set to 1 will only show locations that have at least one event occurring during the scope.', 'default' => 0),
36
+ 'eventless' => array( 'desc'=> 'If set to 1 will only show locations that have no events occurring during the scope.', 'default' => 0),
37
+ 'location' => array( 'desc'=> sprintf('Supply a single id or comma-seperated ids (e.g. "1,2,3") to limit the search to %s with the %s.','locations', 'location_id(s)'), 'default'=>0),
38
+ 'post_id' => array( 'desc' => sprintf('Supply a single id or comma-seperated ids (e.g. "1,2,3") to limit the search to %s with the %s.','locations', 'post_id(s)')),
39
+ 'private' => array( 'desc' => sprintf('Display private %s within your list?','locations'), 'args' => '1 = yes, 0 = no', 'default' => 'If user can view private locations, 1, otherwise 0.'),
40
+ 'private_only' => array( 'desc' =>sprintf('Display only private %s ?','locations'), 'args' => '1 = yes, 0 = no', 'default' => '0'),
41
+ 'scope' => array( 'default' => 'all'),
42
+ 'status' => array( 'desc' => sprintf('Limit search to %s with a spefic status (1 is active, 0 is pending approval)','locations'), 'default'=>1),
43
+ 'country' => array( 'desc'=> sprintf('Search for %s in this %s (no partial matches, case sensitive).','locations','Country'), 'default' => 'none', 'args'=>'Use two-character country codes as defined in <a href="http://countrycode.org/">countrycode.org</a>, e.g. US,GB,ES'),
44
+ 'region' => array( 'desc'=> sprintf('Search for %s in this %s (no partial matches, case sensitive).','locations','Region'), 'default' => 'none'),
45
+ 'state' => array( 'desc'=> sprintf('Search for %s in this %s (no partial matches, case sensitive).','locations','State'), 'default' => 'none'),
46
+ 'town' => array( 'desc'=> sprintf('Search for %s in this %s (no partial matches, case sensitive).','locations','Town'), 'default' => 'none'),
47
+ 'postcode' => array( 'desc'=> sprintf('Search for %s in this %s (no partial matches, case sensitive).','locations','Postcode'), 'default' => 'none')
48
+ ),
49
+ 'categories' => array(
50
+ '' => array( 'desc' => 'See the <a href="http://codex.wordpress.org/Function_Reference/get_terms">WordPress get_terms() Codex</a> for a list of possible search attributes/arguments.'),
51
+ ),
52
+ 'tags' => array(
53
+ '' => array( 'desc' => 'See the <a href="http://codex.wordpress.org/Function_Reference/get_terms">WordPress get_terms() Codex</a> for a list of possible search attributes/arguments.'),
54
+ ),
55
+ 'calendar' => array(
56
+ 'full' => array( 'desc'=> 'If set to 1 it will display a full calendar that shows event names.', 'default' => 0),
57
+ 'long_events' => array( 'desc'=> 'If set to 1, will show events that last longer than a day.', 'default' => 0),
58
+ ),
59
+ //The object is commonly shared by all, so entries above overwrite entries here
60
+ 'general' => array(
61
+ 'array' => array( 'desc'=> 'If you supply this as an argument, the returned data will be in an array, not an object (only useful wen using PHP, not shortcodes)', 'default'=>0),
62
+ 'format_header' => array( 'desc'=> sprintf('If you are displaying lists (e.g. listing events), you can supply the %s html and placeholders here.','header'), 'default'=> 'The relevant default format will be taken from the settings page.'),
63
+ 'format' => array( 'desc'=> 'If you are displaying some information with the shortcode or function (e.g. listing events), you can supply the html and placeholders here.', 'default'=> 'The relevant default format will be taken from the settings page.'),
64
+ 'format_footer' => array( 'desc'=> sprintf('If you are displaying lists (e.g. listing events), you can supply the %s html and placeholders here.','footer'), 'default'=> 'The relevant default format will be taken from the settings page.'),
65
+ 'limit' => array( 'desc'=> 'Limits the amount of values returned to this number.', 'default'=>'0 (no limit)'),
66
+ 'offset' => array( 'desc'=> 'For example, if you have ten results, if you set this to 5, only the last 5 results will be returned. Useful for pagination.', 'default'=>0),
67
+ 'order' => array( 'desc'=> 'Indicates the alphabeitcal/numerical order of the lists. Choose between ASC (ascending) and DESC (descending).', 'default'=>'ASC'),
68
+ 'orderby' => array( 'desc'=> 'Choose what fields to order your results by. You can supply a single field or multiple comma-seperated fields (e.g. "event_start_date,event_name").', 'default'=>0, 'args'=>'Database table fields, e.g. <code>event_name</code> or <code>location_name</code>'),
69
+ 'owner' => array('desc'=> 'Limits returned results to a specific owner, identified by their user id (e.g. list events or locations owned by user)', 'default'=>0),
70
+ 'pagination' => array('desc'=> 'When using a function or shortcode that outputs items (e.g. [events_list] for events, [locations_list] for locations), if the number of items supercede the limit of items to show, setting this to 1 will show page links under the list.', 'default'=>0),
71
+ )
72
+ ),
73
+ 'placeholders' => array(
74
+ 'events' => array(
75
+ 'Event Details' => array(
76
+ 'placeholders' => array(
77
+ '#_EVENTID' => array( 'desc' => 'Shows the event ID number in the wp_em_events table.' ),
78
+ '#_EVENTPOSTID' => array( 'desc' => 'Shows the event corresponding Post ID in the wp_posts table.' ),
79
+ '#_EVENTNAME' => array( 'desc' => 'Displays the name of the event.' ),
80
+ '#_EVENTNOTES' => array( 'desc' => 'Shows the description of the event.' ),
81
+ '#_EVENTEXCERPT' => array( 'desc' => 'If you added a <a href="http://en.support.wordpress.com/splitting-content/more-tag/">more tag</a> to your event description, only the content before this tag will show (currently, no read more link is added).' ),
82
+ '#_EVENTIMAGE' => array( 'desc' => 'Shows the event image, if available.' ),
83
+ '#_EVENTIMAGE{x,y}' => array( 'desc' => 'Shows the event image thumbnail, x and y are width and height respectively, both being numbers e.g. <code>#_EVENTIMAGE{100,100}</code>' ),
84
+ '#_EVENTCATEGORIES' => array( 'desc' => 'Shows a list of category links this event belongs to.' ),
85
+ '#_EVENTCATEGORIESIMAGES' => array( 'desc' => 'Shows a list of category images this event belongs to. Categories without an image will be ignored.' ),
86
+ '#_EVENTTAGS' => array( 'desc' => 'Shows a list of tag links this event belongs to.' ),
87
+ )
88
+ ),
89
+ 'Date and Times' => array(
90
+ 'desc' => '',
91
+ 'placeholders' => array(
92
+ '#_24HSTARTTIME' => array( 'desc' => 'Displays the start time in a 24 hours format (e.g. 16:30).' ),
93
+ '#_24HENDTIME' => array( 'desc' => 'Displays the end time in a 24 hours format (e.g. 18:30).' ),
94
+ '#_12HSTARTTIME' => array( 'desc' => 'Displays the start time in a 12 hours format (e.g. 4:30 PM).' ),
95
+ '#_12HENDTIME' => array( 'desc' => 'Displays the end time in a 12 hours format (e.g. 6:30 PM).' ),
96
+ '#_EVENTTIMES' => array( 'desc' => 'Displays either a single time, time-span, or "All Day" depending on your event times. Format is taken from your Events Manager settings page.' ),
97
+ '#_EVENTDATES' => array( 'desc' => 'Displays either a single date or a date range depending on your event dates. Format is taken from your Events Manager settings page.' ),
98
+ )
99
+ ),
100
+ 'Custom Date/Time Formatting' => array(
101
+ 'desc' => 'Events Manager allows extremely flexible date formatting by using <a href="http://www.php.net/manual/en/function.date.php">PHP date syntax format characters</a> along with placeholders.',
102
+ 'placeholders' => array(
103
+ '# or #@' => array( 'desc' => 'Prepend <code>#</code> or <code>#@</code> before a valid PHP date syntax format character to show start and end date/time information respectively (e.g. <code>#F</code> will show the starting month name like "January", #@h shows the end hour).' ),
104
+ '#{x} or #@{x}' => array( 'desc' => 'You can also create a date format without prepending # to each character by wrapping a valid php date() format in <code>#{}</code> or <code>#@{}</code> (e.g. <code>#_{d/m/Y}</code>). If there is no end date (or is same as start date), the value is not shown. This is useful if you want to show event end dates only on events that are longer than on day, e.g. <code>#j #M #Y #@_{ \u\n\t\i\l j M Y}</code>.' ),
105
+ )
106
+ ),
107
+ 'Links/URLs' => array(
108
+ 'placeholders' => array(
109
+ '#_EVENTIMAGEURL' => array( 'desc' => 'Shows the event image url, if available.' ),
110
+ '#_EVENTURL' => array( 'desc' => 'Simply prints the event URL. You can use this placeholder to build your own customised links.' ),
111
+ '#_EVENTLINK' => array( 'desc' => 'Displays the event name with a link to the event page.' ),
112
+ '#_EDITEVENTLINK' => array( 'desc' => 'Inserts a link to the admin or buddypress (if activated) edit event page, only if a user is logged in and is allowed to edit the event.' ),
113
+ '#_EDITEVENTURL' => array( 'desc' => 'Inserts a url to the admin or buddypress (if activated) edit event page, only if a user is logged in and is allowed to edit the event.' )
114
+ )
115
+ ),
116
+ 'Custom Attributes' => array(
117
+ 'desc' => 'Events Manager allows you to create dynamic attributes to your events, which act as extra information fields for your events (e.g. "Dress Code"). For more information see <a href="http://wp-events-plugin.com/documentation/categories-and-attributes/">our online documentation</a> for more info on attributes.',
118
+ 'placeholders' => array(
119
+ '#_ATT{key}' => array('desc'=> 'This key will appear as an option when adding attributes to your event.'),
120
+ '#_ATT{key}{alternative text}' => array('desc'=> 'This key will appear as an option when adding attributes to your event. The text in the second braces will appear if the attribute is not defined or left blank for that event.'),
121
+ '#_ATT{key}{option 1|option 2|option 3|etc.}' => array('desc'=> 'This key will appear as an option when adding attributes to your event. The second braces are optional and will use a select box with these values as input. If no valid value is defined, the first option is used.'),
122
+ )
123
+ ),
124
+ 'Bookings' => array(
125
+ 'desc' => 'These placeholders will only show if bookings are enabled for the given event and in the events manager settings page. Spaces placeholders will default to 0',
126
+ 'placeholders' => array(
127
+ '#_BOOKINGFORM' => array( 'desc' => 'Adds a booking forms for this event.' ),
128
+ '#_BOOKINGBUTTON' => array( 'desc' => 'A single button that will appear to logged in users, if they click on it, they apply for a booking. This button will only display if there is one ticket.' ),
129
+ '#_AVAILABLESPACES' => array( 'desc' => 'Shows available spaces for the event.' ),
130
+ '#_BOOKEDSPACES' => array( 'desc' => 'Shows the amount of currently booked spaces for the event.' ),
131
+ '#_PENDINGSPACES' => array( 'desc' => 'Shows the amount of pending spaces for the event.' ),
132
+ '#_SPACES' => array( 'desc' => 'Shows the total spaces for the event.' ),
133
+ '#_ATTENDEES' => array( 'desc' => 'Shows the list of user avatars attending events.' ),
134
+ '#_BOOKINGSURL' => array( 'desc' => 'Shows the url to the admin, front-end or buddypress (if activated) bookings management page for this event. Only shown if user is logged in and able to manage bookings.' ),
135
+ '#_BOOKINGSLINK' => array( 'desc' => 'Shows a link to the admin, front-end or buddypress (if activated) bookings management page for this event. Only shown if user is logged in and able to manage bookings.' ),
136
+ '#_EVENTPRICERANGE' => array( 'desc' => 'Shows a "maximum - minimum" price range, or a single price if there is no range. Price is formatted according to currency formatting in your settings page.' ),
137
+ '#_EVENTPRICEMIN' => array( 'desc' => 'Shows the lowest ticket price for this event.' ),
138
+ '#_EVENTPRICEMAX' => array( 'desc' => 'Shows the highest ticket price for this event.' ),
139
+ )
140
+ ),
141
+ 'Contact Details' => array(
142
+ 'desc' => 'The values here are taken from the chosen contact for the specific event, or the default contact in the settings page.',
143
+ 'placeholders' => array(
144
+ '#_CONTACTNAME' => array( 'desc' => 'Name of the contact person for this event (as shown in the dropdown when adding an event).' ),
145
+ '#_CONTACTUSERNAME' => array( 'desc' => 'Contact person\'s username.' ),
146
+ '#_CONTACTEMAIL' => array( 'desc' => 'E-mail of the contact person for this event.' ),
147
+ '#_CONTACTPHONE' => array( 'desc' => 'Phone number of the contact person for this event. Can be set in the user profile page.' ),
148
+ '#_CONTACTAVATAR' => array( 'desc' => 'Contact person\'s avatar.' ),
149
+ '#_CONTACTPROFILELINK' => array( 'desc' => 'Contact person\'s "Profile" link. Only works with BuddyPress enabled.' ),
150
+ '#_CONTACTPROFILEURL' => array( 'desc' => 'Contact person\'s profile url. Only works with BuddyPress enabled.' ),
151
+ '#_CONTACTID' => array( 'desc' => 'Contact person\'s WordPress user ID.'),
152
+ '#_CONTACTMETA' => array( 'desc' => 'Display any user meta of a WordPress account by including the meta key, e.g. #_CONTACTMETA{dbem_phone}'),
153
+ )
154
+ ),
155
+ 'iCal/Calendar' => array(
156
+ 'placeholders' => array(
157
+ '#_EVENTICALURL' => array( 'desc' => 'Displays the URL of the event ical feed (ics file format).' ),
158
+ '#_EVENTICALLINK' => array( 'desc' => 'Displays an html link to the event ical feed (ics file format).' ),
159
+ '#_EVENTGCALURL' => array( 'desc' => 'Displays URL which would take the user to Google Calendar and pre-fill their add new event form.' ),
160
+ '#_EVENTGCALLINK' => array( 'desc' => 'Displays a button which would take the user to Google Calendar and pre-fill their add new event form.' )
161
+ )
162
+ ),
163
+ ),
164
+ 'categories' => array(
165
+ 'Category Details' => array(
166
+ 'placeholders' => array(
167
+ '#_CATEGORYNAME' => array( 'desc' => 'Shows the category name of the event.' ),
168
+ '#_CATEGORYID' => array( 'desc' => 'Shows the category ID of the event.' ),
169
+ '#_CATEGORYIMAGE' => array( 'desc' => 'Shows the event image, if available.' ),
170
+ '#_CATEGORYIMAGE{x,y}' => array( 'desc' => 'Shows the category image thumbnail, x and y are width and height respectively, both being numbers e.g. <code>#_CATEGORYIMAGE{100,100}</code>' ),
171
+ '#_CATEGORYIMAGEURL' => array( 'desc' => 'Shows the category image url, if available.' ),
172
+ '#_CATEGORYNOTES' => array( 'desc' => 'Shows the location description.' )
173
+ )
174
+ ),
175
+ 'Related Events' => array(
176
+ 'desc' => 'You can show lists of other events belonging to this category. The formatting of the list is the same as a normal events list.',
177
+ 'placeholders' => array(
178
+ '#_CATEGORYPASTEVENTS' => array( 'desc' => 'Will show a list of all past events at this category.' ),
179
+ '#_CATEGORYNEXTEVENTS' => array( 'desc' => 'Will show a list of all future events at this category.' ),
180
+ '#_CATEGORYALLEVENTS' => array( 'desc' => 'Will show a list of all events at this category.' )
181
+ )
182
+ )
183
+ ),
184
+ 'locations' => array(
185
+ 'Location Details' => array(
186
+ 'desc' => '',
187
+ 'placeholders' => array(
188
+ '#_LOCATIONID' => array( 'desc' => 'Shows the event ID number in the wp_em_locations table.' ),
189
+ '#_LOCATIONPOSTID' => array( 'desc' => 'Shows the location corresponding Post ID in the wp_posts table.' ),
190
+ '#_LOCATIONNAME' => array( 'desc' => 'Displays the location name.' ),
191
+ '#_LOCATIONADDRESS' => array( 'desc' => 'Displays the address.' ),
192
+ '#_LOCATIONTOWN' => array( 'desc' => 'Displays the town.' ),
193
+ '#_LOCATIONSTATE' => array( 'desc' => 'Displays the state/county.' ),
194
+ '#_LOCATIONPOSTCODE' => array( 'desc' => 'Displays the postcode.' ),
195
+ '#_LOCATIONREGION' => array( 'desc' => 'Displays the region.' ),
196
+ '#_LOCATIONCOUNTRY' => array( 'desc' => 'Displays the country.' ),
197
+ '#_LOCATIONMAP' => array( 'desc' => 'Displays a google map showing where the event is located (Will not show if maps are disabled in the settings page)' ),
198
+ '#_LOCATIONNOTES' => array( 'desc' => 'Shows the location description.' ),
199
+ '#_LOCATIONEXCERPT' => array( 'desc' => 'If you added a <a href="http://en.support.wordpress.com/splitting-content/more-tag/">more tag</a> to your location description, only the content before this tag will show (currently, no read more link is added).' ),
200
+ '#_LOCATIONIMAGE' => array( 'desc' => 'Shows the location image.' ),
201
+ '#_LOCATIONIMAGE{x,y}' => array( 'desc' => 'Shows the location image thumbnail, x and y are width and height respectively, both being numbers e.g. <code>#_LOCATIONIMAGE{100,100}</code>' ),
202
+ '#_LOCATIONIMAGEURL' => array( 'desc' => 'Shows the location image url, if available.' ),
203
+ '#_LOCATIONFULLLINE' => array( 'desc' => 'Shows a comma-seperated line of location information, ommitting blanks (format of address, town, state, postcode, region' ),
204
+ '#_LOCATIONFULLBR' => array( 'desc' => 'Shows a line-break (br tag) seperated location information, ommitting blanks (format of address, town, state, postcode, region' ),
205
+ )
206
+ ),
207
+ 'Custom Attributes' => array(
208
+ 'desc' => 'Events Manager allows you to create dynamic attributes to your locations, which act as extra information fields for your locations (e.g. "Dress Code"). For more information see <a href="http://wp-events-plugin.com/documentation/categories-and-attributes/">our online documentation</a> for more info on attributes.',
209
+ 'placeholders' => array(
210
+ '#_LATT{key}' => array('desc'=> 'This key will appear as an option when adding attributes to your location.'),
211
+ '#_LATT{key}{alternative text}' => array('desc'=> 'This key will appear as an option when adding attributes to your location. The text in the second braces will appear if the attribute is not defined or left blank for that location.'),
212
+ '#_LATT{key}{option 1|option 2|option 3|etc.}' => array('desc'=> 'This key will appear as an option when adding attributes to your location. The second braces are optional and will use a select box with these values as input. If no valid value is defined, the first option is used.'),
213
+ )
214
+ ),
215
+ 'Links' => array(
216
+ 'placeholders' => array(
217
+ '#_LOCATIONURL' => array( 'desc' => 'Simply prints the location URL. You can use this placeholder to build your own customised links.' ),
218
+ '#_LOCATIONLINK' => array( 'desc' => 'Displays the location name with a link to the location page.' ),
219
+ '#_EDITLOCATIONLINK' => array( 'desc' => 'Inserts a link to the admin or buddypress (if activated) edit location page, only if a user is logged in and is allowed to edit the location.' ),
220
+ '#_EDITLOCATIONURL' => array( 'desc' => 'Inserts a url to the admin or buddypress (if activated) edit location page, only if a user is logged in and is allowed to edit the location.' )
221
+ )
222
+ ),
223
+ 'Related Events' => array(
224
+ 'desc' => 'You can show lists of other events that are being held at this location. The formatting of the list is the same as a normal events list.',
225
+ 'placeholders' => array(
226
+ '#_LOCATIONPASTEVENTS' => array( 'desc' => 'Will show a list of all past events at this location.' ),
227
+ '#_LOCATIONNEXTEVENTS' => array( 'desc' => 'Will show a list of all future events at this location.' ),
228
+ '#_LOCATIONALLEVENTS' => array( 'desc' => 'Will show a list of all events at this location.' ),
229
+ '#_LOCATIONNEXTEVENT' => array( 'desc' => 'Will show a link to the next event at this location, or the no events message.' ),
230
+ )
231
+ ),
232
+ ),
233
+ 'bookings' => array(
234
+ 'Booking Person Information' => array(
235
+ 'desc' => 'When a specific booking is displayed (on screen and on email), you can use these placeholders to show specific information about the booking. Event and Location placeholders are also available in these cases.',
236
+ 'placeholders' => array(
237
+ '#_BOOKINGID' => array( 'desc' => 'The unique ID of this booking, useful if you are making your own customizations to this plugin.' ),
238
+ '#_BOOKINGNAME' => array( 'desc' => 'Name of person who made the booking.' ),
239
+ '#_BOOKINGEMAIL' => array( 'desc' => 'Email of person who made the booking.' ),
240
+ '#_BOOKINGPHONE' => array( 'desc' => 'Phone number of person who made the booking.' ),
241
+ '#_BOOKINGSPACES' => array( 'desc' => 'Number of spaces the person has booked.' ),
242
+ '#_BOOKINGCOMMENT' => array( 'desc' => 'Any specific comments made by the person who made the booking.' ),
243
+ '#_BOOKINGTICKETNAME' => array( 'desc' => 'Name of the ticket booked. Useful in single ticket mode, if multiple tickets are booked a random ticket is used.' ),
244
+ '#_BOOKINGTICKETDESCRIPTION' => array( 'desc' => 'Description of the ticket booked. Useful in single ticket mode, if multiple tickets are booked a random ticket is used.' ),
245
+ '#_BOOKINGTICKETPRICE' => array( 'desc' => 'Booked ticket price with currency symbol (e.g. $ 10.00). Useful in single ticket mode, if multiple tickets are booked a random ticket is used.' ),
246
+ '#_BOOKINGTICKETS' => array( 'desc' => 'A list of booked tickets. You can modify this by using template files and modifying templates/emails/bookingtickets.php' ),
247
+ '#_BOOKINGFORMCUSTOM{field_id}' => array( 'desc' => sprintf('(<a href="%s">pro only</a>) Shows booking form custom fields. The field_id value must match that of your custom booking form field.','http://wp-events-plugin.com/upgrade/') ),
248
+ '#_BOOKINGFORMCUSTOMREG{field_id}' => array( 'desc' => sprintf('(<a href="%s">pro only</a>) Shows booking form custom fields that are used for guest user registration. The field_id value must match that of your custom booking form field.','http://wp-events-plugin.com/upgrade/') ),
249
+ '#_BOOKINGFORMCUSTOMFIELDS' => array( 'desc' => sprintf('(<a href="%s">pro only</a>) Generates a list of booking form custom fields that are used in the booking.','http://wp-events-plugin.com/upgrade/') )
250
+ )
251
+ ),
252
+ 'Pricing Information' => array(
253
+ 'desc' => '',
254
+ 'placeholders' => array(
255
+ '#_BOOKINGPRICE' => array( 'desc' => 'Displays booking total price (tax inclusion depends on your booking settings).' ),
256
+ '#_BOOKINGPRICETAX' => array( 'desc' => 'Displays booking total tax.' ),
257
+ '#_BOOKINGPRICEWITHOUTTAX' => array( 'desc' => 'Displays booking total without tax.' ),
258
+ '#_BOOKINGPRICEWITHTAX' => array( 'desc' => 'Displays booking total with tax.' ),
259
+ )
260
+ ),
261
+ 'Ticket Information' => array(
262
+ 'desc' => '',
263
+ 'placeholders' => array(
264
+ '#_BOOKINGTICKETS' => array( 'desc' => 'Shows a breakdown of tickets and pricing, defined in the <code>emails/bookingtickets.php</code> template. (See <a href="http://wp-events-plugin.com/documentation/using-template-files/">Using Template Files</a> for more information)' ),
265
+ '#_BOOKINGTICKETDESCRIPTION' => array( 'desc' => 'Shows the description of the first ticket booked (useful in single ticket mode/events).' ),
266
+ '#_BOOKINGTICKETPRICE' => array( 'desc' => 'Shows the price of the first ticket booked, tax inclusion depending on your booking settings (useful in single ticket mode/events).' ),
267
+ '#_BOOKINGTICKETTAX' => array( 'desc' => 'Shows the tax of the first ticket booked (useful in single ticket mode/events).' ),
268
+ '#_BOOKINGTICKETPRICEWITHTAX' => array( 'desc' => 'Shows the price including tax of the first ticket booked (useful in single ticket mode/events).' ),
269
+ '#_BOOKINGTICKETPRICEWITHOUTTAX' => array( 'desc' => 'Shows the price excluding tax of the first ticket booked (useful in single ticket mode/events).' ),
270
+ )
271
+ ),
272
+ 'Links' => array(
273
+ 'desc' => 'People are able to manage their bookings. Below are some placeholder which automatically provides correctly formatted urls',
274
+ 'placeholders' => array(
275
+ '#_BOOKINGLISTURL' => array( 'desc' => 'URL to page showing that users booked events.' )
276
+ )
277
+ ),
278
+ 'Gateway-Specific Information' => array(
279
+ 'desc' => '',
280
+ 'placeholders' => array(
281
+ '#_BOOKINGTXNID' => array( 'desc' => '<em>Online Payments Only</em> - Prints the transaction ID of this booking if available.' )
282
+ )
283
+ ),
284
+ ),
285
+ ),
286
+ //TODO add capabilites explanations
287
+ 'capabilities' => array()
288
+ );
289
+ }
290
+ }
291
+ add_action('init', 'em_docs_init');
292
+
293
+ function em_docs_placeholders($atts){
294
+ ob_start();
295
+ ?>
296
+ <div class="em-docs">
297
+ <?php
298
+ global $EM_Documentation;
299
+ $type = $atts['type'];
300
+ $data = $EM_Documentation['placeholders'][$type];
301
+ foreach($data as $sectionTitle => $details) : ?>
302
+ <div>
303
+ <h3><?php echo $sectionTitle; ?></h3>
304
+ <?php if( !empty($details['desc']) ): ?>
305
+ <p><?php echo $details['desc']; ?></p>
306
+ <?php endif; ?>
307
+ <dl>
308
+ <?php foreach($details['placeholders'] as $placeholder => $desc ): ?>
309
+ <dt><b><?php echo $placeholder; ?></b></dt>
310
+ <dd><?php echo $desc['desc']; ?></dd>
311
+ <?php endforeach; ?>
312
+ </dl>
313
+ </div>
314
+ <?php endforeach; ?>
315
+ </div>
316
+ <?php
317
+ return ob_get_clean();
318
+ }
319
  ?>
admin/em-event.php DELETED
@@ -1,627 +0,0 @@
1
- <?php
2
- function em_admin_event_actions(){
3
- if( current_user_can(EM_MIN_CAPABILITY) && !empty($_GET['page']) && $_GET['page'] == 'events-manager-event' && !empty($_REQUEST ['action']) ){
4
- global $wpdb;
5
- global $EM_Event;
6
-
7
- //if dealing with new event, we still want an event object
8
- if( !is_object($EM_Event) ){
9
- $EM_Event = new EM_Event();
10
- }
11
-
12
- // UPDATE or CREATE action
13
- if ($_REQUEST['action'] == 'save') {
14
- $validation = $EM_Event->get_post();
15
- if ( $validation ) { //EM_Event gets the event if submitted via POST and validates it (safer than to depend on JS)
16
- //Save
17
- if( $EM_Event->save() ) {
18
- $page = !empty($_REQUEST['pno']) ? $_REQUEST['pno']:'';
19
- $scope = !empty($_REQUEST['scope']) ? $_REQUEST['scope']:'';
20
- wp_redirect( get_bloginfo('wpurl').'/wp-admin/admin.php?page=events-manager&p='.$page.'&scope='.$scope.'&message='.urlencode($EM_Event->feedback_message));
21
- }
22
- }//errors added automatically to event global object
23
- }
24
-
25
- //Copy the event
26
- if ($_REQUEST['action'] == 'duplicate') {
27
- global $EZSQL_ERROR;
28
- $EM_Event = $EM_Event->duplicate();
29
- if( $EM_Event === false ){
30
- $redirect_url = em_add_get_params($_SERVER['HTTP_REFERER'], array('error' => __('There was an error duplicating the event. Try again maybe?', 'dbem'), 'message'=>''), false);
31
- wp_redirect($redirect_url);
32
- }else{
33
- $page = !empty($_REQUEST['pno']) ? $_REQUEST['pno']:'';
34
- $scope = !empty($_REQUEST['scope']) ? $_REQUEST['scope']:'';
35
- wp_redirect( get_bloginfo('wpurl').'/wp-admin/admin.php?page=events-manager-event&event_id='.$EM_Event->id.'&p='.$page.'&scope='.$scope.'&message='.urlencode($EM_Event->feedback_message));
36
- }
37
- }
38
- }
39
- }
40
- add_action('admin_init', 'em_admin_event_actions');
41
-
42
- /**
43
- * Generates Event Admin page, for adding and updating a single (or recurring) event.
44
- * @param $title
45
- * @return null
46
- */
47
- function em_admin_event_page() {
48
- global $EM_Event, $current_user;
49
- global $localised_date_formats;
50
-
51
- //check that user can access this page
52
- if( is_object($EM_Event) && !$EM_Event->can_manage() ){
53
- ?>
54
- <div class="wrap"><h2><?php _e('Unauthorized Access','dbem'); ?></h2><p><?php _e('You do not have the rights to manage this event.','dbem'); ?></p></div>
55
- <?php
56
- return false;
57
- }
58
-
59
- if( is_object($EM_Event) && $EM_Event->id > 0 ){
60
- if($EM_Event->is_recurring()){
61
- $title = __( "Reschedule", 'dbem' )." '{$EM_Event->name}'";
62
- }else{
63
- $title = __ ( "Edit Event", 'dbem' ) . " '" . $EM_Event->name . "'";
64
- }
65
- } else {
66
- $EM_Event = ( is_object($EM_Event) && get_class($EM_Event) == 'EM_Event') ? $EM_Event : new EM_Event();
67
- $title = __ ( "Insert New Event", 'dbem' );
68
- //Give a default location & category
69
- $default_cat = get_option('dbem_default_category');
70
- $default_loc = get_option('dbem_default_location');
71
- if( is_numeric($default_cat) && $default_cat > 0 ){
72
- $EM_Event->category_id = $default_cat;
73
- $EM_Event->category = new EM_Category($default_cat);
74
- }
75
- if( is_numeric($default_loc) && $default_loc > 0 && ( empty($EM_Event->location->id) && empty($EM_Event->location->name) && empty($EM_Event->location->address) && empty($EM_Event->location->town) ) ){
76
- $EM_Event->location_id = $default_loc;
77
- $EM_Event->location = new EM_Location($default_loc);
78
- }
79
- }
80
-
81
- $use_select_for_locations = get_option('dbem_use_select_for_locations');
82
- // change prefix according to event/recurrence
83
- $pref = "event_";
84
-
85
- $locale_code = substr ( get_locale (), 0, 2 );
86
- $localised_date_format = $localised_date_formats[$locale_code];
87
-
88
- //FIXME time useage is very flimsy imho
89
- $hours_locale_regexp = "H:i";
90
- // Setting 12 hours format for those countries using it
91
- if (preg_match ( "/en|sk|zh|us|uk/", $locale_code ))
92
- $hours_locale_regexp = "h:iA";
93
-
94
- $days_names = array (1 => __ ( 'Mon' ), 2 => __ ( 'Tue' ), 3 => __ ( 'Wed' ), 4 => __ ( 'Thu' ), 5 => __ ( 'Fri' ), 6 => __ ( 'Sat' ), 0 => __ ( 'Sun' ) );
95
- ?>
96
- <?php if ( count($EM_Event->errors) > 0 || !empty($_GET['error']) ) : ?>
97
- <div id='message' class='error '>
98
- <p>
99
- <?php if( count($EM_Event->errors) ){ ?>
100
- <strong><?php echo __( "Ach, there's a problem here:", "dbem" ) ?></strong><br /><br />
101
- <?php echo implode('<br />', $EM_Event->errors); ?>
102
- <?php } else { echo $_GET['error']; } ?>
103
- </p>
104
- </div>
105
- <?php endif; ?>
106
- <?php if ( !empty($EM_Event->feedback_message) || !empty($_GET['message']) ) : ?>
107
- <div id='message' class='updated fade'>
108
- <p><?php echo !empty($EM_Event->feedback_message) ? $EM_Event->feedback_message : $_GET['message']; ?></p>
109
- </div>
110
- <?php endif; ?>
111
- <form id="event-form" method="post" action="">
112
- <div class="wrap">
113
- <div id="icon-events" class="icon32"><br /></div>
114
- <h2><?php echo $title; ?></h2>
115
- <?php if ( $EM_Event->is_recurrence() || $EM_Event->is_recurring() ) : ?>
116
- <p id='recurrence_warning'>
117
- <?php
118
- //TODO better warning system when changing a recurring event (e.g. when removing recurrences).
119
- if ( $EM_Event->is_recurring() ) {
120
- _e ( 'WARNING: This is a recurring event.', 'dbem' );
121
- echo "<br />";
122
- _e ( 'Modifying these data all the events linked to this recurrence will be rescheduled', 'dbem' );
123
- echo " ";
124
- _e ( 'and all booking information will be deleted!', 'dbem' );
125
- } elseif ( $EM_Event->is_recurrence() ) {
126
- //TODO Terminology confusing with methods, maybe worth changing?
127
- _e ( 'WARNING: This is a recurrence.', 'dbem' );
128
- echo "<br />";
129
- _e ( 'If you change these data and save, this will become an independent event.', 'dbem' );
130
- }
131
- ?>
132
- </p>
133
- <?php endif; ?>
134
- <div id="poststuff" class="metabox-holder has-right-sidebar">
135
- <!-- SIDEBAR -->
136
- <div id="side-info-column" class='inner-sidebar'>
137
- <div id='side-sortables'>
138
- <?php if(get_option('dbem_recurrence_enabled')) : ?>
139
- <!-- START recurrence postbox -->
140
- <div class="postbox ">
141
- <div class="handlediv" title="Fare clic per cambiare."><br />
142
- </div>
143
- <h3 class='hndle'><span>
144
- <?php _e ( "Recurrence", 'dbem' ); ?>
145
- </span></h3>
146
- <div class="inside">
147
- <?php //TODO add js warning if rescheduling, since all bookings are deleted ?>
148
- <?php if ( !$EM_Event->id || $EM_Event->is_recurring() ) : ?>
149
- <p>
150
- <input id="event-recurrence" type="checkbox" name="repeated_event" value="1" <?php echo ( $EM_Event->is_recurring() ) ? 'checked="checked"':'' ; ?> />
151
- <?php _e ( 'Repeated event', 'dbem' ); ?>
152
- </p>
153
- <div id="event_recurrence_pattern">
154
- <p>
155
- Frequency:
156
- <select id="recurrence-frequency" name="recurrence_freq">
157
- <?php
158
- $freq_options = array ("daily" => __ ( 'Daily', 'dbem' ), "weekly" => __ ( 'Weekly', 'dbem' ), "monthly" => __ ( 'Monthly', 'dbem' ) );
159
- em_option_items ( $freq_options, $EM_Event->freq );
160
- ?>
161
- </select>
162
- </p>
163
- <p>
164
- <?php _e ( 'Every', 'dbem' )?>
165
- <input id="recurrence-interval" name='recurrence_interval' size='2' value='<?php echo $EM_Event->interval ; ?>' />
166
- <span class='interval-desc' id="interval-daily-singular">
167
- <?php _e ( 'day', 'dbem' )?>
168
- </span> <span class='interval-desc' id="interval-daily-plural">
169
- <?php _e ( 'days', 'dbem' ) ?>
170
- </span> <span class='interval-desc' id="interval-weekly-singular">
171
- <?php _e ( 'week', 'dbem' )?>
172
- </span> <span class='interval-desc' id="interval-weekly-plural">
173
- <?php _e ( 'weeks', 'dbem' )?>
174
- </span> <span class='interval-desc' id="interval-monthly-singular">
175
- <?php _e ( 'month', 'dbem' )?>
176
- </span> <span class='interval-desc' id="interval-monthly-plural">
177
- <?php _e ( 'months', 'dbem' )?>
178
- </span>
179
- </p>
180
- <p class="alternate-selector" id="weekly-selector">
181
- <?php
182
- $saved_bydays = ($EM_Event->is_recurring()) ? explode ( ",", $EM_Event->byday ) : array();
183
- em_checkbox_items ( 'recurrence_bydays[]', $days_names, $saved_bydays );
184
- ?>
185
- </p>
186
- <p class="alternate-selector" id="monthly-selector">
187
- <?php _e ( 'Every', 'dbem' )?>
188
- <select id="monthly-modifier" name="recurrence_byweekno">
189
- <?php
190
- $weekno_options = array ("1" => __ ( 'first', 'dbem' ), '2' => __ ( 'second', 'dbem' ), '3' => __ ( 'third', 'dbem' ), '4' => __ ( 'fourth', 'dbem' ), '-1' => __ ( 'last', 'dbem' ) );
191
- em_option_items ( $weekno_options, $EM_Event->byweekno );
192
- ?>
193
- </select>
194
- <select id="recurrence-weekday" name="recurrence_byday">
195
- <?php em_option_items ( $days_names, $EM_Event->byday ); ?>
196
- </select>
197
- &nbsp;
198
- </p>
199
- </div>
200
- <p id="recurrence-tip">
201
- <?php _e ( 'Check if your event happens more than once according to a regular pattern', 'dbem' )?>
202
- </p>
203
- <?php elseif( $EM_Event->is_recurrence() ) : ?>
204
- <p>
205
- <?php echo $EM_Event->get_recurrence_description(); ?>
206
- <br />
207
- <a href="<?php bloginfo ( 'wpurl' )?>/wp-admin/admin.php?page=events-manager-event&amp;event_id=<?php echo $EM_Event->recurrence_id; ?>">
208
- <?php _e ( 'Reschedule', 'dbem' ); ?>
209
- </a>
210
- <input type="hidden" name="recurrence_id" value="<?php echo $EM_Event->recurrence_id; ?>" />
211
- </p>
212
- <?php else : ?>
213
- <p><?php _e ( 'This is\'t a recurrent event', 'dbem' ) ?></p>
214
- <?php endif; ?>
215
- </div>
216
- </div>
217
- <!-- END recurrence postbox -->
218
- <?php endif; ?>
219
- <?php if(get_option('dbem_rsvp_enabled')) : ?>
220
- <!-- START RSVP -->
221
- <?php if ( em_verify_admin() ): ?>
222
- <div class="postbox ">
223
- <div class="handlediv" title="Fare clic per cambiare."><br />
224
- </div>
225
- <h3 class='hndle'><span>
226
- <?php _e ( 'Contact Person', 'dbem' ); ?>
227
- </span></h3>
228
- <div class="inside">
229
- <p><?php _e('Contact','dbem'); ?>
230
- <?php
231
- wp_dropdown_users ( array ('name' => 'event_contactperson_id', 'show_option_none' => __ ( "Select...", 'dbem' ), 'selected' => $EM_Event->contactperson_id ) );
232
- ?>
233
- </p>
234
- </div>
235
- </div>
236
- <?php else: ?>
237
- <input type="hidden" name="event_contactperson_id" value="<?php get_current_user_id() ?>" />
238
- <?php endif; ?>
239
- <div class="postbox ">
240
- <div class="handlediv" title="Fare clic per cambiare."><br />
241
- </div>
242
- <h3 class='hndle'><span><?php _e('RSVP','dbem'); ?></span></h3>
243
- <div class="inside">
244
- <p>
245
- <input id="rsvp-checkbox" name='event_rsvp' value='1' type='checkbox' <?php echo ($EM_Event->rsvp) ? 'checked="checked"' : ''; ?> />
246
- <?php _e ( 'Enable registration for this event', 'dbem' )?>
247
- </p>
248
- <div id='rsvp-data'>
249
- <?php
250
- if ($EM_Event->contactperson_id != NULL){
251
- $selected = $EM_Event->contactperson_id;
252
- }else{
253
- $selected = '0';
254
- }
255
- ?>
256
- <p>
257
- <?php _e ( 'Spaces','dbem' ); ?> :
258
- <input id="seats-input" type="text" name="event_seats" size='5' value="<?php echo $EM_Event->seats ?>" />
259
- </p>
260
- <!-- START RSVP Stats -->
261
- <?php
262
- if ($EM_Event->rsvp ) {
263
- $available_seats = $EM_Event->get_bookings()->get_available_seats();
264
- $booked_seats = $EM_Event->get_bookings()->get_booked_seats();
265
-
266
- if ( count($EM_Event->get_bookings()->bookings) > 0 ) {
267
- ?>
268
- <div class='wrap'>
269
- <p><strong><?php echo __('Available Spaces','dbem').': '.$EM_Event->get_bookings()->get_available_seats(); ?></strong></p>
270
- <p><strong><?php echo __('Confirmed Spaces','dbem').': '.$EM_Event->get_bookings()->get_booked_seats(); ?></strong></p>
271
- <p><strong><?php echo __('Pending Spaces','dbem').': '.$EM_Event->get_bookings()->get_pending_seats(); ?></strong></p>
272
- </div>
273
-
274
- <br class='clear'/>
275
-
276
- <div id='major-publishing-actions'>
277
- <div id='publishing-action'>
278
- <a id='printable' href='<?php echo get_bloginfo('wpurl') . "/wp-admin/admin.php?page=events-manager-bookings&event_id=".$EM_Event->id ?>'><?php _e('manage bookings','dbem')?></a><br />
279
- <a target='_blank' href='<?php echo get_bloginfo('wpurl') . "/wp-admin/admin.php?page=events-manager-bookings&action=bookings_report&event_id=".$EM_Event->id ?>'><?php _e('printable view','dbem')?></a>
280
- <a href='<?php echo get_bloginfo('wpurl') . "/wp-admin/admin.php?page=events-manager-bookings&action=export_csv&event_id=".$EM_Event->id ?>'><?php _e('export csv','dbem')?></a>
281
- <br class='clear'/>
282
- </div>
283
- <br class='clear'/>
284
- </div>
285
- <?php
286
- } else {
287
- ?>
288
- <p><em><?php _e('No responses yet!')?></em></p>
289
- <?php
290
- }
291
- }
292
- ?>
293
- <!-- END RSVP Stats -->
294
- </div>
295
- </div>
296
- </div>
297
- <!-- END RSVP -->
298
- <?php endif; ?>
299
- <?php if(get_option('dbem_categories_enabled')) :?>
300
- <!-- START Categories -->
301
- <div class="postbox ">
302
- <div class="handlediv" title="Fare clic per cambiare."><br />
303
- </div>
304
- <h3 class='hndle'><span>
305
- <?php _e ( 'Category', 'dbem' ); ?>
306
- </span></h3>
307
- <div class="inside">
308
- <?php $categories = EM_Categories::get(array('orderby'=>'category_name')); ?>
309
- <?php if( count($categories) > 0 ): ?>
310
- <p><?php _e ( 'Category:', 'dbem' ); ?>
311
- <select name="event_category_id">
312
- <option value="" <?php echo ($EM_Event->category_id == '') ? "selected='selected'":'' ?>><?php _e('no category','dbem') ?></option>
313
- <?php
314
- foreach ( $categories as $EM_Category ){
315
- $selected = ($EM_Category->id == $EM_Event->category_id) ? "selected='selected'": '';
316
- ?>
317
- <option value="<?php echo $EM_Category->id ?>" <?php echo $selected ?>>
318
- <?php echo $EM_Category->name ?>
319
- </option>
320
- <?php
321
- }
322
- ?>
323
- </select>
324
- </p>
325
- <?php else: ?>
326
- <p><?php sprintf(__('No categories available, <a href="%s">create one here first</a>','dbem'), get_bloginfo('wpurl').'/wp-admin/admin.php?page=events-manager-categories'); ?></p>
327
- <?php endif; ?>
328
- </div>
329
- </div>
330
- <!-- END Categories -->
331
- <?php endif; ?>
332
- </div>
333
- </div>
334
- <!-- END OF SIDEBAR -->
335
- <div id="post-body">
336
- <div id="post-body-content">
337
- <div id="event_name" class="stuffbox">
338
- <h3>
339
- <?php _e ( 'Name', 'dbem' ); ?>
340
- </h3>
341
- <div class="inside">
342
- <input type="text" name="event_name" id="event-name" value="<?php echo htmlspecialchars($EM_Event->name,ENT_QUOTES); ?>" />
343
- <br />
344
- <?php _e ( 'The event name. Example: Birthday party', 'dbem' )?>
345
- </div>
346
- </div>
347
- <div id="event_start_date" class="stuffbox">
348
- <h3 id='event-date-title'>
349
- <?php _e ( 'Event date', 'dbem' ); ?>
350
- </h3>
351
- <h3 id='recurrence-dates-title'>
352
- <?php _e ( 'Recurrence dates', 'dbem' ); ?>
353
- </h3>
354
- <div class="inside">
355
- <input id="localised-date" type="text" name="localised_event_date" style="display: none;" />
356
- <input id="date-to-submit" type="text" name="event_start_date" value="<?php echo $EM_Event->start_date ?>" style="background: #FCFFAA" />
357
- <input id="localised-end-date" type="text" name="localised_event_end_date" style="display: none;" />
358
- <input id="end-date-to-submit" type="text" name="event_end_date" value="<?php echo $EM_Event->end_date ?>" style="background: #FCFFAA" />
359
- <br />
360
- <span id='event-date-explanation'>
361
- <?php
362
- _e ( 'The event date.', 'dbem' );
363
- /* Marcus Begin Edit */
364
- echo " ";
365
- _e ( 'When not reoccurring, this event spans between the beginning and end date.', 'dbem' );
366
- /* Marcus End Edit */
367
- ?>
368
- </span>
369
- <span id='recurrence-dates-explanation'>
370
- <?php _e ( 'The recurrence beginning and end date.', 'dbem' ); ?>
371
- </span>
372
- </div>
373
- </div>
374
- <div id="event_end_day" class="stuffbox">
375
- <h3>
376
- <?php _e ( 'Event time', 'dbem' ); ?>
377
- </h3>
378
- <div class="inside">
379
- <input id="start-time" type="text" size="8" maxlength="8" name="event_start_time" value="<?php echo date( $hours_locale_regexp, strtotime($EM_Event->start_time) ); ?>" />
380
- -
381
- <input id="end-time" type="text" size="8" maxlength="8" name="event_end_time" value="<?php echo date( $hours_locale_regexp, strtotime($EM_Event->end_time) ); ?>" />
382
- <br />
383
- <?php _e ( 'The time of the event beginning and end', 'dbem' )?>.
384
- </div>
385
- </div>
386
- <div id="location_coordinates" class="stuffbox" style='display: none;'>
387
- <h3>
388
- <?php _e ( 'Coordinates', 'dbem' ); ?>
389
- </h3>
390
- <div class="inside">
391
- <input id='location-latitude' name='location_latitude' type='text' value='<?php echo $EM_Event->latitude; ?>' size='15' />
392
- -
393
- <input id='location-longitude' name='location_longitude' type='text' value='<?php echo $EM_Event->longitude; ?>' size='15' />
394
- </div>
395
- </div>
396
- <div id="location_info" class="stuffbox">
397
- <h3>
398
- <?php _e ( 'Location', 'dbem' ); ?>
399
- </h3>
400
- <div class="inside">
401
- <table id="dbem-location-data">
402
- <tr>
403
- <td style="padding-right:20px">
404
- <table>
405
- <?php if($use_select_for_locations) : ?>
406
- <tr>
407
- <th><?php _e('Location:','dbem') ?></th>
408
- <td>
409
- <select name="location-select-id" id='location-select-id' size="1">
410
- <?php
411
- $locations = EM_Locations::get();
412
- foreach($locations as $location) {
413
- $selected = "";
414
- if( is_object($EM_Event->location) ) {
415
- if ($EM_Event->location->id == $location->id)
416
- $selected = "selected='selected' ";
417
- }
418
- ?>
419
- <option value="<?php echo $location->id ?>" title="<?php echo "{$location->latitude},{$location->longitude}" ?>" <?php echo $selected ?>><?php echo $location->name; ?></option>
420
- <?php
421
- }
422
- ?>
423
- </select>
424
- <p><?php _e ( 'The name of the location where the event takes place. You can use the name of a venue, a square, etc', 'dbem' )?></p>
425
- </td>
426
- </tr>
427
- <?php else : ?>
428
- <tr>
429
- <th><?php _e ( 'Name:' )?></th>
430
- <td>
431
- <input id="location-name" type="text" name="location_name" value="<?php echo htmlspecialchars($EM_Event->location->name, ENT_QUOTES); ?>" />
432
- <p><?php _e ( 'Select a location for your event', 'dbem' )?></p>
433
- </td>
434
- </tr>
435
- <tr>
436
- <th><?php _e ( 'Address:' )?>&nbsp;</th>
437
- <td>
438
- <input id="location-address" type="text" name="location_address" value="<?php echo htmlspecialchars($EM_Event->location->address, ENT_QUOTES); ; ?>" />
439
- <p><?php _e ( 'The address of the location where the event takes place. Example: 21, Dominick Street', 'dbem' )?></p>
440
- </td>
441
- </tr>
442
- <tr>
443
- <th><?php _e ( 'Town:' )?>&nbsp;</th>
444
- <td>
445
- <input id="location-town" type="text" name="location_town" value="<?php echo htmlspecialchars($EM_Event->location->town, ENT_QUOTES); ?>" />
446
- <p><?php _e ( 'The town where the location is located. If you\'re using the Google Map integration and want to avoid geotagging ambiguities include the country in the town field. Example: Verona, Italy.', 'dbem' )?></p>
447
- </td>
448
- </tr>
449
- <?php endif; ?>
450
- </table>
451
- </td>
452
- <?php if ( get_option ( 'dbem_gmap_is_active' ) ) : ?>
453
- <td width="400">
454
- <div id='em-map-404' style='width: 400px; vertical-align:middle; text-align: center;'>
455
- <p><em><?php _e ( 'Location not found', 'dbem' ); ?></em></p>
456
- </div>
457
- <div id='em-map' style='width: 400px; height: 300px; display: none;'></div>
458
- </td>
459
- <?php endif; ?>
460
- </tr>
461
- </table>
462
- </div>
463
- </div>
464
- <div id="event_notes" class="postbox">
465
- <h3>
466
- <?php _e ( 'Details', 'dbem' ); ?>
467
- </h3>
468
- <div class="inside">
469
- <div id="<?php echo user_can_richedit() ? 'postdivrich' : 'postdiv'; ?>" class="postarea">
470
- <?php the_editor($EM_Event->notes ); ?>
471
- </div>
472
- <br />
473
- <?php _e ( 'Details about the event', 'dbem' )?>
474
- </div>
475
- </div>
476
-
477
- <?php if(get_option('dbem_attributes_enabled')) : ?>
478
- <div id="event_attributes" class="postbox">
479
- <h3>
480
- <?php _e ( 'Attributes', 'dbem' ); ?>
481
- </h3>
482
- <div class="inside">
483
- <?php
484
- //We also get a list of attribute names and create a ddm list (since placeholders are fixed)
485
- $formats =
486
- get_option ( 'dbem_event_list_item_format' ).
487
- get_option ( 'dbem_event_page_title_format' ).
488
- get_option ( 'dbem_full_calendar_event_format' ).
489
- get_option ( 'dbem_location_baloon_format' ).
490
- get_option ( 'dbem_location_event_list_item_format' ).
491
- get_option ( 'dbem_location_page_title_format' ).
492
- get_option ( 'dbem_map_text_format' ).
493
- get_option ( 'dbem_rss_description_format' ).
494
- get_option ( 'dbem_rss_title_format' ).
495
- get_option ( 'dbem_single_event_format' ).
496
- get_option ( 'dbem_single_location_format' ).
497
- get_option ( 'dbem_placeholders_custom' );
498
- //We now have one long string of formats, get all the attribute placeholders
499
- preg_match_all('/#_ATT\{.+?\}(\{.+?\})?/', $formats, $placeholders);
500
- //Now grab all the unique attributes we can use in our event.
501
- $attributes = array();
502
- foreach($placeholders[0] as $result) {
503
- $attribute = substr( substr($result, 0, strpos($result, '}')), 6 );
504
- if( !in_array($attribute, $attributes) ){
505
- $attributes[] = $attribute ;
506
- }
507
- }
508
- ?>
509
- <div class="wrap">
510
- <?php if( count( $attributes ) > 0 ) : ?>
511
- <h2>Attributes</h2>
512
- <p>Add attributes here</p>
513
- <table class="form-table">
514
- <thead>
515
- <tr valign="top">
516
- <td><strong>Attribute Name</strong></td>
517
- <td><strong>Value</strong></td>
518
- </tr>
519
- </thead>
520
- <tfoot>
521
- <tr valign="top">
522
- <td colspan="3"><a href="#" id="mtm_add_tag">Add new tag</a></td>
523
- </tr>
524
- </tfoot>
525
- <tbody id="mtm_body">
526
- <?php
527
- $count = 1;
528
- if( is_array($EM_Event->attributes) and count($EM_Event->attributes) > 0){
529
- foreach( $EM_Event->attributes as $name => $value){
530
- ?>
531
- <tr valign="top" id="mtm_<?php echo $count ?>">
532
- <td scope="row">
533
- <select name="mtm_<?php echo $count ?>_ref">
534
- <?php
535
- if( !in_array($name, $attributes) ){
536
- echo "<option value='$name'>$name (".__('Not defined in templates', 'dbem').")</option>";
537
- }
538
- foreach( $attributes as $attribute ){
539
- if( $attribute == $name ) {
540
- echo "<option selected='selected'>$attribute</option>";
541
- }else{
542
- echo "<option>$attribute</option>";
543
- }
544
- }
545
- ?>
546
- </select>
547
- <a href="#" rel="<?php echo $count ?>">Remove</a>
548
- </td>
549
- <td>
550
- <input type="text" name="mtm_<?php echo $count ?>_name" value="<?php echo htmlspecialchars($value, ENT_QUOTES); ?>" />
551
- </td>
552
- </tr>
553
- <?php
554
- $count++;
555
- }
556
- }else{
557
- ?>
558
- <tr valign="top" id="mtm_<?php echo $count ?>">
559
- <td scope="row">
560
- <select name="mtm_<?php echo $count ?>_ref">
561
- <?php
562
- foreach( $attributes as $attribute ){
563
- echo "<option>$attribute</option>";
564
- }
565
- ?>
566
- </select>
567
- <a href="#" rel="<?php echo $count ?>">Remove</a>
568
- </td>
569
- <td>
570
- <input type="text" name="mtm_<?php echo $count ?>_name" />
571
- </td>
572
- </tr>
573
- <?php
574
- }
575
- ?>
576
- </tbody>
577
- </table>
578
- <?php else : ?>
579
- <p>
580
- <?php _e('In order to use attributes, you must define some in your templates, otherwise they\'ll never show. Go to Events > Settings to add attribute placeholders.', 'dbem'); ?>
581
- </p>
582
- <script>
583
- jQuery(document).ready(function($){ $('#event_attributes').addClass('closed'); });
584
- </script>
585
- <?php endif; ?>
586
- </div>
587
- </div>
588
- </div>
589
- <?php endif; ?>
590
- </div>
591
- <p class="submit">
592
- <input type="submit" name="events_update" value="<?php _e ( 'Submit Event', 'dbem' ); ?> &raquo;" />
593
- </p>
594
- <input type="hidden" name="p" value="<?php echo ( !empty($_REQUEST['pno']) ) ? $_REQUEST['pno']:''; ?>" /><a>
595
- <input type="hidden" name="scope" value="<?php echo ( !empty($_REQUEST['scope']) ) ? $_REQUEST['scope']:'' ?>" /></a>
596
- <input type="hidden" name="action" value="save" />
597
- </div>
598
- </div>
599
- </div>
600
- </form>
601
- <script type="text/javascript">
602
- jQuery(document).ready( function($) {
603
- <?php if( $EM_Event->is_recurring() ): ?>
604
- //Recurrence Warnings
605
- $('#event_form').submit( function(event){
606
- confirmation = confirm('<?php _e('Are you sure you want to reschedule this recurring event? If you do this, you will lose all booking information and the old recurring events will be deleted.', 'dbem'); ?>');
607
- if( confirmation == false ){
608
- event.preventDefault();
609
- }
610
- });
611
- <?php endif; ?>
612
- <?php if( $EM_Event->rsvp == 1 ): ?>
613
- //RSVP Warning
614
- $('#rsvp-checkbox').click( function(event){
615
- if( !this.checked ){
616
- confirmation = confirm('<?php _e('Are you sure you want to disable bookings? If you do this and save, you will lose all previous bookings. If you wish to prevent further bookings, reduce the number of seats available to the amount of bookings you currently have', 'dbem'); ?>');
617
- if( confirmation == false ){
618
- event.preventDefault();
619
- }
620
- }
621
- });
622
- <?php endif; ?>
623
- });
624
- </script>
625
- <?php
626
- }
627
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/em-events.php DELETED
@@ -1,242 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Determines whether to show event page or events page, and saves any updates to the event or events
5
- * @return null
6
- */
7
- function em_admin_events_page() {
8
- //TODO Simplify panel for events, use form flags to detect certain actions (e.g. submitted, etc)
9
- global $wpdb;
10
- global $EM_Event;
11
- $action = ( !empty($_GET ['action']) ) ? $_GET ['action']:'';
12
- $order = ( !empty($_GET ['order']) ) ? $_GET ['order']:'ASC';
13
- $limit = ( !empty($_GET['limit']) ) ? $_GET['limit'] : 20;//Default limit
14
- $page = ( !empty($_GET['pno']) ) ? $_GET['pno']:1;
15
- $offset = ( $page > 1 ) ? ($page-1)*$limit : 0;
16
- $scope_names = array (
17
- 'past' => __ ( 'Past events', 'dbem' ),
18
- 'all' => __ ( 'All events', 'dbem' ),
19
- 'future' => __ ( 'Future events', 'dbem' )
20
- );
21
- $scope = ( !empty($_GET ['scope']) && array_key_exists($_GET ['scope'], $scope_names) ) ? $_GET ['scope']:'future';
22
- $selectedEvents = ( !empty($_GET ['events']) ) ? $_GET ['events']:'';
23
-
24
- // DELETE action
25
- if ( $action == 'deleteEvents' && EM_Object::array_is_numeric($selectedEvents) ) {
26
- EM_Events::delete( $selectedEvents );
27
- }
28
-
29
- // No action, only showing the events list
30
- switch ($scope) {
31
- case "past" :
32
- $title = __ ( 'Past Events', 'dbem' );
33
- break;
34
- case "all" :
35
- $title = __ ( 'All Events', 'dbem' );
36
- break;
37
- default :
38
- $title = __ ( 'Future Events', 'dbem' );
39
- $scope = "future";
40
- }
41
- $args = array('scope'=>$scope, 'limit'=>0, 'order'=>$order );
42
-
43
- if( !get_option('dbem_permissions_events') && !em_verify_admin() ){
44
- $args['owner'] = get_current_user_id();
45
- }
46
-
47
- $events = EM_Events::get( $args );
48
- $events_count = count ( $events );
49
-
50
- $use_events_end = get_option ( 'dbem_use_event_end' );
51
- ?>
52
- <div class="wrap">
53
- <div id="icon-events" class="icon32"><br />
54
- </div>
55
- <h2>
56
- <?php echo $title; ?>
57
- <a href="admin.php?page=events-manager-event" class="button add-new-h2"><?php _e('Add New','dbem'); ?></a>
58
- </h2>
59
- <?php
60
- $link = array ();
61
- $link ['past'] = "<a href='" . get_bloginfo ( 'wpurl' ) . "/wp-admin/admin.php?page=events-manager&amp;scope=past&amp;order=desc'>" . __ ( 'Past events', 'dbem' ) . "</a>";
62
- $link ['all'] = " <a href='" . get_bloginfo ( 'wpurl' ) . "/wp-admin/admin.php?page=events-manager&amp;scope=all&amp;order=desc'>" . __ ( 'All events', 'dbem' ) . "</a>";
63
- $link ['future'] = " <a href='" . get_bloginfo ( 'wpurl' ) . "/wp-admin/admin.php?page=events-manager&amp;scope=future'>" . __ ( 'Future events', 'dbem' ) . "</a>";
64
- ?>
65
- <?php if ( !empty($_GET['error']) ) : ?>
66
- <div id='message' class='error'>
67
- <p><?php echo $_GET['error']; ?></p>
68
- </div>
69
- <?php endif; ?>
70
- <?php if ( !empty($_GET['message']) ) : ?>
71
- <div id='message' class='updated fade'>
72
- <p><?php echo $_GET['message']; ?></p>
73
- </div>
74
- <?php endif; ?>
75
- <form id="posts-filter" action="" method="get"><input type='hidden' name='page' value='events-manager' />
76
- <ul class="subsubsub">
77
- <li><a href='#' class="current"><?php _e ( 'Total', 'dbem' ); ?> <span class="count">(<?php echo (count ( $events )); ?>)</span></a></li>
78
- </ul>
79
- <p class="search-box">
80
- <label class="screen-reader-text" for="post-search-input"><?php _e('Search Events','dbem'); ?>:</label>
81
- <input type="text" id="post-search-input" name="em_search" value="<?php echo (!empty($_GET['em_search'])) ? $_GET['em_search']:''; ?>" />
82
- <input type="submit" value="<?php _e('Search Events','dbem'); ?>" class="button" />
83
- </p>
84
- <div class="tablenav">
85
-
86
- <div class="alignleft actions">
87
- <select name="action">
88
- <option value="-1" selected="selected"><?php _e ( 'Bulk Actions' ); ?></option>
89
- <option value="deleteEvents"><?php _e ( 'Delete selected','dbem' ); ?></option>
90
- </select>
91
- <input type="submit" value="<?php _e ( 'Apply' ); ?>" name="doaction2" id="doaction2" class="button-secondary action" />
92
- <select name="scope">
93
- <?php
94
- foreach ( $scope_names as $key => $value ) {
95
- $selected = "";
96
- if ($key == $scope)
97
- $selected = "selected='selected'";
98
- echo "<option value='$key' $selected>$value</option> ";
99
- }
100
- ?>
101
- </select>
102
- <input id="post-query-submit" class="button-secondary" type="submit" value="<?php _e ( 'Filter' )?>" />
103
- </div>
104
- <!--
105
- <div class="view-switch">
106
- <a href="/wp-admin/edit.php?mode=list"><img class="current" id="view-switch-list" src="http://wordpress.lan/wp-includes/images/blank.gif" width="20" height="20" title="List View" alt="List View" name="view-switch-list" /></a> <a href="/wp-admin/edit.php?mode=excerpt"><img id="view-switch-excerpt" src="http://wordpress.lan/wp-includes/images/blank.gif" width="20" height="20" title="Excerpt View" alt="Excerpt View" name="view-switch-excerpt" /></a>
107
- </div>
108
- -->
109
- <?php
110
- if ( $events_count >= $limit ) {
111
- $page_link_template = em_add_get_params($_SERVER['REQUEST_URI'], array('pno'=>'%PAGE%'));
112
- $events_nav = em_admin_paginate( $page_link_template, $events_count, $limit, $page, 5);
113
- echo $events_nav;
114
- }
115
- ?>
116
- <br class="clear" />
117
- </div>
118
-
119
- <?php
120
- if (empty ( $events )) {
121
- // TODO localize
122
- _e ( 'no events','dbem' );
123
- } else {
124
- ?>
125
-
126
- <table class="widefat">
127
- <thead>
128
- <tr>
129
- <th class='manage-column column-cb check-column' scope='col'>
130
- <input class='select-all' type="checkbox" value='1' />
131
- </th>
132
- <th><?php _e ( 'Name', 'dbem' ); ?></th>
133
- <th>&nbsp;</th>
134
- <th><?php _e ( 'Location', 'dbem' ); ?></th>
135
- <th colspan="2"><?php _e ( 'Date and time', 'dbem' ); ?></th>
136
- </tr>
137
- </thead>
138
- <tbody>
139
- <?php
140
- $rowno = 0;
141
- $event_count = 0;
142
- foreach ( $events as $event ) {
143
- /* @var $event EM_Event */
144
- if( ($rowno < $limit || empty($limit)) && ($event_count >= $offset || $offset === 0) ) {
145
- $rowno++;
146
- $class = ($rowno % 2) ? ' class="alternate"' : '';
147
- // FIXME set to american
148
- $localised_start_date = date_i18n('D d M Y', $event->start);
149
- $localised_end_date = date_i18n('D d M Y', $event->end);
150
- $style = "";
151
- $today = date ( "Y-m-d" );
152
- $location_summary = "<b>" . $event->location->name . "</b><br/>" . $event->location->address . " - " . $event->location->town;
153
- $category = new EM_Category($event->category_id);
154
-
155
- if ($event->start_date < $today && $event->end_date < $today){
156
- $style = "style ='background-color: #FADDB7;'";
157
- }
158
- ?>
159
- <tr <?php echo "$class $style"; ?>>
160
-
161
- <td>
162
- <input type='checkbox' class='row-selector' value='<?php echo $event->id; ?>' name='events[]' />
163
- </td>
164
- <td>
165
- <strong>
166
- <a class="row-title" href="<?php bloginfo ( 'wpurl' )?>/wp-admin/admin.php?page=events-manager-event&amp;event_id=<?php echo $event->id ?>&amp;scope=<?php echo $scope ?>&amp;p=<?php echo $page ?>"><?php echo ($event->name); ?></a>
167
- </strong>
168
- <?php if( is_object($category) ) : ?>
169
- <br/><span title='<?php echo __( 'Category', 'dbem' ).": ".$category->name ?>'><?php echo $category->name ?></span>
170
- <?php endif; ?>
171
- <?php
172
- if( get_option('dbem_rsvp_enabled') == 1 && $event->rsvp == 1 ){
173
- ?>
174
- <br/>
175
- <a href="<?php bloginfo ( 'wpurl' )?>/wp-admin/admin.php?page=events-manager-bookings&amp;event_id=<?php echo $event->id ?>"><?php echo __("Bookings",'dbem'); ?></a> &ndash;
176
- <?php _e("Booked",'dbem'); ?>: <?php echo $event->get_bookings()->get_booked_seats()."/".$event->seats; ?>
177
- <?php if( get_option('dbem_bookings_approval') == 1 ): ?>
178
- | <?php _e("Pending",'dbem') ?>: <?php echo $event->get_bookings()->get_pending_seats(); ?>
179
- <?php endif;
180
- }
181
- ?>
182
- </td>
183
- <td>
184
- <a href="<?php bloginfo ( 'wpurl' )?>/wp-admin/admin.php?page=events-manager-event&amp;action=duplicate&amp;event_id=<?php echo $event->id; ?>&amp;scope=<?php echo $scope ?>&amp;p=<?php echo $page ?>" title="<?php _e ( 'Duplicate this event', 'dbem' ); ?>">
185
- <strong>+</strong>
186
- </a>
187
- </td>
188
- <td>
189
- <?php echo $location_summary; ?>
190
- </td>
191
-
192
- <td>
193
- <?php echo $localised_start_date; ?>
194
- <?php echo ($localised_end_date != $localised_start_date) ? " - $localised_end_date":'' ?>
195
- <br />
196
- <?php
197
- //TODO Should 00:00 - 00:00 be treated as an all day event?
198
- echo substr ( $event->start_time, 0, 5 ) . " - " . substr ( $event->end_time, 0, 5 );
199
- ?>
200
- </td>
201
- <td>
202
- <?php
203
- if ( $event->is_recurrence() ) {
204
- ?>
205
- <strong>
206
- <?php echo $event->get_recurrence_description(); ?> <br />
207
- <a href="<?php bloginfo ( 'wpurl' )?>/wp-admin/admin.php?page=events-manager-event&amp;event_id=<?php echo $event->recurrence_id ?>&amp;scope=<?php echo $scope ?>&amp;p=<?php echo $page ?>"><?php _e ( 'Reschedule', 'dbem' ); ?></a>
208
- </strong>
209
- <?php
210
- }
211
- ?>
212
- </td>
213
- </tr>
214
- <?php
215
- }
216
- $event_count++;
217
- }
218
- ?>
219
- </tbody>
220
- </table>
221
- <?php
222
- } // end of table
223
- ?>
224
- <div class='tablenav'>
225
- <div class="alignleft actions">
226
- <br class='clear' />
227
- </div>
228
- <?php if ( $events_count >= $limit ) : ?>
229
- <div class="tablenav-pages">
230
- <?php
231
- echo $events_nav;
232
- ?>
233
- </div>
234
- <?php endif; ?>
235
- <br class='clear' />
236
- </div>
237
- </form>
238
- </div>
239
- <?php
240
- }
241
-
242
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/em-help.php CHANGED
@@ -1,52 +1,69 @@
1
- <?php
2
- /**
3
- * Display function for the support page. here we can give links to forums and special upgrade instructions e.g. migration features
4
- */
5
- function em_admin_help_page(){
6
- global $wpdb;
7
- ?>
8
- <div class="wrap">
9
- <div id="icon-events" class="icon32"><br /></div>
10
- <h2><?php _e('Getting Help for Events Manager','dbem'); ?></h2>
11
- <p>
12
- For further information on using this plugin, please view the <a href="http://wp-events-plugin.com/documentation/">documentation pages</a>. If you can't find what you're looking for in the documentation, you may find help on our <a href="http://wp-events-plugin.com/forums/">support forums</a>.
13
- </p>
14
- <div class="em-docs">
15
- <h2><?php _e('Placeholders for customizing event pages','dbem'); ?></h2>
16
- <p><?php echo sprintf( __("In the <a href='%s'>settings page</a>, you'll find various textboxes where you can edit how event information looks, such as for event and location lists. Using the placeholders below, you can choose what information should be displayed.",'dbem'), 'admin.php?page=events-manager-options'); ?></p>
17
- <h3><a name="event-placeholders"><?php _e('Event Related Placeholders','dbem'); ?></a></h3>
18
- <?php echo em_docs_placeholders( array('type'=>'events') ); ?>
19
- <h3><a name="location-placeholders"><?php _e('Location Related Placeholders','dbem'); ?></a></h3>
20
- <?php echo em_docs_placeholders( array('type'=>'locations') ); ?>
21
- <h3><a name="booking-placeholders"><?php _e('Booking Related Placeholders','dbem'); ?></a></h3>
22
- <?php echo em_docs_placeholders( array('type'=>'bookings') ); ?>
23
- </div>
24
- <?php
25
- //Is this a previously imported installation?
26
- $old_table_name = $wpdb->prefix.'dbem_events';
27
- if( $wpdb->get_var("SHOW TABLES LIKE '$old_table_name'") == $old_table_name ){
28
- ?>
29
- <hr style="margin:30px 10px;" />
30
- <div class="updated">
31
- <h3>Troubleshooting upgrades from version 2.x to 3.x</h3>
32
- <p>We notice that you upgraded from version 2, as we are now using new database tables, and we do not delete the old tables in case something went wrong with this upgrade.</p>
33
- <p>If something went wrong with the update to version 3 read on:</p>
34
- <h4>Scenario 1: the plugin is working, but for some reason the old events weren't imported</h4>
35
- <p>You can safely reimport your old events from the previous tables without any risk of deleting them. However, if you click the link below <b>YOU WILL OVERWRITE ANY NEW EVENTS YOU CREATED IN VERSION 3</b></p>
36
- <p><a onclick="return confirm('Are you sure you want to do this? Any new changes made since updating will be overwritten by your old ones, and this cannot be undone');" href="<?php echo wp_nonce_url( get_bloginfo('wpurl').'/wp-admin/admin.php?page=events-manager-help&em_reimport=1', 'em_reimport' ) ?>">Reimport Events from version 2</a></p>
37
- <h4>Scenario 2: the plugin is not working, I want to go back to version 2!</h4>
38
- <p>You can safely downgrade and will not lose any information.</p>
39
- <ol>
40
- <li>First of all, <a href='http://downloads.wordpress.org/plugin/events-manager.2.2.2.zip'>dowload a copy of version 2.2</a></li>
41
- <li>Deactivate and delete Events Manager in the plugin page</li>
42
- <li><a href="<?php bloginfo('wpurl'); ?>/wp-admin/plugin-install.php?tab=upload">Upload the zip file you just downloaded here</a></li>
43
- <li>Let the developers know, of any bugs you ran into while upgrading. We'll help you out if there is a simple solution, and will fix reported bugs within days, if not quicker!</li>
44
- </ol>
45
- </div>
46
- <?php
47
- }
48
- ?>
49
- </div>
50
- <?php
51
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  ?>
1
+ <?php
2
+ /**
3
+ * Display function for the support page. here we can give links to forums and special upgrade instructions e.g. migration features
4
+ */
5
+ function em_admin_help_page(){
6
+ global $wpdb;
7
+ ?>
8
+ <div class="wrap">
9
+ <div id="icon-events" class="icon32"><br /></div>
10
+ <h2><?php _e('Getting Help for Events Manager','dbem'); ?></h2>
11
+ <div class="em-docs">
12
+ <h2>Where To Get Help</h3>
13
+ <p>
14
+ This page is only a small portion of the event documentation which is here for quick reference. If you're just starting out, we recommend you visit the following places for further support:
15
+ </p>
16
+ <ol>
17
+ <li>New users are strongly encouraged to have a look at our <a href="http://wp-events-plugin.com/documentation/getting-started/">getting started page</a>.</li>
18
+ <li>Browse the other documentation pages and <a href="http://wp-events-plugin.com/tutorials/">tutorials</a>.</li>
19
+ <li>View the <a href="http://wp-events-plugin.com/documentation/faq/">FAQ</a> for general questions and <a href="http://wp-events-plugin.com/documentation/troubleshooting/">Troubleshooting</a> for common issues. These are regularly updated with recent issues.</li>
20
+ <li>Rather than trying to contact us directly, we request you use the <a href="http://wordpress.org/tags/events-manager?forum_id=10">support forums</a> as others may be experiencing the same issues as you. For faster support via private member forums and extra features please consider <a href="http://wp-events-plugin.com/events-manager-pro/">upgrading to pro</a>.</li>
21
+ </ol>
22
+ <p>
23
+ If you can't find what you're looking for in the documentation, you may find help on our <a href="http://wp-events-plugin.com/forums/">support forums</a>.
24
+ </p>
25
+ <h2><?php _e('Placeholders for customizing event pages','dbem'); ?></h2>
26
+ <p><?php echo sprintf( __("In the <a href='%s'>settings page</a>, you'll find various textboxes where you can edit how event information looks, such as for event and location lists. Using the placeholders below, you can choose what information should be displayed.",'dbem'), EM_ADMIN_URL .'&amp;events-manager-options'); ?></p>
27
+ <a name="event-placeholders"></a>
28
+ <h3 style="margin-top:20px;"><?php _e('Event Related Placeholders','dbem'); ?></h3>
29
+ <?php echo em_docs_placeholders( array('type'=>'events') ); ?>
30
+ <a name="category-placeholders"></a>
31
+ <h3><?php _e('Category Related Placeholders','dbem'); ?></h3>
32
+ <?php echo em_docs_placeholders( array('type'=>'categories') ); ?>
33
+ <a name="location-placeholders"></a>
34
+ <h3><?php _e('Location Related Placeholders','dbem'); ?></h3>
35
+ <?php echo em_docs_placeholders( array('type'=>'locations') ); ?>
36
+ <a name="booking-placeholders"></a>
37
+ <h3><?php _e('Booking Related Placeholders','dbem'); ?></h3>
38
+ <?php echo em_docs_placeholders( array('type'=>'bookings') ); ?>
39
+ </div>
40
+ <?php
41
+
42
+ //Is this a previously imported installation?
43
+ $old_table_name = $wpdb->prefix.'dbem_events';
44
+ if( $wpdb->get_var("SHOW TABLES LIKE '$old_table_name'") == $old_table_name ){
45
+ ?>
46
+ <hr style="margin:30px 10px;" />
47
+ <div class="updated">
48
+ <h3>Troubleshooting upgrades from version 2.x to 3.x</h3>
49
+ <p>We notice that you upgraded from version 2, as we are now using new database tables, and we do not delete the old tables in case something went wrong with this upgrade.</p>
50
+ <p>If something went wrong with the update to version 3 read on:</p>
51
+ <h4>Scenario 1: the plugin is working, but for some reason the old events weren't imported</h4>
52
+ <p>You can safely reimport your old events from the previous tables without any risk of deleting them. However, if you click the link below <b>YOU WILL OVERWRITE ANY NEW EVENTS YOU CREATED IN VERSION 3</b></p>
53
+ <p><a onclick="return confirm('Are you sure you want to do this? Any new changes made since updating will be overwritten by your old ones, and this cannot be undone');" href="<?php echo wp_nonce_url( EM_ADMIN_URL .'&amp;events-manager-help&em_reimport=1', 'em_reimport' ) ?>">Reimport Events from version 2</a></p>
54
+ <h4>Scenario 2: the plugin is not working, I want to go back to version 2!</h4>
55
+ <p>You can safely downgrade and will not lose any information.</p>
56
+ <ol>
57
+ <li>First of all, <a href='http://downloads.wordpress.org/plugin/events-manager.2.2.2.zip'>dowload a copy of version 2.2</a></li>
58
+ <li>Deactivate and delete Events Manager in the plugin page</li>
59
+ <li><a href="<?php bloginfo('wpurl'); ?>/wp-admin/plugin-install.php?tab=upload">Upload the zip file you just downloaded here</a></li>
60
+ <li>Let the developers know, of any bugs you ran into while upgrading. We'll help you out if there is a simple solution, and will fix reported bugs within days, if not quicker!</li>
61
+ </ol>
62
+ </div>
63
+ <?php
64
+ }
65
+ ?>
66
+ </div>
67
+ <?php
68
+ }
69
  ?>
admin/em-locations-search.php CHANGED
@@ -3,20 +3,25 @@
3
  * This page will search for either a specific location via GET "id" variable
4
  * or will search for events by name via the GET "q" variable.
5
  */
 
6
  require_once('../../../../wp-load.php');
7
  global $wpdb;
8
 
9
- $locations_table = $wpdb->prefix . EM_LOCATIONS_TABLE;
10
- $location_cond = ( get_option('dbem_permissions_locations') < 1 && !em_verify_admin() ) ? "AND location_owner=".get_current_user_id() : '';
11
 
12
  $term = (isset($_GET['term'])) ? '%'.$_GET['term'].'%' : '%'.$_GET['q'].'%';
13
  $sql = $wpdb->prepare("
14
  SELECT
 
15
  Concat( location_name, ', ', location_address, ', ', location_town) AS `label`,
16
  location_name AS `value`,
17
  location_address AS `address`,
18
  location_town AS `town`,
19
- location_id AS `id`
 
 
 
20
  FROM $locations_table
21
  WHERE ( `location_name` LIKE %s ) $location_cond LIMIT 10
22
  ", $term);
3
  * This page will search for either a specific location via GET "id" variable
4
  * or will search for events by name via the GET "q" variable.
5
  */
6
+ //FIXME just plug loc search into ajax catcher
7
  require_once('../../../../wp-load.php');
8
  global $wpdb;
9
 
10
+ $locations_table = EM_LOCATIONS_TABLE;
11
+ $location_cond = ( !current_user_can('edit_others_locations') && !current_user_can('read_others_locations') ) ? "AND location_owner=".get_current_user_id() : '';
12
 
13
  $term = (isset($_GET['term'])) ? '%'.$_GET['term'].'%' : '%'.$_GET['q'].'%';
14
  $sql = $wpdb->prepare("
15
  SELECT
16
+ location_id AS `id`,
17
  Concat( location_name, ', ', location_address, ', ', location_town) AS `label`,
18
  location_name AS `value`,
19
  location_address AS `address`,
20
  location_town AS `town`,
21
+ location_state AS `state`,
22
+ location_region AS `region`,
23
+ location_postcode AS `postcode`,
24
+ location_country AS `country`
25
  FROM $locations_table
26
  WHERE ( `location_name` LIKE %s ) $location_cond LIMIT 10
27
  ", $term);
admin/em-locations.php DELETED
@@ -1,268 +0,0 @@
1
- <?php
2
- /**
3
- * Looks at the request values, saves/updates and then displays the right menu in the admin
4
- * @return null
5
- */
6
- function em_admin_locations_page() {
7
- //TODO EM_Location is globalized, use it fully here
8
- global $EM_Location;
9
- //Take actions
10
- if( !empty($_REQUEST['action']) || !empty($_REQUEST['location_id']) ){
11
- if( $_REQUEST['action'] == "edit" || $_REQUEST['action'] == "add" ) {
12
- //edit/add location
13
- em_admin_location();
14
- } elseif( $_REQUEST['action'] == "delete" ){
15
- //delelte location
16
- $locations = $_REQUEST['locations'];
17
- foreach($locations as $location_id) {
18
- $EM_Location = new EM_Location($location_id);
19
- $EM_Location->delete();
20
- }
21
- em_admin_locations(__('Locations Deleted', "dbem" ));
22
- } elseif( $_REQUEST['action'] == "save") {
23
- // save (add/update) location
24
- if( empty($EM_Location) || !is_object($EM_Location) ){
25
- $EM_Location = new EM_Location(); //blank location
26
- $success_message = __('The location has been added.', 'dbem');
27
- }else{
28
- $success_message = __('The location has been updated.', 'dbem');
29
- }
30
- $EM_Location->get_post();
31
- $validation_result = $EM_Location->validate();
32
- if ( $validation_result ) {
33
- $EM_Location->save(); //FIXME better handling of db write fails when saving location
34
- em_admin_locations($success_message);
35
- } else {
36
- ?>
37
- <div id='message' class='error '>
38
- <p>
39
- <strong><?php _e( "Ach, there's a problem here:", "dbem" ) ?></strong><br /><br /><?php echo implode('<br />', $EM_Location->errors); ?>
40
- </p>
41
- </div>
42
- <?php
43
- unset($EM_Location);
44
- em_admin_location();
45
- }
46
- }
47
- } else {
48
- // no action, just a locations list
49
- em_admin_locations();
50
- }
51
- }
52
-
53
- function em_admin_locations($message='', $fill_fields = false) {
54
- $limit = ( !empty($_REQUEST['limit']) ) ? $_REQUEST['limit'] : 20;//Default limit
55
- $page = ( !empty($_REQUEST['pno']) ) ? $_REQUEST['pno']:1;
56
- $offset = ( $page > 1 ) ? ($page-1)*$limit : 0;
57
- $locations = EM_Locations::get();
58
- $locations_count = count($locations);
59
- ?>
60
- <div class='wrap'>
61
- <div id='icon-edit' class='icon32'>
62
- <br/>
63
- </div>
64
- <h2>
65
- <?php _e('Locations', 'dbem'); ?>
66
- <a href="admin.php?page=events-manager-locations&action=add" class="button add-new-h2"><?php _e('Add New') ?></a>
67
- </h2>
68
-
69
- <?php if($message != "") : ?>
70
- <div id='message' class='updated fade below-h2'>
71
- <p><?php echo $message ?></p>
72
- </div>
73
- <?php endif; ?>
74
-
75
- <form id='bookings-filter' method='post' action=''>
76
- <input type='hidden' name='page' value='locations'/>
77
- <input type='hidden' name='limit' value='<?php echo $limit ?>' />
78
- <input type='hidden' name='p' value='<?php echo $page ?>' />
79
- <?php if ( $locations_count > 0 ) : ?>
80
- <div class='tablenav'>
81
- <div class="alignleft actions">
82
- <select name="action">
83
- <option value="" selected="selected"><?php _e ( 'Bulk Actions' ); ?></option>
84
- <option value="delete"><?php _e ( 'Delete selected','dbem' ); ?></option>
85
- </select>
86
- <input type="submit" value="<?php _e ( 'Apply' ); ?>" id="doaction2" class="button-secondary action" />
87
- <?php
88
- //Pagination (if needed/requested)
89
- if( $locations_count >= $limit ){
90
- //Show the pagination links (unless there's less than 10 events
91
- $page_link_template = preg_replace('/(&|\?)p=\d+/i','',$_SERVER['REQUEST_URI']);
92
- $page_link_template = em_add_get_params($page_link_template, array('pno'=>'%PAGE%'));
93
- $locations_nav = em_paginate( $page_link_template, $locations_count, $limit, $page);
94
- echo $locations_nav;
95
- }
96
- ?>
97
- </div>
98
- </div>
99
- <table class='widefat'>
100
- <thead>
101
- <tr>
102
- <th class='manage-column column-cb check-column' scope='col'><input type='checkbox' class='select-all' value='1'/></th>
103
- <th><?php _e('Name', 'dbem') ?></th>
104
- <th><?php _e('Address', 'dbem') ?></th>
105
- <th><?php _e('Town', 'dbem') ?></th>
106
- </tr>
107
- </thead>
108
- <tfoot>
109
- <tr>
110
- <th class='manage-column column-cb check-column' scope='col'><input type='checkbox' class='select-all' value='1'/></th>
111
- <th><?php _e('Name', 'dbem') ?></th>
112
- <th><?php _e('Address', 'dbem') ?></th>
113
- <th><?php _e('Town', 'dbem') ?></th>
114
- </tr>
115
- </tfoot>
116
- <tbody>
117
- <?php $i = 1; ?>
118
- <?php foreach ($locations as $EM_Location) : ?>
119
- <?php if( $i >= $offset && $i <= $offset+$limit ): ?>
120
- <tr>
121
- <td><input type='checkbox' class ='row-selector' value='<?php echo $EM_Location->id ?>' name='locations[]'/></td>
122
- <td><a href='admin.php?page=events-manager-locations&amp;action=edit&amp;location_id=<?php echo $EM_Location->id ?>'><?php echo $EM_Location->name ?></a></td>
123
- <td><?php echo $EM_Location->address ?></td>
124
- <td><?php echo $EM_Location->town ?></td>
125
- </tr>
126
- <?php endif; ?>
127
- <?php $i++; ?>
128
- <?php endforeach; ?>
129
- </tbody>
130
- </table>
131
- <?php else: ?>
132
- <p><?php _e('No venues have been inserted yet!', 'dbem') ?></p>
133
- <?php endif; ?>
134
- </form>
135
- </div>
136
- <?php
137
- }
138
-
139
- function em_admin_location($message = "") {
140
- global $EM_Location, $EM_Event;
141
- //check that user can access this page
142
- if( is_object($EM_Location) && !$EM_Location->can_manage() ){
143
- ?>
144
- <div class="wrap"><h2><?php _e('Unauthorized Access','dbem'); ?></h2><p><?php _e('You do not have the rights to manage this location.','dbem'); ?></p></div>
145
- <?php
146
- return false;
147
- }
148
- if( empty($EM_Location) || !is_object($EM_Location) ){
149
- $title = __('Add location', 'dbem');
150
- $EM_Location = new EM_Location();
151
- }else{
152
- $title = __('Edit location', 'dbem');
153
- }
154
- ?>
155
- <form enctype='multipart/form-data' name='editcat' id='locationForm' method='post' action='admin.php?page=events-manager-locations' class='validate'>
156
- <input type='hidden' name='action' value='save' />
157
- <input type='hidden' name='location_id' value='<?php echo $EM_Location->id ?>'/>
158
- <div class='wrap'>
159
- <div id='icon-edit' class='icon32'>
160
- <br/>
161
- </div>
162
- <h2><?php echo $title ?></h2>
163
-
164
- <?php if($message != "") : ?>
165
- <div id='message' class='updated fade below-h2' style='background-color: rgb(255, 251, 204);'>
166
- <p><?php echo $message ?></p>
167
- </div>
168
- <?php endif; ?>
169
- <div id='ajax-response'></div>
170
-
171
- <div id="poststuff" class="metabox-holder">
172
- <div id="post-body">
173
- <div id="post-body-content">
174
- <div id="location_name" class="stuffbox">
175
- <h3>
176
- <?php _e ( 'Location Name', 'dbem' ); ?>
177
- </h3>
178
- <div class="inside">
179
- <input name='location_name' id='location-name' type='text' value='<?php echo htmlspecialchars($EM_Location->name, ENT_QUOTES); ?>' size='40' />
180
- <br />
181
- <?php _e('The name of the location', 'dbem') ?>
182
- </div>
183
- </div>
184
- <div id="location_coordinates" class="stuffbox" style='display: none;'>
185
- <h3>
186
- <?php _e ( 'Coordinates', 'dbem' ); ?>
187
- </h3>
188
- <div class="inside">
189
- <input id='location-latitude' name='location_latitude' type='text' value='<?php echo $EM_Location->latitude; ?>' size='15' />
190
- -
191
- <input id='location-longitude' name='location_longitude' type='text' value='<?php echo $EM_Location->longitude; ?>' size='15' />
192
- </div>
193
- </div>
194
- <div id="location_info" class="stuffbox">
195
- <h3>
196
- <?php _e ( 'Location', 'dbem' ); ?>
197
- </h3>
198
- <div class="inside">
199
- <table id="dbem-location-data">
200
- <tr>
201
- <td style="padding-right:20px">
202
- <table>
203
- <tr>
204
- <th><?php _e ( 'Address:' )?>&nbsp;</th>
205
- <td>
206
- <input id="location-address" type="text" name="location_address" value="<?php echo htmlspecialchars($EM_Location->address, ENT_QUOTES); ; ?>" />
207
- <p><?php _e ( 'The address of the location where the event takes place. Example: 21, Dominick Street', 'dbem' )?></p>
208
- </td>
209
- </tr>
210
- <tr>
211
- <th><?php _e ( 'Town:' )?>&nbsp;</th>
212
- <td>
213
- <input id="location-town" type="text" name="location_town" value="<?php echo htmlspecialchars($EM_Location->town, ENT_QUOTES); ?>" />
214
- <p><?php _e ( 'The town where the location is located. If you\'re using the Google Map integration and want to avoid geotagging ambiguities include the country in the town field. Example: Verona, Italy.', 'dbem' )?></p>
215
- </td>
216
- </tr>
217
- </table>
218
- </td>
219
- <?php if ( get_option ( 'dbem_gmap_is_active' ) ) : ?>
220
- <td width="400">
221
- <div id='em-map-404' style='width: 400px; vertical-align:middle; text-align: center;'>
222
- <p><em><?php _e ( 'Location not found', 'dbem' ); ?></em></p>
223
- </div>
224
- <div id='em-map' style='width: 400px; height: 300px; display: none;'></div>
225
- </td>
226
- <?php endif; ?>
227
- </tr>
228
- </table>
229
- </div>
230
- </div>
231
-
232
- <div id="location_description" class="postbox">
233
- <h3>
234
- <?php _e ( 'Details', 'dbem' ); ?>
235
- </h3>
236
- <div class="inside">
237
- <div id="<?php echo user_can_richedit() ? 'postdivrich' : 'postdiv'; ?>" class="postarea">
238
- <?php the_editor($EM_Location->description ); ?>
239
- </div>
240
- <br />
241
- <?php _e ( 'Details about the location', 'dbem' )?>
242
- </div>
243
- </div>
244
-
245
- <div id="location_description" class="stuffbox">
246
- <h3>
247
- <?php _e ( 'Location image', 'dbem' ); ?>
248
- </h3>
249
- <div class="inside" style="padding:10px;">
250
- <?php if ($EM_Location->image_url != '') : ?>
251
- <img src='<?php echo $EM_Location->image_url; ?>' alt='<?php echo $EM_Location->name ?>'/>
252
- <?php else : ?>
253
- <?php _e('No image uploaded for this location yet', 'debm') ?>
254
- <?php endif; ?>
255
- <br /><br />
256
- <label for='location_image'><?php _e('Upload/change picture', 'dbem') ?></label> <input id='location-image' name='location_image' id='location_image' type='file' size='40' />
257
- </div>
258
- </div>
259
- </div>
260
- </div>
261
- </div>
262
- <p class='submit'><input type='submit' class='button-primary' name='submit' value='<?php _e('Update location', 'dbem') ?>' /></p>
263
- </div>
264
- </form>
265
- <?php
266
- }
267
-
268
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/em-ms-locations.php ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Looks at the request values, saves/updates and then displays the right menu in the admin
4
+ * @return null
5
+ */
6
+ function em_admin_ms_locations() {
7
+ //TODO EM_Location is globalized, use it fully here
8
+ global $EM_Location;
9
+ EM_Object::ms_global_switch();
10
+ //Take actions
11
+ if( !empty($_REQUEST['action']) && ($_REQUEST['action'] == "edit" || $_REQUEST['action'] == "location_save")) {
12
+ em_admin_location();
13
+ } else {
14
+ // no action, just a locations list
15
+ em_admin_locations();
16
+ }
17
+ EM_Object::ms_global_switch_back();
18
+ }
19
+
20
+ function em_admin_locations($message='', $fill_fields = false) {
21
+ global $current_site;
22
+ ?>
23
+ <div class='wrap'>
24
+ <div id='icon-edit' class='icon32'>
25
+ <br/>
26
+ </div>
27
+ <h2>
28
+ <?php _e('Locations', 'dbem'); ?>
29
+ <span><a href="<?php echo em_add_get_params($_SERVER['REQUEST_URI'], array('action'=>'edit')); ?>" class="button add-new-h2"><?php _e('Add New','dbem'); ?></a></span>
30
+ </h2>
31
+ <?php em_locate_template('tables/locations.php',true, array('url' => $_SERVER['REQUEST_URI'])); ?>
32
+ </div>
33
+ <?php
34
+ }
35
+
36
+ function em_admin_location($message = "") {
37
+ global $EM_Location, $EM_Notices;
38
+ if( empty($EM_Location) || !is_object($EM_Location) ){
39
+ $title = __('Add location', 'dbem');
40
+ $EM_Location = new EM_Location();
41
+ }else{
42
+ $title = __('Edit location', 'dbem');
43
+ }
44
+ ?>
45
+ <div class='wrap'>
46
+ <div id='icon-edit' class='icon32'>
47
+ <br/>
48
+ </div>
49
+ <h2><?php echo $title ?></h2>
50
+ <?php em_locate_template('forms/location-editor.php', true); ?>
51
+ </div>
52
+ <?php
53
+ }
54
+
55
+ ?>
admin/em-ms-options.php ADDED
@@ -0,0 +1,212 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ function em_ms_upgrade( $blog_id ){
3
+ ?>
4
+ <div class="wrap">
5
+ <div id='icon-options-general' class='icon32'><br /></div>
6
+ <h2><?php _e('Update Network'); ?></h2>
7
+ <?php
8
+ if( $_REQUEST['action'] == 'upgrade' && check_admin_referer('em_ms_ugrade_'.get_current_user_id()) ){
9
+ global $current_site,$wpdb;
10
+ $blog_ids = $wpdb->get_col('SELECT blog_id FROM '.$wpdb->blogs.' WHERE site_id='.$current_site->id);
11
+ foreach($blog_ids as $blog_id){
12
+ switch_to_blog($blog_id);
13
+ if( EM_VERSION > get_option('dbem_version', 0) ){
14
+ require_once( dirname(__FILE__).'/../em-install.php');
15
+ em_install();
16
+ echo "<p>Upgraded - ".get_bloginfo('blogname')."</p>";
17
+ }
18
+ restore_current_blog();
19
+ }
20
+ echo "<p>Done Upgrading</p>";
21
+ }else{
22
+ ?>
23
+ <form action="" method="post">
24
+ <p><?php _e('To update your network blogs with the latest Events Manager automatically, click the update button below.'); ?></p>
25
+ <input type="hidden" name="_wpnonce" value="<?php echo wp_create_nonce('em_ms_ugrade_'.get_current_user_id()); ?>" />
26
+ <input type="hidden" name="action" value="upgrade" />
27
+ <input type="submit" value="<?php _e('Update','dbem'); ?>" />
28
+ </form>
29
+ <?php
30
+ }
31
+ ?>
32
+ </div>
33
+ <?php
34
+ }
35
+
36
+ /**
37
+ * Displays network-related options in the network admin section
38
+ * @uses em_options_save() to save settings
39
+ */
40
+ function em_ms_admin_options_page() {
41
+ global $wpdb,$EM_Notices;
42
+ //Check for uninstall/reset request
43
+ if( !empty($_REQUEST['action']) && $_REQUEST['action'] == 'uninstall' ){
44
+ em_admin_options_uninstall_page();
45
+ return;
46
+ }
47
+ if( !empty($_REQUEST['action']) && $_REQUEST['action'] == 'reset' ){
48
+ em_admin_options_reset_page();
49
+ return;
50
+ }
51
+ //TODO place all options into an array
52
+ $events_placeholders = '<a href="'.EM_ADMIN_URL .'&amp;events-manager-help#event-placeholders">'. __('Event Related Placeholders','dbem') .'</a>';
53
+ $locations_placeholders = '<a href="'.EM_ADMIN_URL .'&amp;events-manager-help#location-placeholders">'. __('Location Related Placeholders','dbem') .'</a>';
54
+ $bookings_placeholders = '<a href="'.EM_ADMIN_URL .'&amp;events-manager-help#booking-placeholders">'. __('Booking Related Placeholders','dbem') .'</a>';
55
+ $categories_placeholders = '<a href="'.EM_ADMIN_URL .'&amp;events-manager-help#category-placeholders">'. __('Category Related Placeholders','dbem') .'</a>';
56
+ $events_placeholder_tip = " ". sprintf(__('This accepts %s and %s placeholders.','dbem'),$events_placeholders, $locations_placeholders);
57
+ $locations_placeholder_tip = " ". sprintf(__('This accepts %s placeholders.','dbem'), $locations_placeholders);
58
+ $categories_placeholder_tip = " ". sprintf(__('This accepts %s placeholders.','dbem'), $categories_placeholders);
59
+ $bookings_placeholder_tip = " ". sprintf(__('This accepts %s, %s and %s placeholders.','dbem'), $bookings_placeholders, $events_placeholders, $locations_placeholders);
60
+
61
+ $save_button = '<tr><th>&nbsp;</th><td><p class="submit" style="margin:0px; padding:0px; text-align:right;"><input type="submit" id="dbem_options_submit" name="Submit" value="'. __( 'Save Changes', 'dbem') .' ('. __('All','dbem') .')" /></p></ts></td></tr>';
62
+ //Do some multisite checking here for reuse
63
+ ?>
64
+ <script type="text/javascript" charset="utf-8">
65
+ jQuery(document).ready(function($){
66
+ var close_text = '<?php _e('Collapse All','dbem'); ?>';
67
+ var open_text = '<?php _e('Expand All','dbem'); ?>';
68
+ var open_close = $('<a href="#" style="display:block; float:right; clear:right; margin:10px;">'+open_text+'</a>');
69
+ $('#em-options-title').before(open_close);
70
+ open_close.click( function(e){
71
+ e.preventDefault();
72
+ if($(this).text() == close_text){
73
+ $(".postbox").addClass('closed');
74
+ $(this).text(open_text);
75
+ }else{
76
+ $(".postbox").removeClass('closed');
77
+ $(this).text(close_text);
78
+ }
79
+ });
80
+ $(".postbox > h3").click(function(){ $(this).parent().toggleClass('closed'); });
81
+ $(".postbox").addClass('closed');
82
+ //MS Mode selection hiders
83
+ $('input[name="dbem_ms_global_table"]').change(function(){ //global
84
+ if( $('input:radio[name="dbem_ms_global_table"]:checked').val() == 1 ){
85
+ $("tbody.em-global-options").show();
86
+ $('input:radio[name="dbem_ms_mainblog_locations"]:checked').trigger('change');
87
+ }else{
88
+ $("tbody.em-global-options").hide();
89
+ }
90
+ }).first().trigger('change');
91
+ //events
92
+ $('input[name="dbem_ms_global_events"]').change(function(){
93
+ if( $('input:radio[name="dbem_ms_global_events"]:checked').val() == 1 ){
94
+ $("tr#dbem_ms_global_events_links_row").show();
95
+ $('input:radio[name="dbem_ms_global_events_links"]:checked').trigger('change');
96
+ }else{
97
+ $("tr#dbem_ms_global_events_links_row, tr#dbem_ms_events_slug_row").hide();
98
+ }
99
+ }).first().trigger('change');
100
+ $('input[name="dbem_ms_global_events_links"]').change(function(){
101
+ if( $('input:radio[name="dbem_ms_global_events_links"]:checked').val() == 1 ){
102
+ $("tr#dbem_ms_events_slug_row").hide();
103
+ }else{
104
+ $("tr#dbem_ms_events_slug_row").show();
105
+ }
106
+ }).first().trigger('change');
107
+ //locations
108
+ $('input[name="dbem_ms_mainblog_locations"]').change(function(){
109
+ if( $('input:radio[name="dbem_ms_mainblog_locations"]:checked').val() == 1 ){
110
+ $("tbody.em-global-locations").hide();
111
+ }else{
112
+ $("tbody.em-global-locations").show();
113
+ }
114
+ }).first().trigger('change');
115
+ $('input[name="dbem_ms_global_locations"]').change(function(){
116
+ if( $('input:radio[name="dbem_ms_global_locations"]:checked').val() == 1 ){
117
+ $("tr#dbem_ms_global_locations_links_row").show();
118
+ $('input:radio[name="dbem_ms_global_locations_links"]:checked').trigger('change');
119
+ }else{
120
+ $("tr#dbem_ms_global_locations_links_row, tr#dbem_ms_locations_slug_row").hide();
121
+ }
122
+ }).first().trigger('change');
123
+ $('input[name="dbem_ms_global_locations_links"]').change(function(){
124
+ if( $('input:radio[name="dbem_ms_global_locations_links"]:checked').val() == 1 ){
125
+ $("tr#dbem_ms_locations_slug_row").hide();
126
+ }else{
127
+ $("tr#dbem_ms_locations_slug_row").show();
128
+ }
129
+ });
130
+ });
131
+ </script>
132
+ <style type="text/css">.postbox h3 { cursor:pointer; }</style>
133
+ <div class="wrap">
134
+ <div id='icon-options-general' class='icon32'><br /></div>
135
+ <h2 class="nav-tab-wrapper">
136
+ <a href="#" id="em-menu-general" class="nav-tab nav-tab-active"><?php _e('General','dbem'); ?></a>
137
+ </h2>
138
+ <h3 id="em-options-title"><?php _e ( 'Event Manager Options', 'dbem' ); ?></h3>
139
+ <?php echo $EM_Notices; ?>
140
+ <form id="em-options-form" method="post" action="">
141
+ <div class="metabox-holder">
142
+ <!-- // TODO Move style in css -->
143
+ <div class='postbox-container' style='width: 99.5%'>
144
+ <div id="">
145
+
146
+ <div class="em-menu-general em-menu-group">
147
+ <div class="postbox " >
148
+ <div class="handlediv" title="<?php __('Click to toggle', 'dbem'); ?>"><br /></div><h3><span><?php _e ( 'Multi Site Options', 'dbem' ); ?></span></h3>
149
+ <div class="inside">
150
+ <table class="form-table">
151
+ <?php
152
+ em_options_radio_binary ( __( 'Enable global tables mode?', 'dbem'), 'dbem_ms_global_table', __( 'Setting this to yes will make all events save in the main site event tables (EM must also be activated). This allows you to share events across different blogs, such as showing events in your network whilst allowing users to display and manage their events within their own blog. Bear in mind that activating this will mean old events created on the sub-blogs will not be accessible anymore, and if you switch back they will be but new events created during global events mode will only remain on the main site.','dbem' ) );
153
+ ?>
154
+ <tbody class="em-global-options">
155
+ <?php
156
+ global $current_site;
157
+ $global_slug_tip = __('%s belonging to other sub-sites will have an extra slug preppended to it so that your main site can differentiate between its own %s and those belonging to other sites in your network.');
158
+ $global_link_tip = __( 'When displaying global %s on the main site you have the option of users viewing the %s details on the main site or being directed to the sub-site.','dbem' );
159
+ $global_post_tip = __( 'Displays %s from all sites on the network by default. You can still restrict %s by blog using shortcodes and template tags coupled with the <code>blog</code> attribute. Requires global tables to be turned on.','dbem');
160
+ $global_link_tip2 = __('You <strong>must</strong> have assigned a %s page in your <a href="%s">main blog settings</a> for this to work.');
161
+ $options_page_link = get_admin_url($current_site->blog_id, 'edit.php?post_type=event&page=events-manager-options#pages');
162
+ ?><tr><td><strong><?php echo sprintf(__('%s Options','dbem'),__('Event','dbem')); ?></strong></td></tr><?php
163
+ em_options_radio_binary ( sprintf(__( 'Display global events on main blog?', 'dbem'), __('events','dbem')), 'dbem_ms_global_events', sprintf($global_post_tip, __('events','dbem'), __('events','dbem')) );
164
+ em_options_radio_binary ( sprintf(__( 'Link sub-site %s directly to sub-site?', 'dbem'), __('events','dbem')), 'dbem_ms_global_events_links', sprintf($global_link_tip, __('events','dbem'), __('event','dbem')).sprintf($global_link_tip2, __('event','dbem'), $options_page_link) );
165
+ em_options_input_text ( sprintf(__( 'Global %s slug', 'dbem' ),__('event','dbem')), 'dbem_ms_events_slug', sprintf($global_slug_tip, __('Events','dbem'), __('events','dbem')).__('Example:','dbem').'<code>http://yoursite.com/events/<strong>event</strong>/subsite-event-slug/', EM_EVENT_SLUG );
166
+ ?><tr><td><strong><?php echo sprintf(__('%s Options','dbem'),__('Location','dbem')); ?></strong></td></tr><?php
167
+ em_options_radio_binary ( sprintf(__( 'Locations on main blog?', 'dbem'), __('locations','dbem')), 'dbem_ms_mainblog_locations', __('If you would prefer all your locations to belong to your main blog, users in sub-sites will still be able to create locations, but the actual locations are created and reside in the main blog.','dbem') );
168
+ ?>
169
+ </tbody>
170
+ <tbody class="em-global-options em-global-locations">
171
+ <?php
172
+ em_options_radio_binary ( sprintf(__( 'Display global %s on main blog?', 'dbem'), __('locations','dbem')), 'dbem_ms_global_locations', sprintf($global_post_tip, __('locations','dbem'), __('locations','dbem')) );
173
+ em_options_radio_binary ( sprintf(__( 'Link sub-site %s directly to sub-site?', 'dbem'), __('locations','dbem')), 'dbem_ms_global_locations_links', sprintf($global_link_tip, __('locations','dbem'), __('location','dbem')).sprintf($global_link_tip2, __('location','dbem'), $options_page_link) );
174
+ em_options_input_text ( sprintf(__( 'Global %s slug', 'dbem' ),__('event','dbem')), 'dbem_ms_locations_slug', sprintf($global_slug_tip, __('Locations','dbem'), __('locations','dbem')).__('Example:','dbem').'<code>http://yoursite.com/locations/<strong>location</strong>/subsite-location-slug/', EM_LOCATION_SLUG );
175
+ ?>
176
+ </tbody>
177
+ <?php echo $save_button; ?>
178
+ </table>
179
+
180
+ </div> <!-- . inside -->
181
+ </div> <!-- .postbox -->
182
+
183
+ <?php
184
+ //including shared MS/non-MS boxes
185
+ em_admin_option_box_caps();
186
+ em_admin_option_box_image_sizes();
187
+ em_admin_option_box_email();
188
+ em_admin_option_box_uninstall();
189
+ ?>
190
+
191
+ <?php do_action('em_ms_options_page_footer'); ?>
192
+ </div> <!-- .em-menu-general -->
193
+
194
+ <div class="em-menu-pages em-menu-group" style="display:none;">
195
+
196
+ </div> <!-- .em-menu-pages -->
197
+
198
+ <p class="submit">
199
+ <input type="submit" id="dbem_options_submit" name="Submit" value="<?php _e ( 'Save Changes' )?>" />
200
+ <input type="hidden" name="em-submitted" value="1" />
201
+ <input type="hidden" name="_wpnonce" value="<?php echo wp_create_nonce('events-manager-options'); ?>" />
202
+ </p>
203
+
204
+ </div> <!-- .metabox-sortables -->
205
+ </div> <!-- .postbox-container -->
206
+
207
+ </div> <!-- .metabox-holder -->
208
+ </form>
209
+ </div>
210
+ <?php
211
+ }
212
+ ?>
admin/em-options.php CHANGED
@@ -1,444 +1,1690 @@
1
- <?php
2
-
3
- //Function composing the options subpanel
4
- function em_options_save(){
5
- if( current_user_can('activate_plugins') && !empty($_POST['em-submitted']) ){
6
- //Build the array of options here
7
- $post = $_POST;
8
- foreach ($_POST as $postKey => $postValue){
9
- if( substr($postKey, 0, 5) == 'dbem_' ){
10
- //TODO some more validation/reporting
11
- $numeric_options = array('dbem_locations_default_limit','dbem_events_default_limit');
12
- if( in_array($postKey,$numeric_options) && !is_numeric($postValue) ){
13
- //Do nothing, keep old setting.
14
- }else{
15
- //TODO slashes being added?
16
- //$postValue = EM_Object::sanitize($postValue)
17
- update_option($postKey, stripslashes($postValue));
18
- }
19
- }
20
- }
21
- function em_options_saved_notice(){
22
- ?>
23
- <div class="updated"><p><strong><?php _e('Changes saved.'); ?></strong></p></div>
24
- <?php
25
- }
26
- add_action ( 'admin_notices', 'em_options_saved_notice' );
27
- }
28
- }
29
- add_action('admin_head', 'em_options_save');
30
-
31
-
32
-
33
- function em_admin_options_page() {
34
- //TODO place all options into an array
35
- $events_placeholders = '<a href="admin.php?page=events-manager-help#event-placeholders">'. __('Event Related Placeholders','dbem') .'</a>';
36
- $locations_placeholders = '<a href="admin.php?page=events-manager-help#location-placeholders">'. __('Location Related Placeholders','dbem') .'</a>';
37
- $bookings_placeholders = '<a href="admin.php?page=events-manager-help#booking-placeholders">'. __('Booking Related Placeholders','dbem') .'</a>';
38
- $events_placeholder_tip = " ". sprintf(__('This accepts %s and %s placeholders.','dbem'),$events_placeholders, $locations_placeholders);
39
- $locations_placeholder_tip = " ". sprintf(__('This accepts %s placeholders.','dbem'), $locations_placeholders);
40
- $bookings_placeholder_tip = " ". sprintf(__('This accepts %s, %s and %s placeholders.','dbem'), $bookings_placeholders, $events_placeholders, $locations_placeholders);
41
-
42
- $save_button = '<tr><th>&nbsp;</th><td><p class="submit" style="margin:0px; padding:0px; text-align:right;"><input type="submit" id="dbem_options_submit" name="Submit" value="'. __( 'Save Changes' ) .' ('. __('All','dbem') .')" /></p></ts></td></tr>';
43
- ?>
44
- <script type="text/javascript" charset="utf-8">
45
- jQuery(document).ready(function($){
46
- var close_text = '<?php _e('Collapse All','dbem'); ?>';
47
- var open_text = '<?php _e('Expand All','dbem'); ?>';
48
- var open_close = $('<a href="#" style="display:block; float:right; clear:right; margin:10px;">'+close_text+'</a>');
49
- $('#icon-options-general').after(open_close);
50
- open_close.click( function(e){
51
- e.preventDefault();
52
- if($(this).text() == close_text){
53
- $(".postbox").addClass('closed');
54
- $(this).text(open_text);
55
- }else{
56
- $(".postbox").removeClass('closed');
57
- $(this).text(close_text);
58
- }
59
- });
60
- //For rewrite titles
61
- $('input:radio[name=dbem_disable_title_rewrites]').live('change',function(){
62
- checked_check = $('input:radio[name=dbem_disable_title_rewrites]:checked');
63
- if( checked_check.val() == 1 ){
64
- $('#dbem_title_html_row').show();
65
- }else{
66
- $('#dbem_title_html_row').hide();
67
- }
68
- });
69
- $('input:radio[name=dbem_disable_title_rewrites]').trigger('change');
70
-
71
- });
72
- </script>
73
- <div class="wrap">
74
- <div id='icon-options-general' class='icon32'><br />
75
- </div>
76
- <h2><?php _e ( 'Event Manager Options', 'dbem' ); ?></h2>
77
-
78
- <form id="dbem_options_form" method="post" action="">
79
-
80
- <div class="metabox-holder">
81
- <!-- // TODO Move style in css -->
82
- <div class='postbox-container' style='width: 99.5%'>
83
- <div id="" class="meta-box-sortables" >
84
-
85
- <div class="postbox " >
86
- <div class="handlediv" title="<?php __('Click to toggle'); ?>"><br /></div><h3 class='hndle'><span><?php _e ( 'General options', 'dbem' ); ?> </span></h3>
87
- <div class="inside">
88
- <table class="form-table">
89
- <?php
90
- em_options_radio_binary ( __( 'Use dropdown for locations?' ), 'dbem_use_select_for_locations', __( 'Select yes to select location from a drow-down menu; location selection will be faster, but you will lose the ability to insert locations with events','dbem' ) );
91
- em_options_radio_binary ( __( 'Use recurrence?' ), 'dbem_recurrence_enabled', __( 'Select yes to enable the recurrence features feature','dbem' ) );
92
- em_options_radio_binary ( __( 'Use RSVP?' ), 'dbem_rsvp_enabled', __( 'Select yes to enable the RSVP feature','dbem' ) );
93
- em_options_radio_binary ( __( 'Use categories?' ), 'dbem_categories_enabled', __( 'Select yes to enable the category features','dbem' ) );
94
- em_options_radio_binary ( __( 'Use attributes?' ), 'dbem_attributes_enabled', __( 'Select yes to enable the attributes feature','dbem' ) );
95
-
96
- /*default category*/
97
- $category_options = array();
98
- $category_options[0] = __('no default category','dbem');
99
- $EM_Categories = EM_Categories::get();
100
- foreach($EM_Categories as $EM_Category){
101
- $category_options[$EM_Category->id] = $EM_Category->name;
102
- }
103
- em_options_select ( __( 'Default Category' ), 'dbem_default_category', $category_options, __( 'This option allows you to select the default category when adding an event.','dbem' )." ".__('(not applicable with event ownership on presently, coming soon!)','dbem') );
104
-
105
- /*default location*/
106
- $location_options = array();
107
- $location_options[0] = __('no default location','dbem');
108
- $EM_Locations = EM_Locations::get();
109
- foreach($EM_Locations as $EM_Location){
110
- $location_options[$EM_Location->id] = $EM_Location->name;
111
- }
112
- em_options_select ( __( 'Default Location' ), 'dbem_default_location', $location_options, __( 'This option allows you to select the default location when adding an event.','dbem' )." ".__('(not applicable with event ownership on presently, coming soon!)','dbem') );
113
-
114
- em_options_textarea ( __( 'Custom Placeholders', 'dbem' ), 'dbem_placeholders_custom', sprintf(__( "You can add custom placeholders here, one per line in this format <code>#_ATT{key}</code>. They will not appear on event pages unless you insert them into another template below, but you may want to store extra information about an event for other uses. <a href='%s'>More information on placeholders.</a>", 'dbem' ), 'wp-events-plugin.com/documentation/the-em-templates-syntax/') );
115
-
116
- echo $save_button;
117
- ?>
118
- </table>
119
-
120
- </div> <!-- . inside -->
121
- </div> <!-- .postbox -->
122
-
123
- <div class="postbox " >
124
- <div class="handlediv" title="<?php __('Click to toggle'); ?>"><br /></div><h3 class='hndle'><span><?php _e ( 'Events page', 'dbem' ); ?> </span></h3>
125
- <div class="inside">
126
- <table class="form-table">
127
- <?php
128
- //Wordpress Pages
129
- global $em_disable_filter; //Using a flag here instead
130
- $em_disable_filter = true;
131
- $get_pages = get_pages();
132
- $events_page_options = array();
133
- $events_page_options[0] = __('[No Events Page]');
134
- //TODO Add the hierarchy style ddm, like when choosing page parents
135
- foreach($get_pages as $page){
136
- $events_page_options[$page->ID] = $page->post_title;
137
- }
138
- em_options_select ( __( 'Events page' ), 'dbem_events_page', $events_page_options, __( 'This option allows you to select which page to use as an events page','dbem' ) );
139
- $em_disable_filter = false;
140
- //Rest
141
- em_options_radio_binary ( __( 'Show events page in lists?', 'dbem' ), 'dbem_list_events_page', __( 'Check this option if you want the events page to appear together with other pages in pages lists.', 'dbem' ) );
142
- em_options_radio_binary ( __( 'Display calendar in events page?', 'dbem' ), 'dbem_display_calendar_in_events_page', __( 'This options allows to display the calendar in the events page, instead of the default list. It is recommended not to display both the calendar widget and a calendar page.','dbem' ).' '.__('If you would like to show events that span over more than one day, see the Calendar section on this page.','dbem') );
143
- em_options_radio_binary ( __( 'Disable title rewriting?', 'dbem' ), 'dbem_disable_title_rewrites', __( "Some wordpress themes don't follow best practices when generating navigation menus, and so the automatic title rewriting feature may cause problems, if your menus aren't working correctly on the event pages, try setting this to 'Yes', and provide an appropriate HTML title format below.",'dbem' ) );
144
- em_options_input_text ( __( 'Event Manager titles', 'dbem' ), 'dbem_title_html', __( "This only setting only matters if you selected 'Yes' to above. You will notice the events page titles aren't being rewritten, and you have a new title underneath the default page name. This is where you control the HTML of this title. Make sure you keep the #_PAGETITLE placeholder here, as that's what is rewritten by events manager. To control what's rewritten in this title, see settings further down for page titles.", 'dbem' ) );
145
- em_options_input_text ( __( 'Event List Limits', 'dbem' ), 'dbem_events_default_limit', __( "This will control how many events are shown on one list by default.", 'dbem' ) );
146
- ?>
147
- <tr valign="top" id='dbem_events_default_orderby_row'>
148
- <th scope="row"><?php _e('Default event list ordering','dbem'); ?></th>
149
- <td>
150
- <select name="dbem_events_default_orderby" >
151
- <?php
152
- $orderby_options = apply_filters('em_settings_events_default_orderby_ddm', array(
153
- 'start_date,start_time,name' => __('Order by start date, start time, then event name','dbem'),
154
- 'name,start_date,start_time' => __('Order by name, start date, then start time','dbem'),
155
- 'name,end_date,end_time' => __('Order by name, end date, then end time','dbem'),
156
- 'end_date,end_time,name' => __('Order by end date, end time, then event name','dbem'),
157
- ));
158
- ?>
159
- <?php foreach($orderby_options as $key => $value) : ?>
160
- <option value='<?php echo $key ?>' <?php echo ($key == get_option('dbem_events_default_orderby')) ? "selected='selected'" : ''; ?>>
161
- <?php echo $value; ?>
162
- </option>
163
- <?php endforeach; ?>
164
- </select>
165
- <select name="dbem_events_default_order" >
166
- <?php
167
- $ascending = __('Ascending','dbem');
168
- $descending = __('Descending','dbem');
169
- $order_options = apply_filters('em_settings_events_default_order_ddm', array(
170
- 'ASC' => __('All Ascending','dbem'),
171
- 'DESC,ASC,ASC' => __("$descending, $ascending, $ascending",'dbem'),
172
- 'DESC,DESC,ASC' => __("$descending, $descending, $ascending",'dbem'),
173
- 'DESC' => __('All Descending','dbem'),
174
- 'ASC,DESC,ASC' => __("$ascending, $descending, $ascending",'dbem'),
175
- 'ASC,DESC,DESC' => __("$ascending, $descending, $descending",'dbem'),
176
- 'ASC,ASC,DESC' => __("$ascending, $ascending, $descending",'dbem'),
177
- 'DESC,ASC,DESC' => __("$descending, $ascending, $descending",'dbem'),
178
- ));
179
- ?>
180
- <?php foreach( $order_options as $key => $value) : ?>
181
- <option value='<?php echo $key ?>' <?php echo ($key == get_option('dbem_events_default_order')) ? "selected='selected'" : ''; ?>>
182
- <?php echo $value; ?>
183
- </option>
184
- <?php endforeach; ?>
185
- </select>
186
- <br/>
187
- <em><?php _e('When Events Manager displays lists of events the default behaviour is ordering by start date in ascending order. To change this, modify the values above.','dbem'); ?></em>
188
- </td>
189
- </tr>
190
- <tr valign="top" id='dbem_events_display_time_limit'>
191
- <th scope="row"><?php _e('Event list range limit','dbem'); ?></th>
192
- <td>
193
- <select name="dbem_events_page_time_limit" >
194
- <?php
195
- $limit_options = apply_filters('em_settings_events_page_time_limit_ddm', array(
196
- '0' => __('no limit','dbem'),
197
- '1' => __('This month','dbem'),
198
- '2' => __('Next two months','dbem'),
199
- '3' => __('Next three months','dbem'),
200
- '6' => __('Next six months','dbem'),
201
- '12' => __('Next twelve months','dbem')
202
- ));
203
- ?>
204
- <?php foreach( $limit_options as $key => $value) : ?>
205
- <option value='<?php echo $key ?>' <?php echo ($key == get_option('dbem_events_page_time_limit')) ? "selected='selected'" : ''; ?>>
206
- <?php echo $value; ?>
207
- </option>
208
- <?php endforeach; ?>
209
- </select>
210
- <br />
211
- <em><?php _e('Only show events starting within a certain time limit on the events page. Default is no time limit is applied.','dbem'); ?></em>
212
- </td>
213
- </tr>
214
- <?php
215
- echo $save_button;
216
- ?>
217
- </table>
218
- </div> <!-- . inside -->
219
- </div> <!-- .postbox -->
220
-
221
- <div class="postbox " >
222
- <div class="handlediv" title="<?php __('Click to toggle'); ?>"><br /></div><h3 class='hndle'><span><?php _e ( 'Events format', 'dbem' ); ?> </span></h3>
223
- <div class="inside">
224
- <table class="form-table">
225
- <?php
226
- em_options_textarea ( __( 'Default event list format header', 'dbem' ), 'dbem_event_list_item_format_header', __( 'This content will appear just above your code for the default event list format. Default is blank', 'dbem' ) );
227
- em_options_textarea ( __( 'Default event list format', 'dbem' ), 'dbem_event_list_item_format', __( 'The format of any events in a list.', 'dbem' ).$events_placeholder_tip );
228
- em_options_textarea ( __( 'Default event list format footer', 'dbem' ), 'dbem_event_list_item_format_footer', __( 'This content will appear just below your code for the default event list format. Default is blank', 'dbem' ) );
229
- em_options_input_text ( __( 'Single event page title format', 'dbem' ), 'dbem_event_page_title_format', __( 'The format of a single event page title.', 'dbem' ).$events_placeholder_tip );
230
- em_options_textarea ( __( 'Default single event format', 'dbem' ), 'dbem_single_event_format', __( 'The format of a single event page.', 'dbem' ).$events_placeholder_tip );
231
- em_options_input_text ( __( 'Events page title', 'dbem' ), 'dbem_events_page_title', __( 'The title on the multiple events page.', 'dbem' ) );
232
- em_options_input_text ( __( 'No events message', 'dbem' ), 'dbem_no_events_message', __( 'The message displayed when no events are available.', 'dbem' ) );
233
- em_options_input_text ( __( 'List events by date title', 'dbem' ), 'dbem_list_date_title', __( 'If viewing a page for events on a specific date, this is the title that would show up. To insert date values, use <a href="http://www.php.net/manual/en/function.date.php">PHP time format characters</a> with a <code>#</code> symbol before them, i.e. <code>#m</code>, <code>#M</code>, <code>#j</code>, etc.<br/>', 'dbem' ) );
234
- echo $save_button;
235
- ?>
236
- </table>
237
- </div> <!-- . inside -->
238
- </div> <!-- .postbox -->
239
-
240
- <div class="postbox " >
241
- <div class="handlediv" title="<?php __('Click to toggle'); ?>"><br /></div><h3 class='hndle'><span><?php _e ( 'Calendar format', 'dbem' ); ?></span></h3>
242
- <div class="inside">
243
- <table class="form-table">
244
- <?php
245
- em_options_input_text ( __( 'Small calendar title', 'dbem' ), 'dbem_small_calendar_event_title_format', __( 'The format of the title, corresponding to the text that appears when hovering on an eventful calendar day.', 'dbem' ).$events_placeholder_tip );
246
- em_options_input_text ( __( 'Small calendar title separator', 'dbem' ), 'dbem_small_calendar_event_title_separator', __( 'The separator appearing on the above title when more than one events are taking place on the same day.', 'dbem' ) );
247
- em_options_input_text ( __( 'Full calendar events format', 'dbem' ), 'dbem_full_calendar_event_format', __( 'The format of each event when displayed in the full calendar. Remember to include <code>li</code> tags before and after the event.', 'dbem' ).$events_placeholder_tip );
248
- em_options_radio_binary ( __( 'Show long events on calendar pages?', 'dbem' ), 'dbem_full_calendar_long_events', __( "If you are showing a calendar on the events page (see Events format section on this page), you have the option of showing events that span over days on each day it occurs.",'dbem' ) );
249
- em_options_radio_binary ( __( 'Show list on day with single event?', 'dbem' ), 'dbem_display_calendar_day_single', __( "By default, if a calendar day only has one event, it display a single event when clicking on the link of that calendar date. If you select Yes here, you will get always see a list of events.",'dbem' ) );
250
- echo $save_button;
251
- ?>
252
- </table>
253
- </div> <!-- . inside -->
254
- </div> <!-- .postbox -->
255
-
256
- <div class="postbox " >
257
- <div class="handlediv" title="<?php __('Click to toggle'); ?>"><br /></div><h3 class='hndle'><span><?php _e ( 'Locations format', 'dbem' ); ?> </span></h3>
258
- <div class="inside">
259
- <table class="form-table">
260
- <?php
261
- em_options_input_text ( __( 'Single location page title format', 'dbem' ), 'dbem_location_page_title_format', __( 'The format of a single location page title.', 'dbem' ).$locations_placeholder_tip );
262
- em_options_textarea ( __( 'Default single location page format', 'dbem' ), 'dbem_single_location_format', __( 'The format of a single location page.', 'dbem' ).$locations_placeholder_tip );
263
- em_options_textarea ( __( 'Default location balloon format', 'dbem' ), 'dbem_location_baloon_format', __( 'The format of of the text appearing in the baloon describing the location in the map.', 'dbem' ).$locations_placeholder_tip );
264
- em_options_textarea ( __( 'Default location event list format', 'dbem' ), 'dbem_location_event_list_item_format', __( 'The format of the events the list inserted in the location page through the <code>#_NEXTEVENTS</code>, <code>#_PASTEVENTS</code> and <code>#_ALLEVENTS</code> element.', 'dbem' ).$locations_placeholder_tip );
265
- em_options_textarea ( __( 'Default no events message', 'dbem' ), 'dbem_location_no_events_message', __( 'The message to be displayed in the list generated by <code>#_NEXTEVENTS</code>, <code>#_PASTEVENTS</code> and <code>#_ALLEVENTS</code> when no events are available.', 'dbem' ) );
266
- echo $save_button;
267
- ?>
268
- </table>
269
- </div> <!-- . inside -->
270
- </div> <!-- .postbox -->
271
-
272
- <div class="postbox " >
273
- <div class="handlediv" title="<?php __('Click to toggle'); ?>"><br /></div><h3 class='hndle'><span><?php _e ( 'RSS feed format', 'dbem' ); ?> </span></h3>
274
- <div class="inside">
275
- <table class="form-table">
276
- <?php
277
- em_options_input_text ( __( 'RSS main title', 'dbem' ), 'dbem_rss_main_title', __( 'The main title of your RSS events feed.', 'dbem' ).$events_placeholder_tip );
278
- em_options_input_text ( __( 'RSS main description', 'dbem' ), 'dbem_rss_main_description', __( 'The main description of your RSS events feed.', 'dbem' ) );
279
- em_options_input_text ( __( 'RSS title format', 'dbem' ), 'dbem_rss_title_format', __( 'The format of the title of each item in the events RSS feed.', 'dbem' ).$events_placeholder_tip );
280
- em_options_input_text ( __( 'RSS description format', 'dbem' ), 'dbem_rss_description_format', __( 'The format of the description of each item in the events RSS feed.', 'dbem' ).$events_placeholder_tip );
281
- echo $save_button;
282
- ?>
283
- </table>
284
- </div> <!-- . inside -->
285
- </div> <!-- .postbox -->
286
-
287
- <div class="postbox " >
288
- <div class="handlediv" title="<?php __('Click to toggle'); ?>"><br /></div><h3 class='hndle'><span><?php _e ( 'Maps and geotagging', 'dbem' ); ?> </span></h3>
289
- <div class="inside">
290
- <table class='form-table'>
291
- <?php $gmap_is_active = get_option ( 'dbem_gmap_is_active' ); ?>
292
- <tr valign="top">
293
- <th scope="row"><?php _e ( 'Enable Google Maps integration?', 'dbem' ); ?></th>
294
- <td>
295
- <?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'":''; ?> />
296
- <?php _e ( 'No' ); ?> <input name="dbem_gmap_is_active" type="radio" value="0" <?php echo ($gmap_is_active) ? '':"checked='checked'"; ?> /><br />
297
- <em><?php _e ( 'Check this option to enable Goggle Map integration.', 'dbem' )?></em>
298
- </td>
299
- </tr>
300
- <?php
301
- em_options_textarea ( __( 'Map text format', 'dbem' ), 'dbem_map_text_format', __( 'The text format inside the map balloons.', 'dbem' ).$events_placeholder_tip );
302
- echo $save_button;
303
- ?>
304
- </table>
305
- </div> <!-- . inside -->
306
- </div> <!-- .postbox -->
307
-
308
- <div class="postbox " >
309
- <div class="handlediv" title="<?php __('Click to toggle'); ?>"><br /></div><h3 class='hndle'><span><?php _e ( 'RSVP and bookings', 'dbem' ); ?> </span></h3>
310
- <div class="inside">
311
- <table class='form-table'>
312
- <?php
313
- em_options_select ( __( 'Default contact person', 'dbem' ), 'dbem_default_contact_person', em_get_wp_users (), __( 'Select the default contact person. This user will be employed whenever a contact person is not explicitly specified for an event', 'dbem' ) );
314
- em_options_radio_binary ( __( 'Approval Required?', 'dbem' ), 'dbem_bookings_approval', __( 'Bookings will not be confirmed until the event administrator approves it.', 'dbem' ) );
315
- em_options_input_text ( __( 'Email events admin?', 'dbem' ), 'dbem_bookings_notify_admin', __( "If you would like every event booking confirmation email sent to an administrator write their email here (leave blank to not send an email).", 'dbem' ) );
316
- em_options_radio_binary ( __( 'Email contact person?', 'dbem' ), 'dbem_bookings_contact_email', __( 'Check this option if you want the event contact to receive an email when someone books places. An email will be sent when a booking is first made (regardless if confirmed or pending)', 'dbem' ) );
317
- ?>
318
- <tr><td colspan='2'><h4><?php _e('Contact person booking confirmed','dbem') ?></h4></td></tr>
319
- <tr><td colspan='2'><?php echo __('An email will be sent to the event contact when a booking is first made.','dbem').$bookings_placeholder_tip ?></td></tr>
320
- <?php
321
- em_options_input_text ( __( 'Contact person email subject', 'dbem' ), 'dbem_bookings_contact_email_subject', '' );
322
- em_options_textarea ( __( 'Contact person email', 'dbem' ), 'dbem_bookings_contact_email_body', '' );
323
- ?>
324
- <tr><td colspan='2'><h4><?php _e('Contact person booking cancelled','dbem') ?></h4></td></tr>
325
- <tr><td colspan='2'><?php echo __('An email will be sent to the event contact if someone cancels their booking.','dbem').$bookings_placeholder_tip ?></td></tr>
326
- <?php
327
- em_options_input_text ( __( 'Contact person cancellation subject', 'dbem' ), 'dbem_contactperson_email_cancelled_subject', '' );
328
- em_options_textarea ( __( 'Contact person cancellation email', 'dbem' ), 'dbem_contactperson_email_cancelled_body', '' );
329
- ?>
330
- <tr><td colspan='2'><h4><?php _e('Confirmed booking email','dbem') ?></h4></td></tr>
331
- <tr><td colspan='2'><?php echo __('This is sent when a person\'s booking is confirmed. This will be sent automatically if approvals are required and the booking is approved. If approvals are disabled, this is sent out when a user first submits their booking.','dbem').$bookings_placeholder_tip ?></td></tr>
332
- <?php
333
- em_options_input_text ( __( 'Booking confirmed email subject', 'dbem' ), 'dbem_bookings_email_confirmed_subject', '' );
334
- em_options_textarea ( __( 'Booking confirmed email', 'dbem' ), 'dbem_bookings_email_confirmed_body', '' );
335
- ?>
336
- <tr><td colspan='2'><h4><?php _e('Pending booking email','dbem') ?></h4></td></tr>
337
- <tr><td colspan='2'><?php echo __( 'This will be sent to the person when they first submit their booking. Not relevant if bookings don\'t require approval.', 'dbem' ).$bookings_placeholder_tip ?></td></tr>
338
- <?php
339
- em_options_input_text ( __( 'Booking pending email subject', 'dbem' ), 'dbem_bookings_email_pending_subject', '');
340
- em_options_textarea ( __( 'Booking pending email', 'dbem' ), 'dbem_bookings_email_pending_body','') ;
341
- ?>
342
- <tr><td colspan='2'><h4><?php _e('Rejected booking email','dbem') ?></h4></td></tr>
343
- <tr><td colspan='2'><?php echo __( 'This will be sent automatically when a booking is rejected. Not relevant if bookings don\'t require approval.', 'dbem' ).$bookings_placeholder_tip ?></td></tr>
344
- <?php
345
- em_options_input_text ( __( 'Booking rejected email subject', 'dbem' ), 'dbem_bookings_email_rejected_subject', __( "The subject of the email sent to the person making a booking that is awaiting administrator approval. Not relevant if bookings don't require approval.", 'dbem' ).$bookings_placeholder_tip );
346
- em_options_textarea ( __( 'Booking rejected email', 'dbem' ), 'dbem_bookings_email_rejected_body', __( 'The body of the email which will be sent to the person if the booking is rejected. Not relevant if bookings don\'t require approval.', 'dbem' ).$bookings_placeholder_tip );
347
- echo $save_button;
348
- ?>
349
- <tr><td colspan='2'><h4><?php _e('Booking cancelled','dbem') ?></h4></td></tr>
350
- <tr><td colspan='2'><?php echo __('This will be sent when a user cancels their booking.','dbem').$bookings_placeholder_tip ?></td></tr>
351
- <?php
352
- em_options_input_text ( __( 'Booking cancelled email subject', 'dbem' ), 'dbem_bookings_email_cancelled_subject', '' );
353
- em_options_textarea ( __( 'Booking cancelled email', 'dbem' ), 'dbem_bookings_email_cancelled_body', '' );
354
- ?>
355
- </table>
356
- </div> <!-- . inside -->
357
- </div> <!-- .postbox -->
358
-
359
- <div class="postbox " >
360
- <div class="handlediv" title="<?php __('Click to toggle'); ?>"><br /></div><h3 class='hndle'><span><?php _e ( 'Email Settings', 'dbem' ); ?> </span></h3>
361
- <div class="inside">
362
- <table class='form-table'>
363
- <?php
364
- em_options_input_text ( __( 'Notification sender name', 'dbem' ), 'dbem_mail_sender_name', __( "Insert the display name of the notification sender.", 'dbem' ) );
365
- em_options_input_text ( __( 'Notification sender address', 'dbem' ), 'dbem_mail_sender_address', __( "Insert the address of the notification sender.", 'dbem' ) );
366
- em_options_input_text ( 'Mail sending port', 'dbem_rsvp_mail_port', __( "The port through which you e-mail notifications will be sent. Make sure the firewall doesn't block this port", 'dbem' ) );
367
- em_options_select ( __( 'Mail sending method', 'dbem' ), 'dbem_rsvp_mail_send_method', array ('smtp' => 'SMTP', 'mail' => __( 'PHP mail function', 'dbem' ), 'sendmail' => 'Sendmail', 'qmail' => 'Qmail', 'wp_mail' => 'WP Mail' ), __( 'Select the method to send email notification.', 'dbem' ) );
368
- em_options_radio_binary ( __( 'Use SMTP authentication?', 'dbem' ), 'dbem_rsvp_mail_SMTPAuth', __( 'SMTP authentication is often needed. If you use GMail, make sure to set this parameter to Yes', 'dbem' ) );
369
- em_options_input_text ( 'SMTP host', 'dbem_smtp_host', __( "The SMTP host. Usually it corresponds to 'localhost'. If you use GMail, set this value to 'ssl://smtp.gmail.com:465'.", 'dbem' ) );
370
- em_options_input_text ( __( 'SMTP username', 'dbem' ), 'dbem_smtp_username', __( "Insert the username to be used to access your SMTP server.", 'dbem' ) );
371
- em_options_input_password ( __( 'SMTP password', 'dbem' ), "dbem_smtp_password", __( "Insert the password to be used to access your SMTP server", 'dbem' ) );
372
- echo $save_button;
373
- ?>
374
- </table>
375
- </div> <!-- . inside -->
376
- </div> <!-- .postbox -->
377
-
378
- <div class="postbox " >
379
- <div class="handlediv" title="<?php __('Click to toggle'); ?>"><br /></div><h3 class='hndle'><span><?php _e ( 'Images size', 'dbem' ); ?> </span></h3>
380
- <div class="inside">
381
- <table class='form-table'>
382
- <?php
383
- em_options_input_text ( __( 'Maximum width (px)', 'dbem' ), 'dbem_image_max_width', __( 'The maximum allowed width for images uploades', 'dbem' ) );
384
- em_options_input_text ( __( 'Maximum height (px)', 'dbem' ), 'dbem_image_max_height', __( "The maximum allowed height for images uploaded, in pixels", 'dbem' ) );
385
- em_options_input_text ( __( 'Maximum size (bytes)', 'dbem' ), 'dbem_image_max_size', __( "The maximum allowed size for images uploaded, in pixels", 'dbem' ) );
386
- echo $save_button;
387
- ?>
388
- </table>
389
- </div> <!-- . inside -->
390
- </div> <!-- .postbox -->
391
-
392
- <div class="postbox " >
393
- <div class="handlediv" title="<?php __('Click to toggle'); ?>"><br /></div><h3 class='hndle'><span><?php _e ( 'Management Permission Options', 'dbem' ); ?> (Beta)</span></h3>
394
- <div class="inside">
395
- <table class="form-table">
396
- <tr><td colspan="2">
397
- <strong><?php _e('Warning: Changing these values may result in exposing previously hidden information to all users.')?></strong><br />
398
- <em><?php _e('Note that currently "users" are considered as wordpress contributor users upwards, as they can create and manage events (we\'re working on that). Wordpress administrators can control all events/locations/categories/etc. on Events Manager.','dbem'); ?></em>
399
- </td></tr>
400
- <tr><th colspan="2"><strong><?php _e('Event Permissions','dbem'); ?></strong></th></tr>
401
- <?php
402
- $location_privacy_options = array(
403
- '0' => __('Every user can create and manage their own events. Users can\'t view or modify each others\' events and booking data','dbem'),
404
- '1' => __('Every user can create/edit/delete any event on this site. (not recommended)','dbem')
405
- );
406
- em_options_radio ( 'dbem_permissions_events', $location_privacy_options );
407
- ?>
408
- <tr><th colspan="2"><strong><?php _e('Location Permissions','dbem'); ?></strong></th></tr>
409
- <?php
410
- $location_privacy_options = array(
411
- '0' => __('Every user can create and manage their own location.','dbem')." ".__('In future releases of Events Manager, sharing locations with more than one user will be possible in this option, as well as connecting different user defined locations to prevent duplicate listings.','dbem'),
412
- '1' => __('Only event administrators can create and edit locations. User must choose from these available locations.','dbem'),
413
- '2' => __('Everyone can create/edit/delete all locations on this site. (not recommended)','dbem')
414
- );
415
- em_options_radio ( 'dbem_permissions_locations', $location_privacy_options );
416
- ?>
417
- <tr><th colspan="2"><strong><?php _e('Category Permissions','dbem'); ?></strong></th></tr>
418
- <?php
419
- $category_privacy_options = array(
420
- '0' => __('Every user can create and manage their own category.','dbem'),
421
- '1' => __('Only event administrators can create and edit categories. User must choose from these available categories.','dbem'),
422
- '2' => __('Everyone can create/edit/delete all categories on the system. (not recommended)','dbem')
423
- );
424
- em_options_radio ( 'dbem_permissions_categories', $category_privacy_options );
425
- ?>
426
- </table>
427
-
428
- </div> <!-- . inside -->
429
- </div> <!-- .postbox -->
430
-
431
- <p class="submit">
432
- <input type="submit" id="dbem_options_submit" name="Submit" value="<?php _e ( 'Save Changes' )?>" />
433
- <input type="hidden" name="em-submitted" value="1" />
434
- </p>
435
-
436
- </div> <!-- .metabox-sortables -->
437
- </div> <!-- .postbox-container -->
438
-
439
- </div> <!-- .metabox-holder -->
440
- </form>
441
- </div>
442
- <?php
443
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
444
  ?>
1
+ <?php
2
+
3
+ //Function composing the options subpanel
4
+ function em_options_save(){
5
+ global $EM_Notices;
6
+ /*
7
+ * Here's the idea, we have an array of all options that need super admin approval if in multi-site mode
8
+ * since options are only updated here, its one place fit all
9
+ */
10
+ if( current_user_can('activate_plugins') && !empty($_POST['em-submitted']) && check_admin_referer('events-manager-options','_wpnonce') ){
11
+ //Build the array of options here
12
+ $post = $_POST;
13
+ foreach ($_POST as $postKey => $postValue){
14
+ if( substr($postKey, 0, 5) == 'dbem_' ){
15
+ //TODO some more validation/reporting
16
+ $numeric_options = array('dbem_locations_default_limit','dbem_events_default_limit');
17
+ if( in_array($postKey,$numeric_options) && !is_numeric($postValue) ){
18
+ //Do nothing, keep old setting.
19
+ }else{
20
+ //TODO slashes being added?
21
+ update_option($postKey, stripslashes($postValue));
22
+ }
23
+ }
24
+ }
25
+ //set capabilities
26
+ if( !empty($_POST['em_capabilities']) && is_array($_POST['em_capabilities']) && (!is_multisite() || is_multisite() && is_super_admin()) ){
27
+ global $em_capabilities_array, $wp_roles;
28
+ if( is_multisite() && is_network_admin() && $_POST['dbem_ms_global_caps'] == 1 ){
29
+ //apply_caps_to_blog
30
+ global $current_site,$wpdb;
31
+ $blog_ids = $wpdb->get_col('SELECT blog_id FROM '.$wpdb->blogs.' WHERE site_id='.$current_site->id);
32
+ foreach($blog_ids as $blog_id){
33
+ switch_to_blog($blog_id);
34
+ //normal blog role application
35
+ foreach( $wp_roles->role_objects as $role_name => $role ){
36
+ foreach( array_keys($em_capabilities_array) as $capability){
37
+ if( !empty($_POST['em_capabilities'][$role_name][$capability]) ){
38
+ $role->add_cap($capability);
39
+ }else{
40
+ $role->remove_cap($capability);
41
+ }
42
+ }
43
+ }
44
+ restore_current_blog();
45
+ }
46
+ }elseif( !is_network_admin() ){
47
+ //normal blog role application
48
+ foreach( $wp_roles->role_objects as $role_name => $role ){
49
+ foreach( array_keys($em_capabilities_array) as $capability){
50
+ if( !empty($_POST['em_capabilities'][$role_name][$capability]) ){
51
+ $role->add_cap($capability);
52
+ }else{
53
+ $role->remove_cap($capability);
54
+ }
55
+ }
56
+ }
57
+ }
58
+ }
59
+ update_option('dbem_flush_needed',1);
60
+ do_action('em_options_save');
61
+ $EM_Notices->add_confirm('<strong>'.__('Changes saved.', 'dbem').'</strong>', true);
62
+ wp_redirect(wp_get_referer());
63
+ exit();
64
+ }
65
+ //Migration
66
+ if( !empty($_GET['em_migrate_images']) && check_admin_referer('em_migrate_images','_wpnonce') && get_option('dbem_migrate_images') ){
67
+ include(plugin_dir_path(__FILE__).'../em-install.php');
68
+ $result = em_migrate_uploads();
69
+ if($result){
70
+ $failed = ( $result['fail'] > 0 ) ? $result['fail'] . ' images failed to migrate.' : '';
71
+ $EM_Notices->add_confirm('<strong>'.$result['success'].' images migrated successfully. '.$failed.'</strong>');
72
+ }
73
+ wp_redirect(admin_url().'edit.php?post_type=event&page=events-manager-options&em_migrate_images');
74
+ }elseif( !empty($_GET['em_not_migrate_images']) && check_admin_referer('em_not_migrate_images','_wpnonce') ){
75
+ delete_option('dbem_migrate_images_nag');
76
+ delete_option('dbem_migrate_images');
77
+ }
78
+ //Uninstall
79
+ if( !empty($_REQUEST['action']) && $_REQUEST['action'] == 'uninstall' && !empty($_REQUEST['confirmed']) && check_admin_referer('em_uninstall_'.get_current_user_id().'_wpnonce') && is_super_admin() ){
80
+ if( check_admin_referer('em_uninstall_'.get_current_user_id().'_confirmed','_wpnonce2') ){
81
+ //We have a go to uninstall
82
+ global $wpdb;
83
+ //delete EM posts
84
+ remove_action('before_delete_post',array('EM_Location_Post_Admin','before_delete_post'),10,1);
85
+ remove_action('before_delete_post',array('EM_Event_Post_Admin','before_delete_post'),10,1);
86
+ remove_action('before_delete_post',array('EM_Event_Recurring_Post_Admin','before_delete_post'),10,1);
87
+ $post_ids = $wpdb->get_col('SELECT ID FROM '.$wpdb->posts." WHERE post_type IN ('".EM_POST_TYPE_EVENT."','".EM_POST_TYPE_LOCATION."','event-recurring')");
88
+ foreach($post_ids as $post_id){
89
+ wp_delete_post($post_id);
90
+ }
91
+ //delete categories
92
+ $cat_terms = get_terms(EM_TAXONOMY_CATEGORY, array('hide_empty'=>false));
93
+ foreach($cat_terms as $cat_term){
94
+ wp_delete_term($cat_term->term_id, EM_TAXONOMY_CATEGORY);
95
+ }
96
+ $tag_terms = get_terms(EM_TAXONOMY_TAG, array('hide_empty'=>false));
97
+ foreach($tag_terms as $tag_term){
98
+ wp_delete_term($tag_term->term_id, EM_TAXONOMY_TAG);
99
+ }
100
+ //delete EM tables
101
+ $wpdb->query('DROP TABLE '.EM_EVENTS_TABLE);
102
+ $wpdb->query('DROP TABLE '.EM_BOOKINGS_TABLE);
103
+ $wpdb->query('DROP TABLE '.EM_LOCATIONS_TABLE);
104
+ $wpdb->query('DROP TABLE '.EM_TICKETS_TABLE);
105
+ $wpdb->query('DROP TABLE '.EM_TICKETS_BOOKINGS_TABLE);
106
+ $wpdb->query('DROP TABLE '.EM_RECURRENCE_TABLE);
107
+ $wpdb->query('DROP TABLE '.EM_CATEGORIES_TABLE);
108
+ $wpdb->query('DROP TABLE '.EM_META_TABLE);
109
+
110
+ //delete options
111
+ $wpdb->query('DELETE FROM '.$wpdb->options.' WHERE option_name LIKE \'em_%\' OR option_name LIKE \'dbem_%\'');
112
+ //deactivate and go!
113
+ deactivate_plugins(array('events-manager/events-manager.php','events-manager-pro/events-manager-pro.php'), true);
114
+ wp_redirect(admin_url('plugins.php?deactivate=true'));
115
+ exit();
116
+ }
117
+ }
118
+ //Reset
119
+ if( !empty($_REQUEST['action']) && $_REQUEST['action'] == 'reset' && !empty($_REQUEST['confirmed']) && check_admin_referer('em_reset_'.get_current_user_id().'_wpnonce') && is_super_admin() ){
120
+ if( check_admin_referer('em_reset_'.get_current_user_id().'_confirmed','_wpnonce2') ){
121
+ //We have a go to uninstall
122
+ global $wpdb;
123
+ //delete options
124
+ $wpdb->query('DELETE FROM '.$wpdb->options.' WHERE option_name LIKE \'em_%\' OR option_name LIKE \'dbem_%\'');
125
+ //reset capabilities
126
+ global $em_capabilities_array, $wp_roles;
127
+ foreach( $wp_roles->role_objects as $role_name => $role ){
128
+ foreach( array_keys($em_capabilities_array) as $capability){
129
+ $role->remove_cap($capability);
130
+ }
131
+ }
132
+ //go back to plugin options page
133
+ $EM_Notices->add_confirm(__('Settings have been reset back to default. Your events, locations and categories have not been modified.','dbem'), true);
134
+ wp_redirect(EM_ADMIN_URL.'&page=events-manager-options');
135
+ exit();
136
+ }
137
+ }
138
+ //Force Update Recheck - Workaround for now
139
+ if( !empty($_REQUEST['action']) && $_REQUEST['action'] == 'recheck_updates' && check_admin_referer('em_recheck_updates_'.get_current_user_id().'_wpnonce') && is_super_admin() ){
140
+ //force recheck of plugin updates, to refresh dl links
141
+ delete_transient('update_plugins');
142
+ delete_site_transient('update_plugins');
143
+ $EM_Notices->add_confirm(__('If there are any new updates, you should now see them in your Plugins or Updates admin pages.','dbem'), true);
144
+ wp_redirect(wp_get_referer());
145
+ exit();
146
+ }
147
+ //Flag version checking to look at trunk, not tag
148
+ if( !empty($_REQUEST['action']) && $_REQUEST['action'] == 'check_devs' && check_admin_referer('em_check_devs_'.get_current_user_id().'_wpnonce') && is_super_admin() ){
149
+ //delete transients, and add a flag to recheck dev version next time round
150
+ delete_transient('update_plugins');
151
+ delete_site_transient('update_plugins');
152
+ update_option('em_check_dev_version', true);
153
+ $EM_Notices->add_confirm(__('Checking for dev versions.','dbem').' '. __('If there are any new updates, you should now see them in your Plugins or Updates admin pages.','dbem'), true);
154
+ wp_redirect(wp_get_referer());
155
+ exit();
156
+ }
157
+
158
+ }
159
+ add_action('admin_init', 'em_options_save');
160
+
161
+ function em_admin_options_reset_page(){
162
+ if( check_admin_referer('em_reset_'.get_current_user_id().'_wpnonce') && is_super_admin() ){
163
+ ?>
164
+ <div class="wrap">
165
+ <div id='icon-options-general' class='icon32'><br /></div>
166
+ <h2><?php _e('Reset Events Manager','dbem'); ?></h2>
167
+ <p style="color:red; font-weight:bold;"><?php _e('Are you sure you want to reset Events Manager?','dbem')?></p>
168
+ <p style="font-weight:bold;"><?php _e('All your settings, including email templates and template formats for Events Manager will be deleted.','dbem')?></p>
169
+ <p>
170
+ <a href="<?php echo add_query_arg(array('_wpnonce2' => wp_create_nonce('em_reset_'.get_current_user_id().'_confirmed'), 'confirmed'=>1)); ?>" class="button-primary"><?php _e('Reset Events Manager','dbem'); ?></a>
171
+ <a href="<?php echo wp_get_referer(); ?>" class="button-secondary"><?php _e('Cancel','dbem'); ?></a>
172
+ </p>
173
+ </div>
174
+ <?php
175
+ }
176
+ }
177
+ function em_admin_options_uninstall_page(){
178
+ if( check_admin_referer('em_uninstall_'.get_current_user_id().'_wpnonce') && is_super_admin() ){
179
+ ?>
180
+ <div class="wrap">
181
+ <div id='icon-options-general' class='icon32'><br /></div>
182
+ <h2><?php _e('Uninstall Events Manager','dbem'); ?></h2>
183
+ <p style="color:red; font-weight:bold;"><?php _e('Are you sure you want to uninstall Events Manager?','dbem')?></p>
184
+ <p style="font-weight:bold;"><?php _e('All your settings and events will be permanently deleted. This cannot be undone.','dbem')?></p>
185
+ <p><?php echo sprintf(__('If you just want to deactivate the plugin, <a href="%s">go to your plugins page</a>.','dbem'), wp_nonce_url(admin_url('plugins.php'))); ?></p>
186
+ <p>
187
+ <a href="<?php echo add_query_arg(array('_wpnonce2' => wp_create_nonce('em_uninstall_'.get_current_user_id().'_confirmed'), 'confirmed'=>1)); ?>" class="button-primary"><?php _e('Uninstall and Deactivate','dbem'); ?></a>
188
+ <a href="<?php echo wp_get_referer(); ?>" class="button-secondary"><?php _e('Cancel','dbem'); ?></a>
189
+ </p>
190
+ </div>
191
+ <?php
192
+ }
193
+ }
194
+
195
+ function em_admin_options_page() {
196
+ global $wpdb, $EM_Notices;
197
+ //Check for uninstall/reset request
198
+ if( !empty($_REQUEST['action']) && $_REQUEST['action'] == 'uninstall' ){
199
+ em_admin_options_uninstall_page();
200
+ return;
201
+ }
202
+ if( !empty($_REQUEST['action']) && $_REQUEST['action'] == 'reset' ){
203
+ em_admin_options_reset_page();
204
+ return;
205
+ }
206
+ //TODO place all options into an array
207
+ global $events_placeholder_tip, $locations_placeholder_tip, $categories_placeholder_tip, $bookings_placeholder_tip;
208
+ $events_placeholders = '<a href="'.EM_ADMIN_URL .'&amp;page=events-manager-help#event-placeholders">'. __('Event Related Placeholders','dbem') .'</a>';
209
+ $locations_placeholders = '<a href="'.EM_ADMIN_URL .'&amp;page=events-manager-help#location-placeholders">'. __('Location Related Placeholders','dbem') .'</a>';
210
+ $bookings_placeholders = '<a href="'.EM_ADMIN_URL .'&amp;page=events-manager-help#booking-placeholders">'. __('Booking Related Placeholders','dbem') .'</a>';
211
+ $categories_placeholders = '<a href="'.EM_ADMIN_URL .'&amp;page=events-manager-help#category-placeholders">'. __('Category Related Placeholders','dbem') .'</a>';
212
+ $events_placeholder_tip = " ". sprintf(__('This accepts %s and %s placeholders.','dbem'),$events_placeholders, $locations_placeholders);
213
+ $locations_placeholder_tip = " ". sprintf(__('This accepts %s placeholders.','dbem'), $locations_placeholders);
214
+ $categories_placeholder_tip = " ". sprintf(__('This accepts %s placeholders.','dbem'), $categories_placeholders);
215
+ $bookings_placeholder_tip = " ". sprintf(__('This accepts %s, %s and %s placeholders.','dbem'), $bookings_placeholders, $events_placeholders, $locations_placeholders);
216
+
217
+ global $save_button;
218
+ $save_button = '<tr><th>&nbsp;</th><td><p class="submit" style="margin:0px; padding:0px; text-align:right;"><input type="submit" id="dbem_options_submit" name="Submit" value="'. __( 'Save Changes', 'dbem') .' ('. __('All','dbem') .')" /></p></ts></td></tr>';
219
+ ?>
220
+ <script type="text/javascript" charset="utf-8">
221
+ jQuery(document).ready(function($){
222
+ //Meta Box Options
223
+ var close_text = '<?php _e('Collapse All','dbem'); ?>';
224
+ var open_text = '<?php _e('Expand All','dbem'); ?>';
225
+ var open_close = $('<a href="#" style="display:block; float:right; clear:right; margin:10px;">'+open_text+'</a>');
226
+ $('#em-options-title').before(open_close);
227
+ open_close.click( function(e){
228
+ e.preventDefault();
229
+ if($(this).text() == close_text){
230
+ $(".postbox").addClass('closed');
231
+ $(this).text(open_text);
232
+ }else{
233
+ $(".postbox").removeClass('closed');
234
+ $(this).text(close_text);
235
+ }
236
+ });
237
+ $(".postbox > h3").click(function(){ $(this).parent().toggleClass('closed'); });
238
+ $(".postbox").addClass('closed');
239
+ //Navigation Tabs
240
+ $('.nav-tab-wrapper .nav-tab').click(function(){
241
+ $('.nav-tab-wrapper .nav-tab').removeClass('nav-tab-active');
242
+ el = $(this);
243
+ elid = el.attr('id');
244
+ $('.em-menu-group').hide();
245
+ $('.'+elid).show();
246
+ el.addClass('nav-tab-active');
247
+ $(".postbox").addClass('closed');
248
+ open_close.text(open_text);
249
+ });
250
+ var navUrl = document.location.toString();
251
+ if (navUrl.match('#')) { //anchor-based navigation
252
+ var current_tab = 'a#em-menu-' + navUrl.split('#')[1];
253
+ $(current_tab).trigger('click');
254
+ }
255
+ $('.nav-tab-link').click(function(){ $($(this).attr('rel')).trigger('click'); }); //links to mimick tabs
256
+ //Page Options
257
+ $('input[name="dbem_cp_events_has_archive"]').change(function(){ //event archives
258
+ if( $('input:radio[name="dbem_cp_events_has_archive"]:checked').val() == 1 ){
259
+ $('tbody.em-event-archive-sub-options').show();
260
+ }else{
261
+ $('tbody.em-event-archive-sub-options').hide();
262
+ }
263
+ }).trigger('change');
264
+ $('select[name="dbem_events_page"]').change(function(){
265
+ if( $('select[name="dbem_events_page"]').val() == 0 ){
266
+ $('tbody.em-event-page-options').hide();
267
+ }else{
268
+ $('tbody.em-event-page-options').show();
269
+ }
270
+ }).trigger('change');
271
+ $('input[name="dbem_cp_locations_has_archive"]').change(function(){ //location archives
272
+ if( $('input:radio[name="dbem_cp_locations_has_archive"]:checked').val() == 1 ){
273
+ $('tbody.em-location-archive-sub-options').show();
274
+ }else{
275
+ $('tbody.em-location-archive-sub-options').hide();
276
+ }
277
+ }).trigger('change');
278
+ $('select[name="dbem_locations_page"]').change(function(){
279
+ if( $('select[name="dbem_locations_page"]').val() == 0 ){
280
+ $('tbody.em-location-page-options').hide();
281
+ }else{
282
+ $('tbody.em-location-page-options').show();
283
+ }
284
+ }).trigger('change');
285
+ //For rewrite titles
286
+ $('input:radio[name=dbem_disable_title_rewrites]').live('change',function(){
287
+ checked_check = $('input:radio[name=dbem_disable_title_rewrites]:checked');
288
+ if( checked_check.val() == 1 ){
289
+ $('#dbem_title_html_row').show();
290
+ }else{
291
+ $('#dbem_title_html_row').hide();
292
+ }
293
+ });
294
+ $('input:radio[name=dbem_disable_title_rewrites]').trigger('change');
295
+ });
296
+ </script>
297
+ <style type="text/css">.postbox h3 { cursor:pointer; }</style>
298
+ <div class="wrap">
299
+ <div id='icon-options-general' class='icon32'><br /></div>
300
+ <h2 class="nav-tab-wrapper">
301
+ <a href="#general" id="em-menu-general" class="nav-tab nav-tab-active"><?php _e('General','dbem'); ?></a>
302
+ <a href="#pages" id="em-menu-pages" class="nav-tab"><?php _e('Pages','dbem'); ?></a>
303
+ <a href="#formats" id="em-menu-formats" class="nav-tab"><?php _e('Formats/Layouts','dbem'); ?></a>
304
+ <?php if( get_option('dbem_rsvp_enabled') ): ?>
305
+ <a href="#bookings" id="em-menu-bookings" class="nav-tab"><?php _e('Booking Options','dbem'); ?></a>
306
+ <?php endif; ?>
307
+ <a href="#emails" id="em-menu-emails" class="nav-tab"><?php _e('Emails','dbem'); ?></a>
308
+ </h2>
309
+ <?php echo $EM_Notices; ?>
310
+ <h3 id="em-options-title"><?php _e ( 'Event Manager Options', 'dbem' ); ?></h3>
311
+ <form id="em-options-form" method="post" action="">
312
+ <div class="metabox-holder">
313
+ <!-- // TODO Move style in css -->
314
+ <div class='postbox-container' style='width: 99.5%'>
315
+ <div id="">
316
+
317
+ <div class="em-menu-general em-menu-group">
318
+
319
+ <!-- GENERAL OPTIONS -->
320
+ <div class="postbox " >
321
+ <div class="handlediv" title="<?php __('Click to toggle', 'dbem'); ?>"><br /></div><h3><span><?php _e ( 'General Options', 'dbem' ); ?> </span></h3>
322
+ <div class="inside">
323
+ <table class="form-table">
324
+ <?php em_options_radio_binary ( __( 'Disable thumbnails?', 'dbem' ), 'dbem_thumbnails_enabled', __( 'Select yes to disable Events Manager from enabling thumbnails (some themes may already have this enabled, which we cannot be turned off here).','dbem' ) ); ?>
325
+ <tr>
326
+ <td colspan="2">
327
+ <h4><?php echo sprintf(__('%s Settings','dbem'),__('Event','dbem')); ?></h4>
328
+ </td>
329
+ </tr>
330
+ <?php
331
+ em_options_radio_binary ( __( 'Enable recurrence?', 'dbem' ), 'dbem_recurrence_enabled', __( 'Select yes to enable the recurrence features feature','dbem' ) );
332
+ em_options_radio_binary ( __( 'Enable bookings?', 'dbem' ), 'dbem_rsvp_enabled', __( 'Select yes to allow bookings and tickets for events.','dbem' ) );
333
+ em_options_radio_binary ( __( 'Enable tags?', 'dbem' ), 'dbem_tags_enabled', __( 'Select yes to enable the tag features','dbem' ) );
334
+ if( !(EM_MS_GLOBAL && !is_main_blog()) ){
335
+ em_options_radio_binary ( __( 'Enable categories?', 'dbem' ), 'dbem_categories_enabled', __( 'Select yes to enable the category features','dbem' ) );
336
+ if( get_option('dbem_categories_enabled') ){
337
+ /*default category*/
338
+ $category_options = array();
339
+ $category_options[0] = __('no default category','dbem');
340
+ $EM_Categories = EM_Categories::get();
341
+ foreach($EM_Categories as $EM_Category){
342
+ $category_options[$EM_Category->id] = $EM_Category->name;
343
+ }
344
+ echo "<tr><td>".__( 'Default Category', 'dbem' )."</td><td>";
345
+ wp_dropdown_categories(array( 'hide_empty' => 0, 'name' => 'dbem_default_category', 'hierarchical' => true, 'taxonomy' => EM_TAXONOMY_CATEGORY, 'selected' => get_option('dbem_default_category'), 'show_option_none' => __('None','dbem'), 'class'=>''));
346
+ echo "</br><em>" .__( 'This option allows you to select the default category when adding an event.','dbem' ).' '.__('If an event does not have a category assigned when editing, this one will be assigned automatically.','dbem')."</em>";
347
+ echo "</td></tr>";
348
+ }
349
+ }
350
+ em_options_radio_binary ( sprintf(__( 'Enable %s attributes?', 'dbem' ),__('event','dbem')), 'dbem_attributes_enabled', __( 'Select yes to enable the attributes feature','dbem' ) );
351
+ em_options_radio_binary ( sprintf(__( 'Enable %s custom fields?', 'dbem' ),__('event','dbem')), 'dbem_cp_events_custom_fields', __( 'Custom fields are the same as attributes, except you cannot restrict specific values, users can add any kind of custom field name/value pair. Only available in the WordPress admin area.','dbem' ) );
352
+ if( get_option('dbem_attributes_enabled') ){
353
+ em_options_textarea ( sprintf(__( '%s Attributes', 'dbem' ),__('Event','dbem')), 'dbem_placeholders_custom', sprintf(__( "You can also add event attributes here, one per line in this format <code>#_ATT{key}</code>. They will not appear on event pages unless you insert them into another template below, but you may want to store extra information about an event for other uses. <a href='%s'>More information on placeholders.</a>", 'dbem' ), EM_ADMIN_URL .'&amp;page=events-manager-help') );
354
+ }
355
+ if( get_option('dbem_locations_enabled') ){
356
+ /*default location*/
357
+ $location_options = array();
358
+ $location_options[0] = __('no default location','dbem');
359
+ $EM_Locations = EM_Locations::get();
360
+ foreach($EM_Locations as $EM_Location){
361
+ $location_options[$EM_Location->location_id] = $EM_Location->location_name;
362
+ }
363
+ em_options_select ( __( 'Default Location', 'dbem' ), 'dbem_default_location', $location_options, __( 'This option allows you to select the default location when adding an event.','dbem' )." ".__('(not applicable with event ownership on presently, coming soon!)','dbem') );
364
+
365
+ /*default location country*/
366
+ em_options_select ( __( 'Default Location Country', 'dbem' ), 'dbem_location_default_country', em_get_countries(__('no default country', 'dbem')), __('If you select a default country, that will be pre-selected when creating a new location.','dbem') );
367
+ }
368
+ ?>
369
+ <tr>
370
+ <td colspan="2">
371
+ <h4><?php echo sprintf(__('%s Settings','dbem'),__('Location','dbem')); ?></h4>
372
+ </td>
373
+ </tr>
374
+ <?php
375
+ em_options_radio_binary ( __( 'Enable locations?', 'dbem' ), 'dbem_locations_enabled', __( 'If you disable locations, bear in mind that you should remove your location page, shortcodes and related placeholders from your formats.','dbem' ) );
376
+ if( get_option('dbem_locations_enabled') ){
377
+ em_options_radio_binary ( __( 'Require locations for events?', 'dbem' ), 'dbem_require_location', __( 'Setting this to no will allow you to submit events without locations. You can use the <code>{no_location}...{/no_location}</code> or <code>{has_location}..{/has_location}</code> conditional placeholder to selectively display location information.','dbem' ) );
378
+ em_options_radio_binary ( __( 'Use dropdown for locations?', 'dbem' ), 'dbem_use_select_for_locations', __( 'Select yes to select location from a drow-down menu; location selection will be faster, but you will lose the ability to insert locations with events','dbem' ) );
379
+ em_options_radio_binary ( sprintf(__( 'Enable %s attributes?', 'dbem' ),__('location','dbem')), 'dbem_location_attributes_enabled', __( 'Select yes to enable the attributes feature','dbem' ) );
380
+ em_options_radio_binary ( sprintf(__( 'Enable %s custom fields?', 'dbem' ),__('location','dbem')), 'dbem_cp_locations_custom_fields', __( 'Custom fields are the same as attributes, except you cannot restrict specific values, users can add any kind of custom field name/value pair. Only available in the WordPress admin area.','dbem' ) );
381
+ if( get_option('dbem_location_attributes_enabled') ){
382
+ em_options_textarea ( sprintf(__( '%s Attributes', 'dbem' ),__('Location','dbem')), 'dbem_location_placeholders_custom', sprintf(__( "You can also add location attributes here, one per line in this format <code>#_LATT{key}</code>. They will not appear on location pages unless you insert them into another template below, but you may want to store extra information about an event for other uses. <a href='%s'>More information on placeholders.</a>", 'dbem' ), EM_ADMIN_URL .'&amp;page=events-manager-help') );
383
+ }
384
+ }
385
+ ?>
386
+ <tr>
387
+ <td colspan="2">
388
+ <h4><?php echo sprintf(__('%s Settings','dbem'),__('Other','dbem')); ?></h4>
389
+ </td>
390
+ </tr>
391
+ <?php
392
+ em_options_radio_binary ( __('Show some love?','dbem'), 'dbem_credits', __( 'Hundreds of free hours have gone into making this free plugin, show your support and add a small link to the plugin website at the bottom of your event pages.','dbem' ) );
393
+ echo $save_button;
394
+ ?>
395
+ </table>
396
+
397
+ </div> <!-- . inside -->
398
+ </div> <!-- .postbox -->
399
+
400
+ <?php if ( !is_multisite() ){ em_admin_option_box_image_sizes(); } ?>
401
+
402
+ <?php if ( !is_multisite() || (is_super_admin() && !get_site_option('dbem_ms_global_caps')) ){ em_admin_option_box_caps(); } ?>
403
+
404
+ <div class="postbox" >
405
+ <div class="handlediv" title="<?php __('Click to toggle', 'dbem'); ?>"><br /></div><h3><span><?php _e ( 'Event Submission Forms', 'dbem' ); ?></span></h3>
406
+ <div class="inside">
407
+ <table class="form-table">
408
+ <tr><td colspan="2">
409
+ <?php echo sprintf(__('You can allow users to publicly submit events on your blog by using the %s shortcode, and enabling anonymous submissions below.','dbem'), '<code>[event_form]</code>'); ?>
410
+ </td></tr>
411
+ <?php
412
+ em_options_radio_binary ( __( 'Use Visual Editor?', 'dbem' ), 'dbem_events_form_editor', __( 'Users can now use the WordPress editor for easy HTML entry in the submission form.', 'dbem' ) );
413
+ em_options_radio_binary ( __( 'Show form again?', 'dbem' ), 'dbem_events_form_reshow', __( 'When a user submits their event, you can display a new event form again.', 'dbem' ) );
414
+ em_options_textarea ( __( 'Success Message', 'dbem' ), 'dbem_events_form_result_success', __( 'Customize the message your user sees when they submitted their event.', 'dbem' ).$events_placeholder_tip );
415
+ ?>
416
+ <tr><td colspan="2">
417
+ <strong><?php echo sprintf(__('Anonymous event submissions','dbem'), '<code>[event_form]</code>'); ?></strong>
418
+ </td></tr>
419
+ <?php
420
+ em_options_radio_binary ( __( 'Allow anonymous event submissions?', 'dbem' ), 'dbem_events_anonymous_submissions', __( 'Would you like to allow users to submit bookings anonymously? If so, you can use the new [event_form] shortcode or <code>em_event_form()</code> template tag with this enabled.', 'dbem' ) );
421
+ em_options_select ( __('Guest Default User', 'dbem'), 'dbem_events_anonymous_user', em_get_wp_users (), __( 'Events require a user to own them. In order to allow events to be submitted anonymously you need to assign that event a specific user. We recommend you create a "Anonymous" subscriber with a very good password and use that. Guests will have the same event permissions as this user when submitting.', 'dbem' ) );
422
+ em_options_textarea ( __( 'Success Message', 'dbem' ), 'dbem_events_anonymous_result_success', __( 'Anonymous submitters cannot see or modify their event once submitted. You can customize the success message they see here.', 'dbem' ).$events_placeholder_tip );
423
+ ?>
424
+ <?php echo $save_button; ?>
425
+ </table>
426
+ </div> <!-- . inside -->
427
+ </div> <!-- .postbox -->
428
+
429
+ <?php do_action('em_options_page_footer'); ?>
430
+
431
+ <?php if ( !is_multisite() ) { em_admin_option_box_uninstall(); } ?>
432
+
433
+ <?php if( get_option('dbem_migrate_images') ): ?>
434
+ <div class="postbox " >
435
+ <div class="handlediv" title="<?php __('Click to toggle', 'dbem'); ?>"><br /></div><h3><span>Migrate Images From Version 4</span></h3>
436
+ <div class="inside">
437
+ <?php /* Not translating as it's temporary */ ?>
438
+ <p>You have the option of migrating images from version 4 so they become the equivalent of 'featured images' like with regular WordPress posts and pages and are also available in your media library.</p>
439
+ <p>Your event and location images will still display correctly on the front-end even if you don't migrate, but will not show up within your edit location/event pages in the admin area.</p>
440
+ <p>
441
+ <a href="<?php echo $_SERVER['REQUEST_URI'] ?>&amp;em_migrate_images=1&amp;_wpnonce=<?php echo wp_create_nonce('em_migrate_images'); ?>" />Migrate Images</a><br />
442
+ <a href="<?php echo $_SERVER['REQUEST_URI'] ?>&amp;em_not_migrate_images=1&amp;_wpnonce=<?php echo wp_create_nonce('em_not_migrate_images'); ?>" />Do Not Migrate Images</a>
443
+ </p>
444
+ </div> <!-- . inside -->
445
+ </div> <!-- .postbox -->
446
+ <?php endif; ?>
447
+ </div> <!-- .em-menu-general -->
448
+
449
+ <!-- PAGE OPTIONS -->
450
+ <div class="em-menu-pages em-menu-group" style="display:none;">
451
+ <?php
452
+ $template_page_tip = __( "Many themes display extra meta information on post pages such as 'posted by' or 'post date' information, which may not be desired. Usually, page templates contain less clutter.", 'dbem' );
453
+ $template_page_tip .= str_replace('#','http://codex.wordpress.org/Post_Types#Template_Files',__("Be aware that some themes will not work with this option, if so (or you want to make your own changes), you can create a file named <code>single-%s.php</code> <a href='#'>as shown on the wordpress codex</a>, and leave this set to Posts.", 'dbem'));
454
+ $format_override_tip = __("By using formats, you can control how your %s are displayed from within the Events Manager <a href='#formats' class='nav-tab-link' rel='#em-menu-formats'>Formats</a> tab above without having to edit your theme files.")
455
+ ?>
456
+ <div class="postbox " >
457
+ <div class="handlediv" title="<?php __('Click to toggle', 'dbem'); ?>"><br /></div><h3><span><?php echo sprintf(__('Permalink Slugs','dbem')); ?></span></h3>
458
+ <div class="inside">
459
+ <p><?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.','dbem'); ?></p>
460
+ <table class="form-table">
461
+ <?php
462
+ em_options_input_text ( __( 'Events', 'dbem' ), 'dbem_cp_events_slug', sprintf(__('e.g. %s - you can use / seperators too', 'dbem' ), '<strong>'.home_url().'/<code>'.get_option('dbem_cp_events_slug',EM_POST_TYPE_EVENT_SLUG).'</code>/2012-olympics/</strong>'), EM_POST_TYPE_EVENT_SLUG );
463
+ if( get_option('dbem_locations_enabled') ){
464
+ em_options_input_text ( __( 'Locations', 'dbem' ), 'dbem_cp_locations_slug', sprintf(__('e.g. %s - you can use / seperators too', 'dbem' ), '<strong>'.home_url().'/<code>'.get_option('dbem_cp_locations_slug',EM_POST_TYPE_LOCATION_SLUG).'</code>/wembley-stadium/</strong>'), EM_POST_TYPE_LOCATION_SLUG );
465
+ }
466
+ if( get_option('dbem_categories_enabled') && !(EM_MS_GLOBAL && !is_main_blog()) ){
467
+ em_options_input_text ( __( 'Event Categories', 'dbem' ), 'dbem_taxonomy_category_slug', sprintf(__('e.g. %s - you can use / seperators too', 'dbem' ), '<strong>'.home_url().'/<code>'.get_option('dbem_taxonomy_category_slug',EM_TAXONOMY_CATEGORY_SLUG).'</code>/sports/</strong>'), EM_TAXONOMY_CATEGORY_SLUG );
468
+ }
469
+ if( get_option('dbem_tags_enabled') ){
470
+ em_options_input_text ( __( 'Event Tags', 'dbem' ), 'dbem_taxonomy_tag_slug', sprintf(__('e.g. %s - you can use / seperators too', 'dbem' ), '<strong>'.home_url().'/<code>'.get_option('dbem_taxonomy_tag_slug',EM_TAXONOMY_TAG_SLUG).'</code>/running/</strong>'), EM_TAXONOMY_TAG_SLUG );
471
+ }
472
+ echo $save_button;
473
+ ?>
474
+ </table>
475
+ </div> <!-- . inside -->
476
+ </div> <!-- .postbox -->
477
+
478
+ <div class="postbox " >
479
+ <div class="handlediv" title="<?php __('Click to toggle', 'dbem'); ?>"><br /></div><h3><span><?php echo sprintf(__('%s Pages','dbem'),__('Event','dbem')); ?></span></h3>
480
+ <div class="inside">
481
+ <table class="form-table">
482
+ <?php
483
+ em_options_radio_binary ( sprintf(__( 'Display %s as', 'dbem' ),__('events','dbem')), 'dbem_cp_events_template_page', sprintf($template_page_tip, EM_POST_TYPE_EVENT), array(__('Posts'),__('Pages')) );
484
+ em_options_radio_binary ( __( 'Override with Formats?', 'dbem' ), 'dbem_cp_events_formats', sprintf($format_override_tip,__('events','dbem')));
485
+ em_options_radio_binary ( __( 'Enable Comments?', 'dbem' ), 'dbem_cp_events_comments', sprintf(__('If you would like to disable comments entirely, disable this, otherwise you can disable comments on each single %s. Note that %s with comments enabled will still be until you resave them.','dbem'),__('event','dbem'),__('events','dbem')));
486
+ echo $save_button;
487
+ ?>
488
+ </table>
489
+ </div> <!-- . inside -->
490
+ </div> <!-- .postbox -->
491
+
492
+ <div class="postbox " >
493
+ <div class="handlediv" title="<?php __('Click to toggle', 'dbem'); ?>"><br /></div><h3><span><?php echo sprintf(__('%s List/Archives','dbem'),__('Event','dbem')); ?></span></h3>
494
+ <div class="inside">
495
+ <table class="form-table">
496
+ <?php //WordPress Pages
497
+ global $em_disable_filter; //Using a flag here instead
498
+ $em_disable_filter = true;
499
+ $get_pages = get_pages();
500
+ $events_page_options = array();
501
+ $events_page_options[0] = sprintf(__('[No %s Page]', 'dbem'),__('Events','dbem'));
502
+ //TODO Add the hierarchy style ddm, like when choosing page parents
503
+ foreach($get_pages as $page){
504
+ $events_page_options[$page->ID] = $page->post_title;
505
+ }
506
+ em_options_select ( __( 'Events page', 'dbem' ), 'dbem_events_page', $events_page_options, __( 'This option allows you to select which page to use as an events page. If you do not select an events page, to display event lists you can enable event archives or use the appropriate shortcodes and/or template tags.','dbem' ) );
507
+ $em_disable_filter = false;
508
+ ?>
509
+ <tbody class="em-event-page-options">
510
+ <?php
511
+ em_options_radio_binary ( __( 'Show events page in lists?', 'dbem' ), 'dbem_list_events_page', __( 'Check this option if you want the events page to appear together with other pages in pages lists.', 'dbem' ) );
512
+ em_options_radio_binary ( __( 'Display calendar in events page?', 'dbem' ), 'dbem_display_calendar_in_events_page', __( 'This options allows to display the calendar in the events page, instead of the default list. It is recommended not to display both the calendar widget and a calendar page.','dbem' ).' '.__('If you would like to show events that span over more than one day, see the Calendar section on this page.','dbem') );
513
+ em_options_radio_binary ( __( 'Disable title rewriting?', 'dbem' ), 'dbem_disable_title_rewrites', __( "Some WordPress themes don't follow best practices when generating navigation menus, and so the automatic title rewriting feature may cause problems, if your menus aren't working correctly on the event pages, try setting this to 'Yes', and provide an appropriate HTML title format below.",'dbem' ) );
514
+ em_options_input_text ( __( 'Event Manager titles', 'dbem' ), 'dbem_title_html', __( "This only setting only matters if you selected 'Yes' to above. You will notice the events page titles aren't being rewritten, and you have a new title underneath the default page name. This is where you control the HTML of this title. Make sure you keep the #_PAGETITLE placeholder here, as that's what is rewritten by events manager. To control what's rewritten in this title, see settings further down for page titles.", 'dbem' ) );
515
+ em_options_radio_binary ( __( 'Show events search?', 'dbem' ), 'dbem_events_page_search', __( "If set to yes, a search form will appear just above your list of events.", 'dbem' ) );
516
+ ?>
517
+ </tbody>
518
+ <tr>
519
+ <td colspan="2">
520
+ <h4><?php echo sprintf(__('WordPress %s Archives','dbem'), __('Event','dbem')); ?></h4>
521
+ <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'), __('Event','dbem'), '<code>'.home_url().'/'.get_option('dbem_cp_events_slug',EM_POST_TYPE_EVENT_SLUG).'/</code>', __('events','dbem')); ?></p>
522
+ <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). You can have both at the same time, but you must ensure that your page and %s slugs are different.'), __('events','dbem'), __('event','dbem')); ?></p>
523
+ </td>
524
+ </tr>
525
+ <tbody class="em-event-archive-options">
526
+ <?php
527
+ em_options_radio_binary ( __( 'Enable Archives?', 'dbem' ), 'dbem_cp_events_has_archive', __( "Allow WordPress post-style archives.", 'dbem' ) );
528
+ ?>
529
+ </tbody>
530
+ <tbody class="em-event-archive-options em-event-archive-sub-options">
531
+ <tr valign="top">
532
+ <th scope="row"><?php _e('Default event archive ordering','dbem'); ?></th>
533
+ <td>
534
+ <select name="dbem_events_default_archive_orderby" >
535
+ <?php
536
+ $event_archive_orderby_options = apply_filters('em_settings_events_default_archive_orderby_ddm', array(
537
+ '_start_ts' => __('Order by start date, start time','dbem'),
538
+ 'title' => __('Order by name','dbem')
539
+ ));
540
+ ?>
541
+ <?php foreach($event_archive_orderby_options as $key => $value) : ?>
542
+ <option value='<?php echo $key ?>' <?php echo ($key == get_option('dbem_events_default_archive_orderby')) ? "selected='selected'" : ''; ?>>
543
+ <?php echo $value; ?>
544
+ </option>
545
+ <?php endforeach; ?>
546
+ </select>
547
+ <select name="dbem_events_default_archive_order" >
548
+ <?php
549
+ $ascending = __('Ascending','dbem');
550
+ $descending = __('Descending','dbem');
551
+ $event_archive_order_options = apply_filters('em_settings_events_default_archive_order_ddm', array(
552
+ 'ASC' => __('Ascending','dbem'),
553
+ 'DESC' => __('Descending','dbem')
554
+ ));
555
+ ?>
556
+ <?php foreach( $event_archive_order_options as $key => $value) : ?>
557
+ <option value='<?php echo $key ?>' <?php echo ($key == get_option('dbem_events_default_archive_order')) ? "selected='selected'" : ''; ?>>
558
+ <?php echo $value; ?>
559
+ </option>
560
+ <?php endforeach; ?>
561
+ </select>
562
+ <br/>
563
+ <em><?php _e('When Events Manager displays lists of events the default behaviour is ordering by start date in ascending order. To change this, modify the values above.','dbem'); ?></em>
564
+ </td>
565
+ </tr>
566
+ </tbody>
567
+ <tr>
568
+ <td colspan="2">
569
+ <h4><?php echo _e('General settings','dbem'); ?></h4>
570
+ </td>
571
+ </tr>
572
+ <?php
573
+ em_options_radio_binary ( __( 'Override with Formats?', 'dbem' ), 'dbem_cp_events_archive_formats', sprintf($format_override_tip,__('events','dbem')));
574
+ em_options_radio_binary ( __( 'Are current events past events?', 'dbem' ), 'dbem_events_current_are_past', __( "By default, events that are have an end date later than today will be included in searches, set this to yes to consider events that started 'yesterday' as past.", 'dbem' ) );
575
+ em_options_radio_binary ( __( 'Include in WordPress Searches?', 'dbem' ), 'dbem_cp_events_search_results', sprintf(__( "Allow %s to appear in the built-in search results.", 'dbem' ),__('events','dbem')) );
576
+ ?>
577
+ <tr>
578
+ <td colspan="2">
579
+ <h4><?php echo sprintf(__('Default %s list options','dbem'), __('event','dbem')); ?></h4>
580
+ <p><?php _e('These can be overriden when using shortcode or template tags.','dbem'); ?></p>
581
+ </td>
582
+ </tr>
583
+ <tr valign="top" id='dbem_events_default_orderby_row'>
584
+ <th scope="row"><?php _e('Default event list ordering','dbem'); ?></th>
585
+ <td>
586
+ <select name="dbem_events_default_orderby" >
587
+ <?php
588
+ $orderby_options = apply_filters('em_settings_events_default_orderby_ddm', array(
589
+ 'event_start_date,event_start_time,event_name' => __('Order by start date, start time, then event name','dbem'),
590
+ 'event_name,event_start_date,event_start_time' => __('Order by name, start date, then start time','dbem'),
591
+ 'event_name,event_end_date,event_end_time' => __('Order by name, end date, then end time','dbem'),
592
+ 'event_end_date,event_end_time,event_name' => __('Order by end date, end time, then event name','dbem'),
593
+ ));
594
+ ?>
595
+ <?php foreach($orderby_options as $key => $value) : ?>
596
+ <option value='<?php echo $key ?>' <?php echo ($key == get_option('dbem_events_default_orderby')) ? "selected='selected'" : ''; ?>>
597
+ <?php echo $value; ?>
598
+ </option>
599
+ <?php endforeach; ?>
600
+ </select>
601
+ <select name="dbem_events_default_order" >
602
+ <?php
603
+ $ascending = __('Ascending','dbem');
604
+ $descending = __('Descending','dbem');
605
+ $order_options = apply_filters('em_settings_events_default_order_ddm', array(
606
+ 'ASC' => __('All Ascending','dbem'),
607
+ 'DESC,ASC,ASC' => __("$descending, $ascending, $ascending",'dbem'),
608
+ 'DESC,DESC,ASC' => __("$descending, $descending, $ascending",'dbem'),
609
+ 'DESC' => __('All Descending','dbem'),
610
+ 'ASC,DESC,ASC' => __("$ascending, $descending, $ascending",'dbem'),
611
+ 'ASC,DESC,DESC' => __("$ascending, $descending, $descending",'dbem'),
612
+ 'ASC,ASC,DESC' => __("$ascending, $ascending, $descending",'dbem'),
613
+ 'DESC,ASC,DESC' => __("$descending, $ascending, $descending",'dbem'),
614
+ ));
615
+ ?>
616
+ <?php foreach( $order_options as $key => $value) : ?>
617
+ <option value='<?php echo $key ?>' <?php echo ($key == get_option('dbem_events_default_order')) ? "selected='selected'" : ''; ?>>
618
+ <?php echo $value; ?>
619
+ </option>
620
+ <?php endforeach; ?>
621
+ </select>
622
+ <br/>
623
+ <em><?php _e('When Events Manager displays lists of events the default behaviour is ordering by start date in ascending order. To change this, modify the values above.','dbem'); ?></em>
624
+ </td>
625
+ </tr>
626
+ <tr valign="top" id='dbem_events_display_time_limit'>
627
+ <th scope="row"><?php _e('Event list scope','dbem'); ?></th>
628
+ <td>
629
+ <select name="dbem_events_page_scope" >
630
+ <?php foreach( em_get_scopes() as $key => $value) : ?>
631
+ <option value='<?php echo $key ?>' <?php echo ($key == get_option('dbem_events_page_scope')) ? "selected='selected'" : ''; ?>>
632
+ <?php echo $value; ?>
633
+ </option>
634
+ <?php endforeach; ?>
635
+ </select>
636
+ <br />
637
+ <em><?php _e('Only show events starting within a certain time limit on the events page. Default is future events with no end time limit.','dbem'); ?></em>
638
+ </td>
639
+ </tr>
640
+ <?php
641
+ em_options_input_text ( __( 'Event List Limits', 'dbem' ), 'dbem_events_default_limit', __( "This will control how many events are shown on one list by default.", 'dbem' ) );
642
+ echo $save_button;
643
+ ?>
644
+ </table>
645
+ </div> <!-- . inside -->
646
+ </div> <!-- .postbox -->
647
+
648
+ <?php if( get_option('dbem_locations_enabled') ): ?>
649
+ <div class="postbox " >
650
+ <div class="handlediv" title="<?php __('Click to toggle', 'dbem'); ?>"><br /></div><h3><span><?php echo sprintf(__('%s Pages','dbem'),__('Location','dbem')); ?></span></h3>
651
+ <div class="inside">
652
+ <table class="form-table">
653
+ <?php
654
+ em_options_radio_binary ( sprintf(__( 'Display %s as', 'dbem' ),__('locations','dbem')), 'dbem_cp_locations_template_page', sprintf($template_page_tip, EM_POST_TYPE_LOCATION), array(__('Posts'),__('Pages')) );
655
+ em_options_radio_binary ( __( 'Override with Formats?', 'dbem' ), 'dbem_cp_locations_formats', sprintf($format_override_tip,__('locations','dbem')));
656
+ em_options_radio_binary ( __( 'Enable Comments?', 'dbem' ), 'dbem_cp_locations_comments', sprintf(__('If you would like to disable comments entirely, disable this, otherwise you can disable comments on each single %s. Note that %s with comments enabled will still be until you resave them.','dbem'),__('location','dbem'),__('locations','dbem')));
657
+ echo $save_button;
658
+ ?>
659
+ </table>
660
+ </div> <!-- . inside -->
661
+ </div> <!-- .postbox -->
662
+
663
+ <div class="postbox " >
664
+ <div class="handlediv" title="<?php __('Click to toggle', 'dbem'); ?>"><br /></div><h3><span><?php echo sprintf(__('%s List/Archives','dbem'),__('Location','dbem')); ?></span></h3>
665
+ <div class="inside">
666
+ <table class="form-table">
667
+ <?php
668
+ $events_page_options[0] = sprintf(__('[No %s Page]', 'dbem'),__('Locations','dbem'));
669
+ em_options_select ( sprintf(__( '%s page', 'dbem' ),__('Locations','dbem')), 'dbem_locations_page', $events_page_options, sprintf(__( 'This option allows you to select which page to use as the %s page. If you do not select no %s page, to display lists you can enable archives or use the appropriate shortcodes and/or template tags.','dbem' ),__('locations','dbem'),__('locations','dbem')) );
670
+ ?>
671
+ <tbody class="em-location-page-options">
672
+ <?php
673
+ em_options_radio_binary ( sprintf(__( 'Show %s page in lists?', 'dbem' ),__('locations','dbem')), 'dbem_list_locations_page', sprintf(__( 'Check this option if you want the %s page to appear together with other pages in pages lists.', 'dbem' ),__('locations','dbem')) );
674
+ ?>
675
+ </tbody>
676
+ <tr>
677
+ <td colspan="2">
678
+ <h4><?php echo sprintf(__('WordPress %s Archives','dbem'), __('Location','dbem')); ?></h4>
679
+ <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'), __('Location','dbem'), '<code>'.home_url().'/'.get_option('dbem_cp_events_slug',EM_POST_TYPE_EVENT_SLUG).'/</code>', __('locations','dbem')); ?></p>
680
+ <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 compatability). You can have both at the same time, but you must ensure that your page and %s slugs are different.'), __('locations','dbem'), __('location','dbem')); ?></p>
681
+ </td>
682
+ </tr>
683
+ <tbody class="em-location-archive-options">
684
+ <?php
685
+ em_options_radio_binary ( __( 'Enable Archives?', 'dbem' ), 'dbem_cp_locations_has_archive', __( "Allow WordPress post-style archives.", 'dbem' ) );
686
+ ?>
687
+ </tbody>
688
+ <tbody class="em-location-archive-options em-location-archive-sub-options">
689
+ <tr valign="top">
690
+ <th scope="row"><?php _e('Default archive ordering','dbem'); ?></th>
691
+ <td>
692
+ <select name="dbem_locations_default_archive_orderby" >
693
+ <?php
694
+ $orderby_options = apply_filters('em_settings_locations_default_archive_orderby_ddm', array(
695
+ '_country' => sprintf(__('Order by %s','dbem'),__('Country','dbem')),
696
+ '_town' => sprintf(__('Order by %s','dbem'),__('Town','dbem')),
697
+ 'title' => sprintf(__('Order by %s','dbem'),__('Name','dbem'))
698
+ ));
699
+ ?>
700
+ <?php foreach($orderby_options as $key => $value) : ?>
701
+ <option value='<?php echo $key ?>' <?php echo ($key == get_option('dbem_locations_default_archive_orderby')) ? "selected='selected'" : ''; ?>>
702
+ <?php echo $value; ?>
703
+ </option>
704
+ <?php endforeach; ?>
705
+ </select>
706
+ <select name="dbem_locations_default_archive_order" >
707
+ <?php
708
+ $ascending = __('Ascending','dbem');
709
+ $descending = __('Descending','dbem');
710
+ $order_options = apply_filters('em_settings_locations_default_archive_order_ddm', array(
711
+ 'ASC' => __('Ascending','dbem'),
712
+ 'DESC' => __('Descending','dbem')
713
+ ));
714
+ ?>
715
+ <?php foreach( $order_options as $key => $value) : ?>
716
+ <option value='<?php echo $key ?>' <?php echo ($key == get_option('dbem_locations_default_archive_order')) ? "selected='selected'" : ''; ?>>
717
+ <?php echo $value; ?>
718
+ </option>
719
+ <?php endforeach; ?>
720
+ </select>
721
+ </td>
722
+ </tr>
723
+ </tbody>
724
+ <tr>
725
+ <td colspan="2">
726
+ <h4><?php echo _e('General settings','dbem'); ?></h4>
727
+ </td>
728
+ </tr>
729
+ <?php
730
+ em_options_radio_binary ( __( 'Override with Formats?', 'dbem' ), 'dbem_cp_locations_archive_formats', sprintf($format_override_tip,__('locations','dbem')));
731
+ em_options_radio_binary ( __( 'Include in WordPress Searches?', 'dbem' ), 'dbem_cp_locations_search_results', sprintf(__( "Allow %s to appear in the built-in search results.", 'dbem' ),__('locations','dbem')) );
732
+ ?>
733
+ <tr>
734
+ <td colspan="2">
735
+ <h4><?php echo sprintf(__('Default %s list options','dbem'), __('location','dbem')); ?></h4>
736
+ <p><?php _e('These can be overriden when using shortcode or template tags.','dbem'); ?></p>
737
+ </td>
738
+ </tr>
739
+ <tr valign="top" id='dbem_locations_default_orderby_row'>
740
+ <th scope="row"><?php _e('Default list ordering','dbem'); ?></th>
741
+ <td>
742
+ <select name="dbem_locations_default_orderby" >
743
+ <?php
744
+ $orderby_options = apply_filters('em_settings_locations_default_orderby_ddm', array(
745
+ 'location_country' => sprintf(__('Order by %s','dbem'),__('Country','dbem')),
746
+ 'location_town' => sprintf(__('Order by %s','dbem'),__('Town','dbem')),
747
+ 'location_name' => sprintf(__('Order by %s','dbem'),__('Name','dbem'))
748
+ ));
749
+ ?>
750
+ <?php foreach($orderby_options as $key => $value) : ?>
751
+ <option value='<?php echo $key ?>' <?php echo ($key == get_option('dbem_locations_default_orderby')) ? "selected='selected'" : ''; ?>>
752
+ <?php echo $value; ?>
753
+ </option>
754
+ <?php endforeach; ?>
755
+ </select>
756
+ <select name="dbem_locations_default_order" >
757
+ <?php
758
+ $ascending = __('Ascending','dbem');
759
+ $descending = __('Descending','dbem');
760
+ $order_options = apply_filters('em_settings_locations_default_order_ddm', array(
761
+ 'ASC' => __('Ascending','dbem'),
762
+ 'DESC' => __('Descending','dbem')
763
+ ));
764
+ ?>
765
+ <?php foreach( $order_options as $key => $value) : ?>
766
+ <option value='<?php echo $key ?>' <?php echo ($key == get_option('dbem_locations_default_order')) ? "selected='selected'" : ''; ?>>
767
+ <?php echo $value; ?>
768
+ </option>
769
+ <?php endforeach; ?>
770
+ </select>
771
+ </td>
772
+ </tr>
773
+ <?php
774
+ em_options_input_text ( __( 'List Limits', 'dbem' ), 'dbem_locations_default_limit', sprintf(__( "This will control how many %s are shown on one list by default.", 'dbem' ),__('locations','dbem')) );
775
+ echo $save_button;
776
+ ?>
777
+ </table>
778
+ </div> <!-- . inside -->
779
+ </div> <!-- .postbox -->
780
+ <?php endif; ?>
781
+
782
+ <?php if( get_option('dbem_categories_enabled') && !(EM_MS_GLOBAL && !is_main_blog()) ): ?>
783
+ <div class="postbox " >
784
+ <div class="handlediv" title="<?php __('Click to toggle', 'dbem'); ?>"><br /></div><h3><span><?php echo __('Event Categories','dbem'); ?></span></h3>
785
+ <div class="inside">
786
+ <table class="form-table">
787
+ <?php
788
+ $events_page_options[0] = sprintf(__('[No %s Page]', 'dbem'),__('Categories','dbem'));
789
+ em_options_select ( sprintf(__( '%s page', 'dbem' ),__('Categories','dbem')), 'dbem_categories_page', $events_page_options, sprintf(__( 'This option allows you to select which page to use as the %s page.','dbem' ),__('categories','dbem'),__('categories','dbem')) );
790
+ ?>
791
+ <tbody class="em-category-page-options">
792
+ <?php
793
+ em_options_radio_binary ( sprintf(__( 'Show %s page in lists?', 'dbem' ),__('categories','dbem')), 'dbem_list_categories_page', sprintf(__( 'Check this option if you want the %s page to appear together with other pages in pages lists.', 'dbem' ),__('categories','dbem')) );
794
+ ?>
795
+ </tbody>
796
+ <tr>
797
+ <td colspan="2">
798
+ <h4><?php echo _e('General settings','dbem'); ?></h4>
799
+ </td>
800
+ </tr>
801
+ <?php
802
+ em_options_radio_binary ( __( 'Override with Formats?', 'dbem' ), 'dbem_cp_categories_formats', sprintf($format_override_tip,__('categories','dbem'))." ".__('Setting this to yes will make categories display as a page rather than an archive.', 'dbem'));
803
+ ?>
804
+ <tr valign="top">
805
+ <th scope="row"><?php _e('Default archive ordering','dbem'); ?></th>
806
+ <td>
807
+ <select name="dbem_categories_default_archive_orderby" >
808
+ <?php foreach($event_archive_orderby_options as $key => $value) : ?>
809
+ <option value='<?php echo $key ?>' <?php echo ($key == get_option('dbem_categories_default_archive_orderby')) ? "selected='selected'" : ''; ?>>
810
+ <?php echo $value; ?>
811
+ </option>
812
+ <?php endforeach; ?>
813
+ </select>
814
+ <select name="dbem_categories_default_archive_order" >
815
+ <?php foreach( $event_archive_order_options as $key => $value) : ?>
816
+ <option value='<?php echo $key ?>' <?php echo ($key == get_option('dbem_categories_default_archive_order')) ? "selected='selected'" : ''; ?>>
817
+ <?php echo $value; ?>
818
+ </option>
819
+ <?php endforeach; ?>
820
+ </select>
821
+ <br /><?php echo __('When listing events for a category, this order is applied.', 'dbem'); ?>
822
+ </td>
823
+ </tr>
824
+ <tr>
825
+ <td colspan="2">
826
+ <h4><?php echo sprintf(__('Default %s list options','dbem'), __('category','dbem')); ?></h4>
827
+ <p><?php _e('These can be overriden when using shortcode or template tags.','dbem'); ?></p>
828
+ </td>
829
+ </tr>
830
+ <tr valign="top" id='dbem_categories_default_orderby_row'>
831
+ <th scope="row"><?php _e('Default list ordering','dbem'); ?></th>
832
+ <td>
833
+ <select name="dbem_categories_default_orderby" >
834
+ <?php
835
+ $orderby_options = apply_filters('em_settings_categories_default_orderby_ddm', array(
836
+ 'id' => sprintf(__('Order by %s','dbem'),__('ID','dbem')),
837
+ 'count' => sprintf(__('Order by %s','dbem'),__('Count','dbem')),
838
+ 'name' => sprintf(__('Order by %s','dbem'),__('Name','dbem')),
839
+ 'slug' => sprintf(__('Order by %s','dbem'),__('Slug','dbem')),
840
+ 'term_group' => sprintf(__('Order by %s','dbem'),'term_group'),
841
+ ));
842
+ ?>
843
+ <?php foreach($orderby_options as $key => $value) : ?>
844
+ <option value='<?php echo $key ?>' <?php echo ($key == get_option('dbem_categories_default_orderby')) ? "selected='selected'" : ''; ?>>
845
+ <?php echo $value; ?>
846
+ </option>
847
+ <?php endforeach; ?>
848
+ </select>
849
+ <select name="dbem_categories_default_order" >
850
+ <?php
851
+ $ascending = __('Ascending','dbem');
852
+ $descending = __('Descending','dbem');
853
+ $order_options = apply_filters('em_settings_categories_default_order_ddm', array(
854
+ 'ASC' => __('Ascending','dbem'),
855
+ 'DESC' => __('Descending','dbem')
856
+ ));
857
+ ?>
858
+ <?php foreach( $order_options as $key => $value) : ?>
859
+ <option value='<?php echo $key ?>' <?php echo ($key == get_option('dbem_categories_default_order')) ? "selected='selected'" : ''; ?>>
860
+ <?php echo $value; ?>
861
+ </option>
862
+ <?php endforeach; ?>
863
+ </select>
864
+ <br /><?php echo __('When listing categories, this order is applied.', 'dbem'); ?>
865
+ </td>
866
+ </tr>
867
+ <?php
868
+ em_options_input_text ( __( 'List Limits', 'dbem' ), 'dbem_categories_default_limit', sprintf(__( "This will control how many %s are shown on one list by default.", 'dbem' ),__('categories','dbem')) );
869
+ echo $save_button;
870
+ ?>
871
+ </table>
872
+ </div> <!-- . inside -->
873
+ </div> <!-- .postbox -->
874
+ <?php endif; ?>
875
+
876
+ <?php if( get_option('dbem_tags_enabled') ): //disabled for now, will add tag stuff later ?>
877
+ <div class="postbox " >
878
+ <div class="handlediv" title="<?php __('Click to toggle', 'dbem'); ?>"><br /></div><h3><span><?php echo __('Event Tags','dbem'); ?></span></h3>
879
+ <div class="inside">
880
+ <table class="form-table">
881
+ <?php
882
+ em_options_radio_binary ( __( 'Override with Formats?', 'dbem' ), 'dbem_cp_tags_formats', sprintf($format_override_tip,__('tags','dbem')));
883
+ ?>
884
+ <tr valign="top">
885
+ <th scope="row"><?php _e('Default archive ordering','dbem'); ?></th>
886
+ <td>
887
+ <select name="dbem_tags_default_archive_orderby" >
888
+ <?php foreach($event_archive_orderby_options as $key => $value) : ?>
889
+ <option value='<?php echo $key ?>' <?php echo ($key == get_option('dbem_tags_default_archive_orderby')) ? "selected='selected'" : ''; ?>>
890
+ <?php echo $value; ?>
891
+ </option>
892
+ <?php endforeach; ?>
893
+ </select>
894
+ <select name="dbem_tags_default_archive_order" >
895
+ <?php foreach( $event_archive_order_options as $key => $value) : ?>
896
+ <option value='<?php echo $key ?>' <?php echo ($key == get_option('dbem_tags_default_archive_order')) ? "selected='selected'" : ''; ?>>
897
+ <?php echo $value; ?>
898
+ </option>
899
+ <?php endforeach; ?>
900
+ </select>
901
+ </td>
902
+ </tr>
903
+ <?php echo $save_button; ?>
904
+ </table>
905
+ </div> <!-- . inside -->
906
+ </div> <!-- .postbox -->
907
+ <?php endif; ?>
908
+
909
+ <div class="postbox " >
910
+ <div class="handlediv" title="<?php __('Click to toggle', 'dbem'); ?>"><br /></div><h3><span><?php echo sprintf(__('%s Pages','dbem'),__('Other','dbem')); ?></span></h3>
911
+ <div class="inside">
912
+ <p><?php _e('These pages allow you to provide an event management interface outside the admin area on whatever page you want on your website. Bear in mind that this is overriden by BuddyPress if activated.'); ?></p>
913
+ <table class="form-table">
914
+ <?php
915
+ $other_pages_tip = 'Using the %s shortcode, you can allow users to manage %s outside the admin area.';
916
+ $events_page_options[0] = '['.__('None', 'dbem').']';
917
+ ?><tr><td colspan="2"><h4><?php echo _e('My Bookings','dbem'); ?></h4></td></tr><?php
918
+ em_options_select ( sprintf(__( '%s page', 'dbem' ),__('My bookings','dbem')), 'dbem_my_bookings_page', $events_page_options, sprintf(__('Users can view their bookings for other events on this page.','dbem' ),'<code>[my_bookings]</code>',__('bookings','dbem')) );
919
+ ?>
920
+ <tr valign="top" id='dbem_bookings_default_orderby_row'>
921
+ <th scope="row"><?php _e('Default list ordering','dbem'); ?></th>
922
+ <td>
923
+ <select name="dbem_bookings_default_orderby" >
924
+ <?php
925
+ $orderby_options = apply_filters('em_settings_bookings_default_orderby_ddm', array(
926
+ 'event_name' => sprintf(__('Order by %s','dbem'),__('Event Name','dbem')),
927
+ 'event_start_date' => sprintf(__('Order by %s','dbem'),__('Start Date','dbem')),
928
+ 'booking_date' => sprintf(__('Order by %s','dbem'),__('Booking Date','dbem'))
929
+ ));
930
+ ?>
931
+ <?php foreach($orderby_options as $key => $value) : ?>
932
+ <option value='<?php echo $key ?>' <?php echo ($key == get_option('dbem_bookings_default_orderby')) ? "selected='selected'" : ''; ?>>
933
+ <?php echo $value; ?>
934
+ </option>
935
+ <?php endforeach; ?>
936
+ </select>
937
+ <select name="dbem_bookings_default_order" >
938
+ <?php
939
+ $ascending = __('Ascending','dbem');
940
+ $descending = __('Descending','dbem');
941
+ $order_options = apply_filters('em_settings_bookings_default_order_ddm', array(
942
+ 'ASC' => __('Ascending','dbem'),
943
+ 'DESC' => __('Descending','dbem')
944
+ ));
945
+ ?>
946
+ <?php foreach( $order_options as $key => $value) : ?>
947
+ <option value='<?php echo $key ?>' <?php echo ($key == get_option('dbem_bookings_default_order')) ? "selected='selected'" : ''; ?>>
948
+ <?php echo $value; ?>
949
+ </option>
950
+ <?php endforeach; ?>
951
+ </select>
952
+ </td>
953
+ </tr>
954
+ <tr><td colspan="2"><h4><?php echo _e('Front-end management pages','dbem'); ?></h4></td></tr>
955
+ <tr><td colspan="2"><?php echo _e('Users can create and edit events and locations, as well as managing bookings for their events.','dbem'); ?></td></tr>
956
+ <?php
957
+ em_options_select ( sprintf(__( '%s page', 'dbem' ),__('Edit events','dbem')), 'dbem_edit_events_page', $events_page_options, sprintf(__('Users can view, add and edit their %s on this page.','dbem'),__('events','dbem')) );
958
+ em_options_select ( sprintf(__( '%s page', 'dbem' ),__('Edit locations','dbem')), 'dbem_edit_locations_page', $events_page_options, sprintf(__('Users can view, add and edit their %s on this page.','dbem'),__('locations','dbem')) );
959
+ em_options_select ( sprintf(__( '%s page', 'dbem' ),__('Manage bookings','dbem')), 'dbem_edit_bookings_page', $events_page_options, __('Users can manage bookings for their events on this page.','dbem') );
960
+ echo $save_button;
961
+ ?>
962
+ </table>
963
+ </div> <!-- . inside -->
964
+ </div> <!-- .postbox -->
965
+
966
+ <?php do_action('em_options_page_footer_pages'); ?>
967
+
968
+ </div> <!-- .em-menu-pages -->
969
+
970
+ <!-- FORMAT OPTIONS -->
971
+ <div class="em-menu-formats em-menu-group" style="display:none;">
972
+ <div class="postbox " >
973
+ <div class="handlediv" title="<?php __('Click to toggle', 'dbem'); ?>"><br /></div><h3><span><?php _e ( 'Events format', 'dbem' ); ?> </span></h3>
974
+ <div class="inside">
975
+ <table class="form-table">
976
+ <tr><td><strong><?php echo sprintf(__('%s Page','dbem'),__('Events','dbem')); ?></strong></td></tr>
977
+ <?php
978
+ em_options_textarea ( __( 'Default event list format header', 'dbem' ), 'dbem_event_list_item_format_header', __( 'This content will appear just above your code for the default event list format. Default is blank', 'dbem' ) );
979
+ em_options_textarea ( __( 'Default event list format', 'dbem' ), 'dbem_event_list_item_format', __( 'The format of any events in a list.', 'dbem' ).$events_placeholder_tip );
980
+ em_options_textarea ( __( 'Default event list format footer', 'dbem' ), 'dbem_event_list_item_format_footer', __( 'This content will appear just below your code for the default event list format. Default is blank', 'dbem' ) );
981
+ em_options_input_text ( __( 'No events message', 'dbem' ), 'dbem_no_events_message', __( 'The message displayed when no events are available.', 'dbem' ) );
982
+ em_options_input_text ( __( 'List events by date title', 'dbem' ), 'dbem_list_date_title', __( 'If viewing a page for events on a specific date, this is the title that would show up. To insert date values, use <a href="http://www.php.net/manual/en/function.date.php">PHP time format characters</a> with a <code>#</code> symbol before them, i.e. <code>#m</code>, <code>#M</code>, <code>#j</code>, etc.<br/>', 'dbem' ) );
983
+ ?>
984
+ <tr><td><strong><?php echo sprintf(__('Single %s Page','dbem'),__('Event','dbem')); ?></strong></td></tr>
985
+ <?php
986
+ if( EM_MS_GLOBAL ){
987
+ em_options_input_text ( __( 'Single event page title format', 'dbem' ), 'dbem_event_page_title_format', __( 'The format of a single event page title.', 'dbem' ).$events_placeholder_tip );
988
+ }
989
+ em_options_textarea ( __( 'Default single event format', 'dbem' ), 'dbem_single_event_format', __( 'The format of a single event page.', 'dbem' ).$events_placeholder_tip );
990
+ echo $save_button;
991
+ ?>
992
+ </table>
993
+ </div> <!-- . inside -->
994
+ </div> <!-- .postbox -->
995
+
996
+ <div class="postbox " >
997
+ <div class="handlediv" title="<?php __('Click to toggle', 'dbem'); ?>"><br /></div><h3><span><?php _e ( 'Search Form Options', 'dbem' ); ?> </span></h3>
998
+ <div class="inside">
999
+ <table class="form-table">
1000
+ <?php
1001
+ em_options_radio_binary ( __( 'Show text search?', 'dbem' ), 'dbem_search_form_text', '' );
1002
+ em_options_input_text ( __( 'Text search label', 'dbem' ), 'dbem_search_form_text_label', __('Appears within the input box.','dbem') );
1003
+ em_options_radio_binary ( __( 'Show date range?', 'dbem' ), 'dbem_search_form_dates', '' );
1004
+ em_options_radio_binary ( __( 'Show categories?', 'dbem' ), 'dbem_search_form_categories', '' );
1005
+ em_options_input_text ( __( 'Categories label', 'dbem' ), 'dbem_search_form_categories_label', __('Appears as the first default search option.','dbem') );
1006
+ em_options_radio_binary ( __( 'Show countries?', 'dbem' ), 'dbem_search_form_countries', '' );
1007
+ em_options_input_text ( __( 'All countries text', 'dbem' ), 'dbem_search_form_countries_label', __('Appears as the first default search option.','dbem') );
1008
+ em_options_radio_binary ( __( 'Show regions?', 'dbem' ), 'dbem_search_form_regions', '' );
1009
+ em_options_input_text ( __( 'All regions text', 'dbem' ), 'dbem_search_form_regions_label', __('Appears as the first default search option.','dbem') );
1010
+ em_options_radio_binary ( __( 'Show states?', 'dbem' ), 'dbem_search_form_states', '' );
1011
+ em_options_input_text ( __( 'All states text', 'dbem' ), 'dbem_search_form_states_label', __('Appears as the first default search option.','dbem') );
1012
+ em_options_radio_binary ( __( 'Show towns/cities?', 'dbem' ), 'dbem_search_form_towns', '' );
1013
+ em_options_input_text ( __( 'All towns/cities text', 'dbem' ), 'dbem_search_form_towns_label', __('Appears as the first default search option.','dbem') );
1014
+ echo $save_button;
1015
+ ?>
1016
+ </table>
1017
+ </div> <!-- . inside -->
1018
+ </div> <!-- .postbox -->
1019
+
1020
+ <div class="postbox " >
1021
+ <div class="handlediv" title="<?php __('Click to toggle', 'dbem'); ?>"><br /></div><h3><span><?php _e ( 'Date/Time formats', 'dbem' ); ?> </span></h3>
1022
+ <div class="inside">
1023
+ <p><?php echo sprintf(__('Date and Time formats follow the <a href="%s">WordPress time formatting conventions</a>', 'dbem'), 'http://codex.wordpress.org/Formatting_Date_and_Time'); ?></p>
1024
+ <table class="form-table">
1025
+ <?php
1026
+ em_options_input_text ( __( 'Date Format', 'dbem' ), 'dbem_date_format', sprintf(__('For use with the %s placeholder'),'<code>#_EVENTDATES</code>') );
1027
+ em_options_input_text ( __( 'Date Picker Format', 'dbem' ), 'dbem_date_format_js', sprintf(__( 'Same as <em>Date Format</em>, but this is used for the datepickers used by Events Manager. This uses a slightly different format to the others on here, for a list of characters to use, visit the <a href="%s">jQuery formatDate reference</a>', 'dbem' ),'http://docs.jquery.com/UI/Datepicker/formatDate') );
1028
+ em_options_input_text ( __( 'Date Seperator', 'dbem' ), 'dbem_dates_seperator', sprintf(__( 'For when start/end %s are present, this will seperate the two (include spaces here if necessary).', 'dbem' ), __('dates','dbem')) );
1029
+ em_options_input_text ( __( 'Time Format', 'dbem' ), 'dbem_time_format', sprintf(__('For use with the %s placeholder'),'<code>#_EVENTTIMES</code>') );
1030
+ em_options_input_text ( __( 'Time Seperator', 'dbem' ), 'dbem_times_seperator', sprintf(__( 'For when start/end %s are present, this will seperate the two (include spaces here if necessary).', 'dbem' ), __('times','dbem')) );
1031
+ em_options_input_text ( __( 'All Day Message', 'dbem' ), 'dbem_event_all_day_message', sprintf(__( 'If an event lasts all day, this text will show if using the %s placeholder', 'dbem' ), '<code>#_EVENTTIMES</code>') );
1032
+ em_options_radio_binary ( __( 'Use 24h Format?', 'dbem' ), 'dbem_time_24h', __( 'When creating events, would you like your times to be shown in 24 hour format?', 'dbem' ) );
1033
+ echo $save_button;
1034
+ ?>
1035
+ </table>
1036
+ </div> <!-- . inside -->
1037
+ </div> <!-- .postbox -->
1038
+
1039
+ <div class="postbox " >
1040
+ <div class="handlediv" title="<?php __('Click to toggle', 'dbem'); ?>"><br /></div><h3><span><?php _e ( 'Calendar format', 'dbem' ); ?></span></h3>
1041
+ <div class="inside">
1042
+ <table class="form-table">
1043
+ <?php
1044
+ em_options_input_text ( __( 'Small calendar title', 'dbem' ), 'dbem_small_calendar_event_title_format', __( 'The format of the title, corresponding to the text that appears when hovering on an eventful calendar day.', 'dbem' ).$events_placeholder_tip );
1045
+ em_options_input_text ( __( 'Small calendar title separator', 'dbem' ), 'dbem_small_calendar_event_title_separator', __( 'The separator appearing on the above title when more than one events are taking place on the same day.', 'dbem' ) );
1046
+ em_options_input_text ( __( 'Full calendar events format', 'dbem' ), 'dbem_full_calendar_event_format', __( 'The format of each event when displayed in the full calendar. Remember to include <code>li</code> tags before and after the event.', 'dbem' ).$events_placeholder_tip );
1047
+ em_options_radio_binary ( __( 'Show long events on calendar pages?', 'dbem' ), 'dbem_full_calendar_long_events', __( "If you are showing a calendar on the events page (see Events format section on this page), you have the option of showing events that span over days on each day it occurs.",'dbem' ) );
1048
+ em_options_radio_binary ( __( 'Link directly to event on day with single event?', 'dbem' ), 'dbem_calendar_direct_links', __( "If a calendar day has only one event, you can force a direct link to the event (recommended to avoid duplicate content).",'dbem' ) );
1049
+ em_options_radio_binary ( __( 'Show list on day with single event?', 'dbem' ), 'dbem_display_calendar_day_single', __( "By default, if a calendar day only has one event, it display a single event when clicking on the link of that calendar date. If you select Yes here, you will get always see a list of events.",'dbem' ) );
1050
+ ?>
1051
+ <tr><td><strong><?php echo __('Calendar Day Event List Settings','dbem'); ?></strong></td></tr>
1052
+ <tr valign="top" id='dbem_display_calendar_orderby_row'>
1053
+ <th scope="row"><?php _e('Default event list ordering','dbem'); ?></th>
1054
+ <td>
1055
+ <select name="dbem_display_calendar_orderby" >
1056
+ <?php
1057
+ $orderby_options = apply_filters('dbem_display_calendar_orderby_ddm', array(
1058
+ 'event_name,event_start_time' => __('Order by event name, then event start time','dbem'),
1059
+ 'event_start_time,event_name' => __('Order by event start time, then event name','dbem')
1060
+ ));
1061
+ ?>
1062
+ <?php foreach($orderby_options as $key => $value) : ?>
1063
+ <option value='<?php echo $key ?>' <?php echo ($key == get_option('dbem_display_calendar_orderby')) ? "selected='selected'" : ''; ?>>
1064
+ <?php echo $value; ?>
1065
+ </option>
1066
+ <?php endforeach; ?>
1067
+ </select>
1068
+ <select name="dbem_display_calendar_order" >
1069
+ <?php
1070
+ $ascending = __('Ascending','dbem');
1071
+ $descending = __('Descending','dbem');
1072
+ $order_options = apply_filters('dbem_display_calendar_order_ddm', array(
1073
+ 'ASC' => __('All Ascending','dbem'),
1074
+ 'DESC,ASC' => "$descending, $ascending",
1075
+ 'DESC,DESC' => "$descending, $descending",
1076
+ 'DESC' => __('All Descending','dbem')
1077
+ ));
1078
+ ?>
1079
+ <?php foreach( $order_options as $key => $value) : ?>
1080
+ <option value='<?php echo $key ?>' <?php echo ($key == get_option('dbem_display_calendar_order')) ? "selected='selected'" : ''; ?>>
1081
+ <?php echo $value; ?>
1082
+ </option>
1083
+ <?php endforeach; ?>
1084
+ </select>
1085
+ <br/>
1086
+ <em><?php _e('When Events Manager displays lists of events the default behaviour is ordering by start date in ascending order. To change this, modify the values above.','dbem'); ?></em>
1087
+ </td>
1088
+ </tr>
1089
+ <?php
1090
+ em_options_input_text ( __( 'Calendar events/day limit', 'dbem' ), 'dbem_display_calendar_events_limit', __( 'Limits the number of events on each calendar day. Leave blank for no limit.', 'dbem' ) );
1091
+ em_options_input_text ( __( 'More Events message', 'dbem' ), 'dbem_display_calendar_events_limit_msg', __( 'Text with link to calendar day page with all events for that day if there are more events than the limit above, leave blank for no link as the day number is also a link.', 'dbem' ) );
1092
+ ?>
1093
+ <tr><td><strong><?php echo sprintf(__('iCal Feed Settings','dbem'),__('Event','dbem')); ?></strong></td></tr>
1094
+ <?php
1095
+ em_options_input_text ( __( 'iCal Title', 'dbem' ), 'dbem_ical_description_format', __( 'The title that will appear in the calendar.', 'dbem' ).$events_placeholder_tip );
1096
+ em_options_input_text ( __( 'iCal Limit', 'dbem' ), 'dbem_ical_limit', __( 'Limits the number of future events shown (0 = unlimited).', 'dbem' ) );
1097
+ echo $save_button;
1098
+ ?>
1099
+ </table>
1100
+ </div> <!-- . inside -->
1101
+ </div> <!-- .postbox -->
1102
+
1103
+ <?php if( get_option('dbem_locations_enabled') ): ?>
1104
+ <div class="postbox " >
1105
+ <div class="handlediv" title="<?php __('Click to toggle', 'dbem'); ?>"><br /></div><h3><span><?php _e ( 'Locations format', 'dbem' ); ?> </span></h3>
1106
+ <div class="inside">
1107
+ <table class="form-table">
1108
+ <tr><td><strong><?php echo sprintf(__('%s Page','dbem'),__('Locations','dbem')); ?></strong></td></tr>
1109
+ <?php
1110
+ em_options_textarea ( sprintf(__('%s list header format','dbem'),__('Locations','dbem')), 'dbem_location_list_item_format_header', sprintf(__( 'This content will appear just above your code for the %s list format below. Default is blank', 'dbem' ), __('locations','dbem')) );
1111
+ em_options_textarea ( sprintf(__('%s list item format','dbem'),__('Locations','dbem')), 'dbem_location_list_item_format', sprintf(__( 'The format of a single %s in a list.', 'dbem' ), __('locations','dbem')).$locations_placeholder_tip );
1112
+ em_options_textarea ( sprintf(__('%s list footer format','dbem'),__('Locations','dbem')), 'dbem_location_list_item_format_footer', sprintf(__( 'This content will appear just below your code for the %s list format above. Default is blank', 'dbem' ), __('locations','dbem')) );
1113
+ em_options_input_text ( sprintf(__( 'No %s message', 'dbem' ),__('Locations','dbem')), 'dbem_no_locations_message', sprintf( __( 'The message displayed when no %s are available.', 'dbem' ), __('locations','dbem')) );
1114
+ ?>
1115
+ <tr><td><strong><?php echo sprintf(__('Single %s Page','dbem'),__('Location','dbem')); ?></strong></td></tr>
1116
+ <?php
1117
+ em_options_input_text (sprintf( __( 'Single %s title format', 'dbem' ),__('location','dbem')), 'dbem_location_page_title_format', __( 'The format of a single location page title.', 'dbem' ).$locations_placeholder_tip );
1118
+ em_options_textarea ( sprintf(__('Single %s page format', 'dbem' ),__('location','dbem')), 'dbem_single_location_format', __( 'The format of a single location page.', 'dbem' ).$locations_placeholder_tip );
1119
+ em_options_textarea ( __( 'Default location balloon format', 'dbem' ), 'dbem_location_baloon_format', __( 'The format of of the text appearing in the baloon describing the location a single location map.', 'dbem' ).$locations_placeholder_tip );
1120
+ ?>
1121
+ <tr><td><strong><?php echo sprintf(__('%s List Formats','dbem'),__('Event','dbem')); ?></strong></td></tr>
1122
+ <?php
1123
+ em_options_input_text ( __( 'Default event list format header', 'dbem' ), 'dbem_location_event_list_item_header_format', __( 'This content will appear just above your code for the default event list format. Default is blank', 'dbem' ) );
1124
+ em_options_textarea ( sprintf(__( 'Default %s list format', 'dbem' ),__('events','dbem')), 'dbem_location_event_list_item_format', __( 'The format of the events the list inserted in the location page through the <code>#_LOCATIONNEXTEVENTS</code>, <code>#_LOCATIONNEXTEVENTS</code> and <code>#_LOCATIONALLEVENTS</code> element.', 'dbem' ).$locations_placeholder_tip );
1125
+ em_options_input_text ( __( 'Default event list format footer', 'dbem' ), 'dbem_location_event_list_item_footer_format', __( 'This content will appear just below your code for the default event list format. Default is blank', 'dbem' ) );
1126
+ em_options_textarea ( sprintf(__( 'No %s message', 'dbem' ),__('events','dbem')), 'dbem_location_no_events_message', __( 'The message to be displayed in the list generated by <code>#_LOCATIONNEXTEVENTS</code>, <code>#_LOCATIONNEXTEVENTS</code> and <code>#_LOCATIONALLEVENTS</code> when no events are available.', 'dbem' ) );
1127
+ echo $save_button;
1128
+ ?>
1129
+ </table>
1130
+ </div> <!-- . inside -->
1131
+ </div> <!-- .postbox -->
1132
+ <?php endif; ?>
1133
+
1134
+ <?php if( get_option('dbem_categories_enabled') && !(EM_MS_GLOBAL && !is_main_blog()) ): ?>
1135
+ <div class="postbox " >
1136
+ <div class="handlediv" title="<?php __('Click to toggle', 'dbem'); ?>"><br /></div><h3><span><?php _e ( 'Categories format', 'dbem' ); ?> </span></h3>
1137
+ <div class="inside">
1138
+ <table class="form-table">
1139
+ <tr><td><strong><?php echo sprintf(__('%s Page','dbem'),__('Categories','dbem')); ?></strong></td></tr>
1140
+ <?php
1141
+ em_options_textarea ( sprintf(__('%s list header format','dbem'),__('Categories','dbem')), 'dbem_categories_list_item_format_header', sprintf(__( 'This content will appear just above your code for the %s list format below. Default is blank', 'dbem' ), __('categories','dbem')) );
1142
+ em_options_textarea ( sprintf(__('%s list item format','dbem'),__('Categories','dbem')), 'dbem_categories_list_item_format', sprintf(__( 'The format of a single %s in a list.', 'dbem' ), __('categories','dbem')).$categories_placeholder_tip );
1143
+ em_options_textarea ( sprintf(__('%s list footer format','dbem'),__('Categories','dbem')), 'dbem_categories_list_item_format_footer', sprintf(__( 'This content will appear just below your code for the %s list format above. Default is blank', 'dbem' ), __('categories','dbem')) );
1144
+ em_options_input_text ( sprintf(__( 'No %s message', 'dbem' ),__('Categories','dbem')), 'dbem_no_categories_message', sprintf( __( 'The message displayed when no %s are available.', 'dbem' ), __('categories','dbem')) );
1145
+ ?>
1146
+ <tr><td><strong><?php echo sprintf(__('Single %s Page','dbem'),__('Category','dbem')); ?></strong></td></tr>
1147
+ <?php
1148
+ em_options_input_text ( sprintf(__( 'Single %s title format', 'dbem' ),__('category','dbem')), 'dbem_category_page_title_format', __( 'The format of a single category page title.', 'dbem' ).$categories_placeholder_tip );
1149
+ em_options_textarea ( sprintf(__('Single %s page format', 'dbem' ),__('category','dbem')), 'dbem_category_page_format', __( 'The format of a single category page.', 'dbem' ).$categories_placeholder_tip );
1150
+ ?>
1151
+ <tr><td><strong><?php echo sprintf(__('%s List Formats','dbem'),__('Event','dbem')); ?></strong></td></tr>
1152
+ <?php
1153
+ em_options_input_text ( __( 'Default event list format header', 'dbem' ), 'dbem_category_event_list_item_header_format', __( 'This content will appear just above your code for the default event list format. Default is blank', 'dbem' ) );
1154
+ em_options_textarea ( sprintf(__( 'Default %s list format', 'dbem' ),__('events','dbem')), 'dbem_category_event_list_item_format', __( 'The format of the events the list inserted in the category page through the <code>#_CATEGORYNEXTEVENTS</code>, <code>#_CATEGORYNEXTEVENTS</code> and <code>#_CATEGORYALLEVENTS</code> element.', 'dbem' ).$categories_placeholder_tip );
1155
+ em_options_input_text ( __( 'Default event list format footer', 'dbem' ), 'dbem_category_event_list_item_footer_format', __( 'This content will appear just below your code for the default event list format. Default is blank', 'dbem' ) );
1156
+ em_options_textarea ( sprintf(__( 'No %s message', 'dbem' ),__('events','dbem')), 'dbem_category_no_events_message', __( 'The message to be displayed in the list generated by <code>#_CATEGORYNEXTEVENTS</code>, <code>#_CATEGORYNEXTEVENTS</code> and <code>#_CATEGORYALLEVENTS</code> when no events are available.', 'dbem' ) );
1157
+ echo $save_button;
1158
+ ?>
1159
+ </table>
1160
+ </div> <!-- . inside -->
1161
+ </div> <!-- .postbox -->
1162
+ <?php endif; ?>
1163
+
1164
+ <?php if( get_option('dbem_tags_enabled') ): ?>
1165
+ <div class="postbox " >
1166
+ <div class="handlediv" title="<?php __('Click to toggle', 'dbem'); ?>"><br /></div><h3><span><?php _e ( 'Tags format', 'dbem' ); ?> </span></h3>
1167
+ <div class="inside">
1168
+ <table class="form-table">
1169
+ <tr><td><strong><?php echo sprintf(__('Single %s Page','dbem'),__('Tag','dbem')); ?></strong></td></tr>
1170
+ <?php
1171
+ em_options_input_text ( sprintf(__( 'Single %s title format', 'dbem' ),__('tag','dbem')), 'dbem_tag_page_title_format', __( 'The format of a single tag page title.', 'dbem' ).$categories_placeholder_tip );
1172
+ em_options_textarea ( sprintf(__('Single %s page format', 'dbem' ),__('tag','dbem')), 'dbem_tag_page_format', __( 'The format of a single tag page.', 'dbem' ).$categories_placeholder_tip );
1173
+ ?>
1174
+ <tr><td><strong><?php echo sprintf(__('%s List Formats','dbem'),__('Event','dbem')); ?></strong></td></tr>
1175
+ <?php
1176
+ em_options_input_text ( __( 'Default event list format header', 'dbem' ), 'dbem_tag_event_list_item_header_format', __( 'This content will appear just above your code for the default event list format. Default is blank', 'dbem' ) );
1177
+ em_options_textarea ( sprintf(__( 'Default %s list format', 'dbem' ),__('events','dbem')), 'dbem_tag_event_list_item_format', __( 'The format of the events the list inserted in the tag page through the <code>#_TAGNEXTEVENTS</code>, <code>#_TAGNEXTEVENTS</code> and <code>#_TAGALLEVENTS</code> element.', 'dbem' ).$categories_placeholder_tip );
1178
+ em_options_input_text ( __( 'Default event list format footer', 'dbem' ), 'dbem_tag_event_list_item_footer_format', __( 'This content will appear just below your code for the default event list format. Default is blank', 'dbem' ) );
1179
+ em_options_textarea ( sprintf(__( 'No %s message', 'dbem' ),__('events','dbem')), 'dbem_tag_no_events_message', __( 'The message to be displayed in the list generated by <code>#_TAGNEXTEVENTS</code>, <code>#_TAGNEXTEVENTS</code> and <code>#_TAGALLEVENTS</code> when no events are available.', 'dbem' ) );
1180
+ echo $save_button;
1181
+ ?>
1182
+ </table>
1183
+ </div> <!-- . inside -->
1184
+ </div> <!-- .postbox -->
1185
+ <?php endif; ?>
1186
+
1187
+ <div class="postbox " >
1188
+ <div class="handlediv" title="<?php __('Click to toggle', 'dbem'); ?>"><br /></div><h3><span><?php _e ( 'RSS feed format', 'dbem' ); ?> </span></h3>
1189
+ <div class="inside">
1190
+ <table class="form-table">
1191
+ <?php
1192
+ em_options_input_text ( __( 'RSS main title', 'dbem' ), 'dbem_rss_main_title', __( 'The main title of your RSS events feed.', 'dbem' ).$events_placeholder_tip );
1193
+ em_options_input_text ( __( 'RSS main description', 'dbem' ), 'dbem_rss_main_description', __( 'The main description of your RSS events feed.', 'dbem' ) );
1194
+ em_options_input_text ( __( 'RSS title format', 'dbem' ), 'dbem_rss_title_format', __( 'The format of the title of each item in the events RSS feed.', 'dbem' ).$events_placeholder_tip );
1195
+ em_options_input_text ( __( 'RSS description format', 'dbem' ), 'dbem_rss_description_format', __( 'The format of the description of each item in the events RSS feed.', 'dbem' ).$events_placeholder_tip );
1196
+ echo $save_button;
1197
+ ?>
1198
+ </table>
1199
+ </div> <!-- . inside -->
1200
+ </div> <!-- .postbox -->
1201
+
1202
+ <div class="postbox " >
1203
+ <div class="handlediv" title="<?php __('Click to toggle', 'dbem'); ?>"><br /></div><h3><span><?php _e ( 'Maps and geotagging', 'dbem' ); ?> </span></h3>
1204
+ <div class="inside">
1205
+ <table class='form-table'>
1206
+ <?php $gmap_is_active = get_option ( 'dbem_gmap_is_active' ); ?>
1207
+ <tr valign="top">
1208
+ <th scope="row"><?php _e ( 'Enable Google Maps integration?', 'dbem' ); ?></th>
1209
+ <td>
1210
+ <?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'":''; ?> />
1211
+ <?php _e ( 'No' ); ?> <input name="dbem_gmap_is_active" type="radio" value="0" <?php echo ($gmap_is_active) ? '':"checked='checked'"; ?> /><br />
1212
+ <em><?php _e ( 'Check this option to enable Goggle Map integration.', 'dbem' )?></em>
1213
+ </td>
1214
+ </tr>
1215
+ <?php
1216
+ em_options_textarea ( __( 'Map text format', 'dbem' ), 'dbem_map_text_format', __( 'The text format inside the map balloons.', 'dbem' ).$events_placeholder_tip );
1217
+ echo $save_button;
1218
+ ?>
1219
+ </table>
1220
+ </div> <!-- . inside -->
1221
+ </div> <!-- .postbox -->
1222
+
1223
+ <?php do_action('em_options_page_footer_formats'); ?>
1224
+
1225
+ </div> <!-- .em-menu-formats -->
1226
+
1227
+ <?php if( get_option('dbem_rsvp_enabled') ): ?>
1228
+ <!-- BOOKING OPTIONS -->
1229
+ <div class="em-menu-bookings em-menu-group" style="display:none;">
1230
+
1231
+ <div class="postbox " >
1232
+ <div class="handlediv" title="<?php __('Click to toggle', 'dbem'); ?>"><br /></div><h3><span><?php echo sprintf(__( '%s Options', 'dbem' ),__('General','dbem')); ?> </span></h3>
1233
+ <div class="inside">
1234
+ <table class='form-table'>
1235
+ <?php
1236
+ em_options_radio_binary ( __( 'Allow guest bookings?', 'dbem' ), 'dbem_bookings_anonymous', __( 'If enabled, guest visitors can supply an email address and a user account will automatically be created for them along with their booking. They will be also be able to log back in with that newly created account.', 'dbem' ) );
1237
+ em_options_radio_binary ( __( 'Approval Required?', 'dbem' ), 'dbem_bookings_approval', __( 'Bookings will not be confirmed until the event administrator approves it.', 'dbem' ) );
1238
+ em_options_radio_binary ( __( 'Reserved unconfirmed spaces?', 'dbem' ), 'dbem_bookings_approval_reserved', __( 'By default, event spaces become unavailable once there are enough CONFIRMED bookings. To reserve spaces even if unnapproved, choose yes.', 'dbem' ) );
1239
+ em_options_radio_binary ( __( 'Can users cancel their booking?', 'dbem' ), 'dbem_bookings_user_cancellation', __( 'If enabled, users can cancel their bookings themselves from their bookings page.', 'dbem' ) );
1240
+ em_options_radio_binary ( __( 'Allow overbooking when approving?', 'dbem' ), 'dbem_bookings_approval_overbooking', __( 'If you get a lot of pending bookings and you decide to allow more bookings than spaces allow, setting this to yes will allow you to override the event space limit when manually approving.', 'dbem' ) );
1241
+ em_options_radio_binary ( __( 'Allow double bookings?', 'dbem' ), 'dbem_bookings_double', __( 'If enabled, users can book an event more than once.', 'dbem' ) );
1242
+ echo $save_button;
1243
+ ?>
1244
+ </table>
1245
+ </div> <!-- . inside -->
1246
+ </div> <!-- .postbox -->
1247
+
1248
+ <div class="postbox " >
1249
+ <div class="handlediv" title="<?php __('Click to toggle', 'dbem'); ?>"><br /></div><h3><span><?php echo sprintf(__( '%s Options', 'dbem' ),__('Pricing','dbem')); ?> </span></h3>
1250
+ <div class="inside">
1251
+ <table class='form-table'>
1252
+ <?php
1253
+ /* Tax & Currency */
1254
+ em_options_select ( __( 'Currency', 'dbem' ), 'dbem_bookings_currency', em_get_currencies()->names, __( 'Choose your currency for displaying event pricing.', 'dbem' ) );
1255
+ em_options_input_text ( __( 'Thousands Seperator', 'dbem' ), 'dbem_bookings_currency_thousands_sep', '<code>'.get_option('dbem_bookings_currency_thousands_sep')." = ".em_get_currency_symbol().'100<strong>'.get_option('dbem_bookings_currency_thousands_sep').'</strong>000<strong>'.get_option('dbem_bookings_currency_decimal_point').'</strong>00</code>' );
1256
+ em_options_input_text ( __( 'Decimal Point', 'dbem' ), 'dbem_bookings_currency_decimal_point', '<code>'.get_option('dbem_bookings_currency_decimal_point')." = ".em_get_currency_symbol().'100<strong>'.get_option('dbem_bookings_currency_decimal_point').'</strong>00</code>' );
1257
+ em_options_input_text ( __( 'Currency Format', 'dbem' ), 'dbem_bookings_currency_format', __('Choose how prices are displayed. <code>@</code> will be replaced by the currency symbol, and <code>#</code> will be replaced by the number.','dbem').' <code>'.get_option('dbem_bookings_currency_format')." = ".em_get_currency_formatted('10000000').'</code>');
1258
+ em_options_input_text ( __( 'Tax Rate', 'dbem' ), 'dbem_bookings_tax', __( 'Add a tax rate to your ticket prices (entering 10 will add 10% to the ticket price).', 'dbem' ) );
1259
+ em_options_radio_binary ( __( 'Add tax to ticket price?', 'dbem' ), 'dbem_bookings_tax_auto_add', __( 'When displaying ticket prices and booking totals, include the tax automatically?', 'dbem' ) );
1260
+ echo $save_button;
1261
+ ?>
1262
+ </table>
1263
+ </div> <!-- . inside -->
1264
+ </div> <!-- .postbox -->
1265
+
1266
+ <div class="postbox " >
1267
+ <div class="handlediv" title="<?php __('Click to toggle', 'dbem'); ?>"><br /></div><h3><span><?php _e( 'Customize Feedback Messages', 'dbem' ); ?> </span></h3>
1268
+ <div class="inside">
1269
+ <p><?php _e('Below you will find texts that will be displayed to users in various areas during the bookings process, particularly on booking forms.','dbem'); ?></p>
1270
+ <table class='form-table'>
1271
+ <tr><td colspan='2'><h4><?php _e('My Bookings messages','dbem') ?></h4></td></tr>
1272
+ <?php
1273
+ em_options_input_text ( __( 'Booking Cancelled', 'dbem' ), 'dbem_booking_feedback_cancelled', __( 'When a user cancels their booking, this message will be displayed confirming the cancellation.', 'dbem' ) );
1274
+ em_options_input_text ( __( 'Booking Cancellation Warning', 'dbem' ), 'dbem_booking_warning_cancel', __( 'When a user chooses to cancel a booking, this warning is displayed for them to confirm.', 'dbem' ) );
1275
+ ?>
1276
+ <tr><td colspan='2'><h4><?php _e('Booking form texts/messages','dbem') ?></h4></td></tr>
1277
+ <?php
1278
+ em_options_input_text ( __( 'Bookings disabled', 'dbem' ), 'dbem_bookings_form_msg_disabled', __( 'An event with no bookings.', 'dbem' ) );
1279
+ em_options_input_text ( __( 'Bookings closed', 'dbem' ), 'dbem_bookings_form_msg_closed', __( 'Bookings have closed (e.g. event has started).', 'dbem' ) );
1280
+ em_options_input_text ( __( 'Fully booked', 'dbem' ), 'dbem_bookings_form_msg_full', __( 'Event is fully booked.', 'dbem' ) );
1281
+ em_options_input_text ( __( 'Already attending', 'dbem' ), 'dbem_bookings_form_msg_attending', __( 'If already attending and double bookings are disabled, this message will be displayed, followed by a link to the users booking page.', 'dbem' ) );
1282
+ em_options_input_text ( __( 'Manage bookings link text', 'dbem' ), 'dbem_bookings_form_msg_bookings_link', __( 'Link text used for link to user bookings.', 'dbem' ) );
1283
+ ?>
1284
+ <tr><td colspan='2'><h4><?php _e('Booking form feedback messages','dbem') ?></h4></td></tr>
1285
+ <tr><td colspan='2'><?php _e('When a booking is made by a user, a feedback message is shown depending on the result, which can be customized below.','dbem'); ?></td></tr>
1286
+ <?php
1287
+ em_options_input_text ( __( 'Successful booking', 'dbem' ), 'dbem_booking_feedback', __( 'When a booking is registered and confirmed.', 'dbem' ) );
1288
+ em_options_input_text ( __( 'Successful pending booking', 'dbem' ), 'dbem_booking_feedback_pending', __( 'When a booking is registered but pending.', 'dbem' ) );
1289
+ em_options_input_text ( __( 'Not enough spaces', 'dbem' ), 'dbem_booking_feedback_full', __( 'When a booking cannot be made due to lack of spaces.', 'dbem' ) );
1290
+ em_options_input_text ( __( 'Errors', 'dbem' ), 'dbem_booking_feedback_error', __( 'When a booking cannot be made due to an error when filling the form. Below this, there will be a dynamic list of errors.', 'dbem' ) );
1291
+ em_options_input_text ( __( 'Email Exists', 'dbem' ), 'dbem_booking_feedback_email_exists', __( 'When a guest tries to book using an email registered with a user account.', 'dbem' ) );
1292
+ em_options_input_text ( __( 'User must log in', 'dbem' ), 'dbem_booking_feedback_log_in', __( 'When a user must log in before making a booking.', 'dbem' ) );
1293
+ em_options_input_text ( __( 'Error mailing user', 'dbem' ), 'dbem_booking_feedback_nomail', __( 'If a booking is made and an email cannot be sent, this is added to the success message.', 'dbem' ) );
1294
+ em_options_input_text ( __( 'Already booked', 'dbem' ), 'dbem_booking_feedback_already_booked', __( 'If the user made a previous booking and cannot double-book.', 'dbem' ) );
1295
+ em_options_input_text ( __( 'No spaces booked', 'dbem' ), 'dbem_booking_feedback_min_space', __( 'If the user tries to make a booking without requesting any spaces.', 'dbem' ) );
1296
+ echo $save_button;
1297
+ ?>
1298
+ </table>
1299
+ </div> <!-- . inside -->
1300
+ </div> <!-- .postbox -->
1301
+
1302
+ <div class="postbox " >
1303
+ <div class="handlediv" title="<?php __('Click to toggle', 'dbem'); ?>"><br /></div><h3><span><?php echo sprintf(__( '%s Options', 'dbem' ),__('Booking Form','dbem')); ?> </span></h3>
1304
+ <div class="inside">
1305
+ <table class='form-table'>
1306
+ <?php
1307
+ em_options_radio_binary ( __( 'Display login form?', 'dbem' ), 'dbem_bookings_login_form', __( 'Choose whether or not to display a login form in the booking form area to remind your members to log in before booking.', 'dbem' ) );
1308
+ em_options_input_text ( __( 'Submit button text', 'dbem' ), 'dbem_bookings_submit_button', sprintf(__( 'The text used by the submit button. To use an image instead, enter the full url starting with %s or %s.', 'dbem' ), '<code>http://</code>','<code>https://</code>') );
1309
+ ?>
1310
+ </table>
1311
+ </div> <!-- . inside -->
1312
+ </div> <!-- .postbox -->
1313
+
1314
+ <div class="postbox " >
1315
+ <div class="handlediv" title="<?php __('Click to toggle', 'dbem'); ?>"><br /></div><h3><span><?php echo sprintf(__( '%s Options', 'dbem' ),__('Ticket','dbem')); ?> </span></h3>
1316
+ <div class="inside">
1317
+ <table class='form-table'>
1318
+ <?php
1319
+ em_options_radio_binary ( __( 'Single ticket mode?', 'dbem' ), 'dbem_bookings_tickets_single', __( 'In single ticket mode, users can only create one ticket per booking (and will not see options to add more tickets).', 'dbem' ) );
1320
+ em_options_radio_binary ( __( 'Show ticket table in single ticket mode?', 'dbem' ), 'dbem_bookings_tickets_single_form', __( 'If you prefer a ticket table like with multiple tickets, even for single ticket events, enable this.', 'dbem' ) );
1321
+ em_options_radio_binary ( __( 'Show unavailable tickets?', 'dbem' ), 'dbem_bookings_tickets_show_unavailable', __( 'You can choose whether or not to show unavailable tickets to visitors.', 'dbem' ) );
1322
+ em_options_radio_binary ( __( 'Show multiple tickets if logged out?', 'dbem' ), 'dbem_bookings_tickets_show_loggedout', __( 'If logged out, a user will be asked to register in order to book. However, we can show available tickets if you have more than one ticket.', 'dbem' ) );
1323
+ $ticket_orders = array(
1324
+ 'ticket_price DESC, ticket_name ASC'=>__('Ticket Price (Descending)','dbem'),
1325
+ 'ticket_price ASC, ticket_name ASC'=>__('Ticket Price (Ascending)','dbem'),
1326
+ 'ticket_name ASC, ticket_price DESC'=>__('Ticket Name (Ascending)','dbem'),
1327
+ 'ticket_name DESC, ticket_price DESC'=>__('Ticket Name (Descending)','dbem')
1328
+ );
1329
+ em_options_select ( __( 'Order Tickets By', 'dbem' ), 'dbem_bookings_tickets_orderby', $ticket_orders, __( 'Choose which order your tickets appear.', 'dbem' ) );
1330
+ echo $save_button;
1331
+ ?>
1332
+ </table>
1333
+ </div> <!-- . inside -->
1334
+ </div> <!-- .postbox -->
1335
+
1336
+ <div class="postbox " >
1337
+ <div class="handlediv" title="<?php __('Click to toggle', 'dbem'); ?>"><br /></div><h3><span><?php _e('No-User Booking Mode','dbem'); ?> </span></h3>
1338
+ <div class="inside">
1339
+ <table class='form-table'>
1340
+ <tr><td colspan='2'>
1341
+ <p><?php _e('By default, when a booking is made by a user, this booking is tied to a user account, if the user is not registered nor logged in and guest bookings are enabled, an account will be created for them.','dbem'); ?></p>
1342
+ <p><?php _e('The option below allows you to disable user accounts and assign all bookings to a parent user, yet you will still see the supplied booking personal information for each booking. When this mode is enabled, extra booking information about the person is stored alongside the booking record rather than as a WordPress user.','dbem'); ?></p>
1343
+ <p><?php _e('<strong>Warning : </strong> Various features afforded to users with an account will not be available, e.g. viewing bookings. Once you enable this and select a user, modifying these values will prevent older non-user bookings from displaying the correct information.','dbem'); ?></p>
1344
+ </td></tr>
1345
+ <?php
1346
+ em_options_radio_binary ( __( 'Enable No-User Booking Mode?', 'dbem' ), 'dbem_bookings_registration_disable', __( 'This disables user registrations for bookings.', 'dbem' ) );
1347
+ $current_user = array();
1348
+ if( get_option('dbem_bookings_registration_user') ){
1349
+ $user = get_user_by('id',get_option('dbem_bookings_registration_user'));
1350
+ $current_user[$user->ID] = $user->display_name;
1351
+ }
1352
+ em_options_select ( __( 'Assign bookings to', 'dbem' ), 'dbem_bookings_registration_user', em_get_wp_users(array('role' => 'subscriber'), $current_user), __( 'Choose a parent user to assign bookings to. People making their booking will be unaware of this and will never have access to those user details. This should be a subscriber user you do not use to log in with yourself.', 'dbem' ) );
1353
+ echo $save_button;
1354
+ ?>
1355
+ </table>
1356
+ </div> <!-- . inside -->
1357
+ </div> <!-- .postbox -->
1358
+
1359
+ <?php do_action('em_options_page_footer_bookings'); ?>
1360
+
1361
+ </div> <!-- .em-menu-bookings -->
1362
+ <?php endif; ?>
1363
+
1364
+ <!-- EMAIL OPTIONS -->
1365
+ <div class="em-menu-emails em-menu-group" style="display:none;">
1366
+
1367
+ <?php if ( !is_multisite() ) { em_admin_option_box_email(); } ?>
1368
+
1369
+ <?php if( get_option('dbem_rsvp_enabled') ): ?>
1370
+ <div class="postbox " >
1371
+ <div class="handlediv" title="<?php __('Click to toggle', 'dbem'); ?>"><br /></div><h3><span><?php _e ( 'Booking Email Templates', 'dbem' ); ?> </span></h3>
1372
+ <div class="inside">
1373
+ <table class='form-table'>
1374
+ <?php
1375
+ $email_subject_tip = __('You can disable this email by leaving the subject blank.','dbem');
1376
+ em_options_select ( __( 'Default contact person', 'dbem' ), 'dbem_default_contact_person', em_get_wp_users(), __( 'Select the default contact person. This user will be employed whenever a contact person is not explicitly specified for an event', 'dbem' ) );
1377
+ em_options_input_text ( __( 'Email events admin?', 'dbem' ), 'dbem_bookings_notify_admin', __( "If you would like every event booking confirmation email sent to an administrator write their email here (leave blank to not send an email).", 'dbem' ).' '.__('For multiple emails, seperate by commas (e.g. email1@test.com,email2@test.com,etc.)','dbem') );
1378
+ em_options_radio_binary ( __( 'Email contact person?', 'dbem' ), 'dbem_bookings_contact_email', __( 'Check this option if you want the event contact to receive an email when someone books places. An email will be sent when a booking is first made (regardless if confirmed or pending)', 'dbem' ) );
1379
+ em_options_radio_binary ( __( 'Disable new registration email?', 'dbem' ), 'dbem_email_disable_registration', __( 'Check this option if you want to prevent the WordPress registration email from going out when a user anonymously books an event.', 'dbem' ) );
1380
+ ?>
1381
+ <tr><td colspan='2'><h4><?php _e('Contact person booking confirmed','dbem') ?></h4></td></tr>
1382
+ <tr><td colspan='2'><?php echo __('An email will be sent to the event contact when a booking is first made.','dbem').$bookings_placeholder_tip ?></td></tr>
1383
+ <?php
1384
+ em_options_input_text ( __( 'Contact person email subject', 'dbem' ), 'dbem_bookings_contact_email_subject', $email_subject_tip );
1385
+ em_options_textarea ( __( 'Contact person email', 'dbem' ), 'dbem_bookings_contact_email_body', '' );
1386
+ ?>
1387
+ <tr><td colspan='2'><h4><?php _e('Contact person booking cancelled','dbem') ?></h4></td></tr>
1388
+ <tr><td colspan='2'><?php echo __('An email will be sent to the event contact if someone cancels their booking.','dbem').$bookings_placeholder_tip ?></td></tr>
1389
+ <?php
1390
+ em_options_input_text ( __( 'Contact person cancellation subject', 'dbem' ), 'dbem_contactperson_email_cancelled_subject', $email_subject_tip );
1391
+ em_options_textarea ( __( 'Contact person cancellation email', 'dbem' ), 'dbem_contactperson_email_cancelled_body', '' );
1392
+ ?>
1393
+ <tr><td colspan='2'><h4><?php _e('Confirmed booking email','dbem') ?></h4></td></tr>
1394
+ <tr><td colspan='2'><?php echo __('This is sent when a person\'s booking is confirmed. This will be sent automatically if approvals are required and the booking is approved. If approvals are disabled, this is sent out when a user first submits their booking.','dbem').$bookings_placeholder_tip ?></td></tr>
1395
+ <?php
1396
+ em_options_input_text ( __( 'Booking confirmed email subject', 'dbem' ), 'dbem_bookings_email_confirmed_subject', $email_subject_tip );
1397
+ em_options_textarea ( __( 'Booking confirmed email', 'dbem' ), 'dbem_bookings_email_confirmed_body', '' );
1398
+ ?>
1399
+ <tr><td colspan='2'><h4><?php _e('Pending booking email','dbem') ?></h4></td></tr>
1400
+ <tr><td colspan='2'><?php echo __( 'This will be sent to the person when they first submit their booking. Not relevant if bookings don\'t require approval.', 'dbem' ).$bookings_placeholder_tip ?></td></tr>
1401
+ <?php
1402
+ em_options_input_text ( __( 'Booking pending email subject', 'dbem' ), 'dbem_bookings_email_pending_subject', $email_subject_tip);
1403
+ em_options_textarea ( __( 'Booking pending email', 'dbem' ), 'dbem_bookings_email_pending_body','') ;
1404
+ ?>
1405
+ <tr><td colspan='2'><h4><?php _e('Rejected booking email','dbem') ?></h4></td></tr>
1406
+ <tr><td colspan='2'><?php echo __( 'This will be sent automatically when a booking is rejected. Not relevant if bookings don\'t require approval.', 'dbem' ).$bookings_placeholder_tip ?></td></tr>
1407
+ <?php
1408
+ em_options_input_text ( __( 'Booking rejected email subject', 'dbem' ), 'dbem_bookings_email_rejected_subject', $email_subject_tip );
1409
+ em_options_textarea ( __( 'Booking rejected email', 'dbem' ), 'dbem_bookings_email_rejected_body', '' );
1410
+ ?>
1411
+ <tr><td colspan='2'><h4><?php _e('Booking cancelled','dbem') ?></h4></td></tr>
1412
+ <tr><td colspan='2'><?php echo __('This will be sent when a user cancels their booking.','dbem').$bookings_placeholder_tip ?></td></tr>
1413
+ <?php
1414
+ em_options_input_text ( __( 'Booking cancelled email subject', 'dbem' ), 'dbem_bookings_email_cancelled_subject', $email_subject_tip );
1415
+ em_options_textarea ( __( 'Booking cancelled email', 'dbem' ), 'dbem_bookings_email_cancelled_body', '' );
1416
+ ?>
1417
+ <?php echo $save_button; ?>
1418
+ </table>
1419
+ </div> <!-- . inside -->
1420
+ </div> <!-- .postbox -->
1421
+ <?php endif; ?>
1422
+
1423
+ <div class="postbox " >
1424
+ <div class="handlediv" title="<?php __('Click to toggle', 'dbem'); ?>"><br /></div><h3><span><?php _e ( 'Event Email Templates', 'dbem' ); ?> </span></h3>
1425
+ <div class="inside">
1426
+ <table class='form-table'>
1427
+ <tr><td colspan='2'><strong><?php _e('Event Submitted','dbem') ?></strong></td></tr>
1428
+ <tr><td colspan='2'><?php echo __('An email will be sent to the an administrator of your choice when an event is submitted and pending approval.','dbem').$bookings_placeholder_tip ?></td></tr>
1429
+ <?php
1430
+ em_options_input_text ( __( 'Administrator Email', 'dbem' ), 'dbem_event_submitted_email_admin', __('If left blank, no email will be sent. Seperate emails with commas for more than one email.','dbem') );
1431
+ em_options_input_text ( __( 'Event approved subject', 'dbem' ), 'dbem_event_submitted_email_subject', '' );
1432
+ em_options_textarea ( __( 'Event approved email', 'dbem' ), 'dbem_event_submitted_email_body', '' );
1433
+ ?>
1434
+ <tr><td colspan='2'><strong><?php _e('Event Approved','dbem') ?></strong></td></tr>
1435
+ <tr><td colspan='2'><?php echo __('An email will be sent to the event owner when their event is approved. Users requiring event approval do not have the <code>publish_events</code> capability.','dbem').$bookings_placeholder_tip ?></td></tr>
1436
+ <?php
1437
+ em_options_input_text ( __( 'Event approved subject', 'dbem' ), 'dbem_event_approved_email_subject', '' );
1438
+ em_options_textarea ( __( 'Event approved email', 'dbem' ), 'dbem_event_approved_email_body', '' );
1439
+ ?>
1440
+ <?php echo $save_button; ?>
1441
+ </table>
1442
+ </div> <!-- . inside -->
1443
+ </div> <!-- .postbox -->
1444
+
1445
+ <?php do_action('em_options_page_footer_emails'); ?>
1446
+
1447
+ </div><!-- .em-group-emails -->
1448
+ <?php /*
1449
+ <div class="postbox " >
1450
+ <div class="handlediv" title="<?php __('Click to toggle', 'dbem'); ?>"><br /></div><h3><span><?php _e ( 'Debug Modes', 'dbem' ); ?> </span></h3>
1451
+ <div class="inside">
1452
+ <table class='form-table'>
1453
+ <?php
1454
+ em_options_radio_binary ( __( 'EM Debug Mode?', 'dbem' ), 'dbem_debug', __( 'Setting this to yes will display different content to admins for event pages and emails so you can see all the available placeholders and their values.', 'dbem' ) );
1455
+ em_options_radio_binary ( __( 'WP Debug Mode?', 'dbem' ), 'dbem_wp_debug', __( 'This will turn WP_DEBUG mode on. Useful if you want to troubleshoot php errors without looking at your logs.', 'dbem' ) );
1456
+ ?>
1457
+ </table>
1458
+ </div> <!-- . inside -->
1459
+ </div> <!-- .postbox -->
1460
+ */ ?>
1461
+
1462
+ <p class="submit">
1463
+ <input type="submit" id="dbem_options_submit" name="Submit" value="<?php _e ( 'Save Changes' )?>" />
1464
+ <input type="hidden" name="em-submitted" value="1" />
1465
+ <input type="hidden" name="_wpnonce" value="<?php echo wp_create_nonce('events-manager-options'); ?>" />
1466
+ </p>
1467
+
1468
+ </div> <!-- .metabox-sortables -->
1469
+ </div> <!-- .postbox-container -->
1470
+
1471
+ </div> <!-- .metabox-holder -->
1472
+ </form>
1473
+ </div>
1474
+ <?php
1475
+ }
1476
+
1477
+ /**
1478
+ * Meta options box for image sizes. Shared in both MS and Normal options page, hence it's own function
1479
+ */
1480
+ function em_admin_option_box_image_sizes(){
1481
+ global $save_button;
1482
+ ?>
1483
+ <div class="postbox " >
1484
+ <div class="handlediv" title="<?php __('Click to toggle', 'dbem'); ?>"><br /></div><h3><span><?php _e ( 'Image Sizes', 'dbem' ); ?> </span></h3>
1485
+ <div class="inside">
1486
+ <table class='form-table'>
1487
+ <?php
1488
+ em_options_input_text ( __( 'Maximum width (px)', 'dbem' ), 'dbem_image_max_width', __( 'The maximum allowed width for images uploades', 'dbem' ) );
1489
+ em_options_input_text ( __( 'Minimum width (px)', 'dbem' ), 'dbem_image_min_width', __( 'The minimum allowed width for images uploades', 'dbem' ) );
1490
+ em_options_input_text ( __( 'Maximum height (px)', 'dbem' ), 'dbem_image_max_height', __( "The maximum allowed height for images uploaded, in pixels", 'dbem' ) );
1491
+ em_options_input_text ( __( 'Minimum height (px)', 'dbem' ), 'dbem_image_min_height', __( "The minimum allowed height for images uploaded, in pixels", 'dbem' ) );
1492
+ em_options_input_text ( __( 'Maximum size (bytes)', 'dbem' ), 'dbem_image_max_size', __( "The maximum allowed size for images uploaded, in bytes", 'dbem' ) );
1493
+ echo $save_button;
1494
+ ?>
1495
+ </table>
1496
+ </div> <!-- . inside -->
1497
+ </div> <!-- .postbox -->
1498
+ <?php
1499
+ }
1500
+
1501
+ /**
1502
+ * Meta options box for email settings. Shared in both MS and Normal options page, hence it's own function
1503
+ */
1504
+ function em_admin_option_box_email(){
1505
+ global $save_button;
1506
+ ?>
1507
+ <div class="postbox " >
1508
+ <div class="handlediv" title="<?php __('Click to toggle', 'dbem'); ?>"><br /></div><h3><span><?php _e ( 'Email Settings', 'dbem' ); ?></span></h3>
1509
+ <div class="inside">
1510
+ <table class='form-table'>
1511
+ <?php
1512
+ em_options_input_text ( __( 'Notification sender name', 'dbem' ), 'dbem_mail_sender_name', __( "Insert the display name of the notification sender.", 'dbem' ) );
1513
+ em_options_input_text ( __( 'Notification sender address', 'dbem' ), 'dbem_mail_sender_address', __( "Insert the address of the notification sender.", 'dbem' ) );
1514
+ em_options_select ( __( 'Mail sending method', 'dbem' ), 'dbem_rsvp_mail_send_method', array ('smtp' => 'SMTP', 'mail' => __( 'PHP mail function', 'dbem' ), 'sendmail' => 'Sendmail', 'qmail' => 'Qmail', 'wp_mail' => 'WP Mail' ), __( 'Select the method to send email notification.', 'dbem' ) );
1515
+ em_options_radio_binary ( __( 'Send HTML Emails?', 'dbem' ), 'dbem_smtp_html', __( 'If set to yes, your emails will be sent in HTML format, otherwise plaintext.', 'dbem' ).' '.__( 'Depending on server settings, some sending methods may ignore this settings.', 'dbem' ) );
1516
+ ?>
1517
+ <tbody class="em-email-settings-smtp">
1518
+ <?php
1519
+ em_options_input_text ( 'Mail sending port', 'dbem_rsvp_mail_port', __( "The port through which you e-mail notifications will be sent. Make sure the firewall doesn't block this port", 'dbem' ) );
1520
+ em_options_radio_binary ( __( 'Use SMTP authentication?', 'dbem' ), 'dbem_rsvp_mail_SMTPAuth', __( 'SMTP authentication is often needed. If you use GMail, make sure to set this parameter to Yes', 'dbem' ) );
1521
+ em_options_input_text ( 'SMTP host', 'dbem_smtp_host', __( "The SMTP host. Usually it corresponds to 'localhost'. If you use GMail, set this value to 'ssl://smtp.gmail.com:465'.", 'dbem' ) );
1522
+ em_options_input_text ( __( 'SMTP username', 'dbem' ), 'dbem_smtp_username', __( "Insert the username to be used to access your SMTP server.", 'dbem' ) );
1523
+ em_options_input_password ( __( 'SMTP password', 'dbem' ), "dbem_smtp_password", __( "Insert the password to be used to access your SMTP server", 'dbem' ) );
1524
+ ?>
1525
+ </tbody>
1526
+ <?php
1527
+ echo $save_button;
1528
+ ?>
1529
+ </table>
1530
+ <script type="text/javascript" charset="utf-8">
1531
+ jQuery(document).ready(function($){
1532
+ $('#dbem_rsvp_mail_send_method_row select').change(function(){
1533
+ el = $(this);
1534
+ if( el.find(':selected').val() == 'smtp' ){
1535
+ $('.em-email-settings-smtp').show();
1536
+ }else{
1537
+ $('.em-email-settings-smtp').hide();
1538
+ }
1539
+ }).trigger('change');
1540
+ });
1541
+ </script>
1542
+ </div> <!-- . inside -->
1543
+ </div> <!-- .postbox -->
1544
+ <?php
1545
+ }
1546
+
1547
+ /**
1548
+ * Meta options box for user capabilities. Shared in both MS and Normal options page, hence it's own function
1549
+ */
1550
+ function em_admin_option_box_caps(){
1551
+ global $save_button, $wpdb;
1552
+ ?>
1553
+ <div class="postbox" >
1554
+ <div class="handlediv" title="<?php __('Click to toggle', 'dbem'); ?>"><br /></div><h3><span><?php _e ( 'User Capabilities', 'dbem' ); ?></span></h3>
1555
+ <div class="inside">
1556
+ <table class="form-table">
1557
+ <tr><td colspan="2">
1558
+ <strong><?php _e('Warning: Changing these values may result in exposing previously hidden information to all users.', 'dbem')?></strong><br />
1559
+ </td></tr>
1560
+ <?php
1561
+ global $wp_roles;
1562
+ $cap_docs = array(
1563
+ sprintf(__('%s Capabilities','dbem'),__('Event','dbem')) => array(
1564
+ /* Event Capabilities */
1565
+ 'publish_events' => sprintf(__('Users can publish %s and skip any admin approval','dbem'),__('events','dbem')),
1566
+ 'delete_others_events' => sprintf(__('User can delete other users %s','dbem'),__('events','dbem')),
1567
+ 'edit_others_events' => sprintf(__('User can edit other users %s','dbem'),__('events','dbem')),
1568
+ 'delete_events' => sprintf(__('User can delete their own %s','dbem'),__('events','dbem')),
1569
+ 'edit_events' => sprintf(__('User can create and edit %s','dbem'),__('events','dbem')),
1570
+ 'read_private_events' => sprintf(__('User can view private %s','dbem'),__('events','dbem')),
1571
+ /*'read_events' => sprintf(__('User can view %s','dbem'),__('events','dbem')),*/
1572
+ ),
1573
+ sprintf(__('%s Capabilities','dbem'),__('Recurring Event','dbem')) => array(
1574
+ /* Recurring Event Capabilties */
1575
+ 'publish_recurring_events' => sprintf(__('Users can publish %s and skip any admin approval','dbem'),__('recurring events','dbem')),
1576
+ 'delete_others_recurring_events' => sprintf(__('User can delete other users %s','dbem'),__('recurring events','dbem')),
1577
+ 'edit_others_recurring_events' => sprintf(__('User can edit other users %s','dbem'),__('recurring events','dbem')),
1578
+ 'delete_recurring_events' => sprintf(__('User can delete their own %s','dbem'),__('recurring events','dbem')),
1579
+ 'edit_recurring_events' => sprintf(__('User can create and edit %s','dbem'),__('recurring events','dbem'))
1580
+ ),
1581
+ sprintf(__('%s Capabilities','dbem'),__('Location','dbem')) => array(
1582
+ /* Location Capabilities */
1583
+ 'publish_locations' => sprintf(__('Users can publish %s and skip any admin approval','dbem'),__('locations','dbem')),
1584
+ 'delete_others_locations' => sprintf(__('User can delete other users %s','dbem'),__('locations','dbem')),
1585
+ 'edit_others_locations' => sprintf(__('User can edit other users %s','dbem'),__('locations','dbem')),
1586
+ 'delete_locations' => sprintf(__('User can delete their own %s','dbem'),__('locations','dbem')),
1587
+ 'edit_locations' => sprintf(__('User can create and edit %s','dbem'),__('locations','dbem')),
1588
+ 'read_private_locations' => sprintf(__('User can view private %s','dbem'),__('locations','dbem')),
1589
+ 'read_others_locations' => __('User can use other user locations for their events.','dbem'),
1590
+ /*'read_locations' => sprintf(__('User can view %s','dbem'),__('locations','dbem')),*/
1591
+ ),
1592
+ sprintf(__('%s Capabilities','dbem'),__('Other','dbem')) => array(
1593
+ /* Category Capabilities */
1594
+ 'delete_event_categories' => sprintf(__('User can delete %s categories and tags.','dbem'),__('event','dbem')),
1595
+ 'edit_event_categories' => sprintf(__('User can edit %s categories and tags.','dbem'),__('event','dbem')),
1596
+ /* Booking Capabilities */
1597
+ 'manage_others_bookings' => __('User can manage other users individual bookings and event booking settings.','dbem'),
1598
+ 'manage_bookings' => __('User can use and manage bookings with their events.','dbem'),
1599
+ 'upload_event_images' => __('User can upload images along with their events and locations.','dbem')
1600
+ )
1601
+ );
1602
+ ?>
1603
+ <tr><td colspan="2">
1604
+ <p><em><?php _e('You can now give fine grained control with regards to what your users can do with events. Each user role can have perform different sets of actions.','dbem'); ?></em></p>
1605
+ </td></tr>
1606
+ <tr><td colspan="2">
1607
+ <?php
1608
+ if( is_multisite() && is_network_admin() ){
1609
+ echo em_options_radio_binary(__('Apply global capabilities?','dbem'), 'dbem_ms_global_caps', __('If set to yes the capabilities will be applied all your network blogs and you will not be able to set custom capabilities each blog. You can select no later and visit specific blog settings pages to add/remove capabilities.','dbem') );
1610
+ }
1611
+ ?>
1612
+ </td></tr>
1613
+ <tr><td colspan="2">
1614
+ <table class="em-caps-table" style="width:auto;" cellspacing="0" cellpadding="0">
1615
+ <thead>
1616
+ <tr>
1617
+ <td>&nbsp;</td>
1618
+ <?php
1619
+ $odd = 0;
1620
+ foreach(array_keys($cap_docs) as $capability_group){
1621
+ ?><th class="<?php echo ( !is_int($odd/2) ) ? 'odd':''; ?>"><?php echo $capability_group ?></th><?php
1622
+ $odd++;
1623
+ }
1624
+ ?>
1625
+ </tr>
1626
+ </thead>
1627
+ <tbody>
1628
+ <?php foreach($wp_roles->role_objects as $role): ?>
1629
+ <tr>
1630
+ <td class="cap"><strong><?php echo $role->name; ?></strong></td>
1631
+ <?php
1632
+ $odd = 0;
1633
+ foreach($cap_docs as $capability_group){
1634
+ ?>
1635
+ <td class="<?php echo ( !is_int($odd/2) ) ? 'odd':''; ?>">
1636
+ <?php foreach($capability_group as $cap => $cap_help){ ?>
1637
+ <input type="checkbox" name="em_capabilities[<?php echo $role->name; ?>][<?php echo $cap ?>]" value="1" id="<?php echo $role->name.'_'.$cap; ?>" <?php echo $role->has_cap($cap) ? 'checked="checked"':''; ?> />
1638
+ &nbsp;<label for="<?php echo $role->name.'_'.$cap; ?>"><?php echo $cap; ?></label>&nbsp;<a href="#" title="<?php echo $cap_help; ?>">?</a>
1639
+ <br />
1640
+ <?php } ?>
1641
+ </td>
1642
+ <?php
1643
+ $odd++;
1644
+ }
1645
+ ?>
1646
+ </tr>
1647
+ <?php endforeach; ?>
1648
+ </tbody>
1649
+ </table>
1650
+ </td></tr>
1651
+ <?php echo $save_button; ?>
1652
+ </table>
1653
+ </div> <!-- . inside -->
1654
+ </div> <!-- .postbox -->
1655
+ <?php
1656
+ }
1657
+
1658
+ function em_admin_option_box_uninstall(){
1659
+ if( is_multisite() ){
1660
+ $uninstall_url = admin_url().'network/admin.php?page=events-manager-options&amp;action=uninstall&amp;_wpnonce='.wp_create_nonce('em_uninstall_'.get_current_user_id().'_wpnonce');
1661
+ $reset_url = admin_url().'network/admin.php?page=events-manager-options&amp;action=reset&amp;_wpnonce='.wp_create_nonce('em_reset_'.get_current_user_id().'_wpnonce');
1662
+ $recheck_updates_url = admin_url().'network/admin.php?page=events-manager-options&amp;action=recheck_updates&amp;_wpnonce='.wp_create_nonce('em_recheck_updates_'.get_current_user_id().'_wpnonce');
1663
+ $check_devs = admin_url().'network/admin.php?page=events-manager-options&amp;action=check_devs&amp;_wpnonce='.wp_create_nonce('em_check_devs'.get_current_user_id().'_wpnonce');
1664
+ }else{
1665
+ $uninstall_url = EM_ADMIN_URL.'&amp;page=events-manager-options&amp;action=uninstall&amp;_wpnonce='.wp_create_nonce('em_uninstall_'.get_current_user_id().'_wpnonce');
1666
+ $reset_url = EM_ADMIN_URL.'&amp;page=events-manager-options&amp;action=reset&amp;_wpnonce='.wp_create_nonce('em_reset_'.get_current_user_id().'_wpnonce');
1667
+ $recheck_updates_url = EM_ADMIN_URL.'&amp;page=events-manager-options&amp;action=recheck_updates&amp;_wpnonce='.wp_create_nonce('em_recheck_updates_'.get_current_user_id().'_wpnonce');
1668
+ $check_devs = EM_ADMIN_URL.'&amp;page=events-manager-options&amp;action=check_devs&amp;_wpnonce='.wp_create_nonce('em_check_devs_'.get_current_user_id().'_wpnonce');
1669
+ }
1670
+ ?>
1671
+ <div class="postbox" >
1672
+ <div class="handlediv" title="<?php __('Click to toggle', 'dbem'); ?>"><br /></div><h3><span><?php _e ( 'Admin Tools', 'dbem' ); ?> (<?php _e ( 'Uninstall/Reset', 'dbem' ); ?>)</span></h3>
1673
+ <div class="inside">
1674
+ <h4 style="font-size:1.1em;"><?php _e ( 'Development Versions &amp; Updates', 'dbem' ); ?></h4>
1675
+ <p><?php _e('We\'re always making improvements, adding features and fixing bugs between releases. We incrementally make these changes in between updates and make it available as a development version. You can download these manually, but we\'ve made it easy for you. <strong>Warning:</strong> Development versions are not always fully tested before release, use wisely!'); ?></p>
1676
+ <table class="form-table">
1677
+ <?php em_options_radio_binary ( __( 'Enable Dev Updates?', 'dbem' ), 'dbem_pro_dev_updates', __('If enabled, the latest dev version will always be checked instead of the latest stable version of the plugin.') ); ?>
1678
+ </table>
1679
+ <p><a href="<?php echo $recheck_updates_url; ?>" class="button-secondary"><?php _e('Re-Check Updates','dbem'); ?></a> - <?php _e('If you would like to check and see if there is a new stable update.','dbem'); ?></p>
1680
+ <p><a href="<?php echo $check_devs; ?>" class="button-secondary"><?php _e('Check Dev Versions','dbem'); ?></a> - <?php _e('If you would like to download a dev version, but just as a one-off, you can force a dev version check by clicking the button below. If there is one available, it should appear in your plugin updates page as a regular update.','dbem'); ?></p>
1681
+
1682
+ <h4 style="font-size:1.1em;"><?php _e ( 'Uninstall/Reset', 'dbem' ); ?></h4>
1683
+ <p><?php _e('Use the buttons below to uninstall Events Manager completely from your system or reset Events Manager to original settings and keep your event data.','dbem'); ?></p>
1684
+ <a href="<?php echo $uninstall_url; ?>" class="button-secondary"><?php _e('Uninstall','dbem'); ?></a>
1685
+ <a href="<?php echo $reset_url; ?>" class="button-secondary"><?php _e('Reset','dbem'); ?></a>
1686
+ </div>
1687
+ </div>
1688
+ <?php
1689
+ }
1690
  ?>
admin/em-people.php DELETED
@@ -1,192 +0,0 @@
1
- <?php
2
- /**
3
- * Check for flags to save personal data
4
- */
5
- function em_person_actions(){
6
- global $EM_Person;
7
- if( !empty($_REQUEST['action']) && is_object($EM_Person) ){
8
- if( $_REQUEST['action'] == 'edit_person' ){
9
- $validation = $EM_Person->get_post();
10
- if ( $validation ) { //EM_Event gets the event if submitted via POST and validates it (safer than to depend on JS)
11
- //Save
12
- if( $EM_Person->save() ) {
13
- function em_person_save_notification(){
14
- global $EM_Person;
15
- ?><div class="updated"><p><strong><?php echo $EM_Person->feedback_message; ?></strong></p></div><?php
16
- }
17
- }else{
18
- function em_person_save_notification(){
19
- global $EM_Person;
20
- ?><div class="error"><p><strong><?php echo $EM_Person->feedback_message; ?></strong></p></div><?php
21
- }
22
- }
23
- }else{
24
- //TODO make errors clearer when saving person
25
- function em_person_save_notification(){
26
- global $EM_Person;
27
- ?><div class="error"><p><strong><?php echo $EM_Person->feedback_message; ?></strong></p></div><?php
28
- }
29
- }
30
- add_action ( 'admin_notices', 'em_person_save_notification' );
31
- }
32
- if( $_REQUEST['action'] == 'person_delete' ){
33
- if( $EM_Person->delete() ){
34
- //TODO delete person needs confirmation
35
- wp_redirect( get_bloginfo('wpurl').'/wp-admin/admin.php?page=events-manager-bookings');
36
- exit();
37
- }else{
38
- function em_person_delete_notification(){
39
- global $EM_Person;
40
- ?><div class="error"><p><strong><?php echo $EM_Person->feedback_message; ?></strong></p></div><?php
41
- }
42
- }
43
- add_action ( 'admin_notices', 'em_person_delete_notification' );
44
- }
45
- }
46
- }
47
- add_action('admin_init','em_person_actions');
48
-
49
- /**
50
- * Generate an edit form for person details.
51
- */
52
- function em_person_edit_form(){
53
- global $EM_Person;
54
- ?>
55
- <form action="" method="post" id="em-person-form">
56
- <table>
57
- <tr><td><strong><?php _e('Name','dbem'); ?></strong></td><td><input type="text" name="person_name" size="60" value="<?php echo $EM_Person->name; ?>" /></td></tr>
58
- <tr><td><strong><?php _e('Phone','dbem'); ?></strong></td><td><input type="text" name="person_phone" size="60" value="<?php echo $EM_Person->phone; ?>" /></td></tr>
59
- <tr><td><strong><?php _e('E-mail','dbem'); ?></strong></td><td><input type="text" name="person_email" size="60" value="<?php echo $EM_Person->email; ?>" /></td></tr>
60
- </table>
61
- <p class="submit">
62
- <input type="submit" name="events_update" value="<?php _e ( 'Save' ); ?> &raquo;" />
63
- </p>
64
- <input type="hidden" name="action" value="person_edit" />
65
- <input type="hidden" name="person_id" value="<?php echo $EM_Person->id; ?>" />
66
- </form>
67
- <?php
68
- }
69
-
70
- /**
71
- * Depreciated page... for now at least.
72
- */
73
- function em_admin_people_page() {
74
- ?>
75
- <div class='wrap'>
76
- <div id="icon-users" class="icon32"><br/></div>
77
- <h2>People</h2>
78
- <?php
79
- $EM_People = EM_People::get();
80
- if (count($EM_People) < 1 ) {
81
- _e("No people have responded to your events yet!", 'dbem');
82
- } else {
83
- ?>
84
- <p><?php _e('This table collects the data about the people who responded to your events', 'dbem') ?></p>
85
- <table id='dbem-people-table' class='widefat post fixed'>
86
- <thead>
87
- <tr>
88
- <th class='manage-column column-cb check-column' scope='col'>&nbsp;</th>
89
- <th class='manage-column ' scope='col'>Name</th>
90
- <th scope='col'>E-mail</th>
91
- <th scope='col'>Phone number</th>
92
- </tr>
93
- </thead>
94
- <tfoot>
95
- <tr>
96
- <th class='manage-column column-cb check-column' scope='col'>&nbsp;</th>
97
- <th class='manage-column ' scope='col'>Name</th>
98
- <th scope='col'>E-mail</th>
99
- <th scope='col'>Phone number</th>
100
- </tr>
101
- </tfoot>
102
- <?php foreach ($EM_People as $EM_Person): ?>
103
- <tr>
104
- <td>&nbsp;</td>
105
- <td><?php echo $EM_Person->name ?></td>
106
- <td><?php echo $EM_Person->email ?></td>
107
- <td><?php echo $EM_Person->phone ?></td>
108
- </tr>
109
- <?php endforeach; ?>
110
- </table>
111
- <?php
112
- }
113
- ?>
114
- </div>
115
- <?php
116
- }
117
-
118
- function em_printable_booking_report() {
119
- global $EM_Event;
120
- //check that user can access this page
121
- if( isset($_GET['page']) && $_GET['page']=='events-manager-bookings' && isset($_GET['action']) && $_GET['action'] == 'bookings_report' && is_object($EM_Event)){
122
- if( is_object($EM_Event) && !$EM_Event->can_manage() ){
123
- ?>
124
- <div class="wrap"><h2><?php _e('Unauthorized Access','dbem'); ?></h2><p><?php _e('You do not have the rights to manage this event.','dbem'); ?></p></div>
125
- <?php
126
- return false;
127
- }
128
- ?>
129
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
130
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
131
- <html>
132
- <head>
133
- <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
134
- <title>Bookings for <?php echo $EM_Event->name; ?></title>
135
- <link rel="stylesheet" href="<?php echo bloginfo('wpurl') ?>/wp-content/plugins/events-manager/includes/css/events_manager.css" type="text/css" media="screen" />
136
- </head>
137
- <body id="printable">
138
- <div id="container">
139
- <h1>Bookings for <?php echo $EM_Event->name; ?></h1>
140
- <p><?php echo $EM_Event->output("#d #M #Y"); ?></p>
141
- <p><?php echo $EM_Event->output("#_LOCATION, #_ADDRESS, #_TOWN"); ?></p>
142
- <h2><?php _e('Bookings data', 'dbem');?></h2>
143
- <table id="bookings-table">
144
- <tr>
145
- <th scope='col'><?php _e('Name', 'dbem')?></th>
146
- <th scope='col'><?php _e('E-mail', 'dbem')?></th>
147
- <th scope='col'><?php _e('Phone number', 'dbem')?></th>
148
- <th scope='col'><?php _e('Seats', 'dbem')?></th>
149
- <th scope='col'><?php _e('Comment', 'dbem')?></th>
150
- </tr>
151
- <?php foreach($EM_Event->get_bookings()->bookings as $EM_Booking) { ?>
152
- <tr>
153
-
154
- <td><?php echo $EM_Booking->person->name ?></td>
155
- <td><?php echo $EM_Booking->person->email ?></td>
156
- <td><?php echo $EM_Booking->person->phone ?></td>
157
- <td class='seats-number'><?php echo $EM_Booking->seats ?></td>
158
- <td><?php echo $EM_Booking->comment ?></td>
159
- </tr>
160
- <?php } ?>
161
- <tr id='booked-seats'>
162
- <td colspan='3'>&nbsp;</td>
163
- <td class='total-label'><?php _e('Booked', 'dbem')?>:</td>
164
- <td class='seats-number'><?php echo $EM_Event->get_bookings()->get_booked_seats(); ?></td>
165
- </tr>
166
- <tr id='available-seats'>
167
- <td colspan='3'>&nbsp;</td>
168
- <td class='total-label'><?php _e('Available', 'dbem')?>:</td>
169
- <td class='seats-number'><?php echo $EM_Event->get_bookings()->get_available_seats(); ?></td>
170
- </tr>
171
- </table>
172
- </div>
173
- </body>
174
- </html>
175
- <?php
176
- die();
177
- }
178
- }
179
- add_action('admin_init', 'em_printable_booking_report');
180
-
181
- /**
182
- * Adds phone number to contact info of users, compatible with previous phone field method
183
- * @param $array
184
- * @return array
185
- */
186
- function em_contact_methods($array){
187
- $array['dbem_phone'] = __('Phone','dbem') . ' <span class="description">('. __('Events Manager','dbem') .')</span>';
188
- return $array;
189
- }
190
- add_filter( 'user_contactmethods' , 'em_contact_methods' , 10 , 1 );
191
-
192
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
buddypress/bp-em-activity.php ADDED
@@ -0,0 +1,130 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // This file handles hooks/filter requiring activity stream publications
3
+
4
+ /**
5
+ * bp_em_record_activity()
6
+ *
7
+ * If the activity stream component is installed, this function will record activity items for your
8
+ * component.
9
+ */
10
+ function bp_em_record_activity( $args = '' ) {
11
+ if ( !function_exists( 'bp_activity_add' ) )
12
+ return false;
13
+
14
+ $defaults = array(
15
+ 'id' => false,
16
+ 'user_id' => '',
17
+ 'action' => '',
18
+ 'content' => '',
19
+ 'primary_link' => '',
20
+ 'component' => 'events-manager',
21
+ 'type' => false,
22
+ 'item_id' => false,
23
+ 'secondary_item_id' => false,
24
+ 'recorded_time' => gmdate( "Y-m-d H:i:s" ),
25
+ 'hide_sitewide' => false
26
+ );
27
+
28
+ $r = wp_parse_args( $args, $defaults );
29
+ extract( $r );
30
+ return bp_activity_add( array( 'id' => $id, 'user_id' => $user_id, 'action' => $action, 'content' => $content, 'primary_link' => $primary_link, 'component' => $component, 'type' => $type, 'item_id' => $item_id, 'secondary_item_id' => $secondary_item_id, 'recorded_time' => $recorded_time, 'hide_sitewide' => $hide_sitewide ) );
31
+ }
32
+
33
+ /**
34
+ * Records new events to the activity stream.
35
+ * @param unknown_type $result
36
+ * @param unknown_type $EM_Event
37
+ * @return unknown
38
+ */
39
+ function bp_em_record_activity_event_save( $result, $EM_Event ){
40
+ if( $result && $EM_Event->event_status == 1 && empty($EM_Event->previous_status) ){
41
+ $user = get_userdata($EM_Event->event_owner);
42
+ $member_slug = function_exists( 'bp_get_members_root_slug' ) ? bp_get_members_root_slug() : BP_MEMBERS_SLUG;
43
+ $member_link = trailingslashit(bp_get_root_domain()) . $member_slug . '/' . $user->user_login;
44
+ if( empty($EM_Event->group_id) ){
45
+ bp_em_record_activity( array(
46
+ 'user_id' => $user->ID,
47
+ 'action' => sprintf(__('%s added the event %s','dbem'), "<a href='".$member_link."/'>".$user->display_name."</a>", $EM_Event->output('#_EVENTLINK') ),
48
+ 'primary_link' => $EM_Event->output('#_EVENTURL'),
49
+ 'type' => 'new_event',
50
+ 'item_id' => $EM_Event->event_id,
51
+ 'hide_sitewide' => $EM_Event->event_private
52
+ ));
53
+ }else{
54
+ //tis a group event
55
+ $group = new BP_Groups_Group($EM_Event->group_id);
56
+ bp_em_record_activity( array(
57
+ 'user_id' => $user->ID,
58
+ 'action' => sprintf(__('%s added the event %s to %s.','dbem'), "<a href='".$member_link."/'>".$user->display_name."</a>", $EM_Event->output('#_EVENTLINK'), '<a href="'.bp_get_group_permalink($group).'">'.bp_get_group_name($group).'</a>' ),
59
+ 'component' => 'groups',
60
+ 'type' => 'new_event',
61
+ 'item_id' => $EM_Event->group_id,
62
+ 'hide_sitewide' => $EM_Event->event_private
63
+ ));
64
+ }
65
+ }
66
+ return $result;
67
+ }
68
+ add_filter('em_event_save','bp_em_record_activity_event_save', 10, 2);
69
+
70
+ /**
71
+ * @param boolean $result
72
+ * @param EM_Booking $EM_Booking
73
+ * @return boolean
74
+ */
75
+ function bp_em_record_activity_booking_save( $result, $EM_Booking ){
76
+ if( $result ){
77
+ $rejected_statuses = array(0,2,3); //these statuses apply to rejected/cancelled bookings
78
+ $user = $EM_Booking->person;
79
+ $member_slug = function_exists( 'bp_get_members_root_slug' ) ? bp_get_members_root_slug() : BP_MEMBERS_SLUG;
80
+ $member_link = trailingslashit(bp_get_root_domain()) . $member_slug . '/' . $user->user_login;
81
+ $user_link = "<a href='".$member_link."/'>".$user->display_name."</a>";
82
+ $event_link = $EM_Booking->get_event()->output('#_EVENTLINK');
83
+ $status = $EM_Booking->booking_status;
84
+ $EM_Event = $EM_Booking->get_event();
85
+ if( empty($EM_Event->group_id) ){
86
+ if( $status == 1 || (!get_option('dbem_bookings_approval') && $status < 2) ){
87
+ $action = sprintf(__('%s is attending %s.','dbem'), $user_link, $event_link );
88
+ }elseif( ($EM_Booking->previous_status == 1 || (!get_option('dbem_bookings_approval') && $EM_Booking->previous_status < 2)) && in_array($status, $rejected_statuses) ){
89
+ $action = sprintf(__('%s will not be attending %s anymore.','dbem'), $user_link, $event_link );
90
+ }
91
+ }else{
92
+ $group = new BP_Groups_Group($EM_Event->group_id);
93
+ $group_link = '<a href="'.bp_get_group_permalink($group).'">'.bp_get_group_name($group).'</a>';
94
+ if( $status == 1 || (!get_option('dbem_bookings_approval') && $status < 2) ){
95
+ $action = sprintf(__('%s is attending %s of the group %s.','dbem'), $user_link, $event_link, $group_link );
96
+ }elseif( ($EM_Booking->previous_status == 1 || (!get_option('dbem_bookings_approval') && $EM_Booking->previous_status < 2)) && in_array($status, $rejected_statuses) ){
97
+ $action = sprintf(__('%s will not be attending %s of group %s anymore.','dbem'), $user_link, $event_link, $group_link );
98
+ }
99
+ }
100
+ if( !empty($action) ){
101
+ bp_em_record_activity( array(
102
+ 'user_id' => $EM_Booking->person->ID,
103
+ 'action' => $action,
104
+ 'primary_link' => $EM_Event->output('#_EVENTURL'),
105
+ 'type' => 'new_booking',
106
+ 'item_id' => $EM_Event->event_id,
107
+ 'secondary_item_id' => $EM_Booking->booking_id,
108
+ 'hide_sitewide' => $EM_Event->event_private
109
+ ));
110
+ //group activity
111
+ if( !empty($EM_Event->group_id) ){
112
+ //tis a group event
113
+ bp_em_record_activity( array(
114
+ 'component' => 'groups',
115
+ 'item_id' => $EM_Event->group_id,
116
+ 'user_id' => $EM_Booking->person->ID,
117
+ 'action' => $action,
118
+ 'primary_link' => $EM_Event->output('#_EVENTURL'),
119
+ 'type' => 'new_booking',
120
+ 'secondary_item_id' => $EM_Booking->booking_id,
121
+ 'hide_sitewide' => $EM_Event->event_private
122
+ ));
123
+ }
124
+ }
125
+ }
126
+ return $result;
127
+ }
128
+ add_filter('em_booking_set_status','bp_em_record_activity_booking_save', 100, 2);
129
+ add_filter('em_booking_save','bp_em_record_activity_booking_save', 100, 2);
130
+ add_filter('em_booking_delete','bp_em_record_activity_booking_save', 100, 2);
buddypress/bp-em-core.php ADDED
@@ -0,0 +1,235 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ //Main loader for buddypress
3
+ /**
4
+ * Events Manager component for BuddyPress
5
+ * @author marcus
6
+ * @since 5.0
7
+ */
8
+ class BP_EM_Component extends BP_Component {
9
+
10
+ function __construct() {
11
+ global $bp;
12
+ parent::start('events', __('Events', 'dbem'), EM_DIR);
13
+ $this->includes();
14
+ //TODO make BP component optional
15
+ $bp->active_components[$this->id] = '1';
16
+ }
17
+
18
+ function includes() {
19
+ // Files to include
20
+ $includes = array(
21
+ 'buddypress/bp-em-activity.php',
22
+ 'buddypress/bp-em-templatetags.php',
23
+ 'buddypress/bp-em-notifications.php',
24
+ 'buddypress/screens/profile.php',
25
+ 'buddypress/screens/my-events.php',
26
+ 'buddypress/screens/my-locations.php',
27
+ 'buddypress/screens/attending.php',
28
+ 'buddypress/screens/my-bookings.php',
29
+ 'buddypress/screens/my-group-events.php'
30
+ );
31
+ if( bp_is_active('groups') ){
32
+ $includes[] = 'buddypress/screens/group-events.php';
33
+ $includes[] = 'buddypress/bp-em-groups.php';
34
+ }
35
+ parent::includes( $includes );
36
+ //TODO add admin pages for extra BP specific settings
37
+ }
38
+
39
+ /**
40
+ * Sets up the global Events Manager BuddyPress Components
41
+ */
42
+ function setup_globals() {
43
+ global $bp, $wpdb;
44
+ // Define a slug constant that will be used to view this components pages
45
+ if ( !defined( 'BP_EM_SLUG' ) )
46
+ define ( 'BP_EM_SLUG', EM_POST_TYPE_EVENT_SLUG );
47
+
48
+ // Set up the $globals array to be passed along to parent::setup_globals()
49
+ $globals = array(
50
+ 'slug' => BP_EM_SLUG,
51
+ 'has_directory' => false, //already done by EM
52
+ 'notification_callback' => 'bp_em_format_notifications',
53
+ 'search_string' => sprintf(__( 'Search %s...', 'dbem' ),__('Events','dbem')),
54
+ );
55
+
56
+ // Let BP_Component::setup_globals() do its work.
57
+ parent::setup_globals( $globals );
58
+
59
+ //quick link shortcut - may need to revisit this
60
+ $bp->{$this->id}->link = trailingslashit($bp->loggedin_user->domain).BP_EM_SLUG.'/';
61
+ }
62
+
63
+ function setup_nav() {
64
+ global $blog_id;
65
+ //check multisite or normal mode for correct permission checking
66
+ if(is_multisite() && $blog_id != BP_ROOT_BLOG){
67
+ //FIXME MS mode doesn't seem to recognize cross subsite caps, using the proper functions, for now we use switch_blog.
68
+ $current_blog = $blog_id;
69
+ switch_to_blog(BP_ROOT_BLOG);
70
+ $can_manage_events = current_user_can_for_blog(BP_ROOT_BLOG, 'edit_events');
71
+ $can_manage_locations = current_user_can_for_blog(BP_ROOT_BLOG, 'edit_locations');
72
+ $can_manage_bookings = current_user_can_for_blog(BP_ROOT_BLOG, 'manage_bookings');
73
+ switch_to_blog($current_blog);
74
+ }else{
75
+ $can_manage_events = current_user_can('edit_events');
76
+ $can_manage_locations = current_user_can('edit_locations');
77
+ $can_manage_bookings = current_user_can('manage_bookings');
78
+ }
79
+ /* Add 'Events' to the main user profile navigation */
80
+ $main_nav = array(
81
+ 'name' => __( 'Events', 'dbem' ),
82
+ 'slug' => em_bp_get_slug(),
83
+ 'position' => 80,
84
+ 'screen_function' => 'bp_em_events',
85
+ 'default_subnav_slug' => 'profile'
86
+ );
87
+
88
+ $em_link = trailingslashit( bp_loggedin_user_domain() . em_bp_get_slug() );
89
+
90
+ /* Create SubNav Items */
91
+ $sub_nav[] = array(
92
+ 'name' => __( 'My Profile', 'dbem' ),
93
+ 'slug' => 'profile',
94
+ 'parent_slug' => em_bp_get_slug(),
95
+ 'parent_url' => $em_link,
96
+ 'screen_function' => 'bp_em_events',
97
+ 'position' => 10
98
+ );
99
+
100
+ $sub_nav[] = array(
101
+ 'name' => __( 'Events I\'m Attending', 'dbem' ),
102
+ 'slug' => 'attending',
103
+ 'parent_slug' => em_bp_get_slug(),
104
+ 'parent_url' => $em_link,
105
+ 'screen_function' => 'bp_em_attending',
106
+ 'position' => 20,
107
+ 'user_has_access' => bp_is_my_profile() // Only the logged in user can access this on his/her profile
108
+ );
109
+
110
+ if( $can_manage_events ){
111
+ $sub_nav[] = array(
112
+ 'name' => __( 'My Events', 'dbem' ),
113
+ 'slug' => 'my-events',
114
+ 'parent_slug' => em_bp_get_slug(),
115
+ 'parent_url' => $em_link,
116
+ 'screen_function' => 'bp_em_my_events',
117
+ 'position' => 30,
118
+ 'user_has_access' => bp_is_my_profile() // Only the logged in user can access this on his/her profile
119
+ );
120
+ }
121
+
122
+ if( $can_manage_locations && get_option('dbem_locations_enabled') ){
123
+ $sub_nav[] = array(
124
+ 'name' => __( 'My Locations', 'dbem' ),
125
+ 'slug' => 'my-locations',
126
+ 'parent_slug' => em_bp_get_slug(),
127
+ 'parent_url' => $em_link,
128
+ 'screen_function' => 'bp_em_my_locations',
129
+ 'position' => 40,
130
+ 'user_has_access' => bp_is_my_profile() // Only the logged in user can access this on his/her profile
131
+ );
132
+ }
133
+
134
+ if( $can_manage_bookings && get_option('dbem_rsvp_enabled') ){
135
+ $sub_nav[] = array(
136
+ 'name' => __( 'My Event Bookings', 'dbem' ),
137
+ 'slug' => 'my-bookings',
138
+ 'parent_slug' => em_bp_get_slug(),
139
+ 'parent_url' => $em_link,
140
+ 'screen_function' => 'bp_em_my_bookings',
141
+ 'position' => 50,
142
+ 'user_has_access' => bp_is_my_profile() // Only the logged in user can access this on his/her profile
143
+ );
144
+ }
145
+
146
+ if( bp_is_active('groups') ){
147
+ /* Create Profile Group Sub-Nav */
148
+ $sub_nav[] = array(
149
+ 'name' => __( 'Events', 'dbem' ),
150
+ 'slug' => 'group-events',
151
+ 'parent_slug' => bp_get_groups_slug(),
152
+ 'parent_url' =>trailingslashit( bp_loggedin_user_domain() . bp_get_groups_slug() ),
153
+ 'screen_function' => 'bp_em_my_group_events',
154
+ 'position' => 60,
155
+ 'user_has_access' => bp_is_my_profile() // Only the logged in user can access this on his/her profile
156
+ );
157
+ }
158
+
159
+ parent::setup_nav( $main_nav, $sub_nav );
160
+ add_action( 'bp_init', array(&$this, 'setup_group_nav') );
161
+ }
162
+
163
+ function setup_group_nav(){
164
+ global $bp;
165
+ /* Add some group subnav items */
166
+ $user_access = false;
167
+ $group_link = '';
168
+ if( bp_is_active('groups') && !empty($bp->groups->current_group) ){
169
+ $group_link = $bp->root_domain . '/' . bp_get_groups_root_slug() . '/' . $bp->groups->current_group->slug . '/';
170
+ $user_access = $bp->groups->current_group->user_has_access;
171
+ if( !empty($bp->current_component) && $bp->current_component == 'groups' ){
172
+ $count = EM_Events::count(array('group'=>$bp->groups->current_group->id));
173
+ if( empty($count) ) $count = 0;
174
+ }
175
+ bp_core_new_subnav_item( array(
176
+ 'name' => __( 'Events', 'dbem' ) . " <span>$count</span>",
177
+ 'slug' => 'events',
178
+ 'parent_url' => $group_link,
179
+ 'parent_slug' => $bp->groups->current_group->slug,
180
+ 'screen_function' => 'bp_em_group_events',
181
+ 'position' => 50,
182
+ 'user_has_access' => $user_access,
183
+ 'item_css_id' => 'forums'
184
+ ));
185
+ }
186
+ }
187
+ }
188
+ function bp_em_load_core_component() {
189
+ global $bp;
190
+ $bp->events = new BP_EM_Component();
191
+ }
192
+ add_action( 'bp_loaded', 'bp_em_load_core_component' );
193
+
194
+ if( !is_admin() ){
195
+ /*
196
+ * Links and URL Rewriting
197
+ */
198
+ function em_bp_rewrite_edit_url($url, $EM_Event){
199
+ global $bp;
200
+ return $bp->events->link.'my-events/?action=edit&event_id='.$EM_Event->event_id;
201
+ }
202
+ if( !get_option('dbem_edit_events_page') ){
203
+ add_filter('em_event_get_edit_url','em_bp_rewrite_edit_url',10,2);
204
+ }
205
+
206
+
207
+ function em_bp_rewrite_bookings_url($url, $EM_Event){
208
+ global $bp;
209
+ return $bp->events->link.'my-bookings/?event_id='.$EM_Event->event_id;
210
+ }
211
+ if( !get_option('dbem_edit_bookings_page') ){
212
+ add_filter('em_event_get_bookings_url','em_bp_rewrite_bookings_url',10,2);
213
+ }
214
+
215
+ function em_bp_rewrite_edit_location_url($url, $EM_Location){
216
+ global $bp;
217
+ return $bp->events->link.'my-locations/?action=edit&location_id='.$EM_Location->location_id;
218
+ }
219
+ if( !get_option('dbem_edit_locations_page') ){
220
+ add_filter('em_location_get_edit_url','em_bp_rewrite_edit_location_url',10,2);
221
+ }
222
+ }
223
+
224
+ /**
225
+ * Delete events when you delete a user.
226
+ */
227
+ function bp_em_remove_data( $user_id ) {
228
+ $EM_Events = EM_Events::get(array('scope'=>'all','owner'=>$user_id, 'status'=>false));
229
+ EM_Events::delete($EM_Events);
230
+ }
231
+ add_action( 'wpmu_delete_user', 'bp_em_remove_data', 1 );
232
+ add_action( 'delete_user', 'bp_em_remove_data', 1 );
233
+
234
+ define('EM_BP_LOADED',true); //so we know
235
+ ?>
buddypress/bp-em-groups.php ADDED
@@ -0,0 +1,140 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @param EM_Event $EM_Event
4
+ */
5
+ function bp_em_group_event_save($result, $EM_Event){
6
+ if( is_object($EM_Event) && !empty($EM_Event->event_id) ){
7
+ if( !empty($_REQUEST['group_id']) && is_numeric($_REQUEST['group_id']) && bp_is_active('groups') ){
8
+ //we have been requested an event creation tied to a group, so does this group exist, and does this person have admin rights to it?
9
+ if( groups_is_user_admin(get_current_user_id(), $_REQUEST['group_id']) ){
10
+ $EM_Event->group_id = $_REQUEST['group_id'];
11
+ }
12
+ if( !empty($EM_Event->group_id) ){
13
+ //if group is private, make it private
14
+ $group = groups_get_group(array('group_id'=>$EM_Event->group_id));
15
+ $is_member = groups_is_user_member(get_current_user_id(), $EM_Event->group_id) || groups_is_user_admin(get_current_user_id(), $EM_Event->group_id) || groups_is_user_mod(get_current_user_id(), $EM_Event->group_id);
16
+ if( $group->status != 'public' && $is_member ){
17
+ //Make sure event status is private and set post status to private
18
+ global $wpdb;
19
+ $EM_Event->event_private = 1;
20
+ $wpdb->update($wpdb->posts, array('post_status'=>'private'), array('ID'=>$EM_Event->post_id));
21
+ $wpdb->update(EM_EVENTS_TABLE, array('event_private'=>1), array('event_id'=>$EM_Event->event_id));
22
+ }
23
+ }
24
+ }else{
25
+ $EM_Event->group_id = null;
26
+ }
27
+ }
28
+ return $result;
29
+ }
30
+ add_action('em_event_save','bp_em_group_event_save',1,2);
31
+
32
+ /**
33
+ * @param boolean $result
34
+ * @param EM_Event $EM_Event
35
+ */
36
+ function bp_em_group_event_can_manage( $result, $EM_Event){
37
+ if( !$result && !empty($EM_Event->group_id) && bp_is_active('groups') ){ //only override if already false, incase it's true
38
+ if( groups_is_user_admin(get_current_user_id(),$EM_Event->group_id) && current_user_can('edit_events') ){
39
+ //This user is an admin of the owner's group, so they can edit this event.
40
+ return true;
41
+ }
42
+ }
43
+ return $result;
44
+ }
45
+ add_filter('em_event_can_manage','bp_em_group_event_can_manage',1,2);
46
+
47
+
48
+ function bp_em_group_events_accepted_searches($searches){
49
+ if( bp_is_active('groups') ){
50
+ $searches[] = 'group';
51
+ }
52
+ return $searches;
53
+ }
54
+ add_filter('em_accepted_searches','bp_em_group_events_accepted_searches',1,1);
55
+
56
+ function bp_em_group_events_get_default_search($searches, $array){
57
+ if( !empty($array['group']) && (is_numeric($array['group']) || $array['group'] == 'my' || $array['group'] == 'this') && bp_is_active('groups') ){
58
+ if($array['group'] == 'this'){ //shows current group, if applicable
59
+ if( is_numeric(bp_get_current_group_id()) ){
60
+ $searches['group'] = bp_get_current_group_id();
61
+ }
62
+ }else{
63
+ $searches['group'] = $array['group'];
64
+ }
65
+ }
66
+ return $searches;
67
+ }
68
+ add_filter('em_events_get_default_search','bp_em_group_events_get_default_search',1,2);
69
+
70
+ /*
71
+ * Privacy Functions
72
+ */
73
+ function bp_em_group_events_build_sql_conditions( $conditions, $args ){
74
+ if( !empty($args['group']) && is_numeric($args['group']) ){
75
+ $conditions['group'] = "( `group_id`={$args['group']} )";
76
+ }elseif( !empty($args['group']) && $args['group'] == 'my' ){
77
+ $groups = groups_get_user_groups(get_current_user_id());
78
+ if( count($groups) > 0 ){
79
+ $conditions['group'] = "( `group_id` IN (".implode(',',$groups['groups']).") )";
80
+ }
81
+ }
82
+ //deal with private groups and events
83
+ if( is_user_logged_in() ){
84
+ global $wpdb;
85
+ //find out what private groups they belong to, and don't show private group events not in their memberships
86
+ $group_ids = BP_Groups_Member::get_group_ids(get_current_user_id());
87
+ if( $group_ids['total'] > 0){
88
+ $conditions['group_privacy'] = "(`event_private`=0 OR (`event_private`=1 AND (`group_id` IS NULL OR `group_id` = 0)) OR (`event_private`=1 AND `group_id` IN (".implode(',',$group_ids['groups']).")))";
89
+ }else{
90
+ //find out what private groups they belong to, and don't show private group events not in their memberships
91
+ $conditions['group_privacy'] = "(`event_private`=0 OR (`event_private`=1 AND (`group_id` IS NULL OR `group_id` = 0)))";
92
+ }
93
+ }
94
+ return $conditions;
95
+ }
96
+ add_filter('em_events_build_sql_conditions','bp_em_group_events_build_sql_conditions',1,2);
97
+
98
+
99
+ /**
100
+ * Overrides the default post format of an event and can display an event as a page, which uses the page.php template.
101
+ * @param string $template
102
+ * @return string
103
+ */
104
+ function bp_em_private_event_check($template){
105
+ global $post, $wpdb, $wp_query, $bp;
106
+ if( $post->post_type == EM_POST_TYPE_EVENT ){
107
+ $EM_Event = em_get_event($post);
108
+ //echo "<pre>"; print_r($EM_Event); echo "</pre>"; die();
109
+ if( !empty($EM_Event->event_private) && !empty($EM_Event->group_id) ){
110
+ if( is_user_logged_in() ){
111
+ //make sure user is a member of this group, whether private or not, private groups just aren't shown to non-members of a group
112
+ $id_lookup = $wpdb->get_var( $wpdb->prepare( "SELECT m.group_id FROM {$bp->groups->table_name_members} m WHERE m.group_id = %s AND m.user_id = %d AND m.is_confirmed = 1 AND m.is_banned = 0", $EM_Event->group_id, get_current_user_id() ) );
113
+ if($id_lookup != $EM_Event->group_id){
114
+ unset($post);
115
+ $wp_query->set_404();
116
+ $template = locate_template(array('404.php'),false);
117
+ }
118
+ }else{
119
+ unset($post);
120
+ $wp_query->set_404();
121
+ $template = locate_template(array('404.php'),false);
122
+ }
123
+ }
124
+ }
125
+ return $template;
126
+ }
127
+ add_filter('single_template','bp_em_private_event_check',20);
128
+
129
+ /*
130
+ * Admin Meta Boxes
131
+ */
132
+ function bp_em_meta_boxes(){
133
+ add_meta_box('em-event-group', __('Group Ownership','dbem'), 'bp_em_meta_box_group',EM_POST_TYPE_EVENT, 'side','low');
134
+ add_meta_box('em-event-group', __('Group Ownership','dbem'), 'bp_em_meta_box_group','event-recurring', 'side','low');
135
+ }
136
+ add_action('add_meta_boxes', 'bp_em_meta_boxes');
137
+
138
+ function bp_em_meta_box_group(){
139
+ em_locate_template('forms/event/group.php',true);
140
+ }
buddypress/bp-em-notifications.php ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ //This file handles hooks requiring notifications
3
+
4
+ /**
5
+ * bp_em_format_notifications()
6
+ *
7
+ * The format notification function will take DB entries for notifications and format them
8
+ * so that they can be displayed and read on the screen.
9
+ *
10
+ * Notifications are "screen" notifications, that is, they appear on the notifications menu
11
+ * in the site wide navigation bar. They are not for email notifications.
12
+ *
13
+ *
14
+ * The recording is done by using bp_core_add_notification() which you can search for in this file for
15
+ * ems of usage.
16
+ */
17
+ function bp_em_format_notifications( $action, $item_id, $secondary_item_id, $total_items ) {
18
+ global $bp;
19
+ switch ( $action ) {
20
+ case 'pending_booking':
21
+ //Count pending bookings
22
+ if( get_option('dbem_bookings_approval')){
23
+ if ( $total_items > 1 ) {
24
+ return '<a href="' . $bp->loggedin_user->domain . $bp->events->slug . '/my-bookings/" title="' . __( 'My Bookings', 'dbem' ) . '">' . __('You have a pending booking','dbem'). '</a>';
25
+ } else {
26
+ return apply_filters( 'bp_em_format_new_booking_notification', '<a href="' . $bp->loggedin_user->domain . $bp->events->slug . '/my-bookings/" title="' . __( 'My Bookings', 'dbem' ) . '">' . sprintf(__('You have %s pending bookings','dbem'), $total_items). '</a>' );
27
+ }
28
+ }
29
+ break;
30
+ case 'confirmed_booking':
31
+ //Count pending bookings
32
+ if ( $total_items > 1 ) {
33
+ return apply_filters( 'bp_em_format_confirmed_booking_notifications', '<a href="' . $bp->loggedin_user->domain . $bp->events->slug . '/my-bookings/" title="' . __( 'My Bookings', 'dbem' ) . '">' . __('You have a confirmed booking','dbem'). '</a>' );
34
+ } else {
35
+ return apply_filters( 'bp_em_format_confirmed_booking_notification', '<a href="' . $bp->loggedin_user->domain . $bp->events->slug . '/my-bookings/" title="' . __( 'My Bookings', 'dbem' ) . '">' . sprintf(__('You have %s confirmed bookings','dbem'), $total_items). '</a>' );
36
+ }
37
+ break;
38
+ case 'cancelled_booking':
39
+ //Count pending bookings
40
+ if ( $total_items > 1 ) {
41
+ return apply_filters( 'bp_em_format_cancelled_booking_notifications', '<a href="' . $bp->loggedin_user->domain . $bp->events->slug . '/my-bookings/" title="' . __( 'My Bookings', 'dbem' ) . '">' . __('A user cancelled a booking','dbem'). '</a>' );
42
+ } else {
43
+ return apply_filters( 'bp_em_format_cancelled_booking_notification', '<a href="' . $bp->loggedin_user->domain . $bp->events->slug . '/my-bookings/" title="' . __( 'My Bookings', 'dbem' ) . '">' . sprintf(__('%s users cancelled bookings.','dbem'), $total_items). '</a>' );
44
+ }
45
+ break;
46
+ }
47
+ do_action( 'bp_em_format_notifications', $action, $item_id, $secondary_item_id, $total_items );
48
+
49
+ return false;
50
+ }
51
+
52
+ /**
53
+ * Remove a screen notification for a user.
54
+ */
55
+ function bp_em_remove_screen_notifications() {
56
+ global $bp;
57
+ bp_core_delete_notifications_by_type( $bp->loggedin_user->id, $bp->events->slug, 'attending' );
58
+ }
59
+ add_action( 'bp_em_my_events', 'bp_em_remove_screen_notifications' );
60
+ add_action( 'xprofile_screen_display_profile', 'bp_em_remove_screen_notifications' );
61
+
62
+ /**
63
+ * Catch booking saves and add a BP notification.
64
+ * @param boolean $result
65
+ * @param EM_Booking $EM_Booking
66
+ * @return boolean
67
+ */
68
+ function bp_em_add_booking_notification($result, $EM_Booking){
69
+ global $bp;
70
+ if( get_option('dbem_bookings_approval') && $EM_Booking->get_status() == 0 ){
71
+ $action = 'pending_booking';
72
+ }elseif( $EM_Booking->get_status() == 1 || (get_option('dbem_bookings_approval') && $EM_Booking->get_status() == 0) ){
73
+ $action = 'confirmed_booking';
74
+ }elseif( $EM_Booking->get_status() == 3 ){
75
+ $action = 'cancelled_booking';
76
+ }
77
+ if( !empty($action) ){
78
+ bp_core_add_notification( $EM_Booking->booking_id, $EM_Booking->get_event()->get_contact()->ID, 'events', $action );
79
+ }
80
+ return $result;
81
+ }
82
+ add_filter('em_booking_save','bp_em_add_booking_notification',1,2);
buddypress/bp-em-templatetags.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Echo the Events Manager BuddyPresss component's slug
4
+ * @since 5.0
5
+ */
6
+ function em_bp_slug() {
7
+ echo em_bp_get_slug();
8
+ }
9
+ /**
10
+ * Return the Events Manager BuddyPresss component's slug
11
+ *
12
+ * @since 5.0
13
+ * @uses apply_filters() Filter 'em_bp_get_slug' to change the output
14
+ * @return str $slug The slug from $bp->events->slug, if it exists
15
+ */
16
+ function em_bp_get_slug() {
17
+ global $bp;
18
+ // Avoid PHP warnings, in case the value is not set for some reason
19
+ $slug = !empty( $bp->evebts->slug ) ? $bp->events->slug : BP_EM_SLUG;
20
+ return apply_filters( 'em_bp_get_slug', $slug );
21
+ }
buddypress/screens/attending.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * bp_em_screen_two()
4
+ *
5
+ * Sets up and displays the screen output for the sub nav item "em/screen-two"
6
+ */
7
+ function bp_em_attending() {
8
+ global $bp;
9
+ /**
10
+ * If the user has not Accepted or Rejected anything, then the code above will not run,
11
+ * we can continue and load the template.
12
+ */
13
+ do_action( 'bp_em_attending' );
14
+
15
+ add_action( 'bp_template_title', 'bp_em_attending_title' );
16
+ add_action( 'bp_template_content', 'bp_em_attending_content' );
17
+
18
+ /* Finally load the plugin template file. */
19
+ bp_core_load_template( apply_filters( 'bp_core_template_plugin', 'members/single/plugins' ) );
20
+ }
21
+
22
+ function bp_em_attending_title() {
23
+ _e( 'Events I\'m Attending', 'dbem' );
24
+ }
25
+
26
+ function bp_em_attending_content() {
27
+ //We can use the same template as the public user interface for non bp sites
28
+ em_locate_template('templates/my-bookings.php',true);
29
+ }
buddypress/screens/group-events.php ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Controller for the event views in BP (using mvc terms here)
4
+ */
5
+ function bp_em_group_events() {
6
+ global $bp;
7
+ do_action( 'bp_em_group_events' );
8
+
9
+ //plug into EM admin code (at least for now)
10
+ include_once(EM_DIR.'/admin/em-admin.php');
11
+
12
+ add_action( 'bp_template_title', 'bp_em_group_events_title' );
13
+ add_action( 'bp_template_content', 'bp_em_group_events_content' );
14
+
15
+ /* Finally load the plugin template file. */
16
+ bp_core_load_template( apply_filters( 'bp_core_template_plugin', 'groups/single/plugins' ) );
17
+ }
18
+
19
+ function bp_em_group_events_title() {
20
+ _e( 'Group Events', 'dbem' );
21
+ }
22
+ /**
23
+ * Determines whether to show event page or events page, and saves any updates to the event or events
24
+ * @return null
25
+ */
26
+ function bp_em_group_events_content() {
27
+ em_locate_template('buddypress/group-events.php', true);
28
+ }
29
+
30
+ ?>
buddypress/screens/my-bookings.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * bp_em_screen_two()
4
+ *
5
+ * Sets up and displays the screen output for the sub nav item "em/screen-two"
6
+ */
7
+ function bp_em_my_bookings() {
8
+ global $bp, $EM_Event;
9
+
10
+ //assume any notifications here are considered viewed via this page
11
+ bp_core_delete_notifications_by_type(get_current_user_id(), 'events','pending_booking');
12
+ bp_core_delete_notifications_by_type(get_current_user_id(), 'events','confirmed_booking');
13
+ bp_core_delete_notifications_by_type(get_current_user_id(), 'events','cancelled_booking');
14
+
15
+ em_load_event();
16
+ /**
17
+ * If the user has not Accepted or Rejected anything, then the code above will not run,
18
+ * we can continue and load the template.
19
+ */
20
+ do_action( 'bp_em_my_bookings' );
21
+
22
+ add_action( 'bp_template_title', 'bp_em_my_bookings_title' );
23
+ add_action( 'bp_template_content', 'bp_em_my_bookings_content' );
24
+
25
+ /* Finally load the plugin template file. */
26
+ bp_core_load_template( apply_filters( 'bp_core_template_plugin', 'members/single/plugins' ) );
27
+ }
28
+
29
+ function bp_em_my_bookings_title() {
30
+ _e( 'My Event Bookings', 'dbem' );
31
+ }
32
+
33
+ function bp_em_my_bookings_content() {
34
+ em_locate_template('buddypress/my-bookings.php',true);
35
+ }
buddypress/screens/my-events.php ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Controller for the event views in BP (using mvc terms here)
4
+ */
5
+ function bp_em_my_events() {
6
+ global $bp, $EM_Event;
7
+ if( !is_object($EM_Event) && !empty($_REQUEST['event_id']) ){
8
+ $EM_Event = new EM_Event($_REQUEST['event_id']);
9
+ }
10
+
11
+ do_action( 'bp_em_my_events' );
12
+
13
+ $template_title = 'bp_em_my_events_title';
14
+ $template_content = 'bp_em_my_events_content';
15
+
16
+ if( !empty($_GET['action']) ){
17
+ switch($_GET['action']){
18
+ case 'edit':
19
+ $template_title = 'bp_em_my_events_editor_title';
20
+ break;
21
+ }
22
+ }
23
+
24
+ add_action( 'bp_template_title', $template_title );
25
+ add_action( 'bp_template_content', $template_content );
26
+
27
+ /* Finally load the plugin template file. */
28
+ bp_core_load_template( apply_filters( 'bp_core_template_plugin', 'members/single/plugins' ) );
29
+ }
30
+
31
+ function bp_em_my_events_title() {
32
+ _e( 'My Events', 'dbem' );
33
+ }
34
+
35
+ /**
36
+ * Determines whether to show event page or events page, and saves any updates to the event or events
37
+ * @return null
38
+ */
39
+ function bp_em_my_events_content() {
40
+ em_locate_template('buddypress/my-events.php', true);
41
+ }
42
+
43
+ function bp_em_my_events_editor_title() {
44
+ global $EM_Event;
45
+ if( is_object($EM_Event) ){
46
+ if($EM_Event->is_recurring()){
47
+ _e( "Reschedule Events", 'dbem' )." '{$EM_Event->event_name}'";
48
+ }else{
49
+ _e ( "Edit Event", 'dbem' ) . " '" . $EM_Event->event_name . "'";
50
+ }
51
+ }else{
52
+ _e( 'Add Event', 'dbem' );
53
+ }
54
+ }
55
+ ?>
buddypress/screens/my-group-events.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Controller for the event views in BP (using mvc terms here)
4
+ */
5
+ function bp_em_my_group_events() {
6
+ global $bp;
7
+ do_action( 'bp_em_my_group_events' );
8
+
9
+ //plug into EM admin code (at least for now)
10
+ include_once(EM_DIR.'/admin/em-admin.php');
11
+
12
+ add_action( 'bp_template_title', 'bp_em_my_group_events_title' );
13
+ add_action( 'bp_template_content', 'bp_em_my_group_events_content' );
14
+
15
+ /* Finally load the plugin template file. */
16
+ bp_core_load_template( apply_filters( 'bp_core_template_plugin', 'members/single/plugins' ) );
17
+ }
18
+
19
+ function bp_em_my_group_events_title() {
20
+ _e( 'Group Events', 'dbem' );
21
+ }
22
+
23
+ function bp_em_my_group_events_content(){
24
+ em_locate_template('buddypress/my-group-events.php', true);
25
+ }
26
+
27
+ ?>
buddypress/screens/my-locations.php ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Controller for the location views in BP (using mvc terms here)
4
+ */
5
+ function bp_em_my_locations() {
6
+ global $bp, $EM_Location;
7
+ if( !is_object($EM_Location) && !empty($_REQUEST['location_id']) ){
8
+ $EM_Location = new EM_Location($_REQUEST['location_id']);
9
+ }
10
+
11
+ do_action( 'bp_em_my_locations' );
12
+
13
+ $template_title = 'bp_em_my_locations_title';
14
+ $template_content = 'bp_em_my_locations_content';
15
+
16
+ if( !empty($_GET['action']) ){
17
+ switch($_GET['action']){
18
+ case 'edit':
19
+ $template_title = 'bp_em_my_locations_editor_title';
20
+ break;
21
+ }
22
+ }
23
+
24
+ add_action( 'bp_template_title', $template_title );
25
+ add_action( 'bp_template_content', $template_content );
26
+
27
+ /* Finally load the plugin template file. */
28
+ bp_core_load_template( apply_filters( 'bp_core_template_plugin', 'members/single/plugins' ) );
29
+ }
30
+
31
+ function bp_em_my_locations_title() {
32
+ _e( 'My Locations', 'dbem' );
33
+ }
34
+
35
+ /**
36
+ * Determines whether to show location page or locations page, and saves any updates to the location or locations
37
+ * @return null
38
+ */
39
+ function bp_em_my_locations_content() {
40
+ em_locate_template('buddypress/my-locations.php', true);
41
+ }
42
+
43
+ function bp_em_my_locations_editor_title() {
44
+ global $EM_Location;
45
+ if( empty($EM_Location) || !is_object($EM_Location) ){
46
+ $title = __('Add Location', 'dbem');
47
+ }else{
48
+ $title = __('Edit Location', 'dbem');
49
+ }
50
+ }
51
+ ?>
buddypress/screens/profile.php ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * bp_em_screen_one()
4
+ *
5
+ * Sets up and displays the screen output for the sub nav item "em/screen-one"
6
+ */
7
+ function bp_em_events() {
8
+ global $bp, $EM_Notices;
9
+
10
+ if( bp_is_my_profile() ){
11
+ $EM_Notices->add_info( __('You are currently viewing your public page, this is what other users will see.', 'dbem') );
12
+ }
13
+
14
+ /* Add a do action here, so your component can be extended by others. */
15
+ do_action( 'bp_em_events' );
16
+
17
+ add_action( 'bp_template_title', 'bp_em_events_title' );
18
+ add_action( 'bp_template_content', 'bp_em_events_content' );
19
+ bp_core_load_template( apply_filters( 'bp_core_template_plugin', 'members/single/plugins' ) );
20
+ //bp_core_load_template( apply_filters( 'bp_em_template_screen_one', 'em/screen-one' ) );
21
+ }
22
+ /***
23
+ * The second argument of each of the above add_action() calls is a function that will
24
+ * display the corresponding information. The functions are presented below:
25
+ */
26
+ function bp_em_events_title() {
27
+ _e( 'Events', 'dbem' );
28
+ }
29
+
30
+ function bp_em_events_content() {
31
+ em_locate_template('buddypress/profile.php',true);
32
+ }
classes/em-booking.php CHANGED
@@ -1,379 +1,696 @@
1
- <?php
2
- class EM_Booking extends EM_Object{
3
- //DB Fields
4
- var $id;
5
- var $event_id;
6
- var $person_id;
7
- var $seats;
8
- var $comment;
9
- var $status = 0;
10
- var $notes = array();
11
- var $fields = array(
12
- 'booking_id' => array('name'=>'id','type'=>'%d'),
13
- 'event_id' => array('name'=>'event_id','type'=>'%d'),
14
- 'person_id' => array('name'=>'person_id','type'=>'%d'),
15
- 'booking_seats' => array('name'=>'seats','type'=>'%d'),
16
- 'booking_comment' => array('name'=>'comment','type'=>'%s'),
17
- 'booking_status' => array('name'=>'status','type'=>'%d')
18
- );
19
- //Other Vars
20
- var $timestamp;
21
- var $person;
22
- var $required_fields = array('booking_id', 'event_id', 'person_id', 'booking_seats');
23
- var $feedback_message = "";
24
- var $errors = array();
25
- /**
26
- * If saved in this instance, you can see what previous approval status was.
27
- * @var int
28
- */
29
- var $previous_status = false;
30
- /**
31
- * The booking approval status number corresponds to a state in this array.
32
- * @var unknown_type
33
- */
34
- var $status_array = array();
35
-
36
- /**
37
- * Creates booking object and retreives booking data (default is a blank booking object). Accepts either array of booking data (from db) or a booking id.
38
- * @param mixed $booking_data
39
- * @return null
40
- */
41
- function EM_Booking( $booking_data = false ){
42
- if( !get_option('dbem_bookings_approval') ){
43
- $this->status = 1;
44
- }
45
- if( $booking_data !== false ){
46
- //Load booking data
47
- $booking = array();
48
- if( is_array($booking_data) ){
49
- $booking = $booking_data;
50
- //Also create a person out of this...
51
- $this->person = new EM_Person($booking_data);
52
- if( !empty($booking['person_id']) && $booking['person_id'] != $this->person->id){
53
- $this->person = new EM_Person($booking['booking_id']);
54
- }
55
- }elseif( is_numeric($booking_data) ){
56
- //Retreiving from the database
57
- global $wpdb;
58
- $sql = "SELECT * FROM ". $wpdb->prefix . EM_BOOKINGS_TABLE ." WHERE booking_id ='$booking_data'";
59
- $booking = $wpdb->get_row($sql, ARRAY_A);
60
- //Get the person for this booking
61
- $this->person = new EM_Person($booking['person_id']);
62
- //Booking notes
63
- $notes = $wpdb->get_results("SELECT * FROM ". $wpdb->prefix . EM_META_TABLE ." WHERE meta_key='booking-note' AND object_id ='$booking_data'", ARRAY_A);
64
- foreach($notes as $note){
65
- $this->notes[] = unserialize($note['meta_value']);
66
- }
67
- }
68
- //Save into the object
69
- $this->to_object($booking);
70
- if( !empty($booking['booking_date']) ){
71
- $this->timestamp = strtotime($booking['booking_date']);
72
- }
73
- }
74
- //Do it here so things appear in the po file.
75
- $this->status_array = array(
76
- 0 => __('Pending','dbem'),
77
- 1 => __('Approved','dbem'),
78
- 2 => __('Rejected','dbem'),
79
- 3 => __('Cacncelled','dbem')
80
- );
81
- }
82
-
83
- /**
84
- * Saves the booking into the database, whether a new or existing booking
85
- * @return boolean
86
- */
87
- function save(){
88
- global $wpdb;
89
- $table = $wpdb->prefix.EM_BOOKINGS_TABLE;
90
- do_action('em_booking_save_pre',$this);
91
- //First the person
92
- if($this->validate()){
93
- //Does this person exist?
94
- $person_result = $this->person->save();
95
- if( $person_result === false ){
96
- $this->errors = array_merge($this->errors, $this->person->errors);
97
- return false;
98
- }
99
- $this->person_id = $this->person->id;
100
-
101
- //Now we save the booking
102
- $data = $this->to_array();
103
- if($this->id != ''){
104
- $where = array( 'booking_id' => $this->id );
105
- $result = $wpdb->update($table, $data, $where, $this->get_types($data));
106
- $this->feedback_message = __('Changes saved');
107
- }else{
108
- $result = $wpdb->insert($table, $data, $this->get_types($data));
109
- $this->id = $wpdb->insert_id;
110
- $this->feedback_message = __('Your booking has been recorded','dbem');
111
- }
112
- if( $result === false ){
113
- $this->feedback_message = __('There was a problem saving the booking.', 'dbem');
114
- $this->errors[] = __('There was a problem saving the booking.', 'dbem');
115
- }
116
- return apply_filters('em_booking_save', ( count($this->errors) == 0 ), $this);
117
- }else{
118
- $this->feedback_message = __('There was a problem saving the booking.', 'dbem');
119
- $this->errors[] = __('There was a problem saving the booking.', 'dbem');
120
- return apply_filters('em_booking_save', false, $this);
121
- }
122
- return true;
123
- }
124
-
125
- /**
126
- * Load an record into this object by passing an associative array of table criterie to search for.
127
- * Returns boolean depending on whether a record is found or not.
128
- * @param $search
129
- * @return boolean
130
- */
131
- function get($search) {
132
- global $wpdb;
133
- $conds = array();
134
- foreach($search as $key => $value) {
135
- if( array_key_exists($key, $this->fields) ){
136
- $value = $wpdb->escape($value);
137
- $conds[] = "`$key`='$value'";
138
- }
139
- }
140
- $sql = "SELECT * FROM ". $wpdb->EM_BOOKINGS_TABLE ." WHERE " . implode(' AND ', $conds) ;
141
- $result = $wpdb->get_row($sql, ARRAY_A);
142
- if($result){
143
- $this->to_object($result);
144
- return true;
145
- }else{
146
- return false;
147
- }
148
- }
149
-
150
- /**
151
- * Get posted data and save it into the object (not db)
152
- * @return boolean
153
- */
154
- function get_post(){
155
- //Currently, only editing allowed, so here we are.
156
- $this->comment = (!empty($_REQUEST['booking_comment'])) ? $_REQUEST['booking_comment']:'';
157
- $this->seats = (!empty($_REQUEST['booking_seats'])) ? $_REQUEST['booking_seats']:'';
158
- return apply_filters('em_booking_get_post',$this->validate(),$this);
159
- }
160
-
161
- function validate(){
162
- return (
163
- (empty($this->event_id) || is_numeric($this->event_id)) &&
164
- (empty($this->person_id) || is_numeric($this->person_id)) &&
165
- is_numeric($this->seats)
166
- );
167
- }
168
-
169
- /**
170
- * Smart event locator, saves a database read if possible.
171
- */
172
- function get_event(){
173
- global $EM_Event;
174
- if( !empty($this->event) && is_object($this->event) && get_class($this->event)=='EM_Event' && $this->event->id == $this->event_id ){
175
- return $this->event;
176
- }elseif( is_object($EM_Event) && $EM_Event->id == $this->event_id ){
177
- $this->event = $EM_Event;
178
- }else{
179
- $this->event = new EM_Event($this->event_id);
180
- }
181
- return $this->event;
182
- }
183
-
184
- /**
185
- * Returns a string representation of the booking's status
186
- * @return string
187
- */
188
- function get_status(){
189
- return $this->status_array[$this->status];
190
- }
191
- /**
192
- * I wonder what this does....
193
- * @return boolean
194
- */
195
- function delete(){
196
- global $wpdb;
197
- $sql = $wpdb->prepare("DELETE FROM ". $wpdb->prefix.EM_BOOKINGS_TABLE . " WHERE booking_id=%d", $this->id);
198
- $result = $wpdb->query( $sql );
199
- return ( $result !== false );
200
- }
201
-
202
- function cancel(){
203
- return $this->set_status(3);
204
- }
205
-
206
- /**
207
- * Approve a booking.
208
- * @return bool
209
- */
210
- function approve(){
211
- return $this->set_status(1);
212
- }
213
- /**
214
- * Reject a booking and save
215
- * @return bool
216
- */
217
- function reject(){
218
- return $this->set_status(2);
219
- }
220
- /**
221
- * Unpprove a booking.
222
- * @return bool
223
- */
224
- function unapprove(){
225
- return $this->set_status(0);
226
- }
227
-
228
- /**
229
- * Change the status of the booking. This will save to the Database too.
230
- * @param unknown_type $status
231
- * @return string|string|string
232
- */
233
- function set_status($status){
234
- $this->previous_status = $this->status;
235
- $this->status = $status;
236
- $result = $this->save();
237
- $action_string = strtolower($this->status_array[$status]);
238
- if($result){
239
- $this->feedback_message = sprintf(__('Booking %s.','dbem'), $action_string);
240
- if( $this->email() ){
241
- $this->feedback_message .= " ".__('Mail Sent.','dbem');
242
- }elseif( $this->previous_status == 0 ){
243
- //extra errors may be logged by email() in EM_Object
244
- $this->feedback_message .= ' <span style="color:red">'.__('ERROR : Mail Not Sent.','dbem').'</span>';
245
- return false;
246
- }
247
- return true;
248
- }else{
249
- //errors should be logged by save()
250
- $this->feedback_message = sprintf(__('Booking could not be %s.','dbem'), $action_string);
251
- return false;
252
- }
253
- }
254
-
255
- /**
256
- * Add a booking note to this booking. returns wpdb result or false if use can't manage this event.
257
- * @param string $note
258
- * @return mixed
259
- */
260
- function add_note( $note_text ){
261
- global $wpdb;
262
- if( $this->can_manage() ){
263
- $note = array('author'=>get_current_user_id(),'note'=>$note_text,'timestamp'=>current_time('timestamp'));
264
- $this->notes[] = $note;
265
- $this->feedback_message = __('Booking note successfully added.','dbem');
266
- return $wpdb->insert($wpdb->prefix.EM_META_TABLE, array('object_id'=>$this->id, 'meta_key'=>'booking-note', 'meta_value'=> serialize($note)),array('%d','%s','%s'));
267
- }
268
- return false;
269
- }
270
-
271
- /**
272
- * @param EM_Booking $EM_Booking
273
- * @param EM_Event $event
274
- * @return boolean
275
- */
276
- function email(){
277
- global $EM_Mailer;
278
- $EM_Event = $this->get_event(); //We NEED event details here.
279
- //Make sure event matches booking, and that booking used to be approved.
280
- if( $this->previous_status == 0 || $this->status == 3 ){
281
- $contact_id = ( $EM_Event->contactperson_id != "") ? $EM_Event->contactperson_id : get_option('dbem_default_contact_person');
282
-
283
- $contact_subject = get_option('dbem_bookings_contact_email_subject');
284
- $contact_body = get_option('dbem_bookings_contact_email_body');
285
-
286
- if( (get_option('dbem_bookings_approval') == 0 && $this->previous_status === false) || $this->status == 1 ){
287
- $booker_subject = get_option('dbem_bookings_email_confirmed_subject');
288
- $booker_body = get_option('dbem_bookings_email_confirmed_body');
289
- }elseif( $this->status == 0 ){
290
- $booker_subject = get_option('dbem_bookings_email_pending_subject');
291
- $booker_body = get_option('dbem_bookings_email_pending_body');
292
- }elseif( $this->status == 2 ){
293
- $booker_subject = get_option('dbem_bookings_email_rejected_subject');
294
- $booker_body = get_option('dbem_bookings_email_rejected_body');
295
- }elseif( $this->status == 3 ){
296
- $booker_subject = get_option('dbem_bookings_email_cancelled_subject');
297
- $booker_body = get_option('dbem_bookings_email_cancelled_body');
298
- $contact_subject = get_option('dbem_contactperson_email_cancelled_subject');
299
- $contact_body = get_option('dbem_contactperson_email_cancelled_body');
300
- }
301
-
302
- // email specific placeholders
303
- $placeholders = array(
304
- '#_RESPNAME' => '#_BOOKINGNAME',//Depreciated
305
- '#_RESPEMAIL' => '#_BOOKINGEMAIL',//Depreciated
306
- '#_RESPPHONE' => '#_BOOKINGPHONE',//Depreciated
307
- '#_COMMENT' => '#_BOOKINGCOMMENT',//Depreciated
308
- '#_RESERVEDSPACES' => '#_BOOKEDSPACES',//Depreciated
309
- '#_BOOKINGNAME' => $this->person->name,
310
- '#_BOOKINGEMAIL' => $this->person->email,
311
- '#_BOOKINGPHONE' => $this->person->phone,
312
- '#_BOOKINGSPACES' => $this->seats,
313
- '#_BOOKINGCOMMENT' => $this->comment,
314
- );
315
- foreach($placeholders as $key => $value) {
316
- $contact_subject = str_replace($key, $value, $contact_subject);
317
- $contact_body = str_replace($key, $value, $contact_body);
318
- $booker_subject = str_replace($key, $value, $booker_subject);
319
- $booker_body = str_replace($key, $value, $booker_body);
320
- }
321
-
322
- $booker_subject = $EM_Event->output($booker_subject, 'email');
323
- $booker_body = $EM_Event->output($booker_body, 'email');
324
-
325
- //Send to the person booking
326
- if( !$this->email_send( $booker_subject,$booker_body, $this->person->email) ){
327
- return false;
328
- }
329
-
330
- //Send admin emails
331
- if( (get_option('dbem_bookings_approval') == 0 || $this->status == 0) && (get_option('dbem_bookings_contact_email') == 1 || get_option('dbem_bookings_notify_admin') != '') ){
332
- //Only gets sent if this is a pending booking, unless approvals are disabled.
333
- $contact_subject = $EM_Event->output($contact_subject, 'email');
334
- $contact_body = $EM_Event->output($contact_body, 'email');
335
-
336
- if( get_option('dbem_bookings_contact_email') == 1 ){
337
- if( !$this->email_send( $contact_subject, $contact_body, $EM_Event->contact->user_email) && current_user_can('activate_plugins')){
338
- $this->errors[] = __('Confirmation email could not be sent to contact person. Registrant should have gotten their email (only admin see this warning).','dbem');
339
- return false;
340
- }
341
- }
342
-
343
- if( get_option('dbem_bookings_notify_admin') != '' && preg_match('/^[_\.0-9a-z-]+@([0-9a-z][0-9a-z-]+\.)+[a-z]{2,3}$/', get_option('dbem_bookings_notify_admin')) ){
344
- if( !$this->email_send( $contact_subject, $contact_body, get_option('dbem_bookings_notify_admin')) ){
345
- $this->errors[] = __('Confirmation email could not be sent to admin. Registrant should have gotten their email (only admin see this warning).','dbem');
346
- return false;
347
- }
348
- }
349
- }
350
- return true;
351
- }
352
- return false;
353
- //TODO need error checking for booking mail send
354
- }
355
-
356
- /**
357
- * Can the user manage this event?
358
- */
359
- function can_manage(){
360
- return ( get_option('dbem_permissions_events') || $this->get_event()->author == get_current_user_id() || em_verify_admin() );
361
- }
362
-
363
- /**
364
- * Returns this object in the form of an array
365
- * @return array
366
- */
367
- function to_array($person = false){
368
- $booking = array();
369
- //Core Data
370
- $booking = parent::to_array();
371
- //Person Data
372
- if($person && is_object($this->person)){
373
- $person = $this->person->to_array();
374
- $booking = array_merge($booking, $person);
375
- }
376
- return $booking;
377
- }
378
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
379
  ?>
1
+ <?php
2
+ class EM_Booking extends EM_Object{
3
+ //DB Fields
4
+ var $booking_id;
5
+ var $event_id;
6
+ var $person_id;
7
+ var $booking_price;
8
+ var $booking_spaces;
9
+ var $booking_comment;
10
+ var $booking_status = false;
11
+ var $booking_meta = array();
12
+ var $fields = array(
13
+ 'booking_id' => array('name'=>'id','type'=>'%d'),
14
+ 'event_id' => array('name'=>'event_id','type'=>'%d'),
15
+ 'person_id' => array('name'=>'person_id','type'=>'%d'),
16
+ 'booking_price' => array('name'=>'price','type'=>'%f'),
17
+ 'booking_spaces' => array('name'=>'spaces','type'=>'%d'),
18
+ 'booking_comment' => array('name'=>'comment','type'=>'%s'),
19
+ 'booking_status' => array('name'=>'status','type'=>'%d'),
20
+ 'booking_meta' => array('name'=>'meta','type'=>'%s')
21
+ );
22
+ //Other Vars
23
+ var $notes; //loaded from em_meta table in construct
24
+ var $timestamp;
25
+ var $person;
26
+ var $required_fields = array('booking_id', 'event_id', 'person_id', 'booking_spaces');
27
+ var $feedback_message = "";
28
+ var $errors = array();
29
+ /**
30
+ * Contains an array of custom fields for a booking. This is loaded from em_meta, where the booking_custom name contains arrays of data.
31
+ * @var array
32
+ */
33
+ var $custom = array();
34
+ /**
35
+ * If saved in this instance, you can see what previous approval status was.
36
+ * @var int
37
+ */
38
+ var $previous_status = false;
39
+ /**
40
+ * The booking approval status number corresponds to a state in this array.
41
+ * @var unknown_type
42
+ */
43
+ var $status_array = array();
44
+ /**
45
+ * @var EM_Tickets
46
+ */
47
+ var $tickets;
48
+ /**
49
+ * @var EM_Event
50
+ */
51
+ var $event;
52
+ /**
53
+ * @var EM_Tickets_Bookings
54
+ */
55
+ var $tickets_bookings;
56
+ /**
57
+ * If set to true, this booking can be managed by any logged in user.
58
+ * @var EM_Tickets_Bookings
59
+ */
60
+ var $manage_override;
61
+
62
+ /**
63
+ * Creates booking object and retreives booking data (default is a blank booking object). Accepts either array of booking data (from db) or a booking id.
64
+ * @param mixed $booking_data
65
+ * @return null
66
+ */
67
+ function EM_Booking( $booking_data = false ){
68
+ //Get the person for this booking
69
+ global $wpdb;
70
+ if( $booking_data !== false ){
71
+ //Load booking data
72
+ $booking = array();
73
+ if( is_array($booking_data) ){
74
+ $booking = $booking_data;
75
+ }elseif( is_numeric($booking_data) ){
76
+ //Retreiving from the database
77
+ $sql = "SELECT * FROM ". EM_BOOKINGS_TABLE ." LEFT JOIN ". EM_META_TABLE ." ON object_id=booking_id WHERE booking_id ='$booking_data'";
78
+ $booking = $wpdb->get_row($sql, ARRAY_A);
79
+ }
80
+ //booking meta
81
+ $booking['booking_meta'] = (!empty($booking['booking_meta'])) ? unserialize($booking['booking_meta']):array();
82
+ //Save into the object
83
+ $this->to_object($booking);
84
+ $this->previous_status = $this->booking_status;
85
+ $this->get_person();
86
+ $this->timestamp = !empty($booking['booking_date']) ? strtotime($booking['booking_date']):false;
87
+ }
88
+ //Do it here so things appear in the po file.
89
+ $this->status_array = array(
90
+ 0 => __('Pending','dbem'),
91
+ 1 => __('Approved','dbem'),
92
+ 2 => __('Rejected','dbem'),
93
+ 3 => __('Cancelled','dbem'),
94
+ 4 => __('Awaiting Online Payment','dbem'),
95
+ 5 => __('Awaiting Payment','dbem')
96
+ );
97
+ $this->compat_keys();
98
+ do_action('em_booking', $this, $booking_data);
99
+ }
100
+
101
+ function get_notes(){
102
+ global $wpdb;
103
+ if( !is_array($this->notes) && !empty($this->booking_id) ){
104
+ $notes = $wpdb->get_results("SELECT * FROM ". EM_META_TABLE ." WHERE meta_key='booking-note' AND object_id ='{$this->booking_id}'", ARRAY_A);
105
+ $this->notes = array();
106
+ foreach($notes as $note){
107
+ $this->notes[] = unserialize($note['meta_value']);
108
+ }
109
+ }elseif( empty($this->booking_id) ){
110
+ $this->notes = array();
111
+ }
112
+ return $this->notes;
113
+ }
114
+
115
+ /**
116
+ * Saves the booking into the database, whether a new or existing booking
117
+ * @param $mail whether or not to email the user and contact people
118
+ * @return boolean
119
+ */
120
+ function save($mail = true){
121
+ global $wpdb;
122
+ $table = EM_BOOKINGS_TABLE;
123
+ do_action('em_booking_save_pre',$this);
124
+ if( $this->validate() ){
125
+ if( $this->can_manage() ){
126
+ $this->person_id = (empty($this->person_id)) ? $this->get_person()->ID : $this->person_id;
127
+ //Step 1. Save the booking
128
+ $data = $this->to_array();
129
+ $data['booking_meta'] = serialize($data['booking_meta']);
130
+ if($this->booking_id != ''){
131
+ $update = true;
132
+ //update price and spaces
133
+ $this->get_spaces(true);
134
+ $this->get_price(true);
135
+ $where = array( 'booking_id' => $this->booking_id );
136
+ $result = $wpdb->update($table, $data, $where, $this->get_types($data));
137
+ $result = ($result !== false);
138
+ $this->feedback_message = __('Changes saved','dbem');
139
+ }else{
140
+ $update = false;
141
+ $result = $wpdb->insert($table, $data, $this->get_types($data));
142
+ $this->booking_id = $wpdb->insert_id;
143
+ $this->feedback_message = __('Your booking has been recorded','dbem');
144
+ }
145
+ //Step 2. Insert ticket bookings for this booking id if no errors so far
146
+ if( $result === false ){
147
+ $this->feedback_message = __('There was a problem saving the booking.', 'dbem');
148
+ $this->errors[] = __('There was a problem saving the booking.', 'dbem');
149
+ }else{
150
+ $tickets_bookings_result = $this->get_tickets_bookings()->save();
151
+ if( !$tickets_bookings_result ){
152
+ if( !$update ){
153
+ //delete the booking and tickets, instead of a transaction
154
+ $this->delete();
155
+ }
156
+ $this->errors[] = __('There was a problem saving the booking.', 'dbem');
157
+ $this->add_error( $this->get_tickets_bookings()->get_errors() );
158
+ }
159
+ }
160
+ //Step 3. email if necessary
161
+ if ( count($this->errors) == 0 && $mail ) {
162
+ $this->email();
163
+ }
164
+ $this->compat_keys();
165
+ return apply_filters('em_booking_save', ( count($this->errors) == 0 ), $this);
166
+ }else{
167
+ $this->feedback_message = __('There was a problem saving the booking.', 'dbem');
168
+ if( !$this->can_manage() ){
169
+ $this->feedback_message = sprintf(__('You cannot manage this %s.', 'dbem'),__('Booking','dbem'));
170
+ }
171
+ }
172
+ }else{
173
+ $this->feedback_message = __('There was a problem saving the booking.', 'dbem');
174
+ if( !$this->can_manage() ){
175
+ $this->feedback_message = sprintf(__('You cannot manage this %s.', 'dbem'),__('Booking','dbem'));
176
+ }
177
+ }
178
+ return apply_filters('em_booking_save', false, $this);
179
+ }
180
+
181
+ /**
182
+ * Load an record into this object by passing an associative array of table criterie to search for.
183
+ * Returns boolean depending on whether a record is found or not.
184
+ * @param $search
185
+ * @return boolean
186
+ */
187
+ function get($search) {
188
+ global $wpdb;
189
+ $conds = array();
190
+ foreach($search as $key => $value) {
191
+ if( array_key_exists($key, $this->fields) ){
192
+ $value = $wpdb->escape($value);
193
+ $conds[] = "`$key`='$value'";
194
+ }
195
+ }
196
+ $sql = "SELECT * FROM ". $wpdb->EM_BOOKINGS_TABLE ." WHERE " . implode(' AND ', $conds) ;
197
+ $result = $wpdb->get_row($sql, ARRAY_A);
198
+ if($result){
199
+ $this->to_object($result);
200
+ $this->person = new EM_Person($this->person_id);
201
+ return true;
202
+ }else{
203
+ return false;
204
+ }
205
+ }
206
+
207
+ /**
208
+ * Get posted data and save it into the object (not db)
209
+ * @return boolean
210
+ */
211
+ function get_post( $override_availability = false ){
212
+ $this->tickets_bookings = new EM_Tickets_Bookings($this->booking_id);
213
+ do_action('em_booking_get_post_pre',$this);
214
+ $result = array();
215
+ $this->event_id = $_REQUEST['event_id'];
216
+ if( isset($_REQUEST['em_tickets']) && is_array($_REQUEST['em_tickets']) && ($_REQUEST['em_tickets'] || $override_availability) ){
217
+ foreach( $_REQUEST['em_tickets'] as $ticket_id => $values){
218
+ //make sure ticket exists
219
+ if( !empty($values['spaces']) || $override_availability ){
220
+ $args = array('ticket_id'=>$ticket_id, 'ticket_booking_spaces'=>$values['spaces'], 'booking_id'=>$this->booking_id);
221
+ if($this->get_event()->get_bookings()->ticket_exists($ticket_id)){
222
+ $EM_Ticket_Booking = new EM_Ticket_Booking($args);
223
+ $EM_Ticket_Booking->booking = $this;
224
+ $this->tickets_bookings->add( $EM_Ticket_Booking, $override_availability );
225
+ }else{
226
+ $this->errors[]=__('You are trying to book a non-existent ticket for this event.','dbem');
227
+ }
228
+ }
229
+ }
230
+ $this->booking_comment = (!empty($_REQUEST['booking_comment'])) ? wp_kses_data(stripslashes($_REQUEST['booking_comment'])):'';
231
+ $this->get_spaces(true);
232
+ $this->get_price(true, false, false);
233
+ $this->get_person();
234
+ $this->compat_keys();
235
+ }
236
+ return apply_filters('em_booking_get_post',$this->validate(),$this);
237
+ }
238
+
239
+ function validate(){
240
+ //step 1, basic info
241
+ $basic = (
242
+ (empty($this->event_id) || is_numeric($this->event_id)) &&
243
+ (empty($this->person_id) || is_numeric($this->person_id)) &&
244
+ is_numeric($this->booking_spaces) && $this->booking_spaces > 0
245
+ );
246
+ //give some errors in step 1
247
+ if( $this->booking_spaces == 0 ){
248
+ $this->add_error(get_option('dbem_booking_feedback_min_space'));
249
+ }
250
+ //step 2, tickets bookings info
251
+ if( count($this->get_tickets_bookings()) > 0 ){
252
+ $ticket_validation = array();
253
+ foreach($this->get_tickets_bookings()->tickets_bookings as $EM_Ticket_Booking){
254
+ if ( !$EM_Ticket_Booking->validate() ){
255
+ $ticket_validation[] = false;
256
+ $result = $basic && !in_array(false,$ticket_validation);
257
+ }
258
+ $this->errors = array_merge($this->errors, $EM_Ticket_Booking->get_errors());
259
+ }
260
+ $result = $basic && !in_array(false,$ticket_validation);
261
+ }else{
262
+ $result = false;
263
+ }
264
+ return apply_filters('em_booking_validate',$result,$this);
265
+ }
266
+
267
+ /**
268
+ * Get the total number of spaces booked in THIS booking. Seting $force_refresh to true will recheck spaces, even if previously done so.
269
+ * @param unknown_type $force_refresh
270
+ * @return mixed
271
+ */
272
+ function get_spaces( $force_refresh=false ){
273
+ if($this->booking_spaces == 0 || $force_refresh == true ){
274
+ $this->booking_spaces = $this->get_tickets_bookings()->get_spaces($force_refresh);
275
+ }
276
+ return apply_filters('em_booking_get_spaces',$this->booking_spaces,$this);
277
+ }
278
+
279
+ /**
280
+ * Gets the total price for this whole booking. Seting $force_reset to true will recheck spaces, even if previously done so.
281
+ * @param boolean $force_refresh
282
+ * @param boolean $format
283
+ * @param boolean $add_tax
284
+ * @return float
285
+ */
286
+ function get_price( $force_refresh=false, $format=false, $add_tax='x' ){
287
+ if($force_refresh || $this->booking_price == 0 || $add_tax !== 'x' || get_option('dbem_bookings_tax_auto_add')){
288
+ $this->booking_price = $this->get_tickets_bookings()->get_price($force_refresh, false, $add_tax);
289
+ $this->booking_price = apply_filters('em_booking_get_price', $this->booking_price, $this, $add_tax);
290
+ }
291
+ if($format){
292
+ return em_get_currency_formatted($this->booking_price);
293
+ }
294
+ return $this->booking_price;
295
+ }
296
+
297
+ /**
298
+ * Gets the event this booking belongs to and saves a refernece in the event property
299
+ * @return EM_Event
300
+ */
301
+ function get_event(){
302
+ global $EM_Event;
303
+ if( is_object($this->event) && get_class($this->event)=='EM_Event' && $this->event->event_id == $this->event_id ){
304
+ return $this->event;
305
+ }elseif( is_object($EM_Event) && ( (is_object($this->event) && $this->event->event_id == $this->event_id) || empty($this->booking_id)) ){
306
+ $this->event = $EM_Event;
307
+ }else{
308
+ $this->event = new EM_Event($this->event_id, 'event_id');
309
+ }
310
+ return apply_filters('em_booking_get_event',$this->event);
311
+ }
312
+
313
+ /**
314
+ * Gets the ticket object this booking belongs to, saves a reference in ticket property
315
+ * @return EM_Tickets
316
+ */
317
+ function get_tickets(){
318
+ if( is_object($this->tickets) && get_class($this->tickets)=='EM_Tickets' ){
319
+ return apply_filters('em_booking_get_tickets', $this->tickets, $this);
320
+ }else{
321
+ $this->tickets = new EM_Tickets($this);
322
+ }
323
+ return apply_filters('em_booking_get_tickets', $this->tickets, $this);
324
+ }
325
+
326
+ /**
327
+ * Gets the ticket object this booking belongs to, saves a reference in ticket property
328
+ * @return EM_Tickets_Bookings
329
+ */
330
+ function get_tickets_bookings(){
331
+ global $wpdb;
332
+ if( !is_object($this->tickets_bookings) || get_class($this->tickets_bookings)!='EM_Tickets_Bookings'){
333
+ $this->tickets_bookings = new EM_Tickets_Bookings($this);
334
+ }
335
+ return apply_filters('em_booking_get_tickets_bookings', $this->tickets_bookings, $this);
336
+ }
337
+
338
+ function get_person(){
339
+ global $EM_Person;
340
+ if( is_object($this->person) && get_class($this->person)=='EM_Person' && ($this->person->ID == $this->person_id || empty($this->person_id) ) ){
341
+ //This person is already included, so don't do anything
342
+ }elseif( is_object($EM_Person) && ($EM_Person->ID === $this->person_id || $this->booking_id == '') ){
343
+ $this->person = $EM_Person;
344
+ }elseif( is_numeric($this->person_id) ){
345
+ $this->person = new EM_Person($this->person_id);
346
+ }else{
347
+ $this->person = new EM_Person(0);
348
+ }
349
+ //if this user is the parent user of disabled registrations, replace user details here:
350
+ if( get_option('dbem_bookings_registration_disable') && $this->person->ID == get_option('dbem_bookings_registration_user') ){
351
+ //override any registration data into the person objet
352
+ if( !empty($this->booking_meta['registration']) ){
353
+ foreach($this->booking_meta['registration'] as $key => $value){
354
+ $this->person->$key = $value;
355
+ }
356
+ }
357
+ $this->person->user_email = ( !empty($this->booking_meta['registration']['user_email']) ) ? $this->booking_meta['registration']['user_email']:$this->person->user_email;
358
+ if( !empty($this->booking_meta['registration']['user_name']) ){
359
+ $name_string = explode(' ',$this->booking_meta['registration']['user_name']);
360
+ $this->booking_meta['registration']['first_name'] = array_shift($name_string);
361
+ $this->booking_meta['registration']['last_name'] = implode(' ', $name_string);
362
+ }
363
+ $this->person->user_firstname = ( !empty($this->booking_meta['registration']['first_name']) ) ? $this->booking_meta['registration']['first_name']:__('Guest User','dbem');
364
+ $this->person->first_name = $this->person->user_firstname;
365
+ $this->person->user_lastname = ( !empty($this->booking_meta['registration']['last_name']) ) ? $this->booking_meta['registration']['last_name']:'';
366
+ $this->person->last_name = $this->person->user_lastname;
367
+ $this->person->phone = ( !empty($this->booking_meta['registration']['dbem_phone']) ) ? $this->booking_meta['registration']['dbem_phone']:__('Not Supplied','dbem');
368
+ //build display name
369
+ $full_name = $this->person->user_firstname . " " . $this->person->user_lastname ;
370
+ $full_name = trim($full_name);
371
+ $display_name = ( empty($full_name) ) ? __('Guest User','dbem'):$full_name;
372
+ $this->person->display_name = $display_name;
373
+ }
374
+ return apply_filters('em_booking_get_person', $this->person, $this);
375
+ }
376
+
377
+ /**
378
+ * Returns a string representation of the booking's status
379
+ * @return string
380
+ */
381
+ function get_status(){
382
+ $status = ($this->booking_status == 0 && !get_option('dbem_bookings_approval') ) ? 1:$this->booking_status;
383
+ return apply_filters('em_booking_get_status', $this->status_array[$status], $this);
384
+ }
385
+
386
+ /**
387
+ * I wonder what this does....
388
+ * @return boolean
389
+ */
390
+ function delete(){
391
+ global $wpdb;
392
+ $result = false;
393
+ if( $this->can_manage('manage_bookings','manage_others_bookings') ){
394
+ $sql = $wpdb->prepare("DELETE FROM ". EM_BOOKINGS_TABLE . " WHERE booking_id=%d", $this->booking_id);
395
+ $result = $wpdb->query( $sql );
396
+ if( $result !== false ){
397
+ //delete the tickets too
398
+ $this->get_tickets_bookings()->delete();
399
+ $this->previous_status = $this->booking_status;
400
+ $this->booking_status = false;
401
+ $this->feedback_message = sprintf(__('%s deleted', 'dbem'), __('Booking','dbem'));
402
+ }else{
403
+ $this->add_error(sprintf(__('%s could not be deleted', 'dbem'), __('Booking','dbem')));
404
+ }
405
+ }
406
+ return apply_filters('em_booking_delete',( $result !== false ), $this);
407
+ }
408
+
409
+ function cancel($email = true){
410
+ if( $this->person->ID == get_current_user_id() ){
411
+ $this->manage_override = true; //normally, users can't manage a bookiing, only event owners, so we allow them to mod their booking status in this case only.
412
+ }
413
+ return $this->set_status(3, $email);
414
+ }
415
+
416
+ /**
417
+ * Approve a booking.
418
+ * @return bool
419
+ */
420
+ function approve($email = true, $ignore_spaces = false){
421
+ return $this->set_status(1, $email, $ignore_spaces);
422
+ }
423
+ /**
424
+ * Reject a booking and save
425
+ * @return bool
426
+ */
427
+ function reject($email = true){
428
+ return $this->set_status(2, $email);
429
+ }
430
+ /**
431
+ * Unpprove a booking.
432
+ * @return bool
433
+ */
434
+ function unapprove($email = true){
435
+ return $this->set_status(0, $email);
436
+ }
437
+
438
+ /**
439
+ * Change the status of the booking. This will save to the Database too.
440
+ * @param int $status
441
+ * @return boolean
442
+ */
443
+ function set_status($status, $email = true, $ignore_spaces = false){
444
+ global $wpdb;
445
+ $action_string = strtolower($this->status_array[$status]);
446
+ //if we're approving we can't approve a booking if spaces are full, so check before it's approved.
447
+ if(!$ignore_spaces && $status == 1){
448
+ if( $this->get_event()->get_bookings()->get_available_spaces() < $this->get_spaces() && !get_option('dbem_bookings_approval_overbooking') ){
449
+ $this->feedback_message = sprintf(__('Not approved, spaces full.','dbem'), $action_string);
450
+ return apply_filters('em_booking_set_status', false, $this);
451
+ }
452
+ }
453
+ $this->previous_status = $this->booking_status;
454
+ $this->booking_status = $status;
455
+ $result = $wpdb->query($wpdb->prepare('UPDATE '.EM_BOOKINGS_TABLE.' SET booking_status=%d WHERE booking_id=%d', array($status, $this->booking_id)));
456
+ if($result !== false){
457
+ $this->feedback_message = sprintf(__('Booking %s.','dbem'), $action_string);
458
+ if( $email ){
459
+ if( $this->email() ){
460
+ $this->feedback_message .= " ".__('Mail Sent.','dbem');
461
+ }elseif( $this->previous_status == 0 ){
462
+ //extra errors may be logged by email() in EM_Object
463
+ $this->feedback_message .= ' <span style="color:red">'.__('ERROR : Mail Not Sent.','dbem').'</span>';
464
+ $this->add_error(__('ERROR : Mail Not Sent.','dbem'));
465
+ $result = false;
466
+ }
467
+ }
468
+ }else{
469
+ //errors should be logged by save()
470
+ $this->feedback_message = sprintf(__('Booking could not be %s.','dbem'), $action_string);
471
+ $this->add_error(sprintf(__('Booking could not be %s.','dbem'), $action_string));
472
+ }
473
+ return apply_filters('em_booking_set_status', $result, $this);
474
+ }
475
+
476
+ /**
477
+ * Add a booking note to this booking. returns wpdb result or false if use can't manage this event.
478
+ * @param string $note
479
+ * @return mixed
480
+ */
481
+ function add_note( $note_text ){
482
+ global $wpdb;
483
+ if( $this->can_manage() ){
484
+ $this->get_notes();
485
+ $note = array('author'=>get_current_user_id(),'note'=>$note_text,'timestamp'=>current_time('timestamp'));
486
+ $this->notes[] = $note;
487
+ $this->feedback_message = __('Booking note successfully added.','dbem');
488
+ return $wpdb->insert(EM_META_TABLE, array('object_id'=>$this->booking_id, 'meta_key'=>'booking-note', 'meta_value'=> serialize($note)),array('%d','%s','%s'));
489
+ }
490
+ return false;
491
+ }
492
+
493
+ function output($format, $target="html") {
494
+ preg_match_all("/(#@?_?[A-Za-z0-9]+)({([^}]+)})?/", $format, $placeholders);
495
+ foreach( $this->get_tickets() as $EM_Ticket){ break; } //Get first ticket for single ticket placeholders
496
+ $output_string = $format;
497
+ $replaces = array();
498
+ foreach($placeholders[1] as $key => $result) {
499
+ $replace = '';
500
+ $full_result = $placeholders[0][$key];
501
+ switch( $result ){
502
+ case '#_BOOKINGID':
503
+ $replace = $this->booking_id;
504
+ break;
505
+ case '#_RESPNAME' : //Depreciated
506
+ case '#_BOOKINGNAME':
507
+ $replace = $this->get_person()->get_name();
508
+ break;
509
+ case '#_RESPEMAIL' : //Depreciated
510
+ case '#_BOOKINGEMAIL':
511
+ $replace = $this->get_person()->user_email;
512
+ break;
513
+ case '#_RESPPHONE' : //Depreciated
514
+ case '#_BOOKINGPHONE':
515
+ $replace = $this->get_person()->phone;
516
+ break;
517
+ case '#_BOOKINGSPACES':
518
+ $replace = $this->get_spaces();
519
+ break;
520
+ case '#_BOOKINGLISTURL':
521
+ $replace = em_get_my_bookings_url();
522
+ break;
523
+ case '#_COMMENT' : //Depreciated
524
+ case '#_BOOKINGCOMMENT':
525
+ $replace = $this->booking_comment;
526
+ break;
527
+ case '#_BOOKINGPRICEWITHTAX':
528
+ $replace = em_get_currency_symbol(true)." ". number_format($this->get_price(false,false,true),2);
529
+ break;
530
+ case '#_BOOKINGPRICEWITHOUTTAX':
531
+ $replace = em_get_currency_symbol(true)." ". number_format($this->get_price(false,false,false),2);
532
+ break;
533
+ case '#_BOOKINGPRICETAX':
534
+ $replace = em_get_currency_symbol(true)." ". number_format($this->get_price(false,false,false)*(get_option('dbem_bookings_tax')/100),2);
535
+ break;
536
+ case '#_BOOKINGPRICE':
537
+ $replace = em_get_currency_symbol(true)." ". number_format($this->get_price(),2);
538
+ break;
539
+ case '#_BOOKINGTICKETNAME':
540
+ $replace = $EM_Ticket->name;
541
+ break;
542
+ case '#_BOOKINGTICKETDESCRIPTION':
543
+ $replace = $EM_Ticket->description;
544
+ break;
545
+ case '#_BOOKINGTICKETPRICEWITHTAX':
546
+ $replace = em_get_currency_symbol(true)." ". number_format($EM_Ticket->get_price(false,true),2);
547
+ break;
548
+ case '#_BOOKINGTICKETPRICEWITHOUTTAX':
549
+ $replace = em_get_currency_symbol(true)." ". number_format($EM_Ticket->get_price(false,false),2);
550
+ break;
551
+ case '#_BOOKINGTICKETTAX':
552
+ $replace = em_get_currency_symbol(true)." ". number_format($EM_Ticket->get_price(false,false)*(get_option('dbem_bookings_tax')/100),2);
553
+ break;
554
+ case '#_BOOKINGTICKETPRICE':
555
+ $replace = em_get_currency_symbol(true)." ". number_format($EM_Ticket->get_price(),2);
556
+ break;
557
+ case '#_BOOKINGTICKETS':
558
+ ob_start();
559
+ em_locate_template('emails/bookingtickets.php', true, array('EM_Booking'=>$this));
560
+ $replace = ob_get_clean();
561
+ break;
562
+ default:
563
+ $replace = $full_result;
564
+ break;
565
+ }
566
+ $replaces[$full_result] = apply_filters('em_booking_output_placeholder', $replace, $this, $full_result, $target);
567
+ }
568
+ //sort out replacements so that during replacements shorter placeholders don't overwrite longer varieties.
569
+ krsort($replaces);
570
+ foreach($replaces as $full_result => $replacement){
571
+ $output_string = str_replace($full_result, $replacement , $output_string );
572
+ }
573
+ //run event output too, since this is never run from within events and will not infinitely loop
574
+ $output_string = $this->get_event()->output($output_string, $target);
575
+ return apply_filters('em_booking_output', $output_string, $this, $format, $target);
576
+ }
577
+
578
+ /**
579
+ * @param EM_Booking $EM_Booking
580
+ * @param EM_Event $event
581
+ * @return boolean
582
+ */
583
+ function email( $email_admin = true, $force_resend = false ){
584
+ global $EM_Mailer;
585
+ $result = true;
586
+
587
+ //FIXME ticket logic needed
588
+ $EM_Event = $this->get_event(); //We NEED event details here.
589
+ $EM_Event->get_bookings(true); //refresh all bookings
590
+
591
+ //Make sure event matches booking, and that booking used to be approved.
592
+ if( $this->booking_status !== $this->previous_status || $force_resend ){
593
+ $msg = array( 'user'=> array('subject'=>'', 'body'=>''), 'admin'=> array('subject'=>'', 'body'=>'')); //blank msg template
594
+
595
+ //admin messages won't change whether pending or already approved
596
+ switch( $this->booking_status ){
597
+ case 0:
598
+ case 5: //TODO remove offline status from here and move to pro
599
+ $msg['user']['subject'] = get_option('dbem_bookings_email_pending_subject');
600
+ $msg['user']['body'] = get_option('dbem_bookings_email_pending_body');
601
+ //admins should get something (if set to)
602
+ $msg['admin']['subject'] = get_option('dbem_bookings_contact_email_subject');
603
+ $msg['admin']['body'] = get_option('dbem_bookings_contact_email_body');
604
+ break;
605
+ case 1:
606
+ $msg['user']['subject'] = get_option('dbem_bookings_email_confirmed_subject');
607
+ $msg['user']['body'] = get_option('dbem_bookings_email_confirmed_body');
608
+ //admins should get something (if set to)
609
+ $msg['admin']['subject'] = get_option('dbem_bookings_contact_email_subject');
610
+ $msg['admin']['body'] = get_option('dbem_bookings_contact_email_body');
611
+ break;
612
+ case 2:
613
+ $msg['user']['subject'] = get_option('dbem_bookings_email_rejected_subject');
614
+ $msg['user']['body'] = get_option('dbem_bookings_email_rejected_body');
615
+ break;
616
+ case 3:
617
+ $msg['user']['subject'] = get_option('dbem_bookings_email_cancelled_subject');
618
+ $msg['user']['body'] = get_option('dbem_bookings_email_cancelled_body');
619
+ //admins should get something (if set to)
620
+ $msg['admin']['subject'] = get_option('dbem_contactperson_email_cancelled_subject');
621
+ $msg['admin']['body'] = get_option('dbem_contactperson_email_cancelled_body');
622
+ break;
623
+ }
624
+ //messages can be overriden just before being sent
625
+ $msg = apply_filters('em_booking_email_messages', $msg, $this);
626
+ $output_type = get_option('dbem_smtp_html') ? 'html':'email';
627
+
628
+ //Send user (booker) emails
629
+ if( !empty($msg['user']['subject']) ){
630
+ $msg['user']['subject'] = $this->output($msg['user']['subject'], $output_type);
631
+ $msg['user']['body'] = $this->output($msg['user']['body'], $output_type);
632
+ if( get_option('dbem_smtp_html') && get_option('dbem_smtp_html_br', 1) ){
633
+ $msg['user']['body'] = nl2br($msg['user']['body']);
634
+ }
635
+ //Send to the person booking
636
+ if( !$this->email_send( $msg['user']['subject'], $msg['user']['body'], $this->get_person()->user_email) ){
637
+ $result = false;
638
+ }
639
+ }
640
+
641
+ //Send admin/contact emails if this isn't the event owner or an events admin
642
+ if( $email_admin && !empty($msg['admin']['subject']) && (!$this->can_manage() || (!empty($_REQUEST['action']) && $_REQUEST['action'] == 'booking_add') || $this->manage_override) ){ //emails won't be sent if admin is logged in unless they book themselves
643
+ if( get_option('dbem_bookings_contact_email') == 1 || get_option('dbem_bookings_notify_admin') ){
644
+ //Only gets sent if this is a pending booking, unless approvals are disabled.
645
+ $msg['admin']['subject'] = $this->output($msg['admin']['subject'], $output_type);
646
+ $msg['admin']['body'] = $this->output($msg['admin']['body'], $output_type);
647
+ if( get_option('dbem_smtp_html') && get_option('dbem_smtp_html_br', 1) ){
648
+ $msg['admin']['body'] = nl2br($msg['admin']['body']);
649
+ }
650
+ //email contact
651
+ if( get_option('dbem_bookings_contact_email') == 1 ){
652
+ if( !$this->email_send( $msg['admin']['subject'], $msg['admin']['body'], $EM_Event->get_contact()->user_email) && current_user_can('activate_plugins')){
653
+ $this->errors[] = __('Confirmation email could not be sent to contact person. Registrant should have gotten their email (only admin see this warning).','dbem');
654
+ $result = false;
655
+ }
656
+ }
657
+ //email admin
658
+ if( get_option('dbem_bookings_notify_admin') != '' && preg_match('/^([_\.0-9a-z-]+@([0-9a-z][0-9a-z-]+\.)+[a-z]{2,3},?)+$/', get_option('dbem_bookings_notify_admin')) ){
659
+ $admin_emails = get_option('dbem_bookings_notify_admin');
660
+ $admin_emails = explode(',', $admin_emails); //supply emails as array
661
+ if( !$this->email_send( $msg['admin']['subject'], $msg['admin']['body'], $admin_emails) ){
662
+ $this->errors[] = __('Confirmation email could not be sent to admin. Registrant should have gotten their email (only admin see this warning).','dbem');
663
+ $result = false;
664
+ }
665
+ }
666
+ }
667
+ }
668
+ }
669
+ return $result;
670
+ //TODO need error checking for booking mail send
671
+ }
672
+
673
+ /**
674
+ * Can the user manage this event?
675
+ */
676
+ function can_manage(){
677
+ return $this->get_event()->can_manage('manage_bookings','manage_others_bookings') || empty($this->booking_id) || !empty($this->manage_override);
678
+ }
679
+
680
+ /**
681
+ * Returns this object in the form of an array
682
+ * @return array
683
+ */
684
+ function to_array($person = false){
685
+ $booking = array();
686
+ //Core Data
687
+ $booking = parent::to_array();
688
+ //Person Data
689
+ if($person && is_object($this->person)){
690
+ $person = $this->person->to_array();
691
+ $booking = array_merge($booking, $person);
692
+ }
693
+ return $booking;
694
+ }
695
+ }
696
  ?>
classes/em-bookings-table.php ADDED
@@ -0,0 +1,623 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ //Builds a table of bookings, still work in progress...
3
+ class EM_Bookings_Table{
4
+ /**
5
+ * associative array of collumns that'll be shown in order from left to right
6
+ *
7
+ * * key - collumn name in the databse, what will be used when searching
8
+ * * value - label for use in collumn headers
9
+ * @var array
10
+ */
11
+ public $cols = array('user_name','event_name','booking_spaces','booking_status','booking_price','actions');
12
+ /**
13
+ * Asoociative array of available collumn keys and corresponding headers, which will be used to display this table of bookings
14
+ * @var unknown_type
15
+ */
16
+ public $cols_template = array();
17
+ public $sortable_cols = array('booking_date');
18
+ /**
19
+ * Object we're viewing bookings in relation to.
20
+ * @var object
21
+ */
22
+ public $cols_view;
23
+ /**
24
+ * Index key used for looking up status information we're filtering in the booking table
25
+ * @var string
26
+ */
27
+ public $string = 'needs-attention';
28
+ /**
29
+ * Associative array of status information.
30
+ *
31
+ * * key - status index value
32
+ * * value - associative array containing keys
33
+ * ** label - the label for use in filter forms
34
+ * ** search - array or integer status numbers to search
35
+ *
36
+ * @var array
37
+ */
38
+ public $statuses = array();
39
+ /**
40
+ * Maximum number of rows to show
41
+ * @var int
42
+ */
43
+ public $limit = 20;
44
+ public $order = 'ASC';
45
+ public $orderby = 'booking_name';
46
+ public $page = 1;
47
+ public $offset = 0;
48
+ public $scope = 'future';
49
+ public $show_tickets = false;
50
+
51
+ function __construct($show_tickets = false){
52
+ $this->statuses = array(
53
+ 'all' => array('label'=>__('All','dbem'), 'search'=>false),
54
+ 'pending' => array('label'=>__('Pending','dbem'), 'search'=>0),
55
+ 'confirmed' => array('label'=>__('Confirmed','dbem'), 'search'=>1),
56
+ 'cancelled' => array('label'=>__('Cancelled','dbem'), 'search'=>2),
57
+ 'rejected' => array('label'=>__('Rejected','dbem'), 'search'=>3),
58
+ 'needs-attention' => array('label'=>__('Needs Attention','dbem'), 'search'=>array(0)),
59
+ 'incomplete' => array('label'=>__('Incomplete Bookings','dbem'), 'search'=>array(0))
60
+ );
61
+ if( !get_option('dbem_bookings_approval') ){
62
+ unset($this->statuses['pending']);
63
+ unset($this->statuses['incomplete']);
64
+ $this->statuses['confirmed']['search'] = array(0,1);
65
+ }
66
+ //Set basic vars
67
+ $this->order = ( !empty($_REQUEST ['order']) ) ? $_REQUEST ['order']:'ASC';
68
+ $this->orderby = ( !empty($_REQUEST ['order']) ) ? $_REQUEST ['order']:'booking_name';
69
+ $this->limit = ( !empty($_REQUEST['limit']) ) ? $_REQUEST['limit'] : 20;//Default limit
70
+ $this->page = ( !empty($_REQUEST['pno']) ) ? $_REQUEST['pno']:1;
71
+ $this->offset = ( $this->page > 1 ) ? ($this->page-1)*$this->limit : 0;
72
+ $this->scope = ( !empty($_REQUEST['scope']) && array_key_exists($_REQUEST ['scope'], em_get_scopes()) ) ? $_REQUEST ['scope']:get_option('dbem_default_bookings_search','future');
73
+ $this->status = ( !empty($_REQUEST['status']) && array_key_exists($_REQUEST['status'], $this->statuses) ) ? $_REQUEST['status']:get_option('dbem_default_bookings_search','needs-attention');
74
+ //build template of possible collumns
75
+ $this->cols_template = apply_filters('em_bookings_table_cols_template', array(
76
+ 'user_name'=>__('Name','dbem'),
77
+ 'event_name'=>__('Event','dbem'),
78
+ 'event_date'=>__('Event Date(s)','dbem'),
79
+ 'event_time'=>__('Event Time(s)','dbem'),
80
+ 'user_email'=>__('E-mail','dbem'),
81
+ 'dbem_phone'=>__('Phone Number','dbem'),
82
+ 'booking_spaces'=>__('Spaces','dbem'),
83
+ 'booking_status'=>__('Status','dbem'),
84
+ 'booking_date'=>__('Booking Date','dbem'),
85
+ 'booking_price'=>__('Total','dbem'),
86
+ 'booking_id'=>__('Booking ID','dbem')
87
+ ), $this);
88
+ $this->cols_tickets_template = apply_filters('em_bookings_table_cols_tickets_template', array(
89
+ 'ticket_name'=>__('Ticket Name','dbem'),
90
+ 'ticket_description'=>__('Ticket Description','dbem'),
91
+ 'ticket_price'=>__('Ticket Price','dbem'),
92
+ 'ticket_id'=>__('Ticket ID','dbem')
93
+ ), $this);
94
+ //add tickets to template if we're showing rows by booking-ticket
95
+ if( $show_tickets ){
96
+ $this->show_tickets = true;
97
+ $this->cols = array('user_name','event_name','ticket_name','ticket_price','booking_spaces','booking_status','actions');
98
+ $this->cols_template = array_merge( $this->cols_template, $this->cols_tickets_template);
99
+ }
100
+ $this->cols_template['actions'] = __('Actions','dbem');
101
+ //calculate collumns if post requests
102
+ if( !empty($_REQUEST ['cols']) && !is_array($_REQUEST ['cols']) ){
103
+ $this->cols = explode(',',$_REQUEST['cols']);
104
+ }elseif( !empty($_REQUEST ['cols']) ){
105
+ $this->cols = $_REQUEST['cols'];
106
+ }
107
+ //load collumn view settings
108
+ if( $this->get_person() !== false ){
109
+ $this->cols_view = $this->get_person();
110
+ }elseif( $this->get_ticket() !== false ){
111
+ $this->cols_view = $this->get_ticket();
112
+ }elseif( $this->get_event() !== false ){
113
+ $this->cols_view = $this->get_event();
114
+ }
115
+ foreach($this->cols as $col_key){
116
+ if( !array_key_exists($col_key, $this->cols_template)){
117
+ unset($this->cols[$col_key]);
118
+ }
119
+ }
120
+ //save collumns depending on context and user preferences
121
+ if( empty($_REQUEST['cols']) ){
122
+ if(!empty($this->cols_view) && is_object($this->cols_view)){
123
+ //check if user has settings for object type
124
+ $settings = get_user_meta(get_current_user_id(), 'em_bookings_view-'.get_class($this->cols_view), true );
125
+ }else{
126
+ $settings = get_user_meta(get_current_user_id(), 'em_bookings_view', true );
127
+ }
128
+ if( !empty($settings) ){
129
+ $this->cols = $settings;
130
+ }
131
+ }elseif( !empty($_REQUEST['cols']) && empty($_REQUEST['no_save']) ){ //save view settings for next time
132
+ if( !empty($this->cols_view) && is_object($this->cols_view) ){
133
+ update_user_meta(get_current_user_id(), 'em_bookings_view-'.get_class($this->cols_view), $this->cols );
134
+ }else{
135
+ update_user_meta(get_current_user_id(), 'em_bookings_view', $this->cols );
136
+ }
137
+ }
138
+ do_action('em_bookings_table', $this);
139
+ }
140
+
141
+
142
+ /**
143
+ * @return EM_Person|false
144
+ */
145
+ function get_person(){
146
+ global $EM_Person;
147
+ if( !empty($this->person) && is_object($this->person) ){
148
+ return $this->person;
149
+ }elseif( !empty($_REQUEST['person_id']) && !empty($EM_Person) && is_object($EM_Person) ){
150
+ return $EM_Person;
151
+ }
152
+ return false;
153
+ }
154
+ /**
155
+ * @return EM_Ticket|false
156
+ */
157
+ function get_ticket(){
158
+ global $EM_Ticket;
159
+ if( !empty($this->ticket) && is_object($this->ticket) ){
160
+ return $this->ticket;
161
+ }elseif( !empty($EM_Ticket) && is_object($EM_Ticket) ){
162
+ return $EM_Ticket;
163
+ }
164
+ return false;
165
+ }
166
+ /**
167
+ * @return $EM_Event|false
168
+ */
169
+ function get_event(){
170
+ global $EM_Event;
171
+ if( !empty($this->event) && is_object($this->event) ){
172
+ return $this->event;
173
+ }elseif( !empty($EM_Event) && is_object($EM_Event) ){
174
+ return $EM_Event;
175
+ }
176
+ return false;
177
+ }
178
+
179
+ function get_bookings($force_refresh = true){
180
+ if( empty($this->bookings) || $force_refresh ){
181
+ $this->events = array();
182
+ $EM_Ticket = $this->get_ticket();
183
+ $EM_Event = $this->get_event();
184
+ $EM_Person = $this->get_person();
185
+ if( $EM_Person !== false ){
186
+ $args = array('person'=>$EM_Person->ID,'scope'=>$this->scope,'status'=>$this->get_status_search(),'order'=>$this->order,'orderby'=>$this->orderby);
187
+ $this->bookings_count = EM_Bookings::count($args);
188
+ $this->bookings = EM_Bookings::get(array_merge($args, array('limit'=>$this->limit,'offset'=>$this->offset)));
189
+ foreach($this->bookings->bookings as $EM_Booking){
190
+ //create event
191
+ if( !array_key_exists($EM_Booking->event_id,$this->events) ){
192
+ $this->events[$EM_Booking->event_id] = new EM_Event($EM_Booking->event_id);
193
+ }
194
+ }
195
+ }elseif( $EM_Ticket !== false ){
196
+ //searching bookings with a specific ticket
197
+ $this->bookings = $EM_Ticket->get_bookings();
198
+ $this->bookings_count = (is_array($this->bookings->bookings)) ? count($this->bookings->bookings):0;
199
+ $this->events[$EM_Ticket->event_id] = $EM_Ticket->get_event();
200
+ }elseif( $EM_Event !== false ){
201
+ //bookings for an event
202
+ $args = array('event'=>$EM_Event->event_id,'scope'=>false,'status'=>$this->get_status_search(),'order'=>$this->order,'orderby'=>$this->orderby);
203
+ $args['owner'] = !current_user_can('manage_others_bookings') ? get_current_user_id() : false;
204
+ $this->bookings_count = EM_Bookings::count($args);
205
+ $this->bookings = EM_Bookings::get(array_merge($args, array('limit'=>$this->limit,'offset'=>$this->offset)));
206
+ $this->events[$EM_Event->event_id] = $EM_Event;
207
+ }else{
208
+ //all bookings for a status
209
+ $args = array('status'=>$this->get_status_search(),'scope'=>$this->scope,'order'=>$this->order,'orderby'=>$this->orderby);
210
+ $args['owner'] = !current_user_can('manage_others_bookings') ? get_current_user_id() : false;
211
+ $this->bookings_count = EM_Bookings::count($args);
212
+ $this->bookings = EM_Bookings::get(array_merge($args, array('limit'=>$this->limit,'offset'=>$this->offset)));
213
+ //Now let's create events and bookings for this instead of giving each booking an event
214
+ foreach($this->bookings->bookings as $EM_Booking){
215
+ //create event
216
+ if( !array_key_exists($EM_Booking->event_id,$this->events) ){
217
+ $this->events[$EM_Booking->event_id] = new EM_Event($EM_Booking->event_id);
218
+ }
219
+ }
220
+ }
221
+ }
222
+ return $this->bookings;
223
+ }
224
+
225
+ function get_count(){
226
+ return $this->bookings_count;
227
+ }
228
+
229
+ function get_status_search(){
230
+ if(is_array($this->statuses[$this->status]['search'])){
231
+ return implode(',',$this->statuses[$this->status]['search']);
232
+ }
233
+ return $this->statuses[$this->status]['search'];
234
+ }
235
+
236
+ function output(){
237
+ do_action('em_bookings_table_header',$this); //won't be overwritten by JS
238
+ $this->output_overlays();
239
+ $this->output_table();
240
+ do_action('em_bookings_table_footer',$this); //won't be overwritten by JS
241
+ }
242
+
243
+ function output_overlays(){
244
+ $EM_Ticket = $this->get_ticket();
245
+ $EM_Event = $this->get_event();
246
+ $EM_Person = $this->get_person();
247
+ ?>
248
+ <div id="em-bookings-table-settings" class="em-bookings-table-overlay" style="display:none;" title="<?php _e('Bookings Table Settings','dbem'); ?>">
249
+ <form id="em-bookings-table-settings-form" class="em-bookings-table-form" action="" method="post">
250
+ <p><?php _e('Modify what information is displayed in this booking table.','dbem') ?></p>
251
+ <div id="em-bookings-table-settings-form-cols">
252
+ <p>
253
+ <strong><?php _e('Collumns to show','dbem')?></strong><br />
254
+ <?php _e('Drag items to or from the left collumn to add or remove them.','dbem'); ?>
255
+ </p>
256
+ <ul id="em-bookings-cols-active" class="em-bookings-cols-sortable">
257
+ <?php foreach( $this->cols as $col_key ): ?>
258
+ <li class="ui-state-highlight">
259
+ <input id="em-bookings-col-<?php echo $col_key; ?>" type="hidden" name="<?php echo $col_key; ?>" value="1" class="em-bookings-col-item" />
260
+ <?php echo $this->cols_template[$col_key]; ?>
261
+ </li>
262
+ <?php endforeach; ?>
263
+ </ul>
264
+ <ul id="em-bookings-cols-inactive" class="em-bookings-cols-sortable">
265
+ <?php foreach( $this->cols_template as $col_key => $col_data ): ?>
266
+ <?php if( !in_array($col_key, $this->cols) ): ?>
267
+ <li class="ui-state-default">
268
+ <input id="em-bookings-col-<?php echo $col_key; ?>" type="hidden" name="<?php echo $col_key; ?>" value="0" class="em-bookings-col-item" />
269
+ <?php echo $col_data; ?>
270
+ </li>
271
+ <?php endif; ?>
272
+ <?php endforeach; ?>
273
+ </ul>
274
+ </div>
275
+ </form>
276
+ </div>
277
+ <div id="em-bookings-table-export" class="em-bookings-table-overlay" style="display:none;" title="<?php _e('Export Bookings','dbem'); ?>">
278
+ <form id="em-bookings-table-export-form" class="em-bookings-table-form" action="" method="post">
279
+ <p><?php _e('Select the options below and export all the bookings you have currently filtered (all pages) into a CSV spreadsheet format.','dbem') ?></p>
280
+ <?php if( !get_option('dbem_bookings_tickets_single') ): //single ticket mode means no splitting by ticket type ?>
281
+ <p><?php _e('Split bookings by ticket type','dbem')?> <input type="checkbox" name="show_tickets" value="1" />
282
+ <a href="#" title="<?php _e('If your events have multiple tickets, enabling this will show a seperate row for each ticket within a booking.'); ?>">?</a>
283
+ <?php endif; ?>
284
+ <div id="em-bookings-table-settings-form-cols">
285
+ <p><strong><?php _e('Collumns to export','dbem')?></strong></p>
286
+ <ul id="em-bookings-export-cols-active" class="em-bookings-cols-sortable">
287
+ <?php foreach( $this->cols as $col_key ): ?>
288
+ <li class="ui-state-highlight">
289
+ <input id="em-bookings-col-<?php echo $col_key; ?>" type="hidden" name="cols[<?php echo $col_key; ?>]" value="1" class="em-bookings-col-item" />
290
+ <?php echo $this->cols_template[$col_key]; ?>
291
+ </li>
292
+ <?php endforeach; ?>
293
+ </ul>
294
+ <ul id="em-bookings-export-cols-inactive" class="em-bookings-cols-sortable">
295
+ <?php foreach( $this->cols_template as $col_key => $col_data ): ?>
296
+ <?php if( !in_array($col_key, $this->cols) ): ?>
297
+ <li class="ui-state-default">
298
+ <input id="em-bookings-col-<?php echo $col_key; ?>" type="hidden" name="cols[<?php echo $col_key; ?>]" value="0" class="em-bookings-col-item" />
299
+ <?php echo $col_data; ?>
300
+ </li>
301
+ <?php endif; ?>
302
+ <?php endforeach; ?>
303
+ <?php if( !$this->show_tickets ): ?>
304
+ <?php foreach( $this->cols_tickets_template as $col_key => $col_data ): ?>
305
+ <?php if( !in_array($col_key, $this->cols) ): ?>
306
+ <li class="ui-state-default <?php if(array_key_exists($col_key, $this->cols_tickets_template)) echo 'em-bookings-col-item-ticket'; ?>">
307
+ <input id="em-bookings-col-<?php echo $col_key; ?>" type="hidden" name="cols[<?php echo $col_key; ?>]" value="0" class="em-bookings-col-item" />
308
+ <?php echo $col_data; ?>
309
+ </li>
310
+ <?php endif; ?>
311
+ <?php endforeach; ?>
312
+ <?php endif; ?>
313
+ </ul>
314
+ </div>
315
+ <?php if( $EM_Event !== false ): ?>
316
+ <input type="hidden" name="event_id" value='<?php echo $EM_Event->event_id; ?>' />
317
+ <?php endif; ?>
318
+ <?php if( $EM_Ticket !== false ): ?>
319
+ <input type="hidden" name="ticket_id" value='<?php echo $EM_Ticket->ticket_id; ?>' />
320
+ <?php endif; ?>
321
+ <?php if( $EM_Person !== false ): ?>
322
+ <input type="hidden" name="person_id" value='<?php echo $EM_Person->ID; ?>' />
323
+ <?php endif; ?>
324
+ <input type="hidden" name="scope" value='<?php echo $this->scope ?>' />
325
+ <input type="hidden" name="status" value='<?php echo $this->status ?>' />
326
+ <input type="hidden" name="no_save" value='1' />
327
+ <input type="hidden" name="_wpnonce" value="<?php echo wp_create_nonce('export_bookings_csv'); ?>" />
328
+ <input type="hidden" name="action" value="export_bookings_csv" />
329
+ </form>
330
+ </div>
331
+ <br class="clear" />
332
+ <?php
333
+ }
334
+
335
+ function output_table(){
336
+ $EM_Ticket = $this->get_ticket();
337
+ $EM_Event = $this->get_event();
338
+ $EM_Person = $this->get_person();
339
+ $this->get_bookings(true); //get bookings and refresh
340
+ ?>
341
+ <div class='em-bookings-table em_obj' id="em-bookings-table">
342
+ <form class='bookings-filter' method='post' action='<?php bloginfo('wpurl') ?>/wp-admin/edit.php'>
343
+ <?php if( $EM_Event !== false ): ?>
344
+ <input type="hidden" name="event_id" value='<?php echo $EM_Event->event_id; ?>' />
345
+ <?php endif; ?>
346
+ <?php if( $EM_Ticket !== false ): ?>
347
+ <input type="hidden" name="ticket_id" value='<?php echo $EM_Ticket->ticket_id; ?>' />
348
+ <?php endif; ?>
349
+ <?php if( $EM_Person !== false ): ?>
350
+ <input type="hidden" name="person_id" value='<?php echo $EM_Person->ID; ?>' />
351
+ <?php endif; ?>
352
+ <input type="hidden" name="pno" value='<?php echo $this->page ?>' />
353
+ <input type="hidden" name="order" value='<?php echo $this->order ?>' />
354
+ <input type="hidden" name="orderby" value='<?php echo $this->orderby ?>' />
355
+ <input type="hidden" name="_wpnonce" value="<?php echo ( !empty($_REQUEST['_wpnonce']) ) ? $_REQUEST['_wpnonce']:wp_create_nonce('em_bookings_table'); ?>" />
356
+ <input type="hidden" name="action" value="em_bookings_table" />
357
+ <input type="hidden" name="cols" value="<?php echo implode(',', $this->cols); ?>" />
358
+
359
+ <div class='tablenav'>
360
+ <div class="alignleft actions">
361
+ <a href="#" class="em-bookings-table-export" id="em-bookings-table-export-trigger" rel="#em-bookings-table-export" title="<?php _e('Export these bookings.','dbem'); ?>"></a>
362
+ <a href="#" class="em-bookings-table-settings" id="em-bookings-table-settings-trigger" rel="#em-bookings-table-settings"></a>
363
+ <?php if( $EM_Event === false ): ?>
364
+ <select name="scope">
365
+ <?php
366
+ foreach ( em_get_scopes() as $key => $value ) {
367
+ $selected = "";
368
+ if ($key == $this->scope)
369
+ $selected = "selected='selected'";
370
+ echo "<option value='$key' $selected>$value</option> ";
371
+ }
372
+ ?>
373
+ </select>
374
+ <?php endif; ?>
375
+ <select name="limit">
376
+ <option value="<?php echo $this->limit ?>"><?php echo sprintf(__('%s Rows','dbem'),$this->limit); ?></option>
377
+ <option value="5">5</option>
378
+ <option value="10">10</option>
379
+ <option value="25">25</option>
380
+ <option value="50">50</option>
381
+ <option value="100">100</option>
382
+ </select>
383
+ <select name="status">
384
+ <?php
385
+ foreach ( $this->statuses as $key => $value ) {
386
+ $selected = "";
387
+ if ($key == $this->status)
388
+ $selected = "selected='selected'";
389
+ echo "<option value='$key' $selected>{$value['label']}</option> ";
390
+ }
391
+ ?>
392
+ </select>
393
+ <input id="post-query-submit" class="button-secondary" type="submit" value="<?php _e ( 'Filter' )?>" />
394
+ <?php if( $EM_Event !== false ): ?>
395
+ <?php _e('Displaying Event','dbem'); ?> : <?php echo $EM_Event->name; ?>
396
+ <?php elseif( $EM_Person !== false ): ?>
397
+ <?php _e('Displaying User','dbem'); echo ' : '.$EM_Person->get_name(); ?>
398
+ <?php endif; ?>
399
+ </div>
400
+ <?php
401
+ if ( $this->bookings_count >= $this->limit ) {
402
+ $bookings_nav = em_admin_paginate( $this->bookings_count, $this->limit, $this->page, array(),'#%#%','#');
403
+ echo $bookings_nav;
404
+ }
405
+ ?>
406
+ <div class="clear"></div>
407
+ </div>
408
+ <div class="clear"></div>
409
+ <div class='table-wrap'>
410
+ <table id='dbem-bookings-table' class='widefat post '>
411
+ <thead>
412
+ <tr>
413
+ <?php /*
414
+ <th class='manage-column column-cb check-column' scope='col'>
415
+ <input class='select-all' type="checkbox" value='1' />
416
+ </th>
417
+ */ ?>
418
+ <th class='manage-column' scope='col'><?php echo implode("</th><th class='manage-column' scope='col'>", $this->get_headers()); ?></th>
419
+ </tr>
420
+ </thead>
421
+ <?php if( $this->bookings_count > 0 ): ?>
422
+ <tbody>
423
+ <?php
424
+ $rowno = 0;
425
+ $event_count = (!empty($event_count)) ? $event_count:0;
426
+ foreach ($this->bookings->bookings as $EM_Booking) {
427
+ ?>
428
+ <tr>
429
+ <?php /*
430
+ <th scope="row" class="check-column" style="padding:7px 0px 7px;"><input type='checkbox' value='<?php echo $EM_Booking->booking_id ?>' name='bookings[]'/></th>
431
+ */
432
+ /* @var $EM_Booking EM_Booking */
433
+ /* @var $EM_Ticket_Booking EM_Ticket_Booking */
434
+ if( $this->show_tickets ){
435
+ foreach($EM_Booking->get_tickets_bookings()->tickets_bookings as $EM_Ticket_Booking){
436
+ ?><td><?php echo implode('</td><td>', $this->get_row($EM_Ticket_Booking)); ?></td><?php
437
+ }
438
+ }else{
439
+ ?><td><?php echo implode('</td><td>', $this->get_row($EM_Booking)); ?></td><?php
440
+ }
441
+ ?>
442
+ </tr>
443
+ <?php
444
+ }
445
+ ?>
446
+ </tbody>
447
+ <?php else: ?>
448
+ <tbody>
449
+ <tr><td scope="row" colspan="<?php echo count($this->cols); ?>"><?php _e('No bookings.', 'dbem'); ?></td></tr>
450
+ </tbody>
451
+ <?php endif; ?>
452
+ </table>
453
+ </div>
454
+ <?php if( !empty($bookings_nav) && $this->bookings_count >= $this->limit ) : ?>
455
+ <div class='tablenav'>
456
+ <?php echo $bookings_nav; ?>
457
+ <div class="clear"></div>
458
+ </div>
459
+ <?php endif; ?>
460
+ </form>
461
+ </div>
462
+ <?php
463
+ }
464
+
465
+ function get_headers($csv = false){
466
+ $headers = array();
467
+ foreach($this->cols as $col){
468
+ if( $col == 'actions' ){
469
+ if( !$csv ) $headers[$col] = '&nbsp;';
470
+ }elseif(array_key_exists($col, $this->cols_template)){
471
+ /* for later - col ordering!
472
+ if($this->orderby == $col){
473
+ if($this->order == 'ASC'){
474
+ $headers[] = '<a class="em-bookings-orderby" href="#'.$col.'">'.$this->cols_template[$col].' (^)</a>';
475
+ }else{
476
+ $headers[] = '<a class="em-bookings-orderby" href="#'.$col.'">'.$this->cols_template[$col].' (d)</a>';
477
+ }
478
+ }else{
479
+ $headers[] = '<a class="em-bookings-orderby" href="#'.$col.'">'.$this->cols_template[$col].'</a>';
480
+ }
481
+ */
482
+ $headers[$col] = $this->cols_template[$col];
483
+ }
484
+ }
485
+ return $headers;
486
+ }
487
+
488
+ function get_table(){
489
+
490
+ }
491
+
492
+ /**
493
+ * @param Object $object
494
+ * @return array()
495
+ */
496
+ function get_row( $object, $csv = false ){
497
+ /* @var $EM_Ticket EM_Ticket */
498
+ /* @var $EM_Ticket_Booking EM_Ticket_Booking */
499
+ /* @var $EM_Booking EM_Booking */
500
+ if( get_class($object) == 'EM_Ticket_Booking' ){
501
+ $EM_Ticket_Booking = $object;
502
+ $EM_Ticket = $EM_Ticket_Booking->get_ticket();
503
+ $EM_Booking = $EM_Ticket_Booking->get_booking();
504
+ }else{
505
+ $EM_Booking = $object;
506
+ }
507
+ $cols = array();
508
+ foreach($this->cols as $col){
509
+ //is col a user col or else?
510
+ //TODO fix urls so this works in all pages in front as well
511
+ if( $col == 'user_email' ){
512
+ $cols[] = $EM_Booking->get_person()->user_email;
513
+ }elseif($col == 'dbem_phone'){
514
+ $cols[] = $EM_Booking->get_person()->phone;
515
+ }elseif($col == 'user_name'){
516
+ if( $csv ){
517
+ $cols[] = $EM_Booking->get_person()->get_name();
518
+ }else{
519
+ $cols[] = '<a href="'.add_query_arg(array('person_id'=>$EM_Booking->person_id, 'event_id'=>null), $EM_Booking->get_event()->get_bookings_url()).'">'. $EM_Booking->person->get_name() .'</a>';
520
+ }
521
+ }elseif($col == 'event_name'){
522
+ if( $csv ){
523
+ $cols[] = $EM_Booking->get_event()->event_name;
524
+ }else{
525
+ $cols[] = '<a href="'.$EM_Booking->get_event()->get_bookings_url().'">'. $this->events[$EM_Booking->event_id]->name .'</a>';
526
+ }
527
+ }elseif($col == 'event_date'){
528
+ $cols[] = $EM_Booking->get_event()->output('#_EVENTDATES');
529
+ }elseif($col == 'event_time'){
530
+ $cols[] = $EM_Booking->get_event()->output('#_EVENTTIMES');
531
+ }elseif($col == 'booking_price'){
532
+ $cols[] = ($this->show_tickets && !empty($EM_Ticket)) ? $EM_Ticket_Booking->get_price(false,true,true):$EM_Booking->get_price(false,true,true);
533
+ }elseif($col == 'booking_status'){
534
+ $cols[] = $EM_Booking->get_status(true);
535
+ }elseif($col == 'booking_date'){
536
+ $cols[] = date_i18n(get_option('dbem_date_format').' '. get_option('dbem_time_format'), $EM_Booking->timestamp);
537
+ }elseif($col == 'actions' ){
538
+ if( !$csv ) $cols[] = implode(' | ', $this->get_booking_actions($EM_Booking));
539
+ }elseif( $col == 'booking_spaces' ){
540
+ $cols[] = ($this->show_tickets && !empty($EM_Ticket)) ? $EM_Ticket_Booking->get_spaces() : $EM_Booking->get_spaces();
541
+ }elseif( $col == 'booking_id' ){
542
+ $cols[] = $EM_Booking->booking_id;
543
+ }elseif( $col == 'ticket_name' && $this->show_tickets && !empty($EM_Ticket) ){
544
+ $cols[] = $EM_Ticket->$col;
545
+ }elseif( $col == 'ticket_description' && $this->show_tickets && !empty($EM_Ticket) ){
546
+ $cols[] = $EM_Ticket->$col;
547
+ }elseif( $col == 'ticket_price' && $this->show_tickets && !empty($EM_Ticket) ){
548
+ $cols[] = $EM_Ticket->get_price(true);
549
+ }elseif( $col == 'ticket_id' && $this->show_tickets && !empty($EM_Ticket) ){
550
+ $cols[] = $EM_Ticket->ticket_id;
551
+ }else{
552
+ $val = apply_filters('em_bookings_table_rows_col_'.$col, '', $EM_Booking, $this, $csv);
553
+ $cols[] = apply_filters('em_bookings_table_rows_col', $val, $col, $EM_Booking, $this, $csv);
554
+ }
555
+ }
556
+ return $cols;
557
+ }
558
+
559
+ function get_row_csv($EM_Booking){
560
+ return $this->get_row($EM_Booking, true);
561
+ }
562
+
563
+ /**
564
+ * @param EM_Booking $EM_Booking
565
+ * @return mixed
566
+ */
567
+ function get_booking_actions($EM_Booking){
568
+ $booking_actions = array();
569
+ switch($EM_Booking->booking_status){
570
+ case 0:
571
+ if( get_option('dbem_bookings_approval') ){
572
+ $booking_actions = array(
573
+ 'approve' => '<a class="em-bookings-approve" href="'.em_add_get_params($_SERVER['REQUEST_URI'], array('action'=>'bookings_approve', 'booking_id'=>$EM_Booking->booking_id)).'">'.__('Approve','dbem').'</a>',
574
+ 'reject' => '<a class="em-bookings-reject" href="'.em_add_get_params($_SERVER['REQUEST_URI'], array('action'=>'bookings_reject', 'booking_id'=>$EM_Booking->booking_id)).'">'.__('Reject','dbem').'</a>',
575
+ 'delete' => '<span class="trash"><a class="em-bookings-delete" href="'.em_add_get_params($_SERVER['REQUEST_URI'], array('action'=>'bookings_delete', 'booking_id'=>$EM_Booking->booking_id)).'">'.__('Delete','dbem').'</a></span>',
576
+ 'edit' => '<a class="em-bookings-edit" href="'.em_add_get_params($EM_Booking->get_event()->get_bookings_url(), array('booking_id'=>$EM_Booking->booking_id, 'em_ajax'=>null, 'em_obj'=>null)).'">'.__('Edit/View','dbem').'</a>',
577
+ );
578
+ break;
579
+ }//if approvals are off, treat as a 1
580
+ case 1:
581
+ $booking_actions = array(
582
+ 'unapprove' => '<a class="em-bookings-unapprove" href="'.em_add_get_params($_SERVER['REQUEST_URI'], array('action'=>'bookings_unapprove', 'booking_id'=>$EM_Booking->booking_id)).'">'.__('Unpprove','dbem').'</a>',
583
+ 'reject' => '<a class="em-bookings-reject" href="'.em_add_get_params($_SERVER['REQUEST_URI'], array('action'=>'bookings_reject', 'booking_id'=>$EM_Booking->booking_id)).'">'.__('Reject','dbem').'</a>',
584
+ 'delete' => '<span class="trash"><a class="em-bookings-delete" href="'.em_add_get_params($_SERVER['REQUEST_URI'], array('action'=>'bookings_delete', 'booking_id'=>$EM_Booking->booking_id)).'">'.__('Delete','dbem').'</a></span>',
585
+ 'edit' => '<a class="em-bookings-edit" href="'.em_add_get_params($EM_Booking->get_event()->get_bookings_url(), array('booking_id'=>$EM_Booking->booking_id, 'em_ajax'=>null, 'em_obj'=>null)).'">'.__('Edit/View','dbem').'</a>',
586
+ );
587
+ break;
588
+ case 2:
589
+ $booking_actions = array(
590
+ 'unapprove' => '<a class="em-bookings-unapprove" href="'.em_add_get_params($_SERVER['REQUEST_URI'], array('action'=>'bookings_unapprove', 'booking_id'=>$EM_Booking->booking_id)).'">'.__('Unpprove','dbem').'</a>',
591
+ 'approve' => '<a class="em-bookings-approve" href="'.em_add_get_params($_SERVER['REQUEST_URI'], array('action'=>'bookings_approve', 'booking_id'=>$EM_Booking->booking_id)).'">'.__('Approve','dbem').'</a>',
592
+ 'delete' => '<span class="trash"><a class="em-bookings-delete" href="'.em_add_get_params($_SERVER['REQUEST_URI'], array('action'=>'bookings_delete', 'booking_id'=>$EM_Booking->booking_id)).'">'.__('Delete','dbem').'</a></span>',
593
+ 'edit' => '<a class="em-bookings-edit" href="'.em_add_get_params($EM_Booking->get_event()->get_bookings_url(), array('booking_id'=>$EM_Booking->booking_id, 'em_ajax'=>null, 'em_obj'=>null)).'">'.__('Edit/View','dbem').'</a>',
594
+ );
595
+ break;
596
+ case 3:
597
+ $booking_actions = array(
598
+ 'unapprove' => '<a class="em-bookings-unapprove" href="'.em_add_get_params($_SERVER['REQUEST_URI'], array('action'=>'bookings_unapprove', 'booking_id'=>$EM_Booking->booking_id)).'">'.__('Unpprove','dbem').'</a>',
599
+ 'approve' => '<a class="em-bookings-approve" href="'.em_add_get_params($_SERVER['REQUEST_URI'], array('action'=>'bookings_approve', 'booking_id'=>$EM_Booking->booking_id)).'">'.__('Approve','dbem').'</a>',
600
+ 'delete' => '<span class="trash"><a class="em-bookings-delete" href="'.em_add_get_params($_SERVER['REQUEST_URI'], array('action'=>'bookings_delete', 'booking_id'=>$EM_Booking->booking_id)).'">'.__('Delete','dbem').'</a></span>',
601
+ 'edit' => '<a class="em-bookings-edit" href="'.em_add_get_params($EM_Booking->get_event()->get_bookings_url(), array('booking_id'=>$EM_Booking->booking_id, 'em_ajax'=>null, 'em_obj'=>null)).'">'.__('Edit/View','dbem').'</a>',
602
+ );
603
+ break;
604
+ case 4:
605
+ $booking_actions = apply_filters('em_bookings_table_booking_actions_4',array(
606
+ 'delete' => '<span class="trash"><a class="em-bookings-delete" href="'.em_add_get_params($_SERVER['REQUEST_URI'], array('action'=>'bookings_delete', 'booking_id'=>$EM_Booking->booking_id)).'">'.__('Delete','dbem').'</a></span>',
607
+ ), $EM_Booking);
608
+ break;
609
+ case 5:
610
+ $booking_actions = apply_filters('em_bookings_table_booking_actions_5',array(
611
+ 'delete' => '<span class="trash"><a class="em-bookings-delete" href="'.em_add_get_params($_SERVER['REQUEST_URI'], array('action'=>'bookings_delete', 'booking_id'=>$EM_Booking->booking_id)).'">'.__('Delete','dbem').'</a></span>',
612
+ ), $EM_Booking);
613
+ break;
614
+ default:
615
+ $booking_actions = apply_filters('em_bookings_table_booking_actions_'.$EM_Booking->booking_status ,array(), $EM_Booking);
616
+ break;
617
+
618
+ }
619
+ if( !get_option('dbem_bookings_approval') ) unset($booking_actions['unapprove']);
620
+ return apply_filters('em_bookings_table_cols_col_action', $booking_actions, $EM_Booking);
621
+ }
622
+ }
623
+ ?>
classes/em-bookings.php CHANGED
@@ -1,488 +1,621 @@
1
- <?php
2
- /**
3
- * Deals with the booking info for an event
4
- * @author marcus
5
- *
6
- */
7
- class EM_Bookings extends EM_Object{
8
-
9
- /**
10
- * Array of EM_Booking objects for a specific event
11
- * @var array
12
- */
13
- var $bookings = array();
14
- /**
15
- * Event ID
16
- * @var int
17
- */
18
- var $event_id;
19
- /**
20
- * Number of seats for this event
21
- * @var int
22
- */
23
- var $seats;
24
-
25
- var $feedback_message = "";
26
- var $errors = array();
27
-
28
- /**
29
- * Creates an EM_Bookings instance,
30
- * @param EM_Event $event
31
- * @return null
32
- */
33
- function EM_Bookings( $event = false ){
34
- if( is_object($event) && get_class($event) == "EM_Event" ){ //Creates a blank bookings object if needed
35
- global $wpdb;
36
- $this->event_id = $event->id;
37
- $this->seats = $event->seats;
38
- $sql = "SELECT * FROM ". $wpdb->prefix . EM_BOOKINGS_TABLE ." b, ". $wpdb->prefix . EM_PEOPLE_TABLE ." p WHERE event_id ='{$this->event_id}' AND p.person_id=b.person_id";
39
- $bookings = $wpdb->get_results($sql, ARRAY_A);
40
- foreach ($bookings as $booking){
41
- $this->bookings[] = new EM_Booking($booking);
42
- }
43
- }
44
- }
45
-
46
- /**
47
- * Add a booking into this event (or add seats if person already booked this), checking that there's enough space for the event
48
- * @param $EM_Booking
49
- * @return boolean
50
- */
51
- function add( $EM_Booking ){
52
- global $wpdb,$EM_Mailer;
53
- if ( $this->get_available_seats() >= $EM_Booking->seats ) {
54
- $EM_Booking->event_id = $this->event_id;
55
- // checking whether the booker has already booked places
56
- $previous_booking = $this->find_previous_booking( $EM_Booking );
57
- $email = false;
58
- if ( is_object($previous_booking) ) {
59
- //Previously booked, so we add these seats to the booking
60
- $new_seats = $EM_Booking->seats;
61
- $EM_Booking = $previous_booking;
62
- $EM_Booking->seats += $new_seats;
63
- $result = $EM_Booking->save();
64
- if($result){
65
- //remove old booking
66
- foreach($this->bookings as $key=>$booking){
67
- if($booking->id == $EM_Booking->id){ unset($this->bookings[$key]); }
68
- }
69
- $this->bookings[] = $EM_Booking;
70
- $email = $EM_Booking->email();
71
- }
72
- } else {
73
- //New booking, so let's save the booking
74
- $result = $EM_Booking->save();
75
- if($result){
76
- $this->bookings[] = $EM_Booking;
77
- $email = $EM_Booking->email();
78
- }
79
- }
80
- if($result){
81
- //Success
82
- if( get_option('dbem_bookings_approval') == 1 ){
83
- $this->feedback_message = __('Booking successful, pending confirmation (you will also receive an email once confirmed).', 'dbem');
84
- }else{
85
- $this->feedback_message = __('Booking successful.', 'dbem');
86
- }
87
- if(!$email){
88
- $this->feedback_message .= ' '.__('However, there were some problems whilst sending confirmation emails to you and/or the event contact person. You may want to contact them directly and letting them know of this error.', 'dbem');
89
- if( current_user_can('activate_plugins') ){
90
- if( is_array($this->errors) && count($this->errors) > 0 ){
91
- $this->feedback_message .= '<br/><strong>Errors:</strong> (only admins see this message)<br/><ul><li>'. implode('</li><li>', $EM_Mailer->errors).'</li></ul>';
92
- }else{
93
- $this->feedback_message .= '<br/><strong>No errors returned by mailer</strong> (only admins see this message)';
94
- }
95
- }
96
- }
97
- return true;
98
- }else{
99
- //Failure
100
- $this->errors[] = "<strong>".__('Booking could not be created','dbem').":</strong><br />". implode('<br />', $EM_Booking->errors);
101
- }
102
- } else {
103
- $this->errors[] = __('Booking cannot be made, not enough seats available!', 'dbem');
104
- return false;
105
- }
106
- }
107
-
108
- /**
109
- * Delete bookings on this id
110
- * @return boolean
111
- */
112
- function delete(){
113
- global $wpdb;
114
- $result = $wpdb->query("DELETE FROM ".$wpdb->prefix.EM_BOOKINGS_TABLE." WHERE event_id='{$this->event_id}'");
115
- return ($result);
116
- }
117
-
118
-
119
- /**
120
- * Will approve all supplied booking ids, which must be in the form of a numeric array or a single number.
121
- * @param array|int $booking_ids
122
- * @return boolean
123
- */
124
- function approve( $booking_ids ){
125
- $this->set_status(1, $booking_ids);
126
- return false;
127
- }
128
-
129
- /**
130
- * Will reject all supplied booking ids, which must be in the form of a numeric array or a single number.
131
- * @param array|int $booking_ids
132
- * @return boolean
133
- */
134
- function reject( $booking_ids ){
135
- return $this->set_status(2, $booking_ids);
136
- }
137
-
138
- /**
139
- * Will unapprove all supplied booking ids, which must be in the form of a numeric array or a single number.
140
- * @param array|int $booking_ids
141
- * @return boolean
142
- */
143
- function unapprove( $booking_ids ){
144
- return $this->set_status(0, $booking_ids);
145
- }
146
-
147
- /**
148
- * @param int $status
149
- * @param array|int $booking_ids
150
- * @return bool
151
- */
152
- function set_status($status, $booking_ids){
153
- //FIXME there is a vulnerability where any user can approve/reject bookings if they know the ID
154
- if( EM_Object::array_is_numeric($booking_ids) ){
155
- //Get all the bookings
156
- $results = array();
157
- $mails = array();
158
- foreach( $booking_ids as $booking_id ){
159
- $EM_Booking = new EM_Booking($booking_id);
160
- $results[] = $EM_Booking->set_status($status);
161
- }
162
- if( !in_array('false',$results) ){
163
- $this->feedback_message = __('Bookings %s. Mails Sent.', 'dbem');
164
- return true;
165
- }else{
166
- //TODO Better error handling needed if some bookings fail approval/failure
167
- $this->feedback_message = __('An error occurred.', 'dbem');
168
- return false;
169
- }
170
- }elseif( is_numeric($booking_ids) || is_object($booking_ids) ){
171
- $EM_Booking = ( is_object($booking_ids) && get_class($booking_ids) == 'EM_Booking') ? $booking_ids : new EM_Booking($booking_ids);
172
- $result = $EM_Booking->set_status($status);
173
- $this->feedback_message = $EM_Booking->feedback_message;
174
- return $result;
175
- }
176
- return false;
177
- }
178
-
179
- /**
180
- * Returns number of available seats for this event. If approval of bookings is on, will include pending bookings depending on em option.
181
- * @return int
182
- */
183
- function get_available_seats(){
184
- $booked_seats = 0;
185
- if( get_option('dbem_bookings_approval_reserved') == 1 ){
186
- return $this->seats - $this->get_booked_seats() - $this->get_pending_seats();
187
- }else{
188
- return $this->seats - $this->get_booked_seats();
189
- }
190
- }
191
-
192
- /**
193
- * Returns number of booked seats for this event. If approval of bookings is on, will return number of booked confirmed seats.
194
- * @return int
195
- */
196
- function get_booked_seats(){
197
- $booked_seats = 0;
198
- foreach ( $this->bookings as $booking ){
199
- if( $booking->status != 3 && (get_option('dbem_bookings_approval') == 0 || $booking->status == 1) ){
200
- $booked_seats += $booking->seats;
201
- }
202
- }
203
- return $booked_seats;
204
- }
205
-
206
- /**
207
- * Gets number of pending seats awaiting approval. Will return 0 if booking approval is not enabled.
208
- * @return int
209
- */
210
- function get_pending_seats(){
211
- if( get_option('dbem_bookings_approval') == 0 ){
212
- return 0;
213
- }
214
- $pending = 0;
215
- foreach ( $this->bookings as $booking ){
216
- if($booking->status == 0){
217
- $pending += $booking->seats;
218
- }
219
- }
220
- return $pending;
221
- }
222
-
223
- /**
224
- * Gets number of bookings (not seats). If booking approval is enabled, only the number of approved bookings will be shown.
225
- * @return array EM_Booking
226
- */
227
- function get_bookings(){
228
- $confirmed = array();
229
- foreach ( $this->bookings as $booking ){
230
- if( $booking->status == 1 || (get_option('dbem_bookings_approval') == 0 && $booking->status < 2) ){
231
- $confirmed[] = $booking;
232
- }
233
- }
234
- return $confirmed;
235
- }
236
-
237
- /**
238
- * Get pending bookings. If booking approval is disabled, will return no bookings.
239
- * @return array EM_Booking
240
- */
241
- function get_pending_bookings(){
242
- if( get_option('dbem_bookings_approval') == 0 ){
243
- return array();
244
- }
245
- $pending = array();
246
- foreach ( $this->bookings as $booking ){
247
- if($booking->status == 0){
248
- $pending[] = $booking;
249
- }
250
- }
251
- return $pending;
252
- }
253
-
254
- /**
255
- * Get rejected bookings.
256
- * @return array EM_Booking
257
- */
258
- function get_rejected_bookings(){
259
- $pending = array();
260
- foreach ( $this->bookings as $booking ){
261
- if($booking->status == 2){
262
- $pending[] = $booking;
263
- }
264
- }
265
- return $pending;
266
- }
267
-
268
- /**
269
- * Get cancelled bookings.
270
- * @return array EM_Booking
271
- */
272
- function get_cancelled_bookings(){
273
- $pending = array();
274
- foreach ( $this->bookings as $booking ){
275
- if($booking->status == 3){
276
- $pending[] = $booking;
277
- }
278
- }
279
- return $pending;
280
- }
281
-
282
- /**
283
- * Checks if a person with similar details has booked for this before
284
- * @param $person_id
285
- * @return EM_Booking
286
- */
287
- function find_previous_booking($EM_Booking){
288
- //First see if we have a similar person on record that's making this booking
289
- $EM_Booking->person->load_similar();
290
- //If person exists on record, see if they've booked this event before, if so return the booking.
291
- if( is_numeric($EM_Booking->person->id) && $EM_Booking->person->id > 0 ){
292
- $EM_Booking->person_id = $EM_Booking->person->id;
293
- foreach ($this->bookings as $booking){
294
- if( $booking->person_id == $EM_Booking->person->id ){
295
- return $booking;
296
- }
297
- }
298
- }
299
- return false;
300
- }
301
-
302
-
303
- /**
304
- * Get all pending bookings for this event
305
- */
306
- function get_pending(){
307
- $pending = array();
308
- foreach($this->bookings as $booking){
309
- if($booking->status == 0){
310
- $pending[] = $booking;
311
- }
312
- }
313
- return $pending;
314
- }
315
-
316
- /**
317
- * Gets the pending number of bookings as a raw associative array.
318
- * @return array
319
- */
320
- function get( $args = array() ){
321
- global $wpdb,$current_user;
322
- $bookings_table = $wpdb->prefix . EM_BOOKINGS_TABLE;
323
- $events_table = $wpdb->prefix . EM_EVENTS_TABLE;
324
- $people_table = $wpdb->prefix . EM_PEOPLE_TABLE;
325
- $locations_table = $wpdb->prefix . EM_LOCATIONS_TABLE;
326
-
327
- //Quick version, we can accept an array of IDs, which is easy to retrieve
328
- if( self::array_is_numeric($args) ){ //Array of numbers, assume they are event IDs to retreive
329
- //We can just get all the events here and return them
330
- $sql = "
331
- SELECT * FROM $bookings_table b
332
- LEFT JOIN $events_table e ON e.event_id=b.event_id
333
- LEFT JOIN $people_table p ON p.person_id=b.person_id
334
- WHERE booking_id".implode(" OR booking_id=", $args);
335
- $results = $wpdb->get_results(apply_filters('em_bookings_get_sql',$sql),ARRAY_A);
336
- $bookings = array();
337
- foreach($results as $result){
338
- $bookings[$result['event_id']] = new EM_Event($result);
339
- }
340
- return $bookings; //We return all the events matched as an EM_Event array.
341
- }
342
-
343
- //We assume it's either an empty array or array of search arguments to merge with defaults
344
- $args = self::get_default_search($args);
345
- $limit = ( $args['limit'] && is_numeric($args['limit'])) ? "LIMIT {$args['limit']}" : '';
346
- $offset = ( $limit != "" && is_numeric($args['offset']) ) ? "OFFSET {$args['offset']}" : '';
347
-
348
- //Get the default conditions
349
- $conditions = self::build_sql_conditions($args);
350
- //Put it all together
351
- $where = ( count($conditions) > 0 ) ? " WHERE " . implode ( " AND ", $conditions ):'';
352
-
353
- //Get ordering instructions
354
- $EM_Booking = new EM_Booking();
355
- $accepted_fields = $EM_Booking->get_fields(true);
356
- $orderby = self::build_sql_orderby($args, $accepted_fields);
357
- //Now, build orderby sql
358
- $orderby_sql = ( count($orderby) > 0 ) ? 'ORDER BY '. implode(', ', $orderby) : '';
359
-
360
- //Create the SQL statement and execute
361
- $sql = "
362
- SELECT * FROM $bookings_table
363
- LEFT JOIN $events_table ON {$events_table}.event_id={$bookings_table}.event_id
364
- LEFT JOIN $people_table ON {$people_table}.person_id={$bookings_table}.person_id
365
- LEFT JOIN $locations_table ON {$locations_table}.location_id={$events_table}.location_id
366
- $where
367
- $orderby_sql
368
- $limit $offset
369
- ";
370
-
371
- $results = $wpdb->get_results( apply_filters('em_events_get_sql',$sql, $args), ARRAY_A);
372
-
373
- //If we want results directly in an array, why not have a shortcut here?
374
- if( $args['array'] == true ){
375
- return $results;
376
- }
377
-
378
- //Make returned results EM_Booking objects
379
- $results = (is_array($results)) ? $results:array();
380
- $bookings = array();
381
- foreach ( $results as $booking ){
382
- $bookings[] = new EM_Booking($booking);
383
- }
384
-
385
- return apply_filters('em_bookings_get', $bookings);
386
- }
387
-
388
-
389
- //List of patients in the patient database, that a user can choose and go on to edit any previous treatment data, or add a new admission.
390
- function export_csv() {
391
- global $EM_Event;
392
- if($EM_Event->id != $this->event_id ){
393
- $event = new EM_Event($this->event_id);
394
- $event_name = $event->name;
395
- }else{
396
- $event_name = $EM_Event->name;
397
- }
398
- // The name of the file on the user's pc
399
- $file_name = sanitize_title($event_name). "-bookings.csv";
400
-
401
- header("Content-Type: application/octet-stream");
402
- header("Content-Disposition: Attachment; filename=$file_name");
403
-
404
- //Headers
405
- $labels = array(
406
- 'ID',
407
- 'Name',
408
- 'Email',
409
- 'Phone',
410
- 'Date',
411
- 'Status',
412
- 'Spaces',
413
- 'Comment'
414
- );
415
- $file = sprintf(__('Booking details for "%s" as of %s','dbem'),$event_name, date_i18n('D d M Y h:i', current_time('timestamp'))) . "\n";
416
- $file = '"'. strtolower(implode('","', $labels)). '"' . "\n";
417
-
418
- //Rows
419
- foreach( $this->bookings as $EM_Booking ) {
420
- $row = array(
421
- $EM_Booking->id,
422
- $EM_Booking->person->name,
423
- $EM_Booking->person->email,
424
- $EM_Booking->person->phone,
425
- date('Y-m-d h:i', $EM_Booking->timestamp),
426
- $EM_Booking->seats,
427
- $EM_Booking->get_status(),
428
- $EM_Booking->comment
429
- );
430
- //Display all values
431
- foreach($row as $value){
432
- $value = str_replace('"', '""', $value);
433
- $value = str_replace("=", "", $value);
434
- $file .= '"' . preg_replace("/\n\r|\r\n|\n|\r/", ". ", $value) . '",';
435
- }
436
- $file .= "\n";
437
- }
438
-
439
- // $file holds the data
440
- echo $file;
441
- $file = "";
442
- }
443
-
444
- /* Overrides EM_Object method to apply a filter to result
445
- * @see wp-content/plugins/events-manager/classes/EM_Object#build_sql_conditions()
446
- */
447
- function build_sql_conditions( $args = array() ){
448
- $conditions = apply_filters( 'em_bookings_build_sql_conditions', parent::build_sql_conditions($args), $args );
449
- if( is_numeric($args['status']) ){
450
- $conditions['status'] = 'booking_status='.$args['status'];
451
- }
452
- return apply_filters('em_bookings_build_sql_conditions', $conditions, $args);
453
- }
454
-
455
- /* Overrides EM_Object method to apply a filter to result
456
- * @see wp-content/plugins/events-manager/classes/EM_Object#build_sql_orderby()
457
- */
458
- function build_sql_orderby( $args, $accepted_fields, $default_order = 'ASC' ){
459
- return apply_filters( 'em_bookings_build_sql_orderby', parent::build_sql_orderby($args, $accepted_fields, get_option('dbem_events_default_order')), $args, $accepted_fields, $default_order );
460
- }
461
-
462
- /*
463
- * Adds custom Events search defaults
464
- * @param array $array
465
- * @return array
466
- * @uses EM_Object#get_default_search()
467
- */
468
- function get_default_search( $array = array() ){
469
- $defaults = array(
470
- 'status' => false,
471
- 'person' => true //to add later, search by person's bookings...
472
- );
473
- if( true || is_admin() ){
474
- //figure out default owning permissions
475
- switch( get_option('dbem_permissions_events') ){
476
- case 0:
477
- $defaults['owner'] = get_current_user_id();
478
- break;
479
- case 1:
480
- $defaults['owner'] = false;
481
- break;
482
- }
483
- $defaults['owner'] = ( em_verify_admin() ) ? false:$defaults['owner'];
484
- }
485
- return apply_filters('em_bookings_get_default_search', parent::get_default_search($defaults,$array), $array, $defaults);
486
- }
487
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
488
  ?>
1
+ <?php
2
+ /**
3
+ * Deals with the booking info for an event
4
+ * @author marcus
5
+ *
6
+ */
7
+ class EM_Bookings extends EM_Object implements Iterator{
8
+
9
+ /**
10
+ * Array of EM_Booking objects for a specific event
11
+ * @var array
12
+ */
13
+ var $bookings = array();
14
+ /**
15
+ * @var EM_Tickets
16
+ */
17
+ var $tickets;
18
+ /**
19
+ * @var int
20
+ */
21
+ var $event_id;
22
+ /**
23
+ * How many spaces this event has
24
+ * @var int
25
+ */
26
+ var $spaces;
27
+
28
+ /**
29
+ * Creates an EM_Bookings instance, currently accepts an EM_Event object (gets all bookings for that event) or array of any EM_Booking objects, which can be manipulated in bulk with helper functions.
30
+ * @param EM_Event $event
31
+ * @return null
32
+ */
33
+ function EM_Bookings( $data = false ){
34
+ if( is_object($data) && get_class($data) == "EM_Event" ){ //Creates a blank bookings object if needed
35
+ global $wpdb;
36
+ $this->event_id = $data->event_id;
37
+ $sql = "SELECT * FROM ". EM_BOOKINGS_TABLE ." WHERE event_id ='{$this->event_id}' ORDER BY booking_date";
38
+ $bookings = $wpdb->get_results($sql, ARRAY_A);
39
+ foreach ($bookings as $booking){
40
+ $this->bookings[] = new EM_Booking($booking);
41
+ }
42
+ $this->spaces = $this->get_spaces();
43
+ }elseif( is_array($data) ){
44
+ foreach( $data as $EM_Booking ){
45
+ if( get_class($EM_Booking) == 'EM_Booking'){
46
+ $this->bookings[] = $EM_Booking;
47
+ }
48
+ }
49
+ }
50
+ }
51
+
52
+ /**
53
+ * Add a booking into this event (or add spaces if person already booked this), checking that there's enough space for the event
54
+ * @param EM_Booking $EM_Booking
55
+ * @return boolean
56
+ */
57
+ function add( $EM_Booking ){
58
+ global $wpdb,$EM_Mailer;
59
+ if ( $this->get_available_spaces() >= $EM_Booking->get_spaces(true) ) {
60
+ //Save the booking
61
+ $email = false;
62
+ //set status depending on approval settings
63
+ if( empty($EM_Booking->booking_status) ){ //if status is not set, give 1 or 0 depending on approval settings
64
+ $EM_Booking->booking_status = get_option('dbem_bookings_approval') ? 0:1;
65
+ }
66
+ $result = $EM_Booking->save(false);
67
+ if($result){
68
+ //Success
69
+ $this->bookings[] = $EM_Booking;
70
+ $email = $EM_Booking->email();
71
+ if( get_option('dbem_bookings_approval') == 1 && $EM_Booking->booking_status == 0){
72
+ $this->feedback_message = get_option('dbem_booking_feedback_pending');
73
+ }else{
74
+ $this->feedback_message = get_option('dbem_booking_feedback');
75
+ }
76
+ if(!$email){
77
+ $EM_Booking->email_not_sent = true;
78
+ $this->feedback_message .= ' '.get_option('dbem_booking_feedback_nomail');
79
+ if( current_user_can('activate_plugins') ){
80
+ if( count($EM_Booking->get_errors()) > 0 ){
81
+ $this->feedback_message .= '<br/><strong>Errors:</strong> (only admins see this message)<br/><ul><li>'. implode('</li><li>', $EM_Booking->get_errors()).'</li></ul>';
82
+ }else{
83
+ $this->feedback_message .= '<br/><strong>No errors returned by mailer</strong> (only admins see this message)';
84
+ }
85
+ }
86
+ }
87
+ return apply_filters('em_bookings_add', true, $EM_Booking);
88
+ }else{
89
+ //Failure
90
+ $this->errors[] = "<strong>".get_option('dbem_booking_feedback_error')."</strong><br />". implode('<br />', $EM_Booking->errors);
91
+ }
92
+ } else {
93
+ $this->add_error(get_option('dbem_booking_feedback_full'));
94
+ }
95
+ return apply_filters('em_bookings_add', false, $EM_Booking);
96
+ }
97
+
98
+ /**
99
+ * Get POST data and create a booking for each ticket requested. If successful, a booking object is returned, false if not.
100
+ * @return false|object
101
+ */
102
+ function add_from_post(){
103
+ $EM_Booking = new EM_booking();
104
+ $result = $EM_Booking->get_post();
105
+ if($result){
106
+ $result = $this->add($EM_Booking);
107
+ if($result){
108
+ $result = $EM_Booking;
109
+ }
110
+ $this->feedback_message = sprintf(__('%s created.','dbem'),__('Booking','dbem'));
111
+ }else{
112
+ $this->errors = array_merge($this->errors, $EM_Booking->errors);
113
+ }
114
+ return apply_filters('em_bookings_add_from_post',$result,$EM_Booking,$this);
115
+ }
116
+
117
+ /**
118
+ * Smart event locator, saves a database read if possible. Note that if an event doesn't exist, a blank object will be created to prevent duplicates.
119
+ */
120
+ function get_event(){
121
+ global $EM_Event;
122
+ if( is_object($EM_Event) && $EM_Event->event_id == $this->event_id ){
123
+ return $EM_Event;
124
+ }else{
125
+ if( is_numeric($this->event_id) && $this->event_id > 0 ){
126
+ return new EM_Event($this->event_id, 'event_id');
127
+ }elseif( count($this->bookings) > 0 ){
128
+ foreach($this->bookings as $EM_Booking){
129
+ /* @var $EM_Booking EM_Booking */
130
+ return new EM_Event($EM_Booking->event_id, 'event_id');
131
+ }
132
+ }
133
+ }
134
+ return new EM_Event($this->event_id);
135
+ }
136
+
137
+ /**
138
+ * Retrieve and save the bookings belonging to instance. If called again will return cached version, set $force_reload to true to create a new EM_Tickets object.
139
+ * @param boolean $force_reload
140
+ * @return EM_Tickets
141
+ */
142
+ function get_tickets( $force_reload = false ){
143
+ if( !is_object($this->tickets) || $force_reload ){
144
+ $this->tickets = new EM_Tickets($this->event_id);
145
+ }else{
146
+ $this->tickets->event_id = $this->event_id;
147
+ }
148
+ return apply_filters('em_bookings_get_tickets', $this->tickets, $this);
149
+ }
150
+
151
+ /**
152
+ * Returns EM_Tickets object with available tickets
153
+ * @return EM_Tickets
154
+ */
155
+ function get_available_tickets(){
156
+ $tickets = array();
157
+ foreach ($this->get_tickets() as $EM_Ticket){
158
+ /* @var $EM_Ticket EM_Ticket */
159
+ if( $EM_Ticket->is_available() ){
160
+ //within time range
161
+ if( $EM_Ticket->get_available_spaces() > 0 ){
162
+ $tickets[] = $EM_Ticket;
163
+ }
164
+ }
165
+ }
166
+ $EM_Tickets = new EM_Tickets($tickets);
167
+ return apply_filters('em_bookings_get_tickets', $EM_Tickets, $this);
168
+ }
169
+
170
+ function get_user_list(){
171
+ $users = array();
172
+ foreach( $this->get_bookings()->bookings as $EM_Booking ){
173
+ $users[$EM_Booking->person->ID] = $EM_Booking->person;
174
+ }
175
+ return $users;
176
+ }
177
+
178
+ /**
179
+ * does this ticket exist?
180
+ * @return bool
181
+ */
182
+ function ticket_exists($ticket_id){
183
+ $EM_Tickets = $this->get_tickets();
184
+ foreach( $EM_Tickets->tickets as $EM_Ticket){
185
+ if($EM_Ticket->ticket_id == $ticket_id){
186
+ return apply_filters('em_bookings_ticket_exists',true, $EM_Ticket, $this);
187
+ }
188
+ }
189
+ return apply_filters('em_bookings_ticket_exists',false, false,$this);
190
+ }
191
+
192
+ function is_open(){
193
+ //TODO extend booking options
194
+ $return = false;
195
+ $EM_Event = $this->get_event();
196
+ if( !empty($EM_Event->event_rsvp_date) && strtotime($EM_Event->event_rsvp_date) > current_time('timestamp') ){
197
+ $return = true;
198
+ }elseif( $EM_Event->start > current_time('timestamp') ){
199
+ $return = true;
200
+ }
201
+ if( count($this->get_available_tickets()->tickets) == 0){
202
+ $return = false;
203
+ }
204
+ return apply_filters('em_bookings_is_open', $return, $this);
205
+ }
206
+
207
+ /**
208
+ * Delete bookings on this id
209
+ * @return boolean
210
+ */
211
+ function delete(){
212
+ global $wpdb;
213
+ $booking_ids = array();
214
+ //get the booking ids tied to this event
215
+ foreach( $this->bookings as $EM_Booking ){
216
+ $booking_ids[] = $EM_Booking->booking_id;
217
+ }
218
+ $result_tickets = true;
219
+ $result = true;
220
+ if( count($booking_ids) > 0 ){
221
+ //Delete bookings and ticket bookings
222
+ $result_tickets = $wpdb->query("DELETE FROM ". EM_TICKETS_BOOKINGS_TABLE ." WHERE booking_id IN (".implode(',',$booking_ids).");");
223
+ $result = $wpdb->query("DELETE FROM ".EM_BOOKINGS_TABLE." WHERE event_id IN (".implode(',',$booking_ids).")");
224
+ }
225
+ return ($result !== false && $result_tickets !== false);
226
+ }
227
+
228
+
229
+ /**
230
+ * Will approve all supplied booking ids, which must be in the form of a numeric array or a single number.
231
+ * @param array|int $booking_ids
232
+ * @return boolean
233
+ */
234
+ function approve( $booking_ids ){
235
+ $this->set_status(1, $booking_ids);
236
+ return false;
237
+ }
238
+
239
+ /**
240
+ * Will reject all supplied booking ids, which must be in the form of a numeric array or a single number.
241
+ * @param array|int $booking_ids
242
+ * @return boolean
243
+ */
244
+ function reject( $booking_ids ){
245
+ return $this->set_status(2, $booking_ids);
246
+ }
247
+
248
+ /**
249
+ * Will unapprove all supplied booking ids, which must be in the form of a numeric array or a single number.
250
+ * @param array|int $booking_ids
251
+ * @return boolean
252
+ */
253
+ function unapprove( $booking_ids ){
254
+ return $this->set_status(0, $booking_ids);
255
+ }
256
+
257
+ /**
258
+ * @param int $status
259
+ * @param array|int $booking_ids
260
+ * @return bool
261
+ */
262
+ function set_status($status, $booking_ids){
263
+ //FIXME status should work with instantiated object
264
+ //FIXME there is a vulnerability where any user can approve/reject bookings if they know the ID
265
+ if( $this->array_is_numeric($booking_ids) ){
266
+ //Get all the bookings
267
+ $results = array();
268
+ $mails = array();
269
+ foreach( $booking_ids as $booking_id ){
270
+ $EM_Booking = new EM_Booking($booking_id);
271
+ if( !$EM_Booking->can_manage() ){
272
+ $this->feedback_message = __('Bookings %s. Mails Sent.', 'dbem');
273
+ return false;
274
+ }
275
+ $results[] = $EM_Booking->set_status($status);
276
+ }
277
+ if( !in_array('false',$results) ){
278
+ $this->feedback_message = __('Bookings %s. Mails Sent.', 'dbem');
279
+ return true;
280
+ }else{
281
+ //TODO Better error handling needed if some bookings fail approval/failure
282
+ $this->feedback_message = __('An error occurred.', 'dbem');
283
+ return false;
284
+ }
285
+ }elseif( is_numeric($booking_ids) || is_object($booking_ids) ){
286
+ $EM_Booking = ( is_object($booking_ids) && get_class($booking_ids) == 'EM_Booking') ? $booking_ids : new EM_Booking($booking_ids);
287
+ $result = $EM_Booking->set_status($status);
288
+ $this->feedback_message = $EM_Booking->feedback_message;
289
+ return $result;
290
+ }
291
+ return false;
292
+ }
293
+
294
+
295
+ /**
296
+ * Get the total number of spaces this event has. This will show the lower value of event global spaces limit or total ticket spaces. Setting $force_refresh to true will recheck spaces, even if previously done so.
297
+ * @param boolean $force_refresh
298
+ * @return int
299
+ */
300
+ function get_spaces( $force_refresh=false ){
301
+ if($force_refresh || $this->spaces == 0){
302
+ $this->spaces = $this->get_tickets()->get_spaces();
303
+ }
304
+ //check overall events cap
305
+ if(!empty($this->get_event()->event_spaces) && $this->get_event()->event_spaces < $this->spaces) $this->spaces = $this->get_event()->event_spaces;
306
+ return apply_filters('em_booking_get_spaces',$this->spaces,$this);
307
+ }
308
+
309
+ /**
310
+ * Returns number of available spaces for this event. If approval of bookings is on, will include pending bookings depending on em option.
311
+ * @return int
312
+ */
313
+ function get_available_spaces(){
314
+ $spaces = $this->get_spaces();
315
+ $available_spaces = $spaces - $this->get_booked_spaces();
316
+ if( get_option('dbem_bookings_approval_reserved') ){ //deduct reserved/pending spaces from available spaces
317
+ $available_spaces -= $this->get_pending_spaces();
318
+ }
319
+ return apply_filters('em_booking_get_available_spaces', $available_spaces, $this);
320
+ }
321
+
322
+ /**
323
+ * Returns number of booked spaces for this event. If approval of bookings is on, will return number of booked confirmed spaces.
324
+ * @return int
325
+ */
326
+ function get_booked_spaces($force_refresh = false){
327
+ $booked_spaces = 0;
328
+ foreach ( $this->bookings as $EM_Booking ){
329
+ if( $EM_Booking->booking_status == 1 ){
330
+ $booked_spaces += $EM_Booking->get_spaces($force_refresh);
331
+ }
332
+ }
333
+ return apply_filters('em_bookings_get_booked_spaces', $booked_spaces, $this);
334
+ }
335
+
336
+ /**
337
+ * Gets number of pending spaces awaiting approval. Will return 0 if booking approval is not enabled.
338
+ * @return int
339
+ */
340
+ function get_pending_spaces(){
341
+ if( get_option('dbem_bookings_approval') == 0 ){
342
+ return apply_filters('em_bookings_get_pending_spaces', 0, $this);
343
+ }
344
+ $pending = 0;
345
+ foreach ( $this->bookings as $booking ){
346
+ if($booking->booking_status == 0){
347
+ $pending += $booking->get_spaces();
348
+ }
349
+ }
350
+ return apply_filters('em_bookings_get_pending_spaces', $pending, $this);
351
+ }
352
+
353
+ /**
354
+ * Gets number of bookings (not spaces). If booking approval is enabled, only the number of approved bookings will be shown.
355
+ * @return EM_Bookings
356
+ */
357
+ function get_bookings( $all_bookings = false ){
358
+ $confirmed = array();
359
+ foreach ( $this->bookings as $booking ){
360
+ if( $booking->booking_status == 1 || (get_option('dbem_bookings_approval') == 0 && $booking->booking_status == 0) || $all_bookings ){
361
+ $confirmed[] = $booking;
362
+ }
363
+ }
364
+ $EM_Bookings = new EM_Bookings($confirmed);
365
+ return $EM_Bookings;
366
+ }
367
+
368
+ /**
369
+ * Get pending bookings. If booking approval is disabled, will return no bookings.
370
+ * @return EM_Bookings
371
+ */
372
+ function get_pending_bookings(){
373
+ if( get_option('dbem_bookings_approval') == 0 ){
374
+ return array();
375
+ }
376
+ $pending = array();
377
+ foreach ( $this->bookings as $booking ){
378
+ if($booking->booking_status == 0){
379
+ $pending[] = $booking;
380
+ }
381
+ }
382
+ $EM_Bookings = new EM_Bookings($pending);
383
+ return $EM_Bookings;
384
+ }
385
+
386
+ /**
387
+ * Get rejected bookings. If booking approval is disabled, will return no bookings.
388
+ * @return array EM_Bookings
389
+ */
390
+ function get_rejected_bookings(){
391
+ $rejected = array();
392
+ foreach ( $this->bookings as $booking ){
393
+ if($booking->booking_status == 2){
394
+ $rejected[] = $booking;
395
+ }
396
+ }
397
+ $EM_Bookings = new EM_Bookings($rejected);
398
+ return $EM_Bookings;
399
+ }
400
+
401
+ /**
402
+ * Get cancelled bookings.
403
+ * @return array EM_Booking
404
+ */
405
+ function get_cancelled_bookings(){
406
+ $cancelled = array();
407
+ foreach ( $this->bookings as $booking ){
408
+ if($booking->booking_status == 3){
409
+ $cancelled[] = $booking;
410
+ }
411
+ }
412
+ $EM_Bookings = new EM_Bookings($cancelled);
413
+ return $EM_Bookings;
414
+ }
415
+
416
+ /**
417
+ * Checks if a person with similar details has booked for this before
418
+ * @param $person_id
419
+ * @return EM_Booking
420
+ */
421
+ function find_previous_booking($EM_Booking){
422
+ //First see if we have a similar person on record that's making this booking
423
+ $EM_Booking->person->load_similar();
424
+ //If person exists on record, see if they've booked this event before, if so return the booking.
425
+ if( is_numeric($EM_Booking->person->ID) && $EM_Booking->person->ID > 0 ){
426
+ $EM_Booking->person_id = $EM_Booking->person->ID;
427
+ foreach ($this->bookings as $booking){
428
+ if( $booking->person_id == $EM_Booking->person->ID ){
429
+ return $booking;
430
+ }
431
+ }
432
+ }
433
+ return false;
434
+ }
435
+
436
+ /**
437
+ * Checks to see if user has a booking for this event
438
+ * @param unknown_type $user_id
439
+ */
440
+ function has_booking( $user_id = false ){
441
+ if( $user_id === false ){
442
+ $user_id = get_current_user_id();
443
+ }
444
+ if( is_numeric($user_id) && $user_id > 0 ){
445
+ foreach ($this->bookings as $EM_Booking){
446
+ if( $EM_Booking->person->ID == $user_id && $EM_Booking->booking_status != 3 ){
447
+ return apply_filters('em_bookings_has_booking', $EM_Booking, $this);
448
+ }
449
+ }
450
+ }
451
+ return apply_filters('em_bookings_has_booking', false, $this);
452
+ }
453
+
454
+ /**
455
+ * Get bookings that match the array of arguments passed.
456
+ * @return array
457
+ * @static
458
+ */
459
+ function get( $args = array(), $count = false ){
460
+ global $wpdb,$current_user;
461
+ $bookings_table = EM_BOOKINGS_TABLE;
462
+ $events_table = EM_EVENTS_TABLE;
463
+ $locations_table = EM_LOCATIONS_TABLE;
464
+
465
+ //Quick version, we can accept an array of IDs, which is easy to retrieve
466
+ if( self::array_is_numeric($args) ){ //Array of numbers, assume they are event IDs to retreive
467
+ //We can just get all the events here and return them
468
+ $sql = "
469
+ SELECT * FROM $bookings_table b
470
+ LEFT JOIN $events_table e ON e.event_id=b.event_id
471
+ WHERE booking_id".implode(" OR booking_id=", $args);
472
+ $results = $wpdb->get_results(apply_filters('em_bookings_get_sql',$sql),ARRAY_A);
473
+ $bookings = array();
474
+ foreach($results as $result){
475
+ $bookings[] = new EM_Booking($result);
476
+ }
477
+ return $bookings; //We return all the bookings matched as an EM_Booking array.
478
+ }
479
+
480
+ //We assume it's either an empty array or array of search arguments to merge with defaults
481
+ $args = self::get_default_search($args);
482
+ $limit = ( $args['limit'] && is_numeric($args['limit'])) ? "LIMIT {$args['limit']}" : '';
483
+ $offset = ( $limit != "" && is_numeric($args['offset']) ) ? "OFFSET {$args['offset']}" : '';
484
+
485
+ //Get the default conditions
486
+ $conditions = self::build_sql_conditions($args);
487
+ //Put it all together
488
+ $where = ( count($conditions) > 0 ) ? " WHERE " . implode ( " AND ", $conditions ):'';
489
+
490
+ //Get ordering instructions
491
+ $EM_Booking = new EM_Booking();
492
+ $accepted_fields = $EM_Booking->get_fields(true);
493
+ $orderby = self::build_sql_orderby($args, $accepted_fields);
494
+ //Now, build orderby sql
495
+ $orderby_sql = ( count($orderby) > 0 ) ? 'ORDER BY '. implode(', ', $orderby) : '';
496
+ //Selector
497
+ $selectors = ( $count ) ? 'COUNT(*)':'*';
498
+
499
+ //Create the SQL statement and execute
500
+ $sql = "
501
+ SELECT $selectors FROM $bookings_table
502
+ LEFT JOIN $events_table ON {$events_table}.event_id={$bookings_table}.event_id
503
+ LEFT JOIN $locations_table ON {$locations_table}.location_id={$events_table}.location_id
504
+ $where
505
+ $orderby_sql
506
+ $limit $offset
507
+ ";
508
+ //If we're only counting results, return the number of results
509
+ if( $count ){
510
+ return apply_filters('em_bookings_get_count', $wpdb->get_var($sql), $args);
511
+ }
512
+ $results = $wpdb->get_results( apply_filters('em_events_get_sql',$sql, $args), ARRAY_A);
513
+
514
+ //If we want results directly in an array, why not have a shortcut here?
515
+ if( $args['array'] == true ){
516
+ return $results;
517
+ }
518
+
519
+ //Make returned results EM_Booking objects
520
+ $results = (is_array($results)) ? $results:array();
521
+ $bookings = array();
522
+ foreach ( $results as $booking ){
523
+ $bookings[] = new EM_Booking($booking);
524
+ }
525
+ $EM_Bookings = new EM_Bookings($bookings);
526
+ return apply_filters('em_bookings_get', $EM_Bookings);
527
+ }
528
+
529
+ function count( $args = array() ){
530
+ return self::get($args, true);
531
+ }
532
+
533
+
534
+ //List of patients in the patient database, that a user can choose and go on to edit any previous treatment data, or add a new admission.
535
+ function export_csv() {
536
+ global $EM_Event;
537
+ if($EM_Event->event_id != $this->event_id ){
538
+ $event = $this->get_event();
539
+ $event_name = $event->name;
540
+ }else{
541
+ $event_name = $EM_Event->name;
542
+ }
543
+ // The name of the file on the user's pc
544
+ $file_name = sanitize_title($event_name). "-bookings.csv";
545
+
546
+ header("Content-Type: application/octet-stream");
547
+ header("Content-Disposition: Attachment; filename=$file_name");
548
+ em_locate_template('templates/csv-event-bookings.php', true);
549
+ exit();
550
+ }
551
+
552
+ /* Overrides EM_Object method to apply a filter to result
553
+ * @see wp-content/plugins/events-manager/classes/EM_Object#build_sql_conditions()
554
+ */
555
+ function build_sql_conditions( $args = array() ){
556
+ $conditions = apply_filters( 'em_bookings_build_sql_conditions', parent::build_sql_conditions($args), $args );
557
+ if( is_numeric($args['status']) ){
558
+ $conditions['status'] = 'booking_status='.$args['status'];
559
+ }elseif( is_array($args['status']) && count($args['status']) > 0 ){
560
+ $conditions['status'] = 'booking_status IN ('.implode(',',$args['status']).')';
561
+ }elseif( !is_array($args['status']) && preg_match('/^([0-9],?)+$/', $args['status']) ){
562
+ $conditions['status'] = 'booking_status IN ('.$args['status'].')';
563
+ }
564
+ if( is_numeric($args['person']) && current_user_can('manage_others_bookings') ){
565
+ $conditions['person'] = EM_BOOKINGS_TABLE.'.person_id='.$args['person'];
566
+ }
567
+ return apply_filters('em_bookings_build_sql_conditions', $conditions, $args);
568
+ }
569
+
570
+ /* Overrides EM_Object method to apply a filter to result
571
+ * @see wp-content/plugins/events-manager/classes/EM_Object#build_sql_orderby()
572
+ */
573
+ function build_sql_orderby( $args, $accepted_fields, $default_order = 'ASC' ){
574
+ return apply_filters( 'em_bookings_build_sql_orderby', parent::build_sql_orderby($args, $accepted_fields, get_option('dbem_events_default_order')), $args, $accepted_fields, $default_order );
575
+ }
576
+
577
+ /*
578
+ * Adds custom Events search defaults
579
+ * @param array $array
580
+ * @return array
581
+ * @uses EM_Object#get_default_search()
582
+ */
583
+ function get_default_search( $array = array() ){
584
+ $defaults = array(
585
+ 'status' => false,
586
+ 'person' => true //to add later, search by person's bookings...
587
+ );
588
+ if( true || is_admin() ){
589
+ //figure out default owning permissions
590
+ if( !current_user_can('edit_others_events') ){
591
+ $defaults['owner'] = get_current_user_id();
592
+ }else{
593
+ $defaults['owner'] = false;
594
+ }
595
+ }
596
+ return apply_filters('em_bookings_get_default_search', parent::get_default_search($defaults,$array), $array, $defaults);
597
+ }
598
+
599
+ //Iterator Implementation
600
+ public function rewind(){
601
+ reset($this->bookings);
602
+ }
603
+ public function current(){
604
+ $var = current($this->bookings);
605
+ return $var;
606
+ }
607
+ public function key(){
608
+ $var = key($this->bookings);
609
+ return $var;
610
+ }
611
+ public function next(){
612
+ $var = next($this->bookings);
613
+ return $var;
614
+ }
615
+ public function valid(){
616
+ $key = key($this->bookings);
617
+ $var = ($key !== NULL && $key !== FALSE);
618
+ return $var;
619
+ }
620
+ }
621
  ?>
classes/em-calendar.php CHANGED
@@ -1,366 +1,372 @@
1
- <?php
2
- class EM_Calendar extends EM_Object {
3
-
4
- function init(){
5
- add_action('wp_head', array('EM_Calendar', 'insert_js'));
6
- }
7
-
8
- function output($args = array()) {
9
- global $wpdb;
10
-
11
- $args = self::get_default_search($args);
12
- $full = $args['full']; //For ZDE, don't delete pls
13
- $month = $args['month'];
14
- $year = $args['year'];
15
- $long_events = $args['long_events'];
16
-
17
- $week_starts_on_sunday = get_option('dbem_week_starts_sunday');
18
- $start_of_week = get_option('start_of_week');
19
-
20
- if( !(is_numeric($month) && $month <= 12 && $month > 0) ) {
21
- $month = date('m');
22
- }
23
- if( !( is_numeric($year) ) ){
24
- $year = date('Y');
25
- }
26
-
27
- // Get the first day of the month
28
- $month_start = mktime(0,0,0,$month, 1, $year);
29
- // Get friendly month name
30
- $month_name = date('M',$month_start);
31
- // Figure out which day of the week
32
- // the month starts on.
33
- $month_start_day = date('D', $month_start);
34
-
35
- switch($month_start_day){
36
- case "Sun": $offset = 0; break;
37
- case "Mon": $offset = 1; break;
38
- case "Tue": $offset = 2; break;
39
- case "Wed": $offset = 3; break;
40
- case "Thu": $offset = 4; break;
41
- case "Fri": $offset = 5; break;
42
- case "Sat": $offset = 6; break;
43
- }
44
- //We need to go back to the WP defined day when the week started, in case the event day is near the end
45
- $offset -= $start_of_week;
46
- if($offset<0)
47
- $offset += 7;
48
-
49
- // determine how many days are in the last month.
50
- $month_last = $month-1;
51
- $month_next = $month+1;
52
- $year_last = $year;
53
- $year_next = $year;
54
- if($month == 1) {
55
- $month_last = 12;
56
- $year_last = $year -1;
57
- }
58
- $num_days_last = self::days_in_month($month_last, $year_last);
59
-
60
- // determine how many days are in the current month.
61
- $num_days_current = self::days_in_month($month, $year);
62
- // Build an array for the current days
63
- // in the month
64
- for($i = 1; $i <= $num_days_current; $i++){
65
- $num_days_array[] = mktime(0,0,0,$month, $i, $year);
66
- }
67
- // Build an array for the number of days
68
- // in last month
69
- for($i = 1; $i <= $num_days_last; $i++){
70
- $num_days_last_array[] = mktime(0,0,0,$month_last, $i, $year_last);
71
- }
72
- // If the $offset from the starting day of the
73
- // week happens to be Sunday, $offset would be 0,
74
- // so don't need an offset correction.
75
-
76
- if($offset > 0){
77
- $offset_correction = array_slice($num_days_last_array, -$offset, $offset);
78
- $new_count = array_merge($offset_correction, $num_days_array);
79
- $offset_count = count($offset_correction);
80
- } else { // The else statement is to prevent building the $offset array.
81
- $offset_count = 0;
82
- $new_count = $num_days_array;
83
- }
84
- // count how many days we have with the two
85
- // previous arrays merged together
86
- $current_num = count($new_count);
87
-
88
- // Since we will have 5 HTML table rows (TR)
89
- // with 7 table data entries (TD)
90
- // we need to fill in 35 TDs
91
- // so, we will have to figure out
92
- // how many days to appened to the end
93
- // of the final array to make it 35 days.
94
-
95
-
96
- if($current_num > 35){
97
- $num_weeks = 6;
98
- $outset = (42 - $current_num);
99
- } elseif($current_num < 35){
100
- $num_weeks = 5;
101
- $outset = (35 - $current_num);
102
- }
103
- if($current_num == 35){
104
- $num_weeks = 5;
105
- $outset = 0;
106
- }
107
- // Outset Correction
108
- for($i = 1; $i <= $outset; $i++){
109
- $new_count[] = mktime(0,0,0,$month_next, $i, $year_next);
110
- }
111
- // Now let's "chunk" the $all_days array
112
- // into weeks. Each week has 7 days
113
- // so we will array_chunk it into 7 days.
114
- $weeks = array_chunk($new_count, 7);
115
-
116
-
117
-
118
- // Build Previous and Next Links
119
- $base_link = "?".$_SERVER['QUERY_STRING']."&amp;";
120
-
121
- $full ? $link_extra_class = "full-link" : $link_extra_class = '';
122
- //Get an array of arguments that don't include default valued args
123
- $link_args = self::get_link_args($args);
124
-
125
- //Get the previous link
126
- if($month == 1){
127
- $back_month = 12;
128
- $back_year = $year-1;
129
- } else {
130
- $back_month = $month -1;
131
- $back_year = $year;
132
- }
133
- $previous_link = "<a class='em-calnav $link_extra_class' href='?ajaxCalendar=1&amp;month={$back_month}&amp;year={$back_year}&amp;{$link_args}'>&lt;&lt;</a>";
134
-
135
- //Now the next
136
- if($month == 12){
137
- $next_month = 1;
138
- $next_year = $year+1;
139
- } else {
140
- $next_month = $month + 1;
141
- $next_year = $year;
142
- }
143
- $next_link = "<a class='em-calnav $link_extra_class' href='?ajaxCalendar=1&amp;month={$next_month}&amp;year={$next_year}&amp;{$link_args}'>&gt;&gt;</a>";
144
-
145
-
146
- $class = ($full) ? 'dbem-calendar-full' : 'dbem-calendar';
147
- $calendar="<div class='$class'><div style='display:none' class='month_n'>$month</div><div class='year_n' style='display:none' >$year</div>";
148
-
149
- $weekdays = array('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday');
150
- $n = 0 ;
151
- while( $n < $start_of_week ) {
152
- $last_day = array_shift($weekdays);
153
- $weekdays[]= $last_day;
154
- $n++;
155
- }
156
-
157
- $days_initials = "";
158
- foreach($weekdays as $weekday) {
159
- $days_initials .= "<td>".self::translate_and_trim($weekday)."</td>";
160
- }
161
- $full ? $fullclass = 'fullcalendar' : $fullclass='';
162
- // Build the heading portion of the calendar table
163
- $calendar .= "<table class='dbem-calendar-table $fullclass'>\n".
164
- "<thead>\n<tr>\n".
165
- "<td>$previous_link</td><td class='month_name' colspan='5'>". apply_filters('dbem_calendar_output_month', ucfirst(date_i18n('M', $month_start)), $month_start, $args)." $year</td><td>$next_link</td>\n".
166
- "</tr>\n</thead>\n".
167
- "<tr class='days-names'>\n".
168
- $days_initials.
169
- "</tr>\n";
170
-
171
- // Now we break each key of the array
172
- // into a week and create a new table row for each
173
- // week with the days of that week in the table data
174
-
175
- $i = 0;
176
- $current_date = date('Y-m-d', current_time('timestamp'));
177
- foreach ( $weeks as $week ) {
178
- $calendar .= "<tr>\n";
179
- foreach ( $week as $d ) {
180
- if ($i < $offset_count) { //if it is PREVIOUS month
181
- $calendar .= "<td class='eventless-pre'>" . date ( 'j', $d ) . "</td>\n";
182
- }
183
- if (($i >= $offset_count) && ($i < ($num_weeks * 7) - $outset)) { // if it is THIS month
184
- $day = date ( 'j', $d );
185
- if ( $current_date == date('Y-m-d', $d) ){
186
- $calendar .= "<td class='eventless-today'>$day</td>\n";
187
- } else {
188
- $calendar .= "<td class='eventless'>$day</td>\n";
189
- }
190
- } elseif (($outset > 0)) { //if it is NEXT month
191
- if (($i >= ($num_weeks * 7) - $outset)) {
192
- $calendar .= "<td class='eventless-post'>" . date ( 'j', $d ) . "</td>\n";
193
- }
194
- }
195
- $i ++;
196
- }
197
- $calendar .= "</tr>\n";
198
- }
199
-
200
- $calendar .= " </table>\n</div>";
201
-
202
- // query the database for events in this time span
203
- if ($month == 1) {
204
- $month_pre=12;
205
- $month_post=2;
206
- $year_pre=$year-1;
207
- $year_post=$year;
208
- } elseif($month == 12) {
209
- $month_pre=11;
210
- $month_post=1;
211
- $year_pre=$year;
212
- $year_post=$year+1;
213
- } else {
214
- $month_pre=$month-1;
215
- $month_post=$month+1;
216
- $year_pre=$year;
217
- $year_post=$year;
218
- }
219
- $args['year'] = array($year_pre, $year_post);
220
- $args['month'] = array($month_pre, $month_post);
221
- $events = EM_Events::get($args);
222
-
223
- $eventful_days= array();
224
- if($events){
225
- //Go through the events and slot them into the right d-m index
226
- foreach($events as $event) {
227
- $event = apply_filters('em_calendar_output_loop_start', $event);
228
- if( $long_events ){
229
- //If $long_events is set then show a date as eventful if there is an multi-day event which runs during that day
230
- $event_start_date = mktime(0,0,0,$month_pre,1,$year_pre);
231
- $event_end_date = mktime(0,0,0,$month_post,date('t', $event_start_date),$year_post );
232
- if( $event_end_date == '' ) $event_end_date = $event_start_date;
233
- while( $event_start_date <= $event->end ){
234
- //Ensure date is within event dates, if so add to eventful days array
235
- if( $event_start_date > $event->start - (86400) ){ //subtract a day since start may be later in day
236
- $event_eventful_date = date('Y-m-d', $event_start_date);
237
- if( array_key_exists($event_eventful_date, $eventful_days) && is_array($eventful_days[$event_eventful_date]) ){
238
- $eventful_days[$event_eventful_date][] = $event;
239
- } else {
240
- $eventful_days[$event_eventful_date] = array($event);
241
- }
242
- }
243
- $event_start_date += (86400); //add a day
244
- }
245
- }else{
246
- //Only show events on the day that they start
247
- if( isset($eventful_days[$event->start_date]) && is_array($eventful_days[$event->start_date]) ){
248
- $eventful_days[$event->start_date][] = $event;
249
- } else {
250
- $eventful_days[$event->start_date] = array($event);
251
- }
252
- }
253
- $event = apply_filters('em_calendar_output_loop_end', $event);
254
- }
255
- }
256
-
257
- $event_format = get_option('dbem_full_calendar_event_format');
258
- $event_title_format = get_option('dbem_small_calendar_event_title_format');
259
- $event_title_separator_format = get_option('dbem_small_calendar_event_title_separator');
260
- $cells = array() ;
261
- foreach($eventful_days as $day_key => $events) {
262
- //Set the date into the key
263
- $event_start_date = explode('-', $day_key);
264
- $cells[$day_key]['day'] = ltrim($event_start_date[2],'0');
265
- $cells[$day_key]['month'] = $event_start_date[1];
266
- $cells[$day_key]['year'] = $event_start_date[0];
267
- $events_titles = array();
268
- foreach($events as $event) {
269
- $events_titles[] = $event->output($event_title_format);
270
- }
271
- $link_title = implode( $event_title_separator_format, $events_titles);
272
-
273
- $events_page_id = get_option('dbem_events_page');
274
- $event_page_link = get_permalink($events_page_id);
275
- if (stristr($event_page_link, "?"))
276
- $joiner = "&amp;";
277
- else
278
- $joiner = "?";
279
-
280
-
281
- $cells[$day_key]['cell'] = "<a title='$link_title' href='".$event_page_link.$joiner."calendar_day={$day_key}'>{$cells[$day_key]['day']}</a>";
282
- if ($full) {
283
- $cells[$day_key]['cell'] .= "<ul>";
284
-
285
- foreach($events as $event) {
286
- $cells[$day_key]['cell'] .= $event->output($event_format);
287
- }
288
- $cells[$day_key]['cell'] .= "</ul>";
289
- }
290
- }
291
-
292
- if($events){
293
- foreach($cells as $cell) {
294
- if ($cell['month'] == $month_pre && $cell['year'] == $year_pre) {
295
- $calendar = str_replace("<td class='eventless-pre'>".$cell['day']."</td>","<td class='eventful-pre'>".$cell['cell']."</td>",$calendar);
296
- } elseif($cell['month'] == $month_post && $cell['year'] == $year_post) {
297
- $calendar = str_replace("<td class='eventless-post'>".$cell['day']."</td>","<td class='eventful-post'>".$cell['cell']."</td>",$calendar);
298
- } elseif( date('Y-m-j', current_time('timestamp')) == $cell['year']."-".$cell['month']."-".$cell['day'] ) {
299
- $calendar = str_replace("<td class='eventless-today'>".$cell['day']."</td>","<td class='eventful-today'>".$cell['cell']."</td>",$calendar);
300
- } elseif( $cell['month'] == $month && $cell['year'] == $year){
301
- $calendar = str_replace("<td class='eventless'>".$cell['day']."</td>","<td class='eventful'>".$cell['cell']."</td>",$calendar);
302
- }
303
- }
304
- }
305
- return apply_filters('em_calendar_output', '<div id="em-calendar-'.rand(100,200).'" class="em-calendar-wrapper">'.$calendar.'</div>');
306
- }
307
-
308
- /**
309
- * Echoes the calendar external JS contents directly into the head of the document
310
- * @return unknown_type
311
- */
312
- function insert_js() {
313
- ?>
314
- <script type='text/javascript'>
315
- <?php include(WP_PLUGIN_DIR.'/events-manager/includes/js/em_calendar_ajax.js'); ?>
316
- </script>
317
- <?php
318
- }
319
-
320
-
321
- function days_in_month($month, $year) {
322
- return date('t', mktime(0,0,0,$month,1,$year));
323
- }
324
-
325
- function translate_and_trim($string, $length = 1) {
326
- return substr(__($string), 0, $length);
327
- }
328
-
329
- /**
330
- * Helper function to create a link querystring from array which contains arguments with only values that aren't defuaults.
331
- */
332
- function get_link_args($args = array(), $html_entities=true){
333
- unset($args['month']); unset($args['year']);
334
- $default_args = self::get_default_search(array());
335
- foreach($default_args as $arg_key => $arg_value){
336
- if( !isset($args[$arg_key]) || $args[$arg_key] == $arg_value ){
337
- unset($args[$arg_key]);
338
- }
339
- }
340
- $qs_array = array();
341
- foreach($args as $key => $value){
342
- if(is_array($value)){
343
- $value = implode(',',$value);
344
- }
345
- $qs_array[] = "$key=".urlencode($value);
346
- }
347
- return ($html_entities) ? implode('&amp;', $qs_array) : implode('&', $qs_array);
348
- }
349
-
350
-
351
- function get_default_search($array=array()){
352
- //These defaults aren't for db queries, but flags for what to display in calendar output
353
- $defaults = array(
354
- 'full' => 0, //Will display a full calendar with event names
355
- 'long_events' => 0, //Events that last longer than a day
356
- 'scope' => 'all',
357
- 'owner' => false
358
- );
359
- $atts = parent::get_default_search($defaults, $array);
360
- $atts['full'] = ($atts['full']==true) ? 1:0;
361
- $atts['long_events'] = ($atts['long_events']==true) ? 1:0;
362
- return apply_filters('em_calendar_get_default_search', $atts, $array, $defaults);
363
- }
364
- }
365
- add_action('init', array('EM_Calendar', 'init'));
366
- ?>
 
 
 
 
 
 
1
+ <?php
2
+ class EM_Calendar extends EM_Object {
3
+
4
+ function init(){
5
+ //nothing to init anymore
6
+ }
7
+
8
+ function get( $args ){
9
+
10
+ global $wpdb;
11
+
12
+ $calendar_array = array();
13
+ $calendar_array['cells'] = array();
14
+
15
+ $original_args = $args;
16
+ $args = self::get_default_search($args);
17
+ $full = $args['full']; //For ZDE, don't delete pls
18
+ $month = $args['month'];
19
+ $year = $args['year'];
20
+ $long_events = $args['long_events'];
21
+
22
+ $week_starts_on_sunday = get_option('dbem_week_starts_sunday');
23
+ $start_of_week = get_option('start_of_week');
24
+
25
+ if( !(is_numeric($month) && $month <= 12 && $month > 0) ) {
26
+ $month = date('m');
27
+ }
28
+ if( !( is_numeric($year) ) ){
29
+ $year = date('Y');
30
+ }
31
+
32
+ // Get the first day of the month
33
+ $month_start = mktime(0,0,0,$month, 1, $year);
34
+ $calendar_array['month_start'] = $month_start;
35
+
36
+ // Get friendly month name
37
+ $month_name = date('M',$month_start);
38
+ // Figure out which day of the week
39
+ // the month starts on.
40
+ $month_start_day = date('D', $month_start);
41
+
42
+ switch($month_start_day){
43
+ case "Sun": $offset = 0; break;
44
+ case "Mon": $offset = 1; break;
45
+ case "Tue": $offset = 2; break;
46
+ case "Wed": $offset = 3; break;
47
+ case "Thu": $offset = 4; break;
48
+ case "Fri": $offset = 5; break;
49
+ case "Sat": $offset = 6; break;
50
+ }
51
+ //We need to go back to the WP defined day when the week started, in case the event day is near the end
52
+ $offset -= $start_of_week;
53
+ if($offset<0)
54
+ $offset += 7;
55
+
56
+ // determine how many days are in the last month.
57
+ $month_last = $month-1;
58
+ $month_next = $month+1;
59
+ $calendar_array['month_next'] = $month_next;
60
+ $year_last = $year;
61
+ $year_next = $year;
62
+ $calendar_array['year_next'] = $year_next;
63
+
64
+ if($month == 1) {
65
+ $month_last = 12;
66
+ $year_last = $year -1;
67
+ }elseif($month == 12){
68
+ $month_next = 1;
69
+ $year_next = $year + 1;
70
+ }
71
+ $calendar_array['month_last'] = $month_last;
72
+ $calendar_array['year_last'] = $year_last;
73
+
74
+ $num_days_last = self::days_in_month($month_last, $year_last);
75
+
76
+ // determine how many days are in the current month.
77
+ $num_days_current = self::days_in_month($month, $year);
78
+ // Build an array for the current days
79
+ // in the month
80
+ for($i = 1; $i <= $num_days_current; $i++){
81
+ $num_days_array[] = mktime(0,0,0,$month, $i, $year);
82
+ }
83
+ // Build an array for the number of days
84
+ // in last month
85
+ for($i = 1; $i <= $num_days_last; $i++){
86
+ $num_days_last_array[] = mktime(0,0,0,$month_last, $i, $year_last);
87
+ }
88
+ // If the $offset from the starting day of the
89
+ // week happens to be Sunday, $offset would be 0,
90
+ // so don't need an offset correction.
91
+
92
+ if($offset > 0){
93
+ $offset_correction = array_slice($num_days_last_array, -$offset, $offset);
94
+ $new_count = array_merge($offset_correction, $num_days_array);
95
+ $offset_count = count($offset_correction);
96
+ } else { // The else statement is to prevent building the $offset array.
97
+ $offset_count = 0;
98
+ $new_count = $num_days_array;
99
+ }
100
+ // count how many days we have with the two
101
+ // previous arrays merged together
102
+ $current_num = count($new_count);
103
+
104
+ // Since we will have 5 HTML table rows (TR)
105
+ // with 7 table data entries (TD)
106
+ // we need to fill in 35 TDs
107
+ // so, we will have to figure out
108
+ // how many days to appened to the end
109
+ // of the final array to make it 35 days.
110
+ if($current_num > 35){
111
+ $num_weeks = 6;
112
+ $outset = (42 - $current_num);
113
+ } elseif($current_num < 35){
114
+ $num_weeks = 5;
115
+ $outset = (35 - $current_num);
116
+ }
117
+ if($current_num == 35){
118
+ $num_weeks = 5;
119
+ $outset = 0;
120
+ }
121
+ // Outset Correction
122
+ for($i = 1; $i <= $outset; $i++){
123
+ $new_count[] = mktime(0,0,0,$month_next, $i, $year_next);
124
+ }
125
+ // Now let's "chunk" the $all_days array
126
+ // into weeks. Each week has 7 days
127
+ // so we will array_chunk it into 7 days.
128
+ $weeks = array_chunk($new_count, 7);
129
+
130
+ //Get an array of arguments that don't include default valued args
131
+ $link_args = self::get_link_args($args);
132
+
133
+ $previous_url = "?ajaxCalendar=1&amp;mo={$month_last}&amp;yr={$year_last}&amp;{$link_args}";
134
+ $next_url = "?ajaxCalendar=1&amp;mo={$month_next}&amp;yr={$year_next}&amp;{$link_args}";
135
+
136
+ $weekdays = array('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday');
137
+ $n = 0 ;
138
+ while( $n < $start_of_week ) {
139
+ $last_day = array_shift($weekdays);
140
+ $weekdays[]= $last_day;
141
+ $n++;
142
+ }
143
+
144
+ $days_initials_array = array();
145
+ foreach($weekdays as $weekday) {
146
+ $days_initials_array[] = self::translate_and_trim($weekday);
147
+ }
148
+
149
+ $calendar_array['links'] = array( 'previous_url'=>$previous_url, 'next_url'=>$next_url);
150
+ $calendar_array['row_headers'] = $days_initials_array;
151
+
152
+ // Now we break each key of the array
153
+ // into a week and create a new table row for each
154
+ // week with the days of that week in the table data
155
+
156
+ $i = 0;
157
+ $current_date = date('Y-m-d', current_time('timestamp'));
158
+ $week_count = 0;
159
+ foreach ( $weeks as $week ) {
160
+ foreach ( $week as $d ) {
161
+ $date = date('Y-m-d', $d);
162
+ $calendar_array['cells'][$date] = array('date'=>$d); //set it up so we have the exact array of dates to be filled
163
+ if ($i < $offset_count) { //if it is PREVIOUS month
164
+ $calendar_array['cells'][$date]['type'] = 'pre';
165
+ }
166
+ if (($i >= $offset_count) && ($i < ($num_weeks * 7) - $outset)) { // if it is THIS month
167
+ if ( $current_date == $date ){
168
+ $calendar_array['cells'][$date]['type'] = 'today';
169
+ }
170
+ } elseif (($outset > 0)) { //if it is NEXT month
171
+ if (($i >= ($num_weeks * 7) - $outset)) {
172
+ $calendar_array['cells'][$date]['type'] = 'post';
173
+ }
174
+ }
175
+ $i ++;
176
+ }
177
+ $week_count++;
178
+ }
179
+
180
+ // query the database for events in this time span
181
+ if ($month == 1) {
182
+ $month_pre=12;
183
+ $month_post=2;
184
+ $year_pre=$year-1;
185
+ $year_post=$year;
186
+ } elseif($month == 12) {
187
+ $month_pre=11;
188
+ $month_post=1;
189
+ $year_pre=$year;
190
+ $year_post=$year+1;
191
+ } else {
192
+ $month_pre=$month-1;
193
+ $month_post=$month+1;
194
+ $year_pre=$year;
195
+ $year_post=$year;
196
+ }
197
+ $args['year'] = array($year_pre, $year_post);
198
+ $args['month'] = array($month_pre, $month_post);
199
+ $events = EM_Events::get($args);
200
+
201
+ $event_format = get_option('dbem_full_calendar_event_format');
202
+ $event_title_format = get_option('dbem_small_calendar_event_title_format');
203
+ $event_title_separator_format = get_option('dbem_small_calendar_event_title_separator');
204
+
205
+ $eventful_days= array();
206
+ if($events){
207
+ //Go through the events and slot them into the right d-m index
208
+ foreach($events as $event) {
209
+ $event = apply_filters('em_calendar_output_loop_start', $event);
210
+ if( $long_events ){
211
+ //If $long_events is set then show a date as eventful if there is an multi-day event which runs during that day
212
+ $event_start_date = strtotime($event->start_date);
213
+ $event_end_date = mktime(0,0,0,$month_post,date('t', $event_start_date),$year_post );
214
+ if( $event_end_date == '' ) $event_end_date = $event_start_date;
215
+ while( $event_start_date <= $event->end ){
216
+ //Ensure date is within event dates, if so add to eventful days array
217
+ $event_eventful_date = date('Y-m-d', $event_start_date);
218
+ if( array_key_exists($event_eventful_date, $eventful_days) && is_array($eventful_days[$event_eventful_date]) ){
219
+ $eventful_days[$event_eventful_date][] = $event;
220
+ } else {
221
+ $eventful_days[$event_eventful_date] = array($event);
222
+ }
223
+ $event_start_date += (86400); //add a day
224
+ }
225
+ }else{
226
+ //Only show events on the day that they start
227
+ if( isset($eventful_days[$event->event_start_date]) && is_array($eventful_days[$event->event_start_date]) ){
228
+ $eventful_days[$event->event_start_date][] = $event;
229
+ } else {
230
+ $eventful_days[$event->event_start_date] = array($event);
231
+ }
232
+ }
233
+ }
234
+ }
235
+ //generate a link argument string containing event search only
236
+ $day_link_args = self::get_link_args( array_intersect_key($original_args, EM_Events::get_post_search($args, true) ));
237
+ foreach($eventful_days as $day_key => $events) {
238
+ if( array_key_exists($day_key, $calendar_array['cells']) ){
239
+ //Get link title for this date
240
+ $events_titles = array();
241
+ foreach($events as $event) {
242
+ if( !get_option('dbem_display_calendar_events_limit') || count($events_titles) < get_option('dbem_display_calendar_events_limit') ){
243
+ $events_titles[] = $event->output($event_title_format);
244
+ }else{
245
+ $events_titles[] = get_option('dbem_display_calendar_events_limit_msg');
246
+ break;
247
+ }
248
+ }
249
+ $calendar_array['cells'][$day_key]['link_title'] = implode( $event_title_separator_format, $events_titles);
250
+
251
+ //Get the link to this calendar day
252
+ global $wp_rewrite;
253
+ if( count($events) > 1 || !get_option('dbem_calendar_direct_links') ){
254
+ if( get_option("dbem_events_page") > 0 ){
255
+ $event_page_link = trailingslashit(get_permalink(get_option("dbem_events_page"))); //PAGE URI OF EM
256
+ }else{
257
+ if( $wp_rewrite->using_permalinks() ){
258
+ $event_page_link = trailingslashit(home_url()).EM_POST_TYPE_EVENT_SLUG.'/'; //don't use EM_URI here, since ajax calls this before EM_URI is defined.
259
+ }else{
260
+ $event_page_link = trailingslashit(home_url()).'?post_type='.EM_POST_TYPE_EVENT; //don't use EM_URI here, since ajax calls this before EM_URI is defined.
261
+ }
262
+ }
263
+ if( $wp_rewrite->using_permalinks() && !defined('EM_DISABLE_PERMALINKS') ){
264
+ $calendar_array['cells'][$day_key]['link'] = $event_page_link.$day_key."/";
265
+ if( !empty($day_link_args) ){
266
+ $calendar_array['cells'][$day_key]['link'] .= '?'.$day_link_args;
267
+ }
268
+ }else{
269
+ $joiner = (stristr($event_page_link, "?")) ? "&amp;" : "?";
270
+ $calendar_array['cells'][$day_key]['link'] = $event_page_link.$joiner."calendar_day=".$day_key;
271
+ if( !empty($day_link_args) ){
272
+ $calendar_array['cells'][$day_key]['link'] .= 'amp;'.$day_link_args;
273
+ }
274
+ }
275
+ }else{
276
+ foreach($events as $EM_Event){
277
+ $calendar_array['cells'][$day_key]['link'] = $EM_Event->get_permalink();
278
+ }
279
+ }
280
+ //Add events to array
281
+ $calendar_array['cells'][$day_key]['events'] = $events;
282
+ }
283
+ }
284
+ return apply_filters('em_calendar_get',$calendar_array, $args);
285
+ }
286
+
287
+ function output($args = array(), $wrapper = true) {
288
+ //Let month and year REQUEST override for non-JS users
289
+ if( !empty($_REQUEST['mo']) || !empty($args['mo']) ){
290
+ $args['month'] = ($_REQUEST['mo']) ? $_REQUEST['mo']:$args['mo'];
291
+ }
292
+ if( !empty($_REQUEST['yr']) || !empty($args['yr']) ){
293
+ $args['year'] = (!empty($_REQUEST['yr'])) ? $_REQUEST['yr']:$args['yr'];
294
+ }
295
+ $calendar_array = self::get($args);
296
+ $template = (!empty($args['full'])) ? 'templates/calendar-full.php':'templates/calendar-small.php';
297
+ ob_start();
298
+ em_locate_template($template, true, array('calendar'=>$calendar_array,'args'=>$args));
299
+ if($wrapper){
300
+ $calendar = '<div id="em-calendar-'.rand(100,200).'" class="em-calendar-wrapper">'.ob_get_clean().'</div>';
301
+ }else{
302
+ $calendar = ob_get_clean();
303
+ }
304
+ return apply_filters('em_calendar_output', $calendar, $args);
305
+ }
306
+
307
+
308
+ function days_in_month($month, $year) {
309
+ return date('t', mktime(0,0,0,$month,1,$year));
310
+ }
311
+
312
+ function translate_and_trim($string, $length = 1) {
313
+ if(function_exists('mb_substr')){ //fix for diacritic calendar names
314
+ return mb_substr(__($string), 0, $length);
315
+ }else{
316
+ return substr(__($string), 0, $length);
317
+ }
318
+ }
319
+
320
+ /**
321
+ * Helper function to create a link querystring from array which contains arguments with only values that aren't defuaults.
322
+ */
323
+ function get_link_args($args = array(), $html_entities=true){
324
+ unset($args['month']); unset($args['year']);
325
+ $default_args = self::get_default_search(array());
326
+ foreach($default_args as $arg_key => $arg_value){
327
+ if( !isset($args[$arg_key]) || $args[$arg_key] == $arg_value ){
328
+ unset($args[$arg_key]);
329
+ }
330
+ }
331
+ $qs_array = array();
332
+ foreach($args as $key => $value){
333
+ if(is_array($value)){
334
+ $value = implode(',',$value);
335
+ }
336
+ $qs_array[] = "$key=".urlencode($value);
337
+ }
338
+ return ($html_entities) ? implode('&amp;', $qs_array) : implode('&', $qs_array);
339
+ }
340
+
341
+
342
+ function get_default_search($array=array()){
343
+ //These defaults aren't for db queries, but flags for what to display in calendar output
344
+ $defaults = array(
345
+ 'full' => 0, //Will display a full calendar with event names
346
+ 'long_events' => 0, //Events that last longer than a day
347
+ 'scope' => 'future',
348
+ 'status' => 1, //approved events only
349
+ 'town' => false,
350
+ 'state' => false,
351
+ 'country' => false,
352
+ 'region' => false,
353
+ 'blog' => get_current_blog_id(),
354
+ 'orderby' => get_option('dbem_display_calendar_orderby'),
355
+ 'order' => get_option('dbem_display_calendar_order')
356
+ );
357
+ if(is_multisite()){
358
+ global $bp;
359
+ if( !is_main_site() && !array_key_exists('blog',$array) ){
360
+ //not the main blog, force single blog search
361
+ $array['blog'] = get_current_blog_id();
362
+ }elseif( empty($array['blog']) && get_site_option('dbem_ms_global_events') ) {
363
+ $array['blog'] = false;
364
+ }
365
+ }
366
+ $atts = parent::get_default_search($defaults, $array);
367
+ $atts['full'] = ($atts['full']==true) ? 1:0;
368
+ $atts['long_events'] = ($atts['long_events']==true) ? 1:0;
369
+ return apply_filters('em_calendar_get_default_search', $atts, $array, $defaults);
370
+ }
371
+ }
372
+ add_action('init', array('EM_Calendar', 'init'));
classes/em-categories-taxonomy.php ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class EM_Categories_Taxonomy{
3
+ function init(){
4
+ add_action( EM_TAXONOMY_CATEGORY.'_edit_form_fields', array('EM_Categories_Taxonomy','form'), 10, 1);
5
+ add_action( EM_TAXONOMY_CATEGORY.'_add_form_fields', array('EM_Categories_Taxonomy','form'), 10, 1);
6
+ add_action( 'edited_'.EM_TAXONOMY_CATEGORY, array('EM_Categories_Taxonomy','save'), 10, 2);
7
+ add_action( 'create_'.EM_TAXONOMY_CATEGORY, array('EM_Categories_Taxonomy','save'), 10, 2);
8
+ add_action( 'delete_'.EM_TAXONOMY_CATEGORY, array('EM_Categories_Taxonomy','delete'), 10, 2);
9
+
10
+ add_filter('manage_edit-'.EM_TAXONOMY_CATEGORY.'_columns' , array('EM_Categories_Taxonomy','columns_add'));
11
+ add_filter('manage_'.EM_TAXONOMY_CATEGORY.'_custom_column' , array('EM_Categories_Taxonomy','columns_output'),10,3);
12
+
13
+ self::admin_init();
14
+ }
15
+
16
+
17
+ function columns_add($columns) {
18
+ //prepend ID after checkbox
19
+ $columns['cat-id'] = __('ID','dbem');
20
+ return $columns;
21
+ }
22
+
23
+ function columns_output( $val, $column, $term_id ) {
24
+ switch ( $column ) {
25
+ case 'cat-id':
26
+ return $term_id;
27
+ break;
28
+ }
29
+ return $val;
30
+ }
31
+
32
+ function admin_init(){
33
+ global $pagenow;
34
+ if($pagenow == 'edit-tags.php' && !empty($_GET['taxonomy']) && $_GET['taxonomy'] == EM_TAXONOMY_CATEGORY){
35
+ wp_enqueue_style( 'farbtastic' );
36
+ wp_enqueue_style( 'thickbox' );
37
+
38
+ wp_enqueue_script( 'em-categories-admin', plugins_url().'/events-manager/includes/js/categories-admin.js', array( 'jquery','media-upload','thickbox','farbtastic' ) );
39
+ }
40
+ }
41
+
42
+ function form($tag){
43
+ $category_color = '#FFFFFF';
44
+ $category_image = '';
45
+ if( $tag != EM_TAXONOMY_CATEGORY ){ //not an add new tag form
46
+ $EM_Category = new EM_Category($tag);
47
+ $category_color = $EM_Category->get_color();
48
+ $category_image = $EM_Category->get_image_url();
49
+ }
50
+ ?>
51
+ <tr class="form-field">
52
+ <th scope="row" valign="top"><label for="category-bgcolor">Calendar Color</label></th>
53
+ <td>
54
+ <input type="text" name="category_bgcolor" id="category-bgcolor" class="colorwell" value="<?php echo esc_attr($category_color); ?>" style="width:100px;"/><br />
55
+ <p class="description"><?php echo sprintf(__('Choose a color for your category. You can access this using the %s placeholder.','dbem'),'<code>#_CATEGORYCOLOR</code>'); ?></p>
56
+ <div id="picker" style="position:absolute; display:none; background:#DEDEDE"></div>
57
+ </td>
58
+ </tr>
59
+ <tr class="form-field">
60
+ <th scope="row" valign="top"><label for="product_package_unit_price">Image</label></th>
61
+ <td>
62
+ <?php if( !empty($category_image) ): ?>
63
+ <p><img src="<?php echo $category_image; ?>" /></p>
64
+ <?php endif; ?>
65
+ <input type="text" name="category_image" id="category-image" value="<?php echo esc_attr($category_image); ?>" style="width:300px;" />
66
+ <input id="upload_image_button" type="button" value="<?php _e('Choose/Upload Image','dbem'); ?>" class="button-secondary" style="width:auto;" /><br />
67
+ <p class="description"><?php echo sprintf(__('Choose an image for your category, which can be displayed using the %s placeholder.','dbem'),'<code>#_CATEGORYIMAGE</code>'); ?></p>
68
+ </td>
69
+ </tr>
70
+ <?php
71
+ }
72
+
73
+ function save($term_id, $tt_id){
74
+ global $wpdb;
75
+ if (!$term_id) return;
76
+ if( !empty($_POST['category_bgcolor']) && preg_match('/^#[a-zA-Z0-9]{6}$/', $_POST['category_bgcolor']) ){
77
+ //get results and save/update
78
+ $prev_settings = $wpdb->get_results('SELECT meta_value FROM '.EM_META_TABLE." WHERE object_id='{$term_id}' AND meta_key='category-bgcolor'");
79
+ if( count($prev_settings) > 0 ){
80
+ $wpdb->update(EM_META_TABLE, array('object_id'=>$term_id,'meta_value'=>$_POST['category_bgcolor']), array('object_id'=>$term_id,'meta_key'=>'category-bgcolor'));
81
+ }else{
82
+ $wpdb->insert(EM_META_TABLE, array('object_id'=>$term_id,'meta_key'=>'category-bgcolor','meta_value'=>$_POST['category_bgcolor']));
83
+ }
84
+ }
85
+ if( !empty($_POST['category_image']) ){
86
+ //get results and save/update
87
+ $prev_settings = $wpdb->get_results('SELECT meta_value FROM '.EM_META_TABLE." WHERE object_id='{$term_id}' AND meta_key='category-image'");
88
+ if( count($prev_settings) > 0 ){
89
+ $wpdb->update(EM_META_TABLE, array('object_id'=>$term_id,'meta_value'=>$_POST['category_image']), array('object_id'=>$term_id,'meta_key'=>'category-image'));
90
+ }else{
91
+ $wpdb->insert(EM_META_TABLE, array('object_id'=>$term_id,'meta_key'=>'category-image','meta_value'=>$_POST['category_image']));
92
+ }
93
+ }
94
+ }
95
+
96
+ function delete( $term_id ){
97
+ global $wpdb;
98
+ //delete category image and color
99
+ $wpdb->query('DELETE FROM '.EM_META_TABLE." WHERE object_id='$term_id' AND (meta_key='category-image' OR meta_key='category-bgcolor')");
100
+ //delete all events category relations
101
+ $wpdb->query('DELETE FROM '.EM_META_TABLE." WHERE meta_value='{$term_id}' AND meta_key='event-category'");
102
+ }
103
+ }
104
+ add_action('admin_init',array('EM_Categories_Taxonomy','init'));
classes/em-categories.php CHANGED
@@ -1,157 +1,321 @@
1
- <?php
2
- class EM_Categories extends EM_Object {
3
-
4
- function get( $args = array() ) {
5
- global $wpdb;
6
- $categories_table = $wpdb->prefix.EM_CATEGORIES_TABLE;
7
- $events_table = $wpdb->prefix.EM_EVENTS_TABLE;
8
-
9
- //Quick version, we can accept an array of IDs, which is easy to retrieve
10
- if( self::array_is_numeric($args) ){ //Array of numbers, assume they are event IDs to retreive
11
- //We can just get all the events here and return them
12
- $sql = "SELECT * FROM $categories_table WHERE category_id=".implode(" OR category_id=", $args);
13
- $results = $wpdb->get_results(apply_filters('em_categories_get_sql',$sql),ARRAY_A);
14
- $categories = array();
15
- foreach($results as $result){
16
- $categories[$result['category_id']] = new EM_Category($result);
17
- }
18
- return $categories; //We return all the categories matched as an EM_Event array.
19
- }
20
-
21
- //We assume it's either an empty array or array of search arguments to merge with defaults
22
- $args = self::get_default_search($args);
23
- $limit = ( $args['limit'] && is_numeric($args['limit'])) ? "LIMIT {$args['limit']}" : '';
24
- $offset = ( $limit != "" && is_numeric($args['offset']) ) ? "OFFSET {$args['offset']}" : '';
25
-
26
- //Get the default conditions
27
- $conditions = self::build_sql_conditions($args);
28
- //Put it all together
29
- $where = ( count($conditions) > 0 ) ? " WHERE " . implode ( " AND ", $conditions ):'';
30
-
31
- //Get ordering instructions
32
- $EM_Category = new EM_Category();
33
- $accepted_fields = $EM_Category->get_fields(true);
34
- $orderby = self::build_sql_orderby($args, $accepted_fields, get_option('dbem_categories_default_order'));
35
- //Now, build orderby sql
36
- $orderby_sql = ( count($orderby) > 0 ) ? 'ORDER BY '. implode(', ', $orderby) : '';
37
-
38
- //Create the SQL statement and execute
39
- $sql = "
40
- SELECT * FROM $categories_table
41
- LEFT JOIN $events_table ON {$events_table}.event_category_id={$categories_table}.category_id
42
- $where
43
- GROUP BY category_id
44
- $orderby_sql
45
- $limit $offset
46
- ";
47
- $results = $wpdb->get_results( apply_filters('em_categories_get_sql',$sql, $args), ARRAY_A);
48
- //If we want results directly in an array, why not have a shortcut here?
49
- if( $args['array'] == true ){
50
- return $results;
51
- }
52
-
53
- //Make returned results EM_Event objects
54
- $results = (is_array($results)) ? $results:array();
55
- $categories = array();
56
- foreach ( $results as $category_array ){
57
- $categories[$category_array['category_id']] = new EM_Category($category_array);
58
- }
59
-
60
- return apply_filters('em_categories_get', $categories);
61
- }
62
-
63
- /**
64
- * Will delete given an array of category_ids or EM_Event objects
65
- * @param unknown_type $id_array
66
- */
67
- function delete( $array ){
68
- global $wpdb;
69
- //Detect array type and generate SQL for event IDs
70
- $category_ids = array();
71
- if( @get_class(current($array)) == 'EM_Category' ){
72
- foreach($array as $EM_Category){
73
- $category_ids[] = $EM_Category->id;
74
- }
75
- }else{
76
- $category_ids = $array;
77
- }
78
- if(self::array_is_numeric($category_ids)){
79
- apply_filters('em_categories_delete', $category_ids);
80
- $condition = implode(" OR category_id=", $category_ids);
81
- //Delete all the bookings
82
- $result_bookings = $wpdb->query("DELETE FROM ". $wpdb->prefix . EM_BOOKINGS_TABLE ." WHERE category_id=$condition;");
83
- //Now delete the categories
84
- $result = $wpdb->query ( "DELETE FROM ". $wpdb->prefix . EM_CATEGORIES_TABLE ." WHERE category_id=$condition;" );
85
- do_action('em_categories_delete', $category_ids);
86
- }
87
- //TODO add error detection on categories delete fails
88
- return apply_filters('em_categories_delete', true, $category_ids);
89
- }
90
-
91
- /* Overrides EM_Object method to apply a filter to result
92
- * @see wp-content/plugins/categories-manager/classes/EM_Object#build_sql_conditions()
93
- */
94
- function build_sql_conditions( $args = array() ){
95
- global $wpdb;
96
- $events_table = $wpdb->prefix . EM_EVENTS_TABLE;
97
- $locations_table = $wpdb->prefix . EM_LOCATIONS_TABLE;
98
-
99
- //FIXME EM_Categories doesn't build sql conditions in EM_Object
100
- $conditions = array();
101
- //eventful locations
102
- if( true == $args['eventful'] ){
103
- $conditions['eventful'] = "{$events_table}.event_id IS NOT NULL";
104
- }elseif( true == $args['eventless'] ){
105
- $conditions['eventless'] = "{$events_table}.event_id IS NULL";
106
- }
107
- //owner lookup
108
- if( is_numeric($args['owner']) ){
109
- $conditions['owner'] = "category_owner=".get_current_user_id();
110
- }elseif( preg_match('/^([0-9],?)+$/', $args['owner']) ){
111
- $conditions['owner'] = "category_owner IN (".explode(',', $args['owner']).")";
112
- }
113
- return apply_filters( 'em_categories_build_sql_conditions', $conditions, $args );
114
- }
115
-
116
- /* Overrides EM_Object method to apply a filter to result
117
- * @see wp-content/plugins/categories-manager/classes/EM_Object#build_sql_orderby()
118
- */
119
- function build_sql_orderby( $args, $accepted_fields, $default_order = 'ASC' ){
120
- return apply_filters( 'em_categories_build_sql_orderby', parent::build_sql_orderby($args, $accepted_fields, get_option('dbem_categories_default_order')), $args, $accepted_fields, $default_order );
121
- }
122
-
123
- /*
124
- * Adds custom categories search defaults
125
- * @param array $array
126
- * @return array
127
- * @uses EM_Object#get_default_search()
128
- */
129
- function get_default_search( $array = array() ){
130
- $defaults = array(
131
- 'scope'=>false,
132
- 'eventful' => false, //cats that have an event (scope will also play a part here
133
- 'eventless' => false, //cats WITHOUT events, eventful takes precedence
134
- );
135
- if( is_admin() ){
136
- //by default, we only get categories the owner can manage
137
- switch( get_option('dbem_permissions_categories') ){
138
- case 0:
139
- $defaults['owner'] = get_current_user_id();
140
- break;
141
- case 1:
142
- $wp_user_search = new WP_User_Search(null, null, 'administrator');
143
- $users = $wp_user_search->get_results();
144
- $users[] = get_current_user_id();
145
- $users[] = 0;
146
- $defaults['owner'] = implode(',', $users);
147
- break;
148
- case 2:
149
- $defaults['owner'] = false;
150
- break;
151
- }
152
- $defaults['owner'] = ( em_verify_admin() ) ? false:$defaults['owner'];
153
- }
154
- return apply_filters('em_categories_get_default_search', parent::get_default_search($defaults,$array), $array, $defaults);
155
- }
156
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
157
  }
1
+ <?php
2
+ class EM_Categories extends EM_Object implements Iterator{
3
+
4
+ /**
5
+ * Array of EM_Category objects for a specific event
6
+ * @var array
7
+ */
8
+ var $categories = array();
9
+ /**
10
+ * Event ID of this set of categories
11
+ * @var int
12
+ */
13
+ var $event_id;
14
+ /**
15
+ * Post ID of this set of categories
16
+ * @var int
17
+ */
18
+ var $post_id;
19
+
20
+ /**
21
+ * Creates an EM_Categories instance, currently accepts an EM_Event object (gets all Categories for that event) or array of any EM_Category objects, which can be manipulated in bulk with helper functions.
22
+ * @param mixed $data
23
+ * @return null
24
+ */
25
+ function EM_Categories( $data = false ){
26
+ global $wpdb;
27
+ $this->ms_global_switch();
28
+ if( is_object($data) && get_class($data) == "EM_Event" && !empty($data->post_id) ){ //Creates a blank categories object if needed
29
+ $this->event_id = $data->event_id;
30
+ $this->post_id = $data->post_id;
31
+ if( EM_MS_GLOBAL && !is_main_site($data->blog_id) ){
32
+ $cat_ids = $wpdb->get_col('SELECT meta_value FROM '.EM_META_TABLE." WHERE object_id='{$this->event_id}' AND meta_key='event-category'");
33
+ foreach($cat_ids as $cat_id){
34
+ $this->categories[$cat_id] = new EM_Category($cat_id);
35
+ }
36
+ }else{
37
+ $results = get_the_terms( $data->post_id, EM_TAXONOMY_CATEGORY );
38
+ if( is_array($results) ){
39
+ foreach($results as $result){
40
+ $this->categories[$result->term_id] = new EM_Category($result);
41
+ }
42
+ }
43
+ }
44
+ }elseif( is_array($data) && $this->array_is_numeric($data) ){
45
+ foreach($data as $category_id){
46
+ $this->categories[$category_id] = new EM_Category($category_id);
47
+ }
48
+ }elseif( is_array($data) ){
49
+ foreach( $data as $EM_Category ){
50
+ if( get_class($EM_Category) == 'EM_Category'){
51
+ $this->categories[] = $EM_Category;
52
+ }
53
+ }
54
+ }
55
+ $this->ms_global_switch_back();
56
+ do_action('em_categories', $this);
57
+ }
58
+
59
+ function get_post(){
60
+ $this->ms_global_switch();
61
+ $this->categories = array();
62
+ if(!empty($_POST['event_categories']) && $this->array_is_numeric($_POST['event_categories'])){
63
+ foreach( $_POST['event_categories'] as $term ){
64
+ $this->categories[$term] = new EM_Category($term);
65
+ }
66
+ }
67
+ $this->ms_global_switch_back();
68
+ do_action('em_categories_get_post', $this);
69
+ }
70
+
71
+ function save(){
72
+ $term_slugs = array();
73
+ foreach($this->categories as $EM_Category){
74
+ /* @var $EM_Category EM_Category */
75
+ if( !empty($EM_Category->slug) ) $term_slugs[] = $EM_Category->slug; //save of category will soft-fail if slug is empty
76
+ }
77
+ if( count($term_slugs) == 0 && get_option('dbem_default_category') > 0 ){
78
+ $default_term = get_term_by('id',get_option('dbem_default_category'), EM_TAXONOMY_CATEGORY);
79
+ if($default_term) $term_slugs[] = $default_term->slug;
80
+ }
81
+ if( count($term_slugs) > 0 ){
82
+ if( is_multisite() ){
83
+ //In MS Global mode, we also save category meta information for global lookups
84
+ if( EM_MS_GLOBAL && !empty($this->event_id) ){
85
+ //delete categories
86
+ $this->save_index();
87
+ }
88
+ if( !EM_MS_GLOBAL || is_main_site() ){
89
+ wp_set_object_terms($this->post_id, $term_slugs, EM_TAXONOMY_CATEGORY);
90
+ }
91
+ }else{
92
+ wp_set_object_terms($this->post_id, $term_slugs, EM_TAXONOMY_CATEGORY);
93
+ }
94
+ }
95
+ do_action('em_categories_save', $this);
96
+ }
97
+
98
+ function save_index(){
99
+ global $wpdb;
100
+ $wpdb->query('DELETE FROM '.EM_META_TABLE." WHERE object_id='{$this->event_id}' AND meta_key='event-category'");
101
+ foreach($this->categories as $EM_Category){
102
+ $wpdb->insert(EM_META_TABLE, array('meta_value'=>$EM_Category->term_id,'object_id'=>$this->event_id,'meta_key'=>'event-category'));
103
+ }
104
+ }
105
+
106
+ function get( $args = array() ) {
107
+ //Quick version, we can accept an array of IDs, which is easy to retrieve
108
+ self::ms_global_switch();
109
+ if( self::array_is_numeric($args) ){ //Array of numbers, assume they are event IDs to retreive
110
+ $results = get_terms( EM_TAXONOMY_CATEGORY );
111
+ $categories = array();
112
+ foreach($results as $result){
113
+ if( in_array($result->term_id, $args) ){
114
+ $categories[$result->term_id] = new EM_Category($result);
115
+ }
116
+ }
117
+ }else{
118
+ //We assume it's either an empty array or array of search arguments to merge with defaults
119
+ $term_args = self::get_default_search($args);
120
+ $results = get_terms( EM_TAXONOMY_CATEGORY, $term_args);
121
+
122
+ //If we want results directly in an array, why not have a shortcut here? We don't use this in code, so if you're using it and filter the em_categories_get hook, you may want to do this one too.
123
+ if( !empty($args['array']) ){
124
+ return apply_filters('em_categories_get_array', $results, $args);
125
+ }
126
+
127
+ //Make returned results EM_Category objects
128
+ $results = (is_array($results)) ? $results:array();
129
+ $categories = array();
130
+ foreach ( $results as $category ){
131
+ $categories[$category->term_id] = new EM_Category($category);
132
+ }
133
+ }
134
+ self::ms_global_switch_back();
135
+ return apply_filters('em_categories_get', $categories, $args);
136
+ }
137
+
138
+ function output( $args ){
139
+ global $EM_Category;
140
+ $EM_Category_old = $EM_Category; //When looping, we can replace EM_Category global with the current event in the loop
141
+ //Can be either an array for the get search or an array of EM_Category objects
142
+ if( is_object(current($args)) && get_class((current($args))) == 'EM_Category' ){
143
+ $func_args = func_get_args();
144
+ $categories = $func_args[0];
145
+ $args = (!empty($func_args[1])) ? $func_args[1] : array();
146
+ $args = apply_filters('em_categories_output_args', self::get_default_search($args), $categories);
147
+ $limit = ( !empty($args['limit']) && is_numeric($args['limit']) ) ? $args['limit']:false;
148
+ $offset = ( !empty($args['offset']) && is_numeric($args['offset']) ) ? $args['offset']:0;
149
+ $page = ( !empty($args['page']) && is_numeric($args['page']) ) ? $args['page']:1;
150
+ }else{
151
+ $args = apply_filters('em_categories_output_args', self::get_default_search($args) );
152
+ $limit = ( !empty($args['limit']) && is_numeric($args['limit']) ) ? $args['limit']:false;
153
+ $offset = ( !empty($args['offset']) && is_numeric($args['offset']) ) ? $args['offset']:0;
154
+ $page = ( !empty($args['page']) && is_numeric($args['page']) ) ? $args['page']:1;
155
+ $args['limit'] = false;
156
+ $args['offset'] = false;
157
+ $args['page'] = false;
158
+ $categories = self::get( $args );
159
+ }
160
+ //What format shall we output this to, or use default
161
+ $format = ( $args['format'] == '' ) ? get_option( 'dbem_categories_list_item_format' ) : $args['format'] ;
162
+
163
+ $output = "";
164
+ $categories_count = count($categories);
165
+ $categories = apply_filters('em_categories_output_categories', $categories);
166
+ if ( count($categories) > 0 ) {
167
+ $category_count = 0;
168
+ $categories_shown = 0;
169
+ foreach ( $categories as $EM_Category ) {
170
+ if( ($categories_shown < $limit || empty($limit)) && ($category_count >= $offset || $offset === 0) ){
171
+ $output .= $EM_Category->output($format);
172
+ $categories_shown++;
173
+ }
174
+ $category_count++;
175
+ }
176
+ //Add headers and footers to output
177
+ if( $format == get_option ( 'dbem_categories_list_item_format' ) ){
178
+ $single_event_format_header = get_option ( 'dbem_categories_list_item_format_header' );
179
+ $single_event_format_header = ( $single_event_format_header != '' ) ? $single_event_format_header : "<ul class='em-categories-list'>";
180
+ $single_event_format_footer = get_option ( 'dbem_categories_list_item_format_footer' );
181
+ $single_event_format_footer = ( $single_event_format_footer != '' ) ? $single_event_format_footer : "</ul>";
182
+ $output = $single_event_format_header . $output . $single_event_format_footer;
183
+ }
184
+ //Pagination (if needed/requested)
185
+ if( !empty($args['pagination']) && !empty($limit) && $categories_count >= $limit ){
186
+ //Show the pagination links (unless there's less than 10 events, or the custom limit)
187
+ $page_link_template = preg_replace('/(&|\?)page=\d+/i','',$_SERVER['REQUEST_URI']);
188
+ $page_link_template = em_add_get_params($page_link_template, array('page'=>'%PAGE%'), false); //don't html encode, so em_paginate does its thing
189
+ $output .= apply_filters('em_events_output_pagination', em_paginate( $page_link_template, $categories_count, $limit, $page), $page_link_template, $categories_count, $limit, $page);
190
+ }
191
+ } else {
192
+ $output = get_option ( 'dbem_no_categories_message' );
193
+ }
194
+ //FIXME check if reference is ok when restoring object, due to changes in php5 v 4
195
+ $EM_Category_old= $EM_Category;
196
+ return apply_filters('em_categories_output', $output, $categories, $args);
197
+ }
198
+
199
+ function has( $search ){
200
+ if( is_numeric($search) ){
201
+ foreach($this->categories as $EM_Category){
202
+ if($EM_Category->term_id == $search) return apply_filters('em_categories_has', true, $search, $this);
203
+ }
204
+ }else{
205
+ foreach($this->categories as $EM_Category){
206
+ if($EM_Category->slug == $search) return apply_filters('em_categories_has', true, $search, $this);
207
+ }
208
+ }
209
+ return apply_filters('em_categories_has', false, $search, $this);
210
+ }
211
+
212
+ function get_first(){
213
+ foreach($this->categories as $EM_Category){
214
+ return $EM_Category;
215
+ }
216
+ return false;
217
+ }
218
+
219
+ function get_ids(){
220
+ $ids = array();
221
+ foreach($this->categories as $EM_Category){
222
+ if( !empty($EM_Category->term_id) ){
223
+ $ids[] = $EM_Category->term_id;
224
+ }
225
+ }
226
+ return $ids;
227
+ }
228
+
229
+ /**
230
+ * Gets the event for this object, or a blank event if none exists
231
+ * @return EM_Event
232
+ */
233
+ function get_event(){
234
+ if( is_numeric($this->event_id) ){
235
+ return em_get_event($this->event_id);
236
+ }else{
237
+ return new EM_Event();
238
+ }
239
+ }
240
+
241
+ /* Overrides EM_Object method to apply a filter to result. Categories won't accept many arguments as you tend to search with events for much else.
242
+ * @see wp-content/plugins/categories-manager/classes/EM_Object#build_sql_conditions()
243
+ */
244
+ function build_sql_conditions( $args = array() ){
245
+ global $wpdb;
246
+ $events_table = EM_EVENTS_TABLE;
247
+ $locations_table = EM_LOCATIONS_TABLE;
248
+
249
+ $temp_conditions = parent::build_sql_conditions($args);
250
+ $conditions = array();
251
+ if( !empty($temp_conditions['category']) ){
252
+ $conditions['category'] = $temp_conditions['category'];
253
+ }
254
+ return apply_filters( 'em_categories_build_sql_conditions', $conditions, $args );
255
+ }
256
+
257
+ /* Overrides EM_Object method to apply a filter to result
258
+ * @see wp-content/plugins/categories-manager/classes/EM_Object#build_sql_orderby()
259
+ */
260
+ function build_sql_orderby( $args, $accepted_fields, $default_order = 'ASC' ){
261
+ return apply_filters( 'em_categories_build_sql_orderby', parent::build_sql_orderby($args, $accepted_fields, get_option('dbem_categories_default_order')), $args, $accepted_fields, $default_order );
262
+ }
263
+
264
+ /*
265
+ * Adds custom categories search defaults
266
+ * @param array $array
267
+ * @return array
268
+ * @uses EM_Object#get_default_search()
269
+ */
270
+ function get_default_search( $array = array() ){
271
+ $defaults = array(
272
+ //added from get_terms, so they don't get filtered out
273
+ 'orderby' => 'name', 'order' => 'ASC',
274
+ 'hide_empty' => false, 'exclude' => array(), 'exclude_tree' => array(), 'include' => array(),
275
+ 'number' => '', 'fields' => 'all', 'slug' => '', 'parent' => '',
276
+ 'hierarchical' => true, 'child_of' => 0, 'get' => '', 'name__like' => '',
277
+ 'pad_counts' => false, 'offset' => '', 'search' => '', 'cache_domain' => 'core'
278
+ );
279
+ return apply_filters('em_categories_get_default_search', parent::get_default_search($defaults,$array), $array, $defaults);
280
+ }
281
+
282
+ /**
283
+ * will return the default search parameter to use according to permission settings
284
+ * @return string
285
+ */
286
+ function get_default_search_owner(){
287
+ //by default, we only get categories the owner can manage
288
+ $defaults = array('owner'=>false);
289
+ //by default, we only get categories the owner can manage
290
+ if( !current_user_can('edit_categories') ){
291
+ $defaults['owner'] = get_current_user_id();
292
+ break;
293
+ }else{
294
+ $defaults['owner'] = false;
295
+ break;
296
+ }
297
+ return $defaults['owner'];
298
+ }
299
+
300
+ //Iterator Implementation
301
+ public function rewind(){
302
+ reset($this->categories);
303
+ }
304
+ public function current(){
305
+ $var = current($this->categories);
306
+ return $var;
307
+ }
308
+ public function key(){
309
+ $var = key($this->categories);
310
+ return $var;
311
+ }
312
+ public function next(){
313
+ $var = next($this->categories);
314
+ return $var;
315
+ }
316
+ public function valid(){
317
+ $key = key($this->categories);
318
+ $var = ($key !== NULL && $key !== FALSE);
319
+ return $var;
320
+ }
321
  }
classes/em-category-taxonomy.php ADDED
@@ -0,0 +1,121 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class EM_Category_Taxonomy{
3
+ function init(){
4
+ if( !is_admin() ){
5
+ add_filter('archive_template', array('EM_Category_Taxonomy','template'));
6
+ add_filter('category_template', array('EM_Category_Taxonomy','template'));
7
+ add_filter('parse_query', array('EM_Category_Taxonomy','parse_query'));
8
+ }
9
+ }
10
+ /**
11
+ * Overrides archive pages e.g. locations, events, event categories, event tags based on user settings
12
+ * @param string $template
13
+ * @return string
14
+ */
15
+ function template($template){
16
+ global $wp_query, $EM_Category;
17
+ if( is_archive() ){
18
+ if( !empty($wp_query->queried_object->taxonomy) && $wp_query->queried_object->taxonomy == EM_TAXONOMY_CATEGORY && get_option('dbem_cp_categories_formats', true)){
19
+ $EM_Category = em_get_category($wp_query->queried_object->term_id);
20
+ add_filter('the_content', array('EM_Category_Taxonomy','the_content'));
21
+ $wp_query->posts = array();
22
+ $wp_query->posts[0] = new stdClass();
23
+ $wp_query->posts[0]->post_title = $EM_Category->output(get_option('dbem_category_page_title_format'));
24
+ $post_array = array('ID', 'post_author', 'post_date','post_date_gmt','post_content','post_excerpt','post_status','comment_status','ping_status','post_password','post_name','to_ping','pinged','post_modified','post_modified_gmt','post_content_filtered','post_parent','guid','menu_order','post_type','post_mime_type','comment_count','filter');
25
+ foreach($post_array as $post_array_item){
26
+ $wp_query->posts[0]->$post_array_item = '';
27
+ }
28
+ $wp_query->post = $wp_query->posts[0];
29
+ $wp_query->post_count = 1;
30
+ $wp_query->found_posts = 1;
31
+ $wp_query->max_num_pages = 1;
32
+ //echo "<pre>"; print_r($wp_query); echo "</pre>";
33
+ $template = locate_template(array('page.php','index.php'),false); //category becomes a page
34
+ }
35
+ }
36
+ return $template;
37
+ }
38
+
39
+ function the_content($content){
40
+ global $wp_query, $EM_Category;
41
+ $EM_Category = new EM_Category($wp_query->queried_object);
42
+ ob_start();
43
+ em_locate_template('templates/category-single.php',true);
44
+ return ob_get_clean();
45
+ }
46
+
47
+ function parse_query( ){
48
+ global $wp_query;
49
+ if( !empty($wp_query->tax_query->queries[0]['taxonomy']) && $wp_query->tax_query->queries[0]['taxonomy'] == EM_TAXONOMY_CATEGORY) {
50
+ //Scope is future
51
+ $today = strtotime(date('Y-m-d', current_time('timestamp')));
52
+ if( get_option('dbem_events_current_are_past') ){
53
+ $wp_query->query_vars['meta_query'][] = array( 'key' => '_start_ts', 'value' => $today, 'compare' => '>=' );
54
+ }else{
55
+ $wp_query->query_vars['meta_query'][] = array( 'key' => '_end_ts', 'value' => $today, 'compare' => '>=' );
56
+ }
57
+ if( get_option('dbem_categories_default_archive_orderby') == 'title'){
58
+ $wp_query->query_vars['orderby'] = 'title';
59
+ }else{
60
+ $wp_query->query_vars['orderby'] = 'meta_value_num';
61
+ $wp_query->query_vars['meta_key'] = get_option('dbem_categories_default_archive_orderby','_start_ts');
62
+ }
63
+ $wp_query->query_vars['order'] = get_option('dbem_categories_default_archive_order','ASC');
64
+ }
65
+ }
66
+ }
67
+ EM_Category_Taxonomy::init();
68
+
69
+ /**
70
+ * Create an array of Categories. Copied from Walker_CategoryDropdown, but makes it possible for the selected argument to be an array.
71
+ *
72
+ * @package WordPress
73
+ * @since 2.1.0
74
+ * @uses Walker
75
+ */
76
+ class EM_Walker_CategoryMultiselect extends Walker {
77
+ /**
78
+ * @see Walker::$tree_type
79
+ * @since 2.1.0
80
+ * @var string
81
+ */
82
+ var $tree_type = 'event-category';
83
+
84
+ /**
85
+ * @see Walker::$db_fields
86
+ * @since 2.1.0
87
+ * @todo Decouple this
88
+ * @var array
89
+ */
90
+ var $db_fields = array ('parent' => 'parent', 'id' => 'term_id');
91
+
92
+ function __construct(){
93
+ $tree_type = EM_TAXONOMY_CATEGORY;
94
+ }
95
+ /**
96
+ * @see Walker::start_el()
97
+ * @since 2.1.0
98
+ *
99
+ * @param string $output Passed by reference. Used to append additional content.
100
+ * @param object $category Category data object.
101
+ * @param int $depth Depth of category. Used for padding.
102
+ * @param array $args Uses 'selected', 'show_count', and 'show_last_update' keys, if they exist.
103
+ */
104
+ function start_el(&$output, $category, $depth, $args) {
105
+ $pad = str_repeat('&nbsp;', $depth * 3);
106
+
107
+ $cat_name = apply_filters('list_cats', $category->name, $category);
108
+ $output .= "\t<option class=\"level-$depth\" value=\"".$category->term_id."\"";
109
+ if ( (is_array($args['selected']) && in_array($category->term_id, $args['selected'])) || ($category->term_id == $args['selected']) )
110
+ $output .= ' selected="selected"';
111
+ $output .= '>';
112
+ $output .= $pad.$cat_name;
113
+ if ( $args['show_count'] )
114
+ $output .= '&nbsp;&nbsp;('. $category->count .')';
115
+ if ( $args['show_last_update'] ) {
116
+ $format = 'Y-m-d';
117
+ $output .= '&nbsp;&nbsp;' . gmdate($format, $category->last_update_timestamp);
118
+ }
119
+ $output .= "</option>\n";
120
+ }
121
+ }
classes/em-category.php CHANGED
@@ -1,152 +1,216 @@
1
- <?php
2
- //TODO expand em_category to be like other classes
3
- class EM_Category extends EM_Object {
4
- //DB Fields
5
- var $id = '';
6
- var $owner = '';
7
- var $name = '';
8
- //Other Vars
9
- var $fields = array(
10
- 'category_id' => array('name'=>'id','type'=>'%d'),
11
- 'category_owner' => array('name'=>'owner','type'=>'%d'),
12
- 'category_name' => array('name'=>'name','type'=>'%s')
13
- );
14
- var $required_fields;
15
- var $feedback_message = "";
16
- var $errors = array();
17
-
18
- /**
19
- * Gets data from POST (default), supplied array, or from the database if an ID is supplied
20
- * @param $location_data
21
- * @return null
22
- */
23
- function EM_Category( $category_data = false ) {
24
- //Initialize
25
- $this->required_fields = array("category_name" => __('The category name', 'dbem'));
26
- $category = array();
27
- if( $category_data != false ){
28
- //Load location data
29
- if( is_array($category_data) && isset($category_data['category_name']) ){
30
- $category = $category_data;
31
- }elseif( is_numeric($category_data) ){
32
- //Retreiving from the database
33
- global $wpdb;
34
- $sql = "SELECT * FROM ". $wpdb->prefix.EM_CATEGORIES_TABLE ." WHERE category_id ='{$category_data}'";
35
- $category = $wpdb->get_row($sql, ARRAY_A);
36
- }
37
- //Save into the object
38
- $this->to_object($category);
39
- }
40
- }
41
-
42
- function get_post(){
43
- //We are getting the values via POST or GET
44
- do_action('em_location_get_post_pre', $this);
45
- $category = array();
46
- $category['category_id'] = ( !empty($_POST['category_id']) ) ? $_POST['category_id']:'';
47
- $category['category_name'] = ( !empty($_POST['category_name']) ) ? stripslashes($_POST['category_name']):'';
48
- $category['category_owner'] = ( !empty($_POST['category_owner']) && is_numeric($_POST['category_owner']) ) ? $_POST['category_owner']:get_current_user_id();
49
- $this->to_object( apply_filters('em_category_get_post', $category, $this) );
50
- }
51
-
52
- function save(){
53
- global $wpdb;
54
- do_action('em_category_save_pre', $this);
55
- $table = $wpdb->prefix.EM_CATEGORIES_TABLE;
56
- $data = $this->to_array();
57
- unset($data['category_id']);
58
- if($this->id != ''){
59
- $where = array( 'category_id' => $this->id );
60
- $wpdb->update($table, $data, $where, $this->get_types($data));
61
- }else{
62
- $wpdb->insert($table, $data, $this->get_types($data));
63
- $this->id = $wpdb->insert_id;
64
- }
65
- return apply_filters('em_category_save', ( $this->id > 0 && $image_upload ), $this, $image_upload);
66
- }
67
-
68
- function delete(){
69
- global $wpdb;
70
- do_action('em_category_delete_pre', $this);
71
- $table_name = $wpdb->prefix.EM_CATEGORIES_TABLE;
72
- $sql = "DELETE FROM $table_name WHERE category_id = '{$this->id}';";
73
- $result = $wpdb->query($sql);
74
- return apply_filters('em_category_delete', $result, $this);
75
- }
76
-
77
- /**
78
- * Validates the category. Should be run during any form submission or saving operation.
79
- * @return boolean
80
- */
81
- function validate(){
82
- $missing_fields = Array ();
83
- foreach ( $this->required_fields as $key => $field ) {
84
- $true_field = $this->fields[$key]['name'];
85
- if ( $this->$true_field == "") {
86
- $missing_fields[] = $field;
87
- }
88
- }
89
- if ( count($missing_fields) > 0){
90
- // TODO Create friendly equivelant names for missing fields notice in validation
91
- $this->errors[] = __ ( 'Missing fields: ' ) . implode ( ", ", $missing_fields ) . ". ";
92
- }
93
- return apply_filters('em_category_validate', ( count($this->errors) == 0 ), $this);
94
- }
95
-
96
- function has_events(){
97
- global $wpdb;
98
- $events_table = $wpdb->prefix.EM_EVENTS_TABLE;
99
- $sql = "SELECT count(event_id) as events_no FROM $events_table WHERE category_id = {$this->id}";
100
- $affected_events = $wpdb->get_row($sql);
101
- return apply_filters('em_category_has_events', (count($affected_events) > 0), $this);
102
- }
103
-
104
- function output_single($target = 'html'){
105
- $format = get_option ( 'dbem_single_category_format' );
106
- return apply_filters('em_category_output_single', $this->output($format, $target), $this, $target);
107
- }
108
-
109
- function output($format, $target="html") {
110
- $category_string = $format;
111
- preg_match_all("/#_[A-Za-z]+/", $format, $placeholders);
112
- foreach($placeholders[0] as $result) {
113
- $match = true;
114
- $replace = '';
115
- switch( $result ){
116
- case '#_CATEGORYNAME':
117
- $replace = $this->name;
118
- break;
119
- case '#_CATEGORYID':
120
- $replace = $this->id;
121
- break;
122
- default:
123
- $match = false;
124
- break;
125
- }
126
- if($match){ //if true, we've got a placeholder that needs replacing
127
- //TODO FILTER - placeholder filter
128
- $replace = apply_filters('em_category_output_placeholder', $replace, $this, $result, $target); //USE WITH CAUTION! THIS MIGHT GET RENAMED
129
- $category_string = str_replace($result, $replace , $category_string );
130
- }
131
- }
132
- $name_filter = ($target == "html") ? 'dbem_general':'dbem_general_rss'; //TODO remove dbem_ filters
133
- $category_string = str_replace('#_CATEGORY', apply_filters($name_filter, $this->name) , $category_string ); //Depreciated
134
- return apply_filters('em_category_output', $category_string, $this, $format, $target);
135
- }
136
-
137
- function can_manage(){
138
- return ( get_option('dbem_permissions_categories') == 2 || $this->owner == get_current_user_id() || empty($this->id) || em_verify_admin() );
139
- }
140
-
141
- function can_use(){
142
- switch( get_option('dbem_permissions_locations') ){
143
- case 0:
144
- return $this->owner == get_current_user_id();
145
- case 1:
146
- return em_verify_admin($this->owner);
147
- case 2:
148
- return true;
149
- }
150
- }
151
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
152
  ?>
1
+ <?php
2
+ /**
3
+ * Get an category in a db friendly way, by checking globals and passed variables to avoid extra class instantiations
4
+ * @param mixed $id
5
+ * @return EM_Category
6
+ */
7
+ function em_get_category($id = false) {
8
+ global $EM_Category;
9
+ //check if it's not already global so we don't instantiate again
10
+ if( is_object($EM_Category) && get_class($EM_Category) == 'EM_Category' ){
11
+ if( $EM_Category->term_id == $id ){
12
+ return $EM_Category;
13
+ }elseif( is_object($id) && $EM_Category->term_id == $id->term_id ){
14
+ return $EM_Category;
15
+ }
16
+ }
17
+ if( is_object($id) && get_class($id) == 'EM_Category' ){
18
+ return $id;
19
+ }else{
20
+ return new EM_Category($id);
21
+ }
22
+ }
23
+ class EM_Category extends EM_Object {
24
+ //Taxonomy Fields
25
+ var $id = '';
26
+ var $term_id;
27
+ var $name;
28
+ var $slug;
29
+ var $term_group;
30
+ var $term_taxonomy_id;
31
+ var $taxonomy;
32
+ var $description = '';
33
+ var $parent = 0;
34
+ var $count;
35
+ //extra attributes imposed by EM_Category
36
+ var $image_url = '';
37
+ var $color;
38
+
39
+ /**
40
+ * Gets data from POST (default), supplied array, or from the database if an ID is supplied
41
+ * @param $category_data
42
+ * @return null
43
+ */
44
+ function EM_Category( $category_data = false ) {
45
+ global $wpdb;
46
+ $this->ms_global_switch();
47
+ //Initialize
48
+ $category = array();
49
+ if( !empty($category_data) ){
50
+ //Load category data
51
+ if( is_object($category_data) && !empty($category_data->taxonomy) && $category_data->taxonomy == EM_TAXONOMY_CATEGORY ){
52
+ $category = $category_data;
53
+ }elseif( !is_numeric($category_data) ){
54
+ $category = get_term_by('slug', $category_data, EM_TAXONOMY_CATEGORY);
55
+ }else{
56
+ $category = get_term_by('id', $category_data, EM_TAXONOMY_CATEGORY);
57
+ }
58
+ }
59
+ if( is_object($category) || is_array($category) ){
60
+ foreach($category as $key => $value){
61
+ $this->$key = $value;
62
+ }
63
+ }
64
+ $this->id = $this->term_id; //backward compatability
65
+ $this->ms_global_switch_back();
66
+ do_action('em_category',$this, $category_data);
67
+ }
68
+
69
+ function get_color(){
70
+ if( empty($this->color) ){
71
+ global $wpdb;
72
+ $color = $wpdb->get_var('SELECT meta_value FROM '.EM_META_TABLE." WHERE object_id='{$this->term_id}' AND meta_key='category-bgcolor' LIMIT 1");
73
+ $this->color = ($color != '') ? $color:'#FFFFFF';
74
+ }
75
+ return $this->color;
76
+ }
77
+
78
+ function get_image_url(){
79
+ if( empty($this->image_url) ){
80
+ global $wpdb;
81
+ $image_url = $wpdb->get_var('SELECT meta_value FROM '.EM_META_TABLE." WHERE object_id='{$this->term_id}' AND meta_key='category-image' LIMIT 1");
82
+ $this->image_url = ($image_url != '') ? $image_url:'';
83
+ }
84
+ return $this->image_url;
85
+ }
86
+
87
+ function get_url(){
88
+ if( empty($this->link) ){
89
+ $this->ms_global_switch();
90
+ $this->link = get_term_link($this->slug, EM_TAXONOMY_CATEGORY);
91
+ $this->ms_global_switch_back();
92
+ if ( is_wp_error($this->link) ) $this->link = '';
93
+ }
94
+ return $this->link;
95
+ }
96
+
97
+ /**
98
+ * Depreciated, don't use.
99
+ * @return mixed
100
+ */
101
+ function has_events(){
102
+ global $wpdb;
103
+ return false;
104
+ }
105
+
106
+ function output_single($target = 'html'){
107
+ $format = get_option ( 'dbem_category_page_format' );
108
+ return apply_filters('em_category_output_single', $this->output($format, $target), $this, $target);
109
+ }
110
+
111
+ function output($format, $target="html") {
112
+ preg_match_all('/\{([a-zA-Z0-9_]+)\}([^{]+)\{\/[a-zA-Z0-9_]+\}/', $format, $conditionals);
113
+ if( count($conditionals[0]) > 0 ){
114
+ //Check if the language we want exists, if not we take the first language there
115
+ foreach($conditionals[1] as $key => $condition){
116
+ $format = str_replace($conditionals[0][$key], apply_filters('em_category_output_condition', '', $condition, $conditionals[0][$key], $this), $format);
117
+ }
118
+ }
119
+ $category_string = $format;
120
+ preg_match_all("/(#@?_?[A-Za-z0-9]+)({([a-zA-Z0-9,]+)})?/", $format, $placeholders);
121
+ foreach($placeholders[1] as $key => $result) {
122
+ $replace = '';
123
+ $full_result = $placeholders[0][$key];
124
+ switch( $result ){
125
+ case '#_CATEGORYNAME':
126
+ $replace = $this->name;
127
+ break;
128
+ case '#_CATEGORYID':
129
+ $replace = $this->term_id;
130
+ break;
131
+ case '#_CATEGORYNOTES':
132
+ case '#_CATEGORYDESCRIPTION':
133
+ $replace = $this->description;
134
+ break;
135
+ case '#_CATEGORYIMAGE':
136
+ case '#_CATEGORYIMAGEURL':
137
+ if( $this->get_image_url() != ''){
138
+ if($result == '#_CATEGORYIMAGEURL'){
139
+ $replace = $this->get_image_url();
140
+ }else{
141
+ if( empty($placeholders[3][$key]) ){
142
+ $replace = "<img src='".esc_url($this->get_image_url())."' alt='".esc_attr($this->name)."'/>";
143
+ }else{
144
+ $image_size = explode(',', $placeholders[3][$key]);
145
+ if( $this->array_is_numeric($image_size) && count($image_size) > 1 ){
146
+ $replace = "<img src='".em_get_thumbnail_url($this->get_image_url(), $image_size[0], $image_size[1])."' alt='".esc_attr($this->name)."'/>";
147
+ }else{
148
+ $replace = "<img src='".esc_url($this->get_image_url())."' alt='".esc_attr($this->name)."'/>";
149
+ }
150
+ }
151
+ }
152
+ }
153
+ break;
154
+ case '#_CATEGORYCOLOR':
155
+ $replace = $this->get_color();
156
+ break;
157
+ case '#_CATEGORYLINK':
158
+ case '#_CATEGORYURL':
159
+ $link = $this->get_url();
160
+ $replace = ($result == '#_CATEGORYURL') ? $link : '<a href="'.$link.'">'.esc_html($this->name).'</a>';
161
+ break;
162
+ case '#_CATEGORYEVENTSPAST': //depreciated, erroneous documentation, left for compatability
163
+ case '#_CATEGORYEVENTSNEXT': //depreciated, erroneous documentation, left for compatability
164
+ case '#_CATEGORYEVENTSALL': //depreciated, erroneous documentation, left for compatability
165
+ case '#_CATEGORYPASTEVENTS':
166
+ case '#_CATEGORYNEXTEVENTS':
167
+ case '#_CATEGORYALLEVENTS':
168
+ //convert depreciated placeholders for compatability
169
+ $result = ($result == '#_CATEGORYEVENTSPAST') ? '#_CATEGORYPASTEVENTS':$result;
170
+ $result = ($result == '#_CATEGORYEVENTSNEXT') ? '#_CATEGORYNEXTEVENTS':$result;
171
+ $result = ($result == '#_CATEGORYEVENTSALL') ? '#_CATEGORYALLEVENTS':$result;
172
+ //forget it ever happened? :/
173
+ if ($result == '#_CATEGORYPASTEVENTS'){ $scope = 'past'; }
174
+ elseif ( $result == '#_CATEGORYNEXTEVENTS' ){ $scope = 'future'; }
175
+ else{ $scope = 'all'; }
176
+ $events = EM_Events::get( array('category'=>$this->term_id, 'scope'=>$scope) );
177
+ if ( count($events) > 0 ){
178
+ $replace .= get_option('dbem_category_event_list_item_header_format','<ul>');
179
+ foreach($events as $EM_Event){
180
+ $replace .= $EM_Event->output(get_option('dbem_category_event_list_item_format'));
181
+ }
182
+ $replace .= get_option('dbem_category_event_list_item_footer_format');
183
+ } else {
184
+ $replace = get_option('dbem_category_no_events_message','</ul>');
185
+ }
186
+ break;
187
+ default:
188
+ $replace = $full_result;
189
+ break;
190
+ }
191
+ $replace = apply_filters('em_category_output_placeholder', $replace, $this, $full_result, $target); //USE WITH CAUTION! THIS MIGHT GET RENAMED
192
+ $category_string = str_replace($full_result, $replace , $category_string );
193
+ }
194
+ $name_filter = ($target == "html") ? 'dbem_general':'dbem_general_rss'; //TODO remove dbem_ filters
195
+ $category_string = str_replace('#_CATEGORY', apply_filters($name_filter, $this->name) , $category_string ); //Depreciated
196
+ return apply_filters('em_category_output', $category_string, $this, $format, $target);
197
+ }
198
+
199
+ function can_manage( $capability_owner = 'edit_categories', $capability_admin = false ){
200
+ global $em_capabilities_array;
201
+ //Figure out if this is multisite and require an extra bit of validation
202
+ $multisite_check = true;
203
+ $can_manage = current_user_can($capability_owner);
204
+ //if multisite and supoer admin, just return true
205
+ if( is_multisite() && is_super_admin() ){ return true; }
206
+ if( EM_MS_GLOBAL && !is_main_site() ){
207
+ //User can't admin this bit, as they're on a sub-blog
208
+ $can_manage = false;
209
+ if(array_key_exists($capability_owner, $em_capabilities_array) ){
210
+ $this->add_error( $em_capabilities_array[$capability_owner]);
211
+ }
212
+ }
213
+ return $can_manage;
214
+ }
215
+ }
216
  ?>
classes/em-event-post-admin.php ADDED
@@ -0,0 +1,382 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Events Edit Page
4
+ */
5
+ class EM_Event_Post_Admin{
6
+ function init(){
7
+ global $pagenow;
8
+ if($pagenow == 'post.php' || $pagenow == 'post-new.php' ){ //only needed if editing post
9
+ add_action('admin_head', array('EM_Event_Post_Admin','admin_head'));
10
+ //Meta Boxes
11
+ add_action('add_meta_boxes', array('EM_Event_Post_Admin','meta_boxes'));
12
+ //Notices
13
+ add_action('admin_notices',array('EM_Event_Post_Admin','admin_notices'));
14
+ }
15
+ //Save/Edit actions
16
+ add_action('save_post',array('EM_Event_Post_Admin','save_post'),10,1);
17
+ add_action('before_delete_post',array('EM_Event_Post_Admin','before_delete_post'),10,1);
18
+ add_action('trashed_post',array('EM_Event_Post_Admin','trashed_post'),10,1);
19
+ add_action('untrash_post',array('EM_Event_Post_Admin','untrash_post'),10,1);
20
+ add_action('untrashed_post',array('EM_Event_Post_Admin','untrashed_post'),10,1);
21
+ //Notices
22
+ add_action('post_updated_messages',array('EM_Event_Post_Admin','admin_notices_filter'),1,1);
23
+ }
24
+
25
+ function admin_head(){
26
+ global $post, $EM_Event;
27
+ if( !empty($post) && $post->post_type == EM_POST_TYPE_EVENT ){
28
+ $EM_Event = em_get_event($post->ID, 'post_id');
29
+ }
30
+ }
31
+
32
+ function admin_notices(){
33
+ //When editing
34
+ global $post, $EM_Event, $pagenow;
35
+ if( $pagenow == 'post.php' && ($post->post_type == EM_POST_TYPE_EVENT || $post->post_type == 'event-recurring') ){
36
+ if ( $EM_Event->is_recurring() ) {
37
+ $warning = "<p><strong>".__( 'WARNING: This is a recurring event.', 'dbem' )."</strong></p>";
38
+ $warning .= "<p>". __( 'Modifications to this event will cause all recurrences of this event to be deleted and recreated and previous bookings will be deleted! You can edit individual recurrences and disassociate them with this recurring event.', 'dbem' );
39
+ ?><div class="updated"><?php echo $warning; ?></div><?php
40
+ } elseif ( $EM_Event->is_recurrence() ) {
41
+ $warning = "<p><strong>".__('WARNING: This is a recurrence in a set of recurring events.', 'dbem')."</strong></p>";
42
+ $warning .= "<p>". sprintf(__('If you update this event data and save, it could get overwritten if you edit the recurring event template. To make it an independent, <a href="%s">detach it</a>.', 'dbem' ), $EM_Event->get_detach_url())."</p>";
43
+ $warning .= "<p>".sprintf(__('To manage the whole set, <a href="%s">edit the recurring event template</a>.', 'dbem'),admin_url('post.php?action=edit&amp;post='.$EM_Event->get_event_recurrence()->post_id))."</p>";
44
+ ?><div class="updated"><?php echo $warning; ?></div><?php
45
+ }
46
+ if( !empty($EM_Event->group_id) && function_exists('groups_get_group') ){
47
+ $group = groups_get_group(array('group_id'=>$EM_Event->group_id));
48
+ $warning = sprintf(__('WARNING: This is a event belonging to the group "%s". Other group admins can also modify this event.', 'dbem'), $group->name);
49
+ ?><div class="updated"><p><?php echo $warning; ?></p></div><?php
50
+ }
51
+ }
52
+ }
53
+
54
+ function admin_notices_filter($messages){
55
+ //When editing
56
+ global $post, $EM_Notices;
57
+ if( $post->post_type == EM_POST_TYPE_EVENT || $post->post_type == 'event-recurring' ){
58
+ if ( $EM_Notices->count_errors() > 0 ) {
59
+ unset($_GET['message']);
60
+ }
61
+ }
62
+ return $messages;
63
+ }
64
+
65
+ function save_post($post_id){
66
+ global $wpdb, $EM_Event, $EM_Location, $EM_Notices;
67
+ $post_type = get_post_type($post_id);
68
+ $is_post_type = $post_type == EM_POST_TYPE_EVENT || $post_type == 'event-recurring';
69
+ $saving_status = !in_array(get_post_status($post_id), array('trash','auto-draft')) && !defined('DOING_AUTOSAVE');
70
+ if(!defined('UNTRASHING_'.$post_id) && $is_post_type && $saving_status ){
71
+ if( wp_verify_nonce($_REQUEST['_emnonce'], 'edit_event') ){
72
+ //this is only run if we know form data was submitted, hence the nonce
73
+ $EM_Event = em_get_event($post_id, 'post_id');
74
+ do_action('em_event_save_pre', $EM_Event); //technically, the event is saved... but the meta isn't. wp doesn't give an pre-intervention action for this (or does it?)
75
+ //Handle Errors by making post draft
76
+ $get_meta = $EM_Event->get_post_meta();
77
+ $save_meta = $EM_Event->save_meta();
78
+ $EM_Event->get_categories()->save(); //save categories in case of default category
79
+ if( !$get_meta || !$save_meta ){
80
+ //failed somewhere, set to draft, don't publish
81
+ $EM_Event->set_status(null, true);
82
+ if( $EM_Event->is_recurring() ){
83
+ $EM_Notices->add_error( '<strong>'.__('Your event details are incorrect and recurrences cannot be created, please correct these errors first:','dbem').'</strong>', true); //Always seems to redirect, so we make it static
84
+ }else{
85
+ $EM_Notices->add_error( '<strong>'.sprintf(__('Your %s details are incorrect and cannot be published, please correct these errors first:','dbem'),__('event','dbem')).'</strong>', true); //Always seems to redirect, so we make it static
86
+ }
87
+ $EM_Notices->add_error($EM_Event->get_errors(), true); //Always seems to redirect, so we make it static
88
+ apply_filters('em_event_save', false, $EM_Event);
89
+ }else{
90
+ //if this is just published, we need to email the user about the publication, or send to pending mode again for review
91
+ if( (!$EM_Event->is_recurring() && !current_user_can('publish_events')) || ($EM_Event->is_recurring() && !current_user_can('publish_recurring_events')) ){
92
+ if( $EM_Event->is_published() ){ $EM_Event->set_status(0, true); } //no publishing and editing... security threat
93
+ }else{
94
+ $EM_Event->send_approval_notification();
95
+ }
96
+ apply_filters('em_event_save', true, $EM_Event);
97
+ }
98
+ }else{
99
+ //we're updating only the quick-edit style information, which is only post info saved into the index
100
+ $EM_Event = em_get_event($post_id, 'post_id'); //grab event, via post info
101
+ if( $EM_Event->validate() ){
102
+ do_action('em_event_save_pre', $EM_Event); //technically, the event is saved... but the meta isn't. wp doesn't give an pre-intervention action for this (or does it?)
103
+ //first things first, we must make sure we have an index, if not, reset it to a new one:
104
+ $event_truly_exists = $wpdb->get_var('SELECT event_id FROM '.EM_EVENTS_TABLE." WHERE event_id={$EM_Event->event_id}") == $EM_Event->event_id;
105
+ if(empty($EM_Event->event_id) || !$event_truly_exists){ $EM_Event->save_meta(); }
106
+ //we can save the status now
107
+ $event_status = $EM_Event->get_status(true);
108
+ //if this is just published, we need to email the user about the publication, or send to pending mode again for review
109
+ if( (!$EM_Event->is_recurring() && !current_user_can('publish_events')) || ($EM_Event->is_recurring() && !current_user_can('publish_recurring_events')) ){
110
+ if( $EM_Event->is_published() ){ $EM_Event->set_status(0, true); } //no publishing and editing... security threat
111
+ }else{
112
+ $EM_Event->previous_status = $EM_Event->get_previous_status(); //save previous status into object before approving
113
+ $EM_Event->send_approval_notification();
114
+ }
115
+ //now update the db
116
+ $wpdb->query("UPDATE ".EM_EVENTS_TABLE." SET event_name='{$EM_Event->event_name}', event_slug='{$EM_Event->event_slug}', event_status={$event_status}, event_private={$EM_Event->event_private} WHERE event_id='{$EM_Event->event_id}'");
117
+ if( $EM_Event->is_recurring() && $EM_Event->is_published()){
118
+ //recurrences are (re)saved only if event is published
119
+ $EM_Event->save_events();
120
+ }
121
+ apply_filters('em_event_save', true, $EM_Event);
122
+ }else{
123
+ do_action('em_event_save_pre', $EM_Event); //technically, the event is saved... but the meta isn't. wp doesn't give an pre-intervention action for this (or does it?)
124
+ //Event doesn't validate, so set status to null
125
+ $EM_Event->set_status(null, true);
126
+ apply_filters('em_event_save', false, $EM_Event);
127
+ }
128
+ }
129
+ self::maybe_publish_location($EM_Event);
130
+ }
131
+ }
132
+
133
+ /**
134
+ * Publish the location if the event has just been approved and the location is pending. We assume an editor published the event and approves the location too.
135
+ * @param EM_Event $EM_Event
136
+ */
137
+ function maybe_publish_location($EM_Event){
138
+ //do a dirty update for location too if it's not published
139
+ if( $EM_Event->is_published() && !empty($EM_Event->location_id) ){
140
+ $EM_Location = $EM_Event->get_location();
141
+ if( $EM_Location->location_status !== 1 ){
142
+ //let's also publish the location
143
+ $EM_Location->set_status(1, true);
144
+ }
145
+ }
146
+ }
147
+
148
+ function before_delete_post($post_id){
149
+ if(get_post_type($post_id) == EM_POST_TYPE_EVENT){
150
+ $EM_Event = em_get_event($post_id,'post_id');
151
+ $EM_Event->delete_meta();
152
+ }
153
+ }
154
+
155
+ function trashed_post($post_id){
156
+ if(get_post_type($post_id) == EM_POST_TYPE_EVENT){
157
+ global $EM_Notices;
158
+ $EM_Event = em_get_event($post_id,'post_id');
159
+ $EM_Event->set_status(null);
160
+ $EM_Notices->remove_all(); //no validation/notices needed
161
+ }
162
+ }
163
+
164
+ function untrash_post($post_id){
165
+ if(get_post_type($post_id) == EM_POST_TYPE_EVENT){
166
+ //set a constant so we know this event doesn't need 'saving'
167
+ if(!defined('UNTRASHING_'.$post_id)) define('UNTRASHING_'.$post_id, true);
168
+ }
169
+ }
170
+
171
+ function untrashed_post($post_id){
172
+ if(get_post_type($post_id) == EM_POST_TYPE_EVENT){
173
+ global $EM_Notices;
174
+ $EM_Event = em_get_event($post_id,'post_id');
175
+ $EM_Event->set_status(1);
176
+ $EM_Notices->remove_all(); //no validation/notices needed
177
+ }
178
+ }
179
+
180
+ function meta_boxes(){
181
+ global $EM_Event;
182
+ if( !empty($EM_Event->event_owner_anonymous) ){
183
+ add_meta_box('em-event-anonymous', __('Anonymous Submitter Info','dbem'), array('EM_Event_Post_Admin','meta_box_anonymous'),EM_POST_TYPE_EVENT, 'side','high');
184
+ }
185
+ add_meta_box('em-event-when', __('When','dbem'), array('EM_Event_Post_Admin','meta_box_date'),EM_POST_TYPE_EVENT, 'side','high');
186
+ if(get_option('dbem_locations_enabled', true)){
187
+ add_meta_box('em-event-where', __('Where','dbem'), array('EM_Event_Post_Admin','meta_box_location'),EM_POST_TYPE_EVENT, 'normal','high');
188
+ }
189
+ if( defined('WP_DEBUG') && WP_DEBUG ){
190
+ add_meta_box('em-event-meta', 'Event Meta (debugging only)', array('EM_Event_Post_Admin','meta_box_metadump'),EM_POST_TYPE_EVENT, 'normal','high');
191
+ }
192
+ if(get_option('dbem_rsvp_enabled', true)){
193
+ add_meta_box('em-event-bookings', __('Bookings/Registration','dbem'), array('EM_Event_Post_Admin','meta_box_bookings'),EM_POST_TYPE_EVENT, 'normal','high');
194
+ if( !empty($EM_Event->event_id) && $EM_Event->event_rsvp ){
195
+ add_meta_box('em-event-bookings-stats', __('Bookings Stats','dbem'), array('EM_Event_Post_Admin','meta_box_bookings_stats'),EM_POST_TYPE_EVENT, 'side','core');
196
+ }
197
+ }
198
+ if( get_option('dbem_attributes_enabled', true) ){
199
+ add_meta_box('em-event-attributes', __('Attributes','dbem'), array('EM_Event_Post_Admin','meta_box_attributes'),EM_POST_TYPE_EVENT, 'normal','default');
200
+ }
201
+ if( EM_MS_GLOBAL && !is_main_site() && get_option('dbem_categories_enabled') ){
202
+ add_meta_box('em-event-categories', __('Site Categories','dbem'), array('EM_Event_Post_Admin','meta_box_ms_categories'),EM_POST_TYPE_EVENT, 'side','low');
203
+ }
204
+ }
205
+
206
+ function meta_box_metadump(){
207
+ global $post,$EM_Event;
208
+ echo "<pre>"; print_r($EM_Event); echo "</pre>";
209
+ }
210
+
211
+ function meta_box_anonymous(){
212
+ global $EM_Event;
213
+ ?>
214
+ <div class='updated'><p><?php _e('This event was submitted by a guest. You will find their details in the <em>Anonymous Submitter Info</em> box','dbem')?></p></div>
215
+ <p><strong><?php _e('Name','dbem'); ?> :</strong> <?php echo $EM_Event->event_owner_name; ?></p>
216
+ <p><strong><?php _e('Name','dbem'); ?> :</strong> <?php echo $EM_Event->event_owner_email; ?></p>
217
+ <?php
218
+ }
219
+
220
+ function meta_box_date(){
221
+ //create meta box check of date nonce
222
+ ?><input type="hidden" name="_emnonce" value="<?php echo wp_create_nonce('edit_event'); ?>" /><?php
223
+ em_locate_template('forms/event/when.php', true);
224
+ }
225
+
226
+ function meta_box_bookings_stats(){
227
+ em_locate_template('forms/event/booking-stats.php',true);
228
+ }
229
+
230
+ function meta_box_bookings(){
231
+ em_locate_template('forms/event/bookings.php', true);
232
+ add_action('admin_footer',array('EM_Event_Post_Admin','meta_box_bookings_overlay'));
233
+ }
234
+
235
+ function meta_box_bookings_overlay(){
236
+ em_locate_template('forms/tickets-form.php', true); //put here as it can't be in the add event form
237
+ }
238
+
239
+ function meta_box_attributes(){
240
+ em_locate_template('forms/event/attributes.php',true);
241
+ }
242
+
243
+ function meta_box_location(){
244
+ em_locate_template('forms/event/location.php',true);
245
+ }
246
+
247
+ function meta_box_ms_categories(){
248
+ global $EM_Event;
249
+ $categories = EM_Categories::get(array('orderby'=>'category_name','hide_empty'=>false));
250
+ ?>
251
+ <?php if( count($categories) > 0 ): ?>
252
+ <p>
253
+ <?php foreach( $categories as $EM_Category ):?>
254
+ <label><input type="checkbox" name="event_categories[]" value="<?php echo $EM_Category->id; ?>" <?php if($EM_Event->get_categories()->has($EM_Category->id)) echo 'checked="checked"'; ?> /> <?php echo $EM_Category->name ?></label><br />
255
+ <?php endforeach; ?>
256
+ </p>
257
+ <?php else: ?>
258
+ <p><?php sprintf(__('No categories available, <a href="%s">create one here first</a>','dbem'), get_bloginfo('wpurl').'/wp-admin/admin.php?page=events-manager-categories'); ?></p>
259
+ <?php endif; ?>
260
+ <!-- END Categories -->
261
+ <?php
262
+ }
263
+ }
264
+ add_action('admin_init',array('EM_Event_Post_Admin','init'));
265
+
266
+ /*
267
+ * Recurring Events
268
+ */
269
+ class EM_Event_Recurring_Post_Admin{
270
+ function init(){
271
+ global $pagenow;
272
+ if($pagenow == 'post.php' || $pagenow == 'post-new.php' ){ //only needed if editing post
273
+ add_action('admin_head', array('EM_Event_Recurring_Post_Admin','admin_head'));
274
+ //Meta Boxes
275
+ add_action('add_meta_boxes', array('EM_Event_Recurring_Post_Admin','meta_boxes'));
276
+ //Notices
277
+ add_action('admin_notices',array('EM_Event_Post_Admin','admin_notices')); //shared with posts
278
+ }
279
+ //Save/Edit actions
280
+ add_action('before_delete_post',array('EM_Event_Recurring_Post_Admin','before_delete_post'),10,1);
281
+ add_action('trashed_post',array('EM_Event_Recurring_Post_Admin','trashed_post'),10,1);
282
+ add_action('untrash_post',array('EM_Event_Recurring_Post_Admin','untrash_post'),10,1);
283
+ add_action('untrashed_post',array('EM_Event_Recurring_Post_Admin','untrashed_post'),10,1);
284
+ //Notices
285
+ add_action('post_updated_messages',array('EM_Event_Post_Admin','admin_notices_filter'),1,1); //shared with posts
286
+ }
287
+
288
+ function admin_head(){
289
+ global $post, $EM_Event;
290
+ if( !empty($post) && $post->post_type == 'event-recurring' ){
291
+ $EM_Event = em_get_event($post->ID, 'post_id');
292
+ //quick hacks to make event admin table make more sense for events
293
+ ?>
294
+ <script type="text/javascript">
295
+ jQuery(document).ready( function($){
296
+ if(!EM.recurrences_menu){
297
+ $('#menu-posts-'+EM.event_post_type+', #menu-posts-'+EM.event_post_type+' > a').addClass('wp-has-current-submenu');
298
+ }
299
+ });
300
+ </script>
301
+ <?php
302
+ }
303
+ }
304
+
305
+ function before_delete_post($post_id){
306
+ if(get_post_type($post_id) == 'event-recurring'){
307
+ $EM_Event = em_get_event($post_id,'post_id');
308
+ //now delete recurrences
309
+ $events_array = EM_Events::get( array('recurrence'=>$EM_Event->event_id, 'scope'=>'all', 'status'=>'all' ) );
310
+ foreach($events_array as $event){
311
+ /* @var $event EM_Event */
312
+ if($EM_Event->event_id == $event->recurrence_id && !empty($event->recurrence_id) ){ //double check the event is a recurrence of this event
313
+ wp_delete_post($event->post_id, true);
314
+ }
315
+ }
316
+ $EM_Event->post_type = EM_POST_TYPE_EVENT; //trick it into thinking it's one event.
317
+ $EM_Event->delete_meta();
318
+ }
319
+ }
320
+
321
+ function trashed_post($post_id){
322
+ if(get_post_type($post_id) == 'event-recurring'){
323
+ global $EM_Notices, $wpdb;
324
+ $EM_Event = em_get_event($post_id,'post_id');
325
+ $EM_Event->set_status(null);
326
+ //now trash recurrences
327
+ $events_array = EM_Events::get( array('recurrence_id'=>$EM_Event->event_id, 'scope'=>'all', 'status'=>'all' ) );
328
+ foreach($events_array as $event){
329
+ /* @var $event EM_Event */
330
+ if($EM_Event->event_id == $event->recurrence_id ){ //double check the event is a recurrence of this event
331
+ wp_trash_post($event->post_id);
332
+ }
333
+ }
334
+ $EM_Notices->remove_all(); //no validation/notices needed
335
+ }
336
+ }
337
+
338
+ function untrash_post($post_id){
339
+ if(get_post_type($post_id) == 'event-recurring'){
340
+ global $wpdb;
341
+ //set a constant so we know this event doesn't need 'saving'
342
+ if(!defined('UNTRASHING_'.$post_id)) define('UNTRASHING_'.$post_id, true);
343
+ $EM_Event = em_get_event($post_id,'post_id');
344
+ $wpdb->query('UPDATE '.EM_EVENTS_TABLE.' SET event_status='.$EM_Event->event_status.' WHERE event_id='.$EM_Event->event_id);
345
+ $events_array = EM_Events::get( array('recurrence_id'=>$EM_Event->event_id, 'scope'=>'all', 'status'=>'all' ) );
346
+ foreach($events_array as $event){
347
+ /* @var $event EM_Event */
348
+ if($EM_Event->event_id == $event->recurrence_id){
349
+ wp_untrash_post($event->post_id);
350
+ }
351
+ }
352
+ }
353
+ }
354
+
355
+ function untrashed_post($post_id){
356
+ if(get_post_type($post_id) == 'event-recurring'){
357
+ global $EM_Notices,$EM_Event;
358
+ $EM_Event->set_status(1);
359
+ $EM_Notices->remove_all(); //no validation/notices needed
360
+ }
361
+ }
362
+
363
+ function meta_boxes(){
364
+ add_meta_box('em-event-recurring', __('Recurrences','dbem'), array('EM_Event_Recurring_Post_Admin','meta_box_recurrence'),'event-recurring', 'normal','high');
365
+ //add_meta_box('em-event-meta', 'Event Meta (debugging only)', array('EM_Event_Post_Admin','meta_box_metadump'),'event-recurring', 'normal','high');
366
+ add_meta_box('em-event-where', __('Where','dbem'), array('EM_Event_Post_Admin','meta_box_location'),'event-recurring', 'normal','high');
367
+ if(get_option('dbem_rsvp_enabled')){
368
+ add_meta_box('em-event-bookings', __('Bookings/Registration','dbem'), array('EM_Event_Post_Admin','meta_box_bookings'),'event-recurring', 'normal','high');
369
+ }
370
+ if( get_option('dbem_attributes_enabled') ){
371
+ add_meta_box('em-event-attributes', __('Attributes','dbem'), array('EM_Event_Post_Admin','meta_box_attributes'),'event-recurring', 'normal','default');
372
+ }
373
+ if( EM_MS_GLOBAL && !is_main_site() && get_option('dbem_categories_enabled') ){
374
+ add_meta_box('em-event-categories', __('Site Categories','dbem'), array('EM_Event_Post_Admin','meta_box_ms_categories'),'event-recurring', 'side','low');
375
+ }
376
+ }
377
+
378
+ function meta_box_recurrence(){
379
+ em_locate_template('forms/event/recurring-when.php', true);
380
+ }
381
+ }
382
+ add_action('admin_init',array('EM_Event_Recurring_Post_Admin','init'));
classes/em-event-post.php ADDED
@@ -0,0 +1,259 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Controls how events are queried and displayed via the WordPress Custom Post APIs
4
+ * @author marcus
5
+ *
6
+ */
7
+ class EM_Event_Post {
8
+ function init(){
9
+ global $wp_query;
10
+ //Front Side Modifiers
11
+ if( !is_admin() ){
12
+ //override single page with formats?
13
+ add_filter('the_content', array('EM_Event_Post','the_content'));
14
+ //display as page template?
15
+ if( get_option('dbem_cp_events_template_page') ){
16
+ add_filter('single_template',array('EM_Event_Post','single_template'));
17
+ }
18
+ //Override post template tags
19
+ add_filter('the_date',array('EM_Event_Post','the_date'));
20
+ add_filter('get_the_date',array('EM_Event_Post','the_date'),10,2);
21
+ add_filter('the_category',array('EM_Event_Post','the_category'),10,3);
22
+ }
23
+ add_action('parse_query', array('EM_Event_Post','parse_query'));
24
+ }
25
+
26
+ /**
27
+ * Overrides the default post format of an event and can display an event as a page, which uses the page.php template.
28
+ * @param string $template
29
+ * @return string
30
+ */
31
+ function single_template($template){
32
+ global $post;
33
+ if( !locate_template('single-'.EM_POST_TYPE_EVENT.'.php') && $post->post_type == EM_POST_TYPE_EVENT ){
34
+ $template = locate_template(array('page.php','index.php'),false);
35
+ }
36
+ return $template;
37
+ }
38
+
39
+ function the_content( $content ){
40
+ global $post, $EM_Event;
41
+ if( $post->post_type == EM_POST_TYPE_EVENT ){
42
+ if( is_archive() || is_search() ){
43
+ if(get_option('dbem_cp_events_archive_formats')){
44
+ $EM_Event = em_get_event($post);
45
+ $content = $EM_Event->output(get_option('dbem_event_list_item_format'));
46
+ }
47
+ }else{
48
+ if( get_option('dbem_cp_events_formats') && !post_password_required() ){
49
+ $EM_Event = em_get_event($post);
50
+ ob_start();
51
+ em_locate_template('templates/event-single.php',true);
52
+ $content = ob_get_clean();
53
+ }
54
+ }
55
+ }
56
+ return $content;
57
+ }
58
+
59
+ function the_date( $the_date, $d = '' ){
60
+ global $post;
61
+ if( $post->post_type == EM_POST_TYPE_EVENT ){
62
+ $EM_Event = em_get_event($post);
63
+ if ( '' == $d ){
64
+ $the_date = date(get_option('date_format'), $EM_Event->start);
65
+ }else{
66
+ $the_date = date($d, $EM_Event->start);
67
+ }
68
+ }
69
+ return $the_date;
70
+ }
71
+
72
+ function the_category( $thelist, $separator = '', $parents='' ){
73
+ global $post, $wp_rewrite;
74
+ if( $post->post_type == EM_POST_TYPE_EVENT ){
75
+ $EM_Event = em_get_event($post);
76
+ $categories = $EM_Event->get_categories();
77
+ if( empty($categories) ) return '';
78
+
79
+ /* Copied from get_the_category_list function, with a few minor edits to make urls work, and removing parent stuff (for now) */
80
+ $rel = ( is_object( $wp_rewrite ) && $wp_rewrite->using_permalinks() ) ? 'rel="category tag"' : 'rel="category"';
81
+
82
+ $thelist = '';
83
+ if ( '' == $separator ) {
84
+ $thelist .= '<ul class="post-categories">';
85
+ foreach ( $categories as $category ) {
86
+ $thelist .= "\n\t<li>";
87
+ switch ( strtolower( $parents ) ) {
88
+ case 'multiple':
89
+ $thelist .= '<a href="' . $category->get_url() . '" title="' . esc_attr( sprintf( __( "View all posts in %s" ), $category->name ) ) . '" ' . $rel . '>' . $category->name.'</a></li>';
90
+ break;
91
+ case 'single':
92
+ $thelist .= '<a href="' . $category->get_url() . '" title="' . esc_attr( sprintf( __( "View all posts in %s" ), $category->name ) ) . '" ' . $rel . '>';
93
+ $thelist .= $category->name.'</a></li>';
94
+ break;
95
+ case '':
96
+ default:
97
+ $thelist .= '<a href="' . $category->get_url() . '" title="' . esc_attr( sprintf( __( "View all posts in %s" ), $category->name ) ) . '" ' . $rel . '>' . $category->name.'</a></li>';
98
+ }
99
+ }
100
+ $thelist .= '</ul>';
101
+ } else {
102
+ $i = 0;
103
+ foreach ( $categories as $category ) {
104
+ if ( 0 < $i )
105
+ $thelist .= $separator;
106
+ switch ( strtolower( $parents ) ) {
107
+ case 'multiple':
108
+ $thelist .= '<a href="' . $category->get_url() . '" title="' . esc_attr( sprintf( __( "View all posts in %s" ), $category->name ) ) . '" ' . $rel . '>' . $category->name.'</a>';
109
+ break;
110
+ case 'single':
111
+ $thelist .= '<a href="' . $category->get_url() . '" title="' . esc_attr( sprintf( __( "View all posts in %s" ), $category->name ) ) . '" ' . $rel . '>';
112
+ $thelist .= "$category->name</a>";
113
+ break;
114
+ case '':
115
+ default:
116
+ $thelist .= '<a href="' . $category->get_url() . '" title="' . esc_attr( sprintf( __( "View all posts in %s" ), $category->name ) ) . '" ' . $rel . '>' . $category->name.'</a>';
117
+ }
118
+ ++$i;
119
+ }
120
+ }
121
+ /* End copying */
122
+ }
123
+ return $thelist;
124
+ }
125
+
126
+ function parse_query( ){
127
+ global $wp_query;
128
+ //Search Query Filtering
129
+ if( !is_admin() ){
130
+ if( !empty($wp_query->query_vars['s']) && !get_option('dbem_cp_events_search_results') ){
131
+ $wp_query->query_vars['post_type'] = array_diff( get_post_types(array('exclude_from_search' => false)), array(EM_POST_TYPE_EVENT));
132
+ }
133
+ }else{
134
+ if( !empty($wp_query->query_vars[EM_TAXONOMY_CATEGORY]) && is_numeric($wp_query->query_vars[EM_TAXONOMY_CATEGORY]) ){
135
+ //sorts out filtering admin-side as it searches by id
136
+ $term = get_term_by('id', $wp_query->query_vars[EM_TAXONOMY_CATEGORY], EM_TAXONOMY_CATEGORY);
137
+ $wp_query->query_vars[EM_TAXONOMY_CATEGORY] = ( $term !== false && !is_wp_error($term) )? $term->name:0;
138
+ }
139
+ }
140
+ //Scoping
141
+ if( !empty($wp_query->query_vars['post_type']) && ($wp_query->query_vars['post_type'] == EM_POST_TYPE_EVENT || $wp_query->query_vars['post_type'] == 'event-recurring') && (empty($wp_query->query_vars['post_status']) || !in_array($wp_query->query_vars['post_status'],array('trash','pending','draft'))) ) {
142
+ //Let's deal with the scope - default is future
143
+ if( is_admin() ){
144
+ $scope = $wp_query->query_vars['scope'] = (!empty($_REQUEST['scope'])) ? $_REQUEST['scope']:'future';
145
+ //TODO limit what a user can see admin side for events/locations/recurring events
146
+ }else{
147
+ if( !empty($wp_query->query_vars['calendar_day']) ) $wp_query->query_vars['scope'] = $wp_query->query_vars['calendar_day'];
148
+ if( empty($wp_query->query_vars['scope']) ){
149
+ if( is_archive() ){
150
+ $scope = $wp_query->query_vars['scope'] = get_option('dbem_events_page_scope');
151
+ }else{
152
+ $scope = $wp_query->query_vars['scope'] = 'all'; //otherwise we'll get 404s for past events
153
+ }
154
+ }else{
155
+ $scope = $wp_query->query_vars['scope'];
156
+ }
157
+ }
158
+ $query = array();
159
+ $time = current_time('timestamp');
160
+ if ( preg_match ( "/^[0-9]{4}-[0-9]{2}-[0-9]{2}$/", $scope ) ) {
161
+ $today = strtotime($scope);
162
+ $tomorrow = $today + 60*60*24-1;
163
+ if( get_option('dbem_events_current_are_past') && $wp_query->query_vars['post_type'] != 'event-recurring' ){
164
+ $query[] = array( 'key' => '_start_ts', 'value' => array($today,$tomorrow), 'compare' => 'BETWEEN' );
165
+ }else{
166
+ $query[] = array( 'key' => '_start_ts', 'value' => $tomorrow, 'compare' => '<=' );
167
+ $query[] = array( 'key' => '_end_ts', 'value' => $today, 'compare' => '>=' );
168
+ }
169
+ }elseif ($scope == "future"){
170
+ $today = strtotime(date('Y-m-d', $time));
171
+ if( get_option('dbem_events_current_are_past') && $wp_query->query_vars['post_type'] != 'event-recurring' ){
172
+ $query[] = array( 'key' => '_start_ts', 'value' => $today, 'compare' => '>=' );
173
+ }else{
174
+ $query[] = array( 'key' => '_end_ts', 'value' => $today, 'compare' => '>=' );
175
+ }
176
+ }elseif ($scope == "past"){
177
+ $today = strtotime(date('Y-m-d', $time));
178
+ if( get_option('dbem_events_current_are_past') && $wp_query->query_vars['post_type'] != 'event-recurring' ){
179
+ $query[] = array( 'key' => '_start_ts', 'value' => $today, 'compare' => '<' );
180
+ }else{
181
+ $query[] = array( 'key' => '_end_ts', 'value' => $today, 'compare' => '<' );
182
+ }
183
+ }elseif ($scope == "today"){
184
+ $today = strtotime(date('Y-m-d', $time));
185
+ if( get_option('dbem_events_current_are_past') && $wp_query->query_vars['post_type'] != 'event-recurring' ){
186
+ //date must be only today
187
+ $query[] = array( 'key' => '_start_ts', 'value' => $today, 'compare' => '=');
188
+ }else{
189
+ $query[] = array( 'key' => '_start_ts', 'value' => $today, 'compare' => '<=' );
190
+ $query[] = array( 'key' => '_end_ts', 'value' => $today, 'compare' => '>=' );
191
+ }
192
+ }elseif ($scope == "tomorrow"){
193
+ $tomorrow = strtotime(date('Y-m-d',$time+60*60*24));
194
+ if( get_option('dbem_events_current_are_past') && $wp_query->query_vars['post_type'] != 'event-recurring' ){
195
+ //date must be only tomorrow
196
+ $query[] = array( 'key' => '_start_ts', 'value' => $tomorrow, 'compare' => '=');
197
+ }else{
198
+ $query[] = array( 'key' => '_start_ts', 'value' => $tomorrow, 'compare' => '<=' );
199
+ $query[] = array( 'key' => '_end_ts', 'value' => $tomorrow, 'compare' => '>=' );
200
+ }
201
+ }elseif ($scope == "month"){
202
+ $start_month = strtotime(date('Y-m-d',$time));
203
+ $end_month = strtotime(date('Y-m-t',$time));
204
+ if( get_option('dbem_events_current_are_past') && $wp_query->query_vars['post_type'] != 'event-recurring' ){
205
+ $query[] = array( 'key' => '_start_ts', 'value' => array($start_month,$end_month), 'type' => 'numeric', 'compare' => 'BETWEEN');
206
+ }else{
207
+ $query[] = array( 'key' => '_start_ts', 'value' => $end_month, 'compare' => '<=' );
208
+ $query[] = array( 'key' => '_end_ts', 'value' => $start_month, 'compare' => '>=' );
209
+ }
210
+ }elseif ($scope == "next-month"){
211
+ $start_month_timestamp = strtotime('+1 month', $time); //get the end of this month + 1 day
212
+ $start_month = strtotime(date('Y-m-1',$start_month_timestamp));
213
+ $end_month = strtotime(date('Y-m-t',$start_month_timestamp));
214
+ if( get_option('dbem_events_current_are_past') && $wp_query->query_vars['post_type'] != 'event-recurring' ){
215
+ $query[] = array( 'key' => '_start_ts', 'value' => array($start_month,$end_month), 'type' => 'numeric', 'compare' => 'BETWEEN');
216
+ }else{
217
+ $query[] = array( 'key' => '_start_ts', 'value' => $end_month, 'compare' => '<=' );
218
+ $query[] = array( 'key' => '_end_ts', 'value' => $start_month, 'compare' => '>=' );
219
+ }
220
+ }elseif( preg_match('/(\d\d?)\-months/',$scope,$matches) ){ // next x months means this month (what's left of it), plus the following x months until the end of that month.
221
+ $months_to_add = $matches[1];
222
+ $start_month = strtotime(date('Y-m-d',$time));
223
+ $end_month = strtotime(date('Y-m-t',strtotime("+$months_to_add month", $time)));
224
+ if( get_option('dbem_events_current_are_past') && $wp_query->query_vars['post_type'] != 'event-recurring' ){
225
+ $query[] = array( 'key' => '_start_ts', 'value' => array($start_month,$end_month), 'type' => 'numeric', 'compare' => 'BETWEEN');
226
+ }else{
227
+ $query[] = array( 'key' => '_start_ts', 'value' => $end_month, 'compare' => '<=' );
228
+ $query[] = array( 'key' => '_end_ts', 'value' => $start_month, 'compare' => '>=' );
229
+ }
230
+ }
231
+ if( !empty($query) && is_array($query) ){
232
+ $wp_query->query_vars['meta_query'] = $query;
233
+ }
234
+ if( is_admin() ){
235
+ //admin areas don't need special ordering, so make it simple
236
+ $wp_query->query_vars['orderby'] = (!empty($_REQUEST['orderby'])) ? $_REQUEST['orderby']:'meta_value_num';
237
+ $wp_query->query_vars['meta_key'] = '_start_ts';
238
+ $wp_query->query_vars['order'] = (!empty($_REQUEST['order'])) ? $_REQUEST['order']:'ASC';
239
+ }else{
240
+ if( get_option('dbem_events_default_archive_orderby') == 'title'){
241
+ $wp_query->query_vars['orderby'] = 'title';
242
+ $wp_query->query_vars['order'] = get_option('dbem_events_default_archive_order','ASC');
243
+ }else{
244
+ $wp_query->query_vars['orderby'] = 'meta_value_num';
245
+ $wp_query->query_vars['meta_key'] = '_start_ts';
246
+ }
247
+ $wp_query->query_vars['order'] = get_option('dbem_events_default_archive_order','ASC');
248
+ }
249
+ }elseif( !empty($wp_query->query_vars['post_type']) && $wp_query->query_vars['post_type'] == EM_POST_TYPE_EVENT ){
250
+ $wp_query->query_vars['scope'] = 'all';
251
+ if( $wp_query->query_vars['post_status'] == 'pending' ){
252
+ $wp_query->query_vars['orderby'] = 'meta_value_num';
253
+ $wp_query->query_vars['order'] = 'ASC';
254
+ $wp_query->query_vars['meta_key'] = '_start_ts';
255
+ }
256
+ }
257
+ }
258
+ }
259
+ EM_Event_Post::init();
classes/em-event-posts-admin.php ADDED
@@ -0,0 +1,280 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class EM_Event_Posts_Admin{
3
+ function init(){
4
+ global $pagenow;
5
+ if( $pagenow == 'edit.php' && !empty($_REQUEST['post_type']) && $_REQUEST['post_type'] == EM_POST_TYPE_EVENT ){ //only needed for events list
6
+ if( !empty($_REQUEST['category_id']) && is_numeric($_REQUEST['category_id']) ){
7
+ $term = get_term_by('id', $_REQUEST['category_id'], EM_TAXONOMY_CATEGORY);
8
+ if( !empty($term->slug) ){
9
+ $_REQUEST['category_id'] = $term->slug;
10
+ }
11
+ }
12
+ //hide some cols by default:
13
+ $screen = 'edit-'.EM_POST_TYPE_EVENT;
14
+ $hidden = get_user_option( 'manage' . $screen . 'columnshidden' );
15
+ if( !$hidden ){
16
+ $hidden = array('event-id');
17
+ update_user_option(get_current_user_id(), "manage{$screen}columnshidden", $hidden, true);
18
+ }
19
+ //deal with actions
20
+ $row_action_type = is_post_type_hierarchical( EM_POST_TYPE_EVENT ) ? 'page_row_actions' : 'post_row_actions';
21
+ add_filter($row_action_type, array('EM_Event_Posts_Admin','row_actions'),10,2);
22
+ add_action('admin_head', array('EM_Event_Posts_Admin','admin_head'));
23
+ //collumns
24
+ add_filter('manage_edit-'.EM_POST_TYPE_EVENT.'_columns' , array('EM_Event_Posts_Admin','columns_add'));
25
+ add_filter('manage_'.EM_POST_TYPE_EVENT.'_posts_custom_column' , array('EM_Event_Posts_Admin','columns_output'),10,2 );
26
+ //TODO alter views of locations, events and recurrences, specifically find a good way to alter the wp_count_posts method to force user owned posts only
27
+ //add_filter('views_edit-'.EM_POST_TYPE_EVENT, array('EM_Event_Posts_Admin','views'),10,1);
28
+ }
29
+ add_action('restrict_manage_posts', array('EM_Event_Posts_Admin','restrict_manage_posts'));
30
+ }
31
+
32
+ function admin_head(){
33
+ //quick hacks to make event admin table make more sense for events
34
+ ?>
35
+ <script type="text/javascript">
36
+ jQuery(document).ready( function($){
37
+ $('.inline-edit-date').prev().css('display','none').next().css('display','none').next().css('display','none');
38
+ $('.em-detach-link').click(function( event ){
39
+ if( !confirm(EM.event_detach_warning) ){
40
+ event.preventDefault();
41
+ return false;
42
+ }
43
+ });
44
+ $('.em-delete-recurrence-link').click(function( event ){
45
+ if( !confirm(EM.delete_recurrence_warning) ){
46
+ event.preventDefault();
47
+ return false;
48
+ }
49
+ });
50
+ });
51
+ </script>
52
+ <style>
53
+ table.fixed{ table-layout:auto !important; }
54
+ .tablenav select[name="m"] { display:none; }
55
+ </style>
56
+ <?php
57
+ }
58
+
59
+ function restrict_manage_posts(){
60
+ global $wp_query;
61
+ if( $wp_query->query_vars['post_type'] == EM_POST_TYPE_EVENT || $wp_query->query_vars['post_type'] == 'event-recurring' ){
62
+ ?>
63
+ <select name="scope">
64
+ <?php
65
+ $scope = (!empty($wp_query->query_vars['scope'])) ? $wp_query->query_vars['scope']:'future';
66
+ foreach ( em_get_scopes() as $key => $value ) {
67
+ $selected = "";
68
+ if ($key == $scope)
69
+ $selected = "selected='selected'";
70
+ echo "<option value='$key' $selected>$value</option> ";
71
+ }
72
+ ?>
73
+ </select>
74
+ <?php
75
+ if( get_option('dbem_categories_enabled') ){
76
+ //Categories
77
+ $selected = !empty($_GET['event-categories']) ? $_GET['event-categories'] : 0;
78
+ wp_dropdown_categories(array( 'hide_empty' => 1, 'name' => 'event-categories',
79
+ 'hierarchical' => true, 'id' => EM_TAXONOMY_CATEGORY,
80
+ 'taxonomy' => EM_TAXONOMY_CATEGORY, 'selected' => $selected,
81
+ 'show_option_all' => __('View all categories')));
82
+ }
83
+ if( !empty($_REQUEST['author']) ){
84
+ ?>
85
+ <input type="hidden" name="author" value="<?php echo $_REQUEST['author'] ?>" />
86
+ <?php
87
+ }
88
+ }
89
+ }
90
+
91
+ function views($views){
92
+ if( !current_user_can('edit_others_events') ){
93
+ //alter the views to reflect correct numbering
94
+
95
+ }
96
+ return $views;
97
+ }
98
+
99
+ function columns_add($columns) {
100
+ if( array_key_exists('cb', $columns) ){
101
+ $cb = $columns['cb'];
102
+ unset($columns['cb']);
103
+ $id_array = array('cb'=>$cb, 'event-id' => sprintf(__('%s ID','dbem'),__('Event','dbem')));
104
+ }else{
105
+ $id_array = array('event-id' => sprintf(__('%s ID','dbem'),__('Event','dbem')));
106
+ }
107
+ unset($columns['comments']);
108
+ unset($columns['date']);
109
+ unset($columns['author']);
110
+ $columns = array_merge($id_array, $columns, array(
111
+ 'location' => __('Location','dbem'),
112
+ 'date-time' => __('Date and Time','dbem'),
113
+ 'author' => __('Owner','dbem'),
114
+ 'extra' => ''
115
+ ));
116
+ if( !get_option('dbem_locations_enabled') ){
117
+ unset($columns['location']);
118
+ }
119
+ return $columns;
120
+ }
121
+
122
+ function columns_output( $column ) {
123
+ global $post, $EM_Event;
124
+ $EM_Event = em_get_event($post, 'post_id');
125
+ /* @var $post EM_Event */
126
+ switch ( $column ) {
127
+ case 'event-id':
128
+ echo $EM_Event->event_id;
129
+ break;
130
+ case 'location':
131
+ //get meta value to see if post has location, otherwise
132
+ $EM_Location = $EM_Event->get_location();
133
+ if( !empty($EM_Location->location_id) ){
134
+ echo "<strong>" . $EM_Location->location_name . "</strong><br/>" . $EM_Location->location_address . " - " . $EM_Location->location_town;
135
+ }else{
136
+ echo __('None','dbem');
137
+ }
138
+ break;
139
+ case 'date-time':
140
+ //get meta value to see if post has location, otherwise
141
+ $localised_start_date = date_i18n(get_option('date_format'), $EM_Event->start);
142
+ $localised_end_date = date_i18n(get_option('date_format'), $EM_Event->end);
143
+ echo $localised_start_date;
144
+ echo ($localised_end_date != $localised_start_date) ? " - $localised_end_date":'';
145
+ echo "<br />";
146
+ if(!$EM_Event->event_all_day){
147
+ echo date_i18n(get_option('time_format'), $EM_Event->start) . " - " . date_i18n(get_option('time_format'), $EM_Event->end);
148
+ }else{
149
+ echo get_option('dbem_event_all_day_message');
150
+ }
151
+ break;
152
+ case 'extra':
153
+ if( get_option('dbem_rsvp_enabled') == 1 && !empty($EM_Event->event_rsvp) && $EM_Event->can_manage('manage_bookings','manage_others_bookings')){
154
+ ?>
155
+ <a href="<?php echo $EM_Event->get_bookings_url(); ?>"><?php echo __("Bookings",'dbem'); ?></a> &ndash;
156
+ <?php _e("Booked",'dbem'); ?>: <?php echo $EM_Event->get_bookings()->get_booked_spaces()."/".$EM_Event->get_spaces(); ?>
157
+ <?php if( get_option('dbem_bookings_approval') == 1 ): ?>
158
+ | <?php _e("Pending",'dbem') ?>: <?php echo $EM_Event->get_bookings()->get_pending_spaces(); ?>
159
+ <?php endif;
160
+ echo ($EM_Event->is_recurrence()) ? '<br />':'';
161
+ }
162
+ if ( $EM_Event->is_recurrence() && $EM_Event->can_manage('edit_recurring_events','edit_others_recurring_events') ) {
163
+ $recurrence_delete_confirm = __('WARNING! You will delete ALL recurrences of this event, including booking history associated with any event in this recurrence. To keep booking information, go to the relevant single event and save it to detach it from this recurrence series.','dbem');
164
+ ?>
165
+ <strong>
166
+ <?php echo $EM_Event->get_recurrence_description(); ?> <br />
167
+ </strong>
168
+ <div class="row-actions">
169
+ <a href="<?php echo admin_url(); ?>post.php?action=edit&amp;post=<?php echo $EM_Event->get_event_recurrence()->post_id ?>"><?php _e ( 'Edit Recurring Events', 'dbem' ); ?></a> | <span class="trash"><a class="em-delete-recurrence-link" href="<?php echo get_delete_post_link($EM_Event->get_event_recurrence()->post_id); ?>"><?php _e('Delete','dbem'); ?></a></span> | <a class="em-detach-link" href="<?php echo $EM_Event->get_detach_url(); ?>"><?php _e('Detach', 'dbem'); ?></a>
170
+ </div>
171
+ <?php
172
+ }
173
+
174
+ break;
175
+ }
176
+ }
177
+
178
+ function row_actions($actions, $post){
179
+ if($post->post_type == EM_POST_TYPE_EVENT){
180
+ global $post, $EM_Event;
181
+ $EM_Event = em_get_event($post, 'post_id');
182
+ $actions['duplicate'] = '<a href="'.admin_url().'edit.php?action=event_duplicate&amp;event_id='.$EM_Event->event_id.'&amp;_wpnonce='.wp_create_nonce('event_duplicate_'.$EM_Event->event_id).'" title="'.sprintf(__('Duplicate %s','dbem'), __('Event','dbem')).'">'.__('Duplicate','dbem').'</a>';
183
+ }
184
+ return $actions;
185
+ }
186
+ }
187
+ add_action('admin_init', array('EM_Event_Posts_Admin','init'));
188
+
189
+ /*
190
+ * Recurring Events
191
+ */
192
+ class EM_Event_Recurring_Posts_Admin{
193
+ function init(){
194
+ global $pagenow;
195
+ if( $pagenow == 'edit.php' && !empty($_REQUEST['post_type']) && $_REQUEST['post_type'] == 'event-recurring' ){
196
+ //hide some cols by default:
197
+ $screen = 'edit-'.EM_POST_TYPE_EVENT;
198
+ $hidden = get_user_option( 'manage' . $screen . 'columnshidden' );
199
+ if( !$hidden ){
200
+ $hidden = array('event-id');
201
+ update_user_option(get_current_user_id(), "manage{$screen}columnshidden", $hidden, true);
202
+ }
203
+ //notices
204
+ add_action('admin_notices',array('EM_Event_Recurring_Posts_Admin','admin_notices'));
205
+ add_action('admin_head', array('EM_Event_Recurring_Posts_Admin','admin_head'));
206
+ //collumns
207
+ add_filter('manage_edit-event-recurring_columns' , array('EM_Event_Recurring_Posts_Admin','columns_add'));
208
+ add_filter('manage_posts_custom_column' , array('EM_Event_Recurring_Posts_Admin','columns_output'),10,1 );
209
+ add_action('restrict_manage_posts', array('EM_Event_Posts_Admin','restrict_manage_posts'));
210
+ }
211
+ }
212
+
213
+ function admin_notices(){
214
+ $warning = sprintf(__( 'Modifications to these events will cause all recurrences of each event to be deleted and recreated and previous bookings will be deleted! You can edit individual recurrences and detach them from recurring events by visiting the <a href="%s">events page</a>.', 'dbem' ), admin_url().'edit.php?post_type='.EM_POST_TYPE_EVENT);
215
+ ?><div class="updated"><p><?php echo $warning; ?></p></div><?php
216
+ }
217
+
218
+ function admin_head(){
219
+ //quick hacks to make event admin table make more sense for events
220
+ ?>
221
+ <script type="text/javascript">
222
+ jQuery(document).ready( function($){
223
+ $('.inline-edit-date').prev().css('display','none').next().css('display','none').next().css('display','none');
224
+ if(!EM.recurrences_menu){
225
+ $('#menu-posts-'+EM.event_post_type+', #menu-posts-'+EM.event_post_type+' > a').addClass('wp-has-current-submenu');
226
+ }
227
+ });
228
+ </script>
229
+ <style>
230
+ table.fixed{ table-layout:auto !important; }
231
+ .tablenav select[name="m"] { display:none; }
232
+ </style>
233
+ <?php
234
+ }
235
+
236
+ function columns_add($columns) {
237
+ if( array_key_exists('cb', $columns) ){
238
+ $cb = $columns['cb'];
239
+ unset($columns['cb']);
240
+ $id_array = array('cb'=>$cb, 'event-id' => sprintf(__('%s ID','dbem'),__('Event','dbem')));
241
+ }else{
242
+ $id_array = array('event-id' => sprintf(__('%s ID','dbem'),__('Event','dbem')));
243
+ }
244
+ unset($columns['comments']);
245
+ unset($columns['date']);
246
+ unset($columns['author']);
247
+ return array_merge($id_array, $columns, array(
248
+ 'location' => __('Location'),
249
+ 'date-time' => __('Date and Time'),
250
+ 'author' => __('Owner','dbem'),
251
+ ));
252
+ }
253
+
254
+
255
+ function columns_output( $column ) {
256
+ global $post, $EM_Event;
257
+ if( $post->post_type == 'event-recurring' ){
258
+ $post = $EM_Event = em_get_event($post);
259
+ /* @var $post EM_Event */
260
+ switch ( $column ) {
261
+ case 'event-id':
262
+ echo $EM_Event->event_id;
263
+ break;
264
+ case 'location':
265
+ //get meta value to see if post has location, otherwise
266
+ $EM_Location = $EM_Event->get_location();
267
+ if( !empty($EM_Location->location_id) ){
268
+ echo "<strong>" . $EM_Location->location_name . "</strong><br/>" . $EM_Location->location_address . " - " . $EM_Location->location_town;
269
+ }else{
270
+ echo __('None','dbem');
271
+ }
272
+ break;
273
+ case 'date-time':
274
+ echo $EM_Event->get_recurrence_description();
275
+ break;
276
+ }
277
+ }
278
+ }
279
+ }
280
+ add_action('admin_init', array('EM_Event_Recurring_Posts_Admin','init'));
classes/em-event.php CHANGED
@@ -1,1006 +1,2096 @@
1
- <?php
2
- /**
3
- * Event Object. This holds all the info pertaining to an event, including location and recurrence info.
4
- * An event object can be one of three "types" a recurring event, recurrence of a recurring event, or a single event.
5
- * The single event might be part of a set of recurring events, but if loaded by specific event id then any operations and saves are
6
- * specifically done on this event. However, if you edit the recurring group, any changes made to single events are overwritten.
7
- *
8
- * @author marcus
9
- */
10
- //TODO Can add more recurring functionality such as "also update all future recurring events" or "edit all events" like google calendar does.
11
- //TODO Integrate recurrences into events table
12
- //FIXME If you create a super long recurrence timespan, there could be thousands of events... need an upper limit here.
13
- class EM_Event extends EM_Object{
14
- /**
15
- * Assoc array where keys are names of database fields and values are array corresponding object property name, regex, data types, etc.
16
- * for use when importing/exporting event data between database and object
17
- * @var array
18
- */
19
- var $fields = array(
20
- 'event_id' => array( 'name'=>'id', 'type'=>'%d' ),
21
- 'event_author' => array( 'name'=>'author', 'type'=>'%d' ),
22
- 'event_name' => array( 'name'=>'name', 'type'=>'%s' ),
23
- 'event_start_time' => array( 'name'=>'start_time', 'type'=>'%s' ),
24
- 'event_end_time' => array( 'name'=>'end_time', 'type'=>'%s' ),
25
- 'event_start_date' => array( 'name'=>'start_date', 'type'=>'%s' ),
26
- 'event_end_date' => array( 'name'=>'end_date', 'type'=>'%s' ),
27
- 'event_notes' => array( 'name'=>'notes', 'type'=>'%s' ),
28
- 'event_rsvp' => array( 'name'=>'rsvp', 'type'=>'%d' ),
29
- 'event_seats' => array( 'name'=>'seats', 'type'=>'%d' ),
30
- 'event_contactperson_id' => array( 'name'=>'contactperson_id', 'type'=>'%d' ),
31
- 'location_id' => array( 'name'=>'location_id', 'type'=>'%d' ),
32
- 'recurrence_id' => array( 'name'=>'recurrence_id', 'type'=>'%d' ),
33
- 'event_category_id' => array( 'name'=>'category_id', 'type'=>'%d' ),
34
- 'event_attributes' => array( 'name'=>'attributes', 'type'=>'%s' ),
35
- 'recurrence' => array( 'name'=>'recurrence', 'type'=>'%d' ),
36
- 'recurrence_interval' => array( 'name'=>'interval', 'type'=>'%d' ), //every x day(s)/week(s)/month(s)
37
- 'recurrence_freq' => array( 'name'=>'freq', 'type'=>'%s' ), //daily,weekly,monthly?
38
- 'recurrence_byday' => array( 'name'=>'byday', 'type'=>'%s' ), //if weekly or monthly, what days of the week?
39
- 'recurrence_byweekno' => array( 'name'=>'byweekno', 'type'=>'%d' ), //if monthly which week (-1 is last)
40
- 'event_date_created' => array( 'name'=>'date_created', 'type'=>'%s' ),
41
- 'event_date_modified' => array( 'name'=>'date_modified', 'type'=>'%s' )
42
- );
43
- /* Field Names - see above for matching DB field names and other field meta data */
44
- var $id;
45
- var $author;
46
- var $name;
47
- var $start_time;
48
- var $end_time;
49
- var $start_date;
50
- var $end_date;
51
- var $notes;
52
- var $rsvp;
53
- var $seats;
54
- var $contactperson_id;
55
- var $location_id;
56
- var $recurrence_id;
57
- var $category_id;
58
- var $attributes;
59
- var $recurrence;
60
- var $interval;
61
- var $freq;
62
- var $byday;
63
- var $byweekno;
64
- var $date_created;
65
- var $date_modified;
66
-
67
- /**
68
- * Timestamp of start date/time
69
- * @var int
70
- */
71
- var $start;
72
- /**
73
- * Timestamp of end date/time
74
- * @var int
75
- */
76
- var $end;
77
- /**
78
- * Created on timestamp, taken from DB, converted to TS
79
- * @var int
80
- */
81
- var $created;
82
- /**
83
- * Created on timestamp, taken from DB, converted to TS
84
- * @var int
85
- */
86
- var $modified;
87
-
88
- /**
89
- * @var EM_Location
90
- */
91
- var $location;
92
- /**
93
- * @var EM_Bookings
94
- */
95
- var $bookings;
96
- /**
97
- * The contact person for this event
98
- * @var WP_User
99
- */
100
- var $contact;
101
- /**
102
- * The category object
103
- * @var EM_Category
104
- */
105
- var $category;
106
- /**
107
- * If there are any errors, they will be added here.
108
- * @var array
109
- */
110
- var $errors = array();
111
- /**
112
- * If something was successful, a feedback message might be supplied here.
113
- * @var string
114
- */
115
- var $feedback_message;
116
- /**
117
- * Array of dbem_event field names required to create an event
118
- * @var array
119
- */
120
- var $required_fields = array('event_name', 'event_start_date');
121
-
122
- /**
123
- * Initialize an event. You can provide event data in an associative array (using database table field names), an id number, or false (default) to create empty event.
124
- * @param mixed $event_data
125
- * @param boolean $recurrent
126
- * @return null
127
- */
128
- function EM_Event($event_data = false, $recurrent = false) {
129
- global $wpdb, $EM_Recurrences;
130
- //TODO Change the way we deal with time, maybe revert to timestamps for manipulation, and worry about output in html and db writes?
131
- if( $event_data !== false ){
132
- $event = array();
133
- if( is_array($event_data) ){
134
- //Accepts a raw array that'll just be imported directly into the object with no DB lookups (same for event and recurrence)
135
- $event = $event_data;
136
- $this->location = new EM_Location( $event );
137
- $this->category = new EM_Category( $event );
138
- }elseif( is_numeric($event_data) && $event_data > 0 ){
139
- //Retreiving from the database
140
- $events_table = $wpdb->prefix . EM_EVENTS_TABLE;
141
- $locations_table = $wpdb->prefix . EM_LOCATIONS_TABLE;
142
- $categories_table = $wpdb->prefix . EM_CATEGORIES_TABLE;
143
- $sql = "
144
- SELECT * FROM $events_table
145
- LEFT JOIN $locations_table ON {$locations_table}.location_id={$events_table}.location_id
146
- LEFT JOIN $categories_table ON {$categories_table}.category_id={$events_table}.event_category_id
147
- WHERE event_id = $event_data
148
- "; //We get event and location data here to avoid extra queries
149
- $event = $wpdb->get_row ( $sql, ARRAY_A );
150
- //Sort Location
151
- $this->location = new EM_Location ( $event );
152
- $this->category = new EM_Category( $event );
153
- }
154
- //Sort out attributes
155
- if( !empty($event['event_attributes']) ){
156
- if( is_serialized($event['event_attributes']) ){
157
- $event['event_attributes'] = @unserialize($event['event_attributes']);
158
- }
159
- $event['event_attributes'] = (!is_array($event['event_attributes'])) ? array() : $event['event_attributes'] ;
160
- }
161
- $event['recurrence_byday'] = ( $event['recurrence_byday'] == 7 ) ? 0:$event['recurrence_byday']; //Backward compatibility (since 3.0.3), using 0 makes more sense due to date() function
162
- $this->to_object($event, true);
163
-
164
- //Start/End times should be available as timestamp
165
- $this->start = strtotime($this->start_date." ".$this->start_time);
166
- $this->end = strtotime($this->end_date." ".$this->end_time);
167
- $this->modified = strtotime($event['event_date_modified']);
168
- $this->created = strtotime($event['event_date_created']);
169
-
170
- //Add Contact Person
171
- if($this->contactperson_id){
172
- if($this->contactperson_id > 0){
173
- $this->contact = get_userdata($this->contactperson_id);
174
- }
175
- }
176
- if( !is_object($this->contact) ){
177
- $this->contactperson_id = get_option('dbem_default_contact_person');
178
- $this->contact = get_userdata($this->contactperson_id);
179
- }
180
- if( is_object($this->contact) ){
181
- $this->contact->phone = get_metadata('user', $this->contact->ID, 'dbem_phone', true);
182
- }
183
- //Now, if this is a recurrence, get the recurring for caching to the $EM_Recurrences
184
- if( $this->is_recurrence() && !array_key_exists($this->recurrence_id, $EM_Recurrences) ){
185
- $EM_Recurrences[$this->recurrence_id] = new EM_Event($this->recurrence_id);
186
- }
187
- }else{
188
- $this->location = new EM_Location(); //blank location
189
- $this->category = new EM_Category(); //blank category
190
- }
191
- }
192
-
193
- /**
194
- * Retrieve event, location and recurring information via POST
195
- * @return boolean
196
- */
197
- function get_post(){
198
- //Build Event Array
199
- do_action('em_event_get_post_pre', $this);
200
- $this->name = ( !empty($_POST['event_name']) ) ? stripslashes($_POST['event_name']) : '' ;
201
- $this->start_date = ( !empty($_POST['event_start_date']) ) ? $_POST['event_start_date'] : '';
202
- $this->end_date = ( !empty($_POST['event_end_date']) ) ? $_POST['event_end_date'] : $this->start_date;
203
- $this->rsvp = ( !empty($_POST['event_rsvp']) ) ? 1:0;
204
- $this->seats = ( !empty($_POST['event_seats']) && is_numeric($_POST['event_seats']) ) ? $_POST['event_seats']:0;
205
- $this->notes = ( !empty($_POST['content']) ) ? stripslashes($_POST['content']) : ''; //WP TinyMCE field
206
- //Sort out time
207
- //TODO make time handling less painful
208
- $match = array();
209
- if( !empty($_POST['event_start_time']) && preg_match ( '/^([01]\d|2[0-3]):([0-5]\d)(AM|PM)?$/', $_POST['event_start_time'], $match ) ){
210
- if( $match[3] == 'PM' && $match[1] != 12 ){
211
- $match[1] = 12+$match[1];
212
- }elseif( $match[3] == 'AM' && $match[1] == 12 ){
213
- $match[1] = '00';
214
- }
215
- $this->start_time = $match[1].":".$match[2].":00";
216
- }else{
217
- $this->start_time = "00:00:00";
218
- }
219
- if( !empty($_POST['event_end_time']) && preg_match ( '/^([01]\d|2[0-3]):([0-5]\d)(AM|PM)?$/', $_POST['event_end_time'], $match ) ){
220
- if( $match[3] == 'PM' && $match[1] != 12 ){
221
- $match[1] = 12+$match[1];
222
- }elseif( $match[3] == 'AM' && $match[1] == 12 ){
223
- $match[1] = '00';
224
- }
225
- $this->end_time = $match[1].":".$match[2].":00";
226
- }else{
227
- $this->end_time = $this->start_time;
228
- }
229
- //Start/End times should be available as timestamp
230
- $this->start = strtotime($this->start_date." ".$this->start_time);
231
- $this->end = strtotime($this->end_date." ".$this->end_time);
232
- //Contact Person
233
- if ( !empty($_POST['event_contactperson_id']) && is_numeric($_POST['event_contactperson_id']) ) {
234
- //TODO contactperson choices needs limiting depending on role
235
- $this->contactperson_id = $_POST['event_contactperson_id'];
236
- }
237
- //category
238
- if( !empty($_POST['event_category_id']) && is_numeric($_POST['event_category_id']) ){
239
- $this->category_id = $_POST['event_category_id'];
240
- }
241
- //Attributes
242
- $event_attributes = array();
243
- for($i=1 ; !empty($_POST["mtm_{$i}_ref"]) && trim($_POST["mtm_{$i}_ref"]) != '' ; $i++ ){
244
- if( !empty($_POST["mtm_{$i}_name"]) && trim($_POST["mtm_{$i}_name"]) != '' ){
245
- $event_attributes[$_POST["mtm_{$i}_ref"]] = stripslashes($_POST["mtm_{$i}_name"]);
246
- }
247
- }
248
- $this->attributes = $event_attributes;
249
- //Recurrence data
250
- $this->recurrence_id = ( !empty($_POST['recurrence_id']) && is_numeric($_POST['recurrence_id']) ) ? $_POST['recurrence_id'] : 0 ;
251
- if( !empty($_POST['repeated_event']) ){
252
- $this->recurrence = 1;
253
- $this->freq = ( !empty($_POST['recurrence_freq']) && in_array($_POST['recurrence_freq'], array('daily','weekly','monthly')) ) ? $_POST['recurrence_freq']:'daily';
254
- if( !empty($_POST['recurrence_bydays']) && $this->freq == 'weekly' && self::array_is_numeric($_POST['recurrence_bydays']) ){
255
- $this->byday = implode ( ",", $_POST['recurrence_bydays'] );
256
- }elseif( !empty($_POST['recurrence_byday']) && $this->freq == 'monthly' ){
257
- $this->byday = $_POST['recurrence_byday'];
258
- }
259
- $this->interval = ( !empty($_POST['recurrence_interval']) ) ? $_POST['recurrence_interval']:1;
260
- $this->byweekno = ( !empty($_POST['recurrence_byweekno']) ) ? $_POST['recurrence_byweekno']:'';
261
- }
262
-
263
- //Add location information, or just link to previous location, this is a requirement...
264
- if( !empty($_POST['location-select-id']) ) {
265
- $this->location = new EM_Location($_POST['location-select-id']);
266
- } else {
267
- $this->location = new EM_Location($_POST);
268
- $this->location->load_similar($_POST);
269
- }
270
- return apply_filters('em_event_get_post', $this->validate(), $this);
271
- }
272
-
273
- /**
274
- * Will save the current instance into the database, along with location information if a new one was created and return true if successful, false if not.
275
- * Will automatically detect what type of event it is (recurrent, recurrence or normal) and whether it's a new or existing event.
276
- * @return boolean
277
- */
278
- function save(){
279
- //FIXME Event doesn't save title when inserting first time
280
- global $wpdb, $current_user;
281
- if( !$this->can_manage(true) ){
282
- return apply_filters('em_event_save', false, $this);
283
- }
284
- do_action('em_event_save_pre', $this);
285
- get_currentuserinfo();
286
- $events_table = $wpdb->prefix.EM_EVENTS_TABLE;
287
- //First let's save the location, no location no event!
288
- if ( !$this->location->id && !$this->location->save() ){ //shouldn't try to save if location exists
289
- $this->errors[] = __ ( 'There was a problem saving the location so event was not saved.', 'dbem' );
290
- return apply_filters('em_event_save', false, $this);
291
- }
292
- $this->location_id = $this->location->id;
293
- //Contact person can be anyone the admin wants, but the creator if not.
294
- if( em_verify_admin() ){
295
- $this->contactperson_id = ( $this->contactperson_id > 0 ) ? $this->contactperson_id:0;
296
- }else{
297
- //force
298
- $this->contactperson_id = get_current_user_id();
299
- }
300
- //Now save the event
301
- if ( !$this->id ) {
302
- // Insert New Event
303
- $this->author = $current_user->ID; //Record creator of event
304
- $event = $this->to_array(false, true);
305
- $event['event_attributes'] = serialize($this->attributes);
306
- $event['recurrence_id'] = ( is_numeric($this->recurrence_id) ) ? $this->recurrence_id : 0;
307
- $event = apply_filters('em_event_save_pre',$event,$this);
308
- $result = $wpdb->insert ( $events_table, $event, $this->get_types($event) );
309
- if($result !== false){
310
- $this->id = $wpdb->insert_id;
311
- //Deal with recurrences
312
- if ( $this->is_recurring() ) {
313
- //Recurrence master event saved, now Save Events & check errors
314
- if( !$this->save_events() ){
315
- $this->errors[] = __ ( 'Something went wrong with the recurrence update...', 'dbem' ).
316
- __ ( 'There was a problem saving the recurring events.', 'dbem' );
317
- $this->delete();
318
- return apply_filters('em_event_save', false, $this);
319
- }
320
- //All good! Event Saved
321
- $this->feedback_message = __ ( 'New recurrent event inserted!', 'dbem' );
322
- return apply_filters('em_event_save', true, $this);
323
- }
324
- //Successful individual save
325
- $this->feedback_message = __ ( 'New event successfully inserted!', 'dbem' );
326
- return apply_filters('em_event_save', true, $this);
327
- }else{
328
- $this->errors[] = __ ( 'Could not save the event details due to a database error.', 'dbem' );
329
- }
330
- } else {
331
- // Update Event
332
- //TODO event privacy protection, only authors and authorized users can edit events
333
- //$this->author = $current_user->ID; //Record creator of event
334
- //FIXME Saving recurrence and disabling recurrence doesn't work
335
- $this->recurrence_id = 0; // If it's saved here, it becomes individual
336
- $event = $this->to_array();
337
- $event['event_attributes'] = serialize($event['event_attributes']);
338
- $event['event_date_modified'] = current_time('mysql');
339
- $event = apply_filters('em_event_save_pre',$event,$this);
340
- $result = $wpdb->update ( $events_table, $event, array('event_id' => $this->id), $this->get_types($event) );
341
- if($result !== false){ //Can't just do $result since if you don't make an actual record details change, it'll return 0 for no changes made
342
- //Deal with recurrences
343
- if ( $this->is_recurring() ) {
344
- if( !$this->save_events() ){
345
- $this->errors[] = __ ( 'Something went wrong with the recurrence update...', 'dbem' ).
346
- __ ( 'There was a problem saving the recurring events.', 'dbem' );
347
- return apply_filters('em_event_save', false, $this);
348
- }
349
- $this->feedback_message = __ ( 'Recurrence updated!', 'dbem' );
350
- return apply_filters('em_event_save', true, $this);
351
- }
352
- }else{
353
- $this->errors[] = __('Could not save the event details due to a database error.', 'dbem');
354
- return apply_filters('em_event_save', false, $this);
355
- }
356
- //Successful individual or recurrence save
357
- $this->feedback_message = "{$this->name} " . __ ( 'updated', 'dbem' ) . "!";
358
- if($this->rsvp == 0){
359
- $this->delete_bookings();
360
- }
361
- return apply_filters('em_event_save', true, $this);
362
- }
363
- }
364
-
365
- /**
366
- * Delete whole event, including recurrence and recurring data
367
- * @param $recurrence_id
368
- * @return boolean
369
- */
370
- function delete(){
371
- global $wpdb;
372
- do_action('em_event_delete_pre', $this);
373
- $result = false;
374
- if( $this->can_manage(true) ){
375
- if( $this->is_recurring() ){
376
- //Delete the recurrences then this recurrence event
377
- $this->delete_events();
378
- }
379
- $result = $wpdb->query ( $wpdb->prepare("DELETE FROM ". $wpdb->prefix . EM_EVENTS_TABLE ." WHERE event_id=%d", $this->id) );
380
- if($result !== false){
381
- $result = $this->get_bookings()->delete();
382
- }
383
- }
384
- return apply_filters('em_event_delete', $result, $this);
385
- }
386
-
387
- /**
388
- * Duplicates this event and returns the duplicated event. Will return false if there is a problem with duplication.
389
- * @return EM_Event
390
- */
391
- function duplicate(){
392
- global $wpdb, $EZSQL_ERROR;
393
- //First, duplicate.
394
- if( $this->can_manage(true) ){
395
- $event_table_name = $wpdb->prefix . EM_EVENTS_TABLE;
396
- $eventArray = $this->to_array(true);
397
- unset($eventArray['event_id']);
398
- $EM_Event = new EM_Event( $eventArray );
399
- if( $EM_Event->save() ){
400
- $EM_Event->feedback_message = __("You are now viewing the duplicated event", 'dbem');
401
- return apply_filters('em_event_duplicate', $EM_Event, $this);
402
- }
403
- }
404
- //TODO add error notifications for duplication failures.
405
- return apply_filters('em_event_duplicate', false, $this);;
406
- }
407
-
408
-
409
- /**
410
- * Validates the event. Should be run during any form submission or saving operation.
411
- * @return boolean
412
- */
413
- function validate() {
414
- $missing_fields = Array ();
415
- foreach ( $this->required_fields as $field ) {
416
- $true_field = $this->fields[$field]['name'];
417
- if ( $this->$true_field == "") {
418
- $missing_fields[] = $field;
419
- }
420
- }
421
- if ( count($missing_fields) > 0){
422
- // TODO Create friendly equivelant names for missing fields notice in validation
423
- $this->errors[] = __ ( 'Missing fields: ' ) . implode ( ", ", $missing_fields ) . ". ";
424
- }
425
- if ( !empty($_POST['repeated_event']) && $_POST['repeated_event'] == "1" && $this->end_date == "" ){
426
- $this->errors[] = __ ( 'Since the event is repeated, you must specify an event date.', 'dbem' );
427
- }
428
- if( preg_match('/\d{4}-\d{2}-\d{2}/', $this->start_date) && preg_match('/\d{4}-\d{2}-\d{2}/', $this->end_date) ){
429
- if( strtotime($this->start_date . $this->start_time) > strtotime($this->end_date . $this->end_time) ){
430
- $this->errors[] = __('Events cannot start after they end.','dbem');
431
- }
432
- }else{
433
- $this->errors[] = __('Dates must have correct formatting. Please use the date picker provided.','dbem');
434
- }
435
- if( !$this->location->validate() ){
436
- $this->errors = array_merge($this->errors, $this->location->errors);
437
- }
438
- //TODO validate recurrence during event validate
439
- return apply_filters('em_event_validate', count($this->errors) == 0, $this );
440
- }
441
-
442
-
443
- /**
444
- * Returns an array with category id and name (in that order) of the EM_Event instance.
445
- * @return array
446
- */
447
- function get_category() {
448
- global $EM_Category;
449
- if( is_object($this->category) && get_class($this->category)=='EM_Category' && $this->category_id == $this->category->id ){
450
- return $this->category;
451
- }elseif( is_object($EM_Category) && $EM_Category->id == $this->category_id ){
452
- $this->category = $EM_Category;
453
- }else{
454
- $this->category = new EM_Category($this->category_id);
455
- }
456
- return $this->event;
457
- global $wpdb;
458
- $sql = "SELECT category_id, category_name FROM ".$wpdb->prefix.EM_EVENTS_TABLE." LEFT JOIN ".$wpdb->prefix.EM_CATEGORIES_TABLE." ON category_id=event_category_id WHERE event_id ='".$this->id."'";
459
- $category = $wpdb->get_row($sql, ARRAY_A);
460
- return apply_filters('em_event_get_category', $category, $this);
461
- }
462
-
463
- /**
464
- * Shortcut function for $this->get_bookings()->delete(), because using the EM_Bookings requires loading previous bookings, which isn't neceesary.
465
- */
466
- function delete_bookings(){
467
- global $wpdb;
468
- do_action('em_event_delete_bookings_pre', $this);
469
- $result = false;
470
- if( $this->can_manage(true) ){
471
- $result = $wpdb->query( $wpdb->prepare("DELETE FROM ".$wpdb->prefix.EM_BOOKINGS_TABLE." WHERE event_id=%d", $this->id) );
472
- }
473
- return apply_filters('em_event_delete_bookings', $result, $this);
474
- }
475
-
476
- /**
477
- * Retrieve and save the bookings belonging to instance. If called again will return cached version, set $force_reload to true to create a new EM_Bookings object.
478
- * @param boolean $force_reload
479
- * @return EM_Bookings
480
- */
481
- function get_bookings( $force_reload = false ){
482
- if( get_option('dbem_rsvp_enabled') ){
483
- if( (!$this->bookings || $force_reload) ){
484
- $this->bookings = new EM_Bookings($this);
485
- }
486
- }
487
- return apply_filters('em_event_get_bookings', $this->bookings, $this);
488
- }
489
-
490
- /**
491
- * Will output a single event format of this event.
492
- * Equivalent of calling EM_Event::output( get_option ( 'dbem_single_event_format' ) )
493
- * @param string $target
494
- * @return string
495
- */
496
- function output_single($target='html'){
497
- $format = get_option ( 'dbem_single_event_format' );
498
- return apply_filters('em_event_output_single', $this->output($format, $target), $this, $target);
499
- }
500
-
501
- /**
502
- * Will output a event list item format of this event.
503
- * Equivalent of calling EM_Event::output( get_option ( 'dbem_event_list_item_format' ) )
504
- * @param string $target
505
- * @return string
506
- */
507
- function output_list($target='html'){
508
- $format = get_option ( 'dbem_event_list_item_format' );
509
- return apply_filters('em_event_output_list', $this->output($format, $target), $this, $target);
510
- }
511
-
512
- /**
513
- * Will output a event in the format passed in $format by replacing placeholders within the format.
514
- * @param string $format
515
- * @param string $target
516
- * @return string
517
- */
518
- function output($format, $target="html") {
519
- $event_string = $format;
520
- preg_match_all("/#@?_?[A-Za-z0-9]+/", $format, $placeholders);
521
- foreach($placeholders[0] as $result) {
522
- $match = true;
523
- $replace = '';
524
- switch( $result ){
525
- //Event Details
526
- case '#_EVENTID':
527
- $replace = $this->id;
528
- break;
529
- case '#_NAME':
530
- $replace = $this->name;
531
- break;
532
- case '#_NOTES':
533
- case '#_EXCERPT':
534
- //SEE AT BOTTOM OF FILE FOR OLD TARGET FILTERS FROM 2.x
535
- $replace = $this->notes;
536
- if($result == "#_EXCERPT"){
537
- $matches = explode('<!--more', $this->notes);
538
- $replace = $matches[0];
539
- }
540
- break;
541
- //Times
542
- case '#_24HSTARTTIME':
543
- case '#_24HENDTIME':
544
- $time = ($result == '#_24HSTARTTIME') ? $this->start_time:$this->end_time;
545
- $replace = substr($time, 0,5);
546
- break;
547
- case '#_12HSTARTTIME':
548
- case '#_12HENDTIME':
549
- $time = ($result == '#_12HSTARTTIME') ? $this->start_time:$this->end_time;
550
- $replace = date('g:i A', strtotime($time));
551
- break;
552
- //Links
553
- case '#_EVENTPAGEURL': //Depreciated
554
- case '#_LINKEDNAME': //Depreciated
555
- case '#_EVENTURL': //Just the URL
556
- case '#_EVENTLINK': //HTML Link
557
- $joiner = (stristr(EM_URI, "?")) ? "&amp;" : "?";
558
- $event_link = EM_URI.$joiner."event_id=".$this->id;
559
- if($result == '#_LINKEDNAME' || $result == '#_EVENTLINK'){
560
- $replace = "<a href='{$event_link}' title='{$this->name}'>{$this->name}</a>";
561
- }else{
562
- $replace = $event_link;
563
- }
564
- break;
565
- case '#_EDITEVENTLINK':
566
- if( $this->can_manage() ){
567
- //TODO user should have permission to edit the event
568
- $replace = "<a href='".get_bloginfo('wpurl')."/wp-admin/admin.php?page=events-manager-event&amp;event_id={$this->id}'>".__('Edit').' '.__('Event', 'dbem')."</a>";
569
- }
570
- break;
571
- //Bookings
572
- case '#_ADDBOOKINGFORM':
573
- case '#_REMOVEBOOKINGFORM':
574
- case '#_BOOKINGFORM':
575
- if ($this->rsvp && get_option('dbem_rsvp_enabled')){
576
- if($result == '#_BOOKINGFORM'){
577
- $replace = em_add_booking_form().em_delete_booking_form();
578
- }else{
579
- $replace = ($result == '#_ADDBOOKINGFORM') ? em_add_booking_form():em_delete_booking_form();
580
- }
581
- }
582
- break;
583
- case '#_AVAILABLESEATS': //Depreciated
584
- case '#_AVAILABLESPACES':
585
- if ($this->rsvp && get_option('dbem_rsvp_enabled')) {
586
- $replace = $this->get_bookings()->get_available_seats();
587
- } else {
588
- $replace = "0";
589
- }
590
- break;
591
- case '#_BOOKEDSEATS': //Depreciated
592
- case '#_BOOKEDSPACES':
593
- if ($this->rsvp && get_option('dbem_rsvp_enabled')) {
594
- $replace = $this->get_bookings()->get_booked_seats();
595
- } else {
596
- $replace = "0";
597
- }
598
- break;
599
- case '#_SEATS': //Depreciated
600
- case '#_SPACES':
601
- $replace = $this->seats;
602
- break;
603
- //Contact Person
604
- case '#_CONTACTNAME':
605
- case '#_CONTACTPERSON': //Depreciated (your call, I think name is better)
606
- $replace = $this->contact->display_name;
607
- break;
608
- case '#_CONTACTUSERNAME':
609
- $replace = $this->contact->user_login;
610
- break;
611
- case '#_CONTACTEMAIL':
612
- case '#_CONTACTMAIL': //Depreciated
613
- $replace = $this->contact->user_email;
614
- break;
615
- case '#_CONTACTID':
616
- $replace = $this->contact->ID;
617
- break;
618
- case '#_CONTACTPHONE':
619
- $replace = ( $this->contact->phone != '') ? $this->contact->phone : __('N/A', 'dbem');
620
- break;
621
- case '#_CONTACTAVATAR':
622
- $replace = get_avatar( $this->contact->ID, $size = '50' );
623
- break;
624
- case '#_CONTACTPROFILELINK':
625
- case '#_CONTACTPROFILEURL':
626
- if( function_exists('bp_core_get_user_domain') ){
627
- $replace = bp_core_get_user_domain($this->contact->ID);
628
- if( $result == '#_CONTACTPROFILELINK' ){
629
- $replace = '<a href="'.$replace.'">'.__('Profile').'</a>';
630
- }
631
- }
632
- break;
633
- default:
634
- $replace = $result;
635
- break;
636
- }
637
- $replace = apply_filters('em_event_output_placeholder', $replace, $this, $result, $target);
638
- $event_string = str_replace($result, $replace , $event_string );
639
- }
640
- //Time placeholders
641
- foreach($placeholders[0] as $result) {
642
- // matches all PHP START date and time placeholders
643
- if (preg_match('/^#[dDjlNSwzWFmMntLoYyaABgGhHisueIOPTZcrU]$/', $result)) {
644
- $replace = date_i18n(ltrim($result, "#"), $this->start);
645
- $replace = apply_filters('em_event_output_placeholder', $replace, $this, $result, $target);
646
- $event_string = str_replace($result, $replace, $event_string );
647
- }
648
- // matches all PHP END time placeholders for endtime
649
- if (preg_match('/^#@[dDjlNSwzWFmMntLoYyaABgGhHisueIOPTZcrU]$/', $result)) {
650
- $replace = date_i18n(ltrim($result, "#@"), $this->end);
651
- $replace = apply_filters('em_event_output_placeholder', $replace, $this, $result, $target);
652
- $event_string = str_replace($result, $replace, $event_string );
653
- }
654
- }
655
- //Time place holder that doesn't show if empty.
656
- //TODO add filter here too
657
- preg_match_all('/#@?_\{[A-Za-z0-9 -\/,\.\\\]+\}/', $format, $results);
658
- foreach($results[0] as $result) {
659
- if(substr($result, 0, 3 ) == "#@_"){
660
- $date = 'end_date';
661
- $offset = 4;
662
- }else{
663
- $date = 'start_date';
664
- $offset = 3;
665
- }
666
- if( $date == 'end_date' && $this->end_date == $this->start_date ){
667
- $replace = __( apply_filters('em_event_output_placeholder', '', $this, $result, $target) );
668
- }else{
669
- $replace = __( apply_filters('em_event_output_placeholder', mysql2date(substr($result, $offset, (strlen($result)-($offset+1)) ), $this->$date), $this, $result, $target) );
670
- }
671
- $event_string = str_replace($result,$replace,$event_string );
672
- }
673
- //This is for the custom attributes
674
- preg_match_all('/#_ATT\{.+?\}(\{(.+)\})?/', $format, $results);
675
- foreach($results[0] as $resultKey => $result) {
676
- //Strip string of placeholder and just leave the reference
677
- $attRef = substr( substr($result, 0, strpos($result, '}')), 6 );
678
- $attString = '';
679
- if( is_array($this->attributes) && array_key_exists($attRef, $this->attributes) ){
680
- $attString = $this->attributes[$attRef];
681
- }elseif( !empty($results[2][$resultKey]) ){
682
- //Check to see if we have a second set of braces;
683
- $attString = $results[2][$resultKey];
684
- }
685
- $attString = apply_filters('em_event_output_placeholder', $attString, $this, $result, $target);
686
- $event_string = str_replace($result, $attString ,$event_string );
687
- }
688
-
689
- //Now do dependent objects
690
- $event_string = $this->location->output($event_string, $target);
691
- $event_string = $this->category->output($event_string, $target);
692
- return apply_filters('em_event_output', $event_string, $this, $target);
693
- }
694
-
695
- /**********************************************************
696
- * RECURRENCE METHODS
697
- ***********************************************************/
698
-
699
- /**
700
- * Saves events and replaces old ones. Returns true if sucecssful or false if not.
701
- * @return boolean
702
- */
703
- function save_events() {
704
- if( $this->is_recurring() && $this->can_manage() ){
705
- do_action('em_event_save_events_pre', $this); //actions/filters only run if event is recurring
706
- global $wpdb;
707
- $event_saves = array();
708
- $matching_days = $this->get_recurrence_days(); //Get days where events recur
709
- $this->delete_events(); //Delete old events beforehand
710
- //Make template event (and we just change dates)
711
- $event = $this->to_array();
712
- unset($event['event_id']); //remove id and we have a event template to feed to wpdb insert
713
- $event['event_attributes'] = serialize($event['event_attributes']);
714
- foreach($event as $key => $value ){ //remove recurrence information
715
- if( substr($key, 0, 10) == 'recurrence' ){
716
- unset($event[$key]);
717
- }
718
- }
719
- $event['recurrence_id'] = $this->id;
720
- //Save event template with different dates
721
- foreach( $matching_days as $day ) {
722
- $event['event_start_date'] = date("Y-m-d", $day);
723
- $event['event_end_date'] = $event['event_start_date'];
724
- $event_saves[] = $wpdb->insert($wpdb->prefix.EM_EVENTS_TABLE, $event, $this->get_types($event));
725
- //TODO should be EM_DEBUG, and do we really need it?
726
- if( DEBUG ){ echo "Entering recurrence " . date("D d M Y", $day)."<br/>"; }
727
- }
728
- return apply_filters('em_event_save_events', !in_array(false, $event_saves), $this);
729
- }
730
- return apply_filters('em_event_save_events', false, $this);;
731
- }
732
-
733
- /**
734
- * Removes all reoccurring events.
735
- * @param $recurrence_id
736
- * @return null
737
- */
738
- function delete_events(){
739
- global $wpdb;
740
- do_action('em_event_delete_events_pre', $this);
741
- //So we don't do something we'll regret later, we could just supply the get directly into the delete, but this is safer
742
- $result = false;
743
- if( $this->can_manage(true) ){
744
- $EM_Events = EM_Events::get( array('recurrence_id'=>$this->id) );
745
- $event_ids = array();
746
- foreach($EM_Events as $EM_Event){
747
- if($EM_Event->recurrence_id == $this->id){
748
- $event_ids[] = $EM_Event->id; //ONLY ADD if id's match - hard coded
749
- }
750
- }
751
- $result = EM_Events::delete( $event_ids );
752
- }
753
- return apply_filters('delete_events', $result, $this);
754
- }
755
-
756
- /**
757
- * Returns true if this event is a recurring event, meaning that it's not an individual event,
758
- * but an event that defines many events that recur over a span of time.
759
- * For checking if a specific event is part of a greater set of recurring events, use is_recurrence()
760
- * @return boolean
761
- */
762
- function is_recurring(){
763
- return ( $this->recurrence );
764
- }
765
- /**
766
- * Will return true if this individual event is part of a set of events that recur
767
- * For checking if this is the "master recurring event", see is_recurring()
768
- * @return boolean
769
- */
770
- function is_recurrence(){
771
- return ( $this->id > 0 && $this->recurrence_id > 0 );
772
- }
773
- /**
774
- * Returns if this is an individual event and is not recurring or a recurrence
775
- * @return boolean
776
- */
777
- function is_individual(){
778
- return ( !$this->is_recurring() && !$this->is_recurrence() );
779
- }
780
-
781
- /**
782
- * Can the user manage this event?
783
- */
784
- function can_manage( $error_msg = false ){
785
- $can_manage = ( get_option('dbem_permissions_events') || $this->author == get_current_user_id() || empty($this->id) || em_verify_admin() );
786
- if($error_msg && !$can_manage){
787
- $this->errors[] = __('You do not have permission to manage this event.','dbem');
788
- }
789
- return apply_filters('em_event_can_manage', $can_manage, $this);
790
- }
791
-
792
- /**
793
- * Returns the days that match the recurrance array passed (unix timestamps)
794
- * @param array $recurrence
795
- * @return array
796
- */
797
- function get_recurrence_days(){
798
- if( $this->is_recurring() ){
799
-
800
- $start_date = strtotime($this->start_date);
801
- $end_date = strtotime($this->end_date);
802
-
803
- $weekdays = explode(",", $this->byday); //what days of the week (or if monthly, one value at index 0)
804
-
805
- $matching_days = array();
806
- $aDay = 86400; // a day in seconds
807
- $aWeek = $aDay * 7;
808
-
809
- //TODO can this be optimized?
810
- switch ( $this->freq ){
811
- case 'daily':
812
- //If daily, it's simple. Get start date, add interval timestamps to that and create matching day for each interval until end date.
813
- $current_date = $start_date;
814
- while( $current_date <= $end_date ){
815
- $matching_days[] = $current_date;
816
- $current_date = $current_date + ($aDay * $this->interval);
817
- }
818
- break;
819
- case 'weekly':
820
- //sort out week one, get starting days and then days that match time span of event (i.e. remove past events in week 1)
821
- $start_of_week = get_option('start_of_week'); //Start of week depends on wordpress
822
- //first, get the start of this week as timestamp
823
- $event_start_day = date('w', $start_date);
824
- $offset = 0;
825
- if( $event_start_day > $start_of_week ){
826
- $offset = $event_start_day - $start_of_week; //x days backwards
827
- }elseif( $event_start_day < $start_of_week ){
828
- $offset = $start_of_week;
829
- }
830
- $start_week_date = $start_date - ( ($event_start_day - $start_of_week) * $aDay );
831
- //then get the timestamps of weekdays during this first week, regardless if within event range
832
- $start_weekday_dates = array(); //Days in week 1 where there would events, regardless of event date range
833
- for($i = 0; $i < 7; $i++){
834
- $weekday_date = $start_week_date+($aDay*$i); //the date of the weekday we're currently checking
835
- $weekday_day = date('w',$weekday_date); //the day of the week we're checking, taking into account wp start of week setting
836
- if( in_array( $weekday_day, $weekdays) ){
837
- $start_weekday_dates[] = $weekday_date; //it's in our starting week day, so add it
838
- }
839
- }
840
- //for each day of eventful days in week 1, add 7 days * weekly intervals
841
- foreach ($start_weekday_dates as $weekday_date){
842
- //Loop weeks by interval until we reach or surpass end date
843
- while($weekday_date <= $end_date){
844
- if( $weekday_date >= $start_date && $weekday_date <= $end_date ){
845
- $matching_days[] = $weekday_date;
846
- }
847
- $weekday_date = $weekday_date + ($aWeek * $this->interval);
848
- }
849
- }//done!
850
- break;
851
- case 'monthly':
852
- //loop months starting this month by intervals
853
- $current_arr = getdate($start_date);
854
- $end_arr = getdate($end_date);
855
- $end_month_date = strtotime( date('Y-m-t', $end_date) ); //End date on last day of month
856
- $current_date = strtotime( date('Y-m-1', $start_date) ); //Start date on first day of month
857
- while( $current_date <= $end_month_date ){
858
- $last_day_of_month = date('t', $current_date);
859
- //Now find which day we're talking about
860
- $current_week_day = date('w',$current_date);
861
- $matching_month_days = array();
862
- //Loop through days of this years month and save matching days to temp array
863
- for($day = 1; $day <= $last_day_of_month; $day++){
864
- if($current_week_day == $this->byday){
865
- $matching_month_days[] = $day;
866
- }
867
- $current_week_day = ($current_week_day < 6) ? $current_week_day+1 : 0;
868
- }
869
- //Now grab from the array the x day of the month
870
- $matching_day = ($this->byweekno > 0) ? $matching_month_days[$this->byweekno-1] : array_pop($matching_month_days);
871
- $matching_date = strtotime(date('Y-m',$current_date).'-'.$matching_day);
872
- if($matching_date >= $start_date && $matching_date <= $end_date){
873
- $matching_days[] = $matching_date;
874
- }
875
- //add the number of days in this month to make start of next month
876
- $current_arr['mon'] += $this->interval;
877
- if($current_arr['mon'] > 12){
878
- //FIXME this won't work if interval is more than 12
879
- $current_arr['mon'] = $current_arr['mon'] - 12;
880
- $current_arr['year']++;
881
- }
882
- $current_date = strtotime("{$current_arr['year']}-{$current_arr['mon']}-1");
883
- }
884
- break;
885
- }
886
- sort($matching_days);
887
- //TODO delete this after testing
888
- /*Delete*/
889
- $test_dates = array();
890
- foreach($matching_days as $matching_day){
891
- $test_dates[] = date('d/m/Y', $matching_day);
892
- }
893
- /*end delete*/
894
- return $matching_days;
895
- }
896
- }
897
-
898
- /**
899
- * Returns a string representation of this recurrence. Will return false if not a recurrence
900
- * @return string
901
- */
902
- function get_recurrence_description() {
903
- //FIXME Recurrence description not working for recurrence
904
- global $EM_Recurrences;
905
- if( $this->is_individual() ) return false;
906
- $recurrence = $EM_Recurrences[$this->recurrence_id]->to_array();
907
- $weekdays_name = array(__('Sunday'),__('Monday'),__('Tuesday'),__('Wednesday'),__('Thursday'),__('Friday'),__('Saturday'));
908
- $monthweek_name = array('1' => __('the first %s of the month', 'dbem'),'2' => __('the second %s of the month', 'dbem'), '3' => __('the third %s of the month', 'dbem'), '4' => __('the fourth %s of the month', 'dbem'), '-1' => __('the last %s of the month', 'dbem'));
909
- $output = sprintf (__('From %1$s to %2$s', 'dbem'), $recurrence['event_start_date'], $recurrence['event_end_date']).", ";
910
- if ($recurrence['recurrence_freq'] == 'daily') {
911
- $freq_desc =__('everyday', 'dbem');
912
- if ($recurrence['recurrence_interval'] > 1 ) {
913
- $freq_desc = sprintf (__("every %s days", 'dbem'), $recurrence['recurrence_interval']);
914
- }
915
- }
916
- if ($recurrence['recurrence_freq'] == 'weekly') {
917
- $weekday_array = explode(",", $recurrence['recurrence_byday']);
918
- $natural_days = array();
919
- foreach($weekday_array as $day){
920
- array_push($natural_days, $weekdays_name[$day]);
921
- }
922
- $output .= implode(" and ", $natural_days);
923
- $freq_desc = ", " . __("every week", 'dbem');
924
- if ($recurrence['recurrence_interval'] > 1 ) {
925
- $freq_desc = ", ".sprintf (__("every %s weeks", 'dbem'), $recurrence['recurrence_interval']);
926
- }
927
-
928
- }
929
- if ($recurrence['recurrence_freq'] == 'monthly') {
930
- $weekday_array = explode(",", $recurrence['recurrence_byday']);
931
- $natural_days = array();
932
- foreach($weekday_array as $day){
933
- array_push($natural_days, $weekdays_name[$day]);
934
- }
935
- $freq_desc = sprintf (($monthweek_name[$recurrence['recurrence_byweekno']]), implode(" and ", $natural_days));
936
- if ($recurrence['recurrence_interval'] > 1 ) {
937
- $freq_desc .= ", ".sprintf (__("every %s months",'dbem'), $recurrence['recurrence_interval']);
938
- }
939
-
940
- }
941
- $output .= $freq_desc;
942
- return $output;
943
- }
944
-
945
- /**********************************************************
946
- * UTILITIES
947
- ***********************************************************/
948
-
949
- /**
950
- * Returns this object in the form of an array, useful for saving directly into the wp_dbem_events table.
951
- * @param boolean $location
952
- * @param boolean $for_database
953
- * @return array
954
- */
955
- function to_array($location = false, $for_database = false){
956
- $event = array();
957
- //Core Event Data
958
- foreach ( $this->fields as $key => $val ) {
959
- //TODO does it matter if it's for db or not... shouldn't it just not include blanks?
960
- if( !$for_database || $for_database && $this->$val['name'] ){
961
- $event[$key] = $this->$val['name'];
962
- }
963
- }
964
- //Location Data
965
- if($location && is_object($this->location)){
966
- $location = $this->location->to_array();
967
- $event = array_merge($event, $location);
968
- }
969
- return $event;
970
- }
971
- }
972
-
973
- //TODO placeholder targets filtering could be streamlined better
974
- /**
975
- * This is a temporary filter function which mimicks the old filters in the old 2.x placeholders function
976
- * @param string $result
977
- * @param EM_Event $event
978
- * @param string $placeholder
979
- * @param string $target
980
- * @return mixed
981
- */
982
- function em_event_output_placeholder($result,$event,$placeholder,$target='html'){
983
- if( ($placeholder == "#_EXCERPT" || $placeholder == "#_LOCATIONEXCERPT") && $target == 'html' ){
984
- $result = apply_filters('dbem_notes_excerpt', $result);
985
- }elseif( $placeholder == '#_CONTACTEMAIL' && $target == 'html' ){
986
- $result = em_ascii_encode($event->contact->user_email);
987
- }elseif( $placeholder == "#_NOTES" || $placeholder == "#_EXCERPT" || $placeholder == "#_LOCATIONEXCERPT" ){
988
- if($target == 'html'){
989
- $result = apply_filters('dbem_notes', $result);
990
- }elseif($target == 'map'){
991
- $result = apply_filters('dbem_notes_map', $result);
992
- }else{
993
- $result = apply_filters('dbem_notes_rss', $result);
994
- $result = apply_filters('the_content_rss', $result);
995
- }
996
- }elseif( in_array($placeholder, array("#_NAME",'#_ADDRESS','#_LOCATION','#_TOWN')) ){
997
- if ($target == "html"){
998
- $result = apply_filters('dbem_general', $result);
999
- }else{
1000
- $result = apply_filters('dbem_general_rss', $result);
1001
- }
1002
- }
1003
- return $result;
1004
- }
1005
- add_filter('em_event_output_placeholder','em_event_output_placeholder',1,4);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1006
  ?>
1
+ <?php
2
+ /**
3
+ * Get an event in a db friendly way, by checking globals and passed variables to avoid extra class instantiations
4
+ * @param mixed $id
5
+ * @param mixed $search_by
6
+ * @return EM_Event
7
+ */
8
+ function em_get_event($id = false, $search_by = 'event_id') {
9
+ global $EM_Event;
10
+ //check if it's not already global so we don't instantiate again
11
+ if( is_object($EM_Event) && get_class($EM_Event) == 'EM_Event' ){
12
+ if( is_object($id) && $EM_Event->post_id == $id->ID ){
13
+ return $EM_Event;
14
+ }elseif( !is_object($id) ){
15
+ if( $search_by == 'event_id' && $EM_Event->event_id == $id ){
16
+ return $EM_Event;
17
+ }elseif( $search_by == 'post_id' && $EM_Event->post_id == $id ){
18
+ return $EM_Event;
19
+ }
20
+ }
21
+ }
22
+ if( is_object($id) && get_class($id) == 'EM_Event' ){
23
+ return $id;
24
+ }else{
25
+ return new EM_Event($id,$search_by);
26
+ }
27
+ }
28
+ /**
29
+ * Event Object. This holds all the info pertaining to an event, including location and recurrence info.
30
+ * An event object can be one of three "types" a recurring event, recurrence of a recurring event, or a single event.
31
+ * The single event might be part of a set of recurring events, but if loaded by specific event id then any operations and saves are
32
+ * specifically done on this event. However, if you edit the recurring group, any changes made to single events are overwritten.
33
+ *
34
+ * @author marcus
35
+ */
36
+ //TODO Can add more recurring functionality such as "also update all future recurring events" or "edit all events" like google calendar does.
37
+ //TODO Integrate recurrences into events table
38
+ //FIXME If you create a super long recurrence timespan, there could be thousands of events... need an upper limit here.
39
+ class EM_Event extends EM_Object{
40
+ /* Field Names */
41
+ var $event_id;
42
+ var $post_id;
43
+ var $event_slug;
44
+ var $event_owner;
45
+ var $event_name;
46
+ var $event_start_time;
47
+ var $event_end_time;
48
+ var $event_all_day;
49
+ var $event_start_date;
50
+ var $event_end_date;
51
+ var $post_content;
52
+ var $event_rsvp;
53
+ var $event_rsvp_date;
54
+ var $event_spaces;
55
+ var $location_id;
56
+ var $recurrence_id;
57
+ var $event_status;
58
+ var $event_date_created;
59
+ var $event_date_modified;
60
+ var $blog_id;
61
+ var $group_id;
62
+ /**
63
+ * Populated with the non-hidden event post custom fields (i.e. not starting with _)
64
+ * @var array
65
+ */
66
+ var $event_attributes = array();
67
+ /* Recurring Specific Values */
68
+ var $recurrence;
69
+ var $recurrence_interval;
70
+ var $recurrence_freq;
71
+ var $recurrence_byday;
72
+ var $recurrence_days = 0;
73
+ var $recurrence_byweekno;
74
+ /* anonymous submission information */
75
+ var $event_owner_anonymous;
76
+ var $event_owner_name;
77
+ var $event_owner_email;
78
+ /**
79
+ * Previously used to give this object shorter property names for db values (each key has a name) but this is now depreciated, use the db field names as properties. This propertey provides extra info about the db fields.
80
+ * @var array
81
+ */
82
+ var $fields = array(
83
+ 'event_id' => array( 'name'=>'id', 'type'=>'%d' ),
84
+ 'post_id' => array( 'name'=>'post_id', 'type'=>'%d' ),
85
+ 'event_slug' => array( 'name'=>'slug', 'type'=>'%s', 'null'=>true ),
86
+ 'event_owner' => array( 'name'=>'owner', 'type'=>'%d', 'null'=>true ),
87
+ 'event_name' => array( 'name'=>'name', 'type'=>'%s', 'null'=>true ),
88
+ 'event_start_time' => array( 'name'=>'start_time', 'type'=>'%s', 'null'=>true ),
89
+ 'event_end_time' => array( 'name'=>'end_time', 'type'=>'%s', 'null'=>true ),
90
+ 'event_all_day' => array( 'name'=>'all_day', 'type'=>'%d', 'null'=>true ),
91
+ 'event_start_date' => array( 'name'=>'start_date', 'type'=>'%s', 'null'=>true ),
92
+ 'event_end_date' => array( 'name'=>'end_date', 'type'=>'%s', 'null'=>true ),
93
+ 'post_content' => array( 'name'=>'notes', 'type'=>'%s', 'null'=>true ),
94
+ 'event_rsvp' => array( 'name'=>'rsvp', 'type'=>'%d', 'null'=>true ), //has a default, so can be null/excluded
95
+ 'event_rsvp_date' => array( 'name'=>'event_rsvp_date', 'type'=>'%s', 'null'=>true ),
96
+ 'event_spaces' => array( 'name'=>'spaces', 'type'=>'%d', 'null'=>true),
97
+ 'location_id' => array( 'name'=>'location_id', 'type'=>'%d', 'null'=>true ),
98
+ 'recurrence_id' => array( 'name'=>'recurrence_id', 'type'=>'%d', 'null'=>true ),
99
+ 'event_status' => array( 'name'=>'status', 'type'=>'%d', 'null'=>true ),
100
+ 'event_private' => array( 'name'=>'status', 'type'=>'%d', 'null'=>true ),
101
+ 'event_date_created' => array( 'name'=>'date_created', 'type'=>'%s', 'null'=>true ),
102
+ 'event_date_modified' => array( 'name'=>'date_modified', 'type'=>'%s', 'null'=>true ),
103
+ 'event_attributes' => array( 'name'=>'attributes', 'type'=>'%s', 'null'=>true ),
104
+ 'blog_id' => array( 'name'=>'blog_id', 'type'=>'%d', 'null'=>true ),
105
+ 'group_id' => array( 'name'=>'group_id', 'type'=>'%d', 'null'=>true ),
106
+ 'recurrence' => array( 'name'=>'recurrence', 'type'=>'%d', 'null'=>true ), //every x day(s)/week(s)/month(s)
107
+ 'recurrence_interval' => array( 'name'=>'interval', 'type'=>'%d', 'null'=>true ), //every x day(s)/week(s)/month(s)
108
+ 'recurrence_freq' => array( 'name'=>'freq', 'type'=>'%s', 'null'=>true ), //daily,weekly,monthly?
109
+ 'recurrence_days' => array( 'name'=>'days', 'type'=>'%d', 'null'=>true ), //daily,weekly,monthly?
110
+ 'recurrence_byday' => array( 'name'=>'byday', 'type'=>'%s', 'null'=>true ), //if weekly or monthly, what days of the week?
111
+ 'recurrence_byweekno' => array( 'name'=>'byweekno', 'type'=>'%d', 'null'=>true ), //if monthly which week (-1 is last)
112
+ );
113
+ var $post_fields = array('event_slug','event_owner','event_name','event_attributes','post_id','post_content'); //fields that won't be taken from the em_events table anymore
114
+ var $recurrence_fields = array('recurrence_interval', 'recurrence_freq', 'recurrence_days', 'recurrence_byday', 'recurrence_byweekno');
115
+
116
+ var $image_url = '';
117
+ /**
118
+ * Timestamp of start date/time
119
+ * @var int
120
+ */
121
+ var $start;
122
+ /**
123
+ * Timestamp of end date/time
124
+ * @var int
125
+ */
126
+ var $end;
127
+ /**
128
+ * Created on timestamp, taken from DB, converted to TS
129
+ * @var int
130
+ */
131
+ var $created;
132
+ /**
133
+ * Created on timestamp, taken from DB, converted to TS
134
+ * @var int
135
+ */
136
+ var $modified;
137
+
138
+ /**
139
+ * @var EM_Location
140
+ */
141
+ var $location;
142
+ /**
143
+ * @var EM_Bookings
144
+ */
145
+ var $bookings;
146
+ /**
147
+ * The contact person for this event
148
+ * @var WP_User
149
+ */
150
+ var $contact;
151
+ /**
152
+ * The category object
153
+ * @var EM_Category
154
+ */
155
+ var $category;
156
+ /**
157
+ * If there are any errors, they will be added here.
158
+ * @var array
159
+ */
160
+ var $errors = array();
161
+ /**
162
+ * If something was successful, a feedback message might be supplied here.
163
+ * @var string
164
+ */
165
+ var $feedback_message;
166
+ /**
167
+ * Any warnings about an event (e.g. bad data, recurrence, etc.)
168
+ * @var string
169
+ */
170
+ var $warnings;
171
+ /**
172
+ * Array of dbem_event field names required to create an event
173
+ * @var array
174
+ */
175
+ var $required_fields = array('event_name', 'event_start_date');
176
+ var $mime_types = array(1 => 'gif', 2 => 'jpg', 3 => 'png');
177
+ /**
178
+ * previous status of event when instantiated
179
+ * @access protected
180
+ * @var mixed
181
+ */
182
+ var $previous_status = 0;
183
+
184
+ /* Post Variables - copied out of post object for easy IDE reference */
185
+ var $ID;
186
+ var $post_author;
187
+ var $post_date;
188
+ var $post_date_gmt;
189
+ var $post_title;
190
+ var $post_excerpt;
191
+ var $post_status;
192
+ var $comment_status;
193
+ var $ping_status;
194
+ var $post_password;
195
+ var $post_name;
196
+ var $to_ping;
197
+ var $pinged;
198
+ var $post_modified;
199
+ var $post_modified_gmt;
200
+ var $post_content_filtered;
201
+ var $post_parent;
202
+ var $guid;
203
+ var $menu_order;
204
+ var $post_type;
205
+ var $post_mime_type;
206
+ var $comment_count;
207
+ var $ancestors;
208
+ var $filter;
209
+
210
+ /**
211
+ * Initialize an event. You can provide event data in an associative array (using database table field names), an id number, or false (default) to create empty event.
212
+ * @param mixed $event_data
213
+ * @param mixed $search_by default is post_id, otherwise it can be by event_id as well.
214
+ * @return null
215
+ */
216
+ function __construct($id = false, $search_by = 'event_id') {
217
+ global $wpdb;
218
+ if( is_array($id) ){
219
+ //deal with the old array style, but we can't supply arrays anymore
220
+ $id = (!empty($id['event_id'])) ? $id['event_id'] : $id['post_id'];
221
+ $search_by = (!empty($id['event_id'])) ? 'event_id':'post_id';
222
+ }
223
+ $is_post = !empty($id->ID) && ($id->post_type == EM_POST_TYPE_EVENT || $id->post_type == 'event-recurring');
224
+ if( is_numeric($id) || $is_post ){ //only load info if $id is a number
225
+ if($search_by == 'event_id' && !$is_post ){
226
+ //search by event_id, get post_id and blog_id (if in ms mode) and load the post
227
+ $results = $wpdb->get_row($wpdb->prepare("SELECT post_id, blog_id FROM ".EM_EVENTS_TABLE." WHERE event_id=%d",$id), ARRAY_A);
228
+ if( is_multisite() && is_numeric($results['blog_id']) ){
229
+ $event_post = get_blog_post($results['blog_id'], $results['post_id']);
230
+ $search_by = $results['blog_id'];
231
+ }else{
232
+ $event_post = get_post($results['post_id']);
233
+ }
234
+ }else{
235
+ if(!$is_post){
236
+ if( is_numeric($search_by) && is_multisite() ){
237
+ //we've been given a blog_id, so we're searching for a post id
238
+ $event_post = get_blog_post($search_by, $id);
239
+ }else{
240
+ //search for the post id only
241
+ $event_post = get_post($id);
242
+ }
243
+ }else{
244
+ $event_post = $id;
245
+ }
246
+ }
247
+ $this->load_postdata($event_post, $search_by);
248
+ }
249
+ $this->recurrence = $this->is_recurring() ? 1:0;
250
+ //if(defined('trashtest')){ print_r($this); die("got here");}
251
+ //Do it here so things appear in the po file.
252
+ $this->status_array = array(
253
+ 0 => __('Pending','dbem'),
254
+ 1 => __('Approved','dbem')
255
+ );
256
+ do_action('em_event', $this, $id, $search_by);
257
+ }
258
+
259
+ function load_postdata($event_post, $search_by = false){
260
+ if( is_object($event_post) ){
261
+ if( $event_post->post_status != 'auto-draft' ){
262
+ if( is_numeric($search_by) && is_multisite() ){
263
+ // if in multisite mode, switch blogs quickly to get the right post meta.
264
+ switch_to_blog($search_by);
265
+ $event_meta = get_post_custom($event_post->ID);
266
+ restore_current_blog();
267
+ $this->blog_id = $search_by;
268
+ }else{
269
+ $event_meta = get_post_custom($event_post->ID);
270
+ }
271
+ //Get custom fields and post meta
272
+ foreach($event_meta as $event_meta_key => $event_meta_val){
273
+ if($event_meta_key[0] != '_'){
274
+ $this->event_attributes[$event_meta_key] = ( count($event_meta_val) > 1 ) ? $event_meta_val:$event_meta_val[0];
275
+ }elseif($event_meta_key != '_event_attributes'){
276
+ $field_name = substr($event_meta_key, 1);
277
+ if( array_key_exists($field_name, $this->fields) ){
278
+ $this->$field_name = $event_meta_val[0];
279
+ }elseif( in_array($field_name, array('event_owner_name','event_owner_anonymous','event_owner_email')) ){
280
+ $this->$field_name = $event_meta_val[0];
281
+ }
282
+ }
283
+ }
284
+ //Start/End times should be available as timestamp
285
+ $this->start = strtotime($this->event_start_date." ".$this->event_start_time);
286
+ $this->end = strtotime($this->event_end_date." ".$this->event_end_time);
287
+ //quick compatability fix in case _event_id isn't loaded or somehow got erased in post meta
288
+ if( empty($this->event_id) && !$this->is_recurring() ){
289
+ global $wpdb;
290
+ $event_array = $wpdb->get_row('SELECT * FROM '.EM_EVENTS_TABLE. ' WHERE post_id='.$event_post->ID, ARRAY_A);
291
+ if( !empty($event_array['event_id']) ){
292
+ foreach($event_array as $key => $value){
293
+ if( !empty($value) && empty($this->$key) ){
294
+ update_post_meta($event_post->ID, '_'.$key, $value);
295
+ $this->$key = $value;
296
+ }
297
+ }
298
+ }
299
+ }
300
+ }
301
+ //load post data - regardless
302
+ $this->post_id = $event_post->ID;
303
+ $this->event_name = $event_post->post_title;
304
+ $this->event_owner = $event_post->post_author;
305
+ $this->post_content = $event_post->post_content;
306
+ $this->event_slug = $event_post->post_name;
307
+ $this->event_modified = $event_post->post_modified;
308
+ foreach( $event_post as $key => $value ){ //merge post object into this object
309
+ $this->$key = $value;
310
+ }
311
+ $this->previous_status = $this->event_status; //so we know about updates
312
+ $this->recurrence = $this->is_recurring() ? 1:0;
313
+ $this->get_status();
314
+ $this->compat_keys();
315
+ }
316
+ }
317
+
318
+ /**
319
+ * Retrieve event information via POST (only used in situations where posts aren't submitted via WP)
320
+ * @return boolean
321
+ */
322
+ function get_post($validate = true){
323
+ global $allowedposttags;
324
+ //we need to get the post/event name and content.... that's it.
325
+ $this->post_content = !empty($_POST['content']) ? wp_kses( stripslashes($_POST['content']), $allowedposttags):'';
326
+ $this->event_name = !empty($_POST['event_name']) ? wp_kses_data( stripslashes($_POST['event_name']) ):'';
327
+ $this->post_type = ($this->is_recurring() || !empty($_POST['recurring'])) ? 'event-recurring':EM_POST_TYPE_EVENT;
328
+ //don't forget categories!
329
+ $this->get_categories()->get_post();
330
+ //anonymous submissions and guest basic info
331
+ if( !is_user_logged_in() && get_option('dbem_events_anonymous_submissions') && empty($this->event_id) ){
332
+ $this->event_owner_anonymous = 1;
333
+ $this->event_owner_name = !empty($_POST['event_owner_name']) ? stripslashes($_POST['event_owner_name']):'';
334
+ $this->event_owner_email = !empty($_POST['event_owner_email']) ? $_POST['event_owner_email']:'';
335
+ }
336
+ //get the rest and validate (optional)
337
+ $this->get_post_meta(false);
338
+ $result = $validate ? $this->validate():true; //validate both post and meta, otherwise return true
339
+ return apply_filters('em_event_get_post', $result, $this);
340
+ }
341
+
342
+ /**
343
+ * Retrieve event post meta information via POST, which should be always be called when saving the event custom post via WP.
344
+ * @param boolean $validate whether or not to run validation, default is true
345
+ * @return boolean
346
+ */
347
+ function get_post_meta($validate = true){
348
+ //Grab POST data
349
+ $this->event_start_date = ( !empty($_POST['event_start_date']) ) ? $_POST['event_start_date'] : '';
350
+ $this->event_end_date = ( !empty($_POST['event_end_date']) ) ? $_POST['event_end_date'] : $this->event_start_date;
351
+ //check if this is recurring or not
352
+ if( !empty($_POST['recurring']) ){
353
+ $this->recurrence = 1;
354
+ $this->post_type = 'event-recurring';
355
+ }
356
+ //Get Location info
357
+ if( !get_option('dbem_locations_enabled') || (!empty($_POST['no_location']) && !get_option('dbem_require_location',true)) || (empty($_POST['location_id']) && !get_option('dbem_require_location',true) && get_option('dbem_use_select_for_locations')) ){
358
+ $this->location_id = 0;
359
+ }elseif( !empty($_POST['location_id']) && is_numeric($_POST['location_id']) ){
360
+ $this->location_id = $_POST['location_id'];
361
+ }else{
362
+ //we're adding a new location, so create an empty location and populate
363
+ $this->location_id = null;
364
+ $this->get_location()->get_post(false);
365
+ $this->get_location()->post_content = ''; //reset post content, as it'll grab the event description otherwise
366
+ }
367
+ //Sort out time
368
+ $this->event_all_day = ( !empty($_POST['event_all_day']) ) ? 1 : 0;
369
+ if( !$this->event_all_day ){
370
+ $match = array();
371
+ foreach( array('event_start_time','event_end_time') as $timeName ){
372
+ if( !empty($_POST[$timeName]) && preg_match ( '/^([01]\d|2[0-3]):([0-5]\d) ?(AM|PM)?$/', $_POST[$timeName], $match ) ){
373
+ if( !empty($match[3]) && $match[3] == 'PM' && $match[1] != 12 ){
374
+ $match[1] = 12+$match[1];
375
+ }elseif( !empty($match[3]) && $match[3] == 'AM' && $match[1] == 12 ){
376
+ $match[1] = '00';
377
+ }
378
+ $this->$timeName = $match[1].":".$match[2].":00";
379
+ }else{
380
+ $this->$timeName = ($timeName == 'event_start_time') ? "00:00:00":$this->event_start_time;
381
+ }
382
+ }
383
+ }else{
384
+ $this->event_start_time = $this->event_end_time = '00:00:00';
385
+ }
386
+ //Start/End times should be available as timestamp
387
+ $this->start = strtotime($this->event_start_date." ".$this->event_start_time);
388
+ $this->end = strtotime($this->event_end_date." ".$this->event_end_time);
389
+ //Bookings
390
+ if( !empty($_POST['event_rsvp']) && $_POST['event_rsvp'] ){
391
+ $this->get_bookings()->get_tickets()->get_post();
392
+ $this->event_rsvp = 1;
393
+ $this->event_rsvp_date = ( !isset($_POST['event_rsvp_date']) ) ? $_POST['event_rsvp_date'] : $this->event_start_date;
394
+ $this->event_spaces = (!isset($_POST['event_spaces'])) ? absint($_POST['event_spaces']):0;
395
+ }else{
396
+ $this->event_rsvp = 0;
397
+ }
398
+ //Sort out event attributes - note that custom post meta now also gets inserted here automatically (and is overwritten by these attributes)
399
+ if(get_option('dbem_attributes_enabled')){
400
+ global $allowedtags;
401
+ if( !is_array($this->event_attributes) ){ $this->event_attributes = array(); }
402
+ $event_available_attributes = em_get_attributes();
403
+ if( !empty($_POST['em_attributes']) && is_array($_POST['em_attributes']) ){
404
+ foreach($_POST['em_attributes'] as $att_key => $att_value ){
405
+ if( (in_array($att_key, $event_available_attributes['names']) || array_key_exists($att_key, $this->event_attributes) ) ){
406
+ if( !empty($att_value) ){
407
+ $att_vals = count($event_available_attributes['values'][$att_key]);
408
+ if( $att_vals == 0 || ($att_vals > 0 && in_array($att_value, $event_available_attributes['values'][$att_key])) ){
409
+ $this->event_attributes[$att_key] = stripslashes($att_value);
410
+ }elseif($att_vals > 0){
411
+ $this->event_attributes[$att_key] = stripslashes(wp_kses($event_available_attributes['values'][$att_key][0], $allowedtags));
412
+ }
413
+ }else{
414
+ $this->event_attributes[$att_key] = '';
415
+ }
416
+ }
417
+ }
418
+ }
419
+ }
420
+ //Set Blog ID
421
+ if( is_multisite() ){
422
+ $this->blog_id = get_current_blog_id();
423
+ }
424
+ //group id
425
+ $this->group_id = (!empty($_POST['group_id']) && is_numeric($_POST['group_id'])) ? $_POST['group_id']:0;
426
+ //Recurrence data
427
+ if( $this->is_recurring() ){
428
+ $this->recurrence = 1; //just in case
429
+ $this->recurrence_freq = ( !empty($_POST['recurrence_freq']) && in_array($_POST['recurrence_freq'], array('daily','weekly','monthly','yearly')) ) ? $_POST['recurrence_freq']:'daily';
430
+ if( !empty($_POST['recurrence_bydays']) && $this->recurrence_freq == 'weekly' && self::array_is_numeric($_POST['recurrence_bydays']) ){
431
+ $this->recurrence_byday = implode( ",", $_POST['recurrence_bydays'] );
432
+ }elseif( !empty($_POST['recurrence_byday']) && $this->recurrence_freq == 'monthly' ){
433
+ $this->recurrence_byday = $_POST['recurrence_byday'];
434
+ }
435
+ $this->recurrence_interval = ( !empty($_POST['recurrence_interval']) && is_numeric($_POST['recurrence_interval']) ) ? $_POST['recurrence_interval']:1;
436
+ $this->recurrence_byweekno = ( !empty($_POST['recurrence_byweekno']) ) ? $_POST['recurrence_byweekno']:'';
437
+ $this->recurrence_days = ( !empty($_POST['recurrence_days']) && is_numeric($_POST['recurrence_days']) ) ? (int) $_POST['recurrence_days']:0;
438
+ }
439
+ //categories in MS GLobal
440
+ if(EM_MS_GLOBAL && !is_main_site()){
441
+ $this->get_categories()->get_post(); //it'll know what to do
442
+ }
443
+ //validate (optional) and return result
444
+ $result = $validate ? $this->validate_meta():true;
445
+ $this->compat_keys(); //compatability
446
+ return apply_filters('em_event_get_post', $result, $this);
447
+ }
448
+
449
+ function validate(){
450
+ $validate_post = true;
451
+ if( empty($this->event_name) ){
452
+ $validate_post = false;
453
+ $this->add_error( sprintf(__("%s is required.", "dbem"), __('Event name','dbem')) );
454
+ }
455
+ //anonymous submissions and guest basic info
456
+ if( !empty($this->event_owner_anonymous) ){
457
+ if( !is_email($this->event_owner_email) ){
458
+ $this->add_error( sprintf(__("%s is required.", "dbem"), __('A valid email','dbem')) );
459
+ }
460
+ if( empty($this->event_owner_name) ){
461
+ $this->add_error( sprintf(__("%s is required.", "dbem"), __('Your name','dbem')) );
462
+ }
463
+ }
464
+ $validate_image = $this->image_validate();
465
+ $validate_meta = $this->validate_meta();
466
+ return apply_filters('em_event_validate', $validate_post && $validate_image && $validate_meta, $this );
467
+ }
468
+ function validate_meta(){
469
+ $missing_fields = Array ();
470
+ foreach ( array('event_start_date') as $field ) {
471
+ if ( $this->$field == "") {
472
+ $missing_fields[$field] = $field;
473
+ }
474
+ }
475
+ if( preg_match('/\d{4}-\d{2}-\d{2}/', $this->event_start_date) && preg_match('/\d{4}-\d{2}-\d{2}/', $this->event_end_date) ){
476
+ if( strtotime($this->event_start_date . $this->event_start_time) > strtotime($this->event_end_date . $this->event_end_time) ){
477
+ $this->add_error(__('Events cannot start after they end.','dbem'));
478
+ }elseif( $this->is_recurring() && $this->recurrence_days == 0 && strtotime($this->event_start_date . $this->event_start_time) > strtotime($this->event_start_date . $this->event_end_time) ){
479
+ $this->add_error(__('Events cannot start after they end.','dbem').' '.__('For recurring events that end the following day, ensure you make your event last 1 or more days.'));
480
+ }
481
+ }else{
482
+ if( !empty($missing_fields['event_start_date']) ) { unset($missing_fields['event_start_date']); }
483
+ if( !empty($missing_fields['event_end_date']) ) { unset($missing_fields['event_end_date']); }
484
+ $this->add_error(__('Dates must have correct formatting. Please use the date picker provided.','dbem'));
485
+ }
486
+ if( $this->event_rsvp && !$this->get_bookings()->get_tickets()->validate() ){
487
+ $this->add_error($this->get_bookings()->get_tickets()->get_errors());
488
+ }
489
+ if( get_option('dbem_locations_enabled') && empty($this->location_id) ){ //location ids don't need validating as we're not saving a location
490
+ if( get_option('dbem_require_location',true) || $this->location_id !== 0 ){
491
+ if( !$this->get_location()->validate() ){
492
+ $this->add_error($this->get_location()->get_errors());
493
+ }
494
+ }
495
+ }
496
+ if ( count($missing_fields) > 0){
497
+ // TODO Create friendly equivelant names for missing fields notice in validation
498
+ $this->add_error( __( 'Missing fields: ', 'dbem') . implode ( ", ", $missing_fields ) . ". " );
499
+ }
500
+ if ( $this->is_recurring() && ($this->event_end_date == "" || $this->event_end_date == $this->event_start_date) ){
501
+ $this->add_error( __( 'Since the event is repeated, you must specify an event end date greater than the start date.', 'dbem' ));
502
+ }
503
+ return apply_filters('em_event_validate_meta', count($this->errors) == 0, $this );
504
+ }
505
+
506
+ /**
507
+ * Will save the current instance into the database, along with location information if a new one was created and return true if successful, false if not.
508
+ * Will automatically detect whether it's a new or existing event.
509
+ * @return boolean
510
+ */
511
+ function save(){
512
+ global $wpdb, $current_user, $blog_id;
513
+ if( !$this->can_manage('edit_events', 'edit_others_events') && !( get_option('dbem_events_anonymous_submissions') && empty($this->event_id)) ){
514
+ //unless events can be submitted by an anonymous user (and this is a new event), user must have permissions.
515
+ return apply_filters('em_event_save', false, $this);
516
+ }
517
+ remove_action('save_post',array('EM_Event_Post_Admin','save_post'),10,1); //disable the default save post action, we'll do it manually this way
518
+ do_action('em_event_save_pre', $this);
519
+ $post_array = array();
520
+ //Deal with updates to an event
521
+ if( !empty($this->post_id) ){
522
+ //get the full array of post data so we don't overwrite anything.
523
+ if( !empty($this->blog_id) && is_multisite() ){
524
+ $post_array = (array) get_blog_post($this->blog_id, $this->post_id);
525
+ }else{
526
+ $post_array = (array) get_post($this->post_id);
527
+ }
528
+ }
529
+ //Overwrite new post info
530
+ $post_array['post_type'] = ($this->recurrence && get_option('dbem_recurrence_enabled')) ? 'event-recurring':EM_POST_TYPE_EVENT;
531
+ $post_array['post_title'] = $this->event_name;
532
+ $post_array['post_content'] = $this->post_content;
533
+ //decide on post status
534
+ if( count($this->errors) == 0 ){
535
+ $post_array['post_status'] = ( $this->can_manage('publish_events','publish_events') ) ? 'publish':'pending';
536
+ }else{
537
+ $post_array['post_status'] = 'draft';
538
+ }
539
+ //anonymous submission only
540
+ if( !is_user_logged_in() && get_option('dbem_events_anonymous_submissions') && empty($this->event_id) ){
541
+ $post_array['post_author'] = get_option('dbem_events_anonymous_user');
542
+ if( !is_numeric($post_array['post_author']) ) $post_array['post_author'] = 0;
543
+ }
544
+ //Save post and continue with meta
545
+ $post_id = wp_insert_post($post_array);
546
+ $post_save = false;
547
+ $meta_save = false;
548
+ if( !is_wp_error($post_id) && !empty($post_id) ){
549
+ $post_save = true;
550
+ //refresh this event with wp post info we'll put into the db
551
+ $post_data = get_post($post_id);
552
+ $this->post_id = $post_id;
553
+ $this->event_slug = $post_data->post_name;
554
+ $this->event_owner = $post_data->post_author;
555
+ $this->post_status = $post_data->post_status;
556
+ $this->get_status();
557
+ //Categories? note that categories will soft-fail, so no errors
558
+ $this->get_categories()->save();
559
+ //anonymous submissions should save this information
560
+ if( !empty($this->event_owner_anonymous) ){
561
+ update_post_meta($this->post_id, '_event_owner_anonymous', 1);
562
+ update_post_meta($this->post_id, '_event_owner_name', $this->event_owner_name);
563
+ update_post_meta($this->post_id, '_event_owner_email', $this->event_owner_email);
564
+ }
565
+ //save the image
566
+ $this->image_upload();
567
+ //now save the meta
568
+ $meta_save = $this->save_meta();
569
+ $image_save = (count($this->errors) == 0); //whilst it might not be an image save that fails, we can know something went wrong
570
+ }
571
+ $result = $meta_save && $post_save && $image_save;
572
+ $previous_status = $this->previous_status;
573
+ if($result) $this->load_postdata($post_data, $blog_id); //reload post info
574
+ $this->previous_status = $previous_status;
575
+ //do a dirty update for location too if it's not published
576
+ if( $this->is_published() && !empty($this->location_id) ){
577
+ $EM_Location = $this->get_location();
578
+ if( $EM_Location->location_status !== 1 ){
579
+ //let's also publish the location
580
+ $EM_Location->set_status(1, true);
581
+ }
582
+ }
583
+ return apply_filters('em_event_save', $result, $this);
584
+ }
585
+
586
+ function save_meta(){
587
+ global $wpdb;
588
+ if( ( get_option('dbem_events_anonymous_submissions') && empty($this->event_id)) || $this->can_manage('edit_events', 'edit_others_events') ){
589
+ do_action('em_event_save_meta_pre', $this);
590
+ //first save location
591
+ if( empty($this->location_id) && !($this->location_id === 0 && !get_option('dbem_require_location',true)) ){
592
+ if( get_site_option('dbem_ms_mainblog_locations') ){ $this->ms_global_switch(); }
593
+ if( !$this->get_location()->save() ){ //soft fail
594
+ global $EM_Notices;
595
+ if( !empty($this->get_location()->location_id) ){
596
+ $EM_Notices->add_error( __('There were some errors saving your location.','dbem').' '.sprintf(__('It will not be displayed on the website listings, to correct this you must <a href="%s">edit your location</a> directly.'),$this->get_location()->output('#_LOCATIONEDITURL')), true);
597
+ }else{
598
+ $this->get_location()->set_status(null);
599
+ $EM_Notices->add_error( __('There were some errors saving your location.'), true);
600
+ }
601
+ }
602
+ if( get_site_option('dbem_ms_mainblog_locations') ){ $this->ms_global_switch_back(); }
603
+ if( !empty($this->location->location_id) ){ //only case we don't use get_location(), since it will fail as location has an id, whereas location_id isn't set in this object
604
+ $this->location_id = $this->location->location_id;
605
+ }
606
+ }
607
+ //Update Post Meta
608
+ foreach($this->fields as $key => $field_info){
609
+ if( !in_array($key, $this->post_fields) && $key != 'event_attributes' ){
610
+ update_post_meta($this->post_id, '_'.$key, $this->$key);
611
+ }elseif($key == 'event_attributes'){
612
+ //attributes get saved as individual keys
613
+ foreach($this->event_attributes as $event_attribute_key => $event_attribute){
614
+ if( !empty($event_attribute) ){
615
+ update_post_meta($this->post_id, $event_attribute_key, $event_attribute);
616
+ }else{
617
+ delete_post_meta($this->post_id, $event_attribute_key);
618
+ }
619
+ }
620
+ }
621
+ }
622
+ //update timestampes
623
+ update_post_meta($this->post_id, '_start_ts', str_pad($this->start, 10, 0, STR_PAD_LEFT));
624
+ update_post_meta($this->post_id, '_end_ts', str_pad($this->end, 10, 0, STR_PAD_LEFT));
625
+ //sort out event status
626
+ $result = count($this->errors) == 0;
627
+ $this->get_status();
628
+ $this->event_status = ($result) ? $this->event_status:null; //set status at this point, it's either the current status, or if validation fails, null
629
+ //Save to em_event table
630
+ $event_array = $this->to_array(true);
631
+ unset($event_array['event_id']);
632
+ if( $this->post_status == 'private' ) $event_array['event_private'] = 1;
633
+ $event_array['event_attributes'] = serialize($this->event_attributes); //might as well
634
+ if( !empty($this->event_id) ){
635
+ $blog_condition = '';
636
+ if( EM_MS_GLOBAL ){
637
+ $blog_condition = " AND blog_id='".get_current_blog_id()."' ";
638
+ }
639
+ $event_truly_exists = $wpdb->get_var('SELECT post_id FROM '.EM_EVENTS_TABLE." WHERE event_id={$this->event_id}".$blog_condition) == $this->post_id;
640
+ }else{
641
+ $event_truly_exists = false;
642
+ }
643
+ if( empty($this->event_id) || !$event_truly_exists ){
644
+ $this->previous_status = 0; //for sure this was previously status 0
645
+ $this->event_date_created = current_time('mysql');
646
+ if ( !$wpdb->insert(EM_EVENTS_TABLE, $event_array) ){
647
+ $this->add_error( sprintf(__('Something went wrong saving your %s to the index table. Please inform a site administrator about this.','dbem'),__('event','dbem')));
648
+ }else{
649
+ //success, so link the event with the post via an event id meta value for easy retrieval
650
+ $this->event_id = $wpdb->insert_id;
651
+ update_post_meta($this->post_id, '_event_id', $this->event_id);
652
+ $this->feedback_message = sprintf(__('Successfully saved %s','dbem'),__('Event','dbem'));
653
+ $just_added_event = true; //make an easy hook
654
+ do_action('em_event_save_new', $this);
655
+ }
656
+ }else{
657
+ $this->previous_status = $this->get_previous_status();
658
+ $this->event_date_modified = $event_array['event_date_modified'] = current_time('mysql');
659
+ if ( $wpdb->update(EM_EVENTS_TABLE, $event_array, array('event_id'=>$this->event_id) ) === false ){
660
+ $this->add_error( sprintf(__('Something went wrong updating your %s to the index table. Please inform a site administrator about this.','dbem'),__('event','dbem')));
661
+ }else{
662
+ //Also set the status here if status != previous status
663
+ if( $this->previous_status != $this->get_status()){
664
+ $status_value = $this->get_status(true);
665
+ $wpdb->query('UPDATE '.EM_EVENTS_TABLE." SET event_status=$status_value WHERE event_id=".$this->event_id);
666
+ }
667
+ $this->feedback_message = sprintf(__('Successfully saved %s','dbem'),__('Event','dbem'));
668
+ }
669
+ }
670
+ //Add/Delete Tickets
671
+ if($this->event_rsvp == 0){
672
+ $this->get_bookings()->delete();
673
+ }else{
674
+ if( !$this->get_bookings()->get_tickets()->save() ){
675
+ $this->add_error( $this->get_bookings()->get_tickets()->get_errors() );
676
+ }
677
+ }
678
+ $result = count($this->errors) == 0;
679
+ //If we're saving event categories in MS Global mode, we'll add them here, saving by term id (cat ids are gone now)
680
+ if( EM_MS_GLOBAL && !is_main_site() ){
681
+ $this->get_categories()->save(); //it'll know what to do
682
+ }elseif( EM_MS_GLOBAL ){
683
+ $this->get_categories()->save_index(); //just save to index, we assume cats are saved in $this->save();
684
+ }
685
+ //build recurrences if needed
686
+ if( $this->is_recurring() && $result && $this->is_published() ){ //only save events if recurring event validates and is published
687
+ if( !$this->save_events() ){ //only save if post is 'published'
688
+ $this->add_error(__ ( 'Something went wrong with the recurrence update...', 'dbem' ). __ ( 'There was a problem saving the recurring events.', 'dbem' ));
689
+ }
690
+ }
691
+ if( !empty($just_added_event) ){
692
+ do_action('em_event_added', $this);
693
+ }
694
+ }
695
+ $this->compat_keys();
696
+ return apply_filters('em_event_save_meta', count($this->errors) == 0, $this);
697
+ }
698
+
699
+ /**
700
+ * Duplicates this event and returns the duplicated event. Will return false if there is a problem with duplication.
701
+ * @return EM_Event
702
+ */
703
+ function duplicate(){
704
+ global $wpdb, $EZSQL_ERROR;
705
+ //First, duplicate.
706
+ if( $this->can_manage('edit_events','edit_others_events') ){
707
+ $EM_Event = clone $this;
708
+ $EM_Event->event_id = null;
709
+ //Duplicate Post
710
+ $fields = $wpdb->get_col("DESCRIBE ".$wpdb->posts);
711
+ unset($fields[0]);
712
+ $fields = implode(',',$fields);
713
+ $sql = "INSERT INTO {$wpdb->posts} ($fields) SELECT $fields FROM {$wpdb->posts} WHERE ID={$this->post_id}";
714
+ $result = $wpdb->query($sql);
715
+ //TODO make a post_id refresher function to change all post ids in objects this contains
716
+ $EM_Event->post_id = $EM_Event->get_categories()->post_id = $EM_Event->ID = $wpdb->insert_id;
717
+ $EM_Event->get_categories()->save();
718
+ //Duplicate Event Table index and tickets
719
+ if( $EM_Event->save_meta() ){
720
+ //duplicate tickets
721
+ $EM_Tickets = $this->get_bookings()->get_tickets();
722
+ foreach($EM_Tickets->tickets as $EM_Ticket){
723
+ $EM_Ticket->ticket_id = '';
724
+ $EM_Ticket->event_id = $EM_Event->event_id;
725
+ $EM_Ticket->save();
726
+ }
727
+ $EM_Event->get_bookings(true); //refresh booking tickets
728
+ $EM_Event->feedback_message = sprintf(__("%s successfully duplicated.", 'dbem'), __('Event','dbem'));
729
+ return apply_filters('em_event_duplicate', $EM_Event, $this);
730
+ }
731
+ }
732
+ //TODO add error notifications for duplication failures.
733
+ return apply_filters('em_event_duplicate', false, $this);;
734
+ }
735
+
736
+ /**
737
+ * Delete whole event, including bookings, tickets, etc.
738
+ * @return boolean
739
+ */
740
+ function delete($force_delete = false){ //atm wp seems to force cp deletions anyway
741
+ global $wpdb;
742
+ if( $this->can_manage('delete_events', 'delete_others_events') ){
743
+ remove_action('before_delete_post',array('EM_Event_Post_Admin','before_delete_post'),10,1); //since we're deleting directly, remove post actions
744
+ do_action('em_event_delete_pre', $this);
745
+ if( $force_delete ){
746
+ $result = wp_delete_post($this->post_id,$force_delete);
747
+ $result_meta = $this->delete_meta();
748
+ }else{
749
+ $result = wp_trash_post($this->post_id);
750
+ $result_meta = true;
751
+ $this->set_status(null); //FIXME status isn't set on trash post, maybe bug/nuance in WP when not admin side?
752
+ }
753
+ }else{
754
+ $result = $result_meta = false;
755
+ }
756
+ //print_r($result); echo "|"; print_r($result_meta); die('DELETING');
757
+ return apply_filters('em_event_delete', $result !== false && $result_meta, $this);
758
+ }
759
+
760
+ function delete_meta(){
761
+ global $wpdb;
762
+ $result = false;
763
+ if( $this->can_manage('delete_events', 'delete_others_events') ){
764
+ do_action('em_event_delete_meta_event_pre', $this);
765
+ $result = $wpdb->query ( $wpdb->prepare("DELETE FROM ". EM_EVENTS_TABLE ." WHERE event_id=%d", $this->event_id) );
766
+ if( $result !== false ){
767
+ $this->delete_bookings();
768
+ $this->delete_tickets();
769
+ //Delete the recurrences then this recurrence event
770
+ if( $this->is_recurring() ){
771
+ $result = $this->delete_events(); //was true at this point, so false if fails
772
+ }
773
+ //Delete categories from meta if in MS global mode
774
+ if( EM_MS_GLOBAL ){
775
+ $wpdb->query('DELETE FROM '.EM_META_TABLE.' WHERE object_id='.$this->event_id." AND meta_key='event-category'");
776
+ }
777
+ }
778
+ }
779
+ return apply_filters('em_event_delete_meta', $result !== false, $this);
780
+ }
781
+
782
+ /**
783
+ * Shortcut function for $this->get_bookings()->delete(), because using the EM_Bookings requires loading previous bookings, which isn't neceesary.
784
+ */
785
+ function delete_bookings(){
786
+ global $wpdb;
787
+ do_action('em_event_delete_bookings_pre', $this);
788
+ $result = false;
789
+ if( $this->can_manage('manage_bookings','manage_others_bookings') ){
790
+ $result_bt = $wpdb->query( $wpdb->prepare("DELETE FROM ".EM_TICKETS_BOOKINGS_TABLE." WHERE booking_id IN (SELECT booking_id FROM ".EM_BOOKINGS_TABLE." WHERE event_id=%d)", $this->event_id) );
791
+ $result = $wpdb->query( $wpdb->prepare("DELETE FROM ".EM_BOOKINGS_TABLE." WHERE event_id=%d", $this->event_id) );
792
+ }
793
+ return apply_filters('em_event_delete_bookings', $result !== false && $result_bt !== false, $this);
794
+ }
795
+
796
+ /**
797
+ * Shortcut function for $this->get_bookings()->delete(), because using the EM_Bookings requires loading previous bookings, which isn't neceesary.
798
+ */
799
+ function delete_tickets(){
800
+ global $wpdb;
801
+ do_action('em_event_delete_tickets_pre', $this);
802
+ $result = false;
803
+ if( $this->can_manage('manage_bookings','manage_others_bookings') ){
804
+ $result_bt = $wpdb->query( $wpdb->prepare("DELETE FROM ".EM_TICKETS_BOOKINGS_TABLE." WHERE ticket_id IN (SELECT ticket_id FROM ".EM_TICKETS_TABLE." WHERE event_id=%d)", $this->event_id) );
805
+ $result = $wpdb->query( $wpdb->prepare("DELETE FROM ".EM_TICKETS_TABLE." WHERE event_id=%d", $this->event_id) );
806
+ }
807
+ return apply_filters('em_event_delete_tickets', $result, $this);
808
+ }
809
+
810
+ /**
811
+ * Publish Events
812
+ * @return bool
813
+ */
814
+ function send_approval_notification(){
815
+ if( (!$this->is_recurring() && !user_can($this->event_owner, 'publish_events')) || ($this->is_recurring() && !user_can($this->event_owner, 'publish_recurring_events')) ){
816
+ //only send email to users that can't publish events themselves and that were previously unpublished
817
+ if( !$this->previous_status && $this->is_published() ){
818
+ //email
819
+ if( $this->event_owner == "" ) return true;
820
+ $subject = $this->output(get_option('dbem_event_approved_email_subject'), 'email');
821
+ $body = $this->output(get_option('dbem_event_approved_email_body'), 'email');
822
+
823
+ //Send to the person booking
824
+ if( !$this->email_send( $subject, $body, $this->get_contact()->user_email) ){
825
+ return false;
826
+ }
827
+ return true;
828
+ }
829
+ }
830
+ return false;
831
+ }
832
+
833
+ /**
834
+ * Change the status of the event. This will save to the Database too.
835
+ * @param int $status
836
+ * @param boolean $set_post_status
837
+ * @return string
838
+ */
839
+ function set_status($status, $set_post_status = false){
840
+ global $wpdb;
841
+ if($status === null){
842
+ $set_status='NULL';
843
+ if($set_post_status){
844
+ //if the post is trash, don't untrash it!
845
+ $wpdb->update( $wpdb->posts, array( 'post_status' => 'draft' ), array( 'ID' => $this->post_id ) );
846
+ $this->post_status = 'draft';
847
+ }
848
+ }else{
849
+ $set_status = $status ? 1:0;
850
+ if($set_post_status){
851
+ if($this->post_status == 'pending'){
852
+ $this->post_name = sanitize_title($this->post_title);
853
+ }
854
+ $this->post_status = $set_status ? 'publish':'pending';
855
+ $wpdb->update( $wpdb->posts, array( 'post_status' => $this->post_status, 'post_name' => $this->post_name ), array( 'ID' => $this->post_id ) );
856
+ }
857
+ }
858
+ $this->previous_status = $this->get_previous_status();
859
+ $result = $wpdb->query("UPDATE ".EM_EVENTS_TABLE." SET event_status=$set_status, event_slug='{$this->post_name}' WHERE event_id=".$this->event_id);
860
+ $this->get_status(); //reload status
861
+ return apply_filters('em_event_set_status', $result !== false, $status, $this);
862
+ }
863
+
864
+ function is_published(){
865
+ return apply_filters('em_event_is_published', ($this->post_status == 'publish' || $this->post_status == 'private'), $this);
866
+ }
867
+
868
+ function get_status($db = false){
869
+ switch( $this->post_status ){
870
+ case 'private':
871
+ $this->event_private = 1;
872
+ $this->event_status = $status = 1;
873
+ break;
874
+ case 'publish':
875
+ $this->event_private = 0;
876
+ $this->event_status = $status = 1;
877
+ break;
878
+ case 'pending':
879
+ $this->event_private = 0;
880
+ $this->event_status = $status = 0;
881
+ break;
882
+ default: //draft or unknown
883
+ $this->event_private = 0;
884
+ $status = $db ? 'NULL':null;
885
+ $this->event_status = null;
886
+ break;
887
+ }
888
+ return $status;
889
+ }
890
+
891
+ function get_previous_status(){
892
+ global $wpdb;
893
+ return $wpdb->get_var('SELECT event_status FROM '.EM_EVENTS_TABLE.' WHERE event_id='.$this->event_id); //get status from db, not post_status, as posts get saved quickly
894
+ }
895
+
896
+ /**
897
+ * Returns an EM_Categories object of the EM_Event instance.
898
+ * @return EM_Categories
899
+ */
900
+ function get_categories() {
901
+ if( empty($this->categories) ){
902
+ $this->categories = new EM_Categories($this);
903
+ }elseif(empty($this->categories->event_id)){
904
+ $this->categories->event_id = $this->event_id;
905
+ $this->categories->post_id = $this->post_id;
906
+ }
907
+ return apply_filters('em_event_get_categories', $this->categories, $this);
908
+ }
909
+
910
+ /**
911
+ * Returns the location object this event belongs to.
912
+ * @return EM_Location
913
+ */
914
+ function get_location() {
915
+ global $EM_Location;
916
+ if( is_object($EM_Location) && $EM_Location->location_id == $this->location_id ){
917
+ $this->location = $EM_Location;
918
+ }else{
919
+ if( !is_object($this->location) || $this->location->location_id != $this->location_id ){
920
+ $this->location = em_get_location($this->location_id);
921
+ }
922
+ }
923
+ return $this->location;
924
+ }
925
+
926
+ /**
927
+ * Returns the location object this event belongs to.
928
+ * @return EM_Person
929
+ */
930
+ function get_contact(){
931
+ if( !is_object($this->contact) ){
932
+ $this->contact = new EM_Person($this->event_owner);
933
+ //if this is anonymous submission, change contact email and name
934
+ if( $this->event_owner_anonymous ){
935
+ $this->contact->user_email = $this->event_owner_email;
936
+ $name = explode(' ',$this->event_owner_name);
937
+ $first_name = array_shift($name);
938
+ $last_name = (count($name) > 0) ? implode(' ',$name):'';
939
+ $this->contact->user_firstname = $this->contact->first_name = $first_name;
940
+ $this->contact->user_lastname = $this->contact->last_name = $last_name;
941
+ }
942
+ }
943
+ return $this->contact;
944
+ }
945
+
946
+ /**
947
+ * Retrieve and save the bookings belonging to instance. If called again will return cached version, set $force_reload to true to create a new EM_Bookings object.
948
+ * @param boolean $force_reload
949
+ * @return EM_Bookings
950
+ */
951
+ function get_bookings( $force_reload = false ){
952
+ if( get_option('dbem_rsvp_enabled') ){
953
+ if( (!$this->bookings || $force_reload) ){
954
+ $this->bookings = new EM_Bookings($this);
955
+ }
956
+ $this->bookings->event_id = $this->event_id; //always refresh event_id
957
+ }else{
958
+ return new EM_Bookings();
959
+ }
960
+ return apply_filters('em_event_get_bookings', $this->bookings, $this);
961
+ }
962
+
963
+ /**
964
+ * Get the tickets related to this event.
965
+ * @param boolean $force_reload
966
+ * @return EM_Tickets
967
+ */
968
+ function get_tickets( $force_reload = false ){
969
+ return $this->get_bookings($force_reload)->get_tickets();
970
+ }
971
+
972
+ /**
973
+ * Gets number of spaces in this event, dependent on ticket spaces or hard limit, whichever is smaller.
974
+ * @param boolean $force_refresh
975
+ * @return int
976
+ */
977
+ function get_spaces($force_refresh=false){
978
+ return $this->get_bookings()->get_spaces($force_refresh);
979
+ }
980
+
981
+ function get_edit_reschedule_url(){
982
+ if( $this->is_recurrence() ){
983
+ $EM_Event = em_get_event($this->recurrence_id);
984
+ return $EM_Event->get_edit_url();
985
+ }
986
+ }
987
+
988
+ function get_edit_url(){
989
+ if( $this->can_manage('edit_events','edit_others_events') ){
990
+ if( EM_MS_GLOBAL && get_site_option('dbem_ms_global_events_links') && !empty($this->blog_id) && is_main_site() && $this->blog_id != get_current_blog_id() ){
991
+ if( get_blog_option($this->blog_id, 'dbem_edit_events_page') ){
992
+ $link = em_add_get_params(get_permalink(get_blog_option($this->blog_id, 'dbem_edit_events_page')), array('action'=>'edit','event_id'=>$this->event_id), false);
993
+ }
994
+ if( empty($link))
995
+ $link = get_admin_url($this->blog_id, "post.php?post={$this->post_id}&action=edit");
996
+ }else{
997
+ if( get_option('dbem_edit_events_page') && !is_admin() ){
998
+ $link = em_add_get_params(get_permalink(get_option('dbem_edit_events_page')), array('action'=>'edit','event_id'=>$this->event_id), false);
999
+ }
1000
+ if( empty($link))
1001
+ $link = admin_url()."post.php?post={$this->post_id}&action=edit";
1002
+ }
1003
+ return apply_filters('em_event_get_edit_url', $link, $this);
1004
+ }
1005
+ }
1006
+
1007
+ function get_bookings_url(){
1008
+ if( get_option('dbem_edit_bookings_page') && !is_admin() ){
1009
+ $my_bookings_page = get_permalink(get_option('dbem_edit_bookings_page'));
1010
+ $bookings_link = em_add_get_params($my_bookings_page, array('event_id'=>$this->event_id), false);
1011
+ }else{
1012
+ if( $this->blog_id != get_current_blog_id() ){
1013
+ $bookings_link = get_admin_url($this->blog_id, 'edit.php?post_type='.EM_POST_TYPE_EVENT."&page=events-manager-bookings&event_id=".$this->event_id);
1014
+ }else{
1015
+ $bookings_link = EM_ADMIN_URL. "&page=events-manager-bookings&event_id=".$this->event_id;
1016
+ }
1017
+ }
1018
+ return apply_filters('em_event_get_bookings_url', $bookings_link, $this);
1019
+ }
1020
+
1021
+ function get_permalink(){
1022
+ if( EM_MS_GLOBAL ){
1023
+ if( get_site_option('dbem_ms_global_events_links') && !empty($this->blog_id) && is_main_site() && $this->blog_id != get_current_blog_id() ){
1024
+ //linking directly to the blog
1025
+ $event_link = get_blog_permalink( $this->blog_id, $this->post_id);
1026
+ }elseif( !empty($this->blog_id) && is_main_site() && $this->blog_id != get_current_blog_id() ){
1027
+ if( get_option('dbem_events_page') ){
1028
+ $event_link = trailingslashit(get_permalink(get_option('dbem_events_page')).get_site_option('dbem_ms_events_slug',EM_EVENT_SLUG).'/'.$this->event_slug.'-'.$this->event_id);
1029
+ }else{
1030
+ $event_link = trailingslashit(home_url()).EM_POST_TYPE_EVENT_SLUG.'/'.get_site_option('dbem_ms_events_slug',EM_EVENT_SLUG).'/'.$this->event_slug.'-'.$this->event_id;
1031
+ }
1032
+ }
1033
+ }
1034
+ if( empty($event_link) ){
1035
+ $event_link = get_post_permalink($this->post_id);
1036
+ }
1037
+ return apply_filters('em_event_get_permalink', $event_link, $this);
1038
+ }
1039
+
1040
+ function get_ical_url(){
1041
+ global $wp_rewrite;
1042
+ if( !empty($wp_rewrite) && $wp_rewrite->using_permalinks() ){
1043
+ return trailingslashit($this->get_permalink()).'ical/';
1044
+ }else{
1045
+ return em_add_get_params($this->get_permalink(), array('ical'=>1));
1046
+ }
1047
+ }
1048
+
1049
+ function is_free(){
1050
+ $free = true;
1051
+ foreach($this->get_tickets() as $EM_Ticket){
1052
+ if( $EM_Ticket->get_price() > 0 ){
1053
+ $free = false;
1054
+ }
1055
+ }
1056
+ return apply_filters('em_event_is_free',$free,$this);
1057
+ }
1058
+
1059
+ /**
1060
+ * Will output a single event format of this event.
1061
+ * Equivalent of calling EM_Event::output( get_option ( 'dbem_single_event_format' ) )
1062
+ * @param string $target
1063
+ * @return string
1064
+ */
1065
+ function output_single($target='html'){
1066
+ $format = get_option ( 'dbem_single_event_format' );
1067
+ return apply_filters('em_event_output_single', $this->output($format, $target), $this, $target);
1068
+ }
1069
+
1070
+ /**
1071
+ * Will output a event in the format passed in $format by replacing placeholders within the format.
1072
+ * @param string $format
1073
+ * @param string $target
1074
+ * @return string
1075
+ */
1076
+ function output($format, $target="html") {
1077
+ $event_string = $format;
1078
+ //Time place holder that doesn't show if empty.
1079
+ //TODO add filter here too
1080
+ preg_match_all('/#@?_\{[^}]+\}/', $format, $results);
1081
+ foreach($results[0] as $result) {
1082
+ if(substr($result, 0, 3 ) == "#@_"){
1083
+ $date = 'end_date';
1084
+ $offset = 4;
1085
+ }else{
1086
+ $date = 'start_date';
1087
+ $offset = 3;
1088
+ }
1089
+ if( $date == 'end_date' && $this->event_end_date == $this->event_start_date ){
1090
+ $replace = __( apply_filters('em_event_output_placeholder', '', $this, $result, $target) );
1091
+ }else{
1092
+ $replace = __( apply_filters('em_event_output_placeholder', mysql2date(substr($result, $offset, (strlen($result)-($offset+1)) ), $this->$date), $this, $result, $target) );
1093
+ }
1094
+ $event_string = str_replace($result,$replace,$event_string );
1095
+ }
1096
+ //This is for the custom attributes
1097
+ preg_match_all('/#_ATT\{([^}]+)\}(\{([^}]+)\})?/', $format, $results);
1098
+ foreach($results[0] as $resultKey => $result) {
1099
+ //Strip string of placeholder and just leave the reference
1100
+ $attRef = substr( substr($result, 0, strpos($result, '}')), 6 );
1101
+ $attString = '';
1102
+ if( is_array($this->event_attributes) && array_key_exists($attRef, $this->event_attributes) ){
1103
+ $attString = $this->event_attributes[$attRef];
1104
+ }elseif( !empty($results[3][$resultKey]) ){
1105
+ //Check to see if we have a second set of braces;
1106
+ $attString = $results[3][$resultKey];
1107
+ }
1108
+ $attString = apply_filters('em_event_output_placeholder', $attString, $this, $result, $target);
1109
+ $event_string = str_replace($result, $attString ,$event_string );
1110
+ }
1111
+ //First let's do some conditional placeholder removals
1112
+ for ($i = 0 ; $i < get_option('dbem_conditional_recursions',1); $i++){ //you can add nested recursions by modifying this setting in your wp_options table
1113
+ preg_match_all('/\{([a-zA-Z0-9_]+)\}(.+?)\{\/\1\}/s', $event_string, $conditionals);
1114
+ if( count($conditionals[0]) > 0 ){
1115
+ //Check if the language we want exists, if not we take the first language there
1116
+ foreach($conditionals[1] as $key => $condition){
1117
+ $show_condition = false;
1118
+ if ($condition == 'has_bookings') {
1119
+ //check if there's a booking, if not, remove this section of code.
1120
+ $show_condition = ($this->event_rsvp && get_option('dbem_rsvp_enabled'));
1121
+ }elseif ($condition == 'no_bookings') {
1122
+ //check if there's a booking, if not, remove this section of code.
1123
+ $show_condition = (!$this->event_rsvp && get_option('dbem_rsvp_enabled'));
1124
+ }elseif ($condition == 'no_location'){
1125
+ //does this event have a valid location?
1126
+ $show_condition = ( empty($this->location_id) || !$this->get_location()->location_status );
1127
+ }elseif ($condition == 'has_location'){
1128
+ //does this event have a valid location?
1129
+ $show_condition = ( !empty($this->location_id) && $this->get_location()->location_status );
1130
+ }elseif ($condition == 'has_image'){
1131
+ //does this event have an image?
1132
+ $show_condition = ( $this->get_image_url() != '' );
1133
+ }elseif ($condition == 'no_image'){
1134
+ //does this event have an image?
1135
+ $show_condition = ( $this->get_image_url() == '' );
1136
+ }elseif ($condition == 'has_time'){
1137
+ //are the booking times different and not an all-day event
1138
+ $show_condition = ( $this->start != $this->end && !$this->event_all_day );
1139
+ }elseif ($condition == 'no_time'){
1140
+ //are the booking times exactly the same and it's not an all-day event.
1141
+ $show_condition = ( $this->event_start_time == $this->event_end_time && !$this->event_all_day );
1142
+ }elseif ($condition == 'all_day'){
1143
+ //is it an all day event
1144
+ $show_condition = !empty($this->event_all_day);
1145
+ }elseif ($condition == 'logged_in'){
1146
+ //user is logged in
1147
+ $show_condition = is_user_logged_in();
1148
+ }elseif ($condition == 'not_logged_in'){
1149
+ //not logged in
1150
+ $show_condition = !is_user_logged_in();
1151
+ }elseif ($condition == 'has_spaces'){
1152
+ //is it an all day event
1153
+ $show_condition = $this->event_rsvp && $this->get_bookings()->get_available_spaces() > 0;
1154
+ }elseif ($condition == 'fully_booked'){
1155
+ //is it an all day event
1156
+ $show_condition = $this->event_rsvp && $this->get_bookings()->get_available_spaces() <= 0;
1157
+ }elseif ($condition == 'is_long'){
1158
+ //is it an all day event
1159
+ $show_condition = $this->event_start_date != $this->event_end_date;
1160
+ }elseif ($condition == 'not_long'){
1161
+ //is it an all day event
1162
+ $show_condition = $this->event_start_date == $this->event_end_date;
1163
+ }elseif ($condition == 'is_past'){
1164
+ //if event is past
1165
+ $show_condition = $this->start <= current_time('timestamp');
1166
+ }elseif ($condition == 'is_future'){
1167
+ //if event is upcoming
1168
+ $show_condition = $this->start > current_time('timestamp');
1169
+ }
1170
+ $show_condition = apply_filters('em_event_output_show_condition', $show_condition, $condition, $conditionals[0][$key], $this);
1171
+ if($show_condition){
1172
+ //calculate lengths to delete placeholders
1173
+ $placeholder_length = strlen($condition)+2;
1174
+ $replacement = substr($conditionals[0][$key], $placeholder_length, strlen($conditionals[0][$key])-($placeholder_length *2 +1));
1175
+ }else{
1176
+ $replacement = '';
1177
+ }
1178
+ $event_string = str_replace($conditionals[0][$key], apply_filters('em_event_output_condition', $replacement, $condition, $conditionals[0][$key], $this), $event_string);
1179
+ }
1180
+ }
1181
+ }
1182
+ //Now let's check out the placeholders.
1183
+ preg_match_all("/(#@?_?[A-Za-z0-9]+)({([a-zA-Z0-9_,]+)})?/", $format, $placeholders);
1184
+ $replaces = array();
1185
+ foreach($placeholders[1] as $key => $result) {
1186
+ $match = true;
1187
+ $replace = '';
1188
+ $full_result = $placeholders[0][$key];
1189
+ switch( $result ){
1190
+ //Event Details
1191
+ case '#_EVENTID':
1192
+ $replace = $this->event_id;
1193
+ break;
1194
+ case '#_EVENTPOSTID':
1195
+ $replace = $this->post_id;
1196
+ break;
1197
+ case '#_NAME': //depreciated
1198
+ case '#_EVENTNAME':
1199
+ $replace = $this->event_name;
1200
+ break;
1201
+ case '#_NOTES': //depreciated
1202
+ case '#_EXCERPT': //depreciated
1203
+ case '#_EVENTNOTES':
1204
+ case '#_EVENTEXCERPT':
1205
+ $replace = $this->post_content;
1206
+ if($result == "#_EXCERPT" || $result == "#_EVENTEXCERPT"){
1207
+ if( !empty($this->post_excerpt) ){
1208
+ $replace = $this->post_excerpt;
1209
+ }else{
1210
+ $matches = explode('<!--more', $this->post_content);
1211
+ $replace = $matches[0];
1212
+ }
1213
+ }
1214
+ break;
1215
+ case '#_EVENTIMAGEURL':
1216
+ case '#_EVENTIMAGE':
1217
+ if($this->get_image_url() != ''){
1218
+ if($result == '#_EVENTIMAGEURL'){
1219
+ $replace = esc_url($this->image_url);
1220
+ }else{
1221
+ if( empty($placeholders[3][$key]) ){
1222
+ $replace = "<img src='".esc_url($this->image_url)."' alt='".esc_attr($this->event_name)."'/>";
1223
+ }else{
1224
+ $image_size = explode(',', $placeholders[3][$key]);
1225
+ $image_src = $this->image_url;
1226
+ if( $this->array_is_numeric($image_size) && count($image_size) > 1 ){
1227
+ global $blog_id;
1228
+ if ( is_multisite() && $blog_id > 0) {
1229
+ $imageParts = explode('/blogs.dir/', $image_src);
1230
+ if (isset($imageParts[1])) {
1231
+ $image_src = network_site_url('/wp-content/blogs.dir/'. $blog_id. '/' . $imageParts[1]);
1232
+ }
1233
+ }
1234
+ $replace = "<img src='".esc_url(em_get_thumbnail_url($image_src, $image_size[0], $image_size[1]))."' alt='".esc_attr($this->event_name)."'/>";
1235
+ }else{
1236
+ $replace = "<img src='".esc_url($image_src)."' alt='".esc_attr($this->event_name)."'/>";
1237
+ }
1238
+ }
1239
+ }
1240
+ }
1241
+ break;
1242
+ //Times & Dates
1243
+ case '#_24HSTARTTIME':
1244
+ case '#_24HENDTIME':
1245
+ $time = ($result == '#_24HSTARTTIME') ? $this->event_start_time:$this->event_end_time;
1246
+ $replace = substr($time, 0,5);
1247
+ break;
1248
+ case '#_12HSTARTTIME':
1249
+ case '#_12HENDTIME':
1250
+ $time = ($result == '#_12HSTARTTIME') ? $this->event_start_time:$this->event_end_time;
1251
+ $replace = date('g:i A', strtotime($time));
1252
+ break;
1253
+ case '#_EVENTTIMES':
1254
+ //get format of time to show
1255
+ if( !$this->event_all_day ){
1256
+ $time_format = ( get_option('dbem_time_format') ) ? get_option('dbem_time_format'):get_option('time_format');
1257
+ if($this->event_start_time != $this->event_end_time ){
1258
+ $replace = date_i18n($time_format, $this->start). get_option('dbem_times_seperator') . date_i18n($time_format, $this->end);
1259
+ }else{
1260
+ $replace = date_i18n($time_format, $this->start);
1261
+ }
1262
+ }else{
1263
+ $replace = get_option('dbem_event_all_day_message');
1264
+ }
1265
+ break;
1266
+ case '#_EVENTDATES':
1267
+ //get format of time to show
1268
+ $date_format = ( get_option('dbem_date_format') ) ? get_option('dbem_date_format'):get_option('date_format');
1269
+ if( $this->event_start_date != $this->event_end_date){
1270
+ $replace = date_i18n($date_format, $this->start). get_option('dbem_dates_seperator') . date_i18n($date_format, $this->end);
1271
+ }else{
1272
+ $replace = date_i18n($date_format, $this->start);
1273
+ }
1274
+ break;
1275
+ //Links
1276
+ case '#_EVENTPAGEURL': //Depreciated
1277
+ case '#_LINKEDNAME': //Depreciated
1278
+ case '#_EVENTURL': //Just the URL
1279
+ case '#_EVENTLINK': //HTML Link
1280
+ $event_link = esc_url($this->get_permalink());
1281
+ if($result == '#_LINKEDNAME' || $result == '#_EVENTLINK'){
1282
+ $replace = '<a href="'.$event_link.'" title="'.esc_attr($this->event_name).'">'.esc_attr($this->event_name).'</a>';
1283
+ }else{
1284
+ $replace = $event_link;
1285
+ }
1286
+ break;
1287
+ case '#_EDITEVENTURL':
1288
+ case '#_EDITEVENTLINK':
1289
+ if( $this->can_manage('edit_events','edit_others_events') ){
1290
+ $link = esc_url($this->get_edit_url());
1291
+ if( $result == '#_EDITEVENTLINK'){
1292
+ $replace = '<a href="'.$link.'">'.esc_html(sprintf(__('Edit %s','dbem'),__('Event','dbem'))).'</a>';
1293
+ }else{
1294
+ $replace = $link;
1295
+ }
1296
+ }
1297
+ break;
1298
+ //Bookings
1299
+ case '#_ADDBOOKINGFORM': //Depreciated
1300
+ case '#_REMOVEBOOKINGFORM': //Depreciated
1301
+ case '#_BOOKINGFORM':
1302
+ if( get_option('dbem_rsvp_enabled')){
1303
+ ob_start();
1304
+ $template = em_locate_template('placeholders/bookingform.php', true, array('EM_Event'=>$this));
1305
+ if( !defined('EM_BOOKING_JS_LOADED') ){
1306
+ //this kicks off the Javascript required by booking forms. This is fired once for all booking forms on a page load and appears at the bottom of the page
1307
+ //your theme must call the wp_footer() function for this to work (as required by many other plugins too)
1308
+ function em_booking_js_footer(){
1309
+ ?>
1310
+ <script type="text/javascript">
1311
+ jQuery(document).ready( function($){
1312
+ <?php
1313
+ //we call the segmented JS files and include them here
1314
+ include(WP_PLUGIN_DIR.'/events-manager/includes/js/bookingsform.js');
1315
+ do_action('em_gateway_js');
1316
+ ?>
1317
+ });
1318
+ </script>
1319
+ <?php
1320
+ }
1321
+ add_action('wp_footer','em_booking_js_footer');
1322
+ add_action('admin_footer','em_booking_js_footer');
1323
+ define('EM_BOOKING_JS_LOADED',true);
1324
+ }
1325
+ $replace = ob_get_clean();
1326
+ }
1327
+ break;
1328
+ case '#_BOOKINGBUTTON':
1329
+ if( get_option('dbem_rsvp_enabled')){
1330
+ ob_start();
1331
+ $template = em_locate_template('placeholders/bookingbutton.php', true, array('EM_Event'=>$this));
1332
+ $replace = ob_get_clean();
1333
+ }
1334
+ break;
1335
+ case '#_EVENTPRICERANGE':
1336
+ //get the range of prices
1337
+ $min = false;
1338
+ $max = 0;
1339
+ foreach( $this->get_tickets()->tickets as $EM_Ticket ){
1340
+ if($EM_Ticket->get_price() > $max ){
1341
+ $max = $EM_Ticket->get_price();
1342
+ }
1343
+ if($EM_Ticket->get_price() < $min || $min === false){
1344
+ $min = $EM_Ticket->get_price();
1345
+ }
1346
+ }
1347
+ if( $min === false ) $min = 0;
1348
+ if( $min != $max ){
1349
+ $replace = em_get_currency_formatted($min).' - '.em_get_currency_formatted($max);
1350
+ }else{
1351
+ $replace = em_get_currency_formatted($min);
1352
+ }
1353
+ break;
1354
+ case '#_EVENTPRICEMIN':
1355
+ //get the range of prices
1356
+ $min = false;
1357
+ foreach( $this->get_tickets()->tickets as $EM_Ticket ){
1358
+ if( $EM_Ticket->get_price() < $min || $min === false){
1359
+ $min = $EM_Ticket->get_price();
1360
+ }
1361
+ }
1362
+ if( $min === false ) $min = 0;
1363
+ $replace = em_get_currency_formatted($min);
1364
+ break;
1365
+ case '#_EVENTPRICEMAX':
1366
+ //get the range of prices
1367
+ $max = 0;
1368
+ foreach( $this->get_tickets()->tickets as $EM_Ticket ){
1369
+ if( $EM_Ticket->get_price() > $max ){
1370
+ $max = $EM_Ticket->get_price();
1371
+ }
1372
+ }
1373
+ $replace = em_get_currency_formatted($max);
1374
+ break;
1375
+ case '#_AVAILABLESEATS': //Depreciated
1376
+ case '#_AVAILABLESPACES':
1377
+ if ($this->event_rsvp && get_option('dbem_rsvp_enabled')) {
1378
+ $replace = $this->get_bookings()->get_available_spaces();
1379
+ } else {
1380
+ $replace = "0";
1381
+ }
1382
+ break;
1383
+ case '#_BOOKEDSEATS': //Depreciated
1384
+ case '#_BOOKEDSPACES':
1385
+ //This placeholder is actually a little misleading, as it'll consider reserved (i.e. pending) bookings as 'booked'
1386
+ if ($this->event_rsvp && get_option('dbem_rsvp_enabled')) {
1387
+ $replace = $this->get_bookings()->get_booked_spaces();
1388
+ if( get_option('dbem_bookings_approval_reserved') ){
1389
+ $replace += $this->get_bookings()->get_pending_spaces();
1390
+ }
1391
+ } else {
1392
+ $replace = "0";
1393
+ }
1394
+ break;
1395
+ case '#_PENDINGSPACES':
1396
+ if ($this->event_rsvp && get_option('dbem_rsvp_enabled')) {
1397
+ $replace = $this->get_bookings()->get_pending_spaces();
1398
+ } else {
1399
+ $replace = "0";
1400
+ }
1401
+ break;
1402
+ case '#_SEATS': //Depreciated
1403
+ case '#_SPACES':
1404
+ $replace = $this->get_spaces();
1405
+ break;
1406
+ case '#_BOOKINGSURL':
1407
+ case '#_BOOKINGSLINK':
1408
+ if( $this->can_manage('manage_bookings','manage_others_bookings') ){
1409
+ $bookings_link = esc_url($this->get_bookings_url());
1410
+ if($result == '#_BOOKINGSLINK'){
1411
+ $replace = '<a href="'.$bookings_link.'" title="'.esc_attr($this->event_name).'">'.esc_html($this->event_name).'</a>';
1412
+ }else{
1413
+ $replace = $bookings_link;
1414
+ }
1415
+ }
1416
+ break;
1417
+ //Contact Person
1418
+ case '#_CONTACTNAME':
1419
+ case '#_CONTACTPERSON': //Depreciated (your call, I think name is better)
1420
+ $replace = $this->get_contact()->display_name;
1421
+ break;
1422
+ case '#_CONTACTUSERNAME':
1423
+ $replace = $this->get_contact()->user_login;
1424
+ break;
1425
+ case '#_CONTACTEMAIL':
1426
+ case '#_CONTACTMAIL': //Depreciated
1427
+ $replace = $this->get_contact()->user_email;
1428
+ break;
1429
+ case '#_CONTACTID':
1430
+ $replace = $this->get_contact()->ID;
1431
+ break;
1432
+ case '#_CONTACTPHONE':
1433
+ $replace = ( $this->get_contact()->phone != '') ? $this->get_contact()->phone : __('N/A', 'dbem');
1434
+ break;
1435
+ case '#_CONTACTAVATAR':
1436
+ $replace = get_avatar( $this->get_contact()->ID, $size = '50' );
1437
+ break;
1438
+ case '#_CONTACTPROFILELINK':
1439
+ case '#_CONTACTPROFILEURL':
1440
+ if( function_exists('bp_core_get_user_domain') ){
1441
+ $replace = bp_core_get_user_domain($this->get_contact()->ID);
1442
+ if( $result == '#_CONTACTPROFILELINK' ){
1443
+ $replace = '<a href="'.esc_url($replace).'">'.__('Profile', 'dbem').'</a>';
1444
+ }
1445
+ }
1446
+ break;
1447
+ case '#_CONTACTMETA':
1448
+ if( !empty($placeholders[3][$key]) ){
1449
+ $replace = get_user_meta($this->event_owner, $placeholders[3][$key], true);
1450
+ }
1451
+ break;
1452
+ case '#_ATTENDEES':
1453
+ ob_start();
1454
+ $template = em_locate_template('placeholders/attendees.php', true, array('EM_Event'=>$this));
1455
+ $replace = ob_get_clean();
1456
+ break;
1457
+ case '#_ATTENDEESLIST':
1458
+ ob_start();
1459
+ $template = em_locate_template('placeholders/attendeeslist.php', true, array('EM_Event'=>$this));
1460
+ $replace = ob_get_clean();
1461
+ break;
1462
+ //Categories and Tags
1463
+ case '#_EVENTCATEGORIESIMAGES':
1464
+ ob_start();
1465
+ $template = em_locate_template('placeholders/eventcategoriesimages.php', true, array('EM_Event'=>$this));
1466
+ $replace = ob_get_clean();
1467
+ break;
1468
+ case '#_EVENTTAGS':
1469
+ ob_start();
1470
+ $template = em_locate_template('placeholders/eventtags.php', true, array('EM_Event'=>$this));
1471
+ $replace = ob_get_clean();
1472
+ break;
1473
+ case '#_CATEGORIES': //depreciated
1474
+ case '#_EVENTCATEGORIES':
1475
+ ob_start();
1476
+ $template = em_locate_template('placeholders/categories.php', true, array('EM_Event'=>$this));
1477
+ $replace = ob_get_clean();
1478
+ break;
1479
+ //Ical Stuff
1480
+ case '#_EVENTICALURL':
1481
+ case '#_EVENTICALLINK':
1482
+ $replace = $this->get_ical_url();
1483
+ if( $result == '#_EVENTICALLINK' ){
1484
+ $replace = '<a href="'.esc_url($replace).'">iCal</a>';
1485
+ }
1486
+ break;
1487
+ case '#_EVENTGCALURL':
1488
+ case '#_EVENTGCALLINK':
1489
+ //get dates
1490
+ if($this->event_all_day && $this->event_start_date == $this->event_end_date){
1491
+ $dateStart = date('Ymd',$this->start - (60*60*get_option('gmt_offset')));
1492
+ $dateEnd = date('Ymd',$this->start + 60*60*24 - (60*60*get_option('gmt_offset')));
1493
+ }else{
1494
+ $dateStart = date('Ymd\THis\Z',$this->start - (60*60*get_option('gmt_offset')));
1495
+ $dateEnd = date('Ymd\THis\Z',$this->end - (60*60*get_option('gmt_offset')));
1496
+ }
1497
+ //build url
1498
+ $gcal_url = 'http://www.google.com/calendar/event?action=TEMPLATE&text=event_name&dates=start_date/end_date&details=post_content&location=location_name&trp=false&sprop=event_url&sprop=name:blog_name';
1499
+ $gcal_url = str_replace('event_name', urlencode($this->event_name), $gcal_url);
1500
+ $gcal_url = str_replace('start_date', urlencode($dateStart), $gcal_url);
1501
+ $gcal_url = str_replace('end_date', urlencode($dateEnd), $gcal_url);
1502
+ $gcal_url = str_replace('location_name', urlencode($this->output('#_LOCATION')), $gcal_url);
1503
+ $gcal_url = str_replace('blog_name', urlencode(get_bloginfo()), $gcal_url);
1504
+ $gcal_url = str_replace('event_url', urlencode($this->get_permalink()), $gcal_url);
1505
+ //calculate URL length so we know how much we can work with to make a description.
1506
+ if( !empty($this->post_excerpt) ){
1507
+ $gcal_url_description = $this->post_excerpt;
1508
+ }else{
1509
+ $matches = explode('<!--more', $this->post_content);
1510
+ $gcal_url_description = wp_kses_data($matches[0]);
1511
+ }
1512
+ $gcal_url_length = strlen($gcal_url) - 9;
1513
+ if( strlen($gcal_url_description) + $gcal_url_length > 1500 ){
1514
+ $gcal_url_description = substr($gcal_url_description, 0, 1530 - $gcal_url_length - 3 ).'...';
1515
+ }
1516
+ $gcal_url = str_replace('post_content', urlencode($gcal_url_description), $gcal_url);
1517
+ //get the final url
1518
+ $replace = $gcal_url;
1519
+ if( $result == '#_EVENTGCALLINK' ){
1520
+ $img_url = 'www.google.com/calendar/images/ext/gc_button2.gif';
1521
+ $img_url = is_ssl() ? 'https://'.$img_url:'http://'.$img_url;
1522
+ $replace = '<a href="'.esc_url($replace).'" target="_blank"><img src="'.esc_url($img_url).'" alt="0" border="0"></a>';
1523
+ }
1524
+ break;
1525
+ default:
1526
+ $replace = $full_result;
1527
+ break;
1528
+ }
1529
+ $replaces[$full_result] = apply_filters('em_event_output_placeholder', $replace, $this, $full_result, $target);
1530
+ }
1531
+ //sort out replacements so that during replacements shorter placeholders don't overwrite longer varieties.
1532
+ krsort($replaces);
1533
+ foreach($replaces as $full_result => $replacement){
1534
+ $event_string = str_replace($full_result, $replacement , $event_string );
1535
+ }
1536
+ //Time placeholders
1537
+ foreach($placeholders[1] as $result) {
1538
+ // matches all PHP START date and time placeholders
1539
+ if (preg_match('/^#[dDjlNSwzWFmMntLoYyaABgGhHisueIOPTZcrU]$/', $result)) {
1540
+ $replace = date_i18n(ltrim($result, "#"), $this->start);
1541
+ $replace = apply_filters('em_event_output_placeholder', $replace, $this, $result, $target);
1542
+ $event_string = str_replace($result, $replace, $event_string );
1543
+ }
1544
+ // matches all PHP END time placeholders for endtime
1545
+ if (preg_match('/^#@[dDjlNSwzWFmMntLoYyaABgGhHisueIOPTZcrU]$/', $result)) {
1546
+ $replace = date_i18n(ltrim($result, "#@"), $this->end);
1547
+ $replace = apply_filters('em_event_output_placeholder', $replace, $this, $result, $target);
1548
+ $event_string = str_replace($result, $replace, $event_string );
1549
+ }
1550
+ }
1551
+ //Now do dependent objects
1552
+ if( !empty($this->location_id) && $this->get_location()->location_status ){
1553
+ $event_string = $this->get_location()->output($event_string, $target);
1554
+ }else{
1555
+ $EM_Location = new EM_Location();
1556
+ $event_string = $EM_Location->output($event_string, $target);
1557
+ }
1558
+
1559
+ //for backwards compat and easy use, take over the individual category placeholders with the frirst cat in th elist.
1560
+ $EM_Categories = $this->get_categories();
1561
+ if( count($EM_Categories->categories) > 0 ){
1562
+ $EM_Category = $EM_Categories->get_first();
1563
+ }
1564
+
1565
+ if( empty($EM_Category) ) $EM_Category = new EM_Category();
1566
+ $event_string = $EM_Category->output($event_string, $target);
1567
+
1568
+ return apply_filters('em_event_output', $event_string, $this, $format, $target);
1569
+ }
1570
+
1571
+ /**********************************************************
1572
+ * RECURRENCE METHODS
1573
+ ***********************************************************/
1574
+
1575
+ /**
1576
+ * Returns true if this is a recurring event.
1577
+ * @return boolean
1578
+ */
1579
+ function is_recurring(){
1580
+ return $this->post_type == 'event-recurring' && get_option('dbem_recurrence_enabled');
1581
+ }
1582
+ /**
1583
+ * Will return true if this individual event is part of a set of events that recur
1584
+ * @return boolean
1585
+ */
1586
+ function is_recurrence(){
1587
+ return ( $this->event_id > 0 && $this->recurrence_id > 0 && get_option('dbem_recurrence_enabled') );
1588
+ }
1589
+ /**
1590
+ * Returns if this is an individual event and is not a recurrence
1591
+ * @return boolean
1592
+ */
1593
+ function is_individual(){
1594
+ return ( !$this->is_recurring() && !$this->is_recurrence() );
1595
+ }
1596
+
1597
+ /**
1598
+ * Gets the event recurrence template, which is an EM_Event_Recurrence object (based off an event-recurring post)
1599
+ * @return EM_Event_Recurrence
1600
+ */
1601
+ function get_event_recurrence(){
1602
+ if(!$this->is_recurring()){
1603
+ return new EM_Event($this->recurrence_id); //remember, recurrence_id is a post!
1604
+ }else{
1605
+ return $this;
1606
+ }
1607
+ }
1608
+
1609
+ function get_detach_url(){
1610
+ return admin_url().'admin.php?event_id='.$this->event_id.'&amp;action=event_detach&amp;_wpnonce='.wp_create_nonce('event_detach_'.get_current_user_id().'_'.$this->event_id);
1611
+ }
1612
+
1613
+ function get_attach_url($recurrence_id){
1614
+ return admin_url().'admin.php?undo_id='.$recurrence_id.'&amp;event_id='.$this->event_id.'&amp;action=event_attach&amp;_wpnonce='.wp_create_nonce('event_attach_'.get_current_user_id().'_'.$this->event_id);
1615
+ }
1616
+
1617
+ /**
1618
+ * Returns if this is an individual event and is not recurring or a recurrence
1619
+ * @return boolean
1620
+ */
1621
+ function detach(){
1622
+ global $wpdb;
1623
+ if( $this->is_recurrence() && !$this->is_recurring() && $this->can_manage('edit_recurring_events','edit_others_recurring_events') ){
1624
+ //remove recurrence id from post meta and index table
1625
+ $url = $this->get_attach_url($this->recurrence_id);
1626
+ $wpdb->update(EM_EVENTS_TABLE, array('recurrence_id'=>0), array('event_id' => $this->event_id));
1627
+ update_post_meta($this->post_id, '_recurrence_id', 0);
1628
+ $this->feedback_message = __('Event detached.','dbem') . ' <a href="'.$url.'">'.__('Undo','dbem').'</a>';
1629
+ $this->recurrence_id = 0;
1630
+ return true;
1631
+ }
1632
+ $this->add_error(__('Event could not be detached.','dbem'));
1633
+ return false;
1634
+ }
1635
+
1636
+ /**
1637
+ * Returns if this is an individual event and is not recurring or a recurrence
1638
+ * @return boolean
1639
+ */
1640
+ function attach($recurrence_id){
1641
+ global $wpdb;
1642
+ if( !$this->is_recurrence() && !$this->is_recurring() && is_numeric($recurrence_id) && $this->can_manage('edit_recurring_events','edit_others_recurring_events') ){
1643
+ //add recurrence id to post meta and index table
1644
+ $wpdb->update(EM_EVENTS_TABLE, array('recurrence_id'=>$recurrence_id), array('event_id' => $this->event_id));
1645
+ update_post_meta($this->post_id, '_recurrence_id', $recurrence_id);
1646
+ $this->feedback_message = __('Event re-attached to recurrence.','dbem');
1647
+ return true;
1648
+ }
1649
+ $this->add_error(__('Event could not be attached.','dbem'));
1650
+ return false;
1651
+ }
1652
+
1653
+ /**
1654
+ * Saves events and replaces old ones. Returns true if sucecssful or false if not.
1655
+ * @return boolean
1656
+ */
1657
+ function save_events() {
1658
+ global $wpdb;
1659
+ if( $this->can_manage('edit_events','edit_others_events') && $this->is_published() ){
1660
+ do_action('em_event_save_events_pre', $this); //actions/filters only run if event is recurring
1661
+ //Make template event index, post, and meta (and we just change event dates)
1662
+ $event = $this->to_array(true); //event template - for index
1663
+ $event['event_attributes'] = serialize($event['event_attributes']);
1664
+ $post_fields = $wpdb->get_row('SELECT * FROM '.$wpdb->posts.' WHERE ID='.$this->post_id, ARRAY_A); //post to copy
1665
+ $post_name = $post_fields['post_name']; //save post slug since we'll be using this
1666
+ $post_fields['post_type'] = 'event'; //make sure we'll save events, not recurrence templates
1667
+ $meta_fields_map = $wpdb->get_results('SELECT meta_key,meta_value FROM '.$wpdb->postmeta.' WHERE post_id='.$this->post_id, ARRAY_A);
1668
+ $meta_fields = array();
1669
+ //convert meta_fields into a cleaner array
1670
+ foreach($meta_fields_map as $meta_data){
1671
+ $meta_fields[$meta_data['meta_key']] = $meta_data['meta_value'];
1672
+ }
1673
+ //remove id and we have a event template to feed to wpdb insert
1674
+ unset($event['event_id']);
1675
+ unset($post_fields['ID']);
1676
+ //remove recurrence meta info we won't need in events
1677
+ foreach( array_keys($this->recurrence_fields) as $recurrence_field){
1678
+ unset($event[$recurrence_field]);
1679
+ unset($meta_fields['_'.$recurrence_field]);
1680
+ }
1681
+ $event['event_date_created'] = current_time('mysql'); //since the recurrences are recreated
1682
+ unset($event['event_date_modified']);
1683
+ //Set the recurrence ID
1684
+ $event['recurrence_id'] = $meta_fields['_recurrence_id'] = $this->event_id;
1685
+ $event['recurrence'] = $meta_fields['_recurrence'] = 0;
1686
+ //Let's start saving!
1687
+ $this->delete_events(); //Delete old events beforehand, this will change soon
1688
+ $event_saves = array();
1689
+ $event_ids = array();
1690
+ $post_ids = array();
1691
+ $matching_days = $this->get_recurrence_days(); //Get days where events recur
1692
+ if( count($matching_days) > 0 ){
1693
+ //first save event post data
1694
+ foreach( $matching_days as $day ) {
1695
+ //rewrite post fields if needed
1696
+ $post_fields['post_name'] = $event['event_slug'] = $meta_fields['_event_slug'] = $post_name.'-'.date("Y-m-d", $day);
1697
+ //adjust certain meta information
1698
+ $event['event_start_date'] = $meta_fields['_event_start_date'] = date("Y-m-d", $day);
1699
+ $meta_fields['_start_ts'] = $day;
1700
+ if($this->recurrence_days > 0){
1701
+ $meta_fields['_end_ts'] = $day + ($this->recurrence_days * 60*60*24);
1702
+ $event['event_end_date'] = $meta_fields['_event_end_date'] = date("Y-m-d", $meta_fields['_end_ts']);
1703
+ }else{
1704
+ $meta_fields['_end_ts'] = $day;
1705
+ $event['event_end_date'] = $meta_fields['_event_end_date'] = $event['event_start_date'];
1706
+ }
1707
+ //create the event
1708
+ if( $wpdb->insert($wpdb->posts, $post_fields ) ){
1709
+ $event['post_id'] = $meta_fields['_post_id'] = $post_id = $post_ids[] = $wpdb->insert_id; //post id saved into event and also as a var for later user
1710
+ // Set GUID and event slug as per wp_insert_post
1711
+ $wpdb->update( $wpdb->posts, array( 'guid' => get_permalink( $post_id ) ), array('ID'=>$post_id) );
1712
+ //insert into events index table
1713
+ $event_saves[] = $wpdb->insert(EM_EVENTS_TABLE, $event);
1714
+ $event_ids[] = $event_id = $wpdb->insert_id;
1715
+ //create the meta inserts for each event
1716
+ $meta_fields['_event_id'] = $event_id;
1717
+ foreach($meta_fields as $meta_key => $meta_val){
1718
+ $meta_inserts[] = $wpdb->prepare("(%d, '%s', '%s')", array($post_id, $meta_key, $meta_val));
1719
+ }
1720
+ }else{
1721
+ $event_saves[] = false;
1722
+ }
1723
+ //if( EM_DEBUG ){ echo "Entering recurrence " . date("D d M Y", $day)."<br/>"; }
1724
+ }
1725
+ //insert the metas in one go, faster than one by one
1726
+ if( count($meta_inserts) > 0 ){
1727
+ $result = $wpdb->query("INSERT INTO ".$wpdb->postmeta." (post_id,meta_key,meta_value) VALUES ".implode(',',$meta_inserts));
1728
+ if($result === false){
1729
+ $this->add_error('There was a problem adding custom fields to your recurring events.','dbem');
1730
+ }
1731
+ }
1732
+ //copy the event tags and categories
1733
+ $categories = $this->get_categories()->categories;
1734
+ foreach( $categories as $category){
1735
+ if( !empty($category->slug) ) $cat_slugs[] = $category->slug; //save of category will soft-fail if slug is empty
1736
+ }
1737
+ $cat_slugs_count = count($categories);
1738
+ $tags = get_the_terms( $this->post_id, EM_TAXONOMY_TAG);
1739
+ $tax_slugs = array();
1740
+ if( is_array($tags) ){
1741
+ foreach($tags as $tag){
1742
+ if( !empty($tag->slug) ) $tax_slugs[] = $tag->slug; //save of category will soft-fail if slug is empty
1743
+ }
1744
+ }
1745
+ $tax_slugs_count = count($categories);
1746
+ foreach($post_ids as $post_id){
1747
+ if( $cat_slugs_count > 0 && !EM_MS_GLOBAL ){
1748
+ wp_set_object_terms($post_id, $cat_slugs, EM_TAXONOMY_CATEGORY);
1749
+ }
1750
+ if( $tax_slugs_count > 0 ){
1751
+ wp_set_object_terms($post_id, $tax_slugs, EM_TAXONOMY_TAG);
1752
+ }
1753
+ }
1754
+ //featured images
1755
+ if( !empty($this->attributes['thumbnail_id']) ){
1756
+ $image_inserts = array();
1757
+ foreach($post_ids as $post_ids){
1758
+ $image_inserts[] = "({$this->post_id}, '_thumbnail_id', {$this->attributes['thumbnail_id']})";
1759
+ }
1760
+ if( count($image_inserts) > 0 ){
1761
+ $wpdb->query('INSERT INTO '.$wpdb->postmeta.' (post_id, meta_key, meta_value) VALUES '.implode(', ', $image_inserts));
1762
+ }
1763
+ }
1764
+ //MS Global Categories
1765
+ if( $cat_slugs_count > 0 && EM_MS_GLOBAL ){
1766
+ foreach($categories as $EM_Category){
1767
+ foreach($event_ids as $event_id){
1768
+ $wpdb->insert(EM_META_TABLE, array('meta_value'=>$EM_Category->term_id,'object_id'=>$event_id,'meta_key'=>'event-category'));
1769
+ }
1770
+ }
1771
+ }
1772
+ //now, save booking info for each event
1773
+ if( $this->event_rsvp ){
1774
+ $meta_inserts = array();
1775
+ foreach($this->get_tickets() as $EM_Ticket){
1776
+ /* @var $EM_Ticket EM_Ticket */
1777
+ //get array, modify event id and insert
1778
+ $ticket = $EM_Ticket->to_array();
1779
+ unset($ticket['ticket_id']);
1780
+ //clean up ticket values
1781
+ foreach($ticket as $k => $v){
1782
+ if( empty($v) && $k != 'ticket_name' ){
1783
+ $ticket[$k] = 'NULL';
1784
+ }else{
1785
+ $data_type = !empty($EM_Ticket->fields[$k]['type']) ? $EM_Ticket->fields[$k]['type']:'%s';
1786
+ $ticket[$k] = $wpdb->prepare($data_type,$v);
1787
+ }
1788
+ }
1789
+ foreach($event_ids as $event_id){
1790
+ $ticket['event_id'] = $event_id;
1791
+ $meta_inserts[] = "(".implode(",",$ticket).")";
1792
+ }
1793
+ }
1794
+ $keys = "(".implode(",",array_keys($ticket)).")";
1795
+ $values = implode(',',$meta_inserts);
1796
+ $sql = "INSERT INTO ".EM_TICKETS_TABLE." $keys VALUES $values";
1797
+ $result = $wpdb->query($sql);
1798
+ }
1799
+ }else{
1800
+ $this->add_error('You have not defined a date range long enough to create a recurrence.','dbem');
1801
+ $result = false;
1802
+ }
1803
+ return apply_filters('em_event_save_events', !in_array(false, $event_saves) && $result !== false, $this, $event_ids);
1804
+ }
1805
+ return apply_filters('em_event_save_events', false, $this, $event_ids);
1806
+ }
1807
+
1808
+ /**
1809
+ * Removes all reoccurring events.
1810
+ * @param $recurrence_id
1811
+ * @return null
1812
+ */
1813
+ function delete_events(){
1814
+ global $wpdb;
1815
+ do_action('em_event_delete_events_pre', $this);
1816
+ //So we don't do something we'll regret later, we could just supply the get directly into the delete, but this is safer
1817
+ $result = false;
1818
+ if( $this->can_manage('delete_events', 'delete_others_events') ){
1819
+ //delete events from em_events table
1820
+ $events_array = EM_Events::get( array('recurrence_id'=>$this->event_id, 'scope'=>'all', 'status'=>false ) );
1821
+ foreach($events_array as $EM_Event){
1822
+ /* @var $EM_Event EM_Event */
1823
+ if($EM_Event->recurrence_id == $this->event_id){
1824
+ $EM_Event->delete(true);
1825
+ }
1826
+ }
1827
+ }
1828
+ return apply_filters('delete_events', $result, $this, $events_array);
1829
+ }
1830
+
1831
+ /**
1832
+ * Returns the days that match the recurrance array passed (unix timestamps)
1833
+ * @param array $recurrence
1834
+ * @return array
1835
+ */
1836
+ function get_recurrence_days(){
1837
+ $start_date = strtotime($this->event_start_date);
1838
+ $end_date = strtotime($this->event_end_date);
1839
+
1840
+ $weekdays = explode(",", $this->recurrence_byday); //what days of the week (or if monthly, one value at index 0)
1841
+
1842
+ $matching_days = array();
1843
+ $aDay = 86400; // a day in seconds
1844
+ $aWeek = $aDay * 7;
1845
+
1846
+ //TODO can this be optimized?
1847
+ switch ( $this->recurrence_freq ){
1848
+ case 'daily':
1849
+ //If daily, it's simple. Get start date, add interval timestamps to that and create matching day for each interval until end date.
1850
+ $current_date = $start_date;
1851
+ while( $current_date <= $end_date ){
1852
+ $matching_days[] = $current_date;
1853
+ $current_date = $current_date + ($aDay * $this->recurrence_interval);
1854
+ }
1855
+ break;
1856
+ case 'weekly':
1857
+ //sort out week one, get starting days and then days that match time span of event (i.e. remove past events in week 1)
1858
+ $start_of_week = get_option('start_of_week'); //Start of week depends on WordPress
1859
+ //first, get the start of this week as timestamp
1860
+ $event_start_day = date('w', $start_date);
1861
+ $offset = 0;
1862
+ if( $event_start_day > $start_of_week ){
1863
+ $offset = $event_start_day - $start_of_week; //x days backwards
1864
+ }elseif( $event_start_day < $start_of_week ){
1865
+ $offset = $start_of_week;
1866
+ }
1867
+ $start_week_date = $start_date - ( ($event_start_day - $start_of_week) * $aDay );
1868
+ //then get the timestamps of weekdays during this first week, regardless if within event range
1869
+ $start_weekday_dates = array(); //Days in week 1 where there would events, regardless of event date range
1870
+ for($i = 0; $i < 7; $i++){
1871
+ $weekday_date = $start_week_date+($aDay*$i); //the date of the weekday we're currently checking
1872
+ $weekday_day = date('w',$weekday_date); //the day of the week we're checking, taking into account wp start of week setting
1873
+ if( in_array( $weekday_day, $weekdays) ){
1874
+ $start_weekday_dates[] = $weekday_date; //it's in our starting week day, so add it
1875
+ }
1876
+ }
1877
+ //for each day of eventful days in week 1, add 7 days * weekly intervals
1878
+ foreach ($start_weekday_dates as $weekday_date){
1879
+ //Loop weeks by interval until we reach or surpass end date
1880
+ while($weekday_date <= $end_date){
1881
+ if( $weekday_date >= $start_date && $weekday_date <= $end_date ){
1882
+ $matching_days[] = $weekday_date;
1883
+ }
1884
+ $weekday_date = $weekday_date + ($aWeek * $this->recurrence_interval);
1885
+ }
1886
+ }//done!
1887
+ break;
1888
+ case 'monthly':
1889
+ //loop months starting this month by intervals
1890
+ $current_arr = getdate($start_date);
1891
+ $end_arr = getdate($end_date);
1892
+ $end_month_date = strtotime( date('Y-m-t', $end_date) ); //End date on last day of month
1893
+ $current_date = strtotime( date('Y-m-1', $start_date) ); //Start date on first day of month
1894
+ while( $current_date <= $end_month_date ){
1895
+ $last_day_of_month = date('t', $current_date);
1896
+ //Now find which day we're talking about
1897
+ $current_week_day = date('w',$current_date);
1898
+ $matching_month_days = array();
1899
+ //Loop through days of this years month and save matching days to temp array
1900
+ for($day = 1; $day <= $last_day_of_month; $day++){
1901
+ if((int) $current_week_day == $this->recurrence_byday){
1902
+ $matching_month_days[] = $day;
1903
+ }
1904
+ $current_week_day = ($current_week_day < 6) ? $current_week_day+1 : 0;
1905
+ }
1906
+ //Now grab from the array the x day of the month
1907
+ $matching_day = ($this->recurrence_byweekno > 0) ? $matching_month_days[$this->recurrence_byweekno-1] : array_pop($matching_month_days);
1908
+ $matching_date = strtotime(date('Y-m',$current_date).'-'.$matching_day);
1909
+ if($matching_date >= $start_date && $matching_date <= $end_date){
1910
+ $matching_days[] = $matching_date;
1911
+ }
1912
+ //add the number of days in this month to make start of next month
1913
+ $current_arr['mon'] += $this->recurrence_interval;
1914
+ if($current_arr['mon'] > 12){
1915
+ //FIXME this won't work if interval is more than 12
1916
+ $current_arr['mon'] = $current_arr['mon'] - 12;
1917
+ $current_arr['year']++;
1918
+ }
1919
+ $current_date = strtotime("{$current_arr['year']}-{$current_arr['mon']}-1");
1920
+ }
1921
+ break;
1922
+ case 'yearly':
1923
+ //If yearly, it's simple. Get start date, add interval timestamps to that and create matching day for each interval until end date.
1924
+ $month = date('m', $this->start);
1925
+ $day = date('d',$this->start);
1926
+ $year = date('Y',$this->start);
1927
+ $end_year = date('Y',$this->end);
1928
+ if( @mktime(0,0,0,$day,$month,$end_year) < $this->end ) $end_year--;
1929
+ while( $year <= $end_year ){
1930
+ $matching_days[] = mktime(0,0,0,$day,$month,$year);
1931
+ $year++;
1932
+ }
1933
+ break;
1934
+ }
1935
+ sort($matching_days);
1936
+ return apply_filters('em_events_get_recurrence_days', $matching_days, $this);
1937
+ }
1938
+
1939
+ /**
1940
+ * If event is recurring, set recurrences to same status as template
1941
+ * @param $status
1942
+ */
1943
+ function set_status_events($status){
1944
+ //give sub events same status
1945
+ $events_array = EM_Events::get( array('recurrence_id'=>$this->post_id, 'scope'=>'all', 'status'=>false ) );
1946
+ foreach($events_array as $EM_Event){
1947
+ /* @var $EM_Event EM_Event */
1948
+ if($EM_Event->recurrence_id == $this->event_id){
1949
+ $EM_Event->set_status($status);
1950
+ }
1951
+ }
1952
+ }
1953
+
1954
+ /**
1955
+ * Returns a string representation of this recurrence. Will return false if not a recurrence
1956
+ * @return string
1957
+ */
1958
+ function get_recurrence_description() {
1959
+ $EM_Event_Recurring = $this->get_event_recurrence();
1960
+ $recurrence = $this->to_array();
1961
+ $weekdays_name = array(__('Sunday', 'dbem'),__('Monday', 'dbem'),__('Tuesday', 'dbem'),__('Wednesday', 'dbem'),__('Thursday', 'dbem'),__('Friday', 'dbem'),__('Saturday', 'dbem'));
1962
+ $monthweek_name = array('1' => __('the first %s of the month', 'dbem'),'2' => __('the second %s of the month', 'dbem'), '3' => __('the third %s of the month', 'dbem'), '4' => __('the fourth %s of the month', 'dbem'), '-1' => __('the last %s of the month', 'dbem'));
1963
+ $output = sprintf (__('From %1$s to %2$s', 'dbem'), $EM_Event_Recurring->event_start_date, $EM_Event_Recurring->event_end_date).", ";
1964
+ if ($EM_Event_Recurring->recurrence_freq == 'daily') {
1965
+ $freq_desc =__('everyday', 'dbem');
1966
+ if ($EM_Event_Recurring->recurrence_interval > 1 ) {
1967
+ $freq_desc = sprintf (__("every %s days", 'dbem'), $EM_Event_Recurring->recurrence_interval);
1968
+ }
1969
+ }elseif ($EM_Event_Recurring->recurrence_freq == 'weekly') {
1970
+ $weekday_array = explode(",", $EM_Event_Recurring->recurrence_byday);
1971
+ $natural_days = array();
1972
+ foreach($weekday_array as $day){
1973
+ array_push($natural_days, $weekdays_name[$day]);
1974
+ }
1975
+ $output .= implode(" and ", $natural_days);
1976
+ $freq_desc = ", " . __("every week", 'dbem');
1977
+ if ($EM_Event_Recurring->recurrence_interval > 1 ) {
1978
+ $freq_desc = ", ".sprintf (__("every %s weeks", 'dbem'), $EM_Event_Recurring->recurrence_interval);
1979
+ }
1980
+
1981
+ }elseif ($EM_Event_Recurring->recurrence_freq == 'monthly') {
1982
+ $weekday_array = explode(",", $EM_Event_Recurring->recurrence_byday);
1983
+ $natural_days = array();
1984
+ foreach($weekday_array as $day){
1985
+ array_push($natural_days, $weekdays_name[$day]);
1986
+ }
1987
+ $freq_desc = sprintf (($monthweek_name[$EM_Event_Recurring->recurrence_byweekno]), implode(" and ", $natural_days));
1988
+ if ($EM_Event_Recurring->recurrence_interval > 1 ) {
1989
+ $freq_desc .= ", ".sprintf (__("every %s months",'dbem'), $EM_Event_Recurring->recurrence_interval);
1990
+ }
1991
+ }elseif ($EM_Event_Recurring->recurrence_freq == 'yearly') {
1992
+ $freq_desc .= __("every year", 'dbem');
1993
+ if ($EM_Event_Recurring->recurrence_interval > 1 ) {
1994
+ $freq_desc .= sprintf (__("every %s years",'dbem'), $EM_Event_Recurring->recurrence_interval);
1995
+ }
1996
+ }else{
1997
+ $freq_desc = "[ERROR: corrupted database record]";
1998
+ }
1999
+ $output .= $freq_desc;
2000
+ return $output;
2001
+ }
2002
+
2003
+ /**********************************************************
2004
+ * UTILITIES
2005
+ ***********************************************************/
2006
+
2007
+ /**
2008
+ * Can the user manage this?
2009
+ */
2010
+ function can_manage( $owner_capability = false, $admin_capability = false, $user_to_check = false ){
2011
+ if( $this->event_id == '' && !is_user_logged_in() && get_option('dbem_events_anonymous_submissions') ){
2012
+ $user_to_check = get_option('dbem_events_anonymous_user');
2013
+ }
2014
+ return apply_filters('em_event_can_manage', parent::can_manage($owner_capability, $admin_capability, $user_to_check), $this, $owner_capability, $admin_capability, $user_to_check);
2015
+ }
2016
+ }
2017
+
2018
+ //TODO placeholder targets filtering could be streamlined better
2019
+ /**
2020
+ * This is a temporary filter function which mimicks the old filters in the old 2.x placeholders function
2021
+ * @param string $result
2022
+ * @param EM_Event $event
2023
+ * @param string $placeholder
2024
+ * @param string $target
2025
+ * @return mixed
2026
+ */
2027
+ function em_event_output_placeholder($result,$event,$placeholder,$target='html'){
2028
+ if( ($placeholder == "#_EXCERPT" || $placeholder == "#_LOCATIONEXCERPT") && $target == 'html' ){
2029
+ $result = apply_filters('dbem_notes_excerpt', $result);
2030
+ }elseif( $placeholder == '#_CONTACTEMAIL' && $target == 'html' ){
2031
+ $result = em_ascii_encode($event->get_contact()->user_email);
2032
+ }elseif( in_array($placeholder, array('#_EVENTNOTES','#_NOTES','#_DESCRIPTION','#_LOCATIONNOTES','#_CATEGORYNOTES')) ){
2033
+ if($target == 'rss'){
2034
+ $result = apply_filters('dbem_notes_rss', $result);
2035
+ $result = apply_filters('the_content_rss', $result);
2036
+ }elseif($target == 'map'){
2037
+ $result = apply_filters('dbem_notes_map', $result);
2038
+ }elseif($target == 'ical'){
2039
+ $result = apply_filters('dbem_notes_ical', $result);
2040
+ }elseif ($target == "email"){
2041
+ $result = apply_filters('dbem_notes_email', $result);
2042
+ }else{ //html
2043
+ $result = apply_filters('dbem_notes', $result);
2044
+ }
2045
+ }elseif( in_array($placeholder, array("#_NAME",'#_LOCATION','#_TOWN','#_ADDRESS','#_LOCATIONNAME',"#_EVENTNAME","#_LOCATIONNAME")) ){
2046
+ if ($target == "rss"){
2047
+ $result = apply_filters('dbem_general_rss', $result);
2048
+ }elseif ($target == "ical"){
2049
+ $result = apply_filters('dbem_general_ical', $result);
2050
+ }elseif ($target == "email"){
2051
+ $result = apply_filters('dbem_general_email', $result);
2052
+ }else{ //html
2053
+ $result = apply_filters('dbem_general', $result);
2054
+ }
2055
+ }
2056
+ return $result;
2057
+ }
2058
+ add_filter('em_category_output_placeholder','em_event_output_placeholder',1,4);
2059
+ add_filter('em_event_output_placeholder','em_event_output_placeholder',1,4);
2060
+ add_filter('em_location_output_placeholder','em_event_output_placeholder',1,4);
2061
+ // FILTERS
2062
+ // filters for general events field (corresponding to those of "the _title")
2063
+ add_filter('dbem_general', 'wptexturize');
2064
+ add_filter('dbem_general', 'convert_chars');
2065
+ add_filter('dbem_general', 'trim');
2066
+ // filters for the notes field in html (corresponding to those of "the _content")
2067
+ add_filter('dbem_notes', 'wptexturize');
2068
+ add_filter('dbem_notes', 'convert_smilies');
2069
+ add_filter('dbem_notes', 'convert_chars');
2070
+ add_filter('dbem_notes', 'wpautop');
2071
+ add_filter('dbem_notes', 'prepend_attachment');
2072
+ // RSS content filter
2073
+ add_filter('dbem_notes_rss', 'convert_chars', 8);
2074
+ add_filter('dbem_general_rss', 'esc_html', 8);
2075
+ // Notes map filters
2076
+ add_filter('dbem_notes_map', 'convert_chars', 8);
2077
+ add_filter('dbem_notes_map', 'js_escape');
2078
+
2079
+ /**
2080
+ * This function replaces the default gallery shortcode, so it can check if this is a recurring event recurrence and pass on the parent post id as the default post.
2081
+ * @param array $attr
2082
+ */
2083
+ function em_event_gallery_override( $attr = array() ){
2084
+ global $post;
2085
+ if( $post->post_type == EM_POST_TYPE_EVENT && empty($attr['id']) ){
2086
+ //no id specified, so check if it's recurring and override id with recurrence template post id
2087
+ $EM_Event = em_get_event($post->ID, 'post_id');
2088
+ if( $EM_Event->is_recurrence() ){
2089
+ $attr['id'] = $EM_Event->get_event_recurrence()->post_id;
2090
+ }
2091
+ }
2092
+ return gallery_shortcode($attr);
2093
+ }
2094
+ remove_shortcode('gallery');
2095
+ add_shortcode('gallery', 'em_event_gallery_override');
2096
  ?>
classes/em-events.php CHANGED
@@ -1,254 +1,387 @@
1
- <?php
2
- /**
3
- * Use this class to query and manipulate sets of events. If dealing with more than one event, you probably want to use this class in some way.
4
- *
5
- */
6
- class EM_Events extends EM_Object {
7
-
8
- /**
9
- * Returns an array of EM_Events that match the given specs in the argument, or returns a list of future evetnts in future
10
- * (see EM_Events::get_default_search() ) for explanation of possible search array values. You can also supply a numeric array
11
- * containing the ids of the events you'd like to obtain
12
- *
13
- * @param array $args
14
- * @return EM_Event array()
15
- */
16
- function get( $args = array() ) {
17
- global $wpdb;
18
- $events_table = $wpdb->prefix . EM_EVENTS_TABLE;
19
- $locations_table = $wpdb->prefix . EM_LOCATIONS_TABLE;
20
- $categories_table = $wpdb->prefix . EM_CATEGORIES_TABLE;
21
-
22
- //Quick version, we can accept an array of IDs, which is easy to retrieve
23
- if( self::array_is_numeric($args) ){ //Array of numbers, assume they are event IDs to retreive
24
- //We can just get all the events here and return them
25
- $sql = "
26
- SELECT * FROM $events_table
27
- LEFT JOIN $locations_table ON {$locations_table}.location_id={$events_table}.location_id
28
- LEFT JOIN $categories_table ON {$categories_table}.category_id={$events_table}.event_category_id
29
- WHERE event_id=".implode(" OR event_id=", $args)."
30
- ";
31
- $results = $wpdb->get_results(apply_filters('em_events_get_sql',$sql),ARRAY_A);
32
- $events = array();
33
- foreach($results as $result){
34
- $events[$result['event_id']] = new EM_Event($result);
35
- }
36
- return $events; //We return all the events matched as an EM_Event array.
37
- }
38
-
39
- //We assume it's either an empty array or array of search arguments to merge with defaults
40
- $args = self::get_default_search($args);
41
- $limit = ( $args['limit'] && is_numeric($args['limit'])) ? "LIMIT {$args['limit']}" : '';
42
- $offset = ( $limit != "" && is_numeric($args['offset']) ) ? "OFFSET {$args['offset']}" : '';
43
-
44
- //Get the default conditions
45
- $conditions = self::build_sql_conditions($args);
46
- //Put it all together
47
- $where = ( count($conditions) > 0 ) ? " WHERE " . implode ( " AND ", $conditions ):'';
48
-
49
- //Get ordering instructions
50
- $EM_Event = new EM_Event();
51
- $accepted_fields = $EM_Event->get_fields(true);
52
- $orderby = self::build_sql_orderby($args, $accepted_fields, get_option('dbem_events_default_order'));
53
- //Now, build orderby sql
54
- $orderby_sql = ( count($orderby) > 0 ) ? 'ORDER BY '. implode(', ', $orderby) : '';
55
-
56
- //Create the SQL statement and execute
57
- $sql = "
58
- SELECT * FROM $events_table
59
- LEFT JOIN $locations_table ON {$locations_table}.location_id={$events_table}.location_id
60
- LEFT JOIN $categories_table ON {$categories_table}.category_id={$events_table}.event_category_id
61
- $where
62
- $orderby_sql
63
- $limit $offset
64
- ";
65
-
66
- $results = $wpdb->get_results( apply_filters('em_events_get_sql',$sql, $args), ARRAY_A);
67
-
68
- //If we want results directly in an array, why not have a shortcut here?
69
- if( $args['array'] == true ){
70
- return $results;
71
- }
72
-
73
- //Make returned results EM_Event objects
74
- $results = (is_array($results)) ? $results:array();
75
- $events = array();
76
- foreach ( $results as $event ){
77
- $events[] = new EM_Event($event);
78
- }
79
-
80
- return apply_filters('em_events_get', $events);
81
- }
82
-
83
- /**
84
- * Returns the number of events on a given date
85
- * @param $date
86
- * @return int
87
- */
88
- function count_date($date){
89
- global $wpdb;
90
- $table_name = $wpdb->prefix . EM_EVENTS_TABLE;
91
- $sql = "SELECT COUNT(*) FROM $table_name WHERE (event_start_date like '$date') OR (event_start_date <= '$date' AND event_end_date >= '$date');";
92
- return apply_filters('em_events_count_date', $wpdb->get_var($sql));
93
- }
94
-
95
- /**
96
- * Will delete given an array of event_ids or EM_Event objects
97
- * @param unknown_type $id_array
98
- */
99
- function delete( $array ){
100
- global $wpdb;
101
- //Detect array type and generate SQL for event IDs
102
- $event_ids = array();
103
- if( @get_class(current($array)) == 'EM_Event' ){
104
- foreach($array as $EM_Event){
105
- $event_ids[] = $EM_Event->id;
106
- }
107
- }else{
108
- $event_ids = $array;
109
- }
110
- if(self::array_is_numeric($event_ids)){
111
- //First we have to check that they're all deletable by this user.
112
- if ( self::can_manage($event_ids) ) {
113
- apply_filters('em_events_delete_pre', $event_ids);
114
- $condition = implode(" OR event_id=", $event_ids);
115
- //Delete all the bookings
116
- $result_bookings = $wpdb->query("DELETE FROM ". $wpdb->prefix . EM_BOOKINGS_TABLE ." WHERE event_id=$condition;");
117
- //Now delete the events
118
- $result = $wpdb->query ( "DELETE FROM ". $wpdb->prefix . EM_EVENTS_TABLE ." WHERE event_id=$condition;" );
119
- return apply_filters('em_events_delete', true, $event_ids);
120
- }else{
121
- return apply_filters('em_events_delete', true, $event_ids);
122
- }
123
- }
124
- //TODO add better error feedback on events delete fails
125
- return apply_filters('em_events_delete', true, $event_ids);
126
- }
127
-
128
-
129
- /**
130
- * Output a set of matched of events. You can pass on an array of EM_Events as well, in this event you can pass args in second param.
131
- * Note that you can pass a 'pagination' boolean attribute to enable pagination, default is enabled (true).
132
- * @param array $args
133
- * @param array $secondary_args
134
- * @return string
135
- */
136
- function output( $args ){
137
- global $EM_Event;
138
- $EM_Event_old = $EM_Event; //When looping, we can replace EM_Event global with the current event in the loop
139
- //Can be either an array for the get search or an array of EM_Event objects
140
- if( is_object(current($args)) && get_class((current($args))) == 'EM_Event' ){
141
- $func_args = func_get_args();
142
- $events = $func_args[0];
143
- $args = apply_filters('em_events_output_args', self::get_default_search($func_args[1]), $events);
144
- $limit = ( !empty($args['limit']) && is_numeric($args['limit']) ) ? $args['limit']:false;
145
- $offset = ( !empty($args['offset']) && is_numeric($args['offset']) ) ? $args['offset']:0;
146
- $page = ( !empty($args['page']) && is_numeric($args['page']) ) ? $args['page']:1;
147
- }else{
148
- //Firstly, let's check for a limit/offset here, because if there is we need to remove it and manually do this
149
- $args = apply_filters('em_events_output_args', self::get_default_search($args) );
150
- $limit = ( !empty($args['limit']) && is_numeric($args['limit']) ) ? $args['limit']:false;
151
- $offset = ( !empty($args['offset']) && is_numeric($args['offset']) ) ? $args['offset']:0;
152
- $page = ( !empty($args['page']) && is_numeric($args['page']) ) ? $args['page']:1;
153
- $args['limit'] = false;
154
- $args['offset'] = false;
155
- $args['page'] = false;
156
- $events = self::get( $args );
157
- }
158
- //What format shall we output this to, or use default
159
- $format = ( empty($args['format']) ) ? get_option( 'dbem_event_list_item_format' ) : $args['format'] ;
160
-
161
- $output = "";
162
- $events_count = count($events);
163
- $events = apply_filters('em_events_output_events', $events);
164
-
165
- if ( $events_count > 0 ) {
166
- $event_count = 0;
167
- $events_shown = 0;
168
- foreach ( $events as $EM_Event ) {
169
- if( ($events_shown < $limit || empty($limit)) && ($event_count >= $offset || $offset === 0) ){
170
- $output .= $EM_Event->output($format);
171
- $events_shown++;
172
- }
173
- $event_count++;
174
- }
175
- //Add headers and footers to output
176
- if( $format == get_option ( 'dbem_event_list_item_format' ) ){
177
- $single_event_format_header = get_option ( 'dbem_event_list_item_format_header' );
178
- $single_event_format_header = ( $single_event_format_header != '' ) ? $single_event_format_header : "<ul class='dbem_events_list'>";
179
- $single_event_format_footer = get_option ( 'dbem_event_list_item_format_footer' );
180
- $single_event_format_footer = ( $single_event_format_footer != '' ) ? $single_event_format_footer : "</ul>";
181
- $output = $single_event_format_header . $output . $single_event_format_footer;
182
- }
183
- //Pagination (if needed/requested)
184
- if( !empty($args['pagination']) && !empty($limit) && $events_count > $limit ){
185
- //Show the pagination links (unless there's less than $limit events)
186
- $page_link_template = preg_replace('/(&|\?)page=\d+/i','',$_SERVER['REQUEST_URI']);
187
- $page_link_template = em_add_get_params($page_link_template, array('page'=>'%PAGE%'));
188
- $output .= apply_filters('em_events_output_pagination', em_paginate( $page_link_template, $events_count, $limit, $page), $page_link_template, $events_count, $limit, $page);
189
- }
190
- } else {
191
- $output = get_option ( 'dbem_no_events_message' );
192
- }
193
- //TODO check if reference is ok when restoring object, due to changes in php5 v 4
194
- $EM_Event = $EM_Event_old;
195
- $output = apply_filters('em_events_output', $output, $events, $args);
196
- return $output;
197
- }
198
-
199
- function can_manage($event_ids){
200
- global $wpdb;
201
- if( em_verify_admin() ){
202
- return apply_filters('em_events_can_manage', true, $event_ids);
203
- }
204
- if( EM_Object::array_is_numeric($event_ids) ){
205
- $condition = implode(" OR event_id=", $event_ids);
206
- //Delete all the bookings
207
- $results = $wpdb->query("SELECT event_author FROM ". $wpdb->prefix . EM_BOOKINGS_TABLE ." WHERE author_id != '". get_current_user_id() ."' event_id=$condition;");
208
- return apply_filters('em_events_can_manage', (count($results) > 0), $event_ids);
209
- }
210
- return apply_filters('em_events_can_manage', false, $event_ids);
211
- }
212
-
213
- /* Overrides EM_Object method to apply a filter to result
214
- * @see wp-content/plugins/events-manager/classes/EM_Object#build_sql_conditions()
215
- */
216
- function build_sql_conditions( $args = array() ){
217
- return apply_filters( 'em_events_build_sql_conditions', parent::build_sql_conditions($args), $args );
218
- }
219
-
220
- /* Overrides EM_Object method to apply a filter to result
221
- * @see wp-content/plugins/events-manager/classes/EM_Object#build_sql_orderby()
222
- */
223
- function build_sql_orderby( $args, $accepted_fields, $default_order = 'ASC' ){
224
- return apply_filters( 'em_events_build_sql_orderby', parent::build_sql_orderby($args, $accepted_fields, get_option('dbem_events_default_order')), $args, $accepted_fields, $default_order );
225
- }
226
-
227
- /*
228
- * Adds custom Events search defaults
229
- * @param array $array
230
- * @return array
231
- * @uses EM_Object#get_default_search()
232
- */
233
- function get_default_search( $array = array() ){
234
- $defaults = array(
235
- 'orderby' => get_option('dbem_events_default_orderby'),
236
- 'order' => get_option('dbem_events_default_order'),
237
- 'rsvp' => false //if set to true, only events with bookings enabled are returned
238
- );
239
- if( is_admin() ){
240
- //figure out default owning permissions
241
- switch( get_option('dbem_permissions_events') ){
242
- case 0:
243
- $defaults['owner'] = get_current_user_id();
244
- break;
245
- case 1:
246
- $defaults['owner'] = false;
247
- break;
248
- }
249
- $defaults['owner'] = ( em_verify_admin() ) ? false:$defaults['owner'];
250
- }
251
- return apply_filters('em_events_get_default_search', parent::get_default_search($defaults,$array), $array, $defaults);
252
- }
253
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
254
  ?>
1
+ <?php
2
+ //TODO EM_Events is currently static, better we make this non-static so we can loop sets of events, and standardize with other objects.
3
+ /**
4
+ * Use this class to query and manipulate sets of events. If dealing with more than one event, you probably want to use this class in some way.
5
+ *
6
+ */
7
+ class EM_Events extends EM_Object implements Iterator {
8
+ /**
9
+ * Array of EM_Event objects
10
+ * @var array EM_Event
11
+ */
12
+ var $events = array();
13
+
14
+ function EM_Events( $args = array() ){
15
+ if( is_array($args) ){
16
+ if( is_object(current($args)) && get_class(current($args)) == 'EM_Event' ){
17
+ $this->events = $args;
18
+ }else{
19
+ $this->events = EM_Events::get($args);
20
+ }
21
+ }else{
22
+ $this->events = EM_Events::get();
23
+ }
24
+ do_action('em_events',$this);
25
+ }
26
+
27
+ /**
28
+ * Returns an array of EM_Events that match the given specs in the argument, or returns a list of future evetnts in future
29
+ * (see EM_Events::get_default_search() ) for explanation of possible search array values. You can also supply a numeric array
30
+ * containing the ids of the events you'd like to obtain
31
+ *
32
+ * @param array $args
33
+ * @return EM_Event array()
34
+ */
35
+ function get( $args = array(), $count=false ) {
36
+ global $wpdb;
37
+ $events_table = EM_EVENTS_TABLE;
38
+ $locations_table = EM_LOCATIONS_TABLE;
39
+
40
+ //Quick version, we can accept an array of IDs, which is easy to retrieve
41
+ if( self::array_is_numeric($args) ){ //Array of numbers, assume they are event IDs to retreive
42
+ //We can just get all the events here and return them
43
+ $sql = "
44
+ SELECT * FROM $events_table
45
+ LEFT JOIN $locations_table ON {$locations_table}.location_id={$events_table}.location_id
46
+ WHERE event_id=".implode(" OR event_id=", $args)."
47
+ ";
48
+ $results = $wpdb->get_results(apply_filters('em_events_get_sql',$sql),ARRAY_A);
49
+ $events = array();
50
+ foreach($results as $result){
51
+ $events[$result['event_id']] = new EM_Event($result);
52
+ }
53
+ return $events; //We return all the events matched as an EM_Event array.
54
+ }
55
+
56
+ //We assume it's either an empty array or array of search arguments to merge with defaults
57
+ $args = self::get_default_search($args);
58
+ $limit = ( $args['limit'] && is_numeric($args['limit'])) ? "LIMIT {$args['limit']}" : '';
59
+ $offset = ( $limit != "" && is_numeric($args['offset']) ) ? "OFFSET {$args['offset']}" : '';
60
+
61
+ //Get the default conditions
62
+ $conditions = self::build_sql_conditions($args);
63
+ //Put it all together
64
+ $where = ( count($conditions) > 0 ) ? " WHERE " . implode ( " AND ", $conditions ):'';
65
+
66
+ //Get ordering instructions
67
+ $EM_Event = new EM_Event();
68
+ $accepted_fields = $EM_Event->get_fields(true);
69
+ $orderby = self::build_sql_orderby($args, $accepted_fields, get_option('dbem_events_default_order'));
70
+ //Now, build orderby sql
71
+ $orderby_sql = ( count($orderby) > 0 ) ? 'ORDER BY '. implode(', ', $orderby) : '';
72
+
73
+ //Create the SQL statement and execute
74
+
75
+ if( EM_MS_GLOBAL ){
76
+ $selectors = ( $count ) ? 'COUNT(*)':$events_table.'.post_id, '.$events_table.'.blog_id';
77
+ }else{
78
+ $selectors = ( $count ) ? 'COUNT(*)':$events_table.'.post_id';
79
+ }
80
+
81
+ $sql = "
82
+ SELECT $selectors FROM $events_table
83
+ LEFT JOIN $locations_table ON {$locations_table}.location_id={$events_table}.location_id
84
+ $where
85
+ $orderby_sql
86
+ $limit $offset
87
+ ";
88
+
89
+ //If we're only counting results, return the number of results
90
+ if( $count ){
91
+ return apply_filters('em_events_get_count', $wpdb->get_var($sql), $args);
92
+ }
93
+ $results = $wpdb->get_results( apply_filters('em_events_get_sql',$sql, $args), ARRAY_A);
94
+
95
+ //If we want results directly in an array, why not have a shortcut here?
96
+ if( $args['array'] == true ){
97
+ return apply_filters('em_events_get_array',$results, $args);
98
+ }
99
+
100
+ //Make returned results EM_Event objects
101
+ $results = (is_array($results)) ? $results:array();
102
+ $events = array();
103
+
104
+ if( EM_MS_GLOBAL ){
105
+ foreach ( $results as $event ){
106
+ $events[] = em_get_event($event['post_id'], $event['blog_id']);
107
+ }
108
+ }else{
109
+ foreach ( $results as $event ){
110
+ $events[] = em_get_event($event['post_id'], 'post_id');
111
+ }
112
+ }
113
+
114
+ return apply_filters('em_events_get', $events, $args);
115
+ }
116
+
117
+ /**
118
+ * Returns the number of events on a given date
119
+ * @param $date
120
+ * @return int
121
+ */
122
+ function count_date($date){
123
+ global $wpdb;
124
+ $table_name = EM_EVENTS_TABLE;
125
+ $sql = "SELECT COUNT(*) FROM $table_name WHERE (event_start_date like '$date') OR (event_start_date <= '$date' AND event_end_date >= '$date');";
126
+ return apply_filters('em_events_count_date', $wpdb->get_var($sql));
127
+ }
128
+
129
+ function count( $args = array() ){
130
+ return apply_filters('em_events_count', self::get($args, true), $args);
131
+ }
132
+
133
+ /**
134
+ * Will delete given an array of event_ids or EM_Event objects
135
+ * @param unknown_type $id_array
136
+ */
137
+ function delete( $array ){
138
+ global $wpdb;
139
+ //Detect array type and generate SQL for event IDs
140
+ $results = array();
141
+ if( !empty($array) && @get_class(current($array)) != 'EM_Event' ){
142
+ $events = self::get($array);
143
+ }else{
144
+ $events = $array;
145
+ }
146
+ foreach ($events as $EM_Event){
147
+ $results[] = $EM_Event->delete();
148
+ }
149
+ //TODO add better error feedback on events delete fails
150
+ return apply_filters('em_events_delete', in_array(false, $results), $event_ids);
151
+ }
152
+
153
+
154
+ /**
155
+ * Output a set of matched of events. You can pass on an array of EM_Events as well, in this event you can pass args in second param.
156
+ * Note that you can pass a 'pagination' boolean attribute to enable pagination, default is enabled (true).
157
+ * @param array $args
158
+ * @param array $secondary_args
159
+ * @return string
160
+ */
161
+ function output( $args ){
162
+ global $EM_Event;
163
+ $EM_Event_old = $EM_Event; //When looping, we can replace EM_Event global with the current event in the loop
164
+ //Can be either an array for the get search or an array of EM_Event objects
165
+ $func_args = func_get_args();
166
+ $page = 1; //default
167
+ if( !array_key_exists('page',$args) && !empty($_REQUEST['page']) && is_numeric($_REQUEST['page']) ){
168
+ $page = $args['page'] = $_REQUEST['page'];
169
+ }
170
+ if( is_object(current($args)) && get_class((current($args))) == 'EM_Event' ){
171
+ $func_args = func_get_args();
172
+ $events = $func_args[0];
173
+ $args = (!empty($func_args[1]) && is_array($func_args[1])) ? $func_args[1] : array();
174
+ $args = apply_filters('em_events_output_args', self::get_default_search($args), $events);
175
+ $limit = ( !empty($args['limit']) && is_numeric($args['limit']) ) ? $args['limit']:false;
176
+ $offset = ( !empty($args['offset']) && is_numeric($args['offset']) ) ? $args['offset']:0;
177
+ $page = ( !empty($args['page']) && is_numeric($args['page']) ) ? $args['page']:$page;
178
+ $events_count = count($events);
179
+ }else{
180
+ //Firstly, let's check for a limit/offset here, because if there is we need to remove it and manually do this
181
+ $args = apply_filters('em_events_output_args', self::get_default_search($args) );
182
+ $limit = ( !empty($args['limit']) && is_numeric($args['limit']) ) ? $args['limit']:false;
183
+ $offset = ( !empty($args['offset']) && is_numeric($args['offset']) ) ? $args['offset']:0;
184
+ $page = ( !empty($args['page']) && is_numeric($args['page']) ) ? $args['page']:$page;
185
+ $args_count = $args;
186
+ $args_count['limit'] = false;
187
+ $args_count['offset'] = false;
188
+ $args_count['page'] = false;
189
+ $events_count = self::count($args_count);
190
+ $events = self::get( $args );
191
+ }
192
+ //What format shall we output this to, or use default
193
+ $format = ( empty($args['format']) ) ? get_option( 'dbem_event_list_item_format' ) : $args['format'] ;
194
+
195
+ $output = "";
196
+ $events = apply_filters('em_events_output_events', $events);
197
+ if ( $events_count > 0 ) {
198
+ foreach ( $events as $EM_Event ) {
199
+ $output .= $EM_Event->output($format);
200
+ }
201
+ //Add headers and footers to output
202
+ if( $format == get_option ( 'dbem_event_list_item_format' ) ){
203
+ $format_header = ( get_option( 'dbem_event_list_item_format_header') == '' ) ? '':get_option ( 'dbem_event_list_item_format_header' );
204
+ $format_footer = ( get_option ( 'dbem_event_list_item_format_footer' ) == '' ) ? '':get_option ( 'dbem_event_list_item_format_footer' );
205
+ }else{
206
+ $format_header = ( !empty($args['format_header']) ) ? $args['format_header']:'';
207
+ $format_footer = ( !empty($args['format_footer']) ) ? $args['format_footer']:'';
208
+ }
209
+ $output = $format_header . $output . $format_footer;
210
+ //Pagination (if needed/requested)
211
+ if( !empty($args['pagination']) && !empty($limit) && $events_count > $limit ){
212
+ //Show the pagination links (unless there's less than $limit events)
213
+ $page_link_template = preg_replace('/(&|\?)page=\d+/i','',$_SERVER['REQUEST_URI']);
214
+ $page_link_template = em_add_get_params($page_link_template, array('page'=>'%PAGE%'), false); //don't html encode, so em_paginate does its thing;
215
+ $output .= apply_filters('em_events_output_pagination', em_paginate( $page_link_template, $events_count, $limit, $page), $page_link_template, $events_count, $limit, $page);
216
+ }
217
+ } else {
218
+ $output = get_option ( 'dbem_no_events_message' );
219
+ }
220
+
221
+ //TODO check if reference is ok when restoring object, due to changes in php5 v 4
222
+ $EM_Event = $EM_Event_old;
223
+ $output = apply_filters('em_events_output', $output, $events, $args);
224
+ return $output;
225
+ }
226
+
227
+ function can_manage($event_ids){
228
+ global $wpdb;
229
+ if( current_user_can('edit_others_events') ){
230
+ return apply_filters('em_events_can_manage', true, $event_ids);
231
+ }
232
+ if( EM_Object::array_is_numeric($event_ids) ){
233
+ $condition = implode(" OR event_id=", $event_ids);
234
+ //we try to find any of these events that don't belong to this user
235
+ $results = $wpdb->get_var("SELECT COUNT(*) FROM ". EM_EVENTS_TABLE ." WHERE event_owner != '". get_current_user_id() ."' event_id=$condition;");
236
+ return apply_filters('em_events_can_manage', ($results == 0), $event_ids);
237
+ }
238
+ return apply_filters('em_events_can_manage', false, $event_ids);
239
+ }
240
+
241
+ function get_post_search($args = array(), $filter = false){
242
+ if( !empty($_REQUEST['em_search']) && empty($args['search']) ) $_REQUEST['search'] = $_REQUEST['em_search'];
243
+ $accepted_searches = apply_filters('em_accepted_searches', array('scope','search','category','country','state','region','town'), $args);
244
+ foreach($_REQUEST as $post_key => $post_value){
245
+ if( in_array($post_key, $accepted_searches) && !empty($post_value) ){
246
+ if(is_array($post_value)){
247
+ $post_value = implode(',',$post_value);
248
+ }
249
+ if($post_value != ',' ){
250
+ $args[$post_key] = $post_value;
251
+ }
252
+ }
253
+ }
254
+ if( $filter ){
255
+ foreach($args as $arg_key => $arg_value){
256
+ if( !in_array($arg_key, $accepted_searches) ){
257
+ unset($args[$arg_key]);
258
+ }
259
+ }
260
+ }
261
+ return apply_filters('em_events_get_post_search', $args);
262
+ }
263
+
264
+ /* Overrides EM_Object method to apply a filter to result
265
+ * @see wp-content/plugins/events-manager/classes/EM_Object#build_sql_conditions()
266
+ */
267
+ function build_sql_conditions( $args = array() ){
268
+ $conditions = parent::build_sql_conditions($args);
269
+ if( !empty($args['search']) ){
270
+ $like_search = array('event_name',EM_EVENTS_TABLE.'.post_content','location_name','location_address','location_town','location_postcode','location_state','location_country');
271
+ $conditions['search'] = "(".implode(" LIKE '%{$args['search']}%' OR ", $like_search). " LIKE '%{$args['search']}%')";
272
+ }
273
+ if( array_key_exists('status',$args) && is_numeric($args['status']) ){
274
+ $null = ($args['status'] == 0) ? ' OR `event_status` = 0':'';
275
+ $conditions['status'] = "(`event_status`={$args['status']}{$null} )";
276
+ }elseif( empty($args['status']) || $args['status'] != 'all'){
277
+ $conditions['status'] = "(`event_status` IS NOT NULL )"; //by default, we don't ever show deleted items
278
+ }
279
+ //private events
280
+ if( empty($args['private']) ){
281
+ $conditions['private'] = "(`event_private`=0)";
282
+ }elseif( !empty($args['private_only']) ){
283
+ $conditions['private_only'] = "(`event_private`=1)";
284
+ }
285
+ if( EM_MS_GLOBAL && array_key_exists('blog',$args) && is_numeric($args['blog']) ){
286
+ if( is_main_site($args['blog']) ){
287
+ $conditions['blog'] = "(".EM_EVENTS_TABLE.".blog_id={$args['blog']} OR ".EM_EVENTS_TABLE.".blog_id IS NULL)";
288
+ }else{
289
+ $conditions['blog'] = "(".EM_EVENTS_TABLE.".blog_id={$args['blog']})";
290
+ }
291
+ }
292
+ if( $args['bookings'] === 'user' && is_user_logged_in()){
293
+ //get bookings of user
294
+ $EM_Person = new EM_Person(get_current_user_id());
295
+ $booking_ids = $EM_Person->get_bookings(true);
296
+ if( count($booking_ids) > 0 ){
297
+ $conditions['bookings'] = "(event_id IN (SELECT event_id FROM ".EM_BOOKINGS_TABLE." WHERE booking_id IN (".implode(',',$booking_ids).")))";
298
+ }else{
299
+ $conditions['bookings'] = "(event_id = 0)";
300
+ }
301
+ }
302
+ //post search
303
+ if( !empty($args['post_id'])){
304
+ if( is_array($args['post_id']) ){
305
+ $conditions['post_id'] = "(".EM_EVENTS_TABLE.".post_id IN (".implode(',',$args['post_id'])."))";
306
+ }else{
307
+ $conditions['post_id'] = "(".EM_EVENTS_TABLE.".post_id={$args['post_id']})";
308
+ }
309
+ }
310
+ return apply_filters( 'em_events_build_sql_conditions', $conditions, $args );
311
+ }
312
+
313
+ /* Overrides EM_Object method to apply a filter to result
314
+ * @see wp-content/plugins/events-manager/classes/EM_Object#build_sql_orderby()
315
+ */
316
+ function build_sql_orderby( $args, $accepted_fields, $default_order = 'ASC' ){
317
+ return apply_filters( 'em_events_build_sql_orderby', parent::build_sql_orderby($args, $accepted_fields, get_option('dbem_events_default_order')), $args, $accepted_fields, $default_order );
318
+ }
319
+
320
+ /*
321
+ * Adds custom Events search defaults
322
+ * @param array $array
323
+ * @return array
324
+ * @uses EM_Object#get_default_search()
325
+ */
326
+ function get_default_search( $array = array() ){
327
+ $defaults = array(
328
+ 'orderby' => get_option('dbem_events_default_orderby'),
329
+ 'order' => get_option('dbem_events_default_order'),
330
+ 'bookings' => false, //if set to true, only events with bookings enabled are returned
331
+ 'status' => 1, //approved events only
332
+ 'format_header' => '', //events can have custom html above the list
333
+ 'format_footer' => '', //events can have custom html below the list
334
+ 'town' => false,
335
+ 'state' => false,
336
+ 'country' => false,
337
+ 'region' => false,
338
+ 'blog' => get_current_blog_id(),
339
+ 'private' => current_user_can('read_private_events'),
340
+ 'private_only' => false,
341
+ 'post_id' => false
342
+ );
343
+ if(EM_MS_GLOBAL){
344
+ global $bp;
345
+ if( !is_main_site() && !array_key_exists('blog', $array) ){
346
+ $array['blog'] = get_current_blog_id();
347
+ }elseif( empty($array['blog']) && get_site_option('dbem_ms_global_events') ) {
348
+ $array['blog'] = false;
349
+ }
350
+ }
351
+ if( is_admin() ){
352
+ //figure out default owning permissions
353
+ $defaults['owner'] = !current_user_can('edit_others_events') ? get_current_user_id() : false;
354
+ if( !array_key_exists('status', $array) && current_user_can('edit_others_events') ){
355
+ $defaults['status'] = false; //by default, admins see pending and live events
356
+ }
357
+ }
358
+ return apply_filters('em_events_get_default_search', parent::get_default_search($defaults,$array), $array, $defaults);
359
+ }
360
+
361
+ //TODO Implement object and interators for handling groups of events.
362
+ public function rewind(){
363
+ reset($this->events);
364
+ }
365
+
366
+ public function current(){
367
+ $var = current($this->events);
368
+ return $var;
369
+ }
370
+
371
+ public function key(){
372
+ $var = key($this->events);
373
+ return $var;
374
+ }
375
+
376
+ public function next(){
377
+ $var = next($this->events);
378
+ return $var;
379
+ }
380
+
381
+ public function valid(){
382
+ $key = key($this->events);
383
+ $var = ($key !== NULL && $key !== FALSE);
384
+ return $var;
385
+ }
386
+ }
387
  ?>
classes/em-location-post-admin.php ADDED
@@ -0,0 +1,134 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class EM_Location_Post_Admin{
3
+ function init(){
4
+ global $pagenow;
5
+ if($pagenow == 'post.php' || $pagenow == 'post-new.php' ){ //only needed if editing post
6
+ add_action('admin_head', array('EM_Location_Post_Admin','admin_head'));
7
+ }
8
+ //Meta Boxes
9
+ add_action('add_meta_boxes', array('EM_Location_Post_Admin','meta_boxes'));
10
+ //Save/Edit actions
11
+ add_action('save_post',array('EM_Location_Post_Admin','save_post'));
12
+ add_action('before_delete_post',array('EM_Location_Post_Admin','before_delete_post'),10,1);
13
+ add_action('trashed_post',array('EM_Location_Post_Admin','trashed_post'),10,1);
14
+ add_action('untrash_post',array('EM_Location_Post_Admin','untrash_post'),10,1);
15
+ add_action('untrashed_post',array('EM_Location_Post_Admin','untrashed_post'),10,1);
16
+ //Notices
17
+ add_action('admin_notices',array('EM_Location_Post_Admin','admin_notices'));
18
+ add_action('post_updated_messages',array('EM_Location_Post_Admin','admin_notices_filter'),1,1);
19
+ }
20
+
21
+ function admin_head(){
22
+ global $post, $EM_Location;
23
+ if( !empty($post) && $post->post_type == EM_POST_TYPE_LOCATION ){
24
+ $EM_Location = em_get_location($post);
25
+ }
26
+ }
27
+
28
+ function admin_notices(){
29
+ //When editing
30
+ global $post, $EM_Notices;
31
+ if( !empty($post) && $post->post_type == EM_POST_TYPE_LOCATION){
32
+ }
33
+ }
34
+
35
+ function admin_notices_filter($messages){
36
+ //When editing
37
+ global $post, $EM_Notices;
38
+ if( $post->post_type == EM_POST_TYPE_LOCATION ){
39
+ if ( $EM_Notices->count_errors() > 0 ) {
40
+ unset($_GET['message']);
41
+ }
42
+ }
43
+ return $messages;
44
+ }
45
+
46
+ function save_post($post_id){
47
+ global $wpdb, $EM_Location, $EM_Notices;
48
+ $saving_status = !in_array(get_post_status($post_id), array('trash','auto-draft')) && !defined('DOING_AUTOSAVE');
49
+ $is_post_type = get_post_type($post_id) == EM_POST_TYPE_LOCATION;
50
+ if(!defined('UNTRASHING_'.$post_id) && $is_post_type && $saving_status){
51
+ if( wp_verify_nonce($_REQUEST['_emnonce'], 'edit_location')){
52
+ $EM_Location = em_get_location($post_id, 'post_id');
53
+ do_action('em_location_save_pre', $EM_Location);
54
+ $get_meta = $EM_Location->get_post_meta();
55
+ $save_meta = $EM_Location->save_meta();
56
+ //Handle Errors by making post draft
57
+ if( !$get_meta || !$save_meta ){
58
+ $EM_Location->set_status(null, true);
59
+ $EM_Notices->add_error( '<strong>'.sprintf(__('Your %s details are incorrect and cannot be published, please correct these errors first:','dbem'),__('location','dbem')).'</strong>', true); //Always seems to redirect, so we make it static
60
+ $EM_Notices->add_error($EM_Location->get_errors(), true); //Always seems to redirect, so we make it static
61
+ apply_filters('em_location_save', false , $EM_Location);
62
+ }else{
63
+ apply_filters('em_location_save', true , $EM_Location);
64
+ }
65
+ }else{
66
+ //do a quick and dirty update
67
+ do_action('em_location_save_pre', $this);
68
+ $EM_Location = new EM_Location($post_id, 'post_id');
69
+ //check for existence of index
70
+ $loc_truly_exists = $wpdb->get_var('SELECT location_id FROM '.EM_LOCATIONS_TABLE." WHERE location_id={$EM_Location->location_id}") == $EM_Location->location_id;
71
+ if(empty($EM_Location->location_id) || !$loc_truly_exists){ $EM_Location->save_meta(); }
72
+ //continue
73
+ $location_status = ($EM_Location->is_published()) ? 1:0;
74
+ $wpdb->query("UPDATE ".EM_LOCATIONS_TABLE." SET location_name='{$EM_Location->location_name}', location_slug='{$EM_Location->location_slug}', location_private='{$EM_Location->location_private}',location_status={$location_status} WHERE location_id='{$EM_Location->location_id}'");
75
+ apply_filters('em_location_save', true , $this);
76
+ }
77
+ }
78
+ }
79
+
80
+ function before_delete_post($post_id){
81
+ if(get_post_type($post_id) == EM_POST_TYPE_LOCATION){
82
+ $EM_Location = em_get_location($post_id,'post_id');
83
+ $EM_Location->delete_meta();
84
+ }
85
+ }
86
+
87
+ function trashed_post($post_id){
88
+ if(get_post_type($post_id) == EM_POST_TYPE_LOCATION){
89
+ global $EM_Notices;
90
+ $EM_Location = em_get_location($post_id,'post_id');
91
+ $EM_Location->set_status(null);
92
+ $EM_Notices->remove_all(); //no validation/notices needed
93
+ }
94
+ }
95
+
96
+ function untrash_post($post_id){
97
+ if(get_post_type($post_id) == EM_POST_TYPE_LOCATION){
98
+ //set a constant so we know this event doesn't need 'saving'
99
+ if(!defined('UNTRASHING_'.$post_id)) define('UNTRASHING_'.$post_id, true);
100
+ }
101
+ }
102
+
103
+ function untrashed_post($post_id){
104
+ if(get_post_type($post_id) == EM_POST_TYPE_LOCATION){
105
+ global $EM_Notices;
106
+ $EM_Location = em_get_location($post_id,'post_id');
107
+ $EM_Location->set_status(1);
108
+ $EM_Notices->remove_all(); //no validation/notices needed
109
+ }
110
+ }
111
+
112
+ function meta_boxes(){
113
+ add_meta_box('em-location-where', __('Where','dbem'), array('EM_Location_Post_Admin','meta_box_where'),EM_POST_TYPE_LOCATION, 'normal','high');
114
+ //add_meta_box('em-location-metadump', __('EM_Location Meta Dump','dbem'), array('EM_Location_Post_Admin','meta_box_metadump'),EM_POST_TYPE_LOCATION, 'normal','high');
115
+ if( get_option('dbem_location_attributes_enabled') ){
116
+ add_meta_box('em-location-attributes', __('Attributes','dbem'), array('EM_Location_Post_Admin','meta_box_attributes'),EM_POST_TYPE_LOCATION, 'normal','default');
117
+ }
118
+ }
119
+
120
+ function meta_box_metadump(){
121
+ global $post,$EM_Location;
122
+ echo "<pre>"; print_r(get_post_custom($post->ID)); echo "</pre>";
123
+ echo "<pre>"; print_r($EM_Location); echo "</pre>";
124
+ }
125
+ function meta_box_where(){
126
+ ?><input type="hidden" name="_emnonce" value="<?php echo wp_create_nonce('edit_location'); ?>" /><?php
127
+ em_locate_template('forms/location/where.php',true);
128
+ }
129
+
130
+ function meta_box_attributes(){
131
+ em_locate_template('forms/location/attributes.php',true);
132
+ }
133
+ }
134
+ add_action('admin_init',array('EM_Location_Post_Admin','init'));
classes/em-location-post.php ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class EM_Location_Post {
3
+ function init(){
4
+ //Front Side Modifiers
5
+ if( !is_admin() ){
6
+ //override single page with formats?
7
+ add_filter('the_content', array('EM_Location_Post','the_content'));
8
+ //display as page template?
9
+ if( get_option('dbem_cp_locations_template_page') ){
10
+ add_filter('single_template',array('EM_Location_Post','single_template'));
11
+ }
12
+ }
13
+ add_action('parse_query', array('EM_Location_Post','parse_query'));
14
+ }
15
+
16
+ /**
17
+ * Overrides the default post format of a location and can display a location as a page, which uses the page.php template.
18
+ * @param string $template
19
+ * @return string
20
+ */
21
+ function single_template($template){
22
+ global $post;
23
+ if( !locate_template('single-'.EM_POST_TYPE_LOCATION.'.php') && $post->post_type == EM_POST_TYPE_LOCATION ){
24
+ $template = locate_template(array('page.php','index.php'),false);
25
+ }
26
+ return $template;
27
+ }
28
+
29
+ function the_content( $content ){
30
+ global $post, $EM_Location;
31
+ if( $post->post_type == EM_POST_TYPE_LOCATION ){
32
+ if( is_archive() || is_search() ){
33
+ if( get_option('dbem_cp_locations_archive_formats') ){
34
+ $EM_Location = em_get_location($post);
35
+ $content = $EM_Location->output(get_option('dbem_location_list_item_format'));
36
+ }
37
+ }else{
38
+ if( get_option('dbem_cp_locations_formats') && !post_password_required() ){
39
+ $EM_Location = em_get_location($post);
40
+ ob_start();
41
+ em_locate_template('templates/location-single.php',true);
42
+ $content = ob_get_clean();
43
+ }
44
+ }
45
+ }
46
+ return $content;
47
+ }
48
+
49
+ function parse_query( ){
50
+ global $wp_query;
51
+ if( !empty($wp_query->query_vars['post_type']) && $wp_query->query_vars['post_type'] == EM_POST_TYPE_LOCATION ){
52
+ if( is_admin() ){
53
+ $wp_query->query_vars['orderby'] = (!empty($_REQUEST['orderby'])) ? $_REQUEST['orderby']:'title';
54
+ $wp_query->query_vars['order'] = (!empty($_REQUEST['order'])) ? $_REQUEST['order']:'ASC';
55
+ }else{
56
+ if( empty($wp_query->query_vars['location']) ) {
57
+ if( get_option('dbem_locations_default_archive_orderby') == 'title'){
58
+ $wp_query->query_vars['orderby'] = 'title';
59
+ }else{
60
+ $wp_query->query_vars['orderby'] = 'meta_value_num';
61
+ $wp_query->query_vars['meta_key'] = get_option('dbem_locations_default_archive_orderby','_location_country');
62
+ }
63
+ $wp_query->query_vars['order'] = get_option('dbem_locations_default_archive_orderby','ASC');
64
+ }
65
+ }
66
+ }
67
+ }
68
+ }
69
+ EM_Location_Post::init();
classes/em-location-posts-admin.php ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class EM_Location_Posts_Admin{
3
+ function init(){
4
+ global $pagenow;
5
+ if($pagenow == 'edit.php' && !empty($_REQUEST['post_type']) && $_REQUEST['post_type'] == EM_POST_TYPE_LOCATION ){ //only needed if editing post
6
+ //hide some cols by default:
7
+ $screen = 'edit-'.EM_POST_TYPE_LOCATION;
8
+ $hidden = get_user_option( 'manage' . $screen . 'columnshidden' );
9
+ if( !$hidden ){
10
+ $hidden = array('location-id');
11
+ update_user_option(get_current_user_id(), "manage{$screen}columnshidden", $hidden, true);
12
+ }
13
+ add_action('admin_head', array('EM_Location_Posts_Admin','admin_head'));
14
+ }
15
+ add_filter('manage_edit-'.EM_POST_TYPE_LOCATION.'_columns' , array('EM_Location_Posts_Admin','columns_add'));
16
+ add_filter('manage_'.EM_POST_TYPE_LOCATION.'_posts_custom_column' , array('EM_Location_Posts_Admin','columns_output'),10,2 );
17
+ }
18
+
19
+ function admin_head(){
20
+ //quick hacks to make event admin table make more sense for events
21
+ ?>
22
+ <script type="text/javascript">
23
+ jQuery(document).ready( function($){
24
+ $('.inline-edit-date').prev().css('display','none').next().css('display','none').next().css('display','none');
25
+ });
26
+ </script>
27
+ <style>
28
+ table.fixed{ table-layout:auto !important; }
29
+ .tablenav select[name="m"] { display:none; }
30
+ </style>
31
+ <?php
32
+ }
33
+
34
+ function admin_menu(){
35
+ global $menu, $submenu;
36
+ // Add a submenu to the custom top-level menu:
37
+ $plugin_pages = array();
38
+ $plugin_pages[] = add_submenu_page('edit.php?post_type='.EM_POST_TYPE_EVENT, __('Locations', 'dbem'), __('Locations', 'dbem'), 'edit_locations', 'events-manager-locations', "edit.php?post_type=event");
39
+ $plugin_pages = apply_filters('em_create_locationss_submenu',$plugin_pages);
40
+ }
41
+
42
+ function columns_add($columns) {
43
+ //prepend ID after checkbox
44
+ if( array_key_exists('cb', $columns) ){
45
+ $cb = $columns['cb'];
46
+ unset($columns['cb']);
47
+ $id_array = array('cb'=>$cb, 'location-id' => sprintf(__('%s ID','dbem'),__('Location','dbem')));
48
+ }else{
49
+ $id_array = array('location-id' => sprintf(__('%s ID','dbem'),__('Location','dbem')));
50
+ }
51
+ unset($columns['author']);
52
+ unset($columns['date']);
53
+ unset($columns['comments']);
54
+ return array_merge($id_array, $columns, array(
55
+ 'address' => __('Address','dbem'),
56
+ 'town' => __('Town','dbem'),
57
+ 'state' => __('State','dbem'),
58
+ 'country' => __('Country','dbem')
59
+ ));
60
+ }
61
+
62
+ function columns_output( $column ) {
63
+ global $post;
64
+ $post = em_get_location($post);
65
+ switch ( $column ) {
66
+ case 'location-id':
67
+ echo $post->location_id;
68
+ break;
69
+ case 'address':
70
+ echo $post->location_address;
71
+ break;
72
+ case 'town':
73
+ echo $post->location_town;
74
+ break;
75
+ case 'state':
76
+ echo $post->location_state;
77
+ break;
78
+ case 'country':
79
+ echo $post->location_country;
80
+ break;
81
+ }
82
+ }
83
+ }
84
+ add_action('admin_init', array('EM_Location_Posts_Admin','init'));
classes/em-location.php CHANGED
@@ -1,307 +1,728 @@
1
- <?php
2
- /**
3
- * Object that holds location info and related functions
4
- * @author marcus
5
- */
6
- class EM_Location extends EM_Object {
7
- //DB Fields
8
- var $id = '';
9
- var $name = '';
10
- var $address = '';
11
- var $town = '';
12
- var $latitude = '';
13
- var $longitude = '';
14
- var $description = '';
15
- var $image_url = '';
16
- var $owner = '';
17
- //Other Vars
18
- var $fields = array(
19
- 'location_id' => array('name'=>'id','type'=>'%d'),
20
- 'location_name' => array('name'=>'name','type'=>'%s'),
21
- 'location_address' => array('name'=>'address','type'=>'%s'),
22
- 'location_town' => array('name'=>'town','type'=>'%s'),
23
- //Not Used - 'location_province' => array('name'=>'province','type'=>'%s'),
24
- 'location_latitude' => array('name'=>'latitude','type'=>'%f'),
25
- 'location_longitude' => array('name'=>'longitude','type'=>'%f'),
26
- 'location_description' => array('name'=>'description','type'=>'%s'),
27
- 'location_owner' => array('name'=>'owner','type'=>'%d')
28
- );
29
- var $required_fields;
30
- var $feedback_message = "";
31
- var $mime_types = array(1 => 'gif', 2 => 'jpg', 3 => 'png');
32
- var $errors = array();
33
-
34
- /**
35
- * Gets data from POST (default), supplied array, or from the database if an ID is supplied
36
- * @param $location_data
37
- * @return null
38
- */
39
- function EM_Location( $location_data = 0 ) {
40
- //Initialize
41
- $this->required_fields = array("name" => __('The location name', 'dbem'), "address" => __('The location address', 'dbem'), "town" => __('The location town', 'dbem'));
42
- if( $location_data != 0 ){
43
- //Load location data
44
- if( is_array($location_data) && isset($location_data['location_name']) ){
45
- $location = $location_data;
46
- }elseif( $location_data > 0 ){
47
- //Retreiving from the database
48
- global $wpdb;
49
- $sql = "SELECT * FROM ". $wpdb->prefix.EM_LOCATIONS_TABLE ." WHERE location_id ='{$location_data}'";
50
- $location = $wpdb->get_row($sql, ARRAY_A);
51
- }
52
- //If gmap is turned off, values may not be returned and set, so we set it here
53
- if(empty($location['location_latitude'])) {
54
- $location['location_latitude'] = 0;
55
- $location['location_longitude'] = 0;
56
- }
57
- //Save into the object
58
- $this->to_object($location, true);
59
- $this->get_image_url();
60
- }
61
- }
62
-
63
- function get_post(){
64
- //We are getting the values via POST or GET
65
- do_action('em_location_get_post_pre', $this);
66
- $location = array();
67
- $location['location_id'] = ( !empty($_POST['location_id']) ) ? $_POST['location_id']:'';
68
- $location['location_name'] = ( !empty($_POST['location_name']) ) ? stripslashes($_POST['location_name']):'';
69
- $location['location_address'] = ( !empty($_POST['location_address']) ) ? stripslashes($_POST['location_address']):'';
70
- $location['location_town'] = ( !empty($_POST['location_town']) ) ? stripslashes($_POST['location_town']):'';
71
- $location['location_latitude'] = ( !empty($_POST['location_latitude']) ) ? $_POST['location_latitude']:'';
72
- $location['location_longitude'] = ( !empty($_POST['location_longitude']) ) ? $_POST['location_longitude']:'';
73
- $location['location_description'] = ( !empty($_POST['content']) ) ? stripslashes($_POST['content']):'';
74
- $this->to_object( apply_filters('em_location_get_post', $location, $this) );
75
- }
76
-
77
- function save(){
78
- global $wpdb, $current_user;
79
- get_currentuserinfo();
80
- do_action('em_location_save_pre', $this);
81
- $table = $wpdb->prefix.EM_LOCATIONS_TABLE;
82
- $data = $this->to_array();
83
- unset($data['location_id']);
84
- unset($data['location_image_url']);
85
- if($this->id != ''){
86
- $where = array( 'location_id' => $this->id );
87
- $wpdb->update($table, $data, $where, $this->get_types($data));
88
- }else{
89
- $this->owner = $current_user->ID; //Record creator of event
90
- $data['location_owner'] = $this->owner;
91
- $wpdb->insert($table, $data, $this->get_types($data));
92
- $this->id = $wpdb->insert_id;
93
- }
94
- $image_upload = $this->image_upload();
95
- return apply_filters('em_location_save', ( $this->id > 0 && $image_upload ), $this, $image_upload);
96
- }
97
-
98
- function delete(){
99
- global $wpdb;
100
- do_action('em_location_delete_pre', $this);
101
- $table_name = $wpdb->prefix.EM_LOCATIONS_TABLE;
102
- $sql = "DELETE FROM $table_name WHERE location_id = '{$this->id}';";
103
- $result = $wpdb->query($sql);
104
- $result = $this->image_delete() && $result;
105
- return apply_filters('em_location_delete', $result, $this);
106
- }
107
-
108
- function get_image_url(){
109
- if($this->image_url == ''){
110
- foreach($this->mime_types as $type) {
111
- $file_path = "/".EM_IMAGE_UPLOAD_DIR."/location-{$this->id}.$type";
112
- if( file_exists( ABSPATH . $file_path) ) {
113
- $result = get_bloginfo('wpurl').$file_path;
114
- $this->image_url = $result;
115
- }
116
- }
117
- }
118
- return apply_filters('em_location_get_image_url', $this->image_url, $this);
119
- }
120
-
121
- function image_delete() {
122
- $file_name= ABSPATH.EM_IMAGE_UPLOAD_DIR."/location-".$this->id;
123
- $result = false;
124
- foreach($this->mime_types as $type) {
125
- if (file_exists($file_name.".".$type))
126
- $result = unlink($file_name.".".$type);
127
- }
128
- return apply_filters('em_location_image_delete', $result, $this);
129
- }
130
-
131
- function image_upload(){
132
- //TODO better image upload error handling
133
- do_action('em_location_image_upload_pre', $this);
134
- $result = true;
135
- if ( !empty($_FILES['location_image']['size']) ) {
136
- if( !file_exists(ABSPATH.EM_IMAGE_UPLOAD_DIR) ){
137
- mkdir(ABSPATH.EM_IMAGE_UPLOAD_DIR, 0777);
138
- }
139
- $this->image_delete();
140
- list($width, $height, $type, $attr) = getimagesize($_FILES['location_image']['tmp_name']);
141
- $image_path = ABSPATH.EM_IMAGE_UPLOAD_DIR."/location-".$this->id.".".$this->mime_types[$type];
142
- if (!move_uploaded_file($_FILES['location_image']['tmp_name'], $image_path)){
143
- $this->errors = __('The image could not be loaded','dbem');
144
- $result = false;
145
- }else{
146
- $result = true;
147
- }
148
- }
149
- return apply_filters('em_location_image_upload', $result, $this);
150
- }
151
-
152
- function load_similar($criteria){
153
- global $wpdb;
154
- if( !empty($criteria['location_name']) && !empty($criteria['location_name']) && !empty($criteria['location_name']) ){
155
- $locations_table = $wpdb->prefix.EM_LOCATIONS_TABLE;
156
- $prepared_sql = $wpdb->prepare("SELECT * FROM $locations_table WHERE location_name = %s AND location_address = %s AND location_town = %s", stripcslashes($criteria['location_name']), stripcslashes($criteria['location_address']), stripcslashes($criteria['location_town']) );
157
- //$wpdb->show_errors(true);
158
- $location = $wpdb->get_row($prepared_sql, ARRAY_A);
159
- if( is_array($location) ){
160
- $this->to_object($location);
161
- }
162
- return apply_filters('em_location_load_similar', $location, $this);
163
- }
164
- return apply_filters('em_location_load_similar', false, $this);
165
- }
166
-
167
- /**
168
- * Validates the location. Should be run during any form submission or saving operation.
169
- * @return boolean
170
- */
171
- function validate(){
172
- foreach ( $this->required_fields as $field => $description) {
173
- if ( $this->$field == "" ) {
174
- $this->errors[] = $description.__(" is missing!", "dbem");
175
- }
176
- }
177
- if ( !empty($_FILES['location_image']) && $_FILES['location_image']['size'] > 0 ) {
178
- if (is_uploaded_file($_FILES['location_image']['tmp_name'])) {
179
- $mime_types = array(1 => 'gif', 2 => 'jpg', 3 => 'png');
180
- $maximum_size = get_option('dbem_image_max_size');
181
- if ($_FILES['location_image']['size'] > $maximum_size){
182
- $this->errors[] = __('The image file is too big! Maximum size:', 'dbem')." $maximum_size";
183
- }
184
- list($width, $height, $type, $attr) = getimagesize($_FILES['location_image']['tmp_name']);
185
- $maximum_width = get_option('dbem_image_max_width');
186
- $maximum_height = get_option('dbem_image_max_height');
187
- if (($width > $maximum_width) || ($height > $maximum_height)) {
188
- $this->errors[] = __('The image is too big! Maximum size allowed:')." $maximum_width x $maximum_height";
189
- }
190
- if (($type!=1) && ($type!=2) && ($type!=3)){
191
- $this->errors[] = __('The image is in a wrong format!');
192
- }
193
- }
194
- }
195
- return apply_filters('em_location_validate', ( count($this->errors) == 0 ), $this);
196
- }
197
-
198
- function has_events(){
199
- global $wpdb;
200
- $events_table = $wpdb->prefix.EM_EVENTS_TABLE;
201
- $sql = "SELECT count(event_id) as events_no FROM $events_table WHERE location_id = {$this->id}";
202
- $affected_events = $wpdb->get_row($sql);
203
- return apply_filters('em_location_has_events', (count($affected_events) > 0), $this);
204
- }
205
-
206
- function can_manage(){
207
- return ( get_option('dbem_permissions_locations') == 2 || $this->owner == get_current_user_id() || empty($this->id) || em_verify_admin() );
208
- }
209
-
210
- function can_use(){
211
- switch( get_option('dbem_permissions_locations') ){
212
- case 0:
213
- return $this->owner == get_current_user_id();
214
- case 1:
215
- return em_verify_admin($this->owner);
216
- case 2:
217
- return true;
218
- }
219
- }
220
-
221
- function output_single($target = 'html'){
222
- $format = get_option ( 'dbem_single_location_format' );
223
- return apply_filters('em_location_output_single', $this->output($format, $target), $this, $target);
224
- }
225
-
226
- function output($format, $target="html") {
227
- $location_string = $format;
228
- preg_match_all("/#_[A-Za-z]+/", $format, $placeholders);
229
- foreach($placeholders[0] as $result) {
230
- $match = true;
231
- $replace = '';
232
- switch( $result ){
233
- case '#_MAP': //Depreciated
234
- case '#_LOCATIONMAP':
235
- $replace = EM_Map::get_single( array('location' => $this) );
236
- break;
237
- case '#_DESCRIPTION': //Depreciated
238
- case '#_EXCERPT': //Depreciated
239
- case '#_LOCATIONNOTES':
240
- case '#_LOCATIONEXCERPT':
241
- $replace = $this->description;
242
- if($result == "#_EXCERPT" || $result == "#_LOCATIONEXCERPT"){
243
- $matches = explode('<!--more', $this->description);
244
- $replace = $matches[0];
245
- }
246
- break;
247
- case '#_LOCATIONURL':
248
- case '#_LOCATIONLINK':
249
- case '#_LOCATIONPAGEURL': //Depreciated
250
- $joiner = (stristr(EM_URI, "?")) ? "&amp;" : "?";
251
- $link = EM_URI.$joiner."location_id=".$this->id;
252
- $replace = ($result == '#_LOCATIONURL' || $result == '#_LOCATIONPAGEURL') ? $link : '<a href="'.$link.'">'.$this->name.'</a>';
253
- break;
254
- case '#_PASTEVENTS': //Depreciated
255
- case '#_LOCATIONPASTEVENTS':
256
- case '#_NEXTEVENTS': //Depreciated
257
- case '#_LOCATIONNEXTEVENTS':
258
- case '#_ALLEVENTS': //Depreciated
259
- case '#_LOCATIONALLEVENTS':
260
- if ($result == '#_PASTEVENTS' || $result == '#_LOCATIONPASTEVENTS'){ $scope = 'past'; }
261
- elseif ( $result == '#_NEXTEVENTS' || $result == '#_LOCATIONNEXTEVENTS' ){ $scope = 'future'; }
262
- else{ $scope = 'all'; }
263
- $events = EM_Events::get( array('location'=>$this->id, 'scope'=>$scope) );
264
- if ( count($events) > 0 ){
265
- foreach($events as $event){
266
- $replace .= $event->output(get_option('dbem_location_event_list_item_format'));
267
- }
268
- } else {
269
- $replace = get_option('dbem_location_no_events_message');
270
- }
271
- break;
272
- case '#_IMAGE': //Depreciated
273
- case '#_LOCATIONIMAGE':
274
- if($this->image_url != ''){
275
- $replace = "<img src='".$this->image_url."' alt='".$this->name."'/>";
276
- }
277
- break;
278
- case '#_NAME': //Depreciated
279
- case '#_LOCATIONNAME':
280
- $replace = $this->name;
281
- break;
282
- case '#_ADDRESS': //Depreciated
283
- case '#_LOCATIONADDRESS':
284
- $replace = $this->address;
285
- break;
286
- case '#_TOWN': //Depreciated
287
- case '#_LOCATIONTOWN':
288
- $replace = $this->town;
289
- break;
290
- case '#_LOCATIONID':
291
- $replace = $this->id;
292
- break;
293
- default:
294
- $match = false;
295
- break;
296
- }
297
- if($match){ //if true, we've got a placeholder that needs replacing
298
- //TODO FILTER - placeholder filter
299
- $replace = apply_filters('em_location_output_placeholder', $replace, $this, $result, $target); //USE WITH CAUTION! THIS MIGHT GET RENAMED
300
- $location_string = str_replace($result, $replace , $location_string );
301
- }
302
- }
303
- $name_filter = ($target == "html") ? 'dbem_general':'dbem_general_rss'; //TODO remove dbem_ filters
304
- $location_string = str_replace('#_LOCATION', apply_filters($name_filter, $this->name) , $location_string ); //Depreciated
305
- return apply_filters('em_location_output', $location_string, $this, $format, $target);
306
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
307
  }
1
+ <?php
2
+ /**
3
+ * gets a location
4
+ * @param mixed $id
5
+ * @param mixed $search_by
6
+ * @return EM_Location
7
+ */
8
+ function em_get_location($id = false, $search_by = 'location_id') {
9
+ if( is_object($id) && get_class($id) == 'EM_Location' ){
10
+ return $id;
11
+ }else{
12
+ return new EM_Location($id,$search_by);
13
+ }
14
+ }
15
+ /**
16
+ * Object that holds location info and related functions
17
+ * @author marcus
18
+ */
19
+ class EM_Location extends EM_Object {
20
+ //DB Fields
21
+ var $location_id = '';
22
+ var $post_id = '';
23
+ var $blog_id = '';
24
+ var $location_slug = '';
25
+ var $location_name = '';
26
+ var $location_address = '';
27
+ var $location_town = '';
28
+ var $location_state = '';
29
+ var $location_postcode = '';
30
+ var $location_region = '';
31
+ var $location_country = '';
32
+ var $location_latitude = 0;
33
+ var $location_longitude = 0;
34
+ var $post_content = '';
35
+ var $location_owner = '';
36
+ var $location_status = 0;
37
+ //Other Vars
38
+ var $fields = array(
39
+ 'location_id' => array('name'=>'id','type'=>'%d'),
40
+ 'post_id' => array('name'=>'post_id','type'=>'%d'),
41
+ 'blog_id' => array('name'=>'blog_id','type'=>'%d'),
42
+ 'location_slug' => array('name'=>'slug','type'=>'%s', 'null'=>true),
43
+ 'location_name' => array('name'=>'name','type'=>'%s', 'null'=>true),
44
+ 'location_address' => array('name'=>'address','type'=>'%s','null'=>true),
45
+ 'location_town' => array('name'=>'town','type'=>'%s','null'=>true),
46
+ 'location_state' => array('name'=>'state','type'=>'%s','null'=>true),
47
+ 'location_postcode' => array('name'=>'postcode','type'=>'%s','null'=>true),
48
+ 'location_region' => array('name'=>'region','type'=>'%s','null'=>true),
49
+ 'location_country' => array('name'=>'country','type'=>'%s','null'=>true),
50
+ 'location_latitude' => array('name'=>'latitude','type'=>'%f','null'=>true),
51
+ 'location_longitude' => array('name'=>'longitude','type'=>'%f','null'=>true),
52
+ 'post_content' => array('name'=>'description','type'=>'%s', 'null'=>true),
53
+ 'location_owner' => array('name'=>'owner','type'=>'%d', 'null'=>true),
54
+ 'location_status' => array('name'=>'status','type'=>'%d', 'null'=>true)
55
+ );
56
+ var $post_fields = array('post_id','location_slug','location_name','post_content','location_owner');
57
+ var $location_attributes = array();
58
+ var $image_url = '';
59
+ var $required_fields = array();
60
+ var $feedback_message = "";
61
+ var $mime_types = array(1 => 'gif', 2 => 'jpg', 3 => 'png');
62
+ var $errors = array();
63
+ /**
64
+ * previous status of location
65
+ * @access protected
66
+ * @var mixed
67
+ */
68
+ var $previous_status = 0;
69
+
70
+ /* Post Variables - copied out of post object for easy IDE reference */
71
+ var $ID;
72
+ var $post_author;
73
+ var $post_date;
74
+ var $post_date_gmt;
75
+ var $post_title;
76
+ var $post_excerpt;
77
+ var $post_status;
78
+ var $comment_status;
79
+ var $ping_status;
80
+ var $post_password;
81
+ var $post_name;
82
+ var $to_ping;
83
+ var $pinged;
84
+ var $post_modified;
85
+ var $post_modified_gmt;
86
+ var $post_content_filtered;
87
+ var $post_parent;
88
+ var $guid;
89
+ var $menu_order;
90
+ var $post_type;
91
+ var $post_mime_type;
92
+ var $comment_count;
93
+ var $ancestors;
94
+ var $filter;
95
+
96
+
97
+ /**
98
+ * Gets data from POST (default), supplied array, or from the database if an ID is supplied
99
+ * @param $location_data
100
+ * @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
101
+ * @return null
102
+ */
103
+ function __construct($id = false, $search_by = 'location_id' ) {
104
+ global $wpdb;
105
+ //Initialize
106
+ $this->required_fields = array("location_address" => __('The location address', 'dbem'), "location_town" => __('The location town', 'dbem'), "location_country" => __('The country', 'dbem'));
107
+ //Get the post_id/location_id
108
+ $is_post = !empty($id->ID) && $id->post_type == EM_POST_TYPE_LOCATION;
109
+ if( $is_post || absint($id) > 0 ){ //only load info if $id is a number
110
+ $location_post = false;
111
+ if($search_by == 'location_id' && !$is_post){
112
+ //search by location_id, get post_id and blog_id (if in ms mode) and load the post
113
+ $results = $wpdb->get_row($wpdb->prepare("SELECT post_id, blog_id FROM ".EM_LOCATIONS_TABLE." WHERE location_id=%d",$id), ARRAY_A);
114
+ if( !empty($results['post_id']) ){
115
+ if( is_multisite() && is_numeric($results['blog_id']) ){
116
+ $location_post = get_blog_post($results['blog_id'], $results['post_id']);
117
+ $search_by = $results['blog_id'];
118
+ }else{
119
+ $location_post = get_post($results['post_id']);
120
+ }
121
+ }
122
+ }else{
123
+ if(!$is_post){
124
+ if( is_numeric($search_by) && is_multisite() ){
125
+ //we've been given a blog_id, so we're searching for a post id
126
+ $location_post = get_blog_post($search_by, $id);
127
+ }else{
128
+ //search for the post id only
129
+ $location_post = get_post($id);
130
+ }
131
+ }else{
132
+ $location_post = $id;
133
+ }
134
+ }
135
+ $this->load_postdata($location_post, $search_by);
136
+ }
137
+ $this->compat_keys();
138
+ do_action('em_location', $this, $id, $search_by);
139
+ }
140
+
141
+ function load_postdata($location_post, $search_by = false){
142
+ if( is_object($location_post) ){
143
+ if( $location_post->post_status != 'auto-draft' ){
144
+ if( is_numeric($search_by) && is_multisite() ){
145
+ // if in multisite mode, switch blogs quickly to get the right post meta.
146
+ switch_to_blog($search_by);
147
+ $location_meta = get_post_custom($location_post->ID);
148
+ restore_current_blog();
149
+ $this->blog_id = $search_by;
150
+ }else{
151
+ $location_meta = get_post_custom($location_post->ID);
152
+ }
153
+ //Get custom fields
154
+ foreach($location_meta as $location_meta_key => $location_meta_val){
155
+ $found = false;
156
+ foreach($this->fields as $field_name => $field_info){
157
+ if( $location_meta_key == '_'.$field_name){
158
+ $this->$field_name = $location_meta_val[0];
159
+ $found = true;
160
+ }
161
+ }
162
+ if(!$found && $location_meta_key[0] != '_'){
163
+ $this->location_attributes[$location_meta_key] = ( count($location_meta_val) > 1 ) ? $location_meta_val:$location_meta_val[0];
164
+ }
165
+ }
166
+ }
167
+ //load post data - regardless
168
+ $this->post_id = $location_post->ID;
169
+ $this->location_name = $location_post->post_title;
170
+ $this->location_slug = $location_post->post_name;
171
+ $this->location_owner = $location_post->post_author;
172
+ $this->post_content = $location_post->post_content;
173
+ foreach( $location_post as $key => $value ){ //merge the post data into location object
174
+ $this->$key = $value;
175
+ }
176
+ $this->previous_status = $this->location_status; //so we know about updates
177
+ $this->get_status();
178
+ }
179
+ }
180
+
181
+ /**
182
+ * Retrieve event information via POST (used in situations where posts aren't submitted via WP)
183
+ * @param boolean $validate whether or not to run validation, default is true
184
+ * @return boolean
185
+ */
186
+ function get_post($validate = true){
187
+ global $allowedtags;
188
+ do_action('em_location_get_post_pre', $this);
189
+ $this->location_name = ( !empty($_POST['location_name']) ) ? wp_kses_data( stripslashes($_POST['location_name'])):'';
190
+ $this->post_content = ( !empty($_POST['content']) ) ? wp_kses( stripslashes($_POST['content']), $allowedtags):'';
191
+ $this->get_post_meta(false);
192
+ $result = $validate ? $this->validate():true; //validate both post and meta, otherwise return true
193
+ $this->compat_keys();
194
+ return apply_filters('em_location_get_post', $result, $this);
195
+ }
196
+ /**
197
+ * Retrieve event post meta information via POST, which should be always be called when saving the event custom post via WP.
198
+ * @param boolean $validate whether or not to run validation, default is true
199
+ * @return mixed
200
+ */
201
+ function get_post_meta($validate = true){
202
+ //We are getting the values via POST or GET
203
+ do_action('em_location_get_post_meta_pre', $this);
204
+ $this->location_address = ( !empty($_POST['location_address']) ) ? wp_kses(stripslashes($_POST['location_address']), array()):'';
205
+ $this->location_town = ( !empty($_POST['location_town']) ) ? wp_kses(stripslashes($_POST['location_town']), array()):'';
206
+ $this->location_state = ( !empty($_POST['location_state']) ) ? wp_kses(stripslashes($_POST['location_state']), array()):'';
207
+ $this->location_postcode = ( !empty($_POST['location_postcode']) ) ? wp_kses(stripslashes($_POST['location_postcode']), array()):'';
208
+ $this->location_region = ( !empty($_POST['location_region']) ) ? wp_kses(stripslashes($_POST['location_region']), array()):'';
209
+ $this->location_country = ( !empty($_POST['location_country']) ) ? wp_kses(stripslashes($_POST['location_country']), array()):'';
210
+ $this->location_latitude = ( !empty($_POST['location_latitude']) && is_numeric($_POST['location_latitude']) ) ? $_POST['location_latitude']:'';
211
+ $this->location_longitude = ( !empty($_POST['location_longitude']) && is_numeric($_POST['location_longitude']) ) ? $_POST['location_longitude']:'';
212
+ //Set Blog ID
213
+ if( is_multisite() && empty($this->blog_id) ){
214
+ $this->blog_id = get_current_blog_id();
215
+ }
216
+ //Sort out event attributes - note that custom post meta now also gets inserted here automatically (and is overwritten by these attributes)
217
+ if(get_option('dbem_location_attributes_enabled')){
218
+ global $allowedtags;
219
+ if( !is_array($this->location_attributes) ){ $this->location_attributes = array(); }
220
+ $location_available_attributes = em_get_attributes(true); //lattributes only
221
+ if( !empty($_POST['em_attributes']) && is_array($_POST['em_attributes']) ){
222
+ foreach($_POST['em_attributes'] as $att_key => $att_value ){
223
+ if( (in_array($att_key, $location_available_attributes['names']) || array_key_exists($att_key, $this->location_attributes) ) ){
224
+ $att_vals = count($location_available_attributes['values'][$att_key]);
225
+ if( $att_vals == 0 || ($att_vals > 0 && in_array($att_value, $location_available_attributes['values'][$att_key])) ){
226
+ $this->location_attributes[$att_key] = stripslashes($att_value);
227
+ }elseif($att_vals > 0){
228
+ $this->location_attributes[$att_key] = stripslashes(wp_kses($location_available_attributes['values'][$att_key][0], $allowedtags));
229
+ }
230
+ }
231
+ }
232
+ }
233
+ }
234
+ $result = $validate ? $this->validate_meta():true; //post returns null
235
+ $this->compat_keys();
236
+ return apply_filters('em_location_get_post_meta',$result,$this);
237
+ }
238
+
239
+ function validate(){
240
+ $validate_post = true;
241
+ if( empty($this->location_name) ){
242
+ $validate_post = false;
243
+ $this->add_error( __('Location name').__(" is required.", "dbem") );
244
+ }
245
+ $validate_image = $this->image_validate();
246
+ $validate_meta = $this->validate_meta();
247
+ return apply_filters('em_location_validate', $validate_post && $validate_image && $validate_meta, $this );
248
+ }
249
+
250
+ /**
251
+ * Validates the location. Should be run during any form submission or saving operation.
252
+ * @return boolean
253
+ */
254
+ function validate_meta(){
255
+ //check required fields
256
+ foreach ( $this->required_fields as $field => $description) {
257
+ if( $field == 'location_country' && !array_key_exists($this->location_country, em_get_countries()) ){
258
+ //country specific checking
259
+ $this->add_error( $this->required_fields['location_country'].__(" is required.", "dbem") );
260
+ }elseif ( $this->$field == "" ) {
261
+ $this->add_error( $description.__(" is required.", "dbem") );
262
+ }
263
+ }
264
+ return apply_filters('em_location_validate_meta', ( count($this->errors) == 0 ), $this);
265
+ }
266
+
267
+ function save(){
268
+ global $wpdb, $current_user, $blog_id;
269
+ //TODO shuffle filters into right place
270
+ if( !$this->can_manage('edit_locations', 'edit_others_locations') && !( get_option('dbem_events_anonymous_submissions') && empty($this->location_id)) ){
271
+ return apply_filters('em_location_save', false, $this);
272
+ }
273
+ remove_action('save_post',array('EM_Location_Post_Admin','save_post'),10,1); //disable the default save post action, we'll do it manually this way
274
+ do_action('em_location_save_pre', $this);
275
+ $post_array = array();
276
+ //Deal with updates to a location
277
+ if( !empty($this->post_id) ){
278
+ //get the full array of post data so we don't overwrite anything.
279
+ if( !empty($this->blog_id) && is_multisite() ){
280
+ $post_array = (array) get_blog_post($this->blog_id, $this->post_id);
281
+ }else{
282
+ $post_array = (array) get_post($this->post_id);
283
+ }
284
+ }
285
+ //Overwrite new post info
286
+ $post_array['post_type'] = EM_POST_TYPE_LOCATION;
287
+ $post_array['post_title'] = $this->location_name;
288
+ $post_array['post_content'] = $this->post_content;
289
+ //decide on post status
290
+ if( count($this->errors) == 0 ){
291
+ if( EM_MS_GLOBAL && !is_main_site() && get_site_option('dbem_ms_mainblog_locations') ){
292
+ //if in global ms mode and user is a valid role to publish on their blog, then we will publish the location on the main blog
293
+ restore_current_blog();
294
+ $switch_back = true;
295
+ }
296
+ $post_array['post_status'] = ( current_user_can('publish_locations') ) ? 'publish':'pending';
297
+ if(!empty($switch_back) && get_site_option('dbem_ms_mainblog_locations') ) EM_Object::ms_global_switch(); //switch 'back' to main blog
298
+ }else{
299
+ $post_array['post_status'] = 'draft';
300
+ }
301
+ //Anonymous submission
302
+ if( !is_user_logged_in() && get_option('dbem_events_anonymous_submissions') && empty($this->location_id) ){
303
+ $post_array['post_author'] = get_option('dbem_events_anonymous_user');
304
+ if( !is_numeric($post_array['post_author']) ) $post_array['post_author'] = 0;
305
+ }
306
+ //Save post and continue with meta
307
+ $post_id = wp_insert_post($post_array);
308
+ $post_save = false;
309
+ $meta_save = false;
310
+ if( !is_wp_error($post_id) && !empty($post_id) ){
311
+ $post_save = true;
312
+ //refresh this event with wp post
313
+ $post_data = get_post($post_id);
314
+ $this->post_id = $post_id;
315
+ $this->location_slug = $post_data->post_name;
316
+ $this->location_owner = $post_data->post_author;
317
+ $this->post_status = $post_data->post_status;
318
+ $this->get_status();
319
+ //now save the meta
320
+ $meta_save = $this->save_meta();
321
+ //save the image
322
+ $this->image_upload();
323
+ $image_save = (count($this->errors) == 0);
324
+ }elseif(is_wp_error($post_id)){
325
+ //location not saved, add an error
326
+ $this->add_error($post_id->get_error_message());
327
+ }
328
+ return apply_filters('em_location_save', $post_save && $meta_save && $image_save, $this);
329
+ }
330
+
331
+ function save_meta(){
332
+ //echo "<pre>"; print_r($this); echo "</pre>"; die();
333
+ global $wpdb, $current_user;
334
+ if( $this->can_manage('edit_locations','edit_others_locations') || ( get_option('dbem_events_anonymous_submissions') && empty($this->location_id)) ){
335
+ do_action('em_location_save_meta_pre', $this);
336
+ $data = $this->to_array();
337
+ //Update Post Meta
338
+ foreach( array_keys($this->fields) as $key ){
339
+ if( !in_array($key, $this->post_fields) ){
340
+ update_post_meta($this->post_id, '_'.$key, $this->$key);
341
+ }
342
+ }
343
+ //Update Post Attributes
344
+ foreach($this->location_attributes as $location_attribute_key => $location_attribute){
345
+ update_post_meta($this->post_id, $location_attribute_key, $location_attribute);
346
+ }
347
+ $this->get_status();
348
+ $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
349
+ //Save to em_locations table
350
+ $location_array = $this->to_array(true);
351
+ if( $this->post_status == 'private' ) $location_array['location_private'] = 1;
352
+ unset($location_array['location_id']);
353
+ if( !empty($this->location_id) ){
354
+ $loc_truly_exists = $wpdb->get_var('SELECT post_id FROM '.EM_LOCATIONS_TABLE." WHERE location_id={$this->location_id}") == $this->post_id;
355
+ }else{
356
+ $loc_truly_exists = false;
357
+ }
358
+ if( empty($this->location_id) || !$loc_truly_exists ){
359
+ $this->previous_status = 0; //for sure this was previously status 0
360
+ if ( !$wpdb->insert(EM_LOCATIONS_TABLE, $location_array) ){
361
+ $this->add_error( sprintf(__('Something went wrong saving your %s to the index table. Please inform a site administrator about this.','dbem'),__('location','dbem')));
362
+ }else{
363
+ //success, so link the event with the post via an event id meta value for easy retrieval
364
+ $this->location_id = $wpdb->insert_id;
365
+ update_post_meta($this->post_id, '_location_id', $this->location_id);
366
+ $this->feedback_message = sprintf(__('Successfully saved %s','dbem'),__('Location','dbem'));
367
+ }
368
+ }else{
369
+ $this->previous_status = $wpdb->get_var('SELECT location_status FROM '.EM_LOCATIONS_TABLE.' WHERE location_id='.$this->location_id); //get status from db, not post_status
370
+ if ( $wpdb->update(EM_LOCATIONS_TABLE, $location_array, array('location_id'=>$this->location_id)) === false ){
371
+ $this->add_error( sprintf(__('Something went wrong updating your %s to the index table. Please inform a site administrator about this.','dbem'),__('location','dbem')));
372
+ }else{
373
+ $this->feedback_message = sprintf(__('Successfully saved %s','dbem'),__('Location','dbem'));
374
+ }
375
+ }
376
+ }else{
377
+ $this->add_error( sprintf(__('You do not have permission to create/edit %s.','dbem'), __('locations','dbem')) );
378
+ }
379
+ $this->compat_keys();
380
+ return apply_filters('em_location_save_meta', count($this->errors) == 0, $this);
381
+ }
382
+
383
+ function delete($force_delete = true){ //atm wp seems to force cp deletions anyway
384
+ global $wpdb;
385
+ $result = false;
386
+ if( $this->can_manage('delete_locations','delete_others_locations') ){
387
+ do_action('em_location_delete_pre', $this);
388
+ $result = wp_delete_post($this->post_id,$force_delete); //the post class will take care of the meta
389
+ if( $force_delete ){
390
+ $result_meta = $this->delete_meta();
391
+ }
392
+ }
393
+ return apply_filters('em_location_delete', $result !== false && $result_meta, $this);
394
+ }
395
+
396
+ function delete_meta(){
397
+ global $wpdb;
398
+ $result = false;
399
+ if( $this->can_manage('delete_locations','delete_others_locations') ){
400
+ do_action('em_location_delete_meta_pre', $this);
401
+ $result = $wpdb->query ( $wpdb->prepare("DELETE FROM ". EM_LOCATIONS_TABLE ." WHERE location_id=%d", $this->location_id) );
402
+ }
403
+ return apply_filters('em_location_delete_meta', $result !== false, $this);
404
+ }
405
+
406
+ function is_published(){
407
+ return apply_filters('em_location_is_published', ($this->post_status == 'publish' || $this->post_status == 'private'), $this);
408
+ }
409
+
410
+ /**
411
+ * Change the status of the location. This will save to the Database too.
412
+ * @param int $status
413
+ * @param boolean $set_post_status
414
+ * @return string
415
+ */
416
+ function set_status($status, $set_post_status = false){
417
+ global $wpdb;
418
+ if($status === null){
419
+ $set_status='NULL';
420
+ if($set_post_status){
421
+ //if the post is trash, don't untrash it!
422
+ $wpdb->update( $wpdb->posts, array( 'post_status' => 'draft' ), array( 'ID' => $this->post_id ) );
423
+ $this->post_status = 'draft';
424
+ }
425
+ }else{
426
+ $set_status = $status ? 1:0;
427
+ if($set_post_status){
428
+ if($this->post_status == 'pending'){
429
+ $this->post_name = sanitize_title($this->post_title);
430
+ }
431
+ $this->post_status = $set_status ? 'publish':'pending';
432
+ $wpdb->update( $wpdb->posts, array( 'post_status' => $this->post_status, 'post_name' => $this->post_name ), array( 'ID' => $this->post_id ) );
433
+ }
434
+ }
435
+ $this->previous_status = $wpdb->get_var('SELECT location_status FROM '.EM_LOCATIONS_TABLE.' WHERE location_id='.$this->location_id); //get status from db, not post_status, as posts get saved quickly
436
+ $result = $wpdb->query("UPDATE ".EM_LOCATIONS_TABLE." SET location_status=$set_status, location_slug='{$this->post_name}' WHERE location_id={$this->location_id}");
437
+ $this->get_status();
438
+ return apply_filters('em_location_set_status', $result !== false, $status, $this);
439
+ }
440
+
441
+ function get_status($db = false){
442
+ switch( $this->post_status ){
443
+ case 'private':
444
+ $this->location_private = 1;
445
+ $this->location_status = $status = 1;
446
+ break;
447
+ case 'publish':
448
+ $this->location_private = 0;
449
+ $this->location_status = $status = 1;
450
+ break;
451
+ case 'pending':
452
+ $this->location_private = 0;
453
+ $this->location_status = $status = 0;
454
+ break;
455
+ default: //draft or unknown
456
+ $this->location_private = 0;
457
+ $status = $db ? 'NULL':null;
458
+ $this->location_status = null;
459
+ break;
460
+ }
461
+ return $status;
462
+ }
463
+
464
+ function load_similar($criteria){
465
+ global $wpdb;
466
+ if( !empty($criteria['location_name']) && !empty($criteria['location_name']) && !empty($criteria['location_name']) ){
467
+ $locations_table = EM_LOCATIONS_TABLE;
468
+ $prepared_sql = $wpdb->prepare("SELECT * FROM $locations_table WHERE location_name = %s AND location_address = %s AND location_town = %s AND location_state = %s AND location_postcode = %s AND location_country = %s", stripcslashes($criteria['location_name']), stripcslashes($criteria['location_address']), stripcslashes($criteria['location_town']), stripcslashes($criteria['location_state']), stripcslashes($criteria['location_postcode']), stripcslashes($criteria['location_country']) );
469
+ //$wpdb->show_errors(true);
470
+ $location = $wpdb->get_row($prepared_sql, ARRAY_A);
471
+ if( is_array($location) ){
472
+ $this->to_object($location);
473
+ }
474
+ return apply_filters('em_location_load_similar', $location, $this);
475
+ }
476
+ return apply_filters('em_location_load_similar', false, $this);
477
+ }
478
+
479
+ function has_events(){
480
+ global $wpdb;
481
+ $events_table = EM_EVENTS_TABLE;
482
+ $sql = "SELECT count(event_id) as events_no FROM $events_table WHERE location_id = {$this->location_id}";
483
+ $affected_events = $wpdb->get_row($sql);
484
+ return apply_filters('em_location_has_events', (count($affected_events) > 0), $this);
485
+ }
486
+
487
+ /**
488
+ * Can the user manage this location?
489
+ */
490
+ function can_manage( $owner_capability = false, $admin_capability = false, $user_to_check = false ){
491
+ if( $this->location_id == '' && !is_user_logged_in() && get_option('dbem_events_anonymous_submissions') ){
492
+ $user_to_check = get_option('dbem_events_anonymous_user');
493
+ }
494
+ return apply_filters('em_location_can_manage', parent::can_manage($owner_capability, $admin_capability, $user_to_check), $this, $owner_capability, $admin_capability, $user_to_check);
495
+ }
496
+
497
+ function get_permalink(){
498
+ if( EM_MS_GLOBAL ){
499
+ if( get_site_option('dbem_ms_global_locations_links') && !empty($this->blog_id) && is_main_site() && $this->blog_id != get_current_blog_id() ){
500
+ //linking directly to the blog, we should be on the main blog here
501
+ $link = get_blog_permalink( $this->blog_id, $this->post_id);
502
+ }elseif( !empty($this->blog_id) && is_main_site() && $this->blog_id != get_current_blog_id() ){
503
+ if( get_option('dbem_locations_page') ){
504
+ $link = trailingslashit(get_permalink(get_option('dbem_locations_page')).get_site_option('dbem_ms_locations_slug',EM_LOCATION_SLUG).'/'.$this->location_slug.'-'.$this->location_id);
505
+ }else{
506
+ $link = trailingslashit(home_url()).EM_POST_TYPE_LOCATION_SLUG.'/'.get_site_option('dbem_ms_events_slug',EM_LOCATION_SLUG).'/'.$this->location_slug.'-'.$this->location_id;
507
+ }
508
+ }
509
+ }
510
+ if( empty($link) ){
511
+ $link = get_post_permalink($this->post_id);
512
+ }
513
+ return apply_filters('em_location_get_permalink', $link, $this); ;
514
+ }
515
+
516
+ function get_edit_url(){
517
+ if( $this->can_manage('edit_locations','edit_others_locations') ){
518
+ if( EM_MS_GLOBAL && get_site_option('dbem_ms_global_locations_links') && !empty($this->blog_id) && is_main_site() && $this->blog_id != get_current_blog_id() ){
519
+ if( get_blog_option($this->blog_id, 'dbem_edit_locations_page') ){
520
+ $link = em_add_get_params(get_permalink(get_blog_option($this->blog_id, 'dbem_edit_locations_page')), array('action'=>'edit','location_id'=>$this->location_id), false);
521
+ }
522
+ if( empty($link))
523
+ $link = get_admin_url($this->blog_id, "post.php?post={$this->post_id}&action=edit");
524
+ }else{
525
+ if( get_option('dbem_edit_locations_page') ){
526
+ $link = em_add_get_params(get_permalink(get_option('dbem_edit_locations_page')), array('action'=>'edit','location_id'=>$this->location_id), false);
527
+ }
528
+ if( empty($link))
529
+ $link = admin_url()."post.php?post={$this->post_id}&action=edit";
530
+ }
531
+ return apply_filters('em_location_get_edit_url', $link, $this);
532
+ }
533
+ }
534
+
535
+ function output_single($target = 'html'){
536
+ $format = get_option ( 'dbem_single_location_format' );
537
+ return apply_filters('em_location_output_single', $this->output($format, $target), $this, $target);
538
+ }
539
+
540
+ function output($format, $target="html") {
541
+ $location_string = $format;
542
+ preg_match_all('/\{([a-zA-Z0-9_]+)\}([^{]+)\{\/[a-zA-Z0-9_]+\}/', $format, $conditionals);
543
+ if( count($conditionals[0]) > 0 ){
544
+ //Check if the language we want exists, if not we take the first language there
545
+ foreach($conditionals[1] as $key => $condition){
546
+ $format = str_replace($conditionals[0][$key], apply_filters('em_location_output_condition', '', $conditionals[0][$key], $condition, $this), $format);
547
+ }
548
+ }
549
+ //This is for the custom attributes
550
+ preg_match_all('/#_LATT\{([^}]+)\}(\{([^}]+)\})?/', $format, $results);
551
+ foreach($results[0] as $resultKey => $result) {
552
+ //Strip string of placeholder and just leave the reference
553
+ $attRef = substr( substr($result, 0, strpos($result, '}')), 7 );
554
+ $attString = '';
555
+ if( is_array($this->location_attributes) && array_key_exists($attRef, $this->location_attributes) && !empty($this->location_attributes[$attRef]) ){
556
+ $attString = $this->location_attributes[$attRef];
557
+ }elseif( !empty($results[3][$resultKey]) ){
558
+ //Check to see if we have a second set of braces;
559
+ $attString = $results[3][$resultKey];
560
+ }
561
+ $attString = apply_filters('em_location_output_placeholder', $attString, $this, $result, $target);
562
+ $location_string = str_replace($result, $attString ,$location_string );
563
+ }
564
+ preg_match_all("/(#@?_?[A-Za-z0-9]+)({([a-zA-Z0-9,]+)})?/", $format, $placeholders);
565
+ $replaces = array();
566
+ foreach($placeholders[1] as $key => $result) {
567
+ $replace = '';
568
+ $full_result = $placeholders[0][$key];
569
+ switch( $result ){
570
+ case '#_LOCATIONID':
571
+ $replace = $this->location_id;
572
+ break;
573
+ case '#_LOCATIONPOSTID':
574
+ $replace = $this->location_id;
575
+ break;
576
+ case '#_NAME': //Depreciated
577
+ case '#_LOCATION': //Depreciated
578
+ case '#_LOCATIONNAME':
579
+ $replace = $this->location_name;
580
+ break;
581
+ case '#_ADDRESS': //Depreciated
582
+ case '#_LOCATIONADDRESS':
583
+ $replace = $this->location_address;
584
+ break;
585
+ case '#_TOWN': //Depreciated
586
+ case '#_LOCATIONTOWN':
587
+ $replace = $this->location_town;
588
+ break;
589
+ case '#_LOCATIONSTATE':
590
+ $replace = $this->location_state;
591
+ break;
592
+ case '#_LOCATIONPOSTCODE':
593
+ $replace = $this->location_postcode;
594
+ break;
595
+ case '#_LOCATIONREGION':
596
+ $replace = $this->location_region;
597
+ break;
598
+ case '#_LOCATIONCOUNTRY':
599
+ $replace = $this->get_country();
600
+ break;
601
+ case '#_LOCATIONFULLLINE':
602
+ $replace = $this->location_address;
603
+ $replace .= empty($this->location_town) ? '':', '.$this->location_town;
604
+ $replace .= empty($this->location_state) ? '':', '.$this->location_state;
605
+ $replace .= empty($this->location_postcode) ? '':', '.$this->location_postcode;
606
+ $replace .= empty($this->location_region) ? '':', '.$this->location_region;
607
+ break;
608
+ case '#_LOCATIONFULLBR':
609
+ $replace = $this->location_address;
610
+ $replace .= empty($this->location_town) ? '':'<br />'.$this->location_town;
611
+ $replace .= empty($this->location_state) ? '':'<br />'.$this->location_state;
612
+ $replace .= empty($this->location_postcode) ? '':'<br />'.$this->location_postcode;
613
+ $replace .= empty($this->location_region) ? '':'<br />'.$this->location_region;
614
+ break;
615
+ case '#_MAP': //Depreciated
616
+ case '#_LOCATIONMAP':
617
+ ob_start();
618
+ $template = em_locate_template('placeholders/locationmap.php', true, array('EM_Location'=>$this));
619
+ $replace = ob_get_clean();
620
+ break;
621
+ case '#_DESCRIPTION': //Depreciated
622
+ case '#_EXCERPT': //Depreciated
623
+ case '#_LOCATIONNOTES':
624
+ case '#_LOCATIONEXCERPT':
625
+ $replace = $this->post_content;
626
+ if($result == "#_EXCERPT" || $result == "#_LOCATIONEXCERPT"){
627
+ if( !empty($this->post_excerpt) ){
628
+ $replace = $this->post_excerpt;
629
+ }else{
630
+ $matches = explode('<!--more', $this->post_content);
631
+ $replace = $matches[0];
632
+ }
633
+ }
634
+ break;
635
+ case '#_LOCATIONIMAGEURL':
636
+ case '#_LOCATIONIMAGE':
637
+ if($this->get_image_url() != ''){
638
+ $image_url = esc_url($this->get_image_url());
639
+ if($result == '#_LOCATIONIMAGEURL'){
640
+ $replace = $this->get_image_url();
641
+ }else{
642
+ if( empty($placeholders[3][$key]) ){
643
+ $replace = "<img src='".$image_url."' alt='".esc_attr($this->location_name)."'/>";
644
+ }else{
645
+ $image_size = explode(',', $placeholders[3][$key]);
646
+ if( $this->array_is_numeric($image_size) && count($image_size) > 1 ){
647
+ global $blog_id;
648
+ if ( is_multisite() && $blog_id > 0) {
649
+ $imageParts = explode('/blogs.dir/', $image_url);
650
+ if (isset($imageParts[1])) {
651
+ $image_url = network_site_url('/wp-content/blogs.dir/'. $blog_id. '/' . $imageParts[1]);
652
+ }
653
+ }
654
+ $replace = "<img src='".esc_url(em_get_thumbnail_url($image_url, $image_size[0], $image_size[1]))."' alt='".esc_attr($this->location_name)."'/>";
655
+ }else{
656
+ $replace = "<img src='".$image_url."' alt='".esc_attr($this->location_name)."'/>";
657
+ }
658
+ }
659
+ }
660
+ }
661
+ break;
662
+ case '#_LOCATIONURL':
663
+ case '#_LOCATIONLINK':
664
+ case '#_LOCATIONPAGEURL': //Depreciated
665
+ $link = esc_url($this->get_permalink());
666
+ $replace = ($result == '#_LOCATIONURL' || $result == '#_LOCATIONPAGEURL') ? $link : '<a href="'.$link.'" title="'.esc_attr($this->location_name).'">'.esc_html($this->location_name).'</a>';
667
+ break;
668
+ case '#_LOCATIONEDITURL':
669
+ case '#_LOCATIONEDITLINK':
670
+ $link = esc_url($this->get_edit_url());
671
+ $replace = ($result == '#_LOCATIONEDITURL') ? $link : '<a href="'.$link.'" title="'.esc_attr($this->location_name).'">'.esc_html(sprintf(__('Edit %s','dbem'),__('Location','dbem'))).'</a>';
672
+ break;
673
+ case '#_PASTEVENTS': //Depreciated
674
+ case '#_LOCATIONPASTEVENTS':
675
+ case '#_NEXTEVENTS': //Depreciated
676
+ case '#_LOCATIONNEXTEVENTS':
677
+ case '#_ALLEVENTS': //Depreciated
678
+ case '#_LOCATIONALLEVENTS':
679
+ //TODO: add limit to lists of events
680
+ //convert depreciated placeholders for compatability
681
+ $result = ($result == '#_PASTEVENTS') ? '#_LOCATIONPASTEVENTS':$result;
682
+ $result = ($result == '#_NEXTEVENTS') ? '#_LOCATIONNEXTEVENTS':$result;
683
+ $result = ($result == '#_ALLEVENTS') ? '#_LOCATIONALLEVENTS':$result;
684
+ //forget it ever happened? :/
685
+ if ( $result == '#_LOCATIONPASTEVENTS'){ $scope = 'past'; }
686
+ elseif ( $result == '#_LOCATIONNEXTEVENTS' ){ $scope = 'future'; }
687
+ else{ $scope = 'all'; }
688
+ $events = EM_Events::get( array('location'=>$this->location_id, 'scope'=>$scope) );
689
+ if ( count($events) > 0 ){
690
+ $replace .= get_option('dbem_location_event_list_item_header_format');
691
+ foreach($events as $event){
692
+ $replace .= $event->output(get_option('dbem_location_event_list_item_format'));
693
+ }
694
+ $replace .= get_option('dbem_location_event_list_item_footer_format');
695
+ } else {
696
+ $replace = get_option('dbem_location_no_events_message');
697
+ }
698
+ break;
699
+ case '#_LOCATIONNEXTEVENT':
700
+ $events = EM_Events::get( array('location'=>$this->location_id, 'scope'=>'future', 'limit'=>1, 'orderby'=>'event_start_date,event_start_time') );
701
+ $replace = get_option('dbem_location_no_events_message');
702
+ foreach($events as $EM_Event){
703
+ $replace = $EM_Event->output('#_EVENTLINK');
704
+ }
705
+ break;
706
+ default:
707
+ $replace = $full_result;
708
+ break;
709
+ }
710
+ $replaces[$full_result] = apply_filters('em_location_output_placeholder', $replace, $this, $full_result, $target);
711
+ }
712
+ //sort out replacements so that during replacements shorter placeholders don't overwrite longer varieties.
713
+ krsort($replaces);
714
+ foreach($replaces as $full_result => $replacement){
715
+ $location_string = str_replace($full_result, $replacement , $location_string );
716
+ }
717
+ return apply_filters('em_location_output', $location_string, $this, $format, $target);
718
+ }
719
+
720
+ function get_country(){
721
+ $countries = em_get_countries();
722
+ if( !empty($countries[$this->location_country]) ){
723
+ return apply_filters('em_location_get_country', $countries[$this->location_country], $this);
724
+ }
725
+ return apply_filters('em_location_get_country', false, $this);
726
+
727
+ }
728
  }
classes/em-locations.php CHANGED
@@ -1,213 +1,306 @@
1
- <?php
2
- /**
3
- * Static class which will help bulk add/edit/retrieve/manipulate arrays of EM_Location objects.
4
- * Optimized for specifically retreiving locations (whether eventful or not). If you want event data AND location information for each event, use EM_Events
5
- *
6
- */
7
- class EM_Locations extends EM_Object {
8
- /**
9
- * Returns an array of EM_Location objects
10
- * @param boolean $eventful
11
- * @param boolean $return_objects
12
- * @return array
13
- */
14
- function get( $args = array() ){
15
- global $wpdb;
16
- $events_table = $wpdb->prefix . EM_EVENTS_TABLE;
17
- $locations_table = $wpdb->prefix . EM_LOCATIONS_TABLE;
18
-
19
- //Quick version, we can accept an array of IDs, which is easy to retrieve
20
- if( self::array_is_numeric($args) && count() ){ //Array of numbers, assume they are event IDs to retreive
21
- //We can just get all the events here and return them
22
- $sql = "SELECT * FROM $locations_table WHERE location_id=".implode(" OR location_id=", $args);
23
- $results = $wpdb->get_results($sql,ARRAY_A);
24
- $events = array();
25
- foreach($results as $result){
26
- $locations[$result['location_id']] = new EM_Location($result);
27
- }
28
- return $locations; //We return all the events matched as an EM_Event array.
29
- }
30
-
31
-
32
- //We assume it's either an empty array or array of search arguments to merge with defaults
33
- $args = self::get_default_search($args);
34
- $limit = ( $args['limit'] && is_numeric($args['limit'])) ? "LIMIT {$args['limit']}" : '';
35
- $offset = ( $limit != "" && is_numeric($args['offset']) ) ? "OFFSET {$args['offset']}" : '';
36
-
37
- //Get the default conditions
38
- $conditions = self::build_sql_conditions($args);
39
-
40
- //Put it all together
41
- $EM_Location = new EM_Location(0); //Empty class for strict message avoidance
42
- $fields = $locations_table .".". implode(", {$locations_table}.", array_keys($EM_Location->fields));
43
- $where = ( count($conditions) > 0 ) ? " WHERE " . implode ( " AND ", $conditions ):'';
44
-
45
- //Get ordering instructions
46
- $EM_Event = new EM_Event(); //blank event for below
47
- $accepted_fields = $EM_Location->get_fields(true);
48
- $accepted_fields = array_merge($EM_Event->get_fields(true),$accepted_fields);
49
- $orderby = self::build_sql_orderby($args, $accepted_fields, get_option('dbem_events_default_order'));
50
- //Now, build orderby sql
51
- $orderby_sql = ( count($orderby) > 0 ) ? 'ORDER BY '. implode(', ', $orderby) : '';
52
-
53
-
54
- //Create the SQL statement and execute
55
- $sql = "
56
- SELECT $fields FROM $locations_table
57
- LEFT JOIN $events_table ON {$locations_table}.location_id={$events_table}.location_id
58
- $where
59
- GROUP BY location_id
60
- $orderby_sql
61
- $limit $offset
62
- ";
63
-
64
- $results = $wpdb->get_results($sql, ARRAY_A);
65
-
66
- //If we want results directly in an array, why not have a shortcut here?
67
- if( $args['array'] == true ){
68
- return $results;
69
- }
70
-
71
- $locations = array();
72
- foreach ($results as $location){
73
- $locations[] = new EM_Location($location);
74
- }
75
- return apply_filters('em_locations_get', $locations, $args);
76
- }
77
-
78
- /**
79
- * Output a set of matched of events
80
- * @param array $args
81
- * @return string
82
- */
83
- function output( $args ){
84
- global $EM_Location;
85
- $EM_Location_old = $EM_Location; //When looping, we can replace EM_Location global with the current event in the loop
86
- //Can be either an array for the get search or an array of EM_Location objects
87
- if( is_object(current($args)) && get_class((current($args))) == 'EM_Location' ){
88
- $func_args = func_get_args();
89
- $locations = $func_args[0];
90
- $args = apply_filters('em_locations_output_args', self::get_default_search($func_args[1]), $locations);
91
- $limit = ( !empty($args['limit']) && is_numeric($args['limit']) ) ? $args['limit']:false;
92
- $offset = ( !empty($args['offset']) && is_numeric($args['offset']) ) ? $args['offset']:0;
93
- $page = ( !empty($args['page']) && is_numeric($args['page']) ) ? $args['page']:1;
94
- }else{
95
- $args = apply_filters('em_locations_output_args', self::get_default_search($args) );
96
- $limit = ( !empty($args['limit']) && is_numeric($args['limit']) ) ? $args['limit']:false;
97
- $offset = ( !empty($args['offset']) && is_numeric($args['offset']) ) ? $args['offset']:0;
98
- $page = ( !empty($args['page']) && is_numeric($args['page']) ) ? $args['page']:1;
99
- $args['limit'] = false;
100
- $args['offset'] = false;
101
- $args['page'] = false;
102
- $locations = self::get( $args );
103
- }
104
- //What format shall we output this to, or use default
105
- $format = ( $args['format'] == '' ) ? get_option( 'dbem_location_list_item_format' ) : $args['format'] ;
106
-
107
- $output = "";
108
- $locations_count = count($locations);
109
- $locations = apply_filters('em_locations_output_locations', $locations);
110
-
111
- if ( count($locations) > 0 ) {
112
- $location_count = 0;
113
- $locations_shown = 0;
114
- foreach ( $locations as $EM_Location ) {
115
- if( ($locations_shown < $limit || empty($limit)) && ($location_count >= $offset || $offset === 0) ){
116
- $output .= $EM_Location->output($format);
117
- $locations_shown++;
118
- }
119
- $location_count++;
120
- }
121
- //Add headers and footers to output
122
- if( $format == get_option ( 'dbem_location_list_item_format' ) ){
123
- $single_event_format_header = get_option ( 'dbem_location_list_item_format_header' );
124
- $single_event_format_header = ( $single_event_format_header != '' ) ? $single_event_format_header : "<ul class='dbem_events_list'>";
125
- $single_event_format_footer = get_option ( 'dbem_location_list_item_format_footer' );
126
- $single_event_format_footer = ( $single_event_format_footer != '' ) ? $single_event_format_footer : "</ul>";
127
- $output = $single_event_format_header . $output . $single_event_format_footer;
128
- }
129
- //Pagination (if needed/requested)
130
- if( !empty($args['pagination']) && !empty($limit) && $locations_count >= $limit ){
131
- //Show the pagination links (unless there's less than 10 events
132
- $page_link_template = preg_replace('/(&|\?)page=\d+/i','',$_SERVER['REQUEST_URI']);
133
- $page_link_template = em_add_get_params($page_link_template, array('page'=>'%PAGE%'));
134
- $output .= apply_filters('em_events_output_pagination', em_paginate( $page_link_template, $locations_count, $limit, $page), $page_link_template, $locations_count, $limit, $page);
135
- }
136
- } else {
137
- $output = get_option ( 'dbem_no_events_message' );
138
- }
139
- //FIXME check if reference is ok when restoring object, due to changes in php5 v 4
140
- $EM_Location_old= $EM_Location;
141
- return apply_filters('em_locations_output', $output, $locations, $args);
142
- }
143
-
144
- /**
145
- * Builds an array of SQL query conditions based on regularly used arguments
146
- * @param array $args
147
- * @return array
148
- */
149
- function build_sql_conditions( $args = array() ){
150
- global $wpdb;
151
- $events_table = $wpdb->prefix . EM_EVENTS_TABLE;
152
- $locations_table = $wpdb->prefix . EM_LOCATIONS_TABLE;
153
-
154
- $conditions = parent::build_sql_conditions($args);
155
- //eventful locations
156
- if( true == $args['eventful'] ){
157
- $conditions['eventful'] = "{$events_table}.event_id IS NOT NULL";
158
- }elseif( true == $args['eventless'] ){
159
- $conditions['eventless'] = "{$events_table}.event_id IS NULL";
160
- }
161
- //owner lookup
162
- if( !empty($args['owner']) ){
163
- if ( get_option('dbem_permissions_locations') < 1 && !em_verify_admin() ){
164
- $conditions['owner'] = "location_owner=".get_current_user_id();
165
- }
166
- }
167
- return apply_filters('em_locations_build_sql_conditions', $conditions, $args);
168
- }
169
-
170
- /* Overrides EM_Object method to apply a filter to result
171
- * @see wp-content/plugins/events-manager/classes/EM_Object#build_sql_orderby()
172
- */
173
- function build_sql_orderby( $args, $accepted_fields, $default_order = 'ASC' ){
174
- return apply_filters( 'em_locations_build_sql_orderby', parent::build_sql_orderby($args, $accepted_fields, get_option('dbem_events_default_order')), $args, $accepted_fields, $default_order );
175
- }
176
-
177
- /*
178
- * Generate a search arguments array from defalut and user-defined.
179
- * @see wp-content/plugins/events-manager/classes/EM_Object::get_default_search()
180
- */
181
- function get_default_search($array = array()){
182
- $defaults = array(
183
- 'eventful' => false, //Locations that have an event (scope will also play a part here
184
- 'eventless' => false, //Locations WITHOUT events, eventful takes precedence
185
- 'orderby' => 'name',
186
- 'scope' => 'all' //we probably want to search all locations by default, not like events
187
- );
188
- $array['eventful'] = ( !empty($array['eventful']) && $array['eventful'] == true );
189
- $array['eventless'] = ( !empty($array['eventless']) && $array['eventless'] == true );
190
- if( is_admin() ){
191
- //by default, we only get categories the owner can manage
192
- switch( get_option('dbem_permissions_locations') ){
193
- case 0:
194
- $defaults['owner'] = get_current_user_id();
195
- break;
196
- case 1:
197
- $wp_user_search = new WP_User_Search(null, null, 'administrator');
198
- $users = $wp_user_search->get_results();
199
- $users[] = get_current_user_id();
200
- $users[] = 0;
201
- $defaults['owner'] = implode(',', $users);
202
- break;
203
- case 2:
204
- $defaults['owner'] = false;
205
- break;
206
- }
207
- $defaults['owner'] = ( em_verify_admin() ) ? false:$defaults['owner'];
208
- }
209
- return apply_filters('em_locations_get_default_search', parent::get_default_search($defaults, $array), $array, $defaults);
210
- }
211
- //TODO for all the static plural classes like this one, we might benefit from bulk actions like delete/add/save etc.... just a random thought.
212
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
213
  ?>
1
+ <?php
2
+ /**
3
+ * Static class which will help bulk add/edit/retrieve/manipulate arrays of EM_Location objects.
4
+ * Optimized for specifically retreiving locations (whether eventful or not). If you want event data AND location information for each event, use EM_Events
5
+ *
6
+ */
7
+ class EM_Locations extends EM_Object implements Iterator {
8
+ /**
9
+ * Array of EM_Location objects
10
+ * @var array EM_Location
11
+ */
12
+ var $locations = array();
13
+
14
+ /**
15
+ * Returns an array of EM_Location objects
16
+ * @param boolean $eventful
17
+ * @param boolean $return_objects
18
+ * @return array
19
+ */
20
+ function get( $args = array(), $count=false ){
21
+ global $wpdb;
22
+ $events_table = EM_EVENTS_TABLE;
23
+ $locations_table = EM_LOCATIONS_TABLE;
24
+ $locations = array();
25
+
26
+ //Quick version, we can accept an array of IDs, which is easy to retrieve
27
+ if( self::array_is_numeric($args) ){ //Array of numbers, assume they are event IDs to retreive
28
+ //We can just get all the events here and return them
29
+ $sql = "SELECT * FROM $locations_table WHERE location_id=".implode(" OR location_id=", $args);
30
+ $results = $wpdb->get_results($sql,ARRAY_A);
31
+ $events = array();
32
+ foreach($results as $result){
33
+ $locations[$result['location_id']] = new EM_Location($result);
34
+ }
35
+ return apply_filters('em_locations_get', $locations, $args); //We return all the events matched as an EM_Event array.
36
+ }elseif( is_numeric($args) ){
37
+ //return an event in the usual array format
38
+ return apply_filters('em_locations_get', array(new EM_Location($args)), $args);
39
+ }elseif( is_array($args) && is_object(current($args)) && get_class((current($args))) == 'EM_Location' ){
40
+ return apply_filters('em_locations_get', $args, $args);
41
+ }
42
+
43
+ //We assume it's either an empty array or array of search arguments to merge with defaults
44
+ $args = self::get_default_search($args);
45
+ $limit = ( $args['limit'] && is_numeric($args['limit'])) ? "LIMIT {$args['limit']}" : '';
46
+ $offset = ( $limit != "" && is_numeric($args['offset']) ) ? "OFFSET {$args['offset']}" : '';
47
+
48
+ //Get the default conditions
49
+ $conditions = self::build_sql_conditions($args);
50
+
51
+ //Put it all together
52
+ $EM_Location = new EM_Location(0); //Empty class for strict message avoidance
53
+ $fields = $locations_table .".". implode(", {$locations_table}.", array_keys($EM_Location->fields));
54
+ $where = ( count($conditions) > 0 ) ? " WHERE " . implode ( " AND ", $conditions ):'';
55
+
56
+ //Get ordering instructions
57
+ $EM_Event = new EM_Event(); //blank event for below
58
+ $accepted_fields = $EM_Location->get_fields(true);
59
+ $accepted_fields = array_merge($EM_Event->get_fields(true),$accepted_fields);
60
+ $orderby = self::build_sql_orderby($args, $accepted_fields, get_option('dbem_events_default_order'));
61
+ //Now, build orderby sql
62
+ $orderby_sql = ( count($orderby) > 0 ) ? 'ORDER BY '. implode(', ', $orderby) : '';
63
+
64
+ $fields = ( $count ) ? $locations_table.'.location_id':$locations_table.'.post_id';
65
+ if( EM_MS_GLOBAL ){
66
+ $selectors = ( $count ) ? 'COUNT('.$locations_table.'.location_id)':$locations_table.'.post_id, '.$locations_table.'.blog_id';
67
+ }else{
68
+ $selectors = ( $count ) ? 'COUNT('.$locations_table.'.location_id)':$locations_table.'.post_id';
69
+ }
70
+ //Create the SQL statement and execute
71
+ $sql = "
72
+ SELECT $selectors FROM $locations_table
73
+ LEFT JOIN $events_table ON {$locations_table}.location_id={$events_table}.location_id
74
+ $where
75
+ GROUP BY {$locations_table}.location_id
76
+ $orderby_sql
77
+ $limit $offset
78
+ ";
79
+
80
+ //If we're only counting results, return the number of results
81
+ if( $count ){
82
+ return apply_filters('em_locations_get_array', count($wpdb->get_col($sql)), $args);
83
+ }
84
+ $results = $wpdb->get_results($sql, ARRAY_A);
85
+
86
+ //If we want results directly in an array, why not have a shortcut here?
87
+ if( $args['array'] == true ){
88
+ return apply_filters('em_locations_get_array', $results, $args);
89
+ }
90
+
91
+ if( EM_MS_GLOBAL ){
92
+ foreach ( $results as $location ){
93
+ $locations[] = em_get_location($location['post_id'], $location['blog_id']);
94
+ }
95
+ }else{
96
+ foreach ( $results as $location ){
97
+ $locations[] = em_get_location($location['post_id'], 'post_id');
98
+ }
99
+ }
100
+ return apply_filters('em_locations_get', $locations, $args);
101
+ }
102
+
103
+ function count( $args = array() ){
104
+ return apply_filters('em_locations_count', self::get($args, true), $args);
105
+ }
106
+
107
+ /**
108
+ * Output a set of matched of events
109
+ * @param array $args
110
+ * @return string
111
+ */
112
+ function output( $args ){
113
+ global $EM_Location;
114
+ $EM_Location_old = $EM_Location; //When looping, we can replace EM_Location global with the current event in the loop
115
+ //Can be either an array for the get search or an array of EM_Location objects
116
+ if( is_object(current($args)) && get_class((current($args))) == 'EM_Location' ){
117
+ $func_args = func_get_args();
118
+ $locations = $func_args[0];
119
+ $args = (!empty($func_args[1])) ? $func_args[1] : array();
120
+ $args = apply_filters('em_locations_output_args', self::get_default_search($args), $locations);
121
+ $limit = ( !empty($args['limit']) && is_numeric($args['limit']) ) ? $args['limit']:false;
122
+ $offset = ( !empty($args['offset']) && is_numeric($args['offset']) ) ? $args['offset']:0;
123
+ $page = ( !empty($args['page']) && is_numeric($args['page']) ) ? $args['page']:1;
124
+ $locations_count = count($locations);
125
+ }else{
126
+ $args = apply_filters('em_locations_output_args', self::get_default_search($args) );
127
+ $limit = ( !empty($args['limit']) && is_numeric($args['limit']) ) ? $args['limit']:false;
128
+ $offset = ( !empty($args['offset']) && is_numeric($args['offset']) ) ? $args['offset']:0;
129
+ $page = ( !empty($args['page']) && is_numeric($args['page']) ) ? $args['page']:1;
130
+ $args_count = $args;
131
+ $args_count['limit'] = 0;
132
+ $args_count['offset'] = 0;
133
+ $args_count['page'] = 1;
134
+ $locations_count = self::count($args_count);
135
+ $locations = self::get( $args );
136
+ }
137
+ //What format shall we output this to, or use default
138
+ $format = ( $args['format'] == '' ) ? get_option( 'dbem_location_list_item_format' ) : $args['format'] ;
139
+
140
+ $output = "";
141
+ $locations = apply_filters('em_locations_output_locations', $locations);
142
+ if ( count($locations) > 0 ) {
143
+ foreach ( $locations as $EM_Location ) {
144
+ $output .= $EM_Location->output($format);
145
+ }
146
+ //Add headers and footers to output
147
+ if( $format == get_option ( 'dbem_location_list_item_format' ) ){
148
+ $single_event_format_header = get_option ( 'dbem_location_list_item_format_header' );
149
+ $single_event_format_header = ( $single_event_format_header != '' ) ? $single_event_format_header : "<ul class='em-locations-list'>";
150
+ $single_event_format_footer = get_option ( 'dbem_location_list_item_format_footer' );
151
+ $single_event_format_footer = ( $single_event_format_footer != '' ) ? $single_event_format_footer : "</ul>";
152
+ $output = $single_event_format_header . $output . $single_event_format_footer;
153
+ }
154
+ //Pagination (if needed/requested)
155
+ if( !empty($args['pagination']) && !empty($limit) && $locations_count >= $limit ){
156
+ //Show the pagination links (unless there's less than 10 events
157
+ $page_link_template = preg_replace('/(&|\?)page=\d+/i','',$_SERVER['REQUEST_URI']);
158
+ $page_link_template = em_add_get_params($page_link_template, array('page'=>'%PAGE%'), false); //don't html encode, so em_paginate does its thing
159
+ $output .= apply_filters('em_events_output_pagination', em_paginate( $page_link_template, $locations_count, $limit, $page), $page_link_template, $locations_count, $limit, $page);
160
+ }
161
+ } else {
162
+ $output = get_option ( 'dbem_no_locations_message' );
163
+ }
164
+ //FIXME check if reference is ok when restoring object, due to changes in php5 v 4
165
+ $EM_Location_old= $EM_Location;
166
+ return apply_filters('em_locations_output', $output, $locations, $args);
167
+ }
168
+
169
+ function delete( $args = array() ){
170
+ if( !is_object(current($args)) && get_class((current($args))) != 'EM_Location' ){
171
+ $locations = self::get($args);
172
+ }else{
173
+ $locations = $args;
174
+ }
175
+ $results = array();
176
+ foreach ( $locations as $EM_Location ){
177
+ $results[] = $EM_Location->delete();
178
+ }
179
+ return apply_filters('em_locations_delete', in_array(false, $results), $locations);
180
+ }
181
+
182
+ /**
183
+ * Builds an array of SQL query conditions based on regularly used arguments
184
+ * @param array $args
185
+ * @return array
186
+ */
187
+ function build_sql_conditions( $args = array(), $count=false ){
188
+ global $wpdb;
189
+ $events_table = EM_EVENTS_TABLE;
190
+ $locations_table = EM_LOCATIONS_TABLE;
191
+
192
+ $conditions = parent::build_sql_conditions($args);
193
+ //eventful locations
194
+ if( true == $args['eventful'] ){
195
+ $conditions['eventful'] = "{$events_table}.event_id IS NOT NULL";
196
+ }elseif( true == $args['eventless'] ){
197
+ $conditions['eventless'] = "{$events_table}.event_id IS NULL";
198
+ }
199
+ //owner lookup
200
+ if( !empty($args['owner']) && is_numeric($args['owner'])){
201
+ $conditions['owner'] = "location_owner=".$args['owner'];
202
+ }elseif( !empty($args['owner']) && $args['owner'] == 'me' && is_user_logged_in() ){
203
+ $conditions['owner'] = 'location_owner='.get_current_user_id();
204
+ }
205
+ //blog id in events table
206
+ if( EM_MS_GLOBAL && !empty($args['blog']) ){
207
+ if( is_main_site($args['blog']) ){
208
+ $conditions['blog'] = "($locations_table.blog_id={$args['blog']} OR $locations_table.blog_id IS NULL)";
209
+ }else{
210
+ $conditions['blog'] = "($locations_table.blog_id={$args['blog']})";
211
+ }
212
+ }
213
+ //status
214
+ if( array_key_exists('status',$args) && is_numeric($args['status']) ){
215
+ $null = ($args['status'] == 0) ? ' OR `location_status` = 0':'';
216
+ $conditions['status'] = "(`location_status`={$args['status']}{$null} )";
217
+ }else{
218
+ $conditions['status'] = "(`location_status` IS NOT NULL)";
219
+ }
220
+ //private locations
221
+ if( empty($args['private']) ){
222
+ $conditions['private'] = "(`location_private`=0)";
223
+ }elseif( !empty($args['private_only']) ){
224
+ $conditions['private_only'] = "(`location_private`=1)";
225
+ }
226
+ //post search
227
+ if( !empty($args['post_id'])){
228
+ if( is_array($args['post_id']) ){
229
+ $conditions['post_id'] = "($locations_table.post_id IN (".implode(',',$args['post_id'])."))";
230
+ }else{
231
+ $conditions['post_id'] = "($locations_table.post_id={$args['post_id']})";
232
+ }
233
+ }
234
+ return apply_filters('em_locations_build_sql_conditions', $conditions, $args);
235
+ }
236
+
237
+ /* Overrides EM_Object method to apply a filter to result
238
+ * @see wp-content/plugins/events-manager/classes/EM_Object#build_sql_orderby()
239
+ */
240
+ function build_sql_orderby( $args, $accepted_fields, $default_order = 'ASC' ){
241
+ return apply_filters( 'em_locations_build_sql_orderby', parent::build_sql_orderby($args, $accepted_fields, get_option('dbem_events_default_order')), $args, $accepted_fields, $default_order );
242
+ }
243
+
244
+ /*
245
+ * Generate a search arguments array from defalut and user-defined.
246
+ * @see wp-content/plugins/events-manager/classes/EM_Object::get_default_search()
247
+ */
248
+ function get_default_search($array = array()){
249
+ $defaults = array(
250
+ 'eventful' => false, //Locations that have an event (scope will also play a part here
251
+ 'eventless' => false, //Locations WITHOUT events, eventful takes precedence
252
+ 'orderby' => 'location_name',
253
+ 'town' => false,
254
+ 'state' => false,
255
+ 'country' => false,
256
+ 'region' => false,
257
+ 'status' => 1, //approved locations only
258
+ 'scope' => 'all', //we probably want to search all locations by default, not like events
259
+ 'blog' => get_current_blog_id(),
260
+ 'private' => !current_user_can('read_private_locations'),
261
+ 'private_only' => false,
262
+ 'post_id' => false
263
+ );
264
+ if(EM_MS_GLOBAL){
265
+ global $bp;
266
+ if( !is_main_site() && !array_key_exists('blog', $array) ){
267
+ $array['blog'] = get_current_blog_id();
268
+ }elseif( array_key_exists('blog', $array) ) {
269
+ $array['blog'] = $array['blog'];
270
+ }
271
+ }
272
+ $array['eventful'] = ( !empty($array['eventful']) && $array['eventful'] == true );
273
+ $array['eventless'] = ( !empty($array['eventless']) && $array['eventless'] == true );
274
+ if( is_admin() ){
275
+ $defaults['owner'] = !current_user_can('read_others_locations') ? get_current_user_id():false;
276
+ }
277
+ return apply_filters('em_locations_get_default_search', parent::get_default_search($defaults, $array), $array, $defaults);
278
+ }
279
+
280
+ //Iteratior methods
281
+ public function rewind(){
282
+ reset($this->locations);
283
+ }
284
+
285
+ public function current(){
286
+ $var = current($this->locations);
287
+ return $var;
288
+ }
289
+
290
+ public function key(){
291
+ $var = key($this->locations);
292
+ return $var;
293
+ }
294
+
295
+ public function next(){
296
+ $var = next($this->locations);
297
+ return $var;
298
+ }
299
+
300
+ public function valid(){
301
+ $key = key($this->locations);
302
+ $var = ($key !== NULL && $key !== FALSE);
303
+ return $var;
304
+ }
305
+ }
306
  ?>
classes/em-mailer.php CHANGED
@@ -1,80 +1,116 @@
1
- <?php
2
- /**
3
- * phpmailer support
4
- *
5
- */
6
- class EM_Mailer {
7
-
8
- /**
9
- * if any errors crop up, here they are
10
- * @var array
11
- */
12
- var $errors = array();
13
-
14
- /**
15
- * @param $subject
16
- * @param $body
17
- * @param $receiver
18
- */
19
- function send($subject="no title",$body="No message specified", $receiver='') {
20
- //TODO add an EM_Error global object, for this sort of error reporting. (@marcus like StatusNotice)
21
- global $smtpsettings, $phpmailer, $cformsSettings;
22
-
23
- if( preg_match('/^[_.0-9a-z-]+@([0-9a-z][0-9a-z-]+.)+[a-z]{2,3}$/i', $receiver) ){
24
- $this->load_phpmailer();
25
- $mail = new EM_PHPMailer();
26
- //$mail->SMTPDebug = true;
27
- $mail->ClearAllRecipients();
28
- $mail->ClearAddresses();
29
- $mail->ClearAttachments();
30
- $mail->CharSet = 'utf-8';
31
- $mail->SetLanguage('en', dirname(__FILE__).'/');
32
- $mail->PluginDir = dirname(__FILE__).'/phpmailer/';
33
- $mail->Host = get_option('dbem_smtp_host');
34
- $mail->port = get_option('dbem_rsvp_mail_port');
35
- $mail->Username = get_option('dbem_smtp_username');
36
- $mail->Password = get_option('dbem_smtp_password');
37
- $mail->From = get_option('dbem_mail_sender_address');
38
- $mail->FromName = get_option('dbem_mail_sender_name'); // This is the from name in the email, you can put anything you like here
39
- $mail->Body = $body;
40
- $mail->Subject = $subject;
41
- $mail->AddAddress($receiver);
42
-
43
- //Protocols
44
- if ( get_option('dbem_rsvp_mail_send_method') == 'wp_mail' ){
45
- $mail->Mailer = 'wp_mail';
46
- $send = wp_mail($receiver, $subject, $body);
47
- if(!$send){
48
- global $phpmailer;
49
- $this->errors[] = $phpmailer->ErrorInfo;
50
- }
51
- }else{
52
- if( get_option('dbem_rsvp_mail_send_method') == 'qmail' ){
53
- $mail->IsQmail();
54
- }else {
55
- $mail->Mailer = get_option('dbem_rsvp_mail_send_method');
56
- }
57
- if(get_option('dbem_rsvp_mail_SMTPAuth') == '1'){
58
- $mail->SMTPAuth = TRUE;
59
- }
60
- $send = $mail->Send();
61
- if(!$send){
62
- $this->errors[] = $mail->ErrorInfo;
63
- }
64
- }
65
- return $send;
66
- }else{
67
- $this->errors = __('Please supply a valid email format.', 'dbem');
68
- return false;
69
- }
70
- }
71
-
72
- /**
73
- * load phpmailer classes
74
- */
75
- function load_phpmailer(){
76
- require_once(dirname(__FILE__) . '/phpmailer/class.phpmailer.php');
77
- require_once(dirname(__FILE__) . '/phpmailer/class.smtp.php');
78
- }
79
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80
  ?>
1
+ <?php
2
+ /**
3
+ * phpmailer support
4
+ *
5
+ */
6
+ class EM_Mailer {
7
+
8
+ /**
9
+ * if any errors crop up, here they are
10
+ * @var array
11
+ */
12
+ var $errors = array();
13
+
14
+ /**
15
+ * @param $subject
16
+ * @param $body
17
+ * @param $receiver
18
+ */
19
+ function send($subject="no title",$body="No message specified", $receiver='') {
20
+ //TODO add an EM_Error global object, for this sort of error reporting. (@marcus like StatusNotice)
21
+ global $smtpsettings, $phpmailer, $cformsSettings;
22
+ if( is_array($receiver) ){
23
+ $receiver_emails = array();
24
+ foreach($receiver as $receiver_email){
25
+ $receiver_emails[] = is_email($receiver_email);
26
+ }
27
+ $emails_ok = !in_array(false, $receiver_emails);
28
+ }else{
29
+ $emails_ok = is_email($receiver);
30
+ }
31
+ if ( $emails_ok && get_option('dbem_rsvp_mail_send_method') == 'wp_mail' ){
32
+ $from = get_option('dbem_mail_sender_address');
33
+ $headers = get_option('dbem_mail_sender_name') ? 'From: '.get_option('dbem_mail_sender_name').' <'.$from.'>':'From: '.$from;
34
+ if( get_option('dbem_smtp_html') ){ //create filter to change content type to html in wp_mail
35
+ add_filter('wp_mail_content_type',create_function('', 'return "text/html";'));
36
+ }
37
+ $send = wp_mail($receiver, $subject, $body, $headers);
38
+ if(!$send){
39
+ global $phpmailer;
40
+ $this->errors[] = $phpmailer->ErrorInfo;
41
+ }
42
+ return $send;
43
+ }elseif ( $emails_ok && get_option('dbem_rsvp_mail_send_method') == 'mail' ){
44
+ if(is_array($receiver)){
45
+ $receiver = implode(', ', $receiver);
46
+ }
47
+ $headers = '';
48
+ if( get_option('dbem_smtp_html') ){
49
+ $headers = 'MIME-Version: 1.0' . "\r\n";
50
+ $headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
51
+ }
52
+ $from = get_option('dbem_mail_sender_address');
53
+ $headers .= get_option('dbem_mail_sender_name') ? 'From: '.get_option('dbem_mail_sender_name').' <'.$from.'>':'From: '.$from;
54
+ $send = mail($receiver, $subject, $body, $headers);
55
+ if(!$send){
56
+ $this->errors = __('Could not send email.', 'dbem');
57
+ }
58
+ return $send;
59
+ }elseif( $emails_ok ){
60
+ $this->load_phpmailer();
61
+ $mail = new EM_PHPMailer();
62
+ //$mail->SMTPDebug = true;
63
+ if( get_option('dbem_smtp_html') ){
64
+ $mail->isHTML();
65
+ }
66
+ $mail->ClearAllRecipients();
67
+ $mail->ClearAddresses();
68
+ $mail->ClearAttachments();
69
+ $mail->CharSet = 'utf-8';
70
+ $mail->SetLanguage('en', dirname(__FILE__).'/');
71
+ $mail->PluginDir = dirname(__FILE__).'/phpmailer/';
72
+ $mail->Host = get_option('dbem_smtp_host');
73
+ $mail->port = get_option('dbem_rsvp_mail_port');
74
+ $mail->Username = get_option('dbem_smtp_username');
75
+ $mail->Password = get_option('dbem_smtp_password');
76
+ $mail->From = get_option('dbem_mail_sender_address');
77
+ $mail->FromName = get_option('dbem_mail_sender_name'); // This is the from name in the email, you can put anything you like here
78
+ $mail->Body = $body;
79
+ $mail->Subject = $subject;
80
+ if(is_array($receiver)){
81
+ foreach($receiver as $receiver_email){
82
+ $mail->AddAddress($receiver_email);
83
+ }
84
+ }else{
85
+ $mail->AddAddress($receiver);
86
+ }
87
+
88
+ //Protocols
89
+ if( get_option('dbem_rsvp_mail_send_method') == 'qmail' ){
90
+ $mail->IsQmail();
91
+ }else {
92
+ $mail->Mailer = get_option('dbem_rsvp_mail_send_method');
93
+ }
94
+ if(get_option('dbem_rsvp_mail_SMTPAuth') == '1'){
95
+ $mail->SMTPAuth = TRUE;
96
+ }
97
+ $send = $mail->Send();
98
+ if(!$send){
99
+ $this->errors[] = $mail->ErrorInfo;
100
+ }
101
+ return $send;
102
+ }else{
103
+ $this->errors = __('Please supply a valid email format.', 'dbem');
104
+ return false;
105
+ }
106
+ }
107
+
108
+ /**
109
+ * load phpmailer classes
110
+ */
111
+ function load_phpmailer(){
112
+ require_once(dirname(__FILE__) . '/phpmailer/class.phpmailer.php');
113
+ require_once(dirname(__FILE__) . '/phpmailer/class.smtp.php');
114
+ }
115
+ }
116
  ?>
classes/em-map.php DELETED
@@ -1,60 +0,0 @@
1
- <?php
2
- /**
3
- * Obtains the html required to display a google map for given location(s)
4
- *
5
- */
6
- class EM_Map extends EM_Object {
7
- /**
8
- * Shortcode for producing a google map with all the locations. Unfinished and undocumented.
9
- * @param array $atts
10
- * @return string
11
- */
12
- function get_global($atts) {
13
- //TODO Finish and document this feature, need to add balloons here
14
- if (get_option('dbem_gmap_is_active') == '1') {
15
- ob_start();
16
- $atts['em_ajax'] = true;
17
- $atts['query'] = 'GlobalMapData';
18
- $rand = substr(md5(rand().rand()),0,5);
19
- //build js array of arguments to send to event query
20
- ?>
21
- <div class='em-locations-map' id='em-locations-map-<?php echo $rand; ?>' style='width:<?php echo $atts['width']; ?>px; height:<?php echo $atts['height']; ?>px'><em><?php _e('Loading Map....', 'dbem'); ?></em></div>
22
- <div class='em-locations-map-coords' id='em-locations-map-coords-<?php echo $rand; ?>' style="display:none; visibility:hidden;"><?php echo EM_Object::json_encode($atts); ?></div>
23
- <?php
24
- return apply_filters('em_map_get_global', ob_get_clean());
25
- }else{
26
- return '';
27
- }
28
- }
29
-
30
-
31
- /**
32
- * Returns th HTML and JS required to produce a google map in for this location.
33
- * @param EM_Location $location
34
- * @return string
35
- */
36
- function get_single($args) {
37
- //TODO do some validation here of defaults
38
- //FIXME change baloon to balloon for consistent spelling
39
- $location = $args['location'];
40
- if ( get_option('dbem_gmap_is_active') && ( is_object($location) && $location->latitude != 0 && $location->longitude != 0 ) ) {
41
- $width = (isset($args['width'])) ? $args['width']:'400';
42
- $height = (isset($args['height'])) ? $args['height']:'300';
43
- ob_start();
44
- $rand = substr(md5(rand().rand()),0,5);
45
- ?>
46
- <div class='em-location-map' id='em-location-map-<?php echo $rand ?>' style='background: #CDCDCD; width: <?php echo $width ?>px; height: <?php echo $height ?>px'><?php _e('Loading Map....', 'dbem'); ?></div>
47
- <div class='em-location-map-info' id='em-location-map-info-<?php echo $rand ?>' style="display:none; visibility:hidden;"><div class="em-map-balloon" style="font-size:12px;"><div class="em-map-balloon-content" ><?php echo $location->output(get_option('dbem_location_baloon_format')); ?></div></div></div>
48
- <div class='em-location-map-coords' id='em-location-map-coords-<?php echo $rand ?>' style="display:none; visibility:hidden;">
49
- <span class="lat"><?php echo $location->latitude; ?></span>
50
- <span class="lng"><?php echo $location->longitude; ?></span>
51
- </div>
52
- <?php
53
- return ob_get_clean();
54
- }elseif( is_object($location) && $location->latitude == 0 && $location->longitude == 0 ){
55
- return '<i>'. __('Map Unavailable', 'dbem') .'</i>';
56
- }else{
57
- return '';
58
- }
59
- }
60
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/em-notices.php ADDED
@@ -0,0 +1,201 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ *
4
+ * @author marcus
5
+ *
6
+ */
7
+ class EM_Notices implements Iterator {
8
+ var $notices = array('errors'=>array(), 'infos'=>array(), 'alerts'=>array(), 'confirms'=>array());
9
+
10
+ function __construct(){
11
+ session_start();
12
+ //Grab from session
13
+ if( !empty($_SESSION['events-manager']['notices']) && is_serialized($_SESSION['events-manager']['notices']) ){
14
+ $this->notices = unserialize($_SESSION['events-manager']['notices']);
15
+ }
16
+ //Flush notices that weren't made to stay cross-requests, we can do this if initialized immediately.
17
+ foreach($this->notices as $notice_type => $notices){
18
+ foreach ($notices as $key => $notice){
19
+ if( empty($notice['static']) ){
20
+ unset($this->notices[$notice_type][$key]);
21
+ }else{
22
+ unset($this->notices[$notice_type][$key]['static']); //so it gets removed next request
23
+ }
24
+ }
25
+ }
26
+ add_action('shutdown', array(&$this,'destruct'));
27
+ add_filter('wp_redirect', array(&$this,'destruct'), 1,1);
28
+ }
29
+
30
+ function destruct($redirect = false){
31
+ //die('destructing');
32
+ $_SESSION['events-manager']['notices'] = serialize($this->notices);
33
+ return $redirect;
34
+ }
35
+
36
+ function __toString(){
37
+ $string = false;
38
+ if(count($this->notices['errors']) > 0){
39
+ $string .= "<div class='em-warning em-warning-errors error'>{$this->get_errors()}</div>";
40
+ }
41
+ if(count($this->notices['alerts']) > 0){
42
+ $string .= "<div class='em-warning em-warning-alerts updated'>{$this->get_alerts()}</div>";
43
+ }
44
+ if(count($this->notices['infos']) > 0){
45
+ $string .= "<div class='em-warning em-warning-infos updated'>{$this->get_infos()}</div>";
46
+ }
47
+ if(count($this->notices['confirms']) > 0){
48
+ $string .= "<div class='em-warning em-warning-confirms updated'>{$this->get_confirms()}</div>";
49
+ }
50
+ return ($string !== false) ? "<div class='statusnotice'>".$string."</div>" : '';
51
+ }
52
+
53
+ /* General */
54
+ function add($string, $type, $static = false){
55
+ if( is_array($string) ){
56
+ $result = true;
57
+ foreach($string as $string_item){
58
+ if( $this->add($string_item, $type, $static) === false ){ $result = false; }
59
+ }
60
+ return $result;
61
+ }
62
+ if($string != ''){
63
+ if( isset($this->notices[$type]) ){
64
+ $notice_key = 0;
65
+ foreach( $this->notices[$type] as $notice_key => $notice ){
66
+ if($string == $notice['string']){
67
+ return $notice_key;
68
+ }
69
+ }
70
+ $i = $notice_key+1;
71
+ $this->notices[$type][$i]['string'] = $string;
72
+ if( $static ){
73
+ $this->notices[$type][$i]['static'] = true;
74
+ }
75
+ return $i;
76
+ }else{
77
+ return false;
78
+ }
79
+ }else{
80
+ return false;
81
+ }
82
+ }
83
+ function remove($key, $type){
84
+ if( isset($this->notices[$type]) ){
85
+ unset($this->notices[$type][$key]);
86
+ return true;
87
+ }else{
88
+ return false;
89
+ }
90
+ }
91
+ function remove_all(){
92
+ $this->notices = array('errors'=>array(), 'infos'=>array(), 'alerts'=>array(), 'confirms'=>array());
93
+ }
94
+ function get($type){
95
+ if( isset($this->notices[$type]) ){
96
+ $string = '';
97
+ foreach ($this->notices[$type] as $key => $error){
98
+ $class = substr($type, 0, (strlen($type)-1));
99
+ $string .= "<p>{$error['string']}</p>";
100
+ /* Disabled for now, pending review due to issues in the_content firing x times e.g. in SFC
101
+ if( empty($error['static']) || $error['static'] !== true){
102
+ $this->remove($key, $type);
103
+ }
104
+ */
105
+ }
106
+ return $string;
107
+ }
108
+ return false;
109
+ }
110
+ function count($type){
111
+ if( isset($this->notices[$type]) ){
112
+ return count($this->notices[$type]);
113
+ }
114
+ return 0;
115
+ }
116
+
117
+ /* Errors */
118
+ function add_error($string, $static=false){
119
+ return $this->add($string, 'errors', $static);
120
+ }
121
+ function remove_error($key){
122
+ return $this->remove($key, 'errors');
123
+ }
124
+ function get_errors(){
125
+ return $this->get('errors');
126
+ }
127
+ function count_errors(){
128
+ return $this->count('errors');
129
+ }
130
+
131
+ /* Alerts */
132
+ function add_alert($string, $static=false){
133
+ return $this->add($string, 'alerts', $static);
134
+ }
135
+ function remove_alert($key){
136
+ return $this->remove($key, 'alerts');
137
+ }
138
+ function get_alerts(){
139
+ return $this->get('alerts');
140
+ }
141
+ function count_alerts(){
142
+ return $this->count('alerts');
143
+ }
144
+
145
+ /* Info */
146
+ function add_info($string, $static=false){
147
+ return $this->add($string, 'infos', $static);
148
+ }
149
+ function remove_info($key){
150
+ return $this->remove($key, 'infos');
151
+ }
152
+ function get_infos(){
153
+ return $this->get('infos');
154
+ }
155
+ function count_infos(){
156
+ return $this->count('infos');
157
+ }
158
+
159
+ /* Confirms */
160
+ function add_confirm($string, $static=false){
161
+ return $this->add($string, 'confirms', $static);
162
+ }
163
+ function remove_confirm($key){
164
+ return $this->remove($key, 'confirms');
165
+ }
166
+ function get_confirms(){
167
+ return $this->get('confirms');
168
+ }
169
+ function count_confirms(){
170
+ return $this->count('confirms');
171
+ }
172
+
173
+ //Iterator Implementation
174
+ function rewind(){
175
+ reset($this->bookings);
176
+ }
177
+ function current(){
178
+ $var = current($this->bookings);
179
+ return $var;
180
+ }
181
+ function key(){
182
+ $var = key($this->bookings);
183
+ return $var;
184
+ }
185
+ function next(){
186
+ $var = next($this->bookings);
187
+ return $var;
188
+ }
189
+ function valid(){
190
+ $key = key($this->bookings);
191
+ $var = ($key !== NULL && $key !== FALSE);
192
+ return $var;
193
+ }
194
+
195
+ }
196
+ function em_notices_init(){
197
+ global $EM_Notices;
198
+ $EM_Notices = new EM_Notices();
199
+ }
200
+ add_action('plugins_loaded', 'em_notices_init');
201
+ ?>
classes/em-object.php CHANGED
@@ -1,486 +1,1215 @@
1
- <?php
2
- /**
3
- * Base class which others extend on. Contains functions shared across all EM objects.
4
- *
5
- */
6
- class EM_Object {
7
-
8
- var $fields = array();
9
-
10
- /**
11
- * Takes the array and provides a clean array of search parameters, along with details
12
- * @param array $defaults
13
- * @param array $array
14
- * @return array
15
- */
16
- function get_default_search($defaults=array(), $array = array()){
17
- //TODO accept all objects as search options as well as ids (e.g. location vs. location_id, person vs. person_id)
18
- //Create minimal defaults array, merge it with supplied defaults array
19
- $super_defaults = array(
20
- 'limit' => false,
21
- 'scope' => 'future',
22
- 'order' => 'ASC', //hard-coded at end of this function
23
- 'orderby' => false,
24
- 'format' => '',
25
- 'category' => 0,
26
- 'location' => 0,
27
- 'event' => 0,
28
- 'offset'=>0,
29
- 'page'=>1,//basically, if greater than 0, calculates offset at end
30
- 'recurrence'=>0,
31
- 'recurring'=>false,
32
- 'month'=>'',
33
- 'year'=>'',
34
- 'pagination'=>false,
35
- 'array'=>false,
36
- 'owner'=>false,
37
- 'rsvp'=>false
38
- );
39
- //Return default if nothing passed
40
- if( empty($defaults) && empty($array) ){
41
- return $super_defaults;
42
- }
43
- //TODO decide on search defaults shared across all objects and then validate here
44
- $defaults = array_merge($super_defaults, $defaults);
45
-
46
- //We are still dealing with recurrence_id, location_id, category_id in some place, so we do a quick replace here just in case
47
- if( array_key_exists('recurrence_id', $array) && !array_key_exists('recurrence', $array) ) { $array['recurrence'] = $array['recurrence_id']; }
48
- if( array_key_exists('location_id', $array) && !array_key_exists('location', $array) ) { $array['location'] = $array['location_id']; }
49
- if( array_key_exists('category_id', $array) && !array_key_exists('category', $array) ) { $array['category'] = $array['category_id']; }
50
-
51
- if(is_array($array)){
52
- //Clean all id lists
53
- $array = self::clean_id_atts($array, array('location', 'event', 'category'));
54
-
55
- //OrderBy - can be a comma-seperated array of field names to order by (field names of object, not db)
56
- if( array_key_exists('orderby', $array)){
57
- if( !is_array($array['orderby']) && preg_match('/,/', $array['orderby']) ) {
58
- $array['orderby'] = explode(',', $array['orderby']);
59
- }
60
- }
61
- //TODO validate search query array
62
- //Clean the supplied array, so we only have allowed keys
63
- foreach( array_keys($array) as $key){
64
- if( !array_key_exists($key, $defaults) ) unset($array[$key]);
65
- }
66
- //return clean array
67
- $defaults = array_merge ( $defaults, $array ); //No point using WP's cleaning function, we're doing it already.
68
- }
69
- //Do some spring cleaning for known values
70
- //Month & Year - may be array or single number
71
- $month_regex = '/^[0-9]{1,2}$/';
72
- $year_regex = '/^[0-9]{4}$/';
73
- if( is_array($defaults['month']) ){
74
- $defaults['month'] = ( preg_match($month_regex, $defaults['month'][0]) && preg_match($month_regex, $defaults['month'][1]) ) ? $defaults['month']:'';
75
- }else{
76
- $defaults['month'] = preg_match($month_regex, $defaults['month']) ? $defaults['month']:'';
77
- }
78
- if( is_array($defaults['year']) ){
79
- $defaults['year'] = ( preg_match($year_regex, $defaults['year'][0]) && preg_match($year_regex, $defaults['year'][1]) ) ? $defaults['year']:'';
80
- }else{
81
- $defaults['year'] = preg_match($year_regex, $defaults['year']) ? $defaults['year']:'';
82
- }
83
- //Order - it's either ASC or DESC, so let's just validate
84
- if( !is_array($defaults['order']) && preg_match('/,/', $defaults['order']) ) {
85
- $defaults['order'] = explode(',', $defaults['order']);
86
- }elseif( !in_array($defaults['order'], array('ASC','DESC')) ){
87
- $defaults['order'] = $super_defaults['order'];
88
- }
89
- //ORDER BY, split if an array
90
- if( !is_array($defaults['orderby']) && preg_match('/,/', $defaults['orderby']) ) {
91
- $defaults['orderby'] = explode(',', $defaults['orderby']);
92
- }
93
- //TODO should we clean format of malicious code over here and run everything thorugh this?
94
- $defaults['array'] = ($defaults['array'] == true);
95
- $defaults['pagination'] = ($defaults['pagination'] == true);
96
- $defaults['limit'] = (is_numeric($defaults['limit'])) ? $defaults['limit']:$super_defaults['limit'];
97
- $defaults['offset'] = (is_numeric($defaults['offset'])) ? $defaults['offset']:$super_defaults['offset'];
98
- $defaults['recurring'] = ($defaults['recurring'] == true);
99
- $defaults['owner'] = (is_numeric($defaults['owner'])) ? $defaults['owner']:$super_defaults['owner'];
100
- //Calculate offset in event page is set
101
- if($defaults['page'] > 1){
102
- $defaults['offset'] = $defaults['limit'] * ($defaults['page']-1);
103
- }else{
104
- $defaults['page'] = ($defaults['limit'] > 0 ) ? floor($defaults['offset']/$defaults['limit']) + 1 : 1;
105
- }
106
- return apply_filters('em_object_get_default_search', $defaults, $array, $super_defaults);
107
- }
108
-
109
- /**
110
- * Builds an array of SQL query conditions based on regularly used arguments
111
- * @param array $args
112
- * @return array
113
- */
114
- function build_sql_conditions( $args = array() ){
115
- global $wpdb;
116
- $events_table = $wpdb->prefix . EM_EVENTS_TABLE;
117
- $locations_table = $wpdb->prefix . EM_LOCATIONS_TABLE;
118
-
119
- $args = apply_filters('em_object_build_sql_conditions_args',$args);
120
-
121
- //Format the arguments passed on
122
- $scope = $args['scope'];//undefined variable warnings in ZDE, could just delete this (but dont pls!)
123
- $recurring = $args['recurring'];
124
- $recurrence = $args['recurrence'];
125
- $category = $args['category'];
126
- $location = $args['location'];
127
- $rsvp = $args['rsvp'];
128
- $owner = $args['owner'];
129
- $event = $args['event'];
130
- $month = $args['month'];
131
- $year = $args['year'];
132
- $today = date('Y-m-d', current_time('timestamp'));
133
- //Create the WHERE statement
134
-
135
- //Recurrences
136
- $conditions = array();
137
- if( $recurring ){
138
- $conditions['recurring'] = "`recurrence`=1";
139
- }elseif( $recurrence > 0 ){
140
- $conditions['recurrence'] = "`recurrence_id`=$recurrence";
141
- }else{
142
- $conditions['recurring'] = "(`recurrence`!=1 OR `recurrence` IS NULL)";
143
- }
144
- //Dates - first check 'month', and 'year', and adjust scope if needed
145
- if( !($month=='' && $year=='') ){
146
- //Sort out month range, if supplied an array of array(month,month), it'll check between these two months
147
- if( self::array_is_numeric($month) ){
148
- $date_month_start = $month[0];
149
- $date_month_end = $month[1];
150
- }else{
151
- $date_month_start = $date_month_end = $month;
152
- }
153
- //Sort out year range, if supplied an array of array(year,year), it'll check between these two years
154
- if( self::array_is_numeric($year) ){
155
- $date_year_start = $year[0];
156
- $date_year_end = $year[1];
157
- }else{
158
- $date_year_start = $date_year_end = $year;
159
- }
160
- $date_start = $date_year_start."-".$date_month_start."-01";
161
- $date_end = date('Y-m-t', mktime(0,0,0,$date_month_end,1,$date_year_end));
162
- $scope = $date_start.",".$date_end; //just modify the scope here
163
- }
164
- //No date requested, so let's look at scope
165
- if ( preg_match ( "/^[0-9]{4}-[0-9]{2}-[0-9]{2},[0-9]{4}-[0-9]{2}-[0-9]{2}$/", $scope ) ) {
166
- //This is an array, let's split it up
167
- $dates = explode(',', $scope);
168
- $date_start = $dates[0];
169
- $date_end = $dates[1];
170
- $conditions['scope'] = " ( ( event_start_date <= CAST('$date_end' AS DATE) AND event_end_date >= CAST('$date_start' AS DATE) ) OR (event_start_date BETWEEN CAST('$date_start' AS DATE) AND CAST('$date_end' AS DATE)) OR (event_end_date BETWEEN CAST('$date_start' AS DATE) AND CAST('$date_end' AS DATE)) )";
171
- } elseif ( preg_match ( "/^[0-9]{4}-[0-9]{2}-[0-9]{2}$/", $scope ) ) {
172
- //Scope can also be a specific date. However, if 'day', 'month', or 'year' are set, that will take precedence
173
- $conditions['scope'] = " ( event_start_date = CAST('$scope' AS DATE) OR ( event_start_date <= CAST('$scope' AS DATE) AND event_end_date >= CAST('$scope' AS DATE) ) )";
174
- } else {
175
- if ($scope == "past"){
176
- $conditions['scope'] = " event_start_date < '$today'";
177
- }elseif ($scope == "today"){
178
- $conditions['scope'] = " ( (event_start_date = CAST('$today' AS DATE)) OR (event_start_date <= CAST('$today' AS DATE) AND event_end_date >= CAST('$today' AS DATE)) )";
179
- }elseif ($scope == "future"){
180
- $conditions['scope'] = " (event_start_date >= CAST('$today' AS DATE) OR (event_end_date >= CAST('$today' AS DATE) AND event_end_date != '0000-00-00' AND event_end_date IS NOT NULL))";
181
- }
182
- }
183
-
184
- //Filter by Location - can be object, array, or id
185
- if ( is_numeric($location) && $location > 0 ) { //Location ID takes precedence
186
- $conditions['location'] = " {$locations_table}.location_id = $location";
187
- }elseif ( self::array_is_numeric($location) ){
188
- $conditions['location'] = "( {$locations_table}.location_id = " . implode(" OR {$locations_table}.location_id = ", $location) .' )';
189
- }elseif ( is_object($location) && get_class($location)=='EM_Location' ){ //Now we deal with objects
190
- $conditions['location'] = " {$locations_table}.location_id = $location->id";
191
- }elseif ( is_array($location) && @get_class(current($location)=='EM_Location') ){ //we can accept array of ids or EM_Location objects
192
- foreach($location as $EM_Location){
193
- $location_ids[] = $EM_Location->id;
194
- }
195
- $conditions['location'] = "( {$locations_table}.location_id=". implode(" {$locations_table}.location_id=", $location_ids) ." )";
196
- }
197
-
198
- //Filter by Event - can be object, array, or id
199
- if ( is_numeric($event) && $event > 0 ) { //event ID takes precedence
200
- $conditions['event'] = " {$events_table}.event_id = $event";
201
- }elseif ( self::array_is_numeric($event) ){ //array of ids
202
- $conditions['event'] = "( {$events_table}.event_id = " . implode(" OR {$events_table}.event_id = ", $event) .' )';
203
- }elseif ( is_object($event) && get_class($event)=='EM_Event' ){ //Now we deal with objects
204
- $conditions['event'] = " {$events_table}.event_id = $event->id";
205
- }elseif ( is_array($event) && @get_class(current($event)=='EM_Event') ){ //we can accept array of ids or EM_event objects
206
- foreach($event as $EM_Event){
207
- $event_ids[] = $EM_Event->id;
208
- }
209
- $conditions['event'] = "( {$events_table}.event_id=". implode(" {$events_table}.event_id=", $event_ids) ." )";
210
- }
211
-
212
- //Add conditions for category selection
213
- //Filter by category, can be id or comma seperated ids
214
- //TODO create an exclude category option
215
- if ( is_numeric($category) && $category > 0 ){
216
- $conditions['category'] = " event_category_id = $category";
217
- }elseif( self::array_is_numeric($category) ){
218
- $conditions['category'] = "( event_category_id = ". implode(' OR event_category_id = ', $category).")";
219
- }
220
-
221
- //If we want rsvped items, we usually check the event
222
- if( $rsvp == 1 ){
223
- $conditions['rsvp'] = 'event_rsvp=1';
224
- }
225
- //Default ownership belongs to an event, child objects can just overwrite this if needed.
226
- if( is_numeric($owner) ){
227
- $conditions['owner'] = 'event_author='.$owner;
228
- }
229
- return apply_filters('em_object_build_sql_conditions', $conditions);
230
- }
231
-
232
- function build_sql_orderby( $args, $accepted_fields, $default_order = 'ASC' ){
233
- //First, ORDER BY
234
- $args = apply_filters('em_object_build_sql_orderby_args', $args);
235
- $orderby = array();
236
- if(is_array($args['orderby'])){
237
- //Clean orderby array so we only have accepted values
238
- foreach( $args['orderby'] as $key => $field ){
239
- if( array_key_exists($field, $accepted_fields) ){
240
- $orderby[] = $accepted_fields[$field];
241
- }elseif( in_array($field,$accepted_fields) ){
242
- $orderby[] = $field;
243
- }else{
244
- unset($args['orderby'][$key]);
245
- }
246
- }
247
- }elseif( $args['orderby'] != '' && array_key_exists($args['orderby'], $accepted_fields) ){
248
- $orderby[] = $accepted_fields[$args['orderby']];
249
- }elseif( $args['orderby'] != '' && in_array($args['orderby'], $accepted_fields) ){
250
- $orderby[] = $args['orderby'];
251
- }
252
- //ORDER
253
- //If order is an array, we'll go through the orderby array and match the order values (in order of array) with orderby values
254
- //If orders don't match up, or it's not ASC/DESC, the default events search in EM settings/options page will be used.
255
- foreach($orderby as $i => $field){
256
- $orderby[$i] .= ' ';
257
- if(is_array($args['order'])){
258
- if( in_array($args['order'][$i], array('ASC','DESC')) ){
259
- $orderby[$i] .= $args['order'][$i];
260
- }else{
261
- $orderby[$i] .= $default_order;
262
- }
263
- }else{
264
- $orderby[$i] .= ( in_array($args['order'], array('ASC','DESC')) ) ? $args['order'] : $default_order;
265
- }
266
- }
267
- return apply_filters('em_object_build_sql_orderby', $orderby);
268
- }
269
-
270
- /**
271
- * Save an array into this class.
272
- * If you provide a record from the database table corresponding to this class type it will add the data to this object.
273
- * @param array $array
274
- * @return null
275
- */
276
- function to_object( $array = array(), $addslashes = false ){
277
- //Save core data
278
- if( is_array($array) ){
279
- $array = apply_filters('em_to_object', $array);
280
- foreach ( $this->fields as $key => $val ) {
281
- if(array_key_exists($key, $array)){
282
- if( !is_object($array[$key]) && !is_array($array[$key]) ){
283
- $array[$key] = ($addslashes) ? stripslashes($array[$key]):$array[$key];
284
- }
285
- $this->$val['name'] = $array[$key];
286
- }
287
- }
288
- }
289
- }
290
-
291
- /**
292
- * Returns this object in the form of an array, useful for saving directly into a database table.
293
- * @return array
294
- */
295
- function to_array(){
296
- $array = array();
297
- foreach ( $this->fields as $key => $val ) {
298
- $array[$key] = $this->$val['name'];
299
- }
300
- return apply_filters('em_to_array', $array);
301
- }
302
-
303
-
304
- /**
305
- * Function to retreive wpdb types for all fields, or if you supply an assoc array with field names as keys it'll return an equivalent array of wpdb types
306
- * @param array $array
307
- * @return array:
308
- */
309
- function get_types($array = array()){
310
- $types = array();
311
- if( count($array)>0 ){
312
- //So we look at assoc array and find equivalents
313
- foreach ($array as $key => $val){
314
- $types[] = $this->fields[$key]['type'];
315
- }
316
- }else{
317
- //Blank array, let's assume we're getting a standard list of types
318
- foreach ($this->fields as $field){
319
- $types[] = $field['type'];
320
- }
321
- }
322
- return apply_filters('em_object_get_types', $types, $this, $array);
323
- }
324
-
325
- function get_fields( $inverted_array=false ){
326
- if( is_array($this->fields) ){
327
- $return = array();
328
- foreach($this->fields as $fieldName => $fieldArray){
329
- if($inverted_array){
330
- $return[$fieldArray['name']] = $fieldName;
331
- }else{
332
- $return[$fieldName] = $fieldArray['name'];
333
- }
334
- }
335
- return apply_filters('em_object_get_fields', $return, $this, $inverted_array);
336
- }
337
- return apply_filters('em_object_get_fields', array(), $this, $inverted_array);
338
- }
339
-
340
- /**
341
- * Sanitize text before inserting into database
342
- * @param string $value
343
- * @return string
344
- */
345
- function sanitize( $value ) {
346
- if( get_magic_quotes_gpc() )
347
- $value = stripslashes( $value );
348
-
349
- //check if this function exists
350
- if( function_exists( "mysql_real_escape_string" ) ) {
351
- $value = mysql_real_escape_string( $value );
352
- //for PHP version < 4.3.0 use addslashes
353
- } else {
354
- $value = addslashes( $value );
355
- }
356
- return apply_filters('em_object_sanitize', $value);
357
- }
358
-
359
- /**
360
- * Cleans arrays that contain id lists. Takes an array of items and will clean the keys passed in second argument so that if they keep numbers, explode comma-seperated numbers, and unsets the key if there's any other value
361
- * @param array $array
362
- * @param array $id_atts
363
- */
364
- function clean_id_atts( $array = array(), $id_atts = array() ){
365
- if( is_array($array) && is_array($id_atts) ){
366
- foreach( $array as $key => $string ){
367
- if( in_array($key, $id_atts) ){
368
- //This is in the list of atts we want cleaned
369
- if( is_numeric($string) ){
370
- $array[$key] = (int) $string;
371
- }elseif( self::array_is_numeric($string) ){
372
- $array[$key] = $string;
373
- }elseif( preg_match('/^([0-9],?)+$/', $string) ){
374
- $array[$key] = explode(',', $string);
375
- }else{
376
- //No format we accept
377
- unset($array[$key]);
378
- }
379
- }
380
- }
381
- }
382
- return $array;
383
- }
384
-
385
- /**
386
- * Send an email and log errors in this object
387
- * @param string $subject
388
- * @param string $body
389
- * @param string $email
390
- * @return string
391
- */
392
- function email_send($subject, $body, $email){
393
- global $EM_Mailer;
394
- if( !$EM_Mailer->send($subject,$body,$email) ){
395
- foreach($EM_Mailer->errors as $error){
396
- $this->errors[] = $error;
397
- }
398
- return false;
399
- }
400
- return true;
401
- }
402
-
403
- /**
404
- * Will return true if this is a simple (non-assoc) numeric array, meaning it has at one or more numeric entries and nothing else
405
- * @param mixed $array
406
- * @return boolean
407
- */
408
- function array_is_numeric($array){
409
- $results = array();
410
- if(is_array($array)){
411
- foreach($array as $key => $item){
412
- $results[] = (is_numeric($item)&&is_numeric($key));
413
- }
414
- }
415
- return (!in_array(false, $results) && count($results) > 0);
416
- }
417
-
418
- /**
419
- * Converts an array to JSON format, useful for outputting data for AJAX calls. Uses a PHP4 fallback function, given it doesn't support json_encode().
420
- * @param array $array
421
- * @return string
422
- */
423
- function json_encode($array){
424
- if( function_exists("json_encode") ){
425
- $return = json_encode($array);
426
- }else{
427
- $return = self::array_to_json($array);
428
- }
429
- if( isset($_GET['callback']) ){
430
- $return = $_GET['callback']."($return)";
431
- }
432
- return apply_filters('em_object_json_encode', $return, $array);
433
- }
434
-
435
- /**
436
- * Compatible json encoder function for PHP4
437
- * @param array $array
438
- * @return string
439
- */
440
- function array_to_json($array){
441
- //PHP4 Comapatability - This encodes the array into JSON. Thanks go to Andy - http://www.php.net/manual/en/function.json-encode.php#89908
442
- if( !is_array( $array ) ){
443
- $array = array();
444
- }
445
- $associative = count( array_diff( array_keys($array), array_keys( array_keys( $array )) ));
446
- if( $associative ){
447
- $construct = array();
448
- foreach( $array as $key => $value ){
449
- // We first copy each key/value pair into a staging array,
450
- // formatting each key and value properly as we go.
451
- // Format the key:
452
- if( is_numeric($key) ){
453
- $key = "key_$key";
454
- }
455
- $key = "'".addslashes($key)."'";
456
- // Format the value:
457
- if( is_array( $value )){
458
- $value = $this->array_to_json( $value );
459
- }else if( is_bool($value) ) {
460
- $value = ($value) ? "true" : "false";
461
- }else if( !is_numeric( $value ) || is_string( $value ) ){
462
- $value = "'".addslashes($value)."'";
463
- }
464
- // Add to staging array:
465
- $construct[] = "$key: $value";
466
- }
467
- // Then we collapse the staging array into the JSON form:
468
- $result = "{ " . implode( ", ", $construct ) . " }";
469
- } else { // If the array is a vector (not associative):
470
- $construct = array();
471
- foreach( $array as $value ){
472
- // Format the value:
473
- if( is_array( $value )){
474
- $value = $this->array_to_json( $value );
475
- } else if( !is_numeric( $value ) || is_string( $value ) ){
476
- $value = "'".addslashes($value)."'";
477
- }
478
- // Add to staging array:
479
- $construct[] = $value;
480
- }
481
- // Then we collapse the staging array into the JSON form:
482
- $result = "[ " . implode( ", ", $construct ) . " ]";
483
- }
484
- return $result;
485
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
486
  }
1
+ <?php
2
+ /**
3
+ * Base class which others extend on. Contains functions shared across all EM objects.
4
+ *
5
+ */
6
+ class EM_Object {
7
+ var $fields = array();
8
+ var $required_fields = array();
9
+ var $feedback_message = "";
10
+ var $errors = array();
11
+ var $mime_types = array(1 => 'gif', 2 => 'jpg', 3 => 'png');
12
+
13
+ /**
14
+ * Takes the array and provides a clean array of search parameters, along with details
15
+ * @param array $defaults
16
+ * @param array $array
17
+ * @return array
18
+ */
19
+ function get_default_search($defaults=array(), $array = array()){
20
+ global $wpdb;
21
+ //TODO accept all objects as search options as well as ids (e.g. location vs. location_id, person vs. person_id)
22
+ //Create minimal defaults array, merge it with supplied defaults array
23
+ $super_defaults = array(
24
+ 'limit' => false,
25
+ 'scope' => 'future',
26
+ 'order' => 'ASC', //hard-coded at end of this function
27
+ 'orderby' => false,
28
+ 'format' => '',
29
+ 'category' => 0,
30
+ 'tag' => 0,
31
+ 'location' => 0,
32
+ 'event' => 0,
33
+ 'offset'=>0,
34
+ 'page'=>1,//basically, if greater than 0, calculates offset at end
35
+ 'recurrence'=>0,
36
+ 'recurring'=>false,
37
+ 'month'=>'',
38
+ 'year'=>'',
39
+ 'pagination'=>false,
40
+ 'array'=>false,
41
+ 'owner'=>false,
42
+ 'rsvp'=>false, //depreciated for bookings
43
+ 'bookings'=>false,
44
+ 'search'=>false
45
+ );
46
+ //Return default if nothing passed
47
+ if( empty($defaults) && empty($array) ){
48
+ return $super_defaults;
49
+ }
50
+ //TODO decide on search defaults shared across all objects and then validate here
51
+ $defaults = array_merge($super_defaults, $defaults);
52
+
53
+ if(is_array($array)){
54
+ //We are still dealing with recurrence_id, location_id, category_id in some place, so we do a quick replace here just in case
55
+ if( array_key_exists('recurrence_id', $array) && !array_key_exists('recurrence', $array) ) { $array['recurrence'] = $array['recurrence_id']; }
56
+ if( array_key_exists('location_id', $array) && !array_key_exists('location', $array) ) { $array['location'] = $array['location_id']; }
57
+ if( array_key_exists('category_id', $array) && !array_key_exists('category', $array) ) { $array['category'] = $array['category_id']; }
58
+
59
+ //Clean all id lists
60
+ $array = self::clean_id_atts($array, array('location', 'event', 'category', 'post_id'));
61
+ if( !empty($array['tag']) && strstr(',', $array['tag']) !== false ){
62
+ $array['tag'] = explode(',',$array['tag']);
63
+ }
64
+
65
+ //OrderBy - can be a comma-seperated array of field names to order by (field names of object, not db)
66
+ if( array_key_exists('orderby', $array)){
67
+ if( !is_array($array['orderby']) && preg_match('/,/', $array['orderby']) ) {
68
+ $array['orderby'] = explode(',', $array['orderby']);
69
+ }
70
+ }
71
+ //TODO validate search query array
72
+ //Clean the supplied array, so we only have allowed keys
73
+ foreach( array_keys($array) as $key){
74
+ if( !array_key_exists($key, $defaults) ) unset($array[$key]);
75
+ }
76
+ //return clean array
77
+ $defaults = array_merge ( $defaults, $array ); //No point using WP's cleaning function, we're doing it already.
78
+ }
79
+
80
+ //Do some spring cleaning for known values
81
+ //Month & Year - may be array or single number
82
+ $month_regex = '/^[0-9]{1,2}$/';
83
+ $year_regex = '/^[0-9]{4}$/';
84
+ if( is_array($defaults['month']) ){
85
+ $defaults['month'] = ( preg_match($month_regex, $defaults['month'][0]) && preg_match($month_regex, $defaults['month'][1]) ) ? $defaults['month']:'';
86
+ }else{
87
+ $defaults['month'] = preg_match($month_regex, $defaults['month']) ? $defaults['month']:'';
88
+ }
89
+ if( is_array($defaults['year']) ){
90
+ $defaults['year'] = ( preg_match($year_regex, $defaults['year'][0]) && preg_match($year_regex, $defaults['year'][1]) ) ? $defaults['year']:'';
91
+ }else{
92
+ $defaults['year'] = preg_match($year_regex, $defaults['year']) ? $defaults['year']:'';
93
+ }
94
+ //Deal with scope and date searches
95
+ if ( !is_array($defaults['scope']) && preg_match ( "/^([0-9]{4}-[0-9]{2}-[0-9]{2})?,([0-9]{4}-[0-9]{2}-[0-9]{2})?$/", $defaults['scope'] ) ) {
96
+ //This is to become an array, so let's split it up
97
+ $defaults['scope'] = explode(',', $defaults['scope']);
98
+ }
99
+ if( is_array($defaults['scope']) ){
100
+ //looking for a date range here, so we'll verify the dates validate, if not get the default.
101
+ if ( !preg_match("/^[0-9]{4}-[0-9]{2}-[0-9]{2}$/", $defaults['scope'][0]) ){
102
+ $defaults['scope'][0] = '';
103
+ }
104
+ if( !preg_match("/^[0-9]{4}-[0-9]{2}-[0-9]{2}$/", $defaults['scope'][1]) ) {
105
+ $defaults['scope'][1] = '';
106
+ }
107
+ if( empty($defaults['scope'][0]) && empty($defaults['scope'][1]) ){
108
+ $defaults['scope'] = $super_defaults['scope'];
109
+ }
110
+ }
111
+ //Order - it's either ASC or DESC, so let's just validate
112
+ if( !is_array($defaults['order']) && preg_match('/,/', $defaults['order']) ) {
113
+ $defaults['order'] = explode(',', $defaults['order']);
114
+ }elseif( !in_array($defaults['order'], array('ASC','DESC')) ){
115
+ $defaults['order'] = $super_defaults['order'];
116
+ }
117
+ //ORDER BY, split if an array
118
+ if( !is_array($defaults['orderby']) && preg_match('/,/', $defaults['orderby']) ) {
119
+ $defaults['orderby'] = explode(',', $defaults['orderby']);
120
+ }
121
+ //TODO should we clean format of malicious code over here and run everything thorugh this?
122
+ $defaults['array'] = ($defaults['array'] == true);
123
+ $defaults['pagination'] = ($defaults['pagination'] == true);
124
+ $defaults['limit'] = (is_numeric($defaults['limit'])) ? $defaults['limit']:$super_defaults['limit'];
125
+ $defaults['offset'] = (is_numeric($defaults['offset'])) ? $defaults['offset']:$super_defaults['offset'];
126
+ $defaults['recurring'] = ($defaults['recurring'] == true);
127
+ $defaults['owner'] = (is_numeric($defaults['owner']) || $defaults['owner'] == 'me') ? $defaults['owner']:$super_defaults['owner'];
128
+ $defaults['search'] = ($defaults['search']) ? trim($wpdb->escape(like_escape($defaults['search']))):false;
129
+ //Calculate offset if event page is set
130
+ if($defaults['page'] > 1){
131
+ $defaults['offset'] = $defaults['limit'] * ($defaults['page']-1);
132
+ }else{
133
+ $defaults['page'] = ($defaults['limit'] > 0 ) ? floor($defaults['offset']/$defaults['limit']) + 1 : 1;
134
+ }
135
+ return apply_filters('em_object_get_default_search', $defaults, $array, $super_defaults);
136
+ }
137
+
138
+ /**
139
+ * Builds an array of SQL query conditions based on regularly used arguments
140
+ * @param array $args
141
+ * @return array
142
+ */
143
+ function build_sql_conditions( $args = array() ){
144
+ global $wpdb;
145
+ $events_table = EM_EVENTS_TABLE;
146
+ $locations_table = EM_LOCATIONS_TABLE;
147
+
148
+ $args = apply_filters('em_object_build_sql_conditions_args',$args);
149
+
150
+ //Format the arguments passed on
151
+ $scope = $args['scope'];//undefined variable warnings in ZDE, could just delete this (but dont pls!)
152
+ $recurring = $args['recurring'];
153
+ $recurrence = $args['recurrence'];
154
+ $category = $args['category'];
155
+ $tag = $args['tag'];
156
+ $location = $args['location'];
157
+ $bookings = $args['rsvp'];
158
+ $bookings = !empty($args['bookings']) ? $args['bookings']:$bookings;
159
+ $owner = $args['owner'];
160
+ $event = $args['event'];
161
+ $month = $args['month'];
162
+ $year = $args['year'];
163
+ $today = date('Y-m-d', current_time('timestamp'));
164
+ //Create the WHERE statement
165
+
166
+ //Recurrences
167
+ $conditions = array();
168
+ if( $recurring ){
169
+ $conditions['recurring'] = "`recurrence`=1";
170
+ }elseif( $recurrence > 0 ){
171
+ $conditions['recurrence'] = "`recurrence_id`=$recurrence";
172
+ }else{
173
+ $conditions['recurring'] = "(`recurrence`!=1 OR `recurrence` IS NULL)";
174
+ }
175
+ //Dates - first check 'month', and 'year', and adjust scope if needed
176
+ if( !($month=='' && $year=='') ){
177
+ //Sort out month range, if supplied an array of array(month,month), it'll check between these two months
178
+ if( self::array_is_numeric($month) ){
179
+ $date_month_start = $month[0];
180
+ $date_month_end = $month[1];
181
+ }else{
182
+ if( !empty($month) ){
183
+ $date_month_start = $date_month_end = $month;
184
+ }else{
185
+ $date_month_start = 1;
186
+ $date_month_end = 12;
187
+ }
188
+ }
189
+ //Sort out year range, if supplied an array of array(year,year), it'll check between these two years
190
+ if( self::array_is_numeric($year) ){
191
+ $date_year_start = $year[0];
192
+ $date_year_end = $year[1];
193
+ }else{
194
+ $date_year_start = $date_year_end = $year;
195
+ }
196
+ $date_start = $date_year_start."-".$date_month_start."-01";
197
+ $date_end = date('Y-m-t', mktime(0,0,0,$date_month_end,1,$date_year_end));
198
+ $scope = array($date_start,$date_end); //just modify the scope here
199
+ }
200
+ //No date requested, so let's look at scope
201
+ if ( is_array($scope) ) {
202
+ //This is an array, let's split it up
203
+ $date_start = $scope[0];
204
+ $date_end = $scope[1];
205
+ if( !empty($date_start) && empty($date_end) ){
206
+ //do a from till infinity
207
+ $conditions['scope'] = " event_start_date >= CAST('$date_start' AS DATE)";
208
+ }elseif( empty($date_start) && !empty($date_end) ){
209
+ //do past till $date_end
210
+ if( get_option('dbem_events_current_are_past') ){
211
+ $conditions['scope'] = " event_start_date <= CAST('$date_end' AS DATE)";
212
+ }else{
213
+ $conditions['scope'] = " event_end_date <= CAST('$date_end' AS DATE)";
214
+ }
215
+ }else{
216
+ //date range
217
+ //$conditions['scope'] = " ( ( event_start_date <= CAST('$date_end' AS DATE) AND event_end_date >= CAST('$date_start' AS DATE) ) OR (event_start_date BETWEEN CAST('$date_start' AS DATE) AND CAST('$date_end' AS DATE)) OR (event_end_date BETWEEN CAST('$date_start' AS DATE) AND CAST('$date_end' AS DATE)) )";
218
+ $conditions['scope'] = "( (event_start_date BETWEEN CAST('$date_start' AS DATE) AND CAST('$date_end' AS DATE)) OR (event_end_date BETWEEN CAST('$date_start' AS DATE) AND CAST('$date_end' AS DATE)) )";
219
+ }
220
+ } elseif ( preg_match ( "/^[0-9]{4}-[0-9]{2}-[0-9]{2}$/", $scope ) ) {
221
+ //Scope can also be a specific date. However, if 'day', 'month', or 'year' are set, that will take precedence
222
+ $conditions['scope'] = " ( event_start_date = CAST('$scope' AS DATE) OR ( event_start_date <= CAST('$scope' AS DATE) AND event_end_date >= CAST('$scope' AS DATE) ) )";
223
+ } else {
224
+ if ($scope == "past"){
225
+ if( get_option('dbem_events_current_are_past') ){
226
+ $conditions['scope'] = " event_start_date < '$today'";
227
+ }else{
228
+ $conditions['scope'] = " event_end_date < '$today'";
229
+ }
230
+ }elseif ($scope == "today"){
231
+ $conditions['scope'] = " (event_start_date = CAST('$today' AS DATE))";
232
+ if( !get_option('dbem_events_current_are_past') ){
233
+ $conditions['scope'] .= " OR (event_start_date <= CAST('$today' AS DATE) AND event_end_date >= CAST('$today' AS DATE))";
234
+ }
235
+ }elseif ($scope == "tomorrow"){
236
+ $tomorrow = date('Y-m-d',current_time('timestamp')+60*60*24);
237
+ $conditions['scope'] = "(event_start_date = CAST('$tomorrow' AS DATE))";
238
+ if( !get_option('dbem_events_current_are_past') ){
239
+ $conditions['scope'] .= " OR (event_start_date <= CAST('$tomorrow' AS DATE) AND event_end_date >= CAST('$tomorrow' AS DATE))";
240
+ }
241
+ }elseif ($scope == "month"){
242
+ $start_month = date('Y-m-d',current_time('timestamp'));
243
+ $end_month = date('Y-m-t',current_time('timestamp'));
244
+ $conditions['scope'] = " (event_start_date BETWEEN CAST('$start_month' AS DATE) AND CAST('$end_month' AS DATE))";
245
+ if( !get_option('dbem_events_current_are_past') ){
246
+ $conditions['scope'] .= " OR (event_start_date < CAST('$start_month' AS DATE) AND event_end_date >= CAST('$start_month' AS DATE))";
247
+ }
248
+ }elseif ($scope == "next-month"){
249
+ $start_month_timestamp = strtotime('+1 month', current_time('timestamp')); //get the end of this month + 1 day
250
+ $start_month = date('Y-m-1',$start_month_timestamp);
251
+ $end_month = date('Y-m-t',$start_month_timestamp);
252
+ $conditions['scope'] = " (event_start_date BETWEEN CAST('$start_month' AS DATE) AND CAST('$end_month' AS DATE))";
253
+ if( !get_option('dbem_events_current_are_past') ){
254
+ $conditions['scope'] .= " OR (event_start_date < CAST('$start_month' AS DATE) AND event_end_date >= CAST('$start_month' AS DATE))";
255
+ }
256
+ }elseif( preg_match('/([0-9]+)\-months/',$scope,$matches) ){ // next x months means this month (what's left of it), plus the following x months until the end of that month.
257
+ $months_to_add = $matches[1];
258
+ $start_month = date('Y-m-d',current_time('timestamp'));
259
+ $end_month = date('Y-m-t',strtotime("+$months_to_add month", current_time('timestamp')));
260
+ $conditions['scope'] = " (event_start_date BETWEEN CAST('$start_month' AS DATE) AND CAST('$end_month' AS DATE))";
261
+ if( !get_option('dbem_events_current_are_past') ){
262
+ $conditions['scope'] .= " OR (event_start_date < CAST('$start_month' AS DATE) AND event_end_date >= CAST('$start_month' AS DATE))";
263
+ }
264
+ }elseif ($scope == "future"){
265
+ $conditions['scope'] = " event_start_date >= CAST('$today' AS DATE)";
266
+ if( !get_option('dbem_events_current_are_past') ){
267
+ $conditions['scope'] .= " OR (event_end_date >= CAST('$today' AS DATE) AND event_end_date != '0000-00-00' AND event_end_date IS NOT NULL)";
268
+ }
269
+ }
270
+ if( !empty($conditions['scope']) ){
271
+ $conditions['scope'] = '('.$conditions['scope'].')';
272
+ }
273
+ }
274
+
275
+ //Filter by Location - can be object, array, or id
276
+ if ( is_numeric($location) && $location > 0 ) { //Location ID takes precedence
277
+ $conditions['location'] = " {$locations_table}.location_id = $location";
278
+ }elseif ( self::array_is_numeric($location) ){
279
+ $conditions['location'] = "( {$locations_table}.location_id = " . implode(" OR {$locations_table}.location_id = ", $location) .' )';
280
+ }elseif ( is_object($location) && get_class($location)=='EM_Location' ){ //Now we deal with objects
281
+ $conditions['location'] = " {$locations_table}.location_id = $location->location_id";
282
+ }elseif ( is_array($location) && @get_class(current($location)=='EM_Location') ){ //we can accept array of ids or EM_Location objects
283
+ foreach($location as $EM_Location){
284
+ $location_ids[] = $EM_Location->location_id;
285
+ }
286
+ $conditions['location'] = "( {$locations_table}.location_id=". implode(" {$locations_table}.location_id=", $location_ids) ." )";
287
+ }
288
+
289
+ //Filter by Event - can be object, array, or id
290
+ if ( is_numeric($event) && $event > 0 ) { //event ID takes precedence
291
+ $conditions['event'] = " {$events_table}.event_id = $event";
292
+ }elseif ( self::array_is_numeric($event) ){ //array of ids
293
+ $conditions['event'] = "( {$events_table}.event_id = " . implode(" OR {$events_table}.event_id = ", $event) .' )';
294
+ }elseif ( is_object($event) && get_class($event)=='EM_Event' ){ //Now we deal with objects
295
+ $conditions['event'] = " {$events_table}.event_id = $event->event_id";
296
+ }elseif ( is_array($event) && @get_class(current($event)=='EM_Event') ){ //we can accept array of ids or EM_event objects
297
+ foreach($event as $EM_Event){
298
+ $event_ids[] = $EM_Event->event_id;
299
+ }
300
+ $conditions['event'] = "( {$events_table}.event_id=". implode(" {$events_table}.event_id=", $event_ids) ." )";
301
+ }
302
+ //Location specific filters
303
+ //country lookup
304
+ if( !empty($args['country']) ){
305
+ $countries = em_get_countries();
306
+ //we can accept country codes or names
307
+ if( in_array($args['country'], $countries) ){
308
+ //we have a country name,
309
+ $conditions['country'] = "location_country='".array_search($args['country'])."'";
310
+ }elseif( array_key_exists($args['country'], $countries) ){
311
+ //we have a country code
312
+ $conditions['country'] = "location_country='".$args['country']."'";
313
+ }
314
+ }
315
+ //state lookup
316
+ if( !empty($args['state']) ){
317
+ $conditions['state'] = $wpdb->prepare('location_state=%s', $args['state']);
318
+ }
319
+ //state lookup
320
+ if( !empty($args['town']) ){
321
+ $conditions['town'] = $wpdb->prepare('location_town=%s', $args['town']);
322
+ }
323
+ //region lookup
324
+ if( !empty($args['region']) ){
325
+ $conditions['region'] = $wpdb->prepare('location_region=%s', $args['region']);
326
+ }
327
+ //Add conditions for category selection
328
+ //Filter by category, can be id or comma seperated ids
329
+ $not = '';
330
+ if ( is_numeric($category) ){
331
+ $not = ( $category < 0 ) ? "NOT":'';
332
+ //get the term id directly
333
+ $term = new EM_Category(absint($category));
334
+ if( !empty($term->term_id) ){
335
+ if( EM_MS_GLOBAL ){
336
+ $conditions['category'] = " ".EM_EVENTS_TABLE.".event_id $not IN ( SELECT object_id FROM ".EM_META_TABLE." WHERE meta_value={$term->term_id} AND meta_key='event-category' ) ";
337
+ }else{
338
+ $conditions['category'] = " ".EM_EVENTS_TABLE.".post_id $not IN ( SELECT object_id FROM ".$wpdb->term_relationships." WHERE term_taxonomy_id={$term->term_taxonomy_id} ) ";
339
+ }
340
+ }
341
+ }elseif( self::array_is_numeric($category) ){
342
+ $term_ids = array();
343
+ $term_not_ids = array();
344
+ foreach($category as $category_id){
345
+ $term = new EM_Category(absint($category_id));
346
+ if( !empty($term->term_taxonomy_id) ){
347
+ if( $category_id > 0 ){
348
+ $term_ids[] = $term->term_taxonomy_id;
349
+ }else{
350
+ $term_not_ids[] = $term->term_taxonomy_id;
351
+ }
352
+ }
353
+ }
354
+ if( count($term_ids) > 0 || count($term_not_ids) > 0 ){
355
+ if( EM_MS_GLOBAL ){
356
+ $cat_conds = array();
357
+ if( count($term_ids) > 0 ){
358
+ $cat_conds[] = EM_EVENTS_TABLE.".event_id IN ( SELECT object_id FROM ".EM_META_TABLE." WHERE meta_value IN (".implode(',',$term_ids).") AND meta_name='event-category' )";
359
+ }
360
+ if( count($term_not_ids) > 0 ){
361
+ $cat_conds[] = EM_EVENTS_TABLE.".event_id NOT IN ( SELECT object_id FROM ".EM_META_TABLE." WHERE meta_value IN (".implode(',',$term_not_ids).") AND meta_name='event-category' )";
362
+ }
363
+ $conditions['category'] = '('. implode(' || ', $cat_conds) .')';
364
+ }else{
365
+ $cat_conds = array();
366
+ if( count($term_ids) > 0 ){
367
+ $cat_conds[] = EM_EVENTS_TABLE.".post_id IN ( SELECT object_id FROM ".$wpdb->term_relationships." WHERE term_taxonomy_id IN (".implode(',',$term_ids).") )";
368
+ }
369
+ if( count($term_not_ids) > 0 ){
370
+ $cat_conds[] = EM_EVENTS_TABLE.".post_id NOT IN ( SELECT object_id FROM ".$wpdb->term_relationships." WHERE term_taxonomy_id IN (".implode(',',$term_not_ids).") )";
371
+ }
372
+ $conditions['category'] = '('. implode(' || ', $cat_conds) .')';
373
+ }
374
+ }
375
+ }
376
+ //Add conditions for tags
377
+ //Filter by tag, can be id or comma seperated ids
378
+ if ( !empty($tag) && !is_array($tag) ){
379
+ //get the term id directly
380
+ $term = new EM_Tag($tag);
381
+ if( !empty($term->term_id) ){
382
+ $conditions['tag'] = " ".EM_EVENTS_TABLE.".post_id IN ( SELECT object_id FROM ".$wpdb->term_relationships." WHERE term_taxonomy_id={$term->term_taxonomy_id} ) ";
383
+ }
384
+ }elseif( is_array($tag) ){
385
+ $term_ids = array();
386
+ foreach($tag as $tag_id){
387
+ $term = new EM_Tag($tag_id);
388
+ if( !empty($term->term_id) ){
389
+ $term_ids[] = $term->term_taxonomy_id;
390
+ }
391
+ }
392
+ if( count($term_ids) > 0 ){
393
+ $conditions['tag'] = " ".EM_EVENTS_TABLE.".post_id IN ( SELECT object_id FROM ".$wpdb->term_relationships." WHERE term_taxonomy_id IN (".implode(',',$term_ids).") ) ";
394
+ }
395
+ }
396
+
397
+ //If we want rsvped items, we usually check the event
398
+ if( $bookings == 1 ){
399
+ $conditions['bookings'] = 'event_rsvp=1';
400
+ }
401
+ //Default ownership belongs to an event, child objects can just overwrite this if needed.
402
+ if( is_numeric($owner) ){
403
+ $conditions['owner'] = 'event_owner='.$owner;
404
+ }elseif( $owner == 'me' && is_user_logged_in() ){
405
+ $conditions['owner'] = 'event_owner='.get_current_user_id();
406
+ }
407
+ return apply_filters('em_object_build_sql_conditions', $conditions);
408
+ }
409
+
410
+ /**
411
+ * WORK IN PROGRESS
412
+ * Builds an array of SQL query conditions based on regularly used arguments
413
+ * @param array $args
414
+ * @return array
415
+ */
416
+ function build_wpquery_conditions( $args = array(), $wp_query ){
417
+ global $wpdb;
418
+
419
+ $args = apply_filters('em_object_build_sql_conditions_args',$args);
420
+
421
+ //Format the arguments passed on
422
+ $scope = $args['scope'];//undefined variable warnings in ZDE, could just delete this (but dont pls!)
423
+ $recurring = $args['recurring'];
424
+ $recurrence = $args['recurrence'];
425
+ $category = $args['category'];
426
+ $tag = $args['tag'];
427
+ $location = $args['location'];
428
+ $bookings = $args['rsvp'];
429
+ $bookings = !empty($args['bookings']) ? $args['bookings']:$bookings;
430
+ $owner = $args['owner'];
431
+ $event = $args['event'];
432
+ $month = $args['month'];
433
+ $year = $args['year'];
434
+ $today = date('Y-m-d', current_time('timestamp'));
435
+ //Create the WHERE statement
436
+
437
+ //Recurrences
438
+ $query = array();
439
+ if( $recurrence > 0 ){
440
+ $query[] = array( 'key' => '_recurrence_id', 'value' => $recurrence, 'compare' => '=' );
441
+ }
442
+ //Dates - first check 'month', and 'year', and adjust scope if needed
443
+ if( !($month=='' && $year=='') ){
444
+ //Sort out month range, if supplied an array of array(month,month), it'll check between these two months
445
+ if( self::array_is_numeric($month) ){
446
+ $date_month_start = $month[0];
447
+ $date_month_end = $month[1];
448
+ }else{
449
+ if( !empty($month) ){
450
+ $date_month_start = $date_month_end = $month;
451
+ }else{
452
+ $date_month_start = 1;
453
+ $date_month_end = 12;
454
+ }
455
+ }
456
+ //Sort out year range, if supplied an array of array(year,year), it'll check between these two years
457
+ if( self::array_is_numeric($year) ){
458
+ $date_year_start = $year[0];
459
+ $date_year_end = $year[1];
460
+ }else{
461
+ $date_year_start = $date_year_end = $year;
462
+ }
463
+ $date_start = $date_year_start."-".$date_month_start."-01";
464
+ $date_end = date('Y-m-t', mktime(0,0,0,$date_month_end,1,$date_year_end));
465
+ $scope = array($date_start,$date_end); //just modify the scope here
466
+ }
467
+ //No date requested, so let's look at scope
468
+ $time = current_time('timestamp');
469
+ if ( preg_match ( "/^[0-9]{4}-[0-9]{2}-[0-9]{2}$/", $scope ) ) {
470
+ $today = strtotime($scope);
471
+ $tomorrow = $today + 60*60*24-1;
472
+ if( get_option('dbem_events_current_are_past') && $wp_query->query_vars['post_type'] != 'event-recurring' ){
473
+ $query[] = array( 'key' => '_start_ts', 'value' => array($today,$tomorrow), 'compare' => 'BETWEEN' );
474
+ }else{
475
+ $query[] = array( 'key' => '_start_ts', 'value' => $tomorrow, 'compare' => '<=' );
476
+ $query[] = array( 'key' => '_end_ts', 'value' => $today, 'compare' => '>=' );
477
+ }
478
+ }elseif ( is_array($scope) || preg_match( "/^[0-9]{4}-[0-9]{2}-[0-9]{2},[0-9]{4}-[0-9]{2}-[0-9]{2}$/", $scope ) ) {
479
+ if( !is_array($scope) ) $scope = explode(',',$scope);
480
+ if( !empty($scope[0]) ){
481
+ $start = strtotime(date('Y-m-d',$scope[0]));
482
+ $end = !empty($scope[1]) ? strtotime(date('Y-m-t',$scope[1])):$start;
483
+ if( get_option('dbem_events_current_are_past') && $wp_query->query_vars['post_type'] != 'event-recurring' ){
484
+ $query[] = array( 'key' => '_start_ts', 'value' => array($start,$end), 'type' => 'numeric', 'compare' => 'BETWEEN');
485
+ }else{
486
+ $query[] = array( 'key' => '_start_ts', 'value' => $end, 'compare' => '<=' );
487
+ $query[] = array( 'key' => '_end_ts', 'value' => $start, 'compare' => '>=' );
488
+ }
489
+ }
490
+ }elseif ($scope == "future"){
491
+ $today = strtotime(date('Y-m-d', $time));
492
+ if( get_option('dbem_events_current_are_past') && $wp_query->query_vars['post_type'] != 'event-recurring' ){
493
+ $query[] = array( 'key' => '_start_ts', 'value' => $today, 'compare' => '>=' );
494
+ }else{
495
+ $query[] = array( 'key' => '_end_ts', 'value' => $today, 'compare' => '>=' );
496
+ }
497
+ }elseif ($scope == "past"){
498
+ $today = strtotime(date('Y-m-d', $time));
499
+ if( get_option('dbem_events_current_are_past') && $wp_query->query_vars['post_type'] != 'event-recurring' ){
500
+ $query[] = array( 'key' => '_start_ts', 'value' => $today, 'compare' => '<' );
501
+ }else{
502
+ $query[] = array( 'key' => '_end_ts', 'value' => $today, 'compare' => '<' );
503
+ }
504
+ }elseif ($scope == "today"){
505
+ $today = strtotime(date('Y-m-d', $time));
506
+ if( get_option('dbem_events_current_are_past') && $wp_query->query_vars['post_type'] != 'event-recurring' ){
507
+ //date must be only today
508
+ $query[] = array( 'key' => '_start_ts', 'value' => $today, 'compare' => '=');
509
+ }else{
510
+ $query[] = array( 'key' => '_start_ts', 'value' => $today, 'compare' => '<=' );
511
+ $query[] = array( 'key' => '_end_ts', 'value' => $today, 'compare' => '>=' );
512
+ }
513
+ }elseif ($scope == "tomorrow"){
514
+ $tomorrow = strtotime(date('Y-m-d',$time+60*60*24));
515
+ if( get_option('dbem_events_current_are_past') && $wp_query->query_vars['post_type'] != 'event-recurring' ){
516
+ //date must be only tomorrow
517
+ $query[] = array( 'key' => '_start_ts', 'value' => $tomorrow, 'compare' => '=');
518
+ }else{
519
+ $query[] = array( 'key' => '_start_ts', 'value' => $tomorrow, 'compare' => '<=' );
520
+ $query[] = array( 'key' => '_end_ts', 'value' => $tomorrow, 'compare' => '>=' );
521
+ }
522
+ }elseif ($scope == "month"){
523
+ $start_month = strtotime(date('Y-m-d',$time));
524
+ $end_month = strtotime(date('Y-m-t',$time));
525
+ if( get_option('dbem_events_current_are_past') && $wp_query->query_vars['post_type'] != 'event-recurring' ){
526
+ $query[] = array( 'key' => '_start_ts', 'value' => array($start_month,$end_month), 'type' => 'numeric', 'compare' => 'BETWEEN');
527
+ }else{
528
+ $query[] = array( 'key' => '_start_ts', 'value' => $end_month, 'compare' => '<=' );
529
+ $query[] = array( 'key' => '_end_ts', 'value' => $start_month, 'compare' => '>=' );
530
+ }
531
+ }elseif ($scope == "next-month"){
532
+ $start_month_timestamp = strtotime('+1 month', $time); //get the end of this month + 1 day
533
+ $start_month = strtotime(date('Y-m-1',$start_month_timestamp));
534
+ $end_month = strtotime(date('Y-m-t',$start_month_timestamp));
535
+ if( get_option('dbem_events_current_are_past') && $wp_query->query_vars['post_type'] != 'event-recurring' ){
536
+ $query[] = array( 'key' => '_start_ts', 'value' => array($start_month,$end_month), 'type' => 'numeric', 'compare' => 'BETWEEN');
537
+ }else{
538
+ $query[] = array( 'key' => '_start_ts', 'value' => $end_month, 'compare' => '<=' );
539
+ $query[] = array( 'key' => '_end_ts', 'value' => $start_month, 'compare' => '>=' );
540
+ }
541
+ }elseif( preg_match('/(\d\d?)\-months/',$scope,$matches) ){ // next x months means this month (what's left of it), plus the following x months until the end of that month.
542
+ $months_to_add = $matches[1];
543
+ $start_month = strtotime(date('Y-m-d',$time));
544
+ $end_month = strtotime(date('Y-m-t',strtotime("+$months_to_add month", $time)));
545
+ if( get_option('dbem_events_current_are_past') && $wp_query->query_vars['post_type'] != 'event-recurring' ){
546
+ $query[] = array( 'key' => '_start_ts', 'value' => array($start_month,$end_month), 'type' => 'numeric', 'compare' => 'BETWEEN');
547
+ }else{
548
+ $query[] = array( 'key' => '_start_ts', 'value' => $end_month, 'compare' => '<=' );
549
+ $query[] = array( 'key' => '_end_ts', 'value' => $start_month, 'compare' => '>=' );
550
+ }
551
+ }
552
+
553
+ //Filter by Location - can be object, array, or id
554
+ if ( is_numeric($location) && $location > 0 ) { //Location ID takes precedence
555
+ $query[] = array( 'key' => '_location_id', 'value' => $location, 'compare' => '=' );
556
+ }elseif ( self::array_is_numeric($location) ){
557
+ $query[] = array( 'key' => '_location_id', 'value' => $location, 'compare' => 'IN' );
558
+ }elseif ( is_object($location) && get_class($location)=='EM_Location' ){ //Now we deal with objects
559
+ $query[] = array( 'key' => '_location_id', 'value' => $location->location_id, 'compare' => '=' );
560
+ }elseif ( is_array($location) && @get_class(current($location)=='EM_Location') ){ //we can accept array of ids or EM_Location objects
561
+ foreach($location as $EM_Location){
562
+ $location_ids[] = $EM_Location->location_id;
563
+ }
564
+ $query[] = array( 'key' => '_location_id', 'value' => $location_ids, 'compare' => 'IN' );
565
+ }
566
+
567
+ //Filter by Event - can be object, array, or id
568
+ if ( is_numeric($event) && $event > 0 ) { //event ID takes precedence
569
+ $query[] = array( 'key' => '_event_id', 'value' => $event, 'compare' => '=' );
570
+ }elseif ( self::array_is_numeric($event) ){ //array of ids
571
+ $query[] = array( 'key' => '_event_id', 'value' => $event, 'compare' => 'IN' );
572
+ }elseif ( is_object($event) && get_class($event)=='EM_Event' ){ //Now we deal with objects
573
+ $query[] = array( 'key' => '_event_id', 'value' => $event->event_id, 'compare' => '=' );
574
+ }elseif ( is_array($event) && @get_class(current($event)=='EM_Event') ){ //we can accept array of ids or EM_event objects
575
+ foreach($event as $EM_Event){
576
+ $event_ids[] = $EM_Event->event_id;
577
+ }
578
+ $query[] = array( 'key' => '_event_id', 'value' => $event_ids, 'compare' => 'IN' );
579
+ }
580
+ //country lookup
581
+ if( !empty($args['country']) ){
582
+ $countries = em_get_countries();
583
+ //we can accept country codes or names
584
+ if( in_array($args['country'], $countries) ){
585
+ //we have a country name,
586
+ $country = $countries[$args['country']]."'";
587
+ }elseif( array_key_exists($args['country'], $countries) ){
588
+ //we have a country code
589
+ $country = $args['country'];
590
+ }
591
+ if(!empty($country)){
592
+ //get loc ids
593
+ $ids = $wpdb->get_col("SELECT post_id FROM ".$wpdb->postmeta." WHERE meta_key='_location_country' AND meta_value='$country'");
594
+ $query[] = array( 'key' => '_location_id', 'value' => $ids, 'compare' => 'IN' );
595
+ }
596
+ }
597
+ //state lookup
598
+ if( !empty($args['state']) ){
599
+ $ids = $wpdb->get_col($wpdb->prepare("SELECT post_id FROM ".$wpdb->postmeta." WHERE meta_key='_location_country' AND meta_value='%s'", $args['state']));
600
+ if( is_array($wp_query->query_vars['post__in']) ){
601
+ //remove values not in this array.
602
+ $wp_query->query_vars['post__in'] = array_intersect($wp_query->query_vars['post__in'], $ids);
603
+ }else{
604
+ $wp_query->query_vars['post__in'] = $ids;
605
+ }
606
+ }
607
+ //state lookup
608
+ if( !empty($args['town']) ){
609
+ $ids = $wpdb->get_col($wpdb->prepare("SELECT post_id FROM ".$wpdb->postmeta." WHERE meta_key='_location_town' AND meta_value='%s'", $args['town']));
610
+ if( is_array($wp_query->query_vars['post__in']) ){
611
+ //remove values not in this array.
612
+ $wp_query->query_vars['post__in'] = array_intersect($wp_query->query_vars['post__in'], $ids);
613
+ }else{
614
+ $wp_query->query_vars['post__in'] = $ids;
615
+ }
616
+ }
617
+ //region lookup
618
+ if( !empty($args['region']) ){
619
+ $ids = $wpdb->get_col($wpdb->prepare("SELECT post_id FROM ".$wpdb->postmeta." WHERE meta_key='_location_region' AND meta_value='%s'", $args['region']));
620
+ if( is_array($wp_query->query_vars['post__in']) ){
621
+ //remove values not in this array.
622
+ $wp_query->query_vars['post__in'] = array_intersect($wp_query->query_vars['post__in'], $ids);
623
+ }else{
624
+ $wp_query->query_vars['post__in'] = $ids;
625
+ }
626
+ }
627
+ //Add conditions for category selection
628
+ //Filter by category, can be id or comma seperated ids
629
+ //TODO create an exclude category option
630
+ if ( is_numeric($category) && $category > 0 ){
631
+ //get the term id directly
632
+ $term = new EM_Category($category);
633
+ if( !empty($term->term_id) ){
634
+ if( EM_MS_GLOBAL ){
635
+ $event_ids = $wpdb->get_col($wpdb->prepare("SELECT object_id FROM ".EM_META_TABLE." WHERE meta_value={$term->term_id} AND meta_key='event-category'"));
636
+ $query[] = array( 'key' => '_event_id', 'value' => $event_ids, 'compare' => 'IN' );
637
+ }else{
638
+ if( !is_array($wp_query->query_vars['tax_query']) ) $wp_query->query_vars['tax_query'] = array();
639
+ $wp_query->query_vars['tax_query'] = array('taxonomy' => EM_TAXONOMY_CATEGORY, 'field'=>'id', 'terms'=>$term->term_id);
640
+ }
641
+ }
642
+ }elseif( self::array_is_numeric($category) ){
643
+ $term_ids = array();
644
+ foreach($category as $category_id){
645
+ $term = new EM_Category($category_id);
646
+ if( !empty($term->term_id) ){
647
+ $term_ids[] = $term->term_taxonomy_id;
648
+ }
649
+ }
650
+ if( count($term_ids) > 0 ){
651
+ if( EM_MS_GLOBAL ){
652
+ $event_ids = $wpdb->get_col($wpdb->prepare("SELECT object_id FROM ".EM_META_TABLE." WHERE meta_value IN (".implode(',',$term_ids).") AND meta_name='event-category'"));
653
+ $query[] = array( 'key' => '_event_id', 'value' => $event_ids, 'compare' => 'IN' );
654
+ }else{
655
+ if( !is_array($wp_query->query_vars['tax_query']) ) $wp_query->query_vars['tax_query'] = array();
656
+ $wp_query->query_vars['tax_query'] = array('taxonomy' => EM_TAXONOMY_CATEGORY, 'field'=>'id', 'terms'=>$term_ids);
657
+ }
658
+ }
659
+ }
660
+ //Add conditions for tags
661
+ //Filter by tag, can be id or comma seperated ids
662
+ if ( !empty($tag) && !is_array($tag) ){
663
+ //get the term id directly
664
+ $term = new EM_Tag($tag);
665
+ if( !empty($term->term_id) ){
666
+ if( !is_array($wp_query->query_vars['tax_query']) ) $wp_query->query_vars['tax_query'] = array();
667
+ $wp_query->query_vars['tax_query'] = array('taxonomy' => EM_TAXONOMY_TAXONOMY, 'field'=>'id', 'terms'=>$term->term_taxonomy_id);
668
+ }
669
+ }elseif( is_array($tag) ){
670
+ $term_ids = array();
671
+ foreach($tag as $tag_data){
672
+ $term = new EM_Tag($tag_data);
673
+ if( !empty($term->term_id) ){
674
+ $term_ids[] = $term->term_taxonomy_id;
675
+ }
676
+ }
677
+ if( count($term_ids) > 0 ){
678
+ if( !is_array($wp_query->query_vars['tax_query']) ) $wp_query->query_vars['tax_query'] = array();
679
+ $wp_query->query_vars['tax_query'] = array('taxonomy' => EM_TAXONOMY_TAXONOMY, 'field'=>'id', 'terms'=>$term_ids);
680
+ }
681
+ }
682
+
683
+ //If we want rsvped items, we usually check the event
684
+ if( $bookings == 1 ){
685
+ $query[] = array( 'key' => '_event_rsvp', 'value' => 1, 'compare' => '=' );
686
+ }
687
+ //Default ownership belongs to an event, child objects can just overwrite this if needed.
688
+ if( is_numeric($owner) ){
689
+ $wp_query->query_vars['author'] = $owner;
690
+ }elseif( $owner == 'me' && is_user_logged_in() ){
691
+ $wp_query->query_vars['author'] = get_current_user_id();
692
+ }
693
+ if( !empty($query) && is_array($query) ){
694
+ $wp_query->query_vars['meta_query'] = $query;
695
+ }
696
+ return apply_filters('em_object_build_wp_query_conditions', $wp_query);
697
+ }
698
+
699
+ function build_sql_orderby( $args, $accepted_fields, $default_order = 'ASC' ){
700
+ //First, ORDER BY
701
+ $args = apply_filters('em_object_build_sql_orderby_args', $args);
702
+ $orderby = array();
703
+ if(is_array($args['orderby'])){
704
+ //Clean orderby array so we only have accepted values
705
+ foreach( $args['orderby'] as $key => $field ){
706
+ if( array_key_exists($field, $accepted_fields) ){
707
+ $orderby[] = $accepted_fields[$field];
708
+ }elseif( in_array($field,$accepted_fields) ){
709
+ $orderby[] = $field;
710
+ }else{
711
+ unset($args['orderby'][$key]);
712
+ }
713
+ }
714
+ }elseif( $args['orderby'] != '' && array_key_exists($args['orderby'], $accepted_fields) ){
715
+ $orderby[] = $accepted_fields[$args['orderby']];
716
+ }elseif( $args['orderby'] != '' && in_array($args['orderby'], $accepted_fields) ){
717
+ $orderby[] = $args['orderby'];
718
+ }
719
+ //ORDER
720
+ //If order is an array, we'll go through the orderby array and match the order values (in order of array) with orderby values
721
+ //If orders don't match up, or it's not ASC/DESC, the default events search in EM settings/options page will be used.
722
+ foreach($orderby as $i => $field){
723
+ $orderby[$i] .= ' ';
724
+ if(is_array($args['order'])){
725
+ if( in_array($args['order'][$i], array('ASC','DESC')) ){
726
+ $orderby[$i] .= $args['order'][$i];
727
+ }else{
728
+ $orderby[$i] .= $default_order;
729
+ }
730
+ }else{
731
+ $orderby[$i] .= ( in_array($args['order'], array('ASC','DESC')) ) ? $args['order'] : $default_order;
732
+ }
733
+ }
734
+ return apply_filters('em_object_build_sql_orderby', $orderby);
735
+ }
736
+
737
+ /**
738
+ * Used by "single" objects, e.g. bookings, events, locations to verify if they have the capability to edit this or someone else's object. Relies on the fact that the object has an owner property with id of user (or admin capability must pass).
739
+ * @param string $owner_capability If the object has an owner property and the user id matches that, this capability will be checked for.
740
+ * @param string $admin_capability If the user isn't the owner of the object, this capability will be checked for.
741
+ * @return boolean
742
+ */
743
+ function can_manage( $owner_capability = false, $admin_capability = false, $user_to_check = false ){
744
+ global $em_capabilities_array;
745
+ if( $user_to_check ){
746
+ $user = new WP_User($user_to_check);
747
+ if( empty($user->ID) ) $user = false;
748
+ }
749
+ //if multisite and supoer admin, just return true
750
+ if( is_multisite() && is_super_admin() ){ return true; }
751
+ //do they own this?
752
+ $is_owner = ( (!empty($this->owner) && ($this->owner == get_current_user_id()) || empty($this->id) || (!empty($user) && $this->owner == $user->ID)) );
753
+ //now check capability
754
+ $can_manage = false;
755
+ if( $is_owner && (current_user_can($owner_capability) || (!empty($user) && $user->has_cap($owner_capability))) ){
756
+ //user owns the object and can therefore manage it
757
+ $can_manage = true;
758
+ }elseif( array_key_exists($owner_capability, $em_capabilities_array) ){
759
+ //currently user is not able to manage as they aren't the owner
760
+ $error_msg = $em_capabilities_array[$owner_capability];
761
+ }
762
+ //admins have special rights
763
+ if( current_user_can($admin_capability) || (!empty($user) && $user->has_cap($admin_capability)) ){
764
+ $can_manage = true;
765
+ }elseif( array_key_exists($admin_capability, $em_capabilities_array) ){
766
+ $error_msg = $em_capabilities_array[$admin_capability];
767
+ }
768
+
769
+ if( !$can_manage && !$is_owner && !empty($error_msg) ){
770
+ $this->add_error($error_msg);
771
+ }
772
+ return $can_manage;
773
+ }
774
+
775
+
776
+ function ms_global_switch(){
777
+ if( EM_MS_GLOBAL && !is_main_site() ){
778
+ //If in multisite global, then get the main blog categories
779
+ global $current_site;
780
+ switch_to_blog($current_site->blog_id);
781
+ }
782
+ }
783
+
784
+ function ms_global_switch_back(){
785
+ if( EM_MS_GLOBAL && !is_main_site() ){
786
+ restore_current_blog();
787
+ }
788
+ }
789
+
790
+ /**
791
+ * Save an array into this class.
792
+ * If you provide a record from the database table corresponding to this class type it will add the data to this object.
793
+ * @param array $array
794
+ * @return null
795
+ */
796
+ function to_object( $array = array(), $addslashes = false ){
797
+ //Save core data
798
+ if( is_array($array) ){
799
+ $array = apply_filters('em_to_object', $array);
800
+ foreach ( array_keys($this->fields) as $key ) {
801
+ if(array_key_exists($key, $array)){
802
+ if( !is_object($array[$key]) && !is_array($array[$key]) ){
803
+ $array[$key] = ($addslashes) ? stripslashes($array[$key]):$array[$key];
804
+ }elseif( is_array($array[$key]) ){
805
+ $array[$key] = ($addslashes) ? stripslashes_deep($array[$key]):$array[$key];
806
+ }
807
+ $this->$key = $array[$key];
808
+ }
809
+ }
810
+ }
811
+ }
812
+
813
+ /**
814
+ * Copies all the properties to shorter property names for compatability, do not use the old properties.
815
+ */
816
+ function compat_keys(){
817
+ foreach($this->fields as $key => $fieldinfo){
818
+ if(!empty($this->$key)) $this->$fieldinfo['name'] = $this->$key;
819
+ }
820
+ }
821
+
822
+ /**
823
+ * Returns this object in the form of an array, useful for saving directly into a database table.
824
+ * @return array
825
+ */
826
+ function to_array($db = false){
827
+ $array = array();
828
+ foreach ( $this->fields as $key => $val ) {
829
+ if($db){
830
+ if( !empty($this->$key) || $this->$key === 0 || empty($val['null']) ){
831
+ $array[$key] = $this->$key;
832
+ }
833
+ }else{
834
+ $array[$key] = $this->$key;
835
+ }
836
+ }
837
+ return apply_filters('em_to_array', $array);
838
+ }
839
+
840
+
841
+ /**
842
+ * Function to retreive wpdb types for all fields, or if you supply an assoc array with field names as keys it'll return an equivalent array of wpdb types
843
+ * @param array $array
844
+ * @return array:
845
+ */
846
+ function get_types($array = array()){
847
+ $types = array();
848
+ if( count($array)>0 ){
849
+ //So we look at assoc array and find equivalents
850
+ foreach ($array as $key => $val){
851
+ $types[] = $this->fields[$key]['type'];
852
+ }
853
+ }else{
854
+ //Blank array, let's assume we're getting a standard list of types
855
+ foreach ($this->fields as $field){
856
+ $types[] = $field['type'];
857
+ }
858
+ }
859
+ return apply_filters('em_object_get_types', $types, $this, $array);
860
+ }
861
+
862
+ function get_fields( $inverted_array=false ){
863
+ if( is_array($this->fields) ){
864
+ $return = array();
865
+ foreach($this->fields as $fieldName => $fieldArray){
866
+ if($inverted_array){
867
+ $return[$fieldName] = $fieldName;
868
+ }else{
869
+ $return[$fieldName] = $fieldName;
870
+ }
871
+ }
872
+ return apply_filters('em_object_get_fields', $return, $this, $inverted_array);
873
+ }
874
+ return apply_filters('em_object_get_fields', array(), $this, $inverted_array);
875
+ }
876
+
877
+ /**
878
+ * Sanitize text before inserting into database
879
+ * @param string $value
880
+ * @return string
881
+ */
882
+ function sanitize( $value ) {
883
+ if( get_magic_quotes_gpc() )
884
+ $value = stripslashes( $value );
885
+
886
+ //check if this function exists
887
+ if( function_exists( "mysql_real_escape_string" ) ) {
888
+ $value = mysql_real_escape_string( $value );
889
+ //for PHP version < 4.3.0 use addslashes
890
+ } else {
891
+ $value = addslashes( $value );
892
+ }
893
+ return apply_filters('em_object_sanitize', $value);
894
+ }
895
+
896
+ /**
897
+ * Cleans arrays that contain id lists. Takes an array of items and will clean the keys passed in second argument so that if they keep numbers, explode comma-seperated numbers, and unsets the key if there's any other value
898
+ * @param array $array
899
+ * @param array $id_atts
900
+ */
901
+ function clean_id_atts( $array = array(), $id_atts = array() ){
902
+ if( is_array($array) && is_array($id_atts) ){
903
+ foreach( $array as $key => $string ){
904
+ if( in_array($key, $id_atts) ){
905
+ //This is in the list of atts we want cleaned
906
+ if( is_numeric($string) ){
907
+ $array[$key] = (int) $string;
908
+ }elseif( self::array_is_numeric($string) ){
909
+ $array[$key] = $string;
910
+ }elseif( !is_array($string) && preg_match('/^([\-0-9],?)+$/', $string) ){
911
+ $array[$key] = explode(',', $string);
912
+ }else{
913
+ //No format we accept
914
+ unset($array[$key]);
915
+ }
916
+ }
917
+ }
918
+ }
919
+ return $array;
920
+ }
921
+
922
+ /**
923
+ * Send an email and log errors in this object
924
+ * @param string $subject
925
+ * @param string $body
926
+ * @param string $email
927
+ * @return string
928
+ */
929
+ function email_send($subject, $body, $email){
930
+ global $EM_Mailer;
931
+ if( !is_object($EM_Mailer) ){
932
+ $EM_Mailer = new EM_Mailer();
933
+ }
934
+ if( !$EM_Mailer->send($subject,$body,$email) ){
935
+ if( is_array($EM_Mailer->errors) ){
936
+ foreach($EM_Mailer->errors as $error){
937
+ $this->errors[] = $error;
938
+ }
939
+ }else{
940
+ $this->errors[] = $EM_Mailer->errors;
941
+ }
942
+ return false;
943
+ }
944
+ return true;
945
+ }
946
+
947
+ /**
948
+ * Will return true if this is a simple (non-assoc) numeric array, meaning it has at one or more numeric entries and nothing else
949
+ * @param mixed $array
950
+ * @return boolean
951
+ */
952
+ function array_is_numeric($array){
953
+ $results = array();
954
+ if(is_array($array)){
955
+ foreach($array as $key => $item){
956
+ $results[] = (is_numeric($item)&&is_numeric($key));
957
+ }
958
+ }
959
+ return (!in_array(false, $results) && count($results) > 0);
960
+ }
961
+
962
+ /**
963
+ * Returns an array of errors in this object
964
+ * @return array
965
+ */
966
+ function get_errors(){
967
+ if(is_array($this->errors)){
968
+ return $this->errors;
969
+ }else{
970
+ return array();
971
+ }
972
+ }
973
+
974
+ /**
975
+ * Adds an error to the object
976
+ */
977
+ function add_error($errors){
978
+ if(!is_array($errors)){ $errors = array($errors); } //make errors var an array if it isn't already
979
+ if(!is_array($this->errors)){ $this->errors = array(); } //create empty array if this isn't an array
980
+ foreach($errors as $error){
981
+ if( !in_array($error, $this->errors) ){
982
+ $this->errors[] = $error;
983
+ }
984
+ }
985
+ }
986
+
987
+ /**
988
+ * Converts an array to JSON format, useful for outputting data for AJAX calls. Uses a PHP4 fallback function, given it doesn't support json_encode().
989
+ * @param array $array
990
+ * @return string
991
+ */
992
+ function json_encode($array){
993
+ if( function_exists("json_encode") ){
994
+ $return = json_encode($array);
995
+ }else{
996
+ $return = self::array_to_json($array);
997
+ }
998
+ if( isset($_REQUEST['callback']) && preg_match("/^jQuery[_a-zA-Z0-9]+$/", $_REQUEST['callback']) ){
999
+ $return = $_REQUEST['callback']."($return)";
1000
+ }
1001
+ return apply_filters('em_object_json_encode', $return, $array);
1002
+ }
1003
+
1004
+ /**
1005
+ * Compatible json encoder function for PHP4
1006
+ * @param array $array
1007
+ * @return string
1008
+ */
1009
+ function array_to_json($array){
1010
+ //PHP4 Comapatability - This encodes the array into JSON. Thanks go to Andy - http://www.php.net/manual/en/function.json-encode.php#89908
1011
+ if( !is_array( $array ) ){
1012
+ $array = array();
1013
+ }
1014
+ $associative = count( array_diff( array_keys($array), array_keys( array_keys( $array )) ));
1015
+ if( $associative ){
1016
+ $construct = array();
1017
+ foreach( $array as $key => $value ){
1018
+ // We first copy each key/value pair into a staging array,
1019
+ // formatting each key and value properly as we go.
1020
+ // Format the key:
1021
+ if( is_numeric($key) ){
1022
+ $key = "key_$key";
1023
+ }
1024
+ $key = "'".addslashes($key)."'";
1025
+ // Format the value:
1026
+ if( is_array( $value )){
1027
+ $value = $this->array_to_json( $value );
1028
+ }else if( is_bool($value) ) {
1029
+ $value = ($value) ? "true" : "false";
1030
+ }else if( !is_numeric( $value ) || is_string( $value ) ){
1031
+ $value = "'".addslashes($value)."'";
1032
+ }
1033
+ // Add to staging array:
1034
+ $construct[] = "$key: $value";
1035
+ }
1036
+ // Then we collapse the staging array into the JSON form:
1037
+ $result = "{ " . implode( ", ", $construct ) . " }";
1038
+ } else { // If the array is a vector (not associative):
1039
+ $construct = array();
1040
+ foreach( $array as $value ){
1041
+ // Format the value:
1042
+ if( is_array( $value )){
1043
+ $value = $this->array_to_json( $value );
1044
+ } else if( !is_numeric( $value ) || is_string( $value ) ){
1045
+ $value = "'".addslashes($value)."'";
1046
+ }
1047
+ // Add to staging array:
1048
+ $construct[] = $value;
1049
+ }
1050
+ // Then we collapse the staging array into the JSON form:
1051
+ $result = "[ " . implode( ", ", $construct ) . " ]";
1052
+ }
1053
+ return $result;
1054
+ }
1055
+
1056
+ /*
1057
+ * START IMAGE UPlOAD FUNCTIONS
1058
+ * Used for various objects, so shared in one place
1059
+ */
1060
+ /**
1061
+ * Returns the type of image in lowercase, if $path is true, a base filename is returned which indicates where to store the file from the root upload folder.
1062
+ * @param unknown_type $path
1063
+ * @return mixed|mixed
1064
+ */
1065
+ function get_image_type($path = false){
1066
+ $type = false;
1067
+ switch( get_class($this) ){
1068
+ case 'EM_Event':
1069
+ $dir = (EM_IMAGE_DS == '/') ? 'events/':'';
1070
+ $type = 'event';
1071
+ break;
1072
+ case 'EM_Location':
1073
+ $dir = (EM_IMAGE_DS == '/') ? 'locations/':'';
1074
+ $type = 'location';
1075
+ break;
1076
+ case 'EM_Category':
1077
+ $dir = (EM_IMAGE_DS == '/') ? 'categories/':'';
1078
+ $type = 'category';
1079
+ break;
1080
+ }
1081
+ if($path){
1082
+ return apply_filters('em_object_get_image_type',$dir.$type, $path, $this);
1083
+ }
1084
+ return apply_filters('em_object_get_image_type',$type, $path, $this);
1085
+ }
1086
+
1087
+ function get_image_url($size = 'full'){
1088
+ $image_url = $this->image_url;
1089
+ if( !empty($this->post_id) && (empty($this->image_url) || $size != 'full') ){
1090
+ $post_thumbnail_id = get_post_thumbnail_id( $this->post_id );
1091
+ $src = wp_get_attachment_image_src($post_thumbnail_id, $size);
1092
+ if( !empty($src[0]) && $size == 'full' ){
1093
+ $image_url = $this->image_url = $src[0];
1094
+ }elseif(!empty($src[0])){
1095
+ $image_url = $src[0];
1096
+ }
1097
+ //legacy image finder, annoying, but must be done
1098
+ if( empty($image_url) ){
1099
+ $type = $this->get_image_type();
1100
+ if( get_class($this) == "EM_Event" ){
1101
+ $id = ( $this->is_recurrence() ) ? $this->recurrence_id:$this->event_id; //quick fix for recurrences
1102
+ }elseif( get_class($this) == "EM_Location" ){
1103
+ $id = $this->location_id;
1104
+ }else{
1105
+ $id = $this->id;
1106
+ }
1107
+ if( $type ){
1108
+ foreach($this->mime_types as $mime_type) {
1109
+ $file_name = $this->get_image_type(true)."-{$id}.$mime_type";
1110
+ if( file_exists( EM_IMAGE_UPLOAD_DIR . $file_name) ) {
1111
+ $image_url = $this->image_url = EM_IMAGE_UPLOAD_URI.$file_name;
1112
+ }
1113
+ }
1114
+ }
1115
+ }
1116
+ }
1117
+ return apply_filters('em_object_get_image_url', $image_url, $this);
1118
+ }
1119
+
1120
+ function image_delete($force_delete=true) {
1121
+ $type = $this->get_image_type();
1122
+ if( $type ){
1123
+ if( $this->get_image_url() == '' ){
1124
+ $result = true;
1125
+ }else{
1126
+ $post_thumbnail_id = get_post_thumbnail_id( $this->post_id );
1127
+ $delete_attachment = wp_delete_attachment($post_thumbnail_id, $force_delete);
1128
+ if( $delete_attachment !== false ){
1129
+ //check legacy image
1130
+ $type_id_name = $type.'_id';
1131
+ $file_name= EM_IMAGE_UPLOAD_DIR.$this->get_image_type(true)."-".$this->$type_id_name;
1132
+ $result = false;
1133
+ foreach($this->mime_types as $mime_type) {
1134
+ if (file_exists($file_name.".".$mime_type)){
1135
+ $result = unlink($file_name.".".$mime_type);
1136
+ $this->image_url = '';
1137
+ }
1138
+ }
1139
+ }
1140
+ }
1141
+ }
1142
+ return apply_filters('em_object_get_image_url', $result, $this);
1143
+ }
1144
+
1145
+ function image_upload(){
1146
+ $type = $this->get_image_type();
1147
+ //Handle the attachment as a WP Post
1148
+ $attachment = '';
1149
+ $user_to_check = ( !is_user_logged_in() && get_option('dbem_events_anonymous_submissions') ) ? get_option('dbem_events_anonymous_user'):false;
1150
+ if ( !empty($_FILES[$type.'_image']['size']) && file_exists($_FILES[$type.'_image']['tmp_name']) && $this->image_validate() && $this->can_manage('upload_event_images','upload_event_images', $user_to_check) ) {
1151
+ require_once(ABSPATH . "wp-admin" . '/includes/file.php');
1152
+ require_once(ABSPATH . "wp-admin" . '/includes/image.php');
1153
+
1154
+ $attachment = wp_handle_upload($_FILES[$type.'_image'], array('test_form'=>false), current_time('mysql'));
1155
+
1156
+ if ( isset($attachment['error']) ){
1157
+ $this->add_error('Image Error: ' . $attachment['error'] );
1158
+ }
1159
+
1160
+ /* Attach file to ticket */
1161
+ if ( count($this->errors) == 0 && $attachment ){
1162
+ $attachment_data = array(
1163
+ 'post_mime_type' => $attachment['type'],
1164
+ 'post_title' => $this->post_title,
1165
+ 'post_content' => '',
1166
+ 'post_status' => 'inherit'
1167
+ );
1168
+ $attachment_id = wp_insert_attachment( $attachment_data, $attachment['file'], $this->post_id );
1169
+ $attachment_metadata = wp_generate_attachment_metadata( $attachment_id, $attachment['file'] );
1170
+ wp_update_attachment_metadata( $attachment_id, $attachment_metadata );
1171
+ //delete the old attachment
1172
+ $this->image_delete();
1173
+ update_post_meta($this->post_id, '_thumbnail_id', $attachment_id);
1174
+ return apply_filters('em_object_image_upload', true, $this);
1175
+ }else{
1176
+ return apply_filters('em_object_image_upload', false, $this);
1177
+ }
1178
+ }elseif( !empty($_REQUEST[$type.'_image_delete']) ){
1179
+ $this->image_delete();
1180
+ }
1181
+ return apply_filters('em_object_image_upload', false, $this);
1182
+ }
1183
+
1184
+ function image_validate(){
1185
+ $type = $this->get_image_type();
1186
+ if( $type ){
1187
+ if ( !empty($_FILES[$type.'_image']) && $_FILES[$type.'_image']['size'] > 0 ) {
1188
+ if (is_uploaded_file($_FILES[$type.'_image']['tmp_name'])) {
1189
+ list($width, $height, $mime_type, $attr) = getimagesize($_FILES[$type.'_image']['tmp_name']);
1190
+ $maximum_size = get_option('dbem_image_max_size');
1191
+ if ($_FILES[$type.'_image']['size'] > $maximum_size){
1192
+ $this->add_error( __('The image file is too big! Maximum size:', 'dbem')." $maximum_size");
1193
+ }
1194
+ $maximum_width = get_option('dbem_image_max_width');
1195
+ $maximum_height = get_option('dbem_image_max_height');
1196
+ $minimum_width = get_option('dbem_image_min_width');
1197
+ $minimum_height = get_option('dbem_image_min_height');
1198
+ if (($width > $maximum_width) || ($height > $maximum_height)) {
1199
+ $this->add_error( __('The image is too big! Maximum size allowed:','dbem')." $maximum_width x $maximum_height");
1200
+ }
1201
+ if (($width < $minimum_width) || ($height < $minimum_height)) {
1202
+ $this->add_error( __('The image is too small! Minimum size allowed:','dbem')." $minimum_width x $minimum_height");
1203
+ }
1204
+ if ( empty($mime_type) || !array_key_exists($mime_type, $this->mime_types) ){
1205
+ $this->add_error(__('The image is in a wrong format!','dbem'));
1206
+ }
1207
+ }
1208
+ }
1209
+ }
1210
+ return apply_filters('em_object_image_validate', count($this->errors) == 0, $this);
1211
+ }
1212
+ /*
1213
+ * END IMAGE UPlOAD FUNCTIONS
1214
+ */
1215
  }
classes/em-people.php CHANGED
@@ -1,129 +1,34 @@
1
- <?php
2
- class EM_People extends EM_Object {
3
-
4
- /**
5
- * Gets all users, if $return_people false an array associative arrays will be returned. If $return_people is true this will return an array of EM_Person objects
6
- * @param $return_people
7
- * @return array
8
- */
9
- function get( $return_people = true ) {
10
- global $wpdb;
11
- $sql = "SELECT * FROM ". $wpdb->prefix.EM_PEOPLE_TABLE ;
12
- $result = $wpdb->get_results($sql, ARRAY_A);
13
- if( $return_people ){
14
- //Return people as EM_Person objects
15
- $people = array();
16
- foreach ($result as $person){
17
- $people[] = new EM_Person($person);
18
- }
19
- return $people;
20
- }
21
- return $result;
22
- }
23
-
24
- function get_new( $args = array() ) {
25
- global $wpdb;
26
- $people_table = $wpdb->prefix.EM_PEOPLE_TABLE;
27
- $bookings_table = $wpdb->prefix.EM_BOOKINGS_TABLE;
28
-
29
- //Quick version, we can accept an array of IDs, which is easy to retrieve
30
- if( self::array_is_numeric($args) ){ //Array of numbers, assume they are event IDs to retreive
31
- //We can just get all the events here and return them
32
- $sql = "SELECT * FROM $people_table WHERE person_id=".implode(" OR person_id=", $args);
33
- $results = $wpdb->get_results(apply_filters('em_people_get_sql',$sql),ARRAY_A);
34
- $people = array();
35
- foreach($results as $result){
36
- $people[$result['person_id']] = new EM_Person($result);
37
- }
38
- return $people; //We return all the people matched as an EM_Event array.
39
- }
40
-
41
- //We assume it's either an empty array or array of search arguments to merge with defaults
42
- $args = self::get_default_search($args);
43
- $limit = ( $args['limit'] && is_numeric($args['limit'])) ? "LIMIT {$args['limit']}" : '';
44
- $offset = ( $limit != "" && is_numeric($args['offset']) ) ? "OFFSET {$args['offset']}" : '';
45
-
46
- //Get the default conditions
47
- $conditions = self::build_sql_conditions($args);
48
- //Put it all together
49
- $where = ( count($conditions) > 0 ) ? " WHERE " . implode ( " AND ", $conditions ):'';
50
-
51
- //Get ordering instructions
52
- $EM_Person = new EM_Person();
53
- $accepted_fields = $EM_Person->get_fields(true);
54
- $orderby = self::build_sql_orderby($args, $accepted_fields, get_option('dbem_people_default_order'));
55
- //Now, build orderby sql
56
- $orderby_sql = ( count($orderby) > 0 ) ? 'ORDER BY '. implode(', ', $orderby) : '';
57
-
58
- //Create the SQL statement and execute
59
- $sql = "
60
- SELECT * FROM $people_table
61
- LEFT JOIN $bookings_table ON {$bookings_table}.person_id={$people_table}.person_id
62
- $where
63
- GROUP BY person_id
64
- $orderby_sql
65
- $limit $offset
66
- ";
67
- $results = $wpdb->get_results( apply_filters('em_people_get_sql',$sql, $args), ARRAY_A);
68
- //If we want results directly in an array, why not have a shortcut here?
69
- if( $args['array'] == true ){
70
- return $results;
71
- }
72
-
73
- //Make returned results EM_Event objects
74
- $results = (is_array($results)) ? $results:array();
75
- $people = array();
76
- foreach ( $results as $person_array ){
77
- $people[$person_array['person_id']] = new EM_Person($person_array);
78
- }
79
-
80
- return apply_filters('em_people_get', $people);
81
- }
82
-
83
- /* Overrides EM_Object method to apply a filter to result
84
- * @see wp-content/plugins/events-manager/classes/EM_Object#build_sql_conditions()
85
- */
86
- function build_sql_conditions( $args = array() ){
87
- global $wpdb;
88
- //FIXME EM_People doesn't build sql conditions in EM_Object
89
- $conditions = array();
90
-
91
- return apply_filters( 'em_people_build_sql_conditions', $conditions, $args );
92
- }
93
-
94
- /* Overrides EM_Object method to apply a filter to result
95
- * @see wp-content/plugins/people-manager/classes/EM_Object#build_sql_orderby()
96
- */
97
- function build_sql_orderby( $args, $accepted_fields, $default_order = 'ASC' ){
98
- return apply_filters( 'em_people_build_sql_orderby', parent::build_sql_orderby($args, $accepted_fields, get_option('dbem_people_default_order')), $args, $accepted_fields, $default_order );
99
- }
100
-
101
- /*
102
- * Adds custom people search defaults
103
- * @param array $array
104
- * @return array
105
- * @uses EM_Object#get_default_search()
106
- */
107
- function get_default_search( $array = array() ){
108
- $defaults = array(
109
- 'scope'=>false,
110
- 'eventful' => false, //cats that have an event (scope will also play a part here
111
- 'eventless' => false, //cats WITHOUT events, eventful takes precedence
112
- );
113
- //figure out default owning permissions, but since public is for viewing events, only impose limitations in admin area
114
- if( is_admin() ){
115
- switch( get_option('dbem_permissions_events') ){
116
- case 0:
117
- $defaults['owner'] = get_current_user_id();
118
- break;
119
- case 1:
120
- $defaults['owner'] = false;
121
- break;
122
- }
123
- $defaults['owner'] = ( em_verify_admin() ) ? false:$defaults['owner'];
124
- }
125
- return apply_filters('em_people_get_default_search', parent::get_default_search($defaults,$array), $array, $defaults);
126
- }
127
-
128
- }
129
  ?>
1
+ <?php
2
+ class EM_People extends EM_Object {
3
+
4
+ /**
5
+ * Handles the action of someone being deleted on WordPress
6
+ * @param int $id
7
+ */
8
+ function delete_user( $id ){
9
+ global $wpdb;
10
+ if( current_user_can('delete_users') ){
11
+ if( $_REQUEST['delete_option'] == 'reassign' && is_numeric($_REQUEST['reassign_user']) ){
12
+ $wpdb->update(EM_EVENTS_TABLE, array('event_owner'=>$_REQUEST['reassign_user']), array('event_owner'=>$id));
13
+ }else{
14
+ //User is being deleted, so we delete their events and cancel their bookings.
15
+ $wpdb->query("DELETE FROM ".EM_EVENTS_TABLE." WHERE event_owner=$id");
16
+ }
17
+ }
18
+ //set bookings to cancelled
19
+ $wpdb->update(EM_BOOKINGS_TABLE, array('booking_status'=>3, 'person_id'=>0, 'booking_comment'=>__('User deleted by administrators','dbem')), array('person_id'=>$id));
20
+ }
21
+
22
+ /**
23
+ * Adds phone number to contact info of users, compatible with previous phone field method
24
+ * @param $array
25
+ * @return array
26
+ */
27
+ function user_contactmethods($array){
28
+ $array['dbem_phone'] = __('Phone','dbem') . ' <span class="description">('. __('Events Manager','dbem') .')</span>';
29
+ return $array;
30
+ }
31
+ }
32
+ add_action('delete_user', array('EM_People','delete_user'),10,1);
33
+ add_filter( 'user_contactmethods' , array('EM_People','user_contactmethods'),10,1);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
  ?>
classes/em-permalinks.php ADDED
@@ -0,0 +1,241 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if( !class_exists('EM_Permalinks') ){
4
+ class EM_Permalinks {
5
+ static $em_queryvars = array(
6
+ 'event_id','event_slug', 'em_redirect',
7
+ 'location_id','location_slug',
8
+ 'person_id',
9
+ 'booking_id',
10
+ 'category_id', 'category_slug',
11
+ 'ticket_id',
12
+ 'calendar_day',
13
+ 'rss', 'ical', 'bookings_page','event_categories','event_locations'
14
+ );
15
+
16
+ function init(){
17
+ add_filter('pre_update_option_dbem_events_page', array('EM_Permalinks','option_update'));
18
+ if( get_option('dbem_flush_needed') ){
19
+ add_filter('init', array('EM_Permalinks','flush'));
20
+ }
21
+ add_filter('rewrite_rules_array',array('EM_Permalinks','rewrite_rules_array'));
22
+ add_filter('query_vars',array('EM_Permalinks','query_vars'));
23
+ add_action('parse_query',array('EM_Permalinks','init_objects'), 1);
24
+ add_action('parse_query',array('EM_Permalinks','redirection'), 1);
25
+ if( !defined('EM_EVENT_SLUG') ){ define('EM_EVENT_SLUG','event'); }
26
+ if( !defined('EM_LOCATION_SLUG') ){ define('EM_LOCATION_SLUG','location'); }
27
+ if( !defined('EM_LOCATIONS_SLUG') ){ define('EM_LOCATIONS_SLUG','locations'); }
28
+ if( !defined('EM_CATEGORY_SLUG') ){ define('EM_CATEGORY_SLUG','category'); }
29
+ if( !defined('EM_CATEGORIES_SLUG') ){ define('EM_CATEGORIES_SLUG','categories'); }
30
+ add_filter('post_type_archive_link',array('EM_Permalinks','post_type_archive_link'),10,2);
31
+ }
32
+
33
+ function flush(){
34
+ global $wp_rewrite;
35
+ $wp_rewrite->flush_rules();
36
+ delete_option('dbem_flush_needed');
37
+ }
38
+
39
+ function post_type_archive_link($link, $post_type){
40
+ if( $post_type == EM_POST_TYPE_EVENT ){
41
+ if( get_option('dbem_events_page') ){
42
+ $new_link = get_permalink(get_option('dbem_events_page'));
43
+ }
44
+ }
45
+ if( $post_type == EM_POST_TYPE_LOCATION ){
46
+ if( get_option('dbem_locations_page') ){
47
+ $new_link = get_permalink(get_option('dbem_locations_page'));
48
+ }
49
+ }
50
+ if( !empty($new_link) ){
51
+ $link = $new_link;
52
+ }
53
+ return $link;
54
+ }
55
+
56
+ /**
57
+ * will redirect old links to new link structures.
58
+ * @return mixed
59
+ */
60
+ function redirection(){
61
+ global $wpdb, $wp_rewrite, $post, $wp_query;
62
+ if( is_object($wp_query) && $wp_query->get('em_redirect') ){
63
+ //is this a querystring url?
64
+ if( $wp_query->get('event_slug') ){
65
+ $event = $wpdb->get_row('SELECT event_id, post_id FROM '.EM_EVENTS_TABLE." WHERE event_slug='".$wp_query->get('event_slug')."' AND (blog_id=".get_current_blog_id()." OR blog_id IS NULL OR blog_id=0)", ARRAY_A);
66
+ if( !empty($event) ){
67
+ $EM_Event = em_get_event($event['event_id']);
68
+ $url = get_permalink($EM_Event->post_id);
69
+ }
70
+ }elseif( $wp_query->get('location_slug') ){
71
+ $location = $wpdb->get_row('SELECT location_id, post_id FROM '.EM_LOCATIONS_TABLE." WHERE location_slug='".$wp_query->get('location_slug')."' AND (blog_id=".get_current_blog_id()." OR blog_id IS NULL OR blog_id=0)", ARRAY_A);
72
+ if( !empty($location) ){
73
+ $EM_Location = em_get_location($location['location_id']);
74
+ $url = get_permalink($EM_Location->post_id);
75
+ }
76
+ }elseif( $wp_query->get('category_slug') ){
77
+ $url = get_term_link($wp_query->get('category_slug'), EM_TAXONOMY_CATEGORY);
78
+ }
79
+ if(!empty($url)){
80
+ wp_redirect($url,301);
81
+ exit();
82
+ }
83
+ }
84
+ }
85
+ // Adding a new rule
86
+ function rewrite_rules_array($rules){
87
+ //get the slug of the event page
88
+ $events_page_id = get_option ( 'dbem_events_page' );
89
+ $events_page = get_post($events_page_id);
90
+ $em_rules = array();
91
+ if( is_object($events_page) ){
92
+ $events_slug = preg_replace('/\/$/', '', str_replace( trailingslashit(home_url()), '', get_permalink($events_page_id)) );
93
+ $events_slug = ( !empty($events_slug) ) ? trailingslashit($events_slug) : $events_slug;
94
+ $em_rules[$events_slug.'(\d{4}-\d{2}-\d{2})$'] = 'index.php?pagename='.$events_slug.'&calendar_day=$matches[1]'; //event calendar date search
95
+ $em_rules[$events_slug.'rss$'] = 'index.php?pagename='.$events_slug.'&rss=1'; //rss page
96
+ $em_rules[$events_slug.'feed$'] = 'index.php?pagename='.$events_slug.'&rss=1'; //compatible rss page
97
+ if( EM_POST_TYPE_EVENT_SLUG.'/' == $events_slug ){ //won't apply on homepage
98
+ //make sure we hard-code rewrites for child pages of events
99
+ $child_posts = get_posts(array('post_type'=>'page', 'post_parent'=>$events_page->ID, 'numberposts'=>0));
100
+ foreach($child_posts as $child_post){
101
+ $em_rules[$events_slug.$child_post->post_name.'/?$'] = 'index.php?page_id='.$child_post->ID; //single event booking form with slug
102
+ }
103
+ }
104
+ if( EM_MS_GLOBAL && !get_site_option('dbem_ms_global_events_links', true) ){
105
+ //MS Mode has slug also for global links
106
+ $em_rules[$events_slug.get_site_option('dbem_ms_events_slug',EM_EVENT_SLUG).'/(.+)$'] = 'index.php?pagename='.$events_slug.'&em_redirect=1&event_slug=$matches[1]'; //single event from subsite
107
+ }
108
+ //add redirection for backwards compatability
109
+ $em_rules[$events_slug.EM_EVENT_SLUG.'/(.+)$'] = 'index.php?pagename='.$events_slug.'&em_redirect=1&event_slug=$matches[1]'; //single event
110
+ $em_rules[$events_slug.EM_LOCATION_SLUG.'/(.+)$'] = 'index.php?pagename='.$events_slug.'&em_redirect=1&location_slug=$matches[1]'; //single location page
111
+ $em_rules[$events_slug.EM_CATEGORY_SLUG.'/(.+)$'] = 'index.php?pagename='.$events_slug.'&em_redirect=1&category_slug=$matches[1]'; //single category page slug
112
+ //add a rule that ensures that the events page is found and used over other pages
113
+ $em_rules[trim($events_slug,'/').'/?$'] = 'index.php?pagename='.trim($events_slug,'/') ;
114
+ }else{
115
+ $events_slug = EM_POST_TYPE_EVENT_SLUG;
116
+ $em_rules[$events_slug.'/(\d{4}-\d{2}-\d{2})$'] = 'index.php?post_type='.EM_POST_TYPE_EVENT.'&calendar_day=$matches[1]'; //event calendar date search
117
+ if( !get_option( 'dbem_my_bookings_page') || !is_object(get_post(get_option( 'dbem_my_bookings_page'))) ){ //only added if bookings page isn't assigned
118
+ $em_rules[$events_slug.'/my\-bookings$'] = 'index.php?post_type='.EM_POST_TYPE_EVENT.'&bookings_page=1'; //page for users to manage bookings
119
+ }
120
+ //check for potentially conflicting posts with the same slug as events
121
+ $conflicting_posts = get_posts(array('name'=>EM_POST_TYPE_EVENT_SLUG, 'post_type'=>'any', 'numberposts'=>0));
122
+ if( count($conflicting_posts) > 0 ){ //won't apply on homepage
123
+ foreach($conflicting_posts as $conflicting_post){
124
+ //make sure we hard-code rewrites for child pages of events
125
+ $child_posts = get_posts(array('post_type'=>'any', 'post_parent'=>$conflicting_post->ID, 'numberposts'=>0));
126
+ foreach($child_posts as $child_post){
127
+ $em_rules[EM_POST_TYPE_EVENT_SLUG.'/'.$child_post->post_name.'/?$'] = 'index.php?page_id='.$child_post->ID; //single event booking form with slug
128
+ }
129
+ }
130
+ }
131
+ }
132
+ //make sure there's no page with same name as archives, that should take precedence as it can easily be deleted wp admin side
133
+ $em_query = new WP_Query(array('pagename'=>EM_POST_TYPE_EVENT_SLUG));
134
+ if( $em_query->have_posts() ){
135
+ $em_rules[trim(EM_POST_TYPE_EVENT_SLUG,'/').'/?$'] = 'index.php?pagename='.trim(EM_POST_TYPE_EVENT_SLUG,'/') ;
136
+ wp_reset_postdata();
137
+ }
138
+ //make sure there's no page with same name as archives, that should take precedence as it can easily be deleted wp admin side
139
+ $em_query = new WP_Query(array('pagename'=>EM_POST_TYPE_LOCATION_SLUG));
140
+ if( $em_query->have_posts() ){
141
+ $em_rules[trim(EM_POST_TYPE_LOCATION_SLUG,'/').'/?$'] = 'index.php?pagename='.trim(EM_POST_TYPE_LOCATION_SLUG,'/') ;
142
+ wp_reset_postdata();
143
+ }
144
+ //If in MS global mode and locations are linked on same site
145
+ if( EM_MS_GLOBAL && !get_site_option('dbem_ms_global_locations_links', true) ){
146
+ $locations_page_id = get_option ( 'dbem_locations_page' );
147
+ $locations_page = get_post($locations_page_id);
148
+ if( is_object($locations_page) ){
149
+ $locations_slug = preg_replace('/\/$/', '', str_replace( trailingslashit(home_url()), '', get_permalink($locations_page_id) ));
150
+ $em_rules[$locations_slug.'/'.get_site_option('dbem_ms_locations_slug',EM_LOCATION_SLUG).'/(.+)$'] = 'index.php?pagename='.$locations_slug.'&location_slug=$matches[1]'; //single event booking form with slug
151
+ }
152
+ }
153
+ //add ical endpoint
154
+ $em_rules[EM_POST_TYPE_EVENT_SLUG."/([^/]+)/ical/?$"] = 'index.php?event=$matches[1]&ical=1';
155
+ return $em_rules + $rules;
156
+ }
157
+
158
+ /**
159
+ * Depreciated, use get_post_permalink() from now on or the output function with a placeholder
160
+ * Generate a URL. Pass each section of a link as a parameter, e.g. EM_Permalinks::url('event',$event_id); will create an event link.
161
+ * @param mixed
162
+ */
163
+ function url(){
164
+ global $wp_rewrite;
165
+ $args = func_get_args();
166
+ $em_uri = get_permalink(get_option("dbem_events_page")); //PAGE URI OF EM
167
+ if ( $wp_rewrite->using_permalinks() /*&& !defined('EM_DISABLE_PERMALINKS')*/ ) {
168
+ $event_link = trailingslashit(trailingslashit($em_uri). implode('/',$args));
169
+ }
170
+ return $event_link;
171
+ }
172
+
173
+ /**
174
+ * checks if the events page has changed, and sets a flag to flush wp_rewrite.
175
+ * @param mixed $val
176
+ * @return mixed
177
+ */
178
+ function option_update( $val ){
179
+ if( get_option('dbem_events_page') != $val ){
180
+ update_option('dbem_flush_needed',1);
181
+ }
182
+ return $val;
183
+ }
184
+
185
+ // Adding the id var so that WP recognizes it
186
+ function query_vars($vars){
187
+ foreach(self::$em_queryvars as $em_queryvar){
188
+ array_push($vars, $em_queryvar);
189
+ }
190
+ return $vars;
191
+ }
192
+
193
+ /**
194
+ * Not the "WP way" but for now this'll do!
195
+ */
196
+ function init_objects(){
197
+ global $wp_query, $wp_rewrite;
198
+ //check some homepage conditions
199
+ $events_page_id = get_option ( 'dbem_events_page' );
200
+ if( is_object($wp_query) && $wp_query->is_home && 'page' == get_option('show_on_front') && get_option('page_on_front') == $events_page_id ){
201
+ $wp_query->is_page = true;
202
+ $wp_query->is_home = false;
203
+ $wp_query->query_vars['page_id'] = $events_page_id;
204
+ }
205
+ if ( is_object($wp_query) && is_object($wp_rewrite) && $wp_rewrite->using_permalinks() ) {
206
+ foreach(self::$em_queryvars as $em_queryvar){
207
+ if( $wp_query->get($em_queryvar) ) {
208
+ $_REQUEST[$em_queryvar] = $wp_query->get($em_queryvar);
209
+ }
210
+ }
211
+ }
212
+ //dirty rss condition
213
+ if( !empty($_REQUEST['rss']) ){
214
+ $_REQUEST['rss_main'] = 'main';
215
+ }
216
+ }
217
+ }
218
+ EM_Permalinks::init();
219
+ }
220
+
221
+ //Specific links that aren't generated by objects
222
+
223
+ /**
224
+ * returns the url of the my bookings page, depending on the settings page and if BP is installed.
225
+ * @return string
226
+ */
227
+ function em_get_my_bookings_url(){
228
+ global $bp, $wp_rewrite;
229
+ if( is_object($bp) ){
230
+ //get member url
231
+ return $bp->events->link.'attending/';
232
+ }elseif( get_option('dbem_my_bookings_page') ){
233
+ return get_permalink(get_option('dbem_my_bookings_page'));
234
+ }else{
235
+ if( $wp_rewrite->using_permalinks() && !defined('EM_DISABLE_PERMALINKS') ){
236
+ return trailingslashit(EM_URI)."my-bookings/";
237
+ }else{
238
+ return preg_match('/\?/',EM_URI) ? EM_URI.'&bookings_page=1':EM_URI.'?bookings_page=1';
239
+ }
240
+ }
241
+ }
classes/em-person.php CHANGED
@@ -1,154 +1,93 @@
1
- <?php
2
- // TODO make person details more secure and integrate with WP user data
3
- class EM_Person extends EM_Object{
4
- //DB Fields
5
- var $id = '';
6
- var $owner = '';
7
- var $name = '';
8
- var $email = '';
9
- var $phone = '';
10
- //Other Vars
11
- var $fields = array(
12
- 'person_id' => array('name'=>'id','type'=>'%d'),
13
- 'person_name' => array('name'=>'name','type'=>'%s'),
14
- 'person_email' => array('name'=>'email','type'=>'%s'),
15
- 'person_phone' => array('name'=>'phone','type'=>'%s')
16
- );
17
- var $required_fields = array('person_id', 'person_name', 'person_email', 'person_phone');
18
- var $feedback_message = "";
19
- var $errors = array();
20
-
21
- function EM_Person( $person_data = false ){
22
- if( $person_data != 0 ){
23
- //Load person data
24
- $person = array();
25
- if( is_array($person_data) ){
26
- $person = $person_data;
27
- }elseif( is_numeric($person_data) ){
28
- //Retreiving from the database
29
- global $wpdb;
30
- $sql = "SELECT * FROM ". $wpdb->prefix . EM_PEOPLE_TABLE ." WHERE person_id ='$person_data'";
31
- $person = $wpdb->get_row($sql, ARRAY_A);
32
- }
33
- //Save into the object
34
- $this->to_object($person);
35
- }
36
- }
37
-
38
- /**
39
- * Load an record into this object by passing an associative array of table criterie to search for.
40
- * Returns boolean depending on whether a record is found or not.
41
- * @param $search
42
- * @return boolean
43
- */
44
- function get($search) {
45
- global $wpdb;
46
- $conds = array();
47
- foreach($search as $key => $value) {
48
- if( array_key_exists($key, $this->fields) ){
49
- $conds[] = "`$key`='$value'";
50
- }
51
- }
52
- $sql = "SELECT * FROM ". $wpdb->prefix.EM_PEOPLE_TABLE ." WHERE " . implode(' AND ', $conds) ;
53
- $result = $wpdb->get_row($sql, ARRAY_A);
54
- if($result){
55
- $this->to_object($result);
56
- return true;
57
- }else{
58
- return false;
59
- }
60
- }
61
-
62
- function get_post(){
63
- $this->name = ( !empty($_REQUEST['person_name']) ) ? stripslashes($_REQUEST['person_name']) : '' ;
64
- $this->email = ( !empty($_REQUEST['person_email']) ) ? $_REQUEST['person_email'] : '';
65
- $this->phone = ( !empty($_REQUEST['person_phone']) ) ? $_REQUEST['person_phone'] : '';
66
- return apply_filters('em_person_get_post', $this->validate(), $this);
67
- }
68
-
69
- function save(){
70
- global $wpdb;
71
- do_action('em_person_save_pre',$this);
72
- if($this->validate()){
73
- //Does this person already exist?
74
- $this->load_similar();
75
- $table = $wpdb->prefix.EM_PEOPLE_TABLE;
76
- $data = $this->to_array();
77
- unset($data['person_id']);
78
- if($this->id != ''){
79
- $where = array( 'person_id' => $this->id );
80
- $result = $wpdb->update($table, $data, $where);
81
- }else{
82
- $result = $wpdb->insert($table, $data);
83
- $this->id = $wpdb->insert_id;
84
- }
85
- $this->feedback_message = ($result) ? __('Changes saved.'): __('Could not edit person details.','dbem');
86
- return apply_filters('em_save_delete', $result, $this);
87
- }else{
88
- $this->feedback_message = __('Could not edit person details.','dbem');
89
- return apply_filters('em_save_delete', false, $this);
90
- }
91
- }
92
-
93
- function delete(){
94
- global $wpdb;
95
- do_action('em_person_delete_pre', $this);
96
- $results = array();
97
- $results[] = $wpdb->query ( $wpdb->prepare("DELETE FROM ". $wpdb->prefix . EM_PEOPLE_TABLE ." WHERE person_id=%d", $this->id) );
98
- $results[] = $wpdb->query ( $wpdb->prepare("DELETE FROM ". $wpdb->prefix . EM_BOOKINGS_TABLE ." WHERE person_id=%d", $this->id) );
99
- return apply_filters('em_event_delete', !in_array(false,$results), $this);
100
- }
101
-
102
- function validate(){
103
- if( !preg_match('/^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$/', $this->email) ){
104
- $this->errors[] = __('Please provide a valid email address.', 'dbem');
105
- return false;
106
- }
107
- return true;
108
- }
109
-
110
- function get_bookings(){
111
- global $wpdb;
112
- $results = $wpdb->get_results("SELECT * FROM ".$wpdb->prefix.EM_BOOKINGS_TABLE." WHERE person_id={$this->id}",ARRAY_A);
113
- $bookings = array();
114
- foreach($results as $booking_data){
115
- $bookings[] = new EM_Booking($booking_data);
116
- }
117
- return $bookings;
118
- }
119
-
120
- /**
121
- * Checks agains the database to see if this user exists already
122
- * @return boolean|int
123
- */
124
- function find_similar(){
125
- global $wpdb;
126
- $sql = "SELECT * FROM ". $wpdb->prefix.EM_PEOPLE_TABLE ." WHERE person_name='%s' AND person_email='%s' AND person_phone='%s'";
127
- $row = $wpdb->get_row( $wpdb->prepare($sql, array($this->name, $this->email, $this->phone)), ARRAY_A );
128
- if( is_array($row) ){
129
- return $row['person_id'];
130
- }
131
- return false;
132
- }
133
-
134
- /**
135
- * Checks if a similar record exists (same name, email and phone) and if so it loads
136
- * @return boolean
137
- */
138
- function load_similar(){
139
- $return = $this->find_similar();
140
- if( is_numeric($return) ){
141
- $this->id = $return;
142
- return true;
143
- }
144
- return false;
145
- }
146
-
147
- /**
148
- * Can the user manage this event?
149
- */
150
- function can_manage(){
151
- return ( get_option('dbem_permissions_events') || $this->owner == get_current_user_id() || em_verify_admin() );
152
- }
153
- }
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 EM_Person( $person_id = false, $username = false ){
6
+ if( is_array($person_id) ){
7
+ if( array_key_exists('person_id',$person_id) ){
8
+ $person_id = $person_id['person_id'];
9
+ }elseif ( array_key_exists('user_id',$person_id) ){
10
+ $person_id = $person_id['user_id'];
11
+ }else{
12
+ $person_id = $person_id['ID'];
13
+ }
14
+ }elseif( is_object($person_id) && get_class($person_id) == 'WP_User'){
15
+ $person_id = $person_id->ID; //create new object if passed a wp_user
16
+ }
17
+ if($username){
18
+ parent::__construct($person_id, $username);
19
+ }elseif( is_numeric($person_id) && $person_id == 0 ){
20
+ $this->ID = 0;
21
+ $this->display_name = 'Non-Registered User';
22
+ $this->user_email = 'n/a';
23
+ }else{
24
+ parent::__construct($person_id);
25
+ }
26
+ $this->phone = get_metadata('user', $this->ID, 'dbem_phone', true); //extra field for EM
27
+ do_action('em_person',$this, $person_id, $username);
28
+ }
29
+
30
+ function get_bookings($ids_only = false){
31
+ global $wpdb;
32
+ $blog_condition = '';
33
+ if( is_multisite() ){
34
+ if( !is_main_site() ){
35
+ //not the main blog, force single blog search
36
+ $blog_condition = "AND e.blog_id=".get_current_blog_id();
37
+ }elseif(is_main_site() && !get_option('dbem_ms_global_events')){
38
+ $blog_condition = "AND (e.blog_id=".get_current_blog_id().' OR e.blog_id IS NULL)';
39
+ }
40
+ }
41
+ $EM_Booking = new EM_Booking(); //empty booking for fields
42
+ $results = $wpdb->get_results("SELECT b.".implode(', b.', array_keys($EM_Booking->fields))." FROM ".EM_BOOKINGS_TABLE." b, ".EM_EVENTS_TABLE." e WHERE e.event_id=b.event_id AND person_id={$this->ID} {$blog_condition} ORDER BY ".get_option('dbem_bookings_default_orderby','event_start_date')." ".get_option('dbem_bookings_default_order','ASC'),ARRAY_A);
43
+ $bookings = array();
44
+ if($ids_only){
45
+ foreach($results as $booking_data){
46
+ $bookings[] = $booking_data['booking_id'];
47
+ }
48
+ return apply_filters('em_person_get_bookings', $bookings, $this);
49
+ }else{
50
+ foreach($results as $booking_data){
51
+ $bookings[] = new EM_Booking($booking_data);
52
+ }
53
+ return apply_filters('em_person_get_bookings', new EM_Bookings($bookings), $this);
54
+ }
55
+ }
56
+
57
+ /**
58
+ * @return EM_Events
59
+ */
60
+ function get_events(){
61
+ global $wpdb;
62
+ $events = array();
63
+ foreach( $this->get_bookings()->get_bookings() as $EM_Booking ){
64
+ $events[$EM_Booking->event_id] = $EM_Booking->get_event();
65
+ }
66
+ return apply_filters('em_person_get_events', $events);
67
+ }
68
+
69
+ function display_summary(){
70
+ ob_start();
71
+ ?>
72
+ <table>
73
+ <tr>
74
+ <td><?php echo get_avatar($this->ID); ?></td>
75
+ <td style="padding-left:10px; vertical-align: top;">
76
+ <strong><?php _e('Name','dbem'); ?></strong> : <a href="<?php echo EM_ADMIN_URL ?>&amp;page=events-manager-bookings&amp;person_id=<?php echo $this->ID; ?>"><?php echo $this->get_name() ?></a><br /><br />
77
+ <strong><?php _e('Email','dbem'); ?></strong> : <?php echo $this->user_email; ?><br /><br />
78
+ <strong><?php _e('Phone','dbem'); ?></strong> : <?php echo $this->phone; ?>
79
+ </td>
80
+ </tr>
81
+ </table>
82
+ <?php
83
+ return apply_filters('em_person_displ