Events Manager - Version 5.6.3

Version Description

  • fixed events disappearing from calendar with WP FullCalendar plugin
  • fixed PHP warning for delete booking when a user can't manage booking
  • removed our EM_PHPMailer class and started using the one shipped with WordPress
  • added %passwordurl% placeholder for new user registration email template
  • added check for whether categories are enabled in many areas of code potentially avoiding a array_map PHP notice
  • fixed preview mode duplicating tickets
  • fixed widget formats stripping certain HTML elements
  • fixed erratic date picker range behaviour when adjusting a start date later than the end date
  • fixed original image getting deleted when modifying duplicated event image
  • fixed orderby not including event_date_created and event_date_modified since 5.6.2
  • fixed PHP warning when calling #_ATT to a non-existent attribute
  • changed event debug meta box to display when WP_DEBUG_DISPLAY is also true rather than just WP_DEBUG
  • fixed front-end submission false validation errors when submitting events with bookings enabled
  • changed headers to new h1 standard on WP Dashboard pages
  • fixed bookings admin viewer table not showing specific ticket bookings on front-end
  • fixed ML hooking into em_event_save_meta and messing up the internal hook pointer by triggering it again
  • fixed translated options PHP fatal error in rare occasions/setups
  • fixed deprecated get_currentuserinfo notice in WP 4.5
  • fixed PHP 7 division by zero warning
  • fixed PHP 7 "array to string" notice
  • fixed PHP 7 issues with EM_Ticket validation
  • fixed grouped events list not showing long events on each group provided limit=0 is also supplied
  • fixed apostrophes not passing email validation
  • fixed buddypress fatal error when booking with notifications disabled,
  • fixed buddypress activity stream items being created twice for new bookings
  • fixed booking admin notes not being added in the front-end
  • updated google maps api version and removed deprecated sensor parameter
  • fixed searches not working for search terms containing apostrophes
  • fixed blank settings pages due to 4.5 code changes to wp_get_referer()
  • added em_bookings_deleted action which will execute when one or more bookings are deleted
  • added em_bookings_delete filter for when a group of bookings are deleted with event(s)
  • fixed EM_Bookings->delete() not deleting bookings properly
  • deprecated use of EM_Event->delete_bookings() and EM_Event->delete_tickets() in favor of EM_Event->EM_Bookings->delete()
Download this release

Release Info

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

Code changes from version 5.6.2 to 5.6.3

Files changed (59) hide show
  1. admin/em-admin.php +1 -1
  2. admin/em-bookings.php +26 -46
  3. admin/em-help.php +1 -2
  4. admin/em-ms-options.php +1 -1
  5. admin/em-options.php +7 -8
  6. buddypress/bp-em-activity.php +4 -1
  7. buddypress/bp-em-notifications.php +1 -0
  8. classes/em-booking.php +10 -8
  9. classes/em-bookings.php +5 -2
  10. classes/em-event-post-admin.php +3 -3
  11. classes/em-event.php +42 -28
  12. classes/em-events.php +55 -7
  13. classes/em-locations.php +5 -1
  14. classes/em-mailer.php +3 -3
  15. classes/em-object.php +48 -16
  16. classes/em-person.php +1 -1
  17. classes/em-ticket.php +1 -2
  18. classes/em-tickets-bookings.php +1 -0
  19. classes/phpmailer/class.phpmailer.php +0 -2532
  20. classes/phpmailer/class.smtp.php +0 -818
  21. classes/phpmailer/language/phpmailer.lang-ar.php +0 -27
  22. classes/phpmailer/language/phpmailer.lang-br.php +0 -26
  23. classes/phpmailer/language/phpmailer.lang-ca.php +0 -26
  24. classes/phpmailer/language/phpmailer.lang-ch.php +0 -26
  25. classes/phpmailer/language/phpmailer.lang-cz.php +0 -25
  26. classes/phpmailer/language/phpmailer.lang-de.php +0 -25
  27. classes/phpmailer/language/phpmailer.lang-dk.php +0 -26
  28. classes/phpmailer/language/phpmailer.lang-en.php +0 -23
  29. classes/phpmailer/language/phpmailer.lang-es.php +0 -26
  30. classes/phpmailer/language/phpmailer.lang-et.php +0 -26
  31. classes/phpmailer/language/phpmailer.lang-fi.php +0 -27
  32. classes/phpmailer/language/phpmailer.lang-fo.php +0 -27
  33. classes/phpmailer/language/phpmailer.lang-fr.php +0 -25
  34. classes/phpmailer/language/phpmailer.lang-hu.php +0 -25
  35. classes/phpmailer/language/phpmailer.lang-it.php +0 -27
  36. classes/phpmailer/language/phpmailer.lang-ja.php +0 -26
  37. classes/phpmailer/language/phpmailer.lang-nl.php +0 -25
  38. classes/phpmailer/language/phpmailer.lang-no.php +0 -25
  39. classes/phpmailer/language/phpmailer.lang-pl.php +0 -25
  40. classes/phpmailer/language/phpmailer.lang-ro.php +0 -27
  41. classes/phpmailer/language/phpmailer.lang-ru.php +0 -25
  42. classes/phpmailer/language/phpmailer.lang-se.php +0 -26
  43. classes/phpmailer/language/phpmailer.lang-tr.php +0 -27
  44. classes/phpmailer/language/phpmailer.lang-zh.php +0 -26
  45. classes/phpmailer/language/phpmailer.lang-zh_cn.php +0 -26
  46. em-actions.php +22 -11
  47. em-functions.php +24 -3
  48. em-install.php +1 -2
  49. em-template-tags.php +1 -1
  50. em-wpfc.php +3 -6
  51. events-manager.php +21 -6
  52. includes/js/events-manager-source.js +0 -1263
  53. includes/js/events-manager.js +4 -2
  54. multilingual/em-ml-io.php +11 -0
  55. multilingual/em-ml-options.php +1 -1
  56. readme.txt +38 -3
  57. templates/tables/events.php +7 -5
  58. widgets/em-events.php +2 -1
  59. widgets/em-locations.php +2 -1
admin/em-admin.php CHANGED
@@ -144,7 +144,7 @@ function em_admin_warnings() {
144
  update_option('dbem_hello_to_user',0);
145
  }elseif ( get_option ( 'dbem_hello_to_user' ) ) {
146
  //FIXME update welcome msg with good links
147
- $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>", 'events-manager'), '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');
148
  ?>
149
  <div id="message" class="updated">
150
  <?php echo $advice; ?>
144
  update_option('dbem_hello_to_user',0);
145
  }elseif ( get_option ( 'dbem_hello_to_user' ) ) {
146
  //FIXME update welcome msg with good links
147
+ $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>", 'events-manager'), 'http://wp-events-plugin.com/documentation/getting-started-guide/?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');
148
  ?>
149
  <div id="message" class="updated">
150
  <?php echo $advice; ?>
admin/em-bookings.php CHANGED
@@ -1,20 +1,12 @@
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' && wp_verify_nonce($_REQUEST['_wpnonce'],'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();
@@ -37,10 +29,10 @@ function em_bookings_page(){
37
  em_bookings_single();
38
  }elseif( !empty($_REQUEST['person_id']) ){
39
  em_bookings_person();
40
- }elseif( !empty($_REQUEST['event_id']) ){
41
- em_bookings_event();
42
  }elseif( !empty($_REQUEST['ticket_id']) ){
43
  em_bookings_ticket();
 
 
44
  }else{
45
  em_bookings_dashboard();
46
  }
@@ -54,12 +46,7 @@ function em_bookings_dashboard(){
54
  ?>
55
  <div class='wrap em-bookings-dashboard'>
56
  <?php if( is_admin() ): ?>
57
- <div id='icon-users' class='icon32'>
58
- <br/>
59
- </div>
60
- <h2>
61
- <?php esc_html_e('Event Bookings Dashboard', 'events-manager'); ?>
62
- </h2>
63
  <?php else: echo $EM_Notices; ?>
64
  <?php endif; ?>
65
  <div class="em-bookings-recent">
@@ -94,20 +81,18 @@ function em_bookings_event(){
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', 'events-manager'), "'{$EM_Event->event_name}'"); ?>
104
- <a href="<?php echo $EM_Event->get_permalink(); ?>" class="button add-new-h2"><?php echo sprintf(__('View %s','events-manager'), __('Event', 'events-manager')) ?></a>
105
- <a href="<?php echo $EM_Event->get_edit_url(); ?>" class="button add-new-h2"><?php echo sprintf(__('Edit %s','events-manager'), __('Event', 'events-manager')) ?></a>
106
  <?php if( locate_template('plugins/events-manager/templates/csv-event-bookings.php', false) ): //support for legacy template ?>
107
- <a href='<?php echo EM_ADMIN_URL ."&amp;page=events-manager-bookings&amp;action=bookings_export_csv&amp;_wpnonce=".wp_create_nonce('bookings_export_csv')."&amp;event_id=".$EM_Event->event_id ?>' class="button add-new-h2"><?php esc_html_e('Export CSV','events-manager')?></a>
108
  <?php endif; ?>
109
  <?php do_action('em_admin_event_booking_options_buttons'); ?>
110
- </h2>
111
  <?php if( !is_admin() ) echo $EM_Notices; ?>
112
  <div>
113
  <p><strong><?php esc_html_e('Event Name','events-manager'); ?></strong> : <?php echo esc_html($EM_Event->event_name); ?></p>
@@ -153,16 +138,15 @@ function em_bookings_ticket(){
153
  <?php
154
  return false;
155
  }
 
156
  ?>
157
  <div class='wrap'>
158
- <div id='icon-users' class='icon32'>
159
- <br/>
160
- </div>
161
- <h2>
162
  <?php echo sprintf(__('Ticket for %s', 'events-manager'), "'{$EM_Event->name}'"); ?>
163
- <a href="<?php echo $EM_Event->get_edit_url(); ?>" class="button add-new-h2"><?php esc_html_e('View/Edit Event','events-manager') ?></a>
164
- <a href="<?php echo $EM_Event->get_bookings_url(); ?>" class="button add-new-h2"><?php esc_html_e('View Event Bookings','events-manager') ?></a>
165
- </h2>
 
166
  <?php if( !is_admin() ) echo $EM_Notices; ?>
167
  <div>
168
  <table>
@@ -177,7 +161,6 @@ function em_bookings_ticket(){
177
  <?php do_action('em_booking_admin_ticket_row', $EM_Ticket); ?>
178
  </table>
179
  </div>
180
- <div class="icon32" id="icon-bookings"><br></div>
181
  <h2><?php esc_html_e('Bookings','events-manager'); ?></h2>
182
  <?php
183
  $EM_Bookings_Table = new EM_Bookings_Table();
@@ -203,10 +186,10 @@ function em_bookings_single(){
203
  }
204
  ?>
205
  <div class='wrap' id="em-bookings-admin-booking">
206
- <div class="icon32" id="icon-bookings"><br></div>
207
- <h2>
208
  <?php esc_html_e('Edit Booking', 'events-manager'); ?>
209
- </h2>
 
210
  <div id="poststuff" class="metabox-holder">
211
  <div id="post-body">
212
  <div id="post-body-content">
@@ -505,20 +488,18 @@ function em_bookings_person(){
505
  <?php
506
  return false;
507
  }
 
508
  ?>
509
  <div class='wrap'>
510
- <div id='icon-users' class='icon32'>
511
- <br/>
512
- </div>
513
- <h2>
514
  <?php esc_html_e('Manage Person\'s Booking', 'events-manager'); ?>
515
  <?php if( current_user_can('edit_users') ) : ?>
516
- <a href="<?php echo admin_url('user-edit.php?user_id='.$EM_Person->ID); ?>" class="button add-new-h2"><?php esc_html_e('Edit User','events-manager') ?></a>
517
  <?php endif; ?>
518
  <?php if( current_user_can('delete_users') ) : ?>
519
- <a href="<?php echo wp_nonce_url( admin_url("users.php?action=delete&amp;user=$EM_Person->ID"), 'bulk-users' ); ?>" class="button add-new-h2"><?php esc_html_e('Delete User','events-manager') ?></a>
520
  <?php endif; ?>
521
- </h2>
522
  <?php if( !is_admin() ) echo $EM_Notices; ?>
523
  <?php do_action('em_bookings_person_header'); ?>
524
  <div id="poststuff" class="metabox-holder has-right-sidebar">
@@ -537,7 +518,6 @@ function em_bookings_person(){
537
  </div>
538
  <br style="clear:both;" />
539
  <?php do_action('em_bookings_person_body_1'); ?>
540
- <div class="icon32" id="icon-bookings"><br></div>
541
  <h2><?php esc_html_e('Past And Present Bookings','events-manager'); ?></h2>
542
  <?php
543
  $EM_Bookings_Table = new EM_Bookings_Table();
1
  <?php
2
  /**
3
+ * Deprecated - see em-actions.php - this will be removed at some point in 6.0
4
  * Check if there's any admin-related actions to take for bookings. All actions are caught here.
5
  * @return null
6
+ * @todo remove in 6.0
7
  */
8
  function em_admin_actions_bookings() {
9
+ global $EM_Event;
 
 
 
 
 
 
 
 
 
 
10
  if( is_object($EM_Event) && !empty($_REQUEST['action']) ){
11
  if( $_REQUEST['action'] == 'bookings_export_csv' && wp_verify_nonce($_REQUEST['_wpnonce'],'bookings_export_csv') ){
12
  $EM_Event->get_bookings()->export_csv();
29
  em_bookings_single();
30
  }elseif( !empty($_REQUEST['person_id']) ){
31
  em_bookings_person();
 
 
32
  }elseif( !empty($_REQUEST['ticket_id']) ){
33
  em_bookings_ticket();
34
+ }elseif( !empty($_REQUEST['event_id']) ){
35
+ em_bookings_event();
36
  }else{
37
  em_bookings_dashboard();
38
  }
46
  ?>
47
  <div class='wrap em-bookings-dashboard'>
48
  <?php if( is_admin() ): ?>
49
+ <h1><?php esc_html_e('Event Bookings Dashboard', 'events-manager'); ?></h1>
 
 
 
 
 
50
  <?php else: echo $EM_Notices; ?>
51
  <?php endif; ?>
52
  <div class="em-bookings-recent">
81
  }
82
  $localised_start_date = date_i18n('D d M Y', $EM_Event->start);
83
  $localised_end_date = date_i18n('D d M Y', $EM_Event->end);
84
+ $header_button_classes = is_admin() ? 'page-title-action':'button add-new-h2';
85
  ?>
86
  <div class='wrap'>
87
+ <?php if( is_admin() ): ?><h1><?php else: ?><h2><?php endif; ?>
 
 
 
88
  <?php echo sprintf(__('Manage %s Bookings', 'events-manager'), "'{$EM_Event->event_name}'"); ?>
89
+ <a href="<?php echo $EM_Event->get_permalink(); ?>" class="<?php echo $header_button_classes; ?>"><?php echo sprintf(__('View %s','events-manager'), __('Event', 'events-manager')) ?></a>
90
+ <a href="<?php echo $EM_Event->get_edit_url(); ?>" class="<?php echo $header_button_classes; ?>"><?php echo sprintf(__('Edit %s','events-manager'), __('Event', 'events-manager')) ?></a>
91
  <?php if( locate_template('plugins/events-manager/templates/csv-event-bookings.php', false) ): //support for legacy template ?>
92
+ <a href='<?php echo EM_ADMIN_URL ."&amp;page=events-manager-bookings&amp;action=bookings_export_csv&amp;_wpnonce=".wp_create_nonce('bookings_export_csv')."&amp;event_id=".$EM_Event->event_id ?>' class="<?php echo $header_button_classes; ?>"><?php esc_html_e('Export CSV','events-manager')?></a>
93
  <?php endif; ?>
94
  <?php do_action('em_admin_event_booking_options_buttons'); ?>
95
+ <?php if( !is_admin() ): ?></h2><?php else: ?></h1><?php endif; ?>
96
  <?php if( !is_admin() ) echo $EM_Notices; ?>
97
  <div>
98
  <p><strong><?php esc_html_e('Event Name','events-manager'); ?></strong> : <?php echo esc_html($EM_Event->event_name); ?></p>
138
  <?php
139
  return false;
140
  }
141
+ $header_button_classes = is_admin() ? 'page-title-action':'button add-new-h2';
142
  ?>
143
  <div class='wrap'>
144
+ <?php if( is_admin() ): ?><h1><?php else: ?><h2><?php endif; ?>
 
 
 
145
  <?php echo sprintf(__('Ticket for %s', 'events-manager'), "'{$EM_Event->name}'"); ?>
146
+ <a href="<?php echo $EM_Event->get_edit_url(); ?>" class="<?php echo $header_button_classes; ?>"><?php esc_html_e('View/Edit Event','events-manager') ?></a>
147
+ <a href="<?php echo $EM_Event->get_bookings_url(); ?>" class="<?php echo $header_button_classes; ?>"><?php esc_html_e('View Event Bookings','events-manager') ?></a>
148
+
149
+ <?php if( !is_admin() ): ?></h2><?php else: ?></h1><?php endif; ?>
150
  <?php if( !is_admin() ) echo $EM_Notices; ?>
151
  <div>
152
  <table>
161
  <?php do_action('em_booking_admin_ticket_row', $EM_Ticket); ?>
162
  </table>
163
  </div>
 
164
  <h2><?php esc_html_e('Bookings','events-manager'); ?></h2>
165
  <?php
166
  $EM_Bookings_Table = new EM_Bookings_Table();
186
  }
187
  ?>
188
  <div class='wrap' id="em-bookings-admin-booking">
189
+ <?php if( is_admin() ): ?><h1><?php else: ?><h2><?php endif; ?>
 
190
  <?php esc_html_e('Edit Booking', 'events-manager'); ?>
191
+ <?php if( !is_admin() ): ?></h2><?php else: ?></h1><?php endif; ?>
192
+ <?php if( !is_admin() ) echo $EM_Notices; ?>
193
  <div id="poststuff" class="metabox-holder">
194
  <div id="post-body">
195
  <div id="post-body-content">
488
  <?php
489
  return false;
490
  }
491
+ $header_button_classes = is_admin() ? 'page-title-action':'button add-new-h2';
492
  ?>
493
  <div class='wrap'>
494
+ <?php if( is_admin() ): ?><h1><?php else: ?><h2><?php endif; ?>
 
 
 
495
  <?php esc_html_e('Manage Person\'s Booking', 'events-manager'); ?>
496
  <?php if( current_user_can('edit_users') ) : ?>
497
+ <a href="<?php echo admin_url('user-edit.php?user_id='.$EM_Person->ID); ?>" class="<?php echo $header_button_classes; ?>"><?php esc_html_e('Edit User','events-manager') ?></a>
498
  <?php endif; ?>
499
  <?php if( current_user_can('delete_users') ) : ?>
500
+ <a href="<?php echo wp_nonce_url( admin_url("users.php?action=delete&amp;user=$EM_Person->ID"), 'bulk-users' ); ?>" class="<?php echo $header_button_classes; ?>"><?php esc_html_e('Delete User','events-manager') ?></a>
501
  <?php endif; ?>
502
+ <?php if( !is_admin() ): ?></h2><?php else: ?></h1><?php endif; ?>
503
  <?php if( !is_admin() ) echo $EM_Notices; ?>
504
  <?php do_action('em_bookings_person_header'); ?>
505
  <div id="poststuff" class="metabox-holder has-right-sidebar">
518
  </div>
519
  <br style="clear:both;" />
520
  <?php do_action('em_bookings_person_body_1'); ?>
 
521
  <h2><?php esc_html_e('Past And Present Bookings','events-manager'); ?></h2>
522
  <?php
523
  $EM_Bookings_Table = new EM_Bookings_Table();
admin/em-help.php CHANGED
@@ -6,8 +6,7 @@ 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','events-manager'); ?></h2>
11
  <div class="em-docs">
12
  <h2>Where To Get Help</h3>
13
  <p>
6
  global $wpdb;
7
  ?>
8
  <div class="wrap">
9
+ <h1><?php _e('Getting Help for Events Manager','events-manager'); ?></h1>
 
10
  <div class="em-docs">
11
  <h2>Where To Get Help</h3>
12
  <p>
admin/em-ms-options.php CHANGED
@@ -125,10 +125,10 @@ function em_ms_admin_options_page() {
125
  <style type="text/css">.postbox h3 { cursor:pointer; }</style>
126
  <div class="wrap">
127
  <div id='icon-options-general' class='icon32'><br /></div>
 
128
  <h2 class="nav-tab-wrapper">
129
  <a href="#" id="em-menu-general" class="nav-tab nav-tab-active"><?php esc_html_e('General','events-manager'); ?></a>
130
  </h2>
131
- <h3 id="em-options-title"><?php _e ( 'Event Manager Options', 'events-manager'); ?></h3>
132
  <?php echo $EM_Notices; ?>
133
  <form id="em-options-form" method="post" action="">
134
  <div class="metabox-holder">
125
  <style type="text/css">.postbox h3 { cursor:pointer; }</style>
126
  <div class="wrap">
127
  <div id='icon-options-general' class='icon32'><br /></div>
128
+ <h1 id="em-options-title"><?php _e ( 'Event Manager Options', 'events-manager'); ?></h1>
129
  <h2 class="nav-tab-wrapper">
130
  <a href="#" id="em-menu-general" class="nav-tab nav-tab-active"><?php esc_html_e('General','events-manager'); ?></a>
131
  </h2>
 
132
  <?php echo $EM_Notices; ?>
133
  <form id="em-options-form" method="post" action="">
134
  <div class="metabox-holder">
admin/em-options.php CHANGED
@@ -67,7 +67,7 @@ function em_options_save(){
67
  update_option('dbem_flush_needed',1);
68
  do_action('em_options_save');
69
  $EM_Notices->add_confirm('<strong>'.__('Changes saved.', 'events-manager').'</strong>', true);
70
- wp_redirect(wp_get_referer());
71
  exit();
72
  }
73
  //Migration
@@ -149,7 +149,7 @@ function em_options_save(){
149
  delete_transient('update_plugins');
150
  delete_site_transient('update_plugins');
151
  $EM_Notices->add_confirm(__('If there are any new updates, you should now see them in your Plugins or Updates admin pages.','events-manager'), true);
152
- wp_redirect(wp_get_referer());
153
  exit();
154
  }
155
  //Flag version checking to look at trunk, not tag
@@ -159,7 +159,7 @@ function em_options_save(){
159
  delete_site_transient('update_plugins');
160
  update_option('em_check_dev_version', true);
161
  $EM_Notices->add_confirm(__('Checking for dev versions.','events-manager').' '. __('If there are any new updates, you should now see them in your Plugins or Updates admin pages.','events-manager'), true);
162
- wp_redirect(wp_get_referer());
163
  exit();
164
  }
165
 
@@ -218,7 +218,7 @@ function em_admin_options_reset_page(){
218
  <p style="font-weight:bold;"><?php _e('All your settings, including email templates and template formats for Events Manager will be deleted.','events-manager')?></p>
219
  <p>
220
  <a href="<?php echo esc_url(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','events-manager'); ?></a>
221
- <a href="<?php echo wp_get_referer(); ?>" class="button-secondary"><?php _e('Cancel','events-manager'); ?></a>
222
  </p>
223
  </div>
224
  <?php
@@ -235,7 +235,7 @@ function em_admin_options_uninstall_page(){
235
  <p><?php echo sprintf(__('If you just want to deactivate the plugin, <a href="%s">go to your plugins page</a>.','events-manager'), wp_nonce_url(admin_url('plugins.php'))); ?></p>
236
  <p>
237
  <a href="<?php echo esc_url(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','events-manager'); ?></a>
238
- <a href="<?php echo wp_get_referer(); ?>" class="button-secondary"><?php _e('Cancel','events-manager'); ?></a>
239
  </p>
240
  </div>
241
  <?php
@@ -285,8 +285,8 @@ function em_admin_options_page() {
285
  ?>
286
  <script type="text/javascript" charset="utf-8"><?php include(EM_DIR.'/includes/js/admin-settings.js'); ?></script>
287
  <style type="text/css">.postbox h3 { cursor:pointer; }</style>
288
- <div class="wrap <?php if(empty($tabs_enabled)) echo 'tabs-active' ?>">
289
- <div id='icon-options-general' class='icon32'><br /></div>
290
  <h2 class="nav-tab-wrapper">
291
  <a href="<?php echo $general_tab_link; ?>#general" id="em-menu-general" class="nav-tab nav-tab-active"><?php _e('General','events-manager'); ?></a>
292
  <a href="<?php echo $pages_tab_link; ?>#pages" id="em-menu-pages" class="nav-tab"><?php _e('Pages','events-manager'); ?></a>
@@ -296,7 +296,6 @@ function em_admin_options_page() {
296
  <?php endif; ?>
297
  <a href="<?php echo $emails_tab_link; ?>#emails" id="em-menu-emails" class="nav-tab"><?php _e('Emails','events-manager'); ?></a>
298
  </h2>
299
- <h3 id="em-options-title"><?php _e ( 'Event Manager Options', 'events-manager'); ?></h3>
300
  <form id="em-options-form" method="post" action="">
301
  <div class="metabox-holder">
302
  <!-- // TODO Move style in css -->
67
  update_option('dbem_flush_needed',1);
68
  do_action('em_options_save');
69
  $EM_Notices->add_confirm('<strong>'.__('Changes saved.', 'events-manager').'</strong>', true);
70
+ wp_redirect(em_wp_get_referer());
71
  exit();
72
  }
73
  //Migration
149
  delete_transient('update_plugins');
150
  delete_site_transient('update_plugins');
151
  $EM_Notices->add_confirm(__('If there are any new updates, you should now see them in your Plugins or Updates admin pages.','events-manager'), true);
152
+ wp_redirect(em_wp_get_referer());
153
  exit();
154
  }
155
  //Flag version checking to look at trunk, not tag
159
  delete_site_transient('update_plugins');
160
  update_option('em_check_dev_version', true);
161
  $EM_Notices->add_confirm(__('Checking for dev versions.','events-manager').' '. __('If there are any new updates, you should now see them in your Plugins or Updates admin pages.','events-manager'), true);
162
+ wp_redirect(em_wp_get_referer());
163
  exit();
164
  }
165
 
218
  <p style="font-weight:bold;"><?php _e('All your settings, including email templates and template formats for Events Manager will be deleted.','events-manager')?></p>
219
  <p>
220
  <a href="<?php echo esc_url(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','events-manager'); ?></a>
221
+ <a href="<?php echo esc_url(em_wp_get_referer()); ?>" class="button-secondary"><?php _e('Cancel','events-manager'); ?></a>
222
  </p>
223
  </div>
224
  <?php
235
  <p><?php echo sprintf(__('If you just want to deactivate the plugin, <a href="%s">go to your plugins page</a>.','events-manager'), wp_nonce_url(admin_url('plugins.php'))); ?></p>
236
  <p>
237
  <a href="<?php echo esc_url(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','events-manager'); ?></a>
238
+ <a href="<?php echo esc_url(em_wp_get_referer()); ?>" class="button-secondary"><?php _e('Cancel','events-manager'); ?></a>
239
  </p>
240
  </div>
241
  <?php
285
  ?>
286
  <script type="text/javascript" charset="utf-8"><?php include(EM_DIR.'/includes/js/admin-settings.js'); ?></script>
287
  <style type="text/css">.postbox h3 { cursor:pointer; }</style>
288
+ <div class="wrap <?php if(empty($tabs_enabled)) echo 'tabs-active' ?>">
289
+ <h1 id="em-options-title"><?php _e ( 'Event Manager Options', 'events-manager'); ?></h1>
290
  <h2 class="nav-tab-wrapper">
291
  <a href="<?php echo $general_tab_link; ?>#general" id="em-menu-general" class="nav-tab nav-tab-active"><?php _e('General','events-manager'); ?></a>
292
  <a href="<?php echo $pages_tab_link; ?>#pages" id="em-menu-pages" class="nav-tab"><?php _e('Pages','events-manager'); ?></a>
296
  <?php endif; ?>
297
  <a href="<?php echo $emails_tab_link; ?>#emails" id="em-menu-emails" class="nav-tab"><?php _e('Emails','events-manager'); ?></a>
298
  </h2>
 
299
  <form id="em-options-form" method="post" action="">
300
  <div class="metabox-holder">
301
  <!-- // TODO Move style in css -->
buddypress/bp-em-activity.php CHANGED
@@ -159,7 +159,11 @@ add_filter('em_event_save','bp_em_record_activity_event_save', 10, 2);
159
  * @return boolean
160
  */
161
  function bp_em_record_activity_booking_save( $result, $EM_Booking ){
 
162
  if( !empty($EM_Booking->event_id) && $result ){
 
 
 
163
  $rejected_statuses = array(0,2,3); //these statuses apply to rejected/cancelled bookings
164
  $user = $EM_Booking->get_person();
165
  $member_link = bp_core_get_user_domain($user->ID);
@@ -167,7 +171,6 @@ function bp_em_record_activity_booking_save( $result, $EM_Booking ){
167
  $event_link = $EM_Booking->get_event()->output('#_EVENTLINK');
168
  $status = $EM_Booking->booking_status;
169
  $EM_Event = $EM_Booking->get_event();
170
- $action_type = 'new_booking';
171
  if( empty($EM_Event->group_id) ){
172
  if( $status == 1 || (!get_option('dbem_bookings_approval') && $status < 2) ){
173
  $action = sprintf(__('%s is attending %s.','events-manager'), $user_link, $event_link );
159
  * @return boolean
160
  */
161
  function bp_em_record_activity_booking_save( $result, $EM_Booking ){
162
+ /* @todo this isn't good at detecting status changes. */
163
  if( !empty($EM_Booking->event_id) && $result ){
164
+ $action_type = 'new_booking';
165
+ if( !empty($EM_Booking->last_bp_activity) && $EM_Booking->last_bp_activity == $action_type ) return $result; //prevent duplicates
166
+ $EM_Booking->last_bp_activity = $action_type;
167
  $rejected_statuses = array(0,2,3); //these statuses apply to rejected/cancelled bookings
168
  $user = $EM_Booking->get_person();
169
  $member_link = bp_core_get_user_domain($user->ID);
171
  $event_link = $EM_Booking->get_event()->output('#_EVENTLINK');
172
  $status = $EM_Booking->booking_status;
173
  $EM_Event = $EM_Booking->get_event();
 
174
  if( empty($EM_Event->group_id) ){
175
  if( $status == 1 || (!get_option('dbem_bookings_approval') && $status < 2) ){
176
  $action = sprintf(__('%s is attending %s.','events-manager'), $user_link, $event_link );
buddypress/bp-em-notifications.php CHANGED
@@ -71,6 +71,7 @@ add_action( 'xprofile_screen_display_profile', 'bp_em_remove_screen_notification
71
  */
72
  function bp_em_add_booking_notification($result, $EM_Booking){
73
  global $bp;
 
74
  if( get_option('dbem_bookings_approval') && $EM_Booking->get_status() == 0 ){
75
  $action = 'pending_booking';
76
  }elseif( $EM_Booking->get_status() == 1 || (get_option('dbem_bookings_approval') && $EM_Booking->get_status() == 0) ){
71
  */
72
  function bp_em_add_booking_notification($result, $EM_Booking){
73
  global $bp;
74
+ if( !function_exists('bp_notifications_add_notification') ) return $result; //no need if notifications are disabled
75
  if( get_option('dbem_bookings_approval') && $EM_Booking->get_status() == 0 ){
76
  $action = 'pending_booking';
77
  }elseif( $EM_Booking->get_status() == 1 || (get_option('dbem_bookings_approval') && $EM_Booking->get_status() == 0) ){
classes/em-booking.php CHANGED
@@ -645,22 +645,23 @@ class EM_Booking extends EM_Object{
645
  $registration = true;
646
  if( empty($this->booking_meta['registration']) ) $this->booking_meta['registration'] = array();
647
  // Check the e-mail address
648
- if ( $_REQUEST['user_email'] == '' ) {
 
649
  $registration = false;
650
  $this->add_error(__( '<strong>ERROR</strong>: Please type your e-mail address.', 'events-manager') );
651
- } elseif ( !is_email( $_REQUEST['user_email'] ) ) {
652
  $registration = false;
653
  $this->add_error( __( '<strong>ERROR</strong>: The email address isn&#8217;t correct.', 'events-manager') );
654
- }elseif(email_exists( $_REQUEST['user_email'] ) && !get_option('dbem_bookings_registration_disable_user_emails') ){
655
  $registration = false;
656
  $this->add_error( get_option('dbem_booking_feedback_email_exists') );
657
  }else{
658
- $user_data['user_email'] = $_REQUEST['user_email'];
659
  }
660
  //Check the user name
661
  if( !empty($_REQUEST['user_name']) ){
662
  //split full name up and save full, first and last names
663
- $user_data['user_name'] = wp_kses($_REQUEST['user_name'], array());
664
  $name_string = explode(' ',$user_data['user_name']);
665
  $user_data['first_name'] = array_shift($name_string);
666
  $user_data['last_name'] = implode(' ', $name_string);
@@ -668,10 +669,10 @@ class EM_Booking extends EM_Object{
668
  //Check the first/last name
669
  $name_string = array();
670
  if( !empty($_REQUEST['first_name']) ){
671
- $user_data['first_name'] = $name_string[] = wp_kses($_REQUEST['first_name'], array());
672
  }
673
  if( !empty($_REQUEST['last_name']) ){
674
- $user_data['last_name'] = $name_string[] = wp_kses($_REQUEST['last_name'], array());
675
  }
676
  if( !empty($name_string) ) $user_data['user_name'] = implode(' ', $name_string);
677
  }
@@ -679,7 +680,7 @@ class EM_Booking extends EM_Object{
679
  if( !empty($user_data['first_name']) || !empty($user_data['last_name']) )
680
  //Check the phone
681
  if( !empty($_REQUEST['dbem_phone']) ){
682
- $user_data['dbem_phone'] = wp_kses($_REQUEST['dbem_phone'], array());
683
  }
684
  //Add booking meta
685
  if( $registration ){
@@ -746,6 +747,7 @@ class EM_Booking extends EM_Object{
746
  $this->add_error(sprintf(__('%s could not be deleted', 'events-manager'), __('Booking','events-manager')));
747
  }
748
  }
 
749
  return apply_filters('em_booking_delete',( $result !== false ), $this);
750
  }
751
 
645
  $registration = true;
646
  if( empty($this->booking_meta['registration']) ) $this->booking_meta['registration'] = array();
647
  // Check the e-mail address
648
+ $user_email = stripslashes($_REQUEST['user_email']); //apostrophes will not be allowed otherwise
649
+ if ( $user_email == '' ) {
650
  $registration = false;
651
  $this->add_error(__( '<strong>ERROR</strong>: Please type your e-mail address.', 'events-manager') );
652
+ } elseif ( !is_email( $user_email ) ) {
653
  $registration = false;
654
  $this->add_error( __( '<strong>ERROR</strong>: The email address isn&#8217;t correct.', 'events-manager') );
655
+ }elseif(email_exists( $user_email ) && !get_option('dbem_bookings_registration_disable_user_emails') ){
656
  $registration = false;
657
  $this->add_error( get_option('dbem_booking_feedback_email_exists') );
658
  }else{
659
+ $user_data['user_email'] = $user_email;
660
  }
661
  //Check the user name
662
  if( !empty($_REQUEST['user_name']) ){
663
  //split full name up and save full, first and last names
664
+ $user_data['user_name'] = wp_kses(stripslashes($_REQUEST['user_name']), array());
665
  $name_string = explode(' ',$user_data['user_name']);
666
  $user_data['first_name'] = array_shift($name_string);
667
  $user_data['last_name'] = implode(' ', $name_string);
669
  //Check the first/last name
670
  $name_string = array();
671
  if( !empty($_REQUEST['first_name']) ){
672
+ $user_data['first_name'] = $name_string[] = wp_kses(stripslashes($_REQUEST['first_name']), array());
673
  }
674
  if( !empty($_REQUEST['last_name']) ){
675
+ $user_data['last_name'] = $name_string[] = wp_kses(stripslashes($_REQUEST['last_name']), array());
676
  }
677
  if( !empty($name_string) ) $user_data['user_name'] = implode(' ', $name_string);
678
  }
680
  if( !empty($user_data['first_name']) || !empty($user_data['last_name']) )
681
  //Check the phone
682
  if( !empty($_REQUEST['dbem_phone']) ){
683
+ $user_data['dbem_phone'] = wp_kses(stripslashes($_REQUEST['dbem_phone']), array());
684
  }
685
  //Add booking meta
686
  if( $registration ){
747
  $this->add_error(sprintf(__('%s could not be deleted', 'events-manager'), __('Booking','events-manager')));
748
  }
749
  }
750
+ do_action('em_bookings_deleted', $result, array($this->booking_id));
751
  return apply_filters('em_booking_delete',( $result !== false ), $this);
752
  }
753
 
classes/em-bookings.php CHANGED
@@ -260,9 +260,10 @@ class EM_Bookings extends EM_Object implements Iterator{
260
  if( count($booking_ids) > 0 ){
261
  //Delete bookings and ticket bookings
262
  $result_tickets = $wpdb->query("DELETE FROM ". EM_TICKETS_BOOKINGS_TABLE ." WHERE booking_id IN (".implode(',',$booking_ids).");");
263
- $result = $wpdb->query("DELETE FROM ".EM_BOOKINGS_TABLE." WHERE event_id IN (".implode(',',$booking_ids).")");
264
  }
265
- return ($result !== false && $result_tickets !== false);
 
266
  }
267
 
268
 
@@ -572,6 +573,8 @@ class EM_Bookings extends EM_Object implements Iterator{
572
 
573
 
574
  //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.
 
 
575
  function export_csv() {
576
  global $EM_Event;
577
  if($EM_Event->event_id != $this->event_id ){
260
  if( count($booking_ids) > 0 ){
261
  //Delete bookings and ticket bookings
262
  $result_tickets = $wpdb->query("DELETE FROM ". EM_TICKETS_BOOKINGS_TABLE ." WHERE booking_id IN (".implode(',',$booking_ids).");");
263
+ $result = $wpdb->query("DELETE FROM ".EM_BOOKINGS_TABLE." WHERE booking_id IN (".implode(',',$booking_ids).")");
264
  }
265
+ do_action('em_bookings_deleted', $result, $booking_ids);
266
+ return apply_filters('em_bookings_delete', $result !== false && $result_tickets !== false, $booking_ids, $this);
267
  }
268
 
269
 
573
 
574
 
575
  //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.
576
+ //Deprecated
577
+ //@todo remove in 6.0
578
  function export_csv() {
579
  global $EM_Event;
580
  if($EM_Event->event_id != $this->event_id ){
classes/em-event-post-admin.php CHANGED
@@ -122,7 +122,7 @@ class EM_Event_Post_Admin{
122
  if( key($wp_filter[$tag]) == $wp_filter_priority ) break;
123
  }while ( next($wp_filter[$tag]) !== false );
124
  //save categories in case of default category
125
- $EM_Event->get_categories()->save();
126
  //continue whether all went well or not
127
  if( !$get_meta || !$validate_meta || !$save_meta ){
128
  //failed somewhere, set to draft, don't publish
@@ -238,7 +238,7 @@ class EM_Event_Post_Admin{
238
  if(get_option('dbem_locations_enabled', true)){
239
  add_meta_box('em-event-where', __('Where','events-manager'), array('EM_Event_Post_Admin','meta_box_location'),EM_POST_TYPE_EVENT, 'normal','high');
240
  }
241
- if( defined('WP_DEBUG') && WP_DEBUG ){
242
  add_meta_box('em-event-meta', 'Event Meta (debugging only)', array('EM_Event_Post_Admin','meta_box_metadump'),EM_POST_TYPE_EVENT, 'normal','high');
243
  }
244
  if( get_option('dbem_rsvp_enabled', true) && $EM_Event->can_manage('manage_bookings','manage_others_bookings') ){
@@ -467,7 +467,7 @@ class EM_Event_Recurring_Post_Admin{
467
  if( EM_MS_GLOBAL && !is_main_site() && get_option('dbem_categories_enabled') ){
468
  add_meta_box('em-event-categories', __('Site Categories','events-manager'), array('EM_Event_Post_Admin','meta_box_ms_categories'),'event-recurring', 'side','low');
469
  }
470
- if( defined('WP_DEBUG') && WP_DEBUG ){
471
  add_meta_box('em-event-meta', 'Event Meta (debugging only)', array('EM_Event_Post_Admin','meta_box_metadump'),'event-recurring', 'normal','high');
472
  }
473
  }
122
  if( key($wp_filter[$tag]) == $wp_filter_priority ) break;
123
  }while ( next($wp_filter[$tag]) !== false );
124
  //save categories in case of default category
125
+ if( get_option('dbem_categories_enabled') ) $EM_Event->get_categories()->save();
126
  //continue whether all went well or not
127
  if( !$get_meta || !$validate_meta || !$save_meta ){
128
  //failed somewhere, set to draft, don't publish
238
  if(get_option('dbem_locations_enabled', true)){
239
  add_meta_box('em-event-where', __('Where','events-manager'), array('EM_Event_Post_Admin','meta_box_location'),EM_POST_TYPE_EVENT, 'normal','high');
240
  }
241
+ if( defined('WP_DEBUG') && WP_DEBUG && defined('WP_DEBUG_DISPLAY') && WP_DEBUG_DISPLAY ){
242
  add_meta_box('em-event-meta', 'Event Meta (debugging only)', array('EM_Event_Post_Admin','meta_box_metadump'),EM_POST_TYPE_EVENT, 'normal','high');
243
  }
244
  if( get_option('dbem_rsvp_enabled', true) && $EM_Event->can_manage('manage_bookings','manage_others_bookings') ){
467
  if( EM_MS_GLOBAL && !is_main_site() && get_option('dbem_categories_enabled') ){
468
  add_meta_box('em-event-categories', __('Site Categories','events-manager'), array('EM_Event_Post_Admin','meta_box_ms_categories'),'event-recurring', 'side','low');
469
  }
470
+ if( defined('WP_DEBUG') && WP_DEBUG && defined('WP_DEBUG_DISPLAY') && WP_DEBUG_DISPLAY ){
471
  add_meta_box('em-event-meta', 'Event Meta (debugging only)', array('EM_Event_Post_Admin','meta_box_metadump'),'event-recurring', 'normal','high');
472
  }
473
  }
classes/em-event.php CHANGED
@@ -260,7 +260,6 @@ class EM_Event extends EM_Object{
260
  $this->load_postdata($event_post, $search_by);
261
  }
262
  $this->recurrence = $this->is_recurring() ? 1:0;
263
- //if(defined('trashtest')){ print_r($this); die("got here");}
264
  //Do it here so things appear in the po file.
265
  $this->status_array = array(
266
  0 => __('Pending','events-manager'),
@@ -369,7 +368,7 @@ class EM_Event extends EM_Object{
369
  $this->event_name = !empty($_POST['event_name']) ? htmlspecialchars_decode(wp_kses_data(htmlspecialchars_decode(stripslashes($_POST['event_name'])))):'';
370
  $this->post_type = ($this->is_recurring() || !empty($_POST['recurring'])) ? 'event-recurring':EM_POST_TYPE_EVENT;
371
  //don't forget categories!
372
- $this->get_categories()->get_post();
373
  //anonymous submissions and guest basic info
374
  if( !is_user_logged_in() && get_option('dbem_events_anonymous_submissions') && empty($this->event_id) ){
375
  $this->event_owner_anonymous = 1;
@@ -432,7 +431,8 @@ class EM_Event extends EM_Object{
432
  $this->end = strtotime($this->event_end_date." ".$this->event_end_time);
433
  //Bookings
434
  $can_manage_bookings = $this->can_manage('manage_bookings','manage_others_bookings');
435
- if( $can_manage_bookings && !empty($_POST['event_rsvp']) && $_POST['event_rsvp'] ){
 
436
  $this->get_bookings()->get_tickets()->get_post();
437
  $this->event_rsvp = 1;
438
  //RSVP cuttoff TIME is set up above where start/end times are as well
@@ -496,7 +496,7 @@ class EM_Event extends EM_Object{
496
  }
497
  $this->event_spaces = ( isset($_POST['event_spaces']) ) ? absint($_POST['event_spaces']):0;
498
  $this->event_rsvp_spaces = ( isset($_POST['event_rsvp_spaces']) ) ? absint($_POST['event_rsvp_spaces']):0;
499
- }elseif( $can_manage_bookings || !$this->event_rsvp ){
500
  $this->event_rsvp = 0;
501
  $this->event_rsvp_time = '00:00:00';
502
  }
@@ -509,7 +509,7 @@ class EM_Event extends EM_Object{
509
  foreach($_POST['em_attributes'] as $att_key => $att_value ){
510
  if( (in_array($att_key, $event_available_attributes['names']) || array_key_exists($att_key, $this->event_attributes) ) ){
511
  $this->event_attributes[$att_key] = '';
512
- $att_vals = count($event_available_attributes['values'][$att_key]);
513
  if( !empty($att_value) ){
514
  if( $att_vals <= 1 || ($att_vals > 1 && in_array($att_value, $event_available_attributes['values'][$att_key])) ){
515
  $this->event_attributes[$att_key] = stripslashes($att_value);
@@ -542,7 +542,7 @@ class EM_Event extends EM_Object{
542
  $this->recurrence_days = ( !empty($_POST['recurrence_days']) && is_numeric($_POST['recurrence_days']) ) ? (int) $_POST['recurrence_days']:0;
543
  }
544
  //categories in MS GLobal
545
- if(EM_MS_GLOBAL && !is_main_site()){
546
  $this->get_categories()->get_post(); //it'll know what to do
547
  }
548
  //validate (optional) and return result
@@ -678,10 +678,12 @@ class EM_Event extends EM_Object{
678
  $this->event_owner = $post_data->post_author;
679
  $this->post_status = $post_data->post_status;
680
  $this->get_status();
681
- //Categories? note that categories will soft-fail, so no errors
682
- $this->get_categories()->event_id = $this->event_id;
683
- $this->categories->post_id = $this->post_id;
684
- $this->categories->save();
 
 
685
  //anonymous submissions should save this information
686
  if( !empty($this->event_owner_anonymous) ){
687
  update_post_meta($this->post_id, '_event_owner_anonymous', 1);
@@ -818,10 +820,12 @@ class EM_Event extends EM_Object{
818
  }
819
  $result = count($this->errors) == 0;
820
  //If we're saving event categories in MS Global mode, we'll add them here, saving by term id (cat ids are gone now)
821
- if( EM_MS_GLOBAL && !is_main_site() ){
822
- $this->get_categories()->save(); //it'll know what to do
823
- }elseif( EM_MS_GLOBAL ){
824
- $this->get_categories()->save_index(); //just save to index, we assume cats are saved in $this->save();
 
 
825
  }
826
  $this->compat_keys(); //compatability keys, loaded before saving recurrences
827
  //build recurrences if needed
@@ -850,7 +854,7 @@ class EM_Event extends EM_Object{
850
  //First, duplicate.
851
  if( $this->can_manage('edit_events','edit_others_events') ){
852
  $EM_Event = clone $this;
853
- $EM_Event->get_categories(); //before we remove event/post ids
854
  $EM_Event->get_bookings()->get_tickets(); //in case this wasn't loaded and before we reset ids
855
  $EM_Event->event_id = null;
856
  $EM_Event->post_id = null;
@@ -955,8 +959,7 @@ class EM_Event extends EM_Object{
955
  do_action('em_event_delete_meta_event_pre', $this);
956
  $result = $wpdb->query ( $wpdb->prepare("DELETE FROM ". EM_EVENTS_TABLE ." WHERE event_id=%d", $this->event_id) );
957
  if( $result !== false ){
958
- $this->delete_bookings();
959
- $this->delete_tickets();
960
  //Delete the recurrences then this recurrence event
961
  if( $this->is_recurring() ){
962
  $result = $this->delete_events(); //was true at this point, so false if fails
@@ -971,6 +974,7 @@ class EM_Event extends EM_Object{
971
  }
972
 
973
  /**
 
974
  * Shortcut function for $this->get_bookings()->delete(), because using the EM_Bookings requires loading previous bookings, which isn't neceesary.
975
  */
976
  function delete_bookings(){
@@ -985,6 +989,7 @@ class EM_Event extends EM_Object{
985
  }
986
 
987
  /**
 
988
  * Shortcut function for $this->get_bookings()->delete(), because using the EM_Bookings requires loading previous bookings, which isn't neceesary.
989
  */
990
  function delete_tickets(){
@@ -1403,7 +1408,7 @@ class EM_Event extends EM_Object{
1403
  //if event is upcoming
1404
  $show_condition = $this->start > current_time('timestamp');
1405
  }elseif ($condition == 'is_current'){
1406
- //if event is upcoming
1407
  $ts = current_time('timestamp');
1408
  $show_condition = $this->start <= $ts && $this->end >= $ts;
1409
  }elseif ($condition == 'is_recurrence'){
@@ -1775,20 +1780,29 @@ class EM_Event extends EM_Object{
1775
  break;
1776
  //Categories and Tags
1777
  case '#_EVENTCATEGORIESIMAGES':
1778
- ob_start();
1779
- $template = em_locate_template('placeholders/eventcategoriesimages.php', true, array('EM_Event'=>$this));
1780
- $replace = ob_get_clean();
 
 
 
1781
  break;
1782
  case '#_EVENTTAGS':
1783
- ob_start();
1784
- $template = em_locate_template('placeholders/eventtags.php', true, array('EM_Event'=>$this));
1785
- $replace = ob_get_clean();
 
 
 
1786
  break;
1787
  case '#_CATEGORIES': //deprecated
1788
  case '#_EVENTCATEGORIES':
1789
- ob_start();
1790
- $template = em_locate_template('placeholders/categories.php', true, array('EM_Event'=>$this));
1791
- $replace = ob_get_clean();
 
 
 
1792
  break;
1793
  //Ical Stuff
1794
  case '#_EVENTICALURL':
@@ -2118,7 +2132,7 @@ class EM_Event extends EM_Object{
2118
  }
2119
  }
2120
  //MS Global Categories
2121
- if( EM_MS_GLOBAL ){
2122
  foreach( self::get_categories() as $EM_Category ){
2123
  foreach($event_ids as $event_id){
2124
  $wpdb->insert(EM_META_TABLE, array('meta_value'=>$EM_Category->term_id,'object_id'=>$event_id,'meta_key'=>'event-category'));
260
  $this->load_postdata($event_post, $search_by);
261
  }
262
  $this->recurrence = $this->is_recurring() ? 1:0;
 
263
  //Do it here so things appear in the po file.
264
  $this->status_array = array(
265
  0 => __('Pending','events-manager'),
368
  $this->event_name = !empty($_POST['event_name']) ? htmlspecialchars_decode(wp_kses_data(htmlspecialchars_decode(stripslashes($_POST['event_name'])))):'';
369
  $this->post_type = ($this->is_recurring() || !empty($_POST['recurring'])) ? 'event-recurring':EM_POST_TYPE_EVENT;
370
  //don't forget categories!
371
+ if( get_option('dbem_categories_enabled') ) $this->get_categories()->get_post();
372
  //anonymous submissions and guest basic info
373
  if( !is_user_logged_in() && get_option('dbem_events_anonymous_submissions') && empty($this->event_id) ){
374
  $this->event_owner_anonymous = 1;
431
  $this->end = strtotime($this->event_end_date." ".$this->event_end_time);
432
  //Bookings
433
  $can_manage_bookings = $this->can_manage('manage_bookings','manage_others_bookings');
434
+ $preview_autosave = is_admin() && !empty($_REQUEST['_emnonce']) && !empty($_REQUEST['wp-preview']) && $_REQUEST['wp-preview'] == 'dopreview'; //we shouldn't save new data during a preview auto-save
435
+ if( !$preview_autosave && $can_manage_bookings && !empty($_POST['event_rsvp']) && $_POST['event_rsvp'] ){
436
  $this->get_bookings()->get_tickets()->get_post();
437
  $this->event_rsvp = 1;
438
  //RSVP cuttoff TIME is set up above where start/end times are as well
496
  }
497
  $this->event_spaces = ( isset($_POST['event_spaces']) ) ? absint($_POST['event_spaces']):0;
498
  $this->event_rsvp_spaces = ( isset($_POST['event_rsvp_spaces']) ) ? absint($_POST['event_rsvp_spaces']):0;
499
+ }elseif( !$preview_autosave && ($can_manage_bookings || !$this->event_rsvp) ){
500
  $this->event_rsvp = 0;
501
  $this->event_rsvp_time = '00:00:00';
502
  }
509
  foreach($_POST['em_attributes'] as $att_key => $att_value ){
510
  if( (in_array($att_key, $event_available_attributes['names']) || array_key_exists($att_key, $this->event_attributes) ) ){
511
  $this->event_attributes[$att_key] = '';
512
+ $att_vals = isset($event_available_attributes['values'][$att_key]) ? count($event_available_attributes['values'][$att_key]) : 0;
513
  if( !empty($att_value) ){
514
  if( $att_vals <= 1 || ($att_vals > 1 && in_array($att_value, $event_available_attributes['values'][$att_key])) ){
515
  $this->event_attributes[$att_key] = stripslashes($att_value);
542
  $this->recurrence_days = ( !empty($_POST['recurrence_days']) && is_numeric($_POST['recurrence_days']) ) ? (int) $_POST['recurrence_days']:0;
543
  }
544
  //categories in MS GLobal
545
+ if(EM_MS_GLOBAL && !is_main_site() && get_option('dbem_categories_enabled') ){
546
  $this->get_categories()->get_post(); //it'll know what to do
547
  }
548
  //validate (optional) and return result
678
  $this->event_owner = $post_data->post_author;
679
  $this->post_status = $post_data->post_status;
680
  $this->get_status();
681
+ //Categories
682
+ if( get_option('dbem_categories_enabled') ){
683
+ $this->get_categories()->event_id = $this->event_id;
684
+ $this->categories->post_id = $this->post_id;
685
+ $this->categories->save();
686
+ }
687
  //anonymous submissions should save this information
688
  if( !empty($this->event_owner_anonymous) ){
689
  update_post_meta($this->post_id, '_event_owner_anonymous', 1);
820
  }
821
  $result = count($this->errors) == 0;
822
  //If we're saving event categories in MS Global mode, we'll add them here, saving by term id (cat ids are gone now)
823
+ if( EM_MS_GLOBAL && get_option('dbem_categories_enabled') ){ //EM_MS_Globals should look up original blog
824
+ if( !is_main_site() ){
825
+ $this->get_categories()->save(); //it'll know what to do
826
+ }else{
827
+ $this->get_categories()->save_index(); //just save to index, we assume cats are saved in $this->save();
828
+ }
829
  }
830
  $this->compat_keys(); //compatability keys, loaded before saving recurrences
831
  //build recurrences if needed
854
  //First, duplicate.
855
  if( $this->can_manage('edit_events','edit_others_events') ){
856
  $EM_Event = clone $this;
857
+ if( get_option('dbem_categories_enabled') ) $EM_Event->get_categories(); //before we remove event/post ids
858
  $EM_Event->get_bookings()->get_tickets(); //in case this wasn't loaded and before we reset ids
859
  $EM_Event->event_id = null;
860
  $EM_Event->post_id = null;
959
  do_action('em_event_delete_meta_event_pre', $this);
960
  $result = $wpdb->query ( $wpdb->prepare("DELETE FROM ". EM_EVENTS_TABLE ." WHERE event_id=%d", $this->event_id) );
961
  if( $result !== false ){
962
+ $this->get_bookings()->delete();
 
963
  //Delete the recurrences then this recurrence event
964
  if( $this->is_recurring() ){
965
  $result = $this->delete_events(); //was true at this point, so false if fails
974
  }
975
 
976
  /**
977
+ * Deprecated, use $this->get_bookings->delete() instead.
978
  * Shortcut function for $this->get_bookings()->delete(), because using the EM_Bookings requires loading previous bookings, which isn't neceesary.
979
  */
980
  function delete_bookings(){
989
  }
990
 
991
  /**
992
+ * Deprecated, use $this->get_bookings->delete() instead.
993
  * Shortcut function for $this->get_bookings()->delete(), because using the EM_Bookings requires loading previous bookings, which isn't neceesary.
994
  */
995
  function delete_tickets(){
1408
  //if event is upcoming
1409
  $show_condition = $this->start > current_time('timestamp');
1410
  }elseif ($condition == 'is_current'){
1411
+ //if event is currently happening
1412
  $ts = current_time('timestamp');
1413
  $show_condition = $this->start <= $ts && $this->end >= $ts;
1414
  }elseif ($condition == 'is_recurrence'){
1780
  break;
1781
  //Categories and Tags
1782
  case '#_EVENTCATEGORIESIMAGES':
1783
+ $replace = '';
1784
+ if( get_option('dbem_categories_enabled') ){
1785
+ ob_start();
1786
+ $template = em_locate_template('placeholders/eventcategoriesimages.php', true, array('EM_Event'=>$this));
1787
+ $replace = ob_get_clean();
1788
+ }
1789
  break;
1790
  case '#_EVENTTAGS':
1791
+ $replace = '';
1792
+ if( get_option('dbem_tags_enabled') ){
1793
+ ob_start();
1794
+ $template = em_locate_template('placeholders/eventtags.php', true, array('EM_Event'=>$this));
1795
+ $replace = ob_get_clean();
1796
+ }
1797
  break;
1798
  case '#_CATEGORIES': //deprecated
1799
  case '#_EVENTCATEGORIES':
1800
+ $replace = '';
1801
+ if( get_option('dbem_categories_enabled') ){
1802
+ ob_start();
1803
+ $template = em_locate_template('placeholders/categories.php', true, array('EM_Event'=>$this));
1804
+ $replace = ob_get_clean();
1805
+ }
1806
  break;
1807
  //Ical Stuff
1808
  case '#_EVENTICALURL':
2132
  }
2133
  }
2134
  //MS Global Categories
2135
+ if( EM_MS_GLOBAL && get_option('dbem_categories_enabled') ){
2136
  foreach( self::get_categories() as $EM_Category ){
2137
  foreach($event_ids as $event_id){
2138
  $wpdb->insert(EM_META_TABLE, array('meta_value'=>$EM_Category->term_id,'object_id'=>$event_id,'meta_key'=>'event-category'));
classes/em-events.php CHANGED
@@ -221,6 +221,12 @@ class EM_Events extends EM_Object {
221
 
222
  /**
223
  * Generate a grouped list of events by year, month, week or day.
 
 
 
 
 
 
224
  * @since 5.4.4.2
225
  * @param array $args
226
  * @return string
@@ -252,11 +258,21 @@ class EM_Events extends EM_Object {
252
  //go through the events and put them into a monthly array
253
  $format = (!empty($args['date_format'])) ? $args['date_format']:'Y';
254
  $events_dates = array();
255
- foreach($EM_Events as $EM_Event){
256
- $events_dates[date_i18n($format,$EM_Event->start)][] = $EM_Event;
 
 
 
 
 
 
 
 
 
 
257
  }
258
  foreach ($events_dates as $year => $events){
259
- echo str_replace('#s', $year, $args['header_format']);
260
  echo self::output($events, $atts);
261
  }
262
  break;
@@ -265,10 +281,18 @@ class EM_Events extends EM_Object {
265
  $format = (!empty($args['date_format'])) ? $args['date_format']:'M Y';
266
  $events_dates = array();
267
  foreach($EM_Events as $EM_Event){
268
- $events_dates[date_i18n($format, $EM_Event->start)][] = $EM_Event;
 
 
 
 
 
 
 
 
269
  }
270
  foreach ($events_dates as $month => $events){
271
- echo str_replace('#s', $month, $args['header_format']);
272
  echo self::output($events, $atts);
273
  }
274
  break;
@@ -284,6 +308,14 @@ class EM_Events extends EM_Object {
284
  $offset = $offset * 60*60*24; //days in seconds
285
  $start_day = strtotime($EM_Event->start_date);
286
  $events_dates[$start_day - $offset][] = $EM_Event;
 
 
 
 
 
 
 
 
287
  }
288
  foreach ($events_dates as $event_day_ts => $events){
289
  echo str_replace('#s', date_i18n($format,$event_day_ts). get_option('dbem_dates_separator') .date_i18n($format,$event_day_ts+(60*60*24*6)), $args['header_format']);
@@ -295,7 +327,16 @@ class EM_Events extends EM_Object {
295
  $format = (!empty($args['date_format'])) ? $args['date_format']:get_option('date_format');
296
  $events_dates = array();
297
  foreach($EM_Events as $EM_Event){
298
- $events_dates[strtotime($EM_Event->start_date)][] = $EM_Event;
 
 
 
 
 
 
 
 
 
299
  }
300
  foreach ($events_dates as $event_day_ts => $events){
301
  echo str_replace('#s', date_i18n($format,$event_day_ts), $args['header_format']);
@@ -351,10 +392,15 @@ class EM_Events extends EM_Object {
351
  */
352
  public static function build_sql_conditions( $args = array() ){
353
  self::$context = EM_POST_TYPE_EVENT;
 
354
  $conditions = parent::build_sql_conditions($args);
355
  if( !empty($args['search']) ){
356
  $like_search = array('event_name',EM_EVENTS_TABLE.'.post_content','location_name','location_address','location_town','location_postcode','location_state','location_country','location_region');
357
- $conditions['search'] = "(".implode(" LIKE '%{$args['search']}%' OR ", $like_search). " LIKE '%{$args['search']}%')";
 
 
 
 
358
  }
359
  $conditions['status'] = "(`event_status` >= 0 )"; //shows pending & published if not defined
360
  if( array_key_exists('status',$args) ){
@@ -421,6 +467,8 @@ class EM_Events extends EM_Object {
421
  */
422
  public static function build_sql_orderby( $args, $accepted_fields, $default_order = 'ASC' ){
423
  self::$context = EM_POST_TYPE_EVENT;
 
 
424
  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 );
425
  }
426
 
221
 
222
  /**
223
  * Generate a grouped list of events by year, month, week or day.
224
+ *
225
+ * There is a nuance with this function, long_events won't work unless you add a limit of 0. The reason is because this won't work with pagination, due to the fact
226
+ * that you need to alter the event total count to reflect each time an event is displayed in a time range. e.g. if an event lasts 2 days and it's daily grouping,
227
+ * then that event would count as 2 events for pagination purposes. For that you need to count every single event and calculate date range etc. which is too resource
228
+ * heavy and not scalabale, therefore we've added this limitation.
229
+ *
230
  * @since 5.4.4.2
231
  * @param array $args
232
  * @return string
258
  //go through the events and put them into a monthly array
259
  $format = (!empty($args['date_format'])) ? $args['date_format']:'Y';
260
  $events_dates = array();
261
+ foreach($EM_Events as $EM_Event){ /* @var $EM_Event EM_Event */
262
+ $year = date('Y',$EM_Event->start);
263
+ $events_dates[$year][] = $EM_Event;
264
+ //if long events requested, add event to other dates too
265
+ if( empty($args['limit']) && !empty($args['long_events']) && $EM_Event->event_end_date != $EM_Event->event_start_date ) {
266
+ $next_year = $year + 1;
267
+ $year_end = date('Y', $EM_Event->end);
268
+ while( $next_year <= $year_end ){
269
+ $events_dates[$next_year][] = $EM_Event;
270
+ $next_year = $next_year + 1;
271
+ }
272
+ }
273
  }
274
  foreach ($events_dates as $year => $events){
275
+ echo str_replace('#s', date_i18n($format,strtotime($year.'-01-01', current_time('timestamp'))), $args['header_format']);
276
  echo self::output($events, $atts);
277
  }
278
  break;
281
  $format = (!empty($args['date_format'])) ? $args['date_format']:'M Y';
282
  $events_dates = array();
283
  foreach($EM_Events as $EM_Event){
284
+ $events_dates[date('Y-m-'.'01', $EM_Event->start)][] = $EM_Event;
285
+ //if long events requested, add event to other dates too
286
+ if( empty($args['limit']) && !empty($args['long_events']) && $EM_Event->event_end_date != $EM_Event->event_start_date ) {
287
+ $next_month = strtotime("+1 Month", $EM_Event->start);
288
+ while( $next_month <= $EM_Event->end ){
289
+ $events_dates[date('Y-m-'.'01',$next_month)][] = $EM_Event;
290
+ $next_month = strtotime("+1 Month", $next_month);
291
+ }
292
+ }
293
  }
294
  foreach ($events_dates as $month => $events){
295
+ echo str_replace('#s', date_i18n($format, strtotime($month, current_time('timestamp'))), $args['header_format']);
296
  echo self::output($events, $atts);
297
  }
298
  break;
308
  $offset = $offset * 60*60*24; //days in seconds
309
  $start_day = strtotime($EM_Event->start_date);
310
  $events_dates[$start_day - $offset][] = $EM_Event;
311
+ //if long events requested, add event to other dates too
312
+ if( empty($args['limit']) && !empty($args['long_events']) && $EM_Event->event_end_date != $EM_Event->event_start_date ) {
313
+ $next_week = $start_day - $offset + (86400 * 7);
314
+ while( $next_week <= $EM_Event->end ){
315
+ $events_dates[$next_week][] = $EM_Event;
316
+ $next_week = $next_week + (86400 * 7);
317
+ }
318
+ }
319
  }
320
  foreach ($events_dates as $event_day_ts => $events){
321
  echo str_replace('#s', date_i18n($format,$event_day_ts). get_option('dbem_dates_separator') .date_i18n($format,$event_day_ts+(60*60*24*6)), $args['header_format']);
327
  $format = (!empty($args['date_format'])) ? $args['date_format']:get_option('date_format');
328
  $events_dates = array();
329
  foreach($EM_Events as $EM_Event){
330
+ $event_start_date = strtotime($EM_Event->start_date);
331
+ $events_dates[$event_start_date][] = $EM_Event;
332
+ //if long events requested, add event to other dates too
333
+ if( empty($args['limit']) && !empty($args['long_events']) && $EM_Event->event_end_date != $EM_Event->event_start_date ) {
334
+ $tomorrow = $event_start_date + 86400;
335
+ while( $tomorrow <= $EM_Event->end ){
336
+ $events_dates[$tomorrow][] = $EM_Event;
337
+ $tomorrow = $tomorrow + 86400;
338
+ }
339
+ }
340
  }
341
  foreach ($events_dates as $event_day_ts => $events){
342
  echo str_replace('#s', date_i18n($format,$event_day_ts), $args['header_format']);
392
  */
393
  public static function build_sql_conditions( $args = array() ){
394
  self::$context = EM_POST_TYPE_EVENT;
395
+ global $wpdb;
396
  $conditions = parent::build_sql_conditions($args);
397
  if( !empty($args['search']) ){
398
  $like_search = array('event_name',EM_EVENTS_TABLE.'.post_content','location_name','location_address','location_town','location_postcode','location_state','location_country','location_region');
399
+ $like_search_string = '%'.$wpdb->esc_like($args['search']).'%';
400
+ $like_search_strings = array();
401
+ foreach( $like_search as $v ) $like_search_strings[] = $like_search_string;
402
+ $like_search_sql = "(".implode(" LIKE %s OR ", $like_search). " LIKE %s)";
403
+ $conditions['search'] = $wpdb->prepare($like_search_sql, $like_search_strings);
404
  }
405
  $conditions['status'] = "(`event_status` >= 0 )"; //shows pending & published if not defined
406
  if( array_key_exists('status',$args) ){
467
  */
468
  public static function build_sql_orderby( $args, $accepted_fields, $default_order = 'ASC' ){
469
  self::$context = EM_POST_TYPE_EVENT;
470
+ $accepted_fields[] = 'event_date_modified';
471
+ $accepted_fields[] = 'event_date_created';
472
  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 );
473
  }
474
 
classes/em-locations.php CHANGED
@@ -217,7 +217,11 @@ class EM_Locations extends EM_Object {
217
  //search locations
218
  if( !empty($args['search']) ){
219
  $like_search = array($locations_table.'.post_content','location_name','location_address','location_town','location_postcode','location_state','location_region','location_country');
220
- $conditions['search'] = "(".implode(" LIKE '%{$args['search']}%' OR ", $like_search). " LIKE '%{$args['search']}%')";
 
 
 
 
221
  }
222
  //eventful locations
223
  if( true == $args['eventful'] ){
217
  //search locations
218
  if( !empty($args['search']) ){
219
  $like_search = array($locations_table.'.post_content','location_name','location_address','location_town','location_postcode','location_state','location_region','location_country');
220
+ $like_search_string = '%'.$wpdb->esc_like($args['search']).'%';
221
+ $like_search_strings = array();
222
+ foreach( $like_search as $v ) $like_search_strings[] = $like_search_string;
223
+ $like_search_sql = "(".implode(" LIKE %s OR ", $like_search). " LIKE %s)";
224
+ $conditions['search'] = $wpdb->prepare($like_search_sql, $like_search_strings);
225
  }
226
  //eventful locations
227
  if( true == $args['eventful'] ){
classes/em-mailer.php CHANGED
@@ -64,7 +64,7 @@ class EM_Mailer {
64
  return $send;
65
  }elseif( $emails_ok ){
66
  $this->load_phpmailer();
67
- $mail = new EM_PHPMailer();
68
  //$mail->SMTPDebug = true;
69
  if( get_option('dbem_smtp_html') ){
70
  $mail->isHTML();
@@ -129,8 +129,8 @@ class EM_Mailer {
129
  * load phpmailer classes
130
  */
131
  function load_phpmailer(){
132
- require_once(dirname(__FILE__) . '/phpmailer/class.phpmailer.php');
133
- require_once(dirname(__FILE__) . '/phpmailer/class.smtp.php');
134
  }
135
  }
136
  ?>
64
  return $send;
65
  }elseif( $emails_ok ){
66
  $this->load_phpmailer();
67
+ $mail = new PHPMailer();
68
  //$mail->SMTPDebug = true;
69
  if( get_option('dbem_smtp_html') ){
70
  $mail->isHTML();
129
  * load phpmailer classes
130
  */
131
  function load_phpmailer(){
132
+ require_once ABSPATH . WPINC . '/class-phpmailer.php';
133
+ require_once ABSPATH . WPINC . '/class-smtp.php';
134
  }
135
  }
136
  ?>
classes/em-object.php CHANGED
@@ -165,7 +165,7 @@ class EM_Object {
165
  $defaults['limit'] = (is_numeric($defaults['limit'])) ? $defaults['limit']:$super_defaults['limit'];
166
  $defaults['offset'] = (is_numeric($defaults['offset'])) ? $defaults['offset']:$super_defaults['offset'];
167
  $defaults['recurring'] = $defaults['recurring'] === 'include' ? $defaults['recurring']:($defaults['recurring'] == true);
168
- $defaults['search'] = ($defaults['search']) ? trim(esc_sql($wpdb->esc_like($defaults['search']))):false;
169
  //Calculate offset if event page is set
170
  if($defaults['page'] > 1){
171
  $defaults['offset'] = $defaults['limit'] * ($defaults['page']-1);
@@ -966,7 +966,7 @@ class EM_Object {
966
  $unique_args['action'] = $pag_args['action'] = $search_action;
967
  }
968
  //if we're in an ajax call, make sure we aren't calling admin-ajax.php
969
- if( defined('DOING_AJAX') ) $page_url = wp_get_referer();
970
  //finally, glue the url with querystring and pass onto pagination function
971
  $page_link_template = em_add_get_params($page_url, $pag_args, false); //don't html encode, so em_paginate does its thing;
972
  if( empty($args['ajax']) || defined('DOING_AJAX') ) $unique_args = array(); //don't use data method if ajax is disabled or if we're already in an ajax request (SERP irrelevenat)
@@ -999,6 +999,24 @@ class EM_Object {
999
  case 'EM_Ticket_Booking':
1000
  return $this->ticket_booking_id;
1001
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1002
  }
1003
 
1004
  /**
@@ -1017,7 +1035,8 @@ class EM_Object {
1017
  }
1018
  if( empty($user->ID) ) $user = wp_get_current_user();
1019
  //do they own this?
1020
- $is_owner = ( (!empty($this->owner) && ($this->owner == get_current_user_id()) || !$this->get_id() || (!empty($user) && $this->owner == $user->ID)) );
 
1021
  //now check capability
1022
  $can_manage = false;
1023
  if( $is_owner && $owner_capability && $user->has_cap($owner_capability) ){
@@ -1084,7 +1103,8 @@ class EM_Object {
1084
  */
1085
  function compat_keys(){
1086
  foreach($this->fields as $key => $fieldinfo){
1087
- if(!empty($this->$key)) $this->$fieldinfo['name'] = $this->$key;
 
1088
  }
1089
  }
1090
 
@@ -1396,22 +1416,34 @@ class EM_Object {
1396
  function image_delete($force_delete=true) {
1397
  $type = $this->get_image_type();
1398
  if( $type ){
 
1399
  if( $this->get_image_url() == '' ){
1400
  $result = true;
1401
  }else{
1402
  $post_thumbnail_id = get_post_thumbnail_id( $this->post_id );
1403
- $delete_attachment = wp_delete_attachment($post_thumbnail_id, $force_delete);
1404
- if( $delete_attachment !== false ){
1405
- //check legacy image
1406
- $type_id_name = $type.'_id';
1407
- $file_name= EM_IMAGE_UPLOAD_DIR.$this->get_image_type(true)."-".$this->$type_id_name;
1408
- $result = false;
1409
- foreach($this->mime_types as $mime_type) {
1410
- if (file_exists($file_name.".".$mime_type)){
1411
- $result = unlink($file_name.".".$mime_type);
1412
- $this->image_url = '';
1413
- }
1414
- }
 
 
 
 
 
 
 
 
 
 
 
1415
  }
1416
  }
1417
  }
165
  $defaults['limit'] = (is_numeric($defaults['limit'])) ? $defaults['limit']:$super_defaults['limit'];
166
  $defaults['offset'] = (is_numeric($defaults['offset'])) ? $defaults['offset']:$super_defaults['offset'];
167
  $defaults['recurring'] = $defaults['recurring'] === 'include' ? $defaults['recurring']:($defaults['recurring'] == true);
168
+ $defaults['search'] = ($defaults['search']) ? trim($defaults['search']):false;
169
  //Calculate offset if event page is set
170
  if($defaults['page'] > 1){
171
  $defaults['offset'] = $defaults['limit'] * ($defaults['page']-1);
966
  $unique_args['action'] = $pag_args['action'] = $search_action;
967
  }
968
  //if we're in an ajax call, make sure we aren't calling admin-ajax.php
969
+ if( defined('DOING_AJAX') ) $page_url = em_wp_get_referer();
970
  //finally, glue the url with querystring and pass onto pagination function
971
  $page_link_template = em_add_get_params($page_url, $pag_args, false); //don't html encode, so em_paginate does its thing;
972
  if( empty($args['ajax']) || defined('DOING_AJAX') ) $unique_args = array(); //don't use data method if ajax is disabled or if we're already in an ajax request (SERP irrelevenat)
999
  case 'EM_Ticket_Booking':
1000
  return $this->ticket_booking_id;
1001
  }
1002
+ return 0;
1003
+ }
1004
+
1005
+ /**
1006
+ * Returns the user id for the owner (author) of a particular object in the table it is stored, be it Event (event_owner) or Location (location_owner).
1007
+ * This function accounts for the fact that previously the property $this->owner was used by objects as a shortcut and consequently in code in EM_Object, which should now use this method instead.
1008
+ * Extending classes should override this and provide the relevant user id that owns this object instance.
1009
+ * @return int
1010
+ */
1011
+ function get_owner(){
1012
+ if( !empty($this->owner) ) return $this->owner;
1013
+ switch( get_class($this) ){
1014
+ case 'EM_Event':
1015
+ return $this->event_owner;
1016
+ case 'EM_Location':
1017
+ return $this->location_owner;
1018
+ }
1019
+ return 0;
1020
  }
1021
 
1022
  /**
1035
  }
1036
  if( empty($user->ID) ) $user = wp_get_current_user();
1037
  //do they own this?
1038
+ $owner_id = $this->get_owner();
1039
+ $is_owner = ( (!empty($owner_id) && ($owner_id == get_current_user_id()) || !$this->get_id() || (!empty($user) && $owner_id == $user->ID)) );
1040
  //now check capability
1041
  $can_manage = false;
1042
  if( $is_owner && $owner_capability && $user->has_cap($owner_capability) ){
1103
  */
1104
  function compat_keys(){
1105
  foreach($this->fields as $key => $fieldinfo){
1106
+ $field_name = $fieldinfo['name'];
1107
+ if(!empty($this->$key)) $this->$field_name = $this->$key;
1108
  }
1109
  }
1110
 
1416
  function image_delete($force_delete=true) {
1417
  $type = $this->get_image_type();
1418
  if( $type ){
1419
+ $this->image_url = '';
1420
  if( $this->get_image_url() == '' ){
1421
  $result = true;
1422
  }else{
1423
  $post_thumbnail_id = get_post_thumbnail_id( $this->post_id );
1424
+ //check that this image isn't being used by another CPT
1425
+ global $wpdb;
1426
+ $sql = $wpdb->prepare('SELECT count(*) FROM '.$wpdb->postmeta." WHERE meta_key='_thumbnail_id' AND meta_value=%d", array($post_thumbnail_id));
1427
+ if( $wpdb->get_var($sql) <= 1 ){
1428
+ //not used by any other CPT, so just delete the image entirely (would usually only be used via front-end which has no media manager)
1429
+ //@todo add setting option to delete images from filesystem/media if not used by other posts
1430
+ $delete_attachment = wp_delete_attachment($post_thumbnail_id, $force_delete);
1431
+ if( false === $delete_attachment ){
1432
+ //check legacy image
1433
+ $type_id_name = $type.'_id';
1434
+ $file_name= EM_IMAGE_UPLOAD_DIR.$this->get_image_type(true)."-".$this->$type_id_name;
1435
+ $result = false;
1436
+ foreach($this->mime_types as $mime_type) {
1437
+ if (file_exists($file_name.".".$mime_type)){
1438
+ $result = unlink($file_name.".".$mime_type);
1439
+ }
1440
+ }
1441
+ }else{
1442
+ $result = true;
1443
+ }
1444
+ }else{
1445
+ //just delete image association
1446
+ delete_post_meta($this->post_id, '_thumbnail_id');
1447
  }
1448
  }
1449
  }
classes/em-person.php CHANGED
@@ -24,7 +24,7 @@ class EM_Person extends WP_User{
24
  }else{
25
  parent::__construct($person_id);
26
  }
27
- $this->phone = wp_kses_data(get_metadata('user', $this->ID, 'dbem_phone', true)); //extra field for EM
28
  do_action('em_person',$this, $person_id, $username);
29
  }
30
 
24
  }else{
25
  parent::__construct($person_id);
26
  }
27
+ $this->phone = get_metadata('user', $this->ID, 'dbem_phone', true); //extra field for EM
28
  do_action('em_person',$this, $person_id, $username);
29
  }
30
 
classes/em-ticket.php CHANGED
@@ -235,8 +235,7 @@ class EM_Ticket extends EM_Object{
235
  $missing_fields = Array ();
236
  $this->errors = array();
237
  foreach ( $this->required_fields as $field ) {
238
- $true_field = $this->fields[$field]['name'];
239
- if ( $this->$true_field == "") {
240
  $missing_fields[] = $field;
241
  }
242
  }
235
  $missing_fields = Array ();
236
  $this->errors = array();
237
  foreach ( $this->required_fields as $field ) {
238
+ if ( $this->$field == "") {
 
239
  $missing_fields[] = $field;
240
  }
241
  }
classes/em-tickets-bookings.php CHANGED
@@ -152,6 +152,7 @@ class EM_Tickets_Bookings extends EM_Object implements Iterator{
152
  */
153
  function delete(){
154
  global $wpdb;
 
155
  if( $this->get_booking()->can_manage() ){
156
  $result = $wpdb->query("DELETE FROM ".EM_TICKETS_BOOKINGS_TABLE." WHERE booking_id='{$this->get_booking_id()}'");
157
  //echo "<pre>";print_r($this->get_booking());echo "</pre>";
152
  */
153
  function delete(){
154
  global $wpdb;
155
+ $result = false;
156
  if( $this->get_booking()->can_manage() ){
157
  $result = $wpdb->query("DELETE FROM ".EM_TICKETS_BOOKINGS_TABLE." WHERE booking_id='{$this->get_booking_id()}'");
158
  //echo "<pre>";print_r($this->get_booking());echo "</pre>";
classes/phpmailer/class.phpmailer.php DELETED
@@ -1,2532 +0,0 @@
1
- <?php
2
- /*~ class.phpmailer.php
3
- .---------------------------------------------------------------------------.
4
- | Software: PHPMailer - PHP email class |
5
- | Version: 5.2.1 |
6
- | Site: https://code.google.com/a/apache-extras.org/p/phpmailer/ |
7
- | ------------------------------------------------------------------------- |
8
- | Admin: Jim Jagielski (project admininistrator) |
9
- | Authors: Andy Prevost (codeworxtech) codeworxtech@users.sourceforge.net |
10
- | : Marcus Bointon (coolbru) coolbru@users.sourceforge.net |
11
- | : Jim Jagielski (jimjag) jimjag@gmail.com |
12
- | Founder: Brent R. Matzelle (original founder) |
13
- | Copyright (c) 2010-2012, Jim Jagielski. All Rights Reserved. |
14
- | Copyright (c) 2004-2009, Andy Prevost. All Rights Reserved. |
15
- | Copyright (c) 2001-2003, Brent R. Matzelle |
16
- | ------------------------------------------------------------------------- |
17
- | License: Distributed under the Lesser General Public License (LGPL) |
18
- | http://www.gnu.org/copyleft/lesser.html |
19
- | This program is distributed in the hope that it will be useful - WITHOUT |
20
- | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
21
- | FITNESS FOR A PARTICULAR PURPOSE. |
22
- '---------------------------------------------------------------------------'
23
- */
24
-
25
- /**
26
- * PHPMailer - PHP email transport class
27
- * NOTE: Requires PHP version 5 or later
28
- * @package PHPMailer
29
- * @author Andy Prevost
30
- * @author Marcus Bointon
31
- * @author Jim Jagielski
32
- * @copyright 2010 - 2012 Jim Jagielski
33
- * @copyright 2004 - 2009 Andy Prevost
34
- * @version $Id: class.phpmailer.php 450 2010-06-23 16:46:33Z coolbru $
35
- * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
36
- */
37
-
38
- if (version_compare(PHP_VERSION, '5.0.0', '<') ) exit("Sorry, this version of PHPMailer will only run on PHP version 5 or greater!\n");
39
-
40
- class EM_PHPMailer {
41
-
42
- /////////////////////////////////////////////////
43
- // PROPERTIES, PUBLIC
44
- /////////////////////////////////////////////////
45
-
46
- /**
47
- * Email priority (1 = High, 3 = Normal, 5 = low).
48
- * @var int
49
- */
50
- public $Priority = 3;
51
-
52
- /**
53
- * Sets the CharSet of the message.
54
- * @var string
55
- */
56
- public $CharSet = 'iso-8859-1';
57
-
58
- /**
59
- * Sets the Content-type of the message.
60
- * @var string
61
- */
62
- public $ContentType = 'text/plain';
63
-
64
- /**
65
- * Sets the Encoding of the message. Options for this are
66
- * "8bit", "7bit", "binary", "base64", and "quoted-printable".
67
- * @var string
68
- */
69
- public $Encoding = '8bit';
70
-
71
- /**
72
- * Holds the most recent mailer error message.
73
- * @var string
74
- */
75
- public $ErrorInfo = '';
76
-
77
- /**
78
- * Sets the From email address for the message.
79
- * @var string
80
- */
81
- public $From = 'root@localhost';
82
-
83
- /**
84
- * Sets the From name of the message.
85
- * @var string
86
- */
87
- public $FromName = 'Root User';
88
-
89
- /**
90
- * Sets the Sender email (Return-Path) of the message. If not empty,
91
- * will be sent via -f to sendmail or as 'MAIL FROM' in smtp mode.
92
- * @var string
93
- */
94
- public $Sender = '';
95
-
96
- /**
97
- * Sets the Subject of the message.
98
- * @var string
99
- */
100
- public $Subject = '';
101
-
102
- /**
103
- * Sets the Body of the message. This can be either an HTML or text body.
104
- * If HTML then run IsHTML(true).
105
- * @var string
106
- */
107
- public $Body = '';
108
-
109
- /**
110
- * Sets the text-only body of the message. This automatically sets the
111
- * email to multipart/alternative. This body can be read by mail
112
- * clients that do not have HTML email capability such as mutt. Clients
113
- * that can read HTML will view the normal Body.
114
- * @var string
115
- */
116
- public $AltBody = '';
117
-
118
- /**
119
- * Stores the complete compiled MIME message body.
120
- * @var string
121
- * @access protected
122
- */
123
- protected $MIMEBody = '';
124
-
125
- /**
126
- * Stores the complete compiled MIME message headers.
127
- * @var string
128
- * @access protected
129
- */
130
- protected $MIMEHeader = '';
131
-
132
- /**
133
- * Stores the complete sent MIME message (Body and Headers)
134
- * @var string
135
- * @access protected
136
- */
137
- protected $SentMIMEMessage = '';
138
-
139
- /**
140
- * Sets word wrapping on the body of the message to a given number of
141
- * characters.
142
- * @var int
143
- */
144
- public $WordWrap = 0;
145
-
146
- /**
147
- * Method to send mail: ("mail", "sendmail", or "smtp").
148
- * @var string
149
- */
150
- public $Mailer = 'mail';
151
-
152
- /**
153
- * Sets the path of the sendmail program.
154
- * @var string
155
- */
156
- public $Sendmail = '/usr/sbin/sendmail';
157
-
158
- /**
159
- * Path to PHPMailer plugins. Useful if the SMTP class
160
- * is in a different directory than the PHP include path.
161
- * @var string
162
- */
163
- public $PluginDir = '';
164
-
165
- /**
166
- * Sets the email address that a reading confirmation will be sent.
167
- * @var string
168
- */
169
- public $ConfirmReadingTo = '';
170
-
171
- /**
172
- * Sets the hostname to use in Message-Id and Received headers
173
- * and as default HELO string. If empty, the value returned
174
- * by SERVER_NAME is used or 'localhost.localdomain'.
175
- * @var string
176
- */
177
- public $Hostname = '';
178
-
179
- /**
180
- * Sets the message ID to be used in the Message-Id header.
181
- * If empty, a unique id will be generated.
182
- * @var string
183
- */
184
- public $MessageID = '';
185
-
186
- /////////////////////////////////////////////////
187
- // PROPERTIES FOR SMTP
188
- /////////////////////////////////////////////////
189
-
190
- /**
191
- * Sets the SMTP hosts. All hosts must be separated by a
192
- * semicolon. You can also specify a different port
193
- * for each host by using this format: [hostname:port]
194
- * (e.g. "smtp1.example.com:25;smtp2.example.com").
195
- * Hosts will be tried in order.
196
- * @var string
197
- */
198
- public $Host = 'localhost';
199
-
200
- /**
201
- * Sets the default SMTP server port.
202
- * @var int
203
- */
204
- public $Port = 25;
205
-
206
- /**
207
- * Sets the SMTP HELO of the message (Default is $Hostname).
208
- * @var string
209
- */
210
- public $Helo = '';
211
-
212
- /**
213
- * Sets connection prefix.
214
- * Options are "", "ssl" or "tls"
215
- * @var string
216
- */
217
- public $SMTPSecure = '';
218
-
219
- /**
220
- * Sets SMTP authentication. Utilizes the Username and Password variables.
221
- * @var bool
222
- */
223
- public $SMTPAuth = false;
224
-
225
- /**
226
- * Sets SMTP username.
227
- * @var string
228
- */
229
- public $Username = '';
230
-
231
- /**
232
- * Sets SMTP password.
233
- * @var string
234
- */
235
- public $Password = '';
236
-
237
- /**
238
- * Sets the SMTP server timeout in seconds.
239
- * This function will not work with the win32 version.
240
- * @var int
241
- */
242
- public $Timeout = 10;
243
-
244
- /**
245
- * Sets SMTP class debugging on or off.
246
- * @var bool
247
- */
248
- public $SMTPDebug = false;
249
-
250
- /**
251
- * Prevents the SMTP connection from being closed after each mail
252
- * sending. If this is set to true then to close the connection
253
- * requires an explicit call to SmtpClose().
254
- * @var bool
255
- */
256
- public $SMTPKeepAlive = false;
257
-
258
- /**
259
- * Provides the ability to have the TO field process individual
260
- * emails, instead of sending to entire TO addresses
261
- * @var bool
262
- */
263
- public $SingleTo = false;
264
-
265
- /**
266
- * If SingleTo is true, this provides the array to hold the email addresses
267
- * @var bool
268
- */
269
- public $SingleToArray = array();
270
-
271
- /**
272
- * Provides the ability to change the line ending
273
- * @var string
274
- */
275
- public $LE = "\n";
276
-
277
- /**
278
- * Used with DKIM DNS Resource Record
279
- * @var string
280
- */
281
- public $DKIM_selector = 'phpmailer';
282
-
283
- /**
284
- * Used with DKIM DNS Resource Record
285
- * optional, in format of email address 'you@yourdomain.com'
286
- * @var string
287
- */
288
- public $DKIM_identity = '';
289
-
290
- /**
291
- * Used with DKIM DNS Resource Record
292
- * @var string
293
- */
294
- public $DKIM_passphrase = '';
295
-
296
- /**
297
- * Used with DKIM DNS Resource Record
298
- * optional, in format of email address 'you@yourdomain.com'
299
- * @var string
300
- */
301
- public $DKIM_domain = '';
302
-
303
- /**
304
- * Used with DKIM DNS Resource Record
305
- * optional, in format of email address 'you@yourdomain.com'
306
- * @var string
307
- */
308
- public $DKIM_private = '';
309
-
310
- /**
311
- * Callback Action function name
312
- * the function that handles the result of the send email action. Parameters:
313
- * bool $result result of the send action
314
- * string $to email address of the recipient
315
- * string $cc cc email addresses
316
- * string $bcc bcc email addresses
317
- * string $subject the subject
318
- * string $body the email body
319
- * @var string
320
- */
321
- public $action_function = ''; //'callbackAction';
322
-
323
- /**
324
- * Sets the PHPMailer Version number
325
- * @var string
326
- */
327
- public $Version = '5.2.1';
328
-
329
- /**
330
- * What to use in the X-Mailer header
331
- * @var string
332
- */
333
- public $XMailer = '';
334
-
335
- /////////////////////////////////////////////////
336
- // PROPERTIES, PRIVATE AND PROTECTED
337
- /////////////////////////////////////////////////
338
-
339
- protected $smtp = NULL;
340
- protected $to = array();
341
- protected $cc = array();
342
- protected $bcc = array();
343
- protected $ReplyTo = array();
344
- protected $all_recipients = array();
345
- protected $attachment = array();
346
- protected $CustomHeader = array();
347
- protected $message_type = '';
348
- protected $boundary = array();
349
- protected $language = array();
350
- protected $error_count = 0;
351
- protected $sign_cert_file = '';
352
- protected $sign_key_file = '';
353
- protected $sign_key_pass = '';
354
- protected $exceptions = false;
355
-
356
- /////////////////////////////////////////////////
357
- // CONSTANTS
358
- /////////////////////////////////////////////////
359
-
360
- const STOP_MESSAGE = 0; // message only, continue processing
361
- const STOP_CONTINUE = 1; // message?, likely ok to continue processing
362
- const STOP_CRITICAL = 2; // message, plus full stop, critical error reached
363
-
364
- /////////////////////////////////////////////////
365
- // METHODS, VARIABLES
366
- /////////////////////////////////////////////////
367
-
368
- /**
369
- * Constructor
370
- * @param boolean $exceptions Should we throw external exceptions?
371
- */
372
- public function __construct($exceptions = false) {
373
- $this->exceptions = ($exceptions == true);
374
- }
375
-
376
- /**
377
- * Sets message type to HTML.
378
- * @param bool $ishtml
379
- * @return void
380
- */
381
- public function IsHTML($ishtml = true) {
382
- if ($ishtml) {
383
- $this->ContentType = 'text/html';
384
- } else {
385
- $this->ContentType = 'text/plain';
386
- }
387
- }
388
-
389
- /**
390
- * Sets Mailer to send message using SMTP.
391
- * @return void
392
- */
393
- public function IsSMTP() {
394
- $this->Mailer = 'smtp';
395
- }
396
-
397
- /**
398
- * Sets Mailer to send message using PHP mail() function.
399
- * @return void
400
- */
401
- public function IsMail() {
402
- $this->Mailer = 'mail';
403
- }
404
-
405
- /**
406
- * Sets Mailer to send message using the $Sendmail program.
407
- * @return void
408
- */
409
- public function IsSendmail() {
410
- if (!stristr(ini_get('sendmail_path'), 'sendmail')) {
411
- $this->Sendmail = '/var/qmail/bin/sendmail';
412
- }
413
- $this->Mailer = 'sendmail';
414
- }
415
-
416
- /**
417
- * Sets Mailer to send message using the qmail MTA.
418
- * @return void
419
- */
420
- public function IsQmail() {
421
- if (stristr(ini_get('sendmail_path'), 'qmail')) {
422
- $this->Sendmail = '/var/qmail/bin/sendmail';
423
- }
424
- $this->Mailer = 'sendmail';
425
- }
426
-
427
- /////////////////////////////////////////////////
428
- // METHODS, RECIPIENTS
429
- /////////////////////////////////////////////////
430
-
431
- /**
432
- * Adds a "To" address.
433
- * @param string $address
434
- * @param string $name
435
- * @return boolean true on success, false if address already used
436
- */
437
- public function AddAddress($address, $name = '') {
438
- return $this->AddAnAddress('to', $address, $name);
439
- }
440
-
441
- /**
442
- * Adds a "Cc" address.
443
- * Note: this function works with the SMTP mailer on win32, not with the "mail" mailer.
444
- * @param string $address
445
- * @param string $name
446
- * @return boolean true on success, false if address already used
447
- */
448
- public function AddCC($address, $name = '') {
449
- return $this->AddAnAddress('cc', $address, $name);
450
- }
451
-
452
- /**
453
- * Adds a "Bcc" address.
454
- * Note: this function works with the SMTP mailer on win32, not with the "mail" mailer.
455
- * @param string $address
456
- * @param string $name
457
- * @return boolean true on success, false if address already used
458
- */
459
- public function AddBCC($address, $name = '') {
460
- return $this->AddAnAddress('bcc', $address, $name);
461
- }
462
-
463
- /**
464
- * Adds a "Reply-to" address.
465
- * @param string $address
466
- * @param string $name
467
- * @return boolean
468
- */
469
- public function AddReplyTo($address, $name = '') {
470
- return $this->AddAnAddress('Reply-To', $address, $name);
471
- }
472
-
473
- /**
474
- * Adds an address to one of the recipient arrays
475
- * Addresses that have been added already return false, but do not throw exceptions
476
- * @param string $kind One of 'to', 'cc', 'bcc', 'ReplyTo'
477
- * @param string $address The email address to send to
478
- * @param string $name
479
- * @return boolean true on success, false if address already used or invalid in some way
480
- * @access protected
481
- */
482
- protected function AddAnAddress($kind, $address, $name = '') {
483
- if (!preg_match('/^(to|cc|bcc|Reply-To)$/', $kind)) {
484
- $this->SetError($this->Lang('Invalid recipient array').': '.$kind);
485
- if ($this->exceptions) {
486
- throw new EM_phpmailerException('Invalid recipient array: ' . $kind);
487
- }
488
- if ($this->SMTPDebug) {
489
- echo $this->Lang('Invalid recipient array').': '.$kind;
490
- }
491
- return false;
492
- }
493
- $address = trim($address);
494
- $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim
495
- if (!self::ValidateAddress($address)) {
496
- $this->SetError($this->Lang('invalid_address').': '. $address);
497
- if ($this->exceptions) {
498
- throw new EM_phpmailerException($this->Lang('invalid_address').': '.$address);
499
- }
500
- if ($this->SMTPDebug) {
501
- echo $this->Lang('invalid_address').': '.$address;
502
- }
503
- return false;
504
- }
505
- if ($kind != 'Reply-To') {
506
- if (!isset($this->all_recipients[strtolower($address)])) {
507
- array_push($this->$kind, array($address, $name));
508
- $this->all_recipients[strtolower($address)] = true;
509
- return true;
510
- }
511
- } else {
512
- if (!array_key_exists(strtolower($address), $this->ReplyTo)) {
513
- $this->ReplyTo[strtolower($address)] = array($address, $name);
514
- return true;
515
- }
516
- }
517
- return false;
518
- }
519
-
520
- /**
521
- * Set the From and FromName properties
522
- * @param string $address
523
- * @param string $name
524
- * @return boolean
525
- */
526
- public function SetFrom($address, $name = '', $auto = 1) {
527
- $address = trim($address);
528
- $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim
529
- if (!self::ValidateAddress($address)) {
530
- $this->SetError($this->Lang('invalid_address').': '. $address);
531
- if ($this->exceptions) {
532
- throw new EM_phpmailerException($this->Lang('invalid_address').': '.$address);
533
- }
534
- if ($this->SMTPDebug) {
535
- echo $this->Lang('invalid_address').': '.$address;
536
- }
537
- return false;
538
- }
539
- $this->From = $address;
540
- $this->FromName = $name;
541
- if ($auto) {
542
- if (empty($this->ReplyTo)) {
543
- $this->AddAnAddress('Reply-To', $address, $name);
544
- }
545
- if (empty($this->Sender)) {
546
- $this->Sender = $address;
547
- }
548
- }
549
- return true;
550
- }
551
-
552
- /**
553
- * Check that a string looks roughly like an email address should
554
- * Static so it can be used without instantiation
555
- * Tries to use PHP built-in validator in the filter extension (from PHP 5.2), falls back to a reasonably competent regex validator
556
- * Conforms approximately to RFC2822
557
- * @link http://www.hexillion.com/samples/#Regex Original pattern found here
558
- * @param string $address The email address to check
559
- * @return boolean
560
- * @static
561
- * @access public
562
- */
563
- public static function ValidateAddress($address) {
564
- if (function_exists('filter_var')) { //Introduced in PHP 5.2
565
- if(filter_var($address, FILTER_VALIDATE_EMAIL) === FALSE) {
566
- return false;
567
- } else {
568
- return true;
569
- }
570
- } else {
571
- return preg_match('/^(?:[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+\.)*[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+@(?:(?:(?:[a-zA-Z0-9_](?:[a-zA-Z0-9_\-](?!\.)){0,61}[a-zA-Z0-9_-]?\.)+[a-zA-Z0-9_](?:[a-zA-Z0-9_\-](?!$)){0,61}[a-zA-Z0-9_]?)|(?:\[(?:(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\.){3}(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\]))$/', $address);
572
- }
573
- }
574
-
575
- /////////////////////////////////////////////////
576
- // METHODS, MAIL SENDING
577
- /////////////////////////////////////////////////
578
-
579
- /**
580
- * Creates message and assigns Mailer. If the message is
581
- * not sent successfully then it returns false. Use the ErrorInfo
582
- * variable to view description of the error.
583
- * @return bool
584
- */
585
- public function Send() {
586
- try {
587
- if(!$this->PreSend()) return false;
588
- return $this->PostSend();
589
- } catch (EM_phpmailerException $e) {
590
- $this->SentMIMEMessage = '';
591
- $this->SetError($e->getMessage());
592
- if ($this->exceptions) {
593
- throw $e;
594
- }
595
- return false;
596
- }
597
- }
598
-
599
- protected function PreSend() {
600
- try {
601
- $mailHeader = "";
602
- if ((count($this->to) + count($this->cc) + count($this->bcc)) < 1) {
603
- throw new EM_phpmailerException($this->Lang('provide_address'), self::STOP_CRITICAL);
604
- }
605
-
606
- // Set whether the message is multipart/alternative
607
- if(!empty($this->AltBody)) {
608
- $this->ContentType = 'multipart/alternative';
609
- }
610
-
611
- $this->error_count = 0; // reset errors
612
- $this->SetMessageType();
613
- //Refuse to send an empty message
614
- if (empty($this->Body)) {
615
- throw new EM_phpmailerException($this->Lang('empty_message'), self::STOP_CRITICAL);
616
- }
617
-
618
- $this->MIMEHeader = $this->CreateHeader();
619
- $this->MIMEBody = $this->CreateBody();
620
-
621
- // To capture the complete message when using mail(), create
622
- // an extra header list which CreateHeader() doesn't fold in
623
- if ($this->Mailer == 'mail') {
624
- if (count($this->to) > 0) {
625
- $mailHeader .= $this->AddrAppend("To", $this->to);
626
- } else {
627
- $mailHeader .= $this->HeaderLine("To", "undisclosed-recipients:;");
628
- }
629
- $mailHeader .= $this->HeaderLine('Subject', $this->EncodeHeader($this->SecureHeader(trim($this->Subject))));
630
- // if(count($this->cc) > 0) {
631
- // $mailHeader .= $this->AddrAppend("Cc", $this->cc);
632
- // }
633
- }
634
-
635
- // digitally sign with DKIM if enabled
636
- if ($this->DKIM_domain && $this->DKIM_private) {
637
- $header_dkim = $this->DKIM_Add($this->MIMEHeader, $this->EncodeHeader($this->SecureHeader($this->Subject)), $this->MIMEBody);
638
- $this->MIMEHeader = str_replace("\r\n", "\n", $header_dkim) . $this->MIMEHeader;
639
- }
640
-
641
- $this->SentMIMEMessage = sprintf("%s%s\r\n\r\n%s",$this->MIMEHeader,$mailHeader,$this->MIMEBody);
642
- return true;
643
-
644
- } catch (EM_phpmailerException $e) {
645
- $this->SetError($e->getMessage());
646
- if ($this->exceptions) {
647
- throw $e;
648
- }
649
- return false;
650
- }
651
- }
652
-
653
- protected function PostSend() {
654
- try {
655
- // Choose the mailer and send through it
656
- switch($this->Mailer) {
657
- case 'sendmail':
658
- return $this->SendmailSend($this->MIMEHeader, $this->MIMEBody);
659
- case 'smtp':
660
- return $this->SmtpSend($this->MIMEHeader, $this->MIMEBody);
661
- case 'mail':
662
- return $this->MailSend($this->MIMEHeader, $this->MIMEBody);
663
- default:
664
- return $this->MailSend($this->MIMEHeader, $this->MIMEBody);
665
- }
666
-
667
- } catch (EM_phpmailerException $e) {
668
- $this->SetError($e->getMessage());
669
- if ($this->exceptions) {
670
- throw $e;
671
- }
672
- if ($this->SMTPDebug) {
673
- echo $e->getMessage()."\n";
674
- }
675
- return false;
676
- }
677
- }
678
-
679
- /**
680
- * Sends mail using the $Sendmail program.
681
- * @param string $header The message headers
682
- * @param string $body The message body
683
- * @access protected
684
- * @return bool
685
- */
686
- protected function SendmailSend($header, $body) {
687
- if ($this->Sender != '') {
688
- $sendmail = sprintf("%s -oi -f %s -t", escapeshellcmd($this->Sendmail), escapeshellarg($this->Sender));
689
- } else {
690
- $sendmail = sprintf("%s -oi -t", escapeshellcmd($this->Sendmail));
691
- }
692
- if ($this->SingleTo === true) {
693
- foreach ($this->SingleToArray as $key => $val) {
694
- if(!@$mail = popen($sendmail, 'w')) {
695
- throw new EM_phpmailerException($this->Lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
696
- }
697
- fputs($mail, "To: " . $val . "\n");
698
- fputs($mail, $header);
699
- fputs($mail, $body);
700
- $result = pclose($mail);
701
- // implement call back function if it exists
702
- $isSent = ($result == 0) ? 1 : 0;
703
- $this->doCallback($isSent, $val, $this->cc, $this->bcc, $this->Subject, $body);
704
- if($result != 0) {
705
- throw new EM_phpmailerException($this->Lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
706
- }
707
- }
708
- } else {
709
- if(!@$mail = popen($sendmail, 'w')) {
710
- throw new EM_phpmailerException($this->Lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
711
- }
712
- fputs($mail, $header);
713
- fputs($mail, $body);
714
- $result = pclose($mail);
715
- // implement call back function if it exists
716
- $isSent = ($result == 0) ? 1 : 0;
717
- $this->doCallback($isSent, $this->to, $this->cc, $this->bcc, $this->Subject, $body);
718
- if($result != 0) {
719
- throw new EM_phpmailerException($this->Lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
720
- }
721
- }
722
- return true;
723
- }
724
-
725
- /**
726
- * Sends mail using the PHP mail() function.
727
- * @param string $header The message headers
728
- * @param string $body The message body
729
- * @access protected
730
- * @return bool
731
- */
732
- protected function MailSend($header, $body) {
733
- $toArr = array();
734
- foreach($this->to as $t) {
735
- $toArr[] = $this->AddrFormat($t);
736
- }
737
- $to = implode(', ', $toArr);
738
-
739
- if (empty($this->Sender)) {
740
- $params = "-oi ";
741
- } else {
742
- $params = sprintf("-oi -f %s", $this->Sender);
743
- }
744
- if ($this->Sender != '' and !ini_get('safe_mode')) {
745
- $old_from = ini_get('sendmail_from');
746
- ini_set('sendmail_from', $this->Sender);
747
- if ($this->SingleTo === true && count($toArr) > 1) {
748
- foreach ($toArr as $key => $val) {
749
- $rt = @mail($val, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params);
750
- // implement call back function if it exists
751
- $isSent = ($rt == 1) ? 1 : 0;
752
- $this->doCallback($isSent, $val, $this->cc, $this->bcc, $this->Subject, $body);
753
- }
754
- } else {
755
- $rt = @mail($to, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params);
756
- // implement call back function if it exists
757
- $isSent = ($rt == 1) ? 1 : 0;
758
- $this->doCallback($isSent, $to, $this->cc, $this->bcc, $this->Subject, $body);
759
- }
760
- } else {
761
- if ($this->SingleTo === true && count($toArr) > 1) {
762
- foreach ($toArr as $key => $val) {
763
- $rt = @mail($val, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params);
764
- // implement call back function if it exists
765
- $isSent = ($rt == 1) ? 1 : 0;
766
- $this->doCallback($isSent, $val, $this->cc, $this->bcc, $this->Subject, $body);
767
- }
768
- } else {
769
- $rt = @mail($to, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params);
770
- // implement call back function if it exists
771
- $isSent = ($rt == 1) ? 1 : 0;
772
- $this->doCallback($isSent, $to, $this->cc, $this->bcc, $this->Subject, $body);
773
- }
774
- }
775
- if (isset($old_from)) {
776
- ini_set('sendmail_from', $old_from);
777
- }
778
- if(!$rt) {
779
- throw new EM_phpmailerException($this->Lang('instantiate'), self::STOP_CRITICAL);
780
- }
781
- return true;
782
- }
783
-
784
- /**
785
- * Sends mail via SMTP using PhpSMTP
786
- * Returns false if there is a bad MAIL FROM, RCPT, or DATA input.
787
- * @param string $header The message headers
788
- * @param string $body The message body
789
- * @uses SMTP
790
- * @access protected
791
- * @return bool
792
- */
793
- protected function SmtpSend($header, $body) {
794
- require_once $this->PluginDir . 'class.smtp.php';
795
- $bad_rcpt = array();
796
-
797
- if(!$this->SmtpConnect()) {
798
- throw new EM_phpmailerException($this->Lang('smtp_connect_failed'), self::STOP_CRITICAL);
799
- }
800
- $smtp_from = ($this->Sender == '') ? $this->From : $this->Sender;
801
- if(!$this->smtp->Mail($smtp_from)) {
802
- throw new EM_phpmailerException($this->Lang('from_failed') . $smtp_from, self::STOP_CRITICAL);
803
- }
804
-
805
- // Attempt to send attach all recipients
806
- foreach($this->to as $to) {
807
- if (!$this->smtp->Recipient($to[0])) {
808
- $bad_rcpt[] = $to[0];
809
- // implement call back function if it exists
810
- $isSent = 0;
811
- $this->doCallback($isSent, $to[0], '', '', $this->Subject, $body);
812
- } else {
813
- // implement call back function if it exists
814
- $isSent = 1;
815
- $this->doCallback($isSent, $to[0], '', '', $this->Subject, $body);
816
- }
817
- }
818
- foreach($this->cc as $cc) {
819
- if (!$this->smtp->Recipient($cc[0])) {
820
- $bad_rcpt[] = $cc[0];
821
- // implement call back function if it exists
822
- $isSent = 0;
823
- $this->doCallback($isSent, '', $cc[0], '', $this->Subject, $body);
824
- } else {
825
- // implement call back function if it exists
826
- $isSent = 1;
827
- $this->doCallback($isSent, '', $cc[0], '', $this->Subject, $body);
828
- }
829
- }
830
- foreach($this->bcc as $bcc) {
831
- if (!$this->smtp->Recipient($bcc[0])) {
832
- $bad_rcpt[] = $bcc[0];
833
- // implement call back function if it exists
834
- $isSent = 0;
835
- $this->doCallback($isSent, '', '', $bcc[0], $this->Subject, $body);
836
- } else {
837
- // implement call back function if it exists
838
- $isSent = 1;
839
- $this->doCallback($isSent, '', '', $bcc[0], $this->Subject, $body);
840
- }
841
- }
842
-
843
-
844
- if (count($bad_rcpt) > 0 ) { //Create error message for any bad addresses
845
- $badaddresses = implode(', ', $bad_rcpt);
846
- throw new EM_phpmailerException($this->Lang('recipients_failed') . $badaddresses);
847
- }
848
- if(!$this->smtp->Data($header . $body)) {
849
- throw new EM_phpmailerException($this->Lang('data_not_accepted'), self::STOP_CRITICAL);
850
- }
851
- if($this->SMTPKeepAlive == true) {
852
- $this->smtp->Reset();
853
- }
854
- return true;
855
- }
856
-
857
- /**
858
- * Initiates a connection to an SMTP server.
859
- * Returns false if the operation failed.
860
- * @uses SMTP
861
- * @access public
862
- * @return bool
863
- */
864
- public function SmtpConnect() {
865
- if(is_null($this->smtp)) {
866
- $this->smtp = new EM_SMTP();
867
- }
868
-
869
- $this->smtp->do_debug = $this->SMTPDebug;
870
- $hosts = explode(';', $this->Host);
871
- $index = 0;
872
- $connection = $this->smtp->Connected();
873
-
874
- // Retry while there is no connection
875
- try {
876
- while($index < count($hosts) && !$connection) {
877
- $hostinfo = array();
878
- if (preg_match('/^(.+):([0-9]+)$/', $hosts[$index], $hostinfo)) {
879
- $host = $hostinfo[1];
880
- $port = $hostinfo[2];
881
- } else {
882
- $host = $hosts[$index];
883
- $port = $this->Port;
884
- }
885
-
886
- $tls = ($this->SMTPSecure == 'tls');
887
- $ssl = ($this->SMTPSecure == 'ssl');
888
-
889
- if ($this->smtp->Connect(($ssl ? 'ssl://':'').$host, $port, $this->Timeout)) {
890
-
891
- $hello = ($this->Helo != '' ? $this->Helo : $this->ServerHostname());
892
- $this->smtp->Hello($hello);
893
-
894
- if ($tls) {
895
- if (!$this->smtp->StartTLS()) {
896
- throw new EM_phpmailerException($this->Lang('tls'));
897
- }
898
-
899
- //We must resend HELO after tls negotiation
900
- $this->smtp->Hello($hello);
901
- }
902
-
903
- $connection = true;
904
- if ($this->SMTPAuth) {
905
- if (!$this->smtp->Authenticate($this->Username, $this->Password)) {
906
- throw new EM_phpmailerException($this->Lang('authenticate'));
907
- }
908
- }
909
- }
910
- $index++;
911
- if (!$connection) {
912
- throw new EM_phpmailerException($this->Lang('connect_host'));
913
- }
914
- }
915
- } catch (EM_phpmailerException $e) {
916
- $this->smtp->Reset();
917
- if ($this->exceptions) {
918
- throw $e;
919
- }
920
- }
921
- return true;
922
- }
923
-
924
- /**
925
- * Closes the active SMTP session if one exists.
926
- * @return void
927
- */
928
- public function SmtpClose() {
929
- if(!is_null($this->smtp)) {
930
- if($this->smtp->Connected()) {
931
- $this->smtp->Quit();
932
- $this->smtp->Close();
933
- }
934
- }
935
- }
936
-
937
- /**
938
- * Sets the language for all class error messages.
939
- * Returns false if it cannot load the language file. The default language is English.
940
- * @param string $langcode ISO 639-1 2-character language code (e.g. Portuguese: "br")
941
- * @param string $lang_path Path to the language file directory
942
- * @access public
943
- */
944
- function SetLanguage($langcode = 'en', $lang_path = 'language/') {
945
- //Define full set of translatable strings
946
- $PHPMAILER_LANG = array(
947
- 'provide_address' => 'You must provide at least one recipient email address.',
948
- 'mailer_not_supported' => ' mailer is not supported.',
949
- 'execute' => 'Could not execute: ',
950
- 'instantiate' => 'Could not instantiate mail function.',
951
- 'authenticate' => 'SMTP Error: Could not authenticate.',
952
- 'from_failed' => 'The following From address failed: ',
953
- 'recipients_failed' => 'SMTP Error: The following recipients failed: ',
954
- 'data_not_accepted' => 'SMTP Error: Data not accepted.',
955
- 'connect_host' => 'SMTP Error: Could not connect to SMTP host.',
956
- 'file_access' => 'Could not access file: ',
957
- 'file_open' => 'File Error: Could not open file: ',
958
- 'encoding' => 'Unknown encoding: ',
959
- 'signing' => 'Signing Error: ',
960
- 'smtp_error' => 'SMTP server error: ',
961
- 'empty_message' => 'Message body empty',
962
- 'invalid_address' => 'Invalid address',
963
- 'variable_set' => 'Cannot set or reset variable: '
964
- );
965
- //Overwrite language-specific strings. This way we'll never have missing translations - no more "language string failed to load"!
966
- $l = true;
967
- if ($langcode != 'en') { //There is no English translation file
968
- $l = @include $lang_path.'phpmailer.lang-'.$langcode.'.php';
969
- }
970
- $this->language = $PHPMAILER_LANG;
971
- return ($l == true); //Returns false if language not found
972
- }
973
-
974
- /**
975
- * Return the current array of language strings
976
- * @return array
977
- */
978
- public function GetTranslations() {
979
- return $this->language;
980
- }
981
-
982
- /////////////////////////////////////////////////
983
- // METHODS, MESSAGE CREATION
984
- /////////////////////////////////////////////////
985
-
986
- /**
987
- * Creates recipient headers.
988
- * @access public
989
- * @return string
990
- */
991
- public function AddrAppend($type, $addr) {
992
- $addr_str = $type . ': ';
993
- $addresses = array();
994
- foreach ($addr as $a) {
995
- $addresses[] = $this->AddrFormat($a);
996
- }
997
- $addr_str .= implode(', ', $addresses);
998
- $addr_str .= $this->LE;
999
-
1000
- return $addr_str;
1001
- }
1002
-
1003
- /**
1004
- * Formats an address correctly.
1005
- * @access public
1006
- * @return string
1007
- */
1008
- public function AddrFormat($addr) {
1009
- if (empty($addr[1])) {
1010
- return $this->SecureHeader($addr[0]);
1011
- } else {
1012
- return $this->EncodeHeader($this->SecureHeader($addr[1]), 'phrase') . " <" . $this->SecureHeader($addr[0]) . ">";
1013
- }
1014
- }
1015
-
1016
- /**
1017
- * Wraps message for use with mailers that do not
1018
- * automatically perform wrapping and for quoted-printable.
1019
- * Original written by philippe.
1020
- * @param string $message The message to wrap
1021
- * @param integer $length The line length to wrap to
1022
- * @param boolean $qp_mode Whether to run in Quoted-Printable mode
1023
- * @access public
1024
- * @return string
1025
- */
1026
- public function WrapText($message, $length, $qp_mode = false) {
1027
- $soft_break = ($qp_mode) ? sprintf(" =%s", $this->LE) : $this->LE;
1028
- // If utf-8 encoding is used, we will need to make sure we don't
1029
- // split multibyte characters when we wrap
1030
- $is_utf8 = (strtolower($this->CharSet) == "utf-8");
1031
-
1032
- $message = $this->FixEOL($message);
1033
- if (substr($message, -1) == $this->LE) {
1034
- $message = substr($message, 0, -1);
1035
- }
1036
-
1037
- $line = explode($this->LE, $message);
1038
- $message = '';
1039
- for ($i = 0 ;$i < count($line); $i++) {
1040
- $line_part = explode(' ', $line[$i]);
1041
- $buf = '';
1042
- for ($e = 0; $e<count($line_part); $e++) {
1043
- $word = $line_part[$e];
1044
- if ($qp_mode and (strlen($word) > $length)) {
1045
- $space_left = $length - strlen($buf) - 1;
1046
- if ($e != 0) {
1047
- if ($space_left > 20) {
1048
- $len = $space_left;
1049
- if ($is_utf8) {
1050
- $len = $this->UTF8CharBoundary($word, $len);
1051
- } elseif (substr($word, $len - 1, 1) == "=") {
1052
- $len--;
1053
- } elseif (substr($word, $len - 2, 1) == "=") {
1054
- $len -= 2;
1055
- }
1056
- $part = substr($word, 0, $len);
1057
- $word = substr($word, $len);
1058
- $buf .= ' ' . $part;
1059
- $message .= $buf . sprintf("=%s", $this->LE);
1060
- } else {
1061
- $message .= $buf . $soft_break;
1062
- }
1063
- $buf = '';
1064
- }
1065
- while (strlen($word) > 0) {
1066
- $len = $length;
1067
- if ($is_utf8) {
1068
- $len = $this->UTF8CharBoundary($word, $len);
1069
- } elseif (substr($word, $len - 1, 1) == "=") {
1070
- $len--;
1071
- } elseif (substr($word, $len - 2, 1) == "=") {
1072
- $len -= 2;
1073
- }
1074
- $part = substr($word, 0, $len);
1075
- $word = substr($word, $len);
1076
-
1077
- if (strlen($word) > 0) {
1078
- $message .= $part . sprintf("=%s", $this->LE);
1079
- } else {
1080
- $buf = $part;
1081
- }
1082
- }
1083
- } else {
1084
- $buf_o = $buf;
1085
- $buf .= ($e == 0) ? $word : (' ' . $word);
1086
-
1087
- if (strlen($buf) > $length and $buf_o != '') {
1088
- $message .= $buf_o . $soft_break;
1089
- $buf = $word;
1090
- }
1091
- }
1092
- }
1093
- $message .= $buf . $this->LE;
1094
- }
1095
-
1096
- return $message;
1097
- }
1098
-
1099
- /**
1100
- * Finds last character boundary prior to maxLength in a utf-8
1101
- * quoted (printable) encoded string.
1102
- * Original written by Colin Brown.
1103
- * @access public
1104
- * @param string $encodedText utf-8 QP text
1105
- * @param int $maxLength find last character boundary prior to this length
1106
- * @return int
1107
- */
1108
- public function UTF8CharBoundary($encodedText, $maxLength) {
1109
- $foundSplitPos = false;
1110
- $lookBack = 3;
1111
- while (!$foundSplitPos) {
1112
- $lastChunk = substr($encodedText, $maxLength - $lookBack, $lookBack);
1113
- $encodedCharPos = strpos($lastChunk, "=");
1114
- if ($encodedCharPos !== false) {
1115
- // Found start of encoded character byte within $lookBack block.
1116
- // Check the encoded byte value (the 2 chars after the '=')
1117
- $hex = substr($encodedText, $maxLength - $lookBack + $encodedCharPos + 1, 2);
1118
- $dec = hexdec($hex);
1119
- if ($dec < 128) { // Single byte character.
1120
- // If the encoded char was found at pos 0, it will fit
1121
- // otherwise reduce maxLength to start of the encoded char
1122
- $maxLength = ($encodedCharPos == 0) ? $maxLength :
1123
- $maxLength - ($lookBack - $encodedCharPos);
1124
- $foundSplitPos = true;
1125
- } elseif ($dec >= 192) { // First byte of a multi byte character
1126
- // Reduce maxLength to split at start of character
1127
- $maxLength = $maxLength - ($lookBack - $encodedCharPos);
1128
- $foundSplitPos = true;
1129
- } elseif ($dec < 192) { // Middle byte of a multi byte character, look further back
1130
- $lookBack += 3;
1131
- }
1132
- } else {
1133
- // No encoded character found
1134
- $foundSplitPos = true;
1135
- }
1136
- }
1137
- return $maxLength;
1138
- }
1139
-
1140
-
1141
- /**
1142
- * Set the body wrapping.
1143
- * @access public
1144
- * @return void
1145
- */
1146
- public function SetWordWrap() {
1147
- if($this->WordWrap < 1) {
1148
- return;
1149
- }
1150
-
1151
- switch($this->message_type) {
1152
- case 'alt':
1153
- case 'alt_inline':
1154
- case 'alt_attach':
1155
- case 'alt_inline_attach':
1156
- $this->AltBody = $this->WrapText($this->AltBody, $this->WordWrap);
1157
- break;
1158
- default:
1159
- $this->Body = $this->WrapText($this->Body, $this->WordWrap);
1160
- break;
1161
- }
1162
- }
1163
-
1164
- /**
1165
- * Assembles message header.
1166
- * @access public
1167
- * @return string The assembled header
1168
- */
1169
- public function CreateHeader() {
1170
- $result = '';
1171
-
1172
- // Set the boundaries
1173
- $uniq_id = md5(uniqid(time()));
1174
- $this->boundary[1] = 'b1_' . $uniq_id;
1175
- $this->boundary[2] = 'b2_' . $uniq_id;
1176
- $this->boundary[3] = 'b3_' . $uniq_id;
1177
-
1178
- $result .= $this->HeaderLine('Date', self::RFCDate());
1179
- if($this->Sender == '') {
1180
- $result .= $this->HeaderLine('Return-Path', trim($this->From));
1181
- } else {
1182
- $result .= $this->HeaderLine('Return-Path', trim($this->Sender));
1183
- }
1184
-
1185
- // To be created automatically by mail()
1186
- if($this->Mailer != 'mail') {
1187
- if ($this->SingleTo === true) {
1188
- foreach($this->to as $t) {
1189
- $this->SingleToArray[] = $this->AddrFormat($t);
1190
- }
1191
- } else {
1192
- if(count($this->to) > 0) {
1193
- $result .= $this->AddrAppend('To', $this->to);
1194
- } elseif (count($this->cc) == 0) {
1195
- $result .= $this->HeaderLine('To', 'undisclosed-recipients:;');
1196
- }
1197
- }
1198
- }
1199
-
1200
- $from = array();
1201
- $from[0][0] = trim($this->From);
1202
- $from[0][1] = $this->FromName;
1203
- $result .= $this->AddrAppend('From', $from);
1204
-
1205
- // sendmail and mail() extract Cc from the header before sending
1206
- if(count($this->cc) > 0) {
1207
- $result .= $this->AddrAppend('Cc', $this->cc);
1208
- }
1209
-
1210
- // sendmail and mail() extract Bcc from the header before sending
1211
- if((($this->Mailer == 'sendmail') || ($this->Mailer == 'mail')) && (count($this->bcc) > 0)) {
1212
- $result .= $this->AddrAppend('Bcc', $this->bcc);
1213
- }
1214
-
1215
- if(count($this->ReplyTo) > 0) {
1216
- $result .= $this->AddrAppend('Reply-To', $this->ReplyTo);
1217
- }
1218
-
1219
- // mail() sets the subject itself
1220
- if($this->Mailer != 'mail') {
1221
- $result .= $this->HeaderLine('Subject', $this->EncodeHeader($this->SecureHeader($this->Subject)));
1222
- }
1223
-
1224
- if($this->MessageID != '') {
1225
- $result .= $this->HeaderLine('Message-ID', $this->MessageID);
1226
- } else {
1227
- $result .= sprintf("Message-ID: <%s@%s>%s", $uniq_id, $this->ServerHostname(), $this->LE);
1228
- }
1229
- $result .= $this->HeaderLine('X-Priority', $this->Priority);
1230
- if($this->XMailer) {
1231
- $result .= $this->HeaderLine('X-Mailer', $this->XMailer);
1232
- } else {
1233
- $result .= $this->HeaderLine('X-Mailer', 'PHPMailer '.$this->Version.' (http://code.google.com/a/apache-extras.org/p/phpmailer/)');
1234
- }
1235
-
1236
- if($this->ConfirmReadingTo != '') {
1237
- $result .= $this->HeaderLine('Disposition-Notification-To', '<' . trim($this->ConfirmReadingTo) . '>');
1238
- }
1239
-
1240
- // Add custom headers
1241
- for($index = 0; $index < count($this->CustomHeader); $index++) {
1242
- $result .= $this->HeaderLine(trim($this->CustomHeader[$index][0]), $this->EncodeHeader(trim($this->CustomHeader[$index][1])));
1243
- }
1244
- if (!$this->sign_key_file) {
1245
- $result .= $this->HeaderLine('MIME-Version', '1.0');
1246
- $result .= $this->GetMailMIME();
1247
- }
1248
-
1249
- return $result;
1250
- }
1251
-
1252
- /**
1253
- * Returns the message MIME.
1254
- * @access public
1255
- * @return string
1256
- */
1257
- public function GetMailMIME() {
1258
- $result = '';
1259
- switch($this->message_type) {
1260
- case 'plain':
1261
- $result .= $this->HeaderLine('Content-Transfer-Encoding', $this->Encoding);
1262
- $result .= $this->TextLine('Content-Type: '.$this->ContentType.'; charset="'.$this->CharSet.'"');
1263
- break;
1264
- case 'inline':
1265
- $result .= $this->HeaderLine('Content-Type', 'multipart/related;');
1266
- $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"');
1267
- break;
1268
- case 'attach':
1269
- case 'inline_attach':
1270
- case 'alt_attach':
1271
- case 'alt_inline_attach':
1272
- $result .= $this->HeaderLine('Content-Type', 'multipart/mixed;');
1273
- $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"');
1274
- break;
1275
- case 'alt':
1276
- case 'alt_inline':
1277
- $result .= $this->HeaderLine('Content-Type', 'multipart/alternative;');
1278
- $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"');
1279
- break;
1280
- }
1281
-
1282
- if($this->Mailer != 'mail') {
1283
- $result .= $this->LE.$this->LE;
1284
- }
1285
-
1286
- return $result;
1287
- }
1288
-
1289
- /**
1290
- * Returns the MIME message (headers and body). Only really valid post PreSend().
1291
- * @access public
1292
- * @return string
1293
- */
1294
- public function GetSentMIMEMessage() {
1295
- return $this->SentMIMEMessage;
1296
- }
1297
-
1298
-
1299
- /**
1300
- * Assembles the message body. Returns an empty string on failure.
1301
- * @access public
1302
- * @return string The assembled message body
1303
- */
1304
- public function CreateBody() {
1305
- $body = '';
1306
-
1307
- if ($this->sign_key_file) {
1308
- $body .= $this->GetMailMIME();
1309
- }
1310
-
1311
- $this->SetWordWrap();
1312
-
1313
- switch($this->message_type) {
1314
- case 'plain':
1315
- $body .= $this->EncodeString($this->Body, $this->Encoding);
1316
- break;
1317
- case 'inline':
1318
- $body .= $this->GetBoundary($this->boundary[1], '', '', '');
1319
- $body .= $this->EncodeString($this->Body, $this->Encoding);
1320
- $body .= $this->LE.$this->LE;
1321
- $body .= $this->AttachAll("inline", $this->boundary[1]);
1322
- break;
1323
- case 'attach':
1324
- $body .= $this->GetBoundary($this->boundary[1], '', '', '');
1325
- $body .= $this->EncodeString($this->Body, $this->Encoding);
1326
- $body .= $this->LE.$this->LE;
1327
- $body .= $this->AttachAll("attachment", $this->boundary[1]);
1328
- break;
1329
- case 'inline_attach':
1330
- $body .= $this->TextLine("--" . $this->boundary[1]);
1331
- $body .= $this->HeaderLine('Content-Type', 'multipart/related;');
1332
- $body .= $this->TextLine("\tboundary=\"" . $this->boundary[2] . '"');
1333
- $body .= $this->LE;
1334
- $body .= $this->GetBoundary($this->boundary[2], '', '', '');
1335
- $body .= $this->EncodeString($this->Body, $this->Encoding);
1336
- $body .= $this->LE.$this->LE;
1337
- $body .= $this->AttachAll("inline", $this->boundary[2]);
1338
- $body .= $this->LE;
1339
- $body .= $this->AttachAll("attachment", $this->boundary[1]);
1340
- break;
1341
- case 'alt':
1342
- $body .= $this->GetBoundary($this->boundary[1], '', 'text/plain', '');
1343
- $body .= $this->EncodeString($this->AltBody, $this->Encoding);
1344
- $body .= $this->LE.$this->LE;
1345
- $body .= $this->GetBoundary($this->boundary[1], '', 'text/html', '');
1346
- $body .= $this->EncodeString($this->Body, $this->Encoding);
1347
- $body .= $this->LE.$this->LE;
1348
- $body .= $this->EndBoundary($this->boundary[1]);
1349
- break;
1350
- case 'alt_inline':
1351
- $body .= $this->GetBoundary($this->boundary[1], '', 'text/plain', '');
1352
- $body .= $this->EncodeString($this->AltBody, $this->Encoding);
1353
- $body .= $this->LE.$this->LE;
1354
- $body .= $this->TextLine("--" . $this->boundary[1]);
1355
- $body .= $this->HeaderLine('Content-Type', 'multipart/related;');
1356
- $body .= $this->TextLine("\tboundary=\"" . $this->boundary[2] . '"');
1357
- $body .= $this->LE;
1358
- $body .= $this->GetBoundary($this->boundary[2], '', 'text/html', '');
1359
- $body .= $this->EncodeString($this->Body, $this->Encoding);
1360
- $body .= $this->LE.$this->LE;
1361
- $body .= $this->AttachAll("inline", $this->boundary[2]);
1362
- $body .= $this->LE;
1363
- $body .= $this->EndBoundary($this->boundary[1]);
1364
- break;
1365
- case 'alt_attach':
1366
- $body .= $this->TextLine("--" . $this->boundary[1]);
1367
- $body .= $this->HeaderLine('Content-Type', 'multipart/alternative;');
1368
- $body .= $this->TextLine("\tboundary=\"" . $this->boundary[2] . '"');
1369
- $body .= $this->LE;
1370
- $body .= $this->GetBoundary($this->boundary[2], '', 'text/plain', '');
1371
- $body .= $this->EncodeString($this->AltBody, $this->Encoding);
1372
- $body .= $this->LE.$this->LE;
1373
- $body .= $this->GetBoundary($this->boundary[2], '', 'text/html', '');
1374
- $body .= $this->EncodeString($this->Body, $this->Encoding);
1375
- $body .= $this->LE.$this->LE;
1376
- $body .= $this->EndBoundary($this->boundary[2]);
1377
- $body .= $this->LE;
1378
- $body .= $this->AttachAll("attachment", $this->boundary[1]);
1379
- break;
1380
- case 'alt_inline_attach':
1381
- $body .= $this->TextLine("--" . $this->boundary[1]);
1382
- $body .= $this->HeaderLine('Content-Type', 'multipart/alternative;');
1383
- $body .= $this->TextLine("\tboundary=\"" . $this->boundary[2] . '"');
1384
- $body .= $this->LE;
1385
- $body .= $this->GetBoundary($this->boundary[2], '', 'text/plain', '');
1386
- $body .= $this->EncodeString($this->AltBody, $this->Encoding);
1387
- $body .= $this->LE.$this->LE;
1388
- $body .= $this->TextLine("--" . $this->boundary[2]);
1389
- $body .= $this->HeaderLine('Content-Type', 'multipart/related;');
1390
- $body .= $this->TextLine("\tboundary=\"" . $this->boundary[3] . '"');
1391
- $body .= $this->LE;
1392
- $body .= $this->GetBoundary($this->boundary[3], '', 'text/html', '');
1393
- $body .= $this->EncodeString($this->Body, $this->Encoding);
1394
- $body .= $this->LE.$this->LE;
1395
- $body .= $this->AttachAll("inline", $this->boundary[3]);
1396
- $body .= $this->LE;
1397
- $body .= $this->EndBoundary($this->boundary[2]);
1398
- $body .= $this->LE;
1399
- $body .= $this->AttachAll("attachment", $this->boundary[1]);
1400
- break;
1401
- }
1402
-
1403
- if ($this->IsError()) {
1404
- $body = '';
1405
- } elseif ($this->sign_key_file) {
1406
- try {
1407
- $file = tempnam('', 'mail');
1408
- file_put_contents($file, $body); //TODO check this worked
1409
- $signed = tempnam("", "signed");
1410
- if (@openssl_pkcs7_sign($file, $signed, "file://".$this->sign_cert_file, array("file://".$this->sign_key_file, $this->sign_key_pass), NULL)) {
1411
- @unlink($file);
1412
- $body = file_get_contents($signed);
1413
- @unlink($signed);
1414
- } else {
1415
- @unlink($file);
1416
- @unlink($signed);
1417
- throw new EM_phpmailerException($this->Lang("signing").openssl_error_string());
1418
- }
1419
- } catch (EM_phpmailerException $e) {
1420
- $body = '';
1421
- if ($this->exceptions) {
1422
- throw $e;
1423
- }
1424
- }
1425
- }
1426
-
1427
- return $body;
1428
- }
1429
-
1430
- /**
1431
- * Returns the start of a message boundary.
1432
- * @access protected
1433
- * @return string
1434
- */
1435
- protected function GetBoundary($boundary, $charSet, $contentType, $encoding) {
1436
- $result = '';
1437
- if($charSet == '') {
1438
- $charSet = $this->CharSet;
1439
- }
1440
- if($contentType == '') {
1441
- $contentType = $this->ContentType;
1442
- }
1443
- if($encoding == '') {
1444
- $encoding = $this->Encoding;
1445
- }
1446
- $result .= $this->TextLine('--' . $boundary);
1447
- $result .= sprintf("Content-Type: %s; charset=\"%s\"", $contentType, $charSet);
1448
- $result .= $this->LE;
1449
- $result .= $this->HeaderLine('Content-Transfer-Encoding', $encoding);
1450
- $result .= $this->LE;
1451
-
1452
- return $result;
1453
- }
1454
-
1455
- /**
1456
- * Returns the end of a message boundary.
1457
- * @access protected
1458
- * @return string
1459
- */
1460
- protected function EndBoundary($boundary) {
1461
- return $this->LE . '--' . $boundary . '--' . $this->LE;
1462
- }
1463
-
1464
- /**
1465
- * Sets the message type.
1466
- * @access protected
1467
- * @return void
1468
- */
1469
- protected function SetMessageType() {
1470
- $this->message_type = array();
1471
- if($this->AlternativeExists()) $this->message_type[] = "alt";
1472
- if($this->InlineImageExists()) $this->message_type[] = "inline";
1473
- if($this->AttachmentExists()) $this->message_type[] = "attach";
1474
- $this->message_type = implode("_", $this->message_type);
1475
- if($this->message_type == "") $this->message_type = "plain";
1476
- }
1477
-
1478
- /**
1479
- * Returns a formatted header line.
1480
- * @access public
1481
- * @return string
1482
- */
1483
- public function HeaderLine($name, $value) {
1484
- return $name . ': ' . $value . $this->LE;
1485
- }
1486
-
1487
- /**
1488
- * Returns a formatted mail line.
1489
- * @access public
1490
- * @return string
1491
- */
1492
- public function TextLine($value) {
1493
- return $value . $this->LE;
1494
- }
1495
-
1496
- /////////////////////////////////////////////////
1497
- // CLASS METHODS, ATTACHMENTS
1498
- /////////////////////////////////////////////////
1499
-
1500
- /**
1501
- * Adds an attachment from a path on the filesystem.
1502
- * Returns false if the file could not be found
1503
- * or accessed.
1504
- * @param string $path Path to the attachment.
1505
- * @param string $name Overrides the attachment name.
1506
- * @param string $encoding File encoding (see $Encoding).
1507
- * @param string $type File extension (MIME) type.
1508
- * @return bool
1509
- */
1510
- public function AddAttachment($path, $name = '', $encoding = 'base64', $type = 'application/octet-stream') {
1511
- try {
1512
- if ( !@is_file($path) ) {
1513
- throw new EM_phpmailerException($this->Lang('file_access') . $path, self::STOP_CONTINUE);
1514
- }
1515
- $filename = basename($path);
1516
- if ( $name == '' ) {
1517
- $name = $filename;
1518
- }
1519
-
1520
- $this->attachment[] = array(
1521
- 0 => $path,
1522
- 1 => $filename,
1523
- 2 => $name,
1524
- 3 => $encoding,
1525
- 4 => $type,
1526
- 5 => false, // isStringAttachment
1527
- 6 => 'attachment',
1528
- 7 => 0
1529
- );
1530
-
1531
- } catch (EM_phpmailerException $e) {
1532
- $this->SetError($e->getMessage());
1533
- if ($this->exceptions) {
1534
- throw $e;
1535
- }
1536
- if ($this->SMTPDebug) {
1537
- echo $e->getMessage()."\n";
1538
- }
1539
- if ( $e->getCode() == self::STOP_CRITICAL ) {
1540
- return false;
1541
- }
1542
- }
1543
- return true;
1544
- }
1545
-
1546
- /**
1547
- * Return the current array of attachments
1548
- * @return array
1549
- */
1550
- public function GetAttachments() {
1551
- return $this->attachment;
1552
- }
1553
-
1554
- /**
1555
- * Attaches all fs, string, and binary attachments to the message.
1556
- * Returns an empty string on failure.
1557
- * @access protected
1558
- * @return string
1559
- */
1560
- protected function AttachAll($disposition_type, $boundary) {
1561
- // Return text of body
1562
- $mime = array();
1563
- $cidUniq = array();
1564
- $incl = array();
1565
-
1566
- // Add all attachments
1567
- foreach ($this->attachment as $attachment) {
1568
- // CHECK IF IT IS A VALID DISPOSITION_FILTER
1569
- if($attachment[6] == $disposition_type) {
1570
- // Check for string attachment
1571
- $bString = $attachment[5];
1572
- if ($bString) {
1573
- $string = $attachment[0];
1574
- } else {
1575
- $path = $attachment[0];
1576
- }
1577
-
1578
- $inclhash = md5(serialize($attachment));
1579
- if (in_array($inclhash, $incl)) { continue; }
1580
- $incl[] = $inclhash;
1581
- $filename = $attachment[1];
1582
- $name = $attachment[2];
1583
- $encoding = $attachment[3];
1584
- $type = $attachment[4];
1585
- $disposition = $attachment[6];
1586
- $cid = $attachment[7];
1587
- if ( $disposition == 'inline' && isset($cidUniq[$cid]) ) { continue; }
1588
- $cidUniq[$cid] = true;
1589
-
1590
- $mime[] = sprintf("--%s%s", $boundary, $this->LE);
1591
- $mime[] = sprintf("Content-Type: %s; name=\"%s\"%s", $type, $this->EncodeHeader($this->SecureHeader($name)), $this->LE);
1592
- $mime[] = sprintf("Content-Transfer-Encoding: %s%s", $encoding, $this->LE);
1593
-
1594
- if($disposition == 'inline') {
1595
- $mime[] = sprintf("Content-ID: <%s>%s", $cid, $this->LE);
1596
- }
1597
-
1598
- $mime[] = sprintf("Content-Disposition: %s; filename=\"%s\"%s", $disposition, $this->EncodeHeader($this->SecureHeader($name)), $this->LE.$this->LE);
1599
-
1600
- // Encode as string attachment
1601
- if($bString) {
1602
- $mime[] = $this->EncodeString($string, $encoding);
1603
- if($this->IsError()) {
1604
- return '';
1605
- }
1606
- $mime[] = $this->LE.$this->LE;
1607
- } else {
1608
- $mime[] = $this->EncodeFile($path, $encoding);
1609
- if($this->IsError()) {
1610
- return '';
1611
- }
1612
- $mime[] = $this->LE.$this->LE;
1613
- }
1614
- }
1615
- }
1616
-
1617
- $mime[] = sprintf("--%s--%s", $boundary, $this->LE);
1618
-
1619
- return implode("", $mime);
1620
- }
1621
-
1622
- /**
1623
- * Encodes attachment in requested format.
1624
- * Returns an empty string on failure.
1625
- * @param string $path The full path to the file
1626
- * @param string $encoding The encoding to use; one of 'base64', '7bit', '8bit', 'binary', 'quoted-printable'
1627
- * @see EncodeFile()
1628
- * @access protected
1629
- * @return string
1630
- */
1631
- protected function EncodeFile($path, $encoding = 'base64') {
1632
- try {
1633
- if (!is_readable($path)) {
1634
- throw new EM_phpmailerException($this->Lang('file_open') . $path, self::STOP_CONTINUE);
1635
- }
1636
- if (function_exists('get_magic_quotes')) {
1637
- function get_magic_quotes() {
1638
- return false;
1639
- }
1640
- }
1641
- $magic_quotes = get_magic_quotes_runtime();
1642
- if ($magic_quotes) {
1643
- if (version_compare(PHP_VERSION, '5.3.0', '<')) {
1644
- set_magic_quotes_runtime(0);
1645
- } else {
1646
- ini_set('magic_quotes_runtime', 0);
1647
- }
1648
- }
1649
- $file_buffer = file_get_contents($path);
1650
- $file_buffer = $this->EncodeString($file_buffer, $encoding);
1651
- if ($magic_quotes) {
1652
- if (version_compare(PHP_VERSION, '5.3.0', '<')) {
1653
- set_magic_quotes_runtime($magic_quotes);
1654
- } else {
1655
- ini_set('magic_quotes_runtime', $magic_quotes);
1656
- }
1657
- }
1658
- return $file_buffer;
1659
- } catch (Exception $e) {
1660
- $this->SetError($e->getMessage());
1661
- return '';
1662
- }
1663
- }
1664
-
1665
- /**
1666
- * Encodes string to requested format.
1667
- * Returns an empty string on failure.
1668
- * @param string $str The text to encode
1669
- * @param string $encoding The encoding to use; one of 'base64', '7bit', '8bit', 'binary', 'quoted-printable'
1670
- * @access public
1671
- * @return string
1672
- */
1673
- public function EncodeString($str, $encoding = 'base64') {
1674
- $encoded = '';
1675
- switch(strtolower($encoding)) {
1676
- case 'base64':
1677
- $encoded = chunk_split(base64_encode($str), 76, $this->LE);
1678
- break;
1679
- case '7bit':
1680
- case '8bit':
1681
- $encoded = $this->FixEOL($str);
1682
- //Make sure it ends with a line break
1683
- if (substr($encoded, -(strlen($this->LE))) != $this->LE)
1684
- $encoded .= $this->LE;
1685
- break;
1686
- case 'binary':
1687
- $encoded = $str;
1688
- break;
1689
- case 'quoted-printable':
1690
- $encoded = $this->EncodeQP($str);
1691
- break;
1692
- default:
1693
- $this->SetError($this->Lang('encoding') . $encoding);
1694
- break;
1695
- }
1696
- return $encoded;
1697
- }
1698
-
1699
- /**
1700
- * Encode a header string to best (shortest) of Q, B, quoted or none.
1701
- * @access public
1702
- * @return string
1703
- */
1704
- public function EncodeHeader($str, $position = 'text') {
1705
- $x = 0;
1706
-
1707
- switch (strtolower($position)) {
1708
- case 'phrase':
1709
- if (!preg_match('/[\200-\377]/', $str)) {
1710
- // Can't use addslashes as we don't know what value has magic_quotes_sybase
1711
- $encoded = addcslashes($str, "\0..\37\177\\\"");
1712
- if (($str == $encoded) && !preg_match('/[^A-Za-z0-9!#$%&\'*+\/=?^_`{|}~ -]/', $str)) {
1713
- return ($encoded);
1714
- } else {
1715
- return ("\"$encoded\"");
1716
- }
1717
- }
1718
- $x = preg_match_all('/[^\040\041\043-\133\135-\176]/', $str, $matches);
1719
- break;
1720
- case 'comment':
1721
- $x = preg_match_all('/[()"]/', $str, $matches);
1722
- // Fall-through
1723
- case 'text':
1724
- default:
1725
- $x += preg_match_all('/[\000-\010\013\014\016-\037\177-\377]/', $str, $matches);
1726
- break;
1727
- }
1728
-
1729
- if ($x == 0) {
1730
- return ($str);
1731
- }
1732
-
1733
- $maxlen = 75 - 7 - strlen($this->CharSet);
1734
- // Try to select the encoding which should produce the shortest output
1735
- if (strlen($str)/3 < $x) {
1736
- $encoding = 'B';
1737
- if (function_exists('mb_strlen') && $this->HasMultiBytes($str)) {
1738
- // Use a custom function which correctly encodes and wraps long
1739
- // multibyte strings without breaking lines within a character
1740
- $encoded = $this->Base64EncodeWrapMB($str);
1741
- } else {
1742
- $encoded = base64_encode($str);
1743
- $maxlen -= $maxlen % 4;
1744
- $encoded = trim(chunk_split($encoded, $maxlen, "\n"));
1745
- }
1746
- } else {
1747
- $encoding = 'Q';
1748
- $encoded = $this->EncodeQ($str, $position);
1749
- $encoded = $this->WrapText($encoded, $maxlen, true);
1750
- $encoded = str_replace('='.$this->LE, "\n", trim($encoded));
1751
- }
1752
-
1753
- $encoded = preg_replace('/^(.*)$/m', " =?".$this->CharSet."?$encoding?\\1?=", $encoded);
1754
- $encoded = trim(str_replace("\n", $this->LE, $encoded));
1755
-
1756
- return $encoded;
1757
- }
1758
-
1759
- /**
1760
- * Checks if a string contains multibyte characters.
1761
- * @access public
1762
- * @param string $str multi-byte text to wrap encode
1763
- * @return bool
1764
- */
1765
- public function HasMultiBytes($str) {
1766
- if (function_exists('mb_strlen')) {
1767
- return (strlen($str) > mb_strlen($str, $this->CharSet));
1768
- } else { // Assume no multibytes (we can't handle without mbstring functions anyway)
1769
- return false;
1770
- }
1771
- }
1772
-
1773
- /**
1774
- * Correctly encodes and wraps long multibyte strings for mail headers
1775
- * without breaking lines within a character.
1776
- * Adapted from a function by paravoid at http://uk.php.net/manual/en/function.mb-encode-mimeheader.php
1777
- * @access public
1778
- * @param string $str multi-byte text to wrap encode
1779
- * @return string
1780
- */
1781
- public function Base64EncodeWrapMB($str) {
1782
- $start = "=?".$this->CharSet."?B?";
1783
- $end = "?=";
1784
- $encoded = "";
1785
-
1786
- $mb_length = mb_strlen($str, $this->CharSet);
1787
- // Each line must have length <= 75, including $start and $end
1788
- $length = 75 - strlen($start) - strlen($end);
1789
- // Average multi-byte ratio
1790
- $ratio = $mb_length / strlen($str);
1791
- // Base64 has a 4:3 ratio
1792
- $offset = $avgLength = floor($length * $ratio * .75);
1793
-
1794
- for ($i = 0; $i < $mb_length; $i += $offset) {
1795
- $lookBack = 0;
1796
-
1797
- do {
1798
- $offset = $avgLength - $lookBack;
1799
- $chunk = mb_substr($str, $i, $offset, $this->CharSet);
1800
- $chunk = base64_encode($chunk);
1801
- $lookBack++;
1802
- }
1803
- while (strlen($chunk) > $length);
1804
-
1805
- $encoded .= $chunk . $this->LE;
1806
- }
1807
-
1808
- // Chomp the last linefeed
1809
- $encoded = substr($encoded, 0, -strlen($this->LE));
1810
- return $encoded;
1811
- }
1812
-
1813
- /**
1814
- * Encode string to quoted-printable.
1815
- * Only uses standard PHP, slow, but will always work
1816
- * @access public
1817
- * @param string $string the text to encode
1818
- * @param integer $line_max Number of chars allowed on a line before wrapping
1819
- * @return string
1820
- */
1821
- public function EncodeQPphp( $input = '', $line_max = 76, $space_conv = false) {
1822
- $hex = array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F');
1823
- $lines = preg_split('/(?:\r\n|\r|\n)/', $input);
1824
- $eol = "\r\n";
1825
- $escape = '=';
1826
- $output = '';
1827
- while( list(, $line) = each($lines) ) {
1828
- $linlen = strlen($line);
1829
- $newline = '';
1830
- for($i = 0; $i < $linlen; $i++) {
1831
- $c = substr( $line, $i, 1 );
1832
- $dec = ord( $c );
1833
- if ( ( $i == 0 ) && ( $dec == 46 ) ) { // convert first point in the line into =2E
1834
- $c = '=2E';
1835
- }
1836
- if ( $dec == 32 ) {
1837
- if ( $i == ( $linlen - 1 ) ) { // convert space at eol only
1838
- $c = '=20';
1839
- } else if ( $space_conv ) {
1840
- $c = '=20';
1841
- }
1842
- } elseif ( ($dec == 61) || ($dec < 32 ) || ($dec > 126) ) { // always encode "\t", which is *not* required
1843
- $h2 = floor($dec/16);
1844
- $h1 = floor($dec%16);
1845
- $c = $escape.$hex[$h2].$hex[$h1];
1846
- }
1847
- if ( (strlen($newline) + strlen($c)) >= $line_max ) { // CRLF is not counted
1848
- $output .= $newline.$escape.$eol; // soft line break; " =\r\n" is okay
1849
- $newline = '';
1850
- // check if newline first character will be point or not
1851
- if ( $dec == 46 ) {
1852
- $c = '=2E';
1853
- }
1854
- }
1855
- $newline .= $c;
1856
- } // end of for
1857
- $output .= $newline.$eol;
1858
- } // end of while
1859
- return $output;
1860
- }
1861
-
1862
- /**
1863
- * Encode string to RFC2045 (6.7) quoted-printable format
1864
- * Uses a PHP5 stream filter to do the encoding about 64x faster than the old version
1865
- * Also results in same content as you started with after decoding
1866
- * @see EncodeQPphp()
1867
- * @access public
1868
- * @param string $string the text to encode
1869
- * @param integer $line_max Number of chars allowed on a line before wrapping
1870
- * @param boolean $space_conv Dummy param for compatibility with existing EncodeQP function
1871
- * @return string
1872
- * @author Marcus Bointon
1873
- */
1874
- public function EncodeQP($string, $line_max = 76, $space_conv = false) {
1875
- if (function_exists('quoted_printable_encode')) { //Use native function if it's available (>= PHP5.3)
1876
- return quoted_printable_encode($string);
1877
- }
1878
- $filters = stream_get_filters();
1879
- if (!in_array('convert.*', $filters)) { //Got convert stream filter?
1880
- return $this->EncodeQPphp($string, $line_max, $space_conv); //Fall back to old implementation
1881
- }
1882
- $fp = fopen('php://temp/', 'r+');
1883
- $string = preg_replace('/\r\n?/', $this->LE, $string); //Normalise line breaks
1884
- $params = array('line-length' => $line_max, 'line-break-chars' => $this->LE);
1885
- $s = stream_filter_append($fp, 'convert.quoted-printable-encode', STREAM_FILTER_READ, $params);
1886
- fputs($fp, $string);
1887
- rewind($fp);
1888
- $out = stream_get_contents($fp);
1889
- stream_filter_remove($s);
1890
- $out = preg_replace('/^\./m', '=2E', $out); //Encode . if it is first char on a line, workaround for bug in Exchange
1891
- fclose($fp);
1892
- return $out;
1893
- }
1894
-
1895
- /**
1896
- * Encode string to q encoding.
1897
- * @link http://tools.ietf.org/html/rfc2047
1898
- * @param string $str the text to encode
1899
- * @param string $position Where the text is going to be used, see the RFC for what that means
1900
- * @access public
1901
- * @return string
1902
- */
1903
- public function EncodeQ($str, $position = 'text') {
1904
- // There should not be any EOL in the string
1905
- $encoded = preg_replace('/[\r\n]*/', '', $str);
1906
-
1907
- switch (strtolower($position)) {
1908
- case 'phrase':
1909
- $encoded = preg_replace("/([^A-Za-z0-9!*+\/ -])/e", "'='.sprintf('%02X', ord('\\1'))", $encoded);
1910
- break;
1911
- case 'comment':
1912
- $encoded = preg_replace("/([\(\)\"])/e", "'='.sprintf('%02X', ord('\\1'))", $encoded);
1913
- case 'text':
1914
- default:
1915
- // Replace every high ascii, control =, ? and _ characters
1916
- //TODO using /e (equivalent to eval()) is probably not a good idea
1917
- $encoded = preg_replace('/([\000-\011\013\014\016-\037\075\077\137\177-\377])/e',
1918
- "'='.sprintf('%02X', ord(stripslashes('\\1')))", $encoded);
1919
- break;
1920
- }
1921
-
1922
- // Replace every spaces to _ (more readable than =20)
1923
- $encoded = str_replace(' ', '_', $encoded);
1924
-
1925
- return $encoded;
1926
- }
1927
-
1928
- /**
1929
- * Adds a string or binary attachment (non-filesystem) to the list.
1930
- * This method can be used to attach ascii or binary data,
1931
- * such as a BLOB record from a database.
1932
- * @param string $string String attachment data.
1933
- * @param string $filename Name of the attachment.
1934
- * @param string $encoding File encoding (see $Encoding).
1935
- * @param string $type File extension (MIME) type.
1936
- * @return void
1937
- */
1938
- public function AddStringAttachment($string, $filename, $encoding = 'base64', $type = 'application/octet-stream') {
1939
- // Append to $attachment array
1940
- $this->attachment[] = array(
1941
- 0 => $string,
1942
- 1 => $filename,
1943
- 2 => basename($filename),
1944
- 3 => $encoding,
1945
- 4 => $type,
1946
- 5 => true, // isStringAttachment
1947
- 6 => 'attachment',
1948
- 7 => 0
1949
- );
1950
- }
1951
-
1952
- /**
1953
- * Adds an embedded attachment. This can include images, sounds, and
1954
- * just about any other document. Make sure to set the $type to an
1955
- * image type. For JPEG images use "image/jpeg" and for GIF images
1956
- * use "image/gif".
1957
- * @param string $path Path to the attachment.
1958
- * @param string $cid Content ID of the attachment. Use this to identify
1959
- * the Id for accessing the image in an HTML form.
1960
- * @param string $name Overrides the attachment name.
1961
- * @param string $encoding File encoding (see $Encoding).
1962
- * @param string $type File extension (MIME) type.
1963
- * @return bool
1964
- */
1965
- public function AddEmbeddedImage($path, $cid, $name = '', $encoding = 'base64', $type = 'application/octet-stream') {
1966
-
1967
- if ( !@is_file($path) ) {
1968
- $this->SetError($this->Lang('file_access') . $path);
1969
- return false;
1970
- }
1971
-
1972
- $filename = basename($path);
1973
- if ( $name == '' ) {
1974
- $name = $filename;
1975
- }
1976
-
1977
- // Append to $attachment array
1978
- $this->attachment[] = array(
1979
- 0 => $path,
1980
- 1 => $filename,
1981
- 2 => $name,
1982
- 3 => $encoding,
1983
- 4 => $type,
1984
- 5 => false, // isStringAttachment
1985
- 6 => 'inline',
1986
- 7 => $cid
1987
- );
1988
-
1989
- return true;
1990
- }
1991
-
1992
- public function AddStringEmbeddedImage($string, $cid, $filename = '', $encoding = 'base64', $type = 'application/octet-stream') {
1993
- // Append to $attachment array
1994
- $this->attachment[] = array(
1995
- 0 => $string,
1996
- 1 => $filename,
1997
- 2 => basename($filename),
1998
- 3 => $encoding,
1999
- 4 => $type,
2000
- 5 => true, // isStringAttachment
2001
- 6 => 'inline',
2002
- 7 => $cid
2003
- );
2004
- }
2005
-
2006
- /**
2007
- * Returns true if an inline attachment is present.
2008
- * @access public
2009
- * @return bool
2010
- */
2011
- public function InlineImageExists() {
2012
- foreach($this->attachment as $attachment) {
2013
- if ($attachment[6] == 'inline') {
2014
- return true;
2015
- }
2016
- }
2017
- return false;
2018
- }
2019
-
2020
- public function AttachmentExists() {
2021
- foreach($this->attachment as $attachment) {
2022
- if ($attachment[6] == 'attachment') {
2023
- return true;
2024
- }
2025
- }
2026
- return false;
2027
- }
2028
-
2029
- public function AlternativeExists() {
2030
- return strlen($this->AltBody)>0;
2031
- }
2032
-
2033
- /////////////////////////////////////////////////
2034
- // CLASS METHODS, MESSAGE RESET
2035
- /////////////////////////////////////////////////
2036
-
2037
- /**
2038
- * Clears all recipients assigned in the TO array. Returns void.
2039
- * @return void
2040
- */
2041
- public function ClearAddresses() {
2042
- foreach($this->to as $to) {
2043
- unset($this->all_recipients[strtolower($to[0])]);
2044
- }
2045
- $this->to = array();
2046
- }
2047
-
2048
- /**
2049
- * Clears all recipients assigned in the CC array. Returns void.
2050
- * @return void
2051
- */
2052
- public function ClearCCs() {
2053
- foreach($this->cc as $cc) {
2054
- unset($this->all_recipients[strtolower($cc[0])]);
2055
- }
2056
- $this->cc = array();
2057
- }
2058
-
2059
- /**
2060
- * Clears all recipients assigned in the BCC array. Returns void.
2061
- * @return void
2062
- */
2063
- public function ClearBCCs() {
2064
- foreach($this->bcc as $bcc) {
2065
- unset($this->all_recipients[strtolower($bcc[0])]);
2066
- }
2067
- $this->bcc = array();
2068
- }
2069
-
2070
- /**
2071
- * Clears all recipients assigned in the ReplyTo array. Returns void.
2072
- * @return void
2073
- */
2074
- public function ClearReplyTos() {
2075
- $this->ReplyTo = array();
2076
- }
2077
-
2078
- /**
2079
- * Clears all recipients assigned in the TO, CC and BCC
2080
- * array. Returns void.
2081
- * @return void
2082
- */
2083
- public function ClearAllRecipients() {
2084
- $this->to = array();
2085
- $this->cc = array();
2086
- $this->bcc = array();
2087
- $this->all_recipients = array();
2088
- }
2089
-
2090
- /**
2091
- * Clears all previously set filesystem, string, and binary
2092
- * attachments. Returns void.
2093
- * @return void
2094
- */
2095
- public function ClearAttachments() {
2096
- $this->attachment = array();
2097
- }
2098
-
2099
- /**
2100
- * Clears all custom headers. Returns void.
2101
- * @return void
2102
- */
2103
- public function ClearCustomHeaders() {
2104
- $this->CustomHeader = array();
2105
- }
2106
-
2107
- /////////////////////////////////////////////////
2108
- // CLASS METHODS, MISCELLANEOUS
2109
- /////////////////////////////////////////////////
2110
-
2111
- /**
2112
- * Adds the error message to the error container.
2113
- * @access protected
2114
- * @return void
2115
- */
2116
- protected function SetError($msg) {
2117
- $this->error_count++;
2118
- if ($this->Mailer == 'smtp' and !is_null($this->smtp)) {
2119
- $lasterror = $this->smtp->getError();
2120
- if (!empty($lasterror) and array_key_exists('smtp_msg', $lasterror)) {
2121
- $msg .= '<p>' . $this->Lang('smtp_error') . $lasterror['smtp_msg'] . "</p>\n";
2122
- }
2123
- }
2124
- $this->ErrorInfo = $msg;
2125
- }
2126
-
2127
- /**
2128
- * Returns the proper RFC 822 formatted date.
2129
- * @access public
2130
- * @return string
2131
- * @static
2132
- */
2133
- public static function RFCDate() {
2134
- $tz = date('Z');
2135
- $tzs = ($tz < 0) ? '-' : '+';
2136
- $tz = abs($tz);
2137
- $tz = (int)($tz/3600)*100 + ($tz%3600)/60;
2138
- $result = sprintf("%s %s%04d", date('D, j M Y H:i:s'), $tzs, $tz);
2139
-
2140
- return $result;
2141
- }
2142
-
2143
- /**
2144
- * Returns the server hostname or 'localhost.localdomain' if unknown.
2145
- * @access protected
2146
- * @return string
2147
- */
2148
- protected function ServerHostname() {
2149
- if (!empty($this->Hostname)) {
2150
- $result = $this->Hostname;
2151
- } elseif (isset($_SERVER['SERVER_NAME'])) {
2152
- $result = $_SERVER['SERVER_NAME'];
2153
- } else {
2154
- $result = 'localhost.localdomain';
2155
- }
2156
-
2157
- return $result;
2158
- }
2159
-
2160
- /**
2161
- * Returns a message in the appropriate language.
2162
- * @access protected
2163
- * @return string
2164
- */
2165
- protected function Lang($key) {
2166
- if(count($this->language) < 1) {
2167
- $this->SetLanguage('en'); // set the default language
2168
- }
2169
-
2170
- if(isset($this->language[$key])) {
2171
- return $this->language[$key];
2172
- } else {
2173
- return 'Language string failed to load: ' . $key;
2174
- }
2175
- }
2176
-
2177
- /**
2178
- * Returns true if an error occurred.
2179
- * @access public
2180
- * @return bool
2181
- */
2182
- public function IsError() {
2183
- return ($this->error_count > 0);
2184
- }
2185
-
2186
- /**
2187
- * Changes every end of line from CR or LF to CRLF.
2188
- * @access public
2189
- * @return string
2190
- */
2191
- public function FixEOL($str) {
2192
- $str = str_replace("\r\n", "\n", $str);
2193
- $str = str_replace("\r", "\n", $str);
2194
- $str = str_replace("\n", $this->LE, $str);
2195
- return $str;
2196
- }
2197
-
2198
- /**
2199
- * Adds a custom header.
2200
- * @access public
2201
- * @return void
2202
- */
2203
- public function AddCustomHeader($custom_header) {
2204
- $this->CustomHeader[] = explode(':', $custom_header, 2);
2205
- }
2206
-
2207
- /**
2208
- * Evaluates the message and returns modifications for inline images and backgrounds
2209
- * @access public
2210
- * @return $message
2211
- */
2212
- public function MsgHTML($message, $basedir = '') {
2213
- preg_match_all("/(src|background)=[\"'](.*)[\"']/Ui", $message, $images);
2214
- if(isset($images[2])) {
2215
- foreach($images[2] as $i => $url) {
2216
- // do not change urls for absolute images (thanks to corvuscorax)
2217
- if (!preg_match('#^[A-z]+://#', $url)) {
2218
- $filename = basename($url);
2219
- $directory = dirname($url);
2220
- ($directory == '.') ? $directory='': '';
2221
- $cid = 'cid:' . md5($filename);
2222
- $ext = pathinfo($filename, PATHINFO_EXTENSION);
2223
- $mimeType = self::_mime_types($ext);
2224
- if ( strlen($basedir) > 1 && substr($basedir, -1) != '/') { $basedir .= '/'; }
2225
- if ( strlen($directory) > 1 && substr($directory, -1) != '/') { $directory .= '/'; }
2226
- if ( $this->AddEmbeddedImage($basedir.$directory.$filename, md5($filename), $filename, 'base64', $mimeType) ) {
2227
- $message = preg_replace("/".$images[1][$i]."=[\"']".preg_quote($url, '/')."[\"']/Ui", $images[1][$i]."=\"".$cid."\"", $message);
2228
- }
2229
- }
2230
- }
2231
- }
2232
- $this->IsHTML(true);
2233
- $this->Body = $message;
2234
- if (empty($this->AltBody)) {
2235
- $textMsg = trim(strip_tags(preg_replace('/<(head|title|style|script)[^>]*>.*?<\/\\1>/s', '', $message)));
2236
- if (!empty($textMsg)) {
2237
- $this->AltBody = html_entity_decode($textMsg, ENT_QUOTES, $this->CharSet);
2238
- }
2239
- }
2240
- if (empty($this->AltBody)) {
2241
- $this->AltBody = 'To view this email message, open it in a program that understands HTML!' . "\n\n";
2242
- }
2243
- return $message;
2244
- }
2245
-
2246
- /**
2247
- * Gets the MIME type of the embedded or inline image
2248
- * @param string File extension
2249
- * @access public
2250
- * @return string MIME type of ext
2251
- * @static
2252
- */
2253
- public static function _mime_types($ext = '') {
2254
- $mimes = array(
2255
- 'hqx' => 'application/mac-binhex40',
2256
- 'cpt' => 'application/mac-compactpro',
2257
- 'doc' => 'application/msword',
2258
- 'bin' => 'application/macbinary',
2259
- 'dms' => 'application/octet-stream',
2260
- 'lha' => 'application/octet-stream',
2261
- 'lzh' => 'application/octet-stream',
2262
- 'exe' => 'application/octet-stream',
2263
- 'class' => 'application/octet-stream',
2264
- 'psd' => 'application/octet-stream',
2265
- 'so' => 'application/octet-stream',
2266
- 'sea' => 'application/octet-stream',
2267
- 'dll' => 'application/octet-stream',
2268
- 'oda' => 'application/oda',
2269
- 'pdf' => 'application/pdf',
2270
- 'ai' => 'application/postscript',
2271
- 'eps' => 'application/postscript',
2272
- 'ps' => 'application/postscript',
2273
- 'smi' => 'application/smil',
2274
- 'smil' => 'application/smil',
2275
- 'mif' => 'application/vnd.mif',
2276
- 'xls' => 'application/vnd.ms-excel',
2277
- 'ppt' => 'application/vnd.ms-powerpoint',
2278
- 'wbxml' => 'application/vnd.wap.wbxml',
2279
- 'wmlc' => 'application/vnd.wap.wmlc',
2280
- 'dcr' => 'application/x-director',
2281
- 'dir' => 'application/x-director',
2282
- 'dxr' => 'application/x-director',
2283
- 'dvi' => 'application/x-dvi',
2284
- 'gtar' => 'application/x-gtar',
2285
- 'php' => 'application/x-httpd-php',
2286
- 'php4' => 'application/x-httpd-php',
2287
- 'php3' => 'application/x-httpd-php',
2288
- 'phtml' => 'application/x-httpd-php',
2289
- 'phps' => 'application/x-httpd-php-source',
2290
- 'js' => 'application/x-javascript',
2291
- 'swf' => 'application/x-shockwave-flash',
2292
- 'sit' => 'application/x-stuffit',
2293
- 'tar' => 'application/x-tar',
2294
- 'tgz' => 'application/x-tar',
2295
- 'xhtml' => 'application/xhtml+xml',
2296
- 'xht' => 'application/xhtml+xml',
2297
- 'zip' => 'application/zip',
2298
- 'mid' => 'audio/midi',
2299
- 'midi' => 'audio/midi',
2300
- 'mpga' => 'audio/mpeg',
2301
- 'mp2' => 'audio/mpeg',
2302
- 'mp3' => 'audio/mpeg',
2303
- 'aif' => 'audio/x-aiff',
2304
- 'aiff' => 'audio/x-aiff',
2305
- 'aifc' => 'audio/x-aiff',
2306
- 'ram' => 'audio/x-pn-realaudio',
2307
- 'rm' => 'audio/x-pn-realaudio',
2308
- 'rpm' => 'audio/x-pn-realaudio-plugin',
2309
- 'ra' => 'audio/x-realaudio',
2310
- 'rv' => 'video/vnd.rn-realvideo',
2311
- 'wav' => 'audio/x-wav',
2312
- 'bmp' => 'image/bmp',
2313
- 'gif' => 'image/gif',
2314
- 'jpeg' => 'image/jpeg',
2315
- 'jpg' => 'image/jpeg',
2316
- 'jpe' => 'image/jpeg',
2317
- 'png' => 'image/png',
2318
- 'tiff' => 'image/tiff',
2319
- 'tif' => 'image/tiff',
2320
- 'css' => 'text/css',
2321
- 'html' => 'text/html',
2322
- 'htm' => 'text/html',
2323
- 'shtml' => 'text/html',
2324
- 'txt' => 'text/plain',
2325
- 'text' => 'text/plain',
2326
- 'log' => 'text/plain',
2327
- 'rtx' => 'text/richtext',
2328
- 'rtf' => 'text/rtf',
2329
- 'xml' => 'text/xml',
2330
- 'xsl' => 'text/xml',
2331
- 'mpeg' => 'video/mpeg',
2332
- 'mpg' => 'video/mpeg',
2333
- 'mpe' => 'video/mpeg',
2334
- 'qt' => 'video/quicktime',
2335
- 'mov' => 'video/quicktime',
2336
- 'avi' => 'video/x-msvideo',
2337
- 'movie' => 'video/x-sgi-movie',
2338
- 'doc' => 'application/msword',
2339
- 'word' => 'application/msword',
2340
- 'xl' => 'application/excel',
2341
- 'eml' => 'message/rfc822'
2342
- );
2343
- return (!isset($mimes[strtolower($ext)])) ? 'application/octet-stream' : $mimes[strtolower($ext)];
2344
- }
2345
-
2346
- /**
2347
- * Set (or reset) Class Objects (variables)
2348
- *
2349
- * Usage Example:
2350
- * $page->set('X-Priority', '3');
2351
- *
2352
- * @access public
2353
- * @param string $name Parameter Name
2354
- * @param mixed $value Parameter Value
2355
- * NOTE: will not work with arrays, there are no arrays to set/reset
2356
- * @todo Should this not be using __set() magic function?
2357
- */
2358
- public function set($name, $value = '') {
2359
- try {
2360
- if (isset($this->$name) ) {
2361
- $this->$name = $value;
2362
- } else {
2363
- throw new EM_phpmailerException($this->Lang('variable_set') . $name, self::STOP_CRITICAL);
2364
- }
2365
- } catch (Exception $e) {
2366
- $this->SetError($e->getMessage());
2367
- if ($e->getCode() == self::STOP_CRITICAL) {
2368
- return false;
2369
- }
2370
- }
2371
- return true;
2372
- }
2373
-
2374
- /**
2375
- * Strips newlines to prevent header injection.
2376
- * @access public
2377
- * @param string $str String
2378
- * @return string
2379
- */
2380
- public function SecureHeader($str) {
2381
- $str = str_replace("\r", '', $str);
2382
- $str = str_replace("\n", '', $str);
2383
- return trim($str);
2384
- }
2385
-
2386
- /**
2387
- * Set the private key file and password to sign the message.
2388
- *
2389
- * @access public
2390
- * @param string $key_filename Parameter File Name
2391
- * @param string $key_pass Password for private key
2392
- */
2393
- public function Sign($cert_filename, $key_filename, $key_pass) {
2394
- $this->sign_cert_file = $cert_filename;
2395
- $this->sign_key_file = $key_filename;
2396
- $this->sign_key_pass = $key_pass;
2397
- }
2398
-
2399
- /**
2400
- * Set the private key file and password to sign the message.
2401
- *
2402
- * @access public
2403
- * @param string $key_filename Parameter File Name
2404
- * @param string $key_pass Password for private key
2405
- */
2406
- public function DKIM_QP($txt) {
2407
- $tmp = '';
2408
- $line = '';
2409
- for ($i = 0; $i < strlen($txt); $i++) {
2410
- $ord = ord($txt[$i]);
2411
- if ( ((0x21 <= $ord) && ($ord <= 0x3A)) || $ord == 0x3C || ((0x3E <= $ord) && ($ord <= 0x7E)) ) {
2412
- $line .= $txt[$i];
2413
- } else {
2414
- $line .= "=".sprintf("%02X", $ord);
2415
- }
2416
- }
2417
- return $line;
2418
- }
2419
-
2420
- /**
2421
- * Generate DKIM signature
2422
- *
2423
- * @access public
2424
- * @param string $s Header
2425
- */
2426
- public function DKIM_Sign($s) {
2427
- $privKeyStr = file_get_contents($this->DKIM_private);
2428
- if ($this->DKIM_passphrase != '') {
2429
- $privKey = openssl_pkey_get_private($privKeyStr, $this->DKIM_passphrase);
2430
- } else {
2431
- $privKey = $privKeyStr;
2432
- }
2433
- if (openssl_sign($s, $signature, $privKey)) {
2434
- return base64_encode($signature);
2435
- }
2436
- }
2437
-
2438
- /**
2439
- * Generate DKIM Canonicalization Header
2440
- *
2441
- * @access public
2442
- * @param string $s Header
2443
- */
2444
- public function DKIM_HeaderC($s) {
2445
- $s = preg_replace("/\r\n\s+/", " ", $s);
2446
- $lines = explode("\r\n", $s);
2447
- foreach ($lines as $key => $line) {
2448
- list($heading, $value) = explode(":", $line, 2);
2449
- $heading = strtolower($heading);
2450
- $value = preg_replace("/\s+/", " ", $value) ; // Compress useless spaces
2451
- $lines[$key] = $heading.":".trim($value) ; // Don't forget to remove WSP around the value
2452
- }
2453
- $s = implode("\r\n", $lines);
2454
- return $s;
2455
- }
2456
-
2457
- /**
2458
- * Generate DKIM Canonicalization Body
2459
- *
2460
- * @access public
2461
- * @param string $body Message Body
2462
- */
2463
- public function DKIM_BodyC($body) {
2464
- if ($body == '') return "\r\n";
2465
- // stabilize line endings
2466
- $body = str_replace("\r\n", "\n", $body);
2467
- $body = str_replace("\n", "\r\n", $body);
2468
- // END stabilize line endings
2469
- while (substr($body, strlen($body) - 4, 4) == "\r\n\r\n") {
2470
- $body = substr($body, 0, strlen($body) - 2);
2471
- }
2472
- return $body;
2473
- }
2474
-
2475
- /**
2476
- * Create the DKIM header, body, as new header
2477
- *
2478
- * @access public
2479
- * @param string $headers_line Header lines
2480
- * @param string $subject Subject
2481
- * @param string $body Body
2482
- */
2483
- public function DKIM_Add($headers_line, $subject, $body) {
2484
- $DKIMsignatureType = 'rsa-sha1'; // Signature & hash algorithms
2485
- $DKIMcanonicalization = 'relaxed/simple'; // Canonicalization of header/body
2486
- $DKIMquery = 'dns/txt'; // Query method
2487
- $DKIMtime = time() ; // Signature Timestamp = seconds since 00:00:00 - Jan 1, 1970 (UTC time zone)
2488
- $subject_header = "Subject: $subject";
2489
- $headers = explode($this->LE, $headers_line);
2490
- foreach($headers as $header) {
2491
- if (strpos($header, 'From:') === 0) {
2492
- $from_header = $header;
2493
- } elseif (strpos($header, 'To:') === 0) {
2494
- $to_header = $header;
2495
- }
2496
- }
2497
- $from = str_replace('|', '=7C', $this->DKIM_QP($from_header));
2498
- $to = str_replace('|', '=7C', $this->DKIM_QP($to_header));
2499
- $subject = str_replace('|', '=7C', $this->DKIM_QP($subject_header)) ; // Copied header fields (dkim-quoted-printable
2500
- $body = $this->DKIM_BodyC($body);
2501
- $DKIMlen = strlen($body) ; // Length of body
2502
- $DKIMb64 = base64_encode(pack("H*", sha1($body))) ; // Base64 of packed binary SHA-1 hash of body
2503
- $ident = ($this->DKIM_identity == '')? '' : " i=" . $this->DKIM_identity . ";";
2504
- $dkimhdrs = "DKIM-Signature: v=1; a=" . $DKIMsignatureType . "; q=" . $DKIMquery . "; l=" . $DKIMlen . "; s=" . $this->DKIM_selector . ";\r\n".
2505
- "\tt=" . $DKIMtime . "; c=" . $DKIMcanonicalization . ";\r\n".
2506
- "\th=From:To:Subject;\r\n".
2507
- "\td=" . $this->DKIM_domain . ";" . $ident . "\r\n".
2508
- "\tz=$from\r\n".
2509
- "\t|$to\r\n".
2510
- "\t|$subject;\r\n".
2511
- "\tbh=" . $DKIMb64 . ";\r\n".
2512
- "\tb=";
2513
- $toSign = $this->DKIM_HeaderC($from_header . "\r\n" . $to_header . "\r\n" . $subject_header . "\r\n" . $dkimhdrs);
2514
- $signed = $this->DKIM_Sign($toSign);
2515
- return "X-PHPMAILER-DKIM: phpmailer.worxware.com\r\n".$dkimhdrs.$signed."\r\n";
2516
- }
2517
-
2518
- protected function doCallback($isSent, $to, $cc, $bcc, $subject, $body) {
2519
- if (!empty($this->action_function) && function_exists($this->action_function)) {
2520
- $params = array($isSent, $to, $cc, $bcc, $subject, $body);
2521
- call_user_func_array($this->action_function, $params);
2522
- }
2523
- }
2524
- }
2525
-
2526
- class EM_phpmailerException extends Exception {
2527
- public function errorMessage() {
2528
- $errorMsg = '<strong>' . $this->getMessage() . "</strong><br />\n";
2529
- return $errorMsg;
2530
- }
2531
- }
2532
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/phpmailer/class.smtp.php DELETED
@@ -1,818 +0,0 @@
1
- <?php
2
- /*~ class.smtp.php
3
- .---------------------------------------------------------------------------.
4
- | Software: PHPMailer - PHP email class |
5
- | Version: 5.2.1 |
6
- | Site: https://code.google.com/a/apache-extras.org/p/phpmailer/ |
7
- | ------------------------------------------------------------------------- |
8
- | Admin: Jim Jagielski (project admininistrator) |
9
- | Authors: Andy Prevost (codeworxtech) codeworxtech@users.sourceforge.net |
10
- | : Marcus Bointon (coolbru) coolbru@users.sourceforge.net |
11
- | : Jim Jagielski (jimjag) jimjag@gmail.com |
12
- | Founder: Brent R. Matzelle (original founder) |
13
- | Copyright (c) 2010-2012, Jim Jagielski. All Rights Reserved. |
14
- | Copyright (c) 2004-2009, Andy Prevost. All Rights Reserved. |
15
- | Copyright (c) 2001-2003, Brent R. Matzelle |
16
- | ------------------------------------------------------------------------- |
17
- | License: Distributed under the Lesser General Public License (LGPL) |
18
- | http://www.gnu.org/copyleft/lesser.html |
19
- | This program is distributed in the hope that it will be useful - WITHOUT |
20
- | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
21
- | FITNESS FOR A PARTICULAR PURPOSE. |
22
- '---------------------------------------------------------------------------'
23
- */
24
-
25
- /**
26
- * PHPMailer - PHP SMTP email transport class
27
- * NOTE: Designed for use with PHP version 5 and up
28
- * @package PHPMailer
29
- * @author Andy Prevost
30
- * @author Marcus Bointon
31
- * @copyright 2004 - 2008 Andy Prevost
32
- * @author Jim Jagielski
33
- * @copyright 2010 - 2012 Jim Jagielski
34
- * @license http://www.gnu.org/copyleft/lesser.html Distributed under the Lesser General Public License (LGPL)
35
- * @version $Id: class.smtp.php 450 2010-06-23 16:46:33Z coolbru $
36
- */
37
-
38
- /**
39
- * SMTP is rfc 821 compliant and implements all the rfc 821 SMTP
40
- * commands except TURN which will always return a not implemented
41
- * error. SMTP also provides some utility methods for sending mail
42
- * to an SMTP server.
43
- * original author: Chris Ryan
44
- */
45
-
46
- class EM_SMTP {
47
- /**
48
- * SMTP server port
49
- * @var int
50
- */
51
- public $SMTP_PORT = 25;
52
-
53
- /**
54
- * SMTP reply line ending
55
- * @var string
56
- */
57
- public $CRLF = "\r\n";
58
-
59
- /**
60
- * Sets whether debugging is turned on
61
- * @var bool
62
- */
63
- public $do_debug; // the level of debug to perform
64
-
65
- /**
66
- * Sets VERP use on/off (default is off)
67
- * @var bool
68
- */
69
- public $do_verp = false;
70
-
71
- /**
72
- * Sets the SMTP PHPMailer Version number
73
- * @var string
74
- */
75
- public $Version = '5.2.1';
76
-
77
- /////////////////////////////////////////////////
78
- // PROPERTIES, PRIVATE AND PROTECTED
79
- /////////////////////////////////////////////////
80
-
81
- private $smtp_conn; // the socket to the server
82
- private $error; // error if any on the last call
83
- private $helo_rply; // the reply the server sent to us for HELO
84
-
85
- /**
86
- * Initialize the class so that the data is in a known state.
87
- * @access public
88
- * @return void
89
- */
90
- public function __construct() {
91
- $this->smtp_conn = 0;
92
- $this->error = null;
93
- $this->helo_rply = null;
94
-
95
- $this->do_debug = 0;
96
- }
97
-
98
- /////////////////////////////////////////////////
99
- // CONNECTION FUNCTIONS
100
- /////////////////////////////////////////////////
101
-
102
- /**
103
- * Connect to the server specified on the port specified.
104
- * If the port is not specified use the default SMTP_PORT.
105
- * If tval is specified then a connection will try and be
106
- * established with the server for that number of seconds.
107
- * If tval is not specified the default is 30 seconds to
108
- * try on the connection.
109
- *
110
- * SMTP CODE SUCCESS: 220
111
- * SMTP CODE FAILURE: 421
112
- * @access public
113
- * @return bool
114
- */
115
- public function Connect($host, $port = 0, $tval = 30) {
116
- // set the error val to null so there is no confusion
117
- $this->error = null;
118
-
119
- // make sure we are __not__ connected
120
- if($this->connected()) {
121
- // already connected, generate error
122
- $this->error = array("error" => "Already connected to a server");
123
- return false;
124
- }
125
-
126
- if(empty($port)) {
127
- $port = $this->SMTP_PORT;
128
- }
129
-
130
- // connect to the smtp server
131
- $this->smtp_conn = @fsockopen($host, // the host of the server
132
- $port, // the port to use
133
- $errno, // error number if any
134
- $errstr, // error message if any
135
- $tval); // give up after ? secs
136
- // verify we connected properly
137
- if(empty($this->smtp_conn)) {
138
- $this->error = array("error" => "Failed to connect to server",
139
- "errno" => $errno,
140
- "errstr" => $errstr);
141
- if($this->do_debug >= 1) {
142
- echo "SMTP -> ERROR: " . $this->error["error"] . ": $errstr ($errno)" . $this->CRLF . '<br />';
143
- }
144
- return false;
145
- }
146
-
147
- // SMTP server can take longer to respond, give longer timeout for first read
148
- // Windows does not have support for this timeout function
149
- if(substr(PHP_OS, 0, 3) != "WIN")
150
- socket_set_timeout($this->smtp_conn, $tval, 0);
151
-
152
- // get any announcement
153
- $announce = $this->get_lines();
154
-
155
- if($this->do_debug >= 2) {
156
- echo "SMTP -> FROM SERVER:" . $announce . $this->CRLF . '<br />';
157
- }
158
-
159
- return true;
160
- }
161
-
162
- /**
163
- * Initiate a TLS communication with the server.
164
- *
165
- * SMTP CODE 220 Ready to start TLS
166
- * SMTP CODE 501 Syntax error (no parameters allowed)
167
- * SMTP CODE 454 TLS not available due to temporary reason
168
- * @access public
169
- * @return bool success
170
- */
171
- public function StartTLS() {
172
- $this->error = null; # to avoid confusion
173
-
174
- if(!$this->connected()) {
175
- $this->error = array("error" => "Called StartTLS() without being connected");
176
- return false;
177
- }
178
-
179
- fputs($this->smtp_conn,"STARTTLS" . $this->CRLF);
180
-
181
- $rply = $this->get_lines();
182
- $code = substr($rply,0,3);
183
-
184
- if($this->do_debug >= 2) {
185
- echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />';
186
- }
187
-
188
- if($code != 220) {
189
- $this->error =
190
- array("error" => "STARTTLS not accepted from server",
191
- "smtp_code" => $code,
192
- "smtp_msg" => substr($rply,4));
193
- if($this->do_debug >= 1) {
194
- echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
195
- }
196
- return false;
197
- }
198
-
199
- // Begin encrypted connection
200
- if(!stream_socket_enable_crypto($this->smtp_conn, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) {
201
- return false;
202
- }
203
-
204
- return true;
205
- }
206
-
207
- /**
208
- * Performs SMTP authentication. Must be run after running the
209
- * Hello() method. Returns true if successfully authenticated.
210
- * @access public
211
- * @return bool
212
- */
213
- public function Authenticate($username, $password) {
214
- // Start authentication
215
- fputs($this->smtp_conn,"AUTH LOGIN" . $this->CRLF);
216
-
217
- $rply = $this->get_lines();
218
- $code = substr($rply,0,3);
219
-
220
- if($code != 334) {
221
- $this->error =
222
- array("error" => "AUTH not accepted from server",
223
- "smtp_code" => $code,
224
- "smtp_msg" => substr($rply,4));
225
- if($this->do_debug >= 1) {
226
- echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
227
- }
228
- return false;
229
- }
230
-
231
- // Send encoded username
232
- fputs($this->smtp_conn, base64_encode($username) . $this->CRLF);
233
-
234
- $rply = $this->get_lines();
235
- $code = substr($rply,0,3);
236
-
237
- if($code != 334) {
238
- $this->error =
239
- array("error" => "Username not accepted from server",
240
- "smtp_code" => $code,
241
- "smtp_msg" => substr($rply,4));
242
- if($this->do_debug >= 1) {
243
- echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
244
- }
245
- return false;
246
- }
247
-
248
- // Send encoded password
249
- fputs($this->smtp_conn, base64_encode($password) . $this->CRLF);
250
-
251
- $rply = $this->get_lines();
252
- $code = substr($rply,0,3);
253
-
254
- if($code != 235) {
255
- $this->error =
256
- array("error" => "Password not accepted from server",
257
- "smtp_code" => $code,
258
- "smtp_msg" => substr($rply,4));
259
- if($this->do_debug >= 1) {
260
- echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
261
- }
262
- return false;
263
- }
264
-
265
- return true;
266
- }
267
-
268
- /**
269
- * Returns true if connected to a server otherwise false
270
- * @access public
271
- * @return bool
272
- */
273
- public function Connected() {
274
- if(!empty($this->smtp_conn)) {
275
- $sock_status = socket_get_status($this->smtp_conn);
276
- if($sock_status["eof"]) {
277
- // the socket is valid but we are not connected
278
- if($this->do_debug >= 1) {
279
- echo "SMTP -> NOTICE:" . $this->CRLF . "EOF caught while checking if connected";
280
- }
281
- $this->Close();
282
- return false;
283
- }
284
- return true; // everything looks good
285
- }
286
- return false;
287
- }
288
-
289
- /**
290
- * Closes the socket and cleans up the state of the class.
291
- * It is not considered good to use this function without
292
- * first trying to use QUIT.
293
- * @access public
294
- * @return void
295
- */
296
- public function Close() {
297
- $this->error = null; // so there is no confusion
298
- $this->helo_rply = null;
299
- if(!empty($this->smtp_conn)) {
300
- // close the connection and cleanup
301
- fclose($this->smtp_conn);
302
- $this->smtp_conn = 0;
303
- }
304
- }
305
-
306
- /////////////////////////////////////////////////
307
- // SMTP COMMANDS
308
- /////////////////////////////////////////////////
309
-
310
- /**
311
- * Issues a data command and sends the msg_data to the server
312
- * finializing the mail transaction. $msg_data is the message
313
- * that is to be send with the headers. Each header needs to be
314
- * on a single line followed by a <CRLF> with the message headers
315
- * and the message body being separated by and additional <CRLF>.
316
- *
317
- * Implements rfc 821: DATA <CRLF>
318
- *
319
- * SMTP CODE INTERMEDIATE: 354
320
- * [data]
321
- * <CRLF>.<CRLF>
322
- * SMTP CODE SUCCESS: 250
323
- * SMTP CODE FAILURE: 552,554,451,452
324
- * SMTP CODE FAILURE: 451,554
325
- * SMTP CODE ERROR : 500,501,503,421
326
- * @access public
327
- * @return bool
328
- */
329
- public function Data($msg_data) {
330
- $this->error = null; // so no confusion is caused
331
-
332
- if(!$this->connected()) {
333
- $this->error = array(
334
- "error" => "Called Data() without being connected");
335
- return false;
336
- }
337
-
338
- fputs($this->smtp_conn,"DATA" . $this->CRLF);
339
-
340
- $rply = $this->get_lines();
341
- $code = substr($rply,0,3);
342
-
343
- if($this->do_debug >= 2) {
344
- echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />';
345
- }
346
-
347
- if($code != 354) {
348
- $this->error =
349
- array("error" => "DATA command not accepted from server",
350
- "smtp_code" => $code,
351
- "smtp_msg" => substr($rply,4));
352
- if($this->do_debug >= 1) {
353
- echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
354
- }
355
- return false;
356
- }
357
-
358
- /* the server is ready to accept data!
359
- * according to rfc 821 we should not send more than 1000
360
- * including the CRLF
361
- * characters on a single line so we will break the data up
362
- * into lines by \r and/or \n then if needed we will break
363
- * each of those into smaller lines to fit within the limit.
364
- * in addition we will be looking for lines that start with
365
- * a period '.' and append and additional period '.' to that
366
- * line. NOTE: this does not count towards limit.
367
- */
368
-
369
- // normalize the line breaks so we know the explode works
370
- $msg_data = str_replace("\r\n","\n",$msg_data);
371
- $msg_data = str_replace("\r","\n",$msg_data);
372
- $lines = explode("\n",$msg_data);
373
-
374
- /* we need to find a good way to determine is headers are
375
- * in the msg_data or if it is a straight msg body
376
- * currently I am assuming rfc 822 definitions of msg headers
377
- * and if the first field of the first line (':' sperated)
378
- * does not contain a space then it _should_ be a header
379
- * and we can process all lines before a blank "" line as
380
- * headers.
381
- */
382
-
383
- $field = substr($lines[0],0,strpos($lines[0],":"));
384
- $in_headers = false;
385
- if(!empty($field) && !strstr($field," ")) {
386
- $in_headers = true;
387
- }
388
-
389
- $max_line_length = 998; // used below; set here for ease in change
390
-
391
- while(list(,$line) = @each($lines)) {
392
- $lines_out = null;
393
- if($line == "" && $in_headers) {
394
- $in_headers = false;
395
- }
396
- // ok we need to break this line up into several smaller lines
397
- while(strlen($line) > $max_line_length) {
398
- $pos = strrpos(substr($line,0,$max_line_length)," ");
399
-
400
- // Patch to fix DOS attack
401
- if(!$pos) {
402
- $pos = $max_line_length - 1;
403
- $lines_out[] = substr($line,0,$pos);
404
- $line = substr($line,$pos);
405
- } else {
406
- $lines_out[] = substr($line,0,$pos);
407
- $line = substr($line,$pos + 1);
408
- }
409
-
410
- /* if processing headers add a LWSP-char to the front of new line
411
- * rfc 822 on long msg headers
412
- */
413
- if($in_headers) {
414
- $line = "\t" . $line;
415
- }
416
- }
417
- $lines_out[] = $line;
418
-
419
- // send the lines to the server
420
- while(list(,$line_out) = @each($lines_out)) {
421
- if(strlen($line_out) > 0)
422
- {
423
- if(substr($line_out, 0, 1) == ".") {
424
- $line_out = "." . $line_out;
425
- }
426
- }
427
- fputs($this->smtp_conn,$line_out . $this->CRLF);
428
- }
429
- }
430
-
431
- // message data has been sent
432
- fputs($this->smtp_conn, $this->CRLF . "." . $this->CRLF);
433
-
434
- $rply = $this->get_lines();
435
- $code = substr($rply,0,3);
436
-
437
- if($this->do_debug >= 2) {
438
- echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />';
439
- }
440
-
441
- if($code != 250) {
442
- $this->error =
443
- array("error" => "DATA not accepted from server",
444
- "smtp_code" => $code,
445
- "smtp_msg" => substr($rply,4));
446
- if($this->do_debug >= 1) {
447
- echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
448
- }
449
- return false;
450
- }
451
- return true;
452
- }
453
-
454
- /**
455
- * Sends the HELO command to the smtp server.
456
- * This makes sure that we and the server are in
457
- * the same known state.
458
- *
459
- * Implements from rfc 821: HELO <SP> <domain> <CRLF>
460
- *
461
- * SMTP CODE SUCCESS: 250
462
- * SMTP CODE ERROR : 500, 501, 504, 421
463
- * @access public
464
- * @return bool
465
- */
466
- public function Hello($host = '') {
467
- $this->error = null; // so no confusion is caused
468
-
469
- if(!$this->connected()) {
470
- $this->error = array(
471
- "error" => "Called Hello() without being connected");
472
- return false;
473
- }
474
-
475
- // if hostname for HELO was not specified send default
476
- if(empty($host)) {
477
- // determine appropriate default to send to server
478
- $host = "localhost";
479
- }
480
-
481
- // Send extended hello first (RFC 2821)
482
- if(!$this->SendHello("EHLO", $host)) {
483
- if(!$this->SendHello("HELO", $host)) {
484
- return false;
485
- }
486
- }
487
-
488
- return true;
489
- }
490
-
491
- /**
492
- * Sends a HELO/EHLO command.
493
- * @access private
494
- * @return bool
495
- */
496
- private function SendHello($hello, $host) {
497
- fputs($this->smtp_conn, $hello . " " . $host . $this->CRLF);
498
-
499
- $rply = $this->get_lines();
500
- $code = substr($rply,0,3);
501
-
502
- if($this->do_debug >= 2) {
503
- echo "SMTP -> FROM SERVER: " . $rply . $this->CRLF . '<br />';
504
- }
505
-
506
- if($code != 250) {
507
- $this->error =
508
- array("error" => $hello . " not accepted from server",
509
- "smtp_code" => $code,
510
- "smtp_msg" => substr($rply,4));
511
- if($this->do_debug >= 1) {
512
- echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
513
- }
514
- return false;
515
- }
516
-
517
- $this->helo_rply = $rply;
518
-
519
- return true;
520
- }
521
-
522
- /**
523
- * Starts a mail transaction from the email address specified in
524
- * $from. Returns true if successful or false otherwise. If True
525
- * the mail transaction is started and then one or more Recipient
526
- * commands may be called followed by a Data command.
527
- *
528
- * Implements rfc 821: MAIL <SP> FROM:<reverse-path> <CRLF>
529
- *
530
- * SMTP CODE SUCCESS: 250
531
- * SMTP CODE SUCCESS: 552,451,452
532
- * SMTP CODE SUCCESS: 500,501,421
533
- * @access public
534
- * @return bool
535
- */
536
- public function Mail($from) {
537
- $this->error = null; // so no confusion is caused
538
-
539
- if(!$this->connected()) {
540
- $this->error = array(
541
- "error" => "Called Mail() without being connected");
542
- return false;
543
- }
544
-
545
- $useVerp = ($this->do_verp ? "XVERP" : "");
546
- fputs($this->smtp_conn,"MAIL FROM:<" . $from . ">" . $useVerp . $this->CRLF);
547
-
548
- $rply = $this->get_lines();
549
- $code = substr($rply,0,3);
550
-
551
- if($this->do_debug >= 2) {
552
- echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />';
553
- }
554
-
555
- if($code != 250) {
556
- $this->error =
557
- array("error" => "MAIL not accepted from server",
558
- "smtp_code" => $code,
559
- "smtp_msg" => substr($rply,4));
560
- if($this->do_debug >= 1) {
561
- echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
562
- }
563
- return false;
564
- }
565
- return true;
566
- }
567
-
568
- /**
569
- * Sends the quit command to the server and then closes the socket
570
- * if there is no error or the $close_on_error argument is true.
571
- *
572
- * Implements from rfc 821: QUIT <CRLF>
573
- *
574
- * SMTP CODE SUCCESS: 221
575
- * SMTP CODE ERROR : 500
576
- * @access public
577
- * @return bool
578
- */
579
- public function Quit($close_on_error = true) {
580
- $this->error = null; // so there is no confusion
581
-
582
- if(!$this->connected()) {
583
- $this->error = array(
584
- "error" => "Called Quit() without being connected");
585
- return false;
586
- }
587
-
588
- // send the quit command to the server
589
- fputs($this->smtp_conn,"quit" . $this->CRLF);
590
-
591
- // get any good-bye messages
592
- $byemsg = $this->get_lines();
593
-
594
- if($this->do_debug >= 2) {
595
- echo "SMTP -> FROM SERVER:" . $byemsg . $this->CRLF . '<br />';
596
- }
597
-
598
- $rval = true;
599
- $e = null;
600
-
601
- $code = substr($byemsg,0,3);
602
- if($code != 221) {
603
- // use e as a tmp var cause Close will overwrite $this->error
604
- $e = array("error" => "SMTP server rejected quit command",
605
- "smtp_code" => $code,
606
- "smtp_rply" => substr($byemsg,4));
607
- $rval = false;
608
- if($this->do_debug >= 1) {
609
- echo "SMTP -> ERROR: " . $e["error"] . ": " . $byemsg . $this->CRLF . '<br />';
610
- }
611
- }
612
-
613
- if(empty($e) || $close_on_error) {
614
- $this->Close();
615
- }
616
-
617
- return $rval;
618
- }
619
-
620
- /**
621
- * Sends the command RCPT to the SMTP server with the TO: argument of $to.
622
- * Returns true if the recipient was accepted false if it was rejected.
623
- *
624
- * Implements from rfc 821: RCPT <SP> TO:<forward-path> <CRLF>
625
- *
626
- * SMTP CODE SUCCESS: 250,251
627
- * SMTP CODE FAILURE: 550,551,552,553,450,451,452
628
- * SMTP CODE ERROR : 500,501,503,421
629
- * @access public
630
- * @return bool
631
- */
632
- public function Recipient($to) {
633
- $this->error = null; // so no confusion is caused
634
-
635
- if(!$this->connected()) {
636
- $this->error = array(
637
- "error" => "Called Recipient() without being connected");
638
- return false;
639
- }
640
-
641
- fputs($this->smtp_conn,"RCPT TO:<" . $to . ">" . $this->CRLF);
642
-
643
- $rply = $this->get_lines();
644
- $code = substr($rply,0,3);
645
-
646
- if($this->do_debug >= 2) {
647
- echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />';
648
- }
649
-
650
- if($code != 250 && $code != 251) {
651
- $this->error =
652
- array("error" => "RCPT not accepted from server",
653
- "smtp_code" => $code,
654
- "smtp_msg" => substr($rply,4));
655
- if($this->do_debug >= 1) {
656
- echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
657
- }
658
- return false;
659
- }
660
- return true;
661
- }
662
-
663
- /**
664
- * Sends the RSET command to abort and transaction that is
665
- * currently in progress. Returns true if successful false
666
- * otherwise.
667
- *
668
- * Implements rfc 821: RSET <CRLF>
669
- *
670
- * SMTP CODE SUCCESS: 250
671
- * SMTP CODE ERROR : 500,501,504,421
672
- * @access public
673
- * @return bool
674
- */
675
- public function Reset() {
676
- $this->error = null; // so no confusion is caused
677
-
678
- if(!$this->connected()) {
679
- $this->error = array(
680
- "error" => "Called Reset() without being connected");
681
- return false;
682
- }
683
-
684
- fputs($this->smtp_conn,"RSET" . $this->CRLF);
685
-
686
- $rply = $this->get_lines();
687
- $code = substr($rply,0,3);
688
-
689
- if($this->do_debug >= 2) {
690
- echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />';
691
- }
692
-
693
- if($code != 250) {
694
- $this->error =
695
- array("error" => "RSET failed",
696
- "smtp_code" => $code,
697
- "smtp_msg" => substr($rply,4));
698
- if($this->do_debug >= 1) {
699
- echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
700
- }
701
- return false;
702
- }
703
-
704
- return true;
705
- }
706
-
707
- /**
708
- * Starts a mail transaction from the email address specified in
709
- * $from. Returns true if successful or false otherwise. If True
710
- * the mail transaction is started and then one or more Recipient
711
- * commands may be called followed by a Data command. This command
712
- * will send the message to the users terminal if they are logged
713
- * in and send them an email.
714
- *
715
- * Implements rfc 821: SAML <SP> FROM:<reverse-path> <CRLF>
716
- *
717
- * SMTP CODE SUCCESS: 250
718
- * SMTP CODE SUCCESS: 552,451,452
719
- * SMTP CODE SUCCESS: 500,501,502,421
720
- * @access public
721
- * @return bool
722
- */
723
- public function SendAndMail($from) {
724
- $this->error = null; // so no confusion is caused
725
-
726
- if(!$this->connected()) {
727
- $this->error = array(
728
- "error" => "Called SendAndMail() without being connected");
729
- return false;
730
- }
731
-
732
- fputs($this->smtp_conn,"SAML FROM:" . $from . $this->CRLF);
733
-
734
- $rply = $this->get_lines();
735
- $code = substr($rply,0,3);
736
-
737
- if($this->do_debug >= 2) {
738
- echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />';
739
- }
740
-
741
- if($code != 250) {
742
- $this->error =
743
- array("error" => "SAML not accepted from server",
744
- "smtp_code" => $code,
745
- "smtp_msg" => substr($rply,4));
746
- if($this->do_debug >= 1) {
747
- echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
748
- }
749
- return false;
750
- }
751
- return true;
752
- }
753
-
754
- /**
755
- * This is an optional command for SMTP that this class does not
756
- * support. This method is here to make the RFC821 Definition
757
- * complete for this class and __may__ be implimented in the future
758
- *
759
- * Implements from rfc 821: TURN <CRLF>
760
- *
761
- * SMTP CODE SUCCESS: 250
762
- * SMTP CODE FAILURE: 502
763
- * SMTP CODE ERROR : 500, 503
764
- * @access public
765
- * @return bool
766
- */
767
- public function Turn() {
768
- $this->error = array("error" => "This method, TURN, of the SMTP ".
769
- "is not implemented");
770
- if($this->do_debug >= 1) {
771
- echo "SMTP -> NOTICE: " . $this->error["error"] . $this->CRLF . '<br />';
772
- }
773
- return false;
774
- }
775
-
776
- /**
777
- * Get the current error
778
- * @access public
779
- * @return array
780
- */
781
- public function getError() {
782
- return $this->error;
783
- }
784
-
785
- /////////////////////////////////////////////////
786
- // INTERNAL FUNCTIONS
787
- /////////////////////////////////////////////////
788
-
789
- /**
790
- * Read in as many lines as possible
791
- * either before eof or socket timeout occurs on the operation.
792
- * With SMTP we can tell if we have more lines to read if the
793
- * 4th character is '-' symbol. If it is a space then we don't
794
- * need to read anything else.
795
- * @access private
796
- * @return string
797
- */
798
- private function get_lines() {
799
- $data = "";
800
- while(!feof($this->smtp_conn)) {
801
- $str = @fgets($this->smtp_conn,515);
802
- if($this->do_debug >= 4) {
803
- echo "SMTP -> get_lines(): \$data was \"$data\"" . $this->CRLF . '<br />';
804
- echo "SMTP -> get_lines(): \$str is \"$str\"" . $this->CRLF . '<br />';
805
- }
806
- $data .= $str;
807
- if($this->do_debug >= 4) {
808
- echo "SMTP -> get_lines(): \$data is \"$data\"" . $this->CRLF . '<br />';
809
- }
810
- // if 4th character is a space, we are done reading, break the loop
811
- if(substr($str,3,1) == " ") { break; }
812
- }
813
- return $data;
814
- }
815
-
816
- }
817
-
818
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/phpmailer/language/phpmailer.lang-ar.php DELETED
@@ -1,27 +0,0 @@
1
- <?php
2
- /**
3
- * PHPMailer language file: refer to English translation for definitive list
4
- * Arabic Version, UTF-8
5
- * by : bahjat al mostafa <bahjat983@hotmail.com>
6
- */
7
-
8
- $PHPMAILER_LANG['authenticate'] = 'SMTP Error: لم نستطع تأكيد الهوية.';
9
- $PHPMAILER_LANG['connect_host'] = 'SMTP Error: لم نستطع الاتصال بمخدم SMTP.';
10
- $PHPMAILER_LANG['data_not_accepted'] = 'SMTP Error: لم يتم قبول المعلومات .';
11
- //$PHPMAILER_LANG['empty_message'] = 'Message body empty';
12
- $PHPMAILER_LANG['encoding'] = 'ترميز غير معروف: ';
13
- $PHPMAILER_LANG['execute'] = 'لم أستطع تنفيذ : ';
14
- $PHPMAILER_LANG['file_access'] = 'لم نستطع الوصول للملف: ';
15
- $PHPMAILER_LANG['file_open'] = 'File Error: لم نستطع فتح الملف: ';
16
- $PHPMAILER_LANG['from_failed'] = 'البريد التالي لم نستطع ارسال البريد له : ';
17
- $PHPMAILER_LANG['instantiate'] = 'لم نستطع توفير خدمة البريد.';
18
- //$PHPMAILER_LANG['invalid_email'] = 'Not sending, email address is invalid: ';
19
- $PHPMAILER_LANG['mailer_not_supported'] = ' mailer غير مدعوم.';
20
- //$PHPMAILER_LANG['provide_address'] = 'You must provide at least one recipient email address.';
21
- $PHPMAILER_LANG['recipients_failed'] = 'SMTP Error: الأخطاء التالية ' .
22
- 'فشل في الارسال لكل من : ';
23
- $PHPMAILER_LANG['signing'] = 'خطأ في التوقيع: ';
24
- //$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.';
25
- //$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: ';
26
- //$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: ';
27
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/phpmailer/language/phpmailer.lang-br.php DELETED
@@ -1,26 +0,0 @@
1
- <?php
2
- /**
3
- * PHPMailer language file: refer to English translation for definitive list
4
- * Portuguese Version
5
- * By Paulo Henrique Garcia - paulo@controllerweb.com.br
6
- */
7
-
8
- $PHPMAILER_LANG['authenticate'] = 'Erro de SMTP: Não foi possível autenticar.';
9
- $PHPMAILER_LANG['connect_host'] = 'Erro de SMTP: Não foi possível conectar com o servidor SMTP.';
10
- $PHPMAILER_LANG['data_not_accepted'] = 'Erro de SMTP: Dados não aceitos.';
11
- //$PHPMAILER_LANG['empty_message'] = 'Message body empty';
12
- $PHPMAILER_LANG['encoding'] = 'Codificação desconhecida: ';
13
- $PHPMAILER_LANG['execute'] = 'Não foi possível executar: ';
14
- $PHPMAILER_LANG['file_access'] = 'Não foi possível acessar o arquivo: ';
15
- $PHPMAILER_LANG['file_open'] = 'Erro de Arquivo: Não foi possível abrir o arquivo: ';
16
- $PHPMAILER_LANG['from_failed'] = 'Os endereços de rementente a seguir falharam: ';
17
- $PHPMAILER_LANG['instantiate'] = 'Não foi possível instanciar a função mail.';
18
- //$PHPMAILER_LANG['invalid_email'] = 'Not sending, email address is invalid: ';
19
- $PHPMAILER_LANG['mailer_not_supported'] = ' mailer não suportado.';
20
- $PHPMAILER_LANG['provide_address'] = 'Você deve fornecer pelo menos um endereço de destinatário de email.';
21
- $PHPMAILER_LANG['recipients_failed'] = 'Erro de SMTP: Os endereços de destinatário a seguir falharam: ';
22
- //$PHPMAILER_LANG['signing'] = 'Signing Error: ';
23
- //$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.';
24
- //$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: ';
25
- //$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: ';
26
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/phpmailer/language/phpmailer.lang-ca.php DELETED
@@ -1,26 +0,0 @@
1
- <?php
2
- /**
3
- * PHPMailer language file: refer to English translation for definitive list
4
- * Catalan Version
5
- * By Ivan: web AT microstudi DOT com
6
- */
7
-
8
- $PHPMAILER_LANG['authenticate'] = 'Error SMTP: No s\'hapogut autenticar.';
9
- $PHPMAILER_LANG['connect_host'] = 'Error SMTP: No es pot connectar al servidor SMTP.';
10
- $PHPMAILER_LANG['data_not_accepted'] = 'Error SMTP: Dades no acceptades.';
11
- //$PHPMAILER_LANG['empty_message'] = 'Message body empty';
12
- $PHPMAILER_LANG['encoding'] = 'Codificació desconeguda: ';
13
- $PHPMAILER_LANG['execute'] = 'No es pot executar: ';
14
- $PHPMAILER_LANG['file_access'] = 'No es pot accedir a l\'arxiu: ';
15
- $PHPMAILER_LANG['file_open'] = 'Error d\'Arxiu: No es pot obrir l\'arxiu: ';
16
- $PHPMAILER_LANG['from_failed'] = 'La(s) següent(s) adreces de remitent han fallat: ';
17
- $PHPMAILER_LANG['instantiate'] = 'No s\'ha pogut crear una instància de la funció Mail.';
18
- //$PHPMAILER_LANG['invalid_email'] = 'Not sending, email address is invalid: ';
19
- $PHPMAILER_LANG['mailer_not_supported'] = ' mailer no està suportat';
20
- $PHPMAILER_LANG['provide_address'] = 'S\'ha de proveir almenys una adreça d\'email com a destinatari.';
21
- $PHPMAILER_LANG['recipients_failed'] = 'Error SMTP: Els següents destinataris han fallat: ';
22
- //$PHPMAILER_LANG['signing'] = 'Signing Error: ';
23
- //$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.';
24
- //$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: ';
25
- //$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: ';
26
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/phpmailer/language/phpmailer.lang-ch.php DELETED
@@ -1,26 +0,0 @@
1
- <?php
2
- /**
3
- * PHPMailer language file: refer to English translation for definitive list
4
- * Chinese Version
5
- * By LiuXin: www.80x86.cn/blog/
6
- */
7
-
8
- $PHPMAILER_LANG['authenticate'] = 'SMTP 错误:身份验证失败。';
9
- $PHPMAILER_LANG['connect_host'] = 'SMTP 错误: 不能连接SMTP主机。';
10
- $PHPMAILER_LANG['data_not_accepted'] = 'SMTP 错误: 数据不可接受。';
11
- //$PHPMAILER_LANG['empty_message'] = 'Message body empty';
12
- $PHPMAILER_LANG['encoding'] = '未知编码:';
13
- $PHPMAILER_LANG['execute'] = '不能执行: ';
14
- $PHPMAILER_LANG['file_access'] = '不能访问文件:';
15
- $PHPMAILER_LANG['file_open'] = '文件错误:不能打开文件:';
16
- $PHPMAILER_LANG['from_failed'] = '下面的发送地址邮件发送失败了: ';
17
- $PHPMAILER_LANG['instantiate'] = '不能实现mail方法。';
18
- //$PHPMAILER_LANG['invalid_email'] = 'Not sending, email address is invalid: ';
19
- $PHPMAILER_LANG['mailer_not_supported'] = ' 您所选择的发送邮件的方法并不支持。';
20
- $PHPMAILER_LANG['provide_address'] = '您必须提供至少一个 收信人的email地址。';
21
- $PHPMAILER_LANG['recipients_failed'] = 'SMTP 错误: 下面的 收件人失败了: ';
22
- //$PHPMAILER_LANG['signing'] = 'Signing Error: ';
23
- //$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.';
24
- //$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: ';
25
- //$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: ';
26
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/phpmailer/language/phpmailer.lang-cz.php DELETED
@@ -1,25 +0,0 @@
1
- <?php
2
- /**
3
- * PHPMailer language file: refer to English translation for definitive list
4
- * Czech Version
5
- */
6
-
7
- $PHPMAILER_LANG['authenticate'] = 'SMTP Error: Chyba autentikace.';
8
- $PHPMAILER_LANG['connect_host'] = 'SMTP Error: Nelze navázat spojení se SMTP serverem.';
9
- $PHPMAILER_LANG['data_not_accepted'] = 'SMTP Error: Data nebyla pøijata';
10
- //$PHPMAILER_LANG['empty_message'] = 'Message body empty';
11
- $PHPMAILER_LANG['encoding'] = 'Neznámé kódování: ';
12
- $PHPMAILER_LANG['execute'] = 'Nelze provést: ';
13
- $PHPMAILER_LANG['file_access'] = 'Soubor nenalezen: ';
14
- $PHPMAILER_LANG['file_open'] = 'File Error: Nelze otevøít soubor pro ètení: ';
15
- $PHPMAILER_LANG['from_failed'] = 'Následující adresa From je nesprávná: ';
16
- $PHPMAILER_LANG['instantiate'] = 'Nelze vytvoøit instanci emailové funkce.';
17
- //$PHPMAILER_LANG['invalid_email'] = 'Not sending, email address is invalid: ';
18
- $PHPMAILER_LANG['mailer_not_supported'] = ' mailový klient není podporován.';
19
- $PHPMAILER_LANG['provide_address'] = 'Musíte zadat alespoò jednu emailovou adresu pøíjemce.';
20
- $PHPMAILER_LANG['recipients_failed'] = 'SMTP Error: Adresy pøíjemcù nejsou správné ';
21
- //$PHPMAILER_LANG['signing'] = 'Signing Error: ';
22
- //$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.';
23
- //$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: ';
24
- //$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: ';
25
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/phpmailer/language/phpmailer.lang-de.php DELETED
@@ -1,25 +0,0 @@
1
- <?php
2
- /**
3
- * PHPMailer language file: refer to English translation for definitive list
4
- * German Version
5
- */
6
-
7
- $PHPMAILER_LANG['authenticate'] = 'SMTP Fehler: Authentifizierung fehlgeschlagen.';
8
- $PHPMAILER_LANG['connect_host'] = 'SMTP Fehler: Konnte keine Verbindung zum SMTP-Host herstellen.';
9
- $PHPMAILER_LANG['data_not_accepted'] = 'SMTP Fehler: Daten werden nicht akzeptiert.';
10
- $PHPMAILER_LANG['empty_message'] = 'E-Mail Inhalt ist leer.';
11
- $PHPMAILER_LANG['encoding'] = 'Unbekanntes Encoding-Format: ';
12
- $PHPMAILER_LANG['execute'] = 'Konnte folgenden Befehl nicht ausführen: ';
13
- $PHPMAILER_LANG['file_access'] = 'Zugriff auf folgende Datei fehlgeschlagen: ';
14
- $PHPMAILER_LANG['file_open'] = 'Datei Fehler: konnte folgende Datei nicht öffnen: ';
15
- $PHPMAILER_LANG['from_failed'] = 'Die folgende Absenderadresse ist nicht korrekt: ';
16
- $PHPMAILER_LANG['instantiate'] = 'Mail Funktion konnte nicht initialisiert werden.';
17
- $PHPMAILER_LANG['invalid_email'] = 'E-Mail wird nicht gesendet, die Adresse ist ungültig.';
18
- $PHPMAILER_LANG['mailer_not_supported'] = ' mailer wird nicht unterstützt.';
19
- $PHPMAILER_LANG['provide_address'] = 'Bitte geben Sie mindestens eine Empfänger E-Mailadresse an.';
20
- $PHPMAILER_LANG['recipients_failed'] = 'SMTP Fehler: Die folgenden Empfänger sind nicht korrekt: ';
21
- $PHPMAILER_LANG['signing'] = 'Fehler beim Signieren: ';
22
- $PHPMAILER_LANG['smtp_connect_failed'] = 'Verbindung zu SMTP Server fehlgeschlagen.';
23
- $PHPMAILER_LANG['smtp_error'] = 'Fehler vom SMTP Server: ';
24
- $PHPMAILER_LANG['variable_set'] = 'Kann Variable nicht setzen oder zurücksetzen: ';
25
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/phpmailer/language/phpmailer.lang-dk.php DELETED
@@ -1,26 +0,0 @@
1
- <?php
2
- /**
3
- * PHPMailer language file: refer to English translation for definitive list
4
- * Danish Version
5
- * Author: Mikael Stokkebro <info@stokkebro.dk>
6
- */
7
-
8
- $PHPMAILER_LANG['authenticate'] = 'SMTP fejl: Kunne ikke logge på.';
9
- $PHPMAILER_LANG['connect_host'] = 'SMTP fejl: Kunne ikke tilslutte SMTP serveren.';
10
- $PHPMAILER_LANG['data_not_accepted'] = 'SMTP fejl: Data kunne ikke accepteres.';
11
- //$PHPMAILER_LANG['empty_message'] = 'Message body empty';
12
- $PHPMAILER_LANG['encoding'] = 'Ukendt encode-format: ';
13
- $PHPMAILER_LANG['execute'] = 'Kunne ikke køre: ';
14
- $PHPMAILER_LANG['file_access'] = 'Ingen adgang til fil: ';
15
- $PHPMAILER_LANG['file_open'] = 'Fil fejl: Kunne ikke åbne filen: ';
16
- $PHPMAILER_LANG['from_failed'] = 'Følgende afsenderadresse er forkert: ';
17
- $PHPMAILER_LANG['instantiate'] = 'Kunne ikke initialisere email funktionen.';
18
- //$PHPMAILER_LANG['invalid_email'] = 'Not sending, email address is invalid: ';
19
- $PHPMAILER_LANG['mailer_not_supported'] = ' mailer understøttes ikke.';
20
- $PHPMAILER_LANG['provide_address'] = 'Du skal indtaste mindst en modtagers emailadresse.';
21
- $PHPMAILER_LANG['recipients_failed'] = 'SMTP fejl: Følgende modtagere er forkerte: ';
22
- //$PHPMAILER_LANG['signing'] = 'Signing Error: ';
23
- //$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.';
24
- //$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: ';
25
- //$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: ';
26
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/phpmailer/language/phpmailer.lang-en.php DELETED
@@ -1,23 +0,0 @@
1
- <?php
2
- /**
3
- * PHPMailer language file.
4
- * English Version
5
- */
6
-
7
- $PHPMAILER_LANG = array();
8
-
9
- $PHPMAILER_LANG["provide_address"] = 'You must provide at least one ' .
10
- 'recipient email address.';
11
- $PHPMAILER_LANG["mailer_not_supported"] = ' mailer is not supported.';
12
- $PHPMAILER_LANG["execute"] = 'Could not execute: ';
13
- $PHPMAILER_LANG["instantiate"] = 'Could not instantiate mail function.';
14
- $PHPMAILER_LANG["authenticate"] = 'SMTP Error: Could not authenticate.';
15
- $PHPMAILER_LANG["from_failed"] = 'The following From address failed: ';
16
- $PHPMAILER_LANG["recipients_failed"] = 'SMTP Error: The following ' .
17
- 'recipients failed: ';
18
- $PHPMAILER_LANG["data_not_accepted"] = 'SMTP Error: Data not accepted.';
19
- $PHPMAILER_LANG["connect_host"] = 'SMTP Error: Could not connect to SMTP host.';
20
- $PHPMAILER_LANG["file_access"] = 'Could not access file: ';
21
- $PHPMAILER_LANG["file_open"] = 'File Error: Could not open file: ';
22
- $PHPMAILER_LANG["encoding"] = 'Unknown encoding: ';
23
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/phpmailer/language/phpmailer.lang-es.php DELETED
@@ -1,26 +0,0 @@
1
- <?php
2
- /**
3
- * PHPMailer language file: refer to English translation for definitive list
4
- * Spanish version
5
- * Versión en español
6
- */
7
-
8
- $PHPMAILER_LANG['authenticate'] = 'Error SMTP: No se pudo autentificar.';
9
- $PHPMAILER_LANG['connect_host'] = 'Error SMTP: No puedo conectar al servidor SMTP.';
10
- $PHPMAILER_LANG['data_not_accepted'] = 'Error SMTP: Datos no aceptados.';
11
- //$PHPMAILER_LANG['empty_message'] = 'Message body empty';
12
- $PHPMAILER_LANG['encoding'] = 'Codificación desconocida: ';
13
- $PHPMAILER_LANG['execute'] = 'No puedo ejecutar: ';
14
- $PHPMAILER_LANG['file_access'] = 'No puedo acceder al archivo: ';
15
- $PHPMAILER_LANG['file_open'] = 'Error de Archivo: No puede abrir el archivo: ';
16
- $PHPMAILER_LANG['from_failed'] = 'La(s) siguiente(s) direcciones de remitente fallaron: ';
17
- $PHPMAILER_LANG['instantiate'] = 'No pude crear una instancia de la función Mail.';
18
- //$PHPMAILER_LANG['invalid_email'] = 'Not sending, email address is invalid: ';
19
- $PHPMAILER_LANG['mailer_not_supported'] = ' mailer no está soportado.';
20
- $PHPMAILER_LANG['provide_address'] = 'Debe proveer al menos una dirección de email como destinatario.';
21
- $PHPMAILER_LANG['recipients_failed'] = 'Error SMTP: Los siguientes destinatarios fallaron: ';
22
- $PHPMAILER_LANG['signing'] = 'Error al firmar: ';
23
- //$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.';
24
- //$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: ';
25
- //$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: ';
26
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/phpmailer/language/phpmailer.lang-et.php DELETED
@@ -1,26 +0,0 @@
1
- <?php
2
- /**
3
- * PHPMailer language file: refer to English translation for definitive list
4
- * Estonian Version
5
- * By Indrek Päri
6
- */
7
-
8
- $PHPMAILER_LANG['authenticate'] = 'SMTP Viga: Autoriseerimise viga.';
9
- $PHPMAILER_LANG['connect_host'] = 'SMTP Viga: Ei õnnestunud luua ühendust SMTP serveriga.';
10
- $PHPMAILER_LANG['data_not_accepted'] = 'SMTP Viga: Vigased andmed.';
11
- //$PHPMAILER_LANG['empty_message'] = 'Message body empty';
12
- $PHPMAILER_LANG['encoding'] = 'Tundmatu Unknown kodeering: ';
13
- $PHPMAILER_LANG['execute'] = 'Tegevus ebaõnnestus: ';
14
- $PHPMAILER_LANG['file_access'] = 'Pole piisavalt õiguseid järgneva faili avamiseks: ';
15
- $PHPMAILER_LANG['file_open'] = 'Faili Viga: Faili avamine ebaõnnestus: ';
16
- $PHPMAILER_LANG['from_failed'] = 'Järgnev saatja e-posti aadress on vigane: ';
17
- $PHPMAILER_LANG['instantiate'] = 'mail funktiooni käivitamine ebaõnnestus.';
18
- //$PHPMAILER_LANG['invalid_email'] = 'Not sending, email address is invalid: ';
19
- $PHPMAILER_LANG['provide_address'] = 'Te peate määrama vähemalt ühe saaja e-posti aadressi.';
20
- $PHPMAILER_LANG['mailer_not_supported'] = ' maileri tugi puudub.';
21
- $PHPMAILER_LANG['recipients_failed'] = 'SMTP Viga: Järgnevate saajate e-posti aadressid on vigased: ';
22
- //$PHPMAILER_LANG['signing'] = 'Signing Error: ';
23
- //$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.';
24
- //$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: ';
25
- //$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: ';
26
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/phpmailer/language/phpmailer.lang-fi.php DELETED
@@ -1,27 +0,0 @@
1
- <?php
2
- /**
3
- * PHPMailer language file: refer to English translation for definitive list
4
- * Finnish Version
5
- * By Jyry Kuukanen
6
- */
7
-
8
- $PHPMAILER_LANG['authenticate'] = 'SMTP-virhe: käyttäjätunnistus epäonnistui.';
9
- $PHPMAILER_LANG['connect_host'] = 'SMTP-virhe: yhteys palvelimeen ei onnistu.';
10
- $PHPMAILER_LANG['data_not_accepted'] = 'SMTP-virhe: data on virheellinen.';
11
- //$PHPMAILER_LANG['empty_message'] = 'Message body empty';
12
- $PHPMAILER_LANG['encoding'] = 'Tuntematon koodaustyyppi: ';
13
- $PHPMAILER_LANG['execute'] = 'Suoritus epäonnistui: ';
14
- $PHPMAILER_LANG['file_access'] = 'Seuraavaan tiedostoon ei ole oikeuksia: ';
15
- $PHPMAILER_LANG['file_open'] = 'Tiedostovirhe: Ei voida avata tiedostoa: ';
16
- $PHPMAILER_LANG['from_failed'] = 'Seuraava lähettäjän osoite on virheellinen: ';
17
- $PHPMAILER_LANG['instantiate'] = 'mail-funktion luonti epäonnistui.';
18
- //$PHPMAILER_LANG['invalid_email'] = 'Not sending, email address is invalid: ';
19
- $PHPMAILER_LANG['mailer_not_supported'] = 'postivälitintyyppiä ei tueta.';
20
- $PHPMAILER_LANG['provide_address'] = 'Aseta vähintään yksi vastaanottajan sähk&ouml;postiosoite.';
21
- $PHPMAILER_LANG['recipients_failed'] = 'SMTP-virhe: seuraava vastaanottaja osoite on virheellinen.';
22
- $PHPMAILER_LANG['encoding'] = 'Tuntematon koodaustyyppi: ';
23
- //$PHPMAILER_LANG['signing'] = 'Signing Error: ';
24
- //$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.';
25
- //$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: ';
26
- //$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: ';
27
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/phpmailer/language/phpmailer.lang-fo.php DELETED
@@ -1,27 +0,0 @@
1
- <?php
2
- /**
3
- * PHPMailer language file: refer to English translation for definitive list
4
- * Faroese Version [language of the Faroe Islands, a Danish dominion]
5
- * This file created: 11-06-2004
6
- * Supplied by Dávur Sørensen [www.profo-webdesign.dk]
7
- */
8
-
9
- $PHPMAILER_LANG['authenticate'] = 'SMTP feilur: Kundi ikki góðkenna.';
10
- $PHPMAILER_LANG['connect_host'] = 'SMTP feilur: Kundi ikki knýta samband við SMTP vert.';
11
- $PHPMAILER_LANG['data_not_accepted'] = 'SMTP feilur: Data ikki góðkent.';
12
- //$PHPMAILER_LANG['empty_message'] = 'Message body empty';
13
- $PHPMAILER_LANG['encoding'] = 'Ókend encoding: ';
14
- $PHPMAILER_LANG['execute'] = 'Kundi ikki útføra: ';
15
- $PHPMAILER_LANG['file_access'] = 'Kundi ikki tilganga fílu: ';
16
- $PHPMAILER_LANG['file_open'] = 'Fílu feilur: Kundi ikki opna fílu: ';
17
- $PHPMAILER_LANG['from_failed'] = 'fylgjandi Frá/From adressa miseydnaðist: ';
18
- $PHPMAILER_LANG['instantiate'] = 'Kuni ikki instantiera mail funktión.';
19
- //$PHPMAILER_LANG['invalid_email'] = 'Not sending, email address is invalid: ';
20
- $PHPMAILER_LANG['mailer_not_supported'] = ' er ikki supporterað.';
21
- $PHPMAILER_LANG['provide_address'] = 'Tú skal uppgeva minst móttakara-emailadressu(r).';
22
- $PHPMAILER_LANG['recipients_failed'] = 'SMTP Feilur: Fylgjandi móttakarar miseydnaðust: ';
23
- //$PHPMAILER_LANG['signing'] = 'Signing Error: ';
24
- //$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.';
25
- //$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: ';
26
- //$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: ';
27
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/phpmailer/language/phpmailer.lang-fr.php DELETED
@@ -1,25 +0,0 @@
1
- <?php
2
- /**
3
- * PHPMailer language file: refer to English translation for definitive list
4
- * French Version
5
- */
6
-
7
- $PHPMAILER_LANG['authenticate'] = 'Erreur SMTP : Echec de l\'authentification.';
8
- $PHPMAILER_LANG['connect_host'] = 'Erreur SMTP : Impossible de se connecter au serveur SMTP.';
9
- $PHPMAILER_LANG['data_not_accepted'] = 'Erreur SMTP : Données incorrects.';
10
- $PHPMAILER_LANG['empty_message'] = 'Corps de message vide';
11
- $PHPMAILER_LANG['encoding'] = 'Encodage inconnu : ';
12
- $PHPMAILER_LANG['execute'] = 'Impossible de lancer l\'exécution : ';
13
- $PHPMAILER_LANG['file_access'] = 'Impossible d\'accéder au fichier : ';
14
- $PHPMAILER_LANG['file_open'] = 'Erreur Fichier : ouverture impossible : ';
15
- $PHPMAILER_LANG['from_failed'] = 'L\'adresse d\'expéditeur suivante a échouée : ';
16
- $PHPMAILER_LANG['instantiate'] = 'Impossible d\'instancier la fonction mail.';
17
- //$PHPMAILER_LANG['invalid_email'] = 'Not sending, email address is invalid: ';
18
- $PHPMAILER_LANG['mailer_not_supported'] = ' client de messagerie non supporté.';
19
- $PHPMAILER_LANG['provide_address'] = 'Vous devez fournir au moins une adresse de destinataire.';
20
- $PHPMAILER_LANG['recipients_failed'] = 'Erreur SMTP : Les destinataires suivants sont en erreur : ';
21
- //$PHPMAILER_LANG['signing'] = 'Signing Error: ';
22
- //$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.';
23
- //$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: ';
24
- //$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: ';
25
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/phpmailer/language/phpmailer.lang-hu.php DELETED
@@ -1,25 +0,0 @@
1
- <?php
2
- /**
3
- * PHPMailer language file: refer to English translation for definitive list
4
- * Hungarian Version
5
- */
6
-
7
- $PHPMAILER_LANG['authenticate'] = 'SMTP Hiba: Sikertelen autentikáció.';
8
- $PHPMAILER_LANG['connect_host'] = 'SMTP Hiba: Nem tudtam csatlakozni az SMTP host-hoz.';
9
- $PHPMAILER_LANG['data_not_accepted'] = 'SMTP Hiba: Nem elfogadható adat.';
10
- //$PHPMAILER_LANG['empty_message'] = 'Message body empty';
11
- $PHPMAILER_LANG['encoding'] = 'Ismeretlen kódolás: ';
12
- $PHPMAILER_LANG['execute'] = 'Nem tudtam végrehajtani: ';
13
- $PHPMAILER_LANG['file_access'] = 'Nem sikerült elérni a következõ fájlt: ';
14
- $PHPMAILER_LANG['file_open'] = 'Fájl Hiba: Nem sikerült megnyitni a következõ fájlt: ';
15
- $PHPMAILER_LANG['from_failed'] = 'Az alábbi Feladó cím hibás: ';
16
- $PHPMAILER_LANG['instantiate'] = 'Nem sikerült példányosítani a mail funkciót.';
17
- //$PHPMAILER_LANG['invalid_email'] = 'Not sending, email address is invalid: ';
18
- $PHPMAILER_LANG['provide_address'] = 'Meg kell adnod legalább egy címzett email címet.';
19
- $PHPMAILER_LANG['mailer_not_supported'] = ' levelezõ nem támogatott.';
20
- $PHPMAILER_LANG['recipients_failed'] = 'SMTP Hiba: Az alábbi címzettek hibásak: ';
21
- //$PHPMAILER_LANG['signing'] = 'Signing Error: ';
22
- //$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.';
23
- //$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: ';
24
- //$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: ';
25
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/phpmailer/language/phpmailer.lang-it.php DELETED
@@ -1,27 +0,0 @@
1
- <?php
2
- /**
3
- * PHPMailer language file: refer to English translation for definitive list
4
- * Italian version
5
- * @package PHPMailer
6
- * @author Ilias Bartolini <brain79@inwind.it>
7
- */
8
-
9
- $PHPMAILER_LANG['authenticate'] = 'SMTP Error: Impossibile autenticarsi.';
10
- $PHPMAILER_LANG['connect_host'] = 'SMTP Error: Impossibile connettersi all\'host SMTP.';
11
- $PHPMAILER_LANG['data_not_accepted'] = 'SMTP Error: Data non accettati dal server.';
12
- //$PHPMAILER_LANG['empty_message'] = 'Message body empty';
13
- $PHPMAILER_LANG['encoding'] = 'Encoding set dei caratteri sconosciuto: ';
14
- $PHPMAILER_LANG['execute'] = 'Impossibile eseguire l\'operazione: ';
15
- $PHPMAILER_LANG['file_access'] = 'Impossibile accedere al file: ';
16
- $PHPMAILER_LANG['file_open'] = 'File Error: Impossibile aprire il file: ';
17
- $PHPMAILER_LANG['from_failed'] = 'I seguenti indirizzi mittenti hanno generato errore: ';
18
- $PHPMAILER_LANG['instantiate'] = 'Impossibile istanziare la funzione mail';
19
- //$PHPMAILER_LANG['invalid_email'] = 'Not sending, email address is invalid: ';
20
- $PHPMAILER_LANG['provide_address'] = 'Deve essere fornito almeno un indirizzo ricevente';
21
- $PHPMAILER_LANG['mailer_not_supported'] = 'Mailer non supportato';
22
- $PHPMAILER_LANG['recipients_failed'] = 'SMTP Error: I seguenti indirizzi destinatari hanno generato errore: ';
23
- //$PHPMAILER_LANG['signing'] = 'Signing Error: ';
24
- //$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.';
25
- //$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: ';
26
- //$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: ';
27
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/phpmailer/language/phpmailer.lang-ja.php DELETED
@@ -1,26 +0,0 @@
1
- <?php
2
- /**
3
- * PHPMailer language file: refer to English translation for definitive list
4
- * Japanese Version
5
- * By Mitsuhiro Yoshida - http://mitstek.com/
6
- */
7
-
8
- $PHPMAILER_LANG['authenticate'] = 'SMTPエラー: 認証できませんでした。';
9
- $PHPMAILER_LANG['connect_host'] = 'SMTPエラー: SMTPホストに接続できませんでした。';
10
- $PHPMAILER_LANG['data_not_accepted'] = 'SMTPエラー: データが受け付けられませんでした。';
11
- //$PHPMAILER_LANG['empty_message'] = 'Message body empty';
12
- $PHPMAILER_LANG['encoding'] = '不明なエンコーディング: ';
13
- $PHPMAILER_LANG['execute'] = '実行できませんでした: ';
14
- $PHPMAILER_LANG['file_access'] = 'ファイルにアクセスできません: ';
15
- $PHPMAILER_LANG['file_open'] = 'ファイルエラー: ファイルを開けません: ';
16
- $PHPMAILER_LANG['from_failed'] = '次のFromアドレスに間違いがあります: ';
17
- $PHPMAILER_LANG['instantiate'] = 'メール関数が正常に動作しませんでした。';
18
- //$PHPMAILER_LANG['invalid_email'] = 'Not sending, email address is invalid: ';
19
- $PHPMAILER_LANG['provide_address'] = '少なくとも1つメールアドレスを 指定する必要があります。';
20
- $PHPMAILER_LANG['mailer_not_supported'] = ' メーラーがサポートされていません。';
21
- $PHPMAILER_LANG['recipients_failed'] = 'SMTPエラー: 次の受信者アドレスに 間違いがあります: ';
22
- //$PHPMAILER_LANG['signing'] = 'Signing Error: ';
23
- //$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.';
24
- //$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: ';
25
- //$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: ';
26
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/phpmailer/language/phpmailer.lang-nl.php DELETED
@@ -1,25 +0,0 @@
1
- <?php
2
- /**
3
- * PHPMailer language file: refer to English translation for definitive list
4
- * Dutch Version
5
- */
6
-
7
- $PHPMAILER_LANG['authenticate'] = 'SMTP Fout: authenticatie mislukt.';
8
- $PHPMAILER_LANG['connect_host'] = 'SMTP Fout: Kon niet verbinden met SMTP host.';
9
- $PHPMAILER_LANG['data_not_accepted'] = 'SMTP Fout: Data niet geaccepteerd.';
10
- //$PHPMAILER_LANG['empty_message'] = 'Message body empty';
11
- $PHPMAILER_LANG['encoding'] = 'Onbekende codering: ';
12
- $PHPMAILER_LANG['execute'] = 'Kon niet uitvoeren: ';
13
- $PHPMAILER_LANG['file_access'] = 'Kreeg geen toegang tot bestand: ';
14
- $PHPMAILER_LANG['file_open'] = 'Bestandsfout: Kon bestand niet openen: ';
15
- $PHPMAILER_LANG['from_failed'] = 'De volgende afzender adressen zijn mislukt: ';
16
- $PHPMAILER_LANG['instantiate'] = 'Kon mail functie niet initialiseren.';
17
- //$PHPMAILER_LANG['invalid_email'] = 'Not sending, email address is invalid: ';
18
- $PHPMAILER_LANG['provide_address'] = 'Er moet tenmiste één ontvanger emailadres opgegeven worden.';
19
- $PHPMAILER_LANG['mailer_not_supported'] = ' mailer wordt niet ondersteund.';
20
- $PHPMAILER_LANG['recipients_failed'] = 'SMTP Fout: De volgende ontvangers zijn mislukt: ';
21
- //$PHPMAILER_LANG['signing'] = 'Signing Error: ';
22
- //$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.';
23
- //$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: ';
24
- //$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: ';
25
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/phpmailer/language/phpmailer.lang-no.php DELETED
@@ -1,25 +0,0 @@
1
- <?php
2
- /**
3
- * PHPMailer language file: refer to English translation for definitive list
4
- * Norwegian Version
5
- */
6
-
7
- $PHPMAILER_LANG['authenticate'] = 'SMTP Feil: Kunne ikke authentisere.';
8
- $PHPMAILER_LANG['connect_host'] = 'SMTP Feil: Kunne ikke koble til SMTP host.';
9
- $PHPMAILER_LANG['data_not_accepted'] = 'SMTP Feil: Data ble ikke akseptert.';
10
- //$PHPMAILER_LANG['empty_message'] = 'Message body empty';
11
- $PHPMAILER_LANG['encoding'] = 'Ukjent encoding: ';
12
- $PHPMAILER_LANG['execute'] = 'Kunne ikke utføre: ';
13
- $PHPMAILER_LANG['file_access'] = 'Kunne ikke få tilgang til filen: ';
14
- $PHPMAILER_LANG['file_open'] = 'Fil feil: Kunne ikke åpne filen: ';
15
- $PHPMAILER_LANG['from_failed'] = 'Følgende Fra feilet: ';
16
- $PHPMAILER_LANG['instantiate'] = 'Kunne ikke instantiate mail funksjonen.';
17
- //$PHPMAILER_LANG['invalid_email'] = 'Not sending, email address is invalid: ';
18
- $PHPMAILER_LANG['provide_address'] = 'Du må ha med minst en mottager adresse.';
19
- $PHPMAILER_LANG['mailer_not_supported'] = ' mailer er ikke supportert.';
20
- $PHPMAILER_LANG['recipients_failed'] = 'SMTP Feil: Følgende mottagere feilet: ';
21
- //$PHPMAILER_LANG['signing'] = 'Signing Error: ';
22
- //$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.';
23
- //$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: ';
24
- //$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: ';
25
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/phpmailer/language/phpmailer.lang-pl.php DELETED
@@ -1,25 +0,0 @@
1
- <?php
2
- /**
3
- * PHPMailer language file: refer to English translation for definitive list
4
- * Polish Version
5
- */
6
-
7
- $PHPMAILER_LANG['authenticate'] = 'Błąd SMTP: Nie można przeprowadzić autentykacji.';
8
- $PHPMAILER_LANG['connect_host'] = 'Błąd SMTP: Nie można połączyć się z wybranym hostem.';
9
- $PHPMAILER_LANG['data_not_accepted'] = 'Błąd SMTP: Dane nie zostały przyjęte.';
10
- //$PHPMAILER_LANG['empty_message'] = 'Message body empty';
11
- $PHPMAILER_LANG['encoding'] = 'Nieznany sposób kodowania znaków: ';
12
- $PHPMAILER_LANG['execute'] = 'Nie można uruchomić: ';
13
- $PHPMAILER_LANG['file_access'] = 'Brak dostępu do pliku: ';
14
- $PHPMAILER_LANG['file_open'] = 'Nie można otworzyć pliku: ';
15
- $PHPMAILER_LANG['from_failed'] = 'Następujący adres Nadawcy jest jest nieprawidłowy: ';
16
- $PHPMAILER_LANG['instantiate'] = 'Nie można wywołać funkcji mail(). Sprawdź konfigurację serwera.';
17
- //$PHPMAILER_LANG['invalid_email'] = 'Not sending, email address is invalid: ';
18
- $PHPMAILER_LANG['provide_address'] = 'Należy podać prawidłowy adres email Odbiorcy.';
19
- $PHPMAILER_LANG['mailer_not_supported'] = 'Wybrana metoda wysyłki wiadomości nie jest obsługiwana.';
20
- $PHPMAILER_LANG['recipients_failed'] = 'Błąd SMTP: Następujący odbiorcy są nieprawidłowi: ';
21
- //$PHPMAILER_LANG['signing'] = 'Signing Error: ';
22
- //$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.';
23
- //$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: ';
24
- //$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: ';
25
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/phpmailer/language/phpmailer.lang-ro.php DELETED
@@ -1,27 +0,0 @@
1
- <?php
2
- /**
3
- * PHPMailer language file: refer to English translation for definitive list
4
- * Romanian Version
5
- * @package PHPMailer
6
- * @author Catalin Constantin <catalin@dazoot.ro>
7
- */
8
-
9
- $PHPMAILER_LANG['authenticate'] = 'Eroare SMTP: Nu a functionat autentificarea.';
10
- $PHPMAILER_LANG['connect_host'] = 'Eroare SMTP: Nu m-am putut conecta la adresa SMTP.';
11
- $PHPMAILER_LANG['data_not_accepted'] = 'Eroare SMTP: Continutul mailului nu a fost acceptat.';
12
- //$PHPMAILER_LANG['empty_message'] = 'Message body empty';
13
- $PHPMAILER_LANG['encoding'] = 'Encodare necunoscuta: ';
14
- $PHPMAILER_LANG['execute'] = 'Nu pot executa: ';
15
- $PHPMAILER_LANG['file_access'] = 'Nu pot accesa fisierul: ';
16
- $PHPMAILER_LANG['file_open'] = 'Eroare de fisier: Nu pot deschide fisierul: ';
17
- $PHPMAILER_LANG['from_failed'] = 'Urmatoarele adrese From au dat eroare: ';
18
- $PHPMAILER_LANG['instantiate'] = 'Nu am putut instantia functia mail.';
19
- //$PHPMAILER_LANG['invalid_email'] = 'Not sending, email address is invalid: ';
20
- $PHPMAILER_LANG['mailer_not_supported'] = ' mailer nu este suportat.';
21
- $PHPMAILER_LANG['provide_address'] = 'Trebuie sa adaugati cel putin un recipient (adresa de mail).';
22
- $PHPMAILER_LANG['recipients_failed'] = 'Eroare SMTP: Urmatoarele adrese de mail au dat eroare: ';
23
- //$PHPMAILER_LANG['signing'] = 'Signing Error: ';
24
- //$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.';
25
- //$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: ';
26
- //$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: ';
27
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/phpmailer/language/phpmailer.lang-ru.php DELETED
@@ -1,25 +0,0 @@
1
- <?php
2
- /**
3
- * PHPMailer language file: refer to English translation for definitive list
4
- * Russian Version by Alexey Chumakov <alex@chumakov.ru>
5
- */
6
-
7
- $PHPMAILER_LANG['authenticate'] = 'Ошибка SMTP: ошибка авторизации.';
8
- $PHPMAILER_LANG['connect_host'] = 'Ошибка SMTP: не удается подключиться к серверу SMTP.';
9
- $PHPMAILER_LANG['data_not_accepted'] = 'Ошибка SMTP: данные не приняты.';
10
- //$PHPMAILER_LANG['empty_message'] = 'Message body empty';
11
- $PHPMAILER_LANG['encoding'] = 'Неизвестный вид кодировки: ';
12
- $PHPMAILER_LANG['execute'] = 'Невозможно выполнить команду: ';
13
- $PHPMAILER_LANG['file_access'] = 'Нет доступа к файлу: ';
14
- $PHPMAILER_LANG['file_open'] = 'Файловая ошибка: не удается открыть файл: ';
15
- $PHPMAILER_LANG['from_failed'] = 'Неверный адрес отправителя: ';
16
- $PHPMAILER_LANG['instantiate'] = 'Невозможно запустить функцию mail.';
17
- //$PHPMAILER_LANG['invalid_email'] = 'Not sending, email address is invalid: ';
18
- $PHPMAILER_LANG['provide_address'] = 'Пожалуйста, введите хотя бы один адрес e-mail получателя.';
19
- $PHPMAILER_LANG['mailer_not_supported'] = ' - почтовый сервер не поддерживается.';
20
- $PHPMAILER_LANG['recipients_failed'] = 'Ошибка SMTP: отправка по следующим адресам получателей не удалась: ';
21
- //$PHPMAILER_LANG['signing'] = 'Signing Error: ';
22
- //$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.';
23
- //$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: ';
24
- //$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: ';
25
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/phpmailer/language/phpmailer.lang-se.php DELETED
@@ -1,26 +0,0 @@
1
- <?php
2
- /**
3
- * PHPMailer language file: refer to English translation for definitive list
4
- * Swedish Version
5
- * Author: Johan Linnér <johan@linner.biz>
6
- */
7
-
8
- $PHPMAILER_LANG['authenticate'] = 'SMTP fel: Kunde inte autentisera.';
9
- $PHPMAILER_LANG['connect_host'] = 'SMTP fel: Kunde inte ansluta till SMTP-server.';
10
- $PHPMAILER_LANG['data_not_accepted'] = 'SMTP fel: Data accepterades inte.';
11
- //$PHPMAILER_LANG['empty_message'] = 'Message body empty';
12
- $PHPMAILER_LANG['encoding'] = 'Okänt encode-format: ';
13
- $PHPMAILER_LANG['execute'] = 'Kunde inte köra: ';
14
- $PHPMAILER_LANG['file_access'] = 'Ingen åtkomst till fil: ';
15
- $PHPMAILER_LANG['file_open'] = 'Fil fel: Kunde inte öppna fil: ';
16
- $PHPMAILER_LANG['from_failed'] = 'Följande avsändaradress är felaktig: ';
17
- $PHPMAILER_LANG['instantiate'] = 'Kunde inte initiera e-postfunktion.';
18
- //$PHPMAILER_LANG['invalid_email'] = 'Not sending, email address is invalid: ';
19
- $PHPMAILER_LANG['provide_address'] = 'Du måste ange minst en mottagares e-postadress.';
20
- $PHPMAILER_LANG['mailer_not_supported'] = ' mailer stöds inte.';
21
- $PHPMAILER_LANG['recipients_failed'] = 'SMTP fel: Följande mottagare är felaktig: ';
22
- //$PHPMAILER_LANG['signing'] = 'Signing Error: ';
23
- //$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.';
24
- //$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: ';
25
- //$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: ';
26
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/phpmailer/language/phpmailer.lang-tr.php DELETED
@@ -1,27 +0,0 @@
1
- <?php
2
- /**
3
- * PHPMailer language file: refer to English translation for definitive list
4
- * Turkish version
5
- * Türkçe Versiyonu
6
- * ÝZYAZILIM - Elçin Özel - Can Yýlmaz - Mehmet Benlioðlu
7
- */
8
-
9
- $PHPMAILER_LANG['authenticate'] = 'SMTP Hatasý: Doðrulanamýyor.';
10
- $PHPMAILER_LANG['connect_host'] = 'SMTP Hatasý: SMTP hosta baðlanýlamýyor.';
11
- $PHPMAILER_LANG['data_not_accepted'] = 'SMTP Hatasý: Veri kabul edilmedi.';
12
- //$PHPMAILER_LANG['empty_message'] = 'Message body empty';
13
- $PHPMAILER_LANG['encoding'] = 'Bilinmeyen þifreleme: ';
14
- $PHPMAILER_LANG['execute'] = 'Çalýþtýrýlamýyor: ';
15
- $PHPMAILER_LANG['file_access'] = 'Dosyaya eriþilemiyor: ';
16
- $PHPMAILER_LANG['file_open'] = 'Dosya Hatasý: Dosya açýlamýyor: ';
17
- $PHPMAILER_LANG['from_failed'] = 'Baþarýsýz olan gönderici adresi: ';
18
- $PHPMAILER_LANG['instantiate'] = 'Örnek mail fonksiyonu yaratýlamadý.';
19
- //$PHPMAILER_LANG['invalid_email'] = 'Not sending, email address is invalid: ';
20
- $PHPMAILER_LANG['provide_address'] = 'En az bir tane mail adresi belirtmek zorundasýnýz alýcýnýn email adresi.';
21
- $PHPMAILER_LANG['mailer_not_supported'] = ' mailler desteklenmemektedir.';
22
- $PHPMAILER_LANG['recipients_failed'] = 'SMTP Hatasý: alýcýlara ulaþmadý: ';
23
- //$PHPMAILER_LANG['signing'] = 'Signing Error: ';
24
- //$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.';
25
- //$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: ';
26
- //$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: ';
27
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/phpmailer/language/phpmailer.lang-zh.php DELETED
@@ -1,26 +0,0 @@
1
- <?php
2
- /**
3
- * PHPMailer language file: refer to English translation for definitive list
4
- * Traditional Chinese Version
5
- * @author liqwei <liqwei@liqwei.com>
6
- */
7
-
8
- $PHPMAILER_LANG['authenticate'] = 'SMTP 錯誤:登錄失敗。';
9
- $PHPMAILER_LANG['connect_host'] = 'SMTP 錯誤:無法連接到 SMTP 主機。';
10
- $PHPMAILER_LANG['data_not_accepted'] = 'SMTP 錯誤:數據不被接受。';
11
- //$PHPMAILER_LANG['empty_message'] = 'Message body empty';
12
- $PHPMAILER_LANG['encoding'] = '未知編碼: ';
13
- $PHPMAILER_LANG['file_access'] = '無法訪問文件:';
14
- $PHPMAILER_LANG['file_open'] = '文件錯誤:無法打開文件:';
15
- $PHPMAILER_LANG['from_failed'] = '發送地址錯誤:';
16
- $PHPMAILER_LANG['execute'] = '無法執行:';
17
- $PHPMAILER_LANG['instantiate'] = '未知函數調用。';
18
- //$PHPMAILER_LANG['invalid_email'] = 'Not sending, email address is invalid: ';
19
- $PHPMAILER_LANG['provide_address'] = '必須提供至少一個收件人地址。';
20
- $PHPMAILER_LANG['mailer_not_supported'] = '發信客戶端不被支持。';
21
- $PHPMAILER_LANG['recipients_failed'] = 'SMTP 錯誤:收件人地址錯誤:';
22
- //$PHPMAILER_LANG['signing'] = 'Signing Error: ';
23
- //$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.';
24
- //$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: ';
25
- //$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: ';
26
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/phpmailer/language/phpmailer.lang-zh_cn.php DELETED
@@ -1,26 +0,0 @@
1
- <?php
2
- /**
3
- * PHPMailer language file: refer to English translation for definitive list
4
- * Simplified Chinese Version
5
- * @author liqwei <liqwei@liqwei.com>
6
- */
7
-
8
- $PHPMAILER_LANG['authenticate'] = 'SMTP 错误:登录失败。';
9
- $PHPMAILER_LANG['connect_host'] = 'SMTP 错误:无法连接到 SMTP 主机。';
10
- $PHPMAILER_LANG['data_not_accepted'] = 'SMTP 错误:数据不被接受。';
11
- //$P$PHPMAILER_LANG['empty_message'] = 'Message body empty';
12
- $PHPMAILER_LANG['encoding'] = '未知编码: ';
13
- $PHPMAILER_LANG['execute'] = '无法执行:';
14
- $PHPMAILER_LANG['file_access'] = '无法访问文件:';
15
- $PHPMAILER_LANG['file_open'] = '文件错误:无法打开文件:';
16
- $PHPMAILER_LANG['from_failed'] = '发送地址错误:';
17
- $PHPMAILER_LANG['instantiate'] = '未知函数调用。';
18
- //$PHPMAILER_LANG['invalid_email'] = 'Not sending, email address is invalid: ';
19
- $PHPMAILER_LANG['mailer_not_supported'] = '发信客户端不被支持。';
20
- $PHPMAILER_LANG['provide_address'] = '必须提供至少一个收件人地址。';
21
- $PHPMAILER_LANG['recipients_failed'] = 'SMTP 错误:收件人地址错误:';
22
- //$PHPMAILER_LANG['signing'] = 'Signing Error: ';
23
- //$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.';
24
- //$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: ';
25
- //$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: ';
26
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
em-actions.php CHANGED
@@ -76,7 +76,7 @@ function em_init_actions() {
76
  }else{
77
  $EM_Notices->add_confirm( $EM_Event->output(get_option('dbem_events_anonymous_result_success')), true);
78
  }
79
- $redirect = !empty($_REQUEST['redirect_to']) ? $_REQUEST['redirect_to'] : wp_get_referer();
80
  $redirect = em_add_get_params($redirect, array('success'=>1), false, false);
81
  wp_redirect( $redirect );
82
  exit();
@@ -89,7 +89,7 @@ function em_init_actions() {
89
  $event = $EM_Event->duplicate();
90
  if( $event === false ){
91
  $EM_Notices->add_error($EM_Event->errors, true);
92
- wp_redirect( wp_get_referer() );
93
  }else{
94
  $EM_Notices->add_confirm($EM_Event->feedback_message, true);
95
  wp_redirect( $event->get_edit_url() );
@@ -112,7 +112,7 @@ function em_init_actions() {
112
  $message = ( !empty($EM_Event->errors) ) ? $EM_Event->errors : sprintf(__('%s could not be deleted.','events-manager'),$plural);
113
  $EM_Notices->add_error( $message, true );
114
  }
115
- wp_redirect( wp_get_referer() );
116
  exit();
117
  }elseif( $_REQUEST['action'] == 'event_detach' && wp_verify_nonce($_REQUEST['_wpnonce'],'event_detach_'.get_current_user_id().'_'.$EM_Event->event_id) ){
118
  //Detach event and move on
@@ -121,7 +121,7 @@ function em_init_actions() {
121
  }else{
122
  $EM_Notices->add_error( $EM_Event->errors, true );
123
  }
124
- wp_redirect(wp_get_referer());
125
  exit();
126
  }elseif( $_REQUEST['action'] == 'event_attach' && !empty($_REQUEST['undo_id']) && wp_verify_nonce($_REQUEST['_wpnonce'],'event_attach_'.get_current_user_id().'_'.$EM_Event->event_id) ){
127
  //Detach event and move on
@@ -130,7 +130,7 @@ function em_init_actions() {
130
  }else{
131
  $EM_Notices->add_error( $EM_Event->errors, true );
132
  }
133
- wp_redirect(wp_get_referer());
134
  exit();
135
  }
136
 
@@ -161,7 +161,7 @@ function em_init_actions() {
161
  //Grab and validate submitted data
162
  if ( $EM_Location->get_post() && $EM_Location->save() ) { //EM_location gets the location if submitted via POST and validates it (safer than to depend on JS)
163
  $EM_Notices->add_confirm($EM_Location->feedback_message, true);
164
- $redirect = !empty($_REQUEST['redirect_to']) ? $_REQUEST['redirect_to'] : wp_get_referer();
165
  wp_redirect( $redirect );
166
  exit();
167
  }else{
@@ -202,7 +202,7 @@ function em_init_actions() {
202
  $location_cond = " AND location_private=0";
203
  }
204
  $location_cond = apply_filters('em_actions_locations_search_cond', $location_cond);
205
- $term = (isset($_REQUEST['term'])) ? '%'.$_REQUEST['term'].'%' : '%'.$_REQUEST['q'].'%';
206
  $sql = $wpdb->prepare("
207
  SELECT
208
  location_id AS `id`,
@@ -378,7 +378,7 @@ function em_init_actions() {
378
  if( $EM_Booking->can_manage('manage_bookings','manage_others_bookings') ){
379
  if ($EM_Booking->get_post(true) && $EM_Booking->validate(true) && $EM_Booking->save(false) ){
380
  $EM_Notices->add_confirm( $EM_Booking->feedback_message, true );
381
- $redirect = !empty($_REQUEST['redirect_to']) ? $_REQUEST['redirect_to'] : wp_get_referer();
382
  wp_redirect( $redirect );
383
  exit();
384
  }else{
@@ -403,7 +403,7 @@ function em_init_actions() {
403
  }
404
  }
405
  $EM_Notices->add_confirm( $EM_Booking->feedback_message, true );
406
- $redirect = !empty($_REQUEST['redirect_to']) ? $_REQUEST['redirect_to'] : wp_get_referer();
407
  wp_redirect( $redirect );
408
  exit();
409
  }else{
@@ -421,7 +421,7 @@ function em_init_actions() {
421
  }else{
422
  $EM_Notices->add_confirm( _x('No emails to send for this booking.', 'bookings', 'events-manager'), true );
423
  }
424
- $redirect = !empty($_REQUEST['redirect_to']) ? $_REQUEST['redirect_to'] : wp_get_referer();
425
  wp_redirect( $redirect );
426
  exit();
427
  }else{
@@ -440,7 +440,7 @@ function em_init_actions() {
440
  $wpdb->update(EM_BOOKINGS_TABLE, array('booking_meta'=> serialize($EM_Booking->booking_meta)), array('booking_id'=>$EM_Booking->booking_id))
441
  ){
442
  $EM_Notices->add_confirm( $EM_Booking->feedback_message, true );
443
- $redirect = !empty($_REQUEST['redirect_to']) ? $_REQUEST['redirect_to'] : wp_get_referer();
444
  wp_redirect( $redirect );
445
  exit();
446
  }else{
@@ -450,7 +450,18 @@ function em_init_actions() {
450
  }
451
  }
452
  do_action('em_booking_modify_person', $EM_Event, $EM_Booking);
 
 
 
 
 
 
 
 
 
 
453
  }
 
454
  if( $result && defined('DOING_AJAX') ){
455
  $return = array('result'=>true, 'message'=>$feedback);
456
  header( 'Content-Type: application/javascript; charset=UTF-8', true ); //add this for HTTP -> HTTPS requests which assume it's a cross-site request
76
  }else{
77
  $EM_Notices->add_confirm( $EM_Event->output(get_option('dbem_events_anonymous_result_success')), true);
78
  }
79
+ $redirect = !empty($_REQUEST['redirect_to']) ? $_REQUEST['redirect_to'] : em_wp_get_referer();
80
  $redirect = em_add_get_params($redirect, array('success'=>1), false, false);
81
  wp_redirect( $redirect );
82
  exit();
89
  $event = $EM_Event->duplicate();
90
  if( $event === false ){
91
  $EM_Notices->add_error($EM_Event->errors, true);
92
+ wp_redirect( em_wp_get_referer() );
93
  }else{
94
  $EM_Notices->add_confirm($EM_Event->feedback_message, true);
95
  wp_redirect( $event->get_edit_url() );
112
  $message = ( !empty($EM_Event->errors) ) ? $EM_Event->errors : sprintf(__('%s could not be deleted.','events-manager'),$plural);
113
  $EM_Notices->add_error( $message, true );
114
  }
115
+ wp_redirect( em_wp_get_referer() );
116
  exit();
117
  }elseif( $_REQUEST['action'] == 'event_detach' && wp_verify_nonce($_REQUEST['_wpnonce'],'event_detach_'.get_current_user_id().'_'.$EM_Event->event_id) ){
118
  //Detach event and move on
121
  }else{
122
  $EM_Notices->add_error( $EM_Event->errors, true );
123
  }
124
+ wp_redirect(em_wp_get_referer());
125
  exit();
126
  }elseif( $_REQUEST['action'] == 'event_attach' && !empty($_REQUEST['undo_id']) && wp_verify_nonce($_REQUEST['_wpnonce'],'event_attach_'.get_current_user_id().'_'.$EM_Event->event_id) ){
127
  //Detach event and move on
130
  }else{
131
  $EM_Notices->add_error( $EM_Event->errors, true );
132
  }
133
+ wp_redirect(em_wp_get_referer());
134
  exit();
135
  }
136
 
161
  //Grab and validate submitted data
162
  if ( $EM_Location->get_post() && $EM_Location->save() ) { //EM_location gets the location if submitted via POST and validates it (safer than to depend on JS)
163
  $EM_Notices->add_confirm($EM_Location->feedback_message, true);
164
+ $redirect = !empty($_REQUEST['redirect_to']) ? $_REQUEST['redirect_to'] : em_wp_get_referer();
165
  wp_redirect( $redirect );
166
  exit();
167
  }else{
202
  $location_cond = " AND location_private=0";
203
  }
204
  $location_cond = apply_filters('em_actions_locations_search_cond', $location_cond);
205
+ $term = (isset($_REQUEST['term'])) ? '%'.$wpdb->esc_like(stripslashes($_REQUEST['term'])).'%' : '%'.$wpdb->esc_like(stripslashes($_REQUEST['q'])).'%';
206
  $sql = $wpdb->prepare("
207
  SELECT
208
  location_id AS `id`,
378
  if( $EM_Booking->can_manage('manage_bookings','manage_others_bookings') ){
379
  if ($EM_Booking->get_post(true) && $EM_Booking->validate(true) && $EM_Booking->save(false) ){
380
  $EM_Notices->add_confirm( $EM_Booking->feedback_message, true );
381
+ $redirect = !empty($_REQUEST['redirect_to']) ? $_REQUEST['redirect_to'] : em_wp_get_referer();
382
  wp_redirect( $redirect );
383
  exit();
384
  }else{
403
  }
404
  }
405
  $EM_Notices->add_confirm( $EM_Booking->feedback_message, true );
406
+ $redirect = !empty($_REQUEST['redirect_to']) ? $_REQUEST['redirect_to'] : em_wp_get_referer();
407
  wp_redirect( $redirect );
408
  exit();
409
  }else{
421
  }else{
422
  $EM_Notices->add_confirm( _x('No emails to send for this booking.', 'bookings', 'events-manager'), true );
423
  }
424
+ $redirect = !empty($_REQUEST['redirect_to']) ? $_REQUEST['redirect_to'] : em_wp_get_referer();
425
  wp_redirect( $redirect );
426
  exit();
427
  }else{
440
  $wpdb->update(EM_BOOKINGS_TABLE, array('booking_meta'=> serialize($EM_Booking->booking_meta)), array('booking_id'=>$EM_Booking->booking_id))
441
  ){
442
  $EM_Notices->add_confirm( $EM_Booking->feedback_message, true );
443
+ $redirect = !empty($_REQUEST['redirect_to']) ? $_REQUEST['redirect_to'] : em_wp_get_referer();
444
  wp_redirect( $redirect );
445
  exit();
446
  }else{
450
  }
451
  }
452
  do_action('em_booking_modify_person', $EM_Event, $EM_Booking);
453
+ }elseif( $_REQUEST['action'] == 'bookings_add_note' && $EM_Booking->can_manage('manage_bookings','manage_others_bookings') ) {
454
+ em_verify_nonce('bookings_add_note');
455
+ if( $EM_Booking->add_note(stripslashes($_REQUEST['booking_note'])) ){
456
+ $EM_Notices->add_confirm($EM_Booking->feedback_message, true);
457
+ $redirect = !empty($_REQUEST['redirect_to']) ? $_REQUEST['redirect_to'] : em_wp_get_referer();
458
+ wp_redirect( $redirect );
459
+ exit();
460
+ }else{
461
+ $EM_Notices->add_error($EM_Booking->errors);
462
+ }
463
  }
464
+
465
  if( $result && defined('DOING_AJAX') ){
466
  $return = array('result'=>true, 'message'=>$feedback);
467
  header( 'Content-Type: application/javascript; charset=UTF-8', true ); //add this for HTTP -> HTTPS requests which assume it's a cross-site request
em-functions.php CHANGED
@@ -268,6 +268,20 @@ function em_verify_nonce($action, $nonce_name='_wpnonce'){
268
  }
269
  }
270
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
271
  /**
272
  * Gets all WP users
273
  * @return array
@@ -340,14 +354,15 @@ function em_booking_add_registration( $EM_Booking ){
340
  $registration = true;
341
  if( ((!is_user_logged_in() && get_option('dbem_bookings_anonymous')) || EM_Bookings::is_registration_forced()) && !get_option('dbem_bookings_registration_disable') ){
342
  //find random username - less options for user, less things go wrong
343
- $username_root = explode('@', wp_kses_data($_REQUEST['user_email']));
 
344
  $username_root = $username_rand = sanitize_user($username_root[0], true);
345
  while( username_exists($username_rand) ) {
346
  $username_rand = $username_root.rand(1,1000);
347
  }
348
  $_REQUEST['dbem_phone'] = (!empty($_REQUEST['dbem_phone'])) ? wp_kses_data($_REQUEST['dbem_phone']):''; //fix to prevent warnings
349
  $_REQUEST['user_name'] = (!empty($_REQUEST['user_name'])) ? wp_kses_data($_REQUEST['user_name']):''; //fix to prevent warnings
350
- $user_data = array('user_login' => $username_rand, 'user_email'=> $_REQUEST['user_email'], 'user_name'=> $_REQUEST['user_name'], 'dbem_phone'=> $_REQUEST['dbem_phone']);
351
  $id = em_register_new_user($user_data);
352
  if( is_numeric($id) ){
353
  $EM_Person = new EM_Person($id);
@@ -492,7 +507,13 @@ function em_new_user_notification() {
492
  em_locate_template('emails/new-user.php', true);
493
  $message = ob_get_clean();
494
  }
495
- $message = str_replace(array('%password%','%username%'), array($plaintext_pass, $user_login), $message);
 
 
 
 
 
 
496
  global $EM_Mailer;
497
  return $EM_Mailer->send(get_option('dbem_bookings_email_registration_subject'), $message, $user_email);
498
  }
268
  }
269
  }
270
 
271
+ /**
272
+ * Since WP 4.5 em_wp_get_referer() returns false if URL is the same. We use it to get a safe referrer url, so we use the new wp_get_raw_referer() argument instead.
273
+ * @since 5.6.3
274
+ * @return string
275
+ */
276
+ function em_wp_get_referer(){
277
+ if( function_exists('wp_get_raw_referer') ){
278
+ //do essentially what em_wp_get_referer does, but potentially returning the same url as before
279
+ return wp_validate_redirect(wp_get_raw_referer(), false );
280
+ }else{
281
+ return wp_get_referer();
282
+ }
283
+ }
284
+
285
  /**
286
  * Gets all WP users
287
  * @return array
354
  $registration = true;
355
  if( ((!is_user_logged_in() && get_option('dbem_bookings_anonymous')) || EM_Bookings::is_registration_forced()) && !get_option('dbem_bookings_registration_disable') ){
356
  //find random username - less options for user, less things go wrong
357
+ $user_email = stripslashes($_REQUEST['user_email']); //otherwise may fail validation
358
+ $username_root = explode('@', wp_kses_data($user_email));
359
  $username_root = $username_rand = sanitize_user($username_root[0], true);
360
  while( username_exists($username_rand) ) {
361
  $username_rand = $username_root.rand(1,1000);
362
  }
363
  $_REQUEST['dbem_phone'] = (!empty($_REQUEST['dbem_phone'])) ? wp_kses_data($_REQUEST['dbem_phone']):''; //fix to prevent warnings
364
  $_REQUEST['user_name'] = (!empty($_REQUEST['user_name'])) ? wp_kses_data($_REQUEST['user_name']):''; //fix to prevent warnings
365
+ $user_data = array('user_login' => $username_rand, 'user_email'=> $user_email, 'user_name'=> $_REQUEST['user_name'], 'dbem_phone'=> $_REQUEST['dbem_phone']);
366
  $id = em_register_new_user($user_data);
367
  if( is_numeric($id) ){
368
  $EM_Person = new EM_Person($id);
507
  em_locate_template('emails/new-user.php', true);
508
  $message = ob_get_clean();
509
  }
510
+ //for WP 4.4, regenerate password link can be used
511
+ $set_password_url = '';
512
+ if( function_exists('get_password_reset_key')){
513
+ $key = get_password_reset_key( $user );
514
+ $set_password_url = network_site_url("wp-login.php?action=rp&key=$key&login=" . rawurlencode($user_login), 'login');
515
+ }
516
+ $message = str_replace(array('%password%','%username%','%passwordurl%'), array($plaintext_pass, $user_login, $set_password_url), $message);
517
  global $EM_Mailer;
518
  return $EM_Mailer->send(get_option('dbem_bookings_email_registration_subject'), $message, $user_email);
519
  }
em-install.php CHANGED
@@ -93,8 +93,7 @@ function em_sort_out_table_nu_keys($table_name, $clean_keys = array()){
93
  }
94
 
95
  function em_create_events_table() {
96
- global $wpdb, $user_level, $user_ID;
97
- get_currentuserinfo();
98
  require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
99
 
100
  $table_name = $wpdb->prefix.'em_events';
93
  }
94
 
95
  function em_create_events_table() {
96
+ global $wpdb;
 
97
  require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
98
 
99
  $table_name = $wpdb->prefix.'em_events';
em-template-tags.php CHANGED
@@ -189,7 +189,7 @@ function em_event_form($args = array()){
189
  //Give a default location & category
190
  $default_cat = get_option('dbem_default_category');
191
  $default_loc = get_option('dbem_default_location');
192
- if( is_numeric($default_cat) && $default_cat > 0 && !empty($EM_Event->get_categories()->categories) ){
193
  $EM_Category = new EM_Category($default_cat);
194
  $EM_Event->get_categories()->categories[] = $EM_Category;
195
  }
189
  //Give a default location & category
190
  $default_cat = get_option('dbem_default_category');
191
  $default_loc = get_option('dbem_default_location');
192
+ if( get_option('dbem_categories_enabled') && is_numeric($default_cat) && $default_cat > 0 && !empty($EM_Event->get_categories()->categories) ){
193
  $EM_Category = new EM_Category($default_cat);
194
  $EM_Event->get_categories()->categories[] = $EM_Category;
195
  }
em-wpfc.php CHANGED
@@ -135,12 +135,9 @@ function wpfc_em_ajax() {
135
  $_REQUEST['year'] = false;
136
 
137
  //get the year and month to show, which would be the month/year between start and end request params
138
- $month_diff = $_REQUEST['end'] - $_REQUEST['start'];
139
- $month_ts = $_REQUEST['start'] + ($month_diff/2); //get a 'mid-month' timestamp to get year and month
140
- $year = (int) date ( "Y", $month_ts );
141
- $month = (int) date ( "m", $month_ts );
142
 
143
- $args = array ('month'=>$month, 'year'=>$year, 'owner'=>false, 'status'=>1, 'orderby'=>'event_start_time, event_name'); //since wpfc handles date sorting we only care about time and name ordering here
144
  $args['number_of_weeks'] = 6; //WPFC always has 6 weeks
145
  $limit = $args['limit'] = get_option('wpfc_limit',3);
146
  $args['long_events'] = ( isset($_REQUEST['long_events']) && $_REQUEST['long_events'] == 0 ) ? 0:1; //long events are enabled, unless explicitly told not to in the shortcode
@@ -179,7 +176,7 @@ function wpfc_em_ajax() {
179
  foreach( $cell_data['events'] as $EM_Event ){
180
  $color = $borderColor = $orig_color;
181
  $textColor = '#fff';
182
- if ( !empty ( $EM_Event->get_categories()->categories )) {
183
  foreach($EM_Event->get_categories()->categories as $EM_Category){
184
  /* @var $EM_Category EM_Category */
185
  if( $EM_Category->get_color() != '' ){
135
  $_REQUEST['year'] = false;
136
 
137
  //get the year and month to show, which would be the month/year between start and end request params
138
+ $scope = $_REQUEST['start'] .','. $_REQUEST['end'];
 
 
 
139
 
140
+ $args = array ('scope'=>$scope, 'owner'=>false, 'status'=>1, 'orderby'=>'event_start_time, event_name'); //since wpfc handles date sorting we only care about time and name ordering here
141
  $args['number_of_weeks'] = 6; //WPFC always has 6 weeks
142
  $limit = $args['limit'] = get_option('wpfc_limit',3);
143
  $args['long_events'] = ( isset($_REQUEST['long_events']) && $_REQUEST['long_events'] == 0 ) ? 0:1; //long events are enabled, unless explicitly told not to in the shortcode
176
  foreach( $cell_data['events'] as $EM_Event ){
177
  $color = $borderColor = $orig_color;
178
  $textColor = '#fff';
179
+ if ( get_option('dbem_categories_enabled') && !empty ( $EM_Event->get_categories()->categories )) {
180
  foreach($EM_Event->get_categories()->categories as $EM_Category){
181
  /* @var $EM_Category EM_Category */
182
  if( $EM_Category->get_color() != '' ){
events-manager.php CHANGED
@@ -1,7 +1,7 @@
1
  <?php
2
  /*
3
  Plugin Name: Events Manager
4
- Version: 5.6.2
5
  Plugin URI: http://wp-events-plugin.com
6
  Description: Event registration and booking management for WordPress. Recurring events, locations, google maps, rss, ical, booking registration and more!
7
  Author: Marcus Sykes
@@ -10,7 +10,7 @@ Text Domain: events-manager
10
  */
11
 
12
  /*
13
- Copyright (c) 2015, Marcus Sykes
14
 
15
  This program is free software; you can redistribute it and/or
16
  modify it under the terms of the GNU General Public License
@@ -28,7 +28,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
28
  */
29
 
30
  // Setting constants
31
- define('EM_VERSION', 5.62); //self expanatory
32
  define('EM_PRO_MIN_VERSION', 2.392); //self expanatory
33
  define('EM_PRO_MIN_VERSION_CRITICAL', 2.377); //self expanatory
34
  define('EM_DIR', dirname( __FILE__ )); //an absolute path to this directory
@@ -586,6 +586,10 @@ class EM_MS_Globals {
586
  add_filter('pre_update_option_'.$global_option_name, array(&$this, 'pre_update_option_'.$global_option_name), 1,2);
587
  add_action('add_option_'.$global_option_name, array(&$this, 'add_option_'.$global_option_name), 1,1);
588
  }
 
 
 
 
589
  }
590
  function get_globals(){
591
  $globals = array(
@@ -621,6 +625,17 @@ class EM_MS_Globals {
621
  }
622
  return $value[0];
623
  }
 
 
 
 
 
 
 
 
 
 
 
624
  }
625
  if( is_multisite() ){
626
  global $EM_MS_Globals;
@@ -634,7 +649,7 @@ if( is_multisite() ){
634
  * @uses locate_template()
635
  * @return string
636
  */
637
- function em_locate_template( $template_name, $load=false, $args = array() ) {
638
  //First we check if there are overriding tempates in the child or parent theme
639
  $located = locate_template(array('plugins/events-manager/'.$template_name));
640
  if( !$located ){
@@ -642,9 +657,9 @@ function em_locate_template( $template_name, $load=false, $args = array() ) {
642
  $located = EM_DIR.'/templates/'.$template_name;
643
  }
644
  }
645
- $located = apply_filters('em_locate_template', $located, $template_name, $load, $args);
646
  if( $located && $load ){
647
- if( is_array($args) ) extract($args);
648
  include($located);
649
  }
650
  return $located;
1
  <?php
2
  /*
3
  Plugin Name: Events Manager
4
+ Version: 5.6.3
5
  Plugin URI: http://wp-events-plugin.com
6
  Description: Event registration and booking management for WordPress. Recurring events, locations, google maps, rss, ical, booking registration and more!
7
  Author: Marcus Sykes
10
  */
11
 
12
  /*
13
+ Copyright (c) 2016, Marcus Sykes
14
 
15
  This program is free software; you can redistribute it and/or
16
  modify it under the terms of the GNU General Public License
28
  */
29
 
30
  // Setting constants
31
+ define('EM_VERSION', 5.63); //self expanatory
32
  define('EM_PRO_MIN_VERSION', 2.392); //self expanatory
33
  define('EM_PRO_MIN_VERSION_CRITICAL', 2.377); //self expanatory
34
  define('EM_DIR', dirname( __FILE__ )); //an absolute path to this directory
586
  add_filter('pre_update_option_'.$global_option_name, array(&$this, 'pre_update_option_'.$global_option_name), 1,2);
587
  add_action('add_option_'.$global_option_name, array(&$this, 'add_option_'.$global_option_name), 1,1);
588
  }
589
+ //if we're in MS Global mode, the categories option currently resides in the main blog, consider moving this to a network setting in the future
590
+ if( EM_MS_GLOBAL ){
591
+ add_filter('pre_option_dbem_categories_enabled', array(&$this, 'pre_option_dbem_categories_enabled'), 1,1);
592
+ }
593
  }
594
  function get_globals(){
595
  $globals = array(
625
  }
626
  return $value[0];
627
  }
628
+ /**
629
+ * Returns the option of the main site in this network, this function should only be fired if in MS Global mode.
630
+ * @param int $value
631
+ * @return int
632
+ */
633
+ function pre_option_dbem_categories_enabled($value){
634
+ if( !is_main_site() ){ //only alter value if not on main site already
635
+ $value = get_blog_option(get_current_site()->blog_id, 'dbem_categories_enabled') ? 1:0; //return a number since false will not circumvent pre_option_ filter
636
+ }
637
+ return $value;
638
+ }
639
  }
640
  if( is_multisite() ){
641
  global $EM_MS_Globals;
649
  * @uses locate_template()
650
  * @return string
651
  */
652
+ function em_locate_template( $template_name, $load=false, $the_args = array() ) {
653
  //First we check if there are overriding tempates in the child or parent theme
654
  $located = locate_template(array('plugins/events-manager/'.$template_name));
655
  if( !$located ){
657
  $located = EM_DIR.'/templates/'.$template_name;
658
  }
659
  }
660
+ $located = apply_filters('em_locate_template', $located, $template_name, $load, $the_args);
661
  if( $located && $load ){
662
+ if( is_array($the_args) ) extract($the_args);
663
  include($located);
664
  }
665
  return $located;
includes/js/events-manager-source.js DELETED
@@ -1,1263 +0,0 @@
1
- jQuery(document).ready( function($){
2
- var load_ui_css = false; //load jquery ui css?
3
- /* Time Entry */
4
- $('#start-time').each(function(i, el){
5
- $(el).addClass('em-time-input em-time-start').next('#end-time').addClass('em-time-input em-time-end').parent().addClass('em-time-range');
6
- });
7
- if( $(".em-time-input").length > 0 ){
8
- em_setup_timepicker('body');
9
- }
10
- /* Calendar AJAX */
11
- $('.em-calendar-wrapper a').unbind("click");
12
- $('.em-calendar-wrapper a').undelegate("click");
13
- $('.em-calendar-wrapper').delegate('a.em-calnav, a.em-calnav', 'click', function(e){
14
- e.preventDefault();
15
- $(this).closest('.em-calendar-wrapper').prepend('<div class="loading" id="em-loading"></div>');
16
- var url = em_ajaxify($(this).attr('href'));
17
- $(this).closest('.em-calendar-wrapper').load(url, function(){$(this).trigger('em_calendar_load');});
18
- } );
19
-
20
- //Events Search
21
- $(document).delegate('.em-toggle', 'click change', function(e){
22
- e.preventDefault();
23
- //show or hide advanced tickets, hidden by default
24
- var el = $(this);
25
- var rel = el.attr('rel').split(':');
26
- if( el.hasClass('show') ){
27
- if( rel.length > 1 ){ el.closest(rel[1]).find(rel[0]).slideUp(); }
28
- else{ $(rel[0]).slideUp(); }
29
- el.find('.show').show();
30
- el.find('.hide').hide();
31
- el.addClass('hide').removeClass('show');
32
- }else{
33
- if( rel.length > 1 ){ el.closest(rel[1]).find(rel[0]).slideDown(); }
34
- else{ $(rel[0]).slideDown(); }
35
- el.find('.show').hide();
36
- el.find('.hide').show();
37
- el.addClass('show').removeClass('hide');
38
- }
39
-
40
- });
41
- $('.em-search-form select[name=country]').change( function(){
42
- var el = $(this);
43
- if( el.val() != '' ){
44
- el.closest('.em-search-location').find('.em-search-location-meta').slideDown();
45
- }else{
46
- el.closest('.em-search-location').find('.em-search-location-meta').slideUp();
47
- }
48
- $('.em-search select[name=state]').html('<option value="">'+EM.txt_loading+'</option>');
49
- $('.em-search select[name=region]').html('<option value="">'+EM.txt_loading+'</option>');
50
- $('.em-search select[name=town]').html('<option value="">'+EM.txt_loading+'</option>');
51
- var data = {
52
- action : 'search_states',
53
- country : el.val(),
54
- return_html : true
55
- };
56
- $('.em-search select[name=state]').load( EM.ajaxurl, data );
57
- data.action = 'search_regions';
58
- $('.em-search select[name=region]').load( EM.ajaxurl, data );
59
- data.action = 'search_towns';
60
- $('.em-search select[name=town]').load( EM.ajaxurl, data );
61
- });
62
-
63
- $('.em-search-form select[name=region]').change( function(){
64
- $('.em-search select[name=state]').html('<option value="">'+EM.txt_loading+'</option>');
65
- $('.em-search select[name=town]').html('<option value="">'+EM.txt_loading+'</option>');
66
- var data = {
67
- action : 'search_states',
68
- region : $(this).val(),
69
- country : $('.em-search-form select[name=country]').val(),
70
- return_html : true
71
- };
72
- $('.em-search select[name=state]').load( EM.ajaxurl, data );
73
- data.action = 'search_towns';
74
- $('.em-search select[name=town]').load( EM.ajaxurl, data );
75
- });
76
-
77
- $('.em-search-form select[name=state]').change( function(){
78
- $('.em-search select[name=town]').html('<option value="">'+EM.txt_loading+'</option>');
79
- var data = {
80
- action : 'search_towns',
81
- state : $(this).val(),
82
- region : $('.em-search-form select[name=region]').val(),
83
- country : $('.em-search-form select[name=country]').val(),
84
- return_html : true
85
- };
86
- $('.em-search select[name=town]').load( EM.ajaxurl, data );
87
- });
88
-
89
- //in order for this to work, you need the above classes to be present in your templates
90
- $(document).delegate('.em-search-form', 'submit', function(e){
91
- form = $(this);
92
- if( this.em_search && this.em_search.value == EM.txt_search){ this.em_search.value = ''; }
93
- var results_wrapper = form.closest('.em-search-wrapper').find('.em-search-ajax');
94
- if( results_wrapper.length == 0 ) results_wrapper = $('.em-search-ajax');
95
- if( results_wrapper.length > 0 ){
96
- results_wrapper.append('<div class="loading" id="em-loading"></div>');
97
- var submitButton = form.find('.em-search-submit');
98
- submitButton.data('buttonText', submitButton.val()).val(EM.txt_searching);
99
- var img = submitButton.children('img');
100
- if( img.length > 0 ) img.attr('src', img.attr('src').replace('search-mag.png', 'search-loading.gif'));
101
- $.ajax( EM.ajaxurl, {
102
- type : 'POST',
103
- dataType : 'html',
104
- data : form.serialize(),
105
- success : function(responseText){
106
- submitButton.val(submitButton.data('buttonText'));
107
- if( img.length > 0 ) img.attr('src', img.attr('src').replace('search-loading.gif', 'search-mag.png'));
108
- results_wrapper.replaceWith(responseText);
109
- if( form.find('input[name=em_search]').val() == '' ){ form.find('input[name=em_search]').val(EM.txt_search); }
110
- }
111
- });
112
- e.preventDefault();
113
- return false;
114
- }
115
- });
116
- $(document).delegate('div.em-search-submit','click', function(e){ $(this).closest('.em-search-form').trigger('submit'); });
117
- if( $('.em-search-ajax').length > 0 ){
118
- $(document).delegate('.em-search-ajax a.page-numbers', 'click', function(e){
119
- var a = $(this);
120
- var data = a.closest('.em-pagination').attr('data-em-ajax');
121
- var wrapper = a.closest('.em-search-ajax');
122
- var qvars = a.attr('href').split('?');
123
- var vars = qvars[1];
124
- //add data-em-ajax att if it exists
125
- if( data != '' ){
126
- vars = vars != '' ? vars+'&'+data : data;
127
- }
128
- wrapper.append('<div class="loading" id="em-loading"></div>');
129
- $.ajax( EM.ajaxurl, {
130
- type : 'POST',
131
- dataType : 'html',
132
- data : vars,
133
- success : function(responseText) {
134
- wrapper.replaceWith(responseText);
135
- }
136
- });
137
- e.preventDefault();
138
- return false;
139
- });
140
- }
141
-
142
- /*
143
- * ADMIN AREA AND PUBLIC FORMS (Still polishing this section up, note that form ids and classes may change accordingly)
144
- */
145
- //Events List
146
- //Approve/Reject Links
147
- $(document).delegate('.em-event-delete', 'click', function(){
148
- if( !confirm("Are you sure you want to delete?") ){ return false; }
149
- var url = em_ajaxify( el.attr('href'));
150
- var td = el.parents('td').first();
151
- td.html("Loading...");
152
- td.load( url );
153
- return false;
154
- });
155
- //Tickets & Bookings
156
- if( $("#em-tickets-form").length > 0 ){
157
- //Enable/Disable Bookings
158
- $('#event-rsvp').click( function(event){
159
- if( !this.checked ){
160
- confirmation = confirm(EM.disable_bookings_warning);
161
- if( confirmation == false ){
162
- event.preventDefault();
163
- }else{
164
- $('#event-rsvp-options').hide();
165
- }
166
- }else{
167
- $('#event-rsvp-options').fadeIn();
168
- }
169
- });
170
- if($('input#event-rsvp').attr("checked")) {
171
- $("div#rsvp-data").fadeIn();
172
- } else {
173
- $("div#rsvp-data").hide();
174
- }
175
- //Ticket(s) UI
176
- var reset_ticket_forms = function(){
177
- $('#em-tickets-form table tbody tr.em-tickets-row').show();
178
- $('#em-tickets-form table tbody tr.em-tickets-row-form').hide();
179
- };
180
- //Add a new ticket
181
- $("#em-tickets-add").click(function(e){
182
- e.preventDefault();
183
- reset_ticket_forms();
184
- //create copy of template slot, insert so ready for population
185
- var tickets = $('#em-tickets-form table tbody');
186
- var rowNo = tickets.length+1;
187
- var slot = tickets.first().clone(true).attr('id','em-ticket-'+ rowNo).appendTo($('#em-tickets-form table'));
188
- //change the index of the form element names
189
- slot.find('*[name]').each( function(index,el){
190
- el = $(el);
191
- el.attr('name', el.attr('name').replace('em_tickets[0]','em_tickets['+rowNo+']'));
192
- });
193
- //show ticket and switch to editor
194
- slot.show().find('.ticket-actions-edit').trigger('click');
195
- //refresh datepicker and values
196
- slot.find('.em-date-input-loc').datepicker('destroy').removeAttr('id'); //clear all datepickers
197
- slot.find('.em-time-range input.em-time-end, .em-time-range input.em-time-start').unbind(['click','focus','change']); //clear all timepickers - consequently, also other click/blur/change events, recreate the further down
198
- em_setup_datepicker(slot);
199
- em_setup_timepicker(slot);
200
- $('html, body').animate({ scrollTop: slot.offset().top - 30 }); //sends user to form
201
- });
202
- //Edit a Ticket
203
- $(document).delegate('.ticket-actions-edit', 'click', function(e){
204
- e.preventDefault();
205
- reset_ticket_forms();
206
- var tbody = $(this).closest('tbody');
207
- tbody.find('tr.em-tickets-row').hide();
208
- tbody.find('tr.em-tickets-row-form').fadeIn();
209
- return false;
210
- });
211
- $(document).delegate('.ticket-actions-edited', 'click', function(e){
212
- e.preventDefault();
213
- var tbody = $(this).closest('tbody');
214
- var rowNo = tbody.attr('id').replace('em-ticket-','');
215
- tbody.find('.em-tickets-row').fadeIn();
216
- tbody.find('.em-tickets-row-form').hide();
217
- tbody.find('*[name]').each(function(index,el){
218
- el = $(el);
219
- if( el.attr('name') == 'ticket_start_pub'){
220
- tbody.find('span.ticket_start').text(el.attr('value'));
221
- }else if( el.attr('name') == 'ticket_end_pub' ){
222
- tbody.find('span.ticket_end').text(el.attr('value'));
223
- }else if( el.attr('name') == 'em_tickets['+rowNo+'][ticket_type]' ){
224
- if( el.find(':selected').val() == 'members' ){
225
- tbody.find('span.ticket_name').prepend('* ');
226
- }
227
- }else{
228
- tbody.find('.'+el.attr('name').replace('em_tickets['+rowNo+'][','').replace(']','')).text(el.attr('value'));
229
- }
230
- });
231
- //allow for others to hook into this
232
- $(document).triggerHandler('em_maps_tickets_edit', [tbody, rowNo, true]);
233
- $('html, body').animate({ scrollTop: tbody.parent().offset().top - 30 }); //sends user back to top of form
234
- return false;
235
- });
236
- $(document).delegate('.em-ticket-form select.ticket_type','change', function(e){
237
- //check if ticket is for all users or members, if members, show roles to limit the ticket to
238
- var el = $(this);
239
- if( el.find('option:selected').val() == 'members' ){
240
- el.closest('.em-ticket-form').find('.ticket-roles').fadeIn();
241
- }else{
242
- el.closest('.em-ticket-form').find('.ticket-roles').hide();
243
- }
244
- });
245
- $(document).delegate('.em-ticket-form .ticket-options-advanced','click', function(e){
246
- //show or hide advanced tickets, hidden by default
247
- e.preventDefault();
248
- var el = $(this);
249
- if( el.hasClass('show') ){
250
- el.closest('.em-ticket-form').find('.em-ticket-form-advanced').fadeIn();
251
- el.find('.show').hide();
252
- el.find('.hide').show();
253
- }else{
254
- el.closest('.em-ticket-form').find('.em-ticket-form-advanced').hide();
255
- el.find('.show').show();
256
- el.find('.hide').hide();
257
- }
258
- el.toggleClass('show').toggleClass('hide');
259
- });
260
- $('.em-ticket-form').each( function(){
261
- //check whether to show advanced options or not by default for each ticket
262
- var show_advanced = false;
263
- var el = $(this);
264
- el.find('.em-ticket-form-advanced input[type="text"]').each(function(){ if(this.value != '') show_advanced = true; });
265
- if( el.find('.em-ticket-form-advanced input[type="checkbox"]:checked').length > 0 ){ show_advanced = true; }
266
- el.find('.em-ticket-form-advanced option:selected').each(function(){ if(this.value != '') show_advanced = true; });
267
- if( show_advanced ) el.find('.ticket-options-advanced').trigger('click');
268
- });
269
- //Delete a ticket
270
- $(document).delegate('.ticket-actions-delete', 'click', function(e){
271
- e.preventDefault();
272
- var el = $(this);
273
- var tbody = el.closest('tbody');
274
- if( tbody.find('input.ticket_id').val() > 0 ){
275
- //only will happen if no bookings made
276
- el.text('Deleting...');
277
- $.getJSON( $(this).attr('href'), {'em_ajax_action':'delete_ticket', 'id':tbody.find('input.ticket_id').val()}, function(data){
278
- if(data.result){
279
- tbody.remove();
280
- }else{
281
- el.text('Delete');
282
- alert(data.error);
283
- }
284
- });
285
- }else{
286
- //not saved to db yet, so just remove
287
- tbody.remove();
288
- }
289
- return false;
290
- });
291
- }
292
- //Manageing Bookings
293
- if( $('#em-bookings-table').length > 0 ){
294
- //Pagination link clicks
295
- $(document).delegate('#em-bookings-table .tablenav-pages a', 'click', function(){
296
- var el = $(this);
297
- var form = el.parents('#em-bookings-table form.bookings-filter');
298
- //get page no from url, change page, submit form
299
- var match = el.attr('href').match(/#[0-9]+/);
300
- if( match != null && match.length > 0){
301
- var pno = match[0].replace('#','');
302
- form.find('input[name=pno]').val(pno);
303
- }else{
304
- form.find('input[name=pno]').val(1);
305
- }
306
- form.trigger('submit');
307
- return false;
308
- });
309
- //Overlay Options
310
- var em_bookings_settings_dialog = {
311
- modal : true,
312
- autoOpen: false,
313
- minWidth: 500,
314
- height: 'auto',
315
- buttons: [{
316
- text: EM.bookings_settings_save,
317
- click: function(e){
318
- e.preventDefault();
319
- //we know we'll deal with cols, so wipe hidden value from main
320
- var match = $("#em-bookings-table form.bookings-filter [name=cols]").val('');
321
- var booking_form_cols = $('form#em-bookings-table-settings-form input.em-bookings-col-item');
322
- $.each( booking_form_cols, function(i,item_match){
323
- //item_match = $(item_match);
324
- if( item_match.value == 1 ){
325
- if( match.val() != ''){
326
- match.val(match.val()+','+item_match.name);
327
- }else{
328
- match.val(item_match.name);
329
- }
330
- }
331
- });
332
- //submit main form
333
- $('#em-bookings-table-settings').trigger('submitted'); //hook into this with bind()
334
- $('#em-bookings-table form.bookings-filter').trigger('submit');
335
- $(this).dialog('close');
336
- }
337
- }]
338
- };
339
- var em_bookings_export_dialog = {
340
- modal : true,
341
- autoOpen: false,
342
- minWidth: 500,
343
- height: 'auto',
344
- buttons: [{
345
- text: EM.bookings_export_save,
346
- click: function(e){
347
- $(this).children('form').submit();
348
- $(this).dialog('close');
349
- }
350
- }]
351
- };
352
- if( $("#em-bookings-table-settings").length > 0 ){
353
- //Settings Overlay
354
- $("#em-bookings-table-settings").dialog(em_bookings_settings_dialog);
355
- $(document).delegate('#em-bookings-table-settings-trigger','click', function(e){ e.preventDefault(); $("#em-bookings-table-settings").dialog('open'); });
356
- //Export Overlay
357
- $("#em-bookings-table-export").dialog(em_bookings_export_dialog);
358
- $(document).delegate('#em-bookings-table-export-trigger','click', function(e){ e.preventDefault(); $("#em-bookings-table-export").dialog('open'); });
359
- var export_overlay_show_tickets = function(){
360
- if( $('#em-bookings-table-export-form input[name=show_tickets]').is(':checked') ){
361
- $('#em-bookings-table-export-form .em-bookings-col-item-ticket').show();
362
- $('#em-bookings-table-export-form #em-bookings-export-cols-active .em-bookings-col-item-ticket input').val(1);
363
- }else{
364
- $('#em-bookings-table-export-form .em-bookings-col-item-ticket').hide().find('input').val(0);
365
- }
366
- };
367
- //Sync export overlay with table search field changes
368
- $('#em-bookings-table form select').each(function(i, el){
369
- $(el).change(function(e){
370
- var select_el = $(this);
371
- var input_par = $('#em-bookings-table-export-form input[name='+select_el.attr('name')+']');
372
- var input_par_selected = select_el.find('option:selected');
373
- input_par.val(input_par_selected.val());
374
- });
375
- });
376
-
377
- export_overlay_show_tickets();
378
- $('#em-bookings-table-export-form input[name=show_tickets]').click(export_overlay_show_tickets);
379
- //Sortables
380
- $( ".em-bookings-cols-sortable" ).sortable({
381
- connectWith: ".em-bookings-cols-sortable",
382
- update: function(event, ui) {
383
- if( ui.item.parents('ul#em-bookings-cols-active, ul#em-bookings-export-cols-active').length > 0 ){
384
- ui.item.addClass('ui-state-highlight').removeClass('ui-state-default').children('input').val(1);
385
- }else{
386
- ui.item.addClass('ui-state-default').removeClass('ui-state-highlight').children('input').val(0);
387
- }
388
- }
389
- }).disableSelection();
390
- load_ui_css = true;
391
- }
392
- //Widgets and filter submissions
393
- $(document).delegate('#em-bookings-table form.bookings-filter', 'submit', function(e){
394
- var el = $(this);
395
- //append loading spinner
396
- el.parents('#em-bookings-table').find('.table-wrap').first().append('<div id="em-loading" />');
397
- //ajax call
398
- $.post( EM.ajaxurl, el.serializeArray(), function(data){
399
- var root = el.parents('#em-bookings-table').first();
400
- root.replaceWith(data);
401
- //recreate overlays
402
- $('#em-bookings-table-export input[name=scope]').val(root.find('select[name=scope]').val());
403
- $('#em-bookings-table-export input[name=status]').val(root.find('select[name=status]').val());
404
- jQuery(document).triggerHandler('em_bookings_filtered', [data, root, el]);
405
- });
406
- return false;
407
- });
408
- //Approve/Reject Links
409
- $(document).delegate('.em-bookings-approve,.em-bookings-reject,.em-bookings-unapprove,.em-bookings-delete', 'click', function(){
410
- var el = $(this);
411
- if( el.hasClass('em-bookings-delete') ){
412
- if( !confirm(EM.booking_delete) ){ return false; }
413
- }
414
- var url = em_ajaxify( el.attr('href'));
415
- var td = el.parents('td').first();
416
- td.html(EM.txt_loading);
417
- td.load( url );
418
- return false;
419
- });
420
- }
421
- //Old Bookings Table - depreciating soon
422
- if( $('.em_bookings_events_table').length > 0 ){
423
- //Widgets and filter submissions
424
- $(document).delegate('.em_bookings_events_table form', 'submit', function(e){
425
- var el = $(this);
426
- var url = em_ajaxify( el.attr('action') );
427
- el.parents('.em_bookings_events_table').find('.table-wrap').first().append('<div id="em-loading" />');
428
- $.get( url, el.serializeArray(), function(data){
429
- el.parents('.em_bookings_events_table').first().replaceWith(data);
430
- });
431
- return false;
432
- });
433
- //Pagination link clicks
434
- $(document).delegate('.em_bookings_events_table .tablenav-pages a', 'click', function(){
435
- var el = $(this);
436
- var url = em_ajaxify( el.attr('href') );
437
- el.parents('.em_bookings_events_table').find('.table-wrap').first().append('<div id="em-loading" />');
438
- $.get( url, function(data){
439
- el.parents('.em_bookings_events_table').first().replaceWith(data);
440
- });
441
- return false;
442
- });
443
- }
444
-
445
- //Manual Booking
446
- $('a.em-booking-button').click(function(e){
447
- e.preventDefault();
448
- var button = $(this);
449
- if( button.text() != EM.bb_booked && $(this).text() != EM.bb_booking){
450
- button.text(EM.bb_booking);
451
- var button_data = button.attr('id').split('_');
452
- $.ajax({
453
- url: EM.ajaxurl,
454
- dataType: 'jsonp',
455
- data: {
456
- event_id : button_data[1],
457
- _wpnonce : button_data[2],
458
- action : 'booking_add_one'
459
- },
460
- success : function(response, statusText, xhr, $form) {
461
- if(response.result){
462
- button.text(EM.bb_booked);
463
- }else{
464
- button.text(EM.bb_error);
465
- }
466
- if(response.message != '') alert(response.message);
467
- },
468
- error : function(){ button.text(EM.bb_error); }
469
- });
470
- }
471
- return false;
472
- });
473
- $('a.em-cancel-button').click(function(e){
474
- e.preventDefault();
475
- var button = $(this);
476
- if( button.text() != EM.bb_cancelled && button.text() != EM.bb_canceling){
477
- button.text(EM.bb_canceling);
478
- var button_data = button.attr('id').split('_');
479
- $.ajax({
480
- url: EM.ajaxurl,
481
- dataType: 'jsonp',
482
- data: {
483
- booking_id : button_data[1],
484
- _wpnonce : button_data[2],
485
- action : 'booking_cancel'
486
- },
487
- success : function(response, statusText, xhr, $form) {
488
- if(response.result){
489
- button.text(EM.bb_cancelled);
490
- }else{
491
- button.text(EM.bb_cancel_error);
492
- }
493
- },
494
- error : function(){ button.text(EM.bb_cancel_error); }
495
- });
496
- }
497
- return false;
498
- });
499
-
500
- //Datepicker
501
- if( $('.em-date-single, .em-date-range, #em-date-start').length > 0 ){
502
- if( EM.locale != 'en' && EM.locale_data ){
503
- $.datepicker.setDefaults(EM.locale_data);
504
- }
505
- load_ui_css = true;
506
- em_setup_datepicker('body');
507
- }
508
- if( load_ui_css ) em_load_jquery_css();
509
-
510
- //previously in em-admin.php
511
- function updateIntervalDescriptor () {
512
- $(".interval-desc").hide();
513
- var number = "-plural";
514
- if ($('input#recurrence-interval').val() == 1 || $('input#recurrence-interval').val() == "")
515
- number = "-singular";
516
- var descriptor = "span#interval-"+$("select#recurrence-frequency").val()+number;
517
- $(descriptor).show();
518
- }
519
- function updateIntervalSelectors () {
520
- $('p.alternate-selector').hide();
521
- $('p#'+ $('select#recurrence-frequency').val() + "-selector").show();
522
- }
523
- function updateShowHideRecurrence () {
524
- if( $('input#event-recurrence').attr("checked")) {
525
- $("#event_recurrence_pattern").fadeIn();
526
- $("#event-date-explanation").hide();
527
- $("#recurrence-dates-explanation").show();
528
- $("h3#recurrence-dates-title").show();
529
- $("h3#event-date-title").hide();
530
- } else {
531
- $("#event_recurrence_pattern").hide();
532
- $("#recurrence-dates-explanation").hide();
533
- $("#event-date-explanation").show();
534
- $("h3#recurrence-dates-title").hide();
535
- $("h3#event-date-title").show();
536
- }
537
- }
538
- $("#recurrence-dates-explanation").hide();
539
- $("#date-to-submit").hide();
540
- $("#end-date-to-submit").hide();
541
-
542
- $("#localised-date").show();
543
- $("#localised-end-date").show();
544
-
545
- $('#em-wrapper input.select-all').change(function(){
546
- if($(this).is(':checked')){
547
- $('input.row-selector').attr('checked', true);
548
- $('input.select-all').attr('checked', true);
549
- }else{
550
- $('input.row-selector').attr('checked', false);
551
- $('input.select-all').attr('checked', false);
552
- }
553
- });
554
-
555
- updateIntervalDescriptor();
556
- updateIntervalSelectors();
557
- updateShowHideRecurrence();
558
- $('input#event-recurrence').change(updateShowHideRecurrence);
559
-
560
- // recurrency elements
561
- $('input#recurrence-interval').keyup(updateIntervalDescriptor);
562
- $('select#recurrence-frequency').change(updateIntervalDescriptor);
563
- $('select#recurrence-frequency').change(updateIntervalSelectors);
564
-
565
- /* Load any maps */
566
- if( $('.em-location-map').length > 0 || $('.em-locations-map').length > 0 || $('#em-map').length > 0 ){
567
- if ( typeof google !== 'object' || typeof google.maps !== 'object' ){
568
- var script = document.createElement("script");
569
- script.type = "text/javascript";
570
- var proto = (EM.is_ssl) ? 'https:' : 'http:';
571
- script.src = proto + '//maps.google.com/maps/api/js?v=3.12&sensor=false&libraries=places&callback=em_maps';
572
- document.body.appendChild(script);
573
- }else{
574
- em_maps();
575
- }
576
- }
577
-
578
- //Finally, add autocomplete here
579
- //Autocomplete
580
- if( jQuery( "#em-location-data input#location-name" ).length > 0 ){
581
- jQuery( "#em-location-data input#location-name" ).autocomplete({
582
- source: EM.locationajaxurl,
583
- minLength: 2,
584
- focus: function( event, ui ){
585
- jQuery("input#location-id" ).val( ui.item.value );
586
- return false;
587
- },
588
- select: function( event, ui ){
589
- jQuery("input#location-id" ).val(ui.item.id).trigger('change');
590
- jQuery("input#location-name" ).val(ui.item.value);
591
- jQuery('input#location-address').val(ui.item.address);
592
- jQuery('input#location-town').val(ui.item.town);
593
- jQuery('input#location-state').val(ui.item.state);
594
- jQuery('input#location-region').val(ui.item.region);
595
- jQuery('input#location-postcode').val(ui.item.postcode);
596
- if( ui.item.country == '' ){
597
- jQuery('select#location-country option:selected').removeAttr('selected');
598
- }else{
599
- jQuery('select#location-country option[value="'+ui.item.country+'"]').attr('selected', 'selected');
600
- }
601
- jQuery('#em-location-data input, #em-location-data select').css('background-color','#ccc').attr('readonly','readonly');
602
- jQuery('#em-location-reset').show();
603
- jQuery('#em-location-search-tip').hide();
604
- jQuery(document).triggerHandler('em_locations_autocomplete_selected', [event, ui]);
605
- return false;
606
- }
607
- }).data( "ui-autocomplete" )._renderItem = function( ul, item ) {
608
- html_val = "<a>" + item.label + '<br><span style="font-size:11px"><em>'+ item.address + ', ' + item.town+"</em></span></a>";
609
- return jQuery( "<li></li>" ).data( "item.autocomplete", item ).append(html_val).appendTo( ul );
610
- };
611
- jQuery('#em-location-reset a').click( function(){
612
- jQuery('#em-location-data input').css('background-color','#fff').val('').removeAttr('readonly');
613
- jQuery('#em-location-data select').css('background-color','#fff');
614
- jQuery('#em-location-data option:selected').removeAttr('selected');
615
- jQuery('input#location-id').val('');
616
- jQuery('#em-location-reset').hide();
617
- jQuery('#em-location-search-tip').show();
618
- jQuery('#em-map').hide();
619
- jQuery('#em-map-404').show();
620
- if(typeof(marker) !== 'undefined'){
621
- marker.setPosition(new google.maps.LatLng(0, 0));
622
- infoWindow.close();
623
- marker.setDraggable(true);
624
- }
625
- return false;
626
- });
627
- if( jQuery('input#location-id').val() != '0' && jQuery('input#location-id').val() != '' ){
628
- jQuery('#em-location-data input, #em-location-data select').css('background-color','#ccc').attr('readonly','readonly');
629
- jQuery('#em-location-reset').show();
630
- jQuery('#em-location-search-tip').hide();
631
- }
632
- }
633
-
634
- });
635
-
636
- function em_load_jquery_css(){
637
- if( EM.ui_css && jQuery('script#jquery-ui-css').length == 0 ){
638
- var script = document.createElement("link");
639
- script.id = 'jquery-ui-css';
640
- script.rel = "stylesheet";
641
- script.href = EM.ui_css;
642
- document.body.appendChild(script);
643
- }
644
- }
645
-
646
- function em_setup_datepicker(wrap){
647
- wrap = jQuery(wrap);
648
- //default picker vals
649
- var datepicker_vals = { altFormat: "yy-mm-dd", changeMonth: true, changeYear: true, firstDay : EM.firstDay, yearRange:'-100:+10' };
650
- if( EM.dateFormat ) datepicker_vals.dateFormat = EM.dateFormat;
651
- if( EM.yearRange ) datepicker_vals.yearRange = EM.yearRange;
652
- jQuery(document).triggerHandler('em_datepicker', datepicker_vals);
653
-
654
- //apply datepickers
655
- dateDivs = wrap.find('.em-date-single, .em-date-range');
656
- if( dateDivs.length > 0 ){
657
- //apply datepickers to elements
658
- dateDivs.find('input.em-date-input-loc').each(function(i,dateInput){
659
- //init the datepicker
660
- var dateInput = jQuery(dateInput);
661
- var dateValue = dateInput.nextAll('input.em-date-input').first();
662
- var dateValue_value = dateValue.val();
663
- dateInput.datepicker(datepicker_vals);
664
- dateInput.datepicker('option', 'altField', dateValue);
665
- //now set the value
666
- if( dateValue_value ){
667
- var this_date_formatted = jQuery.datepicker.formatDate( EM.dateFormat, jQuery.datepicker.parseDate('yy-mm-dd', dateValue_value) );
668
- dateInput.val(this_date_formatted);
669
- dateValue.val(dateValue_value);
670
- }
671
- //add logic for texts
672
- dateInput.change(function(){
673
- if( jQuery(this).val() == '' ){
674
- jQuery(this).nextAll('.em-date-input').first().val('');
675
- }
676
- });
677
- });
678
- //deal with date ranges
679
- dateDivs.filter('.em-date-range').find('input.em-date-input-loc').each(function(i,dateInput){
680
- //finally, apply start/end logic to this field
681
- dateInput = jQuery(dateInput);
682
- if( dateInput.hasClass('em-date-start') ){
683
- dateInput.datepicker('option','onSelect', function( selectedDate ) {
684
- //get corresponding end date input, we expect ranges to be contained in .em-date-range with a start/end input element
685
- var startDate = jQuery(this);
686
- var endDate = startDate.parents('.em-date-range').find('.em-date-end').first();
687
- if( startDate.val() > endDate.val() && endDate.val() != '' ){
688
- endDate.datepicker( "setDate" , selectedDate );
689
- }
690
- endDate.datepicker( "option", 'minDate', selectedDate );
691
- });
692
- }else if( dateInput.hasClass('em-date-end') ){
693
- var startInput = dateInput.parents('.em-date-range').find('.em-date-start').first();
694
- if( startInput.val() != '' ){
695
- dateInput.datepicker('option', 'minDate', startInput.val());
696
- }
697
- }
698
- });
699
- }
700
- }
701
-
702
- function em_setup_timepicker(wrap){
703
- wrap = jQuery(wrap);
704
- wrap.find(".em-time-input").timePicker({
705
- show24Hours: EM.show24hours == 1,
706
- step:15
707
- });
708
-
709
- // Keep the duration between the two inputs.
710
- wrap.find(".em-time-range input.em-time-start").each( function(i, el){
711
- jQuery(el).data('oldTime', jQuery.timePicker(el).getTime());
712
- }).change( function() {
713
- var start = jQuery(this);
714
- var end = start.nextAll('.em-time-end');
715
- if (end.val()) { // Only update when second input has a value.
716
- // Calculate duration.
717
- var oldTime = start.data('oldTime');
718
- var duration = (jQuery.timePicker(end).getTime() - oldTime);
719
- var time = jQuery.timePicker(start).getTime();
720
- if( jQuery.timePicker(end).getTime() >= oldTime ){
721
- // Calculate and update the time in the second input.
722
- jQuery.timePicker(end).setTime(new Date(new Date(time.getTime() + duration)));
723
- }
724
- start.data('oldTime', time);
725
- }
726
- });
727
- // Validate.
728
- wrap.find(".em-time-range input.em-time-end").change(function() {
729
- var end = jQuery(this);
730
- var start = end.prevAll('.em-time-start');
731
- if( start.val() ){
732
- if( jQuery.timePicker(start).getTime() > jQuery.timePicker(this).getTime() && ( jQuery('.em-date-end').val().length == 0 || jQuery('.em-date-start').val() == jQuery('.em-date-end').val() ) ) { end.addClass("error"); }
733
- else { end.removeClass("error"); }
734
- }
735
- });
736
- //Sort out all day checkbox
737
- wrap.find('.em-time-range input.em-time-all-day').change(function(){
738
- var allday = jQuery(this);
739
- if( allday.is(':checked') ){
740
- allday.siblings('.em-time-input').css('background-color','#ccc');
741
- }else{
742
- allday.siblings('.em-time-input').css('background-color','#fff');
743
- }
744
- }).trigger('change');
745
- }
746
-
747
- /* Useful function for adding the em_ajax flag to a url, regardless of querystring format */
748
- var em_ajaxify = function(url){
749
- if ( url.search('em_ajax=0') != -1){
750
- url = url.replace('em_ajax=0','em_ajax=1');
751
- }else if( url.search(/\?/) != -1 ){
752
- url = url + "&em_ajax=1";
753
- }else{
754
- url = url + "?em_ajax=1";
755
- }
756
- return url;
757
- };
758
-
759
- /*
760
- * MAP FUNCTIONS
761
- */
762
- var maps = {};
763
- var maps_markers = {};
764
- var infowindow;
765
- //Load single maps (each map is treated as a seperate map.
766
- function em_maps() {
767
- //Find all the maps on this page
768
- jQuery('.em-location-map').each( function(index){
769
- el = jQuery(this);
770
- var map_id = el.attr('id').replace('em-location-map-','');
771
- em_LatLng = new google.maps.LatLng( jQuery('#em-location-map-coords-'+map_id+' .lat').text(), jQuery('#em-location-map-coords-'+map_id+' .lng').text());
772
- maps[map_id] = new google.maps.Map( document.getElementById('em-location-map-'+map_id), {
773
- zoom: 14,
774
- center: em_LatLng,
775
- mapTypeId: google.maps.MapTypeId.ROADMAP,
776
- mapTypeControl: false
777
- });
778
- maps_markers[map_id] = new google.maps.Marker({
779
- position: em_LatLng,
780
- map: maps[map_id]
781
- });
782
- infowindow = new google.maps.InfoWindow({ content: jQuery('#em-location-map-info-'+map_id+' .em-map-balloon').get(0) });
783
- infowindow.open(maps[map_id],maps_markers[map_id]);
784
- maps[map_id].panBy(40,-70);
785
-
786
- //JS Hook for handling map after instantiation
787
- //Example hook, which you can add elsewhere in your theme's JS - jQuery(document).bind('em_maps_location_hook', function(){ alert('hi');} );
788
- jQuery(document).triggerHandler('em_maps_location_hook', [maps[map_id], infowindow, maps_markers[map_id], map_id]);
789
- //map resize listener
790
- jQuery(window).on('resize', function(e) {
791
- google.maps.event.trigger(maps[map_id], "resize");
792
- maps[map_id].setCenter(maps_markers[map_id].getPosition());
793
- maps[map_id].panBy(40,-70);
794
- });
795
- });
796
- jQuery('.em-locations-map').each( function(index){
797
- var el = jQuery(this);
798
- var map_id = el.attr('id').replace('em-locations-map-','');
799
- var em_data = jQuery.parseJSON( jQuery('#em-locations-map-coords-'+map_id).text() );
800
- jQuery.getJSON(document.URL, em_data , function(data){
801
- if(data.length > 0){
802
- var myOptions = {
803
- mapTypeId: google.maps.MapTypeId.ROADMAP
804
- };
805
- maps[map_id] = new google.maps.Map(document.getElementById("em-locations-map-"+map_id), myOptions);
806
- maps_markers[map_id] = [];
807
-
808
- var minLatLngArr = [0,0];
809
- var maxLatLngArr = [0,0];
810
-
811
- for (var i = 0; i < data.length; i++) {
812
- if( !(data[i].location_latitude == 0 && data[i].location_longitude == 0) ){
813
- var latitude = parseFloat( data[i].location_latitude );
814
- var longitude = parseFloat( data[i].location_longitude );
815
- var location = new google.maps.LatLng( latitude, longitude );
816
- var marker = new google.maps.Marker({
817
- position: location,
818
- map: maps[map_id]
819
- });
820
- maps_markers[map_id].push(marker);
821
- marker.setTitle(data[i].location_name);
822
- var myContent = '<div class="em-map-balloon"><div id="em-map-balloon-'+map_id+'" class="em-map-balloon-content">'+ data[i].location_balloon +'</div></div>';
823
- em_map_infobox(marker, myContent, maps[map_id]);
824
-
825
- //Get min and max long/lats
826
- minLatLngArr[0] = (latitude < minLatLngArr[0] || i == 0) ? latitude : minLatLngArr[0];
827
- minLatLngArr[1] = (longitude < minLatLngArr[1] || i == 0) ? longitude : minLatLngArr[1];
828
- maxLatLngArr[0] = (latitude > maxLatLngArr[0] || i == 0) ? latitude : maxLatLngArr[0];
829
- maxLatLngArr[1] = (longitude > maxLatLngArr[1] || i == 0) ? longitude : maxLatLngArr[1];
830
- }
831
- }
832
- // Zoom in to the bounds
833
- var minLatLng = new google.maps.LatLng(minLatLngArr[0],minLatLngArr[1]);
834
- var maxLatLng = new google.maps.LatLng(maxLatLngArr[0],maxLatLngArr[1]);
835
- var bounds = new google.maps.LatLngBounds(minLatLng,maxLatLng);
836
- maps[map_id].fitBounds(bounds);
837
-
838
- //Call a hook if exists
839
- jQuery(document).triggerHandler('em_maps_locations_hook', [maps[map_id], data, map_id]);
840
- }else{
841
- el.children().first().html('No locations found');
842
- jQuery(document).triggerHandler('em_maps_locations_hook_not_found', [el]);
843
- }
844
- });
845
- });
846
- //Location stuff - only needed if inputs for location exist
847
- if( jQuery('select#location-select-id, input#location-address').length > 0 ){
848
- var map, marker;
849
- //load map info
850
- var refresh_map_location = function(){
851
- var location_latitude = jQuery('#location-latitude').val();
852
- var location_longitude = jQuery('#location-longitude').val();
853
- if( !(location_latitude == 0 && location_longitude == 0) ){
854
- var position = new google.maps.LatLng(location_latitude, location_longitude); //the location coords
855
- marker.setPosition(position);
856
- var mapTitle = (jQuery('input#location-name').length > 0) ? jQuery('input#location-name').val():jQuery('input#title').val();
857
- marker.setTitle( jQuery('input#location-name input#title, #location-select-id').first().val() );
858
- jQuery('#em-map').show();
859
- jQuery('#em-map-404').hide();
860
- google.maps.event.trigger(map, 'resize');
861
- map.setCenter(position);
862
- map.panBy(40,-55);
863
- infoWindow.setContent(
864
- '<div id="location-balloon-content"><strong>' +
865
- mapTitle +
866
- '</strong><br/>' +
867
- jQuery('#location-address').val() +
868
- '<br/>' + jQuery('#location-town').val()+
869
- '</div>'
870
- );
871
- infoWindow.open(map, marker);
872
- jQuery(document).triggerHandler('em_maps_location_hook', [map, infowindow, marker, 0]);
873
- } else {
874
- jQuery('#em-map').hide();
875
- jQuery('#em-map-404').show();
876
- }
877
- };
878
-
879
- //Add listeners for changes to address
880
- var get_map_by_id = function(id){
881
- if(jQuery('#em-map').length > 0){
882
- jQuery.getJSON(document.URL,{ em_ajax_action:'get_location', id:id }, function(data){
883
- if( data.location_latitude!=0 && data.location_longitude!=0 ){
884
- loc_latlng = new google.maps.LatLng(data.location_latitude, data.location_longitude);
885
- marker.setPosition(loc_latlng);
886
- marker.setTitle( data.location_name );
887
- marker.setDraggable(false);
888
- jQuery('#em-map').show();
889
- jQuery('#em-map-404').hide();
890
- map.setCenter(loc_latlng);
891
- map.panBy(40,-55);
892
- infoWindow.setContent( '<div id="location-balloon-content">'+ data.location_balloon +'</div>');
893
- infoWindow.open(map, marker);
894
- google.maps.event.trigger(map, 'resize');
895
- jQuery(document).triggerHandler('em_maps_location_hook', [map, infowindow, marker, 0]);
896
- }else{
897
- jQuery('#em-map').hide();
898
- jQuery('#em-map-404').show();
899
- }
900
- });
901
- }
902
- };
903
- jQuery('#location-select-id, input#location-id').change( function(){get_map_by_id(jQuery(this).val());} );
904
- jQuery('#location-name, #location-town, #location-address, #location-state, #location-postcode, #location-country').change( function(){
905
- //build address
906
- var addresses = [ jQuery('#location-address').val(), jQuery('#location-town').val(), jQuery('#location-state').val(), jQuery('#location-postcode').val() ];
907
- var address = '';
908
- jQuery.each( addresses, function(i, val){
909
- if( val != '' ){
910
- address = ( address == '' ) ? address+val:address+', '+val;
911
- }
912
- });
913
- if( address == '' ){ //in case only name is entered, no address
914
- jQuery('#em-map').hide();
915
- jQuery('#em-map-404').show();
916
- return false;
917
- }
918
- //do country last, as it's using the text version
919
- if( jQuery('#location-country option:selected').val() != 0 ){
920
- address = ( address == '' ) ? address+jQuery('#location-country option:selected').text():address+', '+jQuery('#location-country option:selected').text();
921
- }
922
- if( address != '' && jQuery('#em-map').length > 0 ){
923
- geocoder.geocode( { 'address': address }, function(results, status) {
924
- if (status == google.maps.GeocoderStatus.OK) {
925
- jQuery('#location-latitude').val(results[0].geometry.location.lat());
926
- jQuery('#location-longitude').val(results[0].geometry.location.lng());
927
- }
928
- refresh_map_location();
929
- });
930
- }
931
- });
932
-
933
- //Load map
934
- if(jQuery('#em-map').length > 0){
935
- var em_LatLng = new google.maps.LatLng(0, 0);
936
- map = new google.maps.Map( document.getElementById('em-map'), {
937
- zoom: 14,
938
- center: em_LatLng,
939
- mapTypeId: google.maps.MapTypeId.ROADMAP,
940
- mapTypeControl: false
941
- });
942
- var marker = new google.maps.Marker({
943
- position: em_LatLng,
944
- map: map,
945
- draggable: true
946
- });
947
- infoWindow = new google.maps.InfoWindow({
948
- content: ''
949
- });
950
- var geocoder = new google.maps.Geocoder();
951
- google.maps.event.addListener(infoWindow, 'domready', function() {
952
- document.getElementById('location-balloon-content').parentNode.style.overflow='';
953
- document.getElementById('location-balloon-content').parentNode.parentNode.style.overflow='';
954
- });
955
- google.maps.event.addListener(marker, 'dragend', function() {
956
- var position = marker.getPosition();
957
- jQuery('#location-latitude').val(position.lat());
958
- jQuery('#location-longitude').val(position.lng());
959
- map.setCenter(position);
960
- map.panBy(40,-55);
961
- });
962
- if( jQuery('#location-select-id').length > 0 ){
963
- jQuery('#location-select-id').trigger('change');
964
- }else{
965
- refresh_map_location();
966
- }
967
- jQuery(document).triggerHandler('em_map_loaded', [map, infowindow, marker]);
968
- }
969
- //map resize listener
970
- jQuery(window).on('resize', function(e) {
971
- google.maps.event.trigger(map, "resize");
972
- map.setCenter(marker.getPosition());
973
- map.panBy(40,-55);
974
- });
975
- }
976
- }
977
-
978
- function em_map_infobox(marker, message, map) {
979
- var iw = new google.maps.InfoWindow({ content: message });
980
- google.maps.event.addListener(marker, 'click', function() {
981
- if( infowindow ) infowindow.close();
982
- infowindow = iw;
983
- iw.open(map,marker);
984
- });
985
- }
986
-
987
-
988
- /* jQuery timePicker - http://labs.perifer.se/timedatepicker/ @ http://github.com/perifer/timePicker commit 100644 */
989
- /*
990
- * A time picker for jQuery
991
- *
992
- * Dual licensed under the MIT and GPL licenses.
993
- * Copyright (c) 2009 Anders Fajerson
994
- * @name timePicker
995
- * @author Anders Fajerson (http://perifer.se)
996
- * @example $("#mytime").timePicker();
997
- * @example $("#mytime").timePicker({step:30, startTime:"15:00", endTime:"18:00"});
998
- *
999
- * Based on timePicker by Sam Collet (http://www.texotela.co.uk/code/jquery/timepicker/)
1000
- *
1001
- * Options:
1002
- * step: # of minutes to step the time by
1003
- * startTime: beginning of the range of acceptable times
1004
- * endTime: end of the range of acceptable times
1005
- * separator: separator string to use between hours and minutes (e.g. ':')
1006
- * show24Hours: use a 24-hour scheme
1007
- */
1008
- (function($){
1009
- $.fn.timePicker = function(options) {
1010
- // Build main options before element iteration
1011
- var settings = $.extend({}, $.fn.timePicker.defaults, options);
1012
-
1013
- return this.each(function() {
1014
- $.timePicker(this, settings);
1015
- });
1016
- };
1017
-
1018
- $.timePicker = function (elm, settings) {
1019
- var e = $(elm)[0];
1020
- return e.timePicker || (e.timePicker = new jQuery._timePicker(e, settings));
1021
- };
1022
-
1023
- $.timePicker.version = '0.3';
1024
-
1025
- $._timePicker = function(elm, settings) {
1026
-
1027
- var tpOver = false;
1028
- var keyDown = false;
1029
- var startTime = timeToDate(settings.startTime, settings);
1030
- var endTime = timeToDate(settings.endTime, settings);
1031
- var selectedClass = "selected";
1032
- var selectedSelector = "li." + selectedClass;
1033
-
1034
- $(elm).attr('autocomplete', 'OFF'); // Disable browser autocomplete
1035
-
1036
- var times = [];
1037
- var time = new Date(startTime); // Create a new date object.
1038
- while(time <= endTime) {
1039
- times[times.length] = formatTime(time, settings);
1040
- time = new Date(time.setMinutes(time.getMinutes() + settings.step));
1041
- }
1042
-
1043
- var $tpDiv = $('<div class="time-picker'+ (settings.show24Hours ? '' : ' time-picker-12hours') +'"></div>');
1044
- var $tpList = $('<ul></ul>');
1045
-
1046
- // Build the list.
1047
- for(var i = 0; i < times.length; i++) {
1048
- $tpList.append("<li>" + times[i] + "</li>");
1049
- }
1050
- $tpDiv.append($tpList);
1051
- // Append the timPicker to the body and position it.
1052
- $tpDiv.appendTo('body').hide();
1053
-
1054
- // Store the mouse state, used by the blur event. Use mouseover instead of
1055
- // mousedown since Opera fires blur before mousedown.
1056
- $tpDiv.mouseover(function() {
1057
- tpOver = true;
1058
- }).mouseout(function() {
1059
- tpOver = false;
1060
- });
1061
-
1062
- $("li", $tpList).mouseover(function() {
1063
- if (!keyDown) {
1064
- $(selectedSelector, $tpDiv).removeClass(selectedClass);
1065
- $(this).addClass(selectedClass);
1066
- }
1067
- }).mousedown(function() {
1068
- tpOver = true;
1069
- }).click(function() {
1070
- setTimeVal(elm, this, $tpDiv, settings);
1071
- tpOver = false;
1072
- });
1073
-
1074
- var showPicker = function() {
1075
- if ($tpDiv.is(":visible")) {
1076
- return false;
1077
- }
1078
- $("li", $tpDiv).removeClass(selectedClass);
1079
-
1080
- // Position
1081
- var elmOffset = $(elm).offset();
1082
- $tpDiv.css({'top':elmOffset.top + elm.offsetHeight, 'left':elmOffset.left});
1083
-
1084
- // Show picker. This has to be done before scrollTop is set since that
1085
- // can't be done on hidden elements.
1086
- $tpDiv.show();
1087
-
1088
- // Try to find a time in the list that matches the entered time.
1089
- var time = elm.value ? timeStringToDate(elm.value, settings) : startTime;
1090
- var startMin = startTime.getHours() * 60 + startTime.getMinutes();
1091
- var min = (time.getHours() * 60 + time.getMinutes()) - startMin;
1092
- var steps = Math.round(min / settings.step);
1093
- var roundTime = normaliseTime(new Date(0, 0, 0, 0, (steps * settings.step + startMin), 0));
1094
- roundTime = (startTime < roundTime && roundTime <= endTime) ? roundTime : startTime;
1095
- var $matchedTime = $("li:contains(" + formatTime(roundTime, settings) + ")", $tpDiv);
1096
-
1097
- if ($matchedTime.length) {
1098
- $matchedTime.addClass(selectedClass);
1099
- // Scroll to matched time.
1100
- $tpDiv[0].scrollTop = $matchedTime[0].offsetTop;
1101
- }
1102
- return true;
1103
- };
1104
- // Attach to click as well as focus so timePicker can be shown again when
1105
- // clicking on the input when it already has focus.
1106
- $(elm).focus(showPicker).click(showPicker);
1107
- // Hide timepicker on blur
1108
- $(elm).blur(function() {
1109
- if (!tpOver) {
1110
- $tpDiv.hide();
1111
- }
1112
- });
1113
- // Keypress doesn't repeat on Safari for non-text keys.
1114
- // Keydown doesn't repeat on Firefox and Opera on Mac.
1115
- // Using kepress for Opera and Firefox and keydown for the rest seems to
1116
- // work with up/down/enter/esc.
1117
- $(elm)['keydown'](function(e) {
1118
- var $selected;
1119
- keyDown = true;
1120
- var top = $tpDiv[0].scrollTop;
1121
- switch (e.keyCode) {
1122
- case 38: // Up arrow.
1123
- // Just show picker if it's hidden.
1124
- if (showPicker()) {
1125
- return false;
1126
- };
1127
- $selected = $(selectedSelector, $tpList);
1128
- var prev = $selected.prev().addClass(selectedClass)[0];
1129
- if (prev) {
1130
- $selected.removeClass(selectedClass);
1131
- // Scroll item into view.
1132
- if (prev.offsetTop < top) {
1133
- $tpDiv[0].scrollTop = top - prev.offsetHeight;
1134
- }
1135
- }
1136
- else {
1137
- // Loop to next item.
1138
- $selected.removeClass(selectedClass);
1139
- prev = $("li:last", $tpList).addClass(selectedClass)[0];
1140
- $tpDiv[0].scrollTop = prev.offsetTop - prev.offsetHeight;
1141
- }
1142
- return false;
1143
- break;
1144
- case 40: // Down arrow, similar in behavior to up arrow.
1145
- if (showPicker()) {
1146
- return false;
1147
- };
1148
- $selected = $(selectedSelector, $tpList);
1149
- var next = $selected.next().addClass(selectedClass)[0];
1150
- if (next) {
1151
- $selected.removeClass(selectedClass);
1152
- if (next.offsetTop + next.offsetHeight > top + $tpDiv[0].offsetHeight) {
1153
- $tpDiv[0].scrollTop = top + next.offsetHeight;
1154
- }
1155
- }
1156
- else {
1157
- $selected.removeClass(selectedClass);
1158
- next = $("li:first", $tpList).addClass(selectedClass)[0];
1159
- $tpDiv[0].scrollTop = 0;
1160
- }
1161
- return false;
1162
- break;
1163
- case 13: // Enter
1164
- if ($tpDiv.is(":visible")) {
1165
- var sel = $(selectedSelector, $tpList)[0];
1166
- setTimeVal(elm, sel, $tpDiv, settings);
1167
- }
1168
- return false;
1169
- break;
1170
- case 27: // Esc
1171
- $tpDiv.hide();
1172
- return false;
1173
- break;
1174
- }
1175
- return true;
1176
- });
1177
- $(elm).keyup(function(e) {
1178
- keyDown = false;
1179
- });
1180
- // Helper function to get an inputs current time as Date object.
1181
- // Returns a Date object.
1182
- this.getTime = function() {
1183
- return timeStringToDate(elm.value, settings);
1184
- };
1185
- // Helper function to set a time input.
1186
- // Takes a Date object or string.
1187
- this.setTime = function(time) {
1188
- elm.value = formatTime(timeToDate(time, settings), settings);
1189
- // Trigger element's change events.
1190
- $(elm).change();
1191
- };
1192
-
1193
- }; // End fn;
1194
-
1195
- // Plugin defaults.
1196
- $.fn.timePicker.defaults = {
1197
- step:30,
1198
- startTime: new Date(0, 0, 0, 0, 0, 0),
1199
- endTime: new Date(0, 0, 0, 23, 30, 0),
1200
- separator: ':',
1201
- show24Hours: true
1202
- };
1203
-
1204
- // Private functions.
1205
-
1206
- function setTimeVal(elm, sel, $tpDiv, settings) {
1207
- // Update input field
1208
- elm.value = $(sel).text();
1209
- // Trigger element's change events.
1210
- $(elm).change();
1211
- // Keep focus for all but IE (which doesn't like it)
1212
- if (!navigator.userAgent.match(/msie/i)) {
1213
- elm.focus();
1214
- }
1215
- // Hide picker
1216
- $tpDiv.hide();
1217
- }
1218
-
1219
- function formatTime(time, settings) {
1220
- var h = time.getHours();
1221
- var hours = settings.show24Hours ? h : (((h + 11) % 12) + 1);
1222
- var minutes = time.getMinutes();
1223
- return formatNumber(hours) + settings.separator + formatNumber(minutes) + (settings.show24Hours ? '' : ((h < 12) ? ' AM' : ' PM'));
1224
- }
1225
-
1226
- function formatNumber(value) {
1227
- return (value < 10 ? '0' : '') + value;
1228
- }
1229
-
1230
- function timeToDate(input, settings) {
1231
- return (typeof input == 'object') ? normaliseTime(input) : timeStringToDate(input, settings);
1232
- }
1233
-
1234
- function timeStringToDate(input, settings) {
1235
- if (input) {
1236
- var array = input.split(settings.separator);
1237
- var hours = parseFloat(array[0]);
1238
- var minutes = parseFloat(array[1]);
1239
-
1240
- // Convert AM/PM hour to 24-hour format.
1241
- if (!settings.show24Hours) {
1242
- if (hours === 12 && input.indexOf('AM') !== -1) {
1243
- hours = 0;
1244
- }
1245
- else if (hours !== 12 && input.indexOf('PM') !== -1) {
1246
- hours += 12;
1247
- }
1248
- }
1249
- var time = new Date(0, 0, 0, hours, minutes, 0);
1250
- return normaliseTime(time);
1251
- }
1252
- return null;
1253
- }
1254
-
1255
- /* Normalise time object to a common date. */
1256
- function normaliseTime(time) {
1257
- time.setFullYear(2001);
1258
- time.setMonth(0);
1259
- time.setDate(0);
1260
- return time;
1261
- }
1262
-
1263
- })(jQuery);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/js/events-manager.js CHANGED
@@ -734,7 +734,9 @@ function em_setup_datepicker(wrap){
734
  //get corresponding end date input, we expect ranges to be contained in .em-date-range with a start/end input element
735
  var startDate = jQuery(this);
736
  var endDate = startDate.parents('.em-date-range').find('.em-date-end').first();
737
- if( startDate.val() > endDate.val() && endDate.val() != '' ){
 
 
738
  endDate.datepicker( "setDate" , selectedDate );
739
  endDate.trigger('change');
740
  }
@@ -824,7 +826,7 @@ function em_maps_load(){
824
  script.type = "text/javascript";
825
  script.id = "google-maps";
826
  var proto = (EM.is_ssl) ? 'https:' : 'http:';
827
- script.src = proto + '//maps.google.com/maps/api/js?v=3.12&sensor=false&libraries=places&callback=em_maps';
828
  document.body.appendChild(script);
829
  }else if( typeof google === 'object' && typeof google.maps === 'object' && !em_maps_loaded ){
830
  em_maps();
734
  //get corresponding end date input, we expect ranges to be contained in .em-date-range with a start/end input element
735
  var startDate = jQuery(this);
736
  var endDate = startDate.parents('.em-date-range').find('.em-date-end').first();
737
+ var startValue = startDate.nextAll('input.em-date-input').first().val();
738
+ var endValue = endDate.nextAll('input.em-date-input').first().val();
739
+ if( startValue > endValue && endValue != '' ){
740
  endDate.datepicker( "setDate" , selectedDate );
741
  endDate.trigger('change');
742
  }
826
  script.type = "text/javascript";
827
  script.id = "google-maps";
828
  var proto = (EM.is_ssl) ? 'https:' : 'http:';
829
+ script.src = proto + '//maps.google.com/maps/api/js?v=3.23&libraries=places&callback=em_maps';
830
  document.body.appendChild(script);
831
  }else if( typeof google === 'object' && typeof google.maps === 'object' && !em_maps_loaded ){
832
  em_maps();
multilingual/em-ml-io.php CHANGED
@@ -48,7 +48,18 @@ class EM_ML_IO {
48
  $event = EM_ML::get_translation($EM_Event, $lang_code); /* @var $EM_Event EM_Event */
49
  if( $event->event_id != $EM_Event->event_id ){
50
  self::event_merge_original_meta($event, $EM_Event);
 
 
 
 
 
 
51
  $event->save_meta();
 
 
 
 
 
52
  }
53
  }
54
  }
48
  $event = EM_ML::get_translation($EM_Event, $lang_code); /* @var $EM_Event EM_Event */
49
  if( $event->event_id != $EM_Event->event_id ){
50
  self::event_merge_original_meta($event, $EM_Event);
51
+ //if we execute a meta save here, we will screw up the current em_event_save_meta $wp_filter pointer executed in do_action()
52
+ //therefore, we save the current pointer position (priority) and set it back after saving the location further down
53
+ global $wp_filter, $wp_current_filter;
54
+ $wp_filter_priority = key($wp_filter['em_event_save_meta']);
55
+ $tag = end($wp_current_filter);
56
+ //save the event meta
57
  $event->save_meta();
58
+ //reset save_post pointer in $wp_filter to its original position
59
+ reset( $wp_filter[$tag] );
60
+ do{
61
+ if( key($wp_filter[$tag]) == $wp_filter_priority ) break;
62
+ }while ( next($wp_filter[$tag]) !== false );
63
  }
64
  }
65
  }
multilingual/em-ml-options.php CHANGED
@@ -227,7 +227,7 @@ class EM_ML_Options {
227
  public static function get_option($option, $lang = false, $return_original = true){
228
  if( self::is_option_translatable($option) ){
229
  $option_langs = get_option($option.'_ml', array());
230
- if( empty($lang) ) $lang = self::$current_language;
231
  if( !empty($option_langs[$lang]) ){
232
  return $option_langs[$lang];
233
  }
227
  public static function get_option($option, $lang = false, $return_original = true){
228
  if( self::is_option_translatable($option) ){
229
  $option_langs = get_option($option.'_ml', array());
230
+ if( empty($lang) ) $lang = EM_ML::$current_language;
231
  if( !empty($option_langs[$lang]) ){
232
  return $option_langs[$lang];
233
  }
readme.txt CHANGED
@@ -1,11 +1,11 @@
1
  === Events Manager ===
2
  Contributors: netweblogic, nutsmuggler
3
  Donate link: http://wp-events-plugin.com
4
- Tags: events, event, event registration, event calendar, events calendar, event management, paypal, registration, ticket, tickets, ticketing, tickets, theme, widget, locations, maps, booking, attendance, attendee, buddypress, calendar, gigs, payment, payments, sports,
5
  Text Domain: events-manager
6
  Requires at least: 3.5
7
- Tested up to: 4.4
8
- Stable tag: 5.6.2
9
 
10
  Fully featured event registration management including recurring events, locations management, calendar, Google map integration, booking management
11
 
@@ -99,6 +99,41 @@ See our [FAQ](http://wp-events-plugin.com/documentation/faq/) page, which is upd
99
  6. Manage attendees with various booking reports
100
 
101
  == Changelog ==
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  = 5.6.2 =
103
  * changed translation gettext domain from dbem to events-manager inline with new wordpress.org translation features
104
  * fixed EM_CSV_DELIMITER not being included in headers, added filter em_csv_delimiter to override EM_CSV_DELIMITER
1
  === Events Manager ===
2
  Contributors: netweblogic, nutsmuggler
3
  Donate link: http://wp-events-plugin.com
4
+ Tags: bookings, buddypress, calendar, event, event management, events, google maps, maps, locations, registration, registration, tickets
5
  Text Domain: events-manager
6
  Requires at least: 3.5
7
+ Tested up to: 4.5
8
+ Stable tag: 5.6.3
9
 
10
  Fully featured event registration management including recurring events, locations management, calendar, Google map integration, booking management
11
 
99
  6. Manage attendees with various booking reports
100
 
101
  == Changelog ==
102
+ = 5.6.3 =
103
+ * fixed events disappearing from calendar with WP FullCalendar plugin
104
+ * fixed PHP warning for delete booking when a user can't manage booking
105
+ * removed our EM_PHPMailer class and started using the one shipped with WordPress
106
+ * added %passwordurl% placeholder for new user registration email template
107
+ * added check for whether categories are enabled in many areas of code potentially avoiding a array_map PHP notice
108
+ * fixed preview mode duplicating tickets
109
+ * fixed widget formats stripping certain HTML elements
110
+ * fixed erratic date picker range behaviour when adjusting a start date later than the end date
111
+ * fixed original image getting deleted when modifying duplicated event image
112
+ * fixed orderby not including event_date_created and event_date_modified since 5.6.2
113
+ * fixed PHP warning when calling #_ATT to a non-existent attribute
114
+ * changed event debug meta box to display when WP_DEBUG_DISPLAY is also true rather than just WP_DEBUG
115
+ * fixed front-end submission false validation errors when submitting events with bookings enabled
116
+ * changed headers to new h1 standard on WP Dashboard pages
117
+ * fixed bookings admin viewer table not showing specific ticket bookings on front-end
118
+ * fixed ML hooking into em_event_save_meta and messing up the internal hook pointer by triggering it again
119
+ * fixed translated options PHP fatal error in rare occasions/setups
120
+ * fixed deprecated get_currentuserinfo notice in WP 4.5
121
+ * fixed PHP 7 division by zero warning
122
+ * fixed PHP 7 "array to string" notice
123
+ * fixed PHP 7 issues with EM_Ticket validation
124
+ * fixed grouped events list not showing long events on each group provided limit=0 is also supplied
125
+ * fixed apostrophes not passing email validation
126
+ * fixed buddypress fatal error when booking with notifications disabled,
127
+ * fixed buddypress activity stream items being created twice for new bookings
128
+ * fixed booking admin notes not being added in the front-end
129
+ * updated google maps api version and removed deprecated sensor parameter
130
+ * fixed searches not working for search terms containing apostrophes
131
+ * fixed blank settings pages due to 4.5 code changes to wp_get_referer()
132
+ * added em_bookings_deleted action which will execute when one or more bookings are deleted
133
+ * added em_bookings_delete filter for when a group of bookings are deleted with event(s)
134
+ * fixed EM_Bookings->delete() not deleting bookings properly
135
+ * deprecated use of EM_Event->delete_bookings() and EM_Event->delete_tickets() in favor of EM_Event->EM_Bookings->delete()
136
+
137
  = 5.6.2 =
138
  * changed translation gettext domain from dbem to events-manager inline with new wordpress.org translation features
139
  * fixed EM_CSV_DELIMITER not being included in headers, added filter em_csv_delimiter to override EM_CSV_DELIMITER
templates/tables/events.php CHANGED
@@ -3,11 +3,13 @@
3
  global $wpdb, $bp, $EM_Notices;
4
  /* @var $args array */
5
  /* @var $EM_Events array */
6
- /* @var events_count int */
7
- /* @var future_count int */
8
- /* @var pending_count int */
9
- /* @var url string */
10
- /* @var show_add_new bool */
 
 
11
  //add new button will only appear if called from em_event_admin template tag, or if the $show_add_new var is set
12
  if(!empty($show_add_new) && current_user_can('edit_events')) echo '<a class="em-button button add-new-h2" href="'.em_add_get_params($_SERVER['REQUEST_URI'],array('action'=>'edit','scope'=>null,'status'=>null,'event_id'=>null, 'success'=>null)).'">'.__('Add New','events-manager').'</a>';
13
  ?>
3
  global $wpdb, $bp, $EM_Notices;
4
  /* @var $args array */
5
  /* @var $EM_Events array */
6
+ /* @var $events_count int */
7
+ /* @var $future_count int */
8
+ /* @var $past_count int */
9
+ /* @var $pending_count int */
10
+ /* @var $url string */
11
+ /* @var $show_add_new bool */
12
+ /* @var $limit int */
13
  //add new button will only appear if called from em_event_admin template tag, or if the $show_add_new var is set
14
  if(!empty($show_add_new) && current_user_can('edit_events')) echo '<a class="em-button button add-new-h2" href="'.em_add_get_params($_SERVER['REQUEST_URI'],array('action'=>'edit','scope'=>null,'status'=>null,'event_id'=>null, 'success'=>null)).'">'.__('Add New','events-manager').'</a>';
15
  ?>
widgets/em-events.php CHANGED
@@ -98,7 +98,8 @@ class EM_Widget extends WP_Widget {
98
  }
99
  //balance tags and sanitize output formats
100
  if( in_array($key, array('format', 'no_events_text', 'all_events_text')) ){
101
- $new_instance[$key] = force_balance_tags(wp_kses_post($new_instance[$key]));
 
102
  }
103
  }
104
  return $new_instance;
98
  }
99
  //balance tags and sanitize output formats
100
  if( in_array($key, array('format', 'no_events_text', 'all_events_text')) ){
101
+ if( is_multisite() && !is_super_admin() ) $new_instance[$key] = wp_kses_post($new_instance[$key]); //for multisite
102
+ $new_instance[$key] = force_balance_tags($new_instance[$key]);
103
  }
104
  }
105
  return $new_instance;
widgets/em-locations.php CHANGED
@@ -70,7 +70,8 @@ class EM_Locations_Widget extends WP_Widget {
70
  }
71
  //balance tags and sanitize output formats
72
  if( in_array($key, array('format', 'no_locations_text')) ){
73
- $new_instance[$key] = force_balance_tags(wp_kses_post($new_instance[$key]));
 
74
  }
75
  }
76
  return $new_instance;
70
  }
71
  //balance tags and sanitize output formats
72
  if( in_array($key, array('format', 'no_locations_text')) ){
73
+ if( is_multisite() && !is_super_admin() ) $new_instance[$key] = wp_kses_post($new_instance[$key]); //for multisite
74
+ $new_instance[$key] = force_balance_tags($new_instance[$key]);
75
  }
76
  }
77
  return $new_instance;