My Calendar - Version 2.5.0

Version Description

  • Update hcalendar structures
  • Better handling when updating event taxonomies
  • Options to restrict management of events by category / user
  • UI Clean up
  • Don't display format toggle on mobile if automatic format switching enabled
  • Add custom date option to upcoming events shortcode builder
  • Improved error message if user creates event with an invalid recurring cycle
  • Updated template editor; ability to create custom templates.
  • Add option to add new dates for an existing event.
  • For single event, show closest available date if no/invalid date ID provided.
  • Added first occurrence data to core event object
  • New template tag: {related} to list other events in the same group
  • New loading indicator for AJAX navigation
  • New filter to modify event classes
  • New function to generate event classes
  • Reduce number of strings in plug-in to reduce burden on translators
  • Multisite: ability to display calendar for any site on any other site
  • in my_calendar_draw_event(), add filter to hide additional days of events
  • Improved HTML filtering to allow input elements and schema.org attributes.
  • Add support for Google Maps API key field, now required for use of Google Maps on new sites
  • Add 'today' keyword for the upcoming events 'to' attribute
  • Updates to Help documentation
  • Bug fix: auto assign events with no category to 'General'
  • Bug fix: some user select lists overwrote select list options
  • Bug fix: new events with no times entered need to be created as all day events
  • Bug fix: wrong number of arguments passed to mass delete events hook
  • Bug fix: Custom JS incorrectly escaped in Script manager
  • Bug fix: removed numerous notices
  • Bug fix: improved handling of missing event posts
  • Bug fix: allow more HTML elements & attributes
  • Bug fix: misc. notices

Breaking Changes: * Breaking change: minor changes to classes to improve structured data in microformats * Breaking change: upcoming events widget no longer uses ID 'upcoming-events'; use class '.upcoming-events' * Breaking change: today's events widget no longer uses ID 'todays-events'; use class '.todays-events'

Download this release

Release Info

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

Code changes from version 2.4.21 to 2.5.0

css/mc-styles.css CHANGED
@@ -251,14 +251,15 @@ span.mc-notice {
251
  float: right
252
  }
253
 
254
- input[id=e_label], input[id=e_title], input[id=location_label], input[id=mc_twitter] {
255
  font-size: 1.4em;
256
- padding: 5px;
257
- width: 100%
 
258
  }
259
 
260
  label[for=mc_twitter] {
261
- background: url(../images/twitter.png) no-repeat;
262
  padding-left: 20px;
263
  }
264
 
@@ -353,10 +354,9 @@ strong.label {
353
  }
354
 
355
  .jd-my-calendar .ui-accordion-header, .mc-settings-page #mc-sortable li {
356
- border: 1px solid #ccc;
357
- border-radius: 2px;
358
- background: rgba(0, 0, 0, .05);
359
- padding: 1px 1em;
360
  margin: 1px 0;
361
  }
362
 
@@ -378,8 +378,27 @@ strong.label {
378
  cursor: move;
379
  }
380
 
 
 
 
 
 
 
 
 
 
 
 
381
  .jd-my-calendar .ui-accordion-header-active {
382
- background: #fff;
 
 
 
 
 
 
 
 
383
  }
384
 
385
  #mc-sortable .mc-calendar {
@@ -420,11 +439,17 @@ strong.label {
420
  }
421
 
422
  .mc_permissions {
423
- padding: .5em;
 
 
424
  }
425
 
426
- .mc_permissions:nth-of-type(odd) {
427
- background: rgba( 0,0,0, .05 );
 
 
 
 
428
  }
429
 
430
  .jd-my-calendar .checkboxes li {
@@ -434,10 +459,6 @@ strong.label {
434
  margin: 2px;
435
  }
436
 
437
- .jd-my-calendar .mc_permissions:nth-of-type(odd) .checkboxes li {
438
- background: transparent;
439
- }
440
-
441
  .jd-my-calendar .checkboxes li:hover {
442
  background: #fff;
443
  }
@@ -545,6 +566,49 @@ strong.label {
545
  float: right;
546
  }
547
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
548
  .postbox.sell {
549
  background: #fff;
550
  color: #000;
@@ -604,11 +668,17 @@ tr.problem .error {
604
  }
605
 
606
  .mc-support-me p, .mc-support-me a {
607
- color: #fff;
 
 
 
 
 
608
  }
609
 
610
  .mc-support-me a:hover, .mc-support-me a:focus {
611
- text-decoration: none;
 
612
  }
613
 
614
  .jd-my-calendar .mc-none {
@@ -625,6 +695,10 @@ tr.problem .error {
625
  .jd-my-calendar .tablenav {
626
  float: none;
627
  }
 
 
 
 
628
 
629
  .jcd-narrow {
630
  width: 100%;
251
  float: right
252
  }
253
 
254
+ input[id=e_label], input[id=e_title], input[id=location_label], textarea[id=mc_twitter] {
255
  font-size: 1.4em;
256
+ padding: 9px;
257
+ width: 100%;
258
+ margin-bottom: .5em;
259
  }
260
 
261
  label[for=mc_twitter] {
262
+ background: url(../images/twitter.png) left 50% no-repeat;
263
  padding-left: 20px;
264
  }
265
 
354
  }
355
 
356
  .jd-my-calendar .ui-accordion-header, .mc-settings-page #mc-sortable li {
357
+ border: 1px solid #ddd;
358
+ background: rgba(0, 0, 0, .10);
359
+ padding: .5em 1em;
 
360
  margin: 1px 0;
361
  }
362
 
378
  cursor: move;
379
  }
380
 
381
+ input[name="mc_uri"] {
382
+ width: 100%;
383
+ padding: 5px;
384
+ font-size: 1.4em;
385
+ }
386
+
387
+ #mc-generator .custom {
388
+ background: #f6f6f6;
389
+ padding: 1em;
390
+ }
391
+
392
  .jd-my-calendar .ui-accordion-header-active {
393
+ background: rgba(0, 0, 0, .05);
394
+ }
395
+
396
+ .jd-my-calendar .ui-accordion-header .dashicons:before {
397
+ content: "\f132";
398
+ }
399
+
400
+ .jd-my-calendar .ui-accordion-header-active .dashicons:before {
401
+ content: "\f460";
402
  }
403
 
404
  #mc-sortable .mc-calendar {
439
  }
440
 
441
  .mc_permissions {
442
+ float: left;
443
+ width: 33%;
444
+ margin-bottom: 1em;
445
  }
446
 
447
+ .jd-my-calendar .mc_permissions .checkboxes li {
448
+ display: block;
449
+ }
450
+
451
+ .mc_permissions fieldset {
452
+ padding: 1em;
453
  }
454
 
455
  .jd-my-calendar .checkboxes li {
459
  margin: 2px;
460
  }
461
 
 
 
 
 
462
  .jd-my-calendar .checkboxes li:hover {
463
  background: #fff;
464
  }
566
  float: right;
567
  }
568
 
569
+ .mc_add_new {
570
+ position: relative;
571
+ z-index: 200;
572
+ padding: 1em;
573
+ background: #fff;
574
+ box-shadow: 0 0 3px #777;
575
+ }
576
+
577
+ .mc_add_new .clonedInput {
578
+ border-bottom: none;
579
+ margin-bottom: 0;
580
+ }
581
+
582
+ .mc-twitter {
583
+ padding: .5em 1em;
584
+ background: #213e7f;
585
+ color: #fff;
586
+ font-size: 1.1em;
587
+ }
588
+
589
+ .add-occurrence .dashicons:before {
590
+ content: "\f132";
591
+ }
592
+
593
+ .jd-my-calendar .postbox .hndle {
594
+ cursor: auto;
595
+ }
596
+
597
+ .save-occurrence {
598
+ position: absolute;
599
+ right: 1em;
600
+ bottom: 1em;
601
+ }
602
+
603
+ .add-occurrence[aria-expanded^="true"] .dashicons:before {
604
+ content: "\f460";
605
+ }
606
+
607
+ .template-description {
608
+ font-weight: 700;
609
+ font-size: 1.1em;
610
+ }
611
+
612
  .postbox.sell {
613
  background: #fff;
614
  color: #000;
668
  }
669
 
670
  .mc-support-me p, .mc-support-me a {
671
+ color: #f3f3f3;
672
+ }
673
+
674
+ .wrap ul.list {
675
+ list-style-type: disc;
676
+ margin-left: 1.5em;
677
  }
678
 
679
  .mc-support-me a:hover, .mc-support-me a:focus {
680
+ text-decoration: none !important;
681
+ color: #fff !important;
682
  }
683
 
684
  .jd-my-calendar .mc-none {
695
  .jd-my-calendar .tablenav {
696
  float: none;
697
  }
698
+
699
+ .mc_permissions {
700
+ width: 50%;
701
+ }
702
 
703
  .jcd-narrow {
704
  width: 100%;
css/reset.css CHANGED
@@ -85,6 +85,48 @@ button.mc-text-button:hover, button .mc-text-button:focus {
85
  text-decoration: underline;
86
  background-color: transparent;
87
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
 
89
  /**
90
  * This is focus passed to a div for the purpose of navigation; visible focus not required.
85
  text-decoration: underline;
86
  background-color: transparent;
87
  }
88
+ .mc-main .mc-loading {
89
+ position: absolute;
90
+ top: 10%;
91
+ left: 50%;
92
+ margin: -20px 0 0 -20px;
93
+ height: 40px;
94
+ width: 40px;
95
+ border: 2px solid rgba(0,0,0,0.3);
96
+ border-left-color: rgba(0,0,0,0.7);
97
+ background-color: rgba(0,0,0,0.05);
98
+ -webkit-border-radius: 50px;
99
+ -moz-border-radius: 50px;
100
+ border-radius: 50px;
101
+ -webkit-animation: animation-rotate 1250ms linear infinite;
102
+ -moz-animation: animation-rotate 1250ms linear infinite;
103
+ -o-animation: animation-rotate 1250ms linear infinite;
104
+ animation: animation-rotate 1250ms linear infinite;
105
+ }
106
+
107
+ @-webkit-keyframes animation-rotate {
108
+ 100% {
109
+ -webkit-transform: rotate(360deg);
110
+ }
111
+ }
112
+
113
+ @-moz-keyframes animation-rotate {
114
+ 100% {
115
+ -moz-transform: rotate(360deg);
116
+ }
117
+ }
118
+
119
+ @-o-keyframes animation-rotate {
120
+ 100% {
121
+ -o-transform: rotate(360deg);
122
+ }
123
+ }
124
+
125
+ @keyframes animation-rotate {
126
+ 100% {
127
+ transform: rotate(360deg);
128
+ }
129
+ }
130
 
131
  /**
132
  * This is focus passed to a div for the purpose of navigation; visible focus not required.
includes/general-utilities.php ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( ! defined( 'ABSPATH' ) ) {
3
+ exit;
4
+ } // Exit if accessed directly
5
+
6
+ function mc_switch_sites() {
7
+ if ( function_exists( 'is_multisite' ) && is_multisite() ) {
8
+ if ( get_site_option( 'mc_multisite' ) == 2 && my_calendar_table() != my_calendar_table( 'global' ) ) {
9
+ if ( get_option( 'mc_current_table' ) == '1' ) {
10
+ // can post to either, but is currently set to post to central table
11
+ return true;
12
+ }
13
+ } else if ( get_site_option( 'mc_multisite' ) == 1 && my_calendar_table() != my_calendar_table( 'global' ) ) {
14
+ // can only post to central table
15
+ return true;
16
+ }
17
+ }
18
+
19
+ return false;
20
+ }
21
+
22
+
23
+ function mc_tweet_approval( $prev, $new ) {
24
+ if ( function_exists( 'jd_doTwitterAPIPost' ) && isset( $_POST['mc_twitter'] ) && trim( $_POST['mc_twitter'] ) != '' ) {
25
+ if ( ( $prev == 0 || $prev == 2 ) && $new == 1 ) {
26
+ jd_doTwitterAPIPost( stripslashes( $_POST['mc_twitter'] ) );
27
+ }
28
+ }
29
+ }
30
+
31
+
32
+ function mc_flatten_event_array( $events ) {
33
+ $flat = array();
34
+ foreach( $events as $event ) {
35
+ foreach( $event as $e ) {
36
+ $flat[] = $e;
37
+ }
38
+ }
39
+
40
+ return $flat;
41
+ }
42
+
43
+
44
+ add_action( 'admin_menu', 'mc_add_outer_box' );
45
+
46
+ // begin add boxes
47
+ function mc_add_outer_box() {
48
+ add_meta_box( 'mcs_add_event', __('My Calendar Event', 'my-calendar'), 'mc_add_inner_box', 'mc-events', 'side','high' );
49
+ }
50
+
51
+ function mc_add_inner_box() {
52
+ global $post;
53
+ $event_id = get_post_meta( $post->ID, '_mc_event_id', true );
54
+ if ( $event_id ) {
55
+ $url = admin_url( 'admin.php?page=my-calendar&mode=edit&event_id='.$event_id );
56
+ $event = mc_get_event_core( $event_id );
57
+ $content = "<p><strong>" . mc_kses_post( $event->event_title ) . '</strong><br />' . $event->event_begin . ' @ ' . $event->event_time . "</p>";
58
+ if ( $event->event_label != '' ) {
59
+ $content .= "<p>" . sprintf( __( '<strong>Location:</strong> %s', 'my-calendar' ), mc_kses_post( $event->event_label ) ) . "</p>";
60
+ }
61
+ $content .= "<p>" . sprintf( __( '<a href="%s">Edit event</a>.', 'my-calendar' ), $url ) . "</p>";
62
+
63
+ echo $content;
64
+ }
65
+ }
includes/kses.php ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( ! defined( 'ABSPATH' ) ) {
3
+ exit;
4
+ } // Exit if accessed directly
5
+
6
+
7
+ function mc_kses_post( $string ) {
8
+ if ( !is_string( $string ) ) {
9
+ return $string;
10
+ } else {
11
+ return wp_kses( $string, 'mycalendar' );
12
+ }
13
+ }
14
+
15
+
16
+ /**
17
+ * My Calendar needs to allow input and select in posts and a variety of other key elements; also provide support for schema.org data.
18
+ *
19
+ * Call using wp_kses( $data, 'mycalendar' );
20
+ */
21
+ add_filter( 'wp_kses_allowed_html', 'mc_allowed_tags', 10, 2 );
22
+ function mc_allowed_tags( $tags, $context ) {
23
+ if ( $context == 'mycalendar' ) {
24
+ global $allowedposttags;
25
+ $tags = $allowedposttags;
26
+ $tags['input'] = array(
27
+ 'type' => true,
28
+ 'value' => true,
29
+ 'name' => true,
30
+ 'class' => true,
31
+ 'aria-labelledby' => true,
32
+ 'aria-describedby' => true,
33
+ 'disabled' => true,
34
+ 'readonly' => true,
35
+ 'min' => true,
36
+ 'max' => true,
37
+ );
38
+ $tags['select'] = array(
39
+ 'name' => true,
40
+ 'id' => true,
41
+ 'class' => true
42
+ );
43
+ $tags['span'] = array(
44
+ 'dir' => true,
45
+ 'align' => true,
46
+ 'lang' => true,
47
+ 'xml:lang' => true,
48
+ 'itemprop' => true,
49
+ 'itemscope' => true,
50
+ 'itemtype' => true,
51
+ );
52
+ $tags['button'] = array(
53
+ 'name' => true,
54
+ 'type' => true,
55
+ 'disabled' => true,
56
+ );
57
+ $tags['form'] = array(
58
+ 'action' => true,
59
+ 'method' => true,
60
+ 'class' => true,
61
+ 'id' => true,
62
+ 'tabindex' => true,
63
+ );
64
+ $tags['div'] = array(
65
+ 'class' => true,
66
+ 'id' => true,
67
+ 'aria-live' => true,
68
+ );
69
+ $tags['fieldset'] = array();
70
+ $tags['legend'] = array();
71
+ $tags['p'] = array(
72
+ 'class' => true,
73
+ );
74
+ $tags['img'] = array(
75
+ 'class' => true,
76
+ 'src' => true,
77
+ 'alt' => true,
78
+ 'width' => true,
79
+ 'height' => true,
80
+ 'id' => true,
81
+ 'longdesc' => true,
82
+ 'tabindex' => true
83
+ );
84
+ }
85
+
86
+ return $tags;
87
+ }
js/ajax.js CHANGED
@@ -2,8 +2,7 @@
2
  $(function () {
3
  // Delete single instances of recurring events.
4
  $( '.mc_response' ).hide();
5
- $('button.delete_occurrence').on( 'click', function (e) {
6
- e.preventDefault();
7
  var value = $(this).attr( 'data-value' );
8
  var data = {
9
  'action': mc_data.action,
@@ -17,6 +16,45 @@
17
  $('.mc_response').text( response.response ).show( 300 );
18
  }, "json" );
19
  });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
  // display notice informing users of lack of support for recur month by day
21
  $( '.mc_recur_notice' ).hide();
22
  $( '#e_recur' ).on( 'change', function (e) {
2
  $(function () {
3
  // Delete single instances of recurring events.
4
  $( '.mc_response' ).hide();
5
+ $('button.delete_occurrence').on( 'click', function () {
 
6
  var value = $(this).attr( 'data-value' );
7
  var data = {
8
  'action': mc_data.action,
16
  $('.mc_response').text( response.response ).show( 300 );
17
  }, "json" );
18
  });
19
+
20
+ $( '.mc_add_new' ).hide();
21
+
22
+ $( 'button.add-occurrence').on( 'click', function() {
23
+ var expanded = $( this ).attr( 'aria-expanded' );
24
+ if ( expanded == 'true' ) {
25
+ $( this ).attr( 'aria-expanded', 'false' );
26
+ } else {
27
+ $( this ).attr( 'aria-expanded', 'true' );
28
+ }
29
+ $( '.mc_add_new' ).toggle();
30
+ });
31
+
32
+ $( 'button.save-occurrence').on( 'click', function() {
33
+ var date = $( '#r_begin' ).val();
34
+ var begin = $( '#r_time' ).val();
35
+ var end = $( '#r_endtime' ).val();
36
+ var enddate = $( '#r_enddate' ).val();
37
+ var event_id = $( 'input[name="event_id"]' ).val();
38
+ var group_id = $( 'input[name="event_group_id"]' ).val();
39
+
40
+ var data = {
41
+ 'action': mc_data.recur,
42
+ 'event_id': event_id,
43
+ 'group_id': group_id,
44
+ 'event_date' : date,
45
+ 'event_time' : begin,
46
+ 'event_endtime' : end,
47
+ 'event_enddate' : enddate,
48
+ 'security': mc_data.security
49
+ };
50
+ $.post( ajaxurl, data, function (response) {
51
+ if ( response.success == 1 ) {
52
+ $( '.instance-list' ).append( '<li class="new"><strong>+</strong> ' + date + ' ' + begin + '</li>' );
53
+ }
54
+ $('.mc_response').text( response.response ).show( 300 );
55
+ }, "json" );
56
+ });
57
+
58
  // display notice informing users of lack of support for recur month by day
59
  $( '.mc_recur_notice' ).hide();
60
  $( '#e_recur' ).on( 'change', function (e) {
js/gmap3.js ADDED
@@ -0,0 +1,1131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ * GMAP3 Plugin for jQuery
3
+ * Version : 7.1
4
+ * Date : 2016/04/17
5
+ * Author : DEMONTE Jean-Baptiste
6
+ * Contact : jbdemonte@gmail.com
7
+ * Web site : http://gmap3.net
8
+ * Licence : GPL-3.0+
9
+ */
10
+ (function ($, window, document) {
11
+ "use strict";
12
+
13
+ var gm, services = {}, loadOptions,
14
+
15
+ // Proxify functions to get shorter minimized code
16
+ when = $.when,
17
+ extend = $.extend,
18
+ isArray = $.isArray,
19
+ isFunction = $.isFunction,
20
+ deferred = $.Deferred;
21
+
22
+ /**
23
+ * Duplicate option to never modify original object
24
+ * @param {Object} options
25
+ * @returns {Object}
26
+ */
27
+ function dupOpts(options) {
28
+ return extend(true, {}, options || {});
29
+ }
30
+
31
+ /**
32
+ * Slice an array like
33
+ * @params {Array|Object}
34
+ * @params {Number} [start]
35
+ * @params {Number} [end]
36
+ * @returns {Array}
37
+ */
38
+ function slice() {
39
+ var fn = Array.prototype.slice,
40
+ args = fn.call(arguments, 1);
41
+ return fn.apply(arguments[0], args);
42
+ }
43
+
44
+ /**
45
+ * Return true if value is undefined
46
+ * @param {*} value
47
+ * @returns {Boolean}
48
+ */
49
+ function isUndefined(value) {
50
+ return typeof value === 'undefined';
51
+ }
52
+
53
+ /**
54
+ * Equivalent to Promise.all
55
+ * @param {Deferred[]} deferreds
56
+ * @returns {Deferred}
57
+ */
58
+ function all(deferreds) {
59
+ return when.apply($, deferreds);
60
+ }
61
+
62
+ /**
63
+ * Equivalent to Promise.resolve
64
+ * @param {*} value
65
+ * @returns {Deferred}
66
+ */
67
+ function resolved(value) {
68
+ return when().then(function () {
69
+ return value;
70
+ });
71
+ }
72
+
73
+ /**
74
+ * return the distance between 2 latLng in meters
75
+ * @param {LatLng} origin
76
+ * @param {LatLng} destination
77
+ * @returns {Number}
78
+ **/
79
+ function distanceInMeter(origin, destination) {
80
+ var m = Math,
81
+ pi = m.PI,
82
+ e = pi * origin.lat() / 180,
83
+ f = pi * origin.lng() / 180,
84
+ g = pi * destination.lat() / 180,
85
+ h = pi * destination.lng() / 180,
86
+ cos = m.cos,
87
+ sin = m.sin;
88
+ return 1000 * 6371 * m.acos(m.min(cos(e) * cos(g) * cos(f) * cos(h) + cos(e) * sin(f) * cos(g) * sin(h) + sin(e) * sin(g), 1));
89
+ }
90
+
91
+ function ready(fn) {
92
+ if (document.readyState != 'loading'){
93
+ fn();
94
+ } else {
95
+ document.addEventListener('DOMContentLoaded', fn);
96
+ }
97
+ }
98
+
99
+ function serialize(obj) {
100
+ return objectKeys(obj).map(function (key) {
101
+ return encodeURIComponent(key) + "=" + encodeURIComponent(obj[key]);
102
+ }).join("&");
103
+ }
104
+
105
+ // Auto-load google maps library if needed
106
+ (function () {
107
+ var dfd = deferred(),
108
+ cbName = '__gmap3',
109
+ script;
110
+
111
+ $.holdReady(true);
112
+
113
+ ready(function () {
114
+ if (window.google && window.google.maps || loadOptions === false) {
115
+ dfd.resolve();
116
+ } else {
117
+ // callback function - resolving promise after maps successfully loaded
118
+ window[cbName] = function () {
119
+ delete window[cbName];
120
+ dfd.resolve();
121
+ };
122
+ script = document.createElement('script');
123
+ script.type = 'text/javascript';
124
+ script.src = 'https://maps.googleapis.com/maps/api/js?callback=' + cbName + (loadOptions ? '&' + (typeof loadOptions === 'string' ? loadOptions : serialize(loadOptions)) : '');
125
+ $("head").append(script);
126
+ }
127
+ });
128
+
129
+ return dfd.promise();
130
+ })().then(function () {
131
+ $.holdReady(false);
132
+ });
133
+
134
+ /**
135
+ * Instantiate only once a google service
136
+ * @param {String} name
137
+ * @returns {Object}
138
+ */
139
+ function service(name) {
140
+ if (!services[name]) {
141
+ services[name] = gmElement(name);
142
+ }
143
+ return services[name];
144
+ }
145
+
146
+ /**
147
+ * Return GoogleMap Class (or overwritten by user) instance
148
+ * @param {String} name
149
+ * @returns {Object}
150
+ */
151
+ function gmElement(name) {
152
+ var cls = gm[name];
153
+
154
+ function F(args) {
155
+ return cls.apply(this, args);
156
+ }
157
+ F.prototype = cls.prototype;
158
+
159
+ return new F(slice(arguments, 1));
160
+ }
161
+
162
+ /**
163
+ * Resolve a GeocodeRequest
164
+ * https://developers.google.com/maps/documentation/javascript/geocoding
165
+ * @param {String|Object} request
166
+ * @returns {Deferred}
167
+ */
168
+ function geocode(request) {
169
+ var dfd = deferred();
170
+ if (typeof request === 'string') {
171
+ request = {
172
+ address: request
173
+ };
174
+ }
175
+ service('Geocoder').geocode(request, function(results, status) {
176
+ if (status === gm.GeocoderStatus.OK) {
177
+ dfd.resolve(results[0].geometry.location);
178
+ } else {
179
+ dfd.reject();
180
+ }
181
+ });
182
+ return dfd;
183
+ }
184
+
185
+ /**
186
+ * Callable function taking a parameter as string
187
+ * @callback StringCallback
188
+ * @param {String}
189
+ */
190
+
191
+ /**
192
+ * Split a string and execute a function on each item
193
+ * @param {String} str - Space separated list of items
194
+ * @param {StringCallback} fn - Callback function
195
+ */
196
+ function foreachStr(str, fn) {
197
+ str.split(' ').forEach(fn);
198
+ }
199
+
200
+ /**
201
+ * Execute a function on each items if items is an array and on items as a single element if it is not an array
202
+ * @param {Array|*} items - Items to execute foreach callback on
203
+ * @param {Function} fn - Callback function
204
+ */
205
+ function foreach(items, fn) {
206
+ (isArray(items) ? items : [items]).forEach(fn);
207
+ }
208
+
209
+ /**
210
+ * Return Object keys
211
+ * @param {Object} obj
212
+ * @returns {String[]}
213
+ */
214
+ function objectKeys(obj) {
215
+ return Object.keys(obj);
216
+ }
217
+
218
+ /**
219
+ * Return Object values
220
+ * @param {Object} obj
221
+ * @returns {*[]}
222
+ */
223
+ function objectValues(obj) {
224
+ return objectKeys(obj).map(function (key) {
225
+ return obj[key];
226
+ });
227
+ }
228
+
229
+ /**
230
+ * Resolution function
231
+ * @callback OptionCallback
232
+ * @param {Object} options
233
+ * @returns {Deferred|*}
234
+ */
235
+
236
+ /**
237
+ * Convert bounds from array [ n, e, s, w ] to google.maps.LatLngBounds
238
+ * @param {Object} options - Container of options.bounds
239
+ * @param {OptionCallback} fn
240
+ * @returns {Deferred}
241
+ */
242
+ function resolveLatLngBounds(options, fn) {
243
+ options = dupOpts(options);
244
+ if (options.bounds) {
245
+ options.bounds = toLatLngBound(options.bounds);
246
+ }
247
+ return resolved(fn(options));
248
+ }
249
+
250
+ /**
251
+ * Resolve an address location / convert a LatLng array to google.maps.LatLng object
252
+ * @param {Object} options
253
+ * @param {String} key - LatLng key name in options object
254
+ * @param {OptionCallback} fn
255
+ * @returns {Deferred}
256
+ */
257
+ function resolveLatLng(options, key, fn) {
258
+ var dfd = deferred();
259
+ options = dupOpts(options);
260
+ when()
261
+ .then(function () {
262
+ var address = options.address;
263
+ if (address) {
264
+ delete options.address;
265
+ return geocode(address).then(function (latLng) {
266
+ options[key] = latLng;
267
+ });
268
+ }
269
+ options[key] = toLatLng(options[key]);
270
+ })
271
+ .then(function () {
272
+ dfd.resolve(fn(options));
273
+ });
274
+ return dfd;
275
+ }
276
+
277
+ /**
278
+ * Convert an array of mixed LatLng to google.maps.LatLng object
279
+ * No address resolution here
280
+ * @param {Object} options
281
+ * @param {String} key - Array key name in options object
282
+ * @param {OptionCallback} fn
283
+ * @returns {Deferred}
284
+ */
285
+ function resolveArrayOfLatLng(options, key, fn) {
286
+ options = dupOpts(options);
287
+ options[key] = (options[key] || []).map(function (item) {
288
+ return toLatLng(item);
289
+ });
290
+ return resolved(fn(options));
291
+ }
292
+
293
+ /**
294
+ * Convert a LatLng array to google.maps.LatLng
295
+ * @param {Array|*} mixed
296
+ * @param {Boolean} [convertLiteral]
297
+ * @returns {LatLng}
298
+ */
299
+ function toLatLng(mixed, convertLiteral) {
300
+ return isArray(mixed) ? new gm.LatLng(mixed[0], mixed[1]) : (convertLiteral && mixed && !(mixed instanceof gm.LatLng) ? new gm.LatLng(mixed.lat, mixed.lng) : mixed);
301
+ }
302
+
303
+ /**
304
+ * Convert a LatLngBound array to google.maps.LatLngBound
305
+ * @param {Array|*} mixed
306
+ * @param {Boolean} [convertLiteral]
307
+ * @returns {LatLngBounds}
308
+ */
309
+ function toLatLngBound(mixed, convertLiteral) {
310
+ if (isArray(mixed)) {
311
+ return new gm.LatLngBounds({lat: mixed[2], lng: mixed[3]}, {lat: mixed[0], lng: mixed[1]});
312
+ } else if (convertLiteral && !mixed.getCenter){
313
+ return new gm.LatLngBounds({lat: mixed.south, lng: mixed.west}, {lat: mixed.north, lng: mixed.east});
314
+ }
315
+ return mixed;
316
+ }
317
+
318
+ /**
319
+ * Create a custom overlay view
320
+ * @param {Map} map
321
+ * @param {Object} options
322
+ * @returns {OverlayView}
323
+ */
324
+ function createOverlayView(map, options) {
325
+
326
+ var GMOverlayView = gm.OverlayView;
327
+
328
+ var $div = $(document.createElement("div"))
329
+ .css({
330
+ border: "none",
331
+ borderWidth: 0,
332
+ position: "absolute"
333
+ })
334
+ .append(options.content);
335
+
336
+ options = extend({x: 0, y: 0}, options);
337
+
338
+ if (options.position) {
339
+ options.position = toLatLng(options.position, true);
340
+ } else if (options.bounds) {
341
+ options.bounds = toLatLngBound(options.bounds, true);
342
+ }
343
+
344
+ /**
345
+ * Class OverlayView
346
+ * @constructor
347
+ */
348
+ function OverlayView() {
349
+ var self = this,
350
+ listeners = [];
351
+
352
+ GMOverlayView.call(self);
353
+ self.setMap(map);
354
+
355
+ function fromLatLngToDivPixel(latlng) {
356
+ return self.getProjection().fromLatLngToDivPixel(latlng);
357
+ }
358
+
359
+ self.onAdd = function () {
360
+ var panes = self.getPanes();
361
+ panes.overlayMouseTarget.appendChild($div[0]);
362
+ };
363
+
364
+ if (options.position) {
365
+ self.getPosition = function () {
366
+ return options.position;
367
+ };
368
+
369
+ self.setPosition = function (latlng) {
370
+ options.position = latlng;
371
+ self.draw();
372
+ };
373
+
374
+ self.draw = function () {
375
+ var ps = fromLatLngToDivPixel(options.position);
376
+ $div.css({
377
+ left: (ps.x + options.x) + 'px',
378
+ top: (ps.y + options.y) + 'px'
379
+ });
380
+ };
381
+ } else {
382
+ self.getBounds = function () {
383
+ return options.bounds;
384
+ };
385
+
386
+ self.setBounds = function (bounds) {
387
+ options.bounds = bounds;
388
+ self.draw();
389
+ };
390
+
391
+ self.draw = function() {
392
+ var sw = fromLatLngToDivPixel(options.bounds.getSouthWest());
393
+ var ne = fromLatLngToDivPixel(options.bounds.getNorthEast());
394
+
395
+ $div.css({
396
+ left: (sw.x + options.x) + 'px',
397
+ top: (ne.y + options.y) + 'px',
398
+ width: (ne.x - sw.x + options.x) + 'px',
399
+ height: (sw.y - ne.y + options.y) + 'px'
400
+ });
401
+ };
402
+ }
403
+
404
+ self.onRemove = function () {
405
+ listeners.map(function (handler) {
406
+ gm.event.removeListener(handler);
407
+ });
408
+ $div.remove();
409
+ self.$ = $div = null; // mem leaks
410
+ };
411
+
412
+ self.$ = $div;
413
+ }
414
+
415
+ OverlayView.prototype = new GMOverlayView();
416
+
417
+ return new OverlayView();
418
+ }
419
+
420
+ /**
421
+ * Return a map projection
422
+ * @param {Map} map
423
+ * @returns {*}
424
+ */
425
+ function getProjection(map) {
426
+ function Overlay() {
427
+ var self = this;
428
+ self.onAdd = self.onRemove = self.draw = function () {};
429
+ return gm.OverlayView.call(self);
430
+ }
431
+ Overlay.prototype = new gm.OverlayView();
432
+ var overlay = new Overlay();
433
+ overlay.setMap(map);
434
+ return overlay.getProjection();
435
+ }
436
+
437
+ /**
438
+ * Class used as event first parameter on clustering overlays
439
+ * @param {Cluster} cluster
440
+ * @param {Marker[]} markers
441
+ * @param {OverlayView} overlay
442
+ * @param {LatLngBounds} bounds
443
+ * @constructor
444
+ */
445
+ function ClusterOverlay(cluster, markers, overlay, bounds) {
446
+ var self = this;
447
+ self.cluster = cluster;
448
+ self.markers = markers;
449
+ self.$ = overlay.$;
450
+ self.overlay = overlay;
451
+
452
+ overlay.getBounds = function () {
453
+ return gmElement('LatLngBounds', bounds.getSouthWest(), bounds.getNorthEast());
454
+ };
455
+ }
456
+
457
+ /**
458
+ * Cluster Group definition.
459
+ * @typedef {Object} ClusterGroupDef
460
+ * @property {String|jQuery} content
461
+ * @property {Number} [x] Offset
462
+ * @property {Number} [y] Offset
463
+ */
464
+
465
+ /**
466
+ * Cluster evaluation function
467
+ * @callback clusterCallback
468
+ * @param {Marker[]} markers
469
+ * @return {ClusterGroupDef|undefined}
470
+ */
471
+
472
+ /**
473
+ * Class used to handle clustering
474
+ * @param {Map} map
475
+ * @param {Object} options
476
+ * @param {Integer} [options.size]
477
+ * @param {Object[]} [options.markers] markers definition
478
+ * @param {clusterCallback} [options.cb] callback used to evaluate clustering elements
479
+ * @constructor
480
+ */
481
+ function Cluster(map, options) {
482
+ var timer, igniter, previousViewHash, projection, filter,
483
+ self = this,
484
+ markers = [],
485
+ radius = (options.size || 200) >> 1,
486
+ enabled = true,
487
+ overlays = {},
488
+ handlers = [];
489
+
490
+ options = options || {};
491
+ options.markers = options.markers || [];
492
+
493
+ /**
494
+ * Cluster evaluation function
495
+ * @callback bindCallback
496
+ * @param {ClusterOverlay[]} instances
497
+ */
498
+
499
+ /**
500
+ * Bind a function to each current or future overlays
501
+ * @param {bindCallback} fn
502
+ */
503
+ self._b = function (fn) {
504
+ fn(objectValues(overlays));
505
+ handlers.push(fn);
506
+ };
507
+
508
+ /**
509
+ * Get the marker list
510
+ * @returns {Marker[]}
511
+ */
512
+ self.markers = function () {
513
+ return slice(markers);
514
+ };
515
+
516
+ /**
517
+ * Get the current groups
518
+ * @returns {ClusterOverlay[]}
519
+ */
520
+ self.groups = function () {
521
+ return objectValues(overlays);
522
+ };
523
+
524
+ /**
525
+ * Enable the clustering feature
526
+ */
527
+ self.enable = function () {
528
+ if (!enabled) {
529
+ enabled = true;
530
+ previousViewHash = '';
531
+ delayRedraw();
532
+ }
533
+ };
534
+
535
+
536
+ /**
537
+ * Disable the clustering feature
538
+ */
539
+ self.disable = function () {
540
+ if (enabled) {
541
+ enabled = false;
542
+ previousViewHash = '';
543
+ delayRedraw();
544
+ }
545
+ };
546
+
547
+ /**
548
+ * Add a marker
549
+ * @param {Marker} marker
550
+ */
551
+ self.add = function (marker) {
552
+ markers.push(marker);
553
+ previousViewHash = '';
554
+ delayRedraw();
555
+ };
556
+
557
+ /**
558
+ * Remove a marker
559
+ * @param {Marker} marker
560
+ */
561
+ self.remove = function (marker) {
562
+ markers = markers.filter(function (item) {
563
+ return item !== marker;
564
+ });
565
+ previousViewHash = '';
566
+ delayRedraw();
567
+ };
568
+
569
+ /**
570
+ * Filtering function, Cluster only handle those who return true
571
+ * @callback filterCallback
572
+ * @param {Marker} marker
573
+ * @returns {Boolean}
574
+ */
575
+
576
+ /**
577
+ * Set a filter function
578
+ * @param {filterCallback} fn
579
+ */
580
+ self.filter = function (fn) {
581
+ if (filter !== fn) {
582
+ filter = fn;
583
+ previousViewHash = '';
584
+ delayRedraw();
585
+ }
586
+ };
587
+
588
+ /**
589
+ * Generate extended visible bounds
590
+ * @returns {LatLngBounds}
591
+ */
592
+ function extendsMapBounds() {
593
+ var circle = gmElement('Circle', {
594
+ center: map.getCenter(),
595
+ radius: 1.15 * distanceInMeter(map.getCenter(), map.getBounds().getNorthEast()) // + 15%
596
+ });
597
+ return circle.getBounds();
598
+ }
599
+
600
+ /**
601
+ * Generate bounds extended by radius
602
+ * @param {LatLng} latLng
603
+ * @returns {LatLngBounds}
604
+ */
605
+ function extendsBounds(latLng) {
606
+ var p = projection.fromLatLngToDivPixel(latLng);
607
+ return gmElement('LatLngBounds',
608
+ projection.fromDivPixelToLatLng(gmElement('Point', p.x - radius, p.y + radius)),
609
+ projection.fromDivPixelToLatLng(gmElement('Point', p.x + radius, p.y - radius))
610
+ );
611
+ }
612
+
613
+ options.markers.map(function (opts) {
614
+ opts.position = toLatLng(opts.position);
615
+ markers.push(gmElement('Marker', opts));
616
+ });
617
+
618
+ /**
619
+ * Redraw clusters
620
+ */
621
+ function redraw() {
622
+ var keys, bounds, overlayOptions, hash, currentMarkers, viewHash,
623
+ zoom = map.getZoom(),
624
+ currentHashes = {},
625
+ newOverlays = [],
626
+ ignore = {};
627
+
628
+ viewHash = '' + zoom;
629
+
630
+ if (zoom > 3) {
631
+ bounds = extendsMapBounds();
632
+ foreach(markers, function (marker, index) {
633
+ if (!bounds.contains(marker.getPosition())) {
634
+ viewHash += '-' + index;
635
+ ignore[index] = true;
636
+ if (marker.getMap()) {
637
+ marker.setMap(null);
638
+ }
639
+ }
640
+ });
641
+ }
642
+ if (filter) {
643
+ foreach(markers, function (marker, index) {
644
+ if (!ignore[index] && !filter(marker)) {
645
+ viewHash += '-' + index;
646
+ ignore[index] = true;
647
+ if (marker.getMap()) {
648
+ marker.setMap(null);
649
+ }
650
+ }
651
+ });
652
+ }
653
+
654
+ if (viewHash === previousViewHash) {
655
+ return;
656
+ }
657
+ previousViewHash = viewHash;
658
+
659
+ foreach(markers, function (marker, index) {
660
+ if (ignore[index]) {
661
+ return;
662
+ }
663
+
664
+ keys = [index];
665
+ bounds = extendsBounds(marker.getPosition());
666
+
667
+ if (enabled) {
668
+ foreach(slice(markers, index + 1), function (marker, idx) {
669
+ idx += index + 1;
670
+ if (!ignore[idx] && bounds.contains(marker.getPosition())) {
671
+ keys.push(idx);
672
+ ignore[idx] = true;
673
+ }
674
+ });
675
+ }
676
+
677
+ hash = keys.join('-');
678
+ currentHashes[hash] = true;
679
+
680
+ if (overlays[hash]) { // hash is already set
681
+ return;
682
+ }
683
+
684
+ currentMarkers = keys.map(function (key) {
685
+ return markers[key];
686
+ });
687
+
688
+ // ask the user callback on this subset (may be composed by only one marker)
689
+ overlayOptions = options.cb(slice(currentMarkers));
690
+
691
+ // create an overlay if cb returns its properties
692
+ if (overlayOptions) {
693
+ bounds = gmElement('LatLngBounds');
694
+ foreach(currentMarkers, function (marker) {
695
+ bounds.extend(marker.getPosition());
696
+ if (marker.getMap()) {
697
+ marker.setMap(null);
698
+ }
699
+ });
700
+
701
+ overlayOptions = dupOpts(overlayOptions);
702
+ overlayOptions.position = bounds.getCenter();
703
+ overlays[hash] = new ClusterOverlay(self, slice(currentMarkers), createOverlayView(map, overlayOptions), bounds);
704
+ newOverlays.push(overlays[hash]);
705
+
706
+ } else {
707
+ foreach(currentMarkers, function (marker) {
708
+ if (!marker.getMap()) { // to avoid marker blinking
709
+ marker.setMap(map);
710
+ }
711
+ });
712
+ }
713
+
714
+ });
715
+
716
+ // remove previous overlays
717
+ foreach(objectKeys(overlays), function (key) {
718
+ if (!currentHashes[key]) {
719
+ overlays[key].overlay.setMap(null);
720
+ delete overlays[key];
721
+ }
722
+ });
723
+
724
+ if (newOverlays.length) {
725
+ foreach(handlers, function (fn) {
726
+ fn(newOverlays);
727
+ });
728
+ }
729
+ }
730
+
731
+ /**
732
+ * Restart redraw timer
733
+ */
734
+ function delayRedraw() {
735
+ clearTimeout(timer);
736
+ timer = setTimeout(redraw, 100);
737
+ }
738
+
739
+ /**
740
+ * Init clustering
741
+ */
742
+ function init() {
743
+ gm.event.addListener(map, "zoom_changed", delayRedraw);
744
+ gm.event.addListener(map, "bounds_changed", delayRedraw);
745
+ redraw();
746
+ }
747
+
748
+ igniter = setInterval(function () {
749
+ projection = getProjection(map);
750
+ if (projection) {
751
+ clearInterval(igniter);
752
+ init();
753
+ }
754
+ }, 10);
755
+ }
756
+
757
+ /**
758
+ * Configure google maps loading library
759
+ * @param {string|object} options
760
+ */
761
+ $.gmap3 = function (options) {
762
+ loadOptions = options;
763
+ };
764
+
765
+ /**
766
+ * jQuery Plugin
767
+ */
768
+ $.fn.gmap3 = function (options) {
769
+ var items = [];
770
+ gm = window.google.maps; // once gmap3 is loaded, google.maps library should be loaded
771
+ this.each(function () {
772
+ var $this = $(this), gmap3 = $this.data("gmap3");
773
+ if (!gmap3) {
774
+ gmap3 = new Gmap3($this, options);
775
+ $this.data("gmap3", gmap3);
776
+ }
777
+ items.push(gmap3);
778
+ });
779
+
780
+ return new Handler(this, items);
781
+ };
782
+
783
+ /**
784
+ * Class Handler
785
+ * Chainable objet which handle all Gmap3 items associated to all jQuery elements in the current command set
786
+ * @param {jQuery} chain - "this" to return to maintain the jQuery chain
787
+ * @param {Gmap3[]} items
788
+ * @constructor
789
+ */
790
+ function Handler(chain, items) {
791
+ var self = this;
792
+
793
+ // Map all functions from Gmap3 class
794
+ objectKeys(items[0]).forEach(function (name) {
795
+ self[name] = function () {
796
+ var results = [],
797
+ args = slice(arguments);
798
+ items.forEach(function (item) {
799
+ results.push(item[name].apply(item, args));
800
+ });
801
+ return name === 'get' ? (results.length > 1 ? results : results[0]) : self;
802
+ };
803
+ });
804
+
805
+ self.$ = chain;
806
+ }
807
+
808
+ /**
809
+ * Class Gmap3
810
+ * Handle a Google.maps.Map instance
811
+ * @param {jQuery} $container - Element to display the map in
812
+ * @param {Object} options - MapOptions
813
+ * @constructor
814
+ */
815
+ function Gmap3($container, options) {
816
+ var map,
817
+ previousResults = [],
818
+ promise = when(),
819
+ self = this;
820
+
821
+ function context() {
822
+ return {
823
+ $: $container,
824
+ get: self.get
825
+ };
826
+ }
827
+
828
+ /**
829
+ * Attach events to instances
830
+ * @param {Object } events
831
+ * @param {Array|Object} instances
832
+ * @param {array} [args] arguments to add
833
+ * @param {Boolean} once
834
+ */
835
+ function attachEvents(events, instances, args, once) {
836
+ var hasArgs = arguments.length > 3;
837
+ if (!hasArgs) {
838
+ once = args;
839
+ }
840
+ $.each(events, function (eventName, handlers) {
841
+ foreach(instances, function (instance) {
842
+ var isClusterOverlay = instance instanceof ClusterOverlay;
843
+ var isDom = isClusterOverlay || (instance instanceof gm.OverlayView);
844
+ var eventListener = isDom ? instance.$.get(0) : instance;
845
+ gm.event['add' + (isDom ? 'Dom' : '') + 'Listener' + (once ? 'Once' : '')](eventListener, eventName, function (event) {
846
+ foreach(handlers, function (handler) {
847
+ if (isFunction(handler)) {
848
+ if (isClusterOverlay) {
849
+ handler.call(context(), undefined /* marker */, instance, instance.cluster, event);
850
+ } else if (hasArgs) {
851
+ var buffer = slice(args);
852
+ buffer.unshift(instance);
853
+ buffer.push(event);
854
+ handler.apply(context(), buffer);
855
+ } else {
856
+ handler.call(context(), instance, event);
857
+ }
858
+ }
859
+ });
860
+ });
861
+ });
862
+ });
863
+ }
864
+
865
+ /**
866
+ * Decorator to handle multiple call based on array of options
867
+ * @param {Function} fn
868
+ * @returns {Deferred}
869
+ */
870
+ function multiple(fn) {
871
+ return function (options) {
872
+ if (isArray(options)) {
873
+ var instances = [];
874
+ var promises = options.map(function (opts) {
875
+ return fn.call(self, opts).then(function (instance) {
876
+ instances.push(instance);
877
+ });
878
+ });
879
+ return all(promises).then(function () {
880
+ previousResults.push(instances);
881
+ return instances;
882
+ });
883
+ } else {
884
+ return fn.apply(self, arguments).then(function (instance) {
885
+ previousResults.push(instance);
886
+ return instance;
887
+ });
888
+ }
889
+ };
890
+ }
891
+
892
+ /**
893
+ * Decorator to chain promise result onto the main promise chain
894
+ * @param {Function} fn
895
+ * @returns {Deferred}
896
+ */
897
+ function chainToPromise(fn) {
898
+ return function () {
899
+ var args = slice(arguments);
900
+ promise = promise.then(function (instance) {
901
+ if (isFunction(args[0])) {
902
+ // handle return as a deferred / promise to support both sync & async result
903
+ return when(args[0].call(context(), instance)).then(function (value) {
904
+ args[0] = value;
905
+ return fn.apply(self, args);
906
+ });
907
+ }
908
+
909
+ return when(fn.apply(self, args));
910
+ });
911
+ return promise;
912
+ };
913
+ }
914
+
915
+ self.map = chainToPromise(function (options) {
916
+ return map || resolveLatLng(options, 'center', function (opts) {
917
+ map = gmElement('Map', $container.get(0), opts);
918
+ previousResults.push(map);
919
+ return map;
920
+ });
921
+ });
922
+
923
+ // Space separated string of : separated element
924
+ // (google.maps class name) : (latLng property name) : (add map - 0|1 - default = 1)
925
+ foreachStr('Marker:position Circle:center InfoWindow:position:0 Polyline:path Polygon:paths', function (item) {
926
+ item = item.split(':');
927
+ var property = item[1] || '';
928
+ self[item[0].toLowerCase()] = chainToPromise(multiple(function (options) {
929
+ return (property.match(/^path/) ? resolveArrayOfLatLng : resolveLatLng)(options, property, function (opts) {
930
+ if (item[2] !== '0') {
931
+ opts.map = map;
932
+ }
933
+ return gmElement(item[0], opts);
934
+ });
935
+ }));
936
+ });
937
+
938
+ foreachStr('TrafficLayer TransitLayer BicyclingLayer', function (item) {
939
+ self[item.toLowerCase()] = chainToPromise(function () {
940
+ var instance = gmElement(item);
941
+ previousResults.push(instance);
942
+ instance.setMap(map);
943
+ return instance;
944
+ });
945
+ });
946
+
947
+ self.kmllayer = chainToPromise(multiple(function (options) {
948
+ options = dupOpts(options);
949
+ options.map = map;
950
+ return when(gmElement('KmlLayer', options));
951
+ }));
952
+
953
+ self.rectangle = chainToPromise(multiple(function (options) {
954
+ return resolveLatLngBounds(options, function (opts) {
955
+ opts.map = map;
956
+ return gmElement('Rectangle', opts);
957
+ });
958
+ }));
959
+
960
+ self.overlay = chainToPromise(multiple(function (options) {
961
+ function fn(opts) {
962
+ return createOverlayView(map, opts);
963
+ }
964
+
965
+ options = dupOpts(options);
966
+ return options.bounds ? resolveLatLngBounds(options, fn) : resolveLatLng(options, 'position', fn);
967
+ }));
968
+
969
+ self.groundoverlay = chainToPromise(function (url, bounds, options) {
970
+ return resolveLatLngBounds({bounds: bounds}, function (opts) {
971
+ options = dupOpts(options);
972
+ options.map = map;
973
+ var instance = gmElement('GroundOverlay', url, opts.bounds, options);
974
+ previousResults.push(instance);
975
+ return instance;
976
+ });
977
+ });
978
+
979
+ self.styledmaptype = chainToPromise(function (styleId, styles, options) {
980
+ var instance = gmElement('StyledMapType', styles, options);
981
+ previousResults.push(instance);
982
+ map.mapTypes.set(styleId, instance);
983
+ return instance;
984
+ });
985
+
986
+ self.streetviewpanorama = chainToPromise(function (container, options) {
987
+ return resolveLatLng(options, 'position', function (opts) {
988
+ var instance = gmElement('StreetViewPanorama', $(container).get(0), opts);
989
+ map.setStreetView(instance);
990
+ previousResults.push(instance);
991
+ return instance;
992
+ });
993
+ });
994
+
995
+ self.route = chainToPromise(function (options) {
996
+ var dfd = deferred();
997
+ options = dupOpts(options);
998
+ options.origin = toLatLng(options.origin);
999
+ options.destination = toLatLng(options.destination);
1000
+ service('DirectionsService').route(options, function (results, status) {
1001
+ previousResults.push(results);
1002
+ dfd.resolve(status === gm.DirectionsStatus.OK ? results : false);
1003
+ });
1004
+ return dfd;
1005
+ });
1006
+
1007
+ self.cluster = chainToPromise(function (options) {
1008
+ var cluster = new Cluster(map, dupOpts(options));
1009
+ previousResults.push(cluster);
1010
+ return resolved(cluster);
1011
+ });
1012
+
1013
+ self.directionsrenderer = chainToPromise(function (options) {
1014
+ var instance;
1015
+ if (options) {
1016
+ options = dupOpts(options);
1017
+ options.map = map;
1018
+ if (options.panel) {
1019
+ options.panel = $(options.panel).get(0);
1020
+ }
1021
+ instance = gmElement('DirectionsRenderer', options);
1022
+ }
1023
+ previousResults.push(instance);
1024
+ return instance;
1025
+ });
1026
+
1027
+ self.latlng = chainToPromise(multiple(function (options) {
1028
+ return resolveLatLng(options, 'latlng', function (opts) {
1029
+ previousResults.push(opts.latlng);
1030
+ return opts.latlng;
1031
+ });
1032
+ }));
1033
+
1034
+ self.fit = chainToPromise(function () {
1035
+ var bounds = gmElement('LatLngBounds');
1036
+ foreach(previousResults, function (instances) {
1037
+ if (instances !== map) {
1038
+ foreach(instances, function (instance) {
1039
+ if (instance) {
1040
+ if (instance.getPosition && instance.getPosition()) {
1041
+ bounds.extend(instance.getPosition());
1042
+ } else if (instance.getBounds && instance.getBounds()) {
1043
+ bounds.extend(instance.getBounds().getNorthEast());
1044
+ bounds.extend(instance.getBounds().getSouthWest());
1045
+ } else if (instance.getPaths && instance.getPaths()) {
1046
+ foreach(instance.getPaths().getArray(), function (path) {
1047
+ foreach(path.getArray(), function (latLng) {
1048
+ bounds.extend(latLng);
1049
+ });
1050
+ });
1051
+ } else if (instance.getPath && instance.getPath()) {
1052
+ foreach(instance.getPath().getArray(), function (latLng) {
1053
+ bounds.extend(latLng);
1054
+ });
1055
+ } else if (instance.getCenter && instance.getCenter()) {
1056
+ bounds.extend(instance.getCenter());
1057
+ }
1058
+ }
1059
+ });
1060
+ }
1061
+ });
1062
+ if (!bounds.isEmpty()) {
1063
+ map.fitBounds(bounds);
1064
+ }
1065
+ return true;
1066
+ });
1067
+
1068
+ self.wait = function (duration) {
1069
+ promise = promise.then(function (instance) {
1070
+ var dfd = deferred();
1071
+ setTimeout(function () {
1072
+ dfd.resolve(instance);
1073
+ }, duration);
1074
+ return dfd;
1075
+ });
1076
+ };
1077
+
1078
+ self.then = function (fn) {
1079
+ if (isFunction(fn)) {
1080
+ promise = promise.then(function (instance) {
1081
+ return when(fn.call(context(), instance)).then(function (newInstance) {
1082
+ return isUndefined(newInstance) ? instance : newInstance;
1083
+ });
1084
+ });
1085
+ }
1086
+ };
1087
+
1088
+ foreachStr('on once', function (name, once) {
1089
+ self[name] = function () {
1090
+ var events = arguments[0];
1091
+ if (events) {
1092
+ if (typeof events === 'string') { // cast call on('click', handler) to on({click: handler})
1093
+ events = {};
1094
+ events[arguments[0]] = slice(arguments, 1);
1095
+ }
1096
+ promise.then(function (instances) {
1097
+ if (instances) {
1098
+ if (instances instanceof Cluster) {
1099
+ instances._b(function (items) {
1100
+ if (items && items.length) {
1101
+ attachEvents(events, items, once);
1102
+ }
1103
+ });
1104
+ return attachEvents(events, instances.markers(), [undefined, instances], once);
1105
+ }
1106
+ attachEvents(events, instances, once);
1107
+ }
1108
+ });
1109
+ }
1110
+ };
1111
+ });
1112
+
1113
+ self.get = function (index) {
1114
+ if (isUndefined(index)) {
1115
+ return previousResults.map(function (instance) {
1116
+ return isArray(instance) ? instance.slice() : instance;
1117
+ });
1118
+ } else {
1119
+ if (index < 0) {
1120
+ index = previousResults.length + index;
1121
+ }
1122
+ return isArray(previousResults[index]) ? previousResults[index].slice() : previousResults[index];
1123
+ }
1124
+ };
1125
+
1126
+ if (options) {
1127
+ self.map(options);
1128
+ }
1129
+ }
1130
+
1131
+ })(jQuery, window, document);
js/jquery.addfields.js CHANGED
@@ -5,14 +5,14 @@ jQuery(document).ready(function ($) {
5
  var newNum = new Number(num + 1); // the numeric ID of the new input field being added
6
  // create the new element via clone(), and manipulate it's ID using newNum value
7
  var newElem = $('#event' + num).clone().attr('id', 'event' + newNum);
8
- // manipulate the name/id values of the input inside the new element
9
  // insert the new element after the last "duplicatable" input field
10
  $('#event' + num).after(newElem);
11
  // enable the "remove" button
12
  $('#del_field').removeAttr('disabled');
13
  // business rule: you can only add 10 occurrences
14
- if (newNum == 20)
15
  $('#add_field').attr('disabled', 'disabled');
 
16
  });
17
 
18
  $('#del_field').on('click', function () {
@@ -21,38 +21,11 @@ jQuery(document).ready(function ($) {
21
  // enable the "add" button
22
  $('#add_field').removeAttr('disabled');
23
  // if only one element remains, disable the "remove" button
24
- if (num - 1 == 1)
25
  $('#del_field').attr('disabled', 'disabled');
 
26
  $('#event_span').hide();
27
  });
28
  $('#del_field').attr('disabled', 'disabled');
29
  $('#event_span').hide();
30
- });
31
-
32
- jQuery(document).ready(function ($) {
33
- $('#add_price').on('click', function () {
34
- var num = $('.clonedPrice').length; // how many "duplicatable" input fields we currently have
35
- var newNum = new Number(num + 1); // the numeric ID of the new input field being added
36
- // create the new element via clone(), and manipulate it's ID using newNum value
37
- var newElem = $('#price' + num).clone().attr('id', 'price' + newNum);
38
- // manipulate the name/id values of the input inside the new element
39
- // insert the new element after the last "duplicatable" input field
40
- $('#price' + num).after(newElem);
41
- // enable the "remove" button
42
- $('#del_price').removeAttr('disabled');
43
- // business rule: you can only add 6 variations
44
- if (newNum == 6)
45
- $('#add_price').attr('disabled', 'disabled');
46
- });
47
-
48
- $('#del_price').on('click', function () {
49
- var num = $('.clonedPrice').length; // how many "duplicatable" input fields we currently have
50
- $('#price' + num).remove(); // remove the last element
51
- // enable the "add" button
52
- $('#add_price').removeAttr('disabled');
53
- // if only one element remains, disable the "remove" button
54
- if (num - 1 == 1)
55
- $('#del_price').attr('disabled', 'disabled');
56
- });
57
- $('#del_price').attr('disabled', 'disabled');
58
  });
5
  var newNum = new Number(num + 1); // the numeric ID of the new input field being added
6
  // create the new element via clone(), and manipulate it's ID using newNum value
7
  var newElem = $('#event' + num).clone().attr('id', 'event' + newNum);
 
8
  // insert the new element after the last "duplicatable" input field
9
  $('#event' + num).after(newElem);
10
  // enable the "remove" button
11
  $('#del_field').removeAttr('disabled');
12
  // business rule: you can only add 10 occurrences
13
+ if ( newNum == 20 ) {
14
  $('#add_field').attr('disabled', 'disabled');
15
+ }
16
  });
17
 
18
  $('#del_field').on('click', function () {
21
  // enable the "add" button
22
  $('#add_field').removeAttr('disabled');
23
  // if only one element remains, disable the "remove" button
24
+ if ( num - 1 == 1 ) {
25
  $('#del_field').attr('disabled', 'disabled');
26
+ }
27
  $('#event_span').hide();
28
  });
29
  $('#del_field').attr('disabled', 'disabled');
30
  $('#event_span').hide();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  });
js/mc-ajax.js CHANGED
@@ -6,7 +6,7 @@
6
  var link = $(this).attr('href');
7
  var height = $('.mc-main.calendar' ).height();
8
  var ref = $(this).attr('data-rel');
9
- $('#' + ref).html('<div class=\"loading\" style=\"height:' + height + 'px\"><span>Loading...</span></div>');
10
  $('#' + ref).load(link + ' #' + ref + ' > *', function () {
11
  $('.calendar-event').children().not('.event-title').hide();
12
  $('#' + ref).attr('tabindex', '-1').focus();
@@ -17,7 +17,7 @@
17
  var link = $(this).attr('href');
18
  var ref = $(this).attr('data-rel');
19
  var height = $('.mc-main.list' ).height();
20
- $('#' + ref).html('<div class=\"loading\" style=\"height:' + height + 'px\"><span>Loading...</span></div>');
21
  $('#' + ref).load(link + ' #' + ref + ' > *', function () {
22
  $('li.mc-events').children().not('.event-date').hide();
23
  $('li.current-day').children().show();
@@ -29,7 +29,7 @@
29
  var link = $(this).attr('href');
30
  var ref = $(this).attr('data-rel');
31
  var height = $('.mc-main.mini' ).height();
32
- $('#' + ref).html('<div class=\"loading\" style=\"height:' + height + 'px\"><span>Loading...</span></div>');
33
  $('#' + ref).load(link + ' #' + ref + ' > *', function () {
34
  $('.mini .has-events').children().not('.trigger, .mc-date, .event-date').hide();
35
  $('#' + ref).attr('tabindex', '-1').focus();
6
  var link = $(this).attr('href');
7
  var height = $('.mc-main.calendar' ).height();
8
  var ref = $(this).attr('data-rel');
9
+ $('#' + ref).html('<div class=\"mc-loading\"></div><div class=\"loading\" style=\"height:' + height + 'px\"><span class="screen-reader-text">Loading...</span></div>');
10
  $('#' + ref).load(link + ' #' + ref + ' > *', function () {
11
  $('.calendar-event').children().not('.event-title').hide();
12
  $('#' + ref).attr('tabindex', '-1').focus();
17
  var link = $(this).attr('href');
18
  var ref = $(this).attr('data-rel');
19
  var height = $('.mc-main.list' ).height();
20
+ $('#' + ref).html('<div class=\"mc-loading\"></div><div class=\"loading\" style=\"height:' + height + 'px\"><span class="screen-reader-text">Loading...</span></div>');
21
  $('#' + ref).load(link + ' #' + ref + ' > *', function () {
22
  $('li.mc-events').children().not('.event-date').hide();
23
  $('li.current-day').children().show();
29
  var link = $(this).attr('href');
30
  var ref = $(this).attr('data-rel');
31
  var height = $('.mc-main.mini' ).height();
32
+ $('#' + ref).html('<div class=\"mc-loading\"></div><div class=\"loading\" style=\"height:' + height + 'px\"><span class="screen-reader-text">Loading...</span></div>');
33
  $('#' + ref).load(link + ' #' + ref + ' > *', function () {
34
  $('.mini .has-events').children().not('.trigger, .mc-date, .event-date').hide();
35
  $('#' + ref).attr('tabindex', '-1').focus();
js/mc-quicktags.js DELETED
@@ -1 +0,0 @@
1
- edButtons[edButtons.length] = new edButton('My Calendar', 'My Calendar', '[my_calendar]', '', '');
 
js/tabs.js CHANGED
@@ -20,4 +20,14 @@ jQuery(document).ready(function ($) {
20
  });
21
  }
22
  });
 
 
 
 
 
 
 
 
 
 
23
  });
20
  });
21
  }
22
  });
23
+
24
+ $( '#mc-generator .custom' ).hide();
25
+ $( '#mc-generator select[name=type]' ).on( 'change', function () {
26
+ var selected = $( this ).val();
27
+ if ( selected == 'custom' ) {
28
+ $( '#mc-generator .custom' ).show();
29
+ } else {
30
+ $( '#mc-generator .custom' ).hide();
31
+ }
32
+ });
33
  });
my-calendar-api.php CHANGED
@@ -355,15 +355,4 @@ function mc_generate_alert_ical( $alarm ) {
355
  $alert .= "END:VALARM";
356
 
357
  return $alert;
358
- }
359
-
360
- function mc_flatten_event_array( $events ) {
361
- $flat = array();
362
- foreach( $events as $event ) {
363
- foreach( $event as $e ) {
364
- $flat[] = $e;
365
- }
366
- }
367
-
368
- return $flat;
369
  }
355
  $alert .= "END:VALARM";
356
 
357
  return $alert;
 
 
 
 
 
 
 
 
 
 
 
358
  }
my-calendar-behaviors.php CHANGED
@@ -101,24 +101,24 @@ function edit_my_calendar_behaviors() {
101
  <label
102
  for="calendar-js"><?php _e( 'Calendar Behaviors: Grid View', 'my-calendar' ); ?></label><br/><textarea
103
  id="calendar-js" name="mc_caljs" rows="12"
104
- cols="80"><?php echo esc_js( $mc_caljs ); ?></textarea>
105
  </p>
106
  <p>
107
  <label
108
  for="list-js"><?php _e( 'Calendar Behaviors: List View', 'my-calendar' ); ?></label><br/><textarea
109
  id="list-js" name="mc_listjs" rows="12"
110
- cols="80"><?php echo esc_js( $mc_listjs ); ?></textarea>
111
  </p>
112
  <p>
113
  <label for="mini-js"><?php _e( 'Calendar Behaviors: Mini Calendar View', 'my-calendar' ); ?></label><br/><textarea
114
  id="mini-js" name="mc_minijs" rows="12"
115
- cols="80"><?php echo esc_js( $mc_minijs ); ?></textarea>
116
  </p>
117
  <p>
118
  <label
119
  for="ajax-js"><?php _e( 'Calendar Behaviors: AJAX', 'my-calendar' ); ?></label><br/><textarea
120
  id="ajax-js" name="mc_ajaxjs" rows="12"
121
- cols="80"><?php echo esc_js( $mc_ajaxjs ); ?></textarea>
122
  </p>
123
  <?php } ?>
124
  <p>
101
  <label
102
  for="calendar-js"><?php _e( 'Calendar Behaviors: Grid View', 'my-calendar' ); ?></label><br/><textarea
103
  id="calendar-js" name="mc_caljs" rows="12"
104
+ cols="80"><?php echo esc_textarea( $mc_caljs ); ?></textarea>
105
  </p>
106
  <p>
107
  <label
108
  for="list-js"><?php _e( 'Calendar Behaviors: List View', 'my-calendar' ); ?></label><br/><textarea
109
  id="list-js" name="mc_listjs" rows="12"
110
+ cols="80"><?php echo esc_textarea( $mc_listjs ); ?></textarea>
111
  </p>
112
  <p>
113
  <label for="mini-js"><?php _e( 'Calendar Behaviors: Mini Calendar View', 'my-calendar' ); ?></label><br/><textarea
114
  id="mini-js" name="mc_minijs" rows="12"
115
+ cols="80"><?php echo esc_textarea( $mc_minijs ); ?></textarea>
116
  </p>
117
  <p>
118
  <label
119
  for="ajax-js"><?php _e( 'Calendar Behaviors: AJAX', 'my-calendar' ); ?></label><br/><textarea
120
  id="ajax-js" name="mc_ajaxjs" rows="12"
121
+ cols="80"><?php echo esc_textarea( $mc_ajaxjs ); ?></textarea>
122
  </p>
123
  <?php } ?>
124
  <p>
my-calendar-categories.php CHANGED
@@ -3,6 +3,15 @@ if ( ! defined( 'ABSPATH' ) ) {
3
  exit;
4
  } // Exit if accessed directly
5
 
 
 
 
 
 
 
 
 
 
6
  // Function to handle the management of categories
7
 
8
  // This is a hack for people who don't have PHP installed with exif_imagetype
@@ -89,7 +98,7 @@ function my_calendar_manage_categories() {
89
  }
90
 
91
  if ( isset( $_POST['mode'] ) && $_POST['mode'] == 'add' ) {
92
- $term = wp_insert_term( wp_kses_post( $_POST['category_name'] ), 'mc-event-category' );
93
  if ( ! is_wp_error( $term ) ) {
94
  $term = $term['term_id'];
95
  } else {
@@ -103,7 +112,7 @@ function my_calendar_manage_categories() {
103
  'category_term' => $term
104
  );
105
 
106
- $add = array_map( 'wp_kses_post', $add );
107
 
108
 
109
  // actions and filters
@@ -249,12 +258,7 @@ function mc_edit_category_form( $view = 'edit', $catID = '' ) {
249
  } ?>"/>
250
  </div>
251
  <?php } ?>
252
- <fieldset>
253
- <legend><?php if ( $view == 'add' ) {
254
- _e( 'Add Category', 'my-calendar' );
255
- } else {
256
- _e( 'Edit Category', 'my-calendar' );
257
- } ?></legend><?php
258
  if ( ! empty( $cur_cat ) && is_object( $cur_cat ) ) {
259
  $color = ( strpos( $cur_cat->category_color, '#' ) !== 0 ) ? '#' : '';
260
  $color .= $cur_cat->category_color;
@@ -277,7 +281,7 @@ function mc_edit_category_form( $view = 'edit', $catID = '' ) {
277
  class="mc-color-input"
278
  size="10"
279
  maxlength="7"
280
- value="<?php echo esc_attr( $color ); ?>"/>
281
  </li>
282
  <li>
283
  <label for="cat_icon"><?php _e( 'Category Icon', 'my-calendar' ); ?></label> <select
@@ -302,19 +306,21 @@ function mc_edit_category_form( $view = 'edit', $catID = '' ) {
302
  } ?>
303
  <?php $checked = ( $view == 'add' ) ? '' : mc_is_checked( 'mc_default_category', $cur_cat->category_id, '', true ); ?>
304
  <?php $holiday_checked = ( $view == 'add' ) ? '' : mc_is_checked( 'mc_skip_holidays_category', $cur_cat->category_id, '', true ); ?>
 
 
305
  <input type="checkbox" value="on" name="category_private"
306
  id="cat_private"<?php echo $private_checked; ?> /> <label
307
- for="cat_private"><?php _e( 'Private category (logged-in users only)', 'my-calendar' ); ?></label>
308
- <input type="checkbox" value="on" name="mc_default_category"
309
  id="mc_default_category"<?php echo $checked; ?> /> <label
310
- for="mc_default_category"><?php _e( 'Default category', 'my-calendar' ); ?></label>
311
- <input type="checkbox" value="on" name="mc_skip_holidays_category"
312
  id="mc_shc"<?php echo $holiday_checked; ?> /> <label
313
- for="mc_shc"><?php _e( 'Holiday Category', 'my-calendar' ); ?></label>
 
314
  </li>
315
  <?php echo apply_filters( 'mc_category_fields', '', $cur_cat ); ?>
316
  </ul>
317
- </fieldset>
318
  <p>
319
  <input type="submit" name="save" class="button-primary"
320
  value="<?php if ( $view == 'add' ) {
@@ -400,18 +406,18 @@ function mc_manage_categories() {
400
  ?>
401
  <tr class="<?php echo $class; ?>">
402
  <th scope="row"><?php echo $cat->category_id; ?></th>
403
- <td><?php echo stripslashes( wp_kses_post( $cat->category_name ) );
404
  if ( $cat->category_id == get_option( 'mc_default_category' ) ) {
405
- echo ' ' . __( '(Default)' );
406
  }
407
  if ( $cat->category_id == get_option( 'mc_skip_holidays_category' ) ) {
408
- echo ' ' . __( '(Holiday)' );
409
  } ?></td>
410
- <td style="background-color:<?php echo $background; ?>;color: <?php echo $foreground; ?>"><?php echo ( $icon_src ) ? "<img src='$icon_src' alt='' />" : ''; ?> <?php echo $background; ?></td>
411
  <td><?php echo ( $cat->category_private == 1 ) ? __( 'Yes', 'my-calendar' ) : __( 'No', 'my-calendar' ); ?></td>
412
  <td><a
413
  href="<?php echo admin_url( "admin.php?page=my-calendar-categories&amp;mode=edit&amp;category_id=$cat->category_id" ); ?>"
414
- class='edit'><?php _e( 'Edit', 'my-calendar' ); ?></a></td><?php
415
  if ( $cat->category_id == 1 ) {
416
  echo '<td>' . __( 'N/A', 'my-calendar' ) . '</td>';
417
  } else {
@@ -419,7 +425,7 @@ function mc_manage_categories() {
419
  <td><a
420
  href="<?php echo admin_url( "admin.php?page=my-calendar-categories&amp;mode=delete&amp;category_id=$cat->category_id" ); ?>"
421
  class="delete"
422
- onclick="return confirm('<?php _e( 'Are you sure you want to delete this category?', 'my-calendar' ); ?>')"><?php _e( 'Delete', 'my-calendar' ); ?></a>
423
  </td><?php
424
  } ?>
425
  </tr><?php
@@ -428,4 +434,60 @@ function mc_manage_categories() {
428
  } else {
429
  echo '<p>' . __( 'There are no categories in the database - or something has gone wrong!', 'my-calendar' ) . '</p>';
430
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
431
  }
3
  exit;
4
  } // Exit if accessed directly
5
 
6
+
7
+ function mc_update_category( $field, $data, $category ) {
8
+ global $wpdb;
9
+ $field = sanitize_key( $field );
10
+ $result = $wpdb->query( $wpdb->prepare( "UPDATE " . my_calendar_categories_table() . " SET $field = %d WHERE category_id=%d", $data, $category ) );
11
+
12
+ return $result;
13
+ }
14
+
15
  // Function to handle the management of categories
16
 
17
  // This is a hack for people who don't have PHP installed with exif_imagetype
98
  }
99
 
100
  if ( isset( $_POST['mode'] ) && $_POST['mode'] == 'add' ) {
101
+ $term = wp_insert_term( strip_tags( $_POST['category_name'] ), 'mc-event-category' );
102
  if ( ! is_wp_error( $term ) ) {
103
  $term = $term['term_id'];
104
  } else {
112
  'category_term' => $term
113
  );
114
 
115
+ $add = array_map( 'mc_kses_post', $add );
116
 
117
 
118
  // actions and filters
258
  } ?>"/>
259
  </div>
260
  <?php } ?>
261
+ <?php
 
 
 
 
 
262
  if ( ! empty( $cur_cat ) && is_object( $cur_cat ) ) {
263
  $color = ( strpos( $cur_cat->category_color, '#' ) !== 0 ) ? '#' : '';
264
  $color .= $cur_cat->category_color;
281
  class="mc-color-input"
282
  size="10"
283
  maxlength="7"
284
+ value="<?php echo ( $color != '#' ) ? esc_attr( $color ) : ''; ?>"/>
285
  </li>
286
  <li>
287
  <label for="cat_icon"><?php _e( 'Category Icon', 'my-calendar' ); ?></label> <select
306
  } ?>
307
  <?php $checked = ( $view == 'add' ) ? '' : mc_is_checked( 'mc_default_category', $cur_cat->category_id, '', true ); ?>
308
  <?php $holiday_checked = ( $view == 'add' ) ? '' : mc_is_checked( 'mc_skip_holidays_category', $cur_cat->category_id, '', true ); ?>
309
+ <ul class='checkboxes'>
310
+ <li>
311
  <input type="checkbox" value="on" name="category_private"
312
  id="cat_private"<?php echo $private_checked; ?> /> <label
313
+ for="cat_private"><?php _e( 'Private category (logged-in users only)', 'my-calendar' ); ?></label></li>
314
+ <li><input type="checkbox" value="on" name="mc_default_category"
315
  id="mc_default_category"<?php echo $checked; ?> /> <label
316
+ for="mc_default_category"><?php _e( 'Default category', 'my-calendar' ); ?></label></li>
317
+ <li><input type="checkbox" value="on" name="mc_skip_holidays_category"
318
  id="mc_shc"<?php echo $holiday_checked; ?> /> <label
319
+ for="mc_shc"><?php _e( 'Holiday Category', 'my-calendar' ); ?></label></li>
320
+ </ul>
321
  </li>
322
  <?php echo apply_filters( 'mc_category_fields', '', $cur_cat ); ?>
323
  </ul>
 
324
  <p>
325
  <input type="submit" name="save" class="button-primary"
326
  value="<?php if ( $view == 'add' ) {
406
  ?>
407
  <tr class="<?php echo $class; ?>">
408
  <th scope="row"><?php echo $cat->category_id; ?></th>
409
+ <td><?php echo stripslashes( mc_kses_post( $cat->category_name ) );
410
  if ( $cat->category_id == get_option( 'mc_default_category' ) ) {
411
+ echo ' <strong>' . __( '(Default)' ) . '</strong>';
412
  }
413
  if ( $cat->category_id == get_option( 'mc_skip_holidays_category' ) ) {
414
+ echo ' <strong>' . __( '(Holiday)' ) . '</strong>';
415
  } ?></td>
416
+ <td style="background-color:<?php echo $background; ?>;color: <?php echo $foreground; ?>"><?php echo ( $icon_src ) ? "<img src='$icon_src' alt='' />" : ''; ?> <?php echo ( $background != '#' ) ? $background : ''; ?></td>
417
  <td><?php echo ( $cat->category_private == 1 ) ? __( 'Yes', 'my-calendar' ) : __( 'No', 'my-calendar' ); ?></td>
418
  <td><a
419
  href="<?php echo admin_url( "admin.php?page=my-calendar-categories&amp;mode=edit&amp;category_id=$cat->category_id" ); ?>"
420
+ class='edit'><?php printf( __( 'Edit %s', 'my-calendar' ), '<span class="screen-reader-text">' . stripslashes( mc_kses_post( $cat->category_name ) ) . '</span>' ); ?></a></td><?php
421
  if ( $cat->category_id == 1 ) {
422
  echo '<td>' . __( 'N/A', 'my-calendar' ) . '</td>';
423
  } else {
425
  <td><a
426
  href="<?php echo admin_url( "admin.php?page=my-calendar-categories&amp;mode=delete&amp;category_id=$cat->category_id" ); ?>"
427
  class="delete"
428
+ onclick="return confirm('<?php _e( 'Are you sure you want to delete this category?', 'my-calendar' ); ?>')"><?php printf( __( 'Delete %s', 'my-calendar' ), '<span class="screen-reader-text">' . stripslashes( mc_kses_post( $cat->category_name ) ) . '</span>' ); ?></a>
429
  </td><?php
430
  } ?>
431
  </tr><?php
434
  } else {
435
  echo '<p>' . __( 'There are no categories in the database - or something has gone wrong!', 'my-calendar' ) . '</p>';
436
  }
437
+ }
438
+
439
+
440
+ add_action( 'show_user_profile', 'mc_profile' );
441
+ add_action( 'edit_user_profile', 'mc_profile' );
442
+ add_action( 'profile_update', 'mc_save_profile' );
443
+ /**
444
+ * Show user profile data on Edit User pages.
445
+ *
446
+ * return @string Configuration forms for My Calendar user-specific settings.
447
+ */
448
+ function mc_profile() {
449
+ global $user_ID;
450
+ $current_user = wp_get_current_user();
451
+ $user_edit = ( isset( $_GET['user_id'] ) ) ? (int) $_GET['user_id'] : $user_ID;
452
+
453
+ if ( user_can( $user_edit, 'mc_manage_events' ) && current_user_can( 'manage_options' ) ) {
454
+ $permissions = (array) get_user_meta( $user_edit, 'mc_user_permissions', true );
455
+ $selected = ( empty( $permissions ) || in_array( 'all', $permissions ) ) ? ' selected="selected"' : '';
456
+ ?>
457
+ <h3><?php _e( 'My Calendar Editor Permissions', 'my-calendar' ); ?></h3>
458
+ <table class="form-table">
459
+ <tr>
460
+ <th scope="row">
461
+ <label for="mc_user_permissions"><?php _e( "Allowed Categories", 'my-calendar' ); ?></label>
462
+ </th>
463
+ <td>
464
+ <select name="mc_user_permissions[]" id="mc_user_permissions" multiple>
465
+ <option value='all'<?php echo $selected; ?>><?php _e( 'All', 'my-calendar' ); ?></option>
466
+ <?php echo mc_category_select( $permissions, true, 'multiple' ); ?>
467
+ </select>
468
+ </td>
469
+ </tr>
470
+ <?php echo apply_filters( 'mc_user_fields', '', $user_edit ); ?>
471
+ </table>
472
+ <?php
473
+ }
474
+ }
475
+
476
+ /**
477
+ * Save user profile data
478
+ */
479
+ function mc_save_profile() {
480
+ global $user_ID;
481
+ $current_user = wp_get_current_user();
482
+ if ( isset( $_POST['user_id'] ) ) {
483
+ $edit_id = (int) $_POST['user_id'];
484
+ } else {
485
+ $edit_id = $user_ID;
486
+ }
487
+ if ( current_user_can( 'manage_options' ) ) {
488
+ $mc_user_permission = $_POST['mc_user_permissions'];
489
+ update_user_meta( $edit_id, 'mc_user_permissions', $mc_user_permission );
490
+ }
491
+
492
+ apply_filters( 'mc_save_user', $edit_id, $_POST );
493
  }
my-calendar-core.php CHANGED
@@ -34,8 +34,12 @@ if ( ! function_exists( 'is_ssl' ) ) {
34
  }
35
  }
36
 
37
- // mod from Mike T
38
  function my_calendar_getUsers() {
 
 
 
 
 
39
  global $blog_id;
40
  $count = count_users( 'time' );
41
  $args = array(
@@ -51,7 +55,7 @@ function my_calendar_getUsers() {
51
 
52
  function mc_selected_users( $selected ) {
53
  $selected = explode( ',', $selected );
54
- $users = my_calendar_getUsers();
55
  $options = '';
56
  foreach ( $users as $u ) {
57
  if ( in_array( $u->ID, $selected ) ) {
@@ -60,7 +64,7 @@ function mc_selected_users( $selected ) {
60
  $checked = '';
61
  }
62
  $display_name = ( $u->display_name == '' ) ? $u->user_nicename : $u->display_name;
63
- $options = '<option value="' . $u->ID . '"' . $checked . ">$display_name</option>\n";
64
  }
65
 
66
  return $options;
@@ -168,11 +172,14 @@ function mc_register_styles() {
168
  $css_array = ( get_option( 'mc_show_css' ) != '' ) ? explode( ",", get_option( 'mc_show_css' ) ) : array();
169
  // check whether any scripts are actually enabled.
170
  if ( get_option( 'mc_calendar_javascript' ) != 1 || get_option( 'mc_list_javascript' ) != 1 || get_option( 'mc_mini_javascript' ) != 1 || get_option( 'mc_ajax_javascript' ) != 1 ) {
171
- if ( @in_array( $id, $js_array ) || get_option( 'mc_show_js' ) == '' ) {
172
  wp_enqueue_script( 'jquery' );
173
  if ( get_option( 'mc_gmap' ) == 'true' ) {
174
- wp_enqueue_script( 'gmaps', "https://maps.google.com/maps/api/js?sensor=true" );
175
- wp_enqueue_script( 'gmap3', plugins_url( 'js/gmap3.min.js', __FILE__ ), array( 'jquery' ) );
 
 
 
176
  }
177
  }
178
  }
@@ -206,7 +213,7 @@ function my_calendar_wp_head() {
206
  if ( @in_array( $id, $array ) || get_option( 'mc_show_css' ) == '' ) {
207
  // generate category colors
208
  $category_styles = $inv = $type = $alt = '';
209
- $categories = $mcdb->get_results( "SELECT * FROM " . MY_CALENDAR_CATEGORIES_TABLE . " ORDER BY category_id ASC" );
210
  foreach ( $categories as $category ) {
211
  $class = "mc_" . sanitize_title( $category->category_name );
212
  $hex = ( strpos( $category->category_color, '#' ) !== 0 ) ? '#' : '';
@@ -332,9 +339,9 @@ function my_calendar_write_js() {
332
  format: mc_time_format,
333
  editable: true
334
  });
335
- $('#mc-accordion').accordion({collapsible: true, active: false});
336
  <?php
337
- if ( function_exists( 'jd_doTwitterAPIPost' ) ) {
338
  ?>
339
  $('#mc_twitter').charCount({
340
  allowed: 140,
@@ -614,7 +621,7 @@ function my_calendar_exists() {
614
  $tables = $wpdb->get_results( "show tables;" );
615
  foreach ( $tables as $table ) {
616
  foreach ( $table as $value ) {
617
- if ( $value == MY_CALENDAR_TABLE ) {
618
  // if the table exists, then My Calendar was already installed.
619
  return true;
620
  }
@@ -663,7 +670,7 @@ function check_my_calendar() {
663
  '2.3.0',
664
  '2.3.11',
665
  '2.3.15',
666
- '2.4.4',
667
  );
668
  foreach ( $valid_upgrades as $upgrade ) {
669
  if ( version_compare( $current_version, $upgrade, "<" ) ) {
@@ -677,8 +684,10 @@ function check_my_calendar() {
677
  if ( $new_install == true ) {
678
  //add default settings
679
  mc_default_settings();
680
- $sql = "INSERT INTO " . MY_CALENDAR_CATEGORIES_TABLE . " SET category_id=1, category_name='General', category_color='#ffffcc', category_icon='event.png'";
681
  $mcdb->query( $sql );
 
 
682
  } else {
683
  // clear cache so updates are immediately available
684
  mc_delete_cache();
@@ -696,9 +705,11 @@ function check_my_calendar() {
696
  }
697
 
698
  function mc_do_upgrades( $upgrade_path ) {
 
 
699
  foreach ( $upgrade_path as $upgrade ) {
700
  switch ( $upgrade ) {
701
- case '2.4.15':
702
  update_option( 'mc_db_version', $mc_version );
703
  mc_upgrade_db();
704
  break;
@@ -783,7 +794,7 @@ function mc_do_upgrades( $upgrade_path ) {
783
  }
784
 
785
  // @data object with event_category value
786
- function mc_category_select( $data = false, $option = true ) {
787
  global $wpdb;
788
  $mcdb = $wpdb;
789
  if ( get_option( 'mc_remote' ) == 'true' && function_exists( 'mc_remote_db' ) ) {
@@ -796,6 +807,7 @@ function mc_category_select( $data = false, $option = true ) {
796
  if ( empty( $cats ) ) {
797
  // need to have categories. Try to create again.
798
  $insert = "INSERT INTO " . my_calendar_categories_table() . " SET category_id=1, category_name='General', category_color='#ffffcc', category_icon='event.png'";
 
799
  $mcdb->query( $insert );
800
  $cats = $mcdb->get_results( $sql );
801
  }
@@ -806,14 +818,22 @@ function mc_category_select( $data = false, $option = true ) {
806
  if ( ! empty( $data ) ) {
807
  if ( ! is_object( $data ) ) {
808
  $category = $data;
 
 
809
  } else {
810
  $category = $data->event_category;
811
  }
812
- if ( $category == $cat->category_id ) {
813
- $c .= ' selected="selected"';
 
 
 
 
 
 
814
  }
815
  }
816
- $c .= '>' . wp_kses_post( stripslashes( $cat->category_name ) ) . '</option>';
817
  if ( $cat->category_id != get_option( 'mc_default_category' ) ) {
818
  $list .= $c;
819
  } else {
@@ -851,7 +871,7 @@ function mc_location_select( $location = false ) {
851
  $l .= ' selected="selected"';
852
  }
853
  }
854
- $l .= '>' . wp_kses_post( stripslashes( $loc->location_label ) ) . '</option>';
855
  $list .= $l;
856
  }
857
 
@@ -992,22 +1012,36 @@ function my_calendar_is_odd( $int ) {
992
  }
993
 
994
  /* Unless an admin, authors can only edit their own events if they don't have mc_manage_events capabilities. */
995
- function mc_can_edit_event( $event_id = false ) {
996
  if ( ! is_user_logged_in() ) {
997
  return false;
998
  }
999
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1000
  $current_user = wp_get_current_user();
1001
  $user = $current_user->ID;
 
1002
 
1003
- if ( $event_id && is_numeric( $event_id ) ) {
1004
- $event = mc_get_event_core( $event_id );
1005
- $event_author = $event->event_author;
1006
  } else {
1007
- return false;
1008
  }
1009
 
1010
- if ( current_user_can( 'mc_manage_events' ) ) {
1011
  $return = true;
1012
  } else if ( $user == $event_author ) {
1013
  $return = true;
@@ -1018,6 +1052,16 @@ function mc_can_edit_event( $event_id = false ) {
1018
  return apply_filters( 'mc_can_edit_event', $return, $event_id );
1019
  }
1020
 
 
 
 
 
 
 
 
 
 
 
1021
  function jd_option_selected( $field, $value, $type = 'checkbox' ) {
1022
  switch ( $type ) {
1023
  case 'radio':
@@ -1098,95 +1142,6 @@ function my_calendar_admin_bar() {
1098
  }
1099
  }
1100
 
1101
- // functions to route db queries
1102
- function my_calendar_table() {
1103
- if ( is_multisite() ) {
1104
- $option = (int) get_site_option( 'mc_multisite' );
1105
- $choice = (int) get_option( 'mc_current_table' );
1106
- switch ( $option ) {
1107
- case 0:
1108
- return MY_CALENDAR_TABLE;
1109
- break;
1110
- case 1:
1111
- return MY_CALENDAR_GLOBAL_TABLE;
1112
- break;
1113
- case 2:
1114
- return ( $choice == 1 ) ? MY_CALENDAR_GLOBAL_TABLE : MY_CALENDAR_TABLE;
1115
- break;
1116
- default:
1117
- return MY_CALENDAR_TABLE;
1118
- }
1119
- } else {
1120
- return MY_CALENDAR_TABLE;
1121
- }
1122
- }
1123
-
1124
- function my_calendar_event_table() {
1125
- if ( is_multisite() ) {
1126
- $option = (int) get_site_option( 'mc_multisite' );
1127
- $choice = (int) get_option( 'mc_current_table' );
1128
- switch ( $option ) {
1129
- case 0:
1130
- return MY_CALENDAR_EVENTS_TABLE;
1131
- break;
1132
- case 1:
1133
- return MY_CALENDAR_GLOBAL_EVENT_TABLE;
1134
- break;
1135
- case 2:
1136
- return ( $choice == 1 ) ? MY_CALENDAR_GLOBAL_EVENT_TABLE : MY_CALENDAR_EVENTS_TABLE;
1137
- break;
1138
- default:
1139
- return MY_CALENDAR_EVENTS_TABLE;
1140
- }
1141
- } else {
1142
- return MY_CALENDAR_EVENTS_TABLE;
1143
- }
1144
- }
1145
-
1146
- function my_calendar_categories_table() {
1147
- if ( is_multisite() ) {
1148
- $option = (int) get_site_option( 'mc_multisite' );
1149
- $choice = (int) get_option( 'mc_current_table' );
1150
- switch ( $option ) {
1151
- case 0:
1152
- return MY_CALENDAR_CATEGORIES_TABLE;
1153
- break;
1154
- case 1:
1155
- return MY_CALENDAR_GLOBAL_CATEGORIES_TABLE;
1156
- break;
1157
- case 2:
1158
- return ( $choice == 1 ) ? MY_CALENDAR_GLOBAL_CATEGORIES_TABLE : MY_CALENDAR_CATEGORIES_TABLE;
1159
- break;
1160
- default:
1161
- return MY_CALENDAR_CATEGORIES_TABLE;
1162
- }
1163
- } else {
1164
- return MY_CALENDAR_CATEGORIES_TABLE;
1165
- }
1166
- }
1167
-
1168
- function my_calendar_locations_table() {
1169
- if ( is_multisite() ) {
1170
- $option = (int) get_site_option( 'mc_multisite' );
1171
- $choice = (int) get_option( 'mc_current_table' );
1172
- switch ( $option ) {
1173
- case 0:
1174
- return MY_CALENDAR_LOCATIONS_TABLE;
1175
- break;
1176
- case 1:
1177
- return MY_CALENDAR_GLOBAL_LOCATIONS_TABLE;
1178
- break;
1179
- case 2:
1180
- return ( $choice == 1 ) ? MY_CALENDAR_GLOBAL_LOCATIONS_TABLE : MY_CALENDAR_LOCATIONS_TABLE;
1181
- break;
1182
- default:
1183
- return MY_CALENDAR_LOCATIONS_TABLE;
1184
- }
1185
- } else {
1186
- return MY_CALENDAR_LOCATIONS_TABLE;
1187
- }
1188
- }
1189
-
1190
  // Mail functions (originally by Roland)
1191
  function my_calendar_send_email( $event ) {
1192
  $details = mc_create_tags( $event );
@@ -1340,6 +1295,7 @@ function mc_scripts() {
1340
  wp_enqueue_script( 'mc.ajax', plugins_url( 'js/ajax.js', __FILE__ ), array( 'jquery' ) );
1341
  wp_localize_script( 'mc.ajax', 'mc_data', array(
1342
  'action' => 'delete_occurrence',
 
1343
  'security' => wp_create_nonce( 'mc-delete-nonce' )
1344
  ) );
1345
  }
@@ -1383,6 +1339,61 @@ function mc_ajax_delete_occurrence() {
1383
  }
1384
 
1385
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1386
  function mc_newline_replace( $string ) {
1387
  return (string) str_replace( array( "\r", "\r\n", "\n" ), '', $string );
1388
  }
@@ -1979,7 +1990,7 @@ function mc_register_actions() {
1979
  add_action( 'mc_transition_event', 'mc_tweet_approval', 10, 2 );
1980
  add_action( 'mc_save_event', 'mc_event_post', 10, 3 );
1981
  add_action( 'mc_delete_event', 'mc_event_delete_post', 10, 2 );
1982
- add_action( 'mc_mass_delete_events', 'mc_event_delete_posts', 10, 2 );
1983
  add_action( 'parse_request', 'my_calendar_api' );
1984
  }
1985
 
@@ -1997,8 +2008,10 @@ function mc_event_delete_posts( $deleted ) {
1997
  'meta_key' => '_mc_event_id',
1998
  'meta_value' => $delete
1999
  ) );
2000
- $post_id = $posts[0]->ID;
2001
- wp_delete_post( $post_id, true );
 
 
2002
  }
2003
  }
2004
 
34
  }
35
  }
36
 
 
37
  function my_calendar_getUsers() {
38
+ return mc_get_users();
39
+ }
40
+
41
+ // mod from Mike T
42
+ function mc_get_users() {
43
  global $blog_id;
44
  $count = count_users( 'time' );
45
  $args = array(
55
 
56
  function mc_selected_users( $selected ) {
57
  $selected = explode( ',', $selected );
58
+ $users = mc_get_users();
59
  $options = '';
60
  foreach ( $users as $u ) {
61
  if ( in_array( $u->ID, $selected ) ) {
64
  $checked = '';
65
  }
66
  $display_name = ( $u->display_name == '' ) ? $u->user_nicename : $u->display_name;
67
+ $options .= '<option value="' . $u->ID . '"' . $checked . ">$display_name</option>\n";
68
  }
69
 
70
  return $options;
172
  $css_array = ( get_option( 'mc_show_css' ) != '' ) ? explode( ",", get_option( 'mc_show_css' ) ) : array();
173
  // check whether any scripts are actually enabled.
174
  if ( get_option( 'mc_calendar_javascript' ) != 1 || get_option( 'mc_list_javascript' ) != 1 || get_option( 'mc_mini_javascript' ) != 1 || get_option( 'mc_ajax_javascript' ) != 1 ) {
175
+ if ( @in_array( $id, $js_array ) || get_option( 'mc_show_js' ) == '' || is_singular( 'mc-events' ) ) {
176
  wp_enqueue_script( 'jquery' );
177
  if ( get_option( 'mc_gmap' ) == 'true' ) {
178
+ $api_key = get_option( 'mc_gmap_api_key' );
179
+ if ( $api_key ) {
180
+ wp_enqueue_script( 'gmaps', "https://maps.googleapis.com/maps/api/js?key=$api_key" );
181
+ wp_enqueue_script( 'gmap3', plugins_url( 'js/gmap3.min.js', __FILE__ ), array( 'jquery' ) );
182
+ }
183
  }
184
  }
185
  }
213
  if ( @in_array( $id, $array ) || get_option( 'mc_show_css' ) == '' ) {
214
  // generate category colors
215
  $category_styles = $inv = $type = $alt = '';
216
+ $categories = $mcdb->get_results( "SELECT * FROM " . my_calendar_categories_table() . " ORDER BY category_id ASC" );
217
  foreach ( $categories as $category ) {
218
  $class = "mc_" . sanitize_title( $category->category_name );
219
  $hex = ( strpos( $category->category_color, '#' ) !== 0 ) ? '#' : '';
339
  format: mc_time_format,
340
  editable: true
341
  });
342
+ $('#mc-accordion').accordion( { collapsible: true, active: false, heightStyle: 'content' } );
343
  <?php
344
+ if ( function_exists( 'jd_doTwitterAPIPost' ) && isset( $_GET['page'] ) && $_GET['page'] == 'my-calendar' ) {
345
  ?>
346
  $('#mc_twitter').charCount({
347
  allowed: 140,
621
  $tables = $wpdb->get_results( "show tables;" );
622
  foreach ( $tables as $table ) {
623
  foreach ( $table as $value ) {
624
+ if ( $value == my_calendar_table() ) {
625
  // if the table exists, then My Calendar was already installed.
626
  return true;
627
  }
670
  '2.3.0',
671
  '2.3.11',
672
  '2.3.15',
673
+ '2.5.0',
674
  );
675
  foreach ( $valid_upgrades as $upgrade ) {
676
  if ( version_compare( $current_version, $upgrade, "<" ) ) {
684
  if ( $new_install == true ) {
685
  //add default settings
686
  mc_default_settings();
687
+ $sql = "INSERT INTO " . my_calendar_categories_table() . " SET category_id=1, category_name='General', category_color='#ffffcc', category_icon='event.png'";
688
  $mcdb->query( $sql );
689
+ $term = wp_insert_term( 'General', 'mc-event-category' );
690
+
691
  } else {
692
  // clear cache so updates are immediately available
693
  mc_delete_cache();
705
  }
706
 
707
  function mc_do_upgrades( $upgrade_path ) {
708
+ global $mc_version;
709
+
710
  foreach ( $upgrade_path as $upgrade ) {
711
  switch ( $upgrade ) {
712
+ case '2.5.0':
713
  update_option( 'mc_db_version', $mc_version );
714
  mc_upgrade_db();
715
  break;
794
  }
795
 
796
  // @data object with event_category value
797
+ function mc_category_select( $data = false, $option = true, $multiple = false ) {
798
  global $wpdb;
799
  $mcdb = $wpdb;
800
  if ( get_option( 'mc_remote' ) == 'true' && function_exists( 'mc_remote_db' ) ) {
807
  if ( empty( $cats ) ) {
808
  // need to have categories. Try to create again.
809
  $insert = "INSERT INTO " . my_calendar_categories_table() . " SET category_id=1, category_name='General', category_color='#ffffcc', category_icon='event.png'";
810
+ $term = wp_insert_term( 'General', 'mc-event-category' );
811
  $mcdb->query( $insert );
812
  $cats = $mcdb->get_results( $sql );
813
  }
818
  if ( ! empty( $data ) ) {
819
  if ( ! is_object( $data ) ) {
820
  $category = $data;
821
+ } else if ( is_array( $data ) && $multiple ) {
822
+ $category = $data;
823
  } else {
824
  $category = $data->event_category;
825
  }
826
+ if ( $multiple ) {
827
+ if ( in_array( $cat->category_id, $category ) ) {
828
+ $c .= ' selected="selected"';
829
+ }
830
+ } else {
831
+ if ( $category == $cat->category_id ) {
832
+ $c .= ' selected="selected"';
833
+ }
834
  }
835
  }
836
+ $c .= '>' . mc_kses_post( stripslashes( $cat->category_name ) ) . '</option>';
837
  if ( $cat->category_id != get_option( 'mc_default_category' ) ) {
838
  $list .= $c;
839
  } else {
871
  $l .= ' selected="selected"';
872
  }
873
  }
874
+ $l .= '>' . mc_kses_post( stripslashes( $loc->location_label ) ) . '</option>';
875
  $list .= $l;
876
  }
877
 
1012
  }
1013
 
1014
  /* Unless an admin, authors can only edit their own events if they don't have mc_manage_events capabilities. */
1015
+ function mc_can_edit_event( $event = false ) {
1016
  if ( ! is_user_logged_in() ) {
1017
  return false;
1018
  }
1019
 
1020
+ if ( !$event ) {
1021
+ return false;
1022
+ }
1023
+
1024
+ if ( is_object( $event ) ) {
1025
+ $event_id = $event->event_id;
1026
+ $event_author = $event->event_author;
1027
+ } else {
1028
+ $event_id = $event;
1029
+ $event = mc_get_event_core( $event );
1030
+ $event_author = $event->event_author;
1031
+ }
1032
+
1033
+
1034
  $current_user = wp_get_current_user();
1035
  $user = $current_user->ID;
1036
+ $has_permissions = mc_can_edit_category( $event->event_category, $user );
1037
 
1038
+ if ( !is_object( $event ) ) {
1039
+ $event_author = 0;
 
1040
  } else {
1041
+ $event_author = $event->event_author;
1042
  }
1043
 
1044
+ if ( current_user_can( 'mc_manage_events' ) && $has_permissions ) {
1045
  $return = true;
1046
  } else if ( $user == $event_author ) {
1047
  $return = true;
1052
  return apply_filters( 'mc_can_edit_event', $return, $event_id );
1053
  }
1054
 
1055
+ function mc_can_edit_category( $category, $user ) {
1056
+ $permissions = get_user_meta( $user, 'mc_user_permissions', true );
1057
+
1058
+ if ( empty( $permissions ) || in_array( 'all', $permissions ) || in_array( $category, $permissions ) ) {
1059
+ return true;
1060
+ }
1061
+
1062
+ return false;
1063
+ }
1064
+
1065
  function jd_option_selected( $field, $value, $type = 'checkbox' ) {
1066
  switch ( $type ) {
1067
  case 'radio':
1142
  }
1143
  }
1144
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1145
  // Mail functions (originally by Roland)
1146
  function my_calendar_send_email( $event ) {
1147
  $details = mc_create_tags( $event );
1295
  wp_enqueue_script( 'mc.ajax', plugins_url( 'js/ajax.js', __FILE__ ), array( 'jquery' ) );
1296
  wp_localize_script( 'mc.ajax', 'mc_data', array(
1297
  'action' => 'delete_occurrence',
1298
+ 'recur' => 'add_date',
1299
  'security' => wp_create_nonce( 'mc-delete-nonce' )
1300
  ) );
1301
  }
1339
  }
1340
 
1341
 
1342
+ add_action( 'wp_ajax_add_date', 'mc_ajax_add_date' );
1343
+ /**
1344
+ * Add a single additional date for an event from the event manager.
1345
+ *
1346
+ * @return string Confirmation message indicating success or failure.
1347
+ */
1348
+ function mc_ajax_add_date() {
1349
+ if ( ! check_ajax_referer( 'mc-delete-nonce', 'security', false ) ) {
1350
+ wp_send_json( array( 'success'=>0, 'response' => __( "Invalid Security Check", 'my-calendar' ) ) );
1351
+ }
1352
+
1353
+ if ( current_user_can( 'mc_manage_events' ) ) {
1354
+
1355
+ global $wpdb;
1356
+ $mcdb = $wpdb;
1357
+ $event_id = (int) $_REQUEST['event_id'];
1358
+
1359
+ if ( $event_id === 0 ) {
1360
+ wp_send_json( array( 'success' => 0, 'response' => __( 'No event ID in that request.', 'my-calendar' ) ) );
1361
+ }
1362
+
1363
+ $event_date = $_REQUEST['event_date'];
1364
+ $event_end = isset( $_REQUEST['event_end'] ) ? $_REQUEST['event_end'] : $event_date;
1365
+ $event_time = $_REQUEST['event_time'];
1366
+ $event_endtime = isset( $_REQUEST['event_endtime'] ) ? $_REQUEST['event_endtime'] : '';
1367
+ $group_id = (int) $_REQUEST['group_id'];
1368
+
1369
+ // event end can not be earlier than event start
1370
+ if ( ! $event_end || strtotime( $event_end ) < strtotime( $event_date ) ) {
1371
+ $event_end = $event_date;
1372
+ }
1373
+
1374
+ $begin = strtotime( $event_date . ' ' . $event_time );
1375
+ $end = ( $event_endtime != '' ) ? strtotime( $event_end . ' ' . $event_endtime ) : strtotime( $event_end . ' ' . $event_time ) + HOUR_IN_SECONDS;
1376
+
1377
+ $format = array( '%d', '%s', '%s', '%d' );
1378
+ $data = array(
1379
+ 'occur_event_id' => $event_id,
1380
+ 'occur_begin' => date( 'Y-m-d H:i:s', $begin ),
1381
+ 'occur_end' => date( 'Y-m-d H:i:s', $end ),
1382
+ 'occur_group_id' => $group_id
1383
+ );
1384
+ $result = $wpdb->insert( my_calendar_event_table(), $data, $format );
1385
+
1386
+ if ( $result ) {
1387
+ wp_send_json( array( 'success'=>1, 'response' => __( 'Thanks! I added your new date.', 'my-calendar' ) ) );
1388
+ } else {
1389
+ wp_send_json( array( 'success'=>0, 'response' => __( 'Sorry! I failed to add that date.', 'my-calendar' ) ) );
1390
+ }
1391
+
1392
+ } else {
1393
+ wp_send_json( array( 'success'=>0, 'response' => __( 'You are not authorized to perform this action', 'my-calendar' ) ) );
1394
+ }
1395
+ }
1396
+
1397
  function mc_newline_replace( $string ) {
1398
  return (string) str_replace( array( "\r", "\r\n", "\n" ), '', $string );
1399
  }
1990
  add_action( 'mc_transition_event', 'mc_tweet_approval', 10, 2 );
1991
  add_action( 'mc_save_event', 'mc_event_post', 10, 3 );
1992
  add_action( 'mc_delete_event', 'mc_event_delete_post', 10, 2 );
1993
+ add_action( 'mc_mass_delete_events', 'mc_event_delete_posts', 10, 1 );
1994
  add_action( 'parse_request', 'my_calendar_api' );
1995
  }
1996
 
2008
  'meta_key' => '_mc_event_id',
2009
  'meta_value' => $delete
2010
  ) );
2011
+ if ( isset( $posts[0] ) && is_object( $posts[0] ) ) {
2012
+ $post_id = $posts[0]->ID;
2013
+ wp_delete_post( $post_id, true );
2014
+ }
2015
  }
2016
  }
2017
 
my-calendar-db.php ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( ! defined( 'ABSPATH' ) ) {
3
+ exit;
4
+ } // Exit if accessed directly
5
+
6
+ // Define the table constants used in My Calendar in case anybody is still using them.
7
+ if ( is_multisite() && get_site_option( 'mc_multisite_show' ) == 1 ) {
8
+ define( 'MY_CALENDAR_TABLE', $wpdb->base_prefix . 'my_calendar' );
9
+ define( 'MY_CALENDAR_EVENTS_TABLE', $wpdb->base_prefix . 'my_calendar_events' );
10
+ define( 'MY_CALENDAR_CATEGORIES_TABLE', $wpdb->base_prefix . 'my_calendar_categories' );
11
+ define( 'MY_CALENDAR_LOCATIONS_TABLE', $wpdb->base_prefix . 'my_calendar_locations' );
12
+ } else {
13
+ define( 'MY_CALENDAR_TABLE', $wpdb->prefix . 'my_calendar' );
14
+ define( 'MY_CALENDAR_EVENTS_TABLE', $wpdb->prefix . 'my_calendar_events' );
15
+ define( 'MY_CALENDAR_CATEGORIES_TABLE', $wpdb->prefix . 'my_calendar_categories' );
16
+ define( 'MY_CALENDAR_LOCATIONS_TABLE', $wpdb->prefix . 'my_calendar_locations' );
17
+ }
18
+
19
+ if ( is_multisite() ) {
20
+ // Define the tables used in My Calendar
21
+ define( 'MY_CALENDAR_GLOBAL_TABLE', $wpdb->base_prefix . 'my_calendar' );
22
+ define( 'MY_CALENDAR_GLOBAL_EVENT_TABLE', $wpdb->base_prefix . 'my_calendar_events' );
23
+ define( 'MY_CALENDAR_GLOBAL_CATEGORIES_TABLE', $wpdb->base_prefix . 'my_calendar_categories' );
24
+ define( 'MY_CALENDAR_GLOBAL_LOCATIONS_TABLE', $wpdb->base_prefix . 'my_calendar_locations' );
25
+ }
26
+
27
+ /**
28
+ * Handlers for backwards compatibility
29
+ */
30
+ function my_calendar_table( $site = false ) {
31
+ return my_calendar_select_table( 'my_calendar', $site );
32
+ }
33
+
34
+ function my_calendar_event_table( $site = false ) {
35
+ return my_calendar_select_table( 'my_calendar_events', $site );
36
+ }
37
+
38
+ function my_calendar_categories_table( $site = false ) {
39
+ return my_calendar_select_table( 'my_calendar_categories', $site );
40
+ }
41
+
42
+ function my_calendar_locations_table( $site = false ) {
43
+ return my_calendar_select_table( 'my_calendar_locations', $site );
44
+ }
45
+
46
+ /**
47
+ * Get table to query based on table data required & required site.
48
+ *
49
+ * @since 2.5.0
50
+ *
51
+ * @param string table name
52
+ * @param mixed 'global' to get global database; site ID to get that site's database; false for defaults according to settings.
53
+ *
54
+ * @return prefixed string table name
55
+ */
56
+ function my_calendar_select_table( $table = 'my_calendar_events', $site = false ) {
57
+ global $wpdb;
58
+ $local = $wpdb->prefix . $table;
59
+
60
+ if ( is_multisite() ) {
61
+ $option = (int) get_site_option( 'mc_multisite' );
62
+ $choice = (int) get_option( 'mc_current_table' );
63
+ $show = (int) get_site_option( 'mc_multisite_show' ); // 1 == use global instead of local
64
+
65
+ if ( $site == 'global' ) {
66
+ return $wpdb->base_prefix . $table;
67
+ }
68
+
69
+ if ( $site != false && $site ) {
70
+ $site = absint( $site );
71
+ $wpdb->set_blog_id( $site );
72
+ }
73
+
74
+ $local = ( $show == 1 ) ? $wpdb->base_prefix . $table : $wpdb->prefix . $table;
75
+ $global = $wpdb->base_prefix . $table;
76
+
77
+ switch ( $option ) {
78
+ case 0:
79
+ return $local;
80
+ break;
81
+ case 1:
82
+ return $global;
83
+ break;
84
+ case 2:
85
+ return ( $choice == 1 ) ? $global : $local;
86
+ break;
87
+ default:
88
+ return $local;
89
+ }
90
+ } else {
91
+ return $local;
92
+ }
93
+ }
my-calendar-event-manager.php CHANGED
@@ -3,45 +3,6 @@ if ( ! defined( 'ABSPATH' ) ) {
3
  exit;
4
  } // Exit if accessed directly
5
 
6
- function mc_switch_sites() {
7
- if ( function_exists( 'is_multisite' ) && is_multisite() ) {
8
- if ( get_site_option( 'mc_multisite' ) == 2 && MY_CALENDAR_TABLE != MY_CALENDAR_GLOBAL_TABLE ) {
9
- if ( get_option( 'mc_current_table' ) == '1' ) {
10
- // can post to either, but is currently set to post to central table
11
- return true;
12
- }
13
- } else if ( get_site_option( 'mc_multisite' ) == 1 && MY_CALENDAR_TABLE != MY_CALENDAR_GLOBAL_TABLE ) {
14
- // can only post to central table
15
- return true;
16
- }
17
- }
18
-
19
- return false;
20
- }
21
-
22
- add_action( 'admin_menu', 'mc_add_outer_box' );
23
-
24
- // begin add boxes
25
- function mc_add_outer_box() {
26
- add_meta_box( 'mcs_add_event', __('My Calendar Event', 'my-calendar'), 'mc_add_inner_box', 'mc-events', 'side','high' );
27
- }
28
-
29
- function mc_add_inner_box() {
30
- global $post;
31
- $event_id = get_post_meta( $post->ID, '_mc_event_id', true );
32
- if ( $event_id ) {
33
- $url = admin_url( 'admin.php?page=my-calendar&mode=edit&event_id='.$event_id );
34
- $event = mc_get_event_core( $event_id );
35
- $content = "<p><strong>" . wp_kses_post( $event->event_title ) . '</strong><br />' . $event->event_begin . ' @ ' . $event->event_time . "</p>";
36
- if ( $event->event_label != '' ) {
37
- $content .= "<p>" . sprintf( __( '<strong>Location:</strong> %s', 'my-calendar' ), wp_kses_post( $event->event_label ) ) . "</p>";
38
- }
39
- $content .= "<p>" . sprintf( __( '<a href="%s">Edit event</a>.', 'my-calendar' ), $url ) . "</p>";
40
-
41
- echo $content;
42
- }
43
- }
44
-
45
  function mc_event_post( $action, $data, $event_id ) {
46
  // if the event save was successful.
47
  if ( $action == 'add' || $action == 'copy' ) {
@@ -57,6 +18,13 @@ function mc_event_post( $action, $data, $event_id ) {
57
  mc_create_event_post( $data, $event_id );
58
  }
59
  $term = mc_get_category_detail( $data['event_category'], 'category_term' );
 
 
 
 
 
 
 
60
  $privacy = ( mc_get_category_detail( $data['event_category'], 'category_private' ) == 1 ) ? 'private' : 'publish';
61
  $title = $data['event_title'];
62
  $template = apply_filters( 'mc_post_template', 'details', $term );
@@ -177,22 +145,6 @@ function mc_update_event( $field, $data, $event, $type = '%d' ) {
177
  return $result;
178
  }
179
 
180
- function mc_update_category( $field, $data, $category ) {
181
- global $wpdb;
182
- $field = sanitize_key( $field );
183
- $result = $wpdb->query( $wpdb->prepare( "UPDATE " . my_calendar_categories_table() . " SET $field = %d WHERE category_id=%d", $data, $category ) );
184
-
185
- return $result;
186
- }
187
-
188
- function mc_update_location( $field, $data, $location ) {
189
- global $wpdb;
190
- $field = sanitize_key( $field );
191
- $result = $wpdb->query( $wpdb->prepare( "UPDATE " . my_calendar_locations_table() . " SET $field = %d WHERE location_id=%d", $data, $location ) );
192
-
193
- return $result;
194
- }
195
-
196
  /**
197
  * @param $event_id
198
  * @param $post_id
@@ -207,9 +159,10 @@ function manage_my_calendar() {
207
  global $wpdb;
208
  $mcdb = $wpdb;
209
  if ( isset( $_GET['mode'] ) && $_GET['mode'] == 'delete' ) {
210
- $sql = "SELECT event_title, event_author FROM " . my_calendar_table() . " WHERE event_id=" . (int) $_GET['event_id'];
 
211
  $result = $mcdb->get_results( $sql, ARRAY_A );
212
- if ( mc_can_edit_event( (int) $_GET['event_id'] ) ) {
213
  if ( isset( $_GET['date'] ) ) {
214
  $event_instance = (int) $_GET['date'];
215
  $sql = "SELECT occur_begin FROM " . my_calendar_event_table() . " WHERE occur_id=" . $event_instance;
@@ -231,7 +184,7 @@ function manage_my_calendar() {
231
  <input type="hidden" name="ref" value="<?php echo esc_url( $_GET['ref'] ); ?>"/>
232
  <?php } ?>
233
 
234
- <input type="hidden" name="event_id" value="<?php echo (int) $_GET['event_id']; ?>"/>
235
  <input type="submit" name="submit" class="button-secondary delete"
236
  value="<?php _e( 'Delete', 'my-calendar' );
237
  echo " &quot;" . stripslashes( $result[0]['event_title'] ) . "&quot; $instance_date"; ?>"/>
@@ -532,14 +485,6 @@ function edit_my_calendar() {
532
  </div><?php
533
  }
534
 
535
- function mc_tweet_approval( $prev, $new ) {
536
- if ( function_exists( 'jd_doTwitterAPIPost' ) && isset( $_POST['mc_twitter'] ) && trim( $_POST['mc_twitter'] ) != '' ) {
537
- if ( ( $prev == 0 || $prev == 2 ) && $new == 1 ) {
538
- jd_doTwitterAPIPost( stripslashes( $_POST['mc_twitter'] ) );
539
- }
540
- }
541
- }
542
-
543
  function my_calendar_save( $action, $output, $event_id = false ) {
544
  global $wpdb, $event_author;
545
  $mcdb = $wpdb;
@@ -600,6 +545,7 @@ function my_calendar_save( $action, $output, $event_id = false ) {
600
  } else {
601
  // do an action using the $action and processed event data
602
  $data = $add;
 
603
  do_action( 'mc_save_event', $action, $data, $event_id, $result );
604
  // Call mail function
605
  if ( get_option( 'mc_event_mail' ) == 'true' ) {
@@ -617,14 +563,19 @@ function my_calendar_save( $action, $output, $event_id = false ) {
617
  //$event_link = mc_build_url( array( 'mc_id' => $event_ids[0]->occur_id ), array( 'page' ), get_option( 'mc_uri' ) );
618
  //$event_link = add_query_arg( 'mc_id', $event_ids[0]->occur_id, get_option( 'mc_uri' ) );
619
  $event_link = mc_get_details_link( $event_ids[0]->occur_id );
 
620
  } else {
621
  $event_link = false;
622
  }
623
- $message = "<div class='updated notice'><p>" . __( 'Event added. It will now show on the calendar.', 'my-calendar' );
624
- if ( $event_link !== false ) {
625
- $message .= sprintf( __( ' <a href="%s">View Event</a>', 'my-calendar' ), $event_link );
 
 
 
 
 
626
  }
627
- $message .= "</p></div>";
628
  }
629
  mc_delete_cache();
630
  }
@@ -682,6 +633,8 @@ function my_calendar_save( $action, $output, $event_id = false ) {
682
  '%d' );
683
  $recur_changed = ( $update['event_repeats'] != $_POST['prev_event_repeats'] || $update['event_recur'] != $_POST['prev_event_recur'] ) ? true : false;
684
  if ( $date_changed || $recur_changed ) {
 
 
685
  mc_delete_instances( $event_id );
686
  mc_increment_event( $event_id );
687
  mc_delete_cache();
@@ -708,6 +661,20 @@ function my_calendar_save( $action, $output, $event_id = false ) {
708
  return array( 'event_id' => $event_id, 'message' => $message );
709
  }
710
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
711
  function mc_delete_event( $event_id ) {
712
  global $wpdb;
713
  $mcdb = $wpdb;
@@ -768,6 +735,15 @@ function mc_form_data( $event_id = false ) {
768
  // The event edit form for the manage events admin page
769
  function mc_edit_event_form( $mode = 'add', $event_id = false ) {
770
  global $users_entries;
 
 
 
 
 
 
 
 
 
771
  if ( $event_id != false ) {
772
  $data = mc_form_data( $event_id );
773
  } else {
@@ -779,6 +755,7 @@ function mc_edit_event_form( $mode = 'add', $event_id = false ) {
779
  $message = "";
780
  }
781
  echo ( $message != '' ) ? "<div class='error'><p>$message</p></div>" : '';
 
782
  mc_form_fields( $data, $mode, $event_id );
783
  }
784
 
@@ -821,7 +798,7 @@ function mc_show_edit_block( $field ) {
821
  }
822
  }
823
 
824
- function mc_show_block( $field, $has_data, $data, $echo = true ) {
825
  global $user_ID;
826
  $return = $checked = $value = '';
827
  $show_block = mc_show_edit_block( $field );
@@ -830,7 +807,7 @@ function mc_show_block( $field, $has_data, $data, $echo = true ) {
830
  switch ( $field ) {
831
  case 'event_host' :
832
  if ( $show_block ) {
833
- $users = my_calendar_getUsers();
834
  $select = '';
835
  foreach ( $users as $u ) {
836
  $display_name = ( $u->display_name == '' ) ? $u->user_nicename : $u->display_name;
@@ -852,6 +829,26 @@ function mc_show_block( $field, $has_data, $data, $echo = true ) {
852
  </p>';
853
  }
854
  break;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
855
  case 'event_desc' :
856
  if ( $show_block ) {
857
  global $current_screen;
@@ -859,13 +856,13 @@ function mc_show_block( $field, $has_data, $data, $echo = true ) {
859
  $value = ( $has_data ) ? stripslashes( $data->event_desc ) : '';
860
  if ( $current_screen->base == 'post' ) {
861
  $return = '<div class="event_description">
862
- <label for="content">' . __( 'Event Description', 'my-calendar' ) . '</label><br />
863
  <textarea id="content" name="content" class="event_desc" rows="8" cols="80">' . stripslashes( esc_attr( $value ) ) . '</textarea>
864
  </div>';
865
  } else {
866
  echo '
867
  <div class="event_description">
868
- <label for="content">' . __( 'Event Description', 'my-calendar' ) . '</label><br />';
869
  if ( user_can_richedit() ) {
870
  wp_editor( $value, 'content', array( 'textarea_rows' => 10 ) );
871
  } else {
@@ -886,19 +883,24 @@ function mc_show_block( $field, $has_data, $data, $echo = true ) {
886
  break;
887
  case 'event_image' :
888
  if ( $show_block ) {
889
- $value = ( $has_data ) ? $data->event_image : '';
 
 
 
 
890
  $return = '
891
  <div class="mc-image-upload field-holder">
892
  <input type="hidden" name="event_image_id" value="" class="textfield" id="e_image_id" />
893
- <label for="e_image">' . __( "Add an image:", 'my-calendar' ) . '</label><br /><input type="text" name="event_image" id="e_image" size="60" value="' . esc_attr( $value ) . '" placeholder="http://yourdomain.com/image.jpg" /> <button class="button textfield-field">' . __( "Upload", 'my-calendar' ) . '</button>';
894
- if ( ! empty( $data->event_image ) ) {
895
- $return .= '<div class="event_image"><img src="' . esc_attr( $data->event_image ) . '" alt="" /></div>';
 
896
  } else {
897
  $return .= '<div class="event_image"></div>';
898
  }
899
  $return .= '</div>';
900
  } else {
901
- $return = '<input type="hidden" name="event_image" value="' . esc_attr( $value ) . '" />';
902
  }
903
  break;
904
  case 'event_category' :
@@ -1071,6 +1073,9 @@ function mc_test_occurrence_overlap( $data, $return = false ) {
1071
  $check = mc_increment_event( $data->event_id, array(), 'test' );
1072
  if ( my_calendar_date_xcomp( $check['occur_begin'], $data->event_end . '' . $data->event_endtime ) ) {
1073
  $warning = "<div class='error'><span class='problem-icon dashicons dashicons-performance'></span> <p><strong>" . __( 'Event hidden from public view.', 'my-calendar' ) . "</strong> " . __( 'This event ends after the next occurrence begins. Events must end <strong>before</strong> the next occurrence begins.', 'my-calendar' ) . "</p><p>" . sprintf( __( 'Event end date: <strong>%s %s</strong>. Next occurrence starts: <strong>%s</strong>', 'my-calendar' ), $data->event_end, $data->event_endtime, $check['occur_begin'] ) . "</p></div>";
 
 
 
1074
  }
1075
  }
1076
  if ( $return ) {
@@ -1096,47 +1101,59 @@ function mc_form_fields( $data, $mode, $event_id ) {
1096
  ?>
1097
 
1098
  <div class="postbox-container jcd-wide">
1099
- <div class="metabox-holder">
1100
- <?php if ( $mode == 'add' || $mode == 'copy' ) {
1101
- $edit_args = '';
1102
- } else {
1103
- $edit_args = "&amp;mode=$mode&amp;event_id=$event_id";
1104
- if ( $instance ) {
1105
- $edit_args .= "&amp;date=$instance";
1106
- }
1107
- }
1108
- ?>
1109
- <form id="my-calendar" method="post" action="<?php echo admin_url( 'admin.php?page=my-calendar' ) . $edit_args; ?>">
 
 
 
 
 
 
 
 
 
 
 
 
1110
  <div>
1111
- <input type="hidden" name="_wpnonce" value="<?php echo wp_create_nonce( 'my-calendar-nonce' ); ?>"/>
1112
  <?php if ( isset( $_GET['ref'] ) ) { ?>
1113
- <input type="hidden" name="ref" value="<?php echo esc_url( $_GET['ref'] ); ?>"/>
1114
  <?php } ?>
1115
- <input type="hidden" name="event_group_id" value="<?php if ( ! empty( $data->event_group_id ) && $mode != 'copy' ) {
1116
- echo $data->event_group_id;
1117
- } else {
1118
- echo mc_group_id();
1119
- } ?>"/>
1120
- <input type="hidden" name="event_action" value="<?php esc_attr_e( $mode ); ?>"/>
1121
  <?php if ( ! empty( $_GET['date'] ) ) { ?>
1122
  <input type="hidden" name="event_instance" value="<?php echo (int) $_GET['date']; ?>"/>
1123
  <?php } ?>
1124
  <input type="hidden" name="event_id" value="<?php echo (int) $event_id; ?>"/>
1125
- <?php if ( $mode == 'edit' ) { ?>
1126
- <input type='hidden' name='event_post' value="<?php echo $data->event_post; ?>"/>
1127
- <?php } ?>
1128
- <input type="hidden" name="event_author" value="<?php if ( $mode != 'edit' ) {
1129
- echo $user_ID;
1130
- } else {
1131
- echo $data->event_author;
1132
- } ?>"/>
1133
- <input type="hidden" name="event_nonce_name" value="<?php echo wp_create_nonce( 'event_nonce' ); ?>"/>
 
 
 
 
1134
  </div>
1135
 
1136
  <div class="ui-sortable meta-box-sortables">
1137
  <div class="postbox">
1138
  <?php
1139
- if ( isset( $_GET['mode'] ) && $_GET['mode'] == 'edit' ) {
1140
  $text = __( 'Edit Event', 'my-calendar' );
1141
  $args = '';
1142
  if ( isset( $_GET['date'] ) ) {
@@ -1145,16 +1162,12 @@ function mc_form_fields( $data, $mode, $event_id ) {
1145
  $args = "&amp;date=$id";
1146
  }
1147
  }
1148
- $delete = " &middot; <a href='" . admin_url( "admin.php?page=my-calendar-manage&amp;mode=delete&amp;event_id=$data->event_id$args" ) . "' class='delete'>" . __( 'Delete', 'my-calendar' ) . "</a>";
1149
  } else {
1150
  $text = __( 'Add Event', 'my-calendar' );
1151
  $delete = '';
1152
  }
1153
- $post_id = ( $has_data ) ? $data->event_post : false;
1154
- if ( $has_data && ! $data->event_post ) {
1155
- $array_data = (array) $data;
1156
- $post_id = mc_event_post( 'add', $array_data, $data->event_id );
1157
- }
1158
  if ( apply_filters( 'mc_use_permalinks', get_option( 'mc_use_permalinks' ) ) == 'true' ) {
1159
  $post_link = ( $post_id ) ? get_edit_post_link( $post_id ) : false;
1160
  $text_link = ( $post_link ) ? sprintf( " &middot; <a href='%s'>" . __( 'Edit Event Post', 'my-calendar' ) . "</a>", $post_link ) : '';
@@ -1240,7 +1253,7 @@ function mc_form_fields( $data, $mode, $event_id ) {
1240
  if ( function_exists( 'jd_doTwitterAPIPost' ) && current_user_can( 'wpt_can_tweet' ) ) {
1241
  if ( ! ( $mode == 'edit' && $data->event_approved == 1 ) ) {
1242
  ?>
1243
- <p>
1244
  <label
1245
  for='mc_twitter'><?php _e( 'Post to Twitter (via WP to Twitter)', 'my-calendar' ); ?></label><br/>
1246
  <textarea cols='70' rows='2' id='mc_twitter'
@@ -1252,6 +1265,7 @@ function mc_form_fields( $data, $mode, $event_id ) {
1252
  mc_show_block( 'event_short', $has_data, $data );
1253
  mc_show_block( 'event_image', $has_data, $data );
1254
  mc_show_block( 'event_host', $has_data, $data );
 
1255
  mc_show_block( 'event_category', $has_data, $data );
1256
  mc_show_block( 'event_link', $has_data, $data );
1257
  echo apply_filters( 'mc_event_details', '', $has_data, $data, 'admin' );
@@ -1294,19 +1308,19 @@ function mc_form_fields( $data, $mode, $event_id ) {
1294
  <em><?php _e( 'Enter start and end dates/times for each occurrence of the event.', 'my-calendar' ); ?></em>
1295
  </p>
1296
  <div>
1297
- <input type="button" id="add_field"
1298
- value="<?php _e( 'Add another occurrence', 'my-calendar' ); ?>" class="button"/>
1299
- <input type="button" id="del_field"
1300
- value="<?php _e( 'Remove last occurrence', 'my-calendar' ); ?>" class="button"/>
1301
  </div>
1302
  <?php } else { ?>
1303
  <div id='mc-accordion'>
1304
  <?php if ( $data->event_recur != 'S' ) { ?>
1305
- <h4><?php _e( 'Scheduled dates for this event', 'my-calendar' ); ?></h4>
1306
  <div>
 
1307
  <?php _e( 'Editing a single date of an event changes only that date. Editing the root event changes all events in the series.', 'my-calendar' ); ?>
 
1308
  <div class='mc_response' aria-live='assertive'></div>
1309
- <ul class="columns">
1310
  <?php if ( isset( $_GET['date'] ) ) {
1311
  $date = (int) $_GET['date'];
1312
  } else {
@@ -1314,13 +1328,18 @@ function mc_form_fields( $data, $mode, $event_id ) {
1314
  } ?>
1315
  <?php echo mc_instance_list( $data->event_id, $date ); ?>
1316
  </ul>
 
 
 
 
 
1317
  </div>
1318
  <?php } ?>
1319
  <?php if ( $data->event_group_id != 0 ) { ?>
1320
  <?php
1321
  $edit_group_url = admin_url( 'admin.php?page=my-calendar-groups&mode=edit&event_id=' . $data->event_id . '&group_id=' . $data->event_group_id );
1322
  ?>
1323
- <h4><?php _e( 'Related Events:', 'my-calendar' ); ?> (<a
1324
  href='<?php echo $edit_group_url; ?>'><?php _e( 'Edit group', 'my-calendar' ); ?></a>)
1325
  </h4>
1326
  <div>
@@ -1363,10 +1382,15 @@ if ( mc_show_edit_block( 'event_location' ) || mc_show_edit_block( 'event_locati
1363
  <option value="none"> --</option><?php
1364
  foreach ( $locs as $loc ) {
1365
  if ( is_object( $loc ) ) {
1366
- echo "<option value=\"" . $loc->location_id . "\">" . wp_kses_post( stripslashes( $loc->location_label ) ) . "</option>";
1367
  if ( is_object( $data ) ) {
1368
- if ( $loc->location_id == $data->event_location ) {
1369
- $current_location = "<span id='mc-current-location'>" . sprintf( __( 'Current location: %s', 'my-calendar' ), wp_kses_post( $loc->location_label ) ) . "</span>";
 
 
 
 
 
1370
  }
1371
  }
1372
  }
@@ -1459,7 +1483,7 @@ function mc_event_access() {
1459
  '10' => __( 'Large Print Playbill', 'my-calendar' ),
1460
  '11' => __( 'Sensory Friendly', 'my-calendar' ),
1461
  '12' => __( 'Other', 'my-calendar' )
1462
- )
1463
  );
1464
 
1465
  return $event_access;
@@ -1474,7 +1498,11 @@ function mc_event_accessibility( $form, $data, $label ) {
1474
  <ul class='accessibility-features checkboxes'>";
1475
  $access = apply_filters( 'mc_event_accessibility', mc_event_access() );
1476
  if ( ! empty( $data ) ) {
1477
- $events_access = get_post_meta( $data->event_post, '_mc_event_access', true );
 
 
 
 
1478
  }
1479
  foreach ( $access as $k => $a ) {
1480
  $id = "events_access_$k";
@@ -1883,13 +1911,11 @@ function mc_list_events() {
1883
  class="screen-reader-text"><?php _e( 'Show only: ', 'my-calendar' ); ?></span><?php echo( is_object( $author ) ? $author->display_name : $author ); ?>
1884
  </a></td>
1885
  <?php
1886
- $this_category = $event->event_category;
1887
- foreach ( $categories as $key => $value ) {
1888
- if ( $value->category_id == $this_category ) {
1889
- $this_cat = $categories[ $key ];
1890
- }
1891
  }
1892
- $color = strip_tags( $this_cat->category_color );
1893
  ?>
1894
  <td>
1895
  <div class="category-color"
@@ -1898,9 +1924,8 @@ function mc_list_events() {
1898
  <a class='mc_filter'
1899
  href='<?php echo admin_url( "admin.php?page=my-calendar-manage&amp;filter=$event->event_category&amp;restrict=category" ); ?>'
1900
  title="<?php _e( 'Filter by category', 'my-calendar' ); ?>"><span
1901
- class="screen-reader-text"><?php _e( 'Show only: ', 'my-calendar' ); ?></span><?php echo wp_kses_post( stripslashes( $this_cat->category_name ) ); ?>
1902
  </a></td>
1903
- <?php unset( $this_cat ); ?>
1904
  </tr>
1905
  <?php
1906
  }
@@ -1939,7 +1964,7 @@ function mc_list_events() {
1939
  }
1940
 
1941
  function mc_check_data( $action, $post, $i ) {
1942
- $post = apply_filters( 'mc_pre_checkdata', $post, $action, $i );
1943
  global $wpdb, $current_user, $users_entries;
1944
  $mcdb = $wpdb;
1945
  $submit = array();
@@ -1988,9 +2013,14 @@ function mc_check_data( $action, $post, $i ) {
1988
 
1989
  $begin = date( 'Y-m-d', strtotime( $begin ) );// regardless of entry format, convert.
1990
  $time = ! empty( $post['event_time'][ $i ] ) ? trim( $post['event_time'][ $i ] ) : '';
1991
- $endtime = ! empty( $post['event_endtime'][ $i ] ) ? trim( $post['event_endtime'][ $i ] ) : date( 'H:i:s', strtotime( $time . ' +1 hour' ) );
1992
- $endtime = ( $time == '' || $time == '00:00:00' ) ? '23:59:59' : $endtime; // set at 23:59:59 if all day.
1993
- $endtime = ( $endtime == '' ) ? '23:59:00' : date( 'H:i:00', strtotime( $endtime ) );
 
 
 
 
 
1994
  // prevent setting enddate to incorrect value on copy.
1995
  if ( strtotime( $end ) < strtotime( $begin ) && $action == 'copy' ) {
1996
  $end = date( 'Y-m-d', ( strtotime( $begin ) + ( strtotime( $post['prev_event_end'] ) - strtotime( $post['prev_event_begin'] ) ) ) );
@@ -1998,15 +2028,22 @@ function mc_check_data( $action, $post, $i ) {
1998
  if ( isset( $post['event_allday'] ) && (int) $post['event_allday'] !== 0 ) {
1999
  $time = '00:00:00'; $endtime = '23:59:59';
2000
  }
 
 
 
 
 
2001
  $end = date( 'Y-m-d', strtotime( $end ) ); // regardless of entry format, convert.
2002
  $repeats = ( isset( $post['event_repeats'] ) ) ? trim( $post['event_repeats'] ) : 0;
2003
  $host = ! empty( $post['event_host'] ) ? $post['event_host'] : $current_user->ID;
2004
- $category = ! empty( $post['event_category'] ) ? $post['event_category'] : '';
 
 
 
2005
  $event_link = ! empty( $post['event_link'] ) ? trim( $post['event_link'] ) : '';
2006
  $expires = ! empty( $post['event_link_expires'] ) ? $post['event_link_expires'] : '0';
2007
  $approved = ! empty( $post['event_approved'] ) ? $post['event_approved'] : '0';
2008
  $location_preset = ! empty( $post['location_preset'] ) ? $post['location_preset'] : '';
2009
- $event_author = ( ! empty( $post['event_author'] ) && is_numeric( $post['event_author'] ) ) ? $post['event_author'] : '';
2010
  $event_open = ( isset( $post['event_open'] ) && $post['event_open'] !== 0 ) ? $post['event_open'] : '2';
2011
  $event_tickets = ( isset( $post['event_tickets'] ) ) ? trim( $post['event_tickets'] ) : '';
2012
  $event_registration = ( isset( $post['event_registration'] ) ) ? trim( $post['event_registration'] ) : '';
@@ -2075,7 +2112,7 @@ function mc_check_data( $action, $post, $i ) {
2075
  'location_access' => ( is_array( $event_access ) ) ? serialize( $event_access ) : ''
2076
  );
2077
 
2078
- $add_loc = array_map( 'wp_kses_post', $add_loc );
2079
 
2080
  $loc_formats = array(
2081
  '%s',
@@ -2154,6 +2191,7 @@ function mc_check_data( $action, $post, $i ) {
2154
  if ( $errors == '' ) {
2155
  $current_user = wp_get_current_user();
2156
  $event_author = ( $event_author == $current_user->ID || current_user_can( 'mc_manage_events' ) ) ? $event_author : $current_user->ID;
 
2157
 
2158
  $ok = true;
2159
  $submit = array(
@@ -2185,7 +2223,7 @@ function mc_check_data( $action, $post, $i ) {
2185
  // integers
2186
  'event_repeats' => $repeats,
2187
  'event_author' => $event_author,
2188
- 'event_category' => $category,
2189
  'event_link_expires' => $expires,
2190
  'event_zoom' => $event_zoom,
2191
  'event_open' => $event_open,
@@ -2202,7 +2240,7 @@ function mc_check_data( $action, $post, $i ) {
2202
  'event_longitude' => $event_longitude,
2203
  'event_latitude' => $event_latitude
2204
  );
2205
- $submit = array_map( 'wp_kses_post', $submit );
2206
 
2207
  } else {
2208
  $ok = false;
@@ -2254,6 +2292,7 @@ function mc_check_data( $action, $post, $i ) {
2254
  $users_entries->event_tickets = $event_tickets;
2255
  $users_entries->event_registration = $event_registration;
2256
  }
 
2257
  $data = array( $ok, $users_entries, $submit, $errors );
2258
 
2259
  return $data;
@@ -2263,8 +2302,8 @@ function mcs_check_conflicts( $begin, $time, $end, $endtime, $event_label ) {
2263
  global $wpdb;
2264
  $select_location = ( $event_label != '' ) ? "event_label = '$event_label'AND" : '';
2265
  $event_query = "SELECT occur_id
2266
- FROM " . MY_CALENDAR_EVENTS_TABLE . "
2267
- JOIN " . MY_CALENDAR_TABLE . "
2268
  ON (event_id=occur_event_id)
2269
  WHERE $select_location
2270
  ( occur_begin BETWEEN '$begin $time'AND '$end $endtime'OR occur_end BETWEEN '$begin $time'AND '$end $endtime')";
@@ -2372,14 +2411,12 @@ function mc_instance_list( $id, $occur = false, $template = '<h3>{title}</h3>{de
2372
  $begin = "<span id='occur_date_$result->occur_id'>" . date_i18n( get_option( 'mc_date_format' ), strtotime( $result->occur_begin ) ) . ', ' . date( get_option( 'mc_time_format' ), strtotime( $result->occur_begin ) ) . "</span>";
2373
  if ( $result->occur_id == $occur ) {
2374
  $form_control = '';
2375
- $current = "<em>" . __( 'Editing: ', 'my-calendar' ) . "</em>";
2376
- $end = '';
2377
  } else {
2378
- $form_control = "<button class='delete_occurrence' data-value='$result->occur_id' />Delete $begin</button> ";
2379
- $current = "<a href='" . admin_url( 'admin.php?page=my-calendar' ) . "&amp;mode=edit&amp;event_id=$id&amp;date=$result->occur_id'>";
2380
- $end = "Edit<span class='screen-reader-text'> $begin</span></a>";
2381
  }
2382
- $output .= "<li>$form_control$current$end</li>";
2383
  }
2384
  } else {
2385
  $details = '';
@@ -2387,9 +2424,11 @@ function mc_instance_list( $id, $occur = false, $template = '<h3>{title}</h3>{de
2387
  $event_id = $result->occur_id;
2388
  $event = mc_get_event( $event_id );
2389
  $array = mc_create_tags( $event );
2390
- if ( in_array( $template, array( 'details', 'grid', 'list', 'mini' ) ) ) {
2391
  if ( get_option( 'mc_use_' . $template . '_template' ) == 1 ) {
2392
  $template = mc_get_template( $template );
 
 
2393
  } else {
2394
  $template = false;
2395
  $details = my_calendar_draw_event( $event, $type = "single", $event->event_begin, $event->event_time, '' );
@@ -2475,6 +2514,25 @@ function mc_standard_datetime_input( $form, $has_data, $data, $instance, $contex
2475
  return $form;
2476
  }
2477
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2478
  function mc_standard_event_registration( $form, $has_data, $data, $context = 'admin' ) {
2479
  if ( $has_data ) {
2480
  $event_open = jd_option_selected( $data->event_open, '1' );
3
  exit;
4
  } // Exit if accessed directly
5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
  function mc_event_post( $action, $data, $event_id ) {
7
  // if the event save was successful.
8
  if ( $action == 'add' || $action == 'copy' ) {
18
  mc_create_event_post( $data, $event_id );
19
  }
20
  $term = mc_get_category_detail( $data['event_category'], 'category_term' );
21
+ if( !$term ) {
22
+ $term = wp_insert_term( 'General', 'mc-event-category' );
23
+ $term = ( !is_wp_error( $term ) ) ? $term['term_id'] : false;
24
+ if ( $term ) {
25
+ $update = mc_update_category( 'category_term', $term, $data['event_category'] );
26
+ }
27
+ }
28
  $privacy = ( mc_get_category_detail( $data['event_category'], 'category_private' ) == 1 ) ? 'private' : 'publish';
29
  $title = $data['event_title'];
30
  $template = apply_filters( 'mc_post_template', 'details', $term );
145
  return $result;
146
  }
147
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
148
  /**
149
  * @param $event_id
150
  * @param $post_id
159
  global $wpdb;
160
  $mcdb = $wpdb;
161
  if ( isset( $_GET['mode'] ) && $_GET['mode'] == 'delete' ) {
162
+ $event_id = ( isset( $_GET['event_id'] ) ) ? intval( $_GET['event_id'] ) : false;
163
+ $sql = "SELECT event_title, event_author FROM " . my_calendar_table() . " WHERE event_id=$event_id";
164
  $result = $mcdb->get_results( $sql, ARRAY_A );
165
+ if ( mc_can_edit_event( $event_id ) ) {
166
  if ( isset( $_GET['date'] ) ) {
167
  $event_instance = (int) $_GET['date'];
168
  $sql = "SELECT occur_begin FROM " . my_calendar_event_table() . " WHERE occur_id=" . $event_instance;
184
  <input type="hidden" name="ref" value="<?php echo esc_url( $_GET['ref'] ); ?>"/>
185
  <?php } ?>
186
 
187
+ <input type="hidden" name="event_id" value="<?php echo $event_id; ?>"/>
188
  <input type="submit" name="submit" class="button-secondary delete"
189
  value="<?php _e( 'Delete', 'my-calendar' );
190
  echo " &quot;" . stripslashes( $result[0]['event_title'] ) . "&quot; $instance_date"; ?>"/>
485
  </div><?php
486
  }
487
 
 
 
 
 
 
 
 
 
488
  function my_calendar_save( $action, $output, $event_id = false ) {
489
  global $wpdb, $event_author;
490
  $mcdb = $wpdb;
545
  } else {
546
  // do an action using the $action and processed event data
547
  $data = $add;
548
+ $event_error = '';
549
  do_action( 'mc_save_event', $action, $data, $event_id, $result );
550
  // Call mail function
551
  if ( get_option( 'mc_event_mail' ) == 'true' ) {
563
  //$event_link = mc_build_url( array( 'mc_id' => $event_ids[0]->occur_id ), array( 'page' ), get_option( 'mc_uri' ) );
564
  //$event_link = add_query_arg( 'mc_id', $event_ids[0]->occur_id, get_option( 'mc_uri' ) );
565
  $event_link = mc_get_details_link( $event_ids[0]->occur_id );
566
+ $event_error = mc_error_check( $event_ids[0]->occur_event_id );
567
  } else {
568
  $event_link = false;
569
  }
570
+ if ( $event_error != '' ) {
571
+ $message = $event_error;
572
+ } else {
573
+ $message = "<div class='updated notice'><p>" . __( 'Event added. It will now show on the calendar.', 'my-calendar' );
574
+ if ( $event_link !== false ) {
575
+ $message .= sprintf( __( ' <a href="%s">View Event</a>', 'my-calendar' ), $event_link );
576
+ }
577
+ $message .= "</p></div>";
578
  }
 
579
  }
580
  mc_delete_cache();
581
  }
633
  '%d' );
634
  $recur_changed = ( $update['event_repeats'] != $_POST['prev_event_repeats'] || $update['event_recur'] != $_POST['prev_event_recur'] ) ? true : false;
635
  if ( $date_changed || $recur_changed ) {
636
+ // TODO: if date or recur changed, do generation of new instances, then iterate over existing occurrences
637
+ // to update & delete remaining
638
  mc_delete_instances( $event_id );
639
  mc_increment_event( $event_id );
640
  mc_delete_cache();
661
  return array( 'event_id' => $event_id, 'message' => $message );
662
  }
663
 
664
+ function mc_error_check( $event_id ) {
665
+ $data = mc_form_data( $event_id );
666
+ $test = '';
667
+ if ( $data ) {
668
+ $test = mc_test_occurrence_overlap( $data, true );
669
+ }
670
+
671
+ $edit_link = " <a href='" . esc_url( add_query_arg( array( 'mode'=>'edit', 'event_id'=>$event_id ), admin_url( 'admin.php?page=my-calendar' ) ) ) . "'>" . __( 'Edit Event', 'my-calendar' ) . "</a>";
672
+
673
+ $test = ( $test != '' ) ? str_replace( "</p></div>", "$edit_link</p></div>", $test ) : $test;
674
+
675
+ return $test;
676
+ }
677
+
678
  function mc_delete_event( $event_id ) {
679
  global $wpdb;
680
  $mcdb = $wpdb;
735
  // The event edit form for the manage events admin page
736
  function mc_edit_event_form( $mode = 'add', $event_id = false ) {
737
  global $users_entries;
738
+
739
+ if ( $event_id && ! mc_can_edit_event( $event_id ) ) {
740
+ echo "<div class='error'><p>";
741
+ _e( 'You do not have permission to edit this event.', 'my-calendar' );
742
+ echo "</p></div>";
743
+
744
+ return;
745
+ }
746
+
747
  if ( $event_id != false ) {
748
  $data = mc_form_data( $event_id );
749
  } else {
755
  $message = "";
756
  }
757
  echo ( $message != '' ) ? "<div class='error'><p>$message</p></div>" : '';
758
+
759
  mc_form_fields( $data, $mode, $event_id );
760
  }
761
 
798
  }
799
  }
800
 
801
+ function mc_show_block( $field, $has_data, $data, $echo = true, $default = '' ) {
802
  global $user_ID;
803
  $return = $checked = $value = '';
804
  $show_block = mc_show_edit_block( $field );
807
  switch ( $field ) {
808
  case 'event_host' :
809
  if ( $show_block ) {
810
+ $users = mc_get_users();
811
  $select = '';
812
  foreach ( $users as $u ) {
813
  $display_name = ( $u->display_name == '' ) ? $u->user_nicename : $u->display_name;
829
  </p>';
830
  }
831
  break;
832
+ case 'event_author' :
833
+ if ( $show_block && is_object( $data ) && $data->event_author === '0' ) {
834
+ $users = mc_get_users();
835
+ $select = '';
836
+ foreach ( $users as $u ) {
837
+ $display_name = ( $u->display_name == '' ) ? $u->user_nicename : $u->display_name;
838
+ $select .= "<option value='$u->ID'>$display_name</option>\n";
839
+ }
840
+ $return = '
841
+ <p>
842
+ <label for="e_author">' . __( 'Author', 'my-calendar' ) . '</label>
843
+ <select id="e_author" name="event_author">
844
+ <option value="0" selected="selected">Public Submitter</option>' .
845
+ $select
846
+ . '</select>
847
+ </p>';
848
+ } else {
849
+ $return = '<input type="hidden" name="event_author" value="' . $default . '" />';
850
+ }
851
+ break;
852
  case 'event_desc' :
853
  if ( $show_block ) {
854
  global $current_screen;
856
  $value = ( $has_data ) ? stripslashes( $data->event_desc ) : '';
857
  if ( $current_screen->base == 'post' ) {
858
  $return = '<div class="event_description">
859
+ <label for="content" class="screen-reader-text">' . __( 'Event Description', 'my-calendar' ) . '</label>
860
  <textarea id="content" name="content" class="event_desc" rows="8" cols="80">' . stripslashes( esc_attr( $value ) ) . '</textarea>
861
  </div>';
862
  } else {
863
  echo '
864
  <div class="event_description">
865
+ <label for="content" class="screen-reader-text">' . __( 'Event Description', 'my-calendar' ) . '</label>';
866
  if ( user_can_richedit() ) {
867
  wp_editor( $value, 'content', array( 'textarea_rows' => 10 ) );
868
  } else {
883
  break;
884
  case 'event_image' :
885
  if ( $show_block ) {
886
+ if ( $has_data && method_exists( $data, 'event_post' ) ) {
887
+ $image = ( has_post_thumbnail( $data->event_post ) ) ? get_the_post_thumbnail_url( $data->event_post ) : $data->event_image;
888
+ } else {
889
+ $image = '';
890
+ }
891
  $return = '
892
  <div class="mc-image-upload field-holder">
893
  <input type="hidden" name="event_image_id" value="" class="textfield" id="e_image_id" />
894
+ <label for="e_image">' . __( "Add an image:", 'my-calendar' ) . '</label><br /><input type="text" name="event_image" id="e_image" size="60" value="' . esc_attr( $image ) . '" placeholder="http://yourdomain.com/image.jpg" /> <button type="button" class="button textfield-field">' . __( "Upload", 'my-calendar' ) . '</button>';
895
+ if ( $image != '' ) {
896
+ $image = ( has_post_thumbnail( $data->event_post ) ) ? get_the_post_thumbnail_url( $data->event_post ) : $data->event_image;
897
+ $return .= '<div class="event_image"><img src="' . esc_attr( $image ) . '" alt="" /></div>';
898
  } else {
899
  $return .= '<div class="event_image"></div>';
900
  }
901
  $return .= '</div>';
902
  } else {
903
+ $return = '<input type="hidden" name="event_image" value="' . esc_attr( $image ) . '" />';
904
  }
905
  break;
906
  case 'event_category' :
1073
  $check = mc_increment_event( $data->event_id, array(), 'test' );
1074
  if ( my_calendar_date_xcomp( $check['occur_begin'], $data->event_end . '' . $data->event_endtime ) ) {
1075
  $warning = "<div class='error'><span class='problem-icon dashicons dashicons-performance'></span> <p><strong>" . __( 'Event hidden from public view.', 'my-calendar' ) . "</strong> " . __( 'This event ends after the next occurrence begins. Events must end <strong>before</strong> the next occurrence begins.', 'my-calendar' ) . "</p><p>" . sprintf( __( 'Event end date: <strong>%s %s</strong>. Next occurrence starts: <strong>%s</strong>', 'my-calendar' ), $data->event_end, $data->event_endtime, $check['occur_begin'] ) . "</p></div>";
1076
+ update_post_meta( $data->event_post, '_occurrence_overlap', 'false' );
1077
+ } else {
1078
+ delete_post_meta( $data->event_post, '_occurrence_overlap' );
1079
  }
1080
  }
1081
  if ( $return ) {
1101
  ?>
1102
 
1103
  <div class="postbox-container jcd-wide">
1104
+ <div class="metabox-holder">
1105
+ <?php if ( $mode == 'add' || $mode == 'copy' ) {
1106
+ $query_args = array();
1107
+ } else {
1108
+ $query_args = array( 'mode' => $mode, 'event_id' => $event_id );
1109
+ if ( $instance ) {
1110
+ $query_args['date'] = $instance;
1111
+ }
1112
+ }
1113
+ echo apply_filters( 'mc_before_event_form', '', $event_id );
1114
+ $action = add_query_arg( $query_args, admin_url( 'admin.php?page=my-calendar' ) );
1115
+ if ( ! empty( $data->event_group_id ) && $mode != 'copy' ) {
1116
+ $group_id = $data->event_group_id;
1117
+ } else {
1118
+ $group_id = mc_group_id();
1119
+ }
1120
+ if ( $mode != 'edit' ) {
1121
+ $event_author = $user_ID;
1122
+ } else {
1123
+ $event_author = $data->event_author;
1124
+ }
1125
+ ?>
1126
+ <form id="my-calendar" method="post" action="<?php echo $action; ?>">
1127
  <div>
1128
+ <input type="hidden" name="_wpnonce" value="<?php echo wp_create_nonce( 'my-calendar-nonce' ); ?>" />
1129
  <?php if ( isset( $_GET['ref'] ) ) { ?>
1130
+ <input type="hidden" name="ref" value="<?php echo esc_url( $_GET['ref'] ); ?>" />
1131
  <?php } ?>
1132
+ <input type="hidden" name="event_group_id" value="<?php echo $group_id; ?>" />
1133
+ <input type="hidden" name="event_action" value="<?php esc_attr_e( $mode ); ?>" />
 
 
 
 
1134
  <?php if ( ! empty( $_GET['date'] ) ) { ?>
1135
  <input type="hidden" name="event_instance" value="<?php echo (int) $_GET['date']; ?>"/>
1136
  <?php } ?>
1137
  <input type="hidden" name="event_id" value="<?php echo (int) $event_id; ?>"/>
1138
+ <?php if ( $mode == 'edit' ) {
1139
+ if ( $has_data && ( ! property_exists( $data, 'event_post' ) || ! $data->event_post ) ) {
1140
+ $array_data = (array) $data;
1141
+ $post_id = mc_event_post( 'add', $array_data, $event_id );
1142
+ } else {
1143
+ $post_id = ( $has_data ) ? $data->event_post : false;
1144
+ }
1145
+ ?>
1146
+ <input type='hidden' name='event_post' value="<?php echo $post_id; ?>" />
1147
+ <?php } else {
1148
+ $post_id = false;
1149
+ } ?>
1150
+ <input type="hidden" name="event_nonce_name" value="<?php echo wp_create_nonce( 'event_nonce' ); ?>" />
1151
  </div>
1152
 
1153
  <div class="ui-sortable meta-box-sortables">
1154
  <div class="postbox">
1155
  <?php
1156
+ if ( $mode == 'edit' ) {
1157
  $text = __( 'Edit Event', 'my-calendar' );
1158
  $args = '';
1159
  if ( isset( $_GET['date'] ) ) {
1162
  $args = "&amp;date=$id";
1163
  }
1164
  }
1165
+ $delete = " &middot; <a href='" . admin_url( "admin.php?page=my-calendar-manage&amp;mode=delete&amp;event_id=$event_id$args" ) . "' class='delete'>" . __( 'Delete', 'my-calendar' ) . "</a>";
1166
  } else {
1167
  $text = __( 'Add Event', 'my-calendar' );
1168
  $delete = '';
1169
  }
1170
+
 
 
 
 
1171
  if ( apply_filters( 'mc_use_permalinks', get_option( 'mc_use_permalinks' ) ) == 'true' ) {
1172
  $post_link = ( $post_id ) ? get_edit_post_link( $post_id ) : false;
1173
  $text_link = ( $post_link ) ? sprintf( " &middot; <a href='%s'>" . __( 'Edit Event Post', 'my-calendar' ) . "</a>", $post_link ) : '';
1253
  if ( function_exists( 'jd_doTwitterAPIPost' ) && current_user_can( 'wpt_can_tweet' ) ) {
1254
  if ( ! ( $mode == 'edit' && $data->event_approved == 1 ) ) {
1255
  ?>
1256
+ <p class='mc-twitter'>
1257
  <label
1258
  for='mc_twitter'><?php _e( 'Post to Twitter (via WP to Twitter)', 'my-calendar' ); ?></label><br/>
1259
  <textarea cols='70' rows='2' id='mc_twitter'
1265
  mc_show_block( 'event_short', $has_data, $data );
1266
  mc_show_block( 'event_image', $has_data, $data );
1267
  mc_show_block( 'event_host', $has_data, $data );
1268
+ mc_show_block( 'event_author', $has_data, $data, true, $event_author );
1269
  mc_show_block( 'event_category', $has_data, $data );
1270
  mc_show_block( 'event_link', $has_data, $data );
1271
  echo apply_filters( 'mc_event_details', '', $has_data, $data, 'admin' );
1308
  <em><?php _e( 'Enter start and end dates/times for each occurrence of the event.', 'my-calendar' ); ?></em>
1309
  </p>
1310
  <div>
1311
+ <input type="button" id="add_field" value="<?php _e( 'Add another occurrence', 'my-calendar' ); ?>" class="button" />
1312
+ <input type="button" id="del_field" value="<?php _e( 'Remove last occurrence', 'my-calendar' ); ?>" class="button" />
 
 
1313
  </div>
1314
  <?php } else { ?>
1315
  <div id='mc-accordion'>
1316
  <?php if ( $data->event_recur != 'S' ) { ?>
1317
+ <h4><span class='dashicons' aria-hidden='true'> </span><?php _e( 'Scheduled dates for this event', 'my-calendar' ); ?></h4>
1318
  <div>
1319
+ <p>
1320
  <?php _e( 'Editing a single date of an event changes only that date. Editing the root event changes all events in the series.', 'my-calendar' ); ?>
1321
+ </p>
1322
  <div class='mc_response' aria-live='assertive'></div>
1323
+ <ul class="columns instance-list">
1324
  <?php if ( isset( $_GET['date'] ) ) {
1325
  $date = (int) $_GET['date'];
1326
  } else {
1328
  } ?>
1329
  <?php echo mc_instance_list( $data->event_id, $date ); ?>
1330
  </ul>
1331
+ <p><button type='button' class='add-occurrence' aria-expanded="false"><span class='dashicons' aria-hidden='true'> </span><?php _e( 'Add another date', 'my-calendar' ); ?></button></p>
1332
+ <div class='mc_add_new'>
1333
+ <?php echo mc_recur_datetime_input(); ?>
1334
+ <button type='button' class='save-occurrence'><?php _e( 'Add Date', 'my-calendar' ); ?></button>
1335
+ </div>
1336
  </div>
1337
  <?php } ?>
1338
  <?php if ( $data->event_group_id != 0 ) { ?>
1339
  <?php
1340
  $edit_group_url = admin_url( 'admin.php?page=my-calendar-groups&mode=edit&event_id=' . $data->event_id . '&group_id=' . $data->event_group_id );
1341
  ?>
1342
+ <h4><span class='dashicons' aria-hidden="true"></span><?php _e( 'Related Events:', 'my-calendar' ); ?> (<a
1343
  href='<?php echo $edit_group_url; ?>'><?php _e( 'Edit group', 'my-calendar' ); ?></a>)
1344
  </h4>
1345
  <div>
1382
  <option value="none"> --</option><?php
1383
  foreach ( $locs as $loc ) {
1384
  if ( is_object( $loc ) ) {
1385
+ echo "<option value=\"" . $loc->location_id . "\">" . mc_kses_post( stripslashes( $loc->location_label ) ) . "</option>";
1386
  if ( is_object( $data ) ) {
1387
+ if ( property_exists( $data, 'event_location' ) ) {
1388
+ $event_location = $data->event_location;
1389
+ } else {
1390
+ $event_location = false;
1391
+ }
1392
+ if ( $loc->location_id == $event_location ) {
1393
+ $current_location = "<span id='mc-current-location'>" . sprintf( __( 'Current location: %s', 'my-calendar' ), mc_kses_post( $loc->location_label ) ) . "</span>";
1394
  }
1395
  }
1396
  }
1483
  '10' => __( 'Large Print Playbill', 'my-calendar' ),
1484
  '11' => __( 'Sensory Friendly', 'my-calendar' ),
1485
  '12' => __( 'Other', 'my-calendar' )
1486
+ )
1487
  );
1488
 
1489
  return $event_access;
1498
  <ul class='accessibility-features checkboxes'>";
1499
  $access = apply_filters( 'mc_event_accessibility', mc_event_access() );
1500
  if ( ! empty( $data ) ) {
1501
+ if ( property_exists( $data, 'event_post' ) ) {
1502
+ $events_access = get_post_meta( $data->event_post, '_mc_event_access', true );
1503
+ } else {
1504
+ $events_access = array();
1505
+ }
1506
  }
1507
  foreach ( $access as $k => $a ) {
1508
  $id = "events_access_$k";
1911
  class="screen-reader-text"><?php _e( 'Show only: ', 'my-calendar' ); ?></span><?php echo( is_object( $author ) ? $author->display_name : $author ); ?>
1912
  </a></td>
1913
  <?php
1914
+ if ( ! $event->event_category ) {
1915
+ // events *must* have a category
1916
+ mc_update_event( 'event_category', 1, $event->event_id, '%d' );
 
 
1917
  }
1918
+ $color = strip_tags( mc_get_category_detail( $event->event_category, 'category_color' ) );
1919
  ?>
1920
  <td>
1921
  <div class="category-color"
1924
  <a class='mc_filter'
1925
  href='<?php echo admin_url( "admin.php?page=my-calendar-manage&amp;filter=$event->event_category&amp;restrict=category" ); ?>'
1926
  title="<?php _e( 'Filter by category', 'my-calendar' ); ?>"><span
1927
+ class="screen-reader-text"><?php _e( 'Show only: ', 'my-calendar' ); ?></span><?php echo mc_kses_post( mc_get_category_detail( $event->event_category, 'category_name' ) ); ?>
1928
  </a></td>
 
1929
  </tr>
1930
  <?php
1931
  }
1964
  }
1965
 
1966
  function mc_check_data( $action, $post, $i ) {
1967
+ $post = apply_filters( 'mc_pre_checkdata', $post, $action, $i );
1968
  global $wpdb, $current_user, $users_entries;
1969
  $mcdb = $wpdb;
1970
  $submit = array();
2013
 
2014
  $begin = date( 'Y-m-d', strtotime( $begin ) );// regardless of entry format, convert.
2015
  $time = ! empty( $post['event_time'][ $i ] ) ? trim( $post['event_time'][ $i ] ) : '';
2016
+ if ( $time != '' ) {
2017
+ $endtime = ! empty( $post['event_endtime'][ $i ] ) ? trim( $post['event_endtime'][ $i ] ) : date( 'H:i:s', strtotime( $time . ' +1 hour' ) );
2018
+ } else {
2019
+ $endtime = ! empty( $post['event_endtime'][ $i ] ) ? trim( $post['event_endtime'][ $i ] ) : '';
2020
+ }
2021
+ $time = ( $time == '' || $time == '00:00:00' ) ? '00:00:00' : $time; // set at midnight if not provided
2022
+ $endtime = ( $endtime == '' && $time == '00:00:00' ) ? '23:59:59' : $endtime; // set at end of night if np
2023
+
2024
  // prevent setting enddate to incorrect value on copy.
2025
  if ( strtotime( $end ) < strtotime( $begin ) && $action == 'copy' ) {
2026
  $end = date( 'Y-m-d', ( strtotime( $begin ) + ( strtotime( $post['prev_event_end'] ) - strtotime( $post['prev_event_begin'] ) ) ) );
2028
  if ( isset( $post['event_allday'] ) && (int) $post['event_allday'] !== 0 ) {
2029
  $time = '00:00:00'; $endtime = '23:59:59';
2030
  }
2031
+
2032
+ // verify formats
2033
+ $time = date( 'H:i:s', strtotime( $time ) );
2034
+ $endtime = date( 'H:i:s', strtotime( $endtime ) );
2035
+
2036
  $end = date( 'Y-m-d', strtotime( $end ) ); // regardless of entry format, convert.
2037
  $repeats = ( isset( $post['event_repeats'] ) ) ? trim( $post['event_repeats'] ) : 0;
2038
  $host = ! empty( $post['event_host'] ) ? $post['event_host'] : $current_user->ID;
2039
+
2040
+ $category = ( isset( $post['event_category'] ) && is_numeric( $post['event_category'] ) ) ? $post['event_category'] : 1;
2041
+ $event_author = ( isset( $post['event_author'] ) && is_numeric( $post['event_author'] ) ) ? $post['event_author'] : 0;
2042
+
2043
  $event_link = ! empty( $post['event_link'] ) ? trim( $post['event_link'] ) : '';
2044
  $expires = ! empty( $post['event_link_expires'] ) ? $post['event_link_expires'] : '0';
2045
  $approved = ! empty( $post['event_approved'] ) ? $post['event_approved'] : '0';
2046
  $location_preset = ! empty( $post['location_preset'] ) ? $post['location_preset'] : '';
 
2047
  $event_open = ( isset( $post['event_open'] ) && $post['event_open'] !== 0 ) ? $post['event_open'] : '2';
2048
  $event_tickets = ( isset( $post['event_tickets'] ) ) ? trim( $post['event_tickets'] ) : '';
2049
  $event_registration = ( isset( $post['event_registration'] ) ) ? trim( $post['event_registration'] ) : '';
2112
  'location_access' => ( is_array( $event_access ) ) ? serialize( $event_access ) : ''
2113
  );
2114
 
2115
+ $add_loc = array_map( 'mc_kses_post', $add_loc );
2116
 
2117
  $loc_formats = array(
2118
  '%s',
2191
  if ( $errors == '' ) {
2192
  $current_user = wp_get_current_user();
2193
  $event_author = ( $event_author == $current_user->ID || current_user_can( 'mc_manage_events' ) ) ? $event_author : $current_user->ID;
2194
+ $event_category = ( ! $category ) ? 1 : $category;
2195
 
2196
  $ok = true;
2197
  $submit = array(
2223
  // integers
2224
  'event_repeats' => $repeats,
2225
  'event_author' => $event_author,
2226
+ 'event_category' => $event_category,
2227
  'event_link_expires' => $expires,
2228
  'event_zoom' => $event_zoom,
2229
  'event_open' => $event_open,
2240
  'event_longitude' => $event_longitude,
2241
  'event_latitude' => $event_latitude
2242
  );
2243
+ $submit = array_map( 'mc_kses_post', $submit );
2244
 
2245
  } else {
2246
  $ok = false;
2292
  $users_entries->event_tickets = $event_tickets;
2293
  $users_entries->event_registration = $event_registration;
2294
  }
2295
+
2296
  $data = array( $ok, $users_entries, $submit, $errors );
2297
 
2298
  return $data;
2302
  global $wpdb;
2303
  $select_location = ( $event_label != '' ) ? "event_label = '$event_label'AND" : '';
2304
  $event_query = "SELECT occur_id
2305
+ FROM " . my_calendar_event_table() . "
2306
+ JOIN " . my_calendar_table() . "
2307
  ON (event_id=occur_event_id)
2308
  WHERE $select_location
2309
  ( occur_begin BETWEEN '$begin $time'AND '$end $endtime'OR occur_end BETWEEN '$begin $time'AND '$end $endtime')";
2411
  $begin = "<span id='occur_date_$result->occur_id'>" . date_i18n( get_option( 'mc_date_format' ), strtotime( $result->occur_begin ) ) . ', ' . date( get_option( 'mc_time_format' ), strtotime( $result->occur_begin ) ) . "</span>";
2412
  if ( $result->occur_id == $occur ) {
2413
  $form_control = '';
2414
+ $edit = "<em>" . __( 'Editing Now', 'my-calendar' ) . "</em>";
 
2415
  } else {
2416
+ $form_control = "$begin: <button class='delete_occurrence' type='button' data-value='$result->occur_id' aria-describedby='occur_date_$result->occur_id' />" . __( 'Delete', 'my-calendar' ) . "</button> ";
2417
+ $edit = "<a href='" . admin_url( 'admin.php?page=my-calendar' ) . "&amp;mode=edit&amp;event_id=$id&amp;date=$result->occur_id' aria-describedby='occur_date_$result->occur_id'>" . __( 'Edit', 'my-calendar' ) . "</a>";
 
2418
  }
2419
+ $output .= "<li>$form_control$edit</li>";
2420
  }
2421
  } else {
2422
  $details = '';
2424
  $event_id = $result->occur_id;
2425
  $event = mc_get_event( $event_id );
2426
  $array = mc_create_tags( $event );
2427
+ if ( in_array( $template, array( 'details', 'grid', 'list', 'mini' ) ) || mc_key_exists( $template ) ) {
2428
  if ( get_option( 'mc_use_' . $template . '_template' ) == 1 ) {
2429
  $template = mc_get_template( $template );
2430
+ } else if ( mc_key_exists( $template ) ) {
2431
+ $template = mc_get_custom_template( $template );
2432
  } else {
2433
  $template = false;
2434
  $details = my_calendar_draw_event( $event, $type = "single", $event->event_begin, $event->event_time, '' );
2514
  return $form;
2515
  }
2516
 
2517
+
2518
+ function mc_recur_datetime_input( $form = '' ) {
2519
+ $event_begin = date( "Y-m-d" );
2520
+ $event_end = $starttime = $endtime = '';
2521
+
2522
+ $form .= '<p>
2523
+ <label for="r_begin">' . __( 'Date (YYYY-MM-DD)', 'my-calendar' ) . '</label> <input type="text" id="r_begin" class="mc-datepicker" name="recur_begin[]" size="10" value="" data-value="' . esc_attr( $event_begin ) . '" />
2524
+ <label for="r_time">' . __( 'From', 'my-calendar' ) . '</label>
2525
+ <input type="text" id="r_time" class="mc-timepicker" name="recur_time[]" size="8" value="' . esc_attr( $starttime ) . '" />
2526
+ <label for="r_endtime">' . __( 'To', 'my-calendar' ) . '</label>
2527
+ <input type="text" id="r_endtime" class="mc-timepicker" name="recur_endtime[]" size="8" value="' . esc_attr( $endtime ) . '" />
2528
+ </p>
2529
+ <p>
2530
+ <label for="r_end"><em>' . __( 'End Date (YYYY-MM-DD, optional)', 'my-calendar' ) . '</em></label> <input type="text" name="recur_end[]" id="r_end" class="mc-datepicker" size="10" value="" data-value="' . esc_attr( $event_end ) . '" />
2531
+ </p>';
2532
+
2533
+ return $form;
2534
+ }
2535
+
2536
  function mc_standard_event_registration( $form, $has_data, $data, $context = 'admin' ) {
2537
  if ( $has_data ) {
2538
  $event_open = jd_option_selected( $data->event_open, '1' );
my-calendar-events.php CHANGED
@@ -24,7 +24,7 @@ function mc_get_private_categories() {
24
  if ( get_option( 'mc_remote' ) == 'true' && function_exists( 'mc_remote_db' ) ) {
25
  $mcdb = mc_remote_db();
26
  }
27
- $query = "SELECT category_id FROM " . MY_CALENDAR_CATEGORIES_TABLE . " WHERE category_private = 1";
28
  $results = $mcdb->get_results( $query );
29
  $categories = array();
30
  foreach ( $results as $result ) {
@@ -35,7 +35,7 @@ function mc_get_private_categories() {
35
  }
36
 
37
  // used to generate upcoming events lists
38
- function mc_get_all_events( $category, $before, $after, $today, $author, $host, $ltype = '', $lvalue = '' ) {
39
  global $wpdb;
40
  $mcdb = $wpdb;
41
  $events1 = $events2 = $events3 = array();
@@ -52,10 +52,10 @@ function mc_get_all_events( $category, $before, $after, $today, $author, $host,
52
  if ( $before > 0 ) {
53
  $before = $before + 15;
54
  $events1 = $mcdb->get_results( "SELECT *, UNIX_TIMESTAMP(occur_begin) AS ts_occur_begin, UNIX_TIMESTAMP(occur_end) AS ts_occur_end
55
- FROM " . MY_CALENDAR_EVENTS_TABLE . "
56
- JOIN " . MY_CALENDAR_TABLE . "
57
  ON (event_id=occur_event_id)
58
- JOIN " . MY_CALENDAR_CATEGORIES_TABLE . "
59
  ON (event_category=category_id) WHERE $select_category $select_author $select_host $limit_string event_approved = 1
60
  AND event_flagged <> 1
61
  AND DATE(occur_begin) < '$date'
@@ -64,10 +64,10 @@ function mc_get_all_events( $category, $before, $after, $today, $author, $host,
64
  }
65
  if ( $today == 'yes' ) {
66
  $events3 = $mcdb->get_results( "SELECT *, UNIX_TIMESTAMP(occur_begin) AS ts_occur_begin, UNIX_TIMESTAMP(occur_end) AS ts_occur_end
67
- FROM " . MY_CALENDAR_EVENTS_TABLE . "
68
- JOIN " . MY_CALENDAR_TABLE . "
69
  ON (event_id=occur_event_id)
70
- JOIN " . MY_CALENDAR_CATEGORIES_TABLE . "
71
  ON (event_category=category_id) WHERE $select_category $select_author $select_host $limit_string event_approved = 1
72
  AND event_flagged <> 1
73
  $exclude_categories
@@ -76,10 +76,10 @@ function mc_get_all_events( $category, $before, $after, $today, $author, $host,
76
  if ( $after > 0 ) {
77
  $after = $after + 15;
78
  $events2 = $mcdb->get_results( "SELECT *, UNIX_TIMESTAMP(occur_begin) AS ts_occur_begin, UNIX_TIMESTAMP(occur_end) AS ts_occur_end
79
- FROM " . MY_CALENDAR_EVENTS_TABLE . "
80
- JOIN " . MY_CALENDAR_TABLE . "
81
  ON (event_id=occur_event_id)
82
- JOIN " . MY_CALENDAR_CATEGORIES_TABLE . "
83
  ON (event_category=category_id) WHERE $select_category $select_author $select_host $limit_string event_approved = 1
84
  AND event_flagged <> 1
85
  $exclude_categories
@@ -108,10 +108,10 @@ function mc_get_all_holidays( $before, $after, $today ) {
108
  if ( $before > 0 ) {
109
  $before = $before + 10;
110
  $events1 = $mcdb->get_results( "SELECT *
111
- FROM " . MY_CALENDAR_EVENTS_TABLE . "
112
- JOIN " . MY_CALENDAR_TABLE . "
113
  ON (event_id=occur_event_id)
114
- JOIN " . MY_CALENDAR_CATEGORIES_TABLE . "
115
  ON (event_category=category_id) WHERE event_category = $holiday AND event_approved = 1 AND event_flagged <> 1
116
  AND DATE(occur_begin) < '$date' ORDER BY occur_begin DESC LIMIT 0,$before" );
117
  } else {
@@ -119,10 +119,10 @@ function mc_get_all_holidays( $before, $after, $today ) {
119
  }
120
  if ( $today == 'yes' ) {
121
  $events3 = $mcdb->get_results( "SELECT *
122
- FROM " . MY_CALENDAR_EVENTS_TABLE . "
123
- JOIN " . MY_CALENDAR_TABLE . "
124
  ON (event_id=occur_event_id)
125
- JOIN " . MY_CALENDAR_CATEGORIES_TABLE . "
126
  ON (event_category=category_id) WHERE event_category = $holiday AND event_approved = 1 AND event_flagged <> 1
127
  AND DATE(occur_begin) = '$date'" );
128
  } else {
@@ -131,10 +131,10 @@ function mc_get_all_holidays( $before, $after, $today ) {
131
  if ( $after > 0 ) {
132
  $after = $after + 10;
133
  $events2 = $mcdb->get_results( "SELECT *
134
- FROM " . MY_CALENDAR_EVENTS_TABLE . "
135
- JOIN " . MY_CALENDAR_TABLE . "
136
  ON (event_id=occur_event_id)
137
- JOIN " . MY_CALENDAR_CATEGORIES_TABLE . "
138
  ON (event_category=category_id) WHERE event_category = $holiday AND event_approved = 1 AND event_flagged <> 1
139
  AND DATE(occur_begin) > '$date' ORDER BY occur_begin ASC LIMIT 0,$after" );
140
  } else {
@@ -159,7 +159,7 @@ function mc_get_rss_events( $cat_id = false ) {
159
  } else {
160
  $cat = 'WHERE event_approved = 1';
161
  }
162
- $events = $mcdb->get_results( "SELECT *, UNIX_TIMESTAMP(occur_begin) AS ts_occur_begin, UNIX_TIMESTAMP(occur_end) AS ts_occur_end FROM " . MY_CALENDAR_EVENTS_TABLE . " JOIN " . MY_CALENDAR_TABLE . " ON (event_id=occur_event_id) JOIN " . MY_CALENDAR_CATEGORIES_TABLE . " ON (event_category=category_id) $cat ORDER BY event_added DESC LIMIT 0,30" );
163
  $groups = $output = array();
164
  foreach ( array_keys( $events ) as $key ) {
165
  $event =& $events[ $key ];
@@ -188,7 +188,12 @@ function mc_get_event_core( $id ) {
188
  if ( get_option( 'mc_remote' ) == 'true' && function_exists( 'mc_remote_db' ) ) {
189
  $mcdb = mc_remote_db();
190
  }
191
- $event = $mcdb->get_row( "SELECT * FROM " . MY_CALENDAR_TABLE . " JOIN " . MY_CALENDAR_CATEGORIES_TABLE . " ON (event_category=category_id) WHERE event_id=$id" );
 
 
 
 
 
192
 
193
  return $event;
194
  }
@@ -200,7 +205,35 @@ function mc_get_first_event( $id ) {
200
  if ( get_option( 'mc_remote' ) == 'true' && function_exists( 'mc_remote_db' ) ) {
201
  $mcdb = mc_remote_db();
202
  }
203
- $event = $mcdb->get_row( "SELECT *, UNIX_TIMESTAMP(occur_begin) AS ts_occur_begin, UNIX_TIMESTAMP(occur_end) AS ts_occur_end FROM " . MY_CALENDAR_EVENTS_TABLE . " JOIN " . MY_CALENDAR_TABLE . " ON (event_id=occur_event_id) JOIN " . MY_CALENDAR_CATEGORIES_TABLE . " ON (event_category=category_id) WHERE occur_event_id=$id" );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
204
 
205
  return $event;
206
  }
@@ -216,7 +249,7 @@ function mc_get_event( $id, $type = 'object' ) {
216
  if ( get_option( 'mc_remote' ) == 'true' && function_exists( 'mc_remote_db' ) ) {
217
  $mcdb = mc_remote_db();
218
  }
219
- $event = $mcdb->get_row( "SELECT *, UNIX_TIMESTAMP(occur_begin) AS ts_occur_begin, UNIX_TIMESTAMP(occur_end) AS ts_occur_end FROM " . MY_CALENDAR_EVENTS_TABLE . " JOIN " . MY_CALENDAR_TABLE . " ON (event_id=occur_event_id) JOIN " . MY_CALENDAR_CATEGORIES_TABLE . " ON (event_category=category_id) WHERE occur_id=$id" );
220
  if ( $type == 'object' ) {
221
  return $event;
222
  } else {
@@ -257,7 +290,7 @@ function mc_get_occurrences( $id ) {
257
  }
258
 
259
  // get all events related to an event ID (group IDs)
260
- function mc_related_events( $id, $return = false ) {
261
  global $wpdb;
262
  $id = (int) $id;
263
  if ( $id === 0 && $return === false ) {
@@ -271,21 +304,60 @@ function mc_related_events( $id, $return = false ) {
271
  $output = '';
272
  $sql = "SELECT * FROM " . my_calendar_event_table() . " WHERE occur_group_id=$id";
273
  $results = $wpdb->get_results( $sql );
 
274
  if ( $return ) {
275
  return $results;
276
  }
 
277
  if ( is_array( $results ) && ! empty( $results ) ) {
278
  foreach ( $results as $result ) {
279
- $event = $result->occur_event_id;
280
- $current = "<a href='" . admin_url( 'admin.php?page=my-calendar' ) . "&amp;mode=edit&amp;event_id=$event'>";
281
- $end = "</a>";
282
- $begin = date_i18n( get_option( 'mc_date_format' ), strtotime( $result->occur_begin ) ) . ', ' . date( get_option( 'mc_time_format' ), strtotime( $result->occur_begin ) );
283
- $output .= "<li>$current$begin$end</li>";
 
284
  }
285
  } else {
286
  $output = "<li>" . __( 'No related events', 'my-calendar' ) . "</li>";
287
  }
288
- echo $output;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
289
  }
290
 
291
  /*
@@ -303,13 +375,13 @@ function mc_related_events( $id, $return = false ) {
303
  * @param int $author Author ID to filter to.
304
  * @return array Array of events with dates as keys.
305
  */
306
- function my_calendar_events( $from, $to, $category, $ltype, $lvalue, $source, $author, $host, $search = '' ) {
307
- $events = my_calendar_grab_events( $from, $to, $category, $ltype, $lvalue, $source, $author, $host, null, $search );
308
 
309
  if ( ! get_option( 'mc_skip_holidays_category' ) || get_option( 'mc_skip_holidays_category' ) == '' ) {
310
  $holidays = array();
311
  } else {
312
- $holidays = my_calendar_grab_events( $from, $to, get_option( 'mc_skip_holidays_category' ), $ltype, $lvalue, $source, $author, $host, 'holidays' );
313
  $holiday_array = mc_set_date_array( $holidays );
314
  }
315
  // get events into an easily parseable set, keyed by date.
@@ -325,7 +397,13 @@ function my_calendar_events( $from, $to, $category, $ltype, $lvalue, $source, $a
325
  return $event_array;
326
  }
327
 
328
- function my_calendar_events_now( $category = 'default', $template = '<strong>{link_title}</strong> {timerange}' ) {
 
 
 
 
 
 
329
  global $wpdb;
330
  $mcdb = $wpdb;
331
  if ( get_option( 'mc_remote' ) == 'true' && function_exists( 'mc_remote_db' ) ) {
@@ -338,10 +416,10 @@ function my_calendar_events_now( $category = 'default', $template = '<strong>{li
338
  $select_location = $select_author = $select_host = '';
339
  $now = date( 'Y-m-d H:i:s', current_time( 'timestamp' ) );
340
  $event_query = "SELECT *, UNIX_TIMESTAMP(occur_begin) AS ts_occur_begin, UNIX_TIMESTAMP(occur_end) AS ts_occur_end
341
- FROM " . MY_CALENDAR_EVENTS_TABLE . " AS e
342
- JOIN " . MY_CALENDAR_TABLE . " AS t
343
  ON (event_id=occur_event_id)
344
- JOIN " . MY_CALENDAR_CATEGORIES_TABLE . " AS c
345
  ON (event_category=category_id)
346
  WHERE $select_category $select_location $select_author $select_host $limit_string
347
  AND ( CAST('$now' AS DATETIME) BETWEEN occur_begin AND occur_end )
@@ -355,16 +433,26 @@ function my_calendar_events_now( $category = 'default', $template = '<strong>{li
355
  }
356
  if ( !empty( $arr_events ) ) {
357
  $event = mc_create_tags( $arr_events[0] );
 
 
 
 
358
 
359
  $output = jd_draw_template( $event, apply_filters( 'mc_happening_now_template', $template, $event ) );
360
- return ( get_option( 'mc_process_shortcodes' ) == 'true' ) ? do_shortcode( $output ) : $output;
361
  } else {
362
- return '';
363
  }
 
 
 
 
 
 
364
  }
365
 
366
  // Grab all events for the requested date from calendar
367
- function my_calendar_grab_events( $from, $to, $category = null, $ltype = '', $lvalue = '', $source = 'calendar', $author = null, $host = null, $holidays = null, $search = '' ) {
368
  global $wpdb;
369
  $mcdb = $wpdb;
370
  if ( get_option( 'mc_remote' ) == 'true' && function_exists( 'mc_remote_db' ) ) {
@@ -455,10 +543,10 @@ function my_calendar_grab_events( $from, $to, $category = null, $ltype = '', $lv
455
  $search = mc_prepare_search_query( $search );
456
 
457
  $event_query = "SELECT *, UNIX_TIMESTAMP(occur_begin) AS ts_occur_begin, UNIX_TIMESTAMP(occur_end) AS ts_occur_end
458
- FROM " . MY_CALENDAR_EVENTS_TABLE . "
459
- JOIN " . MY_CALENDAR_TABLE . "
460
  ON (event_id=occur_event_id)
461
- JOIN " . MY_CALENDAR_CATEGORIES_TABLE . "
462
  ON (event_category=category_id)
463
  WHERE $select_category $select_location $select_author $select_host $limit_string $search
464
  AND ( DATE(occur_begin) BETWEEN '$from 00:00:00' AND '$to 23:59:59'
@@ -470,10 +558,12 @@ function my_calendar_grab_events( $from, $to, $category = null, $ltype = '', $lv
470
 
471
  if ( ! empty( $events ) ) {
472
  foreach ( array_keys( $events ) as $key ) {
473
- $event =& $events[ $key ];
474
- $arr_events[] = $event;
 
475
  }
476
  }
 
477
  if ( $source != 'upcoming' && $caching ) {
478
  $new_cache = mc_create_cache( $arr_events, $hash, $category, $ltype, $lvalue, $author, $host );
479
  if ( $new_cache ) {
@@ -496,10 +586,10 @@ function mc_get_db_type() {
496
  if ( get_option( 'mc_remote' ) == 'true' && function_exists( 'mc_remote_db' ) ) {
497
  $mcdb = mc_remote_db();
498
  }
499
- $my_calendar = MY_CALENDAR_TABLE;
500
  $dbs = $mcdb->get_results( "SHOW TABLE STATUS WHERE name='$my_calendar'" );
501
  foreach( $dbs as $db ) {
502
- if ( $db->Name == MY_CALENDAR_TABLE ) {
503
  $db_type = $db->Engine;
504
  }
505
  }
24
  if ( get_option( 'mc_remote' ) == 'true' && function_exists( 'mc_remote_db' ) ) {
25
  $mcdb = mc_remote_db();
26
  }
27
+ $query = "SELECT category_id FROM " . my_calendar_categories_table() . " WHERE category_private = 1";
28
  $results = $mcdb->get_results( $query );
29
  $categories = array();
30
  foreach ( $results as $result ) {
35
  }
36
 
37
  // used to generate upcoming events lists
38
+ function mc_get_all_events( $category, $before, $after, $today, $author, $host, $ltype = '', $lvalue = '', $site = false ) {
39
  global $wpdb;
40
  $mcdb = $wpdb;
41
  $events1 = $events2 = $events3 = array();
52
  if ( $before > 0 ) {
53
  $before = $before + 15;
54
  $events1 = $mcdb->get_results( "SELECT *, UNIX_TIMESTAMP(occur_begin) AS ts_occur_begin, UNIX_TIMESTAMP(occur_end) AS ts_occur_end
55
+ FROM " . my_calendar_event_table( $site ) . "
56
+ JOIN " . my_calendar_table( $site ) . "
57
  ON (event_id=occur_event_id)
58
+ JOIN " . my_calendar_categories_table( $site ) . "
59
  ON (event_category=category_id) WHERE $select_category $select_author $select_host $limit_string event_approved = 1
60
  AND event_flagged <> 1
61
  AND DATE(occur_begin) < '$date'
64
  }
65
  if ( $today == 'yes' ) {
66
  $events3 = $mcdb->get_results( "SELECT *, UNIX_TIMESTAMP(occur_begin) AS ts_occur_begin, UNIX_TIMESTAMP(occur_end) AS ts_occur_end
67
+ FROM " . my_calendar_event_table( $site ) . "
68
+ JOIN " . my_calendar_table( $site ) . "
69
  ON (event_id=occur_event_id)
70
+ JOIN " . my_calendar_categories_table( $site ) . "
71
  ON (event_category=category_id) WHERE $select_category $select_author $select_host $limit_string event_approved = 1
72
  AND event_flagged <> 1
73
  $exclude_categories
76
  if ( $after > 0 ) {
77
  $after = $after + 15;
78
  $events2 = $mcdb->get_results( "SELECT *, UNIX_TIMESTAMP(occur_begin) AS ts_occur_begin, UNIX_TIMESTAMP(occur_end) AS ts_occur_end
79
+ FROM " . my_calendar_event_table( $site ) . "
80
+ JOIN " . my_calendar_table( $site ) . "
81
  ON (event_id=occur_event_id)
82
+ JOIN " . my_calendar_categories_table( $site ) . "
83
  ON (event_category=category_id) WHERE $select_category $select_author $select_host $limit_string event_approved = 1
84
  AND event_flagged <> 1
85
  $exclude_categories
108
  if ( $before > 0 ) {
109
  $before = $before + 10;
110
  $events1 = $mcdb->get_results( "SELECT *
111
+ FROM " . my_calendar_event_table() . "
112
+ JOIN " . my_calendar_table() . "
113
  ON (event_id=occur_event_id)
114
+ JOIN " . my_calendar_categories_table() . "
115
  ON (event_category=category_id) WHERE event_category = $holiday AND event_approved = 1 AND event_flagged <> 1
116
  AND DATE(occur_begin) < '$date' ORDER BY occur_begin DESC LIMIT 0,$before" );
117
  } else {
119
  }
120
  if ( $today == 'yes' ) {
121
  $events3 = $mcdb->get_results( "SELECT *
122
+ FROM " . my_calendar_event_table() . "
123
+ JOIN " . my_calendar_table() . "
124
  ON (event_id=occur_event_id)
125
+ JOIN " . my_calendar_categories_table() . "
126
  ON (event_category=category_id) WHERE event_category = $holiday AND event_approved = 1 AND event_flagged <> 1
127
  AND DATE(occur_begin) = '$date'" );
128
  } else {
131
  if ( $after > 0 ) {
132
  $after = $after + 10;
133
  $events2 = $mcdb->get_results( "SELECT *
134
+ FROM " . my_calendar_event_table() . "
135
+ JOIN " . my_calendar_table() . "
136
  ON (event_id=occur_event_id)
137
+ JOIN " . my_calendar_categories_table() . "
138
  ON (event_category=category_id) WHERE event_category = $holiday AND event_approved = 1 AND event_flagged <> 1
139
  AND DATE(occur_begin) > '$date' ORDER BY occur_begin ASC LIMIT 0,$after" );
140
  } else {
159
  } else {
160
  $cat = 'WHERE event_approved = 1';
161
  }
162
+ $events = $mcdb->get_results( "SELECT *, UNIX_TIMESTAMP(occur_begin) AS ts_occur_begin, UNIX_TIMESTAMP(occur_end) AS ts_occur_end FROM " . my_calendar_event_table() . " JOIN " . my_calendar_table() . " ON (event_id=occur_event_id) JOIN " . my_calendar_categories_table() . " ON (event_category=category_id) $cat ORDER BY event_added DESC LIMIT 0,30" );
163
  $groups = $output = array();
164
  foreach ( array_keys( $events ) as $key ) {
165
  $event =& $events[ $key ];
188
  if ( get_option( 'mc_remote' ) == 'true' && function_exists( 'mc_remote_db' ) ) {
189
  $mcdb = mc_remote_db();
190
  }
191
+ // get event data
192
+ $event = $mcdb->get_row( "SELECT * FROM " . my_calendar_table() . " JOIN " . my_calendar_categories_table() . " ON (event_category=category_id) WHERE event_id=$id" );
193
+ // include first occurrence
194
+ $occur = $mcdb->get_row( "SELECT *, UNIX_TIMESTAMP(occur_begin) AS ts_occur_begin, UNIX_TIMESTAMP(occur_end) AS ts_occur_end FROM " . my_calendar_event_table() . " WHERE occur_event_id = $id ORDER BY occur_id ASC LIMIT 1" );
195
+
196
+ $event = (object) array_merge( (array) $event, (array) $occur );
197
 
198
  return $event;
199
  }
205
  if ( get_option( 'mc_remote' ) == 'true' && function_exists( 'mc_remote_db' ) ) {
206
  $mcdb = mc_remote_db();
207
  }
208
+ $event = $mcdb->get_row( "SELECT *, UNIX_TIMESTAMP(occur_begin) AS ts_occur_begin, UNIX_TIMESTAMP(occur_end) AS ts_occur_end FROM " . my_calendar_event_table() . " JOIN " . my_calendar_table() . " ON (event_id=occur_event_id) JOIN " . my_calendar_categories_table() . " ON (event_category=category_id) WHERE occur_event_id=$id" );
209
+
210
+ return $event;
211
+ }
212
+
213
+ function mc_valid_id( $mc_id ) {
214
+ global $wpdb;
215
+ $mcdb = $wpdb;
216
+ if ( get_option( 'mc_remote' ) == 'true' && function_exists( 'mc_remote_db' ) ) {
217
+ $mcdb = mc_remote_db();
218
+ }
219
+
220
+ $result = $mcdb->get_row( $wpdb->prepare( "SELECT * FROM " . my_calendar_event_table() . " WHERE occur_id = %d", $mc_id ) );
221
+
222
+ if ( is_object( $result ) ) {
223
+ return true;
224
+ }
225
+
226
+ return false;
227
+ }
228
+
229
+ // get nearest event instance to current date for core
230
+ function mc_get_nearest_event( $id ) {
231
+ global $wpdb;
232
+ $mcdb = $wpdb;
233
+ if ( get_option( 'mc_remote' ) == 'true' && function_exists( 'mc_remote_db' ) ) {
234
+ $mcdb = mc_remote_db();
235
+ }
236
+ $event = $mcdb->get_row( "SELECT *, UNIX_TIMESTAMP(occur_begin) AS ts_occur_begin, UNIX_TIMESTAMP(occur_end) AS ts_occur_end FROM " . my_calendar_event_table() . " JOIN " . my_calendar_table() . " ON (event_id=occur_event_id) JOIN " . my_calendar_categories_table() . " ON (event_category=category_id) WHERE occur_event_id=$id ORDER BY ABS( DATEDIFF( occur_begin, NOW() ) )" );
237
 
238
  return $event;
239
  }
249
  if ( get_option( 'mc_remote' ) == 'true' && function_exists( 'mc_remote_db' ) ) {
250
  $mcdb = mc_remote_db();
251
  }
252
+ $event = $mcdb->get_row( "SELECT *, UNIX_TIMESTAMP(occur_begin) AS ts_occur_begin, UNIX_TIMESTAMP(occur_end) AS ts_occur_end FROM " . my_calendar_event_table() . " JOIN " . my_calendar_table() . " ON (event_id=occur_event_id) JOIN " . my_calendar_categories_table() . " ON (event_category=category_id) WHERE occur_id=$id" );
253
  if ( $type == 'object' ) {
254
  return $event;
255
  } else {
290
  }
291
 
292
  // get all events related to an event ID (group IDs)
293
+ function mc_related_events( $id, $template = false, $return = false ) {
294
  global $wpdb;
295
  $id = (int) $id;
296
  if ( $id === 0 && $return === false ) {
304
  $output = '';
305
  $sql = "SELECT * FROM " . my_calendar_event_table() . " WHERE occur_group_id=$id";
306
  $results = $wpdb->get_results( $sql );
307
+
308
  if ( $return ) {
309
  return $results;
310
  }
311
+
312
  if ( is_array( $results ) && ! empty( $results ) ) {
313
  foreach ( $results as $result ) {
314
+ $event = $result->occur_event_id;
315
+ $current = "<a href='" . admin_url( 'admin.php?page=my-calendar' ) . "&amp;mode=edit&amp;event_id=$event'>";
316
+ $end = "</a>";
317
+ $begin = date_i18n( get_option( 'mc_date_format' ), strtotime( $result->occur_begin ) ) . ', ' . date( get_option( 'mc_time_format' ), strtotime( $result->occur_begin ) );
318
+ $template = $current . $begin . $end;
319
+ $output .= "<li>$template</li>";
320
  }
321
  } else {
322
  $output = "<li>" . __( 'No related events', 'my-calendar' ) . "</li>";
323
  }
324
+ if ( $return == 'template' ) {
325
+ return $output;
326
+ } else {
327
+ echo $output;
328
+ }
329
+ }
330
+
331
+
332
+ // get all events related to an event ID (group IDs)
333
+ function mc_list_related( $id, $this_id, $template = '{date}, {time}' ) {
334
+ global $wpdb;
335
+ $id = (int) $id;
336
+ if ( $id === 0 ) {
337
+ return '';
338
+ }
339
+
340
+ $output = '';
341
+ $sql = "SELECT event_id FROM " . my_calendar_table() . " WHERE event_group_id=$id";
342
+ $results = $wpdb->get_results( $sql );
343
+
344
+ if ( is_array( $results ) && ! empty( $results ) ) {
345
+ foreach ( $results as $result ) {
346
+ $event_id = $result->event_id;
347
+ $event = mc_get_event_core( $event_id );
348
+ $array = mc_create_tags( $event, 'related' );
349
+ if ( mc_key_exists( $template ) ) {
350
+ $template = mc_get_custom_template( $template );
351
+ }
352
+ $html = jd_draw_template( $array, $template );
353
+ $class = ( $event_id == $this_id ) ? ' class="current_event"' : '';
354
+ $output .= "<li$class>$html</li>";
355
+ }
356
+ } else {
357
+ $output = "<li>" . __( 'No related events', 'my-calendar' ) . "</li>";
358
+ }
359
+
360
+ return $output;
361
  }
362
 
363
  /*
375
  * @param int $author Author ID to filter to.
376
  * @return array Array of events with dates as keys.
377
  */
378
+ function my_calendar_events( $from, $to, $category, $ltype, $lvalue, $source, $author, $host, $search = '', $site = 'global' ) {
379
+ $events = my_calendar_grab_events( $from, $to, $category, $ltype, $lvalue, $source, $author, $host, null, $search, $site );
380
 
381
  if ( ! get_option( 'mc_skip_holidays_category' ) || get_option( 'mc_skip_holidays_category' ) == '' ) {
382
  $holidays = array();
383
  } else {
384
+ $holidays = my_calendar_grab_events( $from, $to, get_option( 'mc_skip_holidays_category' ), $ltype, $lvalue, $source, $author, $host, 'holidays', '', $site );
385
  $holiday_array = mc_set_date_array( $holidays );
386
  }
387
  // get events into an easily parseable set, keyed by date.
397
  return $event_array;
398
  }
399
 
400
+ function my_calendar_events_now( $category = 'default', $template = '<strong>{link_title}</strong> {timerange}', $site='' ) {
401
+
402
+ if ( $site ) {
403
+ $site = ( $site == 'global' ) ? BLOG_ID_CURRENT_SITE : $site;
404
+ switch_to_blog( $site );
405
+ }
406
+
407
  global $wpdb;
408
  $mcdb = $wpdb;
409
  if ( get_option( 'mc_remote' ) == 'true' && function_exists( 'mc_remote_db' ) ) {
416
  $select_location = $select_author = $select_host = '';
417
  $now = date( 'Y-m-d H:i:s', current_time( 'timestamp' ) );
418
  $event_query = "SELECT *, UNIX_TIMESTAMP(occur_begin) AS ts_occur_begin, UNIX_TIMESTAMP(occur_end) AS ts_occur_end
419
+ FROM " . my_calendar_event_table( $site ) . " AS e
420
+ JOIN " . my_calendar_table( $site ) . " AS t
421
  ON (event_id=occur_event_id)
422
+ JOIN " . my_calendar_categories_table( $site ) . " AS c
423
  ON (event_category=category_id)
424
  WHERE $select_category $select_location $select_author $select_host $limit_string
425
  AND ( CAST('$now' AS DATETIME) BETWEEN occur_begin AND occur_end )
433
  }
434
  if ( !empty( $arr_events ) ) {
435
  $event = mc_create_tags( $arr_events[0] );
436
+
437
+ if ( mc_key_exists( $template ) ) {
438
+ $template = mc_get_custom_template( $template );
439
+ }
440
 
441
  $output = jd_draw_template( $event, apply_filters( 'mc_happening_now_template', $template, $event ) );
442
+ $return = ( get_option( 'mc_process_shortcodes' ) == 'true' ) ? do_shortcode( $output ) : $output;
443
  } else {
444
+ $return = '';
445
  }
446
+
447
+ if ( $site ) {
448
+ restore_current_blog();
449
+ }
450
+
451
+ return $return;
452
  }
453
 
454
  // Grab all events for the requested date from calendar
455
+ function my_calendar_grab_events( $from, $to, $category = null, $ltype = '', $lvalue = '', $source = 'calendar', $author = null, $host = null, $holidays = null, $search = '', $site = false ) {
456
  global $wpdb;
457
  $mcdb = $wpdb;
458
  if ( get_option( 'mc_remote' ) == 'true' && function_exists( 'mc_remote_db' ) ) {
543
  $search = mc_prepare_search_query( $search );
544
 
545
  $event_query = "SELECT *, UNIX_TIMESTAMP(occur_begin) AS ts_occur_begin, UNIX_TIMESTAMP(occur_end) AS ts_occur_end
546
+ FROM " . my_calendar_event_table( $site ) . "
547
+ JOIN " . my_calendar_table( $site ) . "
548
  ON (event_id=occur_event_id)
549
+ JOIN " . my_calendar_categories_table( $site ) . "
550
  ON (event_category=category_id)
551
  WHERE $select_category $select_location $select_author $select_host $limit_string $search
552
  AND ( DATE(occur_begin) BETWEEN '$from 00:00:00' AND '$to 23:59:59'
558
 
559
  if ( ! empty( $events ) ) {
560
  foreach ( array_keys( $events ) as $key ) {
561
+ $event =& $events[ $key ];
562
+ $event->site_id = $site;
563
+ $arr_events[] = $event;
564
  }
565
  }
566
+
567
  if ( $source != 'upcoming' && $caching ) {
568
  $new_cache = mc_create_cache( $arr_events, $hash, $category, $ltype, $lvalue, $author, $host );
569
  if ( $new_cache ) {
586
  if ( get_option( 'mc_remote' ) == 'true' && function_exists( 'mc_remote_db' ) ) {
587
  $mcdb = mc_remote_db();
588
  }
589
+ $my_calendar = my_calendar_table();
590
  $dbs = $mcdb->get_results( "SHOW TABLE STATUS WHERE name='$my_calendar'" );
591
  foreach( $dbs as $db ) {
592
+ if ( $db->Name == my_calendar_table() ) {
593
  $db_type = $db->Engine;
594
  }
595
  }
my-calendar-generator.php CHANGED
@@ -81,10 +81,10 @@ function mc_generator( $type ) {
81
  </p>
82
  <?php
83
  // Grab users and list them
84
- $users = my_calendar_getUsers();
85
  $options = '';
86
  foreach ( $users as $u ) {
87
- $options = '<option value="' . $u->ID . '">' . esc_html( $u->display_name ) . "</option>\n";
88
  } ?>
89
  <p>
90
  <label for="author"><?php _e( 'Limit by Author', 'my-calendar' ); ?></label>
@@ -130,7 +130,7 @@ function mc_generator( $type ) {
130
  <?php
131
  global $wpdb;
132
  $mcdb = $wpdb;
133
- $query = "SELECT event_begin FROM " . MY_CALENDAR_TABLE . " WHERE event_approved = 1 AND event_flagged <> 1 ORDER BY event_begin ASC LIMIT 0 , 1";
134
  $year1 = date( 'Y', strtotime( $mcdb->get_var( $query ) ) );
135
  $diff1 = date( 'Y' ) - $year1;
136
  $past = $diff1;
@@ -184,7 +184,7 @@ function mc_generator( $type ) {
184
  </select>
185
  </p>
186
  <p id='navigation-info'>
187
- <?php _e( "For navigational fields above and below the calendar: the defaults specified in your settings will be used if the attribute is left blank. Use <code>none</code> to hide all navigation elements.", 'my-calendar' ); ?>
188
  </p>
189
  <p>
190
  <label for="above" id='labove'><?php _e( 'Navigation above calendar', 'my-calendar' ); ?></label>
@@ -228,13 +228,16 @@ function mc_generator( $type ) {
228
  <input type="number" name="skip" id="skip" value="" />
229
  </p>
230
  <p>
231
- <label for="show_today"><?php _e( 'Fallback', 'my-calendar' ); ?></label>
232
  <input type="checkbox" name="show_today" id="show_today" value="yes"/>
233
  </p>
234
  <p>
235
  <label for="type"><?php _e( 'Type of Upcoming Events List', 'my-calendar' ); ?></label>
236
  <select name="type" id="type">
237
  <option value="event" selected="selected"><?php _e( 'Events', 'my-calendar' ); ?></option>
 
 
 
238
  <option value="month"><?php _e( 'Current Month', 'my-calendar' ); ?></option>
239
  <option value="month+1"><?php _e( 'Next Month', 'my-calendar' ); ?></option>
240
  <option value="month+2"><?php _e( '2nd Month Out', 'my-calendar' ); ?></option>
@@ -247,11 +250,17 @@ function mc_generator( $type ) {
247
  <option value="month+9"><?php _e( '9th Month Out', 'my-calendar' ); ?></option>
248
  <option value="month+10"><?php _e( '10th Month Out', 'my-calendar' ); ?></option>
249
  <option value="month+11"><?php _e( '11th Month Out', 'my-calendar' ); ?></option>
250
- <option value="month+12"><?php _e( '12th Month Out', 'my-calendar' ); ?></option>
251
- <option value="year"><?php _e( 'Current Year', 'my-calendar' ); ?></option>
252
- <option value="days"><?php _e( 'Days', 'my-calendar' ); ?></option>
253
  </select>
254
  </p>
 
 
 
 
 
 
 
 
255
  <p>
256
  <label for="order"><?php _e( 'Event Order', 'my-calendar' ); ?></label>
257
  <select name="order" id="order">
81
  </p>
82
  <?php
83
  // Grab users and list them
84
+ $users = mc_get_users();
85
  $options = '';
86
  foreach ( $users as $u ) {
87
+ $options .= '<option value="' . $u->ID . '">' . esc_html( $u->display_name ) . "</option>\n";
88
  } ?>
89
  <p>
90
  <label for="author"><?php _e( 'Limit by Author', 'my-calendar' ); ?></label>
130
  <?php
131
  global $wpdb;
132
  $mcdb = $wpdb;
133
+ $query = "SELECT event_begin FROM " . my_calendar_table() . " WHERE event_approved = 1 AND event_flagged <> 1 ORDER BY event_begin ASC LIMIT 0 , 1";
134
  $year1 = date( 'Y', strtotime( $mcdb->get_var( $query ) ) );
135
  $diff1 = date( 'Y' ) - $year1;
136
  $past = $diff1;
184
  </select>
185
  </p>
186
  <p id='navigation-info'>
187
+ <?php printf( __( "Navigation above and below the calendar: your <a href='%s'>settings</a> if this is left blank. Use <code>none</code> to hide all navigation.", 'my-calendar' ), admin_url( 'admin.php?page=my-calendar-config#mc-output' ) ); ?>
188
  </p>
189
  <p>
190
  <label for="above" id='labove'><?php _e( 'Navigation above calendar', 'my-calendar' ); ?></label>
228
  <input type="number" name="skip" id="skip" value="" />
229
  </p>
230
  <p>
231
+ <label for="show_today"><?php _e( "Show Today's Events", 'my-calendar' ); ?></label>
232
  <input type="checkbox" name="show_today" id="show_today" value="yes"/>
233
  </p>
234
  <p>
235
  <label for="type"><?php _e( 'Type of Upcoming Events List', 'my-calendar' ); ?></label>
236
  <select name="type" id="type">
237
  <option value="event" selected="selected"><?php _e( 'Events', 'my-calendar' ); ?></option>
238
+ <option value="year"><?php _e( 'Current Year', 'my-calendar' ); ?></option>
239
+ <option value="days"><?php _e( 'Days', 'my-calendar' ); ?></option>
240
+ <option value="custom"><?php _e( 'Custom Dates', 'my-calendar' ); ?></option>
241
  <option value="month"><?php _e( 'Current Month', 'my-calendar' ); ?></option>
242
  <option value="month+1"><?php _e( 'Next Month', 'my-calendar' ); ?></option>
243
  <option value="month+2"><?php _e( '2nd Month Out', 'my-calendar' ); ?></option>
250
  <option value="month+9"><?php _e( '9th Month Out', 'my-calendar' ); ?></option>
251
  <option value="month+10"><?php _e( '10th Month Out', 'my-calendar' ); ?></option>
252
  <option value="month+11"><?php _e( '11th Month Out', 'my-calendar' ); ?></option>
253
+ <option value="month+12"><?php _e( '12th Month Out', 'my-calendar' ); ?></option>
 
 
254
  </select>
255
  </p>
256
+ <div class='custom'>
257
+ <p>
258
+ <label for='from'><?php _e( 'Starting Date', 'my-calendar' ); ?></label> <input type='text' name='from' id='from' />
259
+ </p>
260
+ <p>
261
+ <label for='to'><?php _e( 'End Date', 'my-calendar' ); ?></label> <input type='text' name='to' id='to' />
262
+ </p>
263
+ </div>
264
  <p>
265
  <label for="order"><?php _e( 'Event Order', 'my-calendar' ); ?></label>
266
  <select name="order" id="order">
my-calendar-group-manager.php CHANGED
@@ -429,7 +429,7 @@ function my_calendar_print_group_fields( $data, $mode, $event_id, $group_id = ''
429
  <select id="e_host" name="event_host">
430
  <?php
431
  // Grab all the categories and list them
432
- $userList = my_calendar_getUsers();
433
  foreach ( $userList as $u ) {
434
  echo '<option value="' . $u->ID . '"';
435
  if ( is_object( $data ) && $data->event_host == $u->ID ) {
@@ -840,7 +840,7 @@ function mc_check_group_data( $action, $post ) {
840
  'event_latitude' => $event_latitude
841
  );
842
 
843
- $submit = array_map( 'wp_kses_post', $submit );
844
 
845
  if ( $action == 'edit' ) {
846
  unset( $submit['event_author'] );
@@ -1014,9 +1014,8 @@ function mc_list_groups() {
1014
  href="<?php echo admin_url( "admin.php?page=my-calendar-groups&amp;sort=7$sorting" ); ?>"><?php _e( 'Where', 'my-calendar' ) ?></a>
1015
  </th>
1016
  <th scope="col"><a
1017
- href="<?php echo admin_url( "admin.php?page=my-calendar-groups&amp;sort=4$sorting" ); ?>"><?php _e( 'Starts', 'my-calendar' ) ?></a>
1018
  </th>
1019
- <th scope="col"><?php _e( 'Recurs', 'my-calendar' ) ?></th>
1020
  <th scope="col"><a
1021
  href="<?php echo admin_url( "admin.php?page=my-calendar-groups&amp;sort=5$sorting" ); ?>"><?php _e( 'Author', 'my-calendar' ) ?></a>
1022
  </th>
@@ -1036,7 +1035,7 @@ function mc_list_groups() {
1036
  $spam_label = ( $event->event_flagged == 1 ) ? '<strong>Possible spam:</strong> ' : '';
1037
  $author = ( $event->event_author != 0 ) ? get_userdata( $event->event_author ) : 'Public Submitter';
1038
  if ( $event->event_link != '' ) {
1039
- $title = "<a href='" . esc_attr( $event->event_link ) . "'>" . wp_kses_post( $event->event_title ) . "</a>";
1040
  } else {
1041
  $title = $event->event_title;
1042
  } ?>
@@ -1075,43 +1074,58 @@ function mc_list_groups() {
1075
  </div>
1076
  </td>
1077
  <td><?php echo strip_tags( stripslashes( $event->event_label ) ); ?></td>
1078
- <?php if ( $event->event_time != "00:00:00" ) {
1079
  $eventTime = date_i18n( get_option( 'mc_time_format' ), strtotime( $event->event_time ) );
1080
  } else {
1081
  $eventTime = mc_notime_label( $event );
1082
  } ?>
1083
- <td><?php echo "$event->event_begin<br />$eventTime"; ?></td>
1084
- <td>
1085
- <?php
1086
- $recurs = str_split( $event->event_recur, 1 );
1087
- $recur = $recurs[0];
1088
- // Interpret the DB values into something human readable
1089
- if ( $recur == 'S' ) {
1090
- _e( 'Never', 'my-calendar' );
1091
- } else if ( $recur == 'D' ) {
1092
- _e( 'Daily', 'my-calendar' );
1093
- } else if ( $recur == 'E' ) {
1094
- _e( 'Weekdays', 'my-calendar' );
1095
- } else if ( $recur == 'W' ) {
1096
- _e( 'Weekly', 'my-calendar' );
1097
- } else if ( $recur == 'B' ) {
1098
- _e( 'Bi-Weekly', 'my-calendar' );
1099
- } else if ( $recur == 'M' ) {
1100
- _e( 'Monthly (by date)', 'my-calendar' );
1101
- } else if ( $recur == 'U' ) {
1102
- _e( 'Monthly (by day)', 'my-calendar' );
1103
- } else if ( $recur == 'Y' ) {
1104
- _e( 'Yearly', 'my-calendar' );
1105
- }
1106
- ?>&ndash;<?php
1107
- if ( $recur == 'S' ) {
1108
- _e( 'N/A', 'my-calendar' );
1109
- } else if ( mc_event_repeats_forever( $recur, $event->event_repeats ) ) {
1110
- _e( 'Forever', 'my-calendar' );
1111
- } else if ( $event->event_repeats > 0 ) {
1112
- printf( __( '%d Times', 'my-calendar' ), $event->event_repeats );
1113
- }
1114
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1115
  </td>
1116
  <td><?php echo ( is_object( $author ) ) ? $author->display_name : $author; ?></td>
1117
  <?php
@@ -1125,7 +1139,7 @@ function mc_list_groups() {
1125
  <td>
1126
  <div class="category-color"
1127
  style="background-color:<?php echo strip_tags( ( strpos( $this_cat->category_color, '#' ) !== 0 ) ? '#' : '' );
1128
- echo $this_cat->category_color; ?>;"></div> <?php echo wp_kses_post( stripslashes( $this_cat->category_name ) ); ?>
1129
  </td>
1130
  <?php unset( $this_cat ); ?>
1131
  </tr><?php
429
  <select id="e_host" name="event_host">
430
  <?php
431
  // Grab all the categories and list them
432
+ $userList = mc_get_users();
433
  foreach ( $userList as $u ) {
434
  echo '<option value="' . $u->ID . '"';
435
  if ( is_object( $data ) && $data->event_host == $u->ID ) {
840
  'event_latitude' => $event_latitude
841
  );
842
 
843
+ $submit = array_map( 'mc_kses_post', $submit );
844
 
845
  if ( $action == 'edit' ) {
846
  unset( $submit['event_author'] );
1014
  href="<?php echo admin_url( "admin.php?page=my-calendar-groups&amp;sort=7$sorting" ); ?>"><?php _e( 'Where', 'my-calendar' ) ?></a>
1015
  </th>
1016
  <th scope="col"><a
1017
+ href="<?php echo admin_url( "admin.php?page=my-calendar-groups&amp;sort=4$sorting" ); ?>"><?php _e( 'Date/Time', 'my-calendar' ) ?></a>
1018
  </th>
 
1019
  <th scope="col"><a
1020
  href="<?php echo admin_url( "admin.php?page=my-calendar-groups&amp;sort=5$sorting" ); ?>"><?php _e( 'Author', 'my-calendar' ) ?></a>
1021
  </th>
1035
  $spam_label = ( $event->event_flagged == 1 ) ? '<strong>Possible spam:</strong> ' : '';
1036
  $author = ( $event->event_author != 0 ) ? get_userdata( $event->event_author ) : 'Public Submitter';
1037
  if ( $event->event_link != '' ) {
1038
+ $title = "<a href='" . esc_attr( $event->event_link ) . "'>" . mc_kses_post( $event->event_title ) . "</a>";
1039
  } else {
1040
  $title = $event->event_title;
1041
  } ?>
1074
  </div>
1075
  </td>
1076
  <td><?php echo strip_tags( stripslashes( $event->event_label ) ); ?></td>
1077
+ <?php if ( $event->event_endtime != "23:59:59" ) {
1078
  $eventTime = date_i18n( get_option( 'mc_time_format' ), strtotime( $event->event_time ) );
1079
  } else {
1080
  $eventTime = mc_notime_label( $event );
1081
  } ?>
1082
+ <td><?php
1083
+ $date_format = ( get_option( 'mc_date_format' ) == '' ) ? get_option( 'date_format' ) : get_option( 'mc_date_format' );
1084
+ $begin = date_i18n( $date_format, strtotime( $event->event_begin ) );
1085
+ echo "$begin, $eventTime"; ?>
1086
+ <div class="recurs">
1087
+ <strong><?php _e( 'Recurs', 'my-calendar' ); ?></strong>
1088
+ <?php
1089
+ $recurs = str_split( $event->event_recur, 1 );
1090
+ $recur = $recurs[0];
1091
+ $every = ( isset( $recurs[1] ) ) ? $recurs[1] : 1;
1092
+
1093
+ // Interpret the DB values into something human readable
1094
+ switch ( $recur ) {
1095
+ case 'S':
1096
+ _e( 'Never', 'my-calendar' );
1097
+ break;
1098
+ case 'D':
1099
+ ( $every == 1 ) ? _e( 'Daily', 'my-calendar' ) : printf( __( 'Every %d days', 'my-calendar' ), $every );
1100
+ break;
1101
+ case 'E':
1102
+ ( $every == 1 ) ? _e( 'Weekdays', 'my-calendar' ) : printf( __( 'Every %d weekdays', 'my-calendar' ), $every );
1103
+ break;
1104
+ case 'W':
1105
+ ( $every == 1 ) ? _e( 'Weekly', 'my-calendar' ) : printf( __( 'Every %d weeks', 'my-calendar' ), $every );
1106
+ break;
1107
+ case 'B':
1108
+ _e( 'Bi-Weekly', 'my-calendar' );
1109
+ break;
1110
+ case 'M':
1111
+ ( $every == 1 ) ? _e( 'Monthly (by date)', 'my-calendar' ) : printf( __( 'Every %d months (by date)', 'my-calendar' ), $every );
1112
+ break;
1113
+ case 'U':
1114
+ _e( 'Monthly (by day)', 'my-calendar' );
1115
+ break;
1116
+ case 'Y':
1117
+ ( $every == 1 ) ? _e( 'Yearly', 'my-calendar' ) : printf( __( 'Every %d years', 'my-calendar' ), $every );
1118
+ break;
1119
+ }
1120
+ $eternity = _mc_increment_values( $recur );
1121
+ if ( $recur == 'S' ) {
1122
+ } else if ( $event->event_repeats > 0 ) {
1123
+ printf( __( '&ndash; %d Times', 'my-calendar' ), $event->event_repeats );
1124
+ } else if ( $eternity ) {
1125
+ printf( __( '&ndash; %d Times', 'my-calendar' ), $eternity );
1126
+ }
1127
+ ?>
1128
+ </div>
1129
  </td>
1130
  <td><?php echo ( is_object( $author ) ) ? $author->display_name : $author; ?></td>
1131
  <?php
1139
  <td>
1140
  <div class="category-color"
1141
  style="background-color:<?php echo strip_tags( ( strpos( $this_cat->category_color, '#' ) !== 0 ) ? '#' : '' );
1142
+ echo $this_cat->category_color; ?>;"></div> <?php echo mc_kses_post( stripslashes( $this_cat->category_name ) ); ?>
1143
  </td>
1144
  <?php unset( $this_cat ); ?>
1145
  </tr><?php
my-calendar-help.php CHANGED
@@ -17,14 +17,18 @@ function my_calendar_help() {
17
  <h2 id="help"><?php _e( 'Getting Started', 'my-calendar' ); ?></h2>
18
 
19
  <div class="inside">
20
- <ul>
 
 
 
 
 
 
 
21
  <li><?php _e( 'Add the My Calendar shortcode (<code>[my_calendar]</code>) to a page.', 'my-calendar' ); ?></li>
22
  <li><?php _e( 'Add events by clicking on the Add/Edit Events link in the admin or on "Add Events" in the toolbar.', 'my-calendar' ); ?></li>
23
  <li><?php _e( 'Select your preferred stylesheet in the Styles Editor', 'my-calendar' ); ?></li>
24
  </ul>
25
- <p>
26
- <?php printf( __( 'Read more help documentation below or <a href="%s">purchase the My Calendar User\'s Guide</a> to learn more -- but the above is all that you need to do to begin using the calendar.', 'my-calendar' ), 'https://www.joedolson.com/my-calendar/users-guide/' ); ?>
27
- </p>
28
  <?php do_action( 'mc_before_help' ); ?>
29
  <ul class="mc-settings checkboxes">
30
  <li><a href="#mc-generator"><?php _e( 'Shortcode Generator', 'my-calendar' ); ?></a></li>
@@ -32,8 +36,7 @@ function my_calendar_help() {
32
  <li><a href="#icons"><?php _e( 'Icons', 'my-calendar' ); ?></a></li>
33
  <li><a href="#mc-styles"><?php _e( 'Styles', 'my-calendar' ); ?></a></li>
34
  <li><a href="#templates"><?php _e( 'Templating', 'my-calendar' ); ?></a></li>
35
- <li><a href="#get-support"><?php _e( 'Support Form', 'my-calendar' ); ?></a></li>
36
- <li><a href="#notes"><?php _e( 'Helpful Information', 'my-calendar' ); ?></a></li>
37
  </ul>
38
  </div>
39
  </div>
@@ -119,15 +122,13 @@ function my_calendar_help() {
119
  </li>
120
  <li><code>id</code>: <?php _e( 'String to give shortcode a unique ID.', 'my-calendar' ); ?></li>
121
  </ul>
122
- <p>
123
- <em><?php _e( 'The main My Calendar shortcode can be generated from a button in your post and page editor. The mini calendar can also be accessed and configured as a widget.', 'my-calendar' ); ?></em>
124
- </p>
125
  <h4><?php _e( 'Additional Views (Upcoming events, today\'s events)', 'my-calendar' ); ?></h4>
126
 
127
  <textarea readonly='readonly' class="large-text readonly">[my_calendar_upcoming before="3" after="3" type="event" fallback="No events coming up!" category="General" author="1" host="1" template="{title} {date}" order="asc" show_today="yes" skip="0" ltype="" lvalue="" from="" to=""]</textarea>
128
 
129
  <p>
130
- <?php _e( 'Displays the output of the Upcoming Events widget. <code>before</code> and <code>after</code> are numbers; <code>type</code> is either "event" or "days", and <code>category</code> and <code>author</code> work the same as in the main calendar shortcode. Templates use the template codes listed below. <code>fallback</code> provides text if no events meet your criteria. Order sets sort order for the list &ndash; ascending (<code>asc</code>) or descending (<code>desc</code>). <code>show_today</code> indicates whether to include today\'s events in the list. <code>Skip</code> is how many events to skip in the list.', 'my-calendar' ); ?> <?php _e( 'Use <code>from</code> and <code>to</code> to display events between two specific dates', 'my-calendar' ); ?>
131
  </p>
132
 
133
  <textarea readonly='readonly' class="large-text readonly">[my_calendar_today category="" author="1" host="1" fallback="Nothing today!" template="{title} {date}" date=""]</textarea>
@@ -201,11 +202,7 @@ function my_calendar_help() {
201
  <h2><?php _e( 'Category Icons', 'my-calendar' ); ?></h2>
202
 
203
  <div class="inside">
204
- <p>
205
- <?php _e( 'My Calendar is designed to manage multiple calendars. The basis for these calendars are categories; you can setup a calendar page which includes all categories, or you can dedicate separate pages to calendars in each category. For an example, this might be useful for you in managing the tour calendars for multiple bands; event calendars for a variety of locations, etc.', 'my-calendar' ); ?>
206
- </p>
207
-
208
- <p>
209
  <?php _e( 'The pre-installed category icons may not be what you need. I assume that you\'ll upload your own icons -- place your custom icons in a folder at "my-calendar-custom" to avoid having them overwritten by upgrades.', 'my-calendar' ); ?> <?php _e( 'You can alternately place icons in:', 'my-calendar' ); ?>
210
  <code><?php echo str_replace( '/my-calendar', '', plugin_dir_path( __FILE__ ) ) . 'my-calendar-custom/'; ?></code>
211
  </p>
@@ -505,32 +502,6 @@ function my_calendar_help() {
505
  </div>
506
  </div>
507
 
508
- <div class="ui-sortable meta-box-sortables" id="notes">
509
- <div class="postbox">
510
- <h2 id="info"><?php _e( 'Helpful Information', 'my-calendar' ); ?></h2>
511
-
512
- <div class="inside">
513
- <p>
514
- <?php _e( '<strong>Uninstalling the plugin</strong>: Although the WordPress standard and expectation is for plug-ins to delete any custom database tables when they\'re uninstalled, My Calendar <em>does not do this</em>. This was a conscious decision on my part -- the data stored in your My Calendar tables is yours; with the sole exception of the "General" category, you added every piece of it yourself. As such, I feel it would be a major disservice to you to delete this information if you uninstall the plug-in. As a result, if you wish to get rid of the plug-in completely, you\'ll need to remove those tables yourself. All your My Calendar settings will be deleted, however.', 'my-calendar' ); ?>
515
- </p>
516
-
517
- <p>
518
- <?php printf( __( '<strong>Donations</strong>: I appreciate anything you can give. %s may not seem like much, but it can really add up when thousands of people are using the software. Please note that I am not a non-profit organization, and your gifts are not tax deductible. Thank you!', 'my-calendar' ), '$5' ); ?>
519
- </p>
520
- <p>
521
- <?php _e( '<strong>How to upgrade from My Calendar: Submissions to My Calendar Pro</strong>', 'my-calendar' ); ?>
522
- </p>
523
- <ol>
524
- <li><?php _e( 'Update to My Calendar: Submissions version 1.2.9', 'my-calendar' ); ?></li>
525
- <li><?php _e( 'Deactivate and delete My Calendar: Submissions', 'my-calendar' ); ?></li>
526
- <li><?php printf( __( 'Log-in to your account at <a href="%s">Joe Dolson Accessible Web Design</a> and download My Calendar Pro', 'my-calendar' ), 'https://www.joedolson.com/account/' ); ?></li>
527
- <li><?php _e( 'Upload My Calendar Pro and activate.', 'my-calendar' ); ?></li>
528
- <li><?php _e( 'Input your My Calendar: Submissions license key into My Calendar Pro', 'my-calendar' ); ?></li>
529
- </ol>
530
- </div>
531
- </div>
532
- </div>
533
-
534
  </div>
535
  </div>
536
  </div>
17
  <h2 id="help"><?php _e( 'Getting Started', 'my-calendar' ); ?></h2>
18
 
19
  <div class="inside">
20
+ <div class='mc-support-me'>
21
+ <p>
22
+ <?php printf(
23
+ __( 'Please, consider a <a href="%s">donation</a> or a <a href="%s">purchase</a> to support My Calendar!', 'my-calendar' )
24
+ , "https://www.joedolson.com/donate/", "https://www.joedolson.com/my-calendar/pro/" ); ?>
25
+ </p>
26
+ </div>
27
+ <ul class="list">
28
  <li><?php _e( 'Add the My Calendar shortcode (<code>[my_calendar]</code>) to a page.', 'my-calendar' ); ?></li>
29
  <li><?php _e( 'Add events by clicking on the Add/Edit Events link in the admin or on "Add Events" in the toolbar.', 'my-calendar' ); ?></li>
30
  <li><?php _e( 'Select your preferred stylesheet in the Styles Editor', 'my-calendar' ); ?></li>
31
  </ul>
 
 
 
32
  <?php do_action( 'mc_before_help' ); ?>
33
  <ul class="mc-settings checkboxes">
34
  <li><a href="#mc-generator"><?php _e( 'Shortcode Generator', 'my-calendar' ); ?></a></li>
36
  <li><a href="#icons"><?php _e( 'Icons', 'my-calendar' ); ?></a></li>
37
  <li><a href="#mc-styles"><?php _e( 'Styles', 'my-calendar' ); ?></a></li>
38
  <li><a href="#templates"><?php _e( 'Templating', 'my-calendar' ); ?></a></li>
39
+ <li><a href="#get-support"><?php _e( 'Get Support', 'my-calendar' ); ?></a></li>
 
40
  </ul>
41
  </div>
42
  </div>
122
  </li>
123
  <li><code>id</code>: <?php _e( 'String to give shortcode a unique ID.', 'my-calendar' ); ?></li>
124
  </ul>
125
+
 
 
126
  <h4><?php _e( 'Additional Views (Upcoming events, today\'s events)', 'my-calendar' ); ?></h4>
127
 
128
  <textarea readonly='readonly' class="large-text readonly">[my_calendar_upcoming before="3" after="3" type="event" fallback="No events coming up!" category="General" author="1" host="1" template="{title} {date}" order="asc" show_today="yes" skip="0" ltype="" lvalue="" from="" to=""]</textarea>
129
 
130
  <p>
131
+ <?php _e( 'Displays the output of the Upcoming Events widget. <code>before</code> and <code>after</code> are numbers; <code>type</code> is either "event", "days", or "custom" and <code>category</code> and <code>author</code> work the same as in the main calendar shortcode. Templates use the template codes listed below. <code>fallback</code> provides text if no events meet your criteria. Order sets sort order for the list &ndash; ascending (<code>asc</code>) or descending (<code>desc</code>). <code>show_today</code> indicates whether to include today\'s events in the list. <code>Skip</code> is how many events to skip in the list.', 'my-calendar' ); ?> <?php _e( 'Use <code>from</code> and <code>to</code> with type="custom" to display events between two specific dates', 'my-calendar' ); ?> <?php _e( 'The keyword "today" in the <code>to</code> attribute will give you all events between the from date and the current date.', 'my-calendar' ); ?>
132
  </p>
133
 
134
  <textarea readonly='readonly' class="large-text readonly">[my_calendar_today category="" author="1" host="1" fallback="Nothing today!" template="{title} {date}" date=""]</textarea>
202
  <h2><?php _e( 'Category Icons', 'my-calendar' ); ?></h2>
203
 
204
  <div class="inside">
205
+ <p>
 
 
 
 
206
  <?php _e( 'The pre-installed category icons may not be what you need. I assume that you\'ll upload your own icons -- place your custom icons in a folder at "my-calendar-custom" to avoid having them overwritten by upgrades.', 'my-calendar' ); ?> <?php _e( 'You can alternately place icons in:', 'my-calendar' ); ?>
207
  <code><?php echo str_replace( '/my-calendar', '', plugin_dir_path( __FILE__ ) ) . 'my-calendar-custom/'; ?></code>
208
  </p>
502
  </div>
503
  </div>
504
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
505
  </div>
506
  </div>
507
  </div>
my-calendar-locations.php CHANGED
@@ -3,10 +3,15 @@ if ( ! defined( 'ABSPATH' ) ) {
3
  exit;
4
  } // Exit if accessed directly
5
 
6
- if ( ! empty( $_SERVER['SCRIPT_FILENAME'] ) && 'my-calendar-locations.php' == basename( $_SERVER['SCRIPT_FILENAME'] ) ) {
7
- die ( 'Please do not load this page directly. Thanks!' );
 
 
 
 
8
  }
9
 
 
10
  function mc_update_location_controls() {
11
  if ( isset( $_POST['mc_locations'] ) && $_POST['mc_locations'] == 'true' ) {
12
  $nonce = $_POST['_wpnonce'];
@@ -59,7 +64,7 @@ function mc_mass_delete_locations() {
59
  function mc_insert_location( $add ) {
60
  global $wpdb;
61
  $mcdb = $wpdb;
62
- $add = array_map( 'wp_kses_post', $add );
63
  $formats = array( '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%f', '%f', '%d', '%s', '%s', '%s' );
64
  $results = $mcdb->insert( my_calendar_locations_table(), $add, $formats );
65
 
@@ -69,7 +74,7 @@ function mc_insert_location( $add ) {
69
  function mc_modify_location( $update, $where ) {
70
  global $wpdb;
71
  $mcdb = $wpdb;
72
- $update = array_map( 'wp_kses_post', $update );
73
  $formats = array( '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%f', '%f', '%d', '%s', '%s', '%s' );
74
  $results = $mcdb->update( my_calendar_locations_table(), $update, $where, $formats, '%d' );
75
 
@@ -238,7 +243,17 @@ function mc_show_location_form( $view = 'add', $curID = '' ) {
238
  </div>
239
  </div>
240
  </div>
 
 
 
 
 
 
 
 
 
241
  </div>
 
242
  <?php mc_show_sidebar(); ?>
243
  </div>
244
 
@@ -355,56 +370,59 @@ function mc_manage_locations() {
355
  <p><em>
356
  <?php _e( 'Please note: editing or deleting locations stored for re-use will have no effect on any event previously scheduled at that location. The location database exists purely as a shorthand method to enter frequently used locations into event records.', 'my-calendar' ); ?>
357
  </em></p>
 
 
358
 
 
 
359
  <form method="post" action="<?php echo admin_url( "admin.php?page=my-calendar-locations" ); ?>">
360
- <div><input type="hidden" name="_wpnonce" value="<?php echo wp_create_nonce( 'my-calendar-nonce' ); ?>"/></div>
361
- <div><input type="hidden" name="mc_locations" value="true"/></div>
362
- <fieldset>
363
- <legend><?php _e( 'Control Input Options for Location Fields', 'my-calendar' ); ?></legend>
364
- <div id="mc-accordion">
365
- <?php
366
- // array of fields allowing input control.
367
- $location_fields = array(
368
- 'event_label',
369
- 'event_city',
370
- 'event_state',
371
- 'event_country',
372
- 'event_postcode',
373
- 'event_region'
374
- );
375
- $mc_location_controls = get_option( 'mc_location_controls' );
376
- foreach ( $location_fields as $field ) {
377
- ?>
378
- <h4><?php echo ucfirst( str_replace( 'event_', '', $field ) ); ?></h4>
379
- <div>
380
- <label
381
- for="loc_values_<?php echo $field; ?>"><?php printf( __( 'Location Controls for %s', 'my-calendar' ), ucfirst( str_replace( 'event_', '', $field ) ) ); ?>
382
- (<?php _e( 'Value, Label (one per line)', 'my-calendar' ); ?>)</label><br/>
383
- <?php
384
- $locations = '';
385
- if ( is_array( $mc_location_controls ) && isset( $mc_location_controls[ $field ] ) ) {
386
- foreach ( $mc_location_controls[ $field ] as $key => $value ) {
387
- $locations .= stripslashes( "$key,$value" ) . "\n";
388
- }
389
  }
390
- ?>
391
- <textarea name="mc_location_controls[<?php echo $field; ?>][]"
392
- id="loc_values_<?php echo $field; ?>" cols="80"
393
- rows="6"><?php echo trim( $locations ); ?></textarea>
394
- </div>
395
- <?php } ?>
396
- </div>
397
- <p><input type='submit' class='button secondary'
398
- value='<?php _e( 'Save Location Controls', 'my-calendar' ); ?>'/></p>
399
- </fieldset>
400
- </div>
401
- <?php
402
  }
403
 
404
  function mc_locations_fields( $has_data, $data, $context = 'location' ) {
405
  $return = '<div class="mc-locations">';
406
  if ( current_user_can( 'mc_edit_locations' ) && $context == 'event' ) {
407
- $return .= '<p><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>';
408
  }
409
  $return .= '
410
  <p class="checkbox">
@@ -524,7 +542,12 @@ function mc_locations_fields( $has_data, $data, $context = 'location' ) {
524
  if ( $context == 'location' ) {
525
  $location_access = unserialize( $data->{$context . '_access'} );
526
  } else {
527
- $location_access = unserialize( mc_location_data( 'location_access', $data->event_location ) );
 
 
 
 
 
528
  }
529
  } else {
530
  $location_access = array();
3
  exit;
4
  } // Exit if accessed directly
5
 
6
+ function mc_update_location( $field, $data, $location ) {
7
+ global $wpdb;
8
+ $field = sanitize_key( $field );
9
+ $result = $wpdb->query( $wpdb->prepare( "UPDATE " . my_calendar_locations_table() . " SET $field = %d WHERE location_id=%d", $data, $location ) );
10
+
11
+ return $result;
12
  }
13
 
14
+
15
  function mc_update_location_controls() {
16
  if ( isset( $_POST['mc_locations'] ) && $_POST['mc_locations'] == 'true' ) {
17
  $nonce = $_POST['_wpnonce'];
64
  function mc_insert_location( $add ) {
65
  global $wpdb;
66
  $mcdb = $wpdb;
67
+ $add = array_map( 'mc_kses_post', $add );
68
  $formats = array( '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%f', '%f', '%d', '%s', '%s', '%s' );
69
  $results = $mcdb->insert( my_calendar_locations_table(), $add, $formats );
70
 
74
  function mc_modify_location( $update, $where ) {
75
  global $wpdb;
76
  $mcdb = $wpdb;
77
+ $update = array_map( 'mc_kses_post', $update );
78
  $formats = array( '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%f', '%f', '%d', '%s', '%s', '%s' );
79
  $results = $mcdb->update( my_calendar_locations_table(), $update, $where, $formats, '%d' );
80
 
243
  </div>
244
  </div>
245
  </div>
246
+ <div class="ui-sortable meta-box-sortables">
247
+ <div class="postbox">
248
+ <h2><?php _e( 'Location Controls', 'my-calendar' ); ?></h2>
249
+
250
+ <div class="inside">
251
+ <?php mc_location_controls(); ?>
252
+ </div>
253
+ </div>
254
+ </div>
255
  </div>
256
+ </div>
257
  <?php mc_show_sidebar(); ?>
258
  </div>
259
 
370
  <p><em>
371
  <?php _e( 'Please note: editing or deleting locations stored for re-use will have no effect on any event previously scheduled at that location. The location database exists purely as a shorthand method to enter frequently used locations into event records.', 'my-calendar' ); ?>
372
  </em></p>
373
+ <?php
374
+ }
375
 
376
+ function mc_location_controls() {
377
+ ?>
378
  <form method="post" action="<?php echo admin_url( "admin.php?page=my-calendar-locations" ); ?>">
379
+ <div><input type="hidden" name="_wpnonce" value="<?php echo wp_create_nonce( 'my-calendar-nonce' ); ?>"/></div>
380
+ <div><input type="hidden" name="mc_locations" value="true"/></div>
381
+ <fieldset>
382
+ <legend><?php _e( 'Control Input Options for Location Fields', 'my-calendar' ); ?></legend>
383
+ <div id="mc-accordion">
384
+ <?php
385
+ // array of fields allowing input control.
386
+ $location_fields = array(
387
+ 'event_label',
388
+ 'event_city',
389
+ 'event_state',
390
+ 'event_country',
391
+ 'event_postcode',
392
+ 'event_region'
393
+ );
394
+ $mc_location_controls = get_option( 'mc_location_controls' );
395
+ foreach ( $location_fields as $field ) {
396
+ ?>
397
+ <h4><span class="dashicons" aria-hidden="true"> </span><?php echo ucfirst( str_replace( 'event_', '', $field ) ); ?></h4>
398
+ <div>
399
+ <label
400
+ for="loc_values_<?php echo $field; ?>"><?php printf( __( 'Location Controls for %s', 'my-calendar' ), ucfirst( str_replace( 'event_', '', $field ) ) ); ?>
401
+ (<?php _e( 'Value, Label (one per line)', 'my-calendar' ); ?>)</label><br/>
402
+ <?php
403
+ $locations = '';
404
+ if ( is_array( $mc_location_controls ) && isset( $mc_location_controls[ $field ] ) ) {
405
+ foreach ( $mc_location_controls[ $field ] as $key => $value ) {
406
+ $locations .= stripslashes( "$key,$value" ) . "\n";
 
407
  }
408
+ }
409
+ ?>
410
+ <textarea name="mc_location_controls[<?php echo $field; ?>][]"
411
+ id="loc_values_<?php echo $field; ?>" cols="80"
412
+ rows="6"><?php echo trim( $locations ); ?></textarea>
413
+ </div>
414
+ <?php } ?>
415
+ </div>
416
+ <p><input type='submit' class='button secondary'
417
+ value='<?php _e( 'Save Location Controls', 'my-calendar' ); ?>'/></p>
418
+ </fieldset>
419
+ <?php
420
  }
421
 
422
  function mc_locations_fields( $has_data, $data, $context = 'location' ) {
423
  $return = '<div class="mc-locations">';
424
  if ( current_user_can( 'mc_edit_locations' ) && $context == 'event' ) {
425
+ $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>';
426
  }
427
  $return .= '
428
  <p class="checkbox">
542
  if ( $context == 'location' ) {
543
  $location_access = unserialize( $data->{$context . '_access'} );
544
  } else {
545
+ if ( property_exists( $data, 'event_location' ) ) {
546
+ $event_location = $data->event_location;
547
+ } else {
548
+ $event_location = false;
549
+ }
550
+ $location_access = unserialize( mc_location_data( 'location_access', $event_location ) );
551
  }
552
  } else {
553
  $location_access = array();
my-calendar-output.php CHANGED
@@ -54,8 +54,15 @@ function my_calendar_draw_events( $events, $type, $process_date, $time, $templat
54
  $begin .= "<div id='date-$process_date' class='calendar-events'>";
55
  }
56
  foreach ( array_keys( $events ) as $key ) {
57
- $event =& $events[ $key ];
58
- $check = mc_test_occurrence_overlap( $event, true );
 
 
 
 
 
 
 
59
  if ( $check == '' ) {
60
  $output_array[] = my_calendar_draw_event( $event, $type, $process_date, $time, $template );
61
  }
@@ -151,8 +158,12 @@ function mc_category_icon_title( $title, $post_id = null ) {
151
  $event_id = ( isset( $_GET['mc_id'] ) && is_numeric( $_GET['mc_id'] ) ) ? $_GET['mc_id'] : get_post_meta( $post_id, '_mc_event_id', true );
152
  if ( is_numeric( $event_id ) ) {
153
  $event = mc_get_event_core( $event_id );
154
- $icon = mc_category_icon( $event );
155
- $title = $icon . ' ' . wp_kses_post( $title );
 
 
 
 
156
  }
157
  }
158
  }
@@ -167,7 +178,11 @@ function my_calendar_draw_event( $event, $type = "calendar", $process_date, $tim
167
  return '';
168
  }
169
  // if event ends at midnight today (e.g., very first thing of the day), exit without re-drawing
170
- if ( $event->event_endtime == '00:00:00' && date( 'Y-m-d', strtotime( $event->occur_end ) ) == $process_date && date( 'Y-m-d', strtotime( $event->occur_begin ) ) != $process_date ) {
 
 
 
 
171
  return '';
172
  }
173
  if ( $event->category_private == 1 && ! is_user_logged_in() ) {
@@ -185,6 +200,9 @@ function my_calendar_draw_event( $event, $type = "calendar", $process_date, $tim
185
  if ( $template != '' && mc_file_exists( sanitize_file_name( $template ) ) ) {
186
  $template = @file_get_contents( mc_get_file( sanitize_file_name( $template ) ) );
187
  $details = jd_draw_template( $data, $template );
 
 
 
188
  } else {
189
  switch ( $type ) {
190
  case 'mini':
@@ -222,9 +240,10 @@ function my_calendar_draw_event( $event, $type = "calendar", $process_date, $tim
222
  $uid = 'mc_' . $event->occur_id;
223
  $day_id = date( 'd', strtotime( $process_date ) );
224
 
225
- $image = mc_category_icon( $event );
226
  $has_image = ( $image != '' ) ? ' has-image' : '';
227
- $header .= "<div id='$uid-$day_id-$type' class='mc-$uid $type-event " . "mc_" . sanitize_title( $event->category_name ) . " vevent'>\n";
 
228
 
229
  switch ( $type ) {
230
  case 'calendar' : $title_template = ( mc_get_template( 'title' ) == '' ) ? '{title}' : mc_get_template( 'title' ); break;
@@ -234,7 +253,7 @@ function my_calendar_draw_event( $event, $type = "calendar", $process_date, $tim
234
  }
235
 
236
  $event_title = jd_draw_template( $data, $title_template );
237
- $event_title = ( $event_title == '' ) ? jd_draw_template( $data, '{title}' ) : wp_kses_post( $event_title ); //prevent empty titles
238
 
239
  if ( strpos( $event_title, 'href' ) === false && $type != 'mini' && $type != 'list' ) {
240
  if ( get_option( 'mc_open_uri' ) == 'true' ) {
@@ -254,11 +273,11 @@ function my_calendar_draw_event( $event, $type = "calendar", $process_date, $tim
254
  $inner_heading = apply_filters( 'mc_heading_inner_title', $wrap . $image . trim( $event_title ) . $balance, $event_title, $event );
255
  $header .= ( $type != 'single' && $type != 'list' ) ? "<$heading_level class='event-title summary$group_class' id='$uid-$day_id-$type-title'>$inner_heading</$heading_level>\n" : '';
256
  $event_title = ( $type == 'single' ) ? apply_filters( 'mc_single_event_title', $event_title, $event ) : $event_title;
257
- $title = ( $type == 'single' && ! is_singular( 'mc-events' ) ) ? "<h2 class='event-title summary'>$image $event_title</h2>\n" : '';
258
  $title = apply_filters( 'mc_event_title', $title, $event, $event_title, $image );
259
- $header .= $title;
260
  $close_image = apply_filters( 'mc_close_button', "<img src=\"" . plugin_dir_url( __FILE__ ) . "images/event-close.png\" alt='" . __( 'Close', 'my-calendar' ) . "' />" );
261
- $close_button = "<button aria-controls='$uid-$day_id-$type-details' class='mc-toggle close'>$close_image</button>";
262
 
263
  if ( mc_show_details( $time, $type ) ) {
264
  $close = ( $type == 'calendar' || $type == 'mini' ) ? $close_button : '';
@@ -318,21 +337,21 @@ function my_calendar_draw_event( $event, $type = "calendar", $process_date, $tim
318
  $image = ( $event->event_image != '' ) ? "<img src='$event->event_image' alt='' class='mc-image photo' />" : '';
319
  }
320
  if ( get_option( 'mc_desc' ) == 'true' || $type == 'single' ) {
321
- $description = wpautop( stripcslashes( wp_kses_post( $event->event_desc ) ), 1 );
322
- $description = "<div class='longdesc'>$description</div>";
323
  }
324
  if ( get_option( 'mc_short' ) == 'true' && $type != 'single' ) {
325
- $short = wpautop( stripcslashes( wp_kses_post( $event->event_short ) ), 1 );
326
  $short = "<div class='shortdesc'>$short</div>";
327
  }
328
 
329
  if ( get_option( 'mc_event_registration' ) == 'true' ) {
330
  switch ( $event->event_open ) {
331
  case '0':
332
- $status = wp_kses_post( get_option( 'mc_event_closed' ) );
333
  break;
334
  case '1':
335
- $status = wp_kses_post( get_option( 'mc_event_open' ) );
336
  break;
337
  case '2':
338
  $status = '';
@@ -344,9 +363,10 @@ function my_calendar_draw_event( $event, $type = "calendar", $process_date, $tim
344
  $status = '';
345
  }
346
 
347
- $status = ( $status != '' ) ? "<p>$status</p>" : '';
348
- $status = apply_filters( 'mc_registration_state', $status, $event );
349
- $return = ( $type == 'single' ) ? "<p class='view-full'><a href='" . get_option( 'mc_uri' ) . "'>" . __( 'View full calendar', 'my-calendar' ) . "</a></p>" : '';
 
350
 
351
  if ( ! mc_show_details( $time, $type ) ) {
352
  $description = $short = $status = '';
@@ -360,7 +380,7 @@ function my_calendar_draw_event( $event, $type = "calendar", $process_date, $tim
360
 
361
  if ( $event_link != '' && get_option( 'mc_event_link' ) != 'false' ) {
362
  $is_external = mc_external_link( $event_link );
363
- $external_class = ( $is_external ) ? "class='$type-link external'" : "class='$type-link'";
364
  $link_template = ( mc_get_template( 'link' ) != '' ) ? mc_get_template( 'link' ) : '{title}';
365
  $link_text = jd_draw_template( $data, $link_template );
366
  $link = "<p><a href='" . esc_url( $event_link ) . "' $external_class>" . $link_text . "</a></p>";
@@ -408,6 +428,20 @@ function my_calendar_draw_event( $event, $type = "calendar", $process_date, $tim
408
  return $details;
409
  }
410
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
411
  function mc_show_details( $time, $type ) {
412
  return ( $type == 'calendar' && get_option( 'mc_open_uri' ) == 'true' && $time != 'day' ) ? false : true;
413
  }
@@ -416,7 +450,7 @@ add_filter( 'mc_after_event', 'mc_edit_panel', 10, 4 );
416
  function mc_edit_panel( $html, $event, $type, $time ) {
417
  // create edit links
418
  $edit = '';
419
- if ( mc_can_edit_event( $event->event_id ) && get_option( 'mc_remote' ) != 'true' ) {
420
  $mc_id = $event->occur_id;
421
  $groupedit = ( $event->event_group_id != 0 ) ? " &bull; <a href='" . admin_url( "admin.php?page=my-calendar-groups&amp;mode=edit&amp;event_id=$event->event_id&amp;group_id=$event->event_group_id" ) . "' class='group'>" . __( 'Edit Group', 'my-calendar' ) . "</a>\n" : '';
422
  $recurs = str_split( $event->event_recur, 1 );
@@ -484,7 +518,7 @@ function mc_build_date_switcher( $type = 'calendar', $cid = 'all', $time = 'mont
484
  $date_switcher .= '</select>' . "\n" . '
485
  <label class="maybe-hide" for="' . $cid . '-year">' . __( 'Year', 'my-calendar' ) . ':</label> <select id="' . $cid . '-year" name="yr">' . "\n";
486
  // query to identify oldest start date in the database
487
- $query = "SELECT event_begin FROM " . MY_CALENDAR_TABLE . " WHERE event_approved = 1 AND event_flagged <> 1 ORDER BY event_begin ASC LIMIT 0 , 1";
488
  $year1 = date( 'Y', strtotime( $mcdb->get_var( $query ) ) );
489
  $diff1 = date( 'Y' ) - $year1;
490
  $past = $diff1;
@@ -584,6 +618,10 @@ function mc_format_toggle( $format, $toggle, $time ) {
584
  $toggle = '';
585
  }
586
 
 
 
 
 
587
  return apply_filters( 'mc_format_toggle_html', $toggle, $format, $time );
588
  }
589
 
@@ -640,7 +678,8 @@ function mc_date_array( $timestamp, $period ) {
640
  }
641
  $first = date( 'N', $timestamp );
642
  $n = ( get_option( 'start_of_week' ) == 1 ) ? $first - 1 : $first;
643
- $from = date( 'Y-m-d', strtotime( "-$n days", $timestamp ) );
 
644
  $endtime = mktime( 0, 0, 0, date( 'm', $timestamp ), date( 't', $timestamp ), date( 'Y', $timestamp ) );
645
  // $endtime = strtotime("+$months months",$endtime); // this allows multiple months displayed. Will figure out splitting tables...
646
  $last = date( 'N', $endtime );
@@ -683,7 +722,7 @@ function mc_events_class( $events, $date = false ) {
683
  if ( strpos( $class, $cat ) === false ) {
684
  $class .= $cat;
685
  }
686
- if ( mc_get_category_detail( $event->category_id, 'category_private' ) == 1 && !is_user_logged_in() ) {
687
  $class = '';
688
  }
689
  }
@@ -706,7 +745,7 @@ function mc_list_title( $events ) {
706
  } else {
707
  $cstate = sprintf( __( " and %d other events", 'my-calendar' ), $count );
708
  }
709
- $title = apply_filters( 'mc_list_event_title_hint', wp_kses_post( stripcslashes( $now->event_title ) ), $now ) . "<span class='mc-list-extended'>$cstate</span>";
710
 
711
  return $title;
712
  }
@@ -734,13 +773,13 @@ function mc_search_results( $query ) {
734
  // no filters parameter prevents infinite looping on the_content filters.
735
  $output = mc_produce_upcoming_events( $event_array, $template, 'list', 'ASC', 0, $before, $after, 'yes', 'nofilters' );
736
  } else {
737
- $output = "<li class='no-results'>" . __( 'Sorry, your search produced no results.', 'my-calendar' ) . "</li>";
738
  }
 
 
 
739
 
740
- $before = apply_filters( 'mc_search_before', '', $term );
741
- $after = apply_filters( 'mc_search_after', '', $term );
742
-
743
- return "$before<ol class='mc-search-results'>$output</ol>$after";
744
  }
745
 
746
  function mc_flatten_array( $events ) {
@@ -784,29 +823,29 @@ function mc_get_search_results( $search ) {
784
  if ( $before > 0 ) {
785
  $before = $before + 5;
786
  $events1 = $mcdb->get_results( "SELECT *, UNIX_TIMESTAMP(occur_begin) AS ts_occur_begin, UNIX_TIMESTAMP(occur_end) AS ts_occur_end
787
- FROM " . MY_CALENDAR_EVENTS_TABLE . "
788
- JOIN " . MY_CALENDAR_TABLE . "
789
  ON (event_id=occur_event_id)
790
- JOIN " . MY_CALENDAR_CATEGORIES_TABLE . "
791
  ON (event_category=category_id) WHERE event_approved = 1 $search AND event_flagged <> 1
792
  AND DATE(occur_begin) < '$date' ORDER BY occur_begin DESC LIMIT 0,$before" );
793
  } else {
794
  $events1 = array();
795
  }
796
  $events3 = $mcdb->get_results( "SELECT *, UNIX_TIMESTAMP(occur_begin) AS ts_occur_begin, UNIX_TIMESTAMP(occur_end) AS ts_occur_end
797
- FROM " . MY_CALENDAR_EVENTS_TABLE . "
798
- JOIN " . MY_CALENDAR_TABLE . "
799
  ON (event_id=occur_event_id)
800
- JOIN " . MY_CALENDAR_CATEGORIES_TABLE . "
801
  ON (event_category=category_id) WHERE event_approved = 1 $search AND event_flagged <> 1
802
  AND DATE(occur_begin) = '$date'" );
803
  if ( $after > 0 ) {
804
  $after = $after + 5;
805
  $events2 = $mcdb->get_results( "SELECT *, UNIX_TIMESTAMP(occur_begin) AS ts_occur_begin, UNIX_TIMESTAMP(occur_end) AS ts_occur_end
806
- FROM " . MY_CALENDAR_EVENTS_TABLE . "
807
- JOIN " . MY_CALENDAR_TABLE . "
808
  ON (event_id=occur_event_id)
809
- JOIN " . MY_CALENDAR_CATEGORIES_TABLE . "
810
  ON (event_category=category_id) WHERE event_approved = 1 $search AND event_flagged <> 1
811
  AND DATE(occur_begin) > '$date' ORDER BY occur_begin ASC LIMIT 0,$after" );
812
  } else {
@@ -846,18 +885,23 @@ function mc_search_results_title( $title, $id = false ) {
846
 
847
  add_filter( 'the_content', 'mc_show_search_results' );
848
  function mc_show_search_results( $content ) {
849
- // if this is the result of a search, show search output.
850
- $ret = false;
851
- $query = false;
852
- if ( isset( $_GET['mcs'] ) ) { // simple search
853
- $ret = true;
854
- $query = $_GET['mcs'];
855
- } else if ( isset ( $_POST['mcs'] ) ) { // advanced search
856
- $ret = true;
857
- $query = $_POST;
858
- }
859
- if ( $ret && $query ) {
860
- return mc_search_results( $query );
 
 
 
 
 
861
  } else {
862
  return $content;
863
  }
@@ -907,7 +951,7 @@ function mc_show_event_template( $content ) {
907
  // some early versions of this placed the shortcode into the post content. Strip that out.
908
  $new_content = $content;
909
  if ( $post->post_type == 'mc-events' ) {
910
- if ( isset( $_GET['mc_id'] ) ) {
911
  $mc_id = intval( $_GET['mc_id'] );
912
  $event_id = get_post_meta( $post->ID, '_mc_event_id', true );
913
  $event = mc_get_event( $mc_id, 'object' );
@@ -916,14 +960,14 @@ function mc_show_event_template( $content ) {
916
  } else {
917
  $event_id = get_post_meta( $post->ID, '_mc_event_id', true );
918
  if ( is_numeric( $event_id ) ) {
919
- $event = mc_get_first_event( $event_id );
920
- $date = $event->event_begin;
921
- $time = $event->event_time;
922
  } else {
923
  return $content;
924
  }
925
  }
926
- if ( mc_event_is_hidden( $event ) ) {
927
  return $content;
928
  }
929
  if ( get_option( 'mc_use_details_template' ) == 1 ) {
@@ -947,6 +991,9 @@ function mc_show_event_template( $content ) {
947
  }
948
 
949
  function mc_event_is_hidden( $event ) {
 
 
 
950
  $category = $event->event_category;
951
  $private = mc_get_private_categories();
952
  if ( in_array( $category, $private ) && !is_user_logged_in() ) {
@@ -957,7 +1004,13 @@ function mc_event_is_hidden( $event ) {
957
  }
958
 
959
  // Actually do the printing of the calendar
960
- function my_calendar( $name, $format, $category, $time = 'month', $ltype = '', $lvalue = '', $id = '', $template = '', $content = '', $author = null, $host = null, $above = '', $below = '', $syear = false, $smonth = false, $sday = false, $source = 'shortcode' ) {
 
 
 
 
 
 
961
  check_my_calendar();
962
  // category key needs to receive the original category settings.
963
  $original_category = $category;
@@ -1160,9 +1213,7 @@ function my_calendar( $name, $format, $category, $time = 'month', $ltype = '', $
1160
  $current_date = mktime( 0, 0, 0, $c_month, $c_day, $c_year );
1161
  $c_month = str_pad( $c_month, 2, '0', STR_PAD_LEFT );
1162
  $mc_show_months = apply_filters( 'mc_show_months', get_option( 'mc_show_months' ), $args );
1163
- //echo "<p>Debug:<br />Day: $c_day<br />Month: $c_month<br />Year: $c_year<br />Date: ".date('Y-m-d',$current_date)."</p>";
1164
- $num = $mc_show_months - 1; // the value is total months to show; need additional months to show.
1165
-
1166
 
1167
  if ( $format == "list" && $time != 'week' ) { // grid calendar can't show multiple months
1168
  if ( $num > 0 && $time != 'day' && $time != 'week' ) {
@@ -1186,7 +1237,7 @@ function my_calendar( $name, $format, $category, $time = 'month', $ltype = '', $
1186
  }
1187
  $from = apply_filters( 'mc_from_date', $this_dates['from'] );
1188
  $to = apply_filters( 'mc_to_date', $this_dates['to'] );
1189
- $event_array = my_calendar_events( $from, $to, $category, $ltype, $lvalue, 'calendar', $author, $host );
1190
  $no_events = ( empty( $event_array ) ) ? true : false;
1191
 
1192
  // define navigation element strings
@@ -1327,11 +1378,11 @@ function my_calendar( $name, $format, $category, $time = 'month', $ltype = '', $
1327
  $dayclass = strtolower( date( 'D', mktime( 0, 0, 0, $c_month, $c_day, $c_year ) ) );
1328
  $from = $to = "$c_year-$c_month-$c_day";
1329
  //echo "<p>Debug: $from, $to, $category, $ltype, $lvalue, $author</p>";
1330
- $events = my_calendar_grab_events( $from, $to, $category, $ltype, $lvalue, 'calendar', $author, $host );
1331
  if ( ! get_option( 'mc_skip_holidays_category' ) || get_option( 'mc_skip_holidays_category' ) == '' ) {
1332
  $holidays = array();
1333
  } else {
1334
- $holidays = my_calendar_grab_events( $from, $to, get_option( 'mc_skip_holidays_category' ), $ltype, $lvalue, 'calendar', $author, $host, 'holidays' );
1335
  }
1336
  $events_class = mc_events_class( $events, $from );
1337
  $dateclass = mc_dateclass( time() + $offset, mktime( 0, 0, 0, $c_month, $c_day, $c_year ) );
@@ -1452,7 +1503,12 @@ function my_calendar( $name, $format, $category, $time = 'month', $ltype = '', $
1452
  }
1453
  $td = apply_filters( 'mc_grid_day_wrapper', 'td', $format );
1454
  if ( ! empty( $events ) ) {
1455
- $event_output = my_calendar_draw_events( $events, $format, $date, $time, $template );
 
 
 
 
 
1456
  if ( $event_output === true ) {
1457
  $event_output = ' ';
1458
  }
@@ -1575,6 +1631,10 @@ function my_calendar( $name, $format, $category, $time = 'month', $ltype = '', $
1575
  // The actual printing is done by the shortcode function.
1576
  $my_calendar_body .= apply_filters( 'mc_after_calendar', '', $args );
1577
 
 
 
 
 
1578
  return $mc_wrapper . apply_filters( 'my_calendar_body', $my_calendar_body ) . $mc_closer;
1579
  }
1580
 
@@ -1596,7 +1656,7 @@ function my_category_key( $category ) {
1596
  }
1597
  $key = '';
1598
  $cat_limit = mc_select_category( $category, 'all', 'category' );
1599
- $sql = "SELECT * FROM " . MY_CALENDAR_CATEGORIES_TABLE . " $cat_limit ORDER BY category_name ASC";
1600
  $categories = $mcdb->get_results( $sql );
1601
  $key .= '<div class="category-key">
1602
  <h3>' . __( 'Categories', 'my-calendar' ) . "</h3>\n<ul>\n";
@@ -1613,9 +1673,9 @@ function my_category_key( $category ) {
1613
  }
1614
  $url = mc_build_url( array( 'mcat' => $cat->category_id ), array( 'mcat' ) );
1615
  if ( $cat->category_icon != "" && get_option( 'mc_hide_icons' ) != 'true' ) {
1616
- $key .= '<li class="cat_' . $class . '"><a href="' . $url . '"><span class="category-color-sample"><img src="' . $path . $cat->category_icon . '" alt="" style="background:' . $hex . $cat->category_color . ';" /></span>' . wp_kses_post( stripcslashes( $cat->category_name ) ) . "</a></li>\n";
1617
  } else {
1618
- $key .= '<li class="cat_' . $class . '"><a href="' . $url . '"><span class="category-color-sample no-icon" style="background:' . $hex . $cat->category_color . ';"> &nbsp; </span>' . wp_kses_post( stripcslashes( $cat->category_name ) ) . "</a></li>\n";
1619
  }
1620
  }
1621
  if ( isset( $_GET['mcat'] ) ) {
@@ -1865,7 +1925,7 @@ function my_calendar_categories_list( $show = 'list', $context = 'public', $grou
1865
  </div><p>';
1866
  $public_form = ( $context == 'public' ) ? $form : '';
1867
 
1868
- $categories = $mcdb->get_results( "SELECT * FROM " . MY_CALENDAR_CATEGORIES_TABLE . " ORDER BY category_id ASC" );
1869
  if ( ! empty( $categories ) && count( $categories ) >= 1 ) {
1870
  $output = "<div id='mc_categories'>\n";
1871
  $url = mc_build_url( array( 'mcat' => 'all' ), array() );
@@ -1877,7 +1937,7 @@ function my_calendar_categories_list( $show = 'list', $context = 'public', $grou
1877
  <option value="all" selected="selected">' . __( 'All Categories', 'my-calendar' ) . '</option>' . "\n";
1878
 
1879
  foreach ( $categories as $category ) {
1880
- $category_name = wp_kses_post( stripcslashes( $category->category_name ) );
1881
  $mcat = ( empty( $_GET['mcat'] ) ) ? '' : (int) $_GET['mcat'];
1882
  if ( $show == 'list' ) {
1883
  $this_url = mc_build_url( array( 'mcat' => $category->category_id ), array() );
@@ -2039,7 +2099,7 @@ function my_calendar_show_locations( $datatype = 'name', $template = '' ) {
2039
  default:
2040
  $data = "location_label";
2041
  }
2042
- $locations = $mcdb->get_results( "SELECT DISTINCT * FROM " . MY_CALENDAR_LOCATIONS_TABLE . " ORDER BY $data ASC" );
2043
  if ( $locations ) {
2044
  $output = "<ul class='mc-locations'>";
2045
  foreach ( $locations as $key => $value ) {
@@ -2055,6 +2115,9 @@ function my_calendar_show_locations( $datatype = 'name', $template = '' ) {
2055
  $label = mc_hcard( $value, true, true, 'location' );
2056
  $output .= "<li>$label</li>";
2057
  } else if ( $template != '' ) {
 
 
 
2058
  $values = array(
2059
  'id' => $value->location_id,
2060
  'label' => $value->location_label,
@@ -2143,7 +2206,7 @@ function my_calendar_locations_list( $show = 'list', $type = 'saved', $datatype
2143
  }
2144
  $current_url = mc_get_current_url();
2145
  if ( $type == 'saved' ) {
2146
- $locations = $mcdb->get_results( "SELECT DISTINCT $data FROM " . MY_CALENDAR_LOCATIONS_TABLE . " ORDER BY $data ASC", ARRAY_A );
2147
  } else {
2148
  $data = get_option( 'mc_user_settings' );
2149
  $locations = $data['my_calendar_location_default']['values'];
@@ -2188,7 +2251,7 @@ function my_calendar_locations_list( $show = 'list', $type = 'saved', $datatype
2188
  if ( $type == 'saved' ) {
2189
  foreach ( $location as $k => $value ) {
2190
  $vt = urlencode( trim( $value ) );
2191
- $value = wp_kses_post( stripcslashes( $value ) );
2192
  if ( $value == '' ) {
2193
  continue;
2194
  }
@@ -2210,7 +2273,7 @@ function my_calendar_locations_list( $show = 'list', $type = 'saved', $datatype
2210
  }
2211
  } else {
2212
  $vk = urlencode( trim( $key ) );
2213
- $location = wp_kses_post( trim( $location ) );
2214
  if ( $location == '' ) {
2215
  continue;
2216
  }
@@ -2241,6 +2304,7 @@ function my_calendar_locations_list( $show = 'list', $type = 'saved', $datatype
2241
  return '';
2242
  }
2243
  }
 
2244
  /*
2245
  function mc_user_timezone() {
2246
  global $user_ID;
54
  $begin .= "<div id='date-$process_date' class='calendar-events'>";
55
  }
56
  foreach ( array_keys( $events ) as $key ) {
57
+ $event =& $events[ $key ];
58
+ if ( $event->event_recur != 'S1' ) {
59
+ $check = get_post_meta( $event->event_post, '_occurrence_overlap', true );
60
+ if ( $check == 'false' ) {
61
+ $check = mc_test_occurrence_overlap( $event, true );
62
+ }
63
+ } else {
64
+ $check = '';
65
+ }
66
  if ( $check == '' ) {
67
  $output_array[] = my_calendar_draw_event( $event, $type, $process_date, $time, $template );
68
  }
158
  $event_id = ( isset( $_GET['mc_id'] ) && is_numeric( $_GET['mc_id'] ) ) ? $_GET['mc_id'] : get_post_meta( $post_id, '_mc_event_id', true );
159
  if ( is_numeric( $event_id ) ) {
160
  $event = mc_get_event_core( $event_id );
161
+ if ( is_object( $event ) && method_exists( $event, 'category_icon' ) ) {
162
+ $icon = mc_category_icon( $event );
163
+ } else {
164
+ $icon = '';
165
+ }
166
+ $title = $icon . ' ' . mc_kses_post( $title );
167
  }
168
  }
169
  }
178
  return '';
179
  }
180
  // if event ends at midnight today (e.g., very first thing of the day), exit without re-drawing
181
+ // or if event started yesterday & has event_hide_end checked.
182
+ $ends_at_midnight = ( $event->event_endtime == '00:00:00' && date( 'Y-m-d', strtotime( $event->occur_end ) ) == $process_date && date( 'Y-m-d', strtotime( $event->occur_begin ) ) != $process_date ) ? true : false;
183
+ // hides events if hiding end time & not first day.
184
+ $hide_day_two = ( apply_filters( 'mc_hide_additional_days', false, $event ) && ( date( 'Y-m-d', strtotime( $event->occur_begin ) ) != date( 'Y-m-d', strtotime( $process_date ) ) ) ) ? true : false;
185
+ if ( $ends_at_midnight || $hide_day_two ) {
186
  return '';
187
  }
188
  if ( $event->category_private == 1 && ! is_user_logged_in() ) {
200
  if ( $template != '' && mc_file_exists( sanitize_file_name( $template ) ) ) {
201
  $template = @file_get_contents( mc_get_file( sanitize_file_name( $template ) ) );
202
  $details = jd_draw_template( $data, $template );
203
+ } else if ( $template != '' && mc_key_exists( $template ) ) {
204
+ $template = mc_get_custom_template( $template );
205
+ $details = jd_draw_template( $data, $template );
206
  } else {
207
  switch ( $type ) {
208
  case 'mini':
240
  $uid = 'mc_' . $event->occur_id;
241
  $day_id = date( 'd', strtotime( $process_date ) );
242
 
243
+ $image = mc_category_icon( $event );
244
  $has_image = ( $image != '' ) ? ' has-image' : '';
245
+ $event_classes = mc_event_classes( $event, $day_id, $type );
246
+ $header .= "<div id='$uid-$day_id-$type' class='$event_classes'>\n";
247
 
248
  switch ( $type ) {
249
  case 'calendar' : $title_template = ( mc_get_template( 'title' ) == '' ) ? '{title}' : mc_get_template( 'title' ); break;
253
  }
254
 
255
  $event_title = jd_draw_template( $data, $title_template );
256
+ $event_title = ( $event_title == '' ) ? jd_draw_template( $data, '{title}' ) : mc_kses_post( $event_title ); //prevent empty titles
257
 
258
  if ( strpos( $event_title, 'href' ) === false && $type != 'mini' && $type != 'list' ) {
259
  if ( get_option( 'mc_open_uri' ) == 'true' ) {
273
  $inner_heading = apply_filters( 'mc_heading_inner_title', $wrap . $image . trim( $event_title ) . $balance, $event_title, $event );
274
  $header .= ( $type != 'single' && $type != 'list' ) ? "<$heading_level class='event-title summary$group_class' id='$uid-$day_id-$type-title'>$inner_heading</$heading_level>\n" : '';
275
  $event_title = ( $type == 'single' ) ? apply_filters( 'mc_single_event_title', $event_title, $event ) : $event_title;
276
+ $title = ( $type == 'single' && ! is_singular( 'mc-events' ) ) ? "<h2 class='event-title summary'>$image $event_title</h2>\n" : '<span class="summary screen-reader-text">' . $event_title . '</span>';
277
  $title = apply_filters( 'mc_event_title', $title, $event, $event_title, $image );
278
+ $header .= '<span class="summary">' . $title . '</span>';
279
  $close_image = apply_filters( 'mc_close_button', "<img src=\"" . plugin_dir_url( __FILE__ ) . "images/event-close.png\" alt='" . __( 'Close', 'my-calendar' ) . "' />" );
280
+ $close_button = "<button type='button' aria-controls='$uid-$day_id-$type-details' class='mc-toggle close'>$close_image</button>";
281
 
282
  if ( mc_show_details( $time, $type ) ) {
283
  $close = ( $type == 'calendar' || $type == 'mini' ) ? $close_button : '';
337
  $image = ( $event->event_image != '' ) ? "<img src='$event->event_image' alt='' class='mc-image photo' />" : '';
338
  }
339
  if ( get_option( 'mc_desc' ) == 'true' || $type == 'single' ) {
340
+ $description = wpautop( stripcslashes( mc_kses_post( $event->event_desc ) ), 1 );
341
+ $description = "<div class='longdesc description'>$description</div>";
342
  }
343
  if ( get_option( 'mc_short' ) == 'true' && $type != 'single' ) {
344
+ $short = wpautop( stripcslashes( mc_kses_post( $event->event_short ) ), 1 );
345
  $short = "<div class='shortdesc'>$short</div>";
346
  }
347
 
348
  if ( get_option( 'mc_event_registration' ) == 'true' ) {
349
  switch ( $event->event_open ) {
350
  case '0':
351
+ $status = mc_kses_post( get_option( 'mc_event_closed' ) );
352
  break;
353
  case '1':
354
+ $status = mc_kses_post( get_option( 'mc_event_open' ) );
355
  break;
356
  case '2':
357
  $status = '';
363
  $status = '';
364
  }
365
 
366
+ $status = ( $status != '' ) ? "<p>$status</p>" : '';
367
+ $status = apply_filters( 'mc_registration_state', $status, $event );
368
+ $return_url = apply_filters( 'mc_return_uri', get_option( 'mc_uri' ) );
369
+ $return = ( $type == 'single' ) ? "<p class='view-full'><a href='$return_url'>" . __( 'View full calendar', 'my-calendar' ) . "</a></p>" : '';
370
 
371
  if ( ! mc_show_details( $time, $type ) ) {
372
  $description = $short = $status = '';
380
 
381
  if ( $event_link != '' && get_option( 'mc_event_link' ) != 'false' ) {
382
  $is_external = mc_external_link( $event_link );
383
+ $external_class = ( $is_external ) ? "class='$type-link external url'" : "class='$type-link url'";
384
  $link_template = ( mc_get_template( 'link' ) != '' ) ? mc_get_template( 'link' ) : '{title}';
385
  $link_text = jd_draw_template( $data, $link_template );
386
  $link = "<p><a href='" . esc_url( $event_link ) . "' $external_class>" . $link_text . "</a></p>";
428
  return $details;
429
  }
430
 
431
+ function mc_event_classes( $event, $uid, $type ) {
432
+ $uid = 'mc_' . $event->occur_id;
433
+ $classes = array(
434
+ 'mc-' . $uid,
435
+ $type . '-event',
436
+ 'mc_' . $event->category_name,
437
+ 'vevent'
438
+ );
439
+ $classes = apply_filters( 'mc_event_classes', $classes, $event, $uid, $type );
440
+ $class_html = strtolower( implode( ' ', $classes ) );
441
+
442
+ return esc_attr( $class_html );
443
+ }
444
+
445
  function mc_show_details( $time, $type ) {
446
  return ( $type == 'calendar' && get_option( 'mc_open_uri' ) == 'true' && $time != 'day' ) ? false : true;
447
  }
450
  function mc_edit_panel( $html, $event, $type, $time ) {
451
  // create edit links
452
  $edit = '';
453
+ if ( mc_can_edit_event( $event ) && get_option( 'mc_remote' ) != 'true' ) {
454
  $mc_id = $event->occur_id;
455
  $groupedit = ( $event->event_group_id != 0 ) ? " &bull; <a href='" . admin_url( "admin.php?page=my-calendar-groups&amp;mode=edit&amp;event_id=$event->event_id&amp;group_id=$event->event_group_id" ) . "' class='group'>" . __( 'Edit Group', 'my-calendar' ) . "</a>\n" : '';
456
  $recurs = str_split( $event->event_recur, 1 );
518
  $date_switcher .= '</select>' . "\n" . '
519
  <label class="maybe-hide" for="' . $cid . '-year">' . __( 'Year', 'my-calendar' ) . ':</label> <select id="' . $cid . '-year" name="yr">' . "\n";
520
  // query to identify oldest start date in the database
521
+ $query = "SELECT event_begin FROM " . my_calendar_table() . " WHERE event_approved = 1 AND event_flagged <> 1 ORDER BY event_begin ASC LIMIT 0 , 1";
522
  $year1 = date( 'Y', strtotime( $mcdb->get_var( $query ) ) );
523
  $diff1 = date( 'Y' ) - $year1;
524
  $past = $diff1;
618
  $toggle = '';
619
  }
620
 
621
+ if ( ( get_option( 'mc_convert' ) == 'true' || get_option( 'mc_convert' ) == 'mini' ) && mc_is_mobile() ) {
622
+ $toggle = '';
623
+ }
624
+
625
  return apply_filters( 'mc_format_toggle_html', $toggle, $format, $time );
626
  }
627
 
678
  }
679
  $first = date( 'N', $timestamp );
680
  $n = ( get_option( 'start_of_week' ) == 1 ) ? $first - 1 : $first;
681
+ $start = strtotime( "-$n days", $timestamp );
682
+ $from = date( 'Y-m-d', $start );
683
  $endtime = mktime( 0, 0, 0, date( 'm', $timestamp ), date( 't', $timestamp ), date( 'Y', $timestamp ) );
684
  // $endtime = strtotime("+$months months",$endtime); // this allows multiple months displayed. Will figure out splitting tables...
685
  $last = date( 'N', $endtime );
722
  if ( strpos( $class, $cat ) === false ) {
723
  $class .= $cat;
724
  }
725
+ if ( $event->category_private == 1 && !is_user_logged_in() ) {
726
  $class = '';
727
  }
728
  }
745
  } else {
746
  $cstate = sprintf( __( " and %d other events", 'my-calendar' ), $count );
747
  }
748
+ $title = apply_filters( 'mc_list_event_title_hint', mc_kses_post( stripcslashes( $now->event_title ) ), $now, $events ) . "<span class='mc-list-extended'>$cstate</span>";
749
 
750
  return $title;
751
  }
773
  // no filters parameter prevents infinite looping on the_content filters.
774
  $output = mc_produce_upcoming_events( $event_array, $template, 'list', 'ASC', 0, $before, $after, 'yes', 'nofilters' );
775
  } else {
776
+ $output = apply_filters( 'mc_search_no_results', "<li class='no-results'>" . __( 'Sorry, your search produced no results.', 'my-calendar' ) . "</li>" );
777
  }
778
+
779
+ $header = apply_filters( 'mc_search_before', '<ol class="mc-search-results">', $term );
780
+ $footer = apply_filters( 'mc_search_after', '</ol>', $term );
781
 
782
+ return $header . $output . $footer;
 
 
 
783
  }
784
 
785
  function mc_flatten_array( $events ) {
823
  if ( $before > 0 ) {
824
  $before = $before + 5;
825
  $events1 = $mcdb->get_results( "SELECT *, UNIX_TIMESTAMP(occur_begin) AS ts_occur_begin, UNIX_TIMESTAMP(occur_end) AS ts_occur_end
826
+ FROM " . my_calendar_event_table() . "
827
+ JOIN " . my_calendar_table() . "
828
  ON (event_id=occur_event_id)
829
+ JOIN " . my_calendar_categories_table() . "
830
  ON (event_category=category_id) WHERE event_approved = 1 $search AND event_flagged <> 1
831
  AND DATE(occur_begin) < '$date' ORDER BY occur_begin DESC LIMIT 0,$before" );
832
  } else {
833
  $events1 = array();
834
  }
835
  $events3 = $mcdb->get_results( "SELECT *, UNIX_TIMESTAMP(occur_begin) AS ts_occur_begin, UNIX_TIMESTAMP(occur_end) AS ts_occur_end
836
+ FROM " . my_calendar_event_table() . "
837
+ JOIN " . my_calendar_table() . "
838
  ON (event_id=occur_event_id)
839
+ JOIN " . my_calendar_categories_table() . "
840
  ON (event_category=category_id) WHERE event_approved = 1 $search AND event_flagged <> 1
841
  AND DATE(occur_begin) = '$date'" );
842
  if ( $after > 0 ) {
843
  $after = $after + 5;
844
  $events2 = $mcdb->get_results( "SELECT *, UNIX_TIMESTAMP(occur_begin) AS ts_occur_begin, UNIX_TIMESTAMP(occur_end) AS ts_occur_end
845
+ FROM " . my_calendar_event_table() . "
846
+ JOIN " . my_calendar_table() . "
847
  ON (event_id=occur_event_id)
848
+ JOIN " . my_calendar_categories_table() . "
849
  ON (event_category=category_id) WHERE event_approved = 1 $search AND event_flagged <> 1
850
  AND DATE(occur_begin) > '$date' ORDER BY occur_begin ASC LIMIT 0,$after" );
851
  } else {
885
 
886
  add_filter( 'the_content', 'mc_show_search_results' );
887
  function mc_show_search_results( $content ) {
888
+ global $post;
889
+ if ( is_object( $post ) && in_the_loop() ) {
890
+ // if this is the result of a search, show search output.
891
+ $ret = false;
892
+ $query = false;
893
+ if ( isset( $_GET['mcs'] ) ) { // simple search
894
+ $ret = true;
895
+ $query = $_GET['mcs'];
896
+ } else if ( isset ( $_POST['mcs'] ) ) { // advanced search
897
+ $ret = true;
898
+ $query = $_POST;
899
+ }
900
+ if ( $ret && $query ) {
901
+ return mc_search_results( $query );
902
+ } else {
903
+ return $content;
904
+ }
905
  } else {
906
  return $content;
907
  }
951
  // some early versions of this placed the shortcode into the post content. Strip that out.
952
  $new_content = $content;
953
  if ( $post->post_type == 'mc-events' ) {
954
+ if ( isset( $_GET['mc_id'] ) && mc_valid_id( $_GET['mc_id'] ) ) {
955
  $mc_id = intval( $_GET['mc_id'] );
956
  $event_id = get_post_meta( $post->ID, '_mc_event_id', true );
957
  $event = mc_get_event( $mc_id, 'object' );
960
  } else {
961
  $event_id = get_post_meta( $post->ID, '_mc_event_id', true );
962
  if ( is_numeric( $event_id ) ) {
963
+ $event = mc_get_nearest_event( $event_id );
964
+ $date = date( 'Y-m-d', strtotime( $event->occur_begin ) );
965
+ $time = date( 'H:i:s', strtotime( $event->occur_begin ) );
966
  } else {
967
  return $content;
968
  }
969
  }
970
+ if ( is_object( $event ) && mc_event_is_hidden( $event ) ) {
971
  return $content;
972
  }
973
  if ( get_option( 'mc_use_details_template' ) == 1 ) {
991
  }
992
 
993
  function mc_event_is_hidden( $event ) {
994
+ if ( ! is_object( $event ) ) {
995
+ return false;
996
+ }
997
  $category = $event->event_category;
998
  $private = mc_get_private_categories();
999
  if ( in_array( $category, $private ) && !is_user_logged_in() ) {
1004
  }
1005
 
1006
  // Actually do the printing of the calendar
1007
+ function my_calendar( $name, $format, $category, $time = 'month', $ltype = '', $lvalue = '', $id = '', $template = '', $content = '', $author = null, $host = null, $above = '', $below = '', $syear = false, $smonth = false, $sday = false, $source = 'shortcode', $site = false ) {
1008
+
1009
+ if ( $site ) {
1010
+ $site = ( $site == 'global' ) ? BLOG_ID_CURRENT_SITE : $site;
1011
+ switch_to_blog( $site );
1012
+ }
1013
+
1014
  check_my_calendar();
1015
  // category key needs to receive the original category settings.
1016
  $original_category = $category;
1213
  $current_date = mktime( 0, 0, 0, $c_month, $c_day, $c_year );
1214
  $c_month = str_pad( $c_month, 2, '0', STR_PAD_LEFT );
1215
  $mc_show_months = apply_filters( 'mc_show_months', get_option( 'mc_show_months' ), $args );
1216
+ $num = $mc_show_months - 1; // the value is total months to show; need additional months to show.
 
 
1217
 
1218
  if ( $format == "list" && $time != 'week' ) { // grid calendar can't show multiple months
1219
  if ( $num > 0 && $time != 'day' && $time != 'week' ) {
1237
  }
1238
  $from = apply_filters( 'mc_from_date', $this_dates['from'] );
1239
  $to = apply_filters( 'mc_to_date', $this_dates['to'] );
1240
+ $event_array = my_calendar_events( $from, $to, $category, $ltype, $lvalue, 'calendar', $author, $host, '', $site );
1241
  $no_events = ( empty( $event_array ) ) ? true : false;
1242
 
1243
  // define navigation element strings
1378
  $dayclass = strtolower( date( 'D', mktime( 0, 0, 0, $c_month, $c_day, $c_year ) ) );
1379
  $from = $to = "$c_year-$c_month-$c_day";
1380
  //echo "<p>Debug: $from, $to, $category, $ltype, $lvalue, $author</p>";
1381
+ $events = my_calendar_grab_events( $from, $to, $category, $ltype, $lvalue, 'calendar', $author, $host, null, '', $site );
1382
  if ( ! get_option( 'mc_skip_holidays_category' ) || get_option( 'mc_skip_holidays_category' ) == '' ) {
1383
  $holidays = array();
1384
  } else {
1385
+ $holidays = my_calendar_grab_events( $from, $to, get_option( 'mc_skip_holidays_category' ), $ltype, $lvalue, 'calendar', $author, $host, 'holidays', '', $site );
1386
  }
1387
  $events_class = mc_events_class( $events, $from );
1388
  $dateclass = mc_dateclass( time() + $offset, mktime( 0, 0, 0, $c_month, $c_day, $c_year ) );
1503
  }
1504
  $td = apply_filters( 'mc_grid_day_wrapper', 'td', $format );
1505
  if ( ! empty( $events ) ) {
1506
+ $hide_nextmonth = apply_filters( 'mc_hide_nextmonth', false );
1507
+ if ( $hide_nextmonth == true && $monthclass == 'nextmonth' ) {
1508
+ $event_output = ' ';
1509
+ } else {
1510
+ $event_output = my_calendar_draw_events( $events, $format, $date, $time, $template );
1511
+ }
1512
  if ( $event_output === true ) {
1513
  $event_output = ' ';
1514
  }
1631
  // The actual printing is done by the shortcode function.
1632
  $my_calendar_body .= apply_filters( 'mc_after_calendar', '', $args );
1633
 
1634
+ if ( $site ) {
1635
+ restore_current_blog();
1636
+ }
1637
+
1638
  return $mc_wrapper . apply_filters( 'my_calendar_body', $my_calendar_body ) . $mc_closer;
1639
  }
1640
 
1656
  }
1657
  $key = '';
1658
  $cat_limit = mc_select_category( $category, 'all', 'category' );
1659
+ $sql = "SELECT * FROM " . my_calendar_categories_table() . " $cat_limit ORDER BY category_name ASC";
1660
  $categories = $mcdb->get_results( $sql );
1661
  $key .= '<div class="category-key">
1662
  <h3>' . __( 'Categories', 'my-calendar' ) . "</h3>\n<ul>\n";
1673
  }
1674
  $url = mc_build_url( array( 'mcat' => $cat->category_id ), array( 'mcat' ) );
1675
  if ( $cat->category_icon != "" && get_option( 'mc_hide_icons' ) != 'true' ) {
1676
+ $key .= '<li class="cat_' . $class . '"><a href="' . $url . '"><span class="category-color-sample"><img src="' . $path . $cat->category_icon . '" alt="" style="background:' . $hex . $cat->category_color . ';" /></span>' . mc_kses_post( stripcslashes( $cat->category_name ) ) . "</a></li>\n";
1677
  } else {
1678
+ $key .= '<li class="cat_' . $class . '"><a href="' . $url . '"><span class="category-color-sample no-icon" style="background:' . $hex . $cat->category_color . ';"> &nbsp; </span>' . mc_kses_post( stripcslashes( $cat->category_name ) ) . "</a></li>\n";
1679
  }
1680
  }
1681
  if ( isset( $_GET['mcat'] ) ) {
1925
  </div><p>';
1926
  $public_form = ( $context == 'public' ) ? $form : '';
1927
 
1928
+ $categories = $mcdb->get_results( "SELECT * FROM " . my_calendar_categories_table() . " ORDER BY category_id ASC" );
1929
  if ( ! empty( $categories ) && count( $categories ) >= 1 ) {
1930
  $output = "<div id='mc_categories'>\n";
1931
  $url = mc_build_url( array( 'mcat' => 'all' ), array() );
1937
  <option value="all" selected="selected">' . __( 'All Categories', 'my-calendar' ) . '</option>' . "\n";
1938
 
1939
  foreach ( $categories as $category ) {
1940
+ $category_name = mc_kses_post( stripcslashes( $category->category_name ) );
1941
  $mcat = ( empty( $_GET['mcat'] ) ) ? '' : (int) $_GET['mcat'];
1942
  if ( $show == 'list' ) {
1943
  $this_url = mc_build_url( array( 'mcat' => $category->category_id ), array() );
2099
  default:
2100
  $data = "location_label";
2101
  }
2102
+ $locations = $mcdb->get_results( "SELECT DISTINCT * FROM " . my_calendar_locations_table() . " ORDER BY $data ASC" );
2103
  if ( $locations ) {
2104
  $output = "<ul class='mc-locations'>";
2105
  foreach ( $locations as $key => $value ) {
2115
  $label = mc_hcard( $value, true, true, 'location' );
2116
  $output .= "<li>$label</li>";
2117
  } else if ( $template != '' ) {
2118
+ if ( mc_key_exists( $template ) ) {
2119
+ $template = mc_get_custom_template( $template );
2120
+ }
2121
  $values = array(
2122
  'id' => $value->location_id,
2123
  'label' => $value->location_label,
2206
  }
2207
  $current_url = mc_get_current_url();
2208
  if ( $type == 'saved' ) {
2209
+ $locations = $mcdb->get_results( "SELECT DISTINCT $data FROM " . my_calendar_locations_table() . " ORDER BY $data ASC", ARRAY_A );
2210
  } else {
2211
  $data = get_option( 'mc_user_settings' );
2212
  $locations = $data['my_calendar_location_default']['values'];
2251
  if ( $type == 'saved' ) {
2252
  foreach ( $location as $k => $value ) {
2253
  $vt = urlencode( trim( $value ) );
2254
+ $value = mc_kses_post( stripcslashes( $value ) );
2255
  if ( $value == '' ) {
2256
  continue;
2257
  }
2273
  }
2274
  } else {
2275
  $vk = urlencode( trim( $key ) );
2276
+ $location = mc_kses_post( trim( $location ) );
2277
  if ( $location == '' ) {
2278
  continue;
2279
  }
2304
  return '';
2305
  }
2306
  }
2307
+
2308
  /*
2309
  function mc_user_timezone() {
2310
  global $user_ID;
my-calendar-settings.php CHANGED
@@ -190,6 +190,7 @@ function edit_my_calendar_config() {
190
  mc_delete_cache();
191
  $clear = __( 'My Calendar Cache cleared', 'my-calendar' );
192
  }
 
193
  update_option( 'mc_event_approve', $mc_event_approve );
194
  update_option( 'mc_api_enabled', $mc_api_enabled );
195
  update_option( 'mc_remote', $mc_remote );
@@ -267,6 +268,7 @@ function edit_my_calendar_config() {
267
  update_option( 'mc_topnav', $top );
268
  update_option( 'mc_show_map', ( ! empty( $_POST['mc_show_map'] ) && $_POST['mc_show_map'] == 'on' ) ? 'true' : 'false' );
269
  update_option( 'mc_gmap', ( ! empty( $_POST['mc_gmap'] ) && $_POST['mc_gmap'] == 'on' ) ? 'true' : 'false' );
 
270
  update_option( 'mc_show_address', ( ! empty( $_POST['mc_show_address'] ) && $_POST['mc_show_address'] == 'on' ) ? 'true' : 'false' );
271
  update_option( 'mc_display_more', ( ! empty( $_POST['mc_display_more'] ) && $_POST['mc_display_more'] == 'on' ) ? 'true' : 'false' );
272
  update_option( 'mc_hide_icons', ( ! empty( $_POST['mc_hide_icons'] ) && $_POST['mc_hide_icons'] == 'on' ) ? 'true' : 'false' );
@@ -453,6 +455,8 @@ function edit_my_calendar_config() {
453
  <fieldset>
454
  <legend class="screen-reader-text"><?php _e( 'Management', 'my-calendar' ); ?></legend>
455
  <ul>
 
 
456
  <li><?php mc_settings_field( 'mc_remote', __( 'Get data (events, categories and locations) from a remote database.', 'my-calendar' ), '', '', array(), 'checkbox-single' ); ?></li>
457
  <?php if ( get_option( 'mc_remote' ) == 'true' ) { ?>
458
  <li><?php _e( 'Add this code to your theme\'s <code>functions.php</code> file:', 'my-calendar' ); ?>
@@ -484,7 +488,7 @@ function edit_my_calendar_config() {
484
  'DESC' => __( 'Descending', 'my-calendar' )
485
  ), '', array(), 'select' ); ?></li>
486
  <?php
487
- if ( get_site_option( 'mc_multisite' ) == 2 && MY_CALENDAR_TABLE != MY_CALENDAR_GLOBAL_TABLE ) {
488
  mc_settings_field( 'mc_current_table', array(
489
  '0' => __( 'Currently editing my local calendar', 'my-calendar' ),
490
  '1' => __( 'Currently editing the network calendar', 'my-calendar' )
@@ -599,24 +603,6 @@ function edit_my_calendar_config() {
599
  <?php // End General Options // ?>
600
  </fieldset>
601
 
602
- <fieldset>
603
- <legend><?php _e( 'Grid Options', 'my-calendar' ); ?></legend>
604
- <ul>
605
- <li><?php mc_settings_field( 'mc_show_weekends', __( 'Show Weekends on Calendar', 'my-calendar' ), '', '', array(), 'checkbox-single' ); ?></li>
606
- <li><?php mc_settings_field( 'mc_convert', array(
607
- 'true' => __( 'Switch to list view on mobile devices', 'my-calendar' ),
608
- 'mini' => __( 'Switch to mini calendar on mobile devices', 'my-calendar' ),
609
- 'none' => __( 'Do not switch calendar mode', 'my-calendar' )
610
- ), 'false', '', array(), 'radio' ); ?></li>
611
- </ul>
612
- </fieldset>
613
- <fieldset>
614
- <legend><?php _e( 'List Options', 'my-calendar' ); ?></legend>
615
- <ul>
616
- <li><?php mc_settings_field( 'mc_show_months', __( 'How many months of events to show at a time:', 'my-calendar' ), '', '', array( 'size' => '3' ), 'text' ); ?></li>
617
- <li><?php mc_settings_field( 'mc_show_list_info', __( 'Show the first event\'s title and the number of events that day next to the date.', 'my-calendar' ), '', '', array(), 'checkbox-single' ); ?></li>
618
- </ul>
619
- </fieldset>
620
  <fieldset>
621
  <legend><?php _e( 'Re-order calendar layout', 'my-calendar' ); ?></legend>
622
  <?php
@@ -653,12 +639,12 @@ function edit_my_calendar_config() {
653
  }
654
 
655
  if ( $i == 1 ) {
656
- $buttons = "<button class='down'><i class='dashicons dashicons-arrow-down'></i><span class='screen-reader-text'>Down</span></button>";
657
  } else {
658
  if ( $i == $count ) {
659
- $buttons = "<button class='up'><i class='dashicons dashicons-arrow-up'></i><span class='screen-reader-text'>Up</span></button>";
660
  } else {
661
- $buttons = "<button class='up'><i class='dashicons dashicons-arrow-up'></i><span class='screen-reader-text'>Up</span></button> <button class='down'><i class='dashicons dashicons-arrow-down'></i><span class='screen-reader-text'>Down</span></button>";
662
  }
663
  }
664
  $buttons = "<div class='mc-buttons'>$buttons</div>";
@@ -693,6 +679,7 @@ function edit_my_calendar_config() {
693
  <li><?php mc_settings_field( 'mc_show_gcal', __( 'Link to submit event to Google Calendar', 'my-calendar' ), '', '', array(), 'checkbox-single' ); ?></li>
694
  <li><?php mc_settings_field( 'mc_show_map', __( 'Link to Google Map', 'my-calendar' ), '', '', array(), 'checkbox-single' ); ?></li>
695
  <li><?php mc_settings_field( 'mc_gmap', __( 'Google Map (single event view only)', 'my-calendar' ), '', '', array(), 'checkbox-single' ); ?></li>
 
696
  <li><?php mc_settings_field( 'mc_show_address', __( 'Event Address', 'my-calendar' ), '', '', array(), 'checkbox-single' ); ?></li>
697
  <li><?php mc_settings_field( 'mc_short', __( 'Short description', 'my-calendar' ), '', '', array(), 'checkbox-single' ); ?></li>
698
  <li><?php mc_settings_field( 'mc_desc', __( 'Full description', 'my-calendar' ), '', '', array(), 'checkbox-single' ); ?></li>
@@ -702,6 +689,26 @@ function edit_my_calendar_config() {
702
  <li><?php mc_settings_field( 'mc_event_registration', __( 'Registration info', 'my-calendar' ), '', '', array(), 'checkbox-single' ); ?></li>
703
  </ul>
704
  </fieldset>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
705
  <fieldset>
706
  <legend><?php _e( 'Category Colors', 'my-calendar' ); ?></legend>
707
  <ul class='checkboxes'>
@@ -807,7 +814,7 @@ function edit_my_calendar_config() {
807
  <input type='hidden' name='mc_network' value='true'/>
808
  </div>
809
  <fieldset>
810
- <legend><?php _e( 'WP MultiSite configurations', 'my-calendar' ); ?></legend>
811
  <ul>
812
  <li>
813
  <input type="radio" value="0" id="ms0" name="mc_multisite"<?php echo jd_option_selected( get_site_option( 'mc_multisite' ), '0' ); ?> /> <label for="ms0"><?php _e( 'Site owners may only post to their local calendar', 'my-calendar' ); ?></label>
@@ -819,9 +826,12 @@ function edit_my_calendar_config() {
819
  <input type="radio" value="2" id="ms2" name="mc_multisite"<?php echo jd_option_selected( get_site_option( 'mc_multisite' ), 2 ); ?> /> <label for="ms2"><?php _e( 'Site owners may manage either calendar', 'my-calendar' ); ?></label>
820
  </li>
821
  </ul>
822
- <p class="notice">
823
- <strong>*</strong> <?php _e( 'Changes only effect input permissions. Public-facing calendars will be unchanged.', 'my-calendar' ); ?>
824
  </p>
 
 
 
825
  <ul>
826
  <li><input type="radio" value="0" id="mss0"
827
  name="mc_multisite_show"<?php echo jd_option_selected( get_site_option( 'mc_multisite_show' ), '0' ); ?> />
@@ -922,8 +932,7 @@ function edit_my_calendar_config() {
922
  </ul>
923
  </fieldset>
924
  <p>
925
- <input type="submit" name="save" class="button-primary"
926
- value="<?php _e( 'Save Email Settings', 'my-calendar' ); ?>"/>
927
  </p>
928
  </form>
929
  </div>
190
  mc_delete_cache();
191
  $clear = __( 'My Calendar Cache cleared', 'my-calendar' );
192
  }
193
+ update_option( 'mc_uri', $_POST['mc_uri'] );
194
  update_option( 'mc_event_approve', $mc_event_approve );
195
  update_option( 'mc_api_enabled', $mc_api_enabled );
196
  update_option( 'mc_remote', $mc_remote );
268
  update_option( 'mc_topnav', $top );
269
  update_option( 'mc_show_map', ( ! empty( $_POST['mc_show_map'] ) && $_POST['mc_show_map'] == 'on' ) ? 'true' : 'false' );
270
  update_option( 'mc_gmap', ( ! empty( $_POST['mc_gmap'] ) && $_POST['mc_gmap'] == 'on' ) ? 'true' : 'false' );
271
+ update_option( 'mc_gmap_api_key', ( ! empty( $_POST['mc_gmap_api_key'] ) ) ? strip_tags( $_POST['mc_gmap_api_key'] ) : '' );
272
  update_option( 'mc_show_address', ( ! empty( $_POST['mc_show_address'] ) && $_POST['mc_show_address'] == 'on' ) ? 'true' : 'false' );
273
  update_option( 'mc_display_more', ( ! empty( $_POST['mc_display_more'] ) && $_POST['mc_display_more'] == 'on' ) ? 'true' : 'false' );
274
  update_option( 'mc_hide_icons', ( ! empty( $_POST['mc_hide_icons'] ) && $_POST['mc_hide_icons'] == 'on' ) ? 'true' : 'false' );
455
  <fieldset>
456
  <legend class="screen-reader-text"><?php _e( 'Management', 'my-calendar' ); ?></legend>
457
  <ul>
458
+ <?php $guess = mc_guess_calendar(); ?>
459
+ <li><?php mc_settings_field( 'mc_uri', __( 'Where is your main calendar page?', 'my-calendar' ), '', "$guess[message]", array( 'size' => '60' ), 'url' ); ?></li>
460
  <li><?php mc_settings_field( 'mc_remote', __( 'Get data (events, categories and locations) from a remote database.', 'my-calendar' ), '', '', array(), 'checkbox-single' ); ?></li>
461
  <?php if ( get_option( 'mc_remote' ) == 'true' ) { ?>
462
  <li><?php _e( 'Add this code to your theme\'s <code>functions.php</code> file:', 'my-calendar' ); ?>
488
  'DESC' => __( 'Descending', 'my-calendar' )
489
  ), '', array(), 'select' ); ?></li>
490
  <?php
491
+ if ( get_site_option( 'mc_multisite' ) == 2 && my_calendar_table() != my_calendar_table( 'global' ) ) {
492
  mc_settings_field( 'mc_current_table', array(
493
  '0' => __( 'Currently editing my local calendar', 'my-calendar' ),
494
  '1' => __( 'Currently editing the network calendar', 'my-calendar' )
603
  <?php // End General Options // ?>
604
  </fieldset>
605
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
606
  <fieldset>
607
  <legend><?php _e( 'Re-order calendar layout', 'my-calendar' ); ?></legend>
608
  <?php
639
  }
640
 
641
  if ( $i == 1 ) {
642
+ $buttons = "<button class='down' type='button'><i class='dashicons dashicons-arrow-down'></i><span class='screen-reader-text'>Down</span></button>";
643
  } else {
644
  if ( $i == $count ) {
645
+ $buttons = "<button class='up' type='button'><i class='dashicons dashicons-arrow-up'></i><span class='screen-reader-text'>Up</span></button>";
646
  } else {
647
+ $buttons = "<button class='up' type='button'><i class='dashicons dashicons-arrow-up'></i><span class='screen-reader-text'>Up</span></button> <button class='down'><i class='dashicons dashicons-arrow-down'></i><span class='screen-reader-text'>Down</span></button>";
648
  }
649
  }
650
  $buttons = "<div class='mc-buttons'>$buttons</div>";
679
  <li><?php mc_settings_field( 'mc_show_gcal', __( 'Link to submit event to Google Calendar', 'my-calendar' ), '', '', array(), 'checkbox-single' ); ?></li>
680
  <li><?php mc_settings_field( 'mc_show_map', __( 'Link to Google Map', 'my-calendar' ), '', '', array(), 'checkbox-single' ); ?></li>
681
  <li><?php mc_settings_field( 'mc_gmap', __( 'Google Map (single event view only)', 'my-calendar' ), '', '', array(), 'checkbox-single' ); ?></li>
682
+ <li><?php mc_settings_field( 'mc_gmap_api_key', __( 'Google Maps API Key', 'my-calendar' ) ); ?></li>
683
  <li><?php mc_settings_field( 'mc_show_address', __( 'Event Address', 'my-calendar' ), '', '', array(), 'checkbox-single' ); ?></li>
684
  <li><?php mc_settings_field( 'mc_short', __( 'Short description', 'my-calendar' ), '', '', array(), 'checkbox-single' ); ?></li>
685
  <li><?php mc_settings_field( 'mc_desc', __( 'Full description', 'my-calendar' ), '', '', array(), 'checkbox-single' ); ?></li>
689
  <li><?php mc_settings_field( 'mc_event_registration', __( 'Registration info', 'my-calendar' ), '', '', array(), 'checkbox-single' ); ?></li>
690
  </ul>
691
  </fieldset>
692
+
693
+ <fieldset>
694
+ <legend><?php _e( 'Grid Options', 'my-calendar' ); ?></legend>
695
+ <ul>
696
+ <li><?php mc_settings_field( 'mc_show_weekends', __( 'Show Weekends on Calendar', 'my-calendar' ), '', '', array(), 'checkbox-single' ); ?></li>
697
+ <li><?php mc_settings_field( 'mc_convert', array(
698
+ 'true' => __( 'Switch to list view on mobile devices', 'my-calendar' ),
699
+ 'mini' => __( 'Switch to mini calendar on mobile devices', 'my-calendar' ),
700
+ 'none' => __( 'Do not switch calendar mode', 'my-calendar' )
701
+ ), 'false', '', array(), 'radio' ); ?></li>
702
+ </ul>
703
+ </fieldset>
704
+ <fieldset>
705
+ <legend><?php _e( 'List Options', 'my-calendar' ); ?></legend>
706
+ <ul>
707
+ <li><?php mc_settings_field( 'mc_show_months', __( 'How many months of events to show at a time:', 'my-calendar' ), '', '', array( 'size' => '3' ), 'text' ); ?></li>
708
+ <li><?php mc_settings_field( 'mc_show_list_info', __( 'Show the first event\'s title and the number of events that day next to the date.', 'my-calendar' ), '', '', array(), 'checkbox-single' ); ?></li>
709
+ </ul>
710
+ </fieldset>
711
+
712
  <fieldset>
713
  <legend><?php _e( 'Category Colors', 'my-calendar' ); ?></legend>
714
  <ul class='checkboxes'>
814
  <input type='hidden' name='mc_network' value='true'/>
815
  </div>
816
  <fieldset>
817
+ <legend><?php _e( 'Multisite configuration - input', 'my-calendar' ); ?></legend>
818
  <ul>
819
  <li>
820
  <input type="radio" value="0" id="ms0" name="mc_multisite"<?php echo jd_option_selected( get_site_option( 'mc_multisite' ), '0' ); ?> /> <label for="ms0"><?php _e( 'Site owners may only post to their local calendar', 'my-calendar' ); ?></label>
826
  <input type="radio" value="2" id="ms2" name="mc_multisite"<?php echo jd_option_selected( get_site_option( 'mc_multisite' ), 2 ); ?> /> <label for="ms2"><?php _e( 'Site owners may manage either calendar', 'my-calendar' ); ?></label>
827
  </li>
828
  </ul>
829
+ <p>
830
+ <em><?php _e( 'Changes only effect input permissions. Public-facing calendars will be unchanged.', 'my-calendar' ); ?></em>
831
  </p>
832
+ </fieldset>
833
+ <fieldset>
834
+ <legend><?php _e( 'Multisite configuration - output', 'my-calendar' ); ?></legend>
835
  <ul>
836
  <li><input type="radio" value="0" id="mss0"
837
  name="mc_multisite_show"<?php echo jd_option_selected( get_site_option( 'mc_multisite_show' ), '0' ); ?> />
932
  </ul>
933
  </fieldset>
934
  <p>
935
+ <input type="submit" name="save" class="button-primary" value="<?php _e( 'Save Email Settings', 'my-calendar' ); ?>"/>
 
936
  </p>
937
  </form>
938
  </div>
my-calendar-shortcodes.php CHANGED
@@ -19,7 +19,8 @@ function my_calendar_insert( $atts, $content = null ) {
19
  'below' => '',
20
  'year' => false,
21
  'month' => false,
22
- 'day' => false
 
23
  ), $atts, 'my_calendar' ) );
24
  if ( $format != 'mini' ) {
25
  if ( isset( $_GET['format'] ) ) {
@@ -33,8 +34,8 @@ function my_calendar_insert( $atts, $content = null ) {
33
  if ( $host == 'current' ) {
34
  $host = apply_filters( 'mc_display_host', $user_ID, 'main' );
35
  }
36
-
37
- return my_calendar( $name, $format, $category, $time, $ltype, $lvalue, $id, $template, $content, $author, $host, $above, $below, $year, $month, $day );
38
  }
39
 
40
  function my_calendar_insert_upcoming( $atts ) {
@@ -53,8 +54,10 @@ function my_calendar_insert_upcoming( $atts ) {
53
  'ltype' => '',
54
  'lvalue' => '',
55
  'from' => false,
56
- 'to' => false
 
57
  ), $atts, 'my_calendar_upcoming' ) );
 
58
  global $user_ID;
59
  if ( $author == 'current' ) {
60
  $author = apply_filters( 'mc_display_author', $user_ID, 'upcoming' );
@@ -62,8 +65,8 @@ function my_calendar_insert_upcoming( $atts ) {
62
  if ( $host == 'current' ) {
63
  $host = apply_filters( 'mc_display_host', $user_ID, 'upcoming' );
64
  }
65
-
66
- return my_calendar_upcoming_events( $before, $after, $type, $category, $template, $fallback, $order, $skip, $show_today, $author, $host, $ltype, $lvalue, $from, $to );
67
  }
68
 
69
  function my_calendar_insert_today( $atts ) {
@@ -73,7 +76,8 @@ function my_calendar_insert_today( $atts ) {
73
  'host' => 'default',
74
  'template' => 'default',
75
  'fallback' => '',
76
- 'date' => false
 
77
  ), $atts, 'my_calendar_today' ) );
78
  global $user_ID;
79
  if ( $author == 'current' ) {
@@ -83,7 +87,7 @@ function my_calendar_insert_today( $atts ) {
83
  $host = apply_filters( 'mc_display_host', $user_ID, 'today' );
84
  }
85
 
86
- return my_calendar_todays_events( $category, $template, $fallback, $author, $host, $date );
87
  }
88
 
89
  function my_calendar_locations( $atts ) {
@@ -155,8 +159,9 @@ function my_calendar_search( $atts ) {
155
  function my_calendar_now( $atts ) {
156
  extract( shortcode_atts( array(
157
  'category' => '',
158
- 'template' => '<strong>{link_title}</strong> {timerange}'
 
159
  ), $atts, 'my_calendar_now' ) );
160
 
161
- return my_calendar_events_now( $category, $template );
162
  }
19
  'below' => '',
20
  'year' => false,
21
  'month' => false,
22
+ 'day' => false,
23
+ 'site' => false
24
  ), $atts, 'my_calendar' ) );
25
  if ( $format != 'mini' ) {
26
  if ( isset( $_GET['format'] ) ) {
34
  if ( $host == 'current' ) {
35
  $host = apply_filters( 'mc_display_host', $user_ID, 'main' );
36
  }
37
+
38
+ return my_calendar( $name, $format, $category, $time, $ltype, $lvalue, $id, $template, $content, $author, $host, $above, $below, $year, $month, $day, 'shortcode', $site );
39
  }
40
 
41
  function my_calendar_insert_upcoming( $atts ) {
54
  'ltype' => '',
55
  'lvalue' => '',
56
  'from' => false,
57
+ 'to' => false,
58
+ 'site' => false
59
  ), $atts, 'my_calendar_upcoming' ) );
60
+
61
  global $user_ID;
62
  if ( $author == 'current' ) {
63
  $author = apply_filters( 'mc_display_author', $user_ID, 'upcoming' );
65
  if ( $host == 'current' ) {
66
  $host = apply_filters( 'mc_display_host', $user_ID, 'upcoming' );
67
  }
68
+
69
+ return my_calendar_upcoming_events( $before, $after, $type, $category, $template, $fallback, $order, $skip, $show_today, $author, $host, $ltype, $lvalue, $from, $to, $site );
70
  }
71
 
72
  function my_calendar_insert_today( $atts ) {
76
  'host' => 'default',
77
  'template' => 'default',
78
  'fallback' => '',
79
+ 'date' => false,
80
+ 'site' => false
81
  ), $atts, 'my_calendar_today' ) );
82
  global $user_ID;
83
  if ( $author == 'current' ) {
87
  $host = apply_filters( 'mc_display_host', $user_ID, 'today' );
88
  }
89
 
90
+ return my_calendar_todays_events( $category, $template, $fallback, $author, $host, $date, $site );
91
  }
92
 
93
  function my_calendar_locations( $atts ) {
159
  function my_calendar_now( $atts ) {
160
  extract( shortcode_atts( array(
161
  'category' => '',
162
+ 'template' => '<strong>{link_title}</strong> {timerange}',
163
+ 'site' => false
164
  ), $atts, 'my_calendar_now' ) );
165
 
166
+ return my_calendar_events_now( $category, $template, $site );
167
  }
my-calendar-templates.php CHANGED
@@ -8,8 +8,9 @@ function jd_draw_template( $array, $template, $type = 'list' ) {
8
  $template = stripcslashes( $template );
9
  foreach ( $array as $key => $value ) {
10
  // disallow anything not allowed in posts
11
- // everything in 'map' is already cleaned; map itself has to retain scripts
12
- $value = !( 'map' == $key ) ? wp_kses_post( $value ) : $value;
 
13
  if ( is_object( $value ) && ! empty( $value ) ) {
14
  // null values return false...
15
  } else {
@@ -120,7 +121,6 @@ function mc_clean_location( $event, $source = 'event' ) {
120
  return $event;
121
  }
122
 
123
-
124
  // set up link to Google Maps
125
  function mc_maplink( $event, $request = 'map', $source = 'event' ) {
126
  $map_string = mc_map_string( $event, $source );
@@ -130,7 +130,7 @@ function mc_maplink( $event, $request = 'map', $source = 'event' ) {
130
  }
131
  $zoom = ( $event->event_zoom != 0 ) ? $event->event_zoom : '15';
132
  $url = $event->event_url;
133
- $map_label = wp_kses_post( stripslashes( ( $event->event_label != "" ) ? $event->event_label : $event->event_title ) );
134
  $map_string = str_replace( " ", "+", $map_string );
135
  if ( $event->event_longitude != '0.000000' && $event->event_latitude != '0.000000' ) {
136
  $dir_lat = ( $event->event_latitude > 0 ) ? 'N' : 'S';
@@ -141,13 +141,13 @@ function mc_maplink( $event, $request = 'map', $source = 'event' ) {
141
  }
142
  } else {
143
  $url = $event->location_url;
144
- $map_label = wp_kses_post( stripslashes( ( $event->location_label != "" ) ? $event->location_label : $event->event_title ) );
145
  $zoom = ( $event->location_zoom != 0 ) ? $event->location_zoom : '15';
146
  $map_string = str_replace( " ", "+", $map_string );
147
  if ( $event->location_longitude != '0.000000' && $event->location_latitude != '0.000000' ) {
148
  $dir_lat = ( $event->location_latitude > 0 ) ? 'N' : 'S';
149
  $latitude = abs( $event->location_latitude );
150
- $dir_long = ( $event->location_longitude > 0 ) ? 'W' : 'E';
151
  $longitude = abs( $event->location_longitude );
152
  $map_string = $latitude . $dir_lat . ',' . $longitude . $dir_long;
153
  }
@@ -190,17 +190,17 @@ function mc_hcard( $event, $address = 'true', $map = 'true', $source = 'event',
190
  $event = mc_clean_location( $event, $source );
191
  $url = ( $source == 'event' ) ? $event->event_url : $event->location_url;
192
  $url = esc_url( $url );
193
- $label = wp_kses_post( stripslashes( ( $source == 'event' ) ? $event->event_label : $event->location_label ) );
194
- $street = wp_kses_post( stripslashes( ( $source == 'event' ) ? $event->event_street : $event->location_street ) );
195
- $street2 = wp_kses_post( stripslashes( ( $source == 'event' ) ? $event->event_street2 : $event->location_street2 ) );
196
- $city = wp_kses_post( stripslashes( ( $source == 'event' ) ? $event->event_city : $event->location_city ) );
197
- $state = wp_kses_post( stripslashes( ( $source == 'event' ) ? $event->event_state : $event->location_state ) );
198
- $state = wp_kses_post( stripslashes( ( $source == 'event' ) ? $event->event_state : $event->location_state ) );
199
- $zip = wp_kses_post( stripslashes( ( $source == 'event' ) ? $event->event_postcode : $event->location_postcode ) );
200
- $zip = wp_kses_post( stripslashes( ( $source == 'event' ) ? $event->event_postcode : $event->location_postcode ) );
201
- $country = wp_kses_post( stripslashes( ( $source == 'event' ) ? $event->event_country : $event->location_country ) );
202
- $country = wp_kses_post( stripslashes( ( $source == 'event' ) ? $event->event_country : $event->location_country ) );
203
- $phone = wp_kses_post( stripslashes( ( $source == 'event' ) ? $event->event_phone : $event->location_phone ) );
204
  if ( ! $url && ! $label && ! $street && ! $street2 && ! $city && ! $state && ! $zip && ! $country && ! $phone ) {
205
  return '';
206
  }
@@ -223,8 +223,8 @@ function mc_hcard( $event, $address = 'true', $map = 'true', $source = 'event',
223
  $hcard .= "</div>";
224
  }
225
  if ( $map == 'true' ) {
226
- $the_map = "<a href='$the_map' class='external'>" . __( 'Map', 'my-calendar' ) . "<span class='screen-reader-text'> $label</span></a>";
227
- $hcard .= ( $the_map != '' ) ? "<div class='url map'>$the_map</div>" : '';
228
  }
229
  $hcard .= "</div>";
230
 
@@ -233,6 +233,7 @@ function mc_hcard( $event, $address = 'true', $map = 'true', $source = 'event',
233
 
234
  // Produces the array of event details used for drawing templates
235
  function mc_create_tags( $event, $context = 'filters' ) {
 
236
  $event = mc_clean_location( $event, 'event' );
237
  $e = array();
238
  $e['post'] = $event->event_post;
@@ -313,6 +314,7 @@ function mc_create_tags( $event, $context = 'filters' ) {
313
  // links
314
  $templates = get_option( 'mc_templates' );
315
  $e_template = ( ! empty( $templates['label'] ) ) ? stripcslashes( $templates['label'] ) : __( 'Details about', 'my-calendar' ) . ' {title}';
 
316
  $tags = array( "{title}", "{location}", "{color}", "{icon}", "{date}", "{time}" );
317
  $replacements = array(
318
  stripslashes( $event->event_title ),
@@ -333,11 +335,17 @@ function mc_create_tags( $event, $context = 'filters' ) {
333
  $e['link_image'] = $e['image'];
334
  $e['link_title'] = $e['title'];
335
  }
 
336
  $e['details_link'] = ( get_option( 'mc_uri' ) != '' && ! is_numeric( get_option( 'mc_uri' ) ) ) ? $e_link : '';
337
  $e['details'] = ( get_option( 'mc_uri' ) != '' && ! is_numeric( get_option( 'mc_uri' ) ) ) ? "<a href='$e_link' class='mc-details'>$e_label</a>" : '';
338
  $e['linking'] = ( $e['link'] != '' ) ? $event->event_link : $e_link;
339
  $e['linking_title'] = ( $e['linking'] != '' ) ? "<a href='" . $e['linking'] . "'>" . $e['title'] . "</a>" : $e['title'];
340
-
 
 
 
 
 
341
  // location fields
342
  $strip_desc = mc_newline_replace( strip_tags( $event->event_desc ) );
343
  $e['location'] = stripslashes( $event->event_label );
@@ -387,13 +395,18 @@ function mc_create_tags( $event, $context = 'filters' ) {
387
  $e['ical'] = $ical_link;
388
  $e['ical_html'] = "<a class='ical' rel='nofollow' href='$ical_link'>" . __( 'iCal', 'my-calendar' ) . "</a>";
389
  $e = apply_filters( 'mc_filter_shortcodes', $e, $event );
390
-
391
  return $e;
392
  }
393
 
394
  function mc_notime_label( $event ) {
395
- $notime = get_post_meta( $event->event_post, '_event_time_label', true );
 
 
 
 
396
  $notime = ( $notime != '' ) ? $notime : get_option( 'mc_notime_text' );
 
397
  return apply_filters( 'mc_notime_label', $notime, $event );
398
  }
399
 
@@ -425,12 +438,12 @@ function mc_runtime( $start, $end, $event ) {
425
  }
426
 
427
  function mc_event_link( $event ) {
 
428
  if ( $event->event_link_expires == 0 ) {
429
  $link = esc_url( $event->event_link );
430
  } else {
431
- if ( my_calendar_date_xcomp( $event->occur_end, date( 'Y-m-d', current_time( 'timestamp' ) ) ) ) {
432
- $link = '';
433
- do_action( 'mc_event_expired', $event );
434
  } else {
435
  $link = esc_url( $event->event_link );
436
  }
@@ -441,7 +454,9 @@ function mc_event_link( $event ) {
441
 
442
  function mc_event_expired( $event ) {
443
  if ( my_calendar_date_xcomp( $event->occur_end, date( 'Y-m-d', current_time( 'timestamp' ) ) ) ) {
444
- return true;
 
 
445
  }
446
 
447
  return false;
@@ -467,8 +482,14 @@ function mc_generate_map( $event, $source = 'event' ) {
467
  $category_icon = "//maps.google.com/mapfiles/marker_green.png";
468
  }
469
  $address = addslashes( mc_map_string( $event, $source ) );
470
- $latlng = ( $event->event_latitude != '0.000000' && $event->event_longitude != '0.000000' ) ? "latLng: [$event->event_latitude, $event->event_longitude]," : false;
471
- if ( strlen( $address ) < 10 ) {
 
 
 
 
 
 
472
  return '';
473
  }
474
  $hcard = mc_hcard( $event, true, false, 'event', 'map' );
@@ -486,18 +507,17 @@ function mc_generate_map( $event, $source = 'event' ) {
486
  <script type='text/javascript'>
487
  (function ($) { 'use strict';
488
  $(function () {
489
- $('#mc_gmap_$id').gmap3(
490
- {
491
  marker:{
492
  values:[{
493
  $location
494
  options: { icon: new google.maps.MarkerImage( '$category_icon', new google.maps.Size(32,32,'px','px') ) },
495
  data: \"$html\"
496
- }],
497
  events:{
498
  click: function( marker, event, context ){
499
- var map = $(this).gmap3('get'),
500
- infowindow = $(this).gmap3( { get:{name:'infowindow'} } );
501
  if ( infowindow ){
502
  infowindow.open(map, marker);
503
  infowindow.setContent(context.data);
@@ -528,8 +548,8 @@ function mc_generate_map( $event, $source = 'event' ) {
528
  });
529
  })(jQuery);
530
  </script>
531
- <div id='mc_gmap_$id' class='mc-gmap-fupup'$styles></div>";
532
-
533
  return apply_filters( 'mc_gmap_html', $value, $event );
534
  }
535
 
@@ -666,7 +686,7 @@ function mc_image_data( $e, $event ) {
666
  $src = wp_get_attachment_image_src( $attach, $size );
667
  $e[ $size ] = get_the_post_thumbnail( $event->event_post, $size, $atts );
668
  $e[ $size . '_url' ] = $src[0];
669
- }
670
  if ( isset( $e['medium'] ) && $e['medium'] != '' ) {
671
  $e['image_url'] = strip_tags( $e['medium'] );
672
  $e['image'] = $e['medium'];
@@ -685,7 +705,7 @@ function mc_image_data( $e, $event ) {
685
  $e['image_url'] = ( $event->event_image != '' ) ? $event->event_image : '';
686
  $e['image'] = ( $event->event_image != '' ) ? "<img src='$event->event_image' alt='' class='mc-image' />" : '';
687
  }
688
-
689
  return $e;
690
  }
691
 
8
  $template = stripcslashes( $template );
9
  foreach ( $array as $key => $value ) {
10
  // disallow anything not allowed in posts
11
+ // fields where mc_kses_posts shouldn't run
12
+ $retain = array( 'map', 'map_url', 'sitelink', 'icon', 'link', 'details_link', 'linking', 'gcal', 'ical_link', 'edit_link' );
13
+ $value = !( in_array( $key, $retain ) ) ? mc_kses_post( $value ) : $value;
14
  if ( is_object( $value ) && ! empty( $value ) ) {
15
  // null values return false...
16
  } else {
121
  return $event;
122
  }
123
 
 
124
  // set up link to Google Maps
125
  function mc_maplink( $event, $request = 'map', $source = 'event' ) {
126
  $map_string = mc_map_string( $event, $source );
130
  }
131
  $zoom = ( $event->event_zoom != 0 ) ? $event->event_zoom : '15';
132
  $url = $event->event_url;
133
+ $map_label = mc_kses_post( stripslashes( ( $event->event_label != "" ) ? $event->event_label : $event->event_title ) );
134
  $map_string = str_replace( " ", "+", $map_string );
135
  if ( $event->event_longitude != '0.000000' && $event->event_latitude != '0.000000' ) {
136
  $dir_lat = ( $event->event_latitude > 0 ) ? 'N' : 'S';
141
  }
142
  } else {
143
  $url = $event->location_url;
144
+ $map_label = mc_kses_post( stripslashes( ( $event->location_label != "" ) ? $event->location_label : $event->event_title ) );
145
  $zoom = ( $event->location_zoom != 0 ) ? $event->location_zoom : '15';
146
  $map_string = str_replace( " ", "+", $map_string );
147
  if ( $event->location_longitude != '0.000000' && $event->location_latitude != '0.000000' ) {
148
  $dir_lat = ( $event->location_latitude > 0 ) ? 'N' : 'S';
149
  $latitude = abs( $event->location_latitude );
150
+ $dir_long = ( $event->location_longitude > 0 ) ? 'E' : 'W';
151
  $longitude = abs( $event->location_longitude );
152
  $map_string = $latitude . $dir_lat . ',' . $longitude . $dir_long;
153
  }
190
  $event = mc_clean_location( $event, $source );
191
  $url = ( $source == 'event' ) ? $event->event_url : $event->location_url;
192
  $url = esc_url( $url );
193
+ $label = mc_kses_post( stripslashes( ( $source == 'event' ) ? $event->event_label : $event->location_label ) );
194
+ $street = mc_kses_post( stripslashes( ( $source == 'event' ) ? $event->event_street : $event->location_street ) );
195
+ $street2 = mc_kses_post( stripslashes( ( $source == 'event' ) ? $event->event_street2 : $event->location_street2 ) );
196
+ $city = mc_kses_post( stripslashes( ( $source == 'event' ) ? $event->event_city : $event->location_city ) );
197
+ $state = mc_kses_post( stripslashes( ( $source == 'event' ) ? $event->event_state : $event->location_state ) );
198
+ $state = mc_kses_post( stripslashes( ( $source == 'event' ) ? $event->event_state : $event->location_state ) );
199
+ $zip = mc_kses_post( stripslashes( ( $source == 'event' ) ? $event->event_postcode : $event->location_postcode ) );
200
+ $zip = mc_kses_post( stripslashes( ( $source == 'event' ) ? $event->event_postcode : $event->location_postcode ) );
201
+ $country = mc_kses_post( stripslashes( ( $source == 'event' ) ? $event->event_country : $event->location_country ) );
202
+ $country = mc_kses_post( stripslashes( ( $source == 'event' ) ? $event->event_country : $event->location_country ) );
203
+ $phone = mc_kses_post( stripslashes( ( $source == 'event' ) ? $event->event_phone : $event->location_phone ) );
204
  if ( ! $url && ! $label && ! $street && ! $street2 && ! $city && ! $state && ! $zip && ! $country && ! $phone ) {
205
  return '';
206
  }
223
  $hcard .= "</div>";
224
  }
225
  if ( $map == 'true' ) {
226
+ $the_map = "<a href='$the_map' class='url external'>" . __( 'Map', 'my-calendar' ) . "<span class='screen-reader-text fn'> $label</span></a>";
227
+ $hcard .= ( $the_map != '' ) ? "<div class='map'>$the_map</div>" : '';
228
  }
229
  $hcard .= "</div>";
230
 
233
 
234
  // Produces the array of event details used for drawing templates
235
  function mc_create_tags( $event, $context = 'filters' ) {
236
+ $site = ( isset( $event->site_id ) ) ? $event->site_id : false;
237
  $event = mc_clean_location( $event, 'event' );
238
  $e = array();
239
  $e['post'] = $event->event_post;
314
  // links
315
  $templates = get_option( 'mc_templates' );
316
  $e_template = ( ! empty( $templates['label'] ) ) ? stripcslashes( $templates['label'] ) : __( 'Details about', 'my-calendar' ) . ' {title}';
317
+ $e_template = apply_filters( 'mc_details_template', $e_template );
318
  $tags = array( "{title}", "{location}", "{color}", "{icon}", "{date}", "{time}" );
319
  $replacements = array(
320
  stripslashes( $event->event_title ),
335
  $e['link_image'] = $e['image'];
336
  $e['link_title'] = $e['title'];
337
  }
338
+
339
  $e['details_link'] = ( get_option( 'mc_uri' ) != '' && ! is_numeric( get_option( 'mc_uri' ) ) ) ? $e_link : '';
340
  $e['details'] = ( get_option( 'mc_uri' ) != '' && ! is_numeric( get_option( 'mc_uri' ) ) ) ? "<a href='$e_link' class='mc-details'>$e_label</a>" : '';
341
  $e['linking'] = ( $e['link'] != '' ) ? $event->event_link : $e_link;
342
  $e['linking_title'] = ( $e['linking'] != '' ) ? "<a href='" . $e['linking'] . "'>" . $e['title'] . "</a>" : $e['title'];
343
+
344
+ if ( $context != 'related' && is_singular( 'mc-events' ) ) {
345
+ $related_template = apply_filters( 'mc_related_template', "{date}, {time}", $event );
346
+ $e['related'] = '<ul class="related-events">' . mc_list_related( $event->event_group_id, $event->event_id, $related_template ) . '</ul>';
347
+ }
348
+
349
  // location fields
350
  $strip_desc = mc_newline_replace( strip_tags( $event->event_desc ) );
351
  $e['location'] = stripslashes( $event->event_label );
395
  $e['ical'] = $ical_link;
396
  $e['ical_html'] = "<a class='ical' rel='nofollow' href='$ical_link'>" . __( 'iCal', 'my-calendar' ) . "</a>";
397
  $e = apply_filters( 'mc_filter_shortcodes', $e, $event );
398
+
399
  return $e;
400
  }
401
 
402
  function mc_notime_label( $event ) {
403
+ if ( property_exists( $event, 'event_post' ) ) {
404
+ $notime = get_post_meta( $event->event_post, '_event_time_label', true );
405
+ } else {
406
+ $notime = '';
407
+ }
408
  $notime = ( $notime != '' ) ? $notime : get_option( 'mc_notime_text' );
409
+
410
  return apply_filters( 'mc_notime_label', $notime, $event );
411
  }
412
 
438
  }
439
 
440
  function mc_event_link( $event ) {
441
+ $expired = mc_event_expired( $event );
442
  if ( $event->event_link_expires == 0 ) {
443
  $link = esc_url( $event->event_link );
444
  } else {
445
+ if ( $expired ) {
446
+ $link = apply_filters( 'mc_event_expired_link', '', $event );
 
447
  } else {
448
  $link = esc_url( $event->event_link );
449
  }
454
 
455
  function mc_event_expired( $event ) {
456
  if ( my_calendar_date_xcomp( $event->occur_end, date( 'Y-m-d', current_time( 'timestamp' ) ) ) ) {
457
+ do_action( 'mc_event_expired', $event );
458
+
459
+ return true;
460
  }
461
 
462
  return false;
482
  $category_icon = "//maps.google.com/mapfiles/marker_green.png";
483
  }
484
  $address = addslashes( mc_map_string( $event, $source ) );
485
+
486
+ if ( $event->event_longitude != '0.000000' && $event->event_latitude != '0.000000' ) {
487
+ $latlng = "latLng: [$event->event_latitude, $event->event_longitude],";
488
+ } else {
489
+ $latlng = false;
490
+ }
491
+
492
+ if ( strlen( $address ) < 10 && !$latlng ) {
493
  return '';
494
  }
495
  $hcard = mc_hcard( $event, true, false, 'event', 'map' );
507
  <script type='text/javascript'>
508
  (function ($) { 'use strict';
509
  $(function () {
510
+ $('#mc_gmap_$id').gmap3({
 
511
  marker:{
512
  values:[{
513
  $location
514
  options: { icon: new google.maps.MarkerImage( '$category_icon', new google.maps.Size(32,32,'px','px') ) },
515
  data: \"$html\"
516
+ }],
517
  events:{
518
  click: function( marker, event, context ){
519
+ var map = $(this).gmap3('get');
520
+ var infowindow = $(this).gmap3( { get:{name:'infowindow'} } );
521
  if ( infowindow ){
522
  infowindow.open(map, marker);
523
  infowindow.setContent(context.data);
548
  });
549
  })(jQuery);
550
  </script>
551
+ <div id='mc_gmap_$id' class='mc-gmap-fupup'$styles></div>";
552
+
553
  return apply_filters( 'mc_gmap_html', $value, $event );
554
  }
555
 
686
  $src = wp_get_attachment_image_src( $attach, $size );
687
  $e[ $size ] = get_the_post_thumbnail( $event->event_post, $size, $atts );
688
  $e[ $size . '_url' ] = $src[0];
689
+ }
690
  if ( isset( $e['medium'] ) && $e['medium'] != '' ) {
691
  $e['image_url'] = strip_tags( $e['medium'] );
692
  $e['image'] = $e['medium'];
705
  $e['image_url'] = ( $event->event_image != '' ) ? $event->event_image : '';
706
  $e['image'] = ( $event->event_image != '' ) ? "<img src='$event->event_image' alt='' class='mc-image' />" : '';
707
  }
708
+
709
  return $e;
710
  }
711
 
my-calendar-templating.php CHANGED
@@ -13,217 +13,386 @@ function edit_mc_templates() {
13
  die( "Security check failed" );
14
  }
15
  }
16
-
17
- if ( isset( $_POST['mc_grid_template'] ) ) {
18
- $mc_grid_template = $_POST['mc_grid_template'];
19
- $templates['grid'] = $mc_grid_template;
20
- update_option( 'mc_templates', $templates );
21
- update_option( 'mc_use_grid_template', ( empty( $_POST['mc_use_grid_template'] ) ? 0 : 1 ) );
22
- echo "<div class=\"updated\"><p><strong>" . __( 'Grid Output Template saved', 'my-calendar' ) . ".</strong></p></div>";
23
- }
24
-
25
- if ( isset( $_POST['mc_rss_template'] ) ) {
26
- $mc_rss_template = $_POST['mc_rss_template'];
27
- $templates['rss'] = $mc_rss_template;
28
- update_option( 'mc_templates', $templates );
29
- update_option( 'mc_use_rss_template', ( empty( $_POST['mc_use_rss_template'] ) ? 0 : 1 ) );
30
- echo "<div class=\"updated\"><p><strong>" . __( 'RSS Feed Output Template saved', 'my-calendar' ) . ".</strong></p></div>";
31
  }
32
-
33
- if ( isset( $_POST['mc_list_template'] ) ) {
34
- $mc_list_template = $_POST['mc_list_template'];
35
- $templates['list'] = $mc_list_template;
36
- update_option( 'mc_templates', $templates );
37
- update_option( 'mc_use_list_template', ( empty( $_POST['mc_use_list_template'] ) ? 0 : 1 ) );
38
- echo "<div class=\"updated\"><p><strong>" . __( 'List Output Template saved', 'my-calendar' ) . ".</strong></p></div>";
39
- }
40
-
41
- if ( isset( $_POST['mc_mini_template'] ) ) {
42
- $mc_mini_template = $_POST['mc_mini_template'];
43
- $templates['mini'] = $mc_mini_template;
44
- update_option( 'mc_templates', $templates );
45
- update_option( 'mc_use_mini_template', ( empty( $_POST['mc_use_mini_template'] ) ? 0 : 1 ) );
46
- echo "<div class=\"updated\"><p><strong>" . __( 'Mini Output Template saved', 'my-calendar' ) . ".</strong></p></div>";
47
- }
48
-
49
- if ( isset( $_POST['mc_details_template'] ) ) {
50
- $mc_details_template = $_POST['mc_details_template'];
51
- $templates['details'] = $mc_details_template;
52
- update_option( 'mc_templates', $templates );
53
- update_option( 'mc_use_details_template', ( empty( $_POST['mc_use_details_template'] ) ? 0 : 1 ) );
54
- echo "<div class=\"updated\"><p><strong>" . __( 'Event Details Template saved', 'my-calendar' ) . ".</strong></p></div>";
 
 
55
  }
56
-
 
 
57
  global $grid_template, $list_template, $mini_template, $single_template, $rss_template;
58
- $mc_grid_template = stripslashes( ( $templates['grid'] != '' ) ? $templates['grid'] : $grid_template );
59
- $mc_rss_template = stripslashes( ( $templates['rss'] != '' ) ? $templates['rss'] : $rss_template );
60
- $mc_list_template = stripslashes( ( $templates['list'] != '' ) ? $templates['list'] : $list_template );
61
- $mc_mini_template = stripslashes( ( $templates['mini'] != '' ) ? $templates['mini'] : $mini_template );
62
- $mc_details_template = stripslashes( ( $templates['details'] != '' ) ? $templates['details'] : $single_template );
 
 
 
 
63
  ?>
64
  <div class="wrap jd-my-calendar">
65
- <?php my_calendar_check_db(); ?>
66
- <h1><?php _e( 'My Calendar Templates', 'my-calendar' ); ?></h1>
67
-
68
- <div class="postbox-container jcd-wide">
69
- <div class="metabox-holder">
70
-
71
- <p><?php _e( 'Advanced users may customize the HTML template for each event. This page lets you create a customized view of your events in each context. All available template tags are documented on the Help page. These default templates are based on the default views with all output enabled. <strong>Custom templates will override any other output rules in your settings.</strong>', 'my-calendar' ); ?>
72
- <a href="<?php echo admin_url( "admin.php?page=my-calendar-help#templates" ); ?>"><?php _e( "Templates Help", 'my-calendar' ); ?></a> &raquo;
73
- </p>
74
-
75
- <div class="ui-sortable meta-box-sortables">
76
- <div class="postbox">
77
- <h2><?php _e( 'My Calendar: Grid Event Template', 'my-calendar' ); ?></h2>
78
-
79
- <div class="inside">
80
- <form method="post" action="<?php echo admin_url( "admin.php?page=my-calendar-templates" ); ?>">
81
- <div><input type="hidden" name="_wpnonce"
82
- value="<?php echo wp_create_nonce( 'my-calendar-nonce' ); ?>"/></div>
83
  <p>
84
- <input type="checkbox" id="mc_use_grid_template" name="mc_use_grid_template"
85
- value="1" <?php mc_is_checked( 'mc_use_grid_template', 1 ); ?>/> <label
86
- for="mc_use_grid_template"><?php _e( 'Use this grid event template', 'my-calendar' ); ?></label>
87
  </p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
 
89
- <p>
90
- <label
91
- for="mc_grid_template"><?php _e( 'Your custom template for events in the calendar grid output.', 'my-calendar' ); ?></label><br/><textarea
92
- id="mc_grid_template" name="mc_grid_template" class="template-editor" rows="16"
93
- cols="76"><?php echo $mc_grid_template; ?></textarea>
94
- </p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95
 
 
 
96
  <p>
97
- <input type="submit" name="save" class="button-primary"
98
- value="<?php _e( 'Save Grid Template', 'my-calendar' ); ?>"/>
99
- </p>
100
- </form>
101
  </div>
102
  </div>
103
  </div>
 
 
 
 
104
 
105
- <div class="ui-sortable meta-box-sortables">
106
- <div class="postbox">
107
- <h2><?php _e( 'My Calendar: List Event Template', 'my-calendar' ); ?></h2>
108
-
109
- <div class="inside">
110
- <form method="post" action="<?php echo admin_url( "admin.php?page=my-calendar-templates" ); ?>">
111
- <div><input type="hidden" name="_wpnonce"
112
- value="<?php echo wp_create_nonce( 'my-calendar-nonce' ); ?>"/></div>
113
  <p>
114
- <input type="checkbox" id="mc_use_list_template" name="mc_use_list_template"
115
- value="1" <?php mc_is_checked( 'mc_use_list_template', 1 ); ?>/> <label
116
- for="mc_use_list_template"><?php _e( 'Use this list event template', 'my-calendar' ); ?></label>
117
- </p>
 
118
 
119
- <p>
120
- <label
121
- for="mc_list_template"><?php _e( 'Your custom template for events in calendar list output.', 'my-calendar' ); ?></label><br/><textarea
122
- id="mc_list_template" name="mc_list_template" class="template-editor" rows="16"
123
- cols="76"><?php echo $mc_list_template; ?></textarea>
124
- </p>
125
 
126
- <p>
127
- <input type="submit" name="save" class="button-primary"
128
- value="<?php _e( 'Save List Template', 'my-calendar' ); ?>"/>
129
- </p>
130
- </form>
131
- </div>
132
- </div>
133
- </div>
134
 
135
- <div class="ui-sortable meta-box-sortables">
136
- <div class="postbox">
137
- <h2><?php _e( 'My Calendar: Mini Calendar Template', 'my-calendar' ); ?></h2>
138
 
139
- <div class="inside">
140
- <form method="post" action="<?php echo admin_url( "admin.php?page=my-calendar-templates" ); ?>">
141
- <div><input type="hidden" name="_wpnonce"
142
- value="<?php echo wp_create_nonce( 'my-calendar-nonce' ); ?>"/></div>
143
- <p>
144
- <input type="checkbox" id="mc_use_mini_template" name="mc_use_mini_template"
145
- value="1" <?php mc_is_checked( 'mc_use_mini_template', 1 ); ?>/> <label
146
- for="mc_use_mini_template"><?php _e( 'Use this mini event template', 'my-calendar' ); ?></label>
147
- </p>
148
 
149
- <p>
150
- <label
151
- for="mc_mini_template"><?php _e( 'Your custom template for events in sidebar/mini calendar output.', 'my-calendar' ); ?></label><br/><textarea
152
- id="mc_mini_template" name="mc_mini_template" rows="16" cols="76"
153
- class="template-editor"><?php echo $mc_mini_template; ?></textarea>
154
- </p>
155
 
156
- <p>
157
- <input type="submit" name="save" class="button-primary"
158
- value="<?php _e( 'Save Mini Template', 'my-calendar' ); ?>"/>
159
- </p>
160
- </form>
161
- </div>
162
- </div>
163
- </div>
164
 
165
- <div class="ui-sortable meta-box-sortables">
166
- <div class="postbox">
167
- <h2><?php _e( 'My Calendar: Event Details Page Template', 'my-calendar' ); ?></h2>
168
 
169
- <div class="inside">
170
- <form method="post" action="<?php echo admin_url( "admin.php?page=my-calendar-templates" ); ?>">
171
- <div><input type="hidden" name="_wpnonce"
172
- value="<?php echo wp_create_nonce( 'my-calendar-nonce' ); ?>"/></div>
173
- <p>
174
- <input type="checkbox" id="mc_use_details_template" name="mc_use_details_template"
175
- value="1" <?php mc_is_checked( 'mc_use_details_template', 1 ); ?>/> <label
176
- for="mc_use_details_template"><?php _e( 'Use this details template', 'my-calendar' ); ?></label>
177
- </p>
178
 
179
- <p>
180
- <label
181
- for="mc_details_template"><?php _e( 'Your custom template for events on the event details page.', 'my-calendar' ); ?></label><br/><textarea
182
- id="mc_details_template" name="mc_details_template" rows="16" cols="76"
183
- class="template-editor"><?php echo $mc_details_template; ?></textarea>
184
- </p>
185
 
186
- <p>
187
- <input type="submit" name="save" class="button-primary"
188
- value="<?php _e( 'Save Details Template', 'my-calendar' ); ?>"/>
189
- </p>
190
- </form>
191
- </div>
192
- </div>
193
- </div>
194
 
195
- <div class="ui-sortable meta-box-sortables">
196
- <div class="postbox">
197
- <h2><?php _e( 'My Calendar: RSS Event Template', 'my-calendar' ); ?></h2>
198
 
199
- <div class="inside">
200
- <p><?php _e( 'Notice: HTML templates are very forgiving of errors. RSS templates are not. Be sure to test your changes.', 'my-calendar' ); ?></p>
201
 
202
- <form method="post" action="<?php echo admin_url( "admin.php?page=my-calendar-templates" ); ?>">
203
- <div><input type="hidden" name="_wpnonce"
204
- value="<?php echo wp_create_nonce( 'my-calendar-nonce' ); ?>"/></div>
205
- <p>
206
- <input type="checkbox" id="mc_use_rss_template" name="mc_use_rss_template"
207
- value="1" <?php mc_is_checked( 'mc_use_rss_template', 1 ); ?>/> <label
208
- for="mc_use_rss_template"><?php _e( 'Use this custom RSS event template', 'my-calendar' ); ?></label>
209
- </p>
210
 
211
- <p>
212
- <label
213
- for="mc_rss_template"><?php _e( 'Your custom template for events in the RSS feed.', 'my-calendar' ); ?></label><br/><textarea
214
- id="mc_rss_template" name="mc_rss_template" class="template-editor" rows="16"
215
- cols="76"><?php echo $mc_rss_template; ?></textarea>
216
- </p>
217
 
218
- <p>
219
- <input type="submit" name="save" class="button-primary"
220
- value="<?php _e( 'Save RSS Template', 'my-calendar' ); ?>"/>
221
- </p>
222
- </form>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
223
  </div>
224
  </div>
225
  </div>
226
  </div>
227
  </div>
228
- <?php mc_show_sidebar( 'templates' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
229
  }
13
  die( "Security check failed" );
14
  }
15
  }
16
+
17
+ if ( isset( $_POST['mc_template_key'] ) ) {
18
+ $key = $_POST['mc_template_key'];
19
+ } else {
20
+ $key = ( isset( $_GET['mc_template'] ) ) ? $_GET['mc_template'] : 'grid';
 
 
 
 
 
 
 
 
 
 
21
  }
22
+
23
+ if ( isset( $_POST['delete'] ) ) {
24
+ delete_option( 'mc_ctemplate_' . $key );
25
+ echo "<div class=\"updated\"><p>" . __( 'Custom template deleted', 'my-calendar' ) . "</p></div>";
26
+ $key = 'grid';
27
+ } else {
28
+ if ( mc_is_core_template( $key ) && isset( $_POST['add-new'] ) ) {
29
+ echo "<div class=\"updated\"><p>" . __( 'Custom templates cannot have the same key as a core template', 'my-calendar' ) . "</p></div>";
30
+ } else {
31
+ if ( mc_is_core_template( $key ) && isset( $_POST['mc_template'] ) ) {
32
+ $template = $_POST['mc_template'];
33
+ $templates[$key] = $template;
34
+ update_option( 'mc_templates', $templates );
35
+ update_option( 'mc_use_' . $key . '_template', ( empty( $_POST['mc_use_template'] ) ? 0 : 1 ) );
36
+ echo "<div class=\"updated\"><p>" . sprintf( __( '%s Template saved', 'my-calendar' ), ucfirst( $key ) ) . "</p></div>";
37
+ } else if ( isset( $_POST['mc_template'] ) ) {
38
+ $template = $_POST['mc_template'];
39
+ if ( mc_key_exists( $key ) ) {
40
+ $key = mc_update_template( $key, $template );
41
+ } else {
42
+ $key = mc_create_template( $template );
43
+ }
44
+ echo "<div class='updated'><p>" . __( 'Custom Template saved', 'my-calendar' ) . "</p></div>";
45
+ }
46
+ }
47
  }
48
+ // TODO: create UI for managing additional templates
49
+ // TODO: create admin system for modifying shortcodes
50
+
51
  global $grid_template, $list_template, $mini_template, $single_template, $rss_template;
52
+ $mc_grid_template = ( $templates['grid'] != '' ) ? $templates['grid'] : $grid_template;
53
+ $mc_rss_template = ( $templates['rss'] != '' ) ? $templates['rss'] : $rss_template;
54
+ $mc_list_template = ( $templates['list'] != '' ) ? $templates['list'] : $list_template;
55
+ $mc_mini_template = ( $templates['mini'] != '' ) ? $templates['mini'] : $mini_template;
56
+ $mc_details_template = ( $templates['details'] != '' ) ? $templates['details'] : $single_template;
57
+
58
+ $template = ( mc_is_core_template( $key ) ) ? ${"mc_" . $key . "_template"} : mc_get_custom_template( $key );
59
+ $template = stripslashes( $template );
60
+ $core = mc_template_description( $key );
61
  ?>
62
  <div class="wrap jd-my-calendar">
63
+ <?php my_calendar_check_db(); ?>
64
+ <h1 class="wp-heading-inline"><?php _e( 'My Calendar Templates', 'my-calendar' ); ?></h1>
65
+ <a href="<?php echo add_query_arg( 'mc_template', 'add-new', admin_url( "admin.php?page=my-calendar-templates" ) ); ?>" class="page-title-action"><?php _e( 'Add New', 'my-calendar' ); ?></a>
66
+ <hr class="wp-header-end">
67
+ <div class="postbox-container jcd-wide">
68
+ <div class="metabox-holder">
69
+ <div class="ui-sortable meta-box-sortables">
70
+ <div class="postbox">
71
+ <h2><?php _e( 'Edit Template', 'my-calendar' ); ?></h2>
72
+ <div class="inside">
 
 
 
 
 
 
 
 
73
  <p>
74
+ <a href="<?php echo admin_url( "admin.php?page=my-calendar-help#templates" ); ?>"><?php _e( "Templates Help", 'my-calendar' ); ?></a> &raquo;
 
 
75
  </p>
76
+ <?php if ( $core != '' ) { echo "<p class='template-description'>$core</p>"; } ?>
77
+ <?php
78
+ if ( $key == 'add-new' ) {
79
+ ?>
80
+ <form method="post" action="<?php echo add_query_arg( 'mc_template', $key, admin_url( "admin.php?page=my-calendar-templates" ) ); ?>">
81
+ <div>
82
+ <input type="hidden" name="_wpnonce" value="<?php echo wp_create_nonce( 'my-calendar-nonce' ); ?>"/>
83
+ </div>
84
+ <p>
85
+ <label for="mc_template_key"><?php _e( 'Template Description (required)', 'my-calendar' ); ?></label><br />
86
+ <input type="text" class="widefat" name="mc_template_key" id="mc_template_key" value="" required />
87
+ </p>
88
+ <p>
89
+ <label for="mc_template"><?php _e( 'Custom Template', 'my-calendar' ); ?></label><br/>
90
+ <textarea id="mc_template" name="mc_template" class="template-editor widefat" rows="32" cols="76"></textarea>
91
+ </p>
92
 
93
+ <p>
94
+ <input type="submit" name="save" class="button-primary" value="<?php _e( 'Add Template', 'my-calendar' ); ?>" />
95
+ </p>
96
+ </form>
97
+ <?php
98
+ } else {
99
+ ?>
100
+ <form method="post" action="<?php echo add_query_arg( 'mc_template', $key, admin_url( "admin.php?page=my-calendar-templates" ) ); ?>">
101
+ <div>
102
+ <input type="hidden" name="_wpnonce" value="<?php echo wp_create_nonce( 'my-calendar-nonce' ); ?>"/>
103
+ <input type="hidden" name="mc_template_key" value="<?php esc_attr_e( $key ); ?>"/>
104
+ </div>
105
+ <?php if ( mc_is_core_template( $key ) ) { ?>
106
+ <p>
107
+ <input type="checkbox" id="mc_use_template" name="mc_use_template" value="1" <?php mc_is_checked( "mc_use_".$key."_template", 1 ); ?> /> <label for="mc_use_template"><?php _e( 'Use this template', 'my-calendar' ); ?></label>
108
+ </p>
109
+ <?php } ?>
110
+ <p>
111
+ <label for="mc_template"><?php _e( 'Custom Template', 'my-calendar' ); ?></label><br/>
112
+ <textarea id="mc_template" name="mc_template" class="template-editor widefat" rows="32" cols="76"><?php echo $template; ?></textarea>
113
+ </p>
114
+ <p>
115
+ <input type="submit" name="save" class="button-primary" value="<?php _e( 'Update Template', 'my-calendar' ); ?>" />
116
+ <?php if ( ! mc_is_core_template( $key ) ) { ?>
117
+ <input type="submit" name="delete" class="button-secondary" value=<?php _e( 'Delete Template', 'my-calendar' ); ?>" />
118
+ <?php } ?>
119
+ </p>
120
+ </form>
121
+ <?php } ?>
122
+ </div>
123
+ </div>
124
+ </div>
125
+ </div>
126
+ <div class="metabox-holder">
127
+ <div class="ui-sortable meta-box-sortables">
128
+ <div class="postbox">
129
+ <h2><?php _e( 'Templates', 'my-calendar' ); ?></h2>
130
 
131
+ <div class="inside">
132
+ <?php mc_list_templates(); ?>
133
  <p>
134
+ <a href="<?php echo add_query_arg( 'mc_template', 'add-new', admin_url( "admin.php?page=my-calendar-templates" ) ); ?>"><?php _e( 'Add New Template', 'my-calendar' ); ?></a>
135
+ </p>
136
+ </div>
 
137
  </div>
138
  </div>
139
  </div>
140
+ <div class="metabox-holder">
141
+ <div class="ui-sortable meta-box-sortables">
142
+ <div class="postbox">
143
+ <h2 class='hndle'><?php _e( 'Event Template Tags', 'my-calendar' ); ?></h2>
144
 
145
+ <div class='mc_template_tags inside'>
 
 
 
 
 
 
 
146
  <p>
147
+ <a href="<?php echo admin_url( 'admin.php?page=my-calendar-help#templates' ); ?>"><?php _e( 'All Template Tags &raquo;', 'my-calendar' ); ?></a>
148
+ </p>
149
+ <dl>
150
+ <dt><code>{title}</code></dt>
151
+ <dd><?php _e( 'Title of the event.', 'my-calendar' ); ?></dd>
152
 
153
+ <dt><code>{link_title}</code></dt>
154
+ <dd><?php _e( 'Title of the event as a link if a URL is present, or the title alone if not.', 'my-calendar' ); ?></dd>
 
 
 
 
155
 
156
+ <dt><code>{time}</code></dt>
157
+ <dd><?php _e( 'Start time for the event.', 'my-calendar' ); ?></dd>
 
 
 
 
 
 
158
 
159
+ <dt><code>{date}</code></dt>
160
+ <dd><?php _e( 'Date on which the event begins.', 'my-calendar' ); ?></dd>
 
161
 
162
+ <dt><code>{daterange}</code></dt>
163
+ <dd><?php _e( 'Beginning date to end date; excludes end date if same as beginning.', 'my-calendar' ); ?></dd>
 
 
 
 
 
 
 
164
 
165
+ <dt><code>{multidate}</code></dt>
166
+ <dd><?php _e( 'Multi-day events: an unordered list of dates/times. Otherwise, beginning date/time.', 'my-calendar' ); ?></dd>
 
 
 
 
167
 
168
+ <dt><code>{author}</code></dt>
169
+ <dd><?php _e( 'Author who posted the event.', 'my-calendar' ); ?></dd>
 
 
 
 
 
 
170
 
171
+ <dt><code>{host}</code></dt>
172
+ <dd><?php _e( 'Name of the assigned host for the event.', 'my-calendar' ); ?></dd>
 
173
 
174
+ <dt><code>{shortdesc}</code></dt>
175
+ <dd><?php _e( 'Short event description.', 'my-calendar' ); ?></dd>
 
 
 
 
 
 
 
176
 
177
+ <dt><code>{description}</code></dt>
178
+ <dd><?php _e( 'Description of the event.', 'my-calendar' ); ?></dd>
 
 
 
 
179
 
180
+ <dt><code>{image}</code></dt>
181
+ <dd><?php _e( 'Image associated with the event.', 'my-calendar' ); ?></dd>
 
 
 
 
 
 
182
 
183
+ <dt><code>{link}</code></dt>
184
+ <dd><?php _e( 'URL provided for the event.', 'my-calendar' ); ?></dd>
 
185
 
186
+ <dt><code>{details}</code></dt>
187
+ <dd><?php _e( 'Link to an auto-generated page containing information about the event.', 'my-calendar' ); ?>
188
 
189
+ <dt><code>{event_open}</code></dt>
190
+ <dd><?php _e( 'Whether event is currently open for registration.', 'my-calendar' ); ?></dd>
 
 
 
 
 
 
191
 
192
+ <dt><code>{event_status}</code></dt>
193
+ <dd><?php _e( 'Current status of event: either "Published" or "Reserved."', 'my-calendar' ); ?></dd>
194
+ </dl>
 
 
 
195
 
196
+ <h3><?php _e( 'Location Template Tags', 'my-calendar' ); ?></h3>
197
+ <dl>
198
+ <dt><code>{location}</code></dt>
199
+ <dd><?php _e( 'Name of the location of the event.', 'my-calendar' ); ?></dd>
200
+
201
+ <dt><code>{street}</code></dt>
202
+ <dd><?php _e( 'First line of the site address.', 'my-calendar' ); ?></dd>
203
+
204
+ <dt><code>{street2}</code></dt>
205
+ <dd><?php _e( 'Second line of the site address.', 'my-calendar' ); ?></dd>
206
+
207
+ <dt><code>{city}</code></dt>
208
+ <dd><?php _e( 'City', 'my-calendar' ); ?></dd>
209
+
210
+ <dt><code>{state}</code></dt>
211
+ <dd><?php _e( 'State', 'my-calendar' ); ?></dd>
212
+
213
+ <dt><code>{postcode}</code></dt>
214
+ <dd><?php _e( 'Postal Code', 'my-calendar' ); ?></dd>
215
+
216
+ <dt><code>{region}</code></dt>
217
+ <dd><?php _e( 'Custom region.', 'my-calendar' ); ?></dd>
218
+
219
+ <dt><code>{country}</code></dt>
220
+ <dd><?php _e( 'Country for the event location.', 'my-calendar' ); ?></dd>
221
+
222
+ <dt><code>{sitelink}</code></dt>
223
+ <dd><?php _e( 'Output the URL for the location.', 'my-calendar' ); ?></dd>
224
+
225
+ <dt><code>{hcard}</code></dt>
226
+ <dd><?php _e( 'Event address in <a href="http://microformats.org/wiki/hcard">hcard</a> format.', 'my-calendar' ); ?></dd>
227
+
228
+ <dt><code>{link_map}</code></dt>
229
+ <dd><?php _e( 'Link to Google Map to the event, if address information is available.', 'my-calendar' ); ?></dd>
230
+ </dl>
231
+ <h3><?php _e( 'Category Template Tags', 'my-calendar' ); ?></h3>
232
+
233
+ <dl>
234
+ <dt><code>{category}</code></dt>
235
+ <dd><?php _e( 'Name of the category of the event.', 'my-calendar' ); ?></dd>
236
+
237
+ <dt><code>{icon}</code></dt>
238
+ <dd><?php _e( 'URL for the event\'s category icon.', 'my-calendar' ); ?></dd>
239
+
240
+ <dt><code>{color}</code></dt>
241
+ <dd><?php _e( 'Hex code for the event\'s category color.', 'my-calendar' ); ?></dd>
242
+
243
+ <dt><code>{cat_id}</code></dt>
244
+ <dd><?php _e( 'ID of the category of the event.', 'my-calendar' ); ?></dd>
245
+ </dl>
246
+ </div>
247
  </div>
248
  </div>
249
  </div>
250
  </div>
251
  </div>
252
+ <?php mc_show_sidebar();
253
+ }
254
+
255
+ function mc_is_core_template( $key ) {
256
+ switch( $key ) {
257
+ case 'grid':
258
+ case 'details':
259
+ case 'list':
260
+ case 'rss':
261
+ case 'mini':
262
+ return true;
263
+ break;
264
+ default:
265
+ return false;
266
+ }
267
+ }
268
+
269
+ function mc_get_custom_template( $key ) {
270
+ $return = get_option( "mc_ctemplate_$key" );
271
+
272
+ return $return;
273
+ }
274
+
275
+ function mc_key_exists( $key ) {
276
+ if ( get_option( "mc_ctemplate_$key", 'missing' ) != 'missing' ) {
277
+ return true;
278
+ }
279
+
280
+ return false;
281
+ }
282
+
283
+ function mc_template_exists( $template ) {
284
+ $key = md5( $template );
285
+ if ( get_option( "mc_ctemplate_$key", 'missing' ) != 'missing' ) {
286
+ return true;
287
+ }
288
+
289
+ return false;
290
+ }
291
+
292
+ function mc_create_template( $template ) {
293
+ $key = md5( $template );
294
+ $description = $_POST['mc_template_key'];
295
+ update_option( "mc_template_desc_$key", $description );
296
+ update_option( "mc_ctemplate_$key", $template );
297
+
298
+ return $key;
299
+ }
300
+
301
+ function mc_update_template( $key, $template ) {
302
+ update_option( "mc_ctemplate_$key", $template );
303
+
304
+ return $key;
305
+ }
306
+
307
+ function mc_template_description( $key ) {
308
+ $return = sprintf( __( 'Custom template, keyword %s', 'my-calendar' ), "<code>$key</code>" );
309
+ $description = '';
310
+ switch( $key ) {
311
+ case 'grid':
312
+ $return = __( '<strong>Core Template:</strong> used in the details pop-up in the main calendar view.', 'my-calendar' );
313
+ break;
314
+ case 'details':
315
+ $return = __( '<strong>Core Template:</strong> used on the single event view.', 'my-calendar' );
316
+ break;
317
+ case 'list':
318
+ $return = __( '<strong>Core Template:</strong> used when viewing events in the main calendar list view.', 'my-calendar' );
319
+ break;
320
+ case 'rss':
321
+ $return = __( '<strong>Core Template:</strong> used for RSS feeds.', 'my-calendar' );
322
+ break;
323
+ case 'mini':
324
+ $return = __( '<strong>Core Template:</strong> used in pop-ups for the mini calendar.', 'my-calendar' );
325
+ break;
326
+ }
327
+
328
+ if ( ! mc_is_core_template( $key ) ) {
329
+ $description = strip_tags( stripslashes( get_option( "mc_template_desc_$key" ) ) );
330
+ }
331
+
332
+ $br = ( $description != '' ) ? '<br />' : '';
333
+
334
+ return $description . $br . $return;
335
+ }
336
+
337
+ function mc_list_templates() {
338
+ $check = "<span class='dashicons dashicons-yes' aria-hidden='true'></span><span>" . __( 'Enabled', 'my-calendar' ) . "</span>";
339
+ $uncheck = "<span class='dashicons dashicons-no' aria-hidden='true'></span><span>" . __( 'Not Enabled', 'my-calendar' ) . "</span>";
340
+ $grid_enabled = ( get_option( 'mc_use_grid_template' ) == 1 ) ? $check : $uncheck;
341
+ $list_enabled = ( get_option( 'mc_use_list_template' ) == 1 ) ? $check : $uncheck;
342
+ $mini_enabled = ( get_option( 'mc_use_mini_template' ) == 1 ) ? $check : $uncheck;
343
+ $details_enabled = ( get_option( 'mc_use_details_template' ) == 1 ) ? $check : $uncheck;
344
+ $rss_enabled = ( get_option( 'mc_use_rss_template' ) == 1 ) ? $check : $uncheck;
345
+
346
+ $list = "<table class='widefat'>
347
+ <thead>
348
+ <tr>
349
+ <th scope='col'>Template Key</th>
350
+ <th scope='col'>Description</th>
351
+ <th scope='col'>Status</th>
352
+ </tr>
353
+ </thead>
354
+ <tbody>
355
+ <tr>
356
+ <td><a href='" . add_query_arg( 'mc_template', 'grid', admin_url( "admin.php?page=my-calendar-templates" ) ) . "'>grid</a></td>
357
+ <td>" . mc_template_description( 'grid' ) . "</td>
358
+ <td>$grid_enabled</td>
359
+ </tr>
360
+ <tr>
361
+ <td><a href='" . add_query_arg( 'mc_template', 'list', admin_url( "admin.php?page=my-calendar-templates" ) ) . "'>list</a></td>
362
+ <td>" . mc_template_description( 'list' ) . "</td>
363
+ <td>$list_enabled</td>
364
+ </tr>
365
+ <tr>
366
+ <td><a href='" . add_query_arg( 'mc_template', 'mini', admin_url( "admin.php?page=my-calendar-templates" ) ) . "'>mini</a></td>
367
+ <td>" . mc_template_description( 'mini' ) . "</td>
368
+ <td>$mini_enabled</td>
369
+ </tr>
370
+ <tr>
371
+ <td><a href='" . add_query_arg( 'mc_template', 'details', admin_url( "admin.php?page=my-calendar-templates" ) ) . "'>details</a></td>
372
+ <td>" . mc_template_description( 'details' ) . "</td>
373
+ <td>$details_enabled</td>
374
+ </tr>
375
+ <tr>
376
+ <td><a href='" . add_query_arg( 'mc_template', 'rss', admin_url( "admin.php?page=my-calendar-templates" ) ) . "'>rss</a></td>
377
+ <td>" . mc_template_description( 'rss' ) . "</td>
378
+ <td>$rss_enabled</td>
379
+ </tr>";
380
+ global $wpdb;
381
+ $select = "SELECT * FROM " . $wpdb->prefix . "options WHERE option_name LIKE '%mc_ctemplate_%'";
382
+ $results = $wpdb->get_results( $select );
383
+ foreach( $results as $result ) {
384
+ $key = str_replace( 'mc_ctemplate_', '', $result->option_name );
385
+ $desc = mc_template_description( $key );
386
+ $list .= "<tr>
387
+ <td><a href='" . add_query_arg( 'mc_template', $key, admin_url( "admin.php?page=my-calendar-templates" ) ) . "'>$key</a></td>
388
+ <td>$desc</td>
389
+ <td> -- </td>
390
+ </tr>";
391
+ }
392
+
393
+ $list .= "</tbody>
394
+ </table>";
395
+
396
+ echo $list;
397
+
398
  }
my-calendar-widgets.php CHANGED
@@ -71,13 +71,14 @@ class my_calendar_today_widget extends WP_Widget {
71
  $widget_link = ( ! empty( $instance['mc_link'] ) ) ? esc_url( $instance['mc_link'] ) : $widget_link;
72
  $widget_title = empty( $the_title ) ? '' : $the_title;
73
  $date = ( ! empty( $instance['mc_date'] ) ) ? $instance['mc_date'] : false;
74
- $offset = ( 60 * 60 * get_option( 'gmt_offset' ) );
 
75
  if ( strpos( $widget_title, '{date}' ) !== false ) {
76
- $widget_title = str_replace( '{date}', date_i18n( get_option( 'mc_date_format' ), time() + $offset ), $widget_title );
77
  }
78
  $widget_title = ( $widget_link == '' ) ? $widget_title : "<a href='$widget_link'>$widget_title</a>";
79
  $widget_title = ( $widget_title != '' ) ? $before_title . $widget_title . $after_title : '';
80
- $the_events = my_calendar_todays_events( $the_category, $the_template, $the_substitute, $author, $host, $date );
81
  if ( $the_events != '' ) {
82
  echo $before_widget;
83
  echo $widget_title;
@@ -105,6 +106,7 @@ class my_calendar_today_widget extends WP_Widget {
105
  $widget_link = ( ! empty( $instance['mc_link'] ) ) ? esc_url( $instance['mc_link'] ) : $default_link;
106
  $widget_author = ( isset( $instance['my_calendar_today_author'] ) ) ? esc_attr( $instance['my_calendar_today_author'] ) : '';
107
  $widget_host = ( isset( $instance['mc_host'] ) ) ? esc_attr( $instance['mc_host'] ) : '';
 
108
 
109
  ?>
110
  <p>
@@ -115,6 +117,20 @@ class my_calendar_today_widget extends WP_Widget {
115
  name="<?php echo $this->get_field_name( 'my_calendar_today_title' ); ?>"
116
  value="<?php echo $widget_title; ?>"/>
117
  </p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
118
  <p>
119
  <label
120
  for="<?php echo $this->get_field_id( 'my_calendar_today_template' ); ?>"><?php _e( 'Template', 'my-calendar' ); ?></label><br/>
@@ -201,8 +217,9 @@ class my_calendar_upcoming_widget extends WP_Widget {
201
  $widget_title = str_replace( '{month}', $month, $widget_title );
202
  $from = ( isset( $instance['mc_from'] ) ) ? $instance['mc_from'] : false;
203
  $to = ( isset( $instance['mc_to'] ) ) ? $instance['mc_to'] : false;
204
-
205
- $the_events = my_calendar_upcoming_events( $before, $after, $type, $the_category, $the_template, $the_substitute, $order, $skip, $show_today, $author, $host, false, false, $from, $to );
 
206
  if ( $the_events != '' ) {
207
  echo $before_widget;
208
  echo $widget_title;
@@ -230,6 +247,7 @@ class my_calendar_upcoming_widget extends WP_Widget {
230
  $linked = ( isset( $instance['my_calendar_upcoming_linked'] ) ) ? esc_attr( $instance['my_calendar_upcoming_linked'] ) : '';
231
  $from = ( isset( $instance['mc_from'] ) ) ? esc_attr( $instance['mc_from'] ) : '';
232
  $to = ( isset( $instance['mc_to'] ) ) ? esc_attr( $instance['mc_to'] ) : '';
 
233
 
234
  if ( $linked == 'yes' ) {
235
  $default_link = ( is_numeric( get_option( 'mc_uri' ) ) ) ? get_permalink( get_option( 'mc_uri' ) ) : get_option( 'mc_uri' );
@@ -247,6 +265,20 @@ class my_calendar_upcoming_widget extends WP_Widget {
247
  name="<?php echo $this->get_field_name( 'my_calendar_upcoming_title' ); ?>"
248
  value="<?php echo esc_attr( $title ); ?>"/>
249
  </p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
250
  <p>
251
  <label
252
  for="<?php echo $this->get_field_id( 'my_calendar_upcoming_template' ); ?>"><?php _e( 'Template', 'my-calendar' ); ?></label><br/>
@@ -399,9 +431,15 @@ class my_calendar_upcoming_widget extends WP_Widget {
399
  }
400
 
401
  // Widget upcoming events
402
- function my_calendar_upcoming_events( $before = 'default', $after = 'default', $type = 'default', $category = 'default', $template = 'default', $substitute = '', $order = 'asc', $skip = 0, $show_today = 'yes', $author = 'default', $host = 'default', $ltype = '', $lvalue = '', $from = '', $to = '' ) {
403
  global $default_template;
404
- $args = array( 'before'=>$before, 'after'=>$after, 'type'=>$type, 'category'=>$category, 'template'=>$template, 'fallback'=> $substitute, 'order' => $order, 'skip' => $skip, 'show_today'=> $show_today, 'author'=> $author, 'host'=>$host, 'ltype'=>$ltype, 'lvalue'=>$lvalue, 'from'=>$from, 'to'=>$to );
 
 
 
 
 
 
405
  $hash = md5( implode( ',', $args ) );
406
  $output = '';
407
  $widget_defaults = ( array ) get_option( 'mc_widget_defaults' );
@@ -420,9 +458,12 @@ function my_calendar_upcoming_events( $before = 'default', $after = 'default', $
420
  }
421
  $template = ( $template == 'default' ) ? $widget_defaults['upcoming']['template'] : $template;
422
  $template = ( $template == '' ) ? $default_template : $template;
 
 
 
 
423
  $no_event_text = ( $substitute == '' ) ? $widget_defaults['upcoming']['text'] : $substitute;
424
- // $header = "<ul id='upcoming-events-$hash' class='upcoming-events'>";
425
- $header = "<ul id='upcoming-events' class='upcoming-events'>";
426
  $footer = "</ul>";
427
  $display_events = ( $display_upcoming_type == 'events' || $display_upcoming_type == 'event' ) ? true : false;
428
  if ( ! $display_events ) {
@@ -437,7 +478,7 @@ function my_calendar_upcoming_events( $before = 'default', $after = 'default', $
437
  }
438
  if ( $display_upcoming_type == 'custom' && $from != '' && $to != '' ) {
439
  $from = date( 'Y-m-d', strtotime( $from ) );
440
- $to = date( 'Y-m-d', strtotime( $to ) );
441
  }
442
  /* Yes, this is crude. But sometimes simplicity works best. There are only 12 possibilities, after all. */
443
  if ( $display_upcoming_type == 'month+1' ) {
@@ -494,7 +535,8 @@ function my_calendar_upcoming_events( $before = 'default', $after = 'default', $
494
  }
495
  $from = apply_filters( 'mc_upcoming_date_from', $from, $args );
496
  $to = apply_filters( 'mc_upcoming_date_to', $to, $args );
497
- $event_array = my_calendar_events( $from, $to, $category, $ltype, $lvalue, 'upcoming', $author, $host );
 
498
  if ( count( $event_array ) != 0 ) {
499
  foreach ( $event_array as $key => $value ) {
500
  if ( is_array( $value ) ) {
@@ -538,17 +580,17 @@ function my_calendar_upcoming_events( $before = 'default', $after = 'default', $
538
  if ( isset( $cache[ $category ] ) ) {
539
  $events = $cache[ $category ];
540
  } else {
541
- $events = mc_get_all_events( $category, $before, $after, $show_today, $author, $host, $ltype, $lvalue );
542
  $cache[ $category ] = $events;
543
  set_transient( 'mc_cache_upcoming', $cache, 60 * 30 );
544
  }
545
  } else {
546
- $events = mc_get_all_events( $category, $before, $after, $show_today, $author, $host, $ltype, $lvalue );
547
  $cache[ $category ] = $events;
548
  set_transient( 'mc_cache_upcoming', $cache, 60 * 30 );
549
  }
550
  } else {
551
- $events = mc_get_all_events( $category, $before, $after, $show_today, $author, $host, $ltype, $lvalue ); // grab all events within reasonable proximity
552
  }
553
  $holiday_array = array();
554
  if ( ! get_option( 'mc_skip_holidays_category' ) || get_option( 'mc_skip_holidays_category' ) == '' ) {
@@ -572,10 +614,16 @@ function my_calendar_upcoming_events( $before = 'default', $after = 'default', $
572
  if ( $output != '' ) {
573
  $output = apply_filters( 'mc_upcoming_events_header', $header ) . $output . apply_filters( 'mc_upcoming_events_footer', $footer );
574
 
575
- return ( get_option( 'mc_process_shortcodes' ) == 'true' ) ? do_shortcode( $output ) : $output;
576
  } else {
577
- return stripcslashes( $no_event_text );
578
  }
 
 
 
 
 
 
579
  }
580
 
581
  function mc_span_time( $group_id ) {
@@ -599,7 +647,6 @@ function mc_span_time( $group_id ) {
599
  function mc_produce_upcoming_events( $events, $template, $type = 'list', $order = 'asc', $skip = 0, $before, $after, $show_today = 'yes', $context = 'filters' ) {
600
  // $events has +5 before and +5 after if those values are non-zero.
601
  // $events equals array of events based on before/after queries. Nothing skipped, order is not set, holiday conflicts removed.
602
-
603
  $output = array();
604
  $near_events = $temp_array = array();
605
  $past = $future = 1;
@@ -765,7 +812,13 @@ function mc_produce_upcoming_events( $events, $template, $type = 'list', $order
765
  }
766
 
767
  // Widget todays events
768
- function my_calendar_todays_events( $category = 'default', $template = 'default', $substitute = '', $author = 'all', $host = 'all', $date = false ) {
 
 
 
 
 
 
769
  $caching = apply_filters( 'mc_cache_enabled', false );
770
  $todays_cache = ( $caching ) ? get_transient( 'mc_todays_cache' ) : '';
771
  if ( $caching && is_array( $todays_cache ) && @$todays_cache[ $category ] ) {
@@ -776,11 +829,17 @@ function my_calendar_todays_events( $category = 'default', $template = 'default'
776
  global $default_template;
777
  $output = '';
778
 
 
 
 
 
 
779
  $defaults = get_option( 'mc_widget_defaults' );
780
  $template = ( $template == 'default' ) ? $defaults['today']['template'] : $template;
781
- if ( $template == '' ) {
782
- $template = "$default_template";
783
- };
 
784
 
785
  $category = ( $category == 'default' ) ? $defaults['today']['category'] : $category;
786
  $no_event_text = ( $substitute == '' ) ? $defaults['today']['text'] : $substitute;
@@ -790,10 +849,9 @@ function my_calendar_todays_events( $category = 'default', $template = 'default'
790
  } else {
791
  $from = $to = date( 'Y-m-d', current_time( 'timestamp' ) );
792
  }
793
- $events = my_calendar_events( $from, $to, $category, '', '', 'upcoming', $author, $host );
794
  $today = ( isset( $events[ $from ] ) ) ? $events[ $from ] : false;
795
- // $header = "<ul id='todays-events-$hash' class='todays-events'>";
796
- $header = "<ul id='todays-events' class='todays-events'>";
797
  $footer = "</ul>";
798
  $groups = $todays_events = array();
799
  // quick loop through all events today to check for holidays
@@ -847,6 +905,10 @@ function my_calendar_todays_events( $category = 'default', $template = 'default'
847
  $return = stripcslashes( $no_event_text );
848
  }
849
 
 
 
 
 
850
  return ( get_option( 'mc_process_shortcodes' ) == 'true' ) ? do_shortcode( $return ) : $return;
851
 
852
  }
@@ -861,13 +923,14 @@ class my_calendar_mini_widget extends WP_Widget {
861
  extract( $args );
862
  if ( ! empty( $instance ) ) {
863
  $the_title = apply_filters( 'widget_title', $instance['my_calendar_mini_title'], $instance, $args );
864
- $category = ( $instance['my_calendar_mini_category'] == '' ) ? 'all' : esc_attr( $instance['my_calendar_mini_category'] );
865
- $time = ( $instance['my_calendar_mini_time'] == '' ) ? 'month' : esc_attr( $instance['my_calendar_mini_time'] );
866
  $widget_link = ( ! isset( $instance['mc_link'] ) || $instance['mc_link'] == '' ) ? '' : esc_url( $instance['mc_link'] );
867
- $above = ( empty( $instance['above'] ) ) ? 'none' : esc_attr( $instance['above'] );
868
- $below = ( empty( $instance['below'] ) ) ? 'none' : esc_attr( $instance['below'] );
869
- $author = ( !isset( $instance['author'] ) || $instance['author'] == '' ) ? null : esc_attr( $instance['author'] );
870
- $host = ( !isset( $instance['host'] ) || $instance['host'] == '' ) ? null : esc_attr( $instance['host'] );
 
871
  } else {
872
  $the_title = $category = $time = $widget_link = $above = $below = '';
873
  }
@@ -878,7 +941,7 @@ class my_calendar_mini_widget extends WP_Widget {
878
  } else {
879
  $title = '';
880
  }
881
- $the_events = my_calendar( 'mini', 'mini', $category, $time, '', '', str_replace( 'my_calendar', 'mc', $args['widget_id'] ), '', '', $author, $host, $above, $below, false, false, false, 'widget' );
882
  if ( $the_events != '' ) {
883
  echo $before_widget . $title . $the_events . $after_widget;
884
  }
@@ -892,6 +955,7 @@ class my_calendar_mini_widget extends WP_Widget {
892
  $below = ( isset( $instance['below'] ) ) ? $instance['below'] : 'none';
893
  $widget_link = ( isset( $instance['mc_link'] ) ) ? esc_url( $instance['mc_link'] ) : '';
894
  $host = ( isset( $instance['host'] ) ) ? $instance['host'] : '';
 
895
  $author = ( isset( $instance['author'] ) ) ? $instance['author'] : '';
896
  ?>
897
  <p>
@@ -902,6 +966,20 @@ class my_calendar_mini_widget extends WP_Widget {
902
  name="<?php echo $this->get_field_name( 'my_calendar_mini_title' ); ?>"
903
  value="<?php esc_attr_e( $title ); ?>"/>
904
  </p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
905
  <p>
906
  <label
907
  for="<?php echo $this->get_field_id( 'mc_link' ); ?>"><?php _e( 'Widget Title Link', 'my-calendar' ); ?>
@@ -985,15 +1063,8 @@ class my_calendar_mini_widget extends WP_Widget {
985
  }
986
  $instance['author'] = $author;
987
  $instance['host'] = $host;
 
988
 
989
  return $instance;
990
  }
991
- }
992
-
993
- function mc_kses_post( $string ) {
994
- if ( !is_string( $string ) ) {
995
- return '';
996
- } else {
997
- return wp_kses_post( $string );
998
- }
999
  }
71
  $widget_link = ( ! empty( $instance['mc_link'] ) ) ? esc_url( $instance['mc_link'] ) : $widget_link;
72
  $widget_title = empty( $the_title ) ? '' : $the_title;
73
  $date = ( ! empty( $instance['mc_date'] ) ) ? $instance['mc_date'] : false;
74
+ $site = ( isset( $instance['mc_site'] ) ) ? $instance['mc_site'] : false;
75
+
76
  if ( strpos( $widget_title, '{date}' ) !== false ) {
77
+ $widget_title = str_replace( '{date}', date_i18n( get_option( 'mc_date_format' ), current_time( 'timestamp' ) ), $widget_title );
78
  }
79
  $widget_title = ( $widget_link == '' ) ? $widget_title : "<a href='$widget_link'>$widget_title</a>";
80
  $widget_title = ( $widget_title != '' ) ? $before_title . $widget_title . $after_title : '';
81
+ $the_events = my_calendar_todays_events( $the_category, $the_template, $the_substitute, $author, $host, $date, $site );
82
  if ( $the_events != '' ) {
83
  echo $before_widget;
84
  echo $widget_title;
106
  $widget_link = ( ! empty( $instance['mc_link'] ) ) ? esc_url( $instance['mc_link'] ) : $default_link;
107
  $widget_author = ( isset( $instance['my_calendar_today_author'] ) ) ? esc_attr( $instance['my_calendar_today_author'] ) : '';
108
  $widget_host = ( isset( $instance['mc_host'] ) ) ? esc_attr( $instance['mc_host'] ) : '';
109
+ $site = ( isset( $instance['mc_site'] ) ) ? esc_attr( $instance['mc_site'] ) : '';
110
 
111
  ?>
112
  <p>
117
  name="<?php echo $this->get_field_name( 'my_calendar_today_title' ); ?>"
118
  value="<?php echo $widget_title; ?>"/>
119
  </p>
120
+ <?php
121
+ if ( function_exists( 'is_multisite' ) && is_multisite() ) {
122
+ ?>
123
+ <p>
124
+ <label
125
+ for="<?php echo $this->get_field_id( 'mc_site' ); ?>"><?php _e( 'Blog ID', 'my-calendar' ); ?>
126
+ :</label><br/>
127
+ <input class="widefat" type="text" id="<?php echo $this->get_field_id( 'mc_site' ); ?>"
128
+ name="<?php echo $this->get_field_name( 'mc_site' ); ?>"
129
+ value="<?php echo esc_attr( $site ); ?>"/>
130
+ </p>
131
+ <?php
132
+ }
133
+ ?>
134
  <p>
135
  <label
136
  for="<?php echo $this->get_field_id( 'my_calendar_today_template' ); ?>"><?php _e( 'Template', 'my-calendar' ); ?></label><br/>
217
  $widget_title = str_replace( '{month}', $month, $widget_title );
218
  $from = ( isset( $instance['mc_from'] ) ) ? $instance['mc_from'] : false;
219
  $to = ( isset( $instance['mc_to'] ) ) ? $instance['mc_to'] : false;
220
+ $site = ( isset( $instance['mc_site'] ) ) ? $instance['mc_site'] : false;
221
+
222
+ $the_events = my_calendar_upcoming_events( $before, $after, $type, $the_category, $the_template, $the_substitute, $order, $skip, $show_today, $author, $host, false, false, $from, $to, $site );
223
  if ( $the_events != '' ) {
224
  echo $before_widget;
225
  echo $widget_title;
247
  $linked = ( isset( $instance['my_calendar_upcoming_linked'] ) ) ? esc_attr( $instance['my_calendar_upcoming_linked'] ) : '';
248
  $from = ( isset( $instance['mc_from'] ) ) ? esc_attr( $instance['mc_from'] ) : '';
249
  $to = ( isset( $instance['mc_to'] ) ) ? esc_attr( $instance['mc_to'] ) : '';
250
+ $site = ( isset( $instance['mc_site'] ) ) ? esc_attr( $instance['mc_site'] ) : '';
251
 
252
  if ( $linked == 'yes' ) {
253
  $default_link = ( is_numeric( get_option( 'mc_uri' ) ) ) ? get_permalink( get_option( 'mc_uri' ) ) : get_option( 'mc_uri' );
265
  name="<?php echo $this->get_field_name( 'my_calendar_upcoming_title' ); ?>"
266
  value="<?php echo esc_attr( $title ); ?>"/>
267
  </p>
268
+ <?php
269
+ if ( function_exists( 'is_multisite' ) && is_multisite() ) {
270
+ ?>
271
+ <p>
272
+ <label
273
+ for="<?php echo $this->get_field_id( 'mc_site' ); ?>"><?php _e( 'Blog ID', 'my-calendar' ); ?>
274
+ :</label><br/>
275
+ <input class="widefat" type="text" id="<?php echo $this->get_field_id( 'mc_site' ); ?>"
276
+ name="<?php echo $this->get_field_name( 'mc_site' ); ?>"
277
+ value="<?php echo esc_attr( $site ); ?>"/>
278
+ </p>
279
+ <?php
280
+ }
281
+ ?>
282
  <p>
283
  <label
284
  for="<?php echo $this->get_field_id( 'my_calendar_upcoming_template' ); ?>"><?php _e( 'Template', 'my-calendar' ); ?></label><br/>
431
  }
432
 
433
  // Widget upcoming events
434
+ function my_calendar_upcoming_events( $before = 'default', $after = 'default', $type = 'default', $category = 'default', $template = 'default', $substitute = '', $order = 'asc', $skip = 0, $show_today = 'yes', $author = 'default', $host = 'default', $ltype = '', $lvalue = '', $from = '', $to = '', $site = false ) {
435
  global $default_template;
436
+
437
+ if ( $site ) {
438
+ $site = ( $site == 'global' ) ? BLOG_ID_CURRENT_SITE : $site;
439
+ switch_to_blog( $site );
440
+ }
441
+
442
+ $args = array( 'before'=>$before, 'after'=>$after, 'type'=>$type, 'category'=>$category, 'template'=>$template, 'fallback'=> $substitute, 'order' => $order, 'skip' => $skip, 'show_today'=> $show_today, 'author'=> $author, 'host'=>$host, 'ltype'=>$ltype, 'lvalue'=>$lvalue, 'from'=>$from, 'to'=>$to, 'site' => $site );
443
  $hash = md5( implode( ',', $args ) );
444
  $output = '';
445
  $widget_defaults = ( array ) get_option( 'mc_widget_defaults' );
458
  }
459
  $template = ( $template == 'default' ) ? $widget_defaults['upcoming']['template'] : $template;
460
  $template = ( $template == '' ) ? $default_template : $template;
461
+ if ( mc_key_exists( $template ) ) {
462
+ $template = mc_get_custom_template( $template );
463
+ }
464
+ $template = apply_filters( 'mc_upcoming_events_template', $template );
465
  $no_event_text = ( $substitute == '' ) ? $widget_defaults['upcoming']['text'] : $substitute;
466
+ $header = "<ul id='upcoming-events-$hash' class='upcoming-events'>";
 
467
  $footer = "</ul>";
468
  $display_events = ( $display_upcoming_type == 'events' || $display_upcoming_type == 'event' ) ? true : false;
469
  if ( ! $display_events ) {
478
  }
479
  if ( $display_upcoming_type == 'custom' && $from != '' && $to != '' ) {
480
  $from = date( 'Y-m-d', strtotime( $from ) );
481
+ $to = ( $to == 'today' ) ? date( 'Y-m-d', current_time( 'timestamp' ) ) : date( 'Y-m-d', strtotime( $to ) );
482
  }
483
  /* Yes, this is crude. But sometimes simplicity works best. There are only 12 possibilities, after all. */
484
  if ( $display_upcoming_type == 'month+1' ) {
535
  }
536
  $from = apply_filters( 'mc_upcoming_date_from', $from, $args );
537
  $to = apply_filters( 'mc_upcoming_date_to', $to, $args );
538
+ $event_array = my_calendar_events( $from, $to, $category, $ltype, $lvalue, 'upcoming', $author, $host, '', $site );
539
+
540
  if ( count( $event_array ) != 0 ) {
541
  foreach ( $event_array as $key => $value ) {
542
  if ( is_array( $value ) ) {
580
  if ( isset( $cache[ $category ] ) ) {
581
  $events = $cache[ $category ];
582
  } else {
583
+ $events = mc_get_all_events( $category, $before, $after, $show_today, $author, $host, $ltype, $lvalue, $site );
584
  $cache[ $category ] = $events;
585
  set_transient( 'mc_cache_upcoming', $cache, 60 * 30 );
586
  }
587
  } else {
588
+ $events = mc_get_all_events( $category, $before, $after, $show_today, $author, $host, $ltype, $lvalue, $site );
589
  $cache[ $category ] = $events;
590
  set_transient( 'mc_cache_upcoming', $cache, 60 * 30 );
591
  }
592
  } else {
593
+ $events = mc_get_all_events( $category, $before, $after, $show_today, $author, $host, $ltype, $lvalue, $site ); // grab all events within reasonable proximity
594
  }
595
  $holiday_array = array();
596
  if ( ! get_option( 'mc_skip_holidays_category' ) || get_option( 'mc_skip_holidays_category' ) == '' ) {
614
  if ( $output != '' ) {
615
  $output = apply_filters( 'mc_upcoming_events_header', $header ) . $output . apply_filters( 'mc_upcoming_events_footer', $footer );
616
 
617
+ $return = ( get_option( 'mc_process_shortcodes' ) == 'true' ) ? do_shortcode( $output ) : $output;
618
  } else {
619
+ $return = stripcslashes( $no_event_text );
620
  }
621
+
622
+ if ( $site ) {
623
+ restore_current_blog();
624
+ }
625
+
626
+ return $return;
627
  }
628
 
629
  function mc_span_time( $group_id ) {
647
  function mc_produce_upcoming_events( $events, $template, $type = 'list', $order = 'asc', $skip = 0, $before, $after, $show_today = 'yes', $context = 'filters' ) {
648
  // $events has +5 before and +5 after if those values are non-zero.
649
  // $events equals array of events based on before/after queries. Nothing skipped, order is not set, holiday conflicts removed.
 
650
  $output = array();
651
  $near_events = $temp_array = array();
652
  $past = $future = 1;
812
  }
813
 
814
  // Widget todays events
815
+ function my_calendar_todays_events( $category = 'default', $template = 'default', $substitute = '', $author = 'all', $host = 'all', $date = false, $site = false ) {
816
+
817
+ if ( $site ) {
818
+ $site = ( $site == 'global' ) ? BLOG_ID_CURRENT_SITE : $site;
819
+ switch_to_blog( $site );
820
+ }
821
+
822
  $caching = apply_filters( 'mc_cache_enabled', false );
823
  $todays_cache = ( $caching ) ? get_transient( 'mc_todays_cache' ) : '';
824
  if ( $caching && is_array( $todays_cache ) && @$todays_cache[ $category ] ) {
829
  global $default_template;
830
  $output = '';
831
 
832
+ // allow reference by file to external template.
833
+ if ( $template != '' && mc_file_exists( sanitize_file_name( $template ) ) ) {
834
+ $template = @file_get_contents( mc_get_file( sanitize_file_name( $template ) ) );
835
+ }
836
+
837
  $defaults = get_option( 'mc_widget_defaults' );
838
  $template = ( $template == 'default' ) ? $defaults['today']['template'] : $template;
839
+ $template = ( $template = '' ) ? $default_template : $template;
840
+ if ( mc_key_exists( $template ) ) {
841
+ $template = mc_get_custom_template( $template );
842
+ }
843
 
844
  $category = ( $category == 'default' ) ? $defaults['today']['category'] : $category;
845
  $no_event_text = ( $substitute == '' ) ? $defaults['today']['text'] : $substitute;
849
  } else {
850
  $from = $to = date( 'Y-m-d', current_time( 'timestamp' ) );
851
  }
852
+ $events = my_calendar_events( $from, $to, $category, '', '', 'upcoming', $author, $host, '', $site );
853
  $today = ( isset( $events[ $from ] ) ) ? $events[ $from ] : false;
854
+ $header = "<ul id='todays-events-$hash' class='todays-events'>";
 
855
  $footer = "</ul>";
856
  $groups = $todays_events = array();
857
  // quick loop through all events today to check for holidays
905
  $return = stripcslashes( $no_event_text );
906
  }
907
 
908
+ if ( $site ) {
909
+ restore_current_blog();
910
+ }
911
+
912
  return ( get_option( 'mc_process_shortcodes' ) == 'true' ) ? do_shortcode( $return ) : $return;
913
 
914
  }
923
  extract( $args );
924
  if ( ! empty( $instance ) ) {
925
  $the_title = apply_filters( 'widget_title', $instance['my_calendar_mini_title'], $instance, $args );
926
+ $category = ( $instance['my_calendar_mini_category'] == '' ) ? 'all' : $instance['my_calendar_mini_category'];
927
+ $time = ( $instance['my_calendar_mini_time'] == '' ) ? 'month' : $instance['my_calendar_mini_time'];
928
  $widget_link = ( ! isset( $instance['mc_link'] ) || $instance['mc_link'] == '' ) ? '' : esc_url( $instance['mc_link'] );
929
+ $above = ( empty( $instance['above'] ) ) ? 'none' : $instance['above'];
930
+ $below = ( empty( $instance['below'] ) ) ? 'none' : $instance['below'];
931
+ $author = ( !isset( $instance['author'] ) || $instance['author'] == '' ) ? null : $instance['author'];
932
+ $host = ( !isset( $instance['host'] ) || $instance['host'] == '' ) ? null : $instance['host'];
933
+ $site = ( !isset( $instance['site'] ) || $instance['site'] == '' ) ? false : $instance['site'];
934
  } else {
935
  $the_title = $category = $time = $widget_link = $above = $below = '';
936
  }
941
  } else {
942
  $title = '';
943
  }
944
+ $the_events = my_calendar( 'mini', 'mini', $category, $time, '', '', str_replace( 'my_calendar', 'mc', $args['widget_id'] ), '', '', $author, $host, $above, $below, false, false, false, 'widget', $site );
945
  if ( $the_events != '' ) {
946
  echo $before_widget . $title . $the_events . $after_widget;
947
  }
955
  $below = ( isset( $instance['below'] ) ) ? $instance['below'] : 'none';
956
  $widget_link = ( isset( $instance['mc_link'] ) ) ? esc_url( $instance['mc_link'] ) : '';
957
  $host = ( isset( $instance['host'] ) ) ? $instance['host'] : '';
958
+ $site = ( isset( $instance['site'] ) ) ? $instance['site'] : '';
959
  $author = ( isset( $instance['author'] ) ) ? $instance['author'] : '';
960
  ?>
961
  <p>
966
  name="<?php echo $this->get_field_name( 'my_calendar_mini_title' ); ?>"
967
  value="<?php esc_attr_e( $title ); ?>"/>
968
  </p>
969
+ <?php
970
+ if ( function_exists( 'is_multisite' ) && is_multisite() ) {
971
+ ?>
972
+ <p>
973
+ <label
974
+ for="<?php echo $this->get_field_id( 'site' ); ?>"><?php _e( 'Blog ID', 'my-calendar' ); ?>
975
+ :</label><br/>
976
+ <input class="widefat" type="text" id="<?php echo $this->get_field_id( 'site' ); ?>"
977
+ name="<?php echo $this->get_field_name( 'site' ); ?>"
978
+ value="<?php echo esc_attr( $site ); ?>"/>
979
+ </p>
980
+ <?php
981
+ }
982
+ ?>
983
  <p>
984
  <label
985
  for="<?php echo $this->get_field_id( 'mc_link' ); ?>"><?php _e( 'Widget Title Link', 'my-calendar' ); ?>
1063
  }
1064
  $instance['author'] = $author;
1065
  $instance['host'] = $host;
1066
+ $instance['site'] = $new['site'];
1067
 
1068
  return $instance;
1069
  }
 
 
 
 
 
 
 
 
1070
  }
my-calendar.php CHANGED
@@ -7,7 +7,7 @@ Author: Joseph C Dolson
7
  Author URI: http://www.joedolson.com
8
  Text Domain: my-calendar
9
  Domain Path: lang
10
- Version: 2.4.21
11
  */
12
  /* Copyright 2009-2016 Joe Dolson (email : joe@joedolson.com)
13
 
@@ -30,28 +30,7 @@ if ( ! defined( 'ABSPATH' ) ) {
30
  } // Exit if accessed directly
31
 
32
  global $mc_version, $wpdb;
33
- $mc_version = '2.4.21';
34
-
35
- // Define the tables used in My Calendar
36
- if ( is_multisite() && get_site_option( 'mc_multisite_show' ) == 1 ) {
37
- define( 'MY_CALENDAR_TABLE', $wpdb->base_prefix . 'my_calendar' );
38
- define( 'MY_CALENDAR_EVENTS_TABLE', $wpdb->base_prefix . 'my_calendar_events' );
39
- define( 'MY_CALENDAR_CATEGORIES_TABLE', $wpdb->base_prefix . 'my_calendar_categories' );
40
- define( 'MY_CALENDAR_LOCATIONS_TABLE', $wpdb->base_prefix . 'my_calendar_locations' );
41
- } else {
42
- define( 'MY_CALENDAR_TABLE', $wpdb->prefix . 'my_calendar' );
43
- define( 'MY_CALENDAR_EVENTS_TABLE', $wpdb->prefix . 'my_calendar_events' );
44
- define( 'MY_CALENDAR_CATEGORIES_TABLE', $wpdb->prefix . 'my_calendar_categories' );
45
- define( 'MY_CALENDAR_LOCATIONS_TABLE', $wpdb->prefix . 'my_calendar_locations' );
46
- }
47
-
48
- if ( is_multisite() ) {
49
- // Define the tables used in My Calendar
50
- define( 'MY_CALENDAR_GLOBAL_TABLE', $wpdb->base_prefix . 'my_calendar' );
51
- define( 'MY_CALENDAR_GLOBAL_EVENT_TABLE', $wpdb->base_prefix . 'my_calendar_events' );
52
- define( 'MY_CALENDAR_GLOBAL_CATEGORIES_TABLE', $wpdb->base_prefix . 'my_calendar_categories' );
53
- define( 'MY_CALENDAR_GLOBAL_LOCATIONS_TABLE', $wpdb->base_prefix . 'my_calendar_locations' );
54
- }
55
 
56
  register_activation_hook( __FILE__, 'mc_plugin_activated' );
57
  register_deactivation_hook( __FILE__, 'mc_plugin_deactivated' );
@@ -68,7 +47,10 @@ function mc_plugin_deactivated() {
68
  }
69
 
70
  include( dirname( __FILE__ ) . '/includes/date-utilities.php' );
 
 
71
  include( dirname( __FILE__ ) . '/my-calendar-core.php' );
 
72
  include( dirname( __FILE__ ) . '/my-calendar-install.php' );
73
  include( dirname( __FILE__ ) . '/my-calendar-settings.php' );
74
  include( dirname( __FILE__ ) . '/my-calendar-categories.php' );
@@ -176,7 +158,7 @@ function mc_show_sidebar( $show = '', $add = false, $remove = false ) {
176
  <?php if ( ! function_exists( 'mcs_submit_exists' ) ) { ?>
177
  <div class="ui-sortable meta-box-sortables">
178
  <div class="postbox sell support">
179
- <h2 class='sales'><strong><?php _e( 'My Calendar Pro', 'my-calendar' ); ?></strong></h2>
180
 
181
  <div class="inside resources">
182
  <p class="mcbuy"><?php _e( "Buy <a href='https://www.joedolson.com/my-calendar/pro/' rel='external'>My Calendar Pro</a> &mdash; a more powerful calendar for your site.", 'my-calendar' ); ?></p>
@@ -190,13 +172,13 @@ function mc_show_sidebar( $show = '', $add = false, $remove = false ) {
190
  <?php if ( ! function_exists( 'mt_valid' ) ) { ?>
191
  <div class="ui-sortable meta-box-sortables">
192
  <div class="postbox sell my-tickets">
193
- <h2 class='sales'><strong><?php _e( 'My Tickets', 'my-calendar' ); ?></strong></h2>
194
 
195
  <div class="inside resources">
196
  <p class="mcbuy"><?php _e( "Do you sell tickets to your events? <a href='https://wordpress.org/plugins/my-tickets/' rel='external'>Use My Tickets</a> and sell directly from My Calendar.", 'my-calendar' ); ?></p>
197
  <p><?php _e( 'My Tickets integrates with My Calendar or sells tickets independently through posts and pages.', 'my-tickets' ); ?></p>
198
 
199
- <p class="mc-button"><a href="https://wordpress.org/plugins/my-tickets/" rel="external"><?php _e( 'Download My Tickets', 'my-calendar' ); ?></a>
200
  </p>
201
  </div>
202
  </div>
@@ -204,7 +186,7 @@ function mc_show_sidebar( $show = '', $add = false, $remove = false ) {
204
  <?php } ?>
205
  <div class="ui-sortable meta-box-sortables">
206
  <div class="postbox support">
207
- <h2><strong><?php _e( 'Support This Plug-in', 'my-calendar' ); ?></strong></h2>
208
 
209
  <div class="inside resources">
210
  <p>
@@ -226,8 +208,6 @@ function mc_show_sidebar( $show = '', $add = false, $remove = false ) {
226
  rel="external"><?php _e( "Buy the My Calendar User's Guide", 'my-calendar' ); ?></a>
227
  </p>
228
 
229
- <p><strong><?php _e( 'Make a donation today!', 'my-calendar' ); ?></strong></p>
230
-
231
  <form action="https://www.paypal.com/cgi-bin/webscr" method="post">
232
  <p class="mcd">
233
  <input type="hidden" name="cmd" value="_s-xclick" />
@@ -241,7 +221,7 @@ function mc_show_sidebar( $show = '', $add = false, $remove = false ) {
241
  <?php } ?>
242
  <div class="ui-sortable meta-box-sortables">
243
  <div class="postbox">
244
- <h2><?php _e( 'Get Help', 'my-calendar' ); ?></h2>
245
 
246
  <div class="inside">
247
  <ul>
@@ -279,7 +259,7 @@ function mc_show_sidebar( $show = '', $add = false, $remove = false ) {
279
  ?>
280
  <div class="ui-sortable meta-box-sortables">
281
  <div class="postbox">
282
- <h2><?php echo $key; ?></h2>
283
 
284
  <div class='<?php echo sanitize_title( $key ); ?> inside'>
285
  <?php echo $value; ?>
@@ -289,116 +269,6 @@ function mc_show_sidebar( $show = '', $add = false, $remove = false ) {
289
  <?php
290
  }
291
  } ?>
292
- <?php if ( $show == 'templates' ) { ?>
293
- <div class="ui-sortable meta-box-sortables">
294
- <div class="postbox">
295
- <h2><?php _e( 'Event Template Tags', 'my-calendar' ); ?></h2>
296
-
297
- <div class='mc_template_tags inside'>
298
- <dl>
299
- <dt><code>{title}</code></dt>
300
- <dd><?php _e( 'Title of the event.', 'my-calendar' ); ?></dd>
301
-
302
- <dt><code>{link_title}</code></dt>
303
- <dd><?php _e( 'Title of the event as a link if a URL is present, or the title alone if not.', 'my-calendar' ); ?></dd>
304
-
305
- <dt><code>{time}</code></dt>
306
- <dd><?php _e( 'Start time for the event.', 'my-calendar' ); ?></dd>
307
-
308
- <dt><code>{date}</code></dt>
309
- <dd><?php _e( 'Date on which the event begins.', 'my-calendar' ); ?></dd>
310
-
311
- <dt><code>{daterange}</code></dt>
312
- <dd><?php _e( 'Beginning date to end date; excludes end date if same as beginning.', 'my-calendar' ); ?></dd>
313
-
314
- <dt><code>{multidate}</code></dt>
315
- <dd><?php _e( 'Multi-day events: an unordered list of dates/times. Otherwise, beginning date/time.', 'my-calendar' ); ?></dd>
316
-
317
- <dt><code>{author}</code></dt>
318
- <dd><?php _e( 'Author who posted the event.', 'my-calendar' ); ?></dd>
319
-
320
- <dt><code>{host}</code></dt>
321
- <dd><?php _e( 'Name of the assigned host for the event.', 'my-calendar' ); ?></dd>
322
-
323
- <dt><code>{shortdesc}</code></dt>
324
- <dd><?php _e( 'Short event description.', 'my-calendar' ); ?></dd>
325
-
326
- <dt><code>{description}</code></dt>
327
- <dd><?php _e( 'Description of the event.', 'my-calendar' ); ?></dd>
328
-
329
- <dt><code>{image}</code></dt>
330
- <dd><?php _e( 'Image associated with the event.', 'my-calendar' ); ?></dd>
331
-
332
- <dt><code>{link}</code></dt>
333
- <dd><?php _e( 'URL provided for the event.', 'my-calendar' ); ?></dd>
334
-
335
- <dt><code>{details}</code></dt>
336
- <dd><?php _e( 'Link to an auto-generated page containing information about the event.', 'my-calendar' ); ?>
337
-
338
- <dt><code>{event_open}</code></dt>
339
- <dd><?php _e( 'Whether event is currently open for registration.', 'my-calendar' ); ?></dd>
340
-
341
- <dt><code>{event_status}</code></dt>
342
- <dd><?php _e( 'Current status of event: either "Published" or "Reserved."', 'my-calendar' ); ?></dd>
343
- </dl>
344
-
345
- <h3><?php _e( 'Location Template Tags', 'my-calendar' ); ?></h3>
346
- <dl>
347
- <dt><code>{location}</code></dt>
348
- <dd><?php _e( 'Name of the location of the event.', 'my-calendar' ); ?></dd>
349
-
350
- <dt><code>{street}</code></dt>
351
- <dd><?php _e( 'First line of the site address.', 'my-calendar' ); ?></dd>
352
-
353
- <dt><code>{street2}</code></dt>
354
- <dd><?php _e( 'Second line of the site address.', 'my-calendar' ); ?></dd>
355
-
356
- <dt><code>{city}</code></dt>
357
- <dd><?php _e( 'City', 'my-calendar' ); ?></dd>
358
-
359
- <dt><code>{state}</code></dt>
360
- <dd><?php _e( 'State', 'my-calendar' ); ?></dd>
361
-
362
- <dt><code>{postcode}</code></dt>
363
- <dd><?php _e( 'Postal Code', 'my-calendar' ); ?></dd>
364
-
365
- <dt><code>{region}</code></dt>
366
- <dd><?php _e( 'Custom region.', 'my-calendar' ); ?></dd>
367
-
368
- <dt><code>{country}</code></dt>
369
- <dd><?php _e( 'Country for the event location.', 'my-calendar' ); ?></dd>
370
-
371
- <dt><code>{sitelink}</code></dt>
372
- <dd><?php _e( 'Output the URL for the location.', 'my-calendar' ); ?></dd>
373
-
374
- <dt><code>{hcard}</code></dt>
375
- <dd><?php _e( 'Event address in <a href="http://microformats.org/wiki/hcard">hcard</a> format.', 'my-calendar' ); ?></dd>
376
-
377
- <dt><code>{link_map}</code></dt>
378
- <dd><?php _e( 'Link to Google Map to the event, if address information is available.', 'my-calendar' ); ?></dd>
379
- </dl>
380
- <h3><?php _e( 'Category Template Tags', 'my-calendar' ); ?></h3>
381
-
382
- <dl>
383
- <dt><code>{category}</code></dt>
384
- <dd><?php _e( 'Name of the category of the event.', 'my-calendar' ); ?></dd>
385
-
386
- <dt><code>{icon}</code></dt>
387
- <dd><?php _e( 'URL for the event\'s category icon.', 'my-calendar' ); ?></dd>
388
-
389
- <dt><code>{color}</code></dt>
390
- <dd><?php _e( 'Hex code for the event\'s category color.', 'my-calendar' ); ?></dd>
391
-
392
- <dt><code>{cat_id}</code></dt>
393
- <dd><?php _e( 'ID of the category of the event.', 'my-calendar' ); ?></dd>
394
- </dl>
395
- <p>
396
- <a href="<?php echo admin_url( 'admin.php?page=my-calendar-help#templates' ); ?>"><?php _e( 'All Template Tags &raquo;', 'my-calendar' ); ?></a>
397
- </p>
398
- </div>
399
- </div>
400
- </div>
401
- <?php } ?>
402
  </div>
403
  </div>
404
  <?php
7
  Author URI: http://www.joedolson.com
8
  Text Domain: my-calendar
9
  Domain Path: lang
10
+ Version: 2.5.0
11
  */
12
  /* Copyright 2009-2016 Joe Dolson (email : joe@joedolson.com)
13
 
30
  } // Exit if accessed directly
31
 
32
  global $mc_version, $wpdb;
33
+ $mc_version = '2.5.0';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
 
35
  register_activation_hook( __FILE__, 'mc_plugin_activated' );
36
  register_deactivation_hook( __FILE__, 'mc_plugin_deactivated' );
47
  }
48
 
49
  include( dirname( __FILE__ ) . '/includes/date-utilities.php' );
50
+ include( dirname( __FILE__ ) . '/includes/general-utilities.php' );
51
+ include( dirname( __FILE__ ) . '/includes/kses.php' );
52
  include( dirname( __FILE__ ) . '/my-calendar-core.php' );
53
+ include( dirname( __FILE__ ) . '/my-calendar-db.php' );
54
  include( dirname( __FILE__ ) . '/my-calendar-install.php' );
55
  include( dirname( __FILE__ ) . '/my-calendar-settings.php' );
56
  include( dirname( __FILE__ ) . '/my-calendar-categories.php' );
158
  <?php if ( ! function_exists( 'mcs_submit_exists' ) ) { ?>
159
  <div class="ui-sortable meta-box-sortables">
160
  <div class="postbox sell support">
161
+ <h2 class='sales hndle'><strong><?php _e( 'My Calendar Pro', 'my-calendar' ); ?></strong></h2>
162
 
163
  <div class="inside resources">
164
  <p class="mcbuy"><?php _e( "Buy <a href='https://www.joedolson.com/my-calendar/pro/' rel='external'>My Calendar Pro</a> &mdash; a more powerful calendar for your site.", 'my-calendar' ); ?></p>
172
  <?php if ( ! function_exists( 'mt_valid' ) ) { ?>
173
  <div class="ui-sortable meta-box-sortables">
174
  <div class="postbox sell my-tickets">
175
+ <h2 class='sales hndle'><strong><?php _e( 'My Tickets', 'my-calendar' ); ?></strong></h2>
176
 
177
  <div class="inside resources">
178
  <p class="mcbuy"><?php _e( "Do you sell tickets to your events? <a href='https://wordpress.org/plugins/my-tickets/' rel='external'>Use My Tickets</a> and sell directly from My Calendar.", 'my-calendar' ); ?></p>
179
  <p><?php _e( 'My Tickets integrates with My Calendar or sells tickets independently through posts and pages.', 'my-tickets' ); ?></p>
180
 
181
+ <p class="mc-button"><a href="http://dev.josephdolson.com/wp-admin/plugin-install.php?tab=plugin-information&plugin=my-tickets&TB_iframe=true&width=600&height=550" class="thickbox open-plugin-details-modal" rel="external"><?php _e( 'Try My Tickets', 'my-calendar' ); ?></a>
182
  </p>
183
  </div>
184
  </div>
186
  <?php } ?>
187
  <div class="ui-sortable meta-box-sortables">
188
  <div class="postbox support">
189
+ <h2 class='hndle'><strong><?php _e( 'Support This Plug-in', 'my-calendar' ); ?></strong></h2>
190
 
191
  <div class="inside resources">
192
  <p>
208
  rel="external"><?php _e( "Buy the My Calendar User's Guide", 'my-calendar' ); ?></a>
209
  </p>
210
 
 
 
211
  <form action="https://www.paypal.com/cgi-bin/webscr" method="post">
212
  <p class="mcd">
213
  <input type="hidden" name="cmd" value="_s-xclick" />
221
  <?php } ?>
222
  <div class="ui-sortable meta-box-sortables">
223
  <div class="postbox">
224
+ <h2 class='hndle'><?php _e( 'Get Help', 'my-calendar' ); ?></h2>
225
 
226
  <div class="inside">
227
  <ul>
259
  ?>
260
  <div class="ui-sortable meta-box-sortables">
261
  <div class="postbox">
262
+ <h2 class='hndle'><?php echo $key; ?></h2>
263
 
264
  <div class='<?php echo sanitize_title( $key ); ?> inside'>
265
  <?php echo $value; ?>
269
  <?php
270
  }
271
  } ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
272
  </div>
273
  </div>
274
  <?php
php-errors.log DELETED
File without changes
readme.txt CHANGED
@@ -1,10 +1,10 @@
1
  === My Calendar ===
2
  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, conference, meeting, venue, location, box office, tickets, registration
5
- Requires at least: 4.0
6
- Tested up to: 4.5
7
- Stable tag: 2.4.20
8
  Text domain: my-calendar
9
  License: GPLv2 or later
10
 
@@ -22,24 +22,24 @@ Easy to use for anybody, My Calendar provides enormous flexibility for designers
22
 
23
  = Features: =
24
 
25
- * Standard calendar grid and list views of events
26
- * Show events in monthly, weekly, or daily view.
27
- * Mini-calendar view for compact displays (as widget or as shortcode)
28
  * Widgets: today's events, upcoming events, compact calendar, event search
29
  * Custom templates for event output
30
  * Limit views by categories, location, author, or host
31
  * Disable default CSS and default JavaScript or display only on specific Pages/Posts
32
  * Editable CSS styles and JavaScript behaviors
33
- * Schedule a wide variety of recurring events.
34
- * Edit individual occurrences of recurring events
35
  * Rich permissions handling to restrict access to parts of My Calendar
36
  * Email notification to administrator when events are scheduled or reserved
37
  * Post to Twitter when events are created. (with [WP to Twitter](http://wordpress.org/extend/plugins/wp-to-twitter/))
38
  * Location Manager for frequently used venues
39
- * Fetch events from a remote MySQL database. (Sharing events in a network of sites.)
40
  * Import events from [Kieran O'Shea's Calendar plugin](http://wordpress.org/extend/plugins/calendar/)
41
- * Integrated Help page to guide in use of shortcodes and template tags
42
- * Shortcode Generator to help create customized views of My Calendar
43
  * [Developer Documentation](http://www.joedolson.com/doc-category/my-calendar-3/)
44
 
45
  = What's in My Calendar Pro? =
@@ -50,12 +50,13 @@ Easy to use for anybody, My Calendar provides enormous flexibility for designers
50
  * Publish a blog post when you create an event
51
  * Advanced search features
52
  * Responsive mode
 
53
 
54
  = Translations =
55
 
56
- Visit [Wordpress Translations](https://translate.wordpress.org/projects/wp-plugins/my-calendar) to check the progress of your translation.
57
 
58
- Translating my plug-ins is always appreciated. Visit <a href="https://translate.wordpress.org/projects/wp-plugins/my-calendar">WordPress translations</a> to start getting your language into shape! Translations will only be published when they reach 100% completion.
59
 
60
  == Installation ==
61
 
@@ -65,8 +66,8 @@ Translating my plug-ins is always appreciated. Visit <a href="https://translate.
65
 
66
  3. Configure My Calendar using the settings pages in the admin panel:
67
 
68
- My Calendar -> Manage Events
69
  My Calendar -> Add New Event
 
70
  My Calendar -> Manage Categories
71
  My Calendar -> Manage Locations
72
  My Calendar -> Manage Event Groups
@@ -82,29 +83,42 @@ Translating my plug-ins is always appreciated. Visit <a href="https://translate.
82
 
83
  == Changelog ==
84
 
85
- = Future Changes =
86
 
87
- * Make annual view in list mode configurable on a calendar-specific basis rather than globally; effect date switcher; see https://www.joedolson.com/forums/topic/annual-calendar/#post-5427
88
- * Refactor options storage
89
- * Update event taxonomies if category changed/source event taxonomy data from post
90
- * Custom link targets using mc_customize_details_link & template_redirect filter as pointer.
91
- * Handle stylesheet editing as additive (child styles), rather than editing the original stylesheet.
92
- * Update pickadate to version 3.6, when it's out. 3.5.6 has a regression that makes it useless for me.
93
- * Send admin notice when recurring event is about to end
94
- * Change all shortcode 'template' attributes to reference stored templates in settings by name or ID.
95
- * Feature Request: make unqualified event permalinks display next occurrence rather than first (last?) (show list of occurrences?)
96
- * Create mechanism to get & display all events in a group (see group-manager.php line 253)
97
- * Add option to insert new occurrences into an existing event. (Make single event recurring, add arbitrary date into group, etc.)
98
- * Add option to insert events to both global & local calendar in multisite networks
99
- * Revise month by day input & calculation methods
100
  * Update hcalendar structures
101
- * When month starts on Sunday, shows full previous month's week?
102
- * Make iCal timezone configurable via URL params & eliminate that setting.
103
-
104
- = 2.5.0 = (Unreleased)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
 
106
  Breaking Changes:
107
-
108
  * Breaking change: upcoming events widget no longer uses ID 'upcoming-events'; use class '.upcoming-events'
109
  * Breaking change: today's events widget no longer uses ID 'todays-events'; use class '.todays-events'
110
 
@@ -700,6 +714,20 @@ This is a major revision.
700
  * Scheduled removal of showkey, shownav, toggle, and showjump shortcode attributes.
701
  * Removed upgrade support for 1.6.x & 1.7.x series of My Calendar.
702
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
703
  == Frequently Asked Questions ==
704
 
705
  = Hey! Why don't you have any Frequently Asked Questions here! =
1
  === My Calendar ===
2
  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: 4.6
7
+ Stable tag: 2.4.21
8
  Text domain: my-calendar
9
  License: GPLv2 or later
10
 
22
 
23
  = Features: =
24
 
25
+ * Calendar grid and list views of events
26
+ * Monthly, weekly, or daily view.
27
+ * Mini-calendar for compact displays (as widget or as shortcode)
28
  * Widgets: today's events, upcoming events, compact calendar, event search
29
  * Custom templates for event output
30
  * Limit views by categories, location, author, or host
31
  * Disable default CSS and default JavaScript or display only on specific Pages/Posts
32
  * Editable CSS styles and JavaScript behaviors
33
+ * Schedule a variety of recurring events.
34
+ * Edit occurrences of recurring events
35
  * Rich permissions handling to restrict access to parts of My Calendar
36
  * Email notification to administrator when events are scheduled or reserved
37
  * Post to Twitter when events are created. (with [WP to Twitter](http://wordpress.org/extend/plugins/wp-to-twitter/))
38
  * Location Manager for frequently used venues
39
+ * Fetch events from a remote database. (Sharing events in a network of sites.)
40
  * Import events from [Kieran O'Shea's Calendar plugin](http://wordpress.org/extend/plugins/calendar/)
41
+ * Integrated Help to guide in use of shortcodes and template tags
42
+ * Shortcode Generator to create customized views of My Calendar
43
  * [Developer Documentation](http://www.joedolson.com/doc-category/my-calendar-3/)
44
 
45
  = What's in My Calendar Pro? =
50
  * Publish a blog post when you create an event
51
  * Advanced search features
52
  * Responsive mode
53
+ * Import events from .ics or .csv formats via file or URL.
54
 
55
  = Translations =
56
 
57
+ Visit [Wordpress Translations](https://translate.wordpress.org/projects/wp-plugins/my-calendar) to check progress or contribute to your language.
58
 
59
+ Translating my plug-ins is always appreciated. Visit <a href="https://translate.wordpress.org/projects/wp-plugins/my-calendar">WordPress translations</a> to help get your language to 100%!
60
 
61
  == Installation ==
62
 
66
 
67
  3. Configure My Calendar using the settings pages in the admin panel:
68
 
 
69
  My Calendar -> Add New Event
70
+ My Calendar -> Manage Events
71
  My Calendar -> Manage Categories
72
  My Calendar -> Manage Locations
73
  My Calendar -> Manage Event Groups
83
 
84
  == Changelog ==
85
 
86
+ = 2.5.0 =
87
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
  * Update hcalendar structures
89
+ * Better handling when updating event taxonomies
90
+ * Options to restrict management of events by category / user
91
+ * UI Clean up
92
+ * Don't display format toggle on mobile if automatic format switching enabled
93
+ * Add custom date option to upcoming events shortcode builder
94
+ * Improved error message if user creates event with an invalid recurring cycle
95
+ * Updated template editor; ability to create custom templates.
96
+ * Add option to add new dates for an existing event.
97
+ * For single event, show closest available date if no/invalid date ID provided.
98
+ * Added first occurrence data to core event object
99
+ * New template tag: {related} to list other events in the same group
100
+ * New loading indicator for AJAX navigation
101
+ * New filter to modify event classes
102
+ * New function to generate event classes
103
+ * Reduce number of strings in plug-in to reduce burden on translators
104
+ * Multisite: ability to display calendar for any site on any other site
105
+ * in my_calendar_draw_event(), add filter to hide additional days of events
106
+ * Improved HTML filtering to allow input elements and schema.org attributes.
107
+ * Add support for Google Maps API key field, now required for use of Google Maps on new sites
108
+ * Add 'today' keyword for the upcoming events 'to' attribute
109
+ * Updates to Help documentation
110
+ * Bug fix: auto assign events with no category to 'General'
111
+ * Bug fix: some user select lists overwrote select list options
112
+ * Bug fix: new events with no times entered need to be created as all day events
113
+ * Bug fix: wrong number of arguments passed to mass delete events hook
114
+ * Bug fix: Custom JS incorrectly escaped in Script manager
115
+ * Bug fix: removed numerous notices
116
+ * Bug fix: improved handling of missing event posts
117
+ * Bug fix: allow more HTML elements & attributes
118
+ * Bug fix: misc. notices
119
 
120
  Breaking Changes:
121
+ * Breaking change: minor changes to classes to improve structured data in microformats
122
  * Breaking change: upcoming events widget no longer uses ID 'upcoming-events'; use class '.upcoming-events'
123
  * Breaking change: today's events widget no longer uses ID 'todays-events'; use class '.todays-events'
124
 
714
  * Scheduled removal of showkey, shownav, toggle, and showjump shortcode attributes.
715
  * Removed upgrade support for 1.6.x & 1.7.x series of My Calendar.
716
 
717
+ = Future Changes =
718
+
719
+ * Make annual view in list mode configurable on a calendar-specific basis rather than globally; effect date switcher; see https://www.joedolson.com/forums/topic/annual-calendar/#post-5427
720
+ * Refactor options storage
721
+ * Handle stylesheet editing as additive (child styles), rather than editing the original stylesheet.
722
+ * Send admin notice when recurring event is about to end
723
+ - Instead: create plug-in extension that hooks into an appropriate action and adds new occurrences
724
+ * Revise month by day input & calculation methods
725
+ * When month starts on Sunday, shows full previous month's week?
726
+ * Bug: if save generates error, creates ton of notices. [eliminate $users_entries object and use single object model]
727
+ * Add ability to limit by multiple locations (e.g., view all events in Location 1 & Location 2; only on lvalue)
728
+ * Event occurrence IDs can change when events dates are changed
729
+ * Add option to insert events simultaneously to both global & local calendar in multisite networks [todo]
730
+
731
  == Frequently Asked Questions ==
732
 
733
  = Hey! Why don't you have any Frequently Asked Questions here! =