Version Description
- Feature: Ability to merge duplicate locations.
- Bug fix: New locations created with events were not properly saved with the event, leading to possible location duplications.
- Bug fix: Add location to table should not be checked when copying an event.
- Bug fix: Possible fix to meta permissions.
- Bug fix: Fall back to non-fulltext queries if search term below length limit.
- Bug fix: 'search' nav item not rendering.
Download this release
Release Info
Developer | joedolson |
Plugin | My Calendar |
Version | 3.3.9 |
Comparing to | |
See all releases |
Code changes from version 3.3.8 to 3.3.9
- css/mc-styles.css +20 -0
- includes/screen-options.php +16 -0
- js/jquery.admin.js +13 -1
- my-calendar-core.php +11 -3
- my-calendar-event-editor.php +12 -10
- my-calendar-limits.php +2 -1
- my-calendar-location-manager.php +78 -10
- my-calendar-locations.php +10 -5
- my-calendar-navigation.php +1 -1
- my-calendar.php +4 -3
- readme.txt +10 -1
css/mc-styles.css
CHANGED
@@ -960,6 +960,26 @@ input[name="mc_uri"] {
|
|
960 |
text-align: center;
|
961 |
}
|
962 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
963 |
.my-calendar-admin .mc-clear-filters {
|
964 |
position: absolute;
|
965 |
top: -3em;
|
960 |
text-align: center;
|
961 |
}
|
962 |
|
963 |
+
.my-calendar-admin .mass-replace-wrap {
|
964 |
+
position: relative;
|
965 |
+
}
|
966 |
+
|
967 |
+
.my-calendar-admin .mass-replace-container {
|
968 |
+
display: none;
|
969 |
+
position: absolute;
|
970 |
+
left: 1rem;
|
971 |
+
top: 2rem;
|
972 |
+
background: #fff;
|
973 |
+
padding: 1rem;
|
974 |
+
box-shadow: 3px 3px 3px #c3c4c7;
|
975 |
+
border: 1px solid #c3c4c7;
|
976 |
+
width: 13em;
|
977 |
+
}
|
978 |
+
|
979 |
+
.my-calendar-admin .mass-replace-container label {
|
980 |
+
display: block;
|
981 |
+
}
|
982 |
+
|
983 |
.my-calendar-admin .mc-clear-filters {
|
984 |
position: absolute;
|
985 |
top: -3em;
|
includes/screen-options.php
CHANGED
@@ -176,3 +176,19 @@ function mc_add_help_tab() {
|
|
176 |
)
|
177 |
);
|
178 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
176 |
)
|
177 |
);
|
178 |
}
|
179 |
+
|
180 |
+
/**
|
181 |
+
* Add help tab on events.
|
182 |
+
*/
|
183 |
+
function mc_location_help_tab() {
|
184 |
+
$screen = get_current_screen();
|
185 |
+
$content = '<ul><li>' . __( 'Check the locations you wish to remove', 'my-calendar' ) . '</li><li>' . __( 'Check the "Merge Duplicates" option at the top of the table', 'my-calendar' ) . '</li><li>' . __( 'Enter the ID of the location you want to have replace these locations', 'my-calendar' ) . '</li><li>' . __( 'Submit the form', 'my-calendar' ) . '</li></ul><p>' . __( 'The checked locations will be deleted. Events using those locations will be updated to use the provided ID', 'my-calendar' ) . '</p>';
|
186 |
+
|
187 |
+
$screen->add_help_tab(
|
188 |
+
array(
|
189 |
+
'id' => 'mc_location_help_tab',
|
190 |
+
'title' => __( 'Merging Duplicate Locations', 'my-calendar' ),
|
191 |
+
'content' => $content,
|
192 |
+
)
|
193 |
+
);
|
194 |
+
}
|
js/jquery.admin.js
CHANGED
@@ -229,6 +229,16 @@ jQuery(document).ready(function ($) {
|
|
229 |
$( '.event_span' ).hide();
|
230 |
$( '.mc-actions input[type="submit"]' ).attr( 'disabled', 'disabled' );
|
231 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
232 |
$( '.selectall' ).on( 'click', function() {
|
233 |
var checked_status = $(this).prop('checked');
|
234 |
if ( checked_status ) {
|
@@ -262,7 +272,7 @@ jQuery(document).ready(function ($) {
|
|
262 |
$( '#mc_bulk_actions' ).val( value );
|
263 |
});
|
264 |
|
265 |
-
$( '#my-calendar-admin-table input, .mc-actions input' ).on( 'change', function (e) {
|
266 |
var checked_status = $(this).prop('checked');
|
267 |
var groups_table = $(this).parents( 'table' ).hasClass( 'mc-groups-table' );
|
268 |
var checkboxes = $( '#my-calendar-admin-table input:checked' );
|
@@ -270,10 +280,12 @@ jQuery(document).ready(function ($) {
|
|
270 |
if ( checked_status ) {
|
271 |
if ( ( groups_table && checked > 1 ) || ! groups_table ) {
|
272 |
$( '.mc-actions input[type="submit"]' ).removeAttr( 'disabled' );
|
|
|
273 |
}
|
274 |
} else {
|
275 |
if ( ( groups_table && checked < 2 ) || ( ! groups_table && checked == 0 ) ) {
|
276 |
$( '.mc-actions input[type="submit"]' ).attr( 'disabled', 'disabled' );
|
|
|
277 |
}
|
278 |
}
|
279 |
});
|
229 |
$( '.event_span' ).hide();
|
230 |
$( '.mc-actions input[type="submit"]' ).attr( 'disabled', 'disabled' );
|
231 |
|
232 |
+
$( '#mass_replace_on' ).on( 'click', function() {
|
233 |
+
var checked_status = $(this).prop('checked');
|
234 |
+
if ( checked_status ) {
|
235 |
+
// Activate actions on bulk checked.
|
236 |
+
$( '.mass-replace-container' ).show();
|
237 |
+
} else {
|
238 |
+
$( '.mass-replace-container' ).hide();
|
239 |
+
}
|
240 |
+
});
|
241 |
+
|
242 |
$( '.selectall' ).on( 'click', function() {
|
243 |
var checked_status = $(this).prop('checked');
|
244 |
if ( checked_status ) {
|
272 |
$( '#mc_bulk_actions' ).val( value );
|
273 |
});
|
274 |
|
275 |
+
$( '#my-calendar-admin-table input, .mc-actions input:not(#mass_replace_on)' ).on( 'change', function (e) {
|
276 |
var checked_status = $(this).prop('checked');
|
277 |
var groups_table = $(this).parents( 'table' ).hasClass( 'mc-groups-table' );
|
278 |
var checkboxes = $( '#my-calendar-admin-table input:checked' );
|
280 |
if ( checked_status ) {
|
281 |
if ( ( groups_table && checked > 1 ) || ! groups_table ) {
|
282 |
$( '.mc-actions input[type="submit"]' ).removeAttr( 'disabled' );
|
283 |
+
$( '.mc-actions #mass_replace_on' ).removeAttr( 'disabled' );
|
284 |
}
|
285 |
} else {
|
286 |
if ( ( groups_table && checked < 2 ) || ( ! groups_table && checked == 0 ) ) {
|
287 |
$( '.mc-actions input[type="submit"]' ).attr( 'disabled', 'disabled' );
|
288 |
+
$( '.mc-actions #mass_replace_on' ).attr( 'disabled', 'disabled' );
|
289 |
}
|
290 |
}
|
291 |
});
|
my-calendar-core.php
CHANGED
@@ -2190,7 +2190,7 @@ function mc_register_meta() {
|
|
2190 |
'page',
|
2191 |
'_mc_calendar',
|
2192 |
array(
|
2193 |
-
'show_in_rest'
|
2194 |
'schema' => array(
|
2195 |
'type' => 'object',
|
2196 |
'properties' => array(
|
@@ -2206,9 +2206,17 @@ function mc_register_meta() {
|
|
2206 |
),
|
2207 |
),
|
2208 |
),
|
2209 |
-
'single'
|
2210 |
-
'type'
|
|
|
2211 |
)
|
2212 |
);
|
2213 |
}
|
2214 |
add_action( 'init', 'mc_register_meta' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2190 |
'page',
|
2191 |
'_mc_calendar',
|
2192 |
array(
|
2193 |
+
'show_in_rest' => array(
|
2194 |
'schema' => array(
|
2195 |
'type' => 'object',
|
2196 |
'properties' => array(
|
2206 |
),
|
2207 |
),
|
2208 |
),
|
2209 |
+
'single' => true,
|
2210 |
+
'type' => 'array',
|
2211 |
+
'auth_callback' => 'mc_can_update_meta',
|
2212 |
)
|
2213 |
);
|
2214 |
}
|
2215 |
add_action( 'init', 'mc_register_meta' );
|
2216 |
+
|
2217 |
+
/**
|
2218 |
+
* Verify if a user can edit meta fields.
|
2219 |
+
*/
|
2220 |
+
function mc_can_update_meta() {
|
2221 |
+
return current_user_can( 'edit_posts' );
|
2222 |
+
}
|
my-calendar-event-editor.php
CHANGED
@@ -158,7 +158,7 @@ function mc_add_post_meta_data( $post_id, $post, $data, $event_id ) {
|
|
158 |
$event_date = ( is_array( $data['event_begin'] ) ) ? $data['event_begin'][0] : $data['event_begin'];
|
159 |
update_post_meta( $post_id, '_mc_event_date', strtotime( $event_date ) );
|
160 |
}
|
161 |
-
$location_id = ( isset( $post['location_preset'] ) ) ? (int) $post['location_preset'] : false;
|
162 |
if ( $location_id ) { // only change location ID if dropdown set.
|
163 |
update_post_meta( $post_id, '_mc_event_location', $location_id );
|
164 |
mc_update_event( 'event_location', $location_id, $event_id );
|
@@ -189,16 +189,15 @@ function mc_create_event_post( $data, $event_id ) {
|
|
189 |
}
|
190 |
$terms[] = (int) $term;
|
191 |
}
|
192 |
-
|
193 |
$title = $data['event_title'];
|
194 |
$template = apply_filters( 'mc_post_template', 'details', $term );
|
195 |
$data['shortcode'] = "[my_calendar_event event='$event_id' template='$template' list='']";
|
196 |
$description = isset( $data['event_desc'] ) ? $data['event_desc'] : '';
|
197 |
$excerpt = isset( $data['event_short'] ) ? $data['event_short'] : '';
|
198 |
-
$location_id = 0;
|
199 |
-
if ( isset( $_POST['location_preset'] ) ) {
|
200 |
$location_id = (int) $_POST['location_preset'];
|
201 |
-
} elseif ( isset( $data['location_preset'] ) ) {
|
202 |
$location_id = $data['location_preset'];
|
203 |
}
|
204 |
$post_status = $privacy;
|
@@ -393,7 +392,7 @@ function my_calendar_save( $action, $output, $event_id = false ) {
|
|
393 |
global $wpdb;
|
394 |
$proceed = (bool) $output[0];
|
395 |
$message = '';
|
396 |
-
$formats = array( '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%f', '%f' );
|
397 |
|
398 |
if ( ( 'add' === $action || 'copy' === $action ) && true === $proceed ) {
|
399 |
$add = $output[2]; // add format here.
|
@@ -774,7 +773,7 @@ function mc_edit_block_is_visible( $field ) {
|
|
774 |
} else {
|
775 |
if ( 'off' === $input[ $field ] || '' === $input[ $field ] ) {
|
776 |
return false;
|
777 |
-
} elseif ( 'off' === $show[ $field ] ) {
|
778 |
return false;
|
779 |
} else {
|
780 |
return true;
|
@@ -1731,6 +1730,7 @@ function mc_check_data( $action, $post, $i, $ignore_required = false ) {
|
|
1731 |
$event_hide_end = '';
|
1732 |
$event_longitude = '';
|
1733 |
$event_latitude = '';
|
|
|
1734 |
|
1735 |
if ( version_compare( PHP_VERSION, '7.4', '<' ) && get_magic_quotes_gpc() ) {
|
1736 |
$post = array_map( 'stripslashes_deep', $post );
|
@@ -1897,12 +1897,12 @@ function mc_check_data( $action, $post, $i, $ignore_required = false ) {
|
|
1897 |
$event_access = ! empty( $post['event_access_hidden'] ) ? unserialize( $post['event_access_hidden'] ) : $event_access;
|
1898 |
$has_location_data = false;
|
1899 |
|
1900 |
-
if ( '' !== trim( $event_label . $event_street . $event_street2 . $event_city . $event_state . $event_postcode . $event_region . $event_country . $event_url . $event_longitude . $event_latitude . $event_zoom . $event_phone . $event_phone2
|
1901 |
$has_location_data = true;
|
1902 |
}
|
1903 |
if ( $has_location_data && isset( $post['mc_copy_location'] ) && 'on' === $post['mc_copy_location'] && 0 === $i ) {
|
1904 |
// Only add this with the first event, if adding multiples.
|
1905 |
-
$add_loc
|
1906 |
'location_label' => $event_label,
|
1907 |
'location_street' => $event_street,
|
1908 |
'location_street2' => $event_street2,
|
@@ -1919,7 +1919,8 @@ function mc_check_data( $action, $post, $i, $ignore_required = false ) {
|
|
1919 |
'location_phone2' => $event_phone2,
|
1920 |
'location_access' => ( is_array( $event_access ) ) ? serialize( $event_access ) : '',
|
1921 |
);
|
1922 |
-
$loc_id
|
|
|
1923 |
do_action( 'mc_save_location', $loc_id, $add_loc, $add_loc );
|
1924 |
}
|
1925 |
}
|
@@ -2049,6 +2050,7 @@ function mc_check_data( $action, $post, $i, $ignore_required = false ) {
|
|
2049 |
'event_group_id' => $event_group_id,
|
2050 |
'event_span' => $event_span,
|
2051 |
'event_hide_end' => $event_hide_end,
|
|
|
2052 |
// Begin floats.
|
2053 |
'event_longitude' => $event_longitude,
|
2054 |
'event_latitude' => $event_latitude,
|
158 |
$event_date = ( is_array( $data['event_begin'] ) ) ? $data['event_begin'][0] : $data['event_begin'];
|
159 |
update_post_meta( $post_id, '_mc_event_date', strtotime( $event_date ) );
|
160 |
}
|
161 |
+
$location_id = ( isset( $post['location_preset'] ) && is_numeric( $post['location_preset'] ) ) ? (int) $post['location_preset'] : false;
|
162 |
if ( $location_id ) { // only change location ID if dropdown set.
|
163 |
update_post_meta( $post_id, '_mc_event_location', $location_id );
|
164 |
mc_update_event( 'event_location', $location_id, $event_id );
|
189 |
}
|
190 |
$terms[] = (int) $term;
|
191 |
}
|
|
|
192 |
$title = $data['event_title'];
|
193 |
$template = apply_filters( 'mc_post_template', 'details', $term );
|
194 |
$data['shortcode'] = "[my_calendar_event event='$event_id' template='$template' list='']";
|
195 |
$description = isset( $data['event_desc'] ) ? $data['event_desc'] : '';
|
196 |
$excerpt = isset( $data['event_short'] ) ? $data['event_short'] : '';
|
197 |
+
$location_id = isset( $data['event_location'] ) ? $data['event_location'] : 0;
|
198 |
+
if ( isset( $_POST['location_preset'] ) && is_numeric( $_POST['location_preset'] ) ) {
|
199 |
$location_id = (int) $_POST['location_preset'];
|
200 |
+
} elseif ( isset( $data['location_preset'] ) && is_numeric( $data['location_preset'] ) ) {
|
201 |
$location_id = $data['location_preset'];
|
202 |
}
|
203 |
$post_status = $privacy;
|
392 |
global $wpdb;
|
393 |
$proceed = (bool) $output[0];
|
394 |
$message = '';
|
395 |
+
$formats = array( '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%f', '%f' );
|
396 |
|
397 |
if ( ( 'add' === $action || 'copy' === $action ) && true === $proceed ) {
|
398 |
$add = $output[2]; // add format here.
|
773 |
} else {
|
774 |
if ( 'off' === $input[ $field ] || '' === $input[ $field ] ) {
|
775 |
return false;
|
776 |
+
} elseif ( isset( $show[ $field ] ) && 'off' === $show[ $field ] ) {
|
777 |
return false;
|
778 |
} else {
|
779 |
return true;
|
1730 |
$event_hide_end = '';
|
1731 |
$event_longitude = '';
|
1732 |
$event_latitude = '';
|
1733 |
+
$event_location = '';
|
1734 |
|
1735 |
if ( version_compare( PHP_VERSION, '7.4', '<' ) && get_magic_quotes_gpc() ) {
|
1736 |
$post = array_map( 'stripslashes_deep', $post );
|
1897 |
$event_access = ! empty( $post['event_access_hidden'] ) ? unserialize( $post['event_access_hidden'] ) : $event_access;
|
1898 |
$has_location_data = false;
|
1899 |
|
1900 |
+
if ( '' !== trim( $event_label . $event_street . $event_street2 . $event_city . $event_state . $event_postcode . $event_region . $event_country . $event_url . $event_longitude . $event_latitude . $event_zoom . $event_phone . $event_phone2 ) ) {
|
1901 |
$has_location_data = true;
|
1902 |
}
|
1903 |
if ( $has_location_data && isset( $post['mc_copy_location'] ) && 'on' === $post['mc_copy_location'] && 0 === $i ) {
|
1904 |
// Only add this with the first event, if adding multiples.
|
1905 |
+
$add_loc = array(
|
1906 |
'location_label' => $event_label,
|
1907 |
'location_street' => $event_street,
|
1908 |
'location_street2' => $event_street2,
|
1919 |
'location_phone2' => $event_phone2,
|
1920 |
'location_access' => ( is_array( $event_access ) ) ? serialize( $event_access ) : '',
|
1921 |
);
|
1922 |
+
$loc_id = mc_insert_location( $add_loc );
|
1923 |
+
$event_location = $loc_id;
|
1924 |
do_action( 'mc_save_location', $loc_id, $add_loc, $add_loc );
|
1925 |
}
|
1926 |
}
|
2050 |
'event_group_id' => $event_group_id,
|
2051 |
'event_span' => $event_span,
|
2052 |
'event_hide_end' => $event_hide_end,
|
2053 |
+
'event_location' => $event_location,
|
2054 |
// Begin floats.
|
2055 |
'event_longitude' => $event_longitude,
|
2056 |
'event_latitude' => $event_latitude,
|
my-calendar-limits.php
CHANGED
@@ -23,10 +23,11 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
23 |
function mc_prepare_search_query( $query ) {
|
24 |
global $wpdb;
|
25 |
$db_type = mc_get_db_type();
|
|
|
26 |
$search = '';
|
27 |
if ( '' !== trim( $query ) ) {
|
28 |
$query = esc_sql( urldecode( urldecode( $query ) ) );
|
29 |
-
if ( 'MyISAM' === $db_type ) {
|
30 |
$search = ' AND MATCH(' . apply_filters( 'mc_search_fields', 'event_title,event_desc,event_short,event_label,event_city,event_postcode,event_registration' ) . ") AGAINST ( '$query' IN BOOLEAN MODE ) ";
|
31 |
} else {
|
32 |
$search = " AND ( event_title LIKE '%$query%' OR event_desc LIKE '%$query%' OR event_short LIKE '%$query%' OR event_label LIKE '%$query%' OR event_city LIKE '%$query%' OR event_postcode LIKE '%$query%' OR event_registration LIKE '%$query%' ) ";
|
23 |
function mc_prepare_search_query( $query ) {
|
24 |
global $wpdb;
|
25 |
$db_type = mc_get_db_type();
|
26 |
+
$length = strlen( $query );
|
27 |
$search = '';
|
28 |
if ( '' !== trim( $query ) ) {
|
29 |
$query = esc_sql( urldecode( urldecode( $query ) ) );
|
30 |
+
if ( 'MyISAM' === $db_type && $length > 3 ) {
|
31 |
$search = ' AND MATCH(' . apply_filters( 'mc_search_fields', 'event_title,event_desc,event_short,event_label,event_city,event_postcode,event_registration' ) . ") AGAINST ( '$query' IN BOOLEAN MODE ) ";
|
32 |
} else {
|
33 |
$search = " AND ( event_title LIKE '%$query%' OR event_desc LIKE '%$query%' OR event_short LIKE '%$query%' OR event_label LIKE '%$query%' OR event_city LIKE '%$query%' OR event_postcode LIKE '%$query%' OR event_registration LIKE '%$query%' ) ";
|
my-calendar-location-manager.php
CHANGED
@@ -23,6 +23,7 @@ function my_calendar_manage_locations() {
|
|
23 |
my_calendar_check_db();
|
24 |
// We do some checking to see what we're doing.
|
25 |
mc_mass_delete_locations();
|
|
|
26 |
if ( ! empty( $_POST ) && ( ! isset( $_POST['mc_locations'] ) && ! isset( $_POST['mass_delete'] ) ) ) {
|
27 |
$nonce = $_REQUEST['_wpnonce'];
|
28 |
if ( ! wp_verify_nonce( $nonce, 'my-calendar-nonce' ) ) {
|
@@ -95,6 +96,64 @@ function mc_default_location() {
|
|
95 |
return $output;
|
96 |
}
|
97 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
98 |
/**
|
99 |
* Mass delete locations.
|
100 |
*
|
@@ -112,20 +171,21 @@ function mc_mass_delete_locations() {
|
|
112 |
$i = 0;
|
113 |
$total = 0;
|
114 |
$deleted = array();
|
115 |
-
$prepare = array();
|
116 |
foreach ( $locations as $value ) {
|
117 |
-
$total
|
118 |
-
$
|
119 |
-
$
|
|
|
|
|
|
|
|
|
120 |
$i ++;
|
121 |
}
|
122 |
-
|
123 |
-
$result = $wpdb->query( $wpdb->prepare( 'DELETE FROM ' . my_calendar_locations_table() . " WHERE location_id IN ($prepared)", $deleted ) ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.PreparedSQL.NotPrepared,WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare
|
124 |
-
if ( 0 !== $result && false !== $result ) {
|
125 |
// Argument: array of event IDs.
|
126 |
-
do_action( 'mc_mass_delete_locations', $deleted );
|
127 |
// Translators: Number of locations deleted, number selected.
|
128 |
-
$message = mc_show_notice( sprintf( __( '%1$d locations deleted successfully out of %2$d selected', 'my-calendar' ), $
|
129 |
} else {
|
130 |
$message = mc_show_error( __( 'Your locations have not been deleted. Please investigate.', 'my-calendar' ), false );
|
131 |
}
|
@@ -180,9 +240,10 @@ function mc_manage_locations() {
|
|
180 |
$current = empty( $_GET['paged'] ) ? 1 : intval( $_GET['paged'] );
|
181 |
if ( isset( $_POST['mcl'] ) ) {
|
182 |
$query = esc_sql( $_POST['mcl'] );
|
|
|
183 |
$db_type = mc_get_db_type();
|
184 |
if ( '' !== $query ) {
|
185 |
-
if ( 'MyISAM' === $db_type ) {
|
186 |
$search = ' WHERE MATCH(' . apply_filters( 'mc_search_fields', 'location_label,location_city,location_state,location_region,location_country,location_street,location_street2,location_phone' ) . ") AGAINST ( '$query' IN BOOLEAN MODE ) ";
|
187 |
} else {
|
188 |
$search = " WHERE location_label LIKE '%$query%' OR location_city LIKE '%$query%' OR location_state LIKE '%$query%' OR location_region LIKE '%$query%' OR location_country LIKE '%$query%' OR location_street LIKE '%$query%' OR location_street2 LIKE '%$query%' OR location_phone LIKE '%$query%' ";
|
@@ -235,6 +296,13 @@ function mc_manage_locations() {
|
|
235 |
<div><input type="hidden" name="_wpnonce" value="<?php echo wp_create_nonce( 'my-calendar-nonce' ); ?>"/></div>
|
236 |
<div class='mc-actions'>
|
237 |
<input type="submit" class="button-secondary delete" name="mass_delete" value="<?php esc_attr_e( 'Delete locations', 'my-calendar' ); ?>" />
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
238 |
<div><input type='checkbox' class='selectall' id='mass_edit' data-action="mass_edit" /> <label for='mass_edit'><?php esc_html_e( 'Check all', 'my-calendar' ); ?></label></div>
|
239 |
</div>
|
240 |
<table class="widefat striped page" id="my-calendar-admin-table">
|
23 |
my_calendar_check_db();
|
24 |
// We do some checking to see what we're doing.
|
25 |
mc_mass_delete_locations();
|
26 |
+
mc_clean_duplicate_locations();
|
27 |
if ( ! empty( $_POST ) && ( ! isset( $_POST['mc_locations'] ) && ! isset( $_POST['mass_delete'] ) ) ) {
|
28 |
$nonce = $_REQUEST['_wpnonce'];
|
29 |
if ( ! wp_verify_nonce( $nonce, 'my-calendar-nonce' ) ) {
|
96 |
return $output;
|
97 |
}
|
98 |
|
99 |
+
|
100 |
+
/**
|
101 |
+
* Mass replace locations.
|
102 |
+
*
|
103 |
+
* @return mixed boolean/int query result.
|
104 |
+
*/
|
105 |
+
function mc_clean_duplicate_locations() {
|
106 |
+
global $wpdb;
|
107 |
+
// Mass delete locations.
|
108 |
+
if ( ! empty( $_POST['mass_edit'] ) && isset( $_POST['mass_replace'] ) ) {
|
109 |
+
$nonce = $_REQUEST['_wpnonce'];
|
110 |
+
if ( ! wp_verify_nonce( $nonce, 'my-calendar-nonce' ) ) {
|
111 |
+
die( 'Security check failed' );
|
112 |
+
}
|
113 |
+
$locations = $_POST['mass_edit'];
|
114 |
+
$replace = $_POST['mass_replace_id'];
|
115 |
+
$location = mc_get_location( $replace );
|
116 |
+
if ( ! $location ) {
|
117 |
+
// If this isn't a valid location, don't continue.
|
118 |
+
echo mc_show_error( __( 'An invalid ID was provided for the replacement location.', 'my-calendar' ) );
|
119 |
+
return;
|
120 |
+
}
|
121 |
+
$i = 0;
|
122 |
+
$total = 0;
|
123 |
+
$deleted = array();
|
124 |
+
foreach ( $locations as $value ) {
|
125 |
+
$total = count( $locations );
|
126 |
+
$result = mc_delete_location( $value, 'bool' );
|
127 |
+
if ( ! $result ) {
|
128 |
+
$failed[] = absint( $value );
|
129 |
+
} else {
|
130 |
+
$deleted[] = absint( $value );
|
131 |
+
}
|
132 |
+
$change = $wpdb->update(
|
133 |
+
my_calendar_table(),
|
134 |
+
array(
|
135 |
+
'event_location' => $replace,
|
136 |
+
),
|
137 |
+
array(
|
138 |
+
'event_location' => $value,
|
139 |
+
),
|
140 |
+
'%d',
|
141 |
+
'%d'
|
142 |
+
);
|
143 |
+
$i ++;
|
144 |
+
}
|
145 |
+
if ( ! empty( $deleted ) ) {
|
146 |
+
// Argument: array of event IDs.
|
147 |
+
do_action( 'mc_clean_duplicate_locations', $deleted );
|
148 |
+
// Translators: Number of locations deleted, number selected.
|
149 |
+
$message = mc_show_notice( sprintf( __( '%1$d locations deleted successfully out of %2$d selected', 'my-calendar' ), count( $deleted ), $total ), false );
|
150 |
+
} else {
|
151 |
+
$message = mc_show_error( __( 'Your locations have not been deleted. Please investigate.', 'my-calendar' ), false );
|
152 |
+
}
|
153 |
+
echo wp_kses_post( $message );
|
154 |
+
}
|
155 |
+
}
|
156 |
+
|
157 |
/**
|
158 |
* Mass delete locations.
|
159 |
*
|
171 |
$i = 0;
|
172 |
$total = 0;
|
173 |
$deleted = array();
|
|
|
174 |
foreach ( $locations as $value ) {
|
175 |
+
$total = count( $locations );
|
176 |
+
$result = mc_delete_location( $value, 'bool' );
|
177 |
+
if ( ! $result ) {
|
178 |
+
$failed[] = absint( $value );
|
179 |
+
} else {
|
180 |
+
$deleted[] = absint( $value );
|
181 |
+
}
|
182 |
$i ++;
|
183 |
}
|
184 |
+
if ( ! empty( $deleted ) ) {
|
|
|
|
|
185 |
// Argument: array of event IDs.
|
186 |
+
do_action( 'mc_mass_delete_locations', $deleted, $failed );
|
187 |
// Translators: Number of locations deleted, number selected.
|
188 |
+
$message = mc_show_notice( sprintf( __( '%1$d locations deleted successfully out of %2$d selected', 'my-calendar' ), count( $deleted ), $total ), false );
|
189 |
} else {
|
190 |
$message = mc_show_error( __( 'Your locations have not been deleted. Please investigate.', 'my-calendar' ), false );
|
191 |
}
|
240 |
$current = empty( $_GET['paged'] ) ? 1 : intval( $_GET['paged'] );
|
241 |
if ( isset( $_POST['mcl'] ) ) {
|
242 |
$query = esc_sql( $_POST['mcl'] );
|
243 |
+
$length = strlen( $query );
|
244 |
$db_type = mc_get_db_type();
|
245 |
if ( '' !== $query ) {
|
246 |
+
if ( 'MyISAM' === $db_type && $length > 3 ) {
|
247 |
$search = ' WHERE MATCH(' . apply_filters( 'mc_search_fields', 'location_label,location_city,location_state,location_region,location_country,location_street,location_street2,location_phone' ) . ") AGAINST ( '$query' IN BOOLEAN MODE ) ";
|
248 |
} else {
|
249 |
$search = " WHERE location_label LIKE '%$query%' OR location_city LIKE '%$query%' OR location_state LIKE '%$query%' OR location_region LIKE '%$query%' OR location_country LIKE '%$query%' OR location_street LIKE '%$query%' OR location_street2 LIKE '%$query%' OR location_phone LIKE '%$query%' ";
|
296 |
<div><input type="hidden" name="_wpnonce" value="<?php echo wp_create_nonce( 'my-calendar-nonce' ); ?>"/></div>
|
297 |
<div class='mc-actions'>
|
298 |
<input type="submit" class="button-secondary delete" name="mass_delete" value="<?php esc_attr_e( 'Delete locations', 'my-calendar' ); ?>" />
|
299 |
+
<div class="mass-replace-wrap">
|
300 |
+
<input type="checkbox" name="mass_replace_on" disabled id="mass_replace_on" value="true"><label for="mass_replace_on"><?php esc_attr_e( 'Merge duplicates', 'my-calendar' ); ?></label>
|
301 |
+
<div class="mass-replace-container">
|
302 |
+
<label for="mass-replace"><?php _e( 'Replacement ID', 'my-calendar' ); ?></label><input type="text" size="4" id="mass-replace" name="mass_replace_id" class="mass-replace" value="" />
|
303 |
+
<input type="submit" class="button-secondary delete" name="mass_replace" value="<?php _e( 'Replace', 'my-calendar' ); ?>" />
|
304 |
+
</div>
|
305 |
+
</div>
|
306 |
<div><input type='checkbox' class='selectall' id='mass_edit' data-action="mass_edit" /> <label for='mass_edit'><?php esc_html_e( 'Check all', 'my-calendar' ); ?></label></div>
|
307 |
</div>
|
308 |
<table class="widefat striped page" id="my-calendar-admin-table">
|
my-calendar-locations.php
CHANGED
@@ -312,26 +312,29 @@ function mc_modify_location( $update, $where ) {
|
|
312 |
/**
|
313 |
* Delete a single location.
|
314 |
*
|
315 |
-
* @param int
|
|
|
316 |
*
|
317 |
* @return string
|
318 |
*/
|
319 |
-
function mc_delete_location( $location ) {
|
320 |
global $wpdb;
|
321 |
$location = (int) ( ( isset( $_GET['location_id'] ) ) ? $_GET['location_id'] : $location );
|
322 |
$results = $wpdb->query( $wpdb->prepare( 'DELETE FROM ' . my_calendar_locations_table() . ' WHERE location_id=%d', $location ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
323 |
do_action( 'mc_delete_location', $results, $location );
|
324 |
if ( $results ) {
|
|
|
325 |
$return = mc_show_notice( __( 'Location deleted successfully', 'my-calendar' ), false );
|
326 |
$default_location = get_option( 'mc_default_location', false );
|
327 |
if ( (int) $default_location === $location ) {
|
328 |
delete_option( 'mc_default_location' );
|
329 |
}
|
330 |
} else {
|
|
|
331 |
$return = mc_show_error( __( 'Location could not be deleted', 'my-calendar' ), false );
|
332 |
}
|
333 |
|
334 |
-
return $return;
|
335 |
}
|
336 |
|
337 |
/**
|
@@ -699,7 +702,8 @@ function mc_locations_fields( $has_data, $data, $context = 'location', $group_id
|
|
699 |
$return = '<div class="mc-locations" id="location-fields">';
|
700 |
if ( current_user_can( 'mc_edit_locations' ) && 'event' === $context ) {
|
701 |
$checked = ' checked="checked"';
|
702 |
-
if
|
|
|
703 |
$checked = '';
|
704 |
}
|
705 |
$return .= '<p class="checkboxes"><input type="checkbox" value="on" name="mc_copy_location" id="mc_copy_location"' . $checked . ' /> <label for="mc_copy_location">' . __( 'Copy new location into the locations table', 'my-calendar' ) . '</label></p>';
|
@@ -1193,11 +1197,12 @@ function mc_core_search_locations( $query = '' ) {
|
|
1193 |
$current = empty( $_GET['paged'] ) ? 1 : intval( $_GET['paged'] );
|
1194 |
$db_type = mc_get_db_type();
|
1195 |
$query = esc_sql( $query );
|
|
|
1196 |
|
1197 |
if ( '' !== $query ) {
|
1198 |
// Fulltext is supported in InnoDB since MySQL 5.6; minimum required by WP is 5.0 as of WP 5.5.
|
1199 |
// 37% of installs still below 5.6 as of 11/30/2020.
|
1200 |
-
if ( 'MyISAM' === $db_type ) {
|
1201 |
$search = ' WHERE MATCH(' . apply_filters( 'mc_search_fields', 'location_label' ) . ") AGAINST ( '$query' IN BOOLEAN MODE ) ";
|
1202 |
} else {
|
1203 |
$search = " WHERE location_label LIKE '%$query%' ";
|
312 |
/**
|
313 |
* Delete a single location.
|
314 |
*
|
315 |
+
* @param int $location Location ID.
|
316 |
+
* @param string $type Return type.
|
317 |
*
|
318 |
* @return string
|
319 |
*/
|
320 |
+
function mc_delete_location( $location, $type = 'string' ) {
|
321 |
global $wpdb;
|
322 |
$location = (int) ( ( isset( $_GET['location_id'] ) ) ? $_GET['location_id'] : $location );
|
323 |
$results = $wpdb->query( $wpdb->prepare( 'DELETE FROM ' . my_calendar_locations_table() . ' WHERE location_id=%d', $location ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
324 |
do_action( 'mc_delete_location', $results, $location );
|
325 |
if ( $results ) {
|
326 |
+
$value = true;
|
327 |
$return = mc_show_notice( __( 'Location deleted successfully', 'my-calendar' ), false );
|
328 |
$default_location = get_option( 'mc_default_location', false );
|
329 |
if ( (int) $default_location === $location ) {
|
330 |
delete_option( 'mc_default_location' );
|
331 |
}
|
332 |
} else {
|
333 |
+
$value = false;
|
334 |
$return = mc_show_error( __( 'Location could not be deleted', 'my-calendar' ), false );
|
335 |
}
|
336 |
|
337 |
+
return ( 'string' === $type ) ? $return : $value;
|
338 |
}
|
339 |
|
340 |
/**
|
702 |
$return = '<div class="mc-locations" id="location-fields">';
|
703 |
if ( current_user_can( 'mc_edit_locations' ) && 'event' === $context ) {
|
704 |
$checked = ' checked="checked"';
|
705 |
+
// Default unchecked if event has a location or is being copied.
|
706 |
+
if ( ( $has_data && ! empty( $data->event_location ) ) || isset( $_GET['mode'] ) && 'copy' === $_GET['mode'] ) {
|
707 |
$checked = '';
|
708 |
}
|
709 |
$return .= '<p class="checkboxes"><input type="checkbox" value="on" name="mc_copy_location" id="mc_copy_location"' . $checked . ' /> <label for="mc_copy_location">' . __( 'Copy new location into the locations table', 'my-calendar' ) . '</label></p>';
|
1197 |
$current = empty( $_GET['paged'] ) ? 1 : intval( $_GET['paged'] );
|
1198 |
$db_type = mc_get_db_type();
|
1199 |
$query = esc_sql( $query );
|
1200 |
+
$length = strlen( $query );
|
1201 |
|
1202 |
if ( '' !== $query ) {
|
1203 |
// Fulltext is supported in InnoDB since MySQL 5.6; minimum required by WP is 5.0 as of WP 5.5.
|
1204 |
// 37% of installs still below 5.6 as of 11/30/2020.
|
1205 |
+
if ( 'MyISAM' === $db_type && $length > 3 ) {
|
1206 |
$search = ' WHERE MATCH(' . apply_filters( 'mc_search_fields', 'location_label' ) . ") AGAINST ( '$query' IN BOOLEAN MODE ) ";
|
1207 |
} else {
|
1208 |
$search = " WHERE location_label LIKE '%$query%' ";
|
my-calendar-navigation.php
CHANGED
@@ -165,7 +165,7 @@ function mc_generate_calendar_nav( $params, $cat, $start_of_week, $show_months,
|
|
165 |
$access = ( in_array( 'access', $used, true ) ) ? mc_filters( $acc_args, mc_get_current_url() ) : '';
|
166 |
|
167 |
// Set up search.
|
168 |
-
$search = ( in_array( '
|
169 |
|
170 |
// Set up navigation links.
|
171 |
if ( in_array( 'nav', $used, true ) ) {
|
165 |
$access = ( in_array( 'access', $used, true ) ) ? mc_filters( $acc_args, mc_get_current_url() ) : '';
|
166 |
|
167 |
// Set up search.
|
168 |
+
$search = ( in_array( 'search', $used, true ) ) ? my_calendar_searchform( 'simple', mc_get_current_url() ) : '';
|
169 |
|
170 |
// Set up navigation links.
|
171 |
if ( in_array( 'nav', $used, true ) ) {
|
my-calendar.php
CHANGED
@@ -17,7 +17,7 @@
|
|
17 |
* License: GPL-2.0+
|
18 |
* License URI: http://www.gnu.org/license/gpl-2.0.txt
|
19 |
* Domain Path: lang
|
20 |
-
* Version: 3.3.
|
21 |
*/
|
22 |
|
23 |
/*
|
@@ -42,7 +42,7 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
42 |
}
|
43 |
|
44 |
global $mc_version, $wpdb;
|
45 |
-
$mc_version = '3.3.
|
46 |
|
47 |
define( 'MC_DEBUG', false );
|
48 |
|
@@ -426,7 +426,8 @@ function my_calendar_menu() {
|
|
426 |
$page_title = __( 'Add New Location', 'my-calendar' );
|
427 |
}
|
428 |
add_submenu_page( 'my-calendar', $page_title, __( 'Add New Location', 'my-calendar' ), 'mc_edit_locations', 'my-calendar-locations', 'my_calendar_add_locations' );
|
429 |
-
add_submenu_page( 'my-calendar', __( 'Locations', 'my-calendar' ), __( 'Locations', 'my-calendar' ), 'mc_edit_locations', 'my-calendar-location-manager', 'my_calendar_manage_locations' );
|
|
|
430 |
add_submenu_page( 'my-calendar', __( 'Categories', 'my-calendar' ), __( 'Categories', 'my-calendar' ), 'mc_edit_cats', 'my-calendar-categories', 'my_calendar_manage_categories' );
|
431 |
}
|
432 |
$permission = 'manage_options';
|
17 |
* License: GPL-2.0+
|
18 |
* License URI: http://www.gnu.org/license/gpl-2.0.txt
|
19 |
* Domain Path: lang
|
20 |
+
* Version: 3.3.9
|
21 |
*/
|
22 |
|
23 |
/*
|
42 |
}
|
43 |
|
44 |
global $mc_version, $wpdb;
|
45 |
+
$mc_version = '3.3.9';
|
46 |
|
47 |
define( 'MC_DEBUG', false );
|
48 |
|
426 |
$page_title = __( 'Add New Location', 'my-calendar' );
|
427 |
}
|
428 |
add_submenu_page( 'my-calendar', $page_title, __( 'Add New Location', 'my-calendar' ), 'mc_edit_locations', 'my-calendar-locations', 'my_calendar_add_locations' );
|
429 |
+
$locations = add_submenu_page( 'my-calendar', __( 'Locations', 'my-calendar' ), __( 'Locations', 'my-calendar' ), 'mc_edit_locations', 'my-calendar-location-manager', 'my_calendar_manage_locations' );
|
430 |
+
add_action( "load-$locations", 'mc_location_help_tab' );
|
431 |
add_submenu_page( 'my-calendar', __( 'Categories', 'my-calendar' ), __( 'Categories', 'my-calendar' ), 'mc_edit_cats', 'my-calendar-categories', 'my_calendar_manage_categories' );
|
432 |
}
|
433 |
$permission = 'manage_options';
|
readme.txt
CHANGED
@@ -6,7 +6,7 @@ Requires at least: 4.4
|
|
6 |
Tested up to: 5.9
|
7 |
Requires PHP: 7.0
|
8 |
Text domain: my-calendar
|
9 |
-
Stable tag: 3.3.
|
10 |
License: GPLv2 or later
|
11 |
|
12 |
Accessible WordPress event calendar plugin. Show events from multiple calendars on pages, in posts, or in widgets.
|
@@ -84,6 +84,15 @@ Translating my plugins is always appreciated. Visit <a href="https://translate.w
|
|
84 |
|
85 |
== Changelog ==
|
86 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
87 |
= 3.3.8 =
|
88 |
|
89 |
* Bug fix: Generated a duplicate location if event with location unselected location.
|
6 |
Tested up to: 5.9
|
7 |
Requires PHP: 7.0
|
8 |
Text domain: my-calendar
|
9 |
+
Stable tag: 3.3.9
|
10 |
License: GPLv2 or later
|
11 |
|
12 |
Accessible WordPress event calendar plugin. Show events from multiple calendars on pages, in posts, or in widgets.
|
84 |
|
85 |
== Changelog ==
|
86 |
|
87 |
+
= 3.3.9 =
|
88 |
+
|
89 |
+
* Feature: Ability to merge duplicate locations.
|
90 |
+
* Bug fix: New locations created with events were not properly saved with the event, leading to possible location duplications.
|
91 |
+
* Bug fix: Add location to table should not be checked when copying an event.
|
92 |
+
* Bug fix: Possible fix to meta permissions.
|
93 |
+
* Bug fix: Fall back to non-fulltext queries if search term below length limit.
|
94 |
+
* Bug fix: 'search' nav item not rendering.
|
95 |
+
|
96 |
= 3.3.8 =
|
97 |
|
98 |
* Bug fix: Generated a duplicate location if event with location unselected location.
|