Version Description
- Bug fix: Extraneous screen-reader-text summary generated in event views.
- Bug fix: Fixes to missing parameters in Schema.org microdata.
- Bug fix: Incorrect type comparison caused custom templates not to render in single event view.
- New feature: Default location.
Download this release
Release Info
Developer | joedolson |
Plugin | My Calendar |
Version | 3.2.8 |
Comparing to | |
See all releases |
Code changes from version 3.2.5 to 3.2.8
- css/mc-styles.css +11 -1
- my-calendar-api.php +2 -0
- my-calendar-categories.php +59 -18
- my-calendar-event-manager.php +53 -21
- my-calendar-group-manager.php +4 -0
- my-calendar-location-manager.php +35 -2
- my-calendar-locations.php +19 -3
- my-calendar-output.php +22 -12
- my-calendar.php +2 -2
- readme.txt +23 -2
css/mc-styles.css
CHANGED
@@ -765,7 +765,8 @@ select[name="event_recur"] {
|
|
765 |
border: 1px solid burlywood;
|
766 |
}
|
767 |
|
768 |
-
tr.problem
|
|
|
769 |
background-color: #ffa;
|
770 |
}
|
771 |
|
@@ -773,6 +774,15 @@ tr.problem .error {
|
|
773 |
color: #a00;
|
774 |
}
|
775 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
776 |
.problem-icon {
|
777 |
font-size: 64px;
|
778 |
float: left;
|
765 |
border: 1px solid burlywood;
|
766 |
}
|
767 |
|
768 |
+
tr.problem,
|
769 |
+
tr.invalid {
|
770 |
background-color: #ffa;
|
771 |
}
|
772 |
|
774 |
color: #a00;
|
775 |
}
|
776 |
|
777 |
+
.mc_default {
|
778 |
+
padding: 2px 8px 2px 2px;
|
779 |
+
border-radius: 3px;
|
780 |
+
background: #ffa;
|
781 |
+
color: #333;
|
782 |
+
border: 1px solid #888;
|
783 |
+
float: right;
|
784 |
+
}
|
785 |
+
|
786 |
.problem-icon {
|
787 |
font-size: 64px;
|
788 |
float: left;
|
my-calendar-api.php
CHANGED
@@ -94,6 +94,8 @@ function mc_api_format_json( $data ) {
|
|
94 |
* @param array $data array of event objects.
|
95 |
*/
|
96 |
function mc_api_format_csv( $data ) {
|
|
|
|
|
97 |
$keyed = false;
|
98 |
// Create a stream opening it with read / write mode.
|
99 |
$stream = fopen( 'data://text/plain,' . '', 'w+' );
|
94 |
* @param array $data array of event objects.
|
95 |
*/
|
96 |
function mc_api_format_csv( $data ) {
|
97 |
+
ob_clean();
|
98 |
+
ob_start();
|
99 |
$keyed = false;
|
100 |
// Create a stream opening it with read / write mode.
|
101 |
$stream = fopen( 'data://text/plain,' . '', 'w+' );
|
my-calendar-categories.php
CHANGED
@@ -587,6 +587,64 @@ function mc_category_by_name( $string ) {
|
|
587 |
return $cat_id;
|
588 |
}
|
589 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
590 |
/**
|
591 |
* Generate list of categories to edit.
|
592 |
*/
|
@@ -770,30 +828,13 @@ function mc_save_profile() {
|
|
770 |
* @return string HTML fields.
|
771 |
*/
|
772 |
function mc_category_select( $data = false, $option = true, $multiple = false, $name = false ) {
|
773 |
-
global $wpdb;
|
774 |
-
$mcdb = $wpdb;
|
775 |
-
if ( 'true' === get_option( 'mc_remote' ) && function_exists( 'mc_remote_db' ) ) {
|
776 |
-
$mcdb = mc_remote_db();
|
777 |
-
}
|
778 |
if ( ! $name ) {
|
779 |
$name = 'event_category[]';
|
780 |
}
|
781 |
// Grab all the categories and list them.
|
782 |
$list = '';
|
783 |
$default = '';
|
784 |
-
$cats =
|
785 |
-
if ( empty( $cats ) ) {
|
786 |
-
// need to have categories. Try to create again.
|
787 |
-
mc_create_category(
|
788 |
-
array(
|
789 |
-
'category_name' => 'General',
|
790 |
-
'category_color' => '#ffffcc',
|
791 |
-
'category_icon' => 'event.png',
|
792 |
-
)
|
793 |
-
);
|
794 |
-
|
795 |
-
$cats = $mcdb->get_results( $sql );
|
796 |
-
}
|
797 |
if ( ! empty( $cats ) ) {
|
798 |
$cats = apply_filters( 'mc_category_list', $cats, $data, $option, $name );
|
799 |
foreach ( $cats as $cat ) {
|
587 |
return $cat_id;
|
588 |
}
|
589 |
|
590 |
+
/**
|
591 |
+
* Get or create a category if no default set.
|
592 |
+
*
|
593 |
+
* @param bool $single False for all categories; true for individual category.
|
594 |
+
*
|
595 |
+
* @return int
|
596 |
+
*/
|
597 |
+
function mc_no_category_default( $single = false ) {
|
598 |
+
global $wpdb;
|
599 |
+
$mcdb = $wpdb;
|
600 |
+
if ( 'true' === get_option( 'mc_remote' ) && function_exists( 'mc_remote_db' ) ) {
|
601 |
+
$mcdb = mc_remote_db();
|
602 |
+
}
|
603 |
+
|
604 |
+
$cats = $mcdb->get_results( 'SELECT * FROM ' . my_calendar_categories_table() . ' ORDER BY category_name ASC' );
|
605 |
+
$cat_id = $cats[0]->category_id;
|
606 |
+
if ( empty( $cats ) ) {
|
607 |
+
// need to have categories. Try to create again.
|
608 |
+
$cat_id = mc_create_category(
|
609 |
+
array(
|
610 |
+
'category_name' => 'General',
|
611 |
+
'category_color' => '#ffffcc',
|
612 |
+
'category_icon' => 'event.png',
|
613 |
+
)
|
614 |
+
);
|
615 |
+
|
616 |
+
$cats = $mcdb->get_results( 'SELECT * FROM ' . my_calendar_categories_table() . ' ORDER BY category_name ASC' );
|
617 |
+
}
|
618 |
+
if ( $single ) {
|
619 |
+
return $cat_id;
|
620 |
+
}
|
621 |
+
|
622 |
+
return $cats;
|
623 |
+
}
|
624 |
+
|
625 |
+
/**
|
626 |
+
* Fetch category object by ID or name.
|
627 |
+
*
|
628 |
+
* @param int|string $category Category name/id.
|
629 |
+
*
|
630 |
+
* @return object
|
631 |
+
*/
|
632 |
+
function mc_get_category( $category ) {
|
633 |
+
global $wpdb;
|
634 |
+
$mcdb = $wpdb;
|
635 |
+
if ( 'true' === get_option( 'mc_remote' ) && function_exists( 'mc_remote_db' ) ) {
|
636 |
+
$mcdb = mc_remote_db();
|
637 |
+
}
|
638 |
+
if ( is_int( $category ) ) {
|
639 |
+
$sql = 'SELECT * FROM ' . my_calendar_categories_table() . ' WHERE category_id = %d';
|
640 |
+
$cat = $mcdb->get_row( $mcdb->prepare( $sql, $category ) );
|
641 |
+
} else {
|
642 |
+
$cat = mc_category_by_name( $category );
|
643 |
+
}
|
644 |
+
|
645 |
+
return $cat;
|
646 |
+
}
|
647 |
+
|
648 |
/**
|
649 |
* Generate list of categories to edit.
|
650 |
*/
|
828 |
* @return string HTML fields.
|
829 |
*/
|
830 |
function mc_category_select( $data = false, $option = true, $multiple = false, $name = false ) {
|
|
|
|
|
|
|
|
|
|
|
831 |
if ( ! $name ) {
|
832 |
$name = 'event_category[]';
|
833 |
}
|
834 |
// Grab all the categories and list them.
|
835 |
$list = '';
|
836 |
$default = '';
|
837 |
+
$cats = mc_no_category_default();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
838 |
if ( ! empty( $cats ) ) {
|
839 |
$cats = apply_filters( 'mc_category_list', $cats, $data, $option, $name );
|
840 |
foreach ( $cats as $cat ) {
|
my-calendar-event-manager.php
CHANGED
@@ -914,12 +914,16 @@ function mc_delete_event( $event_id ) {
|
|
914 |
$instance = false;
|
915 |
$post_id = mc_get_data( 'event_post', $event_id );
|
916 |
if ( empty( $_POST['event_instance'] ) ) {
|
917 |
-
|
|
|
|
|
918 |
$wpdb->query( $wpdb->prepare( 'DELETE FROM ' . my_calendar_table() . ' WHERE event_id=%d', $event_id ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
919 |
$result = $wpdb->get_results( $wpdb->prepare( 'SELECT event_id FROM ' . my_calendar_table() . ' WHERE event_id=%d', $event_id ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
|
|
|
|
920 |
} else {
|
921 |
$event_in = absint( $_POST['event_instance'] );
|
922 |
-
$result = $wpdb->get_results( $wpdb->prepare( 'DELETE FROM ' . my_calendar_event_table() . ' WHERE occur_id
|
923 |
$instance = true;
|
924 |
}
|
925 |
if ( empty( $result ) || empty( $result[0]->event_id ) ) {
|
@@ -1661,8 +1665,9 @@ function mc_form_fields( $data, $mode, $event_id ) {
|
|
1661 |
foreach ( $locs as $loc ) {
|
1662 |
if ( is_object( $loc ) ) {
|
1663 |
$loc_name = strip_tags( stripslashes( $loc->location_label ), mc_strip_tags() );
|
1664 |
-
$selected = '';
|
1665 |
if ( is_object( $data ) ) {
|
|
|
1666 |
if ( property_exists( $data, 'event_location' ) ) {
|
1667 |
$event_location = $data->event_location;
|
1668 |
} else {
|
@@ -1798,9 +1803,12 @@ function mc_get_users( $group = 'authors' ) {
|
|
1798 |
* @return string select options.
|
1799 |
*/
|
1800 |
function mc_selected_users( $selected = '', $group = 'authors' ) {
|
|
|
|
|
|
|
|
|
1801 |
$selected = explode( ',', $selected );
|
1802 |
$users = mc_get_users( $group );
|
1803 |
-
$options = '';
|
1804 |
foreach ( $users as $u ) {
|
1805 |
if ( in_array( $u->ID, $selected, true ) ) {
|
1806 |
$checked = ' selected="selected"';
|
@@ -2027,7 +2035,6 @@ function mc_list_events() {
|
|
2027 |
$limit = ( strpos( $limit, 'AND' ) === 0 ) ? $limit : 'AND ' . $limit;
|
2028 |
$events = $wpdb->get_results( $wpdb->prepare( 'SELECT DISTINCT SQL_CALC_FOUND_ROWS events.event_id FROM ' . my_calendar_table() . ' AS events JOIN ' . my_calendar_categories_table() . " AS categories WHERE events.event_category = categories.category_id $limit ORDER BY categories.category_name $sortbydirection " . 'LIMIT %d, %d', $query_limit, $items_per_page ) ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.PreparedSQL.NotPrepared
|
2029 |
}
|
2030 |
-
|
2031 |
$found_rows = $wpdb->get_col( 'SELECT FOUND_ROWS();' );
|
2032 |
$items = $found_rows[0];
|
2033 |
$counts = get_option( 'mc_count_cache' );
|
@@ -2174,12 +2181,15 @@ function mc_list_events() {
|
|
2174 |
$categories = $wpdb->get_results( 'SELECT * FROM ' . my_calendar_categories_table() ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
2175 |
|
2176 |
foreach ( array_keys( $events ) as $key ) {
|
2177 |
-
$e
|
2178 |
-
$event
|
|
|
2179 |
if ( ! is_object( $event ) ) {
|
2180 |
-
|
|
|
2181 |
}
|
2182 |
$class = ( 'alternate' === $class ) ? 'even' : 'alternate';
|
|
|
2183 |
$pending = ( 0 === (int) $event->event_approved ) ? 'pending' : '';
|
2184 |
$trashed = ( 2 === (int) $event->event_approved ) ? 'trashed' : '';
|
2185 |
$author = ( 0 !== (int) $event->event_author ) ? get_userdata( $event->event_author ) : 'Public Submitter';
|
@@ -2193,13 +2203,18 @@ function mc_list_events() {
|
|
2193 |
$spam_label = '';
|
2194 |
}
|
2195 |
|
2196 |
-
$trash
|
2197 |
-
$draft
|
2198 |
-
$
|
2199 |
-
$
|
2200 |
-
$
|
2201 |
-
$
|
2202 |
-
$
|
|
|
|
|
|
|
|
|
|
|
2203 |
$group_url = admin_url( "admin.php?page=my-calendar-groups&mode=edit&event_id=$event->event_id&group_id=$event->event_group_id" );
|
2204 |
$delete_url = admin_url( "admin.php?page=my-calendar-manage&mode=delete&event_id=$event->event_id" );
|
2205 |
$can_edit = mc_can_edit_event( $event );
|
@@ -2233,6 +2248,7 @@ function mc_list_events() {
|
|
2233 |
}
|
2234 |
}
|
2235 |
echo $draft;
|
|
|
2236 |
?>
|
2237 |
</strong>
|
2238 |
|
@@ -2332,8 +2348,15 @@ function mc_list_events() {
|
|
2332 |
// Events *must* have a category.
|
2333 |
mc_update_event( 'event_category', 1, $event->event_id, '%d' );
|
2334 |
}
|
2335 |
-
$cat
|
2336 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2337 |
$color = ( 0 !== strpos( $color, '#' ) ) ? '#' . $color : $color;
|
2338 |
$categories = mc_get_categories( $event );
|
2339 |
$cats = array();
|
@@ -2541,7 +2564,7 @@ function mc_check_data( $action, $post, $i ) {
|
|
2541 |
$event_longitude = '';
|
2542 |
$event_latitude = '';
|
2543 |
|
2544 |
-
if ( get_magic_quotes_gpc() ) {
|
2545 |
$post = array_map( 'stripslashes_deep', $post );
|
2546 |
}
|
2547 |
if ( ! wp_verify_nonce( $post['event_nonce_name'], 'event_nonce' ) ) {
|
@@ -2630,6 +2653,11 @@ function mc_check_data( $action, $post, $i ) {
|
|
2630 |
$primary = $cats;
|
2631 |
$cats = array( $cats );
|
2632 |
}
|
|
|
|
|
|
|
|
|
|
|
2633 |
}
|
2634 |
$event_author = ( isset( $post['event_author'] ) && is_numeric( $post['event_author'] ) ) ? $post['event_author'] : 0;
|
2635 |
$event_link = ! empty( $post['event_link'] ) ? trim( $post['event_link'] ) : '';
|
@@ -3045,7 +3073,7 @@ function mc_instance_list( $args ) {
|
|
3045 |
|
3046 |
global $wpdb;
|
3047 |
$output = '';
|
3048 |
-
if ( true === $instance ) {
|
3049 |
$sql = 'SELECT * FROM ' . my_calendar_event_table() . ' WHERE occur_id=%d ORDER BY occur_begin ASC';
|
3050 |
} else {
|
3051 |
$sql = 'SELECT * FROM ' . my_calendar_event_table() . ' WHERE occur_event_id=%d ORDER BY occur_begin ASC';
|
@@ -3499,6 +3527,7 @@ function mc_can_edit_category( $category, $user ) {
|
|
3499 |
* @return boolean
|
3500 |
*/
|
3501 |
function mc_can_edit_event( $event = false ) {
|
|
|
3502 |
if ( ! $event ) {
|
3503 |
|
3504 |
return false;
|
@@ -3519,8 +3548,11 @@ function mc_can_edit_event( $event = false ) {
|
|
3519 |
$event_id = $event->event_id;
|
3520 |
$event_author = $event->event_author;
|
3521 |
} elseif ( is_int( $event ) ) {
|
3522 |
-
$event_id
|
3523 |
-
$event
|
|
|
|
|
|
|
3524 |
$event_author = $event->event_author;
|
3525 |
} else {
|
3526 |
// What is the case where the event is neither an object, int, or falsey? Hmm.
|
914 |
$instance = false;
|
915 |
$post_id = mc_get_data( 'event_post', $event_id );
|
916 |
if ( empty( $_POST['event_instance'] ) ) {
|
917 |
+
// Delete from instance table.
|
918 |
+
$wpdb->query( $wpdb->prepare( 'DELETE FROM ' . my_calendar_event_table() . ' WHERE occur_event_id=%d', $event_id ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
919 |
+
// Delete from event table.
|
920 |
$wpdb->query( $wpdb->prepare( 'DELETE FROM ' . my_calendar_table() . ' WHERE event_id=%d', $event_id ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
921 |
$result = $wpdb->get_results( $wpdb->prepare( 'SELECT event_id FROM ' . my_calendar_table() . ' WHERE event_id=%d', $event_id ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
922 |
+
// Delete category relationship records.
|
923 |
+
$wpdb->query( $wpdb->prepare( 'DELETE FROM ' . my_calendar_category_relationships_table() . ' WHERE event_id=%d', $event_id ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
924 |
} else {
|
925 |
$event_in = absint( $_POST['event_instance'] );
|
926 |
+
$result = $wpdb->get_results( $wpdb->prepare( 'DELETE FROM ' . my_calendar_event_table() . ' WHERE occur_id=%d', $event_in ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
927 |
$instance = true;
|
928 |
}
|
929 |
if ( empty( $result ) || empty( $result[0]->event_id ) ) {
|
1665 |
foreach ( $locs as $loc ) {
|
1666 |
if ( is_object( $loc ) ) {
|
1667 |
$loc_name = strip_tags( stripslashes( $loc->location_label ), mc_strip_tags() );
|
1668 |
+
$selected = ( is_numeric( get_option( 'mc_default_location' ) ) && (int) get_option( 'mc_default_location' ) === (int) $loc->location_id ) ? ' selected="selected"' : '';
|
1669 |
if ( is_object( $data ) ) {
|
1670 |
+
$selected = '';
|
1671 |
if ( property_exists( $data, 'event_location' ) ) {
|
1672 |
$event_location = $data->event_location;
|
1673 |
} else {
|
1803 |
* @return string select options.
|
1804 |
*/
|
1805 |
function mc_selected_users( $selected = '', $group = 'authors' ) {
|
1806 |
+
$options = apply_filters( 'mc_custom_user_select', '', $selected, $group );
|
1807 |
+
if ( '' !== $options ) {
|
1808 |
+
return $options;
|
1809 |
+
}
|
1810 |
$selected = explode( ',', $selected );
|
1811 |
$users = mc_get_users( $group );
|
|
|
1812 |
foreach ( $users as $u ) {
|
1813 |
if ( in_array( $u->ID, $selected, true ) ) {
|
1814 |
$checked = ' selected="selected"';
|
2035 |
$limit = ( strpos( $limit, 'AND' ) === 0 ) ? $limit : 'AND ' . $limit;
|
2036 |
$events = $wpdb->get_results( $wpdb->prepare( 'SELECT DISTINCT SQL_CALC_FOUND_ROWS events.event_id FROM ' . my_calendar_table() . ' AS events JOIN ' . my_calendar_categories_table() . " AS categories WHERE events.event_category = categories.category_id $limit ORDER BY categories.category_name $sortbydirection " . 'LIMIT %d, %d', $query_limit, $items_per_page ) ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.PreparedSQL.NotPrepared
|
2037 |
}
|
|
|
2038 |
$found_rows = $wpdb->get_col( 'SELECT FOUND_ROWS();' );
|
2039 |
$items = $found_rows[0];
|
2040 |
$counts = get_option( 'mc_count_cache' );
|
2181 |
$categories = $wpdb->get_results( 'SELECT * FROM ' . my_calendar_categories_table() ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
2182 |
|
2183 |
foreach ( array_keys( $events ) as $key ) {
|
2184 |
+
$e =& $events[ $key ];
|
2185 |
+
$event = mc_get_first_event( $e->event_id );
|
2186 |
+
$invalid = false;
|
2187 |
if ( ! is_object( $event ) ) {
|
2188 |
+
$event = $wpdb->get_row( $wpdb->prepare( 'SELECT * FROM ' . my_calendar_table() . ' WHERE event_id = %d', $e->event_id ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
2189 |
+
$invalid = true;
|
2190 |
}
|
2191 |
$class = ( 'alternate' === $class ) ? 'even' : 'alternate';
|
2192 |
+
$class = ( $invalid ) ? $class . ' invalid' : $class;
|
2193 |
$pending = ( 0 === (int) $event->event_approved ) ? 'pending' : '';
|
2194 |
$trashed = ( 2 === (int) $event->event_approved ) ? 'trashed' : '';
|
2195 |
$author = ( 0 !== (int) $event->event_author ) ? get_userdata( $event->event_author ) : 'Public Submitter';
|
2203 |
$spam_label = '';
|
2204 |
}
|
2205 |
|
2206 |
+
$trash = ( '' !== $trashed ) ? ' - ' . __( 'Trash', 'my-calendar' ) : '';
|
2207 |
+
$draft = ( '' !== $pending ) ? ' - ' . __( 'Draft', 'my-calendar' ) : $trash;
|
2208 |
+
$invalid = ( $invalid ) ? ' - ' . __( 'Invalid Event', 'my-calendar' ) : $trash;
|
2209 |
+
$check = mc_test_occurrence_overlap( $event, true );
|
2210 |
+
$problem = ( '' !== $check ) ? 'problem' : '';
|
2211 |
+
$edit_url = admin_url( "admin.php?page=my-calendar&mode=edit&event_id=$event->event_id" );
|
2212 |
+
$copy_url = admin_url( "admin.php?page=my-calendar&mode=copy&event_id=$event->event_id" );
|
2213 |
+
if ( ! $invalid ) {
|
2214 |
+
$view_url = mc_get_details_link( $event );
|
2215 |
+
} else {
|
2216 |
+
$view_url = '';
|
2217 |
+
}
|
2218 |
$group_url = admin_url( "admin.php?page=my-calendar-groups&mode=edit&event_id=$event->event_id&group_id=$event->event_group_id" );
|
2219 |
$delete_url = admin_url( "admin.php?page=my-calendar-manage&mode=delete&event_id=$event->event_id" );
|
2220 |
$can_edit = mc_can_edit_event( $event );
|
2248 |
}
|
2249 |
}
|
2250 |
echo $draft;
|
2251 |
+
echo $invalid;
|
2252 |
?>
|
2253 |
</strong>
|
2254 |
|
2348 |
// Events *must* have a category.
|
2349 |
mc_update_event( 'event_category', 1, $event->event_id, '%d' );
|
2350 |
}
|
2351 |
+
$cat = mc_get_category_detail( $event->event_category, false );
|
2352 |
+
if ( ! is_object( $cat ) ) {
|
2353 |
+
$cat = (object) array(
|
2354 |
+
'category_color' => '',
|
2355 |
+
'category_id' => '',
|
2356 |
+
'category_name' => '',
|
2357 |
+
);
|
2358 |
+
}
|
2359 |
+
$color = $cat->category_color;
|
2360 |
$color = ( 0 !== strpos( $color, '#' ) ) ? '#' . $color : $color;
|
2361 |
$categories = mc_get_categories( $event );
|
2362 |
$cats = array();
|
2564 |
$event_longitude = '';
|
2565 |
$event_latitude = '';
|
2566 |
|
2567 |
+
if ( version_compare( PHP_VERSION, '7.4', '<' ) && get_magic_quotes_gpc() ) {
|
2568 |
$post = array_map( 'stripslashes_deep', $post );
|
2569 |
}
|
2570 |
if ( ! wp_verify_nonce( $post['event_nonce_name'], 'event_nonce' ) ) {
|
2653 |
$primary = $cats;
|
2654 |
$cats = array( $cats );
|
2655 |
}
|
2656 |
+
} else {
|
2657 |
+
$default = get_option( 'mc_default_category' );
|
2658 |
+
$default = ( ! $default ) ? mc_no_category_default( true ) : $default;
|
2659 |
+
$cats = array( $default );
|
2660 |
+
$primary = $default;
|
2661 |
}
|
2662 |
$event_author = ( isset( $post['event_author'] ) && is_numeric( $post['event_author'] ) ) ? $post['event_author'] : 0;
|
2663 |
$event_link = ! empty( $post['event_link'] ) ? trim( $post['event_link'] ) : '';
|
3073 |
|
3074 |
global $wpdb;
|
3075 |
$output = '';
|
3076 |
+
if ( true === $instance || '1' === $instance ) {
|
3077 |
$sql = 'SELECT * FROM ' . my_calendar_event_table() . ' WHERE occur_id=%d ORDER BY occur_begin ASC';
|
3078 |
} else {
|
3079 |
$sql = 'SELECT * FROM ' . my_calendar_event_table() . ' WHERE occur_event_id=%d ORDER BY occur_begin ASC';
|
3527 |
* @return boolean
|
3528 |
*/
|
3529 |
function mc_can_edit_event( $event = false ) {
|
3530 |
+
global $wpdb;
|
3531 |
if ( ! $event ) {
|
3532 |
|
3533 |
return false;
|
3548 |
$event_id = $event->event_id;
|
3549 |
$event_author = $event->event_author;
|
3550 |
} elseif ( is_int( $event ) ) {
|
3551 |
+
$event_id = $event;
|
3552 |
+
$event = mc_get_first_event( $event );
|
3553 |
+
if ( ! is_object( $event ) ) {
|
3554 |
+
$event = $wpdb->get_row( $wpdb->prepare( 'SELECT * FROM ' . my_calendar_table() . ' WHERE event_id=%d LIMIT 1', $event_id ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
3555 |
+
}
|
3556 |
$event_author = $event->event_author;
|
3557 |
} else {
|
3558 |
// What is the case where the event is neither an object, int, or falsey? Hmm.
|
my-calendar-group-manager.php
CHANGED
@@ -1150,11 +1150,15 @@ function mc_list_groups() {
|
|
1150 |
<td><?php echo ( is_object( $author ) ) ? $author->display_name : $author; ?></td>
|
1151 |
<?php
|
1152 |
$this_category = $event->event_category;
|
|
|
1153 |
foreach ( $categories as $key => $value ) {
|
1154 |
if ( $value->category_id === $this_category ) {
|
1155 |
$this_cat = $categories[ $key ];
|
1156 |
}
|
1157 |
}
|
|
|
|
|
|
|
1158 |
$background = strip_tags( ( strpos( $this_cat->category_color, '#' ) !== 0 ) ? '#' : '' ) . $this_cat->category_color;
|
1159 |
?>
|
1160 |
<td>
|
1150 |
<td><?php echo ( is_object( $author ) ) ? $author->display_name : $author; ?></td>
|
1151 |
<?php
|
1152 |
$this_category = $event->event_category;
|
1153 |
+
$this_cat = false;
|
1154 |
foreach ( $categories as $key => $value ) {
|
1155 |
if ( $value->category_id === $this_category ) {
|
1156 |
$this_cat = $categories[ $key ];
|
1157 |
}
|
1158 |
}
|
1159 |
+
if ( ! $this_cat ) {
|
1160 |
+
$this_cat = mc_get_category( $event->event_category );
|
1161 |
+
}
|
1162 |
$background = strip_tags( ( strpos( $this_cat->category_color, '#' ) !== 0 ) ? '#' : '' ) . $this_cat->category_color;
|
1163 |
?>
|
1164 |
<td>
|
my-calendar-location-manager.php
CHANGED
@@ -46,11 +46,33 @@ function my_calendar_manage_locations() {
|
|
46 |
</div>
|
47 |
</div>
|
48 |
</div>
|
49 |
-
<?php
|
|
|
|
|
|
|
50 |
</div>
|
51 |
<?php
|
52 |
}
|
53 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
54 |
/**
|
55 |
* Mass delete locations.
|
56 |
*
|
@@ -232,7 +254,18 @@ function mc_manage_locations() {
|
|
232 |
<input type="checkbox" value="<?php echo $location->location_id; ?>" name="mass_edit[]" id="mc<?php echo $location->location_id; ?>"/>
|
233 |
<label for="mc<?php echo $location->location_id; ?>"><?php echo $location->location_id; ?></label>
|
234 |
</th>
|
235 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
236 |
<td><?php echo esc_html( $location->location_city ); ?></td>
|
237 |
<td><?php echo esc_html( $location->location_state ); ?></td>
|
238 |
<td>
|
46 |
</div>
|
47 |
</div>
|
48 |
</div>
|
49 |
+
<?php
|
50 |
+
$default = array( __( 'Default Location', 'my-calendar' ) => mc_default_location() );
|
51 |
+
mc_show_sidebar( '', $default );
|
52 |
+
?>
|
53 |
</div>
|
54 |
<?php
|
55 |
}
|
56 |
|
57 |
+
/**
|
58 |
+
* Fetch default location data.
|
59 |
+
*
|
60 |
+
* @return string
|
61 |
+
*/
|
62 |
+
function mc_default_location() {
|
63 |
+
$default = get_option( 'mc_default_location' );
|
64 |
+
if ( $default ) {
|
65 |
+
$location = mc_get_location( $default );
|
66 |
+
$output = mc_hcard( $location, 'true', false, 'location' );
|
67 |
+
$output .= '<p><a href="' . admin_url( "admin.php?page=my-calendar-locations&mode=edit&location_id=$default" ) . '">' . __( 'Edit Default Location', 'my-calendar' ) . '</a></p>';
|
68 |
+
}
|
69 |
+
if ( ! $output ) {
|
70 |
+
$output = '<p>' . __( 'No default location selected.', 'my-calendar' ) . '</p>';
|
71 |
+
}
|
72 |
+
|
73 |
+
return $output;
|
74 |
+
}
|
75 |
+
|
76 |
/**
|
77 |
* Mass delete locations.
|
78 |
*
|
254 |
<input type="checkbox" value="<?php echo $location->location_id; ?>" name="mass_edit[]" id="mc<?php echo $location->location_id; ?>"/>
|
255 |
<label for="mc<?php echo $location->location_id; ?>"><?php echo $location->location_id; ?></label>
|
256 |
</th>
|
257 |
+
<?php
|
258 |
+
$default = '';
|
259 |
+
if ( (int) get_option( 'mc_default_location' ) === (int) $location->location_id ) {
|
260 |
+
$default = '<span class="mc_default"><span class="dashicons dashicons-location" aria-hidden="true"></span>' . __( 'Default Location', 'my-calendar' ) . '</span>';
|
261 |
+
}
|
262 |
+
?>
|
263 |
+
<td>
|
264 |
+
<?php
|
265 |
+
echo $default;
|
266 |
+
echo mc_hcard( $location, 'true', 'false', 'location' );
|
267 |
+
?>
|
268 |
+
</td>
|
269 |
<td><?php echo esc_html( $location->location_city ); ?></td>
|
270 |
<td><?php echo esc_html( $location->location_state ); ?></td>
|
271 |
<td>
|
my-calendar-locations.php
CHANGED
@@ -298,6 +298,9 @@ function my_calendar_add_locations() {
|
|
298 |
);
|
299 |
|
300 |
$results = mc_insert_location( $add );
|
|
|
|
|
|
|
301 |
do_action( 'mc_save_location', $results, $add, $_POST );
|
302 |
if ( $results ) {
|
303 |
mc_show_notice( __( 'Location added successfully', 'my-calendar' ) );
|
@@ -309,6 +312,10 @@ function my_calendar_add_locations() {
|
|
309 |
do_action( 'mc_delete_location', $results, (int) $_GET['location_id'] );
|
310 |
if ( $results ) {
|
311 |
mc_show_notice( __( 'Location deleted successfully', 'my-calendar' ) );
|
|
|
|
|
|
|
|
|
312 |
} else {
|
313 |
mc_show_error( __( 'Location could not be deleted', 'my-calendar' ) );
|
314 |
}
|
@@ -334,7 +341,10 @@ function my_calendar_add_locations() {
|
|
334 |
'location_access' => isset( $_POST['location_access'] ) ? serialize( $_POST['location_access'] ) : '',
|
335 |
);
|
336 |
|
337 |
-
$where
|
|
|
|
|
|
|
338 |
$results = mc_modify_location( $update, $where );
|
339 |
|
340 |
do_action( 'mc_modify_location', $where, $update, $_POST );
|
@@ -580,8 +590,14 @@ function mc_locations_fields( $has_data, $data, $context = 'location' ) {
|
|
580 |
if ( current_user_can( 'mc_edit_locations' ) && 'event' === $context ) {
|
581 |
$return .= '<p class="checkboxes"><input type="checkbox" value="on" name="mc_copy_location" id="mc_copy_location" /> <label for="mc_copy_location">' . __( 'Copy this location into the locations table', 'my-calendar' ) . '</label></p>';
|
582 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
583 |
$return .= '
|
584 |
-
<p
|
585 |
<label for="e_label">' . __( 'Name of Location (e.g. <em>Joe\'s Bar and Grill</em>)', 'my-calendar' ) . '</label>';
|
586 |
$cur_label = ( ! empty( $data ) ) ? ( stripslashes( $data->{$context . '_label'} ) ) : '';
|
587 |
if ( mc_controlled_field( 'label' ) ) {
|
@@ -988,7 +1004,7 @@ function mc_get_locations( $args ) {
|
|
988 |
// Prevent invalid order columns.
|
989 |
$orderby = 'location_label';
|
990 |
}
|
991 |
-
$results = $wpdb->get_results( $wpdb->prepare( 'SELECT location_id,location_label FROM ' . my_calendar_locations_table() . ' WHERE
|
992 |
|
993 |
return apply_filters( 'mc_filter_results', $results, $args );
|
994 |
}
|
298 |
);
|
299 |
|
300 |
$results = mc_insert_location( $add );
|
301 |
+
if ( isset( $_POST['mc_default_location'] ) && $results ) {
|
302 |
+
update_option( 'mc_default_location', (int) $results );
|
303 |
+
}
|
304 |
do_action( 'mc_save_location', $results, $add, $_POST );
|
305 |
if ( $results ) {
|
306 |
mc_show_notice( __( 'Location added successfully', 'my-calendar' ) );
|
312 |
do_action( 'mc_delete_location', $results, (int) $_GET['location_id'] );
|
313 |
if ( $results ) {
|
314 |
mc_show_notice( __( 'Location deleted successfully', 'my-calendar' ) );
|
315 |
+
$default_location = get_option( 'mc_default_location', false );
|
316 |
+
if ( (int) $default_location === (int) $_GET['location_id'] ) {
|
317 |
+
delete_option( 'mc_default_location' );
|
318 |
+
}
|
319 |
} else {
|
320 |
mc_show_error( __( 'Location could not be deleted', 'my-calendar' ) );
|
321 |
}
|
341 |
'location_access' => isset( $_POST['location_access'] ) ? serialize( $_POST['location_access'] ) : '',
|
342 |
);
|
343 |
|
344 |
+
$where = array( 'location_id' => (int) $_POST['location_id'] );
|
345 |
+
if ( isset( $_POST['mc_default_location'] ) ) {
|
346 |
+
update_option( 'mc_default_location', (int) $_POST['location_id'] );
|
347 |
+
}
|
348 |
$results = mc_modify_location( $update, $where );
|
349 |
|
350 |
do_action( 'mc_modify_location', $where, $update, $_POST );
|
590 |
if ( current_user_can( 'mc_edit_locations' ) && 'event' === $context ) {
|
591 |
$return .= '<p class="checkboxes"><input type="checkbox" value="on" name="mc_copy_location" id="mc_copy_location" /> <label for="mc_copy_location">' . __( 'Copy this location into the locations table', 'my-calendar' ) . '</label></p>';
|
592 |
}
|
593 |
+
if ( current_user_can( 'mc_edit_settings' ) && isset( $_GET['page'] ) && 'my-calendar-locations' === $_GET['page'] ) {
|
594 |
+
$checked = ( isset( $_GET['location_id'] ) && (int) get_option( 'mc_default_location' ) === (int) $_GET['location_id'] ) ? 'checked="checked"' : '';
|
595 |
+
$return .= '<p class="checkbox">';
|
596 |
+
$return .= '<input type="checkbox" name="mc_default_location" id="mc_default_location"' . $checked . ' /> <label for="mc_default_location">' . __( 'Default Location', 'my-calendar' ) . '</label>';
|
597 |
+
$return .= '</p>';
|
598 |
+
}
|
599 |
$return .= '
|
600 |
+
<p>
|
601 |
<label for="e_label">' . __( 'Name of Location (e.g. <em>Joe\'s Bar and Grill</em>)', 'my-calendar' ) . '</label>';
|
602 |
$cur_label = ( ! empty( $data ) ) ? ( stripslashes( $data->{$context . '_label'} ) ) : '';
|
603 |
if ( mc_controlled_field( 'label' ) ) {
|
1004 |
// Prevent invalid order columns.
|
1005 |
$orderby = 'location_label';
|
1006 |
}
|
1007 |
+
$results = $wpdb->get_results( $wpdb->prepare( 'SELECT location_id,location_label FROM ' . my_calendar_locations_table() . ' WHERE ' . esc_sql( $where ) . ' = %s ORDER BY ' . esc_sql( $orderby ) . ' ' . esc_sql( $order ), $is ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
|
1008 |
|
1009 |
return apply_filters( 'mc_filter_results', $results, $args );
|
1010 |
}
|
my-calendar-output.php
CHANGED
@@ -97,7 +97,8 @@ function mc_time_html( $e, $type ) {
|
|
97 |
}
|
98 |
$time_content .= apply_filters( 'mcs_end_time_block', '', $e );
|
99 |
// Generate date/time meta data.
|
100 |
-
$meta =
|
|
|
101 |
$meta .= '<meta itemprop="duration" content="' . mc_duration( $e ) . '"/>';
|
102 |
|
103 |
$time = "
|
@@ -266,6 +267,7 @@ function my_calendar_draw_event( $event, $type = 'calendar', $process_date, $tim
|
|
266 |
$tickets = '';
|
267 |
$data = mc_create_tags( $event, $id );
|
268 |
$details = '';
|
|
|
269 |
if ( mc_show_details( $time, $type ) ) {
|
270 |
$details = apply_filters( 'mc_custom_template', false, $data, $event, $type, $process_date, $time, $template );
|
271 |
$template = apply_filters( 'mc_use_custom_template', $template, $data, $event, $type, $process_date, $time );
|
@@ -318,7 +320,12 @@ function my_calendar_draw_event( $event, $type = 'calendar', $process_date, $tim
|
|
318 |
$event_title = str_replace( ': ', '', $event_title );
|
319 |
}
|
320 |
$event_title = ( '' === $event_title ) ? $data['title'] : strip_tags( $event_title, mc_strip_tags() );
|
321 |
-
|
|
|
|
|
|
|
|
|
|
|
322 |
|
323 |
if ( ( ( strpos( $event_title, 'href' ) === false ) && 'mini' !== $type && 'list' !== $type ) && ! $no_link ) {
|
324 |
if ( 'true' === $open_uri ) {
|
@@ -334,15 +341,18 @@ function my_calendar_draw_event( $event, $type = 'calendar', $process_date, $tim
|
|
334 |
$balance = '';
|
335 |
}
|
336 |
|
337 |
-
$group_class
|
338 |
-
$hlevel
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
|
|
|
|
|
|
346 |
$close_button = mc_close_button( "$uid-$type-details-$id" );
|
347 |
|
348 |
if ( mc_show_details( $time, $type ) ) {
|
@@ -1888,7 +1898,7 @@ function my_calendar( $args ) {
|
|
1888 |
}
|
1889 |
$events = ( isset( $event_array[ $date_is ] ) ) ? $event_array[ $date_is ] : array();
|
1890 |
$week_header = date_i18n( $week_format, $start );
|
1891 |
-
$thisday_heading = ( 'week' === $params['time'] ) ? "<small>$week_header</small>" : mc_date( 'j', $start, false );
|
1892 |
|
1893 |
// Generate event classes & attributes.
|
1894 |
$events_class = mc_events_class( $events, $date_is );
|
97 |
}
|
98 |
$time_content .= apply_filters( 'mcs_end_time_block', '', $e );
|
99 |
// Generate date/time meta data.
|
100 |
+
$meta = "<meta itemprop='startDate' content='" . $start . 'T' . $e->event_time . "' />";
|
101 |
+
$meta .= ( 0 === (int) $e->event_hide_end ) ? "<meta itemprop='endDate' content='" . $end . 'T' . $e->event_endtime . "'/>" : '';
|
102 |
$meta .= '<meta itemprop="duration" content="' . mc_duration( $e ) . '"/>';
|
103 |
|
104 |
$time = "
|
267 |
$tickets = '';
|
268 |
$data = mc_create_tags( $event, $id );
|
269 |
$details = '';
|
270 |
+
|
271 |
if ( mc_show_details( $time, $type ) ) {
|
272 |
$details = apply_filters( 'mc_custom_template', false, $data, $event, $type, $process_date, $time, $template );
|
273 |
$template = apply_filters( 'mc_use_custom_template', $template, $data, $event, $type, $process_date, $time );
|
320 |
$event_title = str_replace( ': ', '', $event_title );
|
321 |
}
|
322 |
$event_title = ( '' === $event_title ) ? $data['title'] : strip_tags( $event_title, mc_strip_tags() );
|
323 |
+
if ( 'single' === $type ) {
|
324 |
+
$event_title = apply_filters( 'mc_single_event_title', $event_title, $event );
|
325 |
+
} else {
|
326 |
+
$event_title = apply_filters( 'mc_event_title', $event_title, $event, $data['title'], $image );
|
327 |
+
}
|
328 |
+
$no_link = apply_filters( 'mc_disable_link', false, $data );
|
329 |
|
330 |
if ( ( ( strpos( $event_title, 'href' ) === false ) && 'mini' !== $type && 'list' !== $type ) && ! $no_link ) {
|
331 |
if ( 'true' === $open_uri ) {
|
341 |
$balance = '';
|
342 |
}
|
343 |
|
344 |
+
$group_class = ( 1 === (int) $event->event_span ) ? ' multidate group' . $event->event_group_id : '';
|
345 |
+
$hlevel = apply_filters( 'mc_heading_level_table', 'h3', $type, $time, $template );
|
346 |
+
// Set up .summary - required once per page for structured data. Should only be added in cases where heading & anchor are removed.
|
347 |
+
if ( 'single' === $type ) {
|
348 |
+
$title = ( ! is_singular( 'mc-events' ) ) ? " <h2 class='event-title summary'>$image $event_title</h2>\n" : ' <span class="summary screen-reader-text">' . strip_tags( $event_title ) . '</span>';
|
349 |
+
} elseif ( 'list' !== $type ) {
|
350 |
+
$inner_heading = apply_filters( 'mc_heading_inner_title', $wrap . $image . trim( $event_title ) . $balance, $event_title, $event );
|
351 |
+
$title = " <$hlevel class='event-title summary$group_class' id='mc_$event->occur_id-title-$id'>$inner_heading</$hlevel>\n";
|
352 |
+
} else {
|
353 |
+
$title = '';
|
354 |
+
}
|
355 |
+
$header .= ( false === stripos( $title, 'summary' ) ) ? ' <span class="summary screen-reader-text">' . strip_tags( $event_title ) . '</span>' : $title;
|
356 |
$close_button = mc_close_button( "$uid-$type-details-$id" );
|
357 |
|
358 |
if ( mc_show_details( $time, $type ) ) {
|
1898 |
}
|
1899 |
$events = ( isset( $event_array[ $date_is ] ) ) ? $event_array[ $date_is ] : array();
|
1900 |
$week_header = date_i18n( $week_format, $start );
|
1901 |
+
$thisday_heading = ( 'week' === $params['time'] ) ? "<small>$week_header</small>" : mc_date( apply_filters( 'mc_grid_date', 'j', $params ), $start, false );
|
1902 |
|
1903 |
// Generate event classes & attributes.
|
1904 |
$events_class = mc_events_class( $events, $date_is );
|
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.2.
|
21 |
*/
|
22 |
|
23 |
/*
|
@@ -42,7 +42,7 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
42 |
}
|
43 |
|
44 |
global $mc_version, $wpdb;
|
45 |
-
$mc_version = '3.2.
|
46 |
|
47 |
define( 'MC_DEBUG', false );
|
48 |
|
17 |
* License: GPL-2.0+
|
18 |
* License URI: http://www.gnu.org/license/gpl-2.0.txt
|
19 |
* Domain Path: lang
|
20 |
+
* Version: 3.2.8
|
21 |
*/
|
22 |
|
23 |
/*
|
42 |
}
|
43 |
|
44 |
global $mc_version, $wpdb;
|
45 |
+
$mc_version = '3.2.8';
|
46 |
|
47 |
define( 'MC_DEBUG', false );
|
48 |
|
readme.txt
CHANGED
@@ -3,9 +3,9 @@ Contributors: joedolson
|
|
3 |
Donate link: http://www.joedolson.com/donate/
|
4 |
Tags: calendar, dates, times, event, events, scheduling, schedule, event manager, event calendar, class, concert, venue, location, box office, tickets, registration
|
5 |
Requires at least: 4.4
|
6 |
-
Tested up to: 5.
|
7 |
Requires PHP: 5.6
|
8 |
-
Stable tag: 3.2.
|
9 |
Text domain: my-calendar
|
10 |
License: GPLv2 or later
|
11 |
|
@@ -83,6 +83,27 @@ Translating my plug-ins is always appreciated. Visit <a href="https://translate.
|
|
83 |
|
84 |
== Changelog ==
|
85 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
86 |
= 3.2.5 =
|
87 |
|
88 |
* Bug fix: CSV exported text fields contained newline characters.
|
3 |
Donate link: http://www.joedolson.com/donate/
|
4 |
Tags: calendar, dates, times, event, events, scheduling, schedule, event manager, event calendar, class, concert, venue, location, box office, tickets, registration
|
5 |
Requires at least: 4.4
|
6 |
+
Tested up to: 5.5
|
7 |
Requires PHP: 5.6
|
8 |
+
Stable tag: 3.2.8
|
9 |
Text domain: my-calendar
|
10 |
License: GPLv2 or later
|
11 |
|
83 |
|
84 |
== Changelog ==
|
85 |
|
86 |
+
= 3.2.8 =
|
87 |
+
|
88 |
+
* Bug fix: Extraneous screen-reader-text summary generated in event views.
|
89 |
+
* Bug fix: Fixes to missing parameters in Schema.org microdata.
|
90 |
+
* Bug fix: Incorrect type comparison caused custom templates not to render in single event view.
|
91 |
+
* New feature: Default location.
|
92 |
+
|
93 |
+
= 3.2.7 =
|
94 |
+
|
95 |
+
* Bug fix: Prevent events from being created without categories.
|
96 |
+
* Bug fix: Ensure category relationships are deleted when related events are deleted.
|
97 |
+
* Add handling for seeing & managing events that are invalid.
|
98 |
+
* Add styles for invalid rows.
|
99 |
+
|
100 |
+
= 3.2.6 =
|
101 |
+
|
102 |
+
* Added filter to change date format on calendar grid.
|
103 |
+
* New filter for modifying user selection output.
|
104 |
+
* Bug fix: only check for get_magic_quotes_gpc() if below PHP 7.4
|
105 |
+
* Bug fix: invalid query in mc_get_locations() if arguments passed as array.
|
106 |
+
|
107 |
= 3.2.5 =
|
108 |
|
109 |
* Bug fix: CSV exported text fields contained newline characters.
|