My Calendar - Version 3.1.0

Version Description

  • Add feature (by Josef Fllman): Print & export view for search results.
  • New filter: mcs_check_conflicts (impacts Pro only)
  • Bug fix: Fix issue causing duplication in some views.
  • Bug fix: Time format should be filtered in initial edit view.
  • Bug fix: Category relationships not retained when Group editing applied.
  • Bug fix: aria-describedby ID mismatch.
Download this release

Release Info

Developer joedolson
Plugin Icon 128x128 My Calendar
Version 3.1.0
Comparing to
See all releases

Code changes from version 3.0.18 to 3.1.0

css/mc-print.css CHANGED
@@ -4,7 +4,7 @@
4
size: landscape;
5
}
6
7
- .my-calendar-header, .mc_bottomnav, h3 img, .mc-toggle, .mc_edit_links, #mc-export, .longdesc, .shortdesc, .mc-print, form, .screen-reader-text {
8
display: none;
9
}
10
@@ -40,10 +40,20 @@ td {
40
border-bottom: 1px solid #ddd;
41
}
42
43
- .details * {
44
display: none;
45
}
46
47
h3 {
48
font-size: 14px;
49
margin: 2px 0 5px;
4
size: landscape;
5
}
6
7
+ .my-calendar-header, .mc_bottomnav, h3 img, .mc-toggle, .mc_edit_links, #mc-export, .longdesc, .shortdesc, .mc-print, form, .screen-reader-text, .sharing {
8
display: none;
9
}
10
40
border-bottom: 1px solid #ddd;
41
}
42
43
+ .calendar .details * {
44
display: none;
45
}
46
47
+ button.mc-text-button {
48
+ border: 0;
49
+ color: inherit;
50
+ background-color: transparent;
51
+ text-decoration: none;
52
+ font-size: 16px;
53
+ font-weight: 700;
54
+ padding: 0 0 .5em
55
+ }
56
+
57
h3 {
58
font-size: 14px;
59
margin: 2px 0 5px;
js/mc-datepicker.js CHANGED
@@ -44,14 +44,14 @@ if ( typeof(mc_months) !== "undefined" ) {
44
/**
45
* In admin, date needs to be converted to UTC
46
*/
47
- function convertDateToUTC(date) {
48
- return new Date(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds());
49
}
50
-
51
});
52
53
} else {
54
- jQuery(document).ready(function ($) {
55
var datepicked = $( '.mc-datepicker' ).attr( 'data-value' );
56
$( '.mc-datepicker' ).val( datepicked );
57
});
44
/**
45
* In admin, date needs to be converted to UTC
46
*/
47
+ function convertDateToUTC(date) {
48
+ return new Date(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds());
49
}
50
+
51
});
52
53
} else {
54
+ jQuery(document).ready(function ($) {
55
var datepicked = $( '.mc-datepicker' ).attr( 'data-value' );
56
$( '.mc-datepicker' ).val( datepicked );
57
});
my-calendar-api.php CHANGED
@@ -98,6 +98,7 @@ function mc_api_format_csv( $data ) {
98
foreach ( $val as $v ) {
99
$values = get_object_vars( $v );
100
unset( $values['categories'] );
101
if ( ! $keyed ) {
102
$keys = array_keys( $values );
103
fputcsv( $stream, $keys );
@@ -446,8 +447,13 @@ function my_calendar_ical() {
446
'site' => $site,
447
);
448
449
- $args = apply_filters( 'mc_ical_attributes', $args, $_GET );
450
- $data = my_calendar_events( $args );
451
$events = mc_flatten_array( $data );
452
453
if ( is_array( $events ) && ! empty( $events ) ) {
98
foreach ( $val as $v ) {
99
$values = get_object_vars( $v );
100
unset( $values['categories'] );
101
+ unset( $values['location'] );
102
if ( ! $keyed ) {
103
$keys = array_keys( $values );
104
fputcsv( $stream, $keys );
447
'site' => $site,
448
);
449
450
+ $args = apply_filters( 'mc_ical_attributes', $args, $_GET );
451
+ // Load search result from $_SESSION array.
452
+ if ( isset( $_GET['searched'] ) && $_GET['searched'] && isset( $_SESSION['MC_SEARCH_RESULT'] ) ) {
453
+ $data = mc_get_searched_events();
454
+ } else {
455
+ $data = my_calendar_events( $args );
456
+ }
457
$events = mc_flatten_array( $data );
458
459
if ( is_array( $events ) && ! empty( $events ) ) {
my-calendar-categories.php CHANGED
@@ -922,6 +922,9 @@ function mc_get_categories( $event, $ids = true ) {
922
function mc_categories_html( $results, $primary ) {
923
if ( $results ) {
924
foreach ( $results as $result ) {
925
$icon = mc_category_icon( $result );
926
$return[] = $icon . $result->category_name;
927
}
922
function mc_categories_html( $results, $primary ) {
923
if ( $results ) {
924
foreach ( $results as $result ) {
925
+ if ( ! is_object( $result ) ) {
926
+ $result = (object) $result;
927
+ }
928
$icon = mc_category_icon( $result );
929
$return[] = $icon . $result->category_name;
930
}
my-calendar-event-manager.php CHANGED
@@ -2722,6 +2722,7 @@ function mc_check_data( $action, $post, $i ) {
2722
}
2723
if ( isset( $post['mcs_check_conflicts'] ) ) {
2724
$conflicts = mcs_check_conflicts( $begin, $time, $end, $endtime, $event_label );
2725
if ( $conflicts ) {
2726
$conflict_id = $conflicts[0]->occur_id;
2727
$conflict_ev = mc_get_event( $conflict_id );
@@ -3133,8 +3134,8 @@ function mc_standard_datetime_input( $form, $has_data, $data, $instance, $contex
3133
$event_end = '';
3134
}
3135
}
3136
- $starttime = ( mc_is_all_day( $data ) ) ? '' : date( 'h:i A', mc_strtotime( $data->event_time ) );
3137
- $endtime = ( mc_is_all_day( $data ) ) ? '' : date( 'h:i A', mc_strtotime( $data->event_endtime ) );
3138
} else {
3139
$event_begin = date( 'Y-m-d' );
3140
$event_end = '';
2722
}
2723
if ( isset( $post['mcs_check_conflicts'] ) ) {
2724
$conflicts = mcs_check_conflicts( $begin, $time, $end, $endtime, $event_label );
2725
+ $conflicts = apply_filters( 'mcs_check_conflicts', $conflicts, $post );
2726
if ( $conflicts ) {
2727
$conflict_id = $conflicts[0]->occur_id;
2728
$conflict_ev = mc_get_event( $conflict_id );
3134
$event_end = '';
3135
}
3136
}
3137
+ $starttime = ( mc_is_all_day( $data ) ) ? '' : date( apply_filters( 'mc_time_format', 'h:i A' ), mc_strtotime( $data->event_time ) );
3138
+ $endtime = ( mc_is_all_day( $data ) ) ? '' : date( apply_filters( 'mc_time_format', 'h:i A' ), mc_strtotime( $data->event_endtime ) );
3139
} else {
3140
$event_begin = date( 'Y-m-d' );
3141
$event_end = '';
my-calendar-events.php CHANGED
@@ -274,7 +274,7 @@ function mc_get_all_events( $args ) {
274
} else {
275
$event->categories = $fetched[ $object_id ];
276
}
277
- $arr_events[] = mc_event_object( $event );
278
}
279
280
return $arr_events;
@@ -421,7 +421,7 @@ function mc_get_search_results( $search ) {
421
}
422
}
423
424
- return $event_array;
425
}
426
427
/**
274
} else {
275
$event->categories = $fetched[ $object_id ];
276
}
277
+ $arr_events[ $key ] = mc_event_object( $event );
278
}
279
280
return $arr_events;
421
}
422
}
423
424
+ return apply_filters( 'mc_searched_events', $event_array );
425
}
426
427
/**
my-calendar-group-manager.php CHANGED
@@ -825,6 +825,7 @@ function mc_check_group_data( $action, $post ) {
825
}
826
} else {
827
$primary = $post['event_category'];
828
}
829
}
830
825
}
826
} else {
827
$primary = $post['event_category'];
828
+ $cats = array( $cats );
829
}
830
}
831
my-calendar-output.php CHANGED
@@ -36,61 +36,66 @@ function mc_get_template( $template ) {
36
/**
37
* HTML output for event time
38
*
39
- * @param object $event Current event.
40
* @param string $type Type of view.
41
*
42
* @return string HTML output.
43
*/
44
- function mc_time_html( $event, $type ) {
45
$orig_format = get_option( 'mc_date_format' );
46
$date_format = ( '' != $orig_format ) ? $orig_format : get_option( 'date_format' );
47
- if ( $event->event_end != $event->event_begin ) {
48
$mult_format = get_option( 'mc_multidate_format' );
49
$mult_format = ( '' != $mult_format ) ? $mult_format : 'F j-%d, Y';
50
- $date_format = str_replace( '%d', date( 'j', strtotime( $event->occur_end ) ), $mult_format );
51
}
52
// If this event crosses years or months, use original date format & show both dates.
53
- if ( date( 'Y', strtotime( $event->occur_end ) ) != date( 'Y', strtotime( $event->occur_begin ) ) || date( 'm', strtotime( $event->occur_end ) ) != date( 'm', strtotime( $event->occur_begin ) ) ) {
54
- $current = date_i18n( $orig_format, strtotime( $event->occur_begin ) ) . ' – ' . date_i18n( $orig_format, strtotime( $event->occur_end ) );
55
} else {
56
- $current = date_i18n( $date_format, strtotime( $event->occur_begin ) );
57
- }
58
- $id_start = date( 'Y-m-d', strtotime( $event->occur_begin ) );
59
- $id_end = date( 'Y-m-d', strtotime( $event->occur_end ) );
60
- $event_date = ( 'list' == $type ) ? '' : "<span class='mc-event-date dtstart' itemprop='startDate' title='" . $id_start . 'T' . $event->event_time . "' content='" . $id_start . 'T' . $event->event_time . "'>$current</span>";
61
- $time_format = get_option( 'mc_time_format' );
62
-
63
- $time = "<div class='time-block'>";
64
- $time .= "<p>$event_date ";
65
- if ( '00:00:00' != $event->event_time && '' != $event->event_time ) {
66
- $time .= "\n
67
<span class='event-time dtstart'>
68
- <time class='value-title' datetime='" . $id_start . 'T' . $event->event_time . "' title='" . $id_start . 'T' . $event->event_time . "'>" .
69
- date_i18n( $time_format, strtotime( $event->event_time ) ) . '
70
</time>
71
</span>';
72
- if ( 0 == $event->event_hide_end ) {
73
- if ( '' != $event->event_endtime && $event->event_endtime != $event->event_time ) {
74
- $time .= "
75
- <span class='time-separator'> &ndash; </span>
76
<span class='end-time dtend'>
77
- <time class='value-title' datetime='" . $id_end . 'T' . $event->event_endtime . "' title='" . $id_end . 'T' . $event->event_endtime . "'>" . date_i18n( $time_format, strtotime( $event->event_endtime ) ) . '
78
</time>
79
</span>';
80
}
81
}
82
} else {
83
- $notime = mc_notime_label( $event );
84
- $time .= "<span class='event-time'>";
85
- $time .= ( 'N/A' == $notime ) ? "<abbr title='" . __( 'Not Applicable', 'my-calendar' ) . "'>" . __( 'N/A', 'my-calendar' ) . "</abbr>\n" : esc_html( $notime );
86
- $time .= '</span></p>';
87
}
88
- $time .= apply_filters( 'mcs_end_time_block', '', $event );
89
- $time .= ( 0 == $event->event_hide_end ) ? "<meta itemprop='endDate' content='" . $id_start . 'T' . $event->event_endtime . "'/>" : '';
90
- $time .= '<meta itemprop="duration" content="' . mc_duration( $event ) . '"/>';
91
- $time .= '</div>';
92
93
- return apply_filters( 'mcs_time_block', $time, $event );
94
}
95
96
/**
@@ -311,7 +316,7 @@ function my_calendar_draw_event( $event, $type = 'calendar', $process_date, $tim
311
$group_class = ( 1 == $event->event_span ) ? ' multidate group' . $event->event_group_id : '';
312
$hlevel = apply_filters( 'mc_heading_level_table', 'h3', $type, $time, $template );
313
$inner_heading = apply_filters( 'mc_heading_inner_title', $wrap . $image . trim( $event_title ) . $balance, $event_title, $event );
314
- $header .= ( 'single' != $type && 'list' != $type ) ? "<$hlevel class='event-title summary$group_class' id='$uid-title'>$inner_heading</$hlevel>\n" : '';
315
$event_title = ( 'single' == $type ) ? apply_filters( 'mc_single_event_title', $event_title, $event ) : $event_title;
316
$title = ( 'single' == $type && ! is_singular( 'mc-events' ) ) ? "<h2 class='event-title summary'>$image $event_title</h2>\n" : '<span class="summary screen-reader-text">' . $event_title . '</span>';
317
$title = apply_filters( 'mc_event_title', $title, $event, $event_title, $image );
@@ -330,7 +335,7 @@ function my_calendar_draw_event( $event, $type = 'calendar', $process_date, $tim
330
$time_html = mc_time_html( $event, $type );
331
if ( 'list' == $type ) {
332
$hlevel = apply_filters( 'mc_heading_level_list', 'h3', $type, $time, $template );
333
- $list_title = "<$hlevel class='event-title summary' id='$uid-title'>$image" . $event_title . "</$hlevel>\n";
334
}
335
if ( 'true' == $display_author ) {
336
if ( 0 != $event->event_author ) {
@@ -411,7 +416,7 @@ function my_calendar_draw_event( $event, $type = 'calendar', $process_date, $tim
411
$link_text = mc_draw_template( $data, $link_template );
412
$link = "
413
<p>
414
- <a href='" . esc_url( $event_link ) . "' class='$external_class' aria-describedby='$uid-title'>" . $link_text . '</a>
415
</p>';
416
}
417
@@ -441,7 +446,7 @@ function my_calendar_draw_event( $event, $type = 'calendar', $process_date, $tim
441
}
442
443
$img_class = ( '' != $img ) ? ' has-image' : ' no-image';
444
- $container = "<div id='$uid-$type-details' class='details$img_class' role='alert' aria-labelledby='$uid-title' itemscope itemtype='http://schema.org/Event'>\n";
445
$container .= "<meta itemprop='name' content='" . strip_tags( $event->event_title ) . "' />";
446
$container = apply_filters( 'mc_before_event', $container, $event, $type, $time );
447
$details = $header . $container . apply_filters( 'mc_inner_content', $details, $event, $type, $time );
@@ -581,6 +586,9 @@ function mc_event_classes( $event, $uid, $type ) {
581
$categories = mc_get_categories( $event, false );
582
}
583
foreach ( $categories as $category ) {
584
$classes[] = 'mc_rel_' . sanitize_html_class( $category->category_name );
585
}
586
@@ -1050,8 +1058,9 @@ function mc_list_titles( $events ) {
1050
* @return string HTML output
1051
*/
1052
function mc_search_results( $query ) {
1053
- $before = apply_filters( 'mc_past_search_results', 0, 'basic' );
1054
- $after = apply_filters( 'mc_future_search_results', 10, 'basic' ); // Return only future events, nearest 10.
1055
if ( is_string( $query ) ) {
1056
$search = mc_prepare_search_query( $query );
1057
$term = $query;
@@ -1068,7 +1077,8 @@ function mc_search_results( $query ) {
1068
$template = '<strong>{date}</strong> {title} {details}';
1069
$template = apply_filters( 'mc_search_template', $template );
1070
// No filters parameter prevents infinite looping on the_content filters.
1071
- $output = mc_produce_upcoming_events( $event_array, $template, 'list', 'ASC', 0, $before, $after, 'yes', 'nofilters' );
1072
} else {
1073
$output = apply_filters( 'mc_search_no_results', "<li class='no-results'>" . __( 'Sorry, your search produced no results.', 'my-calendar' ) . '</li>' );
1074
}
@@ -1076,7 +1086,7 @@ function mc_search_results( $query ) {
1076
$header = apply_filters( 'mc_search_before', '<ol class="mc-search-results">', $term );
1077
$footer = apply_filters( 'mc_search_after', '</ol>', $term );
1078
1079
- return $header . $output . $footer;
1080
}
1081
1082
add_filter( 'the_title', 'mc_search_results_title', 10, 2 );
@@ -1129,6 +1139,71 @@ function mc_show_search_results( $content ) {
1129
}
1130
}
1131
1132
add_action( 'template_redirect', 'mc_hidden_event' );
1133
/**
1134
* If an event is hidden from the current user, redirect to 404.
@@ -1169,6 +1244,7 @@ function mc_hidden_event() {
1169
$uri = mc_get_uri();
1170
if ( ! $is_404 ) {
1171
wp_safe_redirect( $uri );
1172
} else {
1173
global $wp_query;
1174
$wp_query->set_404();
@@ -1543,7 +1619,7 @@ function my_calendar( $args ) {
1543
$from = apply_filters( 'mc_from_date', $dates['from'] );
1544
$to = apply_filters( 'mc_to_date', $dates['to'] );
1545
1546
- $query = array(
1547
'from' => $from,
1548
'to' => $to,
1549
'category' => $params['category'],
@@ -1555,9 +1631,19 @@ function my_calendar( $args ) {
1555
'source' => 'calendar',
1556
'site' => $site,
1557
);
1558
- $query = apply_filters( 'mc_calendar_attributes', $query, $params );
1559
- $event_array = my_calendar_events( $query );
1560
- $no_events = ( empty( $event_array ) ) ? true : false;
1561
1562
$nav = mc_generate_calendar_nav( $params, $args['category'], $start_of_week, $show_months, $main_class, $site, $date, $from );
1563
$top = $nav['top'];
@@ -1638,6 +1724,9 @@ function my_calendar( $args ) {
1638
$list_heading = ( $months <= 1 ) ? $current_header . $caption_text . "\n" : $current_month_header . '&ndash;' . $through_month_header . $caption_text;
1639
// Translators: time period displayed.
1640
$list_heading = sprintf( __( 'Events in %s', 'my-calendar' ), $list_heading );
1641
} else {
1642
$list_heading = mc_draw_template( $values, stripslashes( $week_template ) );
1643
}
@@ -2670,7 +2759,7 @@ function my_calendar_categories_list( $show = 'list', $context = 'public', $grou
2670
</div><p>';
2671
$public_form = ( 'public' == $context ) ? $form : '';
2672
if ( ! is_user_logged_in() ) {
2673
- $categories = $mcdb->get_results( 'SELECT * FROM ' . my_calendar_categories_table() . ' WHERE category_private = 1 ORDER BY category_name ASC' );
2674
} else {
2675
$categories = $mcdb->get_results( 'SELECT * FROM ' . my_calendar_categories_table() . ' ORDER BY category_name ASC' );
2676
}
36
/**
37
* HTML output for event time
38
*
39
+ * @param object $e Current event.
40
* @param string $type Type of view.
41
*
42
* @return string HTML output.
43
*/
44
+ function mc_time_html( $e, $type ) {
45
$orig_format = get_option( 'mc_date_format' );
46
$date_format = ( '' != $orig_format ) ? $orig_format : get_option( 'date_format' );
47
+ $time_format = get_option( 'mc_time_format' );
48
+ $start = date( 'Y-m-d', strtotime( $e->occur_begin ) );
49
+ $end = date( 'Y-m-d', strtotime( $e->occur_end ) );
50
+ $has_time = ( '00:00:00' != $e->event_time && '' != $e->event_time ) ? true : false;
51
+ $final = '';
52
+ // Manipulate date_format based on event data.
53
+ if ( $e->event_end != $e->event_begin && ! $has_time ) {
54
$mult_format = get_option( 'mc_multidate_format' );
55
$mult_format = ( '' != $mult_format ) ? $mult_format : 'F j-%d, Y';
56
+ $date_format = str_replace( '%d', date( 'j', strtotime( $e->occur_end ) ), $mult_format );
57
}
58
// If this event crosses years or months, use original date format & show both dates.
59
+ if ( date( 'Y', strtotime( $e->occur_end ) ) != date( 'Y', strtotime( $e->occur_begin ) ) || date( 'm', strtotime( $e->occur_end ) ) != date( 'm', strtotime( $e->occur_begin ) ) ) {
60
+ $current = date_i18n( $orig_format, strtotime( $e->occur_begin ) ) . ' &ndash; ' . date_i18n( $orig_format, strtotime( $e->occur_end ) );
61
} else {
62
+ $current = date_i18n( $date_format, strtotime( $e->occur_begin ) );
63
+ $final = ( $e->event_end != $e->event_begin ) ? date_i18n( $date_format, strtotime( $e->occur_end ) ) : $final;
64
+ }
65
+ // Do not show info in list view.
66
+ $time_content = ( 'list' == $type ) ? '' : "<span class='mc-event-date dtstart' itemprop='startDate' title='" . $start . 'T' . $e->event_time . "' content='" . $start . 'T' . $e->event_time . "'>$current</span>";
67
+ // Handle cases.
68
+ if ( $has_time ) {
69
+ $time_content .= "\n
70
<span class='event-time dtstart'>
71
+ <time class='value-title' datetime='" . $start . 'T' . $e->event_time . "' title='" . $start . 'T' . $e->event_time . "'>" .
72
+ date_i18n( $time_format, strtotime( $e->event_time ) ) . '
73
</time>
74
</span>';
75
+ if ( 0 == $e->event_hide_end ) {
76
+ if ( '' != $e->event_endtime && $e->event_endtime != $e->event_time ) {
77
+ $time_content .= "
78
+ <span class='time-separator'> &ndash; </span>$final
79
<span class='end-time dtend'>
80
+ <time class='value-title' datetime='" . $end . 'T' . $e->event_endtime . "' title='" . $end . 'T' . $e->event_endtime . "'>" . date_i18n( $time_format, strtotime( $e->event_endtime ) ) . '
81
</time>
82
</span>';
83
}
84
}
85
} else {
86
+ $notime = mc_notime_label( $e );
87
+ $time_content .= "<span class='event-time'>";
88
+ $time_content .= ( 'N/A' == $notime ) ? "<abbr title='" . __( 'Not Applicable', 'my-calendar' ) . "'>" . __( 'N/A', 'my-calendar' ) . "</abbr>\n" : esc_html( $notime );
89
+ $time_content .= '</span>';
90
}
91
+ $time_content .= apply_filters( 'mcs_end_time_block', '', $e );
92
+ // Generate date/time meta data.
93
+ $meta = ( 0 == $e->event_hide_end ) ? "<meta itemprop='endDate' content='" . $start . 'T' . $e->event_endtime . "'/>" : '';
94
+ $meta .= '<meta itemprop="duration" content="' . mc_duration( $e ) . '"/>';
95
96
+ $time = "<div class='time-block'><p>$time_content</p>$meta</div>";
97
+
98
+ return apply_filters( 'mcs_time_block', $time, $e );
99
}
100
101
/**
316
$group_class = ( 1 == $event->event_span ) ? ' multidate group' . $event->event_group_id : '';
317
$hlevel = apply_filters( 'mc_heading_level_table', 'h3', $type, $time, $template );
318
$inner_heading = apply_filters( 'mc_heading_inner_title', $wrap . $image . trim( $event_title ) . $balance, $event_title, $event );
319
+ $header .= ( 'single' != $type && 'list' != $type ) ? "<$hlevel class='event-title summary$group_class' id='mc_$event->occur_id-title'>$inner_heading</$hlevel>\n" : '';
320
$event_title = ( 'single' == $type ) ? apply_filters( 'mc_single_event_title', $event_title, $event ) : $event_title;
321
$title = ( 'single' == $type && ! is_singular( 'mc-events' ) ) ? "<h2 class='event-title summary'>$image $event_title</h2>\n" : '<span class="summary screen-reader-text">' . $event_title . '</span>';
322
$title = apply_filters( 'mc_event_title', $title, $event, $event_title, $image );
335
$time_html = mc_time_html( $event, $type );
336
if ( 'list' == $type ) {
337
$hlevel = apply_filters( 'mc_heading_level_list', 'h3', $type, $time, $template );
338
+ $list_title = "<$hlevel class='event-title summary' id='mc_$event->occur_id-title'>$image" . $event_title . "</$hlevel>\n";
339
}
340
if ( 'true' == $display_author ) {
341
if ( 0 != $event->event_author ) {
416
$link_text = mc_draw_template( $data, $link_template );
417
$link = "
418
<p>
419
+ <a href='" . esc_url( $event_link ) . "' class='$external_class' aria-describedby='mc_$event->occur_id-title'>" . $link_text . '</a>
420
</p>';
421
}
422
446
}
447
448
$img_class = ( '' != $img ) ? ' has-image' : ' no-image';
449
+ $container = "<div id='$uid-$type-details' class='details$img_class' role='alert' aria-labelledby='mc_$event->occur_id-title' itemscope itemtype='http://schema.org/Event'>\n";
450
$container .= "<meta itemprop='name' content='" . strip_tags( $event->event_title ) . "' />";
451
$container = apply_filters( 'mc_before_event', $container, $event, $type, $time );
452
$details = $header . $container . apply_filters( 'mc_inner_content', $details, $event, $type, $time );
586
$categories = mc_get_categories( $event, false );
587
}
588
foreach ( $categories as $category ) {
589
+ if ( ! is_object( $category ) ) {
590
+ $category = (object) $category;
591
+ }
592
$classes[] = 'mc_rel_' . sanitize_html_class( $category->category_name );
593
}
594
1058
* @return string HTML output
1059
*/
1060
function mc_search_results( $query ) {
1061
+ $before = apply_filters( 'mc_past_search_results', 0, 'basic' );
1062
+ $after = apply_filters( 'mc_future_search_results', 10, 'basic' ); // Return only future events, nearest 10.
1063
+ $exports = '';
1064
if ( is_string( $query ) ) {
1065
$search = mc_prepare_search_query( $query );
1066
$term = $query;
1077
$template = '<strong>{date}</strong> {title} {details}';
1078
$template = apply_filters( 'mc_search_template', $template );
1079
// No filters parameter prevents infinite looping on the_content filters.
1080
+ $output = mc_produce_upcoming_events( $event_array, $template, 'list', 'ASC', 0, $before, $after, 'yes', 'nofilters' );
1081
+ $exports = apply_filters( 'mc_search_exportlinks', '', $output );
1082
} else {
1083
$output = apply_filters( 'mc_search_no_results', "<li class='no-results'>" . __( 'Sorry, your search produced no results.', 'my-calendar' ) . '</li>' );
1084
}
1086
$header = apply_filters( 'mc_search_before', '<ol class="mc-search-results">', $term );
1087
$footer = apply_filters( 'mc_search_after', '</ol>', $term );
1088
1089
+ return $header . $output . $footer . $exports;
1090
}
1091
1092
add_filter( 'the_title', 'mc_search_results_title', 10, 2 );
1139
}
1140
}
1141
1142
+ add_filter( 'mc_search_exportlinks', 'mc_search_exportlinks', 10, 0 );
1143
+ /**
1144
+ * Creates the export links for search result
1145
+ */
1146
+ function mc_search_exportlinks() {
1147
+ if ( ! session_id() ) {
1148
+ return;
1149
+ }
1150
+
1151
+ // Setup print link.
1152
+ $print_add = array(
1153
+ 'format' => 'list',
1154
+ 'searched' => true,
1155
+ 'href' => urlencode( mc_get_current_url() ),
1156
+ 'cid' => 'mc-print-view',
1157
+ );
1158
+ $subtract = array( 'time', 'ltype', 'lvalue', 'mcat', 'yr', 'month', 'dy' );
1159
+ $mc_print_url = mc_build_url( $print_add, '', home_url() );
1160
+ $print = "<div class='mc-print'><a href='$mc_print_url'>" . __( 'Print<span class="maybe-hide"> View</span>', 'my-calendar' ) . '</a></div>';
1161
+
1162
+ // Set up exports.
1163
+ $ics_add = array( 'searched' => true );
1164
+ $exports = mc_export_links( 1, 1, 1, $ics_add, $subtract );
1165
+
1166
+ $before = "<div class='mc_bottomnav my-calendar-footer'>";
1167
+ $after = '</div>';
1168
+
1169
+ return $before . $exports . $print . $after;
1170
+ }
1171
+
1172
+ add_filter( 'mc_searched_events', 'mc_searched_events', 10, 1 );
1173
+ /**
1174
+ * Saves all searched events in $_SESSION
1175
+ *
1176
+ * @param array $event_array The events to be saved.
1177
+ *
1178
+ * @return array Events.
1179
+ */
1180
+ function mc_searched_events( $event_array ) {
1181
+ if ( session_id() ) {
1182
+ $_SESSION['MC_SEARCH_RESULT'] = json_encode( $event_array );
1183
+ }
1184
+ return $event_array;
1185
+ }
1186
+
1187
+ /**
1188
+ * Get searched events from $_SESSION array
1189
+ *
1190
+ * @return array event_array
1191
+ */
1192
+ function mc_get_searched_events() {
1193
+ if ( ! session_id() || ! isset( $_SESSION['MC_SEARCH_RESULT'] ) ) {
1194
+ return;
1195
+ }
1196
+ $event_searched = json_decode( $_SESSION['MC_SEARCH_RESULT'], true );
1197
+ foreach ( $event_searched as $key => $value ) {
1198
+ $daily_events = array();
1199
+ foreach ( $value as $k => $v ) {
1200
+ $daily_events[] = (object) $v;
1201
+ }
1202
+ $event_array[ $key ] = $daily_events;
1203
+ }
1204
+ return $event_array;
1205
+ }
1206
+
1207
add_action( 'template_redirect', 'mc_hidden_event' );
1208
/**
1209
* If an event is hidden from the current user, redirect to 404.
1244
$uri = mc_get_uri();
1245
if ( ! $is_404 ) {
1246
wp_safe_redirect( $uri );
1247
+ exit;
1248
} else {
1249
global $wp_query;
1250
$wp_query->set_404();
1619
$from = apply_filters( 'mc_from_date', $dates['from'] );
1620
$to = apply_filters( 'mc_to_date', $dates['to'] );
1621
1622
+ $query = array(
1623
'from' => $from,
1624
'to' => $to,
1625
'category' => $params['category'],
1631
'source' => 'calendar',
1632
'site' => $site,
1633
);
1634
+ $query = apply_filters( 'mc_calendar_attributes', $query, $params );
1635
+ if ( 'mc-print-view' == $id && isset( $_GET['searched'] ) && $_GET['searched'] ) {
1636
+ $event_array = mc_get_searched_events();
1637
+ if ( ! empty( $event_array ) ) {
1638
+ reset( $event_array );
1639
+ $from = key( $event_array );
1640
+ end( $event_array );
1641
+ $to = key( $event_array );
1642
+ }
1643
+ } else {
1644
+ $event_array = my_calendar_events( $query );
1645
+ }
1646
+ $no_events = ( empty( $event_array ) ) ? true : false;
1647
1648
$nav = mc_generate_calendar_nav( $params, $args['category'], $start_of_week, $show_months, $main_class, $site, $date, $from );
1649
$top = $nav['top'];
1724
$list_heading = ( $months <= 1 ) ? $current_header . $caption_text . "\n" : $current_month_header . '&ndash;' . $through_month_header . $caption_text;
1725
// Translators: time period displayed.
1726
$list_heading = sprintf( __( 'Events in %s', 'my-calendar' ), $list_heading );
1727
+ if ( isset( $_GET['searched'] ) && 1 == $_GET['searched'] ) {
1728
+ $list_heading = __( 'Search Results', 'my-calendar' );
1729
+ }
1730
} else {
1731
$list_heading = mc_draw_template( $values, stripslashes( $week_template ) );
1732
}
2759
</div><p>';
2760
$public_form = ( 'public' == $context ) ? $form : '';
2761
if ( ! is_user_logged_in() ) {
2762
+ $categories = $mcdb->get_results( 'SELECT * FROM ' . my_calendar_categories_table() . ' WHERE category_private = 0 ORDER BY category_name ASC' );
2763
} else {
2764
$categories = $mcdb->get_results( 'SELECT * FROM ' . my_calendar_categories_table() . ' ORDER BY category_name ASC' );
2765
}
my-calendar-print.php CHANGED
@@ -70,6 +70,8 @@ function my_calendar_print() {
70
'ltype' => $ltype,
71
'lvalue' => $lvalue,
72
'id' => 'mc-print-view',
73
);
74
75
echo my_calendar( $calendar );
@@ -87,7 +89,7 @@ function my_calendar_print() {
87
unset( $add['cid'] );
88
unset( $add['feed'] );
89
unset( $add['href'] );
90
- $return_url = apply_filters( 'mc_return_to_calendar', mc_build_url( $add, array( 'feed', 'cid', 'href' ), $return_url ), $add );
91
if ( $return_url ) {
92
echo "<p class='return'>&larr; <a href='$return_url'>" . __( 'Return to calendar', 'my-calendar' ) . '</a></p>';
93
}
70
'ltype' => $ltype,
71
'lvalue' => $lvalue,
72
'id' => 'mc-print-view',
73
+ 'below' => 'none',
74
+ 'above' => 'none',
75
);
76
77
echo my_calendar( $calendar );
89
unset( $add['cid'] );
90
unset( $add['feed'] );
91
unset( $add['href'] );
92
+ $return_url = apply_filters( 'mc_return_to_calendar', mc_build_url( $add, array( 'feed', 'cid', 'href', 'searched' ), $return_url ), $add );
93
if ( $return_url ) {
94
echo "<p class='return'>&larr; <a href='$return_url'>" . __( 'Return to calendar', 'my-calendar' ) . '</a></p>';
95
}
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.0.18
21
*/
22
23
/*
@@ -42,7 +42,7 @@ if ( ! defined( 'ABSPATH' ) ) {
42
}
43
44
global $mc_version, $wpdb;
45
- $mc_version = '3.0.18';
46
47
define( 'MC_DEBUG', false );
48
@@ -150,6 +150,16 @@ function mc_custom_canonical() {
150
}
151
}
152
153
/**
154
* Generate canonical link
155
*/
17
* License: GPL-2.0+
18
* License URI: http://www.gnu.org/license/gpl-2.0.txt
19
* Domain Path: lang
20
+ * Version: 3.1.0
21
*/
22
23
/*
42
}
43
44
global $mc_version, $wpdb;
45
+ $mc_version = '3.1.0';
46
47
define( 'MC_DEBUG', false );
48
150
}
151
}
152
153
+ add_action( 'init', 'mc_start_session', 10 );
154
+ /**
155
+ * Makes sure session is started to be able to save search results.
156
+ */
157
+ function mc_start_session() {
158
+ if ( ! session_id() ) {
159
+ session_start();
160
+ }
161
+ }
162
+
163
/**
164
* Generate canonical link
165
*/
readme.txt CHANGED
@@ -5,7 +5,7 @@ Tags: calendar, dates, times, event, events, scheduling, schedule, event manager
5
Requires at least: 4.4
6
Tested up to: 4.9
7
Requires PHP: 5.3
8
- Stable tag: 3.0.18
9
Text domain: my-calendar
10
License: GPLv2 or later
11
@@ -85,6 +85,20 @@ Translating my plug-ins is always appreciated. Visit <a href="https://translate.
85
86
TODO: Support limiting views to multiple locations
87
88
= 3.0.18 =
89
90
* Bug fix: Invalid setting in bottom nav defaults.
@@ -308,4 +322,4 @@ The search feature in My Calendar is pretty basic; but [buying My Calendar Pro](
308
309
== Upgrade Notice ==
310
311
- * 3.0.11 URGENT: Security fix - XSS scripting vulnerability resolved.
5
Requires at least: 4.4
6
Tested up to: 4.9
7
Requires PHP: 5.3
8
+ Stable tag: 3.1.0
9
Text domain: my-calendar
10
License: GPLv2 or later
11
85
86
TODO: Support limiting views to multiple locations
87
88
+ = 3.1.0 =
89
+
90
+ * Add feature (by Josef Fällman): Print & export view for search results.
91
+ * New filter: mcs_check_conflicts (impacts Pro only)
92
+ * Bug fix: Fix issue causing duplication in some views.
93
+ * Bug fix: Time format should be filtered in initial edit view.
94
+ * Bug fix: Category relationships not retained when Group editing applied.
95
+ * Bug fix: aria-describedby ID mismatch.
96
+
97
+ = 3.0.19 =
98
+
99
+ * Bug fix: Fatal error in export API when location object included.
100
+ * BUg fix: my calendar categories queried private categories instead of public.
101
+
102
= 3.0.18 =
103
104
* Bug fix: Invalid setting in bottom nav defaults.
322
323
== Upgrade Notice ==
324
325
+ * 3.1.0 Bug fixes; couple minor new features.
styles/twentyeighteen.css CHANGED
@@ -16,7 +16,7 @@
16
}
17
18
.my-calendar-header > div, .mc_bottomnav > div {
19
- display: inline-block;
20
margin-right: 4px;
21
}
22
@@ -25,19 +25,19 @@
25
position: absolute !important;
26
height: 1px;
27
width: 1px;
28
- overflow: hidden;
29
}
30
31
.my-calendar-header > div:nth-of-type(1), .mc_bottomnav > div:nth-of-type(1) {
32
margin-left: 0;
33
}
34
-
35
.my-calendar-header > div:nth-of-type(last), .mc_bottomnav > div:nth-of-type(last) {
36
margin-right: 0;
37
}
38
39
.mc-main .my-calendar-header input,
40
- .mc-main .my-calendar-header span, .mc-main .my-calendar-header a,
41
.mc-main .mc_bottomnav span, .mc-main .mc_bottomnav a {
42
text-decoration: none;
43
-webkit-box-shadow: inset 0 -1px 0 rgba(15, 15, 15, 1);
@@ -45,10 +45,10 @@
45
-webkit-transition: color 80ms ease-in, -webkit-box-shadow 130ms ease-in-out;
46
transition: color 80ms ease-in, -webkit-box-shadow 130ms ease-in-out;
47
transition: color 80ms ease-in, box-shadow 130ms ease-in-out;
48
- transition: color 80ms ease-in, box-shadow 130ms ease-in-out, -webkit-box-shadow 130ms ease-in-out;
49
}
50
51
- .mc-main .my-calendar-header span, .mc-main .my-calendar-header a,
52
.mc-main .mc_bottomnav span, .mc-main .mc_bottomnav a,
53
.mc-main .my-calendar-header select, .mc-main .my-calendar-header input {
54
color: #313233;
@@ -58,7 +58,7 @@
58
border-radius: 5px;
59
padding: 4px 6px;
60
font-size: 14px;
61
- font-family: Arial;
62
background: #fff;
63
background: var(--secondary-light);
64
}
@@ -69,13 +69,13 @@
69
}
70
71
.mc-main .my-calendar-header input,
72
- .mc-main .my-calendar-header a,
73
.mc-main .mc_bottomnav a {
74
background: linear-gradient(to top, rgba( 210, 210, 210, .95 ) 0%, rgba( 230, 230, 230, .95 ) 70%);
75
}
76
77
- .mc-main .my-calendar-header input:hover, .mc-main .my-calendar-header input:focus,
78
- .mc-main .my-calendar-header a:hover, .mc-main .mc_bottomnav a:hover,
79
.mc-main .my-calendar-header a:focus, .mc-main .mc_bottomnav a:focus {
80
color: #fff;
81
color: var(--primary-light);
@@ -124,7 +124,7 @@
124
.mc-main td {
125
width: 14.285714%;
126
border: 1px solid #efefef;
127
- border: 1px solid var(--highlight-light);
128
padding: 0 !important;
129
height: 6em;
130
}
@@ -136,7 +136,7 @@
136
.mc-main td .event-title {
137
text-overflow: ellipsis;
138
overflow: hidden;
139
- font-size: 13px;
140
}
141
142
.mc-main {
@@ -151,14 +151,14 @@
151
.mc-main .event-title a {
152
display: block;
153
line-height: 1.5;
154
- padding: 6px;
155
position: relative;
156
border-bottom: none;
157
- box-shadow: none;
158
}
159
160
.mc-main .event-title .has-image {
161
- padding-left: 24px;
162
}
163
164
.mc-main.mini .event-title {
@@ -212,7 +212,7 @@
212
top: 0;
213
left: 0;
214
}
215
-
216
.mc-main .calendar-event .details, .mc-main .calendar-events {
217
position: absolute;
218
left: 5%;
@@ -372,7 +372,7 @@
372
.mc-main .current-day .mc-date {
373
background: #000 !important;
374
background: var(--secondary-dark) !important;
375
- color: #fff !important;
376
color: var(--secondary-light) !important;
377
box-shadow: inset 0px 0px 0px 2px #666;
378
box-shadow: inset 0px 0px 0px 2px var(--highlight-dark);
@@ -387,7 +387,7 @@
387
background: var(--primary-dark);
388
}
389
390
- .mc-main .has-events a.mc-date:hover,
391
.mc-main .has-events a.mc-date:focus {
392
color: #333;
393
color: var(--primary-dark);
@@ -414,22 +414,22 @@
414
415
.my-calendar-nav .my-calendar-prev a {
416
border-radius: 5px 0 0 5px;
417
- border-right: 1px solid #bbb;
418
}
419
420
.my-calendar-nav .my-calendar-next a {
421
border-radius: 0 5px 5px 0;
422
- border-left: 1px solid #fff;
423
}
424
425
.mc-main .mc-time .month {
426
border-radius: 5px 0 0 5px;
427
- border-right: 1px solid #bbb;
428
}
429
430
.mc-main .mc-time .week {
431
border-radius: 0;
432
- border-right: 1px solid #bbb;
433
}
434
435
.mc-main .mc-time .day {
@@ -438,7 +438,7 @@
438
439
.my-calendar-prev a:before, .my-calendar-next a:after {
440
font-family: 'dashicons';
441
- vertical-align: middle;
442
}
443
444
.mc-export .rss a:before {
@@ -467,7 +467,7 @@
467
468
/* Category Key */
469
.mc-main .category-key h3 {
470
- margin: 0 0 10px 0 !important;
471
}
472
473
.mc-main .category-key li.current a {
16
}
17
18
.my-calendar-header > div, .mc_bottomnav > div {
19
+ display: inline-block;
20
margin-right: 4px;
21
}
22
25
position: absolute !important;
26
height: 1px;
27
width: 1px;
28
+ overflow: hidden;
29
}
30
31
.my-calendar-header > div:nth-of-type(1), .mc_bottomnav > div:nth-of-type(1) {
32
margin-left: 0;
33
}
34
+
35
.my-calendar-header > div:nth-of-type(last), .mc_bottomnav > div:nth-of-type(last) {
36
margin-right: 0;
37
}
38
39
.mc-main .my-calendar-header input,
40
+ .mc-main .my-calendar-header span, .mc-main .my-calendar-header a,
41
.mc-main .mc_bottomnav span, .mc-main .mc_bottomnav a {
42
text-decoration: none;
43
-webkit-box-shadow: inset 0 -1px 0 rgba(15, 15, 15, 1);
45
-webkit-transition: color 80ms ease-in, -webkit-box-shadow 130ms ease-in-out;
46
transition: color 80ms ease-in, -webkit-box-shadow 130ms ease-in-out;
47
transition: color 80ms ease-in, box-shadow 130ms ease-in-out;
48
+ transition: color 80ms ease-in, box-shadow 130ms ease-in-out, -webkit-box-shadow 130ms ease-in-out;
49
}
50
51
+ .mc-main .my-calendar-header span, .mc-main .my-calendar-header a,
52
.mc-main .mc_bottomnav span, .mc-main .mc_bottomnav a,
53
.mc-main .my-calendar-header select, .mc-main .my-calendar-header input {
54
color: #313233;
58
border-radius: 5px;
59
padding: 4px 6px;
60
font-size: 14px;
61
+ font-family: Arial;
62
background: #fff;
63
background: var(--secondary-light);
64
}
69
}
70
71
.mc-main .my-calendar-header input,
72
+ .mc-main .my-calendar-header a,
73
.mc-main .mc_bottomnav a {
74
background: linear-gradient(to top, rgba( 210, 210, 210, .95 ) 0%, rgba( 230, 230, 230, .95 ) 70%);
75
}
76
77
+ .mc-main .my-calendar-header input:hover, .mc-main .my-calendar-header input:focus,
78
+ .mc-main .my-calendar-header a:hover, .mc-main .mc_bottomnav a:hover,
79
.mc-main .my-calendar-header a:focus, .mc-main .mc_bottomnav a:focus {
80
color: #fff;
81
color: var(--primary-light);
124
.mc-main td {
125
width: 14.285714%;
126
border: 1px solid #efefef;
127
+ border: 1px solid var(--highlight-light);
128
padding: 0 !important;
129
height: 6em;
130
}
136
.mc-main td .event-title {
137
text-overflow: ellipsis;
138
overflow: hidden;
139
+ font-size: 13px;
140
}
141
142
.mc-main {
151
.mc-main .event-title a {
152
display: block;
153
line-height: 1.5;
154
+ padding: 6px;
155
position: relative;
156
border-bottom: none;
157
+ box-shadow: none;
158
}
159
160
.mc-main .event-title .has-image {
161
+ padding-left: 24px;
162
}
163
164
.mc-main.mini .event-title {
212
top: 0;
213
left: 0;
214
}
215
+
216
.mc-main .calendar-event .details, .mc-main .calendar-events {
217
position: absolute;
218
left: 5%;
372
.mc-main .current-day .mc-date {
373
background: #000 !important;
374
background: var(--secondary-dark) !important;
375
+ color: #fff !important;
376
color: var(--secondary-light) !important;
377
box-shadow: inset 0px 0px 0px 2px #666;
378
box-shadow: inset 0px 0px 0px 2px var(--highlight-dark);
387
background: var(--primary-dark);
388
}
389
390
+ .mc-main .has-events a.mc-date:hover,
391
.mc-main .has-events a.mc-date:focus {
392
color: #333;
393
color: var(--primary-dark);
414
415
.my-calendar-nav .my-calendar-prev a {
416
border-radius: 5px 0 0 5px;
417
+ border-right: 1px solid #bbb;
418
}
419
420
.my-calendar-nav .my-calendar-next a {
421
border-radius: 0 5px 5px 0;
422
+ border-left: 1px solid #fff;
423
}
424
425
.mc-main .mc-time .month {
426
border-radius: 5px 0 0 5px;
427
+ border-right: 1px solid #bbb;
428
}
429
430
.mc-main .mc-time .week {
431
border-radius: 0;
432
+ border-right: 1px solid #bbb;
433
}
434
435
.mc-main .mc-time .day {
438
439
.my-calendar-prev a:before, .my-calendar-next a:after {
440
font-family: 'dashicons';
441
+ vertical-align: middle;
442
}
443
444
.mc-export .rss a:before {
467
468
/* Category Key */
469
.mc-main .category-key h3 {
470
+ margin: 0 0 10px 0 !important;
471
}
472
473
.mc-main .category-key li.current a {