My Calendar - Version 2.5.9

Version Description

  • Bug fix: class .mc-main appeared twice in day view
  • Bug fix: iCal output fetches no data on subsites in multisite networks
  • Bug fix: broken image upload script due to localization change
  • Bug fix: sorting events by category should sort by name, not ID
  • Add site name to .ics output file
Download this release

Release Info

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

Code changes from version 2.5.0 to 2.5.9

css/mc-print.css CHANGED
@@ -24,15 +24,19 @@ td {
24
  font-size: 12px;
25
  vertical-align: top;
26
  width: 14.285%;
 
27
  }
28
 
29
  .details {
30
- border-bottom: 1px solid #ddd;
31
  color: #444;
32
  margin-bottom: 2px;
33
  }
34
 
35
- .details a, .details img {
 
 
 
 
36
  display: none;
37
  }
38
 
@@ -58,12 +62,14 @@ abbr {
58
 
59
  a {
60
  text-decoration: none;
61
- color: #f00
62
  }
63
 
64
  .mc-date {
65
  font-weight: 700;
66
  font-size: 1.2em;
 
 
67
  padding: 2px 4px;
68
  line-height: 1;
69
  margin-left: 3px;
@@ -80,4 +86,13 @@ a {
80
  font-weight: 700;
81
  font-size: 1.5em;
82
  text-align: center;
 
 
 
 
 
 
 
 
 
83
  }
24
  font-size: 12px;
25
  vertical-align: top;
26
  width: 14.285%;
27
+ height: 4em;
28
  }
29
 
30
  .details {
 
31
  color: #444;
32
  margin-bottom: 2px;
33
  }
34
 
35
+ .vevent:not(:last-child) .details {
36
+ border-bottom: 1px solid #ddd;
37
+ }
38
+
39
+ .details * {
40
  display: none;
41
  }
42
 
62
 
63
  a {
64
  text-decoration: none;
65
+ color: #d00
66
  }
67
 
68
  .mc-date {
69
  font-weight: 700;
70
  font-size: 1.2em;
71
+ width: 1em;
72
+ text-align: center;
73
  padding: 2px 4px;
74
  line-height: 1;
75
  margin-left: 3px;
86
  font-weight: 700;
87
  font-size: 1.5em;
88
  text-align: center;
89
+ text-decoration: underline;
90
+ }
91
+
92
+ .return:hover, .return:focus {
93
+ text-decoration: none;
94
+ }
95
+
96
+ @media print {
97
+ .return { display: none; }
98
  }
css/mc-styles.css CHANGED
@@ -12,20 +12,6 @@
12
  line-height: 1.5
13
  }
14
 
15
- .mc-button {
16
- text-align: center;
17
- font-size: 1.4em;
18
- padding: 10px 0 0
19
- }
20
-
21
- .mc-button a {
22
- padding: 3px 8px;
23
- border: 1px outset;
24
- border-radius: 7px;
25
- background: #fff;
26
- font-weight: 700;
27
- }
28
-
29
  .mcd {
30
  text-align: center;
31
  margin: 0;
@@ -70,7 +56,7 @@ ul.links li {
70
  font-size: .9em
71
  }
72
 
73
- .jd-my-calendar .metabox-holder .postbox > h2 {
74
  font-size: 14px;
75
  padding: 8px 12px;
76
  margin: 0;
@@ -93,19 +79,19 @@ span.mc-notice {
93
  border: 1px solid #900;
94
  }
95
 
96
- .jd-my-calendar .spam {
97
  background: #ffa
98
  }
99
 
100
- .jd-my-calendar .pending {
101
  background: #eee
102
  }
103
 
104
- .jd-my-calendar .pending td, .jd-my-calendar .row-actions {
105
  color: #666;
106
  }
107
 
108
- .jd-my-calendar fieldset fieldset {
109
  margin: 0 0 20px 0;
110
  padding-top: 2px
111
  }
@@ -167,12 +153,12 @@ span.mc-notice {
167
  column-gap: 30px
168
  }
169
 
170
- .jd-my-calendar .event_image {
171
  float: right;
172
  margin-left: 10px;
173
  }
174
 
175
- .jd-my-calendar .event_image img {
176
  width: 150px;
177
  height: auto;
178
  margin: 2px 0;
@@ -189,52 +175,52 @@ span.mc-notice {
189
  width: 98%
190
  }
191
 
192
- .jd-my-calendar .postbox {
193
  margin: 10px 10px 0 0
194
  }
195
 
196
- .jd-my-calendar .postbox.wptab {
197
  margin: 0 10px 0 0!important;
198
  border: 1px solid #e5e5e5;
199
  }
200
 
201
- .jd-my-calendar .postbox .inside {
202
  overflow: visible !important
203
  }
204
 
205
 
206
 
207
  /* some plugins change this, but I need it at WP default. */
208
- .jd-my-calendar .meta-box-sortables {
209
  min-height: 0
210
  }
211
 
212
- .jd-my-calendar textarea {
213
  width: 100%
214
  }
215
 
216
- .jd-my-calendar pre {
217
  background: #fff;
218
  padding: 5px;
219
  border: 1px solid #ddd;
220
  box-shadow: 1px 1px 2px #ddd
221
  }
222
 
223
- .jd-my-calendar label span.required {
224
  font-size: .9em;
225
  color: #c33
226
  }
227
 
228
- .jd-my-calendar .default {
229
  background: #fff
230
  }
231
 
232
- .jd-my-calendar .button-adjust {
233
  top: 10px;
234
  right: 0
235
  }
236
 
237
- .jd-my-calendar hr {
238
  width: 20%;
239
  margin: 0 auto;
240
  border: none;
@@ -247,7 +233,7 @@ span.mc-notice {
247
  display: inline-block
248
  }
249
 
250
- .jd-my-calendar .tablenav {
251
  float: right
252
  }
253
 
@@ -282,17 +268,17 @@ strong.label {
282
  z-index: 10;
283
  }
284
 
285
- .jd-my-calendar .counter {
286
  padding-right: 6px;
287
  border-right: 16px solid green;
288
  border-radius: 20px;
289
  }
290
 
291
- .jd-my-calendar .counter.warning {
292
  border-color: orange;
293
  }
294
 
295
- .jd-my-calendar .counter.exceeded {
296
  border-color: red;
297
  }
298
 
@@ -353,7 +339,7 @@ strong.label {
353
  display: none;
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;
@@ -369,7 +355,13 @@ strong.label {
369
  width: 7em;
370
  }
371
 
372
- .jd-my-calendar .ui-accordion-header.ui-state-hover, .ui-accordion-header.ui-state-focus, .mc-settings-page #mc-sortable li:hover {
 
 
 
 
 
 
373
  background: #f6f6f6;
374
  box-shadow: 0 0 2px #ddd;
375
  }
@@ -389,15 +381,15 @@ input[name="mc_uri"] {
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
 
@@ -412,6 +404,10 @@ input[name="mc_uri"] {
412
  color: #eee;
413
  }
414
 
 
 
 
 
415
  #mc-sortable li.mc-stop:hover {
416
  background-color: #000;
417
  color: #bbb;
@@ -428,10 +424,10 @@ input[name="mc_uri"] {
428
  text-align: center;
429
  }
430
 
431
- .jd-my-calendar .checkboxes {
432
  margin: 0;
433
  }
434
- .jd-my-calendar .checkboxes:after {
435
  content: '';
436
  display: table;
437
  clear: both;
@@ -444,7 +440,7 @@ input[name="mc_uri"] {
444
  margin-bottom: 1em;
445
  }
446
 
447
- .jd-my-calendar .mc_permissions .checkboxes li {
448
  display: block;
449
  }
450
 
@@ -452,14 +448,14 @@ input[name="mc_uri"] {
452
  padding: 1em;
453
  }
454
 
455
- .jd-my-calendar .checkboxes li {
456
  display: inline-block;
457
  padding: 5px;
458
  background: rgba(0, 0, 0, .05);
459
  margin: 2px;
460
  }
461
 
462
- .jd-my-calendar .checkboxes li:hover {
463
  background: #fff;
464
  }
465
 
@@ -471,7 +467,7 @@ input[name="mc_uri"] {
471
  clear: left;
472
  }
473
 
474
- .jd-my-calendar fieldset legend {
475
  font-weight: 700;
476
  padding: 0;
477
  font-size: 1.1em;
@@ -590,7 +586,7 @@ input[name="mc_uri"] {
590
  content: "\f132";
591
  }
592
 
593
- .jd-my-calendar .postbox .hndle {
594
  cursor: auto;
595
  }
596
 
@@ -620,7 +616,7 @@ input[name="mc_uri"] {
620
  text-shadow: 1px 0 0 #000;
621
  }
622
 
623
- .jd-my-calendar .error .button-secondary {
624
  vertical-align: baseline;
625
  }
626
 
@@ -681,7 +677,7 @@ tr.problem .error {
681
  color: #fff !important;
682
  }
683
 
684
- .jd-my-calendar .mc-none {
685
  clear: both;
686
  }
687
 
@@ -692,7 +688,7 @@ tr.problem .error {
692
  }
693
 
694
  @media (max-width: 782px) {
695
- .jd-my-calendar .tablenav {
696
  float: none;
697
  }
698
 
12
  line-height: 1.5
13
  }
14
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  .mcd {
16
  text-align: center;
17
  margin: 0;
56
  font-size: .9em
57
  }
58
 
59
+ .my-calendar-admin .metabox-holder .postbox > h2 {
60
  font-size: 14px;
61
  padding: 8px 12px;
62
  margin: 0;
79
  border: 1px solid #900;
80
  }
81
 
82
+ .my-calendar-admin .spam {
83
  background: #ffa
84
  }
85
 
86
+ .my-calendar-admin .pending {
87
  background: #eee
88
  }
89
 
90
+ .my-calendar-admin .pending td, .my-calendar-admin .row-actions {
91
  color: #666;
92
  }
93
 
94
+ .my-calendar-admin fieldset fieldset {
95
  margin: 0 0 20px 0;
96
  padding-top: 2px
97
  }
153
  column-gap: 30px
154
  }
155
 
156
+ .my-calendar-admin .event_image {
157
  float: right;
158
  margin-left: 10px;
159
  }
160
 
161
+ .my-calendar-admin .event_image img {
162
  width: 150px;
163
  height: auto;
164
  margin: 2px 0;
175
  width: 98%
176
  }
177
 
178
+ .my-calendar-admin .postbox {
179
  margin: 10px 10px 0 0
180
  }
181
 
182
+ .my-calendar-admin .postbox.wptab {
183
  margin: 0 10px 0 0!important;
184
  border: 1px solid #e5e5e5;
185
  }
186
 
187
+ .my-calendar-admin .postbox .inside {
188
  overflow: visible !important
189
  }
190
 
191
 
192
 
193
  /* some plugins change this, but I need it at WP default. */
194
+ .my-calendar-admin .meta-box-sortables {
195
  min-height: 0
196
  }
197
 
198
+ .my-calendar-admin textarea {
199
  width: 100%
200
  }
201
 
202
+ .my-calendar-admin pre {
203
  background: #fff;
204
  padding: 5px;
205
  border: 1px solid #ddd;
206
  box-shadow: 1px 1px 2px #ddd
207
  }
208
 
209
+ .my-calendar-admin label span.required {
210
  font-size: .9em;
211
  color: #c33
212
  }
213
 
214
+ .my-calendar-admin .default {
215
  background: #fff
216
  }
217
 
218
+ .my-calendar-admin .button-adjust {
219
  top: 10px;
220
  right: 0
221
  }
222
 
223
+ .my-calendar-admin hr {
224
  width: 20%;
225
  margin: 0 auto;
226
  border: none;
233
  display: inline-block
234
  }
235
 
236
+ .my-calendar-admin .tablenav {
237
  float: right
238
  }
239
 
268
  z-index: 10;
269
  }
270
 
271
+ .my-calendar-admin .counter {
272
  padding-right: 6px;
273
  border-right: 16px solid green;
274
  border-radius: 20px;
275
  }
276
 
277
+ .my-calendar-admin .counter.warning {
278
  border-color: orange;
279
  }
280
 
281
+ .my-calendar-admin .counter.exceeded {
282
  border-color: red;
283
  }
284
 
339
  display: none;
340
  }
341
 
342
+ .my-calendar-admin .ui-accordion-header, .mc-settings-page #mc-sortable li {
343
  border: 1px solid #ddd;
344
  background: rgba(0, 0, 0, .10);
345
  padding: .5em 1em;
355
  width: 7em;
356
  }
357
 
358
+ #mc-sortable li:nth-of-type(1) .mc-buttons .up, #mc-sortable li:nth-of-type(9) .mc-buttons .down {
359
+ background: none;
360
+ border: 1px solid transparent;
361
+ color: rgba( 0,0,0,.4 );
362
+ }
363
+
364
+ .my-calendar-admin .ui-accordion-header.ui-state-hover, .ui-accordion-header.ui-state-focus, .mc-settings-page #mc-sortable li:hover {
365
  background: #f6f6f6;
366
  box-shadow: 0 0 2px #ddd;
367
  }
381
  padding: 1em;
382
  }
383
 
384
+ .my-calendar-admin .ui-accordion-header-active {
385
  background: rgba(0, 0, 0, .05);
386
  }
387
 
388
+ .my-calendar-admin .ui-accordion-header .dashicons:before {
389
  content: "\f132";
390
  }
391
 
392
+ .my-calendar-admin .ui-accordion-header-active .dashicons:before {
393
  content: "\f460";
394
  }
395
 
404
  color: #eee;
405
  }
406
 
407
+ #mc-sortable li.mc-stop.mc-updated {
408
+ color: #000;
409
+ }
410
+
411
  #mc-sortable li.mc-stop:hover {
412
  background-color: #000;
413
  color: #bbb;
424
  text-align: center;
425
  }
426
 
427
+ .my-calendar-admin .checkboxes {
428
  margin: 0;
429
  }
430
+ .my-calendar-admin .checkboxes:after {
431
  content: '';
432
  display: table;
433
  clear: both;
440
  margin-bottom: 1em;
441
  }
442
 
443
+ .my-calendar-admin .mc_permissions .checkboxes li {
444
  display: block;
445
  }
446
 
448
  padding: 1em;
449
  }
450
 
451
+ .my-calendar-admin .checkboxes li {
452
  display: inline-block;
453
  padding: 5px;
454
  background: rgba(0, 0, 0, .05);
455
  margin: 2px;
456
  }
457
 
458
+ .my-calendar-admin .checkboxes li:hover {
459
  background: #fff;
460
  }
461
 
467
  clear: left;
468
  }
469
 
470
+ .my-calendar-admin fieldset legend {
471
  font-weight: 700;
472
  padding: 0;
473
  font-size: 1.1em;
586
  content: "\f132";
587
  }
588
 
589
+ .my-calendar-admin .postbox .hndle {
590
  cursor: auto;
591
  }
592
 
616
  text-shadow: 1px 0 0 #000;
617
  }
618
 
619
+ .my-calendar-admin .error .button-secondary {
620
  vertical-align: baseline;
621
  }
622
 
677
  color: #fff !important;
678
  }
679
 
680
+ .my-calendar-admin .mc-none {
681
  clear: both;
682
  }
683
 
688
  }
689
 
690
  @media (max-width: 782px) {
691
+ .my-calendar-admin .tablenav {
692
  float: none;
693
  }
694
 
css/reset.css CHANGED
@@ -140,5 +140,5 @@ button.mc-text-button:hover, button .mc-text-button:focus {
140
  max-width: none ! important;
141
  }
142
 
143
- .mcjs .mc-main .details, .mcjs .mc-main .calendar-events { display: none; }
144
- .mcjs .mc-main .single-event .details, .mcjs .mc-main .list.day .details { display: block; }
140
  max-width: none ! important;
141
  }
142
 
143
+ .mcjs.mc-main .details, .mcjs.mc-main .calendar-events { display: none; }
144
+ .mcjs.mc-main .single-event .details, .mcjs.mc-main .list.day .details { display: block; }
includes/kses.php CHANGED
@@ -34,44 +34,44 @@ function mc_allowed_tags( $tags, $context ) {
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,
@@ -80,8 +80,14 @@ function mc_allowed_tags( $tags, $context ) {
80
  'id' => true,
81
  'longdesc' => true,
82
  'tabindex' => true
 
 
 
 
 
 
83
  );
84
  }
85
 
86
- return $tags;
87
  }
34
  'readonly' => true,
35
  'min' => true,
36
  'max' => true,
37
+ 'id' => true,
38
+ 'checked' => true,
39
+ 'required' => true
40
  );
41
  $tags['select'] = array(
42
  'name' => true,
43
  'id' => true,
44
  'class' => true
45
  );
46
+ $tags['span'] = array_merge( $tags['span'], array(
 
 
 
 
47
  'itemprop' => true,
48
  'itemscope' => true,
49
  'itemtype' => true,
50
+ ) );
51
+ $tags['button'] = array_merge( $tags['button'], array(
52
  'name' => true,
53
  'type' => true,
54
  'disabled' => true,
55
+ 'class' => true,
56
+ ) );
57
+ $tags['form'] = array_merge( $tags['form'], array(
58
  'action' => true,
59
  'method' => true,
60
  'class' => true,
61
  'id' => true,
62
  'tabindex' => true,
63
+ ) );
64
+ $tags['div'] = array_merge( $tags['div'], array(
65
  'class' => true,
66
  'id' => true,
67
  'aria-live' => true,
68
+ ) );
69
+ $tags['fieldset'] = array_merge( $tags['fieldset'], array() );
70
+ $tags['legend'] = array_merge( $tags['legend'], array() );
71
+ $tags['p'] = array_merge( $tags['p'], array(
72
  'class' => true,
73
+ ) );
74
+ $tags['img'] = array_merge( $tags['img'], array(
75
  'class' => true,
76
  'src' => true,
77
  'alt' => true,
80
  'id' => true,
81
  'longdesc' => true,
82
  'tabindex' => true
83
+ ) );
84
+ $tags['iframe'] = array(
85
+ 'width' => true,
86
+ 'height' => true,
87
+ 'src' => true,
88
+ 'frameborder' => true
89
  );
90
  }
91
 
92
+ return apply_filters( 'mc_kses_post', $tags );
93
  }
js/gmap3.js DELETED
@@ -1,1131 +0,0 @@
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 DELETED
@@ -1,31 +0,0 @@
1
- jQuery(document).ready(function ($) {
2
- $('#add_field').on('click', function () {
3
- $('#event_span').show();
4
- var num = $('.clonedInput').length; // how many "duplicatable" input fields we currently have
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 () {
19
- var num = $('.clonedInput').length; // how many "duplicatable" input fields we currently have
20
- $('#event' + num).remove(); // remove the last element
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/jquery.admin.js ADDED
@@ -0,0 +1,150 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ jQuery(document).ready(function ($) {
2
+ $('#add_field').on('click', function () {
3
+ $('#event_span').show();
4
+ var num = $('.clonedInput').length; // how many "duplicatable" input fields we currently have
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 () {
19
+ var num = $('.clonedInput').length; // how many "duplicatable" input fields we currently have
20
+ $('#event' + num).remove(); // remove the last element
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
+ });
32
+
33
+ jQuery(document).ready(function ($) {
34
+ $(".selectall").click(function () {
35
+ var checked_status = $(this).prop('checked');
36
+ var checkbox_name = $(this).attr('id');
37
+ $('input[name="' + checkbox_name + '[]"]').each(function () {
38
+ $(this).prop('checked', checked_status);
39
+ });
40
+ });
41
+ });
42
+
43
+ jQuery(document).ready(function ($) {
44
+ $( '.mc-tabs' ).each( function ( index ) {
45
+ var tabs = $('.mc-tabs .wptab').length;
46
+ var firstItem = window.location.hash;
47
+ if ( ! firstItem ) {
48
+ var firstItem = '#' + $( '.mc-tabs .wptab:nth-of-type(1)' ).attr( 'id' );
49
+ }
50
+ $('.mc-tabs .tabs a[href="' + firstItem + '"]').addClass('active').attr( 'aria-selected', 'true' );
51
+ if ( tabs > 1 ) {
52
+ $( '.mc-tabs .wptab' ).not( firstItem ).hide();
53
+ $( firstItem ).show();
54
+ $( '.mc-tabs .tabs a' ).on( 'click', function (e) {
55
+ e.preventDefault();
56
+ $('.mc-tabs .tabs a').removeClass('active').attr( 'aria-selected', 'false' );
57
+ $(this).addClass('active').attr( 'aria-selected', 'true' );
58
+ var target = $(this).attr('href');
59
+ window.location.hash = target;
60
+ $('.mc-tabs .wptab').not(target).hide();
61
+ $(target).show().attr('tabindex','-1').focus();
62
+ });
63
+ }
64
+ });
65
+
66
+ $( '#mc-generator .custom' ).hide();
67
+ $( '#mc-generator select[name=type]' ).on( 'change', function () {
68
+ var selected = $( this ).val();
69
+ if ( selected == 'custom' ) {
70
+ $( '#mc-generator .custom' ).show();
71
+ } else {
72
+ $( '#mc-generator .custom' ).hide();
73
+ }
74
+ });
75
+ });
76
+
77
+ var mediaPopup = '';
78
+ (function ($) {
79
+ "use strict";
80
+ $(function () {
81
+ /**
82
+ * Clears any existing Media Manager instances
83
+ *
84
+ * @author Gabe Shackle <gabe@hereswhatidid.com>
85
+ * @modified Joe Dolson <plugins@joedolson.com>
86
+ * @return void
87
+ */
88
+ function clear_existing() {
89
+ if (typeof mediaPopup !== 'string') {
90
+ mediaPopup.detach();
91
+ mediaPopup = '';
92
+ }
93
+ }
94
+
95
+ $('.mc-image-upload')
96
+ .on('click', '.textfield-field', function (e) {
97
+ e.preventDefault();
98
+ var $self = $(this),
99
+ $inpField = $self.parent('.field-holder').find('#e_image'),
100
+ $idField = $self.parent('.field-holder').find('#e_image_id'),
101
+ $displayField = $self.parent('.field-holder').find('.event_image');
102
+ clear_existing();
103
+ mediaPopup = wp.media({
104
+ multiple: false, // add, reset, false
105
+ title: 'Choose an Uploaded Document',
106
+ button: {
107
+ text: 'Select'
108
+ }
109
+ });
110
+
111
+ mediaPopup.on('select', function () {
112
+ var selection = mediaPopup.state().get('selection'),
113
+ id = '',
114
+ img = '',
115
+ height = '',
116
+ width = '';
117
+ if (selection) {
118
+ id = selection.first().attributes.id;
119
+ height = thumbHeight;
120
+ width = ( ( selection.first().attributes.width ) / ( selection.first().attributes.height ) ) * thumbHeight;
121
+ img = "<img src='" + selection.first().attributes.url + "' width='" + width + "' height='" + height + "' />";
122
+ $inpField.val(selection.first().attributes.url);
123
+ $idField.val(id);
124
+ $displayField.html(img);
125
+ }
126
+ });
127
+ mediaPopup.open();
128
+ })
129
+ });
130
+ })(jQuery);
131
+
132
+ jQuery(document).ready(function ($) {
133
+ $('#mc-sortable').sortable({
134
+ update: function (event, ui) {
135
+ $('#mc-sortable-update').html( 'Submit form to save changes' );
136
+ }
137
+ });
138
+ $('#mc-sortable .up').on('click', function (e) {
139
+ e.preventDefault();
140
+ $(this).parents('li').insertBefore($(this).parents('li').prev());
141
+ $( '#mc-sortable li' ).removeClass( 'mc-updated' );
142
+ $(this).parents('li').addClass( 'mc-updated' );
143
+ });
144
+ $('#mc-sortable .down').on('click', function (e) {
145
+ e.preventDefault();
146
+ $(this).parents('li').insertAfter($(this).parents('li').next());
147
+ $( '#mc-sortable li' ).removeClass( 'mc-updated' );
148
+ $(this).parents('li').addClass( 'mc-updated' );
149
+ });
150
+ });
js/jquery.checkall.js DELETED
@@ -1,9 +0,0 @@
1
- jQuery(document).ready(function ($) {
2
- $(".selectall").click(function () {
3
- var checked_status = $(this).prop('checked');
4
- var checkbox_name = $(this).attr('id');
5
- $('input[name="' + checkbox_name + '[]"]').each(function () {
6
- $(this).prop('checked', checked_status);
7
- });
8
- });
9
- });
 
 
 
 
 
 
 
 
 
js/jquery.public.js ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (function ($) {
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,
9
+ 'occur_id': value,
10
+ 'security': mc_data.security
11
+ };
12
+ $.post( ajaxurl, data, function (response) {
13
+ if ( response.success == 1 ) {
14
+ $( "button[data-value='"+value+"']" ).parent( 'li' ).hide();
15
+ }
16
+ $('.mc_response').text( response.response ).show( 300 );
17
+ }, "json" );
18
+ });
19
+ }(jQuery));
js/mc-ajax.js CHANGED
@@ -1,39 +1,26 @@
1
  (function ($) {
2
  'use strict';
3
  $(function () {
4
- $(document).on('click', '.calendar .my-calendar-nav a', function (e) {
 
 
5
  e.preventDefault();
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();
13
- });
14
- });
15
- $(document).on('click', '.list .my-calendar-nav a', function (e) {
16
- e.preventDefault();
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();
24
- $('#' + ref).attr('tabindex', '-1').focus();
25
- });
26
- });
27
- $(document).on('click', '.mini .my-calendar-nav a', function (e) {
28
- e.preventDefault();
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();
36
  });
37
- });
38
  });
39
- }(jQuery));
1
  (function ($) {
2
  'use strict';
3
  $(function () {
4
+ $(document).on('click', '.my-calendar-header a.mcajax', function (e) {
5
+ var calendar = $( this ).closest( '.mc-main' );
6
+ var ref = calendar.attr('id');
7
  e.preventDefault();
8
  var link = $(this).attr('href');
9
+ var height = $('.mc-main' ).height();
 
 
 
 
 
 
 
 
 
 
 
 
10
  $('#' + ref).html('<div class=\"mc-loading\"></div><div class=\"loading\" style=\"height:' + height + 'px\"><span class="screen-reader-text">Loading...</span></div>');
11
  $('#' + ref).load(link + ' #' + ref + ' > *', function () {
12
+ // functions to execute when new view loads.
13
+ // List view
14
  $('li.mc-events').children().not('.event-date').hide();
15
  $('li.current-day').children().show();
16
+ // Grid view
17
+ $('.calendar .calendar-event').children().not('.event-title').hide();
18
+ // Mini view
19
+ $('.mini .has-events').children().not('.trigger, .mc-date, .event-date').hide();
20
+ // All views
21
+ $( '#' + ref ).attr('tabindex', '-1').focus();
22
+ // Your Custom ajax load changes if needed
 
 
 
 
 
23
  });
24
+ });
25
  });
26
+ }(jQuery));
js/mc-list.js CHANGED
@@ -10,10 +10,10 @@
10
  $( this ).closest( '.mc-events' ).find( '.vevent' ).toggle();
11
  vevent.attr("tabindex", "-1").focus();
12
  var visible = $(this).closest( '.mc-events' ).find(".vevent").is(":visible");
13
- if (visible) {
14
- $(this).closest( '.mc-events' ).attr("aria-expanded", "true");
15
  } else {
16
- $(this).closest( '.mc-events' ).attr("aria-expanded", "false");
17
  }
18
  });
19
  });
10
  $( this ).closest( '.mc-events' ).find( '.vevent' ).toggle();
11
  vevent.attr("tabindex", "-1").focus();
12
  var visible = $(this).closest( '.mc-events' ).find(".vevent").is(":visible");
13
+ if ( visible ) {
14
+ $(this).attr("aria-expanded", "true");
15
  } else {
16
+ $(this).attr("aria-expanded", "false");
17
  }
18
  });
19
  });
js/mcjs.js ADDED
@@ -0,0 +1 @@
 
1
+ (function ($) { 'use strict'; $(function () { $( '.mc-main' ).removeClass( 'mcjs' ); });}(jQuery));
js/sortable.js DELETED
@@ -1,19 +0,0 @@
1
- jQuery(document).ready(function ($) {
2
- $('#mc-sortable').sortable({
3
- update: function (event, ui) {
4
- $('#mc-sortable-update').html( 'Submit form to save changes' );
5
- }
6
- });
7
- $('#mc-sortable .up').on('click', function (e) {
8
- e.preventDefault();
9
- $(this).parents('li').insertBefore($(this).parents('li').prev());
10
- $( '#mc-sortable li' ).removeClass( 'mc-updated' );
11
- $(this).parents('li').addClass( 'mc-updated' );
12
- });
13
- $('#mc-sortable .down').on('click', function (e) {
14
- e.preventDefault();
15
- $(this).parents('li').insertAfter($(this).parents('li').next());
16
- $( '#mc-sortable li' ).removeClass( 'mc-updated' );
17
- $(this).parents('li').addClass( 'mc-updated' );
18
- });
19
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/tabs.js DELETED
@@ -1,33 +0,0 @@
1
- jQuery(document).ready(function ($) {
2
- $( '.mc-tabs' ).each( function ( index ) {
3
- var tabs = $('.mc-tabs .wptab').length;
4
- var firstItem = window.location.hash;
5
- if ( ! firstItem ) {
6
- var firstItem = '#' + $( '.mc-tabs .wptab:nth-of-type(1)' ).attr( 'id' );
7
- }
8
- $('.mc-tabs .tabs a[href="' + firstItem + '"]').addClass('active').attr( 'aria-selected', 'true' );
9
- if ( tabs > 1 ) {
10
- $( '.mc-tabs .wptab' ).not( firstItem ).hide();
11
- $( firstItem ).show();
12
- $( '.mc-tabs .tabs a' ).on( 'click', function (e) {
13
- e.preventDefault();
14
- $('.mc-tabs .tabs a').removeClass('active').attr( 'aria-selected', 'false' );
15
- $(this).addClass('active').attr( 'aria-selected', 'true' );
16
- var target = $(this).attr('href');
17
- window.location.hash = target;
18
- $('.mc-tabs .wptab').not(target).hide();
19
- $(target).show().attr('tabindex','-1').focus();
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
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/upload.js DELETED
@@ -1,54 +0,0 @@
1
- var mediaPopup = '';
2
- (function ($) {
3
- "use strict";
4
- $(function () {
5
- /**
6
- * Clears any existing Media Manager instances
7
- *
8
- * @author Gabe Shackle <gabe@hereswhatidid.com>
9
- * @modified Joe Dolson <plugins@joedolson.com>
10
- * @return void
11
- */
12
- function clear_existing() {
13
- if (typeof mediaPopup !== 'string') {
14
- mediaPopup.detach();
15
- mediaPopup = '';
16
- }
17
- }
18
-
19
- $('.mc-image-upload')
20
- .on('click', '.textfield-field', function (e) {
21
- e.preventDefault();
22
- var $self = $(this),
23
- $inpField = $self.parent('.field-holder').find('#e_image'),
24
- $idField = $self.parent('.field-holder').find('#e_image_id'),
25
- $displayField = $self.parent('.field-holder').find('.event_image');
26
- clear_existing();
27
- mediaPopup = wp.media({
28
- multiple: false, // add, reset, false
29
- title: 'Choose an Uploaded Document',
30
- button: {
31
- text: 'Select'
32
- }
33
- });
34
-
35
- mediaPopup.on('select', function () {
36
- var selection = mediaPopup.state().get('selection'),
37
- id = '',
38
- img = '',
39
- height = '',
40
- width = '';
41
- if (selection) {
42
- id = selection.first().attributes.id;
43
- height = thumbHeight;
44
- width = ( ( selection.first().attributes.width ) / ( selection.first().attributes.height ) ) * thumbHeight;
45
- img = "<img src='" + selection.first().attributes.url + "' width='" + width + "' height='" + height + "' />";
46
- $inpField.val(selection.first().attributes.url);
47
- $idField.val(id);
48
- $displayField.html(img);
49
- }
50
- });
51
- mediaPopup.open();
52
- })
53
- });
54
- })(jQuery);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
my-calendar-api.php CHANGED
@@ -95,11 +95,12 @@ function mc_export_vcal() {
95
  }
96
 
97
  function my_calendar_send_vcal( $event_id ) {
 
98
  header( "Content-Type: text/calendar" );
99
  header( "Cache-control: private" );
100
  header( 'Pragma: private' );
101
  header( "Expires: Thu, 11 Nov 1977 05:40:00 GMT" ); // That's my birthday. :)
102
- header( "Content-Disposition: inline; filename=my-calendar.ics" );
103
  $output = preg_replace( "~(?<!\r)\n~", "\r\n", my_calendar_generate_vcal( $event_id ) );
104
 
105
  return urldecode( stripcslashes( $output ) );
@@ -275,6 +276,7 @@ function my_calendar_ical() {
275
 
276
  $from = apply_filters( 'mc_ical_download_from', $from, $p );
277
  $to = apply_filters( 'mc_ical_download_to', $to, $p );
 
278
  $atts = array(
279
  'category' => null,
280
  'ltype' => '',
@@ -309,9 +311,10 @@ PRODID:-//Accessible Web Design//My Calendar//http://www.joedolson.com//v' . $mc
309
  //$events = my_calendar_grab_events( $from, $to, $category, $ltype, $lvalue, $source, $author, $host );
310
  // my calendar grab events returns a flat array, but doesn't eliminate holiday cancellations; my-calendar_events eliminates those, but isn't a flat array.
311
  // rewrite array navigation so that this works.
312
- $events = my_calendar_events( $from, $to, $category, $ltype, $lvalue, $source, $author, $host );
 
313
  $events = mc_flatten_event_array( $events );
314
-
315
  if ( is_array( $events ) && ! empty( $events ) ) {
316
  foreach ( array_keys( $events ) as $key ) {
317
  $event =& $events[ $key ];
@@ -335,10 +338,11 @@ PRODID:-//Accessible Web Design//My Calendar//http://www.joedolson.com//v' . $mc
335
  $output .= "\nEND:VCALENDAR";
336
  $output = html_entity_decode( preg_replace( "~(?<!\r)\n~", "\r\n", $output ) );
337
  if ( ! ( isset( $_GET['sync'] ) && $_GET['sync'] == 'true' ) ) {
 
338
  header( "Content-Type: text/calendar; charset=" . get_bloginfo( 'charset' ) );
339
  header( "Pragma: no-cache" );
340
  header( "Expires: 0" );
341
- header( "Content-Disposition: inline; filename=my-calendar.ics" );
342
  }
343
  echo $output;
344
  }
95
  }
96
 
97
  function my_calendar_send_vcal( $event_id ) {
98
+ $sitename = sanitize_title( get_bloginfo( 'name' ) );
99
  header( "Content-Type: text/calendar" );
100
  header( "Cache-control: private" );
101
  header( 'Pragma: private' );
102
  header( "Expires: Thu, 11 Nov 1977 05:40:00 GMT" ); // That's my birthday. :)
103
+ header( "Content-Disposition: inline; filename=my-calendar-$sitename.ics" );
104
  $output = preg_replace( "~(?<!\r)\n~", "\r\n", my_calendar_generate_vcal( $event_id ) );
105
 
106
  return urldecode( stripcslashes( $output ) );
276
 
277
  $from = apply_filters( 'mc_ical_download_from', $from, $p );
278
  $to = apply_filters( 'mc_ical_download_to', $to, $p );
279
+ $category = ( isset( $_GET['mcat'] ) ) ? intval( $_GET['mcal'] ) : null;
280
  $atts = array(
281
  'category' => null,
282
  'ltype' => '',
311
  //$events = my_calendar_grab_events( $from, $to, $category, $ltype, $lvalue, $source, $author, $host );
312
  // my calendar grab events returns a flat array, but doesn't eliminate holiday cancellations; my-calendar_events eliminates those, but isn't a flat array.
313
  // rewrite array navigation so that this works.
314
+ $site = ( !isset( $_GET['site'] ) ) ? get_current_blog_id() : intval( $_GET['site'] );
315
+ $events = my_calendar_events( $from, $to, $category, $ltype, $lvalue, $source, $author, $host, '', $site );
316
  $events = mc_flatten_event_array( $events );
317
+
318
  if ( is_array( $events ) && ! empty( $events ) ) {
319
  foreach ( array_keys( $events ) as $key ) {
320
  $event =& $events[ $key ];
338
  $output .= "\nEND:VCALENDAR";
339
  $output = html_entity_decode( preg_replace( "~(?<!\r)\n~", "\r\n", $output ) );
340
  if ( ! ( isset( $_GET['sync'] ) && $_GET['sync'] == 'true' ) ) {
341
+ $sitename = sanitize_title( get_bloginfo( 'name' ) );
342
  header( "Content-Type: text/calendar; charset=" . get_bloginfo( 'charset' ) );
343
  header( "Pragma: no-cache" );
344
  header( "Expires: 0" );
345
+ header( "Content-Disposition: inline; filename=my-calendar-$sitename.ics" );
346
  }
347
  echo $output;
348
  }
my-calendar-behaviors.php CHANGED
@@ -41,9 +41,8 @@ function edit_my_calendar_behaviors() {
41
  $mc_ajaxjs = stripcslashes( get_option( 'mc_ajaxjs' ) );
42
  $mc_show_js = stripcslashes( get_option( 'mc_show_js' ) );
43
  // Now we render the form
44
-
45
  ?>
46
- <div class="wrap jd-my-calendar">
47
  <?php my_calendar_check_db(); ?>
48
  <h1><?php _e( 'My Calendar Scripting', 'my-calendar' ); ?></h1>
49
 
41
  $mc_ajaxjs = stripcslashes( get_option( 'mc_ajaxjs' ) );
42
  $mc_show_js = stripcslashes( get_option( 'mc_show_js' ) );
43
  // Now we render the form
 
44
  ?>
45
+ <div class="wrap my-calendar-admin">
46
  <?php my_calendar_check_db(); ?>
47
  <h1><?php _e( 'My Calendar Scripting', 'my-calendar' ); ?></h1>
48
 
my-calendar-categories.php CHANGED
@@ -86,7 +86,7 @@ function my_calendar_manage_categories() {
86
  $formats = array( '%s', '%s', '%s' );
87
 
88
  ?>
89
- <div class="wrap jd-my-calendar">
90
  <?php
91
  my_calendar_check_db();
92
  // We do some checking to see what we're doing
@@ -229,8 +229,12 @@ function mc_edit_category_form( $view = 'edit', $catID = '' ) {
229
  ?>
230
  <h1><?php _e( 'Add Category', 'my-calendar' ); ?></h1>
231
  <?php } else { ?>
232
- <h1><?php _e( 'Edit Category', 'my-calendar' ); ?></h1>
 
 
233
  <?php } ?>
 
 
234
 
235
  <div class="postbox-container jcd-wide">
236
  <div class="metabox-holder">
@@ -484,10 +488,54 @@ function mc_save_profile() {
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
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
  $formats = array( '%s', '%s', '%s' );
87
 
88
  ?>
89
+ <div class="wrap my-calendar-admin">
90
  <?php
91
  my_calendar_check_db();
92
  // We do some checking to see what we're doing
229
  ?>
230
  <h1><?php _e( 'Add Category', 'my-calendar' ); ?></h1>
231
  <?php } else { ?>
232
+ <h1 class="wp-heading-inline"><?php _e( 'Edit Category', 'my-calendar' ); ?></h1>
233
+ <a href="<?php echo admin_url( "admin.php?page=my-calendar-categories" ); ?>" class="page-title-action"><?php _e( 'Add New', 'my-calendar' ); ?></a>
234
+ <hr class="wp-header-end">
235
  <?php } ?>
236
+
237
+
238
 
239
  <div class="postbox-container jcd-wide">
240
  <div class="metabox-holder">
488
  } else {
489
  $edit_id = $user_ID;
490
  }
491
+ if ( current_user_can( 'manage_options' ) && isset( $_POST['mc_user_permissions'] ) ) {
492
  $mc_user_permission = $_POST['mc_user_permissions'];
493
  update_user_meta( $edit_id, 'mc_user_permissions', $mc_user_permission );
494
  }
495
 
496
  apply_filters( 'mc_save_user', $edit_id, $_POST );
497
+ }
498
+
499
+
500
+ function mc_inverse_color( $color ) {
501
+ $color = str_replace( '#', '', $color );
502
+ if ( strlen( $color ) != 6 ) {
503
+ return '#000000';
504
+ }
505
+ $rgb = '';
506
+ $total = 0;
507
+ $red = 0.299 * ( 255 - hexdec( substr( $color, 0, 2 ) ) );
508
+ $green = 0.587 * ( 255 - hexdec( substr( $color, 2, 2 ) ) );
509
+ $blue = 0.114 * ( 255 - hexdec( substr( $color, 4, 2 ) ) );
510
+ $luminance = 1 - ( ( $red + $green + $blue ) / 255 );
511
+ if ( $luminance < 0.5 ) {
512
+ return '#ffffff';
513
+ } else {
514
+ return '#000000';
515
+ }
516
+ }
517
+
518
+ function mc_shift_color( $color ) {
519
+ $color = str_replace( '#', '', $color );
520
+ $rgb = ''; // Empty variable
521
+ $percent = ( mc_inverse_color( $color ) == '#ffffff' ) ? - 20 : 20;
522
+ $per = $percent / 100 * 255; // Creates a percentage to work with. Change the middle figure to control colour temperature
523
+ if ( $per < 0 ) {
524
+ // DARKER
525
+ $per = abs( $per ); // Turns Neg Number to Pos Number
526
+ for ( $x = 0; $x < 3; $x ++ ) {
527
+ $c = hexdec( substr( $color, ( 2 * $x ), 2 ) ) - $per;
528
+ $c = ( $c < 0 ) ? 0 : dechex( $c );
529
+ $rgb .= ( strlen( $c ) < 2 ) ? '0' . $c : $c;
530
+ }
531
+ } else {
532
+ // LIGHTER
533
+ for ( $x = 0; $x < 3; $x ++ ) {
534
+ $c = hexdec( substr( $color, ( 2 * $x ), 2 ) ) + $per;
535
+ $c = ( $c > 255 ) ? 'ff' : dechex( $c );
536
+ $rgb .= ( strlen( $c ) < 2 ) ? '0' . $c : $c;
537
+ }
538
+ }
539
+
540
+ return '#' . $rgb;
541
+ }
my-calendar-core.php CHANGED
@@ -6,15 +6,6 @@ if ( ! defined( 'ABSPATH' ) ) {
6
  function my_calendar_add_feed() {
7
  add_feed( 'my-calendar-rss', 'my_calendar_rss' );
8
  add_feed( 'my-calendar-ics', 'my_calendar_ical' );
9
- //add_feed( 'my-calendar-print', 'my_calendar_print' );
10
- }
11
-
12
- add_action( 'template_redirect', 'my_calendar_print_view' );
13
- function my_calendar_print_view() {
14
- if ( isset( $_GET['cid'] ) && $_GET['cid'] == 'mc-print-view' ) {
15
- echo my_calendar_print();
16
- exit;
17
- }
18
  }
19
 
20
  if ( ! function_exists( 'is_ssl' ) ) {
@@ -79,49 +70,6 @@ function mc_plugin_action( $links, $file ) {
79
  return $links;
80
  }
81
 
82
- function mc_inverse_color( $color ) {
83
- $color = str_replace( '#', '', $color );
84
- if ( strlen( $color ) != 6 ) {
85
- return '#000000';
86
- }
87
- $rgb = '';
88
- $total = 0;
89
- $red = 0.299 * ( 255 - hexdec( substr( $color, 0, 2 ) ) );
90
- $green = 0.587 * ( 255 - hexdec( substr( $color, 2, 2 ) ) );
91
- $blue = 0.114 * ( 255 - hexdec( substr( $color, 4, 2 ) ) );
92
- $luminance = 1 - ( ( $red + $green + $blue ) / 255 );
93
- if ( $luminance < 0.5 ) {
94
- return '#ffffff';
95
- } else {
96
- return '#000000';
97
- }
98
- }
99
-
100
- function mc_shift_color( $color ) {
101
- $color = str_replace( '#', '', $color );
102
- $rgb = ''; // Empty variable
103
- $percent = ( mc_inverse_color( $color ) == '#ffffff' ) ? - 20 : 20;
104
- $per = $percent / 100 * 255; // Creates a percentage to work with. Change the middle figure to control colour temperature
105
- if ( $per < 0 ) {
106
- // DARKER
107
- $per = abs( $per ); // Turns Neg Number to Pos Number
108
- for ( $x = 0; $x < 3; $x ++ ) {
109
- $c = hexdec( substr( $color, ( 2 * $x ), 2 ) ) - $per;
110
- $c = ( $c < 0 ) ? 0 : dechex( $c );
111
- $rgb .= ( strlen( $c ) < 2 ) ? '0' . $c : $c;
112
- }
113
- } else {
114
- // LIGHTER
115
- for ( $x = 0; $x < 3; $x ++ ) {
116
- $c = hexdec( substr( $color, ( 2 * $x ), 2 ) ) + $per;
117
- $c = ( $c > 255 ) ? 'ff' : dechex( $c );
118
- $rgb .= ( strlen( $c ) < 2 ) ? '0' . $c : $c;
119
- }
120
- }
121
-
122
- return '#' . $rgb;
123
- }
124
-
125
  function mc_file_exists( $file ) {
126
  $dir = plugin_dir_path( __FILE__ );
127
  $base = basename( $dir );
@@ -180,7 +128,7 @@ function mc_register_styles() {
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
  }
186
  if ( get_option( 'mc_use_styles' ) != 'true' ) {
@@ -215,7 +163,7 @@ function my_calendar_wp_head() {
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 ) ? '#' : '';
220
  $color = $hex . $category->category_color;
221
  if ( $color != '#' ) {
@@ -244,7 +192,7 @@ function my_calendar_wp_head() {
244
  /* Styles by My Calendar - Joseph C Dolson http://www.joedolson.com/ */
245
  $category_styles
246
  .mc-event-visible {
247
- display: block!important;
248
  }
249
  -->
250
  </style>";
@@ -264,13 +212,11 @@ function mc_deal_with_deleted_user( $id ) {
264
  }
265
 
266
  // Function to add the javascript to the admin header
267
- function my_calendar_add_javascript() {
268
- wp_register_script( 'mc.tabs', plugins_url( 'js/tabs.js', __FILE__ ), array( 'jquery' ) );
269
- wp_register_script( 'mc.sortable', plugins_url( 'js/sortable.js', __FILE__ ), array(
270
- 'jquery',
271
- 'jquery-ui-sortable'
272
- ) );
273
- wp_register_script( 'mc-upload', plugins_url( 'js/upload.js', __FILE__ ), array( 'jquery' ) );
274
  if ( isset( $_GET['page'] ) && ( $_GET['page'] == 'my-calendar' || $_GET['page'] == 'my-calendar-groups' || $_GET['page'] == 'my-calendar-locations' ) ) {
275
  wp_enqueue_script( 'jquery-ui-autocomplete' );
276
  wp_enqueue_script( 'jquery-ui-accordion' );
@@ -303,27 +249,16 @@ function my_calendar_add_javascript() {
303
  wp_localize_script( 'pickadate.time', 'mc_time_format', apply_filters( 'mc_time_format', 'h:i A' ) );
304
  wp_localize_script( 'pickadate.time', 'mc_interval', apply_filters( 'mc_interval', '15' ) );
305
 
306
- wp_enqueue_script( 'jquery.addfields', plugins_url( 'js/jquery.addfields.js', __FILE__ ), array( 'jquery' ) );
307
  if ( function_exists( 'wp_enqueue_media' ) && ! did_action( 'wp_enqueue_media' ) ) {
308
  wp_enqueue_media();
309
  }
310
- wp_enqueue_script( 'mc-upload' );
311
- wp_localize_script( 'mc-upload', 'thumbHeight', get_option( 'thumbnail_size_h' ) );
312
- }
313
- if ( isset( $_GET['page'] ) && ( $_GET['page'] == 'my-calendar-config' || $_GET['page'] == 'my-calendar-help' ) ) {
314
- wp_enqueue_script( 'mc.tabs' );
315
- wp_enqueue_script( 'mc.sortable' );
316
- }
317
-
318
- if ( isset( $_GET['page'] ) && ( $_GET['page'] == 'my-calendar-groups' || $_GET['page'] == 'my-calendar-manage' ) ) {
319
- wp_enqueue_script( 'jquery.checkall', plugins_url( 'js/jquery.checkall.js', __FILE__ ), array( 'jquery' ) );
320
  }
321
  }
322
 
323
  function my_calendar_write_js() {
324
  if ( isset( $_GET['page'] ) && ( $_GET['page'] == 'my-calendar' || $_GET['page'] == 'my-calendar-locations' ) ) {
325
  ?>
326
- <script type="text/javascript">
327
  //<![CDATA[
328
  jQuery(document).ready(function ($) {
329
  $( '.mc-datepicker' ).pickadate({
@@ -372,6 +307,8 @@ function mc_plugin_update_message() {
372
 
373
  function mc_footer_js() {
374
  global $wp_query;
 
 
375
  if ( mc_is_mobile() && apply_filters( 'mc_disable_mobile_js', false ) ) {
376
  return;
377
  } else {
@@ -415,7 +352,7 @@ function mc_footer_js() {
415
  if ( get_option( 'mc_ajax_javascript' ) != 1 ) {
416
  $inner .= "\n" . $ajax_js;
417
  }
418
- $script = '
419
  <script type="text/javascript">
420
  (function( $ ) { \'use strict\';'.
421
  $inner
@@ -423,30 +360,39 @@ function mc_footer_js() {
423
  </script>';
424
  }
425
  $inner = apply_filters( 'mc_filter_javascript_footer', $inner );
426
- echo ( $inner != '' ) ? $script : '';
427
  } else {
428
  if ( @in_array( $id, $pages ) || get_option( 'mc_show_js' ) == '' ) {
429
  if ( get_option( 'mc_calendar_javascript' ) != 1 && get_option( 'mc_open_uri' ) != 'true' ) {
430
  $url = apply_filters( 'mc_grid_js', plugins_url( 'js/mc-grid.js', __FILE__ ) );
431
  wp_enqueue_script( 'mc.grid', $url, array( 'jquery' ) );
 
432
  }
433
  if ( get_option( 'mc_list_javascript' ) != 1 ) {
434
  $url = apply_filters( 'mc_list_js', plugins_url( 'js/mc-list.js', __FILE__ ) );
435
  wp_enqueue_script( 'mc.list', $url, array( 'jquery' ) );
 
436
  }
437
- if ( get_option( 'mc_mini_javascript' ) != 1 ) {
438
  $url = apply_filters( 'mc_mini_js', plugins_url( 'js/mc-mini.js', __FILE__ ) );
439
  wp_enqueue_script( 'mc.mini', $url, array( 'jquery' ) );
 
440
  }
441
  if ( get_option( 'mc_ajax_javascript' ) != 1 ) {
442
  $url = apply_filters( 'mc_ajax_js', plugins_url( 'js/mc-ajax.js', __FILE__ ) );
443
  wp_enqueue_script( 'mc.ajax', $url, array( 'jquery' ) );
 
 
 
 
444
  }
445
  }
446
  }
447
  }
448
  }
449
 
 
 
450
  function my_calendar_add_styles() {
451
  if ( isset( $_GET['page'] ) ) {
452
  $pages = array(
@@ -914,31 +860,6 @@ function mc_is_selected( $theFieldname, $theValue, $theArray = '' ) {
914
  return '';
915
  }
916
 
917
- function my_calendar_fouc() {
918
- global $wp_query;
919
- $array = array();
920
- if ( get_option( 'mc_calendar_javascript' ) != 1 || get_option( 'mc_list_javascript' ) != 1 || get_option( 'mc_mini_javascript' ) != 1 ) {
921
- $scripting = "\n<script type='text/javascript'>\n";
922
- $scripting .= " jQuery('html').addClass('mcjs');\n";
923
- $scripting .= " jQuery(document).ready( function($) { \$('html').removeClass('mcjs') } );\n";
924
- $scripting .= "</script>\n";
925
-
926
- if ( ! is_404() ) {
927
- if ( is_object( $wp_query ) && isset( $wp_query->post ) ) {
928
- $id = $wp_query->post->ID;
929
- } else {
930
- $id = '';
931
- }
932
- if ( get_option( 'mc_show_js' ) != '' ) {
933
- $array = explode( ",", get_option( 'mc_show_js' ) );
934
- }
935
- if ( @in_array( $id, $array ) || trim( get_option( 'mc_show_js' ) ) == '' ) {
936
- echo $scripting;
937
- }
938
- }
939
- }
940
- }
941
-
942
  function mc_month_comparison( $month ) {
943
  $current_month = date( "n", current_time( 'timestamp' ) );
944
  if ( isset( $_GET['yr'] ) && isset( $_GET['month'] ) ) {
@@ -1746,7 +1667,8 @@ function mc_delete_instances( $id ) {
1746
  */
1747
  function mc_increment_event( $id, $post = array(), $test = false ) {
1748
  global $wpdb;
1749
- $event = mc_get_event_core( $id );
 
1750
  $data = array();
1751
  $return = array();
1752
  if ( empty( $post ) ) {
@@ -1756,6 +1678,7 @@ function mc_increment_event( $id, $post = array(), $test = false ) {
1756
  $orig_begin = @$post['event_begin'] . ' ' . @$post['event_time'];
1757
  $orig_end = @$post['event_end'] . ' ' . @$post['event_endtime'];
1758
  }
 
1759
  $group_id = $event->event_group_id;
1760
  $format = array( '%d', '%s', '%s', '%d' );
1761
  $recurs = str_split( $event->event_recur, 1 );
6
  function my_calendar_add_feed() {
7
  add_feed( 'my-calendar-rss', 'my_calendar_rss' );
8
  add_feed( 'my-calendar-ics', 'my_calendar_ical' );
 
 
 
 
 
 
 
 
 
9
  }
10
 
11
  if ( ! function_exists( 'is_ssl' ) ) {
70
  return $links;
71
  }
72
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
  function mc_file_exists( $file ) {
74
  $dir = plugin_dir_path( __FILE__ );
75
  $base = basename( $dir );
128
  wp_enqueue_script( 'gmaps', "https://maps.googleapis.com/maps/api/js?key=$api_key" );
129
  wp_enqueue_script( 'gmap3', plugins_url( 'js/gmap3.min.js', __FILE__ ), array( 'jquery' ) );
130
  }
131
+ }
132
  }
133
  }
134
  if ( get_option( 'mc_use_styles' ) != 'true' ) {
163
  $category_styles = $inv = $type = $alt = '';
164
  $categories = $mcdb->get_results( "SELECT * FROM " . my_calendar_categories_table() . " ORDER BY category_id ASC" );
165
  foreach ( $categories as $category ) {
166
+ $class = mc_category_class( $category, 'mc_' );
167
  $hex = ( strpos( $category->category_color, '#' ) !== 0 ) ? '#' : '';
168
  $color = $hex . $category->category_color;
169
  if ( $color != '#' ) {
192
  /* Styles by My Calendar - Joseph C Dolson http://www.joedolson.com/ */
193
  $category_styles
194
  .mc-event-visible {
195
+ display: block!important;
196
  }
197
  -->
198
  </style>";
212
  }
213
 
214
  // Function to add the javascript to the admin header
215
+ function my_calendar_admin_js() {
216
+ if ( isset( $_GET['page'] ) && strpos( $_GET['page'], 'my-calendar' ) !== false ) {
217
+ wp_enqueue_script( 'mc.admin', plugins_url( 'js/jquery.admin.js', __FILE__ ), array( 'jquery', 'jquery-ui-sortable' ) );
218
+ wp_localize_script( 'mc.admin', 'thumbHeight', get_option( 'thumbnail_size_h' ) );
219
+ }
 
 
220
  if ( isset( $_GET['page'] ) && ( $_GET['page'] == 'my-calendar' || $_GET['page'] == 'my-calendar-groups' || $_GET['page'] == 'my-calendar-locations' ) ) {
221
  wp_enqueue_script( 'jquery-ui-autocomplete' );
222
  wp_enqueue_script( 'jquery-ui-accordion' );
249
  wp_localize_script( 'pickadate.time', 'mc_time_format', apply_filters( 'mc_time_format', 'h:i A' ) );
250
  wp_localize_script( 'pickadate.time', 'mc_interval', apply_filters( 'mc_interval', '15' ) );
251
 
 
252
  if ( function_exists( 'wp_enqueue_media' ) && ! did_action( 'wp_enqueue_media' ) ) {
253
  wp_enqueue_media();
254
  }
 
 
 
 
 
 
 
 
 
 
255
  }
256
  }
257
 
258
  function my_calendar_write_js() {
259
  if ( isset( $_GET['page'] ) && ( $_GET['page'] == 'my-calendar' || $_GET['page'] == 'my-calendar-locations' ) ) {
260
  ?>
261
+ <script>
262
  //<![CDATA[
263
  jQuery(document).ready(function ($) {
264
  $( '.mc-datepicker' ).pickadate({
307
 
308
  function mc_footer_js() {
309
  global $wp_query;
310
+ $mcjs = "<script>(function ($) { 'use strict'; $(function () { $( '.mc-main' ).removeClass( 'mcjs' ); });}(jQuery));</script>";
311
+
312
  if ( mc_is_mobile() && apply_filters( 'mc_disable_mobile_js', false ) ) {
313
  return;
314
  } else {
352
  if ( get_option( 'mc_ajax_javascript' ) != 1 ) {
353
  $inner .= "\n" . $ajax_js;
354
  }
355
+ $script = '
356
  <script type="text/javascript">
357
  (function( $ ) { \'use strict\';'.
358
  $inner
360
  </script>';
361
  }
362
  $inner = apply_filters( 'mc_filter_javascript_footer', $inner );
363
+ echo ( $inner != '' ) ? $script . $mcjs : '';
364
  } else {
365
  if ( @in_array( $id, $pages ) || get_option( 'mc_show_js' ) == '' ) {
366
  if ( get_option( 'mc_calendar_javascript' ) != 1 && get_option( 'mc_open_uri' ) != 'true' ) {
367
  $url = apply_filters( 'mc_grid_js', plugins_url( 'js/mc-grid.js', __FILE__ ) );
368
  wp_enqueue_script( 'mc.grid', $url, array( 'jquery' ) );
369
+ $enqueue_mcjs = true;
370
  }
371
  if ( get_option( 'mc_list_javascript' ) != 1 ) {
372
  $url = apply_filters( 'mc_list_js', plugins_url( 'js/mc-list.js', __FILE__ ) );
373
  wp_enqueue_script( 'mc.list', $url, array( 'jquery' ) );
374
+ $enqueue_mcjs = true;
375
  }
376
+ if ( get_option( 'mc_mini_javascript' ) != 1 && get_option( 'mc_open_day_uri' ) != 'true' ) {
377
  $url = apply_filters( 'mc_mini_js', plugins_url( 'js/mc-mini.js', __FILE__ ) );
378
  wp_enqueue_script( 'mc.mini', $url, array( 'jquery' ) );
379
+ $enqueue_mcjs = true;
380
  }
381
  if ( get_option( 'mc_ajax_javascript' ) != 1 ) {
382
  $url = apply_filters( 'mc_ajax_js', plugins_url( 'js/mc-ajax.js', __FILE__ ) );
383
  wp_enqueue_script( 'mc.ajax', $url, array( 'jquery' ) );
384
+ $enqueue_mcjs = true;
385
+ }
386
+ if ( $enqueue_mcjs ) {
387
+ wp_enqueue_script( 'mc.mcjs', plugins_url( 'js/mcjs.js', __FILE__ ), array( 'jquery' ) );
388
  }
389
  }
390
  }
391
  }
392
  }
393
 
394
+
395
+
396
  function my_calendar_add_styles() {
397
  if ( isset( $_GET['page'] ) ) {
398
  $pages = array(
860
  return '';
861
  }
862
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
863
  function mc_month_comparison( $month ) {
864
  $current_month = date( "n", current_time( 'timestamp' ) );
865
  if ( isset( $_GET['yr'] ) && isset( $_GET['month'] ) ) {
1667
  */
1668
  function mc_increment_event( $id, $post = array(), $test = false ) {
1669
  global $wpdb;
1670
+ $event = mc_get_event_core( $id, true );
1671
+
1672
  $data = array();
1673
  $return = array();
1674
  if ( empty( $post ) ) {
1678
  $orig_begin = @$post['event_begin'] . ' ' . @$post['event_time'];
1679
  $orig_end = @$post['event_end'] . ' ' . @$post['event_endtime'];
1680
  }
1681
+
1682
  $group_id = $event->event_group_id;
1683
  $format = array( '%d', '%s', '%s', '%d' );
1684
  $recurs = str_split( $event->event_recur, 1 );
my-calendar-event-manager.php CHANGED
@@ -74,11 +74,14 @@ function mc_event_post( $action, $data, $event_id ) {
74
  add_action( 'mc_update_event_post', 'mc_add_post_meta_data', 10, 4 );
75
  function mc_add_post_meta_data( $post_id, $post, $data, $event_id ) {
76
  // access features for the event
 
 
 
77
  update_post_meta( $post_id, '_mc_event_shortcode', $data['shortcode'] );
78
  update_post_meta( $post_id, '_mc_event_access', ( isset( $_POST['events_access'] ) ) ? $_POST['events_access'] : '' );
79
  update_post_meta( $post_id, '_mc_event_id', $event_id );
80
- update_post_meta( $post_id, '_mc_event_desc', $data['event_desc'] );
81
- update_post_meta( $post_id, '_mc_event_image', $data['event_image'] );
82
  update_post_meta( $post_id, '_event_time_label', ( isset( $_POST['event_time_label'] ) ) ? $_POST['event_time_label'] : '' );
83
  $location_id = ( isset( $post['location_preset'] ) ) ? (int) $post['location_preset'] : 0;
84
  if ( $location_id ) { // only change location ID if dropdown set.
@@ -96,8 +99,8 @@ function mc_create_event_post( $data, $event_id ) {
96
  $title = $data['event_title'];
97
  $template = apply_filters( 'mc_post_template', 'details', $term );
98
  $data['shortcode'] = "[my_calendar_event event='$event_id' template='$template' list='']";
99
- $description = $data['event_desc'];
100
- $excerpt = $data['event_short'];
101
  $location_id = ( isset( $_POST['location_preset'] ) ) ? (int) $_POST['location_preset'] : 0;
102
  $post_status = $privacy;
103
  $auth = $data['event_author'];
@@ -126,16 +129,6 @@ function mc_create_event_post( $data, $event_id ) {
126
  return $post_id;
127
  }
128
 
129
- function mc_get_event_post( $event_id ) {
130
- $event = mc_get_event_core( $event_id );
131
- if ( is_object( $event ) ) {
132
- if ( property_exists( $event, 'event_post' ) && get_post_status( $event->event_post ) ) {
133
- return $event->event_post;
134
- }
135
- }
136
- return false;
137
- }
138
-
139
  function mc_update_event( $field, $data, $event, $type = '%d' ) {
140
  global $wpdb;
141
  $field = sanitize_key( $field );
@@ -146,6 +139,8 @@ function mc_update_event( $field, $data, $event, $type = '%d' ) {
146
  }
147
 
148
  /**
 
 
149
  * @param $event_id
150
  * @param $post_id
151
  */
@@ -207,8 +202,7 @@ function manage_my_calendar() {
207
  } else {
208
  ?>
209
  <div class="error">
210
- <p><strong><?php _e( 'You do not have permission to approve that event.', 'my-calendar' ); ?></strong>
211
- </p>
212
  </div>
213
  <?php
214
  }
@@ -223,8 +217,7 @@ function manage_my_calendar() {
223
  } else {
224
  ?>
225
  <div class="error">
226
- <p><strong><?php _e( 'You do not have permission to reject that event.', 'my-calendar' ); ?></strong>
227
- </p>
228
  </div>
229
  <?php
230
  }
@@ -237,7 +230,7 @@ function manage_my_calendar() {
237
  }
238
  $events = $_POST['mass_edit'];
239
  $i = $total = 0;
240
- $deleted = $ids = array();
241
  foreach ( $events as $value ) {
242
  $value = (int) $value;
243
  $ea = "SELECT event_author FROM " . my_calendar_table() . " WHERE event_id = $value";
@@ -247,7 +240,6 @@ function manage_my_calendar() {
247
  $delete_occurrences = "DELETE FROM " . my_calendar_event_table() . " WHERE occur_event_id = $value";
248
  $mcdb->query( $delete_occurrences );
249
  $ids[] = (int) $value;
250
- $deleted[] = $value;
251
  $i ++;
252
  }
253
  }
@@ -255,9 +247,8 @@ function manage_my_calendar() {
255
  $sql = 'DELETE FROM ' . my_calendar_table() . " WHERE event_id IN ($statement)";
256
  $result = $mcdb->query( $sql );
257
  if ( $result !== 0 && $result !== false ) {
258
- mc_delete_cache();
259
- // argument: array of event IDs
260
- do_action( 'mc_mass_delete_events', $deleted );
261
  $message = "<div class='updated'><p>" . sprintf( __( '%1$d events deleted successfully out of %2$d selected', 'my-calendar' ), $i, $total ) . "</p></div>";
262
  } else {
263
  $message = "<div class='error'><p><strong>" . __( 'Error', 'my-calendar' ) . ":</strong>" . __( 'Your events have not been deleted. Please investigate.', 'my-calendar' ) . "</p></div>";
@@ -278,7 +269,7 @@ function manage_my_calendar() {
278
  $value = (int) $value;
279
  $total = count( $events );
280
  if ( current_user_can( 'mc_approve_events' ) ) {
281
- $sql .= (int) $value . ',';
282
  $approved[] = $value;
283
  $i ++;
284
  }
@@ -290,7 +281,6 @@ function manage_my_calendar() {
290
  $message = "<div class='error'><p><strong>" . __( 'Error', 'my-calendar' ) . ":</strong>" . __( 'Your events have not been approved. Please investigate.', 'my-calendar' ) . "</p></div>";
291
  } else {
292
  mc_delete_cache();
293
- // argument: array of event IDs
294
  do_action( 'mc_mass_approve_events', $approved );
295
  $message = "<div class='updated'><p>" . sprintf( __( '%1$d events approved successfully out of %2$d selected', 'my-calendar' ), $i, $total ) . "</p></div>";
296
  }
@@ -308,7 +298,7 @@ function manage_my_calendar() {
308
  $archived = array();
309
  foreach ( $events as $value ) {
310
  $total = count( $events );
311
- $sql .= (int) $value . ',';
312
  $archived[] = $value;
313
  $i ++;
314
  }
@@ -319,7 +309,6 @@ function manage_my_calendar() {
319
  $message = "<div class='error'><p><strong>" . __( 'Error', 'my-calendar' ) . ":</strong>" . __( 'Could not archive those events.', 'my-calendar' ) . "</p></div>";
320
  } else {
321
  mc_delete_cache();
322
- // argument: array of event IDs
323
  do_action( 'mc_mass_archive_events', $archived );
324
  $message = "<div class='updated'><p>" . sprintf( __( '%1$d events archived successfully out of %2$d selected.', 'my-calendar' ), $i, $total ) . ' ' . __( 'Archived events remain on your calendar, but are removed from the event manager.', 'my-calendar' ) . "</p></div>";
325
  }
@@ -336,8 +325,8 @@ function manage_my_calendar() {
336
  $i = $total = 0;
337
  $archived = array();
338
  foreach ( $events as $value ) {
339
- $total = count( $events );
340
- $sql .= (int) $value . ',';
341
  $archived[] = $value;
342
  $i ++;
343
  }
@@ -348,16 +337,17 @@ function manage_my_calendar() {
348
  $message = "<div class='error'><p><strong>" . __( 'Error', 'my-calendar' ) . ":</strong>" . __( 'Could not undo the archive status on those events.', 'my-calendar' ) . "</p></div>";
349
  } else {
350
  mc_delete_cache();
351
- // argument: array of event IDs
352
  do_action( 'mc_mass_undo_archive_events', $archived );
353
  $message = "<div class='updated'><p>" . sprintf( __( '%1$d events removed from archive successfully out of %2$d selected.', 'my-calendar' ), $i, $total ) . "</p></div>";
354
  }
355
  echo $message;
356
  }
357
  ?>
358
- <div class='wrap jd-my-calendar'>
359
- <h1 id='mc-manage'><?php _e( 'Manage Events', 'my-calendar' ); ?></h1>
360
-
 
 
361
  <div class="postbox-container jcd-wide">
362
  <div class="metabox-holder">
363
  <div class="ui-sortable meta-box-sortables">
@@ -385,7 +375,7 @@ function edit_my_calendar() {
385
  if ( function_exists( 'check_calendar' ) ) {
386
  echo "<div id='message'class='updated'>";
387
  echo "<p>";
388
- _e( 'My Calendar has identified that you have the Calendar plugin by Kieran O\'Shea installed. You can import those events and categories into the My Calendar database. Would you like to import these events?', 'my-calendar' );
389
  echo "</p>";
390
  ?>
391
  <form method="post" action="<?php echo admin_url( 'admin.php?page=my-calendar-config' ); ?>">
@@ -400,7 +390,7 @@ function edit_my_calendar() {
400
  </form>
401
  <?php
402
  echo "<p>";
403
- _e( 'Although it is possible that this import could fail to import your events correctly, it should not have any impact on your existing Calendar database. If you encounter any problems, <a href="http://www.joedolson.com/contact.php">please contact me</a>!', 'my-calendar' );
404
  echo "</p>";
405
  echo "</div>";
406
  }
@@ -448,7 +438,7 @@ function edit_my_calendar() {
448
 
449
  ?>
450
 
451
- <div class="wrap jd-my-calendar">
452
  <?php my_calendar_check_db();
453
  if ( get_site_option( 'mc_multisite' ) == 2 ) {
454
  if ( get_option( 'mc_current_table' ) == 0 ) {
@@ -533,10 +523,11 @@ function my_calendar_save( $action, $output, $event_id = false ) {
533
  '%f',
534
  '%f'
535
  );
 
536
  if ( ( $action == 'add' || $action == 'copy' ) && $proceed == true ) {
537
  $add = $output[2]; // add format here
538
  $add = apply_filters( 'mc_before_save_insert', $add );
539
- // this db write takes most of the processing time for this process.
540
  $result = $mcdb->insert( my_calendar_table(), $add, $formats );
541
  $event_id = $mcdb->insert_id;
542
  mc_increment_event( $event_id );
@@ -555,13 +546,12 @@ function my_calendar_save( $action, $output, $event_id = false ) {
555
  if ( $add['event_approved'] == 0 ) {
556
  $message = "<div class='updated notice'><p>" . __( 'Event saved. An administrator will review and approve your event.', 'my-calendar' ) . "</p></div>";
557
  } else {
 
558
  if ( function_exists( 'jd_doTwitterAPIPost' ) && isset( $_POST['mc_twitter'] ) && trim( $_POST['mc_twitter'] ) != '' ) {
559
  jd_doTwitterAPIPost( stripslashes( $_POST['mc_twitter'] ) );
560
  }
561
  if ( get_option( 'mc_uri' ) != '' ) {
562
  $event_ids = mc_get_occurrences( $event_id );
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 {
@@ -595,7 +585,8 @@ function my_calendar_save( $action, $output, $event_id = false ) {
595
  ( $endtime != $_POST['prev_event_endtime'] && ( $_POST['prev_event_endtime'] != '' && $endtime != '23:59:59' ) ) )
596
  ? true : false;
597
  if ( isset( $_POST['event_instance'] ) ) {
598
- $is_changed = mc_compare( $update, $event_id );// compares the information sent to the information saved for a given event.
 
599
  $event_instance = (int) $_POST['event_instance'];
600
  if ( $is_changed ) {
601
  // if changed, create new event, match group id, update instance to reflect event connection, same group id.
@@ -625,12 +616,12 @@ function my_calendar_save( $action, $output, $event_id = false ) {
625
  }
626
  }
627
  } else {
628
- $result = $mcdb->update(
629
  my_calendar_table(),
630
  $update,
631
  array( 'event_id' => $event_id ),
632
  $formats,
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
@@ -663,13 +654,8 @@ function my_calendar_save( $action, $output, $event_id = false ) {
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;
@@ -882,15 +868,17 @@ function mc_show_block( $field, $has_data, $data, $echo = true, $default = '' )
882
  }
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;
@@ -959,13 +947,13 @@ function mc_show_block( $field, $has_data, $data, $echo = true, $default = '' )
959
  <legend class="screen-reader-text">' . __( 'Recurring Events', 'my-calendar' ) . '</legend>
960
  <p>
961
  <label for="e_repeats">' . __( 'Repeats', 'my-calendar' ) . ' <input type="text" name="event_repeats" aria-labelledby="e_repeats_label" id="e_repeats" size="1" value="' . esc_attr( $repeats ) . '" /> <span id="e_repeats_label">' . __( 'times', 'my-calendar' ) . '</span>, </label>
962
- <label for="e_every">' . __( 'every', 'my-calendar' ) . '</label> <input type="number" name="event_every" id="e_every" size="1" min="1" max="99" maxlength="1" value="' . esc_attr( $every ) . '" />
963
  <label for="e_recur" class="screen-reader-text">' . __( 'Units', 'my-calendar' ) . '</label>
964
  <select name="event_recur" id="e_recur">
965
  ' . mc_recur_options( $recur ) . '
966
  </select><br />
967
  ' . __( 'Your entry is the number of events after the first occurrence of the event: a recurrence of <em>2</em> means the event will happen three times.', 'my-calendar' ) . '
968
- <div class="mc_recur_notice" aria-live="polite"><p><span class="dashicons dashicons-no"></span>' . __( 'Month by day events currently only support monthly recurrances.', 'my-calendar' ) . '</p></div>
969
  </p>
970
  </fieldset>
971
  </div>
@@ -1072,7 +1060,7 @@ function mc_test_occurrence_overlap( $data, $return = false ) {
1072
  if ( !$single_recur && !$start_end ) {
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' );
@@ -1099,7 +1087,6 @@ function mc_form_fields( $data, $mode, $event_id ) {
1099
  $data = mc_get_event_core( $event_id );
1100
  }
1101
  ?>
1102
-
1103
  <div class="postbox-container jcd-wide">
1104
  <div class="metabox-holder">
1105
  <?php if ( $mode == 'add' || $mode == 'copy' ) {
@@ -1186,7 +1173,6 @@ function mc_form_fields( $data, $mode, $event_id ) {
1186
  $event = mc_get_event( $instance );
1187
  $date = date_i18n( get_option( 'mc_date_format' ), strtotime( $event->occur_begin ) );
1188
  $message = __( "You are editing the <strong>$date</strong> instance of this event. Other instances of this event will not be changed.", 'my-calendar' );
1189
- //echo "<div><input type='hidden' name='event_instance' value='$instance' /></div>";
1190
  echo "<div class='message updated'><p>$message</p></div>";
1191
  } else if ( isset( $_GET['date'] ) && empty( $_GET['date'] ) ) {
1192
  echo "<div class='message updated'><p>" . __( 'There was an error acquiring information about this event instance. The ID for this event instance was not provided. <strong>You are editing this entire recurrence set.</strong>', 'my-calendar' ) . "</p></div>";
@@ -1455,10 +1441,17 @@ if ( mc_show_edit_block( 'event_specials' ) ) {
1455
  </div>
1456
  </div><?php
1457
  } else {
 
 
 
 
 
 
 
1458
  ?>
1459
  <div>
1460
- <input type="hidden" name="event_holiday" value="true" <?php checked( get_option( 'mc_skip_holidays' ), 'true' ); ?> />
1461
- <input type="hidden" name="event_fifth_week" value="true" <?php checked( get_option( 'mc_no_fifth_week' ), 'true' ); ?> />
1462
  </div><?php
1463
  } ?>
1464
  <p>
@@ -1577,10 +1570,10 @@ function mc_list_events() {
1577
  $sortbyvalue = "event_begin $sortbydirection, event_time";
1578
  }
1579
  }
1580
- $sorting = ( $sortbydirection == 'DESC' ) ? "&amp;order=ASC" : '&amp;order=DESC';
1581
- $allow_filters = true;
1582
- $status = ( isset( $_GET['limit'] ) ) ? $_GET['limit'] : 'all';
1583
- $restrict = ( isset( $_GET['restrict'] ) ) ? $_GET['restrict'] : 'all';
1584
  switch ( $status ) {
1585
  case 'all':
1586
  $limit = '';
@@ -1634,7 +1627,7 @@ function mc_list_events() {
1634
  if ( $filter == '' || ! $allow_filters ) {
1635
  $filtered = "";
1636
  } else {
1637
- $filtered = "<span class='dashicons dashicons-no'></span><a href='" . admin_url( 'admin.php?page=my-calendar-manage' ) . "'>" . __( 'Clear filters', 'my-calendar' ) . "</a>";
1638
  }
1639
  $current = empty( $_GET['paged'] ) ? 1 : intval( $_GET['paged'] );
1640
  $user = get_current_user_id();
@@ -1655,7 +1648,14 @@ function mc_list_events() {
1655
  $limit .= mc_prepare_search_query( $query );
1656
  }
1657
  $limit .= ( $restrict != 'archived' ) ? " AND event_status = 1" : ' AND event_status = 0';
1658
- $events = $mcdb->get_results( "SELECT SQL_CALC_FOUND_ROWS * FROM " . my_calendar_table() . " $limit ORDER BY $sortbyvalue $sortbydirection LIMIT " . ( ( $current - 1 ) * $items_per_page ) . ", " . $items_per_page );
 
 
 
 
 
 
 
1659
  $found_rows = $wpdb->get_col( "SELECT FOUND_ROWS();" );
1660
  $items = $found_rows[0];
1661
  if ( ( function_exists( 'akismet_http_post' ) || function_exists( 'bs_checker' ) ) && $allow_filters ) {
@@ -1770,7 +1770,11 @@ function mc_list_events() {
1770
  $categories = $mcdb->get_results( $sql );
1771
 
1772
  foreach ( array_keys( $events ) as $key ) {
1773
- $event =& $events[ $key ];
 
 
 
 
1774
  $class = ( $class == 'alternate' ) ? 'even' : 'alternate';
1775
  $pending = ( $event->event_approved == 0 ) ? 'pending' : '';
1776
  $author = ( $event->event_author != 0 ) ? get_userdata( $event->event_author ) : 'Public Submitter';
@@ -1783,12 +1787,13 @@ function mc_list_events() {
1783
  $spam = '';
1784
  $spam_label = '';
1785
  }
1786
- $edit_url = admin_url( "admin.php?page=my-calendar&amp;mode=edit&amp;event_id=$event->event_id" );
1787
- $copy_url = admin_url( "admin.php?page=my-calendar&amp;mode=copy&amp;event_id=$event->event_id" );
1788
- $group_url = admin_url( "admin.php?page=my-calendar-groups&amp;mode=edit&amp;event_id=$event->event_id&amp;group_id=$event->event_group_id" );
 
1789
  $delete_url = admin_url( "admin.php?page=my-calendar-manage&amp;mode=delete&amp;event_id=$event->event_id" );
1790
- $check = mc_test_occurrence_overlap( $event, true );
1791
- $problem = ( $check != '' ) ? 'problem' : '';
1792
  if ( current_user_can( 'mc_manage_events' ) || current_user_can( 'mc_approve_events' ) || mc_can_edit_event( $event->event_id ) ) {
1793
  ?>
1794
  <tr class="<?php echo "$class $spam $pending $problem"; ?>">
@@ -1796,7 +1801,7 @@ function mc_list_events() {
1796
  <input type="checkbox" value="<?php echo $event->event_id; ?>" name="mass_edit[]" id="mc<?php echo $event->event_id; ?>" <?php echo ( $event->event_flagged == 1 ) ? 'checked="checked"' : ''; ?> />
1797
  <label for="mc<?php echo $event->event_id; ?>"><?php echo $event->event_id; ?></label>
1798
  </th>
1799
- <td title="<?php echo esc_attr( substr( strip_tags( stripslashes( $event->event_desc ) ), 0, 240 ) ); ?>">
1800
  <strong><?php if ( mc_can_edit_event( $event->event_id ) ) { ?>
1801
  <a href="<?php echo $edit_url; ?>" class='edit'>
1802
  <?php } ?>
@@ -1809,10 +1814,11 @@ function mc_list_events() {
1809
  } ?></strong>
1810
 
1811
  <div class='row-actions' style="visibility:visible;">
1812
- <a href="<?php echo $copy_url; ?>"
1813
- class='copy'><?php _e( 'Copy', 'my-calendar' ); ?></a> |
 
 
1814
  <?php if ( mc_can_edit_event( $event->event_id ) ) { ?>
1815
- <a href="<?php echo $edit_url; ?>" class='edit'><?php _e( 'Edit', 'my-calendar' ); ?></a>
1816
  <?php if ( mc_event_is_grouped( $event->event_group_id ) ) { ?>
1817
  | <a href="<?php echo $group_url; ?>" class='edit group'><?php _e( 'Edit Group', 'my-calendar' ); ?></a>
1818
  <?php } ?>
@@ -1905,11 +1911,16 @@ function mc_list_events() {
1905
  ?>
1906
  </div>
1907
  </td>
1908
- <td><a class='mc_filter' href="<?php $auth = ( is_object( $author ) ) ? $author->ID : 0;
1909
- echo admin_url( "admin.php?page=my-calendar-manage&amp;filter=$auth&amp;restrict=author" ); ?>"
1910
- title="<?php _e( 'Filter by author', 'my-calendar' ); ?>"><span
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
@@ -1918,14 +1929,13 @@ function mc_list_events() {
1918
  $color = strip_tags( mc_get_category_detail( $event->event_category, 'category_color' ) );
1919
  ?>
1920
  <td>
1921
- <div class="category-color"
1922
- style="background-color:<?php echo ( strpos( $color, '#' ) !== 0 ) ? '#' : ''; echo $color; ?>;">
1923
- </div>
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
  }
@@ -1933,44 +1943,38 @@ function mc_list_events() {
1933
  ?>
1934
  </table>
1935
  <p>
1936
- <input type="submit" class="button-secondary delete" name="mass_delete"
1937
- value="<?php _e( 'Delete events', 'my-calendar' ); ?>"/>
1938
  <?php if ( current_user_can( 'mc_approve_events' ) ) { ?>
1939
- <input type="submit" class="button-secondary mc-approve" name="mass_approve"
1940
- value="<?php _e( 'Approve events', 'my-calendar' ); ?>"/>
1941
- <?php } ?>
1942
- <?php if ( ! ( isset( $_GET['restrict'] ) && $_GET['restrict'] == 'archived' ) ) { ?>
1943
- <input type="submit" class="button-secondary mc-archive" name="mass_archive"
1944
- value="<?php _e( 'Archive events', 'my-calendar' ); ?>"/>
1945
  <?php } ?>
1946
  </p>
1947
 
1948
  <p>
1949
  <?php if ( ! ( isset( $_GET['restrict'] ) && $_GET['restrict'] == 'archived' ) ) { ?>
1950
- <a class='mc_filter'
1951
- href='<?php echo admin_url( "admin.php?page=my-calendar-manage&amp;restrict=archived" ); ?>'><?php _e( 'View Archived Events', 'my-calendar' ); ?></a>
1952
  <?php } else { ?>
1953
- <a class='mc_filter'
1954
- href='<?php echo admin_url( "admin.php?page=my-calendar-manage" ); ?>'><?php _e( 'Return to Manage Events', 'my-calendar' ); ?></a>
1955
  <?php } ?>
1956
  </p>
1957
  </form>
1958
- <?php
1959
- } else {
1960
- ?>
1961
  <p class='mc-none'><?php _e( "There are no events in the database meeting your current criteria.", 'my-calendar' ) ?></p><?php
1962
  }
1963
  }
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();
1971
  $errors = '';
1972
  $every = $recur = $events_access = $begin = $end = $short = $time = $endtime = $event_label = $event_street = $event_street2 = $event_city = $event_state = $event_postcode = $event_region = $event_country = $event_url = $event_image = $event_phone = $event_phone2 = $event_access = $event_tickets = $event_registration = $event_author = $category = $expires = $event_zoom = $event_open = $event_group = $approved = $host = $event_fifth_week = $event_holiday = $event_group_id = $event_span = $event_hide_end = $event_longitude = $event_latitude = '';
1973
-
1974
  if ( get_magic_quotes_gpc() ) {
1975
  $post = array_map( 'stripslashes_deep', $post );
1976
  }
@@ -2152,12 +2156,12 @@ function mc_check_data( $action, $post, $i ) {
2152
  } else {
2153
  $errors .= "<div class='error'><p><strong>" . __( 'Error', 'my-calendar' ) . ":</strong> " . __( 'The time field must either be blank or be entered in the format hh:mm am/pm', 'my-calendar' ) . "</p></div>";
2154
  }
2155
- // We check for a valid end time, or an empty one
2156
  if ( preg_match( $time_format_one, $endtime ) || preg_match( $time_format_two, $endtime ) || $endtime == '' ) {
2157
  } else {
2158
  $errors .= "<div class='error'><p><strong>" . __( 'Error', 'my-calendar' ) . ":</strong> " . __( 'The end time field must either be blank or be entered in the format hh:mm am/pm', 'my-calendar' ) . "</p></div>";
2159
  }
2160
- // We check to make sure the URL is acceptable (blank or starting with http://)
2161
  if ( ! ( $event_link == '' || preg_match( '/^(http)(s?)(:)\/\//', $event_link ) ) ) {
2162
  $event_link = "http://" . $event_link;
2163
  }
@@ -2182,7 +2186,7 @@ function mc_check_data( $action, $post, $i ) {
2182
  }
2183
  }
2184
  $spam = mc_spam( $event_link, $desc, $post );
2185
- // the likelihood that something will be both flagged as spam and have a zero start time
2186
  // and yet be legitimate is crazy minimal. Just kill it.
2187
  if ( $spam == 1 && $begin == '1970-01-01' ) {
2188
  die;
@@ -2240,6 +2244,7 @@ function mc_check_data( $action, $post, $i ) {
2240
  'event_longitude' => $event_longitude,
2241
  'event_latitude' => $event_latitude
2242
  );
 
2243
  $submit = array_map( 'mc_kses_post', $submit );
2244
 
2245
  } else {
@@ -2302,9 +2307,9 @@ function mcs_check_conflicts( $begin, $time, $end, $endtime, $event_label ) {
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')";
2310
  $results = $wpdb->get_results( $event_query );
@@ -2410,13 +2415,13 @@ function mc_instance_list( $id, $occur = false, $template = '<h3>{title}</h3>{de
2410
  foreach ( $results as $result ) {
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 = '';
@@ -2430,7 +2435,6 @@ function mc_instance_list( $id, $occur = false, $template = '<h3>{title}</h3>{de
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, '' );
2435
  }
2436
  }
@@ -2439,8 +2443,12 @@ function mc_instance_list( $id, $occur = false, $template = '<h3>{title}</h3>{de
2439
  $details = ( $template != '' ) ? jd_draw_template( $array, $template ) : '';
2440
  }
2441
  $output .= $item;
 
 
 
2442
  }
2443
  $output = $details . $before . $output . $after;
 
2444
  }
2445
 
2446
  return ( get_option( 'mc_process_shortcodes' ) == 'true' ) ? do_shortcode( $output ) : $output;
@@ -2484,18 +2492,11 @@ function mc_standard_datetime_input( $form, $has_data, $data, $instance, $contex
2484
  $event_begin = date( "Y-m-d" );
2485
  $event_end = $starttime = $endtime = '';
2486
  }
2487
- $allday = $hide = '';
2488
- if ( $has_data && ( mc_is_all_day( $data ) ) ) {
2489
- $allday = " checked=\"checked\"";
2490
- }
2491
- if ( $has_data && $data->event_hide_end == '1' ) {
2492
- $hide = " checked=\"checked\"";
2493
- }
2494
- if ( $has_data ) {
2495
- $allday_label = mc_notime_label( $data );
2496
- } else {
2497
- $allday_label = get_option( 'mc_notime_text' );
2498
- }
2499
  $form .= '<p>
2500
  <label for="e_begin" id="eblabel">' . __( 'Date (YYYY-MM-DD)', 'my-calendar' ) . '</label> <input type="text" id="e_begin" class="mc-datepicker" name="event_begin[]" size="10" value="" data-value="' . esc_attr( $event_begin ) . '" />
2501
  <label for="e_time">' . __( 'From', 'my-calendar' ) . '</label>
@@ -2580,5 +2581,7 @@ function mc_post_update_event( $id ) {
2580
  $post = get_post( $id );
2581
  $featured_image = wp_get_attachment_url( get_post_thumbnail_id( $post->ID ) );
2582
  $event_id = get_post_meta( $post->ID, '_mc_event_id', true );
2583
- mc_update_data( $event_id, 'event_image', $featured_image, '%s' );
 
 
2584
  }
74
  add_action( 'mc_update_event_post', 'mc_add_post_meta_data', 10, 4 );
75
  function mc_add_post_meta_data( $post_id, $post, $data, $event_id ) {
76
  // access features for the event
77
+ $description = isset( $data['event_desc'] ) ? $data['event_desc'] : '';
78
+ $image = isset( $data['event_image'] ) ? esc_url_raw( $data['event_image'] ) : '';
79
+
80
  update_post_meta( $post_id, '_mc_event_shortcode', $data['shortcode'] );
81
  update_post_meta( $post_id, '_mc_event_access', ( isset( $_POST['events_access'] ) ) ? $_POST['events_access'] : '' );
82
  update_post_meta( $post_id, '_mc_event_id', $event_id );
83
+ update_post_meta( $post_id, '_mc_event_desc', $description );
84
+ update_post_meta( $post_id, '_mc_event_image', $image );
85
  update_post_meta( $post_id, '_event_time_label', ( isset( $_POST['event_time_label'] ) ) ? $_POST['event_time_label'] : '' );
86
  $location_id = ( isset( $post['location_preset'] ) ) ? (int) $post['location_preset'] : 0;
87
  if ( $location_id ) { // only change location ID if dropdown set.
99
  $title = $data['event_title'];
100
  $template = apply_filters( 'mc_post_template', 'details', $term );
101
  $data['shortcode'] = "[my_calendar_event event='$event_id' template='$template' list='']";
102
+ $description = isset( $data['event_desc'] ) ? $data['event_desc'] : '';
103
+ $excerpt = isset( $data['event_short'] ) ? $data['event_short'] : '';
104
  $location_id = ( isset( $_POST['location_preset'] ) ) ? (int) $_POST['location_preset'] : 0;
105
  $post_status = $privacy;
106
  $auth = $data['event_author'];
129
  return $post_id;
130
  }
131
 
 
 
 
 
 
 
 
 
 
 
132
  function mc_update_event( $field, $data, $event, $type = '%d' ) {
133
  global $wpdb;
134
  $field = sanitize_key( $field );
139
  }
140
 
141
  /**
142
+ * Delete custom post type associated with event
143
+ *
144
  * @param $event_id
145
  * @param $post_id
146
  */
202
  } else {
203
  ?>
204
  <div class="error">
205
+ <p><strong><?php _e( 'You do not have permission to approve that event.', 'my-calendar' ); ?></strong></p>
 
206
  </div>
207
  <?php
208
  }
217
  } else {
218
  ?>
219
  <div class="error">
220
+ <p><strong><?php _e( 'You do not have permission to reject that event.', 'my-calendar' ); ?></strong></p>
 
221
  </div>
222
  <?php
223
  }
230
  }
231
  $events = $_POST['mass_edit'];
232
  $i = $total = 0;
233
+ $ids = array();
234
  foreach ( $events as $value ) {
235
  $value = (int) $value;
236
  $ea = "SELECT event_author FROM " . my_calendar_table() . " WHERE event_id = $value";
240
  $delete_occurrences = "DELETE FROM " . my_calendar_event_table() . " WHERE occur_event_id = $value";
241
  $mcdb->query( $delete_occurrences );
242
  $ids[] = (int) $value;
 
243
  $i ++;
244
  }
245
  }
247
  $sql = 'DELETE FROM ' . my_calendar_table() . " WHERE event_id IN ($statement)";
248
  $result = $mcdb->query( $sql );
249
  if ( $result !== 0 && $result !== false ) {
250
+ mc_delete_cache();
251
+ do_action( 'mc_mass_delete_events', $ids );
 
252
  $message = "<div class='updated'><p>" . sprintf( __( '%1$d events deleted successfully out of %2$d selected', 'my-calendar' ), $i, $total ) . "</p></div>";
253
  } else {
254
  $message = "<div class='error'><p><strong>" . __( 'Error', 'my-calendar' ) . ":</strong>" . __( 'Your events have not been deleted. Please investigate.', 'my-calendar' ) . "</p></div>";
269
  $value = (int) $value;
270
  $total = count( $events );
271
  if ( current_user_can( 'mc_approve_events' ) ) {
272
+ $sql .= (int) $value . ',';
273
  $approved[] = $value;
274
  $i ++;
275
  }
281
  $message = "<div class='error'><p><strong>" . __( 'Error', 'my-calendar' ) . ":</strong>" . __( 'Your events have not been approved. Please investigate.', 'my-calendar' ) . "</p></div>";
282
  } else {
283
  mc_delete_cache();
 
284
  do_action( 'mc_mass_approve_events', $approved );
285
  $message = "<div class='updated'><p>" . sprintf( __( '%1$d events approved successfully out of %2$d selected', 'my-calendar' ), $i, $total ) . "</p></div>";
286
  }
298
  $archived = array();
299
  foreach ( $events as $value ) {
300
  $total = count( $events );
301
+ $sql .= (int) $value . ',';
302
  $archived[] = $value;
303
  $i ++;
304
  }
309
  $message = "<div class='error'><p><strong>" . __( 'Error', 'my-calendar' ) . ":</strong>" . __( 'Could not archive those events.', 'my-calendar' ) . "</p></div>";
310
  } else {
311
  mc_delete_cache();
 
312
  do_action( 'mc_mass_archive_events', $archived );
313
  $message = "<div class='updated'><p>" . sprintf( __( '%1$d events archived successfully out of %2$d selected.', 'my-calendar' ), $i, $total ) . ' ' . __( 'Archived events remain on your calendar, but are removed from the event manager.', 'my-calendar' ) . "</p></div>";
314
  }
325
  $i = $total = 0;
326
  $archived = array();
327
  foreach ( $events as $value ) {
328
+ $total = count( $events );
329
+ $sql .= (int) $value . ',';
330
  $archived[] = $value;
331
  $i ++;
332
  }
337
  $message = "<div class='error'><p><strong>" . __( 'Error', 'my-calendar' ) . ":</strong>" . __( 'Could not undo the archive status on those events.', 'my-calendar' ) . "</p></div>";
338
  } else {
339
  mc_delete_cache();
 
340
  do_action( 'mc_mass_undo_archive_events', $archived );
341
  $message = "<div class='updated'><p>" . sprintf( __( '%1$d events removed from archive successfully out of %2$d selected.', 'my-calendar' ), $i, $total ) . "</p></div>";
342
  }
343
  echo $message;
344
  }
345
  ?>
346
+ <div class='wrap my-calendar-admin'>
347
+ <h1 id="mc-manage" class="wp-heading-inline"><?php _e( 'Manage Events', 'my-calendar' ); ?></h1>
348
+ <a href="<?php echo admin_url( "admin.php?page=my-calendar" ); ?>" class="page-title-action"><?php _e( 'Add New', 'my-calendar' ); ?></a>
349
+ <hr class="wp-header-end">
350
+
351
  <div class="postbox-container jcd-wide">
352
  <div class="metabox-holder">
353
  <div class="ui-sortable meta-box-sortables">
375
  if ( function_exists( 'check_calendar' ) ) {
376
  echo "<div id='message'class='updated'>";
377
  echo "<p>";
378
+ _e( 'My Calendar has identified that you have the Calendar plugin by Kieran O\'Shea installed. You can import those events and categories into the My Calendar database. Would you like to import these events?', 'my-calendar' );
379
  echo "</p>";
380
  ?>
381
  <form method="post" action="<?php echo admin_url( 'admin.php?page=my-calendar-config' ); ?>">
390
  </form>
391
  <?php
392
  echo "<p>";
393
+ _e( 'Although it is possible that this import could fail to import your events correctly, it should not have any impact on your existing Calendar database.', 'my-calendar' );
394
  echo "</p>";
395
  echo "</div>";
396
  }
438
 
439
  ?>
440
 
441
+ <div class="wrap my-calendar-admin">
442
  <?php my_calendar_check_db();
443
  if ( get_site_option( 'mc_multisite' ) == 2 ) {
444
  if ( get_option( 'mc_current_table' ) == 0 ) {
523
  '%f',
524
  '%f'
525
  );
526
+
527
  if ( ( $action == 'add' || $action == 'copy' ) && $proceed == true ) {
528
  $add = $output[2]; // add format here
529
  $add = apply_filters( 'mc_before_save_insert', $add );
530
+ // this db write takes most of the processing time for this.
531
  $result = $mcdb->insert( my_calendar_table(), $add, $formats );
532
  $event_id = $mcdb->insert_id;
533
  mc_increment_event( $event_id );
546
  if ( $add['event_approved'] == 0 ) {
547
  $message = "<div class='updated notice'><p>" . __( 'Event saved. An administrator will review and approve your event.', 'my-calendar' ) . "</p></div>";
548
  } else {
549
+ // jd_doTwitterAPIPost was changed to wpt_post_to_twitter on 1.19.2017
550
  if ( function_exists( 'jd_doTwitterAPIPost' ) && isset( $_POST['mc_twitter'] ) && trim( $_POST['mc_twitter'] ) != '' ) {
551
  jd_doTwitterAPIPost( stripslashes( $_POST['mc_twitter'] ) );
552
  }
553
  if ( get_option( 'mc_uri' ) != '' ) {
554
  $event_ids = mc_get_occurrences( $event_id );
 
 
555
  $event_link = mc_get_details_link( $event_ids[0]->occur_id );
556
  $event_error = mc_error_check( $event_ids[0]->occur_event_id );
557
  } else {
585
  ( $endtime != $_POST['prev_event_endtime'] && ( $_POST['prev_event_endtime'] != '' && $endtime != '23:59:59' ) ) )
586
  ? true : false;
587
  if ( isset( $_POST['event_instance'] ) ) {
588
+ // compares the information sent to the information saved for a given event.
589
+ $is_changed = mc_compare( $update, $event_id );
590
  $event_instance = (int) $_POST['event_instance'];
591
  if ( $is_changed ) {
592
  // if changed, create new event, match group id, update instance to reflect event connection, same group id.
616
  }
617
  }
618
  } else {
619
+ $result = $mcdb->update(
620
  my_calendar_table(),
621
  $update,
622
  array( 'event_id' => $event_id ),
623
  $formats,
624
+ '%d' );
625
  $recur_changed = ( $update['event_repeats'] != $_POST['prev_event_repeats'] || $update['event_recur'] != $_POST['prev_event_recur'] ) ? true : false;
626
  if ( $date_changed || $recur_changed ) {
627
  // TODO: if date or recur changed, do generation of new instances, then iterate over existing occurrences
654
 
655
  function mc_error_check( $event_id ) {
656
  $data = mc_form_data( $event_id );
657
+ $test = ( $data ) ? mc_test_occurrence_overlap( $data, true ) : '';
 
 
 
 
658
  $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>";
 
659
  $test = ( $test != '' ) ? str_replace( "</p></div>", "$edit_link</p></div>", $test ) : $test;
660
 
661
  return $test;
868
  }
869
  break;
870
  case 'event_image' :
871
+ if ( $has_data && property_exists( $data, 'event_post' ) ) {
872
+ $image = ( has_post_thumbnail( $data->event_post ) ) ? get_the_post_thumbnail_url( $data->event_post ) : $data->event_image;
873
+ $image_id = ( has_post_thumbnail( $data->event_post ) ) ? get_post_thumbnail_id( $data->event_post ) : '';
874
+ } else {
875
+ $image = ( $has_data && $data->event_image != '' ) ? $data->event_image : '';
876
+ $image_id = '';
877
+ }
878
  if ( $show_block ) {
 
 
 
 
 
879
  $return = '
880
  <div class="mc-image-upload field-holder">
881
+ <input type="hidden" name="event_image_id" value="' . esc_attr( $image_id ) . '" class="textfield" id="e_image_id" />
882
  <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>';
883
  if ( $image != '' ) {
884
  $image = ( has_post_thumbnail( $data->event_post ) ) ? get_the_post_thumbnail_url( $data->event_post ) : $data->event_image;
947
  <legend class="screen-reader-text">' . __( 'Recurring Events', 'my-calendar' ) . '</legend>
948
  <p>
949
  <label for="e_repeats">' . __( 'Repeats', 'my-calendar' ) . ' <input type="text" name="event_repeats" aria-labelledby="e_repeats_label" id="e_repeats" size="1" value="' . esc_attr( $repeats ) . '" /> <span id="e_repeats_label">' . __( 'times', 'my-calendar' ) . '</span>, </label>
950
+ <label for="e_every">' . __( 'every', 'my-calendar' ) . '</label> <input type="number" name="event_every" id="e_every" size="1" min="1" max="99" maxlength="2" value="' . esc_attr( $every ) . '" />
951
  <label for="e_recur" class="screen-reader-text">' . __( 'Units', 'my-calendar' ) . '</label>
952
  <select name="event_recur" id="e_recur">
953
  ' . mc_recur_options( $recur ) . '
954
  </select><br />
955
  ' . __( 'Your entry is the number of events after the first occurrence of the event: a recurrence of <em>2</em> means the event will happen three times.', 'my-calendar' ) . '
956
+ <div class="mc_recur_notice" aria-live="polite"><p><span class="dashicons dashicons-no" aria-hidden="true"></span>' . __( 'Month by day events currently only support monthly recurrances.', 'my-calendar' ) . '</p></div>
957
  </p>
958
  </fieldset>
959
  </div>
1060
  if ( !$single_recur && !$start_end ) {
1061
  $check = mc_increment_event( $data->event_id, array(), 'test' );
1062
  if ( my_calendar_date_xcomp( $check['occur_begin'], $data->event_end . '' . $data->event_endtime ) ) {
1063
+ $warning = "<div class='error'><span class='problem-icon dashicons dashicons-performance' aria-hidden='true'></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>";
1064
  update_post_meta( $data->event_post, '_occurrence_overlap', 'false' );
1065
  } else {
1066
  delete_post_meta( $data->event_post, '_occurrence_overlap' );
1087
  $data = mc_get_event_core( $event_id );
1088
  }
1089
  ?>
 
1090
  <div class="postbox-container jcd-wide">
1091
  <div class="metabox-holder">
1092
  <?php if ( $mode == 'add' || $mode == 'copy' ) {
1173
  $event = mc_get_event( $instance );
1174
  $date = date_i18n( get_option( 'mc_date_format' ), strtotime( $event->occur_begin ) );
1175
  $message = __( "You are editing the <strong>$date</strong> instance of this event. Other instances of this event will not be changed.", 'my-calendar' );
 
1176
  echo "<div class='message updated'><p>$message</p></div>";
1177
  } else if ( isset( $_GET['date'] ) && empty( $_GET['date'] ) ) {
1178
  echo "<div class='message updated'><p>" . __( 'There was an error acquiring information about this event instance. The ID for this event instance was not provided. <strong>You are editing this entire recurrence set.</strong>', 'my-calendar' ) . "</p></div>";
1441
  </div>
1442
  </div><?php
1443
  } else {
1444
+ if ( $has_data ) {
1445
+ $event_holiday = ( $data->event_holiday == '1' ) ? 'true' : 'false';
1446
+ $event_fifth = ( $data->event_fifth_week == '1' ) ? 'true' : 'false';
1447
+ } else {
1448
+ $event_holiday = get_option( 'mc_skip_holidays' );
1449
+ $event_fifth = get_option( 'mc_no_fifth_week' );
1450
+ }
1451
  ?>
1452
  <div>
1453
+ <input type="hidden" name="event_holiday" value="<?php esc_attr_e( $event_holiday ); ?>" />
1454
+ <input type="hidden" name="event_fifth_week" value="<?php esc_attr_e( $event_fifth ); ?>" />
1455
  </div><?php
1456
  } ?>
1457
  <p>
1570
  $sortbyvalue = "event_begin $sortbydirection, event_time";
1571
  }
1572
  }
1573
+ $sorting = ( $sortbydirection == 'DESC' ) ? "&amp;order=ASC" : '&amp;order=DESC';
1574
+ $allow_filters = true;
1575
+ $status = ( isset( $_GET['limit'] ) ) ? $_GET['limit'] : 'all';
1576
+ $restrict = ( isset( $_GET['restrict'] ) ) ? $_GET['restrict'] : 'all';
1577
  switch ( $status ) {
1578
  case 'all':
1579
  $limit = '';
1627
  if ( $filter == '' || ! $allow_filters ) {
1628
  $filtered = "";
1629
  } else {
1630
+ $filtered = "<span class='dashicons dashicons-no' aria-hidden='true'></span><a href='" . admin_url( 'admin.php?page=my-calendar-manage' ) . "'>" . __( 'Clear filters', 'my-calendar' ) . "</a>";
1631
  }
1632
  $current = empty( $_GET['paged'] ) ? 1 : intval( $_GET['paged'] );
1633
  $user = get_current_user_id();
1648
  $limit .= mc_prepare_search_query( $query );
1649
  }
1650
  $limit .= ( $restrict != 'archived' ) ? " AND event_status = 1" : ' AND event_status = 0';
1651
+ if ( $sortbyvalue != 'event_category' ) {
1652
+ $events = $mcdb->get_results( "SELECT SQL_CALC_FOUND_ROWS event_id FROM " . my_calendar_table() . " $limit ORDER BY $sortbyvalue $sortbydirection LIMIT " . ( ( $current - 1 ) * $items_per_page ) . ", " . $items_per_page );
1653
+ } else {
1654
+ $limit = str_replace( array( 'WHERE ' ), '', $limit );
1655
+ $limit = ( strpos( $limit, 'AND' ) === 0 ) ? $limit : 'AND ' . $limit;
1656
+ $events = $mcdb->get_results( "SELECT DISTINCT SQL_CALC_FOUND_ROWS events.event_id FROM " . my_calendar_table() . " AS events JOIN " . my_calendar_categories_table() . " AS categories WHERE events.event_category = categories.category_id $limit ORDER BY categories.category_name $sortbydirection LIMIT " . ( ( $current - 1 ) * $items_per_page ) . ", " . $items_per_page );
1657
+ }
1658
+
1659
  $found_rows = $wpdb->get_col( "SELECT FOUND_ROWS();" );
1660
  $items = $found_rows[0];
1661
  if ( ( function_exists( 'akismet_http_post' ) || function_exists( 'bs_checker' ) ) && $allow_filters ) {
1770
  $categories = $mcdb->get_results( $sql );
1771
 
1772
  foreach ( array_keys( $events ) as $key ) {
1773
+ $e =& $events[ $key ];
1774
+ $event = mc_get_event_core( $e->event_id );
1775
+ if ( !is_object( $event ) ) {
1776
+ continue;
1777
+ }
1778
  $class = ( $class == 'alternate' ) ? 'even' : 'alternate';
1779
  $pending = ( $event->event_approved == 0 ) ? 'pending' : '';
1780
  $author = ( $event->event_author != 0 ) ? get_userdata( $event->event_author ) : 'Public Submitter';
1787
  $spam = '';
1788
  $spam_label = '';
1789
  }
1790
+ $edit_url = admin_url( "admin.php?page=my-calendar&amp;mode=edit&amp;event_id=$event->event_id" );
1791
+ $copy_url = admin_url( "admin.php?page=my-calendar&amp;mode=copy&amp;event_id=$event->event_id" );
1792
+ $view_url = mc_get_details_link( $event );
1793
+ $group_url = admin_url( "admin.php?page=my-calendar-groups&amp;mode=edit&amp;event_id=$event->event_id&amp;group_id=$event->event_group_id" );
1794
  $delete_url = admin_url( "admin.php?page=my-calendar-manage&amp;mode=delete&amp;event_id=$event->event_id" );
1795
+ $check = mc_test_occurrence_overlap( $event, true );
1796
+ $problem = ( $check != '' ) ? 'problem' : '';
1797
  if ( current_user_can( 'mc_manage_events' ) || current_user_can( 'mc_approve_events' ) || mc_can_edit_event( $event->event_id ) ) {
1798
  ?>
1799
  <tr class="<?php echo "$class $spam $pending $problem"; ?>">
1801
  <input type="checkbox" value="<?php echo $event->event_id; ?>" name="mass_edit[]" id="mc<?php echo $event->event_id; ?>" <?php echo ( $event->event_flagged == 1 ) ? 'checked="checked"' : ''; ?> />
1802
  <label for="mc<?php echo $event->event_id; ?>"><?php echo $event->event_id; ?></label>
1803
  </th>
1804
+ <td>
1805
  <strong><?php if ( mc_can_edit_event( $event->event_id ) ) { ?>
1806
  <a href="<?php echo $edit_url; ?>" class='edit'>
1807
  <?php } ?>
1814
  } ?></strong>
1815
 
1816
  <div class='row-actions' style="visibility:visible;">
1817
+ <?php if ( mc_event_published( $event ) ) { ?>
1818
+ <a href="<?php echo $view_url; ?>" class='view'><?php _e( 'View', 'my-calendar' ); ?></a> |
1819
+ <?php } ?>
1820
+ <a href="<?php echo $copy_url; ?>" class='copy'><?php _e( 'Copy', 'my-calendar' ); ?></a>
1821
  <?php if ( mc_can_edit_event( $event->event_id ) ) { ?>
 
1822
  <?php if ( mc_event_is_grouped( $event->event_group_id ) ) { ?>
1823
  | <a href="<?php echo $group_url; ?>" class='edit group'><?php _e( 'Edit Group', 'my-calendar' ); ?></a>
1824
  <?php } ?>
1911
  ?>
1912
  </div>
1913
  </td>
1914
+ <?php
1915
+ $auth = ( is_object( $author ) ) ? $author->ID : 0;
1916
+ $filter = admin_url( "admin.php?page=my-calendar-manage&amp;filter=$auth&amp;restrict=author" );
1917
+ $author = ( is_object( $author ) ? $author->display_name : $author );
1918
+ ?>
1919
+ <td>
1920
+ <a class='mc_filter' href="<?php echo $filter; ?>" title="<?php _e( 'Filter by author', 'my-calendar' ); ?>">
1921
+ <span class="screen-reader-text"><?php _e( 'Show only: ', 'my-calendar' ); ?></span><?php echo $author; ?>
1922
+ </a>
1923
+ </td>
1924
  <?php
1925
  if ( ! $event->event_category ) {
1926
  // events *must* have a category
1929
  $color = strip_tags( mc_get_category_detail( $event->event_category, 'category_color' ) );
1930
  ?>
1931
  <td>
1932
+ <div class="category-color" style="background-color:<?php echo ( strpos( $color, '#' ) !== 0 ) ? '#' : ''; echo $color; ?>;"></div>
 
 
1933
  <a class='mc_filter'
1934
  href='<?php echo admin_url( "admin.php?page=my-calendar-manage&amp;filter=$event->event_category&amp;restrict=category" ); ?>'
1935
  title="<?php _e( 'Filter by category', 'my-calendar' ); ?>"><span
1936
+ 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' ) ); ?>
1937
+ </a>
1938
+ </td>
1939
  </tr>
1940
  <?php
1941
  }
1943
  ?>
1944
  </table>
1945
  <p>
1946
+ <input type="submit" class="button-secondary delete" name="mass_delete" value="<?php _e( 'Delete events', 'my-calendar' ); ?>"/>
 
1947
  <?php if ( current_user_can( 'mc_approve_events' ) ) { ?>
1948
+ <input type="submit" class="button-secondary mc-approve" name="mass_approve" value="<?php _e( 'Approve events', 'my-calendar' ); ?>"/>
1949
+ <?php }
1950
+ if ( ! ( isset( $_GET['restrict'] ) && $_GET['restrict'] == 'archived' ) ) { ?>
1951
+ <input type="submit" class="button-secondary mc-archive" name="mass_archive" value="<?php _e( 'Archive events', 'my-calendar' ); ?>"/>
 
 
1952
  <?php } ?>
1953
  </p>
1954
 
1955
  <p>
1956
  <?php if ( ! ( isset( $_GET['restrict'] ) && $_GET['restrict'] == 'archived' ) ) { ?>
1957
+ <a class='mc_filter' href='<?php echo admin_url( "admin.php?page=my-calendar-manage&amp;restrict=archived" ); ?>'><?php _e( 'View Archived Events', 'my-calendar' ); ?></a>
 
1958
  <?php } else { ?>
1959
+ <a class='mc_filter' href='<?php echo admin_url( "admin.php?page=my-calendar-manage" ); ?>'><?php _e( 'Return to Manage Events', 'my-calendar' ); ?></a>
 
1960
  <?php } ?>
1961
  </p>
1962
  </form>
1963
+ <?php
1964
+ } else { ?>
 
1965
  <p class='mc-none'><?php _e( "There are no events in the database meeting your current criteria.", 'my-calendar' ) ?></p><?php
1966
  }
1967
  }
1968
  }
1969
 
1970
  function mc_check_data( $action, $post, $i ) {
 
1971
  global $wpdb, $current_user, $users_entries;
1972
+ $post = apply_filters( 'mc_pre_checkdata', $post, $action, $i );
1973
  $mcdb = $wpdb;
1974
  $submit = array();
1975
  $errors = '';
1976
  $every = $recur = $events_access = $begin = $end = $short = $time = $endtime = $event_label = $event_street = $event_street2 = $event_city = $event_state = $event_postcode = $event_region = $event_country = $event_url = $event_image = $event_phone = $event_phone2 = $event_access = $event_tickets = $event_registration = $event_author = $category = $expires = $event_zoom = $event_open = $event_group = $approved = $host = $event_fifth_week = $event_holiday = $event_group_id = $event_span = $event_hide_end = $event_longitude = $event_latitude = '';
1977
+
1978
  if ( get_magic_quotes_gpc() ) {
1979
  $post = array_map( 'stripslashes_deep', $post );
1980
  }
2156
  } else {
2157
  $errors .= "<div class='error'><p><strong>" . __( 'Error', 'my-calendar' ) . ":</strong> " . __( 'The time field must either be blank or be entered in the format hh:mm am/pm', 'my-calendar' ) . "</p></div>";
2158
  }
2159
+ // Check for a valid or empty end time
2160
  if ( preg_match( $time_format_one, $endtime ) || preg_match( $time_format_two, $endtime ) || $endtime == '' ) {
2161
  } else {
2162
  $errors .= "<div class='error'><p><strong>" . __( 'Error', 'my-calendar' ) . ":</strong> " . __( 'The end time field must either be blank or be entered in the format hh:mm am/pm', 'my-calendar' ) . "</p></div>";
2163
  }
2164
+ // Check for valid URL (blank or starting with http://)
2165
  if ( ! ( $event_link == '' || preg_match( '/^(http)(s?)(:)\/\//', $event_link ) ) ) {
2166
  $event_link = "http://" . $event_link;
2167
  }
2186
  }
2187
  }
2188
  $spam = mc_spam( $event_link, $desc, $post );
2189
+ // the likelihood that something will be flagged as spam, have a zero start time
2190
  // and yet be legitimate is crazy minimal. Just kill it.
2191
  if ( $spam == 1 && $begin == '1970-01-01' ) {
2192
  die;
2244
  'event_longitude' => $event_longitude,
2245
  'event_latitude' => $event_latitude
2246
  );
2247
+
2248
  $submit = array_map( 'mc_kses_post', $submit );
2249
 
2250
  } else {
2307
  global $wpdb;
2308
  $select_location = ( $event_label != '' ) ? "event_label = '$event_label'AND" : '';
2309
  $event_query = "SELECT occur_id
2310
+ FROM " . my_calendar_table() . "
2311
+ ON ( " . my_calendar_event_table() . "
2312
+ JOINevent_id=occur_event_id)
2313
  WHERE $select_location
2314
  ( occur_begin BETWEEN '$begin $time'AND '$end $endtime'OR occur_end BETWEEN '$begin $time'AND '$end $endtime')";
2315
  $results = $wpdb->get_results( $event_query );
2415
  foreach ( $results as $result ) {
2416
  $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>";
2417
  if ( $result->occur_id == $occur ) {
2418
+ $control = '';
2419
+ $edit = "<em>" . __( 'Editing Now', 'my-calendar' ) . "</em>";
2420
  } else {
2421
+ $control = "$begin: <button class='delete_occurrence' type='button' data-value='$result->occur_id' aria-describedby='occur_date_$result->occur_id' />" . __( 'Delete', 'my-calendar' ) . "</button> ";
2422
+ $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>";
2423
  }
2424
+ $output .= "<li>$control$edit</li>";
2425
  }
2426
  } else {
2427
  $details = '';
2435
  } else if ( mc_key_exists( $template ) ) {
2436
  $template = mc_get_custom_template( $template );
2437
  } else {
 
2438
  $details = my_calendar_draw_event( $event, $type = "single", $event->event_begin, $event->event_time, '' );
2439
  }
2440
  }
2443
  $details = ( $template != '' ) ? jd_draw_template( $array, $template ) : '';
2444
  }
2445
  $output .= $item;
2446
+ if ( $list == '' ) {
2447
+ break;
2448
+ }
2449
  }
2450
  $output = $details . $before . $output . $after;
2451
+
2452
  }
2453
 
2454
  return ( get_option( 'mc_process_shortcodes' ) == 'true' ) ? do_shortcode( $output ) : $output;
2492
  $event_begin = date( "Y-m-d" );
2493
  $event_end = $starttime = $endtime = '';
2494
  }
2495
+
2496
+ $allday = ( $has_data && ( mc_is_all_day( $data ) ) ) ? " checked=\"checked\"" : '';
2497
+ $hide = ( $has_data && $data->event_hide_end == '1' ) ? " checked=\"checked\"" : '';
2498
+ $allday_label = ( $has_data ) ? mc_notime_label( $data ) : get_option( 'mc_notime_text' );
2499
+
 
 
 
 
 
 
 
2500
  $form .= '<p>
2501
  <label for="e_begin" id="eblabel">' . __( 'Date (YYYY-MM-DD)', 'my-calendar' ) . '</label> <input type="text" id="e_begin" class="mc-datepicker" name="event_begin[]" size="10" value="" data-value="' . esc_attr( $event_begin ) . '" />
2502
  <label for="e_time">' . __( 'From', 'my-calendar' ) . '</label>
2581
  $post = get_post( $id );
2582
  $featured_image = wp_get_attachment_url( get_post_thumbnail_id( $post->ID ) );
2583
  $event_id = get_post_meta( $post->ID, '_mc_event_id', true );
2584
+ if ( esc_url( $featured_image ) ) {
2585
+ mc_update_data( $event_id, 'event_image', $featured_image, '%s' );
2586
+ }
2587
  }
my-calendar-events.php CHANGED
@@ -11,13 +11,18 @@ function mc_private_categories( $return = 'query' ) {
11
  if ( $cats != '' ) {
12
  $cats = " AND category_id NOT IN ($cats)";
13
  }
14
-
15
- return $cats;
16
  }
17
 
18
  return $cats;
19
  }
20
 
 
 
 
 
 
 
 
21
  function mc_get_private_categories() {
22
  global $wpdb;
23
  $mcdb = $wpdb;
@@ -31,7 +36,7 @@ function mc_get_private_categories() {
31
  $categories[] = $result->category_id;
32
  }
33
 
34
- return $categories;
35
  }
36
 
37
  // used to generate upcoming events lists
@@ -56,7 +61,8 @@ function mc_get_all_events( $category, $before, $after, $today, $author, $host,
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'
62
  $exclude_categories
@@ -68,7 +74,8 @@ function mc_get_all_events( $category, $before, $after, $today, $author, $host,
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
74
  AND ( ( DATE(occur_begin) < '$date' AND DATE(occur_end) > '$date' ) OR DATE(occur_begin) = '$date' )" ); // event crosses or equals
@@ -80,7 +87,8 @@ function mc_get_all_events( $category, $before, $after, $today, $author, $host,
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
86
  AND DATE(occur_begin) > '$date' ORDER BY occur_begin ASC LIMIT 0,$after" );
@@ -89,7 +97,7 @@ function mc_get_all_events( $category, $before, $after, $today, $author, $host,
89
  if ( ! empty( $events1 ) || ! empty( $events2 ) || ! empty( $events3 ) ) {
90
  $arr_events = array_merge( $events1, $events3, $events2 );
91
  }
92
-
93
  return $arr_events;
94
  }
95
 
@@ -159,7 +167,16 @@ 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_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 ];
@@ -170,6 +187,7 @@ function mc_get_rss_events( $cat_id = false ) {
170
  $groups[] = $event->occur_group_id;
171
  }
172
  }
 
173
  return $output;
174
  }
175
 
@@ -178,8 +196,8 @@ function mc_get_rss_events( $cat_id = false ) {
178
  *
179
  * @param integer $id Event ID in my_calendar db
180
  */
181
- function mc_get_event_core( $id ) {
182
- if ( !is_numeric( $id ) ) {
183
  return;
184
  }
185
 
@@ -191,8 +209,11 @@ function mc_get_event_core( $id ) {
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;
@@ -329,6 +350,44 @@ function mc_related_events( $id, $template = false, $return = false ) {
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;
@@ -338,9 +397,17 @@ function mc_list_related( $id, $this_id, $template = '{date}, {time}' ) {
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;
@@ -350,8 +417,9 @@ function mc_list_related( $id, $this_id, $template = '{date}, {time}' ) {
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>";
@@ -412,6 +480,8 @@ function my_calendar_events_now( $category = 'default', $template = '<strong>{li
412
  $arr_events = array();
413
  $limit_string = "event_flagged <> 1 AND event_approved = 1";
414
  $select_category = ( $category != 'default' ) ? mc_select_category( $category ) : '';
 
 
415
  // may add support for location/author/host later.
416
  $select_location = $select_author = $select_host = '';
417
  $now = date( 'Y-m-d H:i:s', current_time( 'timestamp' ) );
@@ -422,6 +492,7 @@ function my_calendar_events_now( $category = 'default', $template = '<strong>{li
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 )
426
  ORDER BY " . apply_filters( 'mc_primary_sort', 'occur_begin' ) . ", " . apply_filters( 'mc_secondary_sort', 'event_title ASC' );
427
  $events = $mcdb->get_results( $event_query );
@@ -451,10 +522,28 @@ function my_calendar_events_now( $category = 'default', $template = '<strong>{li
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' ) ) {
459
  $mcdb = mc_remote_db();
460
  }
@@ -525,10 +614,12 @@ function my_calendar_grab_events( $from, $to, $category = null, $ltype = '', $lv
525
  }
526
  }
527
 
528
- $select_category = ( $ccategory != 'all' ) ? mc_select_category( $ccategory ) : '';
529
- $select_author = ( $clauth != 'all' ) ? mc_select_author( $clauth ) : '';
530
- $select_host = ( $clhost != 'all' ) ? mc_select_host( $clhost ) : '';
531
- $select_location = mc_limit_string( 'grab', $cltype, $clvalue );
 
 
532
 
533
  if ( $caching && $source != 'upcoming' ) {
534
  $select_category = '';
@@ -553,6 +644,7 @@ function my_calendar_grab_events( $from, $to, $category = null, $ltype = '', $lv
553
  OR DATE(occur_end) BETWEEN '$from 00:00:00' AND '$to 23:59:59'
554
  OR ( DATE('$from') BETWEEN DATE(occur_begin) AND DATE(occur_end) )
555
  OR ( DATE('$to') BETWEEN DATE(occur_begin) AND DATE(occur_end) ) )
 
556
  ORDER BY " . apply_filters( 'mc_primary_sort', 'occur_begin' ) . ", " . apply_filters( 'mc_secondary_sort', 'event_title ASC' );
557
  $events = $mcdb->get_results( $event_query );
558
 
@@ -579,6 +671,15 @@ function my_calendar_grab_events( $from, $to, $category = null, $ltype = '', $lv
579
  }
580
  }
581
 
 
 
 
 
 
 
 
 
 
582
  function mc_get_db_type() {
583
  global $wpdb;
584
  $mcdb = $wpdb;
11
  if ( $cats != '' ) {
12
  $cats = " AND category_id NOT IN ($cats)";
13
  }
 
 
14
  }
15
 
16
  return $cats;
17
  }
18
 
19
+ /**
20
+ * Fetch array of private categories.
21
+ *
22
+ * @uses filter mc_private_categories
23
+ *
24
+ * @return array private categories
25
+ */
26
  function mc_get_private_categories() {
27
  global $wpdb;
28
  $mcdb = $wpdb;
36
  $categories[] = $result->category_id;
37
  }
38
 
39
+ return apply_filters( 'mc_private_categories', $categories );
40
  }
41
 
42
  // used to generate upcoming events lists
61
  JOIN " . my_calendar_table( $site ) . "
62
  ON (event_id=occur_event_id)
63
  JOIN " . my_calendar_categories_table( $site ) . "
64
+ ON (event_category=category_id)
65
+ WHERE $select_category $select_author $select_host $limit_string event_approved = 1
66
  AND event_flagged <> 1
67
  AND DATE(occur_begin) < '$date'
68
  $exclude_categories
74
  JOIN " . my_calendar_table( $site ) . "
75
  ON (event_id=occur_event_id)
76
  JOIN " . my_calendar_categories_table( $site ) . "
77
+ ON (event_category=category_id)
78
+ WHERE $select_category $select_author $select_host $limit_string event_approved = 1
79
  AND event_flagged <> 1
80
  $exclude_categories
81
  AND ( ( DATE(occur_begin) < '$date' AND DATE(occur_end) > '$date' ) OR DATE(occur_begin) = '$date' )" ); // event crosses or equals
87
  JOIN " . my_calendar_table( $site ) . "
88
  ON (event_id=occur_event_id)
89
  JOIN " . my_calendar_categories_table( $site ) . "
90
+ ON (event_category=category_id)
91
+ WHERE $select_category $select_author $select_host $limit_string event_approved = 1
92
  AND event_flagged <> 1
93
  $exclude_categories
94
  AND DATE(occur_begin) > '$date' ORDER BY occur_begin ASC LIMIT 0,$after" );
97
  if ( ! empty( $events1 ) || ! empty( $events2 ) || ! empty( $events3 ) ) {
98
  $arr_events = array_merge( $events1, $events3, $events2 );
99
  }
100
+
101
  return $arr_events;
102
  }
103
 
167
  } else {
168
  $cat = 'WHERE event_approved = 1';
169
  }
170
+ $exclude_categories = mc_private_categories();
171
+ $limit = apply_filters( 'mc_rss_feed_size', 30 );
172
+
173
+ $events = $mcdb->get_results(
174
+ "SELECT *, UNIX_TIMESTAMP(occur_begin) AS ts_occur_begin, UNIX_TIMESTAMP(occur_end) AS ts_occur_end
175
+ FROM " . my_calendar_event_table() . "
176
+ JOIN " . my_calendar_table() . " ON (event_id=occur_event_id)
177
+ JOIN " . my_calendar_categories_table() . " ON (event_category=category_id) $cat
178
+ $exclude_categories
179
+ ORDER BY event_added DESC LIMIT 0,$limit" );
180
  $groups = $output = array();
181
  foreach ( array_keys( $events ) as $key ) {
182
  $event =& $events[ $key ];
187
  $groups[] = $event->occur_group_id;
188
  }
189
  }
190
+
191
  return $output;
192
  }
193
 
196
  *
197
  * @param integer $id Event ID in my_calendar db
198
  */
199
+ function mc_get_event_core( $id, $rebuild = false ) {
200
+ if ( !is_numeric( $id ) ) {
201
  return;
202
  }
203
 
209
  // get event data
210
  $event = $mcdb->get_row( "SELECT * FROM " . my_calendar_table() . " JOIN " . my_calendar_categories_table() . " ON (event_category=category_id) WHERE event_id=$id" );
211
  // include first occurrence
212
+ if ( $rebuild ) {
213
+ return $event;
214
+ }
215
 
216
+ $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" );
217
  $event = (object) array_merge( (array) $event, (array) $occur );
218
 
219
  return $event;
350
  }
351
 
352
 
353
+ function mc_holiday_limit( $events, $holidays ) {
354
+ foreach ( array_keys( $events ) as $key ) {
355
+ if ( ! empty( $holidays[ $key ] ) ) {
356
+ foreach ( $events[ $key ] as $k => $event ) {
357
+ if ( $event->event_category != get_option( 'mc_skip_holidays_category' ) && $event->event_holiday == 1 ) {
358
+ unset( $events[ $key ][ $k ] );
359
+ }
360
+ }
361
+ }
362
+ }
363
+
364
+ return $events;
365
+ }
366
+
367
+ // Used to draw multiple events
368
+ function mc_set_date_array( $events ) {
369
+ $event_array = array();
370
+ if ( is_array( $events ) ) {
371
+ foreach ( $events as $event ) {
372
+ $date = date( 'Y-m-d', strtotime( $event->occur_begin ) );
373
+ $end = date( 'Y-m-d', strtotime( $event->occur_end ) );
374
+ if ( $date != $end ) {
375
+ $start = strtotime( $date );
376
+ $end = strtotime( $end );
377
+ do {
378
+ $date = date( 'Y-m-d', $start );
379
+ $event_array[ $date ][] = $event;
380
+ $start = strtotime( "+1 day", $start );
381
+ } while ( $start <= $end );
382
+ } else {
383
+ $event_array[ $date ][] = $event;
384
+ }
385
+ }
386
+ }
387
+
388
+ return $event_array;
389
+ }
390
+
391
  // get all events related to an event ID (group IDs)
392
  function mc_list_related( $id, $this_id, $template = '{date}, {time}' ) {
393
  global $wpdb;
397
  }
398
 
399
  $output = '';
400
+ $classes = '';
401
  $sql = "SELECT event_id FROM " . my_calendar_table() . " WHERE event_group_id=$id";
402
  $results = $wpdb->get_results( $sql );
403
 
404
+ $count = count( $results );
405
+ // If a large number of events, skip this;
406
+ if ( $count > apply_filters( 'mc_related_event_limit', 50 ) ) {
407
+ // filter to return an subset of related events.
408
+ return apply_filters( 'mc_related_events', '', $results );
409
+ }
410
+
411
  if ( is_array( $results ) && ! empty( $results ) ) {
412
  foreach ( $results as $result ) {
413
  $event_id = $result->event_id;
417
  $template = mc_get_custom_template( $template );
418
  }
419
  $html = jd_draw_template( $array, $template );
420
+ $classes = mc_event_classes( $event, '', 'related' );
421
+ $classes .= ( $event_id == $this_id ) ? ' current-event' : '';
422
+ $output .= "<li class='$classes'>$html</li>";
423
  }
424
  } else {
425
  $output = "<li>" . __( 'No related events', 'my-calendar' ) . "</li>";
480
  $arr_events = array();
481
  $limit_string = "event_flagged <> 1 AND event_approved = 1";
482
  $select_category = ( $category != 'default' ) ? mc_select_category( $category ) : '';
483
+ $exclude_categories = mc_private_categories();
484
+
485
  // may add support for location/author/host later.
486
  $select_location = $select_author = $select_host = '';
487
  $now = date( 'Y-m-d H:i:s', current_time( 'timestamp' ) );
492
  JOIN " . my_calendar_categories_table( $site ) . " AS c
493
  ON (event_category=category_id)
494
  WHERE $select_category $select_location $select_author $select_host $limit_string
495
+ $exclude_categories
496
  AND ( CAST('$now' AS DATETIME) BETWEEN occur_begin AND occur_end )
497
  ORDER BY " . apply_filters( 'mc_primary_sort', 'occur_begin' ) . ", " . apply_filters( 'mc_secondary_sort', 'event_title ASC' );
498
  $events = $mcdb->get_results( $event_query );
522
  return $return;
523
  }
524
 
525
+ /**
526
+ * Get post associated with a given My Calendar event
527
+ *
528
+ * @param int $event_id
529
+ *
530
+ * @return mixed int/boolean post ID if found; else false
531
+ */
532
+ function mc_get_event_post( $event_id ) {
533
+ $event = mc_get_event_core( $event_id );
534
+ if ( is_object( $event ) ) {
535
+ if ( property_exists( $event, 'event_post' ) && get_post_status( $event->event_post ) ) {
536
+ return $event->event_post;
537
+ }
538
+ }
539
+ return false;
540
+ }
541
+
542
  // Grab all events for the requested date from calendar
543
  function my_calendar_grab_events( $from, $to, $category = null, $ltype = '', $lvalue = '', $source = 'calendar', $author = null, $host = null, $holidays = null, $search = '', $site = false ) {
544
  global $wpdb;
545
  $mcdb = $wpdb;
546
+
547
  if ( get_option( 'mc_remote' ) == 'true' && function_exists( 'mc_remote_db' ) ) {
548
  $mcdb = mc_remote_db();
549
  }
614
  }
615
  }
616
 
617
+ $select_category = ( $ccategory != 'all' ) ? mc_select_category( $ccategory ) : '';
618
+ $select_author = ( $clauth != 'all' ) ? mc_select_author( $clauth ) : '';
619
+ $select_host = ( $clhost != 'all' ) ? mc_select_host( $clhost ) : '';
620
+ $select_location = mc_limit_string( 'grab', $cltype, $clvalue );
621
+ $exclude_categories = mc_private_categories();
622
+
623
 
624
  if ( $caching && $source != 'upcoming' ) {
625
  $select_category = '';
644
  OR DATE(occur_end) BETWEEN '$from 00:00:00' AND '$to 23:59:59'
645
  OR ( DATE('$from') BETWEEN DATE(occur_begin) AND DATE(occur_end) )
646
  OR ( DATE('$to') BETWEEN DATE(occur_begin) AND DATE(occur_end) ) )
647
+ $exclude_categories
648
  ORDER BY " . apply_filters( 'mc_primary_sort', 'occur_begin' ) . ", " . apply_filters( 'mc_secondary_sort', 'event_title ASC' );
649
  $events = $mcdb->get_results( $event_query );
650
 
671
  }
672
  }
673
 
674
+ // My Calendar does not currently have a draft status
675
+ function mc_event_published( $event ) {
676
+ if ( $event->event_approved == 1 ) {
677
+ return true;
678
+ }
679
+
680
+ return false;
681
+ }
682
+
683
  function mc_get_db_type() {
684
  global $wpdb;
685
  $mcdb = $wpdb;
my-calendar-group-manager.php CHANGED
@@ -86,7 +86,7 @@ function edit_my_calendar_groups() {
86
  }
87
  } ?>
88
 
89
- <div class="wrap jd-my-calendar" id="my-calendar"><?php
90
  my_calendar_check_db();
91
  if ( $action == 'edit' ) {
92
  ?>
86
  }
87
  } ?>
88
 
89
+ <div class="wrap my-calendar-admin" id="my-calendar"><?php
90
  my_calendar_check_db();
91
  if ( $action == 'edit' ) {
92
  ?>
my-calendar-help.php CHANGED
@@ -6,7 +6,7 @@ if ( ! defined( 'ABSPATH' ) ) {
6
  function my_calendar_help() {
7
  ?>
8
 
9
- <div class="wrap jd-my-calendar">
10
  <h1><?php _e( 'How to use My Calendar', 'my-calendar' ); ?></h1>
11
 
12
  <div class="postbox-container jcd-wide">
@@ -291,6 +291,9 @@ function my_calendar_help() {
291
  <dt><code>{multidate}</code></dt>
292
  <dd><?php _e( 'For multi-day events displays an unordered list of dates and times for events in this group. Otherwise, beginning date/time.', 'my-calendar' ); ?></dd>
293
 
 
 
 
294
  <dt><code>{author}</code></dt>
295
  <dd><?php _e( 'Displays the WordPress author who posted the event.', 'my-calendar' ); ?></dd>
296
 
6
  function my_calendar_help() {
7
  ?>
8
 
9
+ <div class="wrap my-calendar-admin">
10
  <h1><?php _e( 'How to use My Calendar', 'my-calendar' ); ?></h1>
11
 
12
  <div class="postbox-container jcd-wide">
291
  <dt><code>{multidate}</code></dt>
292
  <dd><?php _e( 'For multi-day events displays an unordered list of dates and times for events in this group. Otherwise, beginning date/time.', 'my-calendar' ); ?></dd>
293
 
294
+ <dt><code>{related}</code></dt>
295
+ <dd><?php _e( 'List of other events in the same event group. (Only on single event views.)', 'my-calendar' ); ?></dd>
296
+
297
  <dt><code>{author}</code></dt>
298
  <dd><?php _e( 'Displays the WordPress author who posted the event.', 'my-calendar' ); ?></dd>
299
 
my-calendar-locations.php CHANGED
@@ -85,7 +85,7 @@ function my_calendar_manage_locations() {
85
  global $wpdb;
86
  $mcdb = $wpdb;
87
  ?>
88
- <div class="wrap jd-my-calendar">
89
  <?php my_calendar_check_db();
90
  // We do some checking to see what we're doing
91
  mc_update_location_controls();
@@ -188,7 +188,9 @@ function mc_show_location_form( $view = 'add', $curID = '' ) {
188
  ?>
189
  <h1><?php _e( 'Add New Location', 'my-calendar' ); ?></h1>
190
  <?php } else { ?>
191
- <h1><?php _e( 'Edit Location', 'my-calendar' ); ?></h1>
 
 
192
  <?php } ?>
193
  <div class="postbox-container jcd-wide">
194
  <div class="metabox-holder">
@@ -360,8 +362,7 @@ function mc_manage_locations() {
360
  <?php } ?>
361
  </table>
362
  <p>
363
- <input type="submit" class="button-secondary delete" name="mass_delete"
364
- value="<?php _e( 'Delete locations', 'my-calendar' ); ?>"/>
365
  </p>
366
  </form><?php
367
  } else {
85
  global $wpdb;
86
  $mcdb = $wpdb;
87
  ?>
88
+ <div class="wrap my-calendar-admin">
89
  <?php my_calendar_check_db();
90
  // We do some checking to see what we're doing
91
  mc_update_location_controls();
188
  ?>
189
  <h1><?php _e( 'Add New Location', 'my-calendar' ); ?></h1>
190
  <?php } else { ?>
191
+ <h1 class="wp-heading-inline"><?php _e( 'Edit Location', 'my-calendar' ); ?></h1>
192
+ <a href="<?php echo admin_url( "admin.php?page=my-calendar-locations" ); ?>" class="page-title-action"><?php _e( 'Add New', 'my-calendar' ); ?></a>
193
+ <hr class="wp-header-end">
194
  <?php } ?>
195
  <div class="postbox-container jcd-wide">
196
  <div class="metabox-holder">
362
  <?php } ?>
363
  </table>
364
  <p>
365
+ <input type="submit" class="button-secondary delete" name="mass_delete" value="<?php _e( 'Delete locations', 'my-calendar' ); ?>" />
 
366
  </p>
367
  </form><?php
368
  } else {
my-calendar-output.php CHANGED
@@ -3,94 +3,17 @@ if ( ! defined( 'ABSPATH' ) ) {
3
  exit;
4
  } // Exit if accessed directly
5
 
6
- function mc_holiday_limit( $events, $holidays ) {
7
- foreach ( array_keys( $events ) as $key ) {
8
- if ( ! empty( $holidays[ $key ] ) ) {
9
- foreach ( $events[ $key ] as $k => $event ) {
10
- if ( $event->event_category != get_option( 'mc_skip_holidays_category' ) && $event->event_holiday == 1 ) {
11
- unset( $events[ $key ][ $k ] );
12
- }
13
- }
14
- }
15
- }
16
-
17
- return $events;
18
- }
19
-
20
- // Used to draw multiple events
21
- function mc_set_date_array( $events ) {
22
- $event_array = array();
23
- if ( is_array( $events ) ) {
24
- foreach ( $events as $event ) {
25
- $date = date( 'Y-m-d', strtotime( $event->occur_begin ) );
26
- $end = date( 'Y-m-d', strtotime( $event->occur_end ) );
27
- if ( $date != $end ) {
28
- $start = strtotime( $date );
29
- $end = strtotime( $end );
30
- do {
31
- $date = date( 'Y-m-d', $start );
32
- $event_array[ $date ][] = $event;
33
- $start = strtotime( "+1 day", $start );
34
- } while ( $start <= $end );
35
- } else {
36
- $event_array[ $date ][] = $event;
37
- }
38
- }
39
- }
40
-
41
- return $event_array;
42
- }
43
-
44
- function my_calendar_draw_events( $events, $type, $process_date, $time, $template = '' ) {
45
-
46
- if ( $type == 'mini' && ( get_option( 'mc_open_day_uri' ) == 'true' || get_option( 'mc_open_day_uri' ) == 'listanchor' || get_option( 'mc_open_day_uri' ) == 'calendaranchor' ) ) {
47
- return true;
48
- }
49
- // We need to sort arrays of objects by time
50
- if ( is_array( $events ) ) {
51
- $output_array = array();
52
- $begin = $event_output = $end = '';
53
- if ( $type == "mini" && count( $events ) > 0 ) {
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
- }
69
- }
70
- if ( is_array( $output_array ) ) {
71
- foreach ( array_keys( $output_array ) as $key ) {
72
- $value =& $output_array[ $key ];
73
- $event_output .= $value;
74
- }
75
- }
76
- if ( $event_output == '' ) {
77
- return '';
78
- }
79
- if ( $type == "mini" && count( $events ) > 0 ) {
80
- $end .= "</div>";
81
- }
82
-
83
- return $begin . $event_output . $end;
84
- }
85
-
86
- return '';
87
- }
88
-
89
  function mc_get_template( $template ) {
90
  $templates = get_option( 'mc_templates' );
91
- $template = $templates[ $template ];
92
 
93
- return $template;
 
 
 
 
 
 
94
  }
95
 
96
  function mc_time_html( $event, $type, $current_date ) {
@@ -103,25 +26,25 @@ function mc_time_html( $event, $type, $current_date ) {
103
  if ( $event->event_time != "00:00:00" && $event->event_time != '' ) {
104
  $time .= "\n
105
  <span class='event-time dtstart'>
106
- <time class='value-title' datetime='" . $id_start . 'T' . $event->event_time . "' title='" . $id_start . 'T' . $event->event_time . "'>" . date_i18n( get_option( 'mc_time_format' ), strtotime( $event->event_time ) ) . '</time>
 
 
107
  </span>';
108
  if ( $event->event_hide_end == 0 ) {
109
  if ( $event->event_endtime != '' && $event->event_endtime != $event->event_time ) {
110
  $time .= "
111
  <span class='time-separator'> &ndash; </span>
112
  <span class='end-time dtend'>
113
- <time class='value-title' datetime='" . $id_end . 'T' . $event->event_endtime . "' title='" . $id_end . 'T' . $event->event_endtime . "'>" . date_i18n( get_option( 'mc_time_format' ), strtotime( $event->event_endtime ) ) . "</time>
 
 
114
  </span>";
115
  }
116
  }
117
  } else {
 
118
  $time .= "<span class='event-time'>";
119
- $notime = mc_notime_label( $event );
120
- if ( $notime == "N/A" ) {
121
- $time .= "<abbr title='" . __( 'Not Applicable', 'my-calendar' ) . "'>" . __( 'N/A', 'my-calendar' ) . "</abbr>\n";
122
- } else {
123
- $time .= $notime;
124
- }
125
  $time .= "</span></p>";
126
  }
127
  $time .= apply_filters( 'mcs_end_time_block', '', $event );
@@ -131,6 +54,14 @@ function mc_time_html( $event, $type, $current_date ) {
131
  return apply_filters( 'mcs_time_block', $time, $event );
132
  }
133
 
 
 
 
 
 
 
 
 
134
  function mc_category_icon( $event, $html = 'html' ) {
135
  if ( is_object( $event ) ) {
136
  $url = plugin_dir_url( __FILE__ );
@@ -147,10 +78,13 @@ function mc_category_icon( $event, $html = 'html' ) {
147
  }
148
  }
149
 
150
- return $image;
151
  }
152
  }
153
 
 
 
 
154
  add_filter( 'the_title', 'mc_category_icon_title', 10, 2 );
155
  function mc_category_icon_title( $title, $post_id = null ) {
156
  if ( is_singular( 'mc-events' ) && in_the_loop() ) {
@@ -158,7 +92,7 @@ function mc_category_icon_title( $title, $post_id = null ) {
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 = '';
@@ -171,7 +105,74 @@ function mc_category_icon_title( $title, $post_id = null ) {
171
  return $title;
172
  }
173
 
174
- // Used to draw an event to the screen
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
175
  function my_calendar_draw_event( $event, $type = "calendar", $process_date, $time, $template = '' ) {
176
  // if event is not approved, return without processing
177
  if ( get_option( 'mc_event_approve' ) == 'true' && (int) $event->event_approved !== 1 ) {
@@ -247,9 +248,9 @@ function my_calendar_draw_event( $event, $type = "calendar", $process_date, $tim
247
 
248
  switch ( $type ) {
249
  case 'calendar' : $title_template = ( mc_get_template( 'title' ) == '' ) ? '{title}' : mc_get_template( 'title' ); break;
250
- case 'list' : $title_template = ( mc_get_template( 'title_list' ) == '' ) ? '{title}' : mc_get_template( 'title_list' ); break;
251
- case 'single' : $title_template = ( mc_get_template( 'title_solo' ) == '' ) ? '{title}' : mc_get_template( 'title_solo' ); break;
252
- default: $title_template = ( mc_get_template( 'title' ) == '' ) ? '{title}' : mc_get_template( 'title' );
253
  }
254
 
255
  $event_title = jd_draw_template( $data, $title_template );
@@ -299,7 +300,7 @@ function my_calendar_draw_event( $event, $type = "calendar", $process_date, $tim
299
  $author = '<p class="event-author">' . __( 'Posted by', 'my-calendar' ) . ' <span class="author-name">' . $e->display_name . "</span></p>\n";
300
  }
301
  }
302
-
303
  if ( $mc_display_more != 'false' && ! isset( $_GET['mc_id'] ) ) {
304
  $details_label = mc_get_details_label( $event, $data );
305
  $details_link = mc_get_details_link( $event );
@@ -310,8 +311,6 @@ function my_calendar_draw_event( $event, $type = "calendar", $process_date, $tim
310
  }
311
  }
312
  $more = apply_filters( 'mc_details_grid_link', $more, $event );
313
- // handle link expiration
314
- $event_link = mc_event_link( $event );
315
 
316
  if ( function_exists( 'mc_google_cal' ) && get_option( 'mc_show_gcal' ) == 'true' ) {
317
  $gcal_link = "<p class='gcal'>" . jd_draw_template( $data, '{gcal_link}' ) . "</p>";
@@ -330,16 +329,19 @@ function my_calendar_draw_event( $event, $type = "calendar", $process_date, $tim
330
  $default_size = 'thumbnail';
331
  }
332
  $default_size = apply_filters( 'mc_default_image_size', $default_size );
 
333
  if ( is_numeric( $event->event_post ) && $event->event_post != 0 && ( isset( $data[ $default_size ] ) && $data[ $default_size ] != '' ) ) {
334
  $atts = apply_filters( 'mc_post_thumbnail_atts', array( 'class' => 'mc-image photo' ) );
335
  $image = get_the_post_thumbnail( $event->event_post, $default_size, $atts );
336
  } else {
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>";
@@ -377,7 +379,9 @@ function my_calendar_draw_event( $event, $type = "calendar", $process_date, $tim
377
  } else {
378
  $map = '';
379
  }
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'";
@@ -414,10 +418,10 @@ function my_calendar_draw_event( $event, $type = "calendar", $process_date, $tim
414
  $container = "<div id='$uid-$day_id-$type-details' class='details$img_class' role='alert' aria-labelledby='$uid-$day_id-$type-title'>\n";
415
  $container = apply_filters( 'mc_before_event', $container, $event, $type, $time );
416
  $details = $header . $container . apply_filters( 'mc_inner_content', $details, $event, $type, $time );
417
- $details .= apply_filters( 'mc_after_event', '', $event, $type, $time );
418
- $details .= $close; // second close button
419
- $details .= "</div><!--ends .details--></div>";
420
- $details = apply_filters( 'mc_event_content', $details, $event, $type, $time );
421
  } else {
422
  $details = apply_filters( 'mc_before_event_no_details', $container, $event, $type, $time )
423
  . $header
@@ -430,18 +434,49 @@ function my_calendar_draw_event( $event, $type = "calendar", $process_date, $tim
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
  }
@@ -551,66 +586,17 @@ function mc_build_date_switcher( $type = 'calendar', $cid = 'all', $time = 'mont
551
  return $date_switcher;
552
  }
553
 
554
- function my_calendar_print() {
555
- $url = plugin_dir_url( __FILE__ );
556
- $time = ( isset( $_GET['time'] ) ) ? $_GET['time'] : 'month';
557
- $category = ( isset( $_GET['mcat'] ) ) ? $_GET['mcat'] : ''; // these are sanitized elsewhere
558
- $ltype = ( isset( $_GET['ltype'] ) ) ? $_GET['ltype'] : '';
559
- $lvalue = ( isset( $_GET['lvalue'] ) ) ? $_GET['lvalue'] : '';
560
- header( 'Content-Type: ' . get_bloginfo( 'html_type' ) . '; charset=' . get_bloginfo( 'charset' ) );
561
- if ( mc_file_exists( 'css/mc-print.css' ) ) {
562
- $stylesheet = mc_get_file( 'css/mc-print.css', 'url' );
563
- } else {
564
- $stylesheet = $url . "css/mc-print.css";
565
- }
566
- $rtl = ( is_rtl() ) ? 'rtl' : 'ltr';
567
- $head = '<!DOCTYPE html>
568
- <html dir="' . $rtl . '" lang="' . get_bloginfo( 'language' ) . '">
569
- <!--<![endif]-->
570
- <head>
571
- <meta charset="' . get_bloginfo( 'charset' ) . '" />
572
- <meta name="viewport" content="width=device-width" />
573
- <title>' . get_bloginfo( 'name' ) . ' - ' . __( 'Calendar: Print View', 'my-calendar' ) . '</title>
574
- <meta name="generator" content="My Calendar for WordPress" />
575
- <meta name="robots" content="noindex,nofollow" />
576
- <!-- Copy mc-print.css to your theme directory if you wish to replace the default print styles -->
577
- <link rel="stylesheet" href="' . $stylesheet. '" type="text/css" media="screen,print" />
578
- </head>
579
- <body>';
580
- echo $head;
581
- echo my_calendar( 'print', 'calendar', $category, $time, $ltype, $lvalue, 'mc-print-view', '', '', null, null, 'none', 'none' );
582
- $return_url = ( get_option( 'mc_uri' ) != '' && ! is_numeric( get_option( 'mc_uri' ) ) ) ? get_option( 'mc_uri' ) : home_url();
583
- $return_url = apply_filters( 'mc_print_return_url', $return_url, $category, $time, $ltype, $lvalue );
584
-
585
- if ( isset( $_GET['href'] ) ) {
586
- $ref_url = esc_url( urldecode( $_GET['href'] ) );
587
- if ( $ref_url ) {
588
- $return_url = $ref_url;
589
- }
590
- }
591
-
592
- $add = array_map( 'esc_sql', $_GET );
593
- unset( $add['cid'] );
594
- unset( $add['feed'] );
595
- unset( $add['href'] );
596
- $return_url = mc_build_url( $add, array( 'feed', 'cid', 'href' ), $return_url );
597
- echo "<p class='return'><a href='$return_url'>" . __( 'Return to calendar', 'my-calendar' ) . "</a></p>";
598
- echo '
599
- </body>
600
- </html>';
601
- }
602
-
603
  function mc_format_toggle( $format, $toggle, $time ) {
604
  if ( $format != 'mini' && $toggle == 'yes' && $time != 'day' ) {
605
  $toggle = "<div class='mc-format'>";
606
  switch ( $format ) {
607
  case 'list':
608
  $url = mc_build_url( array( 'format' => 'calendar' ), array() );
609
- $toggle .= "<a href='$url' class='grid'>" . __( '<span class="maybe-hide">View as </span>Grid', 'my-calendar' ) . "</a>";
610
  break;
611
  default:
612
  $url = mc_build_url( array( 'format' => 'list' ), array() );
613
- $toggle .= "<a href='$url' class='list'>" . __( '<span class="maybe-hide">View as </span>List', 'my-calendar' ) . "</a>";
614
  break;
615
  }
616
  $toggle .= "</div>";
@@ -632,21 +618,21 @@ function mc_time_toggle( $format, $time, $toggle, $day, $month, $year ) {
632
  switch ( $time ) {
633
  case 'week':
634
  $url = mc_build_url( array( 'time' => 'month' ), array( 'mc_id' ) );
635
- $toggle .= "<a href='$url'>" . __( 'Month', 'my-calendar' ) . "</a> ";
636
  $toggle .= "<span class='mc-active'>" . __( 'Week', 'my-calendar' ) . "</span>";
637
  $url = mc_build_url( array( 'time' => 'day', 'dy' => $day ), array( 'dy', 'mc_id' ) );
638
- $toggle .= " <a href='$url'>" . __( 'Day', 'my-calendar' ) . "</a>";
639
  break;
640
  case 'day':
641
  $url = mc_build_url( array( 'time' => 'month' ), array() );
642
- $toggle .= "<a href='$url'>" . __( 'Month', 'my-calendar' ) . "</a>";
643
  $url = mc_build_url( array(
644
  'time' => 'week',
645
  'dy' => $day,
646
  'month' => $month,
647
  'yr' => $year
648
  ), array( 'dy', 'month', 'mc_id' ) );
649
- $toggle .= " <a href='$url'>" . __( 'Week', 'my-calendar' ) . "</a> ";
650
  $toggle .= "<span class='mc-active'>" . __( 'Day', 'my-calendar' ) . "</span>";
651
  break;
652
  default:
@@ -656,9 +642,9 @@ function mc_time_toggle( $format, $time, $toggle, $day, $month, $year ) {
656
  'month',
657
  'mc_id'
658
  ) );
659
- $toggle .= " <a href='$url'>" . __( 'Week', 'my-calendar' ) . "</a> ";
660
  $url = mc_build_url( array( 'time' => 'day' ), array() );
661
- $toggle .= "<a href='$url'>" . __( 'Day', 'my-calendar' ) . "</a>";
662
  break;
663
  }
664
  $toggle .= "</div>";
@@ -717,13 +703,13 @@ function mc_events_class( $events, $date = false ) {
717
  $author = ' author' . $event->event_author;
718
  if ( strpos( $class, $author ) === false ) {
719
  $class .= $author;
720
- }
721
- $cat = ' mcat_' . sanitize_title( $event->category_name );
722
  if ( strpos( $class, $cat ) === false ) {
723
- $class .= $cat;
724
  }
725
  if ( $event->category_private == 1 && !is_user_logged_in() ) {
726
- $class = '';
727
  }
728
  }
729
  if ( $class ) {
@@ -947,7 +933,7 @@ function mc_hidden_event() {
947
  add_filter( 'the_content', 'mc_show_event_template', 100, 1 );
948
  function mc_show_event_template( $content ) {
949
  global $post;
950
- if ( is_object( $post ) && in_the_loop() ) {
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' ) {
@@ -996,7 +982,8 @@ function mc_event_is_hidden( $event ) {
996
  }
997
  $category = $event->event_category;
998
  $private = mc_get_private_categories();
999
- if ( in_array( $category, $private ) && !is_user_logged_in() ) {
 
1000
  return true;
1001
  }
1002
 
@@ -1100,7 +1087,7 @@ function my_calendar( $name, $format, $category, $time = 'month', $ltype = '', $
1100
  $format = apply_filters( 'mc_display_format', $format, $args );
1101
 
1102
  // mc body wrapper
1103
- $mc_wrapper = "<div id=\"$id\" class=\"mc-main $format $time $main_class\" aria-live='assertive' aria-atomic='true'>";
1104
  $mc_closer = "</div>";
1105
 
1106
  $date_format = ( get_option( 'mc_date_format' ) != '' ) ? get_option( 'mc_date_format' ) : get_option( 'date_format' );
@@ -1315,8 +1302,8 @@ function my_calendar( $name, $format, $category, $time = 'month', $ltype = '', $
1315
  'dy' => $nLink['day'],
1316
  'cid' => $main_class
1317
  ), array() );
1318
- $previous_link = apply_filters( 'mc_previous_link', '<li class="my-calendar-prev"><a href="' . $prevLink . '" rel="nofollow" data-rel="' . $id . '">' . $pLink['label'] . '</a></li>', $pLink );
1319
- $next_link = apply_filters( 'mc_next_link', '<li class="my-calendar-next"><a href="' . $nextLink . '" rel="nofollow" data-rel="' . $id . '">' . $nLink['label'] . '</a></li>', $nLink );
1320
  $nav = '
1321
  <div class="my-calendar-nav">
1322
  <ul>
@@ -1331,7 +1318,7 @@ function my_calendar( $name, $format, $category, $time = 'month', $ltype = '', $
1331
  if ( !isset( $nLink ) ) {
1332
  $nLink = my_calendar_next_link( $c_year, $c_month, $c_day, $format, $time, $mc_show_months );
1333
  }
1334
- $feeds = mc_rss_links( $ical_y, $ical_m, $nLink, $add, $subtract );
1335
  }
1336
  // set up date switcher
1337
  if ( in_array( 'jump', $used ) ) {
@@ -1373,7 +1360,7 @@ function my_calendar( $name, $format, $category, $time = 'month', $ltype = '', $
1373
 
1374
  if ( $time == 'day' ) {
1375
 
1376
- $my_calendar_body .= "<div class='mc-main $format $time'>" . $mc_topnav;
1377
  // single day uses independent cycling.
1378
  $dayclass = strtolower( date( 'D', mktime( 0, 0, 0, $c_month, $c_day, $c_year ) ) );
1379
  $from = $to = "$c_year-$c_month-$c_day";
@@ -1489,6 +1476,7 @@ function my_calendar( $name, $format, $category, $time = 'month', $ltype = '', $
1489
  // date-based classes
1490
  $monthclass = ( date( 'n', $start ) == $c_month || $time != 'month' ) ? '' : 'nextmonth';
1491
  $dateclass = mc_dateclass( time() + $offset, $start );
 
1492
  $dayclass = strtolower( date_i18n( 'D', $start ) );
1493
  $week_format = ( get_option( 'mc_week_format' ) == '' ) ? 'M j, \'y' : get_option( 'mc_week_format' );
1494
  $week_date_format = date_i18n( $week_format, $start );
@@ -1574,7 +1562,7 @@ function my_calendar( $name, $format, $category, $time = 'month', $ltype = '', $
1574
  }
1575
  if ( $event_output != '' ) {
1576
  $my_calendar_body .= "
1577
- <li id='$format-$date' class='mc-events " . esc_attr( "$dayclass $dateclass $events_class $odd" ) . "'>
1578
  <strong class=\"event-date\">$is_anchor" . date_i18n( apply_filters( 'mc_date_format', $date_format, 'list' ), $start ) . "$is_close_anchor" . "$title</strong>" .
1579
  $event_output . "
1580
  </li>";
@@ -1582,7 +1570,7 @@ function my_calendar( $name, $format, $category, $time = 'month', $ltype = '', $
1582
  }
1583
  } else {
1584
  $my_calendar_body .= "
1585
- <$td id='$format-$date' class='" . esc_attr( "$dayclass $dateclass $weekend_class $monthclass $events_class" ) . " day-with-date'>" . "
1586
  <$element class='mc-date $trigger'><span aria-hidden='true'>$thisday_heading</span><span class='screen-reader-text'>" . date_i18n( get_option( 'mc_date_format' ), strtotime( $date ) ) . "</span></$close>" .
1587
  $event_output . "
1588
  </$td>\n";
@@ -1593,13 +1581,13 @@ function my_calendar( $name, $format, $category, $time = 'month', $ltype = '', $
1593
  if ( $format != "list" ) {
1594
  $weekend_class = ( $is_weekend ) ? 'weekend' : '';
1595
  $my_calendar_body .= "
1596
- <$td class='no-events $dayclass $dateclass $weekend_class $monthclass day-with-date'>
1597
  <span class='mc-date no-events'><span aria-hidden='true'>$thisday_heading</span><span class='screen-reader-text'>" . date_i18n( get_option( 'mc_date_format' ), strtotime( $date ) ) . "</span></span>
1598
  </$td>\n";
1599
  } else {
1600
  if ( $show_all == true ) {
1601
  $my_calendar_body .= "
1602
- <li id='$format-$date' class='no-events $dayclass $dateclass $events_class $odd'>
1603
  <strong class=\"event-date\">$is_anchor" . date_i18n( $date_format, $start ) . "$is_close_anchor</strong></li>";
1604
  $odd = ( $odd == 'odd' ) ? 'even' : 'odd';
1605
  }
@@ -1618,11 +1606,16 @@ function my_calendar( $name, $format, $category, $time = 'month', $ltype = '', $
1618
  $end = ( $table == 'table' ) ? "\n</tbody>\n</table>" : "</div></$table>";
1619
  $my_calendar_body .= ( $format == "list" ) ? "\n</ul>" : $end;
1620
  } else {
1621
- if ( ! in_array( $format, array( 'list', 'calendar', 'mini' ) ) ) {
1622
- $my_calendar_body .= "<p class='mc-error-format'>" . __( "Unrecognized calendar format. Please use one of 'list', 'calendar', or 'mini'.", 'my-calendar' ) . "</p>";
1623
- }
1624
- if ( ! in_array( $time, array( 'day', 'week', 'month', 'month+1' ) ) ) {
1625
- $my_calendar_body .= "<p class='mc-error-time'>" . __( "Unrecognized calendar time period. Please use one of 'day', 'week', or 'month'.", 'my-calendar' ) . "</p>";
 
 
 
 
 
1626
  }
1627
  }
1628
  $my_calendar_body .= $mc_bottomnav;
@@ -1659,12 +1652,12 @@ function my_category_key( $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";
1663
  $path = ( is_custom_icon() ) ? str_replace( 'my-calendar', 'my-calendar-custom', $url ) : plugins_url( 'images/icons', __FILE__ ) . '/';
1664
 
1665
  foreach ( $categories as $cat ) {
1666
  $hex = ( strpos( $cat->category_color, '#' ) !== 0 ) ? '#' : '';
1667
- $class = sanitize_title( $cat->category_name );
1668
  if ( isset( $_GET['mcat'] ) && $_GET['mcat'] == $cat->category_id ) {
1669
  $class .= " current";
1670
  }
@@ -1673,13 +1666,13 @@ function my_category_key( $category ) {
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'] ) ) {
1682
- $key .= "<li class='all-categories'><a href='" . esc_url( remove_query_arg( 'mcat', mc_get_current_url() ) ) . "'>" . apply_filters( 'mc_text_all_categories', __( 'All Categories', 'my-calendar' ) ) . "</a></li>";
1683
  }
1684
  $key .= "</ul>\n</div>";
1685
  $key = apply_filters( 'mc_category_key', $key, $categories );
@@ -1688,12 +1681,15 @@ function my_category_key( $category ) {
1688
  }
1689
 
1690
 
1691
- function mc_rss_links( $y, $m, $next, $add, $subtract ) {
1692
  global $wp_rewrite;
1693
  $add['yr'] = $y;
1694
  $add['month'] = $m;
1695
  $add['nyr'] = $next['yr'];
1696
  $add['nmonth'] = $next['month'];
 
 
 
1697
 
1698
  $feed = mc_feed_base() . 'my-calendar-rss';
1699
  $ics = mc_build_url( $add, $subtract, mc_feed_base() . 'my-calendar-ics' );
@@ -2053,18 +2049,9 @@ function mc_build_url( $add, $subtract, $root = '' ) {
2053
  $variables[ $key ] = $value;
2054
  }
2055
  unset( $variables['page_id'] );
2056
- if ( $root == '' ) {
2057
- // root is set to empty when I want to reference the current location
2058
- $char = ( $wp_rewrite->using_permalinks() || is_front_page() || is_archive() ) ? '?' : '&amp;';
2059
- } else {
2060
- $char = ( $wp_rewrite->using_permalinks() ) ? '?' : '&amp;'; // this doesn't work -- may *never* need to be &. Consider
2061
- }
2062
- // escape this when you use it
2063
- if ( $wp_rewrite->using_index_permalinks() && strpos( $home, 'index.php' ) === false ) {
2064
- $home = str_replace( home_url(), home_url( '/' ) . 'index.php', $home );
2065
- }
2066
 
2067
- return $home . $char . http_build_query( $variables, '', '&amp;' );
2068
  }
2069
 
2070
  function my_calendar_show_locations( $datatype = 'name', $template = '' ) {
3
  exit;
4
  } // Exit if accessed directly
5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
  function mc_get_template( $template ) {
7
  $templates = get_option( 'mc_templates' );
8
+ $template = ( isset( $templates[ $template ] ) ) ? $templates[ $template ] : $template;
9
 
10
+ $keys = array( 'title', 'title_list', 'title_solo', 'link', 'mini', 'list', 'details', 'rss', 'grid' );
11
+
12
+ if ( in_array( $template, $keys ) ) {
13
+ $template = '';
14
+ }
15
+
16
+ return trim( $template );
17
  }
18
 
19
  function mc_time_html( $event, $type, $current_date ) {
26
  if ( $event->event_time != "00:00:00" && $event->event_time != '' ) {
27
  $time .= "\n
28
  <span class='event-time dtstart'>
29
+ <time class='value-title' datetime='" . $id_start . 'T' . $event->event_time . "' title='" . $id_start . 'T' . $event->event_time . "'>" .
30
+ date_i18n( get_option( 'mc_time_format' ), strtotime( $event->event_time ) ) . '
31
+ </time>
32
  </span>';
33
  if ( $event->event_hide_end == 0 ) {
34
  if ( $event->event_endtime != '' && $event->event_endtime != $event->event_time ) {
35
  $time .= "
36
  <span class='time-separator'> &ndash; </span>
37
  <span class='end-time dtend'>
38
+ <time class='value-title' datetime='" . $id_end . 'T' . $event->event_endtime . "' title='" . $id_end . 'T' . $event->event_endtime . "'>" .
39
+ date_i18n( get_option( 'mc_time_format' ), strtotime( $event->event_endtime ) ) . "
40
+ </time>
41
  </span>";
42
  }
43
  }
44
  } else {
45
+ $notime = mc_notime_label( $event );
46
  $time .= "<span class='event-time'>";
47
+ $time .= ( $notime == "N/A" ) ? "<abbr title='" . __( 'Not Applicable', 'my-calendar' ) . "'>" . __( 'N/A', 'my-calendar' ) . "</abbr>\n" : $notime;
 
 
 
 
 
48
  $time .= "</span></p>";
49
  }
50
  $time .= apply_filters( 'mcs_end_time_block', '', $event );
54
  return apply_filters( 'mcs_time_block', $time, $event );
55
  }
56
 
57
+ /**
58
+ * Produce filepath & name or full img HTML for specific category's icon
59
+ *
60
+ * @param object $event Current event object
61
+ * @param string $html 'html' to generate HTML
62
+ *
63
+ * @return string image path or HTML
64
+ */
65
  function mc_category_icon( $event, $html = 'html' ) {
66
  if ( is_object( $event ) ) {
67
  $url = plugin_dir_url( __FILE__ );
78
  }
79
  }
80
 
81
+ return apply_filters( 'mc_category_icon', $image, $event, $html );
82
  }
83
  }
84
 
85
+ /**
86
+ * Add category icon into title on individual event pages.
87
+ */
88
  add_filter( 'the_title', 'mc_category_icon_title', 10, 2 );
89
  function mc_category_icon_title( $title, $post_id = null ) {
90
  if ( is_singular( 'mc-events' ) && in_the_loop() ) {
92
  $event_id = ( isset( $_GET['mc_id'] ) && is_numeric( $_GET['mc_id'] ) ) ? $_GET['mc_id'] : get_post_meta( $post_id, '_mc_event_id', true );
93
  if ( is_numeric( $event_id ) ) {
94
  $event = mc_get_event_core( $event_id );
95
+ if ( is_object( $event ) && property_exists( $event, 'category_icon' ) ) {
96
  $icon = mc_category_icon( $event );
97
  } else {
98
  $icon = '';
105
  return $title;
106
  }
107
 
108
+ /**
109
+ * Generate the set of events for a given day
110
+ *
111
+ * @param array $events Array of event objects
112
+ * @param string $type Type of display being viewed.
113
+ * @param string $process_date String formatted date being displayed.
114
+ * @param string $time Time view (month, week, day)
115
+ * @param string $template Template to use for drawing individual events.
116
+ *
117
+ * @return string Generated HTML.
118
+ */
119
+ function my_calendar_draw_events( $events, $type, $process_date, $time, $template = '' ) {
120
+
121
+ if ( $type == 'mini' && ( get_option( 'mc_open_day_uri' ) == 'true' || get_option( 'mc_open_day_uri' ) == 'listanchor' || get_option( 'mc_open_day_uri' ) == 'calendaranchor' ) ) {
122
+ return true;
123
+ }
124
+ // We need to sort arrays of objects by time
125
+ if ( is_array( $events ) ) {
126
+ $output_array = array();
127
+ $begin = $event_output = $end = '';
128
+ if ( $type == "mini" && count( $events ) > 0 ) {
129
+ $begin .= "<div id='date-$process_date' class='calendar-events'>";
130
+ }
131
+ foreach ( array_keys( $events ) as $key ) {
132
+ $event =& $events[ $key ];
133
+ if ( $event->event_recur != 'S1' ) {
134
+ $check = get_post_meta( $event->event_post, '_occurrence_overlap', true );
135
+ if ( $check == 'false' ) {
136
+ $check = mc_test_occurrence_overlap( $event, true );
137
+ }
138
+ } else {
139
+ $check = '';
140
+ }
141
+ if ( $check == '' ) {
142
+ $output_array[] = my_calendar_draw_event( $event, $type, $process_date, $time, $template );
143
+ }
144
+ }
145
+ if ( is_array( $output_array ) ) {
146
+ foreach ( array_keys( $output_array ) as $key ) {
147
+ $value =& $output_array[ $key ];
148
+ $event_output .= $value;
149
+ }
150
+ }
151
+ if ( $event_output == '' ) {
152
+ return '';
153
+ }
154
+ if ( $type == "mini" && count( $events ) > 0 ) {
155
+ $end .= "</div>";
156
+ }
157
+
158
+ return $begin . $event_output . $end;
159
+ }
160
+
161
+ return '';
162
+ }
163
+
164
+
165
+ /**
166
+ * Draw a single event
167
+ *
168
+ * @param object $event Event object
169
+ * @param string $type Type of view being drawn
170
+ * @param string $process_date Current date being displayed
171
+ * @param string $time Time view being drawn
172
+ * @param string $template Template to use to draw event.
173
+ *
174
+ * @return string Generated HTML.
175
+ */
176
  function my_calendar_draw_event( $event, $type = "calendar", $process_date, $time, $template = '' ) {
177
  // if event is not approved, return without processing
178
  if ( get_option( 'mc_event_approve' ) == 'true' && (int) $event->event_approved !== 1 ) {
248
 
249
  switch ( $type ) {
250
  case 'calendar' : $title_template = ( mc_get_template( 'title' ) == '' ) ? '{title}' : mc_get_template( 'title' ); break;
251
+ case 'list' : $title_template = ( mc_get_template( 'title_list' ) == '' ) ? '{title}' : mc_get_template( 'title_list' ); break;
252
+ case 'single' : $title_template = ( mc_get_template( 'title_solo' ) == '' ) ? '{title}' : mc_get_template( 'title_solo' ); break;
253
+ default: $title_template = ( mc_get_template( 'title' ) == '' ) ? '{title}' : mc_get_template( 'title' );
254
  }
255
 
256
  $event_title = jd_draw_template( $data, $title_template );
300
  $author = '<p class="event-author">' . __( 'Posted by', 'my-calendar' ) . ' <span class="author-name">' . $e->display_name . "</span></p>\n";
301
  }
302
  }
303
+
304
  if ( $mc_display_more != 'false' && ! isset( $_GET['mc_id'] ) ) {
305
  $details_label = mc_get_details_label( $event, $data );
306
  $details_link = mc_get_details_link( $event );
311
  }
312
  }
313
  $more = apply_filters( 'mc_details_grid_link', $more, $event );
 
 
314
 
315
  if ( function_exists( 'mc_google_cal' ) && get_option( 'mc_show_gcal' ) == 'true' ) {
316
  $gcal_link = "<p class='gcal'>" . jd_draw_template( $data, '{gcal_link}' ) . "</p>";
329
  $default_size = 'thumbnail';
330
  }
331
  $default_size = apply_filters( 'mc_default_image_size', $default_size );
332
+
333
  if ( is_numeric( $event->event_post ) && $event->event_post != 0 && ( isset( $data[ $default_size ] ) && $data[ $default_size ] != '' ) ) {
334
  $atts = apply_filters( 'mc_post_thumbnail_atts', array( 'class' => 'mc-image photo' ) );
335
  $image = get_the_post_thumbnail( $event->event_post, $default_size, $atts );
336
  } else {
337
  $image = ( $event->event_image != '' ) ? "<img src='$event->event_image' alt='' class='mc-image photo' />" : '';
338
  }
339
+
340
  if ( get_option( 'mc_desc' ) == 'true' || $type == 'single' ) {
341
  $description = wpautop( stripcslashes( mc_kses_post( $event->event_desc ) ), 1 );
342
  $description = "<div class='longdesc description'>$description</div>";
343
  }
344
+
345
  if ( get_option( 'mc_short' ) == 'true' && $type != 'single' ) {
346
  $short = wpautop( stripcslashes( mc_kses_post( $event->event_short ) ), 1 );
347
  $short = "<div class='shortdesc'>$short</div>";
379
  } else {
380
  $map = '';
381
  }
382
+ // handle link expiration
383
+ $event_link = mc_event_link( $event );
384
+
385
  if ( $event_link != '' && get_option( 'mc_event_link' ) != 'false' ) {
386
  $is_external = mc_external_link( $event_link );
387
  $external_class = ( $is_external ) ? "class='$type-link external url'" : "class='$type-link url'";
418
  $container = "<div id='$uid-$day_id-$type-details' class='details$img_class' role='alert' aria-labelledby='$uid-$day_id-$type-title'>\n";
419
  $container = apply_filters( 'mc_before_event', $container, $event, $type, $time );
420
  $details = $header . $container . apply_filters( 'mc_inner_content', $details, $event, $type, $time );
421
+ $details .= apply_filters( 'mc_after_event', '', $event, $type, $time );
422
+ $details .= $close; // second close button
423
+ $details .= "</div><!--end .details--></div>";
424
+ $details = apply_filters( 'mc_event_content', $details, $event, $type, $time );
425
  } else {
426
  $details = apply_filters( 'mc_before_event_no_details', $container, $event, $type, $time )
427
  . $header
434
 
435
  function mc_event_classes( $event, $uid, $type ) {
436
  $uid = 'mc_' . $event->occur_id;
437
+ $ts = strtotime( get_date_from_gmt( date( 'Y-m-d H:i:s', $event->ts_occur_begin ) ) );
438
+ $end = strtotime( get_date_from_gmt( date( 'Y-m-d H:i:s', $event->ts_occur_end ) ) );
439
+ $now = current_time( 'timestamp' );
440
+ if ( $ts < $now && $end > $now ) {
441
+ $date_relation = 'on-now';
442
+ } else if ( $now < $ts ) {
443
+ $date_relation = 'future-event';
444
+ } else if ( $now > $ts ) {
445
+ $date_relation = 'past-event';
446
+ }
447
+
448
  $classes = array(
449
  'mc-' . $uid,
450
  $type . '-event',
451
+ mc_category_class( $event, 'mc_' ),
452
+ 'vevent',
453
+ $date_relation
454
  );
455
+
456
  $classes = apply_filters( 'mc_event_classes', $classes, $event, $uid, $type );
457
  $class_html = strtolower( implode( ' ', $classes ) );
458
 
459
  return esc_attr( $class_html );
460
  }
461
 
462
+ function mc_category_class( $object, $prefix ) {
463
+ if ( is_array( $object ) ) {
464
+ $term = $object['term'];
465
+ $name = $object['category'];
466
+ } else {
467
+ $term = $object->category_term;
468
+ $name = $object->category_name;
469
+ }
470
+ $fallback = get_term_by( 'id', $term, 'mc-event-category' );
471
+ if ( is_object( $fallback ) ) {
472
+ $fallback = $fallback->slug;
473
+ } else {
474
+ $fallback = 'category_slug_missing';
475
+ }
476
+
477
+ return $prefix . strtolower( sanitize_html_class( str_replace( ' ', '-', $name ), $prefix . $fallback ) );
478
+ }
479
+
480
  function mc_show_details( $time, $type ) {
481
  return ( $type == 'calendar' && get_option( 'mc_open_uri' ) == 'true' && $time != 'day' ) ? false : true;
482
  }
586
  return $date_switcher;
587
  }
588
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
589
  function mc_format_toggle( $format, $toggle, $time ) {
590
  if ( $format != 'mini' && $toggle == 'yes' && $time != 'day' ) {
591
  $toggle = "<div class='mc-format'>";
592
  switch ( $format ) {
593
  case 'list':
594
  $url = mc_build_url( array( 'format' => 'calendar' ), array() );
595
+ $toggle .= "<a href='$url' class='grid mcajax'>" . __( '<span class="maybe-hide">View as </span>Grid', 'my-calendar' ) . "</a>";
596
  break;
597
  default:
598
  $url = mc_build_url( array( 'format' => 'list' ), array() );
599
+ $toggle .= "<a href='$url' class='list mcajax'>" . __( '<span class="maybe-hide">View as </span>List', 'my-calendar' ) . "</a>";
600
  break;
601
  }
602
  $toggle .= "</div>";
618
  switch ( $time ) {
619
  case 'week':
620
  $url = mc_build_url( array( 'time' => 'month' ), array( 'mc_id' ) );
621
+ $toggle .= "<a href='$url' class='month mcajax'>" . __( 'Month', 'my-calendar' ) . "</a> ";
622
  $toggle .= "<span class='mc-active'>" . __( 'Week', 'my-calendar' ) . "</span>";
623
  $url = mc_build_url( array( 'time' => 'day', 'dy' => $day ), array( 'dy', 'mc_id' ) );
624
+ $toggle .= " <a href='$url' class='day mcajax'>" . __( 'Day', 'my-calendar' ) . "</a>";
625
  break;
626
  case 'day':
627
  $url = mc_build_url( array( 'time' => 'month' ), array() );
628
+ $toggle .= "<a href='$url' class='month mcajax'>" . __( 'Month', 'my-calendar' ) . "</a>";
629
  $url = mc_build_url( array(
630
  'time' => 'week',
631
  'dy' => $day,
632
  'month' => $month,
633
  'yr' => $year
634
  ), array( 'dy', 'month', 'mc_id' ) );
635
+ $toggle .= " <a href='$url' class='week mcajax'>" . __( 'Week', 'my-calendar' ) . "</a> ";
636
  $toggle .= "<span class='mc-active'>" . __( 'Day', 'my-calendar' ) . "</span>";
637
  break;
638
  default:
642
  'month',
643
  'mc_id'
644
  ) );
645
+ $toggle .= " <a href='$url' class='week mcajax'>" . __( 'Week', 'my-calendar' ) . "</a> ";
646
  $url = mc_build_url( array( 'time' => 'day' ), array() );
647
+ $toggle .= "<a href='$url' class='day mcajax'>" . __( 'Day', 'my-calendar' ) . "</a>";
648
  break;
649
  }
650
  $toggle .= "</div>";
703
  $author = ' author' . $event->event_author;
704
  if ( strpos( $class, $author ) === false ) {
705
  $class .= $author;
706
+ }
707
+ $cat = mc_category_class( $event, 'mcat_' );
708
  if ( strpos( $class, $cat ) === false ) {
709
+ $class .= ' ' . $cat;
710
  }
711
  if ( $event->category_private == 1 && !is_user_logged_in() ) {
712
+ $class = ' private-event hidden';
713
  }
714
  }
715
  if ( $class ) {
933
  add_filter( 'the_content', 'mc_show_event_template', 100, 1 );
934
  function mc_show_event_template( $content ) {
935
  global $post;
936
+ if ( is_single() && in_the_loop() && is_main_query() ) {
937
  // some early versions of this placed the shortcode into the post content. Strip that out.
938
  $new_content = $content;
939
  if ( $post->post_type == 'mc-events' ) {
982
  }
983
  $category = $event->event_category;
984
  $private = mc_get_private_categories();
985
+ $can_see_private_events = apply_filters( 'mc_user_can_see_private_events', is_user_logged_in(), $event );
986
+ if ( in_array( $category, $private ) && !$can_see_private_events ) {
987
  return true;
988
  }
989
 
1087
  $format = apply_filters( 'mc_display_format', $format, $args );
1088
 
1089
  // mc body wrapper
1090
+ $mc_wrapper = "<div id=\"$id\" class=\"mc-main mcjs $format $time $main_class\" aria-live='assertive' aria-atomic='true'>";
1091
  $mc_closer = "</div>";
1092
 
1093
  $date_format = ( get_option( 'mc_date_format' ) != '' ) ? get_option( 'mc_date_format' ) : get_option( 'date_format' );
1302
  'dy' => $nLink['day'],
1303
  'cid' => $main_class
1304
  ), array() );
1305
+ $previous_link = apply_filters( 'mc_previous_link', '<li class="my-calendar-prev"><a href="' . $prevLink . '" rel="nofollow" class="mcajax">' . $pLink['label'] . '</a></li>', $pLink );
1306
+ $next_link = apply_filters( 'mc_next_link', '<li class="my-calendar-next"><a href="' . $nextLink . '" rel="nofollow" class="mcajax">' . $nLink['label'] . '</a></li>', $nLink );
1307
  $nav = '
1308
  <div class="my-calendar-nav">
1309
  <ul>
1318
  if ( !isset( $nLink ) ) {
1319
  $nLink = my_calendar_next_link( $c_year, $c_month, $c_day, $format, $time, $mc_show_months );
1320
  }
1321
+ $feeds = mc_rss_links( $ical_y, $ical_m, $nLink, $add, $subtract, $site );
1322
  }
1323
  // set up date switcher
1324
  if ( in_array( 'jump', $used ) ) {
1360
 
1361
  if ( $time == 'day' ) {
1362
 
1363
+ $my_calendar_body .= "<div class='mcjs $format $time'>" . $mc_topnav;
1364
  // single day uses independent cycling.
1365
  $dayclass = strtolower( date( 'D', mktime( 0, 0, 0, $c_month, $c_day, $c_year ) ) );
1366
  $from = $to = "$c_year-$c_month-$c_day";
1476
  // date-based classes
1477
  $monthclass = ( date( 'n', $start ) == $c_month || $time != 'month' ) ? '' : 'nextmonth';
1478
  $dateclass = mc_dateclass( time() + $offset, $start );
1479
+ $ariacurrent = ( $dateclass == 'current-day' ) ? ' aria-current="' . __( 'date', 'my-calendar' ) . '"' : '';
1480
  $dayclass = strtolower( date_i18n( 'D', $start ) );
1481
  $week_format = ( get_option( 'mc_week_format' ) == '' ) ? 'M j, \'y' : get_option( 'mc_week_format' );
1482
  $week_date_format = date_i18n( $week_format, $start );
1562
  }
1563
  if ( $event_output != '' ) {
1564
  $my_calendar_body .= "
1565
+ <li id='$format-$date' $ariacurrent class='mc-events " . esc_attr( "$dayclass $dateclass $events_class $odd" ) . "'>
1566
  <strong class=\"event-date\">$is_anchor" . date_i18n( apply_filters( 'mc_date_format', $date_format, 'list' ), $start ) . "$is_close_anchor" . "$title</strong>" .
1567
  $event_output . "
1568
  </li>";
1570
  }
1571
  } else {
1572
  $my_calendar_body .= "
1573
+ <$td id='$format-$date' $ariacurrent class='" . esc_attr( "$dayclass $dateclass $weekend_class $monthclass $events_class" ) . " day-with-date'>" . "
1574
  <$element class='mc-date $trigger'><span aria-hidden='true'>$thisday_heading</span><span class='screen-reader-text'>" . date_i18n( get_option( 'mc_date_format' ), strtotime( $date ) ) . "</span></$close>" .
1575
  $event_output . "
1576
  </$td>\n";
1581
  if ( $format != "list" ) {
1582
  $weekend_class = ( $is_weekend ) ? 'weekend' : '';
1583
  $my_calendar_body .= "
1584
+ <$td $ariacurrent class='no-events $dayclass $dateclass $weekend_class $monthclass day-with-date'>
1585
  <span class='mc-date no-events'><span aria-hidden='true'>$thisday_heading</span><span class='screen-reader-text'>" . date_i18n( get_option( 'mc_date_format' ), strtotime( $date ) ) . "</span></span>
1586
  </$td>\n";
1587
  } else {
1588
  if ( $show_all == true ) {
1589
  $my_calendar_body .= "
1590
+ <li id='$format-$date' $ariacurrent class='no-events $dayclass $dateclass $events_class $odd'>
1591
  <strong class=\"event-date\">$is_anchor" . date_i18n( $date_format, $start ) . "$is_close_anchor</strong></li>";
1592
  $odd = ( $odd == 'odd' ) ? 'even' : 'odd';
1593
  }
1606
  $end = ( $table == 'table' ) ? "\n</tbody>\n</table>" : "</div></$table>";
1607
  $my_calendar_body .= ( $format == "list" ) ? "\n</ul>" : $end;
1608
  } else {
1609
+ // only show error message if user has permissions
1610
+ if ( current_user_can( 'manage_options' ) ) {
1611
+ if ( ! in_array( $format, array( 'list', 'calendar', 'mini' ) ) ) {
1612
+ $yours = sprintf( esc_html__( "Your format: %s", 'my-calendar' ), $format );
1613
+ $my_calendar_body .= "<p class='mc-error-format'>" . __( "Unrecognized calendar format. Please use one of 'list', 'calendar', or 'mini'.", 'my-calendar' ) . "$yours</p>";
1614
+ }
1615
+ if ( ! in_array( $time, array( 'day', 'week', 'month', 'month+1' ) ) ) {
1616
+ $yours = sprintf( esc_html__( "Your time period: %s", 'my-calendar' ), $time );
1617
+ $my_calendar_body .= "<p class='mc-error-time'>" . __( "Unrecognized calendar time period. Please use one of 'day', 'week', or 'month'.", 'my-calendar' ) . "$yours</p>";
1618
+ }
1619
  }
1620
  }
1621
  $my_calendar_body .= $mc_bottomnav;
1652
  $sql = "SELECT * FROM " . my_calendar_categories_table() . " $cat_limit ORDER BY category_name ASC";
1653
  $categories = $mcdb->get_results( $sql );
1654
  $key .= '<div class="category-key">
1655
+ <h3>' . __( 'Categories', 'my-calendar' ) . "</h3>\n<ul>\n";
1656
  $path = ( is_custom_icon() ) ? str_replace( 'my-calendar', 'my-calendar-custom', $url ) : plugins_url( 'images/icons', __FILE__ ) . '/';
1657
 
1658
  foreach ( $categories as $cat ) {
1659
  $hex = ( strpos( $cat->category_color, '#' ) !== 0 ) ? '#' : '';
1660
+ $class = mc_category_class( $cat, '' );
1661
  if ( isset( $_GET['mcat'] ) && $_GET['mcat'] == $cat->category_id ) {
1662
  $class .= " current";
1663
  }
1666
  }
1667
  $url = mc_build_url( array( 'mcat' => $cat->category_id ), array( 'mcat' ) );
1668
  if ( $cat->category_icon != "" && get_option( 'mc_hide_icons' ) != 'true' ) {
1669
+ $key .= '<li class="cat_' . $class . '"><a href="' . esc_url( $url ) . '" class="mcajax"><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";
1670
  } else {
1671
+ $key .= '<li class="cat_' . $class . '"><a href="' . esc_url( $url ) . '" class="mcajax"><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";
1672
  }
1673
  }
1674
  if ( isset( $_GET['mcat'] ) ) {
1675
+ $key .= "<li class='all-categories'><a href='" . esc_url( mc_build_url( array(), array( 'mcat' ), mc_get_current_url() ) ) . "' class='mcajax'>" . apply_filters( 'mc_text_all_categories', __( 'All Categories', 'my-calendar' ) ) . "</a></li>";
1676
  }
1677
  $key .= "</ul>\n</div>";
1678
  $key = apply_filters( 'mc_category_key', $key, $categories );
1681
  }
1682
 
1683
 
1684
+ function mc_rss_links( $y, $m, $next, $add, $subtract, $site ) {
1685
  global $wp_rewrite;
1686
  $add['yr'] = $y;
1687
  $add['month'] = $m;
1688
  $add['nyr'] = $next['yr'];
1689
  $add['nmonth'] = $next['month'];
1690
+ if ( $site ) {
1691
+ $add['site'] == $site;
1692
+ }
1693
 
1694
  $feed = mc_feed_base() . 'my-calendar-rss';
1695
  $ics = mc_build_url( $add, $subtract, mc_feed_base() . 'my-calendar-ics' );
2049
  $variables[ $key ] = $value;
2050
  }
2051
  unset( $variables['page_id'] );
2052
+ $home = add_query_arg( $variables, $home );
 
 
 
 
 
 
 
 
 
2053
 
2054
+ return esc_url( $home );
2055
  }
2056
 
2057
  function my_calendar_show_locations( $datatype = 'name', $template = '' ) {
my-calendar-print.php ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( ! defined( 'ABSPATH' ) ) {
3
+ exit;
4
+ } // Exit if accessed directly
5
+
6
+ add_action( 'template_redirect', 'my_calendar_print_view' );
7
+ function my_calendar_print_view() {
8
+ if ( isset( $_GET['cid'] ) && $_GET['cid'] == 'mc-print-view' ) {
9
+ echo my_calendar_print();
10
+ exit;
11
+ }
12
+ }
13
+
14
+
15
+ function my_calendar_print() {
16
+ $url = plugin_dir_url( __FILE__ );
17
+ $time = ( isset( $_GET['time'] ) ) ? $_GET['time'] : 'month';
18
+ $category = ( isset( $_GET['mcat'] ) ) ? $_GET['mcat'] : ''; // these are sanitized elsewhere
19
+ $ltype = ( isset( $_GET['ltype'] ) ) ? $_GET['ltype'] : '';
20
+ $lvalue = ( isset( $_GET['lvalue'] ) ) ? $_GET['lvalue'] : '';
21
+ header( 'Content-Type: ' . get_bloginfo( 'html_type' ) . '; charset=' . get_bloginfo( 'charset' ) );
22
+ if ( mc_file_exists( 'css/mc-print.css' ) ) {
23
+ $stylesheet = mc_get_file( 'css/mc-print.css', 'url' );
24
+ } else {
25
+ $stylesheet = $url . "css/mc-print.css";
26
+ }
27
+ $rtl = ( is_rtl() ) ? 'rtl' : 'ltr';
28
+ $head = '<!DOCTYPE html>
29
+ <html dir="' . $rtl . '" lang="' . get_bloginfo( 'language' ) . '">
30
+ <!--<![endif]-->
31
+ <head>
32
+ <meta charset="' . get_bloginfo( 'charset' ) . '" />
33
+ <meta name="viewport" content="width=device-width" />
34
+ <title>' . get_bloginfo( 'name' ) . ' - ' . __( 'Calendar: Print View', 'my-calendar' ) . '</title>
35
+ <meta name="generator" content="My Calendar for WordPress" />
36
+ <meta name="robots" content="noindex,nofollow" />
37
+ <!-- Copy mc-print.css to your theme directory if you wish to replace the default print styles -->
38
+ <link rel="stylesheet" href="' . $stylesheet. '" type="text/css" media="screen,print" />' .
39
+ do_action( 'mc_print_view_head', '' )
40
+ . '
41
+ </head>
42
+ <body>';
43
+ echo $head;
44
+ echo my_calendar( 'print', 'calendar', $category, $time, $ltype, $lvalue, 'mc-print-view', '', '', null, null, 'none', 'none' );
45
+ $return_url = ( get_option( 'mc_uri' ) != '' && ! is_numeric( get_option( 'mc_uri' ) ) ) ? get_option( 'mc_uri' ) : home_url();
46
+ $return_url = apply_filters( 'mc_print_return_url', $return_url, $category, $time, $ltype, $lvalue );
47
+
48
+ if ( isset( $_GET['href'] ) ) {
49
+ $ref_url = esc_url( urldecode( $_GET['href'] ) );
50
+ if ( $ref_url ) {
51
+ $return_url = $ref_url;
52
+ }
53
+ }
54
+
55
+ $add = array_map( 'esc_sql', $_GET );
56
+ unset( $add['cid'] );
57
+ unset( $add['feed'] );
58
+ unset( $add['href'] );
59
+ $return_url = mc_build_url( $add, array( 'feed', 'cid', 'href' ), $return_url );
60
+ echo "<p class='return'><a href='$return_url'>" . __( 'Return to calendar', 'my-calendar' ) . "</a></p>";
61
+ echo '
62
+ </body>
63
+ </html>';
64
+ }
my-calendar-settings.php CHANGED
@@ -393,7 +393,7 @@ function edit_my_calendar_config() {
393
  $mc_link_label = ( isset( $templates['link'] ) ) ? esc_attr( stripslashes( $templates['link'] ) ) : '';
394
  ?>
395
 
396
- <div class="wrap jd-my-calendar mc-settings-page" id="mc_settings">
397
  <?php my_calendar_check_db(); ?>
398
  <h1><?php _e( 'My Calendar Settings', 'my-calendar' ); ?></h1>
399
 
@@ -482,8 +482,7 @@ function edit_my_calendar_config() {
482
  '5' => __( 'Author', 'my-calendar' ),
483
  '6' => __( 'Category', 'my-calendar' ),
484
  '7' => __( 'Location Name', 'my-calendar' )
485
- ), '', array(), 'select' ); ?></li>
486
- <li><?php mc_settings_field( 'mc_default_direction', __( 'Sort direction', 'my-calendar' ), array(
487
  'ASC' => __( 'Ascending', 'my-calendar' ),
488
  'DESC' => __( 'Descending', 'my-calendar' )
489
  ), '', array(), 'select' ); ?></li>
@@ -637,16 +636,7 @@ function edit_my_calendar_config() {
637
  } else {
638
  $label = $k;
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>";
651
  echo "<li class='ui-state-default mc-$k mc-$class'>$buttons <code>$label</code> $v <input type='hidden' name='mc_nav[]' value='$k' /></li>";
652
  $i++;
@@ -678,8 +668,8 @@ function edit_my_calendar_config() {
678
  <li><?php mc_settings_field( 'mc_show_event_vcal', __( 'Link to single event iCal download', 'my-calendar' ), '', '', array(), 'checkbox-single' ); ?></li>
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>
393
  $mc_link_label = ( isset( $templates['link'] ) ) ? esc_attr( stripslashes( $templates['link'] ) ) : '';
394
  ?>
395
 
396
+ <div class="wrap my-calendar-admin mc-settings-page" id="mc_settings">
397
  <?php my_calendar_check_db(); ?>
398
  <h1><?php _e( 'My Calendar Settings', 'my-calendar' ); ?></h1>
399
 
482
  '5' => __( 'Author', 'my-calendar' ),
483
  '6' => __( 'Category', 'my-calendar' ),
484
  '7' => __( 'Location Name', 'my-calendar' )
485
+ ), '', array(), 'select' ); ?> <?php mc_settings_field( 'mc_default_direction', __( 'Sort direction', 'my-calendar' ), array(
 
486
  'ASC' => __( 'Ascending', 'my-calendar' ),
487
  'DESC' => __( 'Descending', 'my-calendar' )
488
  ), '', array(), 'select' ); ?></li>
636
  } else {
637
  $label = $k;
638
  }
639
+ $buttons = "<button class='up' type='button'><i class='dashicons dashicons-arrow-up' aria-hidden='true'></i><span class='screen-reader-text'>Up</span></button> <button class='down'><i class='dashicons dashicons-arrow-down' aria-hidden='true'></i><span class='screen-reader-text'>Down</span></button>";
 
 
 
 
 
 
 
 
 
640
  $buttons = "<div class='mc-buttons'>$buttons</div>";
641
  echo "<li class='ui-state-default mc-$k mc-$class'>$buttons <code>$label</code> $v <input type='hidden' name='mc_nav[]' value='$k' /></li>";
642
  $i++;
668
  <li><?php mc_settings_field( 'mc_show_event_vcal', __( 'Link to single event iCal download', 'my-calendar' ), '', '', array(), 'checkbox-single' ); ?></li>
669
  <li><?php mc_settings_field( 'mc_show_gcal', __( 'Link to submit event to Google Calendar', 'my-calendar' ), '', '', array(), 'checkbox-single' ); ?></li>
670
  <li><?php mc_settings_field( 'mc_show_map', __( 'Link to Google Map', 'my-calendar' ), '', '', array(), 'checkbox-single' ); ?></li>
671
+ <li><?php mc_settings_field( 'mc_gmap', __( 'Google Map (single view only)', 'my-calendar' ), '', '', array(), 'checkbox-single' ); ?></li>
672
+ <li class="mc_gmap_api_key"><?php mc_settings_field( 'mc_gmap_api_key', __( 'Google Maps API Key', 'my-calendar' ) ); ?></li>
673
  <li><?php mc_settings_field( 'mc_show_address', __( 'Event Address', 'my-calendar' ), '', '', array(), 'checkbox-single' ); ?></li>
674
  <li><?php mc_settings_field( 'mc_short', __( 'Short description', 'my-calendar' ), '', '', array(), 'checkbox-single' ); ?></li>
675
  <li><?php mc_settings_field( 'mc_desc', __( 'Full description', 'my-calendar' ), '', '', array(), 'checkbox-single' ); ?></li>
my-calendar-styles.php CHANGED
@@ -166,7 +166,7 @@ function edit_my_calendar_styles() {
166
  $my_calendar_style = __( 'Sorry. The file you are looking for doesn\'t appear to exist. Please check your file name and location!', 'my-calendar' );
167
  }
168
  ?>
169
- <div class="wrap jd-my-calendar">
170
  <?php my_calendar_check_db(); ?>
171
  <h1><?php _e( 'My Calendar Styles', 'my-calendar' ); ?></h1>
172
  <div class="postbox-container jcd-wide">
@@ -276,7 +276,7 @@ function edit_my_calendar_styles() {
276
  $right_string = normalize_whitespace( $mc_current_style );
277
  if ( $right_string ) { // if right string is blank, there is no default
278
  if ( isset( $_GET['diff'] ) ) {
279
- echo '<div class="wrap jd-my-calendar" id="diff">';
280
  echo mc_text_diff( $left_string, $right_string, array(
281
  'title' => __( 'Comparing Your Style with latest installed version of My Calendar', 'my-calendar' ),
282
  'title_right' => __( 'Latest (from plugin)', 'my-calendar' ),
@@ -284,12 +284,12 @@ function edit_my_calendar_styles() {
284
  ) );
285
  echo '</div>';
286
  } else if ( trim( $left_string ) != trim( $right_string ) ) {
287
- echo '<div class="wrap jd-my-calendar">';
288
  echo '<div class="updated"><p>' . __( 'There have been updates to the stylesheet.', 'my-calendar' ) . ' <a href="' . admin_url( "admin.php?page=my-calendar-styles&amp;diff#diff" ) . '">' . __( 'Compare Your Stylesheet with latest installed version of My Calendar.', 'my-calendar' ) . '</a></p></div>';
289
  echo '</div>';
290
  } else {
291
  echo '
292
- <div class="wrap jd-my-calendar">
293
  <p>' . __( 'Your stylesheet matches that included with My Calendar.', 'my-calendar' ) . '</p>
294
  </div>';
295
  }
166
  $my_calendar_style = __( 'Sorry. The file you are looking for doesn\'t appear to exist. Please check your file name and location!', 'my-calendar' );
167
  }
168
  ?>
169
+ <div class="wrap my-calendar-admin">
170
  <?php my_calendar_check_db(); ?>
171
  <h1><?php _e( 'My Calendar Styles', 'my-calendar' ); ?></h1>
172
  <div class="postbox-container jcd-wide">
276
  $right_string = normalize_whitespace( $mc_current_style );
277
  if ( $right_string ) { // if right string is blank, there is no default
278
  if ( isset( $_GET['diff'] ) ) {
279
+ echo '<div class="wrap my-calendar-admin" id="diff">';
280
  echo mc_text_diff( $left_string, $right_string, array(
281
  'title' => __( 'Comparing Your Style with latest installed version of My Calendar', 'my-calendar' ),
282
  'title_right' => __( 'Latest (from plugin)', 'my-calendar' ),
284
  ) );
285
  echo '</div>';
286
  } else if ( trim( $left_string ) != trim( $right_string ) ) {
287
+ echo '<div class="wrap my-calendar-admin">';
288
  echo '<div class="updated"><p>' . __( 'There have been updates to the stylesheet.', 'my-calendar' ) . ' <a href="' . admin_url( "admin.php?page=my-calendar-styles&amp;diff#diff" ) . '">' . __( 'Compare Your Stylesheet with latest installed version of My Calendar.', 'my-calendar' ) . '</a></p></div>';
289
  echo '</div>';
290
  } else {
291
  echo '
292
+ <div class="wrap my-calendar-admin">
293
  <p>' . __( 'Your stylesheet matches that included with My Calendar.', 'my-calendar' ) . '</p>
294
  </div>';
295
  }
my-calendar-templates.php CHANGED
@@ -9,12 +9,13 @@ function jd_draw_template( $array, $template, $type = 'list' ) {
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 {
17
- if ( strpos( $template, "{" . $key ) !== false ) {
18
  if ( $type != 'list' ) {
19
  if ( $key == 'link' && $value == '' ) {
20
  $value = ( get_option( 'mc_uri' ) != '' && ! is_numeric( get_option( 'mc_uri' ) ) ) ? get_option( 'mc_uri' ) : home_url();
@@ -22,21 +23,21 @@ function jd_draw_template( $array, $template, $type = 'list' ) {
22
  if ( $key != 'guid' ) {
23
  $value = htmlentities( $value );
24
  }
25
- }
26
  if ( strpos( $template, "{" . $key . " " ) !== false ) { // only do preg_match if appropriate
27
  preg_match_all( '/{' . $key . '\b(?>\s+(?:before="([^"]*)"|after="([^"]*)"|format="([^"]*)")|[^\s]+|\s+){0,3}}/', $template, $matches, PREG_PATTERN_ORDER );
28
  if ( $matches ) {
29
  $number = count( $matches[0] );
30
- for ( $i=0; $i<=$number; $i++ ) {
31
  $orig = $value;
32
- $before = @$matches[1][$i];
33
- $after = @$matches[2][$i];
34
- $format = @$matches[3][$i];
35
  if ( $format != '' ) {
36
  $value = date_i18n( stripslashes( $format ), strtotime( stripslashes( $value ) ) );
37
  }
38
  $value = ( $value == '' ) ? '' : $before . $value . $after;
39
- $search = @$matches[0][$i];
40
  $template = str_replace( $search, $value, $template );
41
  $value = $orig;
42
  }
@@ -252,7 +253,7 @@ function mc_create_tags( $event, $context = 'filters' ) {
252
  $real_begin_date = ( isset( $event->occur_begin ) ) ? $event->occur_begin : $event->event_begin . ' ' . $event->event_time;
253
  $dtstart = mc_format_timestamp( strtotime( $real_begin_date ) );
254
  $dtend = mc_format_timestamp( strtotime( $real_end_date ) );
255
-
256
  $e['date_utc'] = date_i18n( apply_filters( 'mc_date_format', $date_format, 'template_begin_ts' ), $event->ts_occur_begin );
257
  $e['date_end_utc'] = date_i18n( apply_filters( 'mc_date_format', $date_format, 'template_end_ts' ), $event->ts_occur_end );
258
  $notime = mc_notime_label( $event );
@@ -287,6 +288,7 @@ function mc_create_tags( $event, $context = 'filters' ) {
287
  // category fields
288
  $e['cat_id'] = $event->event_category;
289
  $e['category'] = stripslashes( $event->category_name );
 
290
  $e['icon'] = mc_category_icon( $event, 'img' );
291
  $e['icon_html'] = "<img src='$e[icon]' class='mc-category-icon' alt='" . __( 'Category', 'my-calendar' ) . ": " . esc_attr( $event->category_name ) . "' />";
292
  $e['color'] = $event->category_color;
@@ -341,9 +343,11 @@ function mc_create_tags( $event, $context = 'filters' ) {
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
@@ -395,12 +399,12 @@ function mc_create_tags( $event, $context = 'filters' ) {
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 = '';
@@ -422,13 +426,37 @@ function mc_get_details_label( $event, $e ) {
422
  return $e_label;
423
  }
424
 
425
- function mc_format_timestamp( $os ) {
426
  $offset = ( 60 * 60 * get_option( 'gmt_offset' ) );
427
  $time = ( get_option( 'mc_ical_utc' ) == 'true' ) ? date( "Ymd\THi00", ( mktime( date( 'H', $os ), date( 'i', $os ), date( 's', $os ), date( 'm', $os ), date( 'd', $os ), date( 'Y', $os ) ) - ( $offset ) ) ) . "Z" : date( "Ymd\THi00", ( mktime( date( 'H', $os ), date( 'i', $os ), date( 's', $os ), date( 'm', $os ), date( 'd', $os ), date( 'Y', $os ) ) ) );
428
 
429
  return $time;
430
  }
431
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
432
  function mc_runtime( $start, $end, $event ) {
433
  if ( $event->event_hide_end || $start == $end || date( 'H:i:s', strtotime( $end ) ) == '23:59:59' ) {
434
  return '';
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', 'register' );
13
  $value = !( in_array( $key, $retain ) ) ? mc_kses_post( $value ) : $value;
14
+
15
  if ( is_object( $value ) && ! empty( $value ) ) {
16
  // null values return false...
17
  } else {
18
+ if ( strpos( $template, "{" . $key ) !== false ) {
19
  if ( $type != 'list' ) {
20
  if ( $key == 'link' && $value == '' ) {
21
  $value = ( get_option( 'mc_uri' ) != '' && ! is_numeric( get_option( 'mc_uri' ) ) ) ? get_option( 'mc_uri' ) : home_url();
23
  if ( $key != 'guid' ) {
24
  $value = htmlentities( $value );
25
  }
26
+ }
27
  if ( strpos( $template, "{" . $key . " " ) !== false ) { // only do preg_match if appropriate
28
  preg_match_all( '/{' . $key . '\b(?>\s+(?:before="([^"]*)"|after="([^"]*)"|format="([^"]*)")|[^\s]+|\s+){0,3}}/', $template, $matches, PREG_PATTERN_ORDER );
29
  if ( $matches ) {
30
  $number = count( $matches[0] );
31
+ for ( $i=0; $i<$number; $i++ ) {
32
  $orig = $value;
33
+ $before = $matches[1][$i];
34
+ $after = $matches[2][$i];
35
+ $format = $matches[3][$i];
36
  if ( $format != '' ) {
37
  $value = date_i18n( stripslashes( $format ), strtotime( stripslashes( $value ) ) );
38
  }
39
  $value = ( $value == '' ) ? '' : $before . $value . $after;
40
+ $search = $matches[0][$i];
41
  $template = str_replace( $search, $value, $template );
42
  $value = $orig;
43
  }
253
  $real_begin_date = ( isset( $event->occur_begin ) ) ? $event->occur_begin : $event->event_begin . ' ' . $event->event_time;
254
  $dtstart = mc_format_timestamp( strtotime( $real_begin_date ) );
255
  $dtend = mc_format_timestamp( strtotime( $real_end_date ) );
256
+
257
  $e['date_utc'] = date_i18n( apply_filters( 'mc_date_format', $date_format, 'template_begin_ts' ), $event->ts_occur_begin );
258
  $e['date_end_utc'] = date_i18n( apply_filters( 'mc_date_format', $date_format, 'template_end_ts' ), $event->ts_occur_end );
259
  $notime = mc_notime_label( $event );
288
  // category fields
289
  $e['cat_id'] = $event->event_category;
290
  $e['category'] = stripslashes( $event->category_name );
291
+ $e['term'] = intval( $event->category_term );
292
  $e['icon'] = mc_category_icon( $event, 'img' );
293
  $e['icon_html'] = "<img src='$e[icon]' class='mc-category-icon' alt='" . __( 'Category', 'my-calendar' ) . ": " . esc_attr( $event->category_name ) . "' />";
294
  $e['color'] = $event->category_color;
343
  $e['linking'] = ( $e['link'] != '' ) ? $event->event_link : $e_link;
344
  $e['linking_title'] = ( $e['linking'] != '' ) ? "<a href='" . $e['linking'] . "'>" . $e['title'] . "</a>" : $e['title'];
345
 
346
+ if ( $context != 'related' && ( is_singular( 'mc-events' ) || isset( $_GET['mc_id'] ) ) ) {
347
  $related_template = apply_filters( 'mc_related_template', "{date}, {time}", $event );
348
  $e['related'] = '<ul class="related-events">' . mc_list_related( $event->event_group_id, $event->event_id, $related_template ) . '</ul>';
349
+ } else {
350
+ $e['related'] = '';
351
  }
352
 
353
  // location fields
399
  $e['ical'] = $ical_link;
400
  $e['ical_html'] = "<a class='ical' rel='nofollow' href='$ical_link'>" . __( 'iCal', 'my-calendar' ) . "</a>";
401
  $e = apply_filters( 'mc_filter_shortcodes', $e, $event );
402
+
403
  return $e;
404
  }
405
 
406
  function mc_notime_label( $event ) {
407
+ if ( is_object( $event ) && property_exists( $event, 'event_post' ) ) {
408
  $notime = get_post_meta( $event->event_post, '_event_time_label', true );
409
  } else {
410
  $notime = '';
426
  return $e_label;
427
  }
428
 
429
+ function old_mc_format_timestamp( $os ) {
430
  $offset = ( 60 * 60 * get_option( 'gmt_offset' ) );
431
  $time = ( get_option( 'mc_ical_utc' ) == 'true' ) ? date( "Ymd\THi00", ( mktime( date( 'H', $os ), date( 'i', $os ), date( 's', $os ), date( 'm', $os ), date( 'd', $os ), date( 'Y', $os ) ) - ( $offset ) ) ) . "Z" : date( "Ymd\THi00", ( mktime( date( 'H', $os ), date( 'i', $os ), date( 's', $os ), date( 'm', $os ), date( 'd', $os ), date( 'Y', $os ) ) ) );
432
 
433
  return $time;
434
  }
435
 
436
+ function mc_format_timestamp( $os ) {
437
+ if ( get_option( 'mc_ical_utc' ) == 'true' ) {
438
+ $timezone_string = get_option( 'timezone_string' );
439
+ if ( ! $timezone_string ) {
440
+ // multiply gmt_offset by -1 because POSIX has it reversed:
441
+ // http://stackoverflow.com/questions/20228224/php-timezone-issue
442
+ $timezone_string = sprintf("Etc/GMT%+d", -1 * get_option('$gmt_offset') );
443
+ }
444
+
445
+ $timezone_object = timezone_open( $timezone_string );
446
+ $date_object = date_create( null, $timezone_object );
447
+ $date_object->setTime( date( 'H', $os ), date( 'i', $os ) );
448
+ $date_object->setDate( date( 'Y', $os ), date( 'm', $os ), date( 'd', $os ) );
449
+ $timestamp = $date_object->getTimestamp( );
450
+ $time = gmdate( "Ymd\THi00", $timestamp ) . "Z";
451
+
452
+ } else {
453
+ $os_time = mktime( date( 'H', $os ), date( 'i', $os ), date( 's', $os ), date( 'm', $os ), date( 'd', $os ), date( 'Y', $os ) );
454
+ $time = date( "Ymd\THi00", $os_time );
455
+ }
456
+
457
+ return $time;
458
+ }
459
+
460
  function mc_runtime( $start, $end, $event ) {
461
  if ( $event->event_hide_end || $start == $end || date( 'H:i:s', strtotime( $end ) ) == '23:59:59' ) {
462
  return '';
my-calendar-templating.php CHANGED
@@ -59,7 +59,7 @@ function edit_mc_templates() {
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>
59
  $template = stripslashes( $template );
60
  $core = mc_template_description( $key );
61
  ?>
62
+ <div class="wrap my-calendar-admin">
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>
my-calendar-widgets.php CHANGED
@@ -555,14 +555,24 @@ function my_calendar_upcoming_events( $before = 'default', $after = 'default', $
555
  $last_item = $last_id = $last_date = '';
556
  $skips = array();
557
  foreach ( reverse_array( $temp_array, true, $order ) as $details ) {
558
- $item = jd_draw_template( $details, $template );
 
 
 
559
  if ( $i < $skip && $skip != 0 ) {
560
  $i ++;
561
  } else {
 
 
 
 
 
 
 
562
  // if same group, and same date, use it.
563
  if ( ( $details['group'] !== $last_id || $details['date'] == $last_date ) || $details['group'] == '0' ) {
564
  if ( ! in_array( $details['dateid'], $skips ) ) {
565
- $output .= ( $item == $last_item ) ? '' : "<li>$item</li>";
566
  }
567
  }
568
  }
@@ -752,13 +762,8 @@ function mc_produce_upcoming_events( $events, $template, $type = 'list', $order
752
  foreach ( array_keys( $events ) as $key ) {
753
  $event =& $events[ $key ];
754
  $event_details = mc_create_tags( $event, $context );
755
- if ( get_option( 'mc_event_approve' ) == 'true' ) {
756
- if ( $event->event_approved != 0 ) {
757
- $temp_array[] = $event_details;
758
- }
759
- } else {
760
- $temp_array[] = $event_details;
761
- }
762
  }
763
  $i = 0;
764
  $groups = array();
@@ -768,7 +773,7 @@ function mc_produce_upcoming_events( $events, $template, $type = 'list', $order
768
  if ( ! in_array( $details['group'], $groups ) ) {
769
  $date = date( 'Y-m-d H:i:s', strtotime( $details['dtstart'] ) );
770
  $class = ( my_calendar_date_comp( $date, $today . date( 'H:i', current_time( 'timestamp' ) ) ) === true ) ? "past-event" : "future-event";
771
- $category = 'mc_' . sanitize_title( $details['category'] );
772
  if ( my_calendar_date_equal( $date, $today ) ) {
773
  $class = "today";
774
  }
@@ -776,16 +781,25 @@ function mc_produce_upcoming_events( $events, $template, $type = 'list', $order
776
  $class = "multiday";
777
  }
778
  if ( $type == 'list' ) {
779
- $prepend = apply_filters( 'mc_event_upcoming_before', "\n<li class=\"$class $category\">", $class, $category );
780
- $append = apply_filters( 'mc_event_upcoming_after', "</li>\n" );
781
  } else {
782
  $prepend = $append = '';
783
  }
 
 
 
784
  if ( $i < $skip && $skip != 0 ) {
785
  $i ++;
786
  } else {
787
  if ( ! in_array( $details['dateid'], $skips ) ) {
788
- $output[] = apply_filters( 'mc_event_upcoming', "$prepend" . jd_draw_template( $details, $template, $type ) . "$append", $event );
 
 
 
 
 
 
789
  $skips[] = $details['dateid'];
790
  }
791
  }
@@ -832,18 +846,17 @@ function my_calendar_todays_events( $category = 'default', $template = 'default'
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;
846
-
847
  if ( $date ) {
848
  $from = $to = date( 'Y-m-d', strtotime( $date ) );
849
  } else {
@@ -861,10 +874,10 @@ function my_calendar_todays_events( $category = 'default', $template = 'default'
861
  } else {
862
  if ( ! in_array( $e->event_group_id, $groups ) ) {
863
  $event_details = mc_create_tags( $e );
864
- $ts = $e->ts_occur_begin;
865
- $end = $e->ts_occur_end;
866
  $now = current_time( 'timestamp' );
867
- $category = 'mc_' . sanitize_title( $e->category_name );
868
  if ( $ts < $now && $end > $now ) {
869
  $class = 'on-now';
870
  } else if ( $now < $ts ) {
@@ -872,15 +885,15 @@ function my_calendar_todays_events( $category = 'default', $template = 'default'
872
  } else if ( $now > $ts ) {
873
  $class = 'past-event';
874
  }
 
875
  $prepend = apply_filters( 'mc_todays_events_before', "<li class='$class $category'>", $class, $category );
876
  $append = apply_filters( 'mc_todays_events_after', "</li>" );
877
- if ( get_option( 'mc_event_approve' ) == 'true' ) {
878
- if ( $e->event_approved != 0 ) {
879
- $todays_events[ $ts ][] = $prepend . jd_draw_template( $event_details, $template ) . $append;
880
- }
881
- } else {
882
- $todays_events[ $ts ][] = $prepend . jd_draw_template( $event_details, $template ) . $append;
883
  }
 
884
  }
885
  }
886
  }
@@ -897,8 +910,8 @@ function my_calendar_todays_events( $category = 'default', $template = 'default'
897
  }
898
  $time = strtotime( date( 'Y-m-d H:m:s', current_time( 'timestamp' ) ) ) - strtotime( date( 'Y-m-d', current_time( 'timestamp' ) ) );
899
  $time_remaining = 24 * 60 * 60 - $time;
900
- $todays_cache[ $category ] = ( $caching ) ? $return : '';
901
  if ( $caching ) {
 
902
  set_transient( 'mc_todays_cache', $todays_cache, $time_remaining );
903
  }
904
  } else {
555
  $last_item = $last_id = $last_date = '';
556
  $skips = array();
557
  foreach ( reverse_array( $temp_array, true, $order ) as $details ) {
558
+ $item = apply_filters( 'mc_draw_upcoming_event', '', $details, $template, $args );
559
+ if ( $item == '' ) {
560
+ $item = jd_draw_template( $details, $template );
561
+ }
562
  if ( $i < $skip && $skip != 0 ) {
563
  $i ++;
564
  } else {
565
+ $today = date( 'Y-m-d H:i', current_time( 'timestamp' ) );
566
+ $date = date( 'Y-m-d H:i', strtotime( $details['date'] . ' ' . $details['time'] ) );
567
+ $class = ( my_calendar_date_comp( $date, $today ) === true ) ? "past-event" : "future-event";
568
+ $category = mc_category_class( $details, 'mc_' );
569
+
570
+ $prepend = apply_filters( 'mc_event_upcoming_before', "<li class='$class $category'>", $class, $category );
571
+ $append = apply_filters( 'mc_event_upcoming_after', '</li>', $class, $category );
572
  // if same group, and same date, use it.
573
  if ( ( $details['group'] !== $last_id || $details['date'] == $last_date ) || $details['group'] == '0' ) {
574
  if ( ! in_array( $details['dateid'], $skips ) ) {
575
+ $output .= ( $item == $last_item ) ? '' : $prepend . $item . $append;
576
  }
577
  }
578
  }
762
  foreach ( array_keys( $events ) as $key ) {
763
  $event =& $events[ $key ];
764
  $event_details = mc_create_tags( $event, $context );
765
+ $temp_array[] = $event_details;
766
+
 
 
 
 
 
767
  }
768
  $i = 0;
769
  $groups = array();
773
  if ( ! in_array( $details['group'], $groups ) ) {
774
  $date = date( 'Y-m-d H:i:s', strtotime( $details['dtstart'] ) );
775
  $class = ( my_calendar_date_comp( $date, $today . date( 'H:i', current_time( 'timestamp' ) ) ) === true ) ? "past-event" : "future-event";
776
+ $category = mc_category_class( $details, 'mc_' );
777
  if ( my_calendar_date_equal( $date, $today ) ) {
778
  $class = "today";
779
  }
781
  $class = "multiday";
782
  }
783
  if ( $type == 'list' ) {
784
+ $prepend = "\n<li class=\"$class $category\">";
785
+ $append = "</li>\n";
786
  } else {
787
  $prepend = $append = '';
788
  }
789
+ $prepend = apply_filters( 'mc_event_upcoming_before', $prepend, $class, $category );
790
+ $append = apply_filters( 'mc_event_upcoming_after', $append, $class, $category );
791
+
792
  if ( $i < $skip && $skip != 0 ) {
793
  $i ++;
794
  } else {
795
  if ( ! in_array( $details['dateid'], $skips ) ) {
796
+
797
+ $item = apply_filters( 'mc_draw_upcoming_event', '', $details, $template, $type );
798
+ if ( $item == '' ) {
799
+ $item = jd_draw_template( $details, $template, $type );
800
+ }
801
+
802
+ $output[] = apply_filters( 'mc_event_upcoming', $prepend . $item . $append, $event );
803
  $skips[] = $details['dateid'];
804
  }
805
  }
846
  // allow reference by file to external template.
847
  if ( $template != '' && mc_file_exists( sanitize_file_name( $template ) ) ) {
848
  $template = @file_get_contents( mc_get_file( sanitize_file_name( $template ) ) );
849
+ }
 
850
  $defaults = get_option( 'mc_widget_defaults' );
851
  $template = ( $template == 'default' ) ? $defaults['today']['template'] : $template;
852
+ $template = ( $template == '' ) ? $default_template : $template;
853
+
854
  if ( mc_key_exists( $template ) ) {
855
  $template = mc_get_custom_template( $template );
856
  }
857
+
858
  $category = ( $category == 'default' ) ? $defaults['today']['category'] : $category;
859
  $no_event_text = ( $substitute == '' ) ? $defaults['today']['text'] : $substitute;
 
860
  if ( $date ) {
861
  $from = $to = date( 'Y-m-d', strtotime( $date ) );
862
  } else {
874
  } else {
875
  if ( ! in_array( $e->event_group_id, $groups ) ) {
876
  $event_details = mc_create_tags( $e );
877
+ $ts = strtotime( get_date_from_gmt( date( 'Y-m-d H:i:s', $e->ts_occur_begin ) ) );
878
+ $end = strtotime( get_date_from_gmt( date( 'Y-m-d H:i:s', $e->ts_occur_end ) ) );
879
  $now = current_time( 'timestamp' );
880
+ $category = mc_category_class( $e, 'mc_' );
881
  if ( $ts < $now && $end > $now ) {
882
  $class = 'on-now';
883
  } else if ( $now < $ts ) {
885
  } else if ( $now > $ts ) {
886
  $class = 'past-event';
887
  }
888
+
889
  $prepend = apply_filters( 'mc_todays_events_before', "<li class='$class $category'>", $class, $category );
890
  $append = apply_filters( 'mc_todays_events_after', "</li>" );
891
+
892
+ $item = apply_filters( 'mc_draw_todays_event', '', $event_details, $template );
893
+ if ( $item == '' ) {
894
+ $item = jd_draw_template( $event_details, $template );
 
 
895
  }
896
+ $todays_events[ $ts ][] = $prepend . $item . $append;
897
  }
898
  }
899
  }
910
  }
911
  $time = strtotime( date( 'Y-m-d H:m:s', current_time( 'timestamp' ) ) ) - strtotime( date( 'Y-m-d', current_time( 'timestamp' ) ) );
912
  $time_remaining = 24 * 60 * 60 - $time;
 
913
  if ( $caching ) {
914
+ $todays_cache[ $category ] = ( $caching ) ? $return : '';
915
  set_transient( 'mc_todays_cache', $todays_cache, $time_remaining );
916
  }
917
  } else {
my-calendar.php CHANGED
@@ -7,9 +7,9 @@ Author: Joseph C Dolson
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
 
14
  This program is free software; you can redistribute it and/or modify
15
  it under the terms of the GNU General Public License as published by
@@ -30,7 +30,7 @@ if ( ! defined( 'ABSPATH' ) ) {
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' );
@@ -63,6 +63,7 @@ include( dirname( __FILE__ ) . '/my-calendar-events.php' );
63
  include( dirname( __FILE__ ) . '/my-calendar-widgets.php' );
64
  include( dirname( __FILE__ ) . '/my-calendar-upgrade-db.php' );
65
  include( dirname( __FILE__ ) . '/my-calendar-output.php' );
 
66
  include( dirname( __FILE__ ) . '/my-calendar-templates.php' );
67
  include( dirname( __FILE__ ) . '/my-calendar-limits.php' );
68
  include( dirname( __FILE__ ) . '/my-calendar-shortcodes.php' );
@@ -87,9 +88,8 @@ add_action( 'widgets_init', create_function( '', 'return register_widget("my_cal
87
  add_action( 'widgets_init', create_function( '', 'return register_widget("my_calendar_mini_widget");' ) );
88
  add_action( 'widgets_init', create_function( '', 'return register_widget("my_calendar_simple_search");' ) );
89
  add_action( 'init', 'my_calendar_add_feed' );
90
- add_action( 'admin_menu', 'my_calendar_add_javascript' );
91
  add_action( 'wp_footer', 'mc_footer_js' );
92
- add_action( 'wp_head', 'my_calendar_fouc' );
93
  add_action( 'init', 'mc_export_vcal', 200 );
94
  // Add filters
95
  add_filter( 'widget_text', 'do_shortcode', 9 );
@@ -161,10 +161,7 @@ function mc_show_sidebar( $show = '', $add = false, $remove = false ) {
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>
165
-
166
- <p class="mc-button"><a href="http://www.joedolson.com/my-calendar/pro/" rel="external"><?php _e( 'Learn more!', 'my-calendar' ); ?></a>
167
- </p>
168
  </div>
169
  </div>
170
  </div>
@@ -175,11 +172,8 @@ function mc_show_sidebar( $show = '', $add = false, $remove = false ) {
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>
185
  </div>
@@ -235,19 +229,19 @@ function mc_show_sidebar( $show = '', $add = false, $remove = false ) {
235
  <a href="<?php echo admin_url( "admin.php?page=my-calendar-help" ); ?>#get-support"><?php _e( "Get Support", 'my-calendar' ); ?></a>
236
  </li>
237
  <li>
238
- <div class="dashicons dashicons-editor-help"></div>
239
  <a href="<?php echo admin_url( "admin.php?page=my-calendar-help" ); ?>"><?php _e( "My Calendar Help", 'my-calendar' ); ?></a>
240
  </li>
241
  <li>
242
- <div class="dashicons dashicons-yes"></div>
243
  <a href="http://profiles.wordpress.org/users/joedolson/"><?php _e( 'Check out my other plug-ins', 'my-calendar' ); ?></a>
244
  </li>
245
  <li>
246
- <div class="dashicons dashicons-star-filled"></div>
247
- <a href="http://wordpress.org/support/view/plugin-reviews/my-calendar"><?php _e( 'Rate this plug-in 5 stars!', 'my-calendar' ); ?></a>
248
  </li>
249
  <li>
250
- <div class="dashicons dashicons-translation"></div>
251
  <a href="http://translate.joedolson.com/projects/my-calendar"><?php _e( 'Help translate this plug-in!', 'my-calendar' ); ?></a>
252
  </li>
253
  </ul>
7
  Author URI: http://www.joedolson.com
8
  Text Domain: my-calendar
9
  Domain Path: lang
10
+ Version: 2.5.9
11
  */
12
+ /* Copyright 2009-2017 Joe Dolson (email : joe@joedolson.com)
13
 
14
  This program is free software; you can redistribute it and/or modify
15
  it under the terms of the GNU General Public License as published by
30
  } // Exit if accessed directly
31
 
32
  global $mc_version, $wpdb;
33
+ $mc_version = '2.5.9';
34
 
35
  register_activation_hook( __FILE__, 'mc_plugin_activated' );
36
  register_deactivation_hook( __FILE__, 'mc_plugin_deactivated' );
63
  include( dirname( __FILE__ ) . '/my-calendar-widgets.php' );
64
  include( dirname( __FILE__ ) . '/my-calendar-upgrade-db.php' );
65
  include( dirname( __FILE__ ) . '/my-calendar-output.php' );
66
+ include( dirname( __FILE__ ) . '/my-calendar-print.php' );
67
  include( dirname( __FILE__ ) . '/my-calendar-templates.php' );
68
  include( dirname( __FILE__ ) . '/my-calendar-limits.php' );
69
  include( dirname( __FILE__ ) . '/my-calendar-shortcodes.php' );
88
  add_action( 'widgets_init', create_function( '', 'return register_widget("my_calendar_mini_widget");' ) );
89
  add_action( 'widgets_init', create_function( '', 'return register_widget("my_calendar_simple_search");' ) );
90
  add_action( 'init', 'my_calendar_add_feed' );
91
+ add_action( 'admin_menu', 'my_calendar_admin_js' );
92
  add_action( 'wp_footer', 'mc_footer_js' );
 
93
  add_action( 'init', 'mc_export_vcal', 200 );
94
  // Add filters
95
  add_filter( 'widget_text', 'do_shortcode', 9 );
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 printf( __( "Buy <a href='%s' rel='external'>My Calendar Pro</a> &mdash; a more powerful calendar for your site.", 'my-calendar' ), 'https://www.joedolson.com/my-calendar/pro/' ); ?></p>
 
 
 
165
  </div>
166
  </div>
167
  </div>
172
  <h2 class='sales hndle'><strong><?php _e( 'My Tickets', 'my-calendar' ); ?></strong></h2>
173
 
174
  <div class="inside resources">
175
+ <p class="mcbuy"><?php printf( __( 'Do you sell tickets to your events? <a href="%s" class="thickbox open-plugin-details-modal" rel="external">Use My Tickets</a> and sell directly from My Calendar.', 'my-calendar' ), 'http://dev.josephdolson.com/wp-admin/plugin-install.php?tab=plugin-information&plugin=my-tickets&TB_iframe=true&width=600&height=550' ); ?></p>
176
  <p><?php _e( 'My Tickets integrates with My Calendar or sells tickets independently through posts and pages.', 'my-tickets' ); ?></p>
 
 
 
177
  </div>
178
  </div>
179
  </div>
229
  <a href="<?php echo admin_url( "admin.php?page=my-calendar-help" ); ?>#get-support"><?php _e( "Get Support", 'my-calendar' ); ?></a>
230
  </li>
231
  <li>
232
+ <div class="dashicons dashicons-editor-help" aria-hidden='true'></div>
233
  <a href="<?php echo admin_url( "admin.php?page=my-calendar-help" ); ?>"><?php _e( "My Calendar Help", 'my-calendar' ); ?></a>
234
  </li>
235
  <li>
236
+ <div class="dashicons dashicons-yes" aria-hidden='true'></div>
237
  <a href="http://profiles.wordpress.org/users/joedolson/"><?php _e( 'Check out my other plug-ins', 'my-calendar' ); ?></a>
238
  </li>
239
  <li>
240
+ <div class="dashicons dashicons-star-filled" aria-hidden='true'></div>
241
+ <a href="http://wordpress.org/support/plugin/my-calendar/reviews/?filter=5"><?php _e( 'Rate this plug-in 5 stars!', 'my-calendar' ); ?></a>
242
  </li>
243
  <li>
244
+ <div class="dashicons dashicons-translation" aria-hidden='true'></div>
245
  <a href="http://translate.joedolson.com/projects/my-calendar"><?php _e( 'Help translate this plug-in!', 'my-calendar' ); ?></a>
246
  </li>
247
  </ul>
readme.txt CHANGED
@@ -3,8 +3,8 @@ 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
 
@@ -42,15 +42,15 @@ Easy to use for anybody, My Calendar provides enormous flexibility for designers
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? =
46
-
47
- * Let your site visitors submit events to your site (pay to post or free!).
48
- * Let logged-in users edit their events from the front-end.
49
- * Create events when you publish a blog post
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
 
@@ -83,6 +83,92 @@ Translating my plug-ins is always appreciated. Visit <a href="https://translate.
83
 
84
  == Changelog ==
85
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
  = 2.5.0 =
87
 
88
  * Update hcalendar structures
@@ -118,6 +204,7 @@ Translating my plug-ins is always appreciated. Visit <a href="https://translate.
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'
@@ -727,6 +814,7 @@ This is a major revision.
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
 
@@ -761,4 +849,4 @@ The search feature in My Calendar is pretty basic; but buying My Calendar Pro gi
761
 
762
  == Upgrade Notice ==
763
 
764
- * 2.4.19: CRITICAL SECURITY UPDATE. UPDATE IMMEDIATELY.
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.7
7
+ Stable tag: 2.5.9
8
  Text domain: my-calendar
9
  License: GPLv2 or later
10
 
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? =
46
+ >
47
+ > * Let your site visitors submit events to your site (pay to post or free!).
48
+ > * Let logged-in users edit their events from the front-end.
49
+ > * Create events when you publish a blog post
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
 
83
 
84
  == Changelog ==
85
 
86
+ = 2.5.9 =
87
+
88
+ * Bug fix: class .mc-main appeared twice in day view
89
+ * Bug fix: iCal output fetches no data on subsites in multisite networks
90
+ * Bug fix: broken image upload script due to localization change
91
+ * Bug fix: sorting events by category should sort by name, not ID
92
+ * Add site name to .ics output file
93
+
94
+ = 2.5.8 =
95
+
96
+ * Bug fix: mc-ajax.js referred to a class that did not always exist
97
+ * Bug fix: Cases missed in interpreting category class values
98
+ * Bug fix: For backwards compatibility, ensure that spaces are replaced with hyphens in category classes
99
+ * Bug fix: Check whether templates returned are empty & ensure fallback renders
100
+ * Bug fix: revise FOUC implementation to avoid jQuery not defined errors
101
+
102
+ = 2.5.7 =
103
+
104
+ * Bug fix: notice in event image field if input disabled
105
+ * Bug fix: class setting was based on GMT timestamp according to MySQL
106
+ * Bug fix: PHP notice thrown if requested template doesn't exist
107
+ * Bug fix: support for embedding videos via iFrame.
108
+ * Bug fix: JS refinements to AJAX loading; changing formats can cause panel closing not to fire due to .list/.calendar switching
109
+ * Bug fix: JS refinements to AJAX loading; make sure everything works when positioned in the header or are excluded
110
+ * Bug fix: always provide a category class that's valid
111
+ * Bug fix: If mini calendar links set to open to new page, automatically disable JS
112
+ * Bug fix: If special options hidden, always set to 'true' on event save.
113
+ * Added: aria-current for current date.
114
+ * Improve KSES implementation
115
+ * Improved URL building
116
+ * Improvements to print CSS
117
+ * Improvements to sortable CSS
118
+ * New filter: 'mc_category_icon'
119
+ * New action: 'mc_print_view_head'
120
+
121
+ = 2.5.6 =
122
+
123
+ * New filter: mc_user_can_see_private_events to change criteria for visibility of private events
124
+ * New filter: mc_private_categories to tweak which categories are considered private
125
+ * Bug fix: PHP warning due to cache query occurring when caching is not enabled
126
+ * Bug fix: images entered only as URLs deleted on edit
127
+ * Accessibility: aria-expanded attached to wrong element in list view
128
+ * Accessibility: ornamental icon fonts exposed to screen readers
129
+
130
+ = 2.5.5 =
131
+
132
+ * Bug fix: notices when generating classes for upcoming events
133
+ * Bug fix: RSS feed should respect private categories
134
+ * Bug fix: Events happening now shortcode should respect private categories
135
+ * Bug fix: iCal output should respect private categories
136
+ * Bug fix: @ suppressed notices in template tag parsing. props @uscore713
137
+ * Bug fix: eliminate two notices in upcoming events class parsing
138
+ * New filter: mc_draw_upcoming_event
139
+ * New filter: mc_draw_todays_event
140
+ * Marked as compatible with 4.7
141
+
142
+ = 2.5.4 =
143
+
144
+ * Add New link on Manage Events screen
145
+ * Add new link on Edit categories screen
146
+ * Add new link on Edit locations screen
147
+ * Changed maxlength on recurrence unit field to 2
148
+ * Eliminate two notices generate on manage events screen
149
+ * Two incorrect method_exists checks; should be property_exists
150
+
151
+ = 2.5.3 =
152
+
153
+ * Bug fix: prevent non-object warning in check for notime text
154
+ * Bug fix: missing classes from some instances of upcoming events list
155
+ * Bug fix: Only show invalid format/time errors if user with permissions.
156
+ * Enhancement: Include invalid format/time in error message.
157
+ * Performance: In single event shortcode, break out of foreach if list of related events not being produced.
158
+
159
+ = 2.5.2 =
160
+
161
+ * Bug fix: Make sure that upcoming events element filters operate in all cases
162
+ * Bug fix: Permit {register} template tag to pass additional attributes
163
+ * Bug fix: Add class to permitted attributes on span tag
164
+
165
+ = 2.5.1 =
166
+
167
+ * Bug fix: Multi-word category titles not hyphenated in event classes
168
+ * Bug fix: Add `{related}` template tag to documentation
169
+ * Bug fix: Today's events template broken
170
+ * Add 'past-event' and 'future-event' classes to related event list & main events lists
171
+
172
  = 2.5.0 =
173
 
174
  * Update hcalendar structures
204
  * Bug fix: misc. notices
205
 
206
  Breaking Changes:
207
+
208
  * Breaking change: minor changes to classes to improve structured data in microformats
209
  * Breaking change: upcoming events widget no longer uses ID 'upcoming-events'; use class '.upcoming-events'
210
  * Breaking change: today's events widget no longer uses ID 'todays-events'; use class '.todays-events'
814
  * Add ability to limit by multiple locations (e.g., view all events in Location 1 & Location 2; only on lvalue)
815
  * Event occurrence IDs can change when events dates are changed
816
  * Add option to insert events simultaneously to both global & local calendar in multisite networks [todo]
817
+ * JS to delete events from front-end when logged-in
818
 
819
  == Frequently Asked Questions ==
820
 
849
 
850
  == Upgrade Notice ==
851
 
852
+ * 2.5.0 Major update! New features, many bug fixes and improvements.