My Calendar - Version 2.4.0

Version Description

New features: * Set upcoming event class based on time, rather than date. * Add past/present classes to today's events widget * Assign Custom All Day label for each event. * Support hiding 'Host' field as option. * Made primary sort order of events filterable: 'mc_primary_sort' * Added action to location saving handling updated locations * Added arguments to from/to filters in Upcoming Events * Enabled option to turn on permalinks * Custom canonical URL for event pages * Added 'date' parameter to today's events list & shortcode accepting any string usable in strtotime() * Added 'from' and 'to' parameter to upcoming events list & shortcode accepting any string usable in strtotime * Added year/month/day parameter to main shortcode to target specific months for initial display. * Make BCC field filterable * Add filters to search query parameters * New option: switch to mini calendar on mobile devices instead of list view. * Add [day] select field to date switcher if in 'day' view. * Option to set default sort direction * Ability to set three separate event title templates: grid, list, and single. * Added admin-bar link to view calendar. * Added option to customize permalink slug on permalink page * Single event pages as permalinks use the same template as main if custom template isn't enabled. * New template tag: {color_css} and {close_color_css} to wrap a block with the category background color. * Add category classes to Upcoming & Today's events widgets * Redirect page to main calendar if event is private * Improved labeling of cell dates

Bug fixes: * Stop setting all day events to end at midnight; use 11:59:59 and filter output * Rewrite iCal output so that the iCal download eliminates Holiday cancellations [todo] * Bug fix: Prevent extraneous variables from leaking into the navigation output. * Rendering post template in permalinks only applies within Loop. * Template attribute preg_match could only pick up 2 parameters * Prevent an invalid mc_id value from returning errors. * Prevent deprecation notice when getting text_direction * Default to not showing navigation options in print view. * Better loading of text domain. * Prevent mini calendar from switching to list format. * Change class construction to PHP 5 syntax * Close button is now a button rather than a link. * Fixed display of text diff for stylesheet comparisons * Two different filters with different names. * mc_after_event filter not running with custom templates. * With My Tickets active, enter key did not submit Add/Edit event form * Fixed documentation error with ical template tags. * Improved efficiency of WP shortcode processing in templates. * A multi-day event crossing the current day was counted as a future event in upcoming events * If event instance was split from recurring event, showed same recurring settings as original event. * If events were mass deleted, the corresponding event post was not also deleted. * Prevent single event pages from displaying content if the event is in a private category.

Important Changes: * Removed references to #jd_calendar and generate custom IDs. [breaking change * Revision of settings page [reorganize settings into tabs] * Reorganized settings pages.

Other: * Moved changelog for versions prior to 2.3.0 into changelog.txt

Translations: * Updated Polish, Portuguese (Portugal), Dutch, Turkish, Slovak, Norwegian, Hungarian, German, Spanish, Persian, Czech, Danish

Download this release

Release Info

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

Code changes from version 2.3.32 to 2.4.0

changelog.txt ADDED
@@ -0,0 +1,1024 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ = 2.2.13 =
2
+
3
+ * Bug fix: Threw error if network-activated (wp_is_mobile() not defined yet)
4
+ * Bug fix: Calendar URI could be saved as integer instead of as URL.
5
+ * Bug fix: hide screen options that current user can't use.
6
+ * Improved localization of Calendrical jQuery plug-in.
7
+ * Feature: my_calendar_upcoming and my_calendar_today shortcodes now support filtering by host.
8
+ * New filter: mc_send_notification -- passes event and user data to determine whether a new event email notification should be sent. Return true|false.
9
+
10
+ = 2.2.12 =
11
+
12
+ * Bug fix: jquery.calendrical time rendering.
13
+
14
+ = 2.2.11 =
15
+
16
+ * Required deleted file.
17
+
18
+ = 2.2.10 =
19
+
20
+ * Bug fix: date comparison in grouped event date output.
21
+ * Bug fix: editing a single occurrence of an event when location fields not displayed could result in duplicating the event.
22
+ * Bug fix: Duplicated <a> on event title in events manager.
23
+ * Bug fix: Generated WP to Twitter empty sentence error.
24
+ * Bug fix: Grouped events within a single day in upcoming events list.
25
+ * Bug fix: Run My Calendar upgrade stylesheet archiving only when My Calendar is updated.
26
+ * Bug fix:
27
+ * Changed: replaced mc_is_mobile() functionality with native wp_is_mobile(). Filterable for My Calendar using 'mc_is_mobile' filter.
28
+ * Changed: properly registered and enqueue most front-end styles.
29
+ * Changed: Removed classes 'prevMonth' and 'nextMonth' from navigation.
30
+ * Misc. minor style changes to front and back end UI.
31
+ * Added: special value for 'author' and 'host' attributes of 'current' to only show events created by the logged-in user. Filter via 'mc_display_author' and 'mc_display_host'
32
+ * Added: date and time to title field for My Calendar RSS feed.
33
+ * Preparation: permission filtering for submissions and registrations add-ons.
34
+ * Updated: German & Slovenian Translations.
35
+
36
+ = 2.2.9 =
37
+
38
+ * Bug fix: Reversed argument in $details filter, breaking custom template editor.
39
+
40
+ = 2.2.8 =
41
+
42
+ * Bug fix: Fix in mini calendar scripting with AJAX.
43
+ * Bug fix: Strict error in My Calendar Search widget.
44
+ * Bug fix: My Calendar screen options disabled other screen options.
45
+ * Updated: Slovenian
46
+ * Documentation error: cat_id, not category_id
47
+ * Added support for <a href="http://wordpress.org/plugins/botsmasher/">BotSmasher</a> as a spam filter for events.
48
+ * Removed location region from Google Maps string (Google Maps choked on that data.)
49
+ * Removed EasyDrag jQuery plug-in due to compatibility issues.
50
+ * Eliminated 4 filters: mc_event_content_{$type}; replaced with single filter mc_event_content with $type parameter.
51
+ * Added support for WP 3.6 shortcode attribute filters.
52
+ * Added more filters & actions. Lots and lots of filters. Actions. Yeah.
53
+ * Maybe I'm the only one excited about the last thing.
54
+
55
+ = 2.2.7 =
56
+
57
+ * Bug fix: map links could render links with no data.
58
+
59
+ = 2.2.6 =
60
+
61
+ * Bug fix: Link to single day events from mini calendar broken.
62
+ * Bug fix: Return to calendar link from print view
63
+ * Bug fix: some map links missing 'external' class.
64
+ * Updated: couple missing i18n strings
65
+ * Bug fix: widget title link could not be saved.
66
+ * Bug fix: Changing the event time on individual occurrences of a recurring event showed wrong time in upcoming events list.
67
+ * Bug fix: rewrite of AJAX scripting to clear bugs.
68
+ * Bug fix: Event authors with "add" capability could not edit their own events or copy events from the admin.
69
+ * Bug fix: Time frame toggles triggered beginning of month instead of current week/day if no params set.
70
+ * Deprecated upgrade paths from versions prior to 1.5.0.
71
+ * Eliminated single-day timeline URL settings field (no longer required.)
72
+ * Added filter mc_modify_day_uri to allow above target URL to be customized.
73
+ * Removed caching option; caching accessible only via filtering.
74
+ * Updated: French, Italian, French, Slovenian
75
+ * Added: Galician
76
+
77
+ = 2.2.5 =
78
+
79
+ * Bug fix: better bug fix in 2.2.3 event duplication bug.
80
+ * Updated: Japanese translation.
81
+
82
+ = 2.2.4 =
83
+
84
+ * Bug fix: event duplication bug in 2.2.3
85
+
86
+ = 2.2.3 =
87
+
88
+ * Bug fix: duplicate attribute 'rel' in prev/next nav.
89
+ * Bug fix: category color associations on event titles when no color assigned.
90
+ * Bug fix: print view would not always display all categories if no limits set.
91
+ * Bug fix: Group editor lost multi-day settings.
92
+ * Improvement: throw a warning on events set up with problem settings, e.g. recurring events where the next occurrence begins before the current event has ended.
93
+ * Added template tag: {map_url} for Google Map URL.
94
+ * New filters: filters for calendar year/month/day (to change the default start date for the calendar.)
95
+ * Language updates: Japanese, Italian, Dutch, Romanian, and Slovenian
96
+
97
+ = 2.2.2 =
98
+
99
+ * Bug fix to importer from Calendar
100
+ * Another fix to link_map (this time, in the standard calendar view.)
101
+ * Bug fix: location preset being assigned didn't allow changes to location details when editing events.
102
+
103
+ = 2.2.1 =
104
+
105
+ * Bug fix: Pull multi-day events in upcoming events list that happen today, but started on a previous day when past events set to 0.
106
+ * Bug fix: broken {link_map} template tag.
107
+ * Update to Italian translation.
108
+
109
+ = 2.2.0 =
110
+
111
+ * New feature: event search (widget).
112
+ * New feature: with <a href="http://wordpress.org/extend/plugins/wp-to-twitter">WP to Twitter</a> installed, auto post events to Twitter when published or approved.
113
+ * New feature: toggle timeframe between month/week/day view
114
+ * New setting: ensure best possible color contrast between background color and title link.
115
+ * Split manage events page and add event page into two separate interfaces.
116
+ * Removed non-sortable fields from display for manage events interface.
117
+ * Moved setting for number of events on manage events page to screen options.
118
+ * New screen option: on event manager screen, users can turn off areas of the event manager they don't use.
119
+ * New template tag: {image_url}, to pull an event's associated image without HTML
120
+ * New template tag: {linking}, event URL with fallback to details link
121
+ * New template tags: {gravatar} and {host_gravatar} to show author/host gravatar images.
122
+ * New filter: mc_event_mail_to.
123
+ * New filter: mc_past_search_results.
124
+ * New filter: mc_future_search_results.
125
+ * New filter: mc_search_template
126
+ * Added support for variable increments (e.g., every 3 weeks, every 4 months, etc.)
127
+ * Added template tag support to notification email subject line
128
+ * Added option to send HTML notification emails
129
+ * Added option to set sending address for notification emails
130
+ * Added template tag to add event to Google Calendar
131
+ * Added 'check all' option to event manager.
132
+ * Accessibility Improvement: added aria-live attributes.
133
+ * New shortcode attributes: 'above' and 'below'. (Control order and display of elements above/below calendar.)
134
+ * Deprecated shortcode attributes: showkey, shownav, toggle, showjump. Will be removed in My Calendar 2.3.0.
135
+ * Updated shortcode generator to use new attributes. Also added support for author and host attributes.
136
+ * Miscellaneous tweaks to all My Calendar themes.
137
+ * jQuery improvements. (jQuery version 1.7 minimum requirement.)
138
+ * Bug fix: multi-day events incorrectly displayed in Upcoming Events by dates view
139
+ * Bug fix: Open events to details page briefly rendered empty details pop-up (requires script update)
140
+ * Bug fix: <title> element filter didn't strip all HTML tags.
141
+ * Bug fix: hcal end time
142
+ * Bug fix: upcoming events miscounted number of events with overlapping multiday single events.
143
+ * Bug fix: today's events are now counted towards total events in upcoming events list
144
+ * Bug fix: retention of location data when location fields disabled in manager
145
+ * Bug fix: documentation correction for remote DB
146
+ * Bug fix: caching issue when filtering by location
147
+ * Language updates: German, Spanish, French, Japanese, Dutch, Polish, Italian, Slovenian
148
+ * Deprecated support for WordPress versions up to 3.3.0 due to jQuery version change.
149
+
150
+ = 2.1.5 =
151
+
152
+ * Bug fix: upcoming events timestamps were converted to UTC.
153
+
154
+ = 2.1.4 =
155
+
156
+ * Bug fix: weekly view when crossing years jumped to next year
157
+ * Bug fix: Upcoming events sorting fix
158
+ * Bug fix: Upcoming events count fix
159
+ * Bug fix: print stylesheet directory fix.
160
+
161
+ = 2.1.3 =
162
+
163
+ * Bug fix: My Calendar stripped title elements from singular posts unless an SEO plug-in was installed.
164
+
165
+ = 2.1.2 =
166
+
167
+ * Bug fix: Miscounted number of events in upcoming events view when events were multiple days.
168
+ * Bug fix: My Calendar URL guessing now only selects from published Pages/posts
169
+ * Tweak: Minor change to HTML output in print view
170
+ * Added: Option to display current month or current year using Upcoming Events widget.
171
+ * Added: Filter to display a custom <title> on single event details pages with settings field to configure that title. (Improves SEO)
172
+ * Language updates: Italian, Russian, Basque
173
+
174
+ = 2.1.1 =
175
+
176
+ * Bug fix: users without 'Approve Event' ability submitted unapproved events even when event approval was disabled.
177
+
178
+ = 2.1.0 =
179
+
180
+ * Miscellaneous filepath fixes for custom icons
181
+ * Fixed filepath issue for custom content directory in loading calendar generator
182
+ * Added templating options to RSS feed event format
183
+ * Added two new template tags: description_stripped and shortdesc_stripped; returns the description fields with HTML removed.
184
+ * Re-organized settings to provide better grouping.
185
+ * Removed jumpbox default setting; jumpbox now only configurable via shortcode.
186
+ * Bug fix: titles missing in list view when open to details link enabled.
187
+ * Bug fix: Multi-day events listed only once in upcoming events lists.
188
+ * Minor stylesheet tweaks.
189
+
190
+ = 2.0.12 =
191
+
192
+ * I horribly screwed up the Upcoming Events widget in 2.0.11. Please accept my apologies.
193
+
194
+ = 2.0.11 =
195
+
196
+ * Fixed Broken custom stylesheets editing/selection.
197
+ * Added Custom links for widget title links
198
+ * Fixed issue with event links expiring immediately
199
+ * Fixed issue with holiday collisions restricted in Upcoming Events/events only when holiday category is displayed.
200
+ * Added full year output option for iCal downloads.
201
+ * Added setting for calendar heading month formatting.
202
+ * Updated language files: Japanese, Italian, German, Turkish
203
+
204
+ = 2.0.10 =
205
+
206
+ * Updated Japanese, Turkish, and Italian translations
207
+ * Bug fix: Upcoming Events list could not be limited to a single author.
208
+ * Bug fix: Un-approved events were being displayed in some public contexts.
209
+ * Bug fix: Problem with RSS feed template elements not rendering in some cases.
210
+ * Bug fix: Upcoming Events removed events inappropriately in certain situations when 'skip on holidays' was checked
211
+ * Bug fix: Updated method for getting current plugin URL.
212
+ * Deprecated support for WordPress versions before 3.0.6.
213
+
214
+ = 2.0.9 =
215
+
216
+ * Bug fix: Email notification on event addition to admin did not receive event data.
217
+ * Bug fix: Accidentally eliminated weekend class. Now it's back!
218
+ * Bug fix: Events crossing multiple dates need per-date unique IDs
219
+ * Code change: Some code simplification for current URL and plugin URL references.
220
+ * Updated languages: Portuguese, Dutch, Italian
221
+
222
+ = 2.0.8 =
223
+
224
+ * Re-written (simplified) holiday exclusion mechanism.
225
+ * Performance improvements to templating and event processing.
226
+ * Bug fix: Import from Kieran's "Calendar" plug-in was broken.
227
+ * Bug fix: 'nextmonth' class was attached to events in weekly view; not appropriate to view.
228
+ * Bug fix: Deleting single instance deleted entire event series.
229
+ * Added option: number of events per page in admin events list
230
+
231
+ = 2.0.7 =
232
+
233
+ * Bug fix: Show list view on mobile devices option did not work.
234
+ * Bug fix: No longer forcing links on titles in list or mini view.
235
+ * Bug fix: All-day events came up with random end times.
236
+ * Change: All-day checkbox added.
237
+ * Change: All-day events automatically forced to hide end times.
238
+ * Change: removed X-WR-CALNAME field from iCal output for improved compatibility
239
+ * Updates: Partial updates to Spanish, Italian, and Dutch translations.
240
+
241
+ = 2.0.6 =
242
+
243
+ * Bug fix: Mini calendar links pointed to current display month regardless of current display date.
244
+ * Bug fix: if day parameter was set, the main calendar views showed events for month starting from that date.
245
+ * Bug fix: if day view was targeted from mini calendar with default cid parameter set, would not react
246
+ * Bug fix: Calendar could not show events which had start and end dates which spanned the displayed period but were not included in the displayed period.
247
+ * Moved screenshots into assets folder in version repository.
248
+ * Translation source updated at http://translate.joedolson.com/ - now the translations need refreshing!
249
+
250
+ = 2.0.5 =
251
+
252
+ * Bug fix: Date links were eliminated in mini calendar if option to link to day-view was enabled.
253
+ * Bug fix: Today's events drew events based on UTC instead of current timezone.
254
+
255
+ = 2.0.4 =
256
+
257
+ * Bug fix: template variable misassigned in the Today's Events shortcode.
258
+ * Change: Added option to output iCal either in UTC or with times as entered. (Previously only UTC)
259
+
260
+ = 2.0.3 =
261
+
262
+ * Bug fix: Upcoming events widget did not support the "show_today's events" option correctly.
263
+ * Bug fix: Was not possible to set 12:00 am as the end time for an event.
264
+ * Bug fix: prevented blank title in main calendar due to faulty template.
265
+
266
+ = 2.0.2 =
267
+
268
+ * Bug fix: My Calendar did not enqueue jQuery
269
+ * Bug fix: Grid view did not display last day of month if first day of week and last day of month were both Sunday
270
+
271
+ = 2.0.1 =
272
+
273
+ * Bug fix: Error in default settings for event titles.
274
+ * Bug fix: Single Event iCal export broken
275
+ * Bug fix: Today's Events shortcode broken if author not specified
276
+ * Change: Deleting or updating categories now refreshes the cache.
277
+
278
+ = 2.0.0 =
279
+
280
+ * Completely re-written database model for events.
281
+ * Added: pagination on event manager list of events.
282
+ * Added: Restrict groups manager lists to currently grouped/ungrouped lists of events.
283
+ * Added links to other event instances visible when editing events with multiple instances.
284
+ * Added default category selection.
285
+ * Added feature: limit calendar views by event author.
286
+ * Added feature: filter event manager view by location, author, or category.
287
+ * Added feature: mark categories as private, to only show those events to logged-in users.
288
+ * Added templating to locations list so user can produce list of any set of location data.
289
+ * Added option in event manager to copy location data into Locations table
290
+ * Added [my_calendar_event] shortcode to fetch information for a single event.
291
+ * Added template tag {timerange} to display start-end times.
292
+ * Change: all events now have an end time. Option to hide end times to maintain current display.
293
+ * Bug fix: iCal had missing newline; events now return labeled UTC time
294
+ * Bug fix: RSS does better job of clearing non-XML special characters.
295
+ * Bug fix: If preset location was selected, no other edits to locations could be done.
296
+ * Bug fix: when copying an event, the new event was grouped in the same group as the source event.
297
+ * Bug fix: if stylesheet was disabled, stylesheet was erased on next save of style settings.
298
+ * Bug fix to category limiting which matched category names like 'baseball' to show 'all' categories.
299
+
300
+ = 1.11.3 =
301
+
302
+ * Fatal error in PHP 5.4+ https://bugs.php.net/bug.php?id=54657
303
+ * Bug fix: {date} and {time} template tags not rendered in details link when run in a template.
304
+ * Bug fix: upgrade database button placement off-screen
305
+ * Bug fix: layout on stylesheet editor caused usability problems
306
+ * Bug fix: added line break in iCal output.
307
+ * Change: added alt attribute to category icons in appropriate contexts.
308
+ * [My Calendar 2.0 beta](http://downloads.wordpress.org/plugin/my-calendar.2.0.0.zip) added to subversion repository. Here there be bugs.
309
+
310
+ = 1.11.2 =
311
+
312
+ * Bug fix: Called wp_editor on versions below 3.3
313
+ * Bug fix: assorted PHP notices cleaned up.
314
+
315
+ = 1.11.1 =
316
+
317
+ * HTML validation issue fixed in calendar output.
318
+ * Added option to hide display of external event links in calendar output.
319
+ * Bug fix: Mini calendar should not toggle from mini view when main view switched.
320
+ * Bug fix: Week time frame of list view did not return the 'no events' message.
321
+ * Feature: No events message can be customized by using an enclosing shortcode: [my_calendar]No events this week![/my_calendar]
322
+
323
+ = 1.11.0 =
324
+
325
+ * Added option to use {date} in Today's Events widget title.
326
+ * Events with the same time are now sub-sorted by title in Upcoming Events lists.
327
+ * Template tag {endtime} returns empty string if same as start time
328
+ * Standard event output returns empty string for event end time if same as start time.
329
+ * Can only check 'multi-day event' option if event has multiple occurrences.
330
+ * Categories in editor now sortable by either ID or category name.
331
+ * Categories in input now sorted by category name.
332
+ * Updated mobile detection class.
333
+ * Major revision to permissions handling to use custom capabilities
334
+ * Redesign of settings pages.
335
+ * Can target tablet devices with CSS by adding a stylesheet called mc-tablet.css to your theme directory.
336
+ * Can target other mobile devices with CSS by adding a stylesheet called mc-mobile.css to your theme directory.
337
+ * Template tags now support before and after attributes: {tag before=&quot;&lt;p&gt;&quot; after=&quot;&lt;/p&gt;&quot;}
338
+ * Added option to retrieve events, categories, and locations from a remote database. (e.g., to share calendar information between 3 related sites.)
339
+ * Eliminated details arrow; forcing anchor element on clickable title.
340
+ * Added 'id' attribute to My Calendar shortcode, to customize unique ID for calendar and avoid non-compliant duplication of IDs
341
+ * Added 'template' attribute to My Calendar shortcode, so specific calendars can use their own individual custom templates. Templates should be text files (.txt) placed in your theme directory.
342
+ * Reduced specificity in stylesheets by eliminating ID-based references.
343
+ * Fixed bug with day/date consistency in 5-day grid calendars.
344
+ * Added day class to date boxes without dates.
345
+ * Jumpbox is now switchable from the shortcode.
346
+ * Fixed google maps link to use the correct directions targeting method
347
+ * Various changes for WP 3.4 compatibility.
348
+ * Updated Danish Translation
349
+ * Updated Czech Translation
350
+ * Added Hindi Translation
351
+
352
+ = 1.10.12 =
353
+
354
+ * Bug fix: List format showed all dates, regardless of whether there were events for that date.
355
+ * Bug fix: List format showed incorrect classes.
356
+ * Bug fix: Pipe separator for categories not supported with caching.
357
+ * ARRRRGGGGHHHH!!! I'm sure you're as frustrated about all these little releases as I am. But who wants to sit on known bugs?
358
+
359
+ = 1.10.11 =
360
+
361
+ * Bug fix: Variable not checked for type threw usort warning.
362
+ * Bug fix: Details links rendered incorrect page if linked from a single post location with permalinks not enabled.
363
+ * Bug fix: Fixed bug where calendar returned no information if cache reached max size.
364
+ * Settings change: Caching is now defaulted to off.
365
+
366
+ = 1.10.10 =
367
+
368
+ * Bug fix: Upcoming events list did not respect category limits.
369
+ * Validation error/bug fix: Date for ID for first of month was incorrect.
370
+ * Validation error: unencoded ampersand in iCal link if permalinks disabled.
371
+
372
+ = 1.10.9 =
373
+
374
+ * Added option to clear cache from settings.
375
+ * Bug fix: Error in caching where cache returned false for multi-category limited calendars.
376
+ * Bug fix: Error in caching where cache returned false for category limited calendars using category name as delimiter. Thanks to [Antti Palosaari](crope@iki.fi) for reporting this bug and for testing fixes.
377
+ * Bug fix: Error notices if user is deleted who is assigned as host of some events. Thanks to Florian Edelmann for reporting this bug and contributing solution.
378
+ * Bug fix: Upcoming events in dates mode returned null for cached dates.
379
+
380
+ = 1.10.8 =
381
+
382
+ * Bug fix: upcoming events list breaks if 'This is a multi-day event' is checked for an event with only a single occurrence.
383
+ * Bug fix: Upcoming events caching did not cache correct data.
384
+ * Modification: eliminated some extraneous database calls
385
+ * Modified: clarifying text edits
386
+ * Added: category classes on calendar date cells
387
+
388
+ = 1.10.7 =
389
+
390
+ * Made 'to' value in Google Maps links a translatable value.
391
+ * Feature change: iCal download now respects currently selected month.
392
+ * Added a phone number field to the Location manager
393
+ * Added a setting to display only the core site's calendar on child sites in multisite mode.
394
+ * Added a setting for the link target for mini calendar dates
395
+ * Re-wrote labels for URL link target settings fields.
396
+ * Bug fix: Location selector did not respect currently selected categories.
397
+ * Bug fix: "Add another occurrence" option available in Edit mode, but not functional. Removed option.
398
+ * Bug fix: Limiting by categories didn't trim whitespace from category names.
399
+ * Bug fix: Fixed RSS/ICS/Print permalinks if PATHINFO permalinks are enabled.
400
+ * Improved cache handling. Cache limit relative to amount of memory available to PHP. Cache stores information more efficiently.
401
+ * Revised RSS/iCal handling to avoid .htaccess problems.
402
+
403
+ = 1.10.6 =
404
+
405
+ * Revised template tags so the description tags are run through wpautop(), and added _raw versions which are not.
406
+ * Fixed a bug in URL generation so that URLs with ports are correctly constructed.
407
+ * Fixed a bug iin Print output which did not allow restriction to multiple categories
408
+ * Added option to use {date} in previous/next navigation links to indicate what date set is being navigated to.
409
+
410
+ = 1.10.5 =
411
+
412
+ * I made a truly bone-headed error in the last update, and I'm not even going to say what. If you didn't notice it, lucky for you!
413
+
414
+ = 1.10.4 =
415
+
416
+ * In my rush to fix the security issue, I broke an aspect of the event navigation. Apologies for this! Now fixed.
417
+
418
+ = 1.10.3 =
419
+
420
+ * Incorrectly called wp_kses(). Apologies for the frequent updates!
421
+
422
+ = 1.10.2 =
423
+
424
+ * Critical security update. Please upgrade promptly. Big thank you to Dean Batha for the bug report.
425
+
426
+ = 1.10.1 =
427
+
428
+ * Bug fix: undeclared array in widget manager
429
+ * Renamed overly-generic constant.
430
+
431
+ = 1.10.0 =
432
+
433
+ * New feature: option to link dates in mini calendar to separate daily view instead of pop-up.
434
+ * New feature: no longer necessary to manually edit behaviors in order to open main calendar event titles to separate page.
435
+ * New feature: Ability to define grouped events as a single multi-day event and remove duplicates from events lists (upcoming events and today's events widgets)
436
+ * New feature: group-association classes assigned to multi-day events in grid display.
437
+ * New template tags: {daterange} and {multidate} for displaying a beginning and ending date range for a single event and for displaying each date in a multi-day event, respectively.
438
+ * Week-view calendar caption now editable.
439
+ * Added printable version.
440
+ * Submit buttons in forms are now duplicated at top and bottom of long editing sections, to improve usability.
441
+ * Minor style change to group editor to avoid group list colliding with editor textarea.
442
+ * Removed angle brackets from Previous/Next events links.
443
+ * Added custom action hooks for event save and event delete
444
+ * Added ability to prevent today's events from showing up in upcoming events listings.
445
+ * Added categories to iCal output.
446
+ * iCal should return times in local time, not in UTC.
447
+ * Bug fix: iCal output not correctly encoded
448
+ * Bug fix: mc_next_link filter did not exist.
449
+ * Bug fix: placed limit on maximum size of cached calendar data.
450
+ * Bug fix: Upcoming events list will no longer occasionally display more items than expected.
451
+ * Bug fix: menu icon not aware of custom content locations
452
+
453
+ = 1.9.8 =
454
+
455
+ * This is just a convenience update due to a warning appearing in 1.9.7 that I missed.
456
+
457
+ = 1.9.7 =
458
+
459
+ * Cache was not cleared when events were approved, rejected, or deleted.
460
+ * Fixed bug with slashed characters in time and date formats
461
+ * Fixed bug where previous/next links did not work on category pages
462
+ * Fixed bug where event description was deleted if edited in groups manager.
463
+ * Easydrag.js now respects conditional loading by page ID.
464
+ * Small change to upcoming events list: events with an end time specifie and not crossing days will move off the list after they end rather than after they start.
465
+
466
+ = 1.9.6 =
467
+
468
+ * Fixed bug in Event Manager where information about whether an event was open for registration saved incorrectly.
469
+ * Added raw details_link template tag.
470
+ * Fixed Google Maps link error when using Long/Lat coordinates.
471
+ * Associated image option was not available if HTML editor was enabled.
472
+
473
+ = 1.9.5 =
474
+
475
+ * Bug fix: Caching of Today's events did not account for category limits
476
+ * Bug fix: Upcoming events listed by day duplication
477
+
478
+ = 1.9.4 =
479
+
480
+ * Bug fix: month-by-day recurring events in upcoming events list
481
+ * Bug fix: duplication of events in upcoming events list
482
+ * Bug fix: when editing a single event with indefinite recurrences, future events set up without continuing recurrence.
483
+ * Function error when data not present fixed.
484
+ * Added display of sending name/address for support messages
485
+
486
+ = 1.9.3 =
487
+
488
+ * Stylesheet saving can write longer files. Solves problem with occasional truncation of stylesheets.
489
+ * Added transient caching for calendar events to improve performance, plus other various performance improvements
490
+ * Small html output change.
491
+ * 1.9.0 made details boxes draggable; made this optional.
492
+ * Added plug-in support request form.
493
+ * Added updated French translation to 1.9.2
494
+ * Fixed bug with date switcher duplicating/skipping months.
495
+ * Updated User's Guide (not included with plug-in)
496
+
497
+ = 1.9.2 =
498
+
499
+ * Bug fix: Fixed sort error returned by calendar if no events are in array.
500
+ * Bug fix: Fixed incorrect URLs for icons in custom directory in category key.
501
+ * Bug fix: Caption text did not display.
502
+ * Added {date} and {time} to details link text templating.
503
+ * Bug fix: Fixed {icon} URL in template output.
504
+ * Bug fix: Fixed bug with table layout of dates when weekends are disabled on grid calendar.
505
+ * Bug fix: Fixed bug with generation of details link when not using permalinks.
506
+ * Bug fix: Fixed bug with HTML editor converting HTML entities.
507
+ * Bug fix: Fixed bug where weekly view showed the wrong dates if the current week started in the previous month.
508
+
509
+ = 1.9.1 =
510
+
511
+ * Bug fix: Incorrect title template tag auto-generated if title template is empty.
512
+ * Bug fix: Create events permissions broken
513
+ * Bug fix: Host list broken in WordPress versions lower than 3.1
514
+ * Bug fix: My Calendar not using WordPress defaults for customizable date and time settings if not set by user.
515
+ * Bug fix: Turning off calendar icons did not turn off icons in key
516
+ * Bug fix: details links used current URL instead of stored URL
517
+ * Bug fix: default widget settings not loaded on upgrade.
518
+ * Bug fix: next/previous links not working on home page if permalinks not set.
519
+ * Bug fix: event title shown in date field in list mode was not for the first event of the day.
520
+ * Style change: Minor change to my-calendar.css to adjust for the green background on weekends. (Which showed up as the result of a fix to an HTML problem in 1.8.9.)
521
+ * Bug fix/Option add: Added option to remove individual iCal link
522
+ * Option add: Added option to conceal first event title/number of events with date in list mode.
523
+
524
+ = 1.9.0 =
525
+
526
+ Additions:
527
+
528
+ * template editing for list, grid, mini, and single event output.
529
+ * pop-up box is now draggable.
530
+ * date format option for grid mode, week view.
531
+ * templating for details link text.
532
+ * templating for event URL link text.
533
+ * location filtering from shortcode.
534
+ * image upload option for events
535
+ * day class to calendar date headings and cells
536
+ * individual instances of repeating events can be edited
537
+ * feature to add multiple occurrences of an event simultaneously. (concept from Dave Heitzman)
538
+ * feature to mass edit information for groups of events (concept from Dave Heitzman)
539
+ * stored URL for locations (contrib by John Colvin)
540
+ * recurring daily events on weekdays only (based on contrib by John Colvin)
541
+ * optional templating for all event output formats
542
+ * individual event occurrence iCal export
543
+ * numerous additional template tags
544
+ * Option to use custom location filter fields as data control
545
+ * Shortcode to generate list of saved locations
546
+ * Network administrators can control whether sub-site calendars contribute only to a central calendar, only to their own calendar, or whether site administrators can make that choice.
547
+ * Upgrade notice information in dashboard for future upgrades.
548
+ * implementation of WordPress text diff to compare your styles and scripts against my current released versions
549
+ * Option to skip a defined number of events in upcoming events lists.
550
+
551
+ Bug fixes:
552
+
553
+ * jump box was displaying in week/grid view.
554
+ * some potentially repeatable IDs (code validation).
555
+ * 'Administrators see all options' did not work.
556
+ * Fixed timestamps on main calendar objects
557
+ * Squashed e_notice errors.
558
+ * category limiting did not work without permalinks due to GET variable conflict with WordPress core
559
+ * Missing nonce in database upgrade routine
560
+ * Mini calendar simultaneously displayed single event view when visited.
561
+ * Link generation for details view did not work if calendar link parameterized
562
+ * Issue with weekdays only calendar if day of week set to start on Sunday
563
+ * Issue with retrieval of user-specific settings
564
+ * Issue with accessing styles and javascript if My Calendar installed in non-standard directory.
565
+ * Problem in Today's Events widget when Holiday restrictions are enabled.
566
+
567
+ Changes:
568
+
569
+ * replaced all default icons with 24-bit transparent PNGs
570
+ * jumpbox output to automatically scope to the oldest dates in the database.
571
+ * iCal output changed to output all events for complete current month
572
+ * RSS output to prioritze newly added events
573
+ * holiday skipping/fifth week customization moved into event manager function
574
+ * new 'close' icon for pop-up box; added close icon and scripting to mini calendar pop-up
575
+ * copy in several places; updated template tags.
576
+ * location lists sorted by location label (contrib by John Colvin)
577
+ * Eliminated calendar heading option
578
+ * default style resets no longer stored in global variables, instead stored as files.
579
+ * Map links now trigger the driving directions dialog in Google Maps
580
+ * New default stylesheet, refresh.css
581
+
582
+ = 1.8.9 =
583
+
584
+ * Fixed bug with database upgrade in multi-user additional calendars
585
+ * Fixed bug where calendar picked up current month labeling using current day of the month
586
+ * Added French translation
587
+
588
+ = 1.8.8 =
589
+
590
+ * Fixed bug in locations filtering that disabled feature if user not logged in.
591
+ * Re-arranged settings and added notices about options which will be removed in a future release.
592
+ * Revised RSS feed to use event permalinks when they are available.
593
+
594
+ = 1.8.7 =
595
+
596
+ * One very minor change in 1.8.6 caused some plug-in conflicts, so I rolled that change back. Will find another solution to the problem it solved. This change affects very few users.
597
+
598
+ = 1.8.6 =
599
+
600
+ * Fixed bug with {details} template tag when Upcoming widgets configured as Events
601
+ * Location and category filters now do not display forms/lists if there isn't more than one choice.
602
+ * Extended details link feature to main calendar output and added to output options.
603
+ * Minor changes to time-entry jQuery plug-in to improve usability.
604
+ * Updated Japanese translation to 1.8.5
605
+ * Added Russian translation to 1.8.5
606
+
607
+ = 1.8.5 =
608
+
609
+ * Another bug fix to monthly-by-day recurrence.
610
+ * Fixed minor problem with default template not being visible in widget.
611
+ * Fixed 'widget title linked' bug.
612
+ * Added Turkish translation by Mehmet Ko&231;ali
613
+
614
+ = 1.8.4 =
615
+
616
+ * Mini calendar widget had a mis-labeled option field
617
+ * Custom User settings for event region didn't function correctly.
618
+ * A variety of bug fixes applied to events repeating on a monthly-by-day basis
619
+
620
+ = 1.8.3 =
621
+
622
+ * Turned on spam flag toggle, which I had commented out and failed to restore...
623
+ * Default return false ('not spam') for privileged users when checking Akismet
624
+
625
+ = 1.8.2 =
626
+
627
+ * Fixed bug with {icon} template tag, for real.
628
+ * Fixed RSS missing argument
629
+ * Fixed empty list rendering in upcoming events widget
630
+
631
+ = 1.8.1 =
632
+
633
+ * Fixed bug with region saving on edit of location
634
+ * Fixed bug with single-event view receiving date as array
635
+ * Fixed bug with {icon} template tag
636
+ * Fixed bug with calendar output if user settings are enabled but not applied by user
637
+ * Fixed bug with list/grid format toggle
638
+ * Fixed bug with upcoming events limited by category names
639
+
640
+ = 1.8.0 =
641
+
642
+ * Added event region as a location field
643
+ * Added time selector and altered calendar range selector.
644
+ * Added visual editor for event description textarea.
645
+ * Added templating tag to add a link to the single event view.
646
+ * Added option to not display weekends in grid format.
647
+ * Added unique ID for each event in calendar.
648
+ * Added default sort order option for admin events list.
649
+ * Added admin events list to screen while editing or copying event.
650
+ * Added shortcode generator for Page and Post editor.
651
+ * Added spam protection: New events are now checked through Akismet if installed and configured.
652
+ * Added category selection shortcode.
653
+ * Added mini calendar widget.
654
+ * Added external link class.
655
+ * Added list/grid view toggle.
656
+ * Added mobile detection so mobile devices receive list format without JavaScript for easier reading.
657
+ * Added Upcoming Events widget sort order option.
658
+ * Added Option to link widget title to main calendar page.
659
+ * Change: Minor reorganization of settings page.
660
+ * Change: Altered time input to use non-military format time, added JavaScript time input.
661
+ * Change: Moved My Calendar menu items into the content menu.
662
+ * Change: When calendar is limited by categories, only the displayed categories are listed in the category key.
663
+ * Change: If widget title is left blank, widget will have no title.
664
+ * Change: Moved translation files into a subdirectory (/lang/)
665
+ * Bug fix: hcal dates
666
+ * Bug fix: problem where restoring styles referenced out of date styles
667
+ * Bug fix: error in primary stylesheet
668
+ * Bug fix: issue with month-by-day recurring events when recurrance set at 0
669
+ * Bug fix: issue with end dates when recurrance set at 0
670
+ * Bug fix: DB installed to match WPDB chararacter set and collation.
671
+ * Bug fix: turn-of-year page navigation in week view.
672
+ * Bug fix: entries not remembered in error condition post
673
+ * Updated German Translation to version 1.7.0 (Christopher Schauer)
674
+ * Updated German Translation to version 1.7.8 (Uwe Jonas)
675
+ * Note: during this update cycle, I received two German translations, and am using the most up to date version.
676
+ * Added Swedish Translation to version 1.7.8
677
+
678
+ = 1.7.8 =
679
+
680
+ * Bug fix: Behaviors page limits lost on settings refresh
681
+ * Bug fix: Fix {enddate} shortcode output.
682
+ * Bug fix: iCal output improvements
683
+ * Modification: RSS and iCal output are disabled entirely when turned off, rather than just hidden.
684
+ * Modification: Added styles for days out of current month
685
+
686
+ = 1.7.7 =
687
+
688
+ * Bug fix: Upcoming Events widget fault in 'dates' mode.
689
+
690
+ = 1.7.6 =
691
+
692
+ * Bug fix: Upcoming Events widget in days mode was not offsetting time using GMT reference. (Committed silently in 1.7.5)
693
+ * Bug fix: Default template not rendered in Today's Events when template left blank
694
+ * Bug fix: Slashes not stripped in category key.
695
+ * Bug fix: Upcoming Events widget if no upcoming events
696
+ * Bug fix: Error with retrieval of Author's ID
697
+ * Fixed some non-translatable text strings
698
+ * Logic change: Upcoming Events now bases choice on time rather than date (events happening later today are future, rather than only events happening tomorrow or later.)
699
+ * Enhancement: respects custom wp-content location definitions
700
+
701
+ = 1.7.5 =
702
+
703
+ * Bug fix: Error with upcoming events when selected by dates and holiday skipping enabled.
704
+ * Bug fix: Upcoming Events widget title defaulted to 'Today's Events'
705
+ * Change: Reversed order of Latitude/Longitude on forms to match Google's implementation.
706
+
707
+ = 1.7.4 =
708
+
709
+ * Bug fix: Upcoming events templates ran htmlentities on output
710
+
711
+ = 1.7.3 =
712
+
713
+ * Bug fix: upcoming events substitute text still not appearing in some contexts.
714
+ * Bug fix: Today's event substitute text had assignment in place of comparison
715
+ * Bug fix: Event location not saved properly on edit if Location Fields are disabled on input
716
+ * Bug fix: Fixed date and time issues in iCal output
717
+ * Bug fix: Fixed character set issue in RSS output
718
+ * Bug fix: Major problem with Holiday category event delimiting
719
+ * Danish translation updated to 1.7.0
720
+ * Japanese translation updated to 1.7.1
721
+ * Minor documentation and readme.txt updates
722
+ * Added additional fallback settings for widgets
723
+ * Fixed minor installation issue with version detection.
724
+ * Added CSS hook .nextmonth on dates occurring past the end of the currently displayed month.
725
+ * Added check for '#' symbol on hex colors in category management.
726
+
727
+ = 1.7.2 =
728
+
729
+ * Bug fix: Fixed import from Calendar feature.
730
+ * Bug fixed: Upcoming events widget default text fixed
731
+ * Italian translation updated to 1.7.0
732
+
733
+ = 1.7.1 =
734
+
735
+ * Default setting for custom user location type not set
736
+ * Reset for inherit.css styles missing
737
+ * Widget shortcodes stripped HTML
738
+ * Added a fallback function for exif_imagetype 'cuz some servers don't have it available by default.
739
+ * Nonce missing in database upgrade
740
+ * Ability to edit text for shortcode fallback (No events text) lost.
741
+ * Widget defaults not installed on new installation
742
+ * Mini and List jQuery did not prevent default link action
743
+ * Changed install action to default User settings to off.
744
+
745
+ = 1.7.0 =
746
+
747
+ * Fix in AJAX navigation for IE
748
+ * Fix in JavaScript to re-activate close button
749
+ * Fixed bug with locations list not registering current location type in form mode
750
+ * Fixed bug with upcoming events and today's events output when regions limits were set
751
+ * Fixed bug with upcoming events producing incorrect dates for events recurring on a specific day of the month.
752
+ * Revision of Widgeting setup to offer multi-widget support (will require you to re-setup your widgets)
753
+ * Revision of style editor to use external stylesheets.
754
+ * Revision of style support to add option for custom stylesheets stored outside of plugin directory
755
+ * Added: multiple base stylesheets
756
+ * Added: Event markup in hCal format
757
+ * Added Weekly mode for list and grid view
758
+ * Added RSS and iCal exports for upcoming events (enable and disable in settings)
759
+ * Added option to block display of an event if there is an event that day which is in a designated 'Holiday' category.
760
+ * Added permission setting to allow non-administrators to edit or delete any event.
761
+ * Added Czech translation (to 1.6.3)
762
+ * Updated Italian and Danish translations
763
+ * Security: Implemented nonces
764
+
765
+ = 1.6.3 =
766
+
767
+ * Updated jQuery to fix conflicts in previous versions and so behaviors would work with AJAX navigation. Not updated by upgrade; use Behaviors reset to apply.
768
+ * Incorporated option to enable AJAX navigation for next/previous navigation.
769
+ * Fixed bug with multi-month display in list format where January could not be displayed.
770
+ * Revised settings page for clarity.
771
+ * Fixed some default settings issues.
772
+ * Fixed a bug where the locations lists didn't respect the datatype parameter.
773
+ * Added templating to event titles for calendar grid or list output.
774
+
775
+ = 1.6.2 =
776
+
777
+ * Fixed broken style editor. (The way it was broken was awfully weird...kinda wonder how I did it!)
778
+ * Fixed missing div in calendar list output.
779
+ * Removed debugging call which had been left from testing.
780
+ * Fixed storage of initial settings for user settings (array did not store probably initially.)
781
+ * Added Italian translation by [Sabir Musta](http://mustaphasabir.altervista.org)
782
+
783
+ = 1.6.1 =
784
+
785
+ * Bug fix in event saving
786
+
787
+ = 1.6.0 =
788
+
789
+ * Feature: User profile defined time zone preference
790
+ * Feature: User profile defined location preference
791
+ * Feature: Define event host as separate from event author
792
+ * Feature: Added ability to hide Prev/Next links as shortcode attribute
793
+ * Change: Separated Style editing from JS editing
794
+
795
+ = 1.5.4 =
796
+
797
+ * Fixed: Bug with permissions in event approval process.
798
+
799
+ = 1.5.3 =
800
+
801
+ * Fixed: Bug which broke the {category} template tag
802
+ * Fixed: Bug which moved extra parameters before the "?" in URLs
803
+ * Fixed: Bug which produced an incorrect date with day/month recurring events on dates with no remainder
804
+ * Added: Japanese translation by [Daisuke Abe](http://www.alter-ego.jp/)
805
+
806
+ = 1.5.2 =
807
+
808
+ * Fixed: Bug where event data wasn't remembered if an error was triggered on submission.
809
+
810
+ = 1.5.1 =
811
+
812
+ * Fixed: Bug where events recurring monthly by days appeared on wrong date when month begins on Sunday.
813
+ * Fixed: Bug where events recurring monthly by days appeared on dates prior to the scheduled event start.
814
+ * Performance improvement: Added SQL join to incorporate category data in event object
815
+ * Added quicktag to provide access to category color and icon in widget templates
816
+ * Changed link expiration to be associated with the end date of events rather than the beginning date.
817
+ * Updated readme plugin description, help files, and screenshots.
818
+
819
+ = 1.5.0 =
820
+
821
+ * Added: German translation.
822
+ * Updated: Danish translation.
823
+ * Added: Administrator notification by email feature [Contributions by Roland]
824
+ * Added: Reservations and Approval system for events. [Contributions by Roland]
825
+ * Added: Events can be recurring on x day of month, e.g. 3rd Monday of the month.
826
+
827
+ = 1.4.10 =
828
+
829
+ * Fixed: Failed to increment internal version pointer in previous version.
830
+ * Fixed: Invalid styles created if category color set to default.
831
+ * Fixed: (Performance) Default calendar view attempted to select invalid category.
832
+ * Updated: Danish translation.
833
+
834
+ = 1.4.9 =
835
+
836
+ * Fixed: Bug where location edits couldn't be saved if location fields were on and dropdown was off
837
+ * Fixed: Bug where latitude and longitude were switched on Google Maps links
838
+ * Fixed: Bug where map link would not be provided if no location data was entered except Lat/Long coordinates.
839
+
840
+ = 1.4.8 =
841
+
842
+ * Added: Ability to copy events to create a new instance of that event
843
+ * Added: Customization of which input elements are visible separate from what output is shown.
844
+ * Fixed: Issue where one JS element could not be fully disabled
845
+ * Fixed: Internationalization fault with Today's Events showing events from previous day
846
+ * Fixed some assorted text errors and missing internationalization strings.
847
+ * Fixed issue where the 'Help' link was added to all plug-in listings.
848
+ * Reorganized settings page UI.
849
+
850
+ = 1.4.7 =
851
+
852
+ * Fixed: Bug where infinitely recurring events whose first occurrence was in the future were not rendered in upcoming events
853
+ * Fixed: Bug where infinitely recurring bi-weekly events only rendered their first event in calendar view
854
+ * Added: Option to indicate whether registration for an event is open or closed, with customizable text.
855
+ * Added: Option to supply a short description alternative to the full description.
856
+
857
+ = 1.4.6 =
858
+
859
+ * Fixed: Flash of unstyled content prevention scripts weren't disabled when other scripting was disabled.
860
+ * Fixed: Categories which started with numerals couldn't have custom styles.
861
+ * Fixed: Locations required valid 0 float value to save records on some servers; now supplied by default.
862
+
863
+ = 1.4.5 =
864
+
865
+ * Fixed a bug with editing and adding locations
866
+ * Fixed a bug with error messages when adding categories
867
+ * Fixed a bug with identification of current day (again?)
868
+ * Added Danish translation (Thanks to Jakob Smith)
869
+
870
+ = 1.4.4 =
871
+
872
+ * Fixed a bug where event end times tags were not rendered when blank in widget templates
873
+ * Fixed a bug with event adding and updating for Windows IIS
874
+ * Fixed a bug with international characters
875
+ * Reduced number of SQL queries made.
876
+ * Moved JavaScript output to footer.
877
+ * Improved error messages.
878
+ * Significant edits to basic codebase to improve efficiency.
879
+ * Fixed bug where full default styles didn't initially load on new installs.
880
+ * Re-organized default styles to make it easier for users to customize colors.
881
+
882
+ = 1.4.3 =
883
+
884
+ * Fixed a bug where event end times were displaying the start time instead when editing.
885
+ * Fixed a bug introduced by the mini calendar option which displayed titles twice in list format.
886
+ * Fixed a bunch of typos.
887
+ * Added a loop which automatically adds the mini calendar styles if you don't already have them.
888
+ * Fixed a bug where JS didn't run if the 'show only on certain pages' option was used.
889
+ * Added a qualifier for upgrading databases when you haven't added any events.
890
+
891
+ = 1.4.2 =
892
+
893
+ * Fixed a bug in the widget display code which caused problems displaying multiple categories.
894
+
895
+ = 1.4.1 =
896
+
897
+ * Database upgrade didn't run for some users in 1.4.0. Added manual check and upgrade if necessary.
898
+
899
+ = 1.4.0 =
900
+
901
+ * Bug fixed: Today's Events widget was not taking internationalized time as it's argument
902
+ * Added end time field for events
903
+ * Added option for links to expire after events have occurred.
904
+ * Added options for alternate applications of category colors in output.
905
+ * Added ability to use My Calendar shortcodes in text widgets.
906
+ * Added GPS location option for locations
907
+ * Added zoom selection options for map links
908
+ * Lengthened maximum length for category and event titles
909
+ * Added a close link on opened events details boxes.
910
+ * Added an option for a mini calendar display type in shortcode
911
+ * Optimized some SQL queries and reduced total number of queries significantly.
912
+ * Extended the featured to show CSS only on certain pages to include JavaScript as well.
913
+ * Upcoming events widget only allowed up to 99 events to be shown forward or back. Changed to 999.
914
+ * Attempted to solve a problem with infinitely recurring events not appearing in upcoming events. Let me know.
915
+ * Added setting to change Previous Month/Next Month text.
916
+ * Yeah, that's enough for now.
917
+
918
+ = 1.3.8 =
919
+
920
+ * Fixed problem with CSS editing which effectively disabled CSS unless a specific choice had been made for pages to show CSS
921
+
922
+ = 1.3.7 =
923
+
924
+ * Aren't you enjoying the daily upgrades? I made a mistake in 1.3.5 which hid text in an incorrect way, causing problems in some contexts.
925
+
926
+ = 1.3.6 =
927
+
928
+ * Fixed an issue where not having defined Pages to show CSS resulted in a PHP warning for some configs.
929
+
930
+ = 1.3.5 =
931
+
932
+ * Fix for flash of unstyled content issue.
933
+ * Added configuration for time text on events with non-specific time.
934
+ * Fixed bug where, in list views with multiple months, events occurring on days which did not exist in the previous month were not rendered. (Such as March 30th where previous month was February.)
935
+ * Fixed bug where the multi-month view setting for lists caused previous/next events buttons to skip months in calendar view.
936
+ * Added option to disable category icons.
937
+ * Added option to insert text in calendar caption/title area, appended to the month/year information.
938
+ * Fixed a bug where it was not possible to choose the "Show by days" option in the upcoming events widget.
939
+ * Updated documentation to match
940
+ * Fixed a bug where upcoming events in Days mode did not display correct date
941
+ * Added an option to define text to be displayed in place of Today's Events widget if there are no events scheduled.
942
+ * Minor changes to default CSS
943
+ * Ability to show CSS and JavaScript only on selected pages.
944
+
945
+ = 1.3.4 =
946
+
947
+ * Fixed a bug with map link and address display which I forgot to deal with in previous release.
948
+
949
+ = 1.3.3 =
950
+
951
+ * Fixed bug with upgrade path which caused locations database to be created on every activation (also cause of errors with some other plugins). (Thanks to Steven J. Kiernan)
952
+ * Made clone object PHP 4 compatible (Thanks to Peder Lindkvist)
953
+ * Corrected errors in shortcode functions for today's events
954
+ * Corrected rendering of non-specific time events as happening at midnight in widget output
955
+
956
+ = 1.3.2 =
957
+
958
+ * Fixed bugs with unstripped slashes in output
959
+ * Fixed a bug where users could not add location information in events if they had not added any recurring locations
960
+ * Removed requirement that address string must be five characters to display a link
961
+
962
+ = 1.3.1 =
963
+
964
+ * Corrected incorrect primary key in upgrade path.
965
+ * Added version incrementing in upgrade path.
966
+
967
+ = 1.3.0 =
968
+
969
+ * Fixed a CSS class which was applied to an incorrect element.
970
+ * Revisions to the Calendar import methods
971
+ * Moved style editing to its own page
972
+ * Added JavaScript editing to allow for customization of jQuery behaviors.
973
+ * Internationalized date formats
974
+ * Shortcode support for multiple categories.
975
+ * Shortcode support for custom templates in upcoming and today's events
976
+ * Added a settings option to eliminate the heading in list format display.
977
+ * Fixed a bug which treated the event repetition value as a string on event adding or updating, not allowing some users to use '0' as an event repetition.
978
+ * Made events listing sortable in admin view
979
+ * Minor revisions in admin UI.
980
+ * Added database storage for frequently used venues or event locations.
981
+ * Modified JavaScript for list display to automatically expand events scheduled for today.
982
+
983
+ = 1.2.1 =
984
+
985
+ * Corrected a typo which broke the upcoming events widget.
986
+
987
+ = 1.2.0 =
988
+
989
+ * Added shortcodes to support inserting upcoming events and todays events lists into page/post content.
990
+ * Added option to restrict upcoming events widgets by category
991
+ * More superficial CSS changes
992
+ * Added Brazilian Portuguese language files
993
+ * Fixed bug where I reversed the future and past variable values for upcoming events widgets
994
+ * Fixed bug in multi-user permissions.
995
+ * Added feature to look for a custom location for icons to prevent overwriting of custom icons on upgrade.
996
+
997
+ = 1.1.0 =
998
+
999
+ * Fixed some problems with Upcoming Events past events not scrolling off; hopefully all!
1000
+ * Fixed some problems with fuzzy interpretations of the numbers of past/future events displayed in Upcoming Events.
1001
+ * Added Bi-weekly events
1002
+ * Added restrictions so that admin level users can edit any events but other users can only edit their own events
1003
+ * Removed character restrictions on event titles
1004
+ * Revised default stylesheet
1005
+
1006
+ = 1.0.2 =
1007
+
1008
+ * Fixed problems with editing and deleting events or categories in multiblog installation
1009
+ * Fixed escaping/character set issue
1010
+ * Fixed issue when blog address and wp address did not match (introduced in 1.0.1)
1011
+ * Added import method to transfer events and categories from Kieran O'Shea's Calendar plugin
1012
+
1013
+ = 1.0.1 =
1014
+
1015
+ * Added missing template code for event end dates.
1016
+ * Changed defaults so that styles and javascript are initially turned on.
1017
+ * Removed function collisions with Calendar
1018
+ * Fixed bug where My Calendar didn't respect the timezone offset in identifying the current day.
1019
+ * Fixed bug where multiblog installations in WP 3.0 were unable to save events and settings.
1020
+ * Added Spanish translation, courtesy of [Esteban Truelsegaard](http://www.netmdp.com). Thanks!
1021
+
1022
+ = 1.0.0 =
1023
+
1024
+ * Initial launch.
css/mc-print.css CHANGED
@@ -1,3 +1,5 @@
 
 
1
  .my-calendar-header, h3 img, .mc-toggle, .mc_edit_links, #mc-export, .longdesc, .shortdesc, .mc-print, form {
2
  display: none;
3
  }
1
+ /* If copying this stylesheet, place in your theme directory in a /css subdirectory. /wp-content/yourtheme/css/mc-print.css */
2
+
3
  .my-calendar-header, h3 img, .mc-toggle, .mc_edit_links, #mc-export, .longdesc, .shortdesc, .mc-print, form {
4
  display: none;
5
  }
css/mc-styles.css CHANGED
@@ -3,6 +3,10 @@
3
  font-size: 1em
4
  }
5
 
 
 
 
 
6
  .mcbuy, .mcsbuy {
7
  font-size: 1.1em;
8
  line-height: 1.5
@@ -86,8 +90,8 @@ ul.links li {
86
  background: #eee
87
  }
88
 
89
- .jd-my-calendar .pending td {
90
- color: #666
91
  }
92
 
93
  .jd-my-calendar fieldset fieldset {
@@ -178,10 +182,17 @@ ul.links li {
178
  margin: 10px 10px 0 0
179
  }
180
 
 
 
 
 
 
181
  .jd-my-calendar .postbox .inside {
182
  overflow: visible !important
183
  }
184
 
 
 
185
  /* some plugins change this, but I need it at WP default. */
186
  .jd-my-calendar .meta-box-sortables {
187
  min-height: 0
@@ -258,6 +269,11 @@ strong.label {
258
  top: .7em;
259
  }
260
 
 
 
 
 
 
261
  .jd-my-calendar .counter {
262
  padding-right: 6px;
263
  border-right: 16px solid green;
@@ -305,9 +321,16 @@ strong.label {
305
  background: #f3f3f3;
306
  }
307
 
 
 
 
 
 
308
  .mc-tabs .tabs a.active {
309
  border-bottom: 1px solid #fefefe;
310
  background: #fefefe;
 
 
311
  }
312
 
313
  .mc-tabs .wptab {
@@ -317,6 +340,10 @@ strong.label {
317
  border: 1px solid #ccc;
318
  }
319
 
 
 
 
 
320
  .jd-my-calendar .ui-accordion-header, .mc-settings-page #mc-sortable li {
321
  border: 1px solid #ccc;
322
  border-radius: 2px;
@@ -325,6 +352,15 @@ strong.label {
325
  margin: 1px 0;
326
  }
327
 
 
 
 
 
 
 
 
 
 
328
  .jd-my-calendar .ui-accordion-header.ui-state-hover, .ui-accordion-header.ui-state-focus, .mc-settings-page #mc-sortable li:hover {
329
  background: #f6f6f6;
330
  box-shadow: 0 0 2px #ddd;
@@ -339,16 +375,19 @@ strong.label {
339
  }
340
 
341
  #mc-sortable .mc-calendar {
342
- background: #ffc;
343
  border: 1px solid #cc8;
344
  }
345
 
346
  #mc-sortable li.mc-stop {
347
- margin: 1px -1em;
348
  border-radius: none;
349
- border-left: none;
350
- border-right: none;
351
- padding: 2px 2em;
 
 
 
 
352
  }
353
 
354
  #mc-sortable div.dashicons {
@@ -372,6 +411,14 @@ strong.label {
372
  margin-bottom: 1em;
373
  }
374
 
 
 
 
 
 
 
 
 
375
  .jd-my-calendar .checkboxes li {
376
  display: inline-block;
377
  padding: 5px;
@@ -379,6 +426,10 @@ strong.label {
379
  margin: 2px;
380
  }
381
 
 
 
 
 
382
  .jd-my-calendar .checkboxes li:hover {
383
  background: #fff;
384
  }
@@ -436,11 +487,10 @@ strong.label {
436
  color: red;
437
  }
438
 
439
- .jd-my-calendar textarea[readonly="readonly"] {
440
- color: #333;
441
- border: none;
442
- box-shadow: none;
443
- font-size: 1.4em;
444
  }
445
 
446
  .mc-locations label {
@@ -520,6 +570,12 @@ tr.problem .error {
520
  display: block;
521
  }
522
 
 
 
 
 
 
 
523
  #my-calendar .inside div iframe {
524
  float: none;
525
  }
3
  font-size: 1em
4
  }
5
 
6
+ #my-calendar #wp-content-editor-tools {
7
+ background: #fff;
8
+ }
9
+
10
  .mcbuy, .mcsbuy {
11
  font-size: 1.1em;
12
  line-height: 1.5
90
  background: #eee
91
  }
92
 
93
+ .jd-my-calendar .pending td, .jd-my-calendar .row-actions {
94
+ color: #666;
95
  }
96
 
97
  .jd-my-calendar fieldset fieldset {
182
  margin: 10px 10px 0 0
183
  }
184
 
185
+ .jd-my-calendar .postbox.wptab {
186
+ margin: 0 10px 0 0!important;
187
+ border: 1px solid #e5e5e5;
188
+ }
189
+
190
  .jd-my-calendar .postbox .inside {
191
  overflow: visible !important
192
  }
193
 
194
+
195
+
196
  /* some plugins change this, but I need it at WP default. */
197
  .jd-my-calendar .meta-box-sortables {
198
  min-height: 0
269
  top: .7em;
270
  }
271
 
272
+ .wp-picker-holder {
273
+ position: absolute;
274
+ z-index: 10;
275
+ }
276
+
277
  .jd-my-calendar .counter {
278
  padding-right: 6px;
279
  border-right: 16px solid green;
321
  background: #f3f3f3;
322
  }
323
 
324
+ .mc-tabs.settings .tabs a {
325
+ padding: 8px;
326
+ font-size: 1.2em;
327
+ }
328
+
329
  .mc-tabs .tabs a.active {
330
  border-bottom: 1px solid #fefefe;
331
  background: #fefefe;
332
+ text-decoration: none;
333
+ cursor: text;
334
  }
335
 
336
  .mc-tabs .wptab {
340
  border: 1px solid #ccc;
341
  }
342
 
343
+ .js .wptab:not( :first-child ) {
344
+ display: none;
345
+ }
346
+
347
  .jd-my-calendar .ui-accordion-header, .mc-settings-page #mc-sortable li {
348
  border: 1px solid #ccc;
349
  border-radius: 2px;
352
  margin: 1px 0;
353
  }
354
 
355
+ .mc-settings-page #mc-sortable .mc-updated {
356
+ background-color: #ffa;
357
+ }
358
+
359
+ #mc-sortable .mc-buttons {
360
+ display: inline-block;
361
+ width: 7em;
362
+ }
363
+
364
  .jd-my-calendar .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;
375
  }
376
 
377
  #mc-sortable .mc-calendar {
378
+ background-color: #ffa!important;
379
  border: 1px solid #cc8;
380
  }
381
 
382
  #mc-sortable li.mc-stop {
 
383
  border-radius: none;
384
+ background-color: #222;
385
+ color: #eee;
386
+ }
387
+
388
+ #mc-sortable li.mc-stop:hover {
389
+ background-color: #000;
390
+ color: #bbb;
391
  }
392
 
393
  #mc-sortable div.dashicons {
411
  margin-bottom: 1em;
412
  }
413
 
414
+ .mc_permissions {
415
+ padding: .5em;
416
+ }
417
+
418
+ .mc_permissions:nth-of-type(odd) {
419
+ background: rgba( 0,0,0, .05 );
420
+ }
421
+
422
  .jd-my-calendar .checkboxes li {
423
  display: inline-block;
424
  padding: 5px;
426
  margin: 2px;
427
  }
428
 
429
+ .jd-my-calendar .mc_permissions:nth-of-type(odd) .checkboxes li {
430
+ background: transparent;
431
+ }
432
+
433
  .jd-my-calendar .checkboxes li:hover {
434
  background: #fff;
435
  }
487
  color: red;
488
  }
489
 
490
+ .mc-controls {
491
+ font-weight: 700;
492
+ text-align: right;
493
+ margin: -3em 0 0;
 
494
  }
495
 
496
  .mc-locations label {
570
  display: block;
571
  }
572
 
573
+ .event_time_label {
574
+ display: inline-block;
575
+ padding: .25em;
576
+ background: #ffc;
577
+ }
578
+
579
  #my-calendar .inside div iframe {
580
  float: none;
581
  }
css/reset.css CHANGED
@@ -66,4 +66,12 @@
66
  overflow: hidden;
67
  position: absolute;
68
  max-height: 1px;
69
- }
 
 
 
 
 
 
 
 
66
  overflow: hidden;
67
  position: absolute;
68
  max-height: 1px;
69
+ }
70
+
71
+ button.mc-toggle {
72
+ border: 0;
73
+ padding: 4px;
74
+ background-color: transparent;
75
+ }
76
+
77
+ .mcjs .mc-main .details, .mcjs .mc-main .calendar-events { display: none; }
js/ajax.js CHANGED
@@ -29,5 +29,19 @@
29
  }
30
  });
31
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
  });
33
  }(jQuery));
29
  }
30
  });
31
 
32
+ var is_checked = $( 'input[id="e_allday"]' ).prop( "checked" );
33
+ if ( ! is_checked ) {
34
+ $( '.event_time_label' ).hide();
35
+ }
36
+
37
+ $( 'input[id="e_allday"]' ).change( function() {
38
+ var checked = $(this).prop( "checked" );
39
+ if ( checked ) {
40
+ $( '.event_time_label' ).show();
41
+ } else {
42
+ $( '.event_time_label' ).hide();
43
+ }
44
+ });
45
+
46
  });
47
  }(jQuery));
js/mc-ajax.js CHANGED
@@ -4,8 +4,9 @@
4
  $(document).on('click', '.calendar .my-calendar-nav a', function (e) {
5
  e.preventDefault();
6
  var link = $(this).attr('href');
 
7
  var ref = $(this).attr('data-rel');
8
- $('#' + ref).html('<div class=\"loading\"><span>Loading...</span></div>');
9
  $('#' + ref).load(link + ' #' + ref + ' > *', function () {
10
  $('.calendar-event').children().not('.event-title').hide();
11
  $('#' + ref).attr('tabindex', '-1').focus();
@@ -15,7 +16,8 @@
15
  e.preventDefault();
16
  var link = $(this).attr('href');
17
  var ref = $(this).attr('data-rel');
18
- $('#' + ref).html('<div class=\"loading\"><span>Loading...</span></div>');
 
19
  $('#' + ref).load(link + ' #' + ref + ' > *', function () {
20
  $('li.mc-events').children().not('.event-date').hide();
21
  $('li.current-day').children().show();
@@ -26,7 +28,8 @@
26
  e.preventDefault();
27
  var link = $(this).attr('href');
28
  var ref = $(this).attr('data-rel');
29
- $('#' + ref).html('<div class=\"loading\"><span>Loading...</span></div>');
 
30
  $('#' + ref).load(link + ' #' + ref + ' > *', function () {
31
  $('.mini .has-events').children().not('.trigger, .mc-date, .event-date').hide();
32
  $('#' + ref).attr('tabindex', '-1').focus();
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=\"loading\" style=\"height:' + height + 'px\"><span>Loading...</span></div>');
10
  $('#' + ref).load(link + ' #' + ref + ' > *', function () {
11
  $('.calendar-event').children().not('.event-title').hide();
12
  $('#' + ref).attr('tabindex', '-1').focus();
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=\"loading\" style=\"height:' + height + 'px\"><span>Loading...</span></div>');
21
  $('#' + ref).load(link + ' #' + ref + ' > *', function () {
22
  $('li.mc-events').children().not('.event-date').hide();
23
  $('li.current-day').children().show();
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=\"loading\" style=\"height:' + height + 'px\"><span>Loading...</span></div>');
33
  $('#' + ref).load(link + ' #' + ref + ' > *', function () {
34
  $('.mini .has-events').children().not('.trigger, .mc-date, .event-date').hide();
35
  $('#' + ref).attr('tabindex', '-1').focus();
js/mc-grid.js CHANGED
@@ -5,8 +5,10 @@
5
  $(document).on("click", ".calendar-event .event-title",
6
  function (e) {
7
  e.preventDefault(); // remove line if you are using a link in the event title
 
8
  $(this).parent().children().not(".event-title").toggle().attr("tabindex", "-1");
9
  $(this).parent().focus();
 
10
  });
11
  $(document).on("click", ".calendar-event .close",
12
  function (e) {
5
  $(document).on("click", ".calendar-event .event-title",
6
  function (e) {
7
  e.preventDefault(); // remove line if you are using a link in the event title
8
+ var current_date = $(this).parent().children();
9
  $(this).parent().children().not(".event-title").toggle().attr("tabindex", "-1");
10
  $(this).parent().focus();
11
+ $(".calendar-event").children().not(".event-title").not( current_date ).hide();
12
  });
13
  $(document).on("click", ".calendar-event .close",
14
  function (e) {
js/sortable.js CHANGED
@@ -1,18 +1,19 @@
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
- $('#mc-sortable-update').css({'padding': '6px', 'background-color': '#ffc', 'font-weight': 'bold'});
6
  }
7
  });
8
  $('#mc-sortable .up').on('click', function (e) {
9
  e.preventDefault();
10
  $(this).parents('li').insertBefore($(this).parents('li').prev());
11
- $(this).parents('li').css({'background': '#ffc'});
 
12
  });
13
  $('#mc-sortable .down').on('click', function (e) {
14
  e.preventDefault();
15
  $(this).parents('li').insertAfter($(this).parents('li').next());
16
- $(this).parents('li').css({'background': '#ffc'});
 
17
  });
18
  });
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 CHANGED
@@ -1,15 +1,23 @@
1
  jQuery(document).ready(function ($) {
2
- var tabs = $('.mc-tabs .wptab').length;
3
- $('.mc-tabs .tabs a[href="#' + firstItem + '"]').addClass('active').attr( 'aria-selected', 'true' );
4
- if ( tabs > 1 ) {
5
- $( '.mc-tabs .wptab' ).not( '#' + firstItem ).hide();
6
- $( '.mc-tabs .tabs a' ).on( 'click', function (e) {
7
- e.preventDefault();
8
- $('.mc-tabs .tabs a').removeClass('active').attr( 'aria-selected', 'false' );
9
- $(this).addClass('active').attr( 'aria-selected', 'true' );
10
- var target = $(this).attr('href');
11
- $('.mc-tabs .wptab').not(target).hide();
12
- $(target).show().attr('tabindex','-1').focus();
13
- });
14
- }
 
 
 
 
 
 
 
 
15
  });
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
  });
lang/my-calendar-cs_CZ.mo CHANGED
Binary file
lang/my-calendar-da_DK.mo CHANGED
Binary file
lang/my-calendar-de_DE.mo CHANGED
Binary file
lang/my-calendar-es_ES.mo CHANGED
Binary file
lang/my-calendar-fa_IR.mo ADDED
Binary file
lang/my-calendar-gl_ES.mo CHANGED
Binary file
lang/my-calendar-hu_HU.mo CHANGED
Binary file
lang/my-calendar-nb_NO.mo CHANGED
Binary file
lang/my-calendar-nl_NL.mo CHANGED
Binary file
lang/my-calendar-pl_PL.mo CHANGED
Binary file
lang/my-calendar-pt_PT.mo CHANGED
Binary file
lang/my-calendar-sk_SK.mo CHANGED
Binary file
lang/my-calendar-sv_SE.mo CHANGED
Binary file
lang/my-calendar-tr_TR.mo CHANGED
Binary file
my-calendar-api.php CHANGED
@@ -150,70 +150,76 @@ function my_calendar_rss( $events = array() ) {
150
  $events = mc_get_rss_events( $cat_id );
151
  }
152
  $output = mc_format_rss( $events );
153
- header( 'Content-type: application/rss+xml' );
154
- header( "Pragma: no-cache" );
155
- header( "Expires: 0" );
156
- echo $output;
 
 
157
  }
158
 
159
  function mc_format_rss( $events ) {
160
- $template = "\n<item>
161
- <title>{rss_title}</title>
162
- <link>{details_link}</link>
163
- <pubDate>{rssdate}</pubDate>
164
- <dc:creator>{author}</dc:creator>
165
- <description><![CDATA[{rss_description}]]></description>
166
- <date>{dtstart}</date>
167
- <dateSubmitted>{rssdate}</dateSubmitted>
168
- <content:encoded><![CDATA[<div class='vevent'>
169
- <h1 class='summary'>{rss_title}</h1>
170
- <div class='description'>{rss_description}</div>
171
- <p class='dtstart' title='{ical_start}'>Begins: {time} on {date}</p>
172
- <p class='dtend' title='{ical_end}'>Ends: {endtime} on {enddate}</p>
173
- <p>Recurrance: {recurs}</p>
174
- <p>Repetition: {repeats} times</p>
175
- <div class='location'>{rss_hcard}</div>
176
- {rss_link_title}
177
- </div>]]></content:encoded>
178
- <dc:format xmlns:dc='http://purl.org/dc/elements/1.1/'>text/html</dc:format>
179
- <dc:source xmlns:dc='http://purl.org/dc/elements/1.1/'>" . home_url() . "</dc:source>
180
- {guid}
181
- </item>\n";
182
-
183
- if ( get_option( 'mc_use_rss_template' ) == 1 ) {
184
- $templates = get_option( 'mc_templates' );
185
- $template = $templates['rss'];
186
- }
187
 
188
- $charset = get_bloginfo( 'charset' );
189
- $output = '<?xml version="1.0" encoding="' . $charset . '"?>
190
- <rss version="2.0"
191
- xmlns:content="http://purl.org/rss/1.0/modules/content/"
192
- xmlns:dc="http://purl.org/dc/elements/1.1/"
193
- xmlns:atom="http://www.w3.org/2005/Atom"
194
- xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
195
- xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
196
- >
197
- <channel>
198
- <title>' . get_bloginfo( 'name' ) . ' Calendar</title>
199
- <link>' . home_url() . '</link>
200
- <description>' . get_bloginfo( 'description' ) . ': My Calendar Events</description>
201
- <language>' . get_bloginfo( 'language' ) . '</language>
202
- <managingEditor>' . get_bloginfo( 'admin_email' ) . ' (' . get_bloginfo( 'name' ) . ' Admin)</managingEditor>
203
- <generator>My Calendar WordPress Plugin http://www.joedolson.com/my-calendar/</generator>
204
- <lastBuildDate>' . mysql2date( 'D, d M Y H:i:s +0000', current_time( 'timestamp' ) ) . '</lastBuildDate>
205
- <atom:link href="' . htmlentities( esc_url( add_query_arg( $_GET, mc_get_current_url() ) ) ) . '" rel="self" type="application/rss+xml" />';
206
- foreach ( $events as $date ) {
207
- foreach ( array_keys( $date ) as $key ) {
208
- $event =& $date[ $key ];
209
- $array = mc_create_tags( $event );
210
- $output .= jd_draw_template( $array, $template, 'rss' );
211
  }
212
- }
213
- $output .= '</channel>
214
- </rss>';
215
 
216
- return mc_strip_to_xml( $output );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
217
  }
218
 
219
  // just a double check to try to ensure that the XML feed can be rendered.
@@ -240,4 +246,81 @@ function mc_strip_to_xml( $value ) {
240
  $ret = iconv( "UTF-8", "UTF-8//IGNORE", $ret );
241
 
242
  return $ret;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
243
  }
150
  $events = mc_get_rss_events( $cat_id );
151
  }
152
  $output = mc_format_rss( $events );
153
+ if ( $output ) {
154
+ header( 'Content-type: application/rss+xml' );
155
+ header( "Pragma: no-cache" );
156
+ header( "Expires: 0" );
157
+ echo $output;
158
+ }
159
  }
160
 
161
  function mc_format_rss( $events ) {
162
+ if ( is_array( $events ) && !empty( $events ) ) {
163
+ $template = "\n<item>
164
+ <title>{rss_title}</title>
165
+ <link>{details_link}</link>
166
+ <pubDate>{rssdate}</pubDate>
167
+ <dc:creator>{author}</dc:creator>
168
+ <description><![CDATA[{rss_description}]]></description>
169
+ <date>{dtstart}</date>
170
+ <dateSubmitted>{rssdate}</dateSubmitted>
171
+ <content:encoded><![CDATA[<div class='vevent'>
172
+ <h1 class='summary'>{rss_title}</h1>
173
+ <div class='description'>{rss_description}</div>
174
+ <p class='dtstart' title='{ical_start}'>Begins: {time} on {date}</p>
175
+ <p class='dtend' title='{ical_end}'>Ends: {endtime} on {enddate}</p>
176
+ <p>Recurrance: {recurs}</p>
177
+ <p>Repetition: {repeats} times</p>
178
+ <div class='location'>{rss_hcard}</div>
179
+ {rss_link_title}
180
+ </div>]]></content:encoded>
181
+ <dc:format xmlns:dc='http://purl.org/dc/elements/1.1/'>text/html</dc:format>
182
+ <dc:source xmlns:dc='http://purl.org/dc/elements/1.1/'>" . home_url() . "</dc:source>
183
+ {guid}
184
+ </item>\n";
 
 
 
 
185
 
186
+ if ( get_option( 'mc_use_rss_template' ) == 1 ) {
187
+ $templates = get_option( 'mc_templates' );
188
+ $template = $templates['rss'];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
189
  }
 
 
 
190
 
191
+ $charset = get_bloginfo( 'charset' );
192
+ $output = '<?xml version="1.0" encoding="' . $charset . '"?>
193
+ <rss version="2.0"
194
+ xmlns:content="http://purl.org/rss/1.0/modules/content/"
195
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
196
+ xmlns:atom="http://www.w3.org/2005/Atom"
197
+ xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
198
+ xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
199
+ >
200
+ <channel>
201
+ <title>' . get_bloginfo( 'name' ) . ' Calendar</title>
202
+ <link>' . home_url() . '</link>
203
+ <description>' . get_bloginfo( 'description' ) . ': My Calendar Events</description>
204
+ <language>' . get_bloginfo( 'language' ) . '</language>
205
+ <managingEditor>' . get_bloginfo( 'admin_email' ) . ' (' . get_bloginfo( 'name' ) . ' Admin)</managingEditor>
206
+ <generator>My Calendar WordPress Plugin http://www.joedolson.com/my-calendar/</generator>
207
+ <lastBuildDate>' . mysql2date( 'D, d M Y H:i:s +0000', current_time( 'timestamp' ) ) . '</lastBuildDate>
208
+ <atom:link href="' . htmlentities( esc_url( add_query_arg( $_GET, mc_get_current_url() ) ) ) . '" rel="self" type="application/rss+xml" />';
209
+ foreach ( $events as $date ) {
210
+ foreach ( array_keys( $date ) as $key ) {
211
+ $event =& $date[ $key ];
212
+ $array = mc_create_tags( $event );
213
+ $output .= jd_draw_template( $array, $template, 'rss' );
214
+ }
215
+ }
216
+ $output .= '</channel>
217
+ </rss>';
218
+
219
+ return mc_strip_to_xml( $output );
220
+ } else {
221
+ return false;
222
+ }
223
  }
224
 
225
  // just a double check to try to ensure that the XML feed can be rendered.
246
  $ret = iconv( "UTF-8", "UTF-8//IGNORE", $ret );
247
 
248
  return $ret;
249
+ }
250
+
251
+
252
+ function my_calendar_ical() {
253
+ $p = ( isset( $_GET['span'] ) ) ? 'year' : false;
254
+ $y = ( isset( $_GET['yr'] ) ) ? $_GET['yr'] : date( 'Y' );
255
+ $m = ( isset( $_GET['month'] ) ) ? $_GET['month'] : date( 'n' );
256
+ $ny = ( isset( $_GET['nyr'] ) ) ? $_GET['nyr'] : $y;
257
+ $nm = ( isset( $_GET['nmonth'] ) ) ? $_GET['nmonth'] : $m;
258
+
259
+ if ( $p ) {
260
+ $from = "$y-1-1";
261
+ $to = "$y-12-31";
262
+ } else {
263
+ $d = date( 't', mktime( 0, 0, 0, $m, 1, $y ) );
264
+ $from = "$y-$m-1";
265
+ $to = "$ny-$nm-$d";
266
+ }
267
+
268
+ $from = apply_filters( 'mc_ical_download_from', $from, $p );
269
+ $to = apply_filters( 'mc_ical_download_to', $to, $p );
270
+ $atts = array(
271
+ 'category' => null,
272
+ 'ltype' => '',
273
+ 'lvalue' => '',
274
+ 'source' => 'calendar',
275
+ 'author' => null,
276
+ 'host' => null
277
+ );
278
+ $atts = apply_filters( 'mc_ical_attributes', $atts );
279
+ extract( $atts );
280
+
281
+ global $mc_version;
282
+ // establish template
283
+ $template = "BEGIN:VEVENT
284
+ UID:{dateid}-{id}
285
+ LOCATION:{ical_location}
286
+ SUMMARY:{title}
287
+ DTSTAMP:{ical_start}
288
+ ORGANIZER;CN={host}:MAILTO:{host_email}
289
+ DTSTART:{ical_start}
290
+ DTEND:{ical_end}
291
+ URL;VALUE=URI:{link}
292
+ DESCRIPTION:{ical_desc}
293
+ CATEGORIES:{category}
294
+ END:VEVENT";
295
+ // add ICAL headers
296
+ $output = 'BEGIN:VCALENDAR
297
+ VERSION:2.0
298
+ METHOD:PUBLISH
299
+ PRODID:-//Accessible Web Design//My Calendar//http://www.joedolson.com//v' . $mc_version . '//EN';
300
+ // to do : add support for other arguments
301
+ $events = my_calendar_grab_events( $from, $to, $category, $ltype, $lvalue, $source, $author, $host );
302
+ // 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.
303
+ // rewrite array navigation so that this works.
304
+ // $events = my_calendar_events( $from, $to, $category, $ltype, $lvalue, $source, $author, $host );
305
+
306
+ if ( is_array( $events ) && ! empty( $events ) ) {
307
+ foreach ( array_keys( $events ) as $key ) {
308
+ $event =& $events[ $key ];
309
+ if ( is_object( $event ) ) {
310
+ if ( ! ( $event->category_private == 1 && ! is_user_logged_in() ) ) {
311
+ $array = mc_create_tags( $event );
312
+ $output .= "\n" . jd_draw_template( $array, $template, 'ical' );
313
+ }
314
+ }
315
+ }
316
+ }
317
+ $output .= "\nEND:VCALENDAR";
318
+ $output = html_entity_decode( preg_replace( "~(?<!\r)\n~", "\r\n", $output ) );
319
+ if ( ! ( isset( $_GET['sync'] ) && $_GET['sync'] == 'true' ) ) {
320
+ header( "Content-Type: text/calendar; charset=" . get_bloginfo( 'charset' ) );
321
+ header( "Pragma: no-cache" );
322
+ header( "Expires: 0" );
323
+ header( "Content-Disposition: inline; filename=my-calendar.ics" );
324
+ }
325
+ echo $output;
326
  }
my-calendar-behaviors.php CHANGED
@@ -69,7 +69,7 @@ function edit_my_calendar_behaviors() {
69
  <label
70
  for="mc_show_js"><?php _e( 'Insert scripts on these pages (comma separated post IDs)', 'my-calendar' ); ?></label>
71
  <input type="text" id="mc_show_js" name="mc_show_js"
72
- value="<?php echo $mc_show_js; ?>"/>
73
  </p>
74
 
75
  <div class='controls'>
@@ -100,25 +100,24 @@ function edit_my_calendar_behaviors() {
100
  <label
101
  for="calendar-js"><?php _e( 'Calendar Behaviors: Grid View', 'my-calendar' ); ?></label><br/><textarea
102
  id="calendar-js" name="mc_caljs" rows="12"
103
- cols="80"><?php echo $mc_caljs; ?></textarea>
104
  </p>
105
  <p>
106
  <label
107
  for="list-js"><?php _e( 'Calendar Behaviors: List View', 'my-calendar' ); ?></label><br/><textarea
108
  id="list-js" name="mc_listjs" rows="12"
109
- cols="80"><?php echo $mc_listjs; ?></textarea>
110
  </p>
111
  <p>
112
- <label
113
- for="mini-js"><?php _e( 'Calendar Behaviors: Mini Calendar View', 'my-calendar' ); ?></label><br/><textarea
114
  id="mini-js" name="mc_minijs" rows="12"
115
- cols="80"><?php echo $mc_minijs; ?></textarea>
116
  </p>
117
  <p>
118
  <label
119
  for="ajax-js"><?php _e( 'Calendar Behaviors: AJAX', 'my-calendar' ); ?></label><br/><textarea
120
  id="ajax-js" name="mc_ajaxjs" rows="12"
121
- cols="80"><?php echo $mc_ajaxjs; ?></textarea>
122
  </p>
123
  <?php } ?>
124
  <p>
69
  <label
70
  for="mc_show_js"><?php _e( 'Insert scripts on these pages (comma separated post IDs)', 'my-calendar' ); ?></label>
71
  <input type="text" id="mc_show_js" name="mc_show_js"
72
+ value="<?php echo esc_attr( $mc_show_js ); ?>"/>
73
  </p>
74
 
75
  <div class='controls'>
100
  <label
101
  for="calendar-js"><?php _e( 'Calendar Behaviors: Grid View', 'my-calendar' ); ?></label><br/><textarea
102
  id="calendar-js" name="mc_caljs" rows="12"
103
+ cols="80"><?php echo esc_js( $mc_caljs ); ?></textarea>
104
  </p>
105
  <p>
106
  <label
107
  for="list-js"><?php _e( 'Calendar Behaviors: List View', 'my-calendar' ); ?></label><br/><textarea
108
  id="list-js" name="mc_listjs" rows="12"
109
+ cols="80"><?php echo esc_js( $mc_listjs ); ?></textarea>
110
  </p>
111
  <p>
112
+ <label for="mini-js"><?php _e( 'Calendar Behaviors: Mini Calendar View', 'my-calendar' ); ?></label><br/><textarea
 
113
  id="mini-js" name="mc_minijs" rows="12"
114
+ cols="80"><?php echo esc_js( $mc_minijs ); ?></textarea>
115
  </p>
116
  <p>
117
  <label
118
  for="ajax-js"><?php _e( 'Calendar Behaviors: AJAX', 'my-calendar' ); ?></label><br/><textarea
119
  id="ajax-js" name="mc_ajaxjs" rows="12"
120
+ cols="80"><?php echo esc_js( $mc_ajaxjs ); ?></textarea>
121
  </p>
122
  <?php } ?>
123
  <p>
my-calendar-categories.php CHANGED
@@ -257,30 +257,34 @@ function mc_edit_category_form( $view = 'edit', $catID = '' ) {
257
  } else {
258
  $color = '';
259
  } ?>
260
- <label for="cat_name"><?php _e( 'Category Name', 'my-calendar' ); ?>:</label> <input
 
 
261
  type="text" id="cat_name" name="category_name" class="input" size="30"
262
  value="<?php if ( ! empty( $cur_cat ) && is_object( $cur_cat ) ) {
263
  echo stripslashes( esc_attr( $cur_cat->category_name ) );
264
  } ?>"/>
265
- <label for="cat_color"><?php _e( 'Color', 'my-calendar' ); ?>:</label> <input
266
- type="text"
267
  id="cat_color"
268
  name="category_color"
269
  class="mc-color-input"
270
  size="10"
271
  maxlength="7"
272
- value="<?php echo $color; ?>"/><br/>
273
- <label for="cat_icon"><?php _e( 'Category Icon', 'my-calendar' ); ?>:</label> <select
 
 
274
  name="category_icon" id="cat_icon">
275
  <?php
276
  foreach ( $iconlist as $value ) {
277
  $selected = ( ( ! empty( $cur_cat ) && is_object( $cur_cat ) ) && $cur_cat->category_icon == $value ) ? " selected='selected'" : '';
278
- echo "<option value='$value'$selected style='background: url(" . str_replace( 'my-calendar/', '', $url ) . "$path/$value) left 50% no-repeat;'>$value</option>";
279
  }
280
  ?>
281
  </select>
282
-
283
- <p>
284
  <?php if ( $view == 'add' ) {
285
  $private_checked = '';
286
  } else {
@@ -300,7 +304,10 @@ function mc_edit_category_form( $view = 'edit', $catID = '' ) {
300
  for="mc_default_category"><?php _e( 'Default category', 'my-calendar' ); ?></label>
301
  <input type="checkbox" value="on" name="mc_skip_holidays_category"
302
  id="mc_shc"<?php echo $holiday_checked; ?> /> <label
303
- for="mc_shc"><?php _e( 'Holiday Category', 'my-calendar' ); ?></label></p>
 
 
 
304
  </fieldset>
305
  <p>
306
  <input type="submit" name="save" class="button-primary"
257
  } else {
258
  $color = '';
259
  } ?>
260
+ <ul>
261
+ <li>
262
+ <label for="cat_name"><?php _e( 'Category Name', 'my-calendar' ); ?></label> <input
263
  type="text" id="cat_name" name="category_name" class="input" size="30"
264
  value="<?php if ( ! empty( $cur_cat ) && is_object( $cur_cat ) ) {
265
  echo stripslashes( esc_attr( $cur_cat->category_name ) );
266
  } ?>"/>
267
+ <label for="cat_color"><?php _e( 'Color', 'my-calendar' ); ?></label> <input
268
+ type="text
269
  id="cat_color"
270
  name="category_color"
271
  class="mc-color-input"
272
  size="10"
273
  maxlength="7"
274
+ value="<?php esc_attr_e( $color ); ?>"/>
275
+ </li>
276
+ <li>
277
+ <label for="cat_icon"><?php _e( 'Category Icon', 'my-calendar' ); ?></label> <select
278
  name="category_icon" id="cat_icon">
279
  <?php
280
  foreach ( $iconlist as $value ) {
281
  $selected = ( ( ! empty( $cur_cat ) && is_object( $cur_cat ) ) && $cur_cat->category_icon == $value ) ? " selected='selected'" : '';
282
+ echo "<option value='" . esc_attr( $value ) . "'$selected style='background: url(" . str_replace( 'my-calendar/', '', esc_url( $url . "$path/$value" ) ) . ") left 50% no-repeat;'>$value</option>";
283
  }
284
  ?>
285
  </select>
286
+ </li>
287
+ <li>
288
  <?php if ( $view == 'add' ) {
289
  $private_checked = '';
290
  } else {
304
  for="mc_default_category"><?php _e( 'Default category', 'my-calendar' ); ?></label>
305
  <input type="checkbox" value="on" name="mc_skip_holidays_category"
306
  id="mc_shc"<?php echo $holiday_checked; ?> /> <label
307
+ for="mc_shc"><?php _e( 'Holiday Category', 'my-calendar' ); ?></label>
308
+ </li>
309
+ <?php echo apply_filters( 'mc_category_fields', '', $cur_cat ); ?>
310
+ </ul>
311
  </fieldset>
312
  <p>
313
  <input type="submit" name="save" class="button-primary"
my-calendar-core.php CHANGED
@@ -146,7 +146,8 @@ add_action( 'wp_enqueue_scripts', 'mc_register_styles' );
146
  function mc_register_styles() {
147
  global $wp_query;
148
  $stylesheet = mc_get_style_path( get_option( 'mc_css_file' ), 'url' );
149
- wp_register_style( 'my-calendar-style', $stylesheet, array( 'dashicons' ) );
 
150
  $admin_stylesheet = plugins_url( 'css/mc-admin.css', __FILE__ );
151
  wp_register_style( 'my-calendar-admin-style', $admin_stylesheet );
152
  if ( current_user_can( 'mc_manage_events' ) ) {
@@ -161,10 +162,8 @@ function mc_register_styles() {
161
  if ( @in_array( $id, $js_array ) || get_option( 'mc_show_js' ) == '' ) {
162
  wp_enqueue_script( 'jquery' );
163
  if ( get_option( 'mc_gmap' ) == 'true' ) {
164
- wp_register_script( 'gmaps', "//maps.google.com/maps/api/js?sensor=true" );
165
- wp_register_script( 'gmap3', plugins_url( 'js/gmap3.min.js', __FILE__ ), array( 'jquery' ) );
166
- wp_enqueue_script( 'gmaps' );
167
- wp_enqueue_script( 'gmap3' );
168
  }
169
  }
170
  }
@@ -183,14 +182,6 @@ function mc_register_styles() {
183
  wp_register_style( 'my-calendar-mobile-style', $mobile );
184
  wp_enqueue_style( 'my-calendar-mobile-style' );
185
  }
186
- if ( function_exists( 'mcs_submissions' ) ) {
187
- $mcs = plugins_url( '/my-calendar-submissions/mcs-styles.css' );
188
- $mcs_ui = plugins_url( '/my-calendar-submissions/css/smoothness/jquery-ui-1.8.23.custom.css' );
189
- wp_register_style( 'my-calendar-submissions-ui-style', $mcs_ui );
190
- wp_enqueue_style( 'my-calendar-submissions-ui-style' );
191
- wp_register_style( 'my-calendar-submissions-style', $mcs );
192
- wp_enqueue_style( 'my-calendar-submissions-style' );
193
- }
194
  }
195
 
196
  // Function to add the calendar style into the header
@@ -234,7 +225,6 @@ function my_calendar_wp_head() {
234
  $all_styles = "
235
  <style type=\"text/css\">
236
  <!--
237
- .mcjs .mc-main .details, .mcjs .mc-main .calendar-events { display: none; }
238
  /* Styles by My Calendar - Joseph C Dolson http://www.joedolson.com/ */
239
  $category_styles
240
  .mc-event-visible {
@@ -253,8 +243,8 @@ function mc_deal_with_deleted_user( $id ) {
253
  $mcdb = $wpdb;
254
  // Do the queries
255
  // This may not work quite right in multi-site. Need to explore further when I have time.
256
- $mcdb->get_results( "UPDATE " . my_calendar_table() . " SET event_author=" . apply_filters( 'mc_deleted_author', $mcdb->get_var( "SELECT MIN(ID) FROM " . $mcdb->prefix . "users", 0, 0 ) ) . " WHERE event_author=" . $id );
257
- $mcdb->get_results( "UPDATE " . my_calendar_table() . " SET event_host=" . apply_filters( 'mc_deleted_host', $mcdb->get_var( "SELECT MIN(ID) FROM " . $mcdb->prefix . "users", 0, 0 ) ) . " WHERE event_host=" . $id );
258
  }
259
 
260
  // Function to add the javascript to the admin header
@@ -294,6 +284,7 @@ function my_calendar_add_javascript() {
294
  date_i18n( 'D', strtotime( 'Friday' ) ),
295
  date_i18n( 'D', strtotime( 'Saturday' ) )
296
  ) );
 
297
 
298
  wp_enqueue_script( 'jquery.addfields', plugins_url( 'js/jquery.addfields.js', __FILE__ ), array( 'jquery' ) );
299
  if ( function_exists( 'wp_enqueue_media' ) && ! did_action( 'wp_enqueue_media' ) ) {
@@ -305,8 +296,8 @@ function my_calendar_add_javascript() {
305
  if ( isset( $_GET['page'] ) && ( $_GET['page'] == 'my-calendar-config' || $_GET['page'] == 'my-calendar-help' ) ) {
306
  wp_enqueue_script( 'mc.tabs' );
307
  wp_enqueue_script( 'mc.sortable' );
308
- $firstItem = ( $_GET['page'] == 'my-calendar-config' ) ? 'mc_editor' : 'mc_main';
309
- wp_localize_script( 'mc.tabs', 'firstItem', $firstItem );
310
  }
311
  if ( isset( $_GET['page'] ) && ( $_GET['page'] == 'my-calendar-groups' || $_GET['page'] == 'my-calendar-manage' ) ) {
312
  wp_enqueue_script( 'jquery.checkall', plugins_url( 'js/jquery.checkall.js', __FILE__ ), array( 'jquery' ) );
@@ -319,7 +310,7 @@ function my_calendar_write_js() {
319
  <script type="text/javascript">
320
  //<![CDATA[
321
  jQuery(document).ready(function ($) {
322
- $('#e_begin,' + '#e_end').pickadate({
323
  monthsFull: mc_months,
324
  weekdaysShort: mc_days,
325
  format: 'yyyy-mm-dd',
@@ -327,7 +318,11 @@ function my_calendar_write_js() {
327
  selectMonths: true,
328
  editable: true
329
  });
330
-
 
 
 
 
331
  $('#mc-accordion').accordion({collapsible: true, active: false});
332
  <?php
333
  if ( function_exists( 'jd_doTwitterAPIPost' ) ) { ?>
@@ -448,12 +443,12 @@ function my_calendar_add_styles() {
448
  'my-calendar-templates'
449
  );
450
  if ( in_array( $_GET['page'], $pages ) ) {
451
- echo '<link type="text/css" rel="stylesheet" href="' . plugins_url( 'css/mc-styles.css', __FILE__ ) . '" />';
452
  }
453
  if ( $_GET['page'] == 'my-calendar' ) {
454
- echo '<link type="text/css" rel="stylesheet" href="' . plugins_url( 'js/pickadate/themes/default.css', __FILE__ ) . '" />';
455
- echo '<link type="text/css" rel="stylesheet" href="' . plugins_url( 'js/pickadate/themes/default.date.css', __FILE__ ) . '" />';
456
- echo '<link type="text/css" rel="stylesheet" href="' . plugins_url( 'js/pickadate/themes/default.time.css', __FILE__ ) . '" />';
457
  }
458
  }
459
  }
@@ -684,10 +679,16 @@ function mc_do_upgrades( $upgrade_path ) {
684
  foreach ( $upgrade_path as $upgrade ) {
685
  switch ( $upgrade ) {
686
  // only upgrade db on most recent version
 
 
 
 
 
 
 
687
  case '2.3.15':
688
  delete_option( 'mc_event_groups' );
689
  delete_option( 'mc_details' );
690
- mc_upgrade_db();
691
  break;
692
  case '2.3.11':
693
  add_option( 'mc_use_custom_js', 0 );
@@ -935,6 +936,19 @@ function mc_month_comparison( $month ) {
935
  return '';
936
  }
937
 
 
 
 
 
 
 
 
 
 
 
 
 
 
938
  function mc_year_comparison( $year ) {
939
  $current_year = date( "Y", current_time( 'timestamp' ) );
940
  if ( isset( $_GET['yr'] ) && isset( $_GET['month'] ) ) {
@@ -1038,6 +1052,15 @@ function my_calendar_admin_bar() {
1038
  $args = array( 'id' => 'mc-add-event', 'title' => __( 'Add Event', 'my-calendar' ), 'href' => $url );
1039
  $wp_admin_bar->add_node( $args );
1040
  }
 
 
 
 
 
 
 
 
 
1041
  if ( current_user_can( 'mc_manage_events' ) && current_user_can( 'mc_add_events' ) ) {
1042
  $url = admin_url( 'admin.php?page=my-calendar-manage' );
1043
  $args = array(
@@ -1158,7 +1181,7 @@ function my_calendar_send_email( $event ) {
1158
  $from = ( get_option( 'mc_event_mail_from' ) == '' ) ? get_bloginfo( 'admin_email' ) : get_option( 'mc_event_mail_from' );
1159
  $from = apply_filters( 'mc_event_mail_from', $from, $details );
1160
  $headers[] = "From: " . __( 'Event Notifications', 'my-calendar' ) . " <$from>";
1161
- $bcc = get_option( 'mc_event_mail_bcc' );
1162
  if ( $bcc ) {
1163
  $bcc = explode( PHP_EOL, $bcc );
1164
  foreach ( $bcc as $b ) {
@@ -1168,7 +1191,7 @@ function my_calendar_send_email( $event ) {
1168
  }
1169
  }
1170
  }
1171
- $headers = apply_filters( 'mc_customize_email_headers', $headers );
1172
  $subject = jd_draw_template( $details, get_option( 'mc_event_mail_subject' ) );
1173
  $message = jd_draw_template( $details, get_option( 'mc_event_mail_message' ) );
1174
  wp_mail( $to, $subject, $message, $headers );
@@ -1396,7 +1419,7 @@ function mc_guess_calendar() {
1396
  );
1397
  $current_uri = get_option( 'mc_uri' );
1398
  // check whether calendar page is a valid URL.
1399
- if ( $current_uri ) {
1400
  $response = wp_remote_head( $current_uri );
1401
  if ( !is_wp_error( $response ) ) {
1402
  $http = $response['response']['code'];
@@ -1557,7 +1580,7 @@ $plugins_string
1557
  <input type='checkbox' name='has_purchased' id='has_purchased' value='on' /> <label for='has_purchased'>" . __( 'I have <a href="http://www.joedolson.com/my-calendar/users-guide/">purchased the User\'s Guide</a>, but could not find an answer to this question.', 'my-calendar' ) . "</label>
1558
  </p>
1559
  <p>
1560
- <label for='support_request'>Support Request:</label><br /><textarea name='support_request' id='support_request' required aria-required='true' cols='80' rows='10'>" . stripslashes( $request ) . "</textarea>
1561
  </p>
1562
  <p>
1563
  <input type='submit' value='" . __( 'Send Support Request', 'my-calendar' ) . "' name='mc_support' class='button-primary' />
@@ -1633,7 +1656,7 @@ function _mc_increment_values( $recur ) {
1633
  function mc_change_instances( $id, $repeats, $begin = false ) {
1634
  global $wpdb;
1635
  $mcdb = $wpdb;
1636
- $events = $mcdb->get_results( "SELECT * FROM " . my_calendar_event_table() . " WHERE occur_event_id = $id ORDER BY occur_begin DESC" );
1637
  $count = count( $events );
1638
  $last = $count - 1;
1639
  if ( $begin == false ) {
@@ -1875,8 +1898,6 @@ function mc_increment_event( $id, $post = array(), $test = false ) {
1875
  'occur_end' => date( 'Y-m-d H:i:s', $end ),
1876
  'occur_group_id' => $group_id
1877
  );
1878
- // Logic shift -- should not have any need to verify occurrences.
1879
- //$occurs = $wpdb->get_results("SELECT * FROM ".my_calendar_event_table()." WHERE occur_event_id = $id ORDER BY occur_begin DESC");
1880
  if ( ! $test ) {
1881
  $wpdb->insert( my_calendar_event_table(), $data, $format );
1882
  }
@@ -1886,6 +1907,9 @@ function mc_increment_event( $id, $post = array(), $test = false ) {
1886
  }
1887
 
1888
  function mc_get_details_link( $event ) {
 
 
 
1889
  // if available, and not querying remotely, use permalink.
1890
  $permalinks = apply_filters( 'mc_use_permalinks', get_option( 'mc_use_permalinks' ) );
1891
  $permalinks = ( $permalinks === 1 || $permalinks === true || $permalinks === 'true' ) ? true : false;
@@ -1906,7 +1930,8 @@ function mc_get_details_link( $event ) {
1906
  'page_id',
1907
  'p',
1908
  'mcs',
1909
- 'time'
 
1910
  ), get_option( 'mc_uri' ) );
1911
  }
1912
  }
@@ -1922,6 +1947,7 @@ function mc_register_actions() {
1922
  add_action( 'mc_transition_event', 'mc_tweet_approval', 10, 2 );
1923
  add_action( 'mc_save_event', 'mc_event_post', 10, 3 );
1924
  add_action( 'mc_delete_event', 'mc_event_delete_post', 10, 2 );
 
1925
  add_action( 'parse_request', 'my_calendar_api' );
1926
  }
1927
 
@@ -1932,6 +1958,33 @@ add_filter( 'post_updated_messages', 'mc_posttypes_messages' );
1932
  add_action( 'init', 'mc_taxonomies', 0 );
1933
  add_action( 'init', 'mc_posttypes' );
1934
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1935
  function mc_posttypes() {
1936
  $arguments = array(
1937
  'public' => apply_filters( 'mc_event_posts_public', true ),
@@ -1953,6 +2006,7 @@ function mc_posttypes() {
1953
  ),
1954
  );
1955
  $enabled = array( 'mc-events' );
 
1956
  if ( is_array( $enabled ) ) {
1957
  foreach ( $enabled as $key ) {
1958
  $value =& $types[ $key ];
@@ -1981,7 +2035,7 @@ function mc_posttypes() {
1981
  'query_var' => true,
1982
  'rewrite' => array(
1983
  'with_front' => false,
1984
- 'slug' => apply_filters( 'mc_event_slug', 'mc-events' )
1985
  ),
1986
  'hierarchical' => false,
1987
  'menu_position' => 20,
@@ -1992,6 +2046,25 @@ function mc_posttypes() {
1992
  }
1993
  }
1994
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1995
  function mc_taxonomies() {
1996
  global $mc_types;
1997
  $types = $mc_types;
146
  function mc_register_styles() {
147
  global $wp_query;
148
  $stylesheet = mc_get_style_path( get_option( 'mc_css_file' ), 'url' );
149
+ wp_register_style( 'my-calendar-reset', plugins_url( 'css/reset.css', __FILE__ ) );
150
+ wp_register_style( 'my-calendar-style', $stylesheet, array( 'dashicons', 'my-calendar-reset' ) );
151
  $admin_stylesheet = plugins_url( 'css/mc-admin.css', __FILE__ );
152
  wp_register_style( 'my-calendar-admin-style', $admin_stylesheet );
153
  if ( current_user_can( 'mc_manage_events' ) ) {
162
  if ( @in_array( $id, $js_array ) || get_option( 'mc_show_js' ) == '' ) {
163
  wp_enqueue_script( 'jquery' );
164
  if ( get_option( 'mc_gmap' ) == 'true' ) {
165
+ wp_enqueue_script( 'gmaps', "https://maps.google.com/maps/api/js?sensor=true" );
166
+ wp_enqueue_script( 'gmap3', plugins_url( 'js/gmap3.min.js', __FILE__ ), array( 'jquery' ) );
 
 
167
  }
168
  }
169
  }
182
  wp_register_style( 'my-calendar-mobile-style', $mobile );
183
  wp_enqueue_style( 'my-calendar-mobile-style' );
184
  }
 
 
 
 
 
 
 
 
185
  }
186
 
187
  // Function to add the calendar style into the header
225
  $all_styles = "
226
  <style type=\"text/css\">
227
  <!--
 
228
  /* Styles by My Calendar - Joseph C Dolson http://www.joedolson.com/ */
229
  $category_styles
230
  .mc-event-visible {
243
  $mcdb = $wpdb;
244
  // Do the queries
245
  // This may not work quite right in multi-site. Need to explore further when I have time.
246
+ $mcdb->get_results( "UPDATE " . my_calendar_table() . " SET event_author=" . esc_sql( apply_filters( 'mc_deleted_author', $mcdb->get_var( "SELECT MIN(ID) FROM " . $mcdb->prefix . "users", 0, 0 ) ) ) . " WHERE event_author=" . $id );
247
+ $mcdb->get_results( "UPDATE " . my_calendar_table() . " SET event_host=" . esc_sql( apply_filters( 'mc_deleted_host', $mcdb->get_var( "SELECT MIN(ID) FROM " . $mcdb->prefix . "users", 0, 0 ) ) ) . " WHERE event_host=" . $id );
248
  }
249
 
250
  // Function to add the javascript to the admin header
284
  date_i18n( 'D', strtotime( 'Friday' ) ),
285
  date_i18n( 'D', strtotime( 'Saturday' ) )
286
  ) );
287
+ wp_localize_script( 'pickadate.time', 'mc_time_format', apply_filters( 'mc_time_format', 'h:i A' ) );
288
 
289
  wp_enqueue_script( 'jquery.addfields', plugins_url( 'js/jquery.addfields.js', __FILE__ ), array( 'jquery' ) );
290
  if ( function_exists( 'wp_enqueue_media' ) && ! did_action( 'wp_enqueue_media' ) ) {
296
  if ( isset( $_GET['page'] ) && ( $_GET['page'] == 'my-calendar-config' || $_GET['page'] == 'my-calendar-help' ) ) {
297
  wp_enqueue_script( 'mc.tabs' );
298
  wp_enqueue_script( 'mc.sortable' );
299
+ //$firstItem = ( $_GET['page'] == 'my-calendar-config' ) ? 'my-calendar-manage' : 'mc_main';
300
+ //wp_localize_script( 'mc.tabs', 'firstItem', $firstItem );
301
  }
302
  if ( isset( $_GET['page'] ) && ( $_GET['page'] == 'my-calendar-groups' || $_GET['page'] == 'my-calendar-manage' ) ) {
303
  wp_enqueue_script( 'jquery.checkall', plugins_url( 'js/jquery.checkall.js', __FILE__ ), array( 'jquery' ) );
310
  <script type="text/javascript">
311
  //<![CDATA[
312
  jQuery(document).ready(function ($) {
313
+ $( '.mc-datepicker' ).pickadate({
314
  monthsFull: mc_months,
315
  weekdaysShort: mc_days,
316
  format: 'yyyy-mm-dd',
318
  selectMonths: true,
319
  editable: true
320
  });
321
+ $( '.mc-timepicker' ).pickatime({
322
+ interval: 15,
323
+ format: mc_time_format,
324
+ editable: true
325
+ });
326
  $('#mc-accordion').accordion({collapsible: true, active: false});
327
  <?php
328
  if ( function_exists( 'jd_doTwitterAPIPost' ) ) { ?>
443
  'my-calendar-templates'
444
  );
445
  if ( in_array( $_GET['page'], $pages ) ) {
446
+ wp_enqueue_style( 'mc-styles', plugins_url( 'css/mc-styles.css', __FILE__ ) );
447
  }
448
  if ( $_GET['page'] == 'my-calendar' ) {
449
+ wp_enqueue_style( 'mc-pickadate-default', plugins_url( 'js/pickadate/themes/default.css', __FILE__ ) );
450
+ wp_enqueue_style( 'mc-pickadate-date', plugins_url( 'js/pickadate/themes/default.date.css', __FILE__ ) );
451
+ wp_enqueue_style( 'mc-pickadate-time', plugins_url( 'js/pickadate/themes/default.time.css', __FILE__ ) );
452
  }
453
  }
454
  }
679
  foreach ( $upgrade_path as $upgrade ) {
680
  switch ( $upgrade ) {
681
  // only upgrade db on most recent version
682
+ case '2.4.0':
683
+ $input_options = get_option( 'mc_input_options' );
684
+ $input_options['event_host'] = 'on';
685
+ update_option( 'mc_input_options', $input_options );
686
+ add_option( 'mc_default_direction', 'DESC' );
687
+ mc_upgrade_db();
688
+ break;
689
  case '2.3.15':
690
  delete_option( 'mc_event_groups' );
691
  delete_option( 'mc_details' );
 
692
  break;
693
  case '2.3.11':
694
  add_option( 'mc_use_custom_js', 0 );
936
  return '';
937
  }
938
 
939
+ function mc_day_comparison( $day ) {
940
+ $current_day = date( "j", current_time( 'timestamp' ) );
941
+ if ( isset( $_GET['yr'] ) && isset( $_GET['month'] ) && isset( $_GET['dy'] ) ) {
942
+ if ( $day == $_GET['dy'] ) {
943
+ return ' selected="selected"';
944
+ }
945
+ } else if ( $day == $current_day ) {
946
+ return ' selected="selected"';
947
+ }
948
+
949
+ return '';
950
+ }
951
+
952
  function mc_year_comparison( $year ) {
953
  $current_year = date( "Y", current_time( 'timestamp' ) );
954
  if ( isset( $_GET['yr'] ) && isset( $_GET['month'] ) ) {
1052
  $args = array( 'id' => 'mc-add-event', 'title' => __( 'Add Event', 'my-calendar' ), 'href' => $url );
1053
  $wp_admin_bar->add_node( $args );
1054
  }
1055
+ if ( _mc_is_url( get_option( 'mc_uri' ) ) ) {
1056
+ $url = esc_url( apply_filters( 'mc_adminbar_uri', get_option( 'mc_uri' ) ) );
1057
+ $args = array( 'id' => 'mc-my-calendar', 'title' => __( 'View Calendar', 'my-calendar' ), 'href' => $url );
1058
+ $wp_admin_bar->add_node( $args );
1059
+ } else {
1060
+ $url = admin_url( 'admin.php?page=my-calendar-config#mc-output' );
1061
+ $args = array( 'id' => 'mc-my-calendar', 'title' => __( 'Set Calendar URL', 'my-calendar' ), 'href' => $url );
1062
+ $wp_admin_bar->add_node( $args );
1063
+ }
1064
  if ( current_user_can( 'mc_manage_events' ) && current_user_can( 'mc_add_events' ) ) {
1065
  $url = admin_url( 'admin.php?page=my-calendar-manage' );
1066
  $args = array(
1181
  $from = ( get_option( 'mc_event_mail_from' ) == '' ) ? get_bloginfo( 'admin_email' ) : get_option( 'mc_event_mail_from' );
1182
  $from = apply_filters( 'mc_event_mail_from', $from, $details );
1183
  $headers[] = "From: " . __( 'Event Notifications', 'my-calendar' ) . " <$from>";
1184
+ $bcc = apply_filters( 'mc_event_mail_bcc', get_option( 'mc_event_mail_bcc' ), $details );
1185
  if ( $bcc ) {
1186
  $bcc = explode( PHP_EOL, $bcc );
1187
  foreach ( $bcc as $b ) {
1191
  }
1192
  }
1193
  }
1194
+ $headers = apply_filters( 'mc_customize_email_headers', $headers, $event );
1195
  $subject = jd_draw_template( $details, get_option( 'mc_event_mail_subject' ) );
1196
  $message = jd_draw_template( $details, get_option( 'mc_event_mail_message' ) );
1197
  wp_mail( $to, $subject, $message, $headers );
1419
  );
1420
  $current_uri = get_option( 'mc_uri' );
1421
  // check whether calendar page is a valid URL.
1422
+ if ( $current_uri ) {
1423
  $response = wp_remote_head( $current_uri );
1424
  if ( !is_wp_error( $response ) ) {
1425
  $http = $response['response']['code'];
1580
  <input type='checkbox' name='has_purchased' id='has_purchased' value='on' /> <label for='has_purchased'>" . __( 'I have <a href="http://www.joedolson.com/my-calendar/users-guide/">purchased the User\'s Guide</a>, but could not find an answer to this question.', 'my-calendar' ) . "</label>
1581
  </p>
1582
  <p>
1583
+ <label for='support_request'>Support Request:</label><br /><textarea name='support_request' id='support_request' required aria-required='true' cols='80' rows='10' class='widefat'>" . stripslashes( $request ) . "</textarea>
1584
  </p>
1585
  <p>
1586
  <input type='submit' value='" . __( 'Send Support Request', 'my-calendar' ) . "' name='mc_support' class='button-primary' />
1656
  function mc_change_instances( $id, $repeats, $begin = false ) {
1657
  global $wpdb;
1658
  $mcdb = $wpdb;
1659
+ $events = $mcdb->get_results( $mcdb->prepare( "SELECT * FROM " . my_calendar_event_table() . " WHERE occur_event_id = %d ORDER BY occur_begin DESC", $id ) );
1660
  $count = count( $events );
1661
  $last = $count - 1;
1662
  if ( $begin == false ) {
1898
  'occur_end' => date( 'Y-m-d H:i:s', $end ),
1899
  'occur_group_id' => $group_id
1900
  );
 
 
1901
  if ( ! $test ) {
1902
  $wpdb->insert( my_calendar_event_table(), $data, $format );
1903
  }
1907
  }
1908
 
1909
  function mc_get_details_link( $event ) {
1910
+ if ( is_numeric( $event ) ) {
1911
+ $event = mc_get_event( $event );
1912
+ }
1913
  // if available, and not querying remotely, use permalink.
1914
  $permalinks = apply_filters( 'mc_use_permalinks', get_option( 'mc_use_permalinks' ) );
1915
  $permalinks = ( $permalinks === 1 || $permalinks === true || $permalinks === 'true' ) ? true : false;
1930
  'page_id',
1931
  'p',
1932
  'mcs',
1933
+ 'time',
1934
+ 'page'
1935
  ), get_option( 'mc_uri' ) );
1936
  }
1937
  }
1947
  add_action( 'mc_transition_event', 'mc_tweet_approval', 10, 2 );
1948
  add_action( 'mc_save_event', 'mc_event_post', 10, 3 );
1949
  add_action( 'mc_delete_event', 'mc_event_delete_post', 10, 2 );
1950
+ add_action( 'mc_mass_delete_events', 'mc_event_delete_posts', 10, 2 );
1951
  add_action( 'parse_request', 'my_calendar_api' );
1952
  }
1953
 
1958
  add_action( 'init', 'mc_taxonomies', 0 );
1959
  add_action( 'init', 'mc_posttypes' );
1960
 
1961
+ function mc_event_delete_posts( $deleted ) {
1962
+ foreach ( $deleted as $delete ) {
1963
+ $posts = get_posts( array(
1964
+ 'post_type' => 'mc-events',
1965
+ 'meta_key' => '_mc_event_id',
1966
+ 'meta_value' => $delete
1967
+ ) );
1968
+ $post_id = $posts[0]->ID;
1969
+ wp_delete_post( $post_id, true );
1970
+ }
1971
+ }
1972
+
1973
+ add_action( 'load-options-permalink.php', 'mc_load_permalinks' );
1974
+ function mc_load_permalinks() {
1975
+ if( isset( $_POST['mc_cpt_base'] ) ) {
1976
+ update_option( 'mc_cpt_base', sanitize_title_with_dashes( $_POST['mc_cpt_base'] ) );
1977
+ }
1978
+
1979
+ // Add a settings field to the permalink page
1980
+ add_settings_field( 'mc_cpt_base', __( 'My Calendar Events base' ), 'mc_field_callback', 'permalink', 'optional', array( 'label_for'=>'mc_cpt_base' ) );
1981
+ }
1982
+
1983
+ function mc_field_callback() {
1984
+ $value = ( get_option( 'mc_cpt_base' ) != '' ) ? get_option( 'mc_cpt_base' ) : 'mc-events';
1985
+ echo '<input type="text" value="' . esc_attr( $value ) . '" name="mc_cpt_base" id="mc_cpt_base" class="regular-text" />';
1986
+ }
1987
+
1988
  function mc_posttypes() {
1989
  $arguments = array(
1990
  'public' => apply_filters( 'mc_event_posts_public', true ),
2006
  ),
2007
  );
2008
  $enabled = array( 'mc-events' );
2009
+ $slug = ( get_option( 'mc_cpt_base' ) != '' ) ? get_option( 'mc_cpt_base' ) : 'mc-events';
2010
  if ( is_array( $enabled ) ) {
2011
  foreach ( $enabled as $key ) {
2012
  $value =& $types[ $key ];
2035
  'query_var' => true,
2036
  'rewrite' => array(
2037
  'with_front' => false,
2038
+ 'slug' => apply_filters( 'mc_event_slug', $slug )
2039
  ),
2040
  'hierarchical' => false,
2041
  'menu_position' => 20,
2046
  }
2047
  }
2048
 
2049
+ /**
2050
+ * Most people don't want comments open on events. This will automatically close them.
2051
+ */
2052
+ function mc_close_comments( $posts ) {
2053
+ if ( !is_single() || empty( $posts ) ) { return $posts; }
2054
+
2055
+ if ( 'mc-events' == get_post_type($posts[0]->ID) ) {
2056
+ if ( apply_filters( 'mc_autoclose_comments', true ) && $posts[0]->comment_status != 'closed' ) {
2057
+ $posts[0]->comment_status = 'closed';
2058
+ $posts[0]->ping_status = 'closed';
2059
+ wp_update_post( $posts[0] );
2060
+ }
2061
+ }
2062
+
2063
+ return $posts;
2064
+ }
2065
+ add_filter( 'the_posts', 'mc_close_comments' );
2066
+
2067
+
2068
  function mc_taxonomies() {
2069
  global $mc_types;
2070
  $types = $mc_types;
my-calendar-event-manager.php CHANGED
@@ -19,6 +19,29 @@ function mc_switch_sites() {
19
  return false;
20
  }
21
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  function mc_event_post( $action, $data, $event_id ) {
23
  // if the event save was successful.
24
  if ( $action == 'add' || $action == 'copy' ) {
@@ -88,6 +111,7 @@ function mc_add_post_meta_data( $post_id, $post, $data, $event_id ) {
88
  update_post_meta( $post_id, '_mc_event_id', $event_id );
89
  update_post_meta( $post_id, '_mc_event_desc', $data['event_desc'] );
90
  update_post_meta( $post_id, '_mc_event_image', $data['event_image'] );
 
91
  $location_id = ( isset( $post['location_preset'] ) ) ? (int) $post['location_preset'] : 0;
92
  if ( $location_id ) { // only change location ID if dropdown set.
93
  update_post_meta( $post_id, '_mc_event_location', $location_id );
@@ -97,41 +121,53 @@ function mc_add_post_meta_data( $post_id, $post, $data, $event_id ) {
97
  }
98
 
99
  function mc_create_event_post( $data, $event_id ) {
100
- $term = mc_get_category_detail( $data['event_category'], 'category_term' );
101
- $privacy = ( mc_get_category_detail( $data['event_category'], 'category_private' ) == 1 ) ? 'private' : 'publish';
102
- $title = $data['event_title'];
103
- $template = apply_filters( 'mc_post_template', 'details', $term );
104
- $data['shortcode'] = "[my_calendar_event event='$event_id' template='$template' list='']";
105
- $description = $data['event_desc'];
106
- $excerpt = $data['event_short'];
107
- $location_id = ( isset( $_POST['location_preset'] ) ) ? (int) $_POST['location_preset'] : 0;
108
- $post_status = $privacy;
109
- $auth = $data['event_author'];
110
- $type = 'mc-events';
111
- $my_post = array(
112
- 'post_title' => $title,
113
- 'post_content' => $description,
114
- 'post_status' => $post_status,
115
- 'post_author' => $auth,
116
- 'post_name' => sanitize_title( $title ),
117
- 'post_date' => date( 'Y-m-d H:i:s', current_time( 'timestamp' ) ),
118
- 'post_type' => $type,
119
- 'post_excerpt' => $excerpt
120
- );
121
- $post_id = wp_insert_post( $my_post );
122
- wp_set_object_terms( $post_id, (int) $term, 'mc-event-category' );
123
- $attachment_id = ( isset( $_POST['event_image_id'] ) && is_numeric( $_POST['event_image_id'] ) ) ? $_POST['event_image_id'] : false;
124
- if ( $attachment_id ) {
125
- set_post_thumbnail( $post_id, $attachment_id );
 
 
 
 
 
 
 
126
  }
127
- mc_update_event( 'event_post', $post_id, $event_id );
128
- mc_update_event( 'event_location', $location_id, $event_id );
129
- do_action( 'mc_update_event_post', $post_id, $_POST, $data, $event_id );
130
- wp_publish_post( $post_id );
131
-
132
  return $post_id;
133
  }
134
 
 
 
 
 
 
 
 
 
 
 
135
  function mc_update_event( $field, $data, $event, $type = '%d' ) {
136
  global $wpdb;
137
  $field = sanitize_key( $field );
@@ -585,7 +621,9 @@ function my_calendar_save( $action, $output, $event_id = false ) {
585
  }
586
  if ( get_option( 'mc_uri' ) != '' ) {
587
  $event_ids = mc_get_occurrences( $event_id );
588
- $event_link = mc_build_url( array( 'mc_id' => $event_ids[0]->occur_id ), array( 'page' ), get_option( 'mc_uri' ) );
 
 
589
  } else {
590
  $event_link = false;
591
  }
@@ -609,14 +647,16 @@ function my_calendar_save( $action, $output, $event_id = false ) {
609
  $update['event_begin'] != $_POST['prev_event_begin'] ||
610
  date( "H:i:00", strtotime( $update['event_time'] ) ) != $_POST['prev_event_time'] ||
611
  $update['event_end'] != $_POST['prev_event_end'] ||
612
- ( date( "H:i:00", strtotime( $update['event_endtime'] ) ) != $_POST['prev_event_endtime'] && ( $_POST['prev_event_endtime'] != '' && date( "H:i:00", strtotime( $update['event_endtime'] ) ) != '00:00:00' ) ) )
613
- ? true : false;
614
  if ( isset( $_POST['event_instance'] ) ) {
615
  $is_changed = mc_compare( $update, $event_id );// compares the information sent to the information saved for a given event.
616
  $event_instance = (int) $_POST['event_instance'];
617
  if ( $is_changed ) {
618
  // if changed, create new event, match group id, update instance to reflect event connection, same group id.
619
  // if group ID == 0, need to add group ID to both records.
 
 
620
  if ( $update['event_group_id'] == 0 ) {
621
  $update['event_group_id'] = $event_id;
622
  mc_update_data( $event_id, 'event_group_id', $event_id );
@@ -635,7 +675,7 @@ function my_calendar_save( $action, $output, $event_id = false ) {
635
  } else {
636
  $result = mc_update_instance( $event_instance, $event_id, $update );
637
  // Only dates were changed
638
- $message = "<div class='updated notice'><p>" . __( 'Date/time information for this event has been updated.', 'my-calendar' ) . "$url</p></div>";
639
  mc_delete_cache();
640
  }
641
  }
@@ -656,11 +696,12 @@ function my_calendar_save( $action, $output, $event_id = false ) {
656
  $data = $update;
657
  do_action( 'mc_save_event', $action, $data, $event_id, $result );
658
  if ( $result === false ) {
659
- $message = "<div class='error'><p><strong>" . __( 'Error', 'my-calendar' ) . ":</strong>" . __( 'Your event was not updated.', 'my-calendar' ) . "$url</p></div>";
660
  } else {
661
  // do an action using the $action and processed event data
662
- do_action( 'mc_transition_event', (int) $_POST['prev_event_status'], (int) $_POST['event_approved'] );
663
- $message = "<div class='updated'><p>" . __( 'Event updated successfully', 'my-calendar' ) . ".$url</p></div>";
 
664
  mc_delete_cache();
665
  }
666
  } else {
@@ -781,25 +822,58 @@ function mc_show_edit_block( $field ) {
781
  }
782
  }
783
 
784
- function mc_show_block( $field, $has_data, $data ) {
 
785
  $return = $checked = $value = '';
786
  $show_block = mc_show_edit_block( $field );
787
  $pre = '<div class="ui-sortable meta-box-sortables"><div class="postbox">';
788
  $post = '</div></div>';
789
  switch ( $field ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
790
  case 'event_desc' :
791
  if ( $show_block ) {
 
792
  // because wp_editor cannot return a value, event_desc fields cannot be filtered if its enabled.
793
  $value = ( $has_data ) ? stripslashes( $data->event_desc ) : '';
794
- echo '
795
- <div class="event_description">
796
- <label for="content">' . __( 'Event Description', 'my-calendar' ) . '</label><br />';
797
- if ( user_can_richedit() ) {
798
- wp_editor( $value, 'content', array( 'textarea_rows' => 10 ) );
799
  } else {
800
- echo '<textarea id="content" name="content" class="event_desc" rows="8" cols="80">' . stripslashes( esc_attr( $value ) ) . '</textarea>';
 
 
 
 
 
 
 
 
801
  }
802
- echo '</div>';
803
  }
804
  break;
805
  case 'event_short' :
@@ -813,11 +887,11 @@ function mc_show_block( $field, $has_data, $data ) {
813
  break;
814
  case 'event_image' :
815
  if ( $show_block ) {
816
- $value = ( $has_data ) ? esc_attr( $data->event_image ) : '';
817
  $return = '
818
  <div class="mc-image-upload field-holder">
819
  <input type="hidden" name="event_image_id" value="" class="textfield" id="e_image_id" />
820
- <label for="e_image">' . __( "Add an image:", 'my-calendar' ) . '</label><br /><input type="text" name="event_image" id="e_image" size="60" value="' . $value . '" placeholder="http://yourdomain.com/image.jpg" /> <a href="#" class="button textfield-field">' . __( "Upload", 'my-calendar' ) . '</a>';
821
  if ( ! empty( $data->event_image ) ) {
822
  $return .= '<div class="event_image"><img src="' . esc_attr( $data->event_image ) . '" alt="" /></div>';
823
  } else {
@@ -825,7 +899,7 @@ function mc_show_block( $field, $has_data, $data ) {
825
  }
826
  $return .= '</div>';
827
  } else {
828
- $return = '<input type="hidden" name="event_image" value="' . $value . '" />';
829
  }
830
  break;
831
  case 'event_category' :
@@ -883,8 +957,8 @@ function mc_show_block( $field, $has_data, $data ) {
883
  <fieldset>
884
  <legend class="screen-reader-text">' . __( 'Recurring Events', 'my-calendar' ) . '</legend>
885
  <p>
886
- <label for="e_repeats">' . __( 'Repeats', 'my-calendar' ) . ' <input type="text" name="event_repeats" aria-labelledby="e_repeats_label" id="e_repeats" size="1" value="' . $repeats . '" /> <span id="e_repeats_label">' . __( 'times', 'my-calendar' ) . '</span>, </label>
887
- <label for="e_every">' . __( 'every', 'my-calendar' ) . '</label> <input type="number" name="event_every" id="e_every" size="1" min="1" max="12" maxlength="1" value="' . $every . '" />
888
  <label for="e_recur" class="screen-reader-text">' . __( 'Units', 'my-calendar' ) . '</label>
889
  <select name="event_recur" id="e_recur">
890
  ' . mc_recur_options( $recur ) . '
@@ -903,9 +977,9 @@ function mc_show_block( $field, $has_data, $data ) {
903
  $return = '
904
  <div>' .
905
  $prev . '
906
- <input type="hidden" name="event_repeats" value="' . $repeats . '" />
907
- <input type="hidden" name="event_every" value="' . $every . '" />
908
- <input type="hidden" name="event_recur" value="' . $recur . '" />
909
  </div>';
910
  }
911
  break;
@@ -932,8 +1006,8 @@ function mc_show_block( $field, $has_data, $data ) {
932
  </div>
933
  ' . $post;
934
  } else {
935
- $open = ( $has_data ) ? $data->event_open : '2';
936
- $tickets = ( $has_data ) ? esc_attr( esc_url( $data->event_tickets ) ) : '';
937
  $registration = ( $has_data ) ? esc_attr( $data->event_registration ) : '';
938
  $return = '
939
  <div>
@@ -951,19 +1025,19 @@ function mc_show_block( $field, $has_data, $data ) {
951
  $return = "
952
  <div>
953
  <input type='hidden' name='event_label' value='" . esc_attr( stripslashes( $data->event_label ) ) . "' />
954
- <input type='hidden' name='event_street' value='" . ( stripslashes( $data->event_street ) ) . "' />
955
- <input type='hidden' name='event_street2' value='" . ( stripslashes( $data->event_street2 ) ) . "' />
956
- <input type='hidden' name='event_phone' value='" . ( stripslashes( $data->event_phone ) ) . "' />
957
- <input type='hidden' name='event_phone2' value='" . ( stripslashes( $data->event_phone2 ) ) . "' />
958
- <input type='hidden' name='event_city' value='" . ( stripslashes( $data->event_city ) ) . "' />
959
- <input type='hidden' name='event_state' value='" . ( stripslashes( $data->event_state ) ) . "' />
960
- <input type='hidden' name='event_postcode' value='" . ( stripslashes( $data->event_postcode ) ) . "' />
961
- <input type='hidden' name='event_region' value='" . ( stripslashes( $data->event_region ) ) . "' />
962
- <input type='hidden' name='event_country' value='" . ( stripslashes( $data->event_country ) ) . "' />
963
- <input type='hidden' name='event_zoom' value='" . ( stripslashes( $data->event_zoom ) ) . "' />
964
- <input type='hidden' name='event_url' value='" . ( stripslashes( $data->event_url ) ) . "' />
965
- <input type='hidden' name='event_latitude' value='" . ( stripslashes( $data->event_latitude ) ) . "' />
966
- <input type='hidden' name='event_longitude' value='" . ( stripslashes( $data->event_longitude ) ) . "' />
967
  </div>";
968
  }
969
  }
@@ -971,7 +1045,12 @@ function mc_show_block( $field, $has_data, $data ) {
971
  default:
972
  return;
973
  }
974
- echo apply_filters( 'mc_show_block', $return, $data, $field );
 
 
 
 
 
975
  }
976
 
977
 
@@ -1039,7 +1118,7 @@ function mc_form_fields( $data, $mode, $event_id ) {
1039
  } else {
1040
  echo mc_group_id();
1041
  } ?>"/>
1042
- <input type="hidden" name="event_action" value="<?php echo $mode; ?>"/>
1043
  <?php if ( ! empty( $_GET['date'] ) ) { ?>
1044
  <input type="hidden" name="event_instance" value="<?php echo (int) $_GET['date']; ?>"/>
1045
  <?php } ?>
@@ -1084,12 +1163,12 @@ function mc_form_fields( $data, $mode, $event_id ) {
1084
  $text_link = '';
1085
  }
1086
  ?>
1087
- <h3><?php echo $text; ?> <span class="alignright"><a
1088
- href="<?php echo admin_url( 'admin.php?page=my-calendar-manage' ); ?>"><?php _e( 'Manage events', 'my-calendar' ); ?></a><?php echo $delete;
1089
- echo $text_link; ?></span>
1090
- </h3>
1091
-
1092
  <div class="inside">
 
 
 
 
1093
  <?php
1094
  if ( ! empty( $_GET['date'] ) && $data->event_recur != 'S' ) {
1095
  $event = mc_get_event( $instance );
@@ -1104,8 +1183,7 @@ function mc_form_fields( $data, $mode, $event_id ) {
1104
  <fieldset>
1105
  <legend class="screen-reader-text"><?php _e( 'Event Details', 'my-calendar' ); ?></legend>
1106
  <p>
1107
- <label for="e_title"><?php _e( 'Event Title', 'my-calendar' ); ?> <span
1108
- class='required'><?php _e( '(required)', 'my-calendar' ); ?></span></label><br/><input
1109
  type="text" id="e_title" name="event_title" size="50" maxlength="255"
1110
  value="<?php if ( $has_data ) {
1111
  echo apply_filters( 'mc_manage_event_title', stripslashes( esc_attr( $data->event_title ) ), $data );
@@ -1113,7 +1191,7 @@ function mc_form_fields( $data, $mode, $event_id ) {
1113
  if ( $mode == 'edit' ) {
1114
  ?>
1115
  <input type='hidden' name='prev_event_status'
1116
- value='<?php echo $data->event_approved; ?>' /><?php
1117
  if ( get_option( 'mc_event_approve' ) == 'true' ) {
1118
  if ( current_user_can( 'mc_approve_events' ) ) { // Added by Roland P.
1119
  if ( $has_data && $data->event_approved == '1' ) {
@@ -1174,28 +1252,7 @@ function mc_form_fields( $data, $mode, $event_id ) {
1174
  mc_show_block( 'event_desc', $has_data, $data );
1175
  mc_show_block( 'event_short', $has_data, $data );
1176
  mc_show_block( 'event_image', $has_data, $data );
1177
- ?>
1178
- <p>
1179
- <label for="e_host"><?php _e( 'Host', 'my-calendar' ); ?></label>
1180
- <select id="e_host" name="event_host">
1181
- <?php
1182
- // Grab all the categories and list them
1183
- $users = my_calendar_getUsers();
1184
- foreach ( $users as $u ) {
1185
- $display_name = ( $u->display_name == '' ) ? $u->user_nicename : $u->display_name;
1186
- if ( is_object( $data ) && $data->event_host == $u->ID ) {
1187
- $selected = ' selected="selected"';
1188
- } else if ( is_object( $u ) && $u->ID == $user_ID && empty( $data->event_host ) ) {
1189
- $selected = ' selected="selected"';
1190
- } else {
1191
- $selected = '';
1192
- }
1193
- echo "<option value='$u->ID'$selected>$display_name</option>\n";
1194
- }
1195
- ?>
1196
- </select>
1197
- </p>
1198
- <?php
1199
  mc_show_block( 'event_category', $has_data, $data );
1200
  mc_show_block( 'event_link', $has_data, $data );
1201
  echo apply_filters( 'mc_event_details', '', $has_data, $data, 'admin' );
@@ -1211,10 +1268,10 @@ function mc_form_fields( $data, $mode, $event_id ) {
1211
 
1212
  <div class="inside">
1213
  <?php if ( is_object( $data ) ) { // information for rewriting recurring data ?>
1214
- <input type="hidden" name="prev_event_begin" value="<?php echo $data->event_begin; ?>"/>
1215
- <input type="hidden" name="prev_event_time" value="<?php echo $data->event_time; ?>"/>
1216
- <input type="hidden" name="prev_event_end" value="<?php echo $data->event_end; ?>"/>
1217
- <input type="hidden" name="prev_event_endtime" value="<?php echo $data->event_endtime; ?>"/>
1218
  <?php } ?>
1219
  <fieldset>
1220
  <legend class="screen-reader-text"><?php _e( 'Event Date and Time', 'my-calendar' ); ?></legend>
@@ -1378,12 +1435,8 @@ if ( mc_show_edit_block( 'event_specials' ) ) {
1378
  } else {
1379
  ?>
1380
  <div>
1381
- <input type="hidden" name="event_holiday" value="true"<?php if ( get_option( 'mc_skip_holidays' ) == 'true' ) {
1382
- echo " checked=\"checked\"";
1383
- } ?> />
1384
- <input type="hidden" name="event_fifth_week" value="true"<?php if ( get_option( 'mc_no_fifth_week' ) == 'true' ) {
1385
- echo " checked=\"checked\"";
1386
- } ?>/>
1387
  </div><?php
1388
  } ?>
1389
  <p>
@@ -1412,13 +1465,13 @@ function mc_event_accessibility( $form, $data, $label ) {
1412
  if ( is_array( $events_access ) ) {
1413
  $checked = ( in_array( $k, $events_access ) || in_array( $a, $events_access ) ) ? " checked='checked'" : '';
1414
  }
1415
- $item = sprintf( '<li><input type="checkbox" id="%1$s" name="events_access[]" value="%4$s" class="checkbox" %2$s /> <label for="%1$s">%3$s</label></li>', $id, $checked, $label, $a );
1416
  $form .= $item;
1417
  }
1418
  if ( isset( $events_access['notes'] ) ) {
1419
  $note_value = esc_attr( $events_access['notes'] );
1420
  }
1421
- $form .= '<li><label for="events_access_notes">' . __( 'Notes', 'my-calendar' ) . '</label> <input type="text" name="events_access[notes]" value="' . $note_value . '" /></li>';
1422
  $form .= "</ul>
1423
  </fieldset>";
1424
 
@@ -1434,10 +1487,11 @@ function mc_list_events() {
1434
 
1435
  if ( isset( $_GET['order'] ) ) {
1436
  $sortdir = ( isset( $_GET['order'] ) && $_GET['order'] == 'ASC' ) ? 'ASC' : 'default';
 
1437
  } else {
1438
  $sortdir = 'default';
1439
  }
1440
- $sortbydirection = ( $sortdir == 'default' ) ? 'DESC' : $sortdir;
1441
  if ( empty( $sortby ) ) {
1442
  $sortbyvalue = 'event_begin';
1443
  } else {
@@ -1743,10 +1797,10 @@ function mc_list_events() {
1743
  <td>
1744
  <?php if ( $event->event_label != '' ) { ?><a class='mc_filter' href='<?php $elabel = urlencode( $event->event_label ); echo admin_url( "admin.php?page=my-calendar-manage&amp;filter=$elabel&amp;restrict=where" ); ?>' title="<?php _e( 'Filter by location', 'my-calendar' ); ?>"><span class="screen-reader-text"><?php _e( 'Show only: ', 'my-calendar' ); ?></span><?php echo stripslashes( $event->event_label ); ?></a><?php } ?>
1745
  </td>
1746
- <?php if ( $event->event_time != "00:00:00" ) {
1747
  $eventTime = date_i18n( get_option( 'mc_time_format' ), strtotime( $event->event_time ) );
1748
  } else {
1749
- $eventTime = get_option( 'mc_notime_text' );
1750
  } ?>
1751
  <td><?php
1752
  $date_format = ( get_option( 'mc_date_format' ) == '' ) ? get_option( 'date_format' ) : get_option( 'mc_date_format' );
@@ -1863,13 +1917,14 @@ function mc_check_data( $action, $post, $i ) {
1863
  $submit = array();
1864
  $errors = '';
1865
  $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 = '';
 
1866
  if ( get_magic_quotes_gpc() ) {
1867
  $post = array_map( 'stripslashes_deep', $post );
1868
  }
1869
  if ( ! wp_verify_nonce( $post['event_nonce_name'], 'event_nonce' ) ) {
1870
  return array();
1871
  }
1872
-
1873
  if ( $action == 'add' || $action == 'edit' || $action == 'copy' ) {
1874
  $title = ! empty( $post['event_title'] ) ? trim( $post['event_title'] ) : '';
1875
  $desc = ! empty( $post['content'] ) ? trim( $post['content'] ) : '';
@@ -1906,18 +1961,14 @@ function mc_check_data( $action, $post, $i ) {
1906
  $begin = date( 'Y-m-d', strtotime( $begin ) );// regardless of entry format, convert.
1907
  $time = ! empty( $post['event_time'][ $i ] ) ? trim( $post['event_time'][ $i ] ) : '';
1908
  $endtime = ! empty( $post['event_endtime'][ $i ] ) ? trim( $post['event_endtime'][ $i ] ) : date( 'H:i:s', strtotime( $time . ' +1 hour' ) );
1909
- $endtime = ( $time == '' || $time == '00:00:00' ) ? '00:00:00' : $endtime; // set at midnight if all day.
1910
- $endtime = ( $endtime == '' ) ? '00:00:00' : date( 'H:i:00', strtotime( $endtime ) );
1911
- // if the end time is midnight but the date is empty, change to tomorrow.
1912
- if ( $endtime == '00:00:00' && $action != 'edit' ) { // cascading problem if this happens on edits!
1913
- $end = date( 'Y-m-d', strtotime( $end . ' +1 day' ) );
1914
- }
1915
  // prevent setting enddate to incorrect value on copy.
1916
  if ( strtotime( $end ) < strtotime( $begin ) && $action == 'copy' ) {
1917
  $end = date( 'Y-m-d', ( strtotime( $begin ) + ( strtotime( $post['prev_event_end'] ) - strtotime( $post['prev_event_begin'] ) ) ) );
1918
  }
1919
  if ( isset( $post['event_allday'] ) && (int) $post['event_allday'] !== 0 ) {
1920
- $time = $endtime = '00:00:00';
1921
  }
1922
  $end = date( 'Y-m-d', strtotime( $end ) ); // regardless of entry format, convert.
1923
  $repeats = ( ! empty( $post['event_repeats'] ) || trim( $post['event_repeats'] ) == '' ) ? trim( $post['event_repeats'] ) : 0;
@@ -1940,7 +1991,7 @@ function mc_check_data( $action, $post, $i ) {
1940
  $event_group_id = ( ( is_array( $post['event_begin'] ) && count( $post['event_begin'] ) > 1 ) || mc_event_is_grouped( $group_id_submitted ) ) ? $group_id_submitted : 0;
1941
  $event_span = ( ! empty( $post['event_span'] ) && $event_group_id != 0 ) ? 1 : 0;
1942
  $event_hide_end = ( ! empty( $post['event_hide_end'] ) ) ? (int) $post['event_hide_end'] : 0;
1943
- $event_hide_end = ( $time == '' || $time == '00:00:00' ) ? 1 : $event_hide_end; // hide end time automatically on all day events
1944
  // set location
1945
  if ( $location_preset != 'none' && is_numeric( $location_preset ) ) {
1946
  $sql = "SELECT * FROM " . my_calendar_locations_table() . " WHERE location_id = $location_preset";
@@ -2026,7 +2077,7 @@ function mc_check_data( $action, $post, $i ) {
2026
  }
2027
 
2028
  // We check for a valid time, or an empty one
2029
- $time = ( $time == '' ) ? '00:00:00' : date( 'H:i:00', strtotime( $time ) );
2030
  $time_format_one = '/^([0-1][0-9]):([0-5][0-9]):([0-5][0-9])$/';
2031
  $time_format_two = '/^([2][0-3]):([0-5][0-9]):([0-5][0-9])$/';
2032
  if ( preg_match( $time_format_one, $time ) || preg_match( $time_format_two, $time ) || $time == '' ) {
@@ -2068,6 +2119,7 @@ function mc_check_data( $action, $post, $i ) {
2068
  if ( $spam == 1 && $begin == '1970-01-01' ) {
2069
  die;
2070
  }
 
2071
  if ( $errors == '' ) {
2072
  $ok = true;
2073
  $submit = array(
@@ -2121,6 +2173,8 @@ function mc_check_data( $action, $post, $i ) {
2121
  $event_access = ( is_array( $event_access ) ) ? serialize( $event_access ) : '';
2122
  // The form is going to be rejected due to field validation issues, so we preserve the users entries here
2123
  // all submitted data should be in this object, regardless of data destination.
 
 
2124
  $users_entries->event_title = $title;
2125
  $users_entries->event_desc = $desc;
2126
  $users_entries->event_begin = $begin;
@@ -2205,7 +2259,11 @@ function mc_compare( $update, $id ) {
2205
  }
2206
  }
2207
 
2208
- // args: instance ID, event ID, array containing updated dates.
 
 
 
 
2209
  function mc_update_instance( $event_instance, $event_id, $update = array() ) {
2210
  global $wpdb;
2211
  $mcdb = $wpdb;
@@ -2306,7 +2364,7 @@ function mc_instance_list( $id, $occur = false, $template = '<h3>{title}</h3>{de
2306
  $output = $details . $before . $output . $after;
2307
  }
2308
 
2309
- return $output;
2310
  }
2311
 
2312
  function mc_event_is_grouped( $group_id ) {
@@ -2325,6 +2383,10 @@ function mc_event_is_grouped( $group_id ) {
2325
  }
2326
  }
2327
 
 
 
 
 
2328
  function mc_standard_datetime_input( $form, $has_data, $data, $instance, $context = 'admin' ) {
2329
  if ( $has_data ) {
2330
  $event_begin = esc_attr( $data->event_begin );
@@ -2337,50 +2399,37 @@ function mc_standard_datetime_input( $form, $has_data, $data, $instance, $contex
2337
  $event_end = '';
2338
  };
2339
  }
2340
- $starttime = ( $data->event_time == "00:00:00" && $data->event_endtime == "00:00:00" ) ? '' : date( "h:i A", strtotime( $data->event_time ) );
2341
- $endtime = ( $data->event_endtime == "00:00:00" && $data->event_time == "00:00:00" ) ? '' : date( "h:i A", strtotime( $data->event_endtime ) );
2342
  } else {
2343
  $event_begin = date( "Y-m-d" );
2344
  $event_end = $starttime = $endtime = '';
2345
  }
2346
  $allday = $hide = '';
2347
- if ( $has_data && ( $data->event_time == '00:00:00' && $data->event_endtime == '00:00:00' ) ) {
2348
  $allday = " checked=\"checked\"";
2349
  }
2350
  if ( $has_data && $data->event_hide_end == '1' ) {
2351
  $hide = " checked=\"checked\"";
2352
  }
2353
- $scripting = '
2354
- <script type="text/javascript">
2355
- //<![CDATA[
2356
- jQuery(document).ready(function($) {
2357
- $("#e_time").pickatime({
2358
- interval: 15,
2359
- format: "' . apply_filters( 'mc_time_format', 'h:i A' ) . '",
2360
- editable: true
2361
- });
2362
- $("#e_endtime").pickatime({
2363
- interval: 15,
2364
- format: "' . apply_filters( 'mc_time_format', 'h:i A' ) . '",
2365
- editable: true
2366
- });
2367
- });
2368
- //]]>
2369
- </script>';
2370
- $form .= $scripting;
2371
  $form .= '<p>
2372
- <label for="e_begin" id="eblabel">' . __( 'Date (YYYY-MM-DD)', 'my-calendar' ) . '</label> <input type="text" id="e_begin" name="event_begin[]" size="10" value="" data-value="' . $event_begin . '" />
2373
  <label for="e_time">' . __( 'From', 'my-calendar' ) . '</label>
2374
- <input type="text" id="e_time" name="event_time[]" size="8" value="' . $starttime . '" />
2375
  <label for="e_endtime">' . __( 'To', 'my-calendar' ) . '</label>
2376
- <input type="text" id="e_endtime" name="event_endtime[]" size="8" value="' . $endtime . '" />
2377
  </p>
2378
  <ul>
2379
- <li><input type="checkbox" value="1" id="e_allday" name="event_allday"' . $allday . ' /> <label for="e_allday">' . __( 'All day event', 'my-calendar' ) . '</label> </li>
2380
  <li><input type="checkbox" value="1" id="e_hide_end" name="event_hide_end"' . $hide . ' /> <label for="e_hide_end">' . __( 'Hide end time', 'my-calendar' ) . '</label></li>
2381
  </ul>
2382
  <p>
2383
- <label for="e_end" id="eelabel"><em>' . __( 'End Date (YYYY-MM-DD, optional)', 'my-calendar' ) . '</em></label> <input type="text" name="event_end[]" id="e_end" size="10" value="" data-value="' . $event_end . '" />
2384
  </p>';
2385
 
2386
  return $form;
@@ -2419,4 +2468,20 @@ function mc_standard_event_registration( $form, $has_data, $data, $context = 'ad
2419
  </p>";
2420
 
2421
  return apply_filters( 'mc_event_registration_form', $form, $has_data, $data, 'admin' );
2422
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  return false;
20
  }
21
 
22
+ add_action( 'admin_menu', 'mc_add_outer_box' );
23
+
24
+ // begin add boxes
25
+ function mc_add_outer_box() {
26
+ add_meta_box( 'mcs_add_event', __('My Calendar Event', 'my-calendar'), 'mc_add_inner_box', 'mc-events', 'side','high' );
27
+ }
28
+
29
+ function mc_add_inner_box() {
30
+ global $post;
31
+ $event_id = get_post_meta( $post->ID, '_mc_event_id', true );
32
+ if ( $event_id ) {
33
+ $url = admin_url( 'admin.php?page=my-calendar&mode=edit&event_id='.$event_id );
34
+ $event = mc_get_event_core( $event_id );
35
+ $content = "<p><strong>" . $event->event_title . '</strong><br />' . $event->event_begin . ' @ ' . $event->event_time . "</p>";
36
+ if ( $event->event_label != '' ) {
37
+ $content .= "<p>" . sprintf( __( '<strong>Location:</strong> %s', 'my-calendar' ), $event->event_label ) . "</p>";
38
+ }
39
+ $content .= "<p>" . sprintf( __( '<a href="%s">Edit event</a>.', 'my-calendar' ), $url ) . "</p>";
40
+
41
+ echo $content;
42
+ }
43
+ }
44
+
45
  function mc_event_post( $action, $data, $event_id ) {
46
  // if the event save was successful.
47
  if ( $action == 'add' || $action == 'copy' ) {
111
  update_post_meta( $post_id, '_mc_event_id', $event_id );
112
  update_post_meta( $post_id, '_mc_event_desc', $data['event_desc'] );
113
  update_post_meta( $post_id, '_mc_event_image', $data['event_image'] );
114
+ update_post_meta( $post_id, '_event_time_label', ( isset( $_POST['event_time_label'] ) ) ? $_POST['event_time_label'] : '' );
115
  $location_id = ( isset( $post['location_preset'] ) ) ? (int) $post['location_preset'] : 0;
116
  if ( $location_id ) { // only change location ID if dropdown set.
117
  update_post_meta( $post_id, '_mc_event_location', $location_id );
121
  }
122
 
123
  function mc_create_event_post( $data, $event_id ) {
124
+ $post_id = mc_get_event_post( $event_id );
125
+ if ( ! $post_id ) {
126
+ $term = mc_get_category_detail( $data['event_category'], 'category_term' );
127
+ $privacy = ( mc_get_category_detail( $data['event_category'], 'category_private' ) == 1 ) ? 'private' : 'publish';
128
+ $title = $data['event_title'];
129
+ $template = apply_filters( 'mc_post_template', 'details', $term );
130
+ $data['shortcode'] = "[my_calendar_event event='$event_id' template='$template' list='']";
131
+ $description = $data['event_desc'];
132
+ $excerpt = $data['event_short'];
133
+ $location_id = ( isset( $_POST['location_preset'] ) ) ? (int) $_POST['location_preset'] : 0;
134
+ $post_status = $privacy;
135
+ $auth = $data['event_author'];
136
+ $type = 'mc-events';
137
+ $my_post = array(
138
+ 'post_title' => $title,
139
+ 'post_content' => $description,
140
+ 'post_status' => $post_status,
141
+ 'post_author' => $auth,
142
+ 'post_name' => sanitize_title( $title ),
143
+ 'post_date' => date( 'Y-m-d H:i:s', current_time( 'timestamp' ) ),
144
+ 'post_type' => $type,
145
+ 'post_excerpt' => $excerpt
146
+ );
147
+ $post_id = wp_insert_post( $my_post );
148
+ wp_set_object_terms( $post_id, (int) $term, 'mc-event-category' );
149
+ $attachment_id = ( isset( $_POST['event_image_id'] ) && is_numeric( $_POST['event_image_id'] ) ) ? $_POST['event_image_id'] : false;
150
+ if ( $attachment_id ) {
151
+ set_post_thumbnail( $post_id, $attachment_id );
152
+ }
153
+ mc_update_event( 'event_post', $post_id, $event_id );
154
+ mc_update_event( 'event_location', $location_id, $event_id );
155
+ do_action( 'mc_update_event_post', $post_id, $_POST, $data, $event_id );
156
+ wp_publish_post( $post_id );
157
  }
 
 
 
 
 
158
  return $post_id;
159
  }
160
 
161
+ function mc_get_event_post( $event_id ) {
162
+ $event = mc_get_event_core( $event_id );
163
+ if ( is_object( $event ) ) {
164
+ if ( property_exists( $event, 'event_post' ) && get_post_status( $event->event_post ) ) {
165
+ return $event->event_post;
166
+ }
167
+ }
168
+ return false;
169
+ }
170
+
171
  function mc_update_event( $field, $data, $event, $type = '%d' ) {
172
  global $wpdb;
173
  $field = sanitize_key( $field );
621
  }
622
  if ( get_option( 'mc_uri' ) != '' ) {
623
  $event_ids = mc_get_occurrences( $event_id );
624
+ //$event_link = mc_build_url( array( 'mc_id' => $event_ids[0]->occur_id ), array( 'page' ), get_option( 'mc_uri' ) );
625
+ //$event_link = add_query_arg( 'mc_id', $event_ids[0]->occur_id, get_option( 'mc_uri' ) );
626
+ $event_link = mc_get_details_link( $event_ids[0]->occur_id );
627
  } else {
628
  $event_link = false;
629
  }
647
  $update['event_begin'] != $_POST['prev_event_begin'] ||
648
  date( "H:i:00", strtotime( $update['event_time'] ) ) != $_POST['prev_event_time'] ||
649
  $update['event_end'] != $_POST['prev_event_end'] ||
650
+ ( date( "H:i:00", strtotime( $update['event_endtime'] ) ) != $_POST['prev_event_endtime'] && ( $_POST['prev_event_endtime'] != '' && date( "H:i:00", strtotime( $update['event_endtime'] ) ) != '23:59:59' ) ) )
651
+ ? true : false; // this may need to be 00:00:00; will have to verify JCD TODO
652
  if ( isset( $_POST['event_instance'] ) ) {
653
  $is_changed = mc_compare( $update, $event_id );// compares the information sent to the information saved for a given event.
654
  $event_instance = (int) $_POST['event_instance'];
655
  if ( $is_changed ) {
656
  // if changed, create new event, match group id, update instance to reflect event connection, same group id.
657
  // if group ID == 0, need to add group ID to both records.
658
+ // if a single instance is edited, it should *not* inherit the recurring settings from parent.
659
+ $update['event_recur'] = 'S1';
660
  if ( $update['event_group_id'] == 0 ) {
661
  $update['event_group_id'] = $event_id;
662
  mc_update_data( $event_id, 'event_group_id', $event_id );
675
  } else {
676
  $result = mc_update_instance( $event_instance, $event_id, $update );
677
  // Only dates were changed
678
+ $message = "<div class='updated notice'><p>" . __( 'Date/time information for this event has been updated.', 'my-calendar' ) . " $url</p></div>";
679
  mc_delete_cache();
680
  }
681
  }
696
  $data = $update;
697
  do_action( 'mc_save_event', $action, $data, $event_id, $result );
698
  if ( $result === false ) {
699
+ $message = "<div class='error'><p><strong>" . __( 'Error', 'my-calendar' ) . ":</strong>" . __( 'Your event was not updated.', 'my-calendar' ) . " $url</p></div>";
700
  } else {
701
  // do an action using the $action and processed event data
702
+ $event_approved = ( isset( $_POST['event_approved'] ) ) ? intval( $_POST['event_approved'] ) : 0;
703
+ do_action( 'mc_transition_event', (int) $_POST['prev_event_status'], $event_approved );
704
+ $message = "<div class='updated'><p>" . __( 'Event updated successfully', 'my-calendar' ) . ". $url</p></div>";
705
  mc_delete_cache();
706
  }
707
  } else {
822
  }
823
  }
824
 
825
+ function mc_show_block( $field, $has_data, $data, $echo = true ) {
826
+ global $user_ID;
827
  $return = $checked = $value = '';
828
  $show_block = mc_show_edit_block( $field );
829
  $pre = '<div class="ui-sortable meta-box-sortables"><div class="postbox">';
830
  $post = '</div></div>';
831
  switch ( $field ) {
832
+ case 'event_host' :
833
+ if ( $show_block ) {
834
+ $users = my_calendar_getUsers();
835
+ $select = '';
836
+ foreach ( $users as $u ) {
837
+ $display_name = ( $u->display_name == '' ) ? $u->user_nicename : $u->display_name;
838
+ if ( is_object( $data ) && $data->event_host == $u->ID ) {
839
+ $selected = ' selected="selected"';
840
+ } else if ( is_object( $u ) && $u->ID == $user_ID && empty( $data->event_host ) ) {
841
+ $selected = ' selected="selected"';
842
+ } else {
843
+ $selected = '';
844
+ }
845
+ $select .= "<option value='$u->ID'$selected>$display_name</option>\n";
846
+ }
847
+ $return = '
848
+ <p>
849
+ <label for="e_host">' . __( 'Host', 'my-calendar' ) . '</label>
850
+ <select id="e_host" name="event_host">' .
851
+ $select
852
+ . '</select>
853
+ </p>';
854
+ }
855
+ break;
856
  case 'event_desc' :
857
  if ( $show_block ) {
858
+ global $current_screen;
859
  // because wp_editor cannot return a value, event_desc fields cannot be filtered if its enabled.
860
  $value = ( $has_data ) ? stripslashes( $data->event_desc ) : '';
861
+ if ( $current_screen->base == 'post' ) {
862
+ $return = '<div class="event_description">
863
+ <label for="content">' . __( 'Event Description', 'my-calendar' ) . '</label><br />
864
+ <textarea id="content" name="content" class="event_desc" rows="8" cols="80">' . stripslashes( esc_attr( $value ) ) . '</textarea>
865
+ </div>';
866
  } else {
867
+ echo '
868
+ <div class="event_description">
869
+ <label for="content">' . __( 'Event Description', 'my-calendar' ) . '</label><br />';
870
+ if ( user_can_richedit() ) {
871
+ wp_editor( $value, 'content', array( 'textarea_rows' => 10 ) );
872
+ } else {
873
+ echo '<textarea id="content" name="content" class="event_desc" rows="8" cols="80">' . stripslashes( esc_attr( $value ) ) . '</textarea>';
874
+ }
875
+ echo '</div>';
876
  }
 
877
  }
878
  break;
879
  case 'event_short' :
887
  break;
888
  case 'event_image' :
889
  if ( $show_block ) {
890
+ $value = ( $has_data ) ? $data->event_image : '';
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( $value ) . '" placeholder="http://yourdomain.com/image.jpg" /> <a href="#" class="button textfield-field">' . __( "Upload", 'my-calendar' ) . '</a>';
895
  if ( ! empty( $data->event_image ) ) {
896
  $return .= '<div class="event_image"><img src="' . esc_attr( $data->event_image ) . '" alt="" /></div>';
897
  } else {
899
  }
900
  $return .= '</div>';
901
  } else {
902
+ $return = '<input type="hidden" name="event_image" value="' . esc_attr( $value ) . '" />';
903
  }
904
  break;
905
  case 'event_category' :
957
  <fieldset>
958
  <legend class="screen-reader-text">' . __( 'Recurring Events', 'my-calendar' ) . '</legend>
959
  <p>
960
+ <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>
961
+ <label for="e_every">' . __( 'every', 'my-calendar' ) . '</label> <input type="number" name="event_every" id="e_every" size="1" min="1" max="12" maxlength="1" value="' . esc_attr( $every ) . '" />
962
  <label for="e_recur" class="screen-reader-text">' . __( 'Units', 'my-calendar' ) . '</label>
963
  <select name="event_recur" id="e_recur">
964
  ' . mc_recur_options( $recur ) . '
977
  $return = '
978
  <div>' .
979
  $prev . '
980
+ <input type="hidden" name="event_repeats" value="' . esc_attr( $repeats ) . '" />
981
+ <input type="hidden" name="event_every" value="' . esc_attr( $every ) . '" />
982
+ <input type="hidden" name="event_recur" value="' . esc_attr( $recur ) . '" />
983
  </div>';
984
  }
985
  break;
1006
  </div>
1007
  ' . $post;
1008
  } else {
1009
+ $open = ( $has_data ) ? esc_attr( $data->event_open ) : '2';
1010
+ $tickets = ( $has_data ) ? esc_url( $data->event_tickets ) : '';
1011
  $registration = ( $has_data ) ? esc_attr( $data->event_registration ) : '';
1012
  $return = '
1013
  <div>
1025
  $return = "
1026
  <div>
1027
  <input type='hidden' name='event_label' value='" . esc_attr( stripslashes( $data->event_label ) ) . "' />
1028
+ <input type='hidden' name='event_street' value='" . esc_attr( stripslashes( $data->event_street ) ) . "' />
1029
+ <input type='hidden' name='event_street2' value='" . esc_attr( stripslashes( $data->event_street2 ) ) . "' />
1030
+ <input type='hidden' name='event_phone' value='" . esc_attr( stripslashes( $data->event_phone ) ) . "' />
1031
+ <input type='hidden' name='event_phone2' value='" . esc_attr( stripslashes( $data->event_phone2 ) ) . "' />
1032
+ <input type='hidden' name='event_city' value='" . esc_attr( stripslashes( $data->event_city ) ) . "' />
1033
+ <input type='hidden' name='event_state' value='" . esc_attr( stripslashes( $data->event_state ) ) . "' />
1034
+ <input type='hidden' name='event_postcode' value='" . esc_attr( stripslashes( $data->event_postcode ) ) . "' />
1035
+ <input type='hidden' name='event_region' value='" . esc_attr( stripslashes( $data->event_region ) ) . "' />
1036
+ <input type='hidden' name='event_country' value='" . esc_attr( stripslashes( $data->event_country ) ) . "' />
1037
+ <input type='hidden' name='event_zoom' value='" . esc_attr( stripslashes( $data->event_zoom ) ) . "' />
1038
+ <input type='hidden' name='event_url' value='" . esc_attr( stripslashes( $data->event_url ) ) . "' />
1039
+ <input type='hidden' name='event_latitude' value='" . esc_attr( stripslashes( $data->event_latitude ) ) . "' />
1040
+ <input type='hidden' name='event_longitude' value='" . esc_attr( stripslashes( $data->event_longitude ) ) . "' />
1041
  </div>";
1042
  }
1043
  }
1045
  default:
1046
  return;
1047
  }
1048
+ $return = apply_filters( 'mc_show_block', $return, $data, $field );
1049
+ if ( $echo == true ) {
1050
+ echo $return;
1051
+ } else {
1052
+ return $return;
1053
+ }
1054
  }
1055
 
1056
 
1118
  } else {
1119
  echo mc_group_id();
1120
  } ?>"/>
1121
+ <input type="hidden" name="event_action" value="<?php esc_attr_e( $mode ); ?>"/>
1122
  <?php if ( ! empty( $_GET['date'] ) ) { ?>
1123
  <input type="hidden" name="event_instance" value="<?php echo (int) $_GET['date']; ?>"/>
1124
  <?php } ?>
1163
  $text_link = '';
1164
  }
1165
  ?>
1166
+ <h3><?php echo $text; ?></h3>
 
 
 
 
1167
  <div class="inside">
1168
+ <p class='mc-controls'>
1169
+ <a href="<?php echo admin_url( 'admin.php?page=my-calendar-manage' ); ?>"><?php echo ( current_user_can( 'mc_manage_events' ) ) ? __( 'Manage events', 'my-calendar' ) : __( 'Manage your events', 'my-calendar' ); ?></a>
1170
+ <?php echo $delete; echo $text_link; ?> <input type="submit" name="save" class="button-primary" value="<?php _e( 'Save Event', 'my-calendar' ); ?>"/>
1171
+ </p>
1172
  <?php
1173
  if ( ! empty( $_GET['date'] ) && $data->event_recur != 'S' ) {
1174
  $event = mc_get_event( $instance );
1183
  <fieldset>
1184
  <legend class="screen-reader-text"><?php _e( 'Event Details', 'my-calendar' ); ?></legend>
1185
  <p>
1186
+ <label for="e_title"><?php _e( 'Event Title', 'my-calendar' ); ?></label><br/><input
 
1187
  type="text" id="e_title" name="event_title" size="50" maxlength="255"
1188
  value="<?php if ( $has_data ) {
1189
  echo apply_filters( 'mc_manage_event_title', stripslashes( esc_attr( $data->event_title ) ), $data );
1191
  if ( $mode == 'edit' ) {
1192
  ?>
1193
  <input type='hidden' name='prev_event_status'
1194
+ value='<?php esc_attr_e( $data->event_approved ); ?>' /><?php
1195
  if ( get_option( 'mc_event_approve' ) == 'true' ) {
1196
  if ( current_user_can( 'mc_approve_events' ) ) { // Added by Roland P.
1197
  if ( $has_data && $data->event_approved == '1' ) {
1252
  mc_show_block( 'event_desc', $has_data, $data );
1253
  mc_show_block( 'event_short', $has_data, $data );
1254
  mc_show_block( 'event_image', $has_data, $data );
1255
+ mc_show_block( 'event_host', $has_data, $data );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1256
  mc_show_block( 'event_category', $has_data, $data );
1257
  mc_show_block( 'event_link', $has_data, $data );
1258
  echo apply_filters( 'mc_event_details', '', $has_data, $data, 'admin' );
1268
 
1269
  <div class="inside">
1270
  <?php if ( is_object( $data ) ) { // information for rewriting recurring data ?>
1271
+ <input type="hidden" name="prev_event_begin" value="<?php esc_attr_e( $data->event_begin ); ?>"/>
1272
+ <input type="hidden" name="prev_event_time" value="<?php esc_attr_e( $data->event_time ); ?>"/>
1273
+ <input type="hidden" name="prev_event_end" value="<?php esc_attr_e( $data->event_end ); ?>"/>
1274
+ <input type="hidden" name="prev_event_endtime" value="<?php esc_attr_e( $data->event_endtime ); ?>"/>
1275
  <?php } ?>
1276
  <fieldset>
1277
  <legend class="screen-reader-text"><?php _e( 'Event Date and Time', 'my-calendar' ); ?></legend>
1435
  } else {
1436
  ?>
1437
  <div>
1438
+ <input type="hidden" name="event_holiday" value="true" <?php checked( get_option( 'mc_skip_holidays' ), 'true' ); ?> />
1439
+ <input type="hidden" name="event_fifth_week" value="true" <?php checked( get_option( 'mc_no_fifth_week' ), 'true' ); ?> />
 
 
 
 
1440
  </div><?php
1441
  } ?>
1442
  <p>
1465
  if ( is_array( $events_access ) ) {
1466
  $checked = ( in_array( $k, $events_access ) || in_array( $a, $events_access ) ) ? " checked='checked'" : '';
1467
  }
1468
+ $item = sprintf( '<li><input type="checkbox" id="%1$s" name="events_access[]" value="%4$s" class="checkbox" %2$s /> <label for="%1$s">%3$s</label></li>', esc_attr( $id ), $checked, esc_html( $label ), esc_attr( $a ) );
1469
  $form .= $item;
1470
  }
1471
  if ( isset( $events_access['notes'] ) ) {
1472
  $note_value = esc_attr( $events_access['notes'] );
1473
  }
1474
+ $form .= '<li><label for="events_access_notes">' . __( 'Notes', 'my-calendar' ) . '</label> <input type="text" name="events_access[notes]" value="' . esc_attr( $note_value ) . '" /></li>';
1475
  $form .= "</ul>
1476
  </fieldset>";
1477
 
1487
 
1488
  if ( isset( $_GET['order'] ) ) {
1489
  $sortdir = ( isset( $_GET['order'] ) && $_GET['order'] == 'ASC' ) ? 'ASC' : 'default';
1490
+ $sortdir = ( isset( $_GET['order'] ) && $_GET['order'] == 'DESC' ) ? 'DESC' : $sortdir;
1491
  } else {
1492
  $sortdir = 'default';
1493
  }
1494
+ $sortbydirection = ( $sortdir == 'default' ) ? get_option( 'mc_default_direction' ) : $sortdir;
1495
  if ( empty( $sortby ) ) {
1496
  $sortbyvalue = 'event_begin';
1497
  } else {
1797
  <td>
1798
  <?php if ( $event->event_label != '' ) { ?><a class='mc_filter' href='<?php $elabel = urlencode( $event->event_label ); echo admin_url( "admin.php?page=my-calendar-manage&amp;filter=$elabel&amp;restrict=where" ); ?>' title="<?php _e( 'Filter by location', 'my-calendar' ); ?>"><span class="screen-reader-text"><?php _e( 'Show only: ', 'my-calendar' ); ?></span><?php echo stripslashes( $event->event_label ); ?></a><?php } ?>
1799
  </td>
1800
+ <?php if ( $event->event_endtime != "23:59:59" ) {
1801
  $eventTime = date_i18n( get_option( 'mc_time_format' ), strtotime( $event->event_time ) );
1802
  } else {
1803
+ $eventTime = mc_notime_label( $event );
1804
  } ?>
1805
  <td><?php
1806
  $date_format = ( get_option( 'mc_date_format' ) == '' ) ? get_option( 'date_format' ) : get_option( 'mc_date_format' );
1917
  $submit = array();
1918
  $errors = '';
1919
  $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 = '';
1920
+
1921
  if ( get_magic_quotes_gpc() ) {
1922
  $post = array_map( 'stripslashes_deep', $post );
1923
  }
1924
  if ( ! wp_verify_nonce( $post['event_nonce_name'], 'event_nonce' ) ) {
1925
  return array();
1926
  }
1927
+
1928
  if ( $action == 'add' || $action == 'edit' || $action == 'copy' ) {
1929
  $title = ! empty( $post['event_title'] ) ? trim( $post['event_title'] ) : '';
1930
  $desc = ! empty( $post['content'] ) ? trim( $post['content'] ) : '';
1961
  $begin = date( 'Y-m-d', strtotime( $begin ) );// regardless of entry format, convert.
1962
  $time = ! empty( $post['event_time'][ $i ] ) ? trim( $post['event_time'][ $i ] ) : '';
1963
  $endtime = ! empty( $post['event_endtime'][ $i ] ) ? trim( $post['event_endtime'][ $i ] ) : date( 'H:i:s', strtotime( $time . ' +1 hour' ) );
1964
+ $endtime = ( $time == '' || $time == '00:00:00' ) ? '23:59:59' : $endtime; // set at 23:59:59 if all day.
1965
+ $endtime = ( $endtime == '' ) ? '23:59:00' : date( 'H:i:00', strtotime( $endtime ) );
 
 
 
 
1966
  // prevent setting enddate to incorrect value on copy.
1967
  if ( strtotime( $end ) < strtotime( $begin ) && $action == 'copy' ) {
1968
  $end = date( 'Y-m-d', ( strtotime( $begin ) + ( strtotime( $post['prev_event_end'] ) - strtotime( $post['prev_event_begin'] ) ) ) );
1969
  }
1970
  if ( isset( $post['event_allday'] ) && (int) $post['event_allday'] !== 0 ) {
1971
+ $time = '00:00:00'; $endtime = '23:59:59';
1972
  }
1973
  $end = date( 'Y-m-d', strtotime( $end ) ); // regardless of entry format, convert.
1974
  $repeats = ( ! empty( $post['event_repeats'] ) || trim( $post['event_repeats'] ) == '' ) ? trim( $post['event_repeats'] ) : 0;
1991
  $event_group_id = ( ( is_array( $post['event_begin'] ) && count( $post['event_begin'] ) > 1 ) || mc_event_is_grouped( $group_id_submitted ) ) ? $group_id_submitted : 0;
1992
  $event_span = ( ! empty( $post['event_span'] ) && $event_group_id != 0 ) ? 1 : 0;
1993
  $event_hide_end = ( ! empty( $post['event_hide_end'] ) ) ? (int) $post['event_hide_end'] : 0;
1994
+ $event_hide_end = ( $time == '' || $time == '23:59:59' ) ? 1 : $event_hide_end; // hide end time automatically on all day events
1995
  // set location
1996
  if ( $location_preset != 'none' && is_numeric( $location_preset ) ) {
1997
  $sql = "SELECT * FROM " . my_calendar_locations_table() . " WHERE location_id = $location_preset";
2077
  }
2078
 
2079
  // We check for a valid time, or an empty one
2080
+ $time = ( $time == '' ) ? '23:59:59' : date( 'H:i:00', strtotime( $time ) );
2081
  $time_format_one = '/^([0-1][0-9]):([0-5][0-9]):([0-5][0-9])$/';
2082
  $time_format_two = '/^([2][0-3]):([0-5][0-9]):([0-5][0-9])$/';
2083
  if ( preg_match( $time_format_one, $time ) || preg_match( $time_format_two, $time ) || $time == '' ) {
2119
  if ( $spam == 1 && $begin == '1970-01-01' ) {
2120
  die;
2121
  }
2122
+
2123
  if ( $errors == '' ) {
2124
  $ok = true;
2125
  $submit = array(
2173
  $event_access = ( is_array( $event_access ) ) ? serialize( $event_access ) : '';
2174
  // The form is going to be rejected due to field validation issues, so we preserve the users entries here
2175
  // all submitted data should be in this object, regardless of data destination.
2176
+ $users_entries = ( !is_object( $users_entries ) ) ? new stdClass() : $users_entries;
2177
+ $users_entries->event_id = ( isset( $_GET['event_id'] ) && is_numeric( $_GET['event_id'] ) ) ? $_GET['event_id'] : false;
2178
  $users_entries->event_title = $title;
2179
  $users_entries->event_desc = $desc;
2180
  $users_entries->event_begin = $begin;
2259
  }
2260
  }
2261
 
2262
+ /**
2263
+ * Update a single event instance.
2264
+ *
2265
+ * args: instance ID, event ID, array containing new dates.
2266
+ */
2267
  function mc_update_instance( $event_instance, $event_id, $update = array() ) {
2268
  global $wpdb;
2269
  $mcdb = $wpdb;
2364
  $output = $details . $before . $output . $after;
2365
  }
2366
 
2367
+ return ( get_option( 'mc_process_shortcodes' ) == 'true' ) ? do_shortcode( $output ) : $output;
2368
  }
2369
 
2370
  function mc_event_is_grouped( $group_id ) {
2383
  }
2384
  }
2385
 
2386
+ function mc_is_all_day( $event ) {
2387
+ return ( $event->event_time == "00:00:00" && $event->event_endtime == "23:59:59" ) ? true : false;
2388
+ }
2389
+
2390
  function mc_standard_datetime_input( $form, $has_data, $data, $instance, $context = 'admin' ) {
2391
  if ( $has_data ) {
2392
  $event_begin = esc_attr( $data->event_begin );
2399
  $event_end = '';
2400
  };
2401
  }
2402
+ $starttime = ( mc_is_all_day( $data ) ) ? '' : date( "h:i A", strtotime( $data->event_time ) );
2403
+ $endtime = ( mc_is_all_day( $data ) ) ? '' : date( "h:i A", strtotime( $data->event_endtime ) );
2404
  } else {
2405
  $event_begin = date( "Y-m-d" );
2406
  $event_end = $starttime = $endtime = '';
2407
  }
2408
  $allday = $hide = '';
2409
+ if ( $has_data && ( mc_is_all_day( $data ) ) ) {
2410
  $allday = " checked=\"checked\"";
2411
  }
2412
  if ( $has_data && $data->event_hide_end == '1' ) {
2413
  $hide = " checked=\"checked\"";
2414
  }
2415
+ if ( $has_data ) {
2416
+ $allday_label = mc_notime_label( $data );
2417
+ } else {
2418
+ $allday_label = get_option( 'mc_notime_text' );
2419
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
2420
  $form .= '<p>
2421
+ <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 ) . '" />
2422
  <label for="e_time">' . __( 'From', 'my-calendar' ) . '</label>
2423
+ <input type="text" id="e_time" class="mc-timepicker" name="event_time[]" size="8" value="' . esc_attr( $starttime ) . '" />
2424
  <label for="e_endtime">' . __( 'To', 'my-calendar' ) . '</label>
2425
+ <input type="text" id="e_endtime" class="mc-timepicker" name="event_endtime[]" size="8" value="' . esc_attr( $endtime ) . '" />
2426
  </p>
2427
  <ul>
2428
+ <li><input type="checkbox" value="1" id="e_allday" name="event_allday"' . $allday . ' /> <label for="e_allday">' . __( 'All day event', 'my-calendar' ) . '</label> <span class="event_time_label"><label for="e_time_label">' . __( 'Time label:', 'my-calendar' ) . '</label> <input type="text" name="event_time_label" id="e_time_label" value="' . esc_attr( $allday_label ) . '" /> </li>
2429
  <li><input type="checkbox" value="1" id="e_hide_end" name="event_hide_end"' . $hide . ' /> <label for="e_hide_end">' . __( 'Hide end time', 'my-calendar' ) . '</label></li>
2430
  </ul>
2431
  <p>
2432
+ <label for="e_end" id="eelabel"><em>' . __( 'End Date (YYYY-MM-DD, optional)', 'my-calendar' ) . '</em></label> <input type="text" name="event_end[]" id="e_end" class="mc-datepicker" size="10" value="" data-value="' . esc_attr( $event_end ) . '" />
2433
  </p>';
2434
 
2435
  return $form;
2468
  </p>";
2469
 
2470
  return apply_filters( 'mc_event_registration_form', $form, $has_data, $data, 'admin' );
2471
+ }
2472
+
2473
+
2474
+ add_action( 'save_post', 'mc_post_update_event' );
2475
+ /**
2476
+ * Re-run a test cycle when updating post.
2477
+ */
2478
+ function mc_post_update_event( $id ) {
2479
+ if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE || wp_is_post_revision( $id ) || !( get_post_type( $id ) == 'mc-events' ) ) {
2480
+ return;
2481
+ }
2482
+ $post = get_post( $id );
2483
+ $featured_image = wp_get_attachment_url( get_post_thumbnail_id( $post->ID ) );
2484
+ $event_id = get_post_meta( $post->ID, '_mc_event_id', true );
2485
+ mc_update_data( $event_id, 'event_image', $featured_image, '%s' );
2486
+
2487
+ }
my-calendar-events.php CHANGED
@@ -3,20 +3,10 @@ if ( ! defined( 'ABSPATH' ) ) {
3
  exit;
4
  } // Exit if accessed directly
5
 
6
- function mc_private_categories() {
7
  $cats = '';
8
  if ( ! is_user_logged_in() ) {
9
- global $wpdb;
10
- $mcdb = $wpdb;
11
- if ( get_option( 'mc_remote' ) == 'true' && function_exists( 'mc_remote_db' ) ) {
12
- $mcdb = mc_remote_db();
13
- }
14
- $query = "SELECT category_id FROM " . MY_CALENDAR_CATEGORIES_TABLE . " WHERE category_private = 1";
15
- $results = $mcdb->get_results( $query );
16
- $categories = array();
17
- foreach ( $results as $result ) {
18
- $categories[] = $result->category_id;
19
- }
20
  $cats = implode( ',', $categories );
21
  if ( $cats != '' ) {
22
  $cats = " AND category_id NOT IN ($cats)";
@@ -28,6 +18,22 @@ function mc_private_categories() {
28
  return $cats;
29
  }
30
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  // used to generate upcoming events lists
32
  function mc_get_all_events( $category, $before, $after, $today, $author, $host, $ltype = '', $lvalue = '' ) {
33
  global $wpdb;
@@ -164,7 +170,6 @@ function mc_get_rss_events( $cat_id = false ) {
164
  $groups[] = $event->occur_group_id;
165
  }
166
  }
167
-
168
  return $output;
169
  }
170
 
@@ -233,6 +238,7 @@ function mc_get_occurrences( $id ) {
233
  if ( $id === 0 ) {
234
  return array();
235
  }
 
236
  $sql = "SELECT * FROM " . my_calendar_event_table() . " WHERE occur_event_id=$id";
237
  $results = $wpdb->get_results( $sql );
238
 
@@ -286,8 +292,8 @@ function mc_related_events( $id, $return = false ) {
286
  * @param int $author Author ID to filter to.
287
  * @return array Array of events with dates as keys.
288
  */
289
- function my_calendar_events( $from, $to, $category, $ltype, $lvalue, $source, $author, $host ) {
290
- $events = my_calendar_grab_events( $from, $to, $category, $ltype, $lvalue, $source, $author, $host );
291
  if ( ! get_option( 'mc_skip_holidays_category' ) || get_option( 'mc_skip_holidays_category' ) == '' ) {
292
  $holidays = array();
293
  } else {
@@ -320,14 +326,14 @@ function my_calendar_events_now( $category = 'default', $template = '<strong>{li
320
  $select_location = $select_author = $select_host = '';
321
  $now = date( 'Y-m-d H:i:s', current_time( 'timestamp' ) );
322
  $event_query = "SELECT *, UNIX_TIMESTAMP(occur_begin) AS ts_occur_begin, UNIX_TIMESTAMP(occur_end) AS ts_occur_end
323
- FROM " . MY_CALENDAR_EVENTS_TABLE . "
324
- JOIN " . MY_CALENDAR_TABLE . "
325
  ON (event_id=occur_event_id)
326
- JOIN " . MY_CALENDAR_CATEGORIES_TABLE . "
327
  ON (event_category=category_id)
328
  WHERE $select_category $select_location $select_author $select_host $limit_string
329
  AND ( CAST('$now' AS DATETIME) BETWEEN occur_begin AND occur_end )
330
- ORDER BY occur_begin, " . apply_filters( 'mc_secondary_sort', 'event_title ASC' );
331
  $events = $mcdb->get_results( $event_query );
332
  if ( ! empty( $events ) ) {
333
  foreach ( array_keys( $events ) as $key ) {
@@ -338,14 +344,15 @@ function my_calendar_events_now( $category = 'default', $template = '<strong>{li
338
  if ( !empty( $arr_events ) ) {
339
  $event = mc_create_tags( $arr_events[0] );
340
 
341
- return jd_draw_template( $event, apply_filters( 'mc_happening_now_template', $template, $event ) );
 
342
  } else {
343
  return '';
344
  }
345
  }
346
 
347
  // Grab all events for the requested date from calendar
348
- function my_calendar_grab_events( $from, $to, $category = null, $ltype = '', $lvalue = '', $source = 'calendar', $author = null, $host = null, $holidays = null ) {
349
  global $wpdb;
350
  $mcdb = $wpdb;
351
  if ( get_option( 'mc_remote' ) == 'true' && function_exists( 'mc_remote_db' ) ) {
@@ -432,16 +439,16 @@ function my_calendar_grab_events( $from, $to, $category = null, $ltype = '', $lv
432
 
433
  $arr_events = array();
434
  $limit_string = "event_flagged <> 1 AND event_approved = 1";
435
-
436
  $event_query = "SELECT *, UNIX_TIMESTAMP(occur_begin) AS ts_occur_begin, UNIX_TIMESTAMP(occur_end) AS ts_occur_end
437
  FROM " . MY_CALENDAR_EVENTS_TABLE . "
438
  JOIN " . MY_CALENDAR_TABLE . "
439
  ON (event_id=occur_event_id)
440
  JOIN " . MY_CALENDAR_CATEGORIES_TABLE . "
441
  ON (event_category=category_id)
442
- WHERE $select_category $select_location $select_author $select_host $limit_string
443
  AND ( DATE(occur_begin) BETWEEN '$from 00:00:00' AND '$to 23:59:59'
444
- OR DATE(occur_end) BETWEEN '$from 00:00:00' and '$to 23:59:59'
445
  OR ( DATE('$from') BETWEEN DATE(occur_begin) AND DATE(occur_end) )
446
  OR ( DATE('$to') BETWEEN DATE(occur_begin) AND DATE(occur_end) ) )
447
  ORDER BY occur_begin, " . apply_filters( 'mc_secondary_sort', 'event_title ASC' );
3
  exit;
4
  } // Exit if accessed directly
5
 
6
+ function mc_private_categories( $return = 'query' ) {
7
  $cats = '';
8
  if ( ! is_user_logged_in() ) {
9
+ $categories = mc_get_private_categories();
 
 
 
 
 
 
 
 
 
 
10
  $cats = implode( ',', $categories );
11
  if ( $cats != '' ) {
12
  $cats = " AND category_id NOT IN ($cats)";
18
  return $cats;
19
  }
20
 
21
+ function mc_get_private_categories() {
22
+ global $wpdb;
23
+ $mcdb = $wpdb;
24
+ if ( get_option( 'mc_remote' ) == 'true' && function_exists( 'mc_remote_db' ) ) {
25
+ $mcdb = mc_remote_db();
26
+ }
27
+ $query = "SELECT category_id FROM " . MY_CALENDAR_CATEGORIES_TABLE . " WHERE category_private = 1";
28
+ $results = $mcdb->get_results( $query );
29
+ $categories = array();
30
+ foreach ( $results as $result ) {
31
+ $categories[] = $result->category_id;
32
+ }
33
+
34
+ return $categories;
35
+ }
36
+
37
  // used to generate upcoming events lists
38
  function mc_get_all_events( $category, $before, $after, $today, $author, $host, $ltype = '', $lvalue = '' ) {
39
  global $wpdb;
170
  $groups[] = $event->occur_group_id;
171
  }
172
  }
 
173
  return $output;
174
  }
175
 
238
  if ( $id === 0 ) {
239
  return array();
240
  }
241
+
242
  $sql = "SELECT * FROM " . my_calendar_event_table() . " WHERE occur_event_id=$id";
243
  $results = $wpdb->get_results( $sql );
244
 
292
  * @param int $author Author ID to filter to.
293
  * @return array Array of events with dates as keys.
294
  */
295
+ function my_calendar_events( $from, $to, $category, $ltype, $lvalue, $source, $author, $host, $search = '' ) {
296
+ $events = my_calendar_grab_events( $from, $to, $category, $ltype, $lvalue, $source, $author, $host, null, $search );
297
  if ( ! get_option( 'mc_skip_holidays_category' ) || get_option( 'mc_skip_holidays_category' ) == '' ) {
298
  $holidays = array();
299
  } else {
326
  $select_location = $select_author = $select_host = '';
327
  $now = date( 'Y-m-d H:i:s', current_time( 'timestamp' ) );
328
  $event_query = "SELECT *, UNIX_TIMESTAMP(occur_begin) AS ts_occur_begin, UNIX_TIMESTAMP(occur_end) AS ts_occur_end
329
+ FROM " . MY_CALENDAR_EVENTS_TABLE . " AS e
330
+ JOIN " . MY_CALENDAR_TABLE . " AS t
331
  ON (event_id=occur_event_id)
332
+ JOIN " . MY_CALENDAR_CATEGORIES_TABLE . " AS c
333
  ON (event_category=category_id)
334
  WHERE $select_category $select_location $select_author $select_host $limit_string
335
  AND ( CAST('$now' AS DATETIME) BETWEEN occur_begin AND occur_end )
336
+ ORDER BY " . apply_filters( 'occur_begin', 'mc_primary_sort' ) . ", " . apply_filters( 'mc_secondary_sort', 'event_title ASC' );
337
  $events = $mcdb->get_results( $event_query );
338
  if ( ! empty( $events ) ) {
339
  foreach ( array_keys( $events ) as $key ) {
344
  if ( !empty( $arr_events ) ) {
345
  $event = mc_create_tags( $arr_events[0] );
346
 
347
+ $output = jd_draw_template( $event, apply_filters( 'mc_happening_now_template', $template, $event ) );
348
+ return ( get_option( 'mc_process_shortcodes' ) == 'true' ) ? do_shortcode( $output ) : $output;
349
  } else {
350
  return '';
351
  }
352
  }
353
 
354
  // Grab all events for the requested date from calendar
355
+ function my_calendar_grab_events( $from, $to, $category = null, $ltype = '', $lvalue = '', $source = 'calendar', $author = null, $host = null, $holidays = null, $search = '' ) {
356
  global $wpdb;
357
  $mcdb = $wpdb;
358
  if ( get_option( 'mc_remote' ) == 'true' && function_exists( 'mc_remote_db' ) ) {
439
 
440
  $arr_events = array();
441
  $limit_string = "event_flagged <> 1 AND event_approved = 1";
442
+ $search = ( $search != '' ) ? " AND MATCH(event_title,event_desc,event_short,event_label,event_city,event_postcode,event_registration) AGAINST ('" . esc_sql( $search ) . "' IN BOOLEAN MODE) " : '';
443
  $event_query = "SELECT *, UNIX_TIMESTAMP(occur_begin) AS ts_occur_begin, UNIX_TIMESTAMP(occur_end) AS ts_occur_end
444
  FROM " . MY_CALENDAR_EVENTS_TABLE . "
445
  JOIN " . MY_CALENDAR_TABLE . "
446
  ON (event_id=occur_event_id)
447
  JOIN " . MY_CALENDAR_CATEGORIES_TABLE . "
448
  ON (event_category=category_id)
449
+ WHERE $select_category $select_location $select_author $select_host $limit_string $search
450
  AND ( DATE(occur_begin) BETWEEN '$from 00:00:00' AND '$to 23:59:59'
451
+ OR DATE(occur_end) BETWEEN '$from 00:00:00' AND '$to 23:59:59'
452
  OR ( DATE('$from') BETWEEN DATE(occur_begin) AND DATE(occur_end) )
453
  OR ( DATE('$to') BETWEEN DATE(occur_begin) AND DATE(occur_end) ) )
454
  ORDER BY occur_begin, " . apply_filters( 'mc_secondary_sort', 'event_title ASC' );
my-calendar-generator.php CHANGED
@@ -42,7 +42,7 @@ function mc_generate() {
42
  }
43
  $output = esc_html( $shortcode . $string );
44
  }
45
- $return = "<div class='updated'><textarea readonly='readonly'>[$output]</textarea></div>";
46
  echo $return;
47
  }
48
  }
@@ -122,18 +122,78 @@ function mc_generator( $type ) {
122
  <option value="day"><?php _e( 'Day', 'my-calendar' ); ?></option>
123
  </select>
124
  </p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
125
  <p id='navigation-info'>
126
  <?php _e( "For navigational fields above and below the calendar: the defaults specified in your settings will be used if the attribute is left blank. Use <code>none</code> to hide all navigation elements.", 'my-calendar' ); ?>
127
  </p>
128
  <p>
129
  <label for="above" id='labove'><?php _e( 'Navigation above calendar', 'my-calendar' ); ?></label>
130
  <input type="text" name="above" id="above" value="nav,toggle,jump,print,timeframe"
131
- aria-labelledby='labove navigation-info'/><br/>
132
  </p>
133
  <p>
134
  <label for="below" id='lbelow'><?php _e( 'Navigation below calendar', 'my-calendar' ); ?></label>
135
  <input type="text" name="below" id="below" value="key,feeds"
136
- aria-labelledby='lbelow navigation-info'/><br/>
137
  </p>
138
  <?php
139
  }
@@ -142,7 +202,7 @@ function mc_generator( $type ) {
142
  ?>
143
  <p>
144
  <label for="fallback"><?php _e( 'Fallback Text', 'my-calendar' ); ?></label>
145
- <input type="text" name="fallback" id="fallback" value=""/>
146
  </p>
147
  <p>
148
  <label for="template"><?php _e( 'Template', 'my-calendar' ); ?></label>
@@ -156,15 +216,15 @@ function mc_generator( $type ) {
156
  ?>
157
  <p>
158
  <label for="before"><?php _e( 'Events/Days Before Current Day', 'my-calendar' ); ?></label>
159
- <input type="number" name="before" id="before" value=""/>
160
  </p>
161
  <p>
162
  <label for="after"><?php _e( 'Events/Days After Current Day', 'my-calendar' ); ?></label>
163
- <input type="number" name="after" id="after" value=""/>
164
  </p>
165
  <p>
166
  <label for="skip"><?php _e( 'Events/Days to Skip', 'my-calendar' ); ?></label>
167
- <input type="number" name="skip" id="skip" value=""/>
168
  </p>
169
  <p>
170
  <label for="show_today"><?php _e( 'Fallback', 'my-calendar' ); ?></label>
42
  }
43
  $output = esc_html( $shortcode . $string );
44
  }
45
+ $return = "<div class='updated'><textarea readonly='readonly' class='large-text readonly'>[$output]</textarea></div>";
46
  echo $return;
47
  }
48
  }
122
  <option value="day"><?php _e( 'Day', 'my-calendar' ); ?></option>
123
  </select>
124
  </p>
125
+ <p>
126
+ <label for="year"><?php _e( 'Year', 'my-calendar' ); ?></label>
127
+ <select name="year" id="year">
128
+ <option value=''><?php _e( 'Default', 'my-calendar' ); ?></option>
129
+ <?php
130
+ global $wpdb;
131
+ $mcdb = $wpdb;
132
+ $query = "SELECT event_begin FROM " . MY_CALENDAR_TABLE . " WHERE event_approved = 1 AND event_flagged <> 1 ORDER BY event_begin ASC LIMIT 0 , 1";
133
+ $year1 = date( 'Y', strtotime( $mcdb->get_var( $query ) ) );
134
+ $diff1 = date( 'Y' ) - $year1;
135
+ $past = $diff1;
136
+ $future = apply_filters( 'mc_jumpbox_future_years', 5, false );
137
+ $fut = 1;
138
+ $f = '';
139
+ $p = '';
140
+ $offset = ( 60 * 60 * get_option( 'gmt_offset' ) );
141
+ while ( $past > 0 ) {
142
+ $p .= '<option value="';
143
+ $p .= date( "Y", time() + ( $offset ) ) - $past;
144
+ $p .= '">';
145
+ $p .= date( "Y", time() + ( $offset ) ) - $past . "</option>\n";
146
+ $past = $past - 1;
147
+ }
148
+ while ( $fut < $future ) {
149
+ $f .= '<option value="';
150
+ $f .= date( "Y", time() + ( $offset ) ) + $fut;
151
+ $f .= '">';
152
+ $f .= date( "Y", time() + ( $offset ) ) + $fut . "</option>\n";
153
+ $fut = $fut + 1;
154
+ }
155
+ echo $p . '<option value="' . date( "Y" ) . '">' . date( "Y" ) . "</option>\n" . $f;
156
+ ?>
157
+ </select>
158
+ </p>
159
+ <p>
160
+ <label for="month"><?php _e( 'Month', 'my-calendar' ); ?></label>
161
+ <select name="month" id="month">
162
+ <option value=''><?php _e( 'Default', 'my-calendar' ); ?></option>
163
+ <?php
164
+ $months = '';
165
+ for ( $i = 1; $i <= 12; $i ++ ) {
166
+ $months .= "<option value='$i'>" . date_i18n( 'F', mktime( 0, 0, 0, $i, 1 ) ) . '</option>' . "\n";
167
+ }
168
+ echo $months;
169
+ ?>
170
+ </select>
171
+ </p>
172
+ <p>
173
+ <label for="day"><?php _e( 'Day', 'my-calendar' ); ?></label>
174
+ <select name="day" id="day">
175
+ <option value=''><?php _e( 'Default', 'my-calendar' ); ?></option>
176
+ <?php
177
+ $days = '';
178
+ for ( $i = 1; $i <= 31; $i++ ) {
179
+ $days .= "<option value='$i'>" . $i . '</option>' . "\n";
180
+ }
181
+ echo $days;
182
+ ?>
183
+ </select>
184
+ </p>
185
  <p id='navigation-info'>
186
  <?php _e( "For navigational fields above and below the calendar: the defaults specified in your settings will be used if the attribute is left blank. Use <code>none</code> to hide all navigation elements.", 'my-calendar' ); ?>
187
  </p>
188
  <p>
189
  <label for="above" id='labove'><?php _e( 'Navigation above calendar', 'my-calendar' ); ?></label>
190
  <input type="text" name="above" id="above" value="nav,toggle,jump,print,timeframe"
191
+ aria-labelledby='labove navigation-info' /><br/>
192
  </p>
193
  <p>
194
  <label for="below" id='lbelow'><?php _e( 'Navigation below calendar', 'my-calendar' ); ?></label>
195
  <input type="text" name="below" id="below" value="key,feeds"
196
+ aria-labelledby='lbelow navigation-info' /><br/>
197
  </p>
198
  <?php
199
  }
202
  ?>
203
  <p>
204
  <label for="fallback"><?php _e( 'Fallback Text', 'my-calendar' ); ?></label>
205
+ <input type="text" name="fallback" id="fallback" value="" />
206
  </p>
207
  <p>
208
  <label for="template"><?php _e( 'Template', 'my-calendar' ); ?></label>
216
  ?>
217
  <p>
218
  <label for="before"><?php _e( 'Events/Days Before Current Day', 'my-calendar' ); ?></label>
219
+ <input type="number" name="before" id="before" value="" />
220
  </p>
221
  <p>
222
  <label for="after"><?php _e( 'Events/Days After Current Day', 'my-calendar' ); ?></label>
223
+ <input type="number" name="after" id="after" value="" />
224
  </p>
225
  <p>
226
  <label for="skip"><?php _e( 'Events/Days to Skip', 'my-calendar' ); ?></label>
227
+ <input type="number" name="skip" id="skip" value="" />
228
  </p>
229
  <p>
230
  <label for="show_today"><?php _e( 'Fallback', 'my-calendar' ); ?></label>
my-calendar-group-manager.php CHANGED
@@ -262,7 +262,7 @@ function mc_group_form( $group_id, $type = 'break' ) {
262
  $group .= $warning;
263
  $group .= ( $type == 'apply' ) ? "<fieldset><legend>" . __( 'Apply these changes to:', 'my-calendar' ) . "</legend>" : '';
264
  $group .= ( $type == 'break' ) ? "<form method='post' action='" . admin_url( "admin.php?page=my-calendar-groups&amp;mode=edit&amp;event_id=$event_id&amp;group_id=$group_id" ) . "'>
265
- <div><input type='hidden' value='$group_id' name='group_id' /><input type='hidden' value='$type' name='event_action' /><input type='hidden' name='_wpnonce' value='$nonce' />
266
  </div>" : '';
267
  $group .= "<ul class='checkboxes'>";
268
  $checked = ( $type == 'apply' ) ? ' checked="checked"' : '';
@@ -318,10 +318,10 @@ function my_calendar_print_group_fields( $data, $mode, $event_id, $group_id = ''
318
  } else {
319
  echo mc_group_id();
320
  } ?>"/>
321
- <input type="hidden" name="event_action" value="<?php echo $mode; ?>"/>
322
- <input type="hidden" name="event_id" value="<?php echo $event_id; ?>"/>
323
- <input type="hidden" name="event_author" value="<?php echo $user_ID; ?>"/>
324
- <input type="hidden" name="event_post" value="<?php echo $data->event_post; ?>"/>
325
  <input type="hidden" name="event_nonce_name" value="<?php echo wp_create_nonce( 'event_nonce' ); ?>"/>
326
  </div>
327
  <div class="ui-sortable meta-box-sortables">
@@ -359,7 +359,7 @@ function my_calendar_print_group_fields( $data, $mode, $event_id, $group_id = ''
359
  } ?></label>
360
  </p>
361
  <?php } else { ?>
362
- <div><input type='hidden' name='event_span' value='<?php echo $data->event_span; ?>'/></div>
363
  <?php } ?>
364
  <?php if ( $mc_input['event_desc'] == 'on' || $mc_input_administrator ) { ?>
365
  <div id="group_description"><?php
@@ -506,7 +506,7 @@ function my_calendar_print_group_fields( $data, $mode, $event_id, $group_id = ''
506
  </div>
507
  <?php } else { ?>
508
  <div>
509
- <input type="hidden" name="event_open" value="<?php echo ( $has_data ) ? $data->event_open : '2'; ?>"/>
510
  <input type="hidden" name="event_tickets"
511
  value="<?php echo ( $has_data ) ? esc_attr( $data->event_tickets ) : ''; ?>"/>
512
  <input type="hidden" name="event_registration"
@@ -536,7 +536,7 @@ function my_calendar_print_group_fields( $data, $mode, $event_id, $group_id = ''
536
  <option value="none"> --</option>
537
  <?php
538
  foreach ( $locations as $location ) {
539
- echo "<option value=\"" . $location->location_id . "\">" . stripslashes( $location->location_label ) . "</option>";
540
  }
541
  ?>
542
  </select>
@@ -704,7 +704,7 @@ function my_calendar_print_group_fields( $data, $mode, $event_id, $group_id = ''
704
  if ( is_array( $location_access ) ) {
705
  $checked = ( in_array( $k, $location_access ) ) ? " checked='checked'" : '';
706
  }
707
- $item = sprintf( '<li><input type="checkbox" id="%1$s" name="event_access[]" value="%4$s" class="checkbox" %2$s /> <label for="%1$s">%3$s</label></li>', $id, $checked, $label, $k );
708
  $access_list .= $item;
709
  }
710
  echo $access_list;
@@ -1075,7 +1075,7 @@ function mc_list_groups() {
1075
  <?php if ( $event->event_time != "00:00:00" ) {
1076
  $eventTime = date_i18n( get_option( 'mc_time_format' ), strtotime( $event->event_time ) );
1077
  } else {
1078
- $eventTime = get_option( 'mc_notime_text' );
1079
  } ?>
1080
  <td><?php echo "$event->event_begin<br />$eventTime"; ?></td>
1081
  <td>
262
  $group .= $warning;
263
  $group .= ( $type == 'apply' ) ? "<fieldset><legend>" . __( 'Apply these changes to:', 'my-calendar' ) . "</legend>" : '';
264
  $group .= ( $type == 'break' ) ? "<form method='post' action='" . admin_url( "admin.php?page=my-calendar-groups&amp;mode=edit&amp;event_id=$event_id&amp;group_id=$group_id" ) . "'>
265
+ <div><input type='hidden' value='" . esc_attr( $group_id ) . "' name='group_id' /><input type='hidden' value='" . esc_attr( $type ) . "' name='event_action' /><input type='hidden' name='_wpnonce' value='$nonce' />
266
  </div>" : '';
267
  $group .= "<ul class='checkboxes'>";
268
  $checked = ( $type == 'apply' ) ? ' checked="checked"' : '';
318
  } else {
319
  echo mc_group_id();
320
  } ?>"/>
321
+ <input type="hidden" name="event_action" value="<?php esc_attr_e( $mode ); ?>"/>
322
+ <input type="hidden" name="event_id" value="<?php esc_attr_e( $event_id ); ?>"/>
323
+ <input type="hidden" name="event_author" value="<?php esc_attr_e( $user_ID ); ?>"/>
324
+ <input type="hidden" name="event_post" value="<?php esc_attr_e( $data->event_post ); ?>"/>
325
  <input type="hidden" name="event_nonce_name" value="<?php echo wp_create_nonce( 'event_nonce' ); ?>"/>
326
  </div>
327
  <div class="ui-sortable meta-box-sortables">
359
  } ?></label>
360
  </p>
361
  <?php } else { ?>
362
+ <div><input type='hidden' name='event_span' value='<?php esc_attr_e( $data->event_span ); ?>'/></div>
363
  <?php } ?>
364
  <?php if ( $mc_input['event_desc'] == 'on' || $mc_input_administrator ) { ?>
365
  <div id="group_description"><?php
506
  </div>
507
  <?php } else { ?>
508
  <div>
509
+ <input type="hidden" name="event_open" value="<?php echo ( $has_data ) ? esc_attr( $data->event_open ) : '2'; ?>"/>
510
  <input type="hidden" name="event_tickets"
511
  value="<?php echo ( $has_data ) ? esc_attr( $data->event_tickets ) : ''; ?>"/>
512
  <input type="hidden" name="event_registration"
536
  <option value="none"> --</option>
537
  <?php
538
  foreach ( $locations as $location ) {
539
+ echo "<option value=\"" . $location->location_id . "\">" . esc_html( stripslashes( $location->location_label ) ) . "</option>";
540
  }
541
  ?>
542
  </select>
704
  if ( is_array( $location_access ) ) {
705
  $checked = ( in_array( $k, $location_access ) ) ? " checked='checked'" : '';
706
  }
707
+ $item = sprintf( '<li><input type="checkbox" id="%1$s" name="event_access[]" value="%4$s" class="checkbox" %2$s /> <label for="%1$s">%3$s</label></li>', esc_attr( $id ), $checked, esc_html( $label ), esc_attr( $k ) );
708
  $access_list .= $item;
709
  }
710
  echo $access_list;
1075
  <?php if ( $event->event_time != "00:00:00" ) {
1076
  $eventTime = date_i18n( get_option( 'mc_time_format' ), strtotime( $event->event_time ) );
1077
  } else {
1078
+ $eventTime = mc_notime_label( $event );
1079
  } ?>
1080
  <td><?php echo "$event->event_begin<br />$eventTime"; ?></td>
1081
  <td>
my-calendar-help.php CHANGED
@@ -12,25 +12,6 @@ function my_calendar_help() {
12
  <div class="postbox-container jcd-wide">
13
  <div class="metabox-holder">
14
 
15
- <div class="ui-sortable meta-box-sortables">
16
- <div class="postbox">
17
- <h3><?php _e( 'My Calendar Help', 'my-calendar' ); ?></h3>
18
-
19
- <div class="inside">
20
- <?php do_action( 'mc_before_help' ); ?>
21
- <ul class="mc-settings checkboxes">
22
- <li><a href="#mc-generator"><?php _e( 'Shortcode Generator', 'my-calendar' ); ?></a></li>
23
- <li><a href="#mc-shortcodes"><?php _e( 'Shortcodes', 'my-calendar' ); ?></a></li>
24
- <li><a href="#icons"><?php _e( 'Icons', 'my-calendar' ); ?></a></li>
25
- <li><a href="#mc-styles"><?php _e( 'Styles', 'my-calendar' ); ?></a></li>
26
- <li><a href="#templates"><?php _e( 'Templating', 'my-calendar' ); ?></a></li>
27
- <li><a href="#get-support"><?php _e( 'Support Form', 'my-calendar' ); ?></a></li>
28
- <li><a href="#notes"><?php _e( 'Helpful Information', 'my-calendar' ); ?></a></li>
29
- </ul>
30
- </div>
31
- </div>
32
- </div>
33
-
34
  <div class="ui-sortable meta-box-sortables" id="get-started">
35
  <div class="postbox">
36
  <h3 id="help"><?php _e( 'Getting Started', 'my-calendar' ); ?></h3>
@@ -44,6 +25,16 @@ function my_calendar_help() {
44
  <p>
45
  <?php printf( __( 'Read more help documentation below or <a href="%s">purchase the My Calendar User\'s Guide</a> to learn more -- but the above is all that you need to do to begin using the calendar.', 'my-calendar' ), 'https://www.joedolson.com/my-calendar/users-guide/' ); ?>
46
  </p>
 
 
 
 
 
 
 
 
 
 
47
  </div>
48
  </div>
49
  </div>
@@ -117,6 +108,15 @@ function my_calendar_help() {
117
  <li>
118
  <code>host</code>: <?php _e( 'Host or comma-separated list (usernames or IDs) to show events from.', 'my-calendar' ); ?>
119
  </li>
 
 
 
 
 
 
 
 
 
120
  <li><code>id</code>: <?php _e( 'String to give shortcode a unique ID.', 'my-calendar' ); ?></li>
121
  </ul>
122
  <p>
@@ -124,23 +124,23 @@ function my_calendar_help() {
124
  </p>
125
  <h4><?php _e( 'Additional Views (Upcoming events, today\'s events)', 'my-calendar' ); ?></h4>
126
 
127
- <textarea readonly='readonly'>[my_calendar_upcoming before="3" after="3" type="event" fallback="No events coming up!" category="General" author="1" host="1" template="{title} {date}" order="asc" show_today="yes" skip="0" ltype="" lvalue=""]</textarea>
128
 
129
  <p>
130
- <?php _e( 'Displays the output of the Upcoming Events widget. <code>before</code> and <code>after</code> are numbers; <code>type</code> is either "event" or "days", and <code>category</code> and <code>author</code> work the same as in the main calendar shortcode. Templates use the template codes listed below. <code>fallback</code> provides text if no events meet your criteria. Order sets sort order for the list &ndash; ascending (<code>asc</code>) or descending (<code>desc</code>). <code>show_today</code> indicates whether to include today\'s events in the list. <code>Skip</code> is how many events to skip in the list.', 'my-calendar' ); ?>
131
  </p>
132
 
133
- <textarea readonly='readonly'>[my_calendar_today category="" author="1" host="1" fallback="Nothing today!" template="{title} {date}"]</textarea>
134
 
135
  <p>
136
- <?php _e( 'Displays the output of the Today\'s Events widget, with four configurable attributes: category, author, template and fallback text.', 'my-calendar' ); ?>
137
  </p>
138
 
139
  <p>
140
  <em><?php _e( 'Upcoming Events and Today\'s Events can also be configured as widgets.', 'my-calendar' ); ?></em>
141
  </p>
142
 
143
- <textarea readonly='readonly'>[my_calendar_event event="" template="&lt;h3&gt;{title}&lt;/h3&gt;{description}" list="&lt;li&gt;{date}, {time}&lt;/li&gt;" before="&lt;ul&gt;" after="&lt;/ul&gt;"]</textarea>
144
 
145
  <p>
146
  <?php _e( 'Displays a single event and/or all dates for that event. If template is set to a blank value, will only display the list of occurrences. If the list attribute is set blank, will only show the event template', 'my-calendar' ); ?>
@@ -149,44 +149,44 @@ function my_calendar_help() {
149
 
150
  <h4><?php _e( 'Calendar Filter Shortcodes', 'my-calendar' ); ?></h4>
151
 
152
- <textarea readonly='readonly'>[mc_filters show="categories,locations"]</textarea>
153
 
154
  <p>
155
  <?php _e( 'Displays all available filters as a single form. The <code>show</code> attribute takes three keywords: categories, locations, and access, to indicate which filters to show and in what order.', 'my-calendar' ); ?>
156
  </p>
157
 
158
- <textarea readonly='readonly'>[my_calendar_locations show="list" type="saved" datatype="name"]</textarea>
159
 
160
  <p>
161
  <?php _e( 'List of event locations, as a list of links or as a select form. <code>show</code> is either <code>list</code> or <code>form</code>, <code>type</code> is <code>saved</code> (to show items from stored locations), or <code>custom</code> (to show options configured in location settings). <code>datatype</code> must be the type of data your limits are using: <code>name</code> (business name), <code>city</code>, <code>state</code>, <code>country</code>, <code>zip</code> (postal code), or <code>region</code>.', 'my-calendar' ); ?>
162
  </p>
163
 
164
- <textarea readonly='readonly'>[my_calendar_categories show="list"]</textarea>
165
 
166
  <p>
167
  <?php _e( 'List of event categories, either as a list of links or as a select dropdown form. The <code>show</code> attribute can either be <code>list</code> or <code>form</code>.', 'my-calendar' ); ?>
168
  </p>
169
 
170
- <textarea readonly='readonly'>[my_calendar_search]</textarea>
171
 
172
  <p>
173
  <?php _e( 'Simple search form to search all events. <code>url</code> attribute to pass a custom search results page, otherwise your My Calendar URL.', 'my-calendar' ); ?>
174
  </p>
175
 
176
- <textarea readonly='readonly'>[my_calendar_now category='default' template='']</textarea>
177
 
178
  <p>
179
  <?php _e( 'Show an event happening right now. Will only ever show one event, which will be the first event returned by checking which events are happening at the moment. Pass a category ID or name to limit by category.', 'my-calendar' ); ?>
180
  </p>
181
 
182
- <textarea readonly='readonly'>[my_calendar_access show="list"]</textarea>
183
 
184
  <p>
185
  <?php _e( 'List of filterable accessibility services, either as a list of links or as a select dropdown form. The <code>show</code> attribute can either be <code>list</code> or <code>form</code>.', 'my-calendar' ); ?>
186
  </p>
187
  <h4><?php _e( 'Information Listing Shortcodes', 'my-calendar' ); ?></h4>
188
 
189
- <textarea readonly='readonly'>[my_calendar_show_locations datatype="" template=""]</textarea>
190
 
191
  <p>
192
  <?php _e( 'List of locations. <code>datatype</code> is the type of data displayed; all lists include a link to the map to that location. In addition to basic location information as in the above shortcode, you can also use "hcard" to display all available location information.', 'my-calendar' ); ?>
@@ -354,7 +354,7 @@ function my_calendar_help() {
354
  <dt><code>{link}</code></dt>
355
  <dd><?php _e( 'Displays the URL provided for the event.', 'my-calendar' ); ?></dd>
356
 
357
- <dt><code>{ical_link}</code></dt>
358
  <dd><?php _e( 'Produces the URL to download an iCal formatted record for the event.', 'my-calendar' ); ?></dd>
359
 
360
  <dt><code>{ical_html}</code></dt>
@@ -374,17 +374,17 @@ function my_calendar_help() {
374
 
375
  <dt><code>{details}</code></dt>
376
  <dd><?php _e( 'Provides a link to an auto-generated page containing all information on the given event.', 'my-calendar' ); ?>
377
- <strong><?php _e( 'Requires that the site URL has been provided on the Settings page', 'my-calendar' ); ?></strong>
378
 
379
  <dt><code>{details_link}</code></dt>
380
- <dd><?php _e( 'Raw URL for the details link; empty if target URL not defined.', 'my-calendar' ); ?>
381
 
382
  <dt><code>{linking}</code></dt>
383
  <dd><?php _e( 'Provides a link to the defined event URL when present, otherwise the {details} link.', 'my-calendar' ); ?>
384
- <strong><?php _e( 'Requires that the site URL has been provided on the Settings page', 'my-calendar' ); ?></strong>
385
 
386
  <dt><code>{linking_title}</code></dt>
387
- <dd><?php _e( 'Like {link_title}, but uses {linking} instead of {link}.', 'my-calendar' ); ?>
388
 
389
  <dt><code>{event_open}</code></dt>
390
  <dd><?php _e( 'Displays text indicating whether registration for the event is currently open or closed; displays nothing if that choice is selected in the event.', 'my-calendar' ); ?></dd>
@@ -508,8 +508,18 @@ function my_calendar_help() {
508
  </p>
509
 
510
  <p>
511
- <?php _e( '<strong>Donations</strong>: I appreciate anything you can give. $2 may not seem like much, but it can really add up when thousands of people are using the software. Please note that I am not a non-profit organization, and your gifts are not tax deductible. Thank you!', 'my-calendar' ); ?>
 
 
 
512
  </p>
 
 
 
 
 
 
 
513
  </div>
514
  </div>
515
  </div>
12
  <div class="postbox-container jcd-wide">
13
  <div class="metabox-holder">
14
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  <div class="ui-sortable meta-box-sortables" id="get-started">
16
  <div class="postbox">
17
  <h3 id="help"><?php _e( 'Getting Started', 'my-calendar' ); ?></h3>
25
  <p>
26
  <?php printf( __( 'Read more help documentation below or <a href="%s">purchase the My Calendar User\'s Guide</a> to learn more -- but the above is all that you need to do to begin using the calendar.', 'my-calendar' ), 'https://www.joedolson.com/my-calendar/users-guide/' ); ?>
27
  </p>
28
+ <?php do_action( 'mc_before_help' ); ?>
29
+ <ul class="mc-settings checkboxes">
30
+ <li><a href="#mc-generator"><?php _e( 'Shortcode Generator', 'my-calendar' ); ?></a></li>
31
+ <li><a href="#mc-shortcodes"><?php _e( 'Shortcodes', 'my-calendar' ); ?></a></li>
32
+ <li><a href="#icons"><?php _e( 'Icons', 'my-calendar' ); ?></a></li>
33
+ <li><a href="#mc-styles"><?php _e( 'Styles', 'my-calendar' ); ?></a></li>
34
+ <li><a href="#templates"><?php _e( 'Templating', 'my-calendar' ); ?></a></li>
35
+ <li><a href="#get-support"><?php _e( 'Support Form', 'my-calendar' ); ?></a></li>
36
+ <li><a href="#notes"><?php _e( 'Helpful Information', 'my-calendar' ); ?></a></li>
37
+ </ul>
38
  </div>
39
  </div>
40
  </div>
108
  <li>
109
  <code>host</code>: <?php _e( 'Host or comma-separated list (usernames or IDs) to show events from.', 'my-calendar' ); ?>
110
  </li>
111
+ <li>
112
+ <code>year</code>: <?php _e( 'A specific year to start the calendar display at. (e.g. 2016)', 'my-calendar' ); ?>
113
+ </li>
114
+ <li>
115
+ <code>month</code>: <?php _e( 'A specific month to start the calendar display at. (e.g. 08)', 'my-calendar' ); ?>
116
+ </li>
117
+ <li>
118
+ <code>day</code>: <?php _e( 'A specific day to start the calendar display at. (e.g. 28)', 'my-calendar' ); ?>
119
+ </li>
120
  <li><code>id</code>: <?php _e( 'String to give shortcode a unique ID.', 'my-calendar' ); ?></li>
121
  </ul>
122
  <p>
124
  </p>
125
  <h4><?php _e( 'Additional Views (Upcoming events, today\'s events)', 'my-calendar' ); ?></h4>
126
 
127
+ <textarea readonly='readonly' class="large-text readonly">[my_calendar_upcoming before="3" after="3" type="event" fallback="No events coming up!" category="General" author="1" host="1" template="{title} {date}" order="asc" show_today="yes" skip="0" ltype="" lvalue="" from="" to=""]</textarea>
128
 
129
  <p>
130
+ <?php _e( 'Displays the output of the Upcoming Events widget. <code>before</code> and <code>after</code> are numbers; <code>type</code> is either "event" or "days", and <code>category</code> and <code>author</code> work the same as in the main calendar shortcode. Templates use the template codes listed below. <code>fallback</code> provides text if no events meet your criteria. Order sets sort order for the list &ndash; ascending (<code>asc</code>) or descending (<code>desc</code>). <code>show_today</code> indicates whether to include today\'s events in the list. <code>Skip</code> is how many events to skip in the list.', 'my-calendar' ); ?> <?php _e( 'Use <code>from</code> and <code>to</code> to display events between two specific dates', 'my-calendar' ); ?>
131
  </p>
132
 
133
+ <textarea readonly='readonly' class="large-text readonly">[my_calendar_today category="" author="1" host="1" fallback="Nothing today!" template="{title} {date}" date=""]</textarea>
134
 
135
  <p>
136
+ <?php _e( 'Displays the output of the Today\'s Events widget, with five configurable attributes: category, author, template, date, and fallback text.', 'my-calendar' ); ?>
137
  </p>
138
 
139
  <p>
140
  <em><?php _e( 'Upcoming Events and Today\'s Events can also be configured as widgets.', 'my-calendar' ); ?></em>
141
  </p>
142
 
143
+ <textarea readonly='readonly' class="large-text readonly">[my_calendar_event event="" template="&lt;h3&gt;{title}&lt;/h3&gt;{description}" list="&lt;li&gt;{date}, {time}&lt;/li&gt;" before="&lt;ul&gt;" after="&lt;/ul&gt;"]</textarea>
144
 
145
  <p>
146
  <?php _e( 'Displays a single event and/or all dates for that event. If template is set to a blank value, will only display the list of occurrences. If the list attribute is set blank, will only show the event template', 'my-calendar' ); ?>
149
 
150
  <h4><?php _e( 'Calendar Filter Shortcodes', 'my-calendar' ); ?></h4>
151
 
152
+ <textarea readonly='readonly' class="large-text readonly">[mc_filters show="categories,locations"]</textarea>
153
 
154
  <p>
155
  <?php _e( 'Displays all available filters as a single form. The <code>show</code> attribute takes three keywords: categories, locations, and access, to indicate which filters to show and in what order.', 'my-calendar' ); ?>
156
  </p>
157
 
158
+ <textarea readonly='readonly' class="large-text readonly">[my_calendar_locations show="list" type="saved" datatype="name"]</textarea>
159
 
160
  <p>
161
  <?php _e( 'List of event locations, as a list of links or as a select form. <code>show</code> is either <code>list</code> or <code>form</code>, <code>type</code> is <code>saved</code> (to show items from stored locations), or <code>custom</code> (to show options configured in location settings). <code>datatype</code> must be the type of data your limits are using: <code>name</code> (business name), <code>city</code>, <code>state</code>, <code>country</code>, <code>zip</code> (postal code), or <code>region</code>.', 'my-calendar' ); ?>
162
  </p>
163
 
164
+ <textarea readonly='readonly' class="large-text readonly">[my_calendar_categories show="list"]</textarea>
165
 
166
  <p>
167
  <?php _e( 'List of event categories, either as a list of links or as a select dropdown form. The <code>show</code> attribute can either be <code>list</code> or <code>form</code>.', 'my-calendar' ); ?>
168
  </p>
169
 
170
+ <textarea readonly='readonly' class="large-text readonly">[my_calendar_search]</textarea>
171
 
172
  <p>
173
  <?php _e( 'Simple search form to search all events. <code>url</code> attribute to pass a custom search results page, otherwise your My Calendar URL.', 'my-calendar' ); ?>
174
  </p>
175
 
176
+ <textarea readonly='readonly' class="large-text readonly">[my_calendar_now category='default' template='']</textarea>
177
 
178
  <p>
179
  <?php _e( 'Show an event happening right now. Will only ever show one event, which will be the first event returned by checking which events are happening at the moment. Pass a category ID or name to limit by category.', 'my-calendar' ); ?>
180
  </p>
181
 
182
+ <textarea readonly='readonly' class="large-text readonly">[my_calendar_access show="list"]</textarea>
183
 
184
  <p>
185
  <?php _e( 'List of filterable accessibility services, either as a list of links or as a select dropdown form. The <code>show</code> attribute can either be <code>list</code> or <code>form</code>.', 'my-calendar' ); ?>
186
  </p>
187
  <h4><?php _e( 'Information Listing Shortcodes', 'my-calendar' ); ?></h4>
188
 
189
+ <textarea readonly='readonly' class="large-text readonly">[my_calendar_show_locations datatype="" template=""]</textarea>
190
 
191
  <p>
192
  <?php _e( 'List of locations. <code>datatype</code> is the type of data displayed; all lists include a link to the map to that location. In addition to basic location information as in the above shortcode, you can also use "hcard" to display all available location information.', 'my-calendar' ); ?>
354
  <dt><code>{link}</code></dt>
355
  <dd><?php _e( 'Displays the URL provided for the event.', 'my-calendar' ); ?></dd>
356
 
357
+ <dt><code>{ical}</code></dt>
358
  <dd><?php _e( 'Produces the URL to download an iCal formatted record for the event.', 'my-calendar' ); ?></dd>
359
 
360
  <dt><code>{ical_html}</code></dt>
374
 
375
  <dt><code>{details}</code></dt>
376
  <dd><?php _e( 'Provides a link to an auto-generated page containing all information on the given event.', 'my-calendar' ); ?>
377
+ <strong><?php _e( 'Requires that the site URL has been provided on the Settings page', 'my-calendar' ); ?></strong></dd>
378
 
379
  <dt><code>{details_link}</code></dt>
380
+ <dd><?php _e( 'Raw URL for the details link; empty if target URL not defined.', 'my-calendar' ); ?></dd>
381
 
382
  <dt><code>{linking}</code></dt>
383
  <dd><?php _e( 'Provides a link to the defined event URL when present, otherwise the {details} link.', 'my-calendar' ); ?>
384
+ <strong><?php _e( 'Requires that the site URL has been provided on the Settings page', 'my-calendar' ); ?></strong></dd>
385
 
386
  <dt><code>{linking_title}</code></dt>
387
+ <dd><?php _e( 'Like {link_title}, but uses {linking} instead of {link}.', 'my-calendar' ); ?></dd>
388
 
389
  <dt><code>{event_open}</code></dt>
390
  <dd><?php _e( 'Displays text indicating whether registration for the event is currently open or closed; displays nothing if that choice is selected in the event.', 'my-calendar' ); ?></dd>
508
  </p>
509
 
510
  <p>
511
+ <?php printf( __( '<strong>Donations</strong>: I appreciate anything you can give. %s may not seem like much, but it can really add up when thousands of people are using the software. Please note that I am not a non-profit organization, and your gifts are not tax deductible. Thank you!', 'my-calendar' ), '$5' ); ?>
512
+ </p>
513
+ <p>
514
+ <?php _e( '<strong>How to upgrade from My Calendar: Submissions to My Calendar Pro</strong>', 'my-calendar' ); ?>
515
  </p>
516
+ <ol>
517
+ <li><?php _e( 'Update to My Calendar: Submissions version 1.2.9', 'my-calendar' ); ?></li>
518
+ <li><?php _e( 'Deactivate and delete My Calendar: Submissions', 'my-calendar' ); ?></li>
519
+ <li><?php printf( __( 'Log-in to your account at <a href="%s">Joe Dolson Accessible Web Design</a> and download My Calendar Pro', 'my-calendar' ), 'https://www.joedolson.com/account/' ); ?></li>
520
+ <li><?php _e( 'Upload My Calendar Pro and activate.', 'my-calendar' ); ?></li>
521
+ <li><?php _e( 'Input your My Calendar: Submissions license key into My Calendar Pro', 'my-calendar' ); ?></li>
522
+ </ol>
523
  </div>
524
  </div>
525
  </div>
my-calendar-ical.php DELETED
@@ -1,76 +0,0 @@
1
- <?php
2
- if ( ! defined( 'ABSPATH' ) ) {
3
- exit;
4
- } // Exit if accessed directly
5
-
6
- function my_calendar_ical() {
7
- $p = ( isset( $_GET['span'] ) ) ? 'year' : false;
8
- $y = ( isset( $_GET['yr'] ) ) ? $_GET['yr'] : date( 'Y' );
9
- $m = ( isset( $_GET['month'] ) ) ? $_GET['month'] : date( 'n' );
10
- $ny = ( isset( $_GET['nyr'] ) ) ? $_GET['nyr'] : $y;
11
- $nm = ( isset( $_GET['nmonth'] ) ) ? $_GET['nmonth'] : $m;
12
-
13
- if ( $p ) {
14
- $from = "$y-1-1";
15
- $to = "$y-12-31";
16
- } else {
17
- $d = date( 't', mktime( 0, 0, 0, $m, 1, $y ) );
18
- $from = "$y-$m-1";
19
- $to = "$ny-$nm-$d";
20
- }
21
-
22
- $from = apply_filters( 'mc_ical_download_from', $from, $p );
23
- $to = apply_filters( 'mc_ical_download_to', $to, $p );
24
- $atts = array(
25
- 'category' => null,
26
- 'ltype' => '',
27
- 'lvalue' => '',
28
- 'source' => 'calendar',
29
- 'author' => null,
30
- 'host' => null
31
- );
32
- $atts = apply_filters( 'mc_ical_attributes', $atts );
33
- extract( $atts );
34
-
35
- global $mc_version;
36
- // establish template
37
- $template = "BEGIN:VEVENT
38
- UID:{dateid}-{id}
39
- LOCATION:{ical_location}
40
- SUMMARY:{title}
41
- DTSTAMP:{ical_start}
42
- ORGANIZER;CN={host}:MAILTO:{host_email}
43
- DTSTART:{ical_start}
44
- DTEND:{ical_end}
45
- URL;VALUE=URI:{link}
46
- DESCRIPTION:{ical_desc}
47
- CATEGORIES:{category}
48
- END:VEVENT";
49
- // add ICAL headers
50
- $output = 'BEGIN:VCALENDAR
51
- VERSION:2.0
52
- METHOD:PUBLISH
53
- PRODID:-//Accessible Web Design//My Calendar//http://www.joedolson.com//v' . $mc_version . '//EN';
54
- // to do : add support for other arguments
55
- $events = my_calendar_grab_events( $from, $to );
56
- if ( is_array( $events ) && ! empty( $events ) ) {
57
- foreach ( array_keys( $events ) as $key ) {
58
- $event =& $events[ $key ];
59
- if ( is_object( $event ) ) {
60
- if ( ! ( $event->category_private == 1 && ! is_user_logged_in() ) ) {
61
- $array = mc_create_tags( $event );
62
- $output .= "\n" . jd_draw_template( $array, $template, 'ical' );
63
- }
64
- }
65
- }
66
- }
67
- $output .= "\nEND:VCALENDAR";
68
- $output = html_entity_decode( preg_replace( "~(?<!\r)\n~", "\r\n", $output ) );
69
- if ( ! ( isset( $_GET['sync'] ) && $_GET['sync'] == 'true' ) ) {
70
- header( "Content-Type: text/calendar; charset=" . get_bloginfo( 'charset' ) );
71
- header( "Pragma: no-cache" );
72
- header( "Expires: 0" );
73
- header( "Content-Disposition: inline; filename=my-calendar.ics" );
74
- }
75
- echo $output;
76
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
my-calendar-install.php CHANGED
@@ -29,21 +29,25 @@ $grid_template = addslashes( '<span class="event-time dtstart value-title" title
29
  <div class="sub-details">
30
  {hcard}
31
  {details before="<p class=\'mc_details\'>" after="</p>"}
32
- <p><a href="{linking}" class="event-link external">{title}</a></p></div>' );
33
 
34
  $list_template = addslashes( '<span class="event-time dtstart value-title" title="{dtstart}">{time}<span class="time-separator"> - </span>{endtime before="<span class=\'end-time dtend value-title\' title=\'{dtend}\'>" after="</span>"}</span>
35
 
 
 
36
  <div class="sub-details">
37
  {hcard}
38
  {details before="<p class=\'mc_details\'>" after="</p>"}
39
- <p><a href="{linking}" class="event-link external">{title}</a></p></div>' );
40
 
41
  $mini_template = addslashes( '<span class="event-time dtstart value-title" title="{dtstart}">{time}<span class="time-separator"> - </span>{endtime before="<span class=\'end-time dtend value-title\' title=\'{dtend}\'>" after="</span>"}</span>
42
 
 
 
43
  <div class="sub-details">
44
  {excerpt before="<div class=\'excerpt\'>" after="</div>"}
45
  {hcard}
46
- <p><a href="{linking}" class="event-link external">{title}</a></p></div>' );
47
 
48
  $single_template = addslashes( '<span class="event-time dtstart value-title" title="{dtstart}">{time}<span class="time-separator"> - </span><span class="end-time dtend value-title" title="{dtend}">{endtime}</span></span>
49
 
@@ -52,7 +56,7 @@ $single_template = addslashes( '<span class="event-time dtstart value-title" tit
52
  <div class="mc-description">{image}{description}</div>
53
  <p>{ical_html} &bull; {gcal_link}</p>
54
  {map}
55
- <p><a href="{linking}" class="event-link external">{title}</a></p></div>' );
56
 
57
  $rss_template = addslashes( "\n<item>
58
  <title>{rss_title}: {date}, {time}</title>
@@ -234,7 +238,8 @@ function mc_default_settings() {
234
  'event_location' => 'off',
235
  'event_location_dropdown' => 'on',
236
  'event_specials' => 'on',
237
- 'event_access' => 'on'
 
238
  ) );
239
  add_option( 'mc_input_options_administrators', 'false' );
240
  add_site_option( 'mc_multisite', '0' );
@@ -252,14 +257,16 @@ function mc_default_settings() {
252
  add_option( 'mc_date_format', get_option( 'date_format' ) );
253
  // This option *must* be complete, if it's partial we get errors. So use update instead of add.
254
  update_option( 'mc_templates', array(
255
- 'title' => '{title}',
256
- 'link' => '{title}',
257
- 'grid' => $grid_template,
258
- 'list' => $list_template,
259
- 'mini' => $mini_template,
260
- 'rss' => $rss_template,
261
- 'details' => $single_template,
262
- 'label' => addslashes( 'More<span class="screen-reader-text"> about {title}</span>' )
 
 
263
  ) );
264
  add_option( 'mc_skip_holidays', 'false' );
265
  add_option( 'mc_css_file', 'twentyfifteen.css' );
@@ -273,6 +280,7 @@ function mc_default_settings() {
273
  add_option( 'mc_event_link', 'true' );
274
  add_option( 'mc_topnav', 'toggle,timeframe,jump,nav' );
275
  add_option( 'mc_bottomnav', 'key,category,feeds' );
 
276
  update_option( 'mc_update_notice', 1 );
277
  mc_add_roles();
278
  $has_uri = mc_guess_calendar();
@@ -299,7 +307,7 @@ function mc_generate_calendar_page( $slug ) {
299
  'post_type' => 'page',
300
  'post_author' => $current_user->ID,
301
  'ping_status' => 'closed',
302
- 'post_content' => '[my_calendar]'
303
  );
304
  $post_ID = wp_insert_post( $page );
305
  $post_slug = wp_unique_post_slug( $slug, $post_ID, 'publish', 'page', 0 );
29
  <div class="sub-details">
30
  {hcard}
31
  {details before="<p class=\'mc_details\'>" after="</p>"}
32
+ <p><a href="{linking}" class="event-link external"><span class="screen-reader-text">More information about </span>{title}</a></p></div>' );
33
 
34
  $list_template = addslashes( '<span class="event-time dtstart value-title" title="{dtstart}">{time}<span class="time-separator"> - </span>{endtime before="<span class=\'end-time dtend value-title\' title=\'{dtend}\'>" after="</span>"}</span>
35
 
36
+ <h3 class="event-title">{title}</h3>
37
+
38
  <div class="sub-details">
39
  {hcard}
40
  {details before="<p class=\'mc_details\'>" after="</p>"}
41
+ <p><a href="{linking}" class="event-link external"><span class="screen-reader-text">More information about </span>{title}</a></p></div>' );
42
 
43
  $mini_template = addslashes( '<span class="event-time dtstart value-title" title="{dtstart}">{time}<span class="time-separator"> - </span>{endtime before="<span class=\'end-time dtend value-title\' title=\'{dtend}\'>" after="</span>"}</span>
44
 
45
+ <h3 class="event-title">{title}</h3>
46
+
47
  <div class="sub-details">
48
  {excerpt before="<div class=\'excerpt\'>" after="</div>"}
49
  {hcard}
50
+ <p><a href="{linking}" class="event-link external"><span class="screen-reader-text">More information about </span>{title}</a></p></div>' );
51
 
52
  $single_template = addslashes( '<span class="event-time dtstart value-title" title="{dtstart}">{time}<span class="time-separator"> - </span><span class="end-time dtend value-title" title="{dtend}">{endtime}</span></span>
53
 
56
  <div class="mc-description">{image}{description}</div>
57
  <p>{ical_html} &bull; {gcal_link}</p>
58
  {map}
59
+ <p><a href="{linking}" class="event-link external"><span class="screen-reader-text">More information about </span>{title}</a></p></div>' );
60
 
61
  $rss_template = addslashes( "\n<item>
62
  <title>{rss_title}: {date}, {time}</title>
238
  'event_location' => 'off',
239
  'event_location_dropdown' => 'on',
240
  'event_specials' => 'on',
241
+ 'event_access' => 'on',
242
+ 'event_host' => 'on'
243
  ) );
244
  add_option( 'mc_input_options_administrators', 'false' );
245
  add_site_option( 'mc_multisite', '0' );
257
  add_option( 'mc_date_format', get_option( 'date_format' ) );
258
  // This option *must* be complete, if it's partial we get errors. So use update instead of add.
259
  update_option( 'mc_templates', array(
260
+ 'title' => '{time}: {title}',
261
+ 'title_list' => '{title}',
262
+ 'title_solo' => '{title}',
263
+ 'link' => '{title}',
264
+ 'grid' => $grid_template,
265
+ 'list' => $list_template,
266
+ 'mini' => $mini_template,
267
+ 'rss' => $rss_template,
268
+ 'details' => $single_template,
269
+ 'label' => addslashes( 'More<span class="screen-reader-text"> about {title}</span>' )
270
  ) );
271
  add_option( 'mc_skip_holidays', 'false' );
272
  add_option( 'mc_css_file', 'twentyfifteen.css' );
280
  add_option( 'mc_event_link', 'true' );
281
  add_option( 'mc_topnav', 'toggle,timeframe,jump,nav' );
282
  add_option( 'mc_bottomnav', 'key,category,feeds' );
283
+ add_option( 'mc_default_direction', 'DESC' );
284
  update_option( 'mc_update_notice', 1 );
285
  mc_add_roles();
286
  $has_uri = mc_guess_calendar();
307
  'post_type' => 'page',
308
  'post_author' => $current_user->ID,
309
  'ping_status' => 'closed',
310
+ 'post_content' => '[my_calendar id="my-calendar"]'
311
  );
312
  $post_ID = wp_insert_post( $page );
313
  $post_slug = wp_unique_post_slug( $slug, $post_ID, 'publish', 'page', 0 );
my-calendar-limits.php CHANGED
@@ -202,7 +202,7 @@ function mc_select_host( $host, $type = 'event' ) {
202
  $host = get_user_by( 'login', $host ); // get author by username
203
 
204
  if ( is_object( $host ) ) {
205
- $host_id = (int) $host->ID;
206
  $select_host = ( $type == 'all' ) ? " WHERE $data = $host_id" : " $data = $host_id AND";
207
  } else {
208
  $select_host = '';
@@ -276,9 +276,9 @@ function mc_limit_string( $type = '', $ltype = '', $lvalue = '' ) {
276
  ) ) ) {
277
  if ( $current_location != 'all' && $current_location != '' ) {
278
  if ( is_numeric( $current_location ) ) {
279
- $limit_string = "$location_type = " . (int) $current_location . " AND";
280
  } else {
281
- $limit_string = "$location_type = '" . esc_sql( $current_location ) . "' AND";
282
  }
283
  }
284
  }
@@ -331,7 +331,7 @@ function mc_secondary_limit( $ltype = '', $lvalue = '' ) {
331
  $location_type = "event_label";
332
  }
333
  if ( $current_location != 'all' && $current_location != '' ) {
334
- $limit_string = " $location_type='" . esc_sql( $current_location ) . "' AND ";
335
  // $limit_string .= ($type=='all')?' AND':"";
336
  }
337
 
202
  $host = get_user_by( 'login', $host ); // get author by username
203
 
204
  if ( is_object( $host ) ) {
205
+ $host_id = $host->ID;
206
  $select_host = ( $type == 'all' ) ? " WHERE $data = $host_id" : " $data = $host_id AND";
207
  } else {
208
  $select_host = '';
276
  ) ) ) {
277
  if ( $current_location != 'all' && $current_location != '' ) {
278
  if ( is_numeric( $current_location ) ) {
279
+ $limit_string = esc_sql( $location_type ) . ' = ' . intval( $current_location ) . ' AND';
280
  } else {
281
+ $limit_string = esc_sql( $location_type ) . " = '" . esc_sql( $current_location ) . "' AND";
282
  }
283
  }
284
  }
331
  $location_type = "event_label";
332
  }
333
  if ( $current_location != 'all' && $current_location != '' ) {
334
+ $limit_string = " $location_type='$current_location' AND ";
335
  // $limit_string .= ($type=='all')?' AND':"";
336
  }
337
 
my-calendar-locations.php CHANGED
@@ -148,6 +148,7 @@ function my_calendar_manage_locations() {
148
  'location_id' => (int) $_POST['location_id']
149
  );
150
  $results = mc_modify_location( $update, $where );
 
151
  if ( $results === false ) {
152
  echo "<div class=\"error\"><p><strong>" . __( 'Location could not be edited.', 'my-calendar' ) . "</strong></p></div>";
153
  } else if ( $results == 0 ) {
@@ -256,7 +257,7 @@ function mc_controlled_field( $this_field ) {
256
 
257
  function mc_location_controller( $fieldname, $selected, $context = 'location' ) {
258
  $field = ( $context == 'location' ) ? 'location_' . $fieldname : 'event_' . $fieldname;
259
- $selected = trim( $selected );
260
  $options = get_option( 'mc_location_controls' );
261
  $regions = $options[ 'event_' . $fieldname ];
262
  $form = "<select name='$field' id='e_$fieldname'>";
@@ -266,7 +267,8 @@ function mc_location_controller( $fieldname, $selected, $context = 'location' )
266
  $form .= "<option value='$selected'>$selected " . __( '(Not a controlled value)', 'my-calendar' ) . "</option>\n";
267
  }
268
  foreach ( $regions as $key => $value ) {
269
- $key = trim( $key );
 
270
  $aselected = ( $selected == $key ) ? " selected='selected'" : '';
271
  $form .= "<option value='$key'$aselected>$value</option>\n";
272
  }
@@ -530,7 +532,7 @@ function mc_locations_fields( $has_data, $data, $context = 'location' ) {
530
  if ( is_array( $location_access ) ) {
531
  $checked = ( in_array( $a, $location_access ) || in_array( $k, $location_access ) ) ? " checked='checked'" : '';
532
  }
533
- $item = sprintf( '<li><input type="checkbox" id="%1$s" name="' . $context . '_access[]" value="%4$s" class="checkbox" %2$s /> <label for="%1$s">%3$s</label></li>', $id, $checked, $label, $a );
534
  $access_list .= $item;
535
  }
536
  $return .= $access_list;
148
  'location_id' => (int) $_POST['location_id']
149
  );
150
  $results = mc_modify_location( $update, $where );
151
+ do_action( 'mc_modify_location', $where, $update );
152
  if ( $results === false ) {
153
  echo "<div class=\"error\"><p><strong>" . __( 'Location could not be edited.', 'my-calendar' ) . "</strong></p></div>";
154
  } else if ( $results == 0 ) {
257
 
258
  function mc_location_controller( $fieldname, $selected, $context = 'location' ) {
259
  $field = ( $context == 'location' ) ? 'location_' . $fieldname : 'event_' . $fieldname;
260
+ $selected = esc_attr( trim( $selected ) );
261
  $options = get_option( 'mc_location_controls' );
262
  $regions = $options[ 'event_' . $fieldname ];
263
  $form = "<select name='$field' id='e_$fieldname'>";
267
  $form .= "<option value='$selected'>$selected " . __( '(Not a controlled value)', 'my-calendar' ) . "</option>\n";
268
  }
269
  foreach ( $regions as $key => $value ) {
270
+ $key = esc_attr( trim( $key ) );
271
+ $value = esc_html( $value );
272
  $aselected = ( $selected == $key ) ? " selected='selected'" : '';
273
  $form .= "<option value='$key'$aselected>$value</option>\n";
274
  }
532
  if ( is_array( $location_access ) ) {
533
  $checked = ( in_array( $a, $location_access ) || in_array( $k, $location_access ) ) ? " checked='checked'" : '';
534
  }
535
+ $item = sprintf( '<li><input type="checkbox" id="%1$s" name="' . $context . '_access[]" value="%4$s" class="checkbox" %2$s /> <label for="%1$s">%3$s</label></li>', esc_attr( $id ), $checked, esc_html( $label ), esc_attr( $a ) );
536
  $access_list .= $item;
537
  }
538
  $return .= $access_list;
my-calendar-output.php CHANGED
@@ -109,10 +109,11 @@ function mc_time_html( $event, $type, $current_date ) {
109
  }
110
  } else {
111
  $time .= "<span class='event-time'>";
112
- if ( get_option( 'mc_notime_text' ) == '' || get_option( 'mc_notime_text' ) == "N/A" ) {
 
113
  $time .= "<abbr title='" . __( 'Not Applicable', 'my-calendar' ) . "'>" . __( 'N/A', 'my-calendar' ) . "</abbr>\n";
114
  } else {
115
- $time .= get_option( 'mc_notime_text' );
116
  }
117
  $time .= "</span></p>";
118
  }
@@ -120,34 +121,38 @@ function mc_time_html( $event, $type, $current_date ) {
120
  $time .= "
121
  </div>";
122
 
123
- return $time;
124
  }
125
 
126
  function mc_category_icon( $event, $html = 'html' ) {
127
- $url = plugin_dir_url( __FILE__ );
128
- $image = '';
129
- if ( get_option( 'mc_hide_icons' ) != 'true' ) {
130
- if ( $event->category_icon != '' ) {
131
- $path = ( is_custom_icon() ) ? str_replace( 'my-calendar', 'my-calendar-custom', $url ) : plugins_url( 'images/icons', __FILE__ ) . '/';
132
- $hex = ( strpos( $event->category_color, '#' ) !== 0 ) ? '#' : '';
133
- if ( $html == 'html' ) {
134
- $image = '<img src="' . $path . $event->category_icon . '" alt="' . __( 'Category', 'my-calendar' ) . ': ' . esc_attr( $event->category_name ) . '" class="category-icon" style="background:' . $hex . $event->category_color . '" />';
135
- } else {
136
- $image = $path . $event->category_icon;
 
 
137
  }
138
  }
139
- }
140
 
141
- return $image;
 
142
  }
143
 
144
- add_filter( 'the_title', 'mc_category_icon_title' );
145
- function mc_category_icon_title( $title ) {
146
  if ( is_singular( 'mc-events' ) && in_the_loop() ) {
147
- $event_id = get_post_meta( get_the_ID(), '_mc_event_id', true );
148
- $event = mc_get_event_core( $event_id );
149
- $icon = mc_category_icon( $event );
150
- $title = $icon . ' ' . $title;
 
 
151
  }
152
 
153
  return $title;
@@ -218,7 +223,13 @@ function my_calendar_draw_event( $event, $type = "calendar", $process_date, $tim
218
  $has_image = ( $image != '' ) ? ' has-image' : '';
219
  $header .= "<div id='$uid-$day_id-$type' class='mc-$uid $type-event " . "mc_" . sanitize_title( $event->category_name ) . " vevent'>\n";
220
 
221
- $title_template = ( $templates['title'] == '' ) ? '{title}' : $templates['title'];
 
 
 
 
 
 
222
  $event_title = jd_draw_template( $data, $title_template );
223
  $event_title = ( $event_title == '' ) ? jd_draw_template( $data, '{title}' ) : $event_title; //prevent empty titles
224
 
@@ -243,9 +254,11 @@ function my_calendar_draw_event( $event, $type = "calendar", $process_date, $tim
243
  $title = ( $type == 'single' && ! is_singular( 'mc-events' ) ) ? "<h2 class='event-title summary'>$image $event_title</h2>\n" : '';
244
  $title = apply_filters( 'mc_event_title', $title, $event, $event_title, $image );
245
  $header .= $title;
246
-
 
 
247
  if ( mc_show_details( $time, $type ) ) {
248
- $close = ( $type == 'calendar' || $type == 'mini' ) ? "<a href=\"#$uid-$day_id-$type\" aria-controls='$uid-$day_id-$type-details' class='mc-toggle mc-close close'><img src=\"" . plugin_dir_url( __FILE__ ) . "images/event-close.png\" alt='" . __( 'Close', 'my-calendar' ) . "' /></a>" : '';
249
 
250
  if ( $details === false ) {
251
  // put together address information as vcard
@@ -302,11 +315,11 @@ function my_calendar_draw_event( $event, $type = "calendar", $process_date, $tim
302
  $image = ( $event->event_image != '' ) ? "<img src='$event->event_image' alt='' class='mc-image photo' />" : '';
303
  }
304
  if ( get_option( 'mc_desc' ) == 'true' || $type == 'single' ) {
305
- $description = ( get_option( 'mc_process_shortcodes' ) == 'true' ) ? apply_filters( 'the_content', stripcslashes( $event->event_desc ) ) : wpautop( stripcslashes( $event->event_desc ), 1 );
306
  $description = "<div class='longdesc'>$description</div>";
307
  }
308
  if ( get_option( 'mc_short' ) == 'true' && $type != 'single' ) {
309
- $short = ( get_option( 'mc_process_shortcodes' ) == 'true' ) ? apply_filters( 'the_content', stripcslashes( $event->event_short ) ) : wpautop( stripcslashes( $event->event_short ), 1 );
310
  $short = "<div class='shortdesc'>$short</div>";
311
  }
312
 
@@ -337,7 +350,7 @@ function my_calendar_draw_event( $event, $type = "calendar", $process_date, $tim
337
  }
338
 
339
  if ( get_option( 'mc_gmap' ) == 'true' ) {
340
- $map = ( is_singular( 'mc-event' ) || $type == 'single' ) ? mc_generate_map( $event ) : '';
341
  } else {
342
  $map = '';
343
  }
@@ -371,7 +384,7 @@ function my_calendar_draw_event( $event, $type = "calendar", $process_date, $tim
371
  . $return;
372
  } else {
373
  // if a custom template is in use
374
- $toggle = ( $type == 'calendar' || $type == 'mini' ) ? "<a href=\"#$uid-$day_id-$type\" aria-controls='$uid-$day_id-$type-details' class='mc-toggle mc-close close'><img src=\"" . plugin_dir_url( __FILE__ ) . "images/event-close.png\" alt='" . __( 'Close', 'my-calendar' ) . "' /></a>" : '';
375
  $details = $toggle . $details . "\n";
376
  }
377
  $img_class = ( $image != '' ) ? ' has-image' : ' no-image';
@@ -383,7 +396,10 @@ function my_calendar_draw_event( $event, $type = "calendar", $process_date, $tim
383
  $details .= "</div><!--ends .details--></div>";
384
  $details = apply_filters( 'mc_event_content', $details, $event, $type, $time );
385
  } else {
386
- $details = $header . "</div>";
 
 
 
387
  }
388
 
389
  return $details;
@@ -419,7 +435,7 @@ function mc_edit_panel( $html, $event, $type, $time ) {
419
  return $html . $edit;
420
  }
421
 
422
- function mc_build_date_switcher( $type = 'calendar', $cid = 'all' ) {
423
  global $wpdb;
424
  $mcdb = $wpdb;
425
  if ( get_option( 'mc_remote' ) == 'true' && function_exists( 'mc_remote_db' ) ) {
@@ -432,7 +448,7 @@ function mc_build_date_switcher( $type = 'calendar', $cid = 'all' ) {
432
  $qsa = array();
433
  parse_str( $_SERVER['QUERY_STRING'], $qsa );
434
  if ( ! isset( $_GET['cid'] ) ) {
435
- $date_switcher .= '<input type="hidden" name="cid" value="' . $cid . '" />';
436
  }
437
  foreach ( $qsa as $name => $argument ) {
438
  $name = esc_attr( strip_tags( $name ) );
@@ -441,14 +457,23 @@ function mc_build_date_switcher( $type = 'calendar', $cid = 'all' ) {
441
  $date_switcher .= '<input type="hidden" name="' . $name . '" value="' . $argument . '" />';
442
  }
443
  }
 
 
 
 
 
 
 
 
 
444
  // We build the months in the switcher
445
  $date_switcher .= '
446
- <label class="maybe-hide" for="mc-' . $type . '-month">' . __( 'Month', 'my-calendar' ) . ':</label> <select id="mc-' . $type . '-month" name="month">' . "\n";
447
  for ( $i = 1; $i <= 12; $i ++ ) {
448
  $date_switcher .= "<option value='$i'" . mc_month_comparison( $i ) . '>' . date_i18n( 'F', mktime( 0, 0, 0, $i, 1 ) ) . '</option>' . "\n";
449
  }
450
  $date_switcher .= '</select>' . "\n" . '
451
- <label class="maybe-hide" for="mc-' . $type . '-year">' . __( 'Year', 'my-calendar' ) . ':</label> <select id="mc-' . $type . '-year" name="yr">' . "\n";
452
  // query to identify oldest start date in the database
453
  $query = "SELECT event_begin FROM " . MY_CALENDAR_TABLE . " WHERE event_approved = 1 AND event_flagged <> 1 ORDER BY event_begin ASC LIMIT 0 , 1";
454
  $year1 = date( 'Y', strtotime( $mcdb->get_var( $query ) ) );
@@ -476,7 +501,7 @@ function mc_build_date_switcher( $type = 'calendar', $cid = 'all' ) {
476
  $date_switcher .= $p;
477
  $date_switcher .= '<option value="' . date( "Y", time() + ( $offset ) ) . '"' . mc_year_comparison( date( "Y", time() + ( $offset ) ) ) . '>' . date( "Y", time() + ( $offset ) ) . "</option>\n";
478
  $date_switcher .= $f;
479
- $date_switcher .= '</select> <input type="submit" class="button" value="' . __( 'Go', 'my-calendar' ) . '" /></div>
480
  </form></div>';
481
  $date_switcher = apply_filters( 'mc_jumpbox', $date_switcher );
482
 
@@ -492,13 +517,13 @@ function my_calendar_print() {
492
  header( 'Content-Type: ' . get_bloginfo( 'html_type' ) . '; charset=' . get_bloginfo( 'charset' ) );
493
  echo '<!DOCTYPE html>
494
  <!--[if IE 7]>
495
- <html id="ie7" dir="' . get_bloginfo( 'text_direction' ) . '" lang="' . get_bloginfo( 'language' ) . '">
496
  <![endif]-->
497
  <!--[if IE 8]>
498
- <html id="ie8" dir="' . get_bloginfo( 'text_direction' ) . '" lang="' . get_bloginfo( 'language' ) . '">
499
  <![endif]-->
500
  <!--[if !(IE 6) | !(IE 7) | !(IE 8) ]><!-->
501
- <html dir="' . get_bloginfo( 'text_direction' ) . '" lang="' . get_bloginfo( 'language' ) . '">
502
  <!--<![endif]-->
503
  <head>
504
  <meta charset="' . get_bloginfo( 'charset' ) . '" />
@@ -516,7 +541,7 @@ function my_calendar_print() {
516
  <link rel='stylesheet' href='$stylesheet' type='text/css' media='screen,print' />
517
  </head>
518
  <body>\n";
519
- echo my_calendar( 'print', 'calendar', $category, $time, $ltype, $lvalue, 'mc-print-view', '', '', null, null, '', '' );
520
  $return_url = ( get_option( 'mc_uri' ) != '' && ! is_numeric( get_option( 'mc_uri' ) ) ) ? get_option( 'mc_uri' ) : home_url();
521
  $add = $_GET;
522
  unset( $add['cid'] );
@@ -668,84 +693,28 @@ function mc_list_title( $events ) {
668
  } else {
669
  $cstate = sprintf( __( " and %d other events", 'my-calendar' ), $count );
670
  }
671
- $title = apply_filters( 'mc_list_event_title_hint', stripcslashes( $now->event_title ), $now ) . $cstate;
672
 
673
  return $title;
674
  }
675
 
676
  function mc_search_results( $query ) {
677
- $before = apply_filters( 'mc_past_search_results', 0 );
678
- $after = apply_filters( 'mc_future_search_results', 10 ); // return only future events, nearest 10
679
  if ( is_string( $query ) ) {
680
- $select_category = $limit_string = $select_author = $select_host = '';
681
- $search = " MATCH(event_title,event_desc,event_short,event_label,event_city,event_postcode,event_registration) AGAINST ('$query' IN BOOLEAN MODE) AND ";
 
682
  } else {
683
- /*
684
- extract( $query );
685
- $select_category = ( $category != 'default' ) ? mc_select_category( $category ) : '';
686
- $limit_string = mc_limit_string();
687
- $select_author = ( $author != 'default' ) ? mc_select_author( $author ) : '';
688
- $select_host = ( $host != 'default' ) ? mc_select_host( $host ) : '';
689
- $prefix = ( $select_category . $limit_string . $select_author . $select_host != '' ) ? ' AND' : '';
690
- $search = "$prefix MATCH(event_title,event_desc,event_short,event_label,event_city,event_postcode,event_registration) AGAINST ('$query' IN BOOLEAN MODE) AND ";
691
- */
692
- }
693
- global $wpdb;
694
- $mcdb = $wpdb;
695
- if ( get_option( 'mc_remote' ) == 'true' && function_exists( 'mc_remote_db' ) ) {
696
- $mcdb = mc_remote_db();
697
  }
 
 
 
698
 
699
- $date = date( 'Y', current_time( 'timestamp' ) ) . '-' . date( 'm', current_time( 'timestamp' ) ) . '-' . date( 'd', current_time( 'timestamp' ) );
700
- // if a value is non-zero, I'll grab a handful of extra events so I can throw out holidays and others like that.
701
- if ( $before > 0 ) {
702
- $before = $before + 5;
703
- $events1 = $mcdb->get_results( "SELECT *, UNIX_TIMESTAMP(occur_begin) AS ts_occur_begin, UNIX_TIMESTAMP(occur_end) AS ts_occur_end
704
- FROM " . MY_CALENDAR_EVENTS_TABLE . "
705
- JOIN " . MY_CALENDAR_TABLE . "
706
- ON (event_id=occur_event_id)
707
- JOIN " . MY_CALENDAR_CATEGORIES_TABLE . "
708
- ON (event_category=category_id) WHERE $select_category $select_author $select_host $limit_string $search event_approved = 1 AND event_flagged <> 1
709
- AND DATE(occur_begin) < '$date' ORDER BY occur_begin DESC LIMIT 0,$before" );
710
- } else {
711
- $events1 = array();
712
- }
713
- $events3 = $mcdb->get_results( "SELECT *, UNIX_TIMESTAMP(occur_begin) AS ts_occur_begin, UNIX_TIMESTAMP(occur_end) AS ts_occur_end
714
- FROM " . MY_CALENDAR_EVENTS_TABLE . "
715
- JOIN " . MY_CALENDAR_TABLE . "
716
- ON (event_id=occur_event_id)
717
- JOIN " . MY_CALENDAR_CATEGORIES_TABLE . "
718
- ON (event_category=category_id) WHERE $select_category $select_author $select_host $limit_string $search event_approved = 1 AND event_flagged <> 1
719
- AND DATE(occur_begin) = '$date'" );
720
- if ( $after > 0 ) {
721
- $after = $after + 5;
722
- $events2 = $mcdb->get_results( "SELECT *, UNIX_TIMESTAMP(occur_begin) AS ts_occur_begin, UNIX_TIMESTAMP(occur_end) AS ts_occur_end
723
- FROM " . MY_CALENDAR_EVENTS_TABLE . "
724
- JOIN " . MY_CALENDAR_TABLE . "
725
- ON (event_id=occur_event_id)
726
- JOIN " . MY_CALENDAR_CATEGORIES_TABLE . "
727
- ON (event_category=category_id) WHERE $select_category $select_author $select_host $limit_string $search event_approved = 1 AND event_flagged <> 1
728
- AND DATE(occur_begin) > '$date' ORDER BY occur_begin ASC LIMIT 0,$after" );
729
- } else {
730
- $events2 = array();
731
- }
732
- $arr_events = array();
733
- if ( ! empty( $events1 ) || ! empty( $events2 ) || ! empty( $events3 ) ) {
734
- $arr_events = array_merge( $events1, $events3, $events2 );
735
- }
736
- if ( ! get_option( 'mc_skip_holidays_category' ) || get_option( 'mc_skip_holidays_category' ) == '' ) {
737
- $holidays = array();
738
- } else {
739
- $holidays = mc_get_all_holidays( $before, $after, 'yes' );
740
- $holiday_array = mc_set_date_array( $holidays );
741
- }
742
- if ( is_array( $arr_events ) && ! empty( $arr_events ) ) {
743
- $no_events = false;
744
- $event_array = mc_set_date_array( $arr_events );
745
- if ( is_array( $holidays ) && count( $holidays ) > 0 ) {
746
- $event_array = mc_holiday_limit( $event_array, $holiday_array ); // if there are holidays, rejigger.
747
- }
748
- }
749
  if ( ! empty( $event_array ) ) {
750
  $template = '<strong>{date}</strong> {title} {details}';
751
  $template = apply_filters( 'mc_search_template', $template );
@@ -754,15 +723,107 @@ function mc_search_results( $query ) {
754
  } else {
755
  $output = "<li class='no-results'>" . __( 'Sorry, your search produced no results.', 'my-calendar' ) . "</li>";
756
  }
 
 
 
757
 
758
- return "<ol class='mc-search-results'>$output</ol>";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
759
  }
760
 
761
  add_filter( 'the_title', 'mc_search_results_title', 10, 2 );
762
  function mc_search_results_title( $title, $id = false ) {
763
- if ( isset( $_GET['mcs'] ) && ( is_page( $id ) || is_single( $id ) ) && in_the_loop() ) {
764
- $query = esc_html( $_GET['mcs'] );
765
- $title = sprintf( __( 'Events Search for &ldquo;%s&rdquo;', 'my-calendar' ), $query );
766
  }
767
 
768
  return $title;
@@ -787,19 +848,90 @@ function mc_show_search_results( $content ) {
787
  }
788
  }
789
 
790
- add_filter( 'the_content', 'mc_show_event_template', 100 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
791
  function mc_show_event_template( $content ) {
792
  global $post;
793
- $new_content = $content;
794
- if ( $post->post_type == 'mc-events' ) {
795
- $new_content = do_shortcode( get_post_meta( $post->ID, '_mc_event_shortcode', true ) ); // -> triggers an infinite loop when shortcode filters enabled in settings. If you're using this view, you have no reason to allow the_content filters.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
796
  }
 
 
 
797
 
798
- return apply_filters( 'mc_event_content', $new_content, $content, $post );
 
 
 
 
 
 
 
799
  }
800
 
801
  // Actually do the printing of the calendar
802
- function my_calendar( $name, $format, $category, $time = 'month', $ltype = '', $lvalue = '', $id = 'jd-calendar', $template = '', $content = '', $author = null, $host = null, $above = '', $below = '' ) {
803
  check_my_calendar();
804
  // category key needs to receive the original category settings.
805
  $original_category = $category;
@@ -815,7 +947,7 @@ function my_calendar( $name, $format, $category, $time = 'month', $ltype = '', $
815
  }
816
  $used = array_merge( $aboves, $belows );
817
 
818
- if ( isset( $_GET['format'] ) && in_array( $_GET['format'], array( 'list', 'mini' ) ) ) {
819
  $format = esc_attr( $_GET['format'] );
820
  } else {
821
  $format = esc_attr( $format );
@@ -849,51 +981,65 @@ function my_calendar( $name, $format, $category, $time = 'month', $ltype = '', $
849
  'ltype' => $ltype,
850
  'lvalue' => $lvalue,
851
  'author' => $author,
852
- 'id' => $id
 
 
 
 
 
 
853
  );
 
854
  $my_calendar_body .= apply_filters( 'mc_before_calendar', '', $args );
 
855
 
856
- $main_class = ( $name != '' ) ? sanitize_title( $name ) : 'all';
857
  $cid = ( isset( $_GET['cid'] ) ) ? esc_attr( strip_tags( $_GET['cid'] ) ) : $main_class;
858
 
 
 
 
 
 
 
 
859
  // mc body wrapper
860
  $mc_wrapper = "<div id=\"$id\" class=\"mc-main $format $time $main_class\" aria-live='assertive' aria-atomic='true'>";
861
  $mc_closer = "</div>";
862
 
863
- if ( get_option( 'mc_convert' ) == 'true' ) {
864
- $format = ( mc_is_mobile() ) ? 'list' : $format;
865
- }
866
- $format = apply_filters( 'mc_display_format', $format, $args );
867
  $date_format = ( get_option( 'mc_date_format' ) != '' ) ? get_option( 'mc_date_format' ) : get_option( 'date_format' );
868
 
869
  if ( isset( $_GET['mc_id'] ) && $format != 'mini' ) {
870
  // single event, main calendar only.
871
- $mc_id = (int) $_GET['mc_id'];
872
- $my_calendar_body .= mc_get_event( $mc_id, 'html' );
 
 
873
  } else {
874
  if ( $category == "" ) {
875
  $category = 'all';
876
  }
877
  // Deal with the week not starting on a monday
878
  $name_days = array(
879
- __( '<abbr title="Sunday">Sun</abbr>', 'my-calendar' ),
880
- __( '<abbr title="Monday">Mon</abbr>', 'my-calendar' ),
881
- __( '<abbr title="Tuesday">Tues</abbr>', 'my-calendar' ),
882
- __( '<abbr title="Wednesday">Wed</abbr>', 'my-calendar' ),
883
- __( '<abbr title="Thursday">Thur</abbr>', 'my-calendar' ),
884
- __( '<abbr title="Friday">Fri</abbr>', 'my-calendar' ),
885
- __( '<abbr title="Saturday">Sat</abbr>', 'my-calendar' )
886
  );
887
  $abbrevs = array( 'sun', 'mon', 'tues', 'wed', 'thur', 'fri', 'sat' );
888
- if ( $format == "mini" ) {
 
889
  $name_days = array(
890
- __( '<abbr title="Sunday">S</abbr>', 'my-calendar' ),
891
- __( '<abbr title="Monday">M</abbr>', 'my-calendar' ),
892
- __( '<abbr title="Tuesday">T</abbr>', 'my-calendar' ),
893
- __( '<abbr title="Wednesday">W</abbr>', 'my-calendar' ),
894
- __( '<abbr title="Thursday">T</abbr>', 'my-calendar' ),
895
- __( '<abbr title="Friday">F</abbr>', 'my-calendar' ),
896
- __( '<abbr title="Saturday">S</abbr>', 'my-calendar' )
897
  );
898
  }
899
  $start_of_week = ( get_option( 'start_of_week' ) == 1 ) ? 1 : 7; // convert start of week to ISO 8601 (Monday/Sunday)
@@ -958,9 +1104,14 @@ function my_calendar( $name, $format, $category, $time = 'month', $ltype = '', $
958
  $c_day = date( "d", time() + ( $offset ) );
959
  }
960
  if ( ! ( isset( $_GET['yr'] ) || isset( $_GET['month'] ) || isset( $_GET['dy'] ) ) ) {
961
- $c_year = apply_filters( 'mc_filter_year', $c_year, $args );
962
- $c_month = apply_filters( 'mc_filter_month', $c_month, $args );
963
- $c_day = apply_filters( 'mc_filter_day', $c_day, $args );
 
 
 
 
 
964
  }
965
  $c_day = ( $c_day == 0 ) ? 1 : $c_day; // c_day can't equal 0.
966
  $current_date = mktime( 0, 0, 0, $c_month, $c_day, $c_year );
@@ -1063,7 +1214,7 @@ function my_calendar( $name, $format, $category, $time = 'month', $ltype = '', $
1063
  'dy' => $nLink['day'],
1064
  'cid' => $main_class
1065
  ), array() );
1066
- $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 );
1067
  $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 );
1068
  $nav = '
1069
  <div class="my-calendar-nav">
@@ -1073,14 +1224,17 @@ function my_calendar( $name, $format, $category, $time = 'month', $ltype = '', $
1073
  </div>';
1074
  }
1075
  // set up rss feeds
1076
- if ( $format != 'mini' ) {
1077
  $ical_m = ( isset( $_GET['month'] ) ) ? (int) $_GET['month'] : date( 'n' );
1078
  $ical_y = ( isset( $_GET['yr'] ) ) ? (int) $_GET['yr'] : date( 'Y' );
 
 
 
1079
  $feeds = mc_rss_links( $ical_y, $ical_m, $nLink, $add, $subtract );
1080
  }
1081
  // set up date switcher
1082
  if ( in_array( 'jump', $used ) ) {
1083
- $jump = ( $time != 'week' && $time != 'day' ) ? mc_build_date_switcher( $format, $main_class ) : '';
1084
  }
1085
  // set up above-calendar order of fields
1086
  if ( get_option( 'mc_topnav' ) != '' ) {
@@ -1091,7 +1245,7 @@ function my_calendar( $name, $format, $category, $time = 'month', $ltype = '', $
1091
  }
1092
 
1093
  foreach ( $mc_toporder as $value ) {
1094
- if ( $value != 'none' ) {
1095
  $value = trim( $value );
1096
  $mc_topnav .= @${$value};
1097
  }
@@ -1107,7 +1261,7 @@ function my_calendar( $name, $format, $category, $time = 'month', $ltype = '', $
1107
  $mc_bottomorder = explode( ',', $below );
1108
  }
1109
  foreach ( $mc_bottomorder as $value ) {
1110
- if ( $value != 'none' && $value != 'stop' ) {
1111
  $value = trim( $value );
1112
  $mc_bottomnav .= @${$value};
1113
  }
@@ -1129,7 +1283,6 @@ function my_calendar( $name, $format, $category, $time = 'month', $ltype = '', $
1129
  } else {
1130
  $holidays = my_calendar_grab_events( $from, $to, get_option( 'mc_skip_holidays_category' ), $ltype, $lvalue, 'calendar', $author, $host, 'holidays' );
1131
  }
1132
- //echo "<pre>".print_r($events,1)."</pre>";
1133
  $events_class = mc_events_class( $events, $from );
1134
  $dateclass = mc_dateclass( time() + $offset, mktime( 0, 0, 0, $c_month, $c_day, $c_year ) );
1135
  $mc_events = '';
@@ -1145,7 +1298,7 @@ function my_calendar( $name, $format, $category, $time = 'month', $ltype = '', $
1145
  $heading_level = apply_filters( 'mc_heading_level', 'h3', $format, $time, $template );
1146
  $my_calendar_body .= "
1147
  <$heading_level class='mc-single'>" . date_i18n( apply_filters( 'mc_date_format', $date_format, 'grid' ), strtotime( "$c_year-$c_month-$c_day" ) ) . "</$heading_level>" . '
1148
- <div id="mc-day" class="' . $dayclass . ' ' . $dateclass . ' ' . $events_class . '">' . "$mc_events\n</div>
1149
  </div>";
1150
  } else {
1151
  // if showing multiple months, figure out how far we're going.
@@ -1164,11 +1317,13 @@ function my_calendar( $name, $format, $category, $time = 'month', $ltype = '', $
1164
  $caption_text = ' ' . stripslashes( trim( get_option( 'mc_caption' ) ) ); // this option should be replaced JCD TODO
1165
  $my_calendar_body .= $mc_topnav;
1166
  if ( $format == "calendar" || $format == "mini" ) {
1167
- $my_calendar_body .= "\n<table class=\"my-calendar-table\">\n";
 
1168
  $week_template = ( get_option( 'mc_week_caption' ) != '' ) ? get_option( 'mc_week_caption' ) : 'Week of {date format="M jS"}';
1169
  $week_caption = jd_draw_template( $values, stripslashes( $week_template ) );
1170
  $caption_heading = ( $time != 'week' ) ? $current_date_header . $caption_text : $week_caption . $caption_text;
1171
- $my_calendar_body .= "<caption class=\"heading my-calendar-$time\">" . $caption_heading . "</caption>\n";
 
1172
  } else {
1173
  // determine which header text to show depending on number of months displayed;
1174
  if ( $time != 'week' && $time != 'day' ) {
@@ -1187,12 +1342,15 @@ function my_calendar( $name, $format, $category, $time = 'month', $ltype = '', $
1187
  'month+1'
1188
  ) )
1189
  ) {
 
 
 
1190
  // If in a calendar format, print the headings of the days of the week
1191
  if ( $format == "list" ) {
1192
- $list_id = ( $id == 'jd-calendar' ) ? 'calendar-list' : "list-$id";
1193
- $my_calendar_body .= "<ul id='$list_id' class='mc-list'>";
1194
  } else {
1195
- $my_calendar_body .= "<thead>\n<tr>\n";
 
1196
  for ( $i = 0; $i <= 6; $i ++ ) {
1197
  if ( $start_of_week == 0 ) {
1198
  $class = ( $i < 6 && $i > 0 ) ? 'day-heading' : 'weekend-heading';
@@ -1201,10 +1359,11 @@ function my_calendar( $name, $format, $category, $time = 'month', $ltype = '', $
1201
  }
1202
  $dayclass = strtolower( strip_tags( $abbrevs[ $i ] ) );
1203
  if ( ( $class == 'weekend-heading' && get_option( 'mc_show_weekends' ) == 'true' ) || $class != 'weekend-heading' ) {
1204
- $my_calendar_body .= "<th scope='col' class='$class $dayclass'>" . $name_days[ $i ] . "</th>\n";
1205
  }
1206
  }
1207
- $my_calendar_body .= "\n</tr>\n</thead>\n<tbody>";
 
1208
  }
1209
  $odd = 'odd';
1210
  // get and display all the events
@@ -1212,7 +1371,7 @@ function my_calendar( $name, $format, $category, $time = 'month', $ltype = '', $
1212
  if ( $no_events && $format == "list" && $show_all == false ) {
1213
  // if there are no events in list format, just display that info.
1214
  $no_events = ( $content == '' ) ? __( 'There are no events scheduled during this period.', 'my-calendar' ) : $content;
1215
- $my_calendar_body .= "<li class='no-events'>$no_events</li>";
1216
  } else {
1217
  $start = strtotime( $from );
1218
  $end = strtotime( $to );
@@ -1221,7 +1380,7 @@ function my_calendar( $name, $format, $category, $time = 'month', $ltype = '', $
1221
  $is_weekend = ( date( 'N', $start ) < 6 ) ? false : true;
1222
  if ( get_option( 'mc_show_weekends' ) == 'true' || ( get_option( 'mc_show_weekends' ) != 'true' && ! $is_weekend ) ) {
1223
  if ( date( 'N', $start ) == $start_of_week && $format != "list" ) {
1224
- $my_calendar_body .= "<tr>";
1225
  }
1226
  // date-based classes
1227
  $monthclass = ( date( 'n', $start ) == $c_month || $time != 'month' ) ? '' : 'nextmonth';
@@ -1238,6 +1397,7 @@ function my_calendar( $name, $format, $category, $time = 'month', $ltype = '', $
1238
  } else {
1239
  $is_anchor = $is_close_anchor = "";
1240
  }
 
1241
  if ( ! empty( $events ) ) {
1242
  $event_output = my_calendar_draw_events( $events, $format, $date, $time, $template );
1243
  if ( $event_output === true ) {
@@ -1299,14 +1459,14 @@ function my_calendar( $name, $format, $category, $time = 'month', $ltype = '', $
1299
  $weekend_class = ( $is_weekend ) ? 'weekend' : '';
1300
  if ( $format == "list" ) {
1301
  if ( get_option( 'mc_show_list_info' ) == 'true' ) {
1302
- $title = ' - ' . $is_anchor . mc_list_title( $events ) . $is_close_anchor;
1303
  } else {
1304
  $title = '';
1305
  }
1306
  //if ( $monthclass != 'nextmonth' ) { // only show current month in list view.
1307
  if ( $event_output != '' ) {
1308
  $my_calendar_body .= "
1309
- <li id='$format-$date' class='mc-events $dayclass $dateclass $events_class $odd'>
1310
  <strong class=\"event-date\">$is_anchor" . date_i18n( apply_filters( 'mc_date_format', $date_format, 'list' ), $start ) . "$is_close_anchor" . "$title</strong>" .
1311
  $event_output . "
1312
  </li>";
@@ -1315,10 +1475,10 @@ function my_calendar( $name, $format, $category, $time = 'month', $ltype = '', $
1315
  //}
1316
  } else {
1317
  $my_calendar_body .= "
1318
- <td id='$format-$date' class='$dayclass $dateclass $weekend_class $monthclass $events_class day-with-date'>" . "
1319
- <$element class='mc-date $trigger'>$thisday_heading</$close>" .
1320
  $event_output . "
1321
- </td>\n";
1322
  }
1323
  }
1324
  } else {
@@ -1326,9 +1486,9 @@ function my_calendar( $name, $format, $category, $time = 'month', $ltype = '', $
1326
  if ( $format != "list" ) {
1327
  $weekend_class = ( $is_weekend ) ? 'weekend' : '';
1328
  $my_calendar_body .= "
1329
- <td class='no-events $dayclass $dateclass $weekend_class $monthclass day-with-date'>
1330
- <span class='mc-date no-events'>$thisday_heading</span>
1331
- </td>\n";
1332
  } else {
1333
  if ( $show_all == true ) {
1334
  $my_calendar_body .= "
@@ -1340,14 +1500,16 @@ function my_calendar( $name, $format, $category, $time = 'month', $ltype = '', $
1340
  }
1341
 
1342
  if ( date( 'N', $start ) == $end_of_week && $format != "list" ) {
1343
- $my_calendar_body .= "</tr>\n"; // end of 'is beginning of week'
1344
  }
1345
  }
1346
  $start = strtotime( "+1 day", $start );
1347
 
1348
  } while ( $start <= $end );
1349
  }
1350
- $my_calendar_body .= ( $format == "list" ) ? "\n</ul>" : "\n</tbody>\n</table>";
 
 
1351
  } else {
1352
  if ( ! in_array( $format, array( 'list', 'calendar', 'mini' ) ) ) {
1353
  $my_calendar_body .= "<p class='mc-error-format'>" . __( "Unrecognized calendar format. Please use one of 'list', 'calendar', or 'mini'.", 'my-calendar' ) . "</p>";
@@ -1365,6 +1527,15 @@ function my_calendar( $name, $format, $category, $time = 'month', $ltype = '', $
1365
  return $mc_wrapper . apply_filters( 'my_calendar_body', $my_calendar_body ) . $mc_closer;
1366
  }
1367
 
 
 
 
 
 
 
 
 
 
1368
  function my_category_key( $category ) {
1369
  global $wpdb;
1370
  $url = plugin_dir_url( __FILE__ );
@@ -1720,7 +1891,7 @@ function mc_access_list( $show = 'list', $group = 'single' ) {
1720
  $output .= " <li$selected><a rel='nofollow' href='$this_url'>$access_name</a></li>";
1721
  } else {
1722
  $selected = ( $this_access == $key ) ? ' selected="selected"' : '';
1723
- $output .= " <option$selected value='$key'>$access_name</option>\n";
1724
  }
1725
  }
1726
  $output .= ( $show == 'list' ) ? '</ul>' : '</select>';
@@ -1853,7 +2024,7 @@ function my_calendar_show_locations( $datatype = 'name', $template = '' ) {
1853
  }
1854
 
1855
  function my_calendar_searchform( $type, $url ) {
1856
- $query = ( isset( $_GET['mcs'] ) ) ? esc_attr( $_GET['mcs'] ) : '';
1857
  if ( $type == 'simple' ) {
1858
  if ( !$url || $url == '' ) {
1859
  $url = ( get_option( 'mc_uri' ) != '' ) ? get_option( 'mc_uri' ) : home_url();
@@ -1862,7 +2033,7 @@ function my_calendar_searchform( $type, $url ) {
1862
  <form role="search" method="get" action="' . apply_filters( 'mc_search_page', esc_url( $url ) ) . '" >
1863
  <div class="mc-search">
1864
  <label class="screen-reader-text" for="mcs">' . __( 'Search Events', 'my-calendar' ) . '</label>
1865
- <input type="text" value="' . stripslashes( $query ) . '" name="mcs" id="mcs" />
1866
  <input type="submit" id="searchsubmit" value="' . __( 'Search Events', 'my-calendar' ) . '" />
1867
  </div>
1868
  </form>';
@@ -1921,14 +2092,14 @@ function my_calendar_locations_list( $show = 'list', $type = 'saved', $datatype
1921
  if ( $show == 'list' ) {
1922
  $url = mc_build_url( array( 'loc' => 'all', 'ltype' => 'all' ), array() );
1923
  $output .= "<ul id='mc-locations-list'>
1924
- <li><a href='$url'>" . __( 'Show all', 'my-calendar' ) . "</a></li>\n";
1925
  } else {
1926
  $ltype = ( ! isset( $_GET['ltype'] ) ) ? $datatype : $_GET['ltype'];
1927
  $output .= "<div id='mc_locations'>";
1928
  $output .= ( $group == 'single' ) ? "
1929
  <form action='" . $current_url . "' method='get'>
1930
  <div>" : '';
1931
- $output .= "<input type='hidden' name='ltype' value='$ltype' />";
1932
  if ( $group == 'single' ) {
1933
  $qsa = array();
1934
  parse_str( $_SERVER['QUERY_STRING'], $qsa );
@@ -1968,7 +2139,7 @@ function my_calendar_locations_list( $show = 'list', $type = 'saved', $datatype
1968
  } else {
1969
  $selected = ( $vt == $loc ) ? " selected='selected'" : '';
1970
  if ( $value != '' ) {
1971
- $output .= " <option value='$vt'$selected>$value</option>\n";
1972
  }
1973
  }
1974
  }
@@ -1984,7 +2155,7 @@ function my_calendar_locations_list( $show = 'list', $type = 'saved', $datatype
1984
  $output .= " <li$selected><a rel='nofollow' href='$this_url'>$location</a></li>\n";
1985
  } else {
1986
  $selected = ( $vk == $_GET['loc'] ) ? " selected='selected'" : '';
1987
- $output .= " <option value='$vk'$selected>$location</option>\n";
1988
  }
1989
  }
1990
  }
109
  }
110
  } else {
111
  $time .= "<span class='event-time'>";
112
+ $notime = mc_notime_label( $event );
113
+ if ( $notime == "N/A" ) {
114
  $time .= "<abbr title='" . __( 'Not Applicable', 'my-calendar' ) . "'>" . __( 'N/A', 'my-calendar' ) . "</abbr>\n";
115
  } else {
116
+ $time .= $notime;
117
  }
118
  $time .= "</span></p>";
119
  }
121
  $time .= "
122
  </div>";
123
 
124
+ return apply_filters( 'mcs_time_block', $time, $event );
125
  }
126
 
127
  function mc_category_icon( $event, $html = 'html' ) {
128
+ if ( is_object( $event ) ) {
129
+ $url = plugin_dir_url( __FILE__ );
130
+ $image = '';
131
+ if ( get_option( 'mc_hide_icons' ) != 'true' ) {
132
+ if ( $event->category_icon != '' ) {
133
+ $path = ( is_custom_icon() ) ? str_replace( 'my-calendar', 'my-calendar-custom', $url ) : plugins_url( 'images/icons', __FILE__ ) . '/';
134
+ $hex = ( strpos( $event->category_color, '#' ) !== 0 ) ? '#' : '';
135
+ if ( $html == 'html' ) {
136
+ $image = '<img src="' . $path . $event->category_icon . '" alt="' . __( 'Category', 'my-calendar' ) . ': ' . esc_attr( $event->category_name ) . '" class="category-icon" style="background:' . $hex . $event->category_color . '" />';
137
+ } else {
138
+ $image = $path . $event->category_icon;
139
+ }
140
  }
141
  }
 
142
 
143
+ return $image;
144
+ }
145
  }
146
 
147
+ add_filter( 'the_title', 'mc_category_icon_title', 10, 2 );
148
+ function mc_category_icon_title( $title, $post_id = null ) {
149
  if ( is_singular( 'mc-events' ) && in_the_loop() ) {
150
+ if ( $post_id ) {
151
+ $event_id = ( isset( $_GET['mc_id'] ) && is_numeric( $_GET['mc_id'] ) ) ? $_GET['mc_id'] : get_post_meta( $post_id, '_mc_event_id', true );
152
+ $event = mc_get_event_core( $event_id );
153
+ $icon = mc_category_icon( $event );
154
+ $title = $icon . ' ' . $title;
155
+ }
156
  }
157
 
158
  return $title;
223
  $has_image = ( $image != '' ) ? ' has-image' : '';
224
  $header .= "<div id='$uid-$day_id-$type' class='mc-$uid $type-event " . "mc_" . sanitize_title( $event->category_name ) . " vevent'>\n";
225
 
226
+ switch ( $type ) {
227
+ case 'calendar' : $title_template = ( $templates['title'] == '' ) ? '{title}' : $templates['title']; break;
228
+ case 'list' : $title_template = ( $templates['title_list'] == '' ) ? '{title}' : $templates['title_list']; break;
229
+ case 'single' : $title_template = ( $templates['title_solo'] == '' ) ? '{title}' : $templates['title_solo']; break;
230
+ default: $title_template = ( $templates['title'] == '' ) ? '{title}' : $templates['title'];
231
+ }
232
+
233
  $event_title = jd_draw_template( $data, $title_template );
234
  $event_title = ( $event_title == '' ) ? jd_draw_template( $data, '{title}' ) : $event_title; //prevent empty titles
235
 
254
  $title = ( $type == 'single' && ! is_singular( 'mc-events' ) ) ? "<h2 class='event-title summary'>$image $event_title</h2>\n" : '';
255
  $title = apply_filters( 'mc_event_title', $title, $event, $event_title, $image );
256
  $header .= $title;
257
+ $close_image = apply_filters( 'mc_close_button', "<img src=\"" . plugin_dir_url( __FILE__ ) . "images/event-close.png\" alt='" . __( 'Close', 'my-calendar' ) . "' />" );
258
+ $close_button = "<button aria-controls='$uid-$day_id-$type-details' class='mc-toggle close'>$close_image</button>";
259
+
260
  if ( mc_show_details( $time, $type ) ) {
261
+ $close = ( $type == 'calendar' || $type == 'mini' ) ? $close_button : '';
262
 
263
  if ( $details === false ) {
264
  // put together address information as vcard
315
  $image = ( $event->event_image != '' ) ? "<img src='$event->event_image' alt='' class='mc-image photo' />" : '';
316
  }
317
  if ( get_option( 'mc_desc' ) == 'true' || $type == 'single' ) {
318
+ $description = wpautop( stripcslashes( $event->event_desc ), 1 );
319
  $description = "<div class='longdesc'>$description</div>";
320
  }
321
  if ( get_option( 'mc_short' ) == 'true' && $type != 'single' ) {
322
+ $short = wpautop( stripcslashes( $event->event_short ), 1 );
323
  $short = "<div class='shortdesc'>$short</div>";
324
  }
325
 
350
  }
351
 
352
  if ( get_option( 'mc_gmap' ) == 'true' ) {
353
+ $map = ( is_singular( 'mc-events' ) || $type == 'single' ) ? mc_generate_map( $event ) : '';
354
  } else {
355
  $map = '';
356
  }
384
  . $return;
385
  } else {
386
  // if a custom template is in use
387
+ $toggle = ( $type == 'calendar' || $type == 'mini' ) ? $close_button : '';
388
  $details = $toggle . $details . "\n";
389
  }
390
  $img_class = ( $image != '' ) ? ' has-image' : ' no-image';
396
  $details .= "</div><!--ends .details--></div>";
397
  $details = apply_filters( 'mc_event_content', $details, $event, $type, $time );
398
  } else {
399
+ $details = apply_filters( 'mc_before_event', $container, $event, $type, $time )
400
+ . $header
401
+ . apply_filters( 'mc_after_event', '', $event, $type, $time )
402
+ . "</div>";
403
  }
404
 
405
  return $details;
435
  return $html . $edit;
436
  }
437
 
438
+ function mc_build_date_switcher( $type = 'calendar', $cid = 'all', $time = 'month' ) {
439
  global $wpdb;
440
  $mcdb = $wpdb;
441
  if ( get_option( 'mc_remote' ) == 'true' && function_exists( 'mc_remote_db' ) ) {
448
  $qsa = array();
449
  parse_str( $_SERVER['QUERY_STRING'], $qsa );
450
  if ( ! isset( $_GET['cid'] ) ) {
451
+ $date_switcher .= '<input type="hidden" name="cid" value="' . esc_attr( $cid ) . '" />';
452
  }
453
  foreach ( $qsa as $name => $argument ) {
454
  $name = esc_attr( strip_tags( $name ) );
457
  $date_switcher .= '<input type="hidden" name="' . $name . '" value="' . $argument . '" />';
458
  }
459
  }
460
+ $day_switcher = '';
461
+ if ( $time == 'day' ) {
462
+ $day_switcher = '
463
+ <label class="maybe-hide" for="' . $cid . '-day">' . __( 'Month', 'my-calendar' ) . ':</label> <select id="' . $cid . '-day" name="dy">' . "\n";
464
+ for ( $i = 1; $i <= 31; $i++ ) {
465
+ $day_switcher .= "<option value='$i'" . mc_day_comparison( $i ) . '>' . $i . '</option>' . "\n";
466
+ }
467
+ $day_switcher .= '</select>';
468
+ }
469
  // We build the months in the switcher
470
  $date_switcher .= '
471
+ <label class="maybe-hide" for="' . $cid . '-month">' . __( 'Month', 'my-calendar' ) . ':</label> <select id="' . $cid . '-month" name="month">' . "\n";
472
  for ( $i = 1; $i <= 12; $i ++ ) {
473
  $date_switcher .= "<option value='$i'" . mc_month_comparison( $i ) . '>' . date_i18n( 'F', mktime( 0, 0, 0, $i, 1 ) ) . '</option>' . "\n";
474
  }
475
  $date_switcher .= '</select>' . "\n" . '
476
+ <label class="maybe-hide" for="' . $cid . '-year">' . __( 'Year', 'my-calendar' ) . ':</label> <select id="' . $cid . '-year" name="yr">' . "\n";
477
  // query to identify oldest start date in the database
478
  $query = "SELECT event_begin FROM " . MY_CALENDAR_TABLE . " WHERE event_approved = 1 AND event_flagged <> 1 ORDER BY event_begin ASC LIMIT 0 , 1";
479
  $year1 = date( 'Y', strtotime( $mcdb->get_var( $query ) ) );
501
  $date_switcher .= $p;
502
  $date_switcher .= '<option value="' . date( "Y", time() + ( $offset ) ) . '"' . mc_year_comparison( date( "Y", time() + ( $offset ) ) ) . '>' . date( "Y", time() + ( $offset ) ) . "</option>\n";
503
  $date_switcher .= $f;
504
+ $date_switcher .= '</select> ' . $day_switcher . '<input type="submit" class="button" value="' . __( 'Go', 'my-calendar' ) . '" /></div>
505
  </form></div>';
506
  $date_switcher = apply_filters( 'mc_jumpbox', $date_switcher );
507
 
517
  header( 'Content-Type: ' . get_bloginfo( 'html_type' ) . '; charset=' . get_bloginfo( 'charset' ) );
518
  echo '<!DOCTYPE html>
519
  <!--[if IE 7]>
520
+ <html id="ie7" dir="' . ( is_rtl() ) ? 'rtl' : 'ltr' . '" lang="' . get_bloginfo( 'language' ) . '">
521
  <![endif]-->
522
  <!--[if IE 8]>
523
+ <html id="ie8" dir="' . ( is_rtl() ) ? 'rtl' : 'ltr' . '" lang="' . get_bloginfo( 'language' ) . '">
524
  <![endif]-->
525
  <!--[if !(IE 6) | !(IE 7) | !(IE 8) ]><!-->
526
+ <html dir="' . ( is_rtl() ) ? 'rtl' : 'ltr' . '" lang="' . get_bloginfo( 'language' ) . '">
527
  <!--<![endif]-->
528
  <head>
529
  <meta charset="' . get_bloginfo( 'charset' ) . '" />
541
  <link rel='stylesheet' href='$stylesheet' type='text/css' media='screen,print' />
542
  </head>
543
  <body>\n";
544
+ echo my_calendar( 'print', 'calendar', $category, $time, $ltype, $lvalue, 'mc-print-view', '', '', null, null, 'none', 'none' );
545
  $return_url = ( get_option( 'mc_uri' ) != '' && ! is_numeric( get_option( 'mc_uri' ) ) ) ? get_option( 'mc_uri' ) : home_url();
546
  $add = $_GET;
547
  unset( $add['cid'] );
693
  } else {
694
  $cstate = sprintf( __( " and %d other events", 'my-calendar' ), $count );
695
  }
696
+ $title = apply_filters( 'mc_list_event_title_hint', stripcslashes( $now->event_title ), $now ) . "<span class='mc-list-extended'>$cstate</span>";
697
 
698
  return $title;
699
  }
700
 
701
  function mc_search_results( $query ) {
702
+ $before = apply_filters( 'mc_past_search_results', 0, 'basic' );
703
+ $after = apply_filters( 'mc_future_search_results', 10, 'basic' ); // return only future events, nearest 10
704
  if ( is_string( $query ) ) {
705
+ $fields = apply_filters( 'mc_search_fields', 'event_title,event_desc,event_short,event_label,event_city,event_postcode,event_registration' );
706
+ $search = " MATCH( $fields ) AGAINST ('$query' IN BOOLEAN MODE) AND ";
707
+ $term = $query;
708
  } else {
709
+ $search = apply_filters( 'mc_advanced_search', '', $query );
710
+ $term = $query['mcs'];
711
+ $before = apply_filters( 'mc_past_search_results', 10, 'advanced' );
712
+ $after = apply_filters( 'mc_future_search_results', 10, 'advanced' );
 
 
 
 
 
 
 
 
 
 
713
  }
714
+
715
+ $event_array = mc_get_search_results( $search );
716
+ //$event_array = mc_flatten_array( $event_array );
717
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
718
  if ( ! empty( $event_array ) ) {
719
  $template = '<strong>{date}</strong> {title} {details}';
720
  $template = apply_filters( 'mc_search_template', $template );
723
  } else {
724
  $output = "<li class='no-results'>" . __( 'Sorry, your search produced no results.', 'my-calendar' ) . "</li>";
725
  }
726
+
727
+ $before = apply_filters( 'mc_search_before', '', $term );
728
+ $after = apply_filters( 'mc_search_after', '', $term );
729
 
730
+ return "$before<ol class='mc-search-results'>$output</ol>$after";
731
+ }
732
+
733
+ function mc_flatten_array( $events ) {
734
+ $new_array = array();
735
+ if ( is_array( $events ) ) {
736
+ foreach( $events as $event ) {
737
+ foreach( $event as $e ) {
738
+ $new_array[] = $e;
739
+ }
740
+ }
741
+ }
742
+
743
+ return $new_array;
744
+ }
745
+
746
+ function mc_get_search_results( $search ) {
747
+ global $wpdb;
748
+ $mcdb = $wpdb;
749
+ if ( get_option( 'mc_remote' ) == 'true' && function_exists( 'mc_remote_db' ) ) {
750
+ $mcdb = mc_remote_db();
751
+ }
752
+ $before = apply_filters( 'mc_past_search_results', 0 );
753
+ $after = apply_filters( 'mc_future_search_results', 15 ); // return only future events, nearest 10
754
+ if ( is_array( $search ) ) {
755
+ // if from & to are set, we need to use an alternate search query
756
+ $from = $search['from'];
757
+ $to = $search['to'];
758
+ $category = ( isset( $search['category'] ) ) ? $search['category'] : null;
759
+ $ltype = ( isset( $search['ltype'] ) ) ? $search['ltype'] : null;
760
+ $lvalue = ( isset( $search['lvalue'] ) ) ? $search['lvalue'] : null;
761
+ $author = ( isset( $search['author'] ) ) ? $search['author'] : null;
762
+ $host = ( isset( $search['host'] ) ) ? $search['host'] : null;
763
+ $search = ( isset( $search['search'] ) ) ? $search['search'] : '';
764
+
765
+ $event_array = my_calendar_events( $from, $to, $category, $ltype, $lvalue, 'search', $author, $host, $search );
766
+ } else {
767
+ $date = date( 'Y', current_time( 'timestamp' ) ) . '-' . date( 'm', current_time( 'timestamp' ) ) . '-' . date( 'd', current_time( 'timestamp' ) );
768
+ // if a value is non-zero, I'll grab a handful of extra events so I can throw out holidays and others like that.
769
+ if ( $before > 0 ) {
770
+ $before = $before + 5;
771
+ $events1 = $mcdb->get_results( "SELECT *, UNIX_TIMESTAMP(occur_begin) AS ts_occur_begin, UNIX_TIMESTAMP(occur_end) AS ts_occur_end
772
+ FROM " . MY_CALENDAR_EVENTS_TABLE . "
773
+ JOIN " . MY_CALENDAR_TABLE . "
774
+ ON (event_id=occur_event_id)
775
+ JOIN " . MY_CALENDAR_CATEGORIES_TABLE . "
776
+ ON (event_category=category_id) WHERE $search event_approved = 1 AND event_flagged <> 1
777
+ AND DATE(occur_begin) < '$date' ORDER BY occur_begin DESC LIMIT 0,$before" );
778
+ } else {
779
+ $events1 = array();
780
+ }
781
+ $events3 = $mcdb->get_results( "SELECT *, UNIX_TIMESTAMP(occur_begin) AS ts_occur_begin, UNIX_TIMESTAMP(occur_end) AS ts_occur_end
782
+ FROM " . MY_CALENDAR_EVENTS_TABLE . "
783
+ JOIN " . MY_CALENDAR_TABLE . "
784
+ ON (event_id=occur_event_id)
785
+ JOIN " . MY_CALENDAR_CATEGORIES_TABLE . "
786
+ ON (event_category=category_id) WHERE $search event_approved = 1 AND event_flagged <> 1
787
+ AND DATE(occur_begin) = '$date'" );
788
+ if ( $after > 0 ) {
789
+ $after = $after + 5;
790
+ $events2 = $mcdb->get_results( "SELECT *, UNIX_TIMESTAMP(occur_begin) AS ts_occur_begin, UNIX_TIMESTAMP(occur_end) AS ts_occur_end
791
+ FROM " . MY_CALENDAR_EVENTS_TABLE . "
792
+ JOIN " . MY_CALENDAR_TABLE . "
793
+ ON (event_id=occur_event_id)
794
+ JOIN " . MY_CALENDAR_CATEGORIES_TABLE . "
795
+ ON (event_category=category_id) WHERE $search event_approved = 1 AND event_flagged <> 1
796
+ AND DATE(occur_begin) > '$date' ORDER BY occur_begin ASC LIMIT 0,$after" );
797
+ } else {
798
+ $events2 = array();
799
+ }
800
+ $arr_events = array();
801
+ if ( ! empty( $events1 ) || ! empty( $events2 ) || ! empty( $events3 ) ) {
802
+ $arr_events = array_merge( $events1, $events3, $events2 );
803
+ }
804
+ if ( ! get_option( 'mc_skip_holidays_category' ) || get_option( 'mc_skip_holidays_category' ) == '' ) {
805
+ $holidays = array();
806
+ } else {
807
+ $holidays = mc_get_all_holidays( $before, $after, 'yes' );
808
+ $holiday_array = mc_set_date_array( $holidays );
809
+ }
810
+ if ( is_array( $arr_events ) && ! empty( $arr_events ) ) {
811
+ $no_events = false;
812
+ $event_array = mc_set_date_array( $arr_events );
813
+ if ( is_array( $holidays ) && count( $holidays ) > 0 ) {
814
+ $event_array = mc_holiday_limit( $event_array, $holiday_array ); // if there are holidays, rejigger.
815
+ }
816
+ }
817
+ }
818
+
819
+ return $event_array;
820
  }
821
 
822
  add_filter( 'the_title', 'mc_search_results_title', 10, 2 );
823
  function mc_search_results_title( $title, $id = false ) {
824
+ if ( ( isset( $_GET['mcs'] ) || isset( $_POST['mcs'] ) ) && ( is_page( $id ) || is_single( $id ) ) && in_the_loop() ) {
825
+ $query = ( isset( $_GET['mcs'] ) ) ? $_GET['mcs'] : $_POST['mcs'];
826
+ $title = sprintf( __( 'Events Search for &ldquo;%s&rdquo;', 'my-calendar' ), esc_html( $query ) );
827
  }
828
 
829
  return $title;
848
  }
849
  }
850
 
851
+ add_action( 'template_redirect', 'mc_hidden_event' );
852
+ function mc_hidden_event() {
853
+ $do_redirect = false;
854
+ if ( isset( $_GET['mc_id'] ) ) {
855
+ $mc_id = intval( $_GET['mc_id'] );
856
+ $event = mc_get_event( $mc_id, 'object' );
857
+ if ( mc_event_is_hidden( $event ) ) {
858
+ $do_redirect = true;
859
+ }
860
+ } else {
861
+ global $wp_query;
862
+ $slug = $wp_query->query_vars['name'];
863
+ $status = get_page_by_path( $slug, OBJECT, 'mc-events' );
864
+ if ( $status ) {
865
+ $post = $status;
866
+ } else {
867
+ return;
868
+ }
869
+ if ( is_object( $post ) && $post->post_type == 'mc-events' ) {
870
+ $event_id = get_post_meta( $post->ID, '_mc_event_id', true );
871
+ $event = mc_get_first_event( $event_id );
872
+ if ( mc_event_is_hidden( $event ) ) {
873
+ $do_redirect = true;
874
+ }
875
+ }
876
+ }
877
+ if ( $do_redirect ) {
878
+ $id = get_option( 'mc_uri_id' );
879
+ $uri = get_option( 'mc_uri' );
880
+ if ( $id ) {
881
+ $uri = get_permalink( $id );
882
+ }
883
+ wp_safe_redirect( $uri );
884
+ }
885
+ }
886
+
887
+ add_filter( 'the_content', 'mc_show_event_template', 100, 1 );
888
  function mc_show_event_template( $content ) {
889
  global $post;
890
+ if ( is_object( $post ) && in_the_loop() ) {
891
+ // some early versions of this placed the shortcode into the post content. Strip that out.
892
+ $new_content = $content;
893
+ if ( $post->post_type == 'mc-events' ) {
894
+ if ( isset( $_GET['mc_id'] ) ) {
895
+ $mc_id = intval( $_GET['mc_id'] );
896
+ $event = mc_get_event( $mc_id, 'object' );
897
+ $date = date( 'Y-m-d', strtotime( $event->occur_begin ) );
898
+ $time = date( 'H:i:00', strtotime( $event->occur_begin ) );
899
+ } else {
900
+ $event_id = get_post_meta( $post->ID, '_mc_event_id', true );
901
+ $event = mc_get_first_event( $event_id );
902
+ $date = $event->event_begin;
903
+ $time = $event->event_time;
904
+ }
905
+ if ( mc_event_is_hidden( $event ) ) {
906
+ return $content;
907
+ }
908
+ if ( get_option( 'mc_use_details_template' ) == 1 ) {
909
+ $new_content = apply_filters( 'mc_before_event', '', $event, 'single', $time );
910
+ $new_content .= do_shortcode( apply_filters( 'mc_single_event_shortcode', get_post_meta( $post->ID, '_mc_event_shortcode', true ) ) );
911
+ $new_content .= apply_filters( 'mc_after_event', '', $event, 'single', $time );
912
+ } else {
913
+ $new_content = my_calendar_draw_event( $event, 'single', $date, $time, '' );
914
+ }
915
+
916
+ $content = do_shortcode( apply_filters( 'mc_event_post_content', $new_content, $content, $post ) );
917
+ }
918
  }
919
+
920
+ return $content;
921
+ }
922
 
923
+ function mc_event_is_hidden( $event ) {
924
+ $category = $event->event_category;
925
+ $private = mc_get_private_categories();
926
+ if ( in_array( $category, $private ) && !is_user_logged_in() ) {
927
+ return true;
928
+ }
929
+
930
+ return false;
931
  }
932
 
933
  // Actually do the printing of the calendar
934
+ function my_calendar( $name, $format, $category, $time = 'month', $ltype = '', $lvalue = '', $id = '', $template = '', $content = '', $author = null, $host = null, $above = '', $below = '', $syear = false, $smonth = false, $sday = false ) {
935
  check_my_calendar();
936
  // category key needs to receive the original category settings.
937
  $original_category = $category;
947
  }
948
  $used = array_merge( $aboves, $belows );
949
 
950
+ if ( isset( $_GET['format'] ) && in_array( $_GET['format'], array( 'list', 'mini' ) ) && $format != 'mini' ) {
951
  $format = esc_attr( $_GET['format'] );
952
  } else {
953
  $format = esc_attr( $format );
981
  'ltype' => $ltype,
982
  'lvalue' => $lvalue,
983
  'author' => $author,
984
+ 'id' => $id,
985
+ 'above' => $above,
986
+ 'below' => $below,
987
+ 'host' => $host,
988
+ 'syear' => $syear,
989
+ 'smonth' => $smonth,
990
+ 'sday' => $sday
991
  );
992
+ $hash = md5( implode( ',', $args ) );
993
  $my_calendar_body .= apply_filters( 'mc_before_calendar', '', $args );
994
+ $id = ( !$id ) ? "mc-$hash" : $id;
995
 
996
+ $main_class = ( $id != '' ) ? sanitize_title( $id ) : 'all';
997
  $cid = ( isset( $_GET['cid'] ) ) ? esc_attr( strip_tags( $_GET['cid'] ) ) : $main_class;
998
 
999
+ if ( get_option( 'mc_convert' ) == 'true' ) {
1000
+ $format = ( mc_is_mobile() && $format == 'calendar' ) ? 'list' : $format;
1001
+ } else if ( get_option( 'mc_convert' ) == 'mini' ) {
1002
+ $format = ( mc_is_mobile() ) ? 'mini' : $format;
1003
+ }
1004
+ $format = apply_filters( 'mc_display_format', $format, $args );
1005
+
1006
  // mc body wrapper
1007
  $mc_wrapper = "<div id=\"$id\" class=\"mc-main $format $time $main_class\" aria-live='assertive' aria-atomic='true'>";
1008
  $mc_closer = "</div>";
1009
 
 
 
 
 
1010
  $date_format = ( get_option( 'mc_date_format' ) != '' ) ? get_option( 'mc_date_format' ) : get_option( 'date_format' );
1011
 
1012
  if ( isset( $_GET['mc_id'] ) && $format != 'mini' ) {
1013
  // single event, main calendar only.
1014
+ $mc_id = ( is_numeric( $_GET['mc_id'] ) ) ? $_GET['mc_id'] : false;
1015
+ if ( $mc_id ) {
1016
+ $my_calendar_body .= mc_get_event( $mc_id, 'html' );
1017
+ }
1018
  } else {
1019
  if ( $category == "" ) {
1020
  $category = 'all';
1021
  }
1022
  // Deal with the week not starting on a monday
1023
  $name_days = array(
1024
+ "<abbr title='" . date_i18n( 'l', strtotime( 'Sunday' ) ) . "' aria-hidden='true'>" . date_i18n( 'D', strtotime( 'Sunday' ) ) . "</abbr><span class='screen-reader-text'>" . date_i18n( 'l', strtotime( 'Sunday' ) ) . "</span>",
1025
+ "<abbr title='" . date_i18n( 'l', strtotime( 'Monday' ) ) . "' aria-hidden='true'>" . date_i18n( 'D', strtotime( 'Monday' ) ) . "</abbr><span class='screen-reader-text'>" . date_i18n( 'l', strtotime( 'Monday' ) ) . "</span>",
1026
+ "<abbr title='" . date_i18n( 'l', strtotime( 'Tuesday' ) ) . "' aria-hidden='true'>" . date_i18n( 'D', strtotime( 'Tuesday' ) ) . "</abbr><span class='screen-reader-text'>" . date_i18n( 'l', strtotime( 'Tuesday' ) ) . "</span>",
1027
+ "<abbr title='" . date_i18n( 'l', strtotime( 'Wednesday' ) ) . "' aria-hidden='true'>" . date_i18n( 'D', strtotime( 'Wednesday' ) ) . "</abbr><span class='screen-reader-text'>" . date_i18n( 'l', strtotime( 'Wednesday' ) ) . "</span>",
1028
+ "<abbr title='" . date_i18n( 'l', strtotime( 'Thursday' ) ) . "' aria-hidden='true'>" . date_i18n( 'D', strtotime( 'Thursday' ) ) . "</abbr><span class='screen-reader-text'>" . date_i18n( 'l', strtotime( 'Thursday' ) ) . "</span>",
1029
+ "<abbr title='" . date_i18n( 'l', strtotime( 'Friday' ) ) . "' aria-hidden='true'>" . date_i18n( 'D', strtotime( 'Friday' ) ) . "</abbr><span class='screen-reader-text'>" . date_i18n( 'l', strtotime( 'Friday' ) ) . "</span>",
1030
+ "<abbr title='" . date_i18n( 'l', strtotime( 'Saturday' ) ) . "' aria-hidden='true'>" . date_i18n( 'D', strtotime( 'Saturday' ) ) . "</abbr><span class='screen-reader-text'>" . date_i18n( 'l', strtotime( 'Saturday' ) ) . "</span>"
1031
  );
1032
  $abbrevs = array( 'sun', 'mon', 'tues', 'wed', 'thur', 'fri', 'sat' );
1033
+ if ( $format == 'mini' ) {
1034
+ // PHP doesn't have a single letter abbreviation, so this has to be a translatable.
1035
  $name_days = array(
1036
+ "<span aria-hidden='true'>" . __( '<abbr title="Sunday">S</abbr>', 'my-calendar' ) . "</span><span class='screen-reader-text'>" . date_i18n( 'l', strtotime( 'Sunday' ) ) . "</span>",
1037
+ "<span aria-hidden='true'>" . __( '<abbr title="Monday">M</abbr>', 'my-calendar' ) . "</span><span class='screen-reader-text'>" . date_i18n( 'l', strtotime( 'Monday' ) ) . "</span>",
1038
+ "<span aria-hidden='true'>" . __( '<abbr title="Tuesday">T</abbr>', 'my-calendar' ) . "</span><span class='screen-reader-text'>" . date_i18n( 'l', strtotime( 'Tuesday' ) ) . "</span>",
1039
+ "<span aria-hidden='true'>" . __( '<abbr title="Wednesday">W</abbr>', 'my-calendar' ) . "</span><span class='screen-reader-text'>" . date_i18n( 'l', strtotime( 'Wednesday' ) ) . "</span>",
1040
+ "<span aria-hidden='true'>" . __( '<abbr title="Thursday">T</abbr>', 'my-calendar' ) . "</span><span class='screen-reader-text'>" . date_i18n( 'l', strtotime( 'Thursday' ) ) . "</span>",
1041
+ "<span aria-hidden='true'>" . __( '<abbr title="Friday">F</abbr>', 'my-calendar' ) . "</span><span class='screen-reader-text'>" . date_i18n( 'l', strtotime( 'Friday' ) ) . "</span>",
1042
+ "<span aria-hidden='true'>" . __( '<abbr title="Saturday">S</abbr>', 'my-calendar' ) . "</span><span class='screen-reader-text'>" . date_i18n( 'l', strtotime( 'Saturday' ) ) . "</span>"
1043
  );
1044
  }
1045
  $start_of_week = ( get_option( 'start_of_week' ) == 1 ) ? 1 : 7; // convert start of week to ISO 8601 (Monday/Sunday)
1104
  $c_day = date( "d", time() + ( $offset ) );
1105
  }
1106
  if ( ! ( isset( $_GET['yr'] ) || isset( $_GET['month'] ) || isset( $_GET['dy'] ) ) ) {
1107
+ // month/year based on shortcode
1108
+ $shortcode_month = ( $smonth != false ) ? $smonth : $c_month;
1109
+ $shortcode_year = ( $syear != false ) ? $syear : $c_year;
1110
+ $shortcode_day = ( $sday != false ) ? $sday : $c_day;
1111
+ // override with filters
1112
+ $c_year = apply_filters( 'mc_filter_year', $shortcode_year, $args );
1113
+ $c_month = apply_filters( 'mc_filter_month', $shortcode_month, $args );
1114
+ $c_day = apply_filters( 'mc_filter_day', $shortcode_day, $args );
1115
  }
1116
  $c_day = ( $c_day == 0 ) ? 1 : $c_day; // c_day can't equal 0.
1117
  $current_date = mktime( 0, 0, 0, $c_month, $c_day, $c_year );
1214
  'dy' => $nLink['day'],
1215
  'cid' => $main_class
1216
  ), array() );
1217
+ $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 );
1218
  $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 );
1219
  $nav = '
1220
  <div class="my-calendar-nav">
1224
  </div>';
1225
  }
1226
  // set up rss feeds
1227
+ if ( in_array( 'feeds', $used ) && $format != 'mini' ) {
1228
  $ical_m = ( isset( $_GET['month'] ) ) ? (int) $_GET['month'] : date( 'n' );
1229
  $ical_y = ( isset( $_GET['yr'] ) ) ? (int) $_GET['yr'] : date( 'Y' );
1230
+ if ( !isset( $nLink ) ) {
1231
+ $nLink = my_calendar_next_link( $c_year, $c_month, $c_day, $format, $time, $mc_show_months );
1232
+ }
1233
  $feeds = mc_rss_links( $ical_y, $ical_m, $nLink, $add, $subtract );
1234
  }
1235
  // set up date switcher
1236
  if ( in_array( 'jump', $used ) ) {
1237
+ $jump = ( $time != 'week' ) ? mc_build_date_switcher( $format, $main_class, $time ) : '';
1238
  }
1239
  // set up above-calendar order of fields
1240
  if ( get_option( 'mc_topnav' ) != '' ) {
1245
  }
1246
 
1247
  foreach ( $mc_toporder as $value ) {
1248
+ if ( $value != 'none' && in_array( $value, $used ) ) {
1249
  $value = trim( $value );
1250
  $mc_topnav .= @${$value};
1251
  }
1261
  $mc_bottomorder = explode( ',', $below );
1262
  }
1263
  foreach ( $mc_bottomorder as $value ) {
1264
+ if ( $value != 'none' && $value != 'stop' && in_array( $value, $used ) ) {
1265
  $value = trim( $value );
1266
  $mc_bottomnav .= @${$value};
1267
  }
1283
  } else {
1284
  $holidays = my_calendar_grab_events( $from, $to, get_option( 'mc_skip_holidays_category' ), $ltype, $lvalue, 'calendar', $author, $host, 'holidays' );
1285
  }
 
1286
  $events_class = mc_events_class( $events, $from );
1287
  $dateclass = mc_dateclass( time() + $offset, mktime( 0, 0, 0, $c_month, $c_day, $c_year ) );
1288
  $mc_events = '';
1298
  $heading_level = apply_filters( 'mc_heading_level', 'h3', $format, $time, $template );
1299
  $my_calendar_body .= "
1300
  <$heading_level class='mc-single'>" . date_i18n( apply_filters( 'mc_date_format', $date_format, 'grid' ), strtotime( "$c_year-$c_month-$c_day" ) ) . "</$heading_level>" . '
1301
+ <div id="mc-day" class="' . esc_attr( $dayclass . ' ' . $dateclass . ' ' . $events_class ) . '">' . "$mc_events\n</div>
1302
  </div>";
1303
  } else {
1304
  // if showing multiple months, figure out how far we're going.
1317
  $caption_text = ' ' . stripslashes( trim( get_option( 'mc_caption' ) ) ); // this option should be replaced JCD TODO
1318
  $my_calendar_body .= $mc_topnav;
1319
  if ( $format == "calendar" || $format == "mini" ) {
1320
+ $table = apply_filters( 'mc_grid_wrapper', 'table' );
1321
+ $my_calendar_body .= "\n<$table class=\"my-calendar-table\">\n";
1322
  $week_template = ( get_option( 'mc_week_caption' ) != '' ) ? get_option( 'mc_week_caption' ) : 'Week of {date format="M jS"}';
1323
  $week_caption = jd_draw_template( $values, stripslashes( $week_template ) );
1324
  $caption_heading = ( $time != 'week' ) ? $current_date_header . $caption_text : $week_caption . $caption_text;
1325
+ $caption = apply_filters( 'mc_grid_caption', 'caption' );
1326
+ $my_calendar_body .= "<$caption class=\"heading my-calendar-$time\">" . $caption_heading . "</$caption>\n";
1327
  } else {
1328
  // determine which header text to show depending on number of months displayed;
1329
  if ( $time != 'week' && $time != 'day' ) {
1342
  'month+1'
1343
  ) )
1344
  ) {
1345
+ $tr = apply_filters( 'mc_grid_week_wrapper', 'tr' );
1346
+ $th = apply_filters( 'mc_grid_header_wrapper', 'th' );
1347
+ $th .= ( $th == 'th' ) ? ' scope="col"' : '';
1348
  // If in a calendar format, print the headings of the days of the week
1349
  if ( $format == "list" ) {
1350
+ $my_calendar_body .= "<ul id='$id' class='mc-list'>";
 
1351
  } else {
1352
+ $my_calendar_body .= ( $tr == 'tr' ) ? "<thead>\n" : '';
1353
+ $my_calendar_body .= "<$tr>\n";
1354
  for ( $i = 0; $i <= 6; $i ++ ) {
1355
  if ( $start_of_week == 0 ) {
1356
  $class = ( $i < 6 && $i > 0 ) ? 'day-heading' : 'weekend-heading';
1359
  }
1360
  $dayclass = strtolower( strip_tags( $abbrevs[ $i ] ) );
1361
  if ( ( $class == 'weekend-heading' && get_option( 'mc_show_weekends' ) == 'true' ) || $class != 'weekend-heading' ) {
1362
+ $my_calendar_body .= "<$th class='$class $dayclass'>" . $name_days[ $i ] . "</$th>\n";
1363
  }
1364
  }
1365
+ $my_calendar_body .= "\n</$tr>\n";
1366
+ $my_calendar_body .= ( $tr == 'tr' ) ? "</thead>\n<tbody>" : '';
1367
  }
1368
  $odd = 'odd';
1369
  // get and display all the events
1371
  if ( $no_events && $format == "list" && $show_all == false ) {
1372
  // if there are no events in list format, just display that info.
1373
  $no_events = ( $content == '' ) ? __( 'There are no events scheduled during this period.', 'my-calendar' ) : $content;
1374
+ $my_calendar_body .= "<li class='mc-events no-events'>$no_events</li>";
1375
  } else {
1376
  $start = strtotime( $from );
1377
  $end = strtotime( $to );
1380
  $is_weekend = ( date( 'N', $start ) < 6 ) ? false : true;
1381
  if ( get_option( 'mc_show_weekends' ) == 'true' || ( get_option( 'mc_show_weekends' ) != 'true' && ! $is_weekend ) ) {
1382
  if ( date( 'N', $start ) == $start_of_week && $format != "list" ) {
1383
+ $my_calendar_body .= "<$tr>";
1384
  }
1385
  // date-based classes
1386
  $monthclass = ( date( 'n', $start ) == $c_month || $time != 'month' ) ? '' : 'nextmonth';
1397
  } else {
1398
  $is_anchor = $is_close_anchor = "";
1399
  }
1400
+ $td = apply_filters( 'mc_grid_day_wrapper', 'td' );
1401
  if ( ! empty( $events ) ) {
1402
  $event_output = my_calendar_draw_events( $events, $format, $date, $time, $template );
1403
  if ( $event_output === true ) {
1459
  $weekend_class = ( $is_weekend ) ? 'weekend' : '';
1460
  if ( $format == "list" ) {
1461
  if ( get_option( 'mc_show_list_info' ) == 'true' ) {
1462
+ $title = ' - ' . $is_anchor . "<span class='mc-list-details'>" . mc_list_title( $events ) . "</span>" . $is_close_anchor;
1463
  } else {
1464
  $title = '';
1465
  }
1466
  //if ( $monthclass != 'nextmonth' ) { // only show current month in list view.
1467
  if ( $event_output != '' ) {
1468
  $my_calendar_body .= "
1469
+ <li id='$format-$date' class='mc-events " . esc_attr( "$dayclass $dateclass $events_class $odd" ) . "'>
1470
  <strong class=\"event-date\">$is_anchor" . date_i18n( apply_filters( 'mc_date_format', $date_format, 'list' ), $start ) . "$is_close_anchor" . "$title</strong>" .
1471
  $event_output . "
1472
  </li>";
1475
  //}
1476
  } else {
1477
  $my_calendar_body .= "
1478
+ <$td id='$format-$date' class='" . esc_attr( "$dayclass $dateclass $weekend_class $monthclass $events_class" ) . " day-with-date'>" . "
1479
+ <$element class='mc-date $trigger'><span aria-hidden='true'>$thisday_heading</span><span class='screen-reader-text'><span class='screen-reader-text'>" . date_i18n( get_option( 'mc_date_format' ), strtotime( $date ) ) . "</span></span></$close>" .
1480
  $event_output . "
1481
+ </$td>\n";
1482
  }
1483
  }
1484
  } else {
1486
  if ( $format != "list" ) {
1487
  $weekend_class = ( $is_weekend ) ? 'weekend' : '';
1488
  $my_calendar_body .= "
1489
+ <$td class='no-events $dayclass $dateclass $weekend_class $monthclass day-with-date'>
1490
+ <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>
1491
+ </$td>\n";
1492
  } else {
1493
  if ( $show_all == true ) {
1494
  $my_calendar_body .= "
1500
  }
1501
 
1502
  if ( date( 'N', $start ) == $end_of_week && $format != "list" ) {
1503
+ $my_calendar_body .= "</$tr>\n"; // end of 'is beginning of week'
1504
  }
1505
  }
1506
  $start = strtotime( "+1 day", $start );
1507
 
1508
  } while ( $start <= $end );
1509
  }
1510
+ $table = apply_filters( 'mc_grid_wrapper', 'table' );
1511
+ $end = ( $table == 'table' ) ? "\n</tbody>\n</table>" : "</$table>";
1512
+ $my_calendar_body .= ( $format == "list" ) ? "\n</ul>" : $end;
1513
  } else {
1514
  if ( ! in_array( $format, array( 'list', 'calendar', 'mini' ) ) ) {
1515
  $my_calendar_body .= "<p class='mc-error-format'>" . __( "Unrecognized calendar format. Please use one of 'list', 'calendar', or 'mini'.", 'my-calendar' ) . "</p>";
1527
  return $mc_wrapper . apply_filters( 'my_calendar_body', $my_calendar_body ) . $mc_closer;
1528
  }
1529
 
1530
+ add_filter( 'my_calendar_body', 'mc_run_shortcodes', 10, 1 );
1531
+ // Process shortcodes on the final rendered calendar instead of each individual case.
1532
+ // Means this runs once instead of potentially hundreds of times.
1533
+ function mc_run_shortcodes( $content ) {
1534
+ $content = ( get_option( 'mc_process_shortcodes' ) == 'true' ) ? do_shortcode( $content ) : $content;
1535
+
1536
+ return $content;
1537
+ }
1538
+
1539
  function my_category_key( $category ) {
1540
  global $wpdb;
1541
  $url = plugin_dir_url( __FILE__ );
1891
  $output .= " <li$selected><a rel='nofollow' href='$this_url'>$access_name</a></li>";
1892
  } else {
1893
  $selected = ( $this_access == $key ) ? ' selected="selected"' : '';
1894
+ $output .= " <option$selected value='" . esc_attr( $key ) . "'>" . esc_html( $access_name ) . "</option>\n";
1895
  }
1896
  }
1897
  $output .= ( $show == 'list' ) ? '</ul>' : '</select>';
2024
  }
2025
 
2026
  function my_calendar_searchform( $type, $url ) {
2027
+ $query = ( isset( $_GET['mcs'] ) ) ? $_GET['mcs'] : '';
2028
  if ( $type == 'simple' ) {
2029
  if ( !$url || $url == '' ) {
2030
  $url = ( get_option( 'mc_uri' ) != '' ) ? get_option( 'mc_uri' ) : home_url();
2033
  <form role="search" method="get" action="' . apply_filters( 'mc_search_page', esc_url( $url ) ) . '" >
2034
  <div class="mc-search">
2035
  <label class="screen-reader-text" for="mcs">' . __( 'Search Events', 'my-calendar' ) . '</label>
2036
+ <input type="text" value="' . esc_attr( stripslashes( $query ) ) . '" name="mcs" id="mcs" />
2037
  <input type="submit" id="searchsubmit" value="' . __( 'Search Events', 'my-calendar' ) . '" />
2038
  </div>
2039
  </form>';
2092
  if ( $show == 'list' ) {
2093
  $url = mc_build_url( array( 'loc' => 'all', 'ltype' => 'all' ), array() );
2094
  $output .= "<ul id='mc-locations-list'>
2095
+ <li class='mc-show-all'><a href='$url'>" . __( 'Show all', 'my-calendar' ) . "</a></li>\n";
2096
  } else {
2097
  $ltype = ( ! isset( $_GET['ltype'] ) ) ? $datatype : $_GET['ltype'];
2098
  $output .= "<div id='mc_locations'>";
2099
  $output .= ( $group == 'single' ) ? "
2100
  <form action='" . $current_url . "' method='get'>
2101
  <div>" : '';
2102
+ $output .= "<input type='hidden' name='ltype' value='" . esc_attr( $ltype ) . "' />";
2103
  if ( $group == 'single' ) {
2104
  $qsa = array();
2105
  parse_str( $_SERVER['QUERY_STRING'], $qsa );
2139
  } else {
2140
  $selected = ( $vt == $loc ) ? " selected='selected'" : '';
2141
  if ( $value != '' ) {
2142
+ $output .= " <option value='" . esc_attr( $vt ) . "'$selected>$value</option>\n";
2143
  }
2144
  }
2145
  }
2155
  $output .= " <li$selected><a rel='nofollow' href='$this_url'>$location</a></li>\n";
2156
  } else {
2157
  $selected = ( $vk == $_GET['loc'] ) ? " selected='selected'" : '';
2158
+ $output .= " <option value='" . esc_attr( $vk ) . "'$selected>$location</option>\n";
2159
  }
2160
  }
2161
  }
my-calendar-settings.php CHANGED
@@ -22,7 +22,7 @@ function mc_settings_field( $name, $label, $default = '', $note = '', $atts = ar
22
  } else {
23
  $note = $aria = '';
24
  }
25
- echo "<label for='$name'>$label</label> <input type='$type' id='$name' name='$name' value='$value'$aria$attributes /> $note";
26
  break;
27
  case 'textarea':
28
  if ( $note ) {
@@ -32,7 +32,7 @@ function mc_settings_field( $name, $label, $default = '', $note = '', $atts = ar
32
  } else {
33
  $note = $aria = '';
34
  }
35
- echo "<label for='$name'>$label</label><br /><textarea id='$name' name='$name'$aria$attributes>$value</textarea>$note";
36
  break;
37
  case 'checkbox-single':
38
  $checked = mc_is_checked( $name, 'true', '', true );
@@ -54,7 +54,7 @@ function mc_settings_field( $name, $label, $default = '', $note = '', $atts = ar
54
  }
55
  foreach ( $label as $k => $v ) {
56
  $checked = ( $k == $value ) ? ' checked="checked"' : '';
57
- $options .= "<li><input type='radio' id='$name-$k' value='$k' name='$name'$aria$attributes$checked /> <label for='$name-$k'>$v</label></li>";
58
  }
59
  echo "$options $note";
60
  break;
@@ -69,7 +69,7 @@ function mc_settings_field( $name, $label, $default = '', $note = '', $atts = ar
69
  if ( is_array( $default ) ) {
70
  foreach ( $default as $k => $v ) {
71
  $checked = ( $k == $value ) ? ' selected="selected"' : '';
72
- $options .= "<option value='$k'$checked>$v</option>";
73
  }
74
  }
75
  echo "
@@ -194,6 +194,7 @@ function edit_my_calendar_config() {
194
  update_option( 'mc_api_enabled', $mc_api_enabled );
195
  update_option( 'mc_remote', $mc_remote );
196
  update_option( 'mc_default_sort', $_POST['mc_default_sort'] );
 
197
  if ( get_site_option( 'mc_multisite' ) == 2 ) {
198
  $mc_current_table = (int) $_POST['mc_current_table'];
199
  update_option( 'mc_current_table', $mc_current_table );
@@ -230,13 +231,13 @@ function edit_my_calendar_config() {
230
  }
231
  // output
232
  if ( isset( $_POST['mc_show_months'] ) ) {
 
233
  $mc_open_day_uri = ( ! empty( $_POST['mc_open_day_uri'] ) ) ? $_POST['mc_open_day_uri'] : '';
234
  update_option( 'mc_uri', $_POST['mc_uri'] );
235
  update_option( 'mc_use_permalinks', ( ! empty( $_POST['mc_use_permalinks'] ) ) ? 'true' : 'false' );
236
  update_option( 'mc_open_uri', ( ! empty( $_POST['mc_open_uri'] ) && $_POST['mc_open_uri'] == 'on' && get_option( 'mc_uri' ) != '' ) ? 'true' : 'false' );
237
  update_option( 'mc_mini_uri', $_POST['mc_mini_uri'] );
238
  update_option( 'mc_open_day_uri', $mc_open_day_uri );
239
- update_option( 'mc_skip_holidays', ( ! empty( $_POST['mc_skip_holidays'] ) && $_POST['mc_skip_holidays'] == 'on' ) ? 'true' : 'false' );
240
  update_option( 'mc_display_author', ( ! empty( $_POST['mc_display_author'] ) && $_POST['mc_display_author'] == 'on' ) ? 'true' : 'false' );
241
  update_option( 'mc_show_event_vcal', ( ! empty( $_POST['mc_show_event_vcal'] ) && $_POST['mc_show_event_vcal'] == 'on' ) ? 'true' : 'false' );
242
  update_option( 'mc_show_gcal', ( ! empty( $_POST['mc_show_gcal'] ) && $_POST['mc_show_gcal'] == 'on' ) ? 'true' : 'false' );
@@ -268,7 +269,6 @@ function edit_my_calendar_config() {
268
  update_option( 'mc_gmap', ( ! empty( $_POST['mc_gmap'] ) && $_POST['mc_gmap'] == 'on' ) ? 'true' : 'false' );
269
  update_option( 'mc_show_address', ( ! empty( $_POST['mc_show_address'] ) && $_POST['mc_show_address'] == 'on' ) ? 'true' : 'false' );
270
  update_option( 'mc_hide_icons', ( ! empty( $_POST['mc_hide_icons'] ) && $_POST['mc_hide_icons'] == 'on' ) ? 'true' : 'false' );
271
- update_option( 'mc_event_link_expires', ( ! empty( $_POST['mc_event_link_expires'] ) && $_POST['mc_event_link_expires'] == 'on' ) ? 'true' : 'false' );
272
  update_option( 'mc_apply_color', $_POST['mc_apply_color'] );
273
  update_option( 'mc_event_registration', ( ! empty( $_POST['mc_event_registration'] ) && $_POST['mc_event_registration'] == 'on' ) ? 'true' : 'false' );
274
  update_option( 'mc_inverse_color', ( ! empty( $_POST['mc_inverse_color'] ) && $_POST['mc_inverse_color'] == 'on' ) ? 'true' : 'false' );
@@ -277,20 +277,16 @@ function edit_my_calendar_config() {
277
  update_option( 'mc_process_shortcodes', ( ! empty( $_POST['mc_process_shortcodes'] ) && $_POST['mc_process_shortcodes'] == 'on' ) ? 'true' : 'false' );
278
  update_option( 'mc_event_link', ( ! empty( $_POST['mc_event_link'] ) && $_POST['mc_event_link'] == 'on' ) ? 'true' : 'false' );
279
  update_option( 'mc_show_weekends', ( ! empty( $_POST['mc_show_weekends'] ) && $_POST['mc_show_weekends'] == 'on' ) ? 'true' : 'false' );
280
- update_option( 'mc_convert', ( ! empty( $_POST['mc_convert'] ) && $_POST['mc_convert'] == 'on' ) ? 'true' : 'false' );
281
- update_option( 'mc_no_fifth_week', ( ! empty( $_POST['mc_no_fifth_week'] ) && $_POST['mc_no_fifth_week'] == 'on' ) ? 'true' : 'false' );
282
- echo "<div class=\"updated\"><p><strong>" . __( 'Output Settings saved', 'my-calendar' ) . "</strong></p></div>";
283
- }
284
- // input
285
- if ( isset( $_POST['mc_dates'] ) ) {
286
- update_option( 'mc_date_format', stripslashes( $_POST['mc_date_format'] ) );
287
- update_option( 'mc_week_format', stripslashes( $_POST['mc_week_format'] ) );
288
- update_option( 'mc_time_format', stripslashes( $_POST['mc_time_format'] ) );
289
- update_option( 'mc_month_format', stripslashes( $_POST['mc_month_format'] ) );
290
- $mc_ical_utc = ( ! empty( $_POST['mc_ical_utc'] ) && $_POST['mc_ical_utc'] == 'on' ) ? 'true' : 'false';
291
- update_option( 'mc_ical_utc', $mc_ical_utc );
292
- echo "<div class=\"updated\"><p><strong>" . __( 'Date/Time Format Settings saved', 'my-calendar' ) . "</strong></p></div>";
293
  }
 
294
  if ( isset( $_POST['mc_input'] ) ) {
295
  $mc_input_options_administrators = ( ! empty( $_POST['mc_input_options_administrators'] ) && $_POST['mc_input_options_administrators'] == 'on' ) ? 'true' : 'false';
296
  $mc_input_options = array(
@@ -304,10 +300,15 @@ function edit_my_calendar_config() {
304
  'event_location' => ( ! empty( $_POST['mci_event_location'] ) && $_POST['mci_event_location'] ) ? 'on' : 'off',
305
  'event_location_dropdown' => ( ! empty( $_POST['mci_event_location_dropdown'] ) && $_POST['mci_event_location_dropdown'] ) ? 'on' : 'off',
306
  'event_specials' => ( ! empty( $_POST['mci_event_specials'] ) && $_POST['mci_event_specials'] ) ? 'on' : 'off',
307
- 'event_access' => ( ! empty( $_POST['mci_event_access'] ) && $_POST['mci_event_access'] ) ? 'on' : 'off'
 
308
  );
309
  update_option( 'mc_input_options', $mc_input_options );
310
  update_option( 'mc_input_options_administrators', $mc_input_options_administrators );
 
 
 
 
311
  echo "<div class=\"updated\"><p><strong>" . __( 'Input Settings saved', 'my-calendar' ) . ".</strong></p></div>";
312
  }
313
  if ( current_user_can( 'manage_network' ) ) {
@@ -322,6 +323,8 @@ function edit_my_calendar_config() {
322
  // custom text
323
  if ( isset( $_POST['mc_previous_events'] ) ) {
324
  $mc_title_template = $_POST['mc_title_template'];
 
 
325
  $mc_details_label = $_POST['mc_details_label'];
326
  $mc_link_label = $_POST['mc_link_label'];
327
  $mc_event_title_template = $_POST['mc_event_title_template'];
@@ -334,6 +337,8 @@ function edit_my_calendar_config() {
334
  $mc_caption = $_POST['mc_caption'];
335
  $templates = get_option( 'mc_templates' );
336
  $templates['title'] = $mc_title_template;
 
 
337
  $templates['label'] = $mc_details_label;
338
  $templates['link'] = $mc_link_label;
339
  update_option( 'mc_templates', $templates );
@@ -345,6 +350,13 @@ function edit_my_calendar_config() {
345
  update_option( 'mc_caption', $mc_caption );
346
  update_option( 'mc_event_open', $mc_event_open );
347
  update_option( 'mc_event_closed', $mc_event_closed );
 
 
 
 
 
 
 
348
  echo "<div class=\"updated\"><p><strong>" . __( 'Custom text settings saved', 'my-calendar' ) . ".</strong></p></div>";
349
  }
350
  // Mail function by Roland
@@ -370,18 +382,20 @@ function edit_my_calendar_config() {
370
  apply_filters( 'mc_save_settings', '', $_POST );
371
 
372
  // pull templates for passing into functions.
373
- $templates = get_option( 'mc_templates' );
374
- $mc_title_template = ( isset( $templates['title'] ) ) ? esc_attr( stripslashes( $templates['title'] ) ) : '';
375
- $mc_details_label = ( isset( $templates['label'] ) ) ? esc_attr( stripslashes( $templates['label'] ) ) : '';
376
- $mc_link_label = ( isset( $templates['link'] ) ) ? esc_attr( stripslashes( $templates['link'] ) ) : '';
 
 
377
  ?>
378
 
379
  <div class="wrap jd-my-calendar mc-settings-page" id="mc_settings">
380
  <?php my_calendar_check_db(); ?>
381
  <div id="icon-options-general" class="icon32"><br/></div>
382
- <h2><?php _e( 'My Calendar Options', 'my-calendar' ); ?></h2>
383
 
384
- <div class="postbox-container jcd-wide">
385
  <div class="metabox-holder">
386
  <?php
387
  //update_option( 'ko_calendar_imported','false' ); // for testing importing.
@@ -414,36 +428,26 @@ function edit_my_calendar_config() {
414
  }
415
  }
416
  ?>
 
 
 
 
 
 
 
 
 
 
 
 
417
 
418
  <div class="ui-sortable meta-box-sortables">
419
- <div class="postbox">
420
- <h3><?php _e( 'My Calendar Settings', 'my-calendar' ); ?></h3>
421
-
422
- <div class="inside">
423
- <ul class="mc-settings checkboxes">
424
- <li><a href="#my-calendar-manage"><?php _e( 'Management', 'my-calendar' ); ?></a></li>
425
- <li><a href="#my-calendar-text"><?php _e( 'Customizable Text', 'my-calendar' ); ?></a></li>
426
- <li><a href="#my-calendar-output"><?php _e( 'Output', 'my-calendar' ); ?></a></li>
427
- <li><a href="#my-calendar-time"><?php _e( 'Date/Time', 'my-calendar' ); ?></a></li>
428
- <li><a href="#my-calendar-input"><?php _e( 'Input', 'my-calendar' ); ?></a></li>
429
- <?php if ( current_user_can( 'manage_network' ) ) { ?>
430
- <li><a href="#my-calendar-multisite"><?php _e( 'Multi-site', 'my-calendar' ); ?></a></li>
431
- <?php } ?>
432
- <li><a href="#my-calendar-permissions"><?php _e( 'Permissions', 'my-calendar' ); ?></a></li>
433
- <li><a href="#my-calendar-email"><?php _e( 'Email Notifications', 'my-calendar' ); ?></a></li>
434
- <?php echo apply_filters( 'mc_settings_section_links', '' ); ?>
435
- </ul>
436
- </div>
437
- </div>
438
- </div>
439
-
440
- <div class="ui-sortable meta-box-sortables">
441
- <div class="postbox" id="my-calendar-manage">
442
  <h3><?php _e( 'My Calendar Management', 'my-calendar' ); ?></h3>
443
 
444
  <div class="inside">
445
  <?php if ( current_user_can( 'administrator' ) ) { ?>
446
- <form method="post" action="<?php echo admin_url( "admin.php?page=my-calendar-config" ); ?>">
447
  <div><input type="hidden" name="_wpnonce"
448
  value="<?php echo wp_create_nonce( 'my-calendar-nonce' ); ?>"/></div>
449
  <fieldset>
@@ -475,6 +479,10 @@ function edit_my_calendar_config() {
475
  '6' => __( 'Category', 'my-calendar' ),
476
  '7' => __( 'Location Name', 'my-calendar' )
477
  ), '', array(), 'select' ); ?></li>
 
 
 
 
478
  <?php
479
  if ( get_site_option( 'mc_multisite' ) == 2 && MY_CALENDAR_TABLE != MY_CALENDAR_GLOBAL_TABLE ) {
480
  mc_settings_field( 'mc_current_table', array(
@@ -500,14 +508,12 @@ function edit_my_calendar_config() {
500
  <?php } ?>
501
  </div>
502
  </div>
503
- </div>
504
 
505
- <div class="ui-sortable meta-box-sortables">
506
- <div class="postbox" id="my-calendar-text">
507
  <h3><?php _e( 'Text Settings', 'my-calendar' ); ?></h3>
508
 
509
  <div class="inside">
510
- <form method="post" action="<?php echo admin_url( "admin.php?page=my-calendar-config" ); ?>">
511
  <div><input type="hidden" name="_wpnonce"
512
  value="<?php echo wp_create_nonce( 'my-calendar-nonce' ); ?>"/></div>
513
  <fieldset>
@@ -520,37 +526,58 @@ function edit_my_calendar_config() {
520
  <li><?php mc_settings_field( 'mc_event_closed', __( 'If events are closed', 'my-calendar' ), __( 'Registration is closed', 'my-calendar' ) ); ?></li>
521
  <li><?php mc_settings_field( 'mc_week_caption', __( 'Week view caption:', 'my-calendar' ), '', __( 'Available tag: <code>{date format=""}</code>', 'my-calendar' ) ); ?></li>
522
  <li><?php mc_settings_field( 'mc_caption', __( 'Extended caption:', 'my-calendar' ), '', __( 'Follows month/year in list views.', 'my-calendar' ) ); ?></li>
523
- <li><?php mc_settings_field( 'mc_title_template', __( 'Event title template', 'my-calendar' ), $mc_title_template, "<a href='" . admin_url( "admin.php?page=my-calendar-help#templates" ) . "'>" . __( "Templating Help", 'my-calendar' ) . '</a>' ); ?></li>
 
 
524
  <li><?php mc_settings_field( 'mc_details_label', __( 'Event details link text', 'my-calendar' ), $mc_details_label, __( 'Tags: <code>{title}</code>, <code>{location}</code>, <code>{color}</code>, <code>{icon}</code>, <code>{date}</code>, <code>{time}</code>.', 'my-calendar' ) ); ?></li>
525
  <li><?php mc_settings_field( 'mc_link_label', __( 'Event URL link text', 'my-calendar' ), $mc_link_label, "<a href='" . admin_url( "admin.php?page=my-calendar-help#templates" ) . "'>" . __( "Templating Help", 'my-calendar' ) . '</a>' ); ?></li>
526
  <li><?php mc_settings_field( 'mc_event_title_template', __( 'Title element template', 'my-calendar' ), '{title} &raquo; {date}', __( 'Current: %s', 'my-calendar' ) ); ?></li>
527
  </ul>
528
  </fieldset>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
529
  <p>
530
  <input type="submit" name="save" class="button-primary"
531
  value="<?php _e( 'Save Custom Text Settings', 'my-calendar' ); ?>"/>
532
  </p>
533
  </form>
 
 
 
534
  </div>
535
  </div>
536
- </div>
537
 
538
- <div class="ui-sortable meta-box-sortables">
539
- <div class="postbox" id="my-calendar-output">
540
  <h3><?php _e( 'Output Settings', 'my-calendar' ); ?></h3>
541
 
542
  <div class="inside">
543
- <form method="post" action="<?php echo admin_url( "admin.php?page=my-calendar-config" ); ?>">
544
  <div><input type="hidden" name="_wpnonce"
545
  value="<?php echo wp_create_nonce( 'my-calendar-nonce' ); ?>"/></div>
 
546
  <fieldset>
547
  <legend><?php _e( 'Calendar Link Targets', 'my-calendar' ); ?></legend>
548
  <ul>
549
- <?php /* <li><?php mc_settings_field( 'mc_use_permalinks', __( 'Use Pretty Permalinks for Events','my-calendar' ), '', '', array(), 'checkbox-single' ); ?></li> This just isn't ready; add in a point release. */ ?>
550
  <?php $guess = mc_guess_calendar(); ?>
551
- <li><?php mc_settings_field( 'mc_uri', __( 'Where is your main calendar page?', 'my-calendar' ), '', "<br /><small>" . __( 'Can be any Page or Post which includes the <code>[my_calendar]</code> shortcode.', 'my-calendar' ) . " $guess[message]</small>", array( 'size' => '60' ), 'url' ); ?></li>
552
- <li><?php mc_settings_field( 'mc_mini_uri', __( 'Target <abbr title="Uniform resource locator">URL</abbr> for mini calendar date links:', 'my-calendar' ), '', "<br /><small>" . __( 'Can be any Page or Post which includes the <code>[my_calendar]</code> shortcode.', 'my-calendar' ) . "</small>", array( 'size' => '60' ), 'url' ); ?></li>
553
  <li><?php mc_settings_field( 'mc_open_uri', __( 'Open calendar links to event details URL', 'my-calendar' ), '', '', array(), 'checkbox-single' ); ?></li>
 
554
  <?php
555
  $disabled = ( ! get_option( 'mc_uri' ) && ! get_option( 'mc_mini_uri' ) ) ? array( 'disabled' => 'disabled' ) : array();
556
  ?>
@@ -565,7 +592,24 @@ function edit_my_calendar_config() {
565
  </fieldset>
566
 
567
  <fieldset>
568
- <legend><?php _e( 'Set Default Navigation Element Order (can be overridden in shortcodes)', 'my-calendar' ); ?></legend>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
569
  <?php
570
  $topnav = explode( ',', get_option( 'mc_topnav' ) );
571
  $calendar = array( 'calendar' );
@@ -585,17 +629,46 @@ function edit_my_calendar_config() {
585
  echo "<div id='mc-sortable-update' aria-live='assertive'></div>";
586
  echo "<ul id='mc-sortable'>";
587
  $inserted = array();
 
 
 
588
  foreach ( $order as $k ) {
589
  $k = trim( $k );
590
  $v = ( isset( $nav_elements[ $k ] ) ) ? $nav_elements[ $k ] : false;
591
  if ( $v !== false ) {
592
  $inserted[ $k ] = $v;
593
- echo "<li class='ui-state-default mc-$k'><button class='up'><i class='dashicons dashicons-arrow-up'></i><span class='screen-reader-text'>Up</span></button> <button class='down'><i class='dashicons dashicons-arrow-down'></i><span class='screen-reader-text'>Down</span></button> <code>$k</code> $v <input type='hidden' name='mc_nav[]' value='$k' /></li>";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
594
  }
595
  }
596
  $missed = array_diff( $nav_elements, $inserted );
 
 
597
  foreach ( $missed as $k => $v ) {
598
- echo "<li class='ui-state-default mc-$k'><button class='up'><i class='dashicons dashicons-arrow-up'></i><span class='screen-reader-text'>Up</span></button> <button class='down'><i class='dashicons dashicons-arrow-down'></i><span class='screen-reader-text'>Down</span></button> <code>$k</code> $v <input type='hidden' name='mc_nav[]' value='$k' /></li>";
 
 
 
 
 
 
 
599
  }
600
 
601
  echo "</ul>";
@@ -603,26 +676,8 @@ function edit_my_calendar_config() {
603
  </fieldset>
604
 
605
  <fieldset>
606
- <legend><?php _e( 'Grid Layout Options', 'my-calendar' ); ?></legend>
607
- <ul>
608
- <li><?php mc_settings_field( 'mc_show_weekends', __( 'Show Weekends on Calendar', 'my-calendar' ), '', '', array(), 'checkbox-single' ); ?></li>
609
- <li><?php mc_settings_field( 'mc_convert', __( 'Switch to list view on mobile devices', 'my-calendar' ), '', '', array(), 'checkbox-single' ); ?></li>
610
- </ul>
611
- <?php // End Grid Options // ?>
612
- </fieldset>
613
-
614
- <fieldset>
615
- <legend><?php _e( 'List Layout Options', 'my-calendar' ); ?></legend>
616
- <ul>
617
- <li><?php mc_settings_field( 'mc_show_months', __( 'How many months of events to show at a time:', 'my-calendar' ), '', '', array( 'size' => '3' ), 'text' ); ?></li>
618
- <li><?php mc_settings_field( 'mc_show_list_info', __( 'Show the first event\'s title and the number of events that day next to the date.', 'my-calendar' ), '', '', array(), 'checkbox-single' ); ?></li>
619
- </ul>
620
- <?php // End List Options // ?>
621
- </fieldset>
622
-
623
- <fieldset>
624
- <legend><?php _e( 'Event Details Pop-up', 'my-calendar' ); ?></legend>
625
- <p><?php _e( 'The checked items will be shown in your event details view. Does not apply if you are using a custom template', 'my-calendar' ); ?>
626
  <ul class="checkboxes">
627
  <li><?php mc_settings_field( 'mc_display_author', __( 'Author\'s name', 'my-calendar' ), '', '', array(), 'checkbox-single' ); ?></li>
628
  <li><?php mc_settings_field( 'mc_show_event_vcal', __( 'Link to single event iCal download', 'my-calendar' ), '', '', array(), 'checkbox-single' ); ?></li>
@@ -638,7 +693,7 @@ function edit_my_calendar_config() {
638
  </ul>
639
  </fieldset>
640
  <fieldset>
641
- <legend><?php _e( 'Event Category Display', 'my-calendar' ); ?></legend>
642
  <ul class='checkboxes'>
643
  <?php mc_settings_field( 'mc_apply_color', array(
644
  'default' => __( 'No category colors with titles.', 'my-calendar' ),
@@ -650,66 +705,17 @@ function edit_my_calendar_config() {
650
  </ul>
651
  <?php // End Event Options // ?>
652
  </fieldset>
653
- <fieldset>
654
- <legend><?php _e( 'Event Scheduling Defaults', 'my-calendar' ); ?></legend>
655
- <ul>
656
- <li><?php mc_settings_field( 'mc_event_link_expires', __( 'Event links expire after event passes.', 'my-calendar' ), '', '', array(), 'checkbox-single' ); ?></li>
657
- <li><?php mc_settings_field( 'mc_no_fifth_week', __( 'If a recurring event falls on a date that doesn\'t exist (like the 5th Wednesday in February), move it back one week.', 'my-calendar' ), '', '', array(), 'checkbox-single' ); ?></li>
658
- <li><?php mc_settings_field( 'mc_skip_holidays', __( 'If an event coincides with an event in the designated "Holiday" category, do not show the event.', 'my-calendar' ), '', '', array(), 'checkbox-single' ); ?></li>
659
- </ul>
660
- <?php // End Scheduling Options // ?>
661
- </fieldset>
662
  <p><input type="submit" name="save" class="button-primary"
663
  value="<?php _e( 'Save Output Settings', 'my-calendar' ); ?>"/></p>
664
  </form>
665
  </div>
666
  </div>
667
- </div>
668
-
669
- <div class="ui-sortable meta-box-sortables">
670
- <div class="postbox" id="my-calendar-time">
671
- <h3><?php _e( 'Calendar Time Formats', 'my-calendar' ); ?></h3>
672
-
673
- <div class="inside">
674
- <form method="post" action="<?php echo admin_url( "admin.php?page=my-calendar-config" ); ?>">
675
- <div><input type="hidden" name="_wpnonce"
676
- value="<?php echo wp_create_nonce( 'my-calendar-nonce' ); ?>"/></div>
677
- <fieldset>
678
- <legend><?php _e( 'Set default date/time formats', 'my-calendar' ); ?></legend>
679
- <div><input type='hidden' name='mc_dates' value='true'/></div>
680
- <ul>
681
- <?php
682
- $month_format = ( get_option( 'mc_month_format' ) == '' ) ? date_i18n( 'F Y' ) : date_i18n( get_option( 'mc_month_format' ) );
683
- $time_format = ( get_option( 'mc_time_format' ) == '' ) ? date_i18n( get_option( 'time_format' ) ) : date_i18n( get_option( 'mc_time_format' ) );
684
- $week_format = ( get_option( 'mc_week_format' ) == '' ) ? date_i18n( 'M j, \'y' ) : date_i18n( get_option( 'mc_week_format' ) );
685
- $date_format = ( get_option( 'mc_date_format' ) == '' ) ? date_i18n( get_option( 'date_format' ) ) : date_i18n( get_option( 'mc_date_format' ) );
686
- ?>
687
- <li><?php mc_settings_field( 'mc_month_format', __( 'Month format (calendar headings)', 'my-calendar' ), '', $month_format ); ?></li>
688
- <li><?php mc_settings_field( 'mc_time_format', __( 'Time format', 'my-calendar' ), '', $time_format ); ?></li>
689
- <li><?php mc_settings_field( 'mc_week_format', __( 'Date in grid mode, week view', 'my-calendar' ), '', $week_format ); ?></li>
690
- <li><?php mc_settings_field( 'mc_date_format', __( 'Date Format in other views', 'my-calendar' ), '', $date_format ); ?></li>
691
- <li>
692
- <?php _e( 'Date formats use syntax from the <a href="http://php.net/date">PHP <code>date()</code> function</a>. Save to update sample output.', 'my-calendar' ); ?>
693
- </li>
694
- <li><?php mc_settings_field( 'mc_ical_utc', __( 'iCal times are UTC', 'my-calendar' ), '', '', array(), 'checkbox-single' ); ?></li>
695
- </ul>
696
- </fieldset>
697
- <p>
698
- <input type="submit" name="save" class="button-primary"
699
- value="<?php _e( 'Save Date/Time Settings', 'my-calendar' ); ?>"/>
700
- </p>
701
- </form>
702
- </div>
703
- </div>
704
- </div>
705
-
706
-
707
- <div class="ui-sortable meta-box-sortables">
708
- <div class="postbox" id="my-calendar-input">
709
  <h3><?php _e( 'Calendar Input Fields', 'my-calendar' ); ?></h3>
710
 
711
  <div class="inside">
712
- <form method="post" action="<?php echo admin_url( "admin.php?page=my-calendar-config" ); ?>">
713
  <div><input type="hidden" name="_wpnonce"
714
  value="<?php echo wp_create_nonce( 'my-calendar-nonce' ); ?>"/></div>
715
  <fieldset>
@@ -729,7 +735,8 @@ function edit_my_calendar_config() {
729
  'event_open' => __( 'Event Registration options', 'my-calendar' ),
730
  'event_location' => __( 'Event Location fields', 'my-calendar' ),
731
  'event_specials' => __( 'Set Special Scheduling options', 'my-calendar' ),
732
- 'event_access' => __( "Event Accessibility", 'my-calendar' )
 
733
  );
734
  $output = '';
735
  // if input options isn't an array, we'll assume that this plugin wasn't upgraded properly, and reset them to the default.
@@ -745,7 +752,8 @@ function edit_my_calendar_config() {
745
  'event_location' => 'off',
746
  'event_location_dropdown' => 'on',
747
  'event_specials' => 'on',
748
- 'event_access' => 'on'
 
749
  ) );
750
  $input_options = get_option( 'mc_input_options' );
751
  }
@@ -760,6 +768,15 @@ function edit_my_calendar_config() {
760
  <li><?php mc_settings_field( 'mc_input_options_administrators', __( 'Administrators see all input options', 'my-calendar' ), '', '', array(), 'checkbox-single' ); ?></li>
761
  </ul>
762
  </fieldset>
 
 
 
 
 
 
 
 
 
763
  <p>
764
  <input type="submit" name="save" class="button-primary"
765
  value="<?php _e( 'Save Input Settings', 'my-calendar' ); ?>"/>
@@ -767,36 +784,29 @@ function edit_my_calendar_config() {
767
  </form>
768
  </div>
769
  </div>
770
- </div>
771
 
772
  <?php if ( current_user_can( 'manage_network' ) ) { ?>
773
- <div class="ui-sortable meta-box-sortables">
774
- <div class="postbox" id="my-calendar-multisite">
775
  <h3><?php _e( 'Multisite Settings (Network Administrators only)', 'my-calendar' ); ?></h3>
776
 
777
  <div class="inside">
778
- <form method="post" action="<?php echo admin_url( "admin.php?page=my-calendar-config" ); ?>">
779
- <div><input type="hidden" name="_wpnonce"
780
- value="<?php echo wp_create_nonce( 'my-calendar-nonce' ); ?>"/></div>
781
- <div><input type='hidden' name='mc_network' value='true'/></div>
 
 
782
  <fieldset>
783
  <legend><?php _e( 'WP MultiSite configurations', 'my-calendar' ); ?></legend>
784
- <p><?php _e( 'The central calendar is the calendar associated with the primary site in your WordPress Multisite network.', 'my-calendar' ); ?></p>
785
  <ul>
786
- <li><input type="radio" value="0" id="ms0"
787
- name="mc_multisite"<?php echo jd_option_selected( get_site_option( 'mc_multisite' ), '0' ); ?> />
788
- <label
789
- for="ms0"><?php _e( 'Site owners may only post to their local calendar', 'my-calendar' ); ?></label>
790
  </li>
791
- <li><input type="radio" value="1" id="ms1"
792
- name="mc_multisite"<?php echo jd_option_selected( get_site_option( 'mc_multisite' ), '1' ); ?> />
793
- <label
794
- for="ms1"><?php _e( 'Site owners may only post to the central calendar', 'my-calendar' ); ?></label>
795
  </li>
796
- <li><input type="radio" value="2" id="ms2"
797
- name="mc_multisite"<?php echo jd_option_selected( get_site_option( 'mc_multisite' ), 2 ); ?> />
798
- <label
799
- for="ms2"><?php _e( 'Site owners may manage either calendar', 'my-calendar' ); ?></label>
800
  </li>
801
  </ul>
802
  <p class="notice">
@@ -822,17 +832,15 @@ function edit_my_calendar_config() {
822
  </form>
823
  </div>
824
  </div>
825
- </div>
826
  <?php } ?>
827
 
828
- <div class="ui-sortable meta-box-sortables">
829
- <div class="postbox" id="my-calendar-permissions">
830
  <h3><?php _e( 'My Calendar Permissions', 'my-calendar' ); ?></h3>
831
 
832
- <div class="inside mc-tabs">
833
  <?php if ( current_user_can( 'administrator' ) ) { ?>
834
 
835
- <form method="post" action="<?php echo admin_url( "admin.php?page=my-calendar-config" ); ?>">
836
  <div><input type="hidden" name="_wpnonce"
837
  value="<?php echo wp_create_nonce( 'my-calendar-nonce' ); ?>"/></div>
838
  <?php
@@ -850,13 +858,12 @@ function edit_my_calendar_config() {
850
  'mc_edit_settings' => __( 'Edit Settings', 'my-calendar' ),
851
  'mc_view_help' => __( 'View Help', 'my-calendar' )
852
  );
853
- $role_tabs = $role_container = '';
854
  foreach ( $roles as $role => $rolename ) {
855
  if ( $role == 'administrator' ) {
856
  continue;
857
  }
858
- $role_tabs .= "<li role='tab' id='tab_$role' aria-controls='mc_$role'><a href='#mc_$role'>$rolename</a></li>\n";
859
- $role_container .= "<div class='wptab mc_$role' aria-labelledby='tab_$role' role='tabpanel' id='mc_$role' aria-live='assertive'><fieldset id='mc_$role' class='roles'><legend>$rolename</legend>";
860
  $role_container .= "<input type='hidden' value='none' name='mc_caps[" . $role . "][none]' />
861
  <ul class='mc-settings checkboxes'>";
862
  foreach ( $caps as $cap => $name ) {
@@ -865,12 +872,7 @@ function edit_my_calendar_config() {
865
  $role_container .= "
866
  </ul></fieldset></div>\n";
867
  }
868
- echo "
869
- <ul class='tabs' role='tablist'>
870
- $role_tabs
871
- </ul>
872
- $role_container";
873
-
874
  ?>
875
  <p>
876
  <input type="submit" name="mc_permissions" class="button-primary"
@@ -882,14 +884,12 @@ function edit_my_calendar_config() {
882
  <?php } ?>
883
  </div>
884
  </div>
885
- </div>
886
 
887
- <div class="ui-sortable meta-box-sortables">
888
- <div class="postbox" id="my-calendar-email">
889
  <h3><?php _e( 'Calendar Email Settings', 'my-calendar' ); ?></h3>
890
 
891
  <div class="inside">
892
- <form method="post" action="<?php echo admin_url( "admin.php?page=my-calendar-config" ); ?>">
893
  <div><input type="hidden" name="_wpnonce"
894
  value="<?php echo wp_create_nonce( 'my-calendar-nonce' ); ?>"/></div>
895
  <fieldset>
22
  } else {
23
  $note = $aria = '';
24
  }
25
+ echo "<label for='$name'>$label</label> <input type='$type' id='$name' name='$name' value='" . esc_attr( $value ) . "'$aria$attributes /> $note";
26
  break;
27
  case 'textarea':
28
  if ( $note ) {
32
  } else {
33
  $note = $aria = '';
34
  }
35
+ echo "<label for='$name'>$label</label><br /><textarea id='$name' name='$name'$aria$attributes>" . esc_attr( $value ) . "</textarea>$note";
36
  break;
37
  case 'checkbox-single':
38
  $checked = mc_is_checked( $name, 'true', '', true );
54
  }
55
  foreach ( $label as $k => $v ) {
56
  $checked = ( $k == $value ) ? ' checked="checked"' : '';
57
+ $options .= "<li><input type='radio' id='$name-$k' value='" . esc_attr( $k ) . "' name='$name'$aria$attributes$checked /> <label for='$name-$k'>$v</label></li>";
58
  }
59
  echo "$options $note";
60
  break;
69
  if ( is_array( $default ) ) {
70
  foreach ( $default as $k => $v ) {
71
  $checked = ( $k == $value ) ? ' selected="selected"' : '';
72
+ $options .= "<option value='" . esc_attr( $k ) . "'$checked>$v</option>";
73
  }
74
  }
75
  echo "
194
  update_option( 'mc_api_enabled', $mc_api_enabled );
195
  update_option( 'mc_remote', $mc_remote );
196
  update_option( 'mc_default_sort', $_POST['mc_default_sort'] );
197
+ update_option( 'mc_default_direction', $_POST['mc_default_direction'] );
198
  if ( get_site_option( 'mc_multisite' ) == 2 ) {
199
  $mc_current_table = (int) $_POST['mc_current_table'];
200
  update_option( 'mc_current_table', $mc_current_table );
231
  }
232
  // output
233
  if ( isset( $_POST['mc_show_months'] ) ) {
234
+ $permalinks = get_option( 'mc_use_permalinks' );
235
  $mc_open_day_uri = ( ! empty( $_POST['mc_open_day_uri'] ) ) ? $_POST['mc_open_day_uri'] : '';
236
  update_option( 'mc_uri', $_POST['mc_uri'] );
237
  update_option( 'mc_use_permalinks', ( ! empty( $_POST['mc_use_permalinks'] ) ) ? 'true' : 'false' );
238
  update_option( 'mc_open_uri', ( ! empty( $_POST['mc_open_uri'] ) && $_POST['mc_open_uri'] == 'on' && get_option( 'mc_uri' ) != '' ) ? 'true' : 'false' );
239
  update_option( 'mc_mini_uri', $_POST['mc_mini_uri'] );
240
  update_option( 'mc_open_day_uri', $mc_open_day_uri );
 
241
  update_option( 'mc_display_author', ( ! empty( $_POST['mc_display_author'] ) && $_POST['mc_display_author'] == 'on' ) ? 'true' : 'false' );
242
  update_option( 'mc_show_event_vcal', ( ! empty( $_POST['mc_show_event_vcal'] ) && $_POST['mc_show_event_vcal'] == 'on' ) ? 'true' : 'false' );
243
  update_option( 'mc_show_gcal', ( ! empty( $_POST['mc_show_gcal'] ) && $_POST['mc_show_gcal'] == 'on' ) ? 'true' : 'false' );
269
  update_option( 'mc_gmap', ( ! empty( $_POST['mc_gmap'] ) && $_POST['mc_gmap'] == 'on' ) ? 'true' : 'false' );
270
  update_option( 'mc_show_address', ( ! empty( $_POST['mc_show_address'] ) && $_POST['mc_show_address'] == 'on' ) ? 'true' : 'false' );
271
  update_option( 'mc_hide_icons', ( ! empty( $_POST['mc_hide_icons'] ) && $_POST['mc_hide_icons'] == 'on' ) ? 'true' : 'false' );
 
272
  update_option( 'mc_apply_color', $_POST['mc_apply_color'] );
273
  update_option( 'mc_event_registration', ( ! empty( $_POST['mc_event_registration'] ) && $_POST['mc_event_registration'] == 'on' ) ? 'true' : 'false' );
274
  update_option( 'mc_inverse_color', ( ! empty( $_POST['mc_inverse_color'] ) && $_POST['mc_inverse_color'] == 'on' ) ? 'true' : 'false' );
277
  update_option( 'mc_process_shortcodes', ( ! empty( $_POST['mc_process_shortcodes'] ) && $_POST['mc_process_shortcodes'] == 'on' ) ? 'true' : 'false' );
278
  update_option( 'mc_event_link', ( ! empty( $_POST['mc_event_link'] ) && $_POST['mc_event_link'] == 'on' ) ? 'true' : 'false' );
279
  update_option( 'mc_show_weekends', ( ! empty( $_POST['mc_show_weekends'] ) && $_POST['mc_show_weekends'] == 'on' ) ? 'true' : 'false' );
280
+ update_option( 'mc_convert', ( ! empty( $_POST['mc_convert'] ) ) ? $_POST['mc_convert'] : 'false' );
281
+ if ( ( isset( $_POST['mc_use_permalinks'] ) && get_option( 'mc_use_permalinks' ) == 'true' ) && $permalinks != 'true' ) {
282
+ $url = admin_url( 'options-permalink.php#mc_cpt_base' );
283
+ $note = ' ' . sprintf( __( 'You activated My Calendar permalinks. Go to <a href="%s">permalink settings</a> to set the base URL for My Calendar Events.', 'my-calendar' ), $url );
284
+ } else {
285
+ $note = '';
286
+ }
287
+ echo "<div class=\"updated\"><p><strong>" . __( 'Output Settings saved', 'my-calendar' ) . "</strong>$note</p></div>";
 
 
 
 
 
288
  }
289
+ // INPUT
290
  if ( isset( $_POST['mc_input'] ) ) {
291
  $mc_input_options_administrators = ( ! empty( $_POST['mc_input_options_administrators'] ) && $_POST['mc_input_options_administrators'] == 'on' ) ? 'true' : 'false';
292
  $mc_input_options = array(
300
  'event_location' => ( ! empty( $_POST['mci_event_location'] ) && $_POST['mci_event_location'] ) ? 'on' : 'off',
301
  'event_location_dropdown' => ( ! empty( $_POST['mci_event_location_dropdown'] ) && $_POST['mci_event_location_dropdown'] ) ? 'on' : 'off',
302
  'event_specials' => ( ! empty( $_POST['mci_event_specials'] ) && $_POST['mci_event_specials'] ) ? 'on' : 'off',
303
+ 'event_access' => ( ! empty( $_POST['mci_event_access'] ) && $_POST['mci_event_access'] ) ? 'on' : 'off',
304
+ 'event_host' => ( ! empty( $_POST['mci_event_host'] ) && $_POST['mci_event_host'] ) ? 'on' : 'off'
305
  );
306
  update_option( 'mc_input_options', $mc_input_options );
307
  update_option( 'mc_input_options_administrators', $mc_input_options_administrators );
308
+ update_option( 'mc_skip_holidays', ( ! empty( $_POST['mc_skip_holidays'] ) && $_POST['mc_skip_holidays'] == 'on' ) ? 'true' : 'false' );
309
+ update_option( 'mc_no_fifth_week', ( ! empty( $_POST['mc_no_fifth_week'] ) && $_POST['mc_no_fifth_week'] == 'on' ) ? 'true' : 'false' );
310
+ update_option( 'mc_event_link_expires', ( ! empty( $_POST['mc_event_link_expires'] ) && $_POST['mc_event_link_expires'] == 'on' ) ? 'true' : 'false' );
311
+
312
  echo "<div class=\"updated\"><p><strong>" . __( 'Input Settings saved', 'my-calendar' ) . ".</strong></p></div>";
313
  }
314
  if ( current_user_can( 'manage_network' ) ) {
323
  // custom text
324
  if ( isset( $_POST['mc_previous_events'] ) ) {
325
  $mc_title_template = $_POST['mc_title_template'];
326
+ $mc_title_template_solo = $_POST['mc_title_template_solo'];
327
+ $mc_title_template_list = $_POST['mc_title_template_list'];
328
  $mc_details_label = $_POST['mc_details_label'];
329
  $mc_link_label = $_POST['mc_link_label'];
330
  $mc_event_title_template = $_POST['mc_event_title_template'];
337
  $mc_caption = $_POST['mc_caption'];
338
  $templates = get_option( 'mc_templates' );
339
  $templates['title'] = $mc_title_template;
340
+ $templates['title_solo'] = $mc_title_template_solo;
341
+ $templates['title_list'] = $mc_title_template_list;
342
  $templates['label'] = $mc_details_label;
343
  $templates['link'] = $mc_link_label;
344
  update_option( 'mc_templates', $templates );
350
  update_option( 'mc_caption', $mc_caption );
351
  update_option( 'mc_event_open', $mc_event_open );
352
  update_option( 'mc_event_closed', $mc_event_closed );
353
+ // date/time
354
+ update_option( 'mc_date_format', stripslashes( $_POST['mc_date_format'] ) );
355
+ update_option( 'mc_week_format', stripslashes( $_POST['mc_week_format'] ) );
356
+ update_option( 'mc_time_format', stripslashes( $_POST['mc_time_format'] ) );
357
+ update_option( 'mc_month_format', stripslashes( $_POST['mc_month_format'] ) );
358
+ $mc_ical_utc = ( ! empty( $_POST['mc_ical_utc'] ) && $_POST['mc_ical_utc'] == 'on' ) ? 'true' : 'false';
359
+ update_option( 'mc_ical_utc', $mc_ical_utc );
360
  echo "<div class=\"updated\"><p><strong>" . __( 'Custom text settings saved', 'my-calendar' ) . ".</strong></p></div>";
361
  }
362
  // Mail function by Roland
382
  apply_filters( 'mc_save_settings', '', $_POST );
383
 
384
  // pull templates for passing into functions.
385
+ $templates = get_option( 'mc_templates' );
386
+ $mc_title_template = ( isset( $templates['title'] ) ) ? esc_attr( stripslashes( $templates['title'] ) ) : '';
387
+ $mc_title_template_solo = ( isset( $templates['title_solo'] ) ) ? esc_attr( stripslashes( $templates['title_solo'] ) ) : '';
388
+ $mc_title_template_list = ( isset( $templates['title_list'] ) ) ? esc_attr( stripslashes( $templates['title_list'] ) ) : '';
389
+ $mc_details_label = ( isset( $templates['label'] ) ) ? esc_attr( stripslashes( $templates['label'] ) ) : '';
390
+ $mc_link_label = ( isset( $templates['link'] ) ) ? esc_attr( stripslashes( $templates['link'] ) ) : '';
391
  ?>
392
 
393
  <div class="wrap jd-my-calendar mc-settings-page" id="mc_settings">
394
  <?php my_calendar_check_db(); ?>
395
  <div id="icon-options-general" class="icon32"><br/></div>
396
+ <h2><?php _e( 'My Calendar Settings', 'my-calendar' ); ?></h2>
397
 
398
+ <div class="mc-tabs settings postbox-container jcd-wide">
399
  <div class="metabox-holder">
400
  <?php
401
  //update_option( 'ko_calendar_imported','false' ); // for testing importing.
428
  }
429
  }
430
  ?>
431
+ <ul class="tabs" role="tablist">
432
+ <li role="tab" id="tab_manage" aria-controls="my-calendar-manage"><a href="#my-calendar-manage"><?php _e( 'General', 'my-calendar' ); ?></a></li>
433
+ <li role="tab" id="tab_text" aria-controls="my-calendar-text"><a href="#my-calendar-text"><?php _e( 'Text', 'my-calendar' ); ?></a></li>
434
+ <li role="tab" id="tab_output" aria-controls="mc-output"><a href="#mc-output"><?php _e( 'Output', 'my-calendar' ); ?></a></li>
435
+ <li role="tab" id="tab_input" aria-controls="my-calendar-input"><a href="#my-calendar-input"><?php _e( 'Input', 'my-calendar' ); ?></a></li>
436
+ <?php if ( current_user_can( 'manage_network' ) ) { ?>
437
+ <li role="tab" id="tab_multi" aria-controls="my-calendar-multisite"><a href="#my-calendar-multisite"><?php _e( 'Multi-site', 'my-calendar' ); ?></a></li>
438
+ <?php } ?>
439
+ <li role="tab" id="tab_permissions" aria-controls="my-calendar-permissions"><a href="#my-calendar-permissions"><?php _e( 'Permissions', 'my-calendar' ); ?></a></li>
440
+ <li role="tab" id="tab_email" aria-controls="my-calendar-email"><a href="#my-calendar-email"><?php _e( 'Notifications', 'my-calendar' ); ?></a></li>
441
+ <?php echo apply_filters( 'mc_settings_section_links', '' ); ?>
442
+ </ul>
443
 
444
  <div class="ui-sortable meta-box-sortables">
445
+ <div class="wptab postbox" aria-labelledby="tab_manage" role="tabpanel" aria-live="assertive" id="my-calendar-manage">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
446
  <h3><?php _e( 'My Calendar Management', 'my-calendar' ); ?></h3>
447
 
448
  <div class="inside">
449
  <?php if ( current_user_can( 'administrator' ) ) { ?>
450
+ <form method="post" action="<?php echo admin_url( "admin.php?page=my-calendar-config#my-calendar-manage" ); ?>">
451
  <div><input type="hidden" name="_wpnonce"
452
  value="<?php echo wp_create_nonce( 'my-calendar-nonce' ); ?>"/></div>
453
  <fieldset>
479
  '6' => __( 'Category', 'my-calendar' ),
480
  '7' => __( 'Location Name', 'my-calendar' )
481
  ), '', array(), 'select' ); ?></li>
482
+ <li><?php mc_settings_field( 'mc_default_direction', __( 'Sort direction', 'my-calendar' ), array(
483
+ 'ASC' => __( 'Ascending', 'my-calendar' ),
484
+ 'DESC' => __( 'Descending', 'my-calendar' )
485
+ ), '', array(), 'select' ); ?></li>
486
  <?php
487
  if ( get_site_option( 'mc_multisite' ) == 2 && MY_CALENDAR_TABLE != MY_CALENDAR_GLOBAL_TABLE ) {
488
  mc_settings_field( 'mc_current_table', array(
508
  <?php } ?>
509
  </div>
510
  </div>
 
511
 
512
+ <div class="wptab postbox" aria-labelledby="tab_text" role="tabpanel" aria-live="assertive" id="my-calendar-text">
 
513
  <h3><?php _e( 'Text Settings', 'my-calendar' ); ?></h3>
514
 
515
  <div class="inside">
516
+ <form method="post" action="<?php echo admin_url( "admin.php?page=my-calendar-config#my-calendar-text" ); ?>">
517
  <div><input type="hidden" name="_wpnonce"
518
  value="<?php echo wp_create_nonce( 'my-calendar-nonce' ); ?>"/></div>
519
  <fieldset>
526
  <li><?php mc_settings_field( 'mc_event_closed', __( 'If events are closed', 'my-calendar' ), __( 'Registration is closed', 'my-calendar' ) ); ?></li>
527
  <li><?php mc_settings_field( 'mc_week_caption', __( 'Week view caption:', 'my-calendar' ), '', __( 'Available tag: <code>{date format=""}</code>', 'my-calendar' ) ); ?></li>
528
  <li><?php mc_settings_field( 'mc_caption', __( 'Extended caption:', 'my-calendar' ), '', __( 'Follows month/year in list views.', 'my-calendar' ) ); ?></li>
529
+ <li><?php mc_settings_field( 'mc_title_template', __( 'Event title (Grid)', 'my-calendar' ), $mc_title_template, "<a href='" . admin_url( "admin.php?page=my-calendar-help#templates" ) . "'>" . __( "Templating Help", 'my-calendar' ) . '</a>' ); ?></li>
530
+ <li><?php mc_settings_field( 'mc_title_template_solo', __( 'Event title (Single)', 'my-calendar' ), $mc_title_template_solo, "<a href='" . admin_url( "admin.php?page=my-calendar-help#templates" ) . "'>" . __( "Templating Help", 'my-calendar' ) . '</a>' ); ?></li>
531
+ <li><?php mc_settings_field( 'mc_title_template_list', __( 'Event title (List)', 'my-calendar' ), $mc_title_template_list, "<a href='" . admin_url( "admin.php?page=my-calendar-help#templates" ) . "'>" . __( "Templating Help", 'my-calendar' ) . '</a>' ); ?></li>
532
  <li><?php mc_settings_field( 'mc_details_label', __( 'Event details link text', 'my-calendar' ), $mc_details_label, __( 'Tags: <code>{title}</code>, <code>{location}</code>, <code>{color}</code>, <code>{icon}</code>, <code>{date}</code>, <code>{time}</code>.', 'my-calendar' ) ); ?></li>
533
  <li><?php mc_settings_field( 'mc_link_label', __( 'Event URL link text', 'my-calendar' ), $mc_link_label, "<a href='" . admin_url( "admin.php?page=my-calendar-help#templates" ) . "'>" . __( "Templating Help", 'my-calendar' ) . '</a>' ); ?></li>
534
  <li><?php mc_settings_field( 'mc_event_title_template', __( 'Title element template', 'my-calendar' ), '{title} &raquo; {date}', __( 'Current: %s', 'my-calendar' ) ); ?></li>
535
  </ul>
536
  </fieldset>
537
+ <fieldset>
538
+ <legend><?php _e( 'Date/Time formats', 'my-calendar' ); ?></legend>
539
+ <div><input type='hidden' name='mc_dates' value='true'/></div>
540
+ <ul>
541
+ <?php
542
+ $month_format = ( get_option( 'mc_month_format' ) == '' ) ? date_i18n( 'F Y' ) : date_i18n( get_option( 'mc_month_format' ) );
543
+ $time_format = ( get_option( 'mc_time_format' ) == '' ) ? date_i18n( get_option( 'time_format' ) ) : date_i18n( get_option( 'mc_time_format' ) );
544
+ $week_format = ( get_option( 'mc_week_format' ) == '' ) ? date_i18n( 'M j, \'y' ) : date_i18n( get_option( 'mc_week_format' ) );
545
+ $date_format = ( get_option( 'mc_date_format' ) == '' ) ? date_i18n( get_option( 'date_format' ) ) : date_i18n( get_option( 'mc_date_format' ) );
546
+ ?>
547
+ <li><?php mc_settings_field( 'mc_month_format', __( 'Month format (calendar headings)', 'my-calendar' ), '', $month_format ); ?></li>
548
+ <li><?php mc_settings_field( 'mc_time_format', __( 'Time format', 'my-calendar' ), '', $time_format ); ?></li>
549
+ <li><?php mc_settings_field( 'mc_week_format', __( 'Date in grid mode, week view', 'my-calendar' ), '', $week_format ); ?></li>
550
+ <li><?php mc_settings_field( 'mc_date_format', __( 'Date Format in other views', 'my-calendar' ), '', $date_format ); ?></li>
551
+ <li><?php mc_settings_field( 'mc_ical_utc', __( 'iCal times are UTC', 'my-calendar' ), '', '', array(), 'checkbox-single' ); ?></li>
552
+ </ul>
553
+ </fieldset>
554
  <p>
555
  <input type="submit" name="save" class="button-primary"
556
  value="<?php _e( 'Save Custom Text Settings', 'my-calendar' ); ?>"/>
557
  </p>
558
  </form>
559
+ <p>
560
+ <?php _e( 'Date formats use syntax from the <a href="http://php.net/date">PHP <code>date()</code> function</a>. Save to update sample output.', 'my-calendar' ); ?>
561
+ </p>
562
  </div>
563
  </div>
 
564
 
565
+ <div class="wptab postbox" aria-labelledby="tab_output" role="tabpanel" aria-live="assertive" id="mc-output">
 
566
  <h3><?php _e( 'Output Settings', 'my-calendar' ); ?></h3>
567
 
568
  <div class="inside">
569
+ <form method="post" action="<?php echo admin_url( "admin.php?page=my-calendar-config#mc-output" ); ?>">
570
  <div><input type="hidden" name="_wpnonce"
571
  value="<?php echo wp_create_nonce( 'my-calendar-nonce' ); ?>"/></div>
572
+ <input type="submit" name="save" class="button screen-reader-text" value="<?php _e( 'Save Output Settings', 'my-calendar' ); ?>" /></p>
573
  <fieldset>
574
  <legend><?php _e( 'Calendar Link Targets', 'my-calendar' ); ?></legend>
575
  <ul>
 
576
  <?php $guess = mc_guess_calendar(); ?>
577
+ <li><?php mc_settings_field( 'mc_uri', __( 'Where is your main calendar page?', 'my-calendar' ), '', "$guess[message]", array( 'size' => '60' ), 'url' ); ?></li>
578
+ <li><?php mc_settings_field( 'mc_use_permalinks', __( 'Use Pretty Permalinks for Events','my-calendar' ), '', '', array(), 'checkbox-single' ); ?></li>
579
  <li><?php mc_settings_field( 'mc_open_uri', __( 'Open calendar links to event details URL', 'my-calendar' ), '', '', array(), 'checkbox-single' ); ?></li>
580
+ <li><?php mc_settings_field( 'mc_mini_uri', __( 'Target <abbr title="Uniform resource locator">URL</abbr> for mini calendar date links:', 'my-calendar' ), '', '', array( 'size' => '60' ), 'url' ); ?></li>
581
  <?php
582
  $disabled = ( ! get_option( 'mc_uri' ) && ! get_option( 'mc_mini_uri' ) ) ? array( 'disabled' => 'disabled' ) : array();
583
  ?>
592
  </fieldset>
593
 
594
  <fieldset>
595
+ <legend><?php _e( 'Grid Options', 'my-calendar' ); ?></legend>
596
+ <ul>
597
+ <li><?php mc_settings_field( 'mc_show_weekends', __( 'Show Weekends on Calendar', 'my-calendar' ), '', '', array(), 'checkbox-single' ); ?></li>
598
+ <li><?php mc_settings_field( 'mc_convert', array(
599
+ 'true' => __( 'Switch to list view on mobile devices', 'my-calendar' ),
600
+ 'mini' => __( 'Switch to mini calendar on mobile devices', 'my-calendar' )
601
+ ), 'false', '', array(), 'radio' ); ?></li>
602
+ </ul>
603
+ </fieldset>
604
+ <fieldset>
605
+ <legend><?php _e( 'List Options', 'my-calendar' ); ?></legend>
606
+ <ul>
607
+ <li><?php mc_settings_field( 'mc_show_months', __( 'How many months of events to show at a time:', 'my-calendar' ), '', '', array( 'size' => '3' ), 'text' ); ?></li>
608
+ <li><?php mc_settings_field( 'mc_show_list_info', __( 'Show the first event\'s title and the number of events that day next to the date.', 'my-calendar' ), '', '', array(), 'checkbox-single' ); ?></li>
609
+ </ul>
610
+ </fieldset>
611
+ <fieldset>
612
+ <legend><?php _e( 'Re-order calendar layout', 'my-calendar' ); ?></legend>
613
  <?php
614
  $topnav = explode( ',', get_option( 'mc_topnav' ) );
615
  $calendar = array( 'calendar' );
629
  echo "<div id='mc-sortable-update' aria-live='assertive'></div>";
630
  echo "<ul id='mc-sortable'>";
631
  $inserted = array();
632
+ $class = 'visible';
633
+ $count = count( $nav_elements );
634
+ $i = 1;
635
  foreach ( $order as $k ) {
636
  $k = trim( $k );
637
  $v = ( isset( $nav_elements[ $k ] ) ) ? $nav_elements[ $k ] : false;
638
  if ( $v !== false ) {
639
  $inserted[ $k ] = $v;
640
+ if ( $k == 'stop' ) {
641
+ $label = 'hide';
642
+ } else {
643
+ $label = $k;
644
+ }
645
+
646
+ if ( $i == 1 ) {
647
+ $buttons = "<button class='down'><i class='dashicons dashicons-arrow-down'></i><span class='screen-reader-text'>Down</span></button>";
648
+ } else {
649
+ if ( $i == $count ) {
650
+ $buttons = "<button class='up'><i class='dashicons dashicons-arrow-up'></i><span class='screen-reader-text'>Up</span></button>";
651
+ } else {
652
+ $buttons = "<button class='up'><i class='dashicons dashicons-arrow-up'></i><span class='screen-reader-text'>Up</span></button> <button class='down'><i class='dashicons dashicons-arrow-down'></i><span class='screen-reader-text'>Down</span></button>";
653
+ }
654
+ }
655
+ $buttons = "<div class='mc-buttons'>$buttons</div>";
656
+ echo "<li class='ui-state-default mc-$k mc-$class'>$buttons <code>$label</code> $v <input type='hidden' name='mc_nav[]' value='$k' /></li>";
657
+ $i++;
658
  }
659
  }
660
  $missed = array_diff( $nav_elements, $inserted );
661
+ $i = 1;
662
+ $count = count( $missed );
663
  foreach ( $missed as $k => $v ) {
664
+ if ( $i != $count ) {
665
+ $buttons = "<button class='up'><i class='dashicons dashicons-arrow-up'></i><span class='screen-reader-text'>Up</span></button> <button class='down'><i class='dashicons dashicons-arrow-down'></i><span class='screen-reader-text'>Down</span></button>";
666
+ } else {
667
+ $buttons = "<button class='up'><i class='dashicons dashicons-arrow-up'></i><span class='screen-reader-text'>Up</span></button>";
668
+ }
669
+ $buttons = "<div class='mc-buttons'>$buttons</div>";
670
+ echo "<li class='ui-state-default mc-$k mc-hidden'>$buttons <code>$k</code> $v <input type='hidden' name='mc_nav[]' value='$k' /></li>";
671
+ $i++;
672
  }
673
 
674
  echo "</ul>";
676
  </fieldset>
677
 
678
  <fieldset>
679
+ <legend><?php _e( 'Single Event Details', 'my-calendar' ); ?></legend>
680
+ <p><?php _e( 'Custom templates override these settings.', 'my-calendar' ); ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
681
  <ul class="checkboxes">
682
  <li><?php mc_settings_field( 'mc_display_author', __( 'Author\'s name', 'my-calendar' ), '', '', array(), 'checkbox-single' ); ?></li>
683
  <li><?php mc_settings_field( 'mc_show_event_vcal', __( 'Link to single event iCal download', 'my-calendar' ), '', '', array(), 'checkbox-single' ); ?></li>
693
  </ul>
694
  </fieldset>
695
  <fieldset>
696
+ <legend><?php _e( 'Category Colors', 'my-calendar' ); ?></legend>
697
  <ul class='checkboxes'>
698
  <?php mc_settings_field( 'mc_apply_color', array(
699
  'default' => __( 'No category colors with titles.', 'my-calendar' ),
705
  </ul>
706
  <?php // End Event Options // ?>
707
  </fieldset>
 
 
 
 
 
 
 
 
 
708
  <p><input type="submit" name="save" class="button-primary"
709
  value="<?php _e( 'Save Output Settings', 'my-calendar' ); ?>"/></p>
710
  </form>
711
  </div>
712
  </div>
713
+
714
+ <div class="wptab postbox" aria-labelledby="tab_input" role="tabpanel" aria-live="assertive" id="my-calendar-input">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
715
  <h3><?php _e( 'Calendar Input Fields', 'my-calendar' ); ?></h3>
716
 
717
  <div class="inside">
718
+ <form method="post" action="<?php echo admin_url( "admin.php?page=my-calendar-config#my-calendar-input" ); ?>">
719
  <div><input type="hidden" name="_wpnonce"
720
  value="<?php echo wp_create_nonce( 'my-calendar-nonce' ); ?>"/></div>
721
  <fieldset>
735
  'event_open' => __( 'Event Registration options', 'my-calendar' ),
736
  'event_location' => __( 'Event Location fields', 'my-calendar' ),
737
  'event_specials' => __( 'Set Special Scheduling options', 'my-calendar' ),
738
+ 'event_access' => __( 'Event Accessibility', 'my-calendar' ),
739
+ 'event_host' => __( 'Event Host', 'my-calendar' )
740
  );
741
  $output = '';
742
  // if input options isn't an array, we'll assume that this plugin wasn't upgraded properly, and reset them to the default.
752
  'event_location' => 'off',
753
  'event_location_dropdown' => 'on',
754
  'event_specials' => 'on',
755
+ 'event_access' => 'on',
756
+ 'event_host' => 'on'
757
  ) );
758
  $input_options = get_option( 'mc_input_options' );
759
  }
768
  <li><?php mc_settings_field( 'mc_input_options_administrators', __( 'Administrators see all input options', 'my-calendar' ), '', '', array(), 'checkbox-single' ); ?></li>
769
  </ul>
770
  </fieldset>
771
+ <fieldset>
772
+ <legend><?php _e( 'Event Scheduling Defaults', 'my-calendar' ); ?></legend>
773
+ <ul>
774
+ <li><?php mc_settings_field( 'mc_event_link_expires', __( 'Event links expire after event passes.', 'my-calendar' ), '', '', array(), 'checkbox-single' ); ?></li>
775
+ <li><?php mc_settings_field( 'mc_no_fifth_week', __( 'If a recurring event falls on a date that doesn\'t exist (like the 5th Wednesday in February), move it back one week.', 'my-calendar' ), '', '', array(), 'checkbox-single' ); ?></li>
776
+ <li><?php mc_settings_field( 'mc_skip_holidays', __( 'If an event coincides with an event in the designated "Holiday" category, do not show the event.', 'my-calendar' ), '', '', array(), 'checkbox-single' ); ?></li>
777
+ </ul>
778
+ <?php // End Scheduling Options // ?>
779
+ </fieldset>
780
  <p>
781
  <input type="submit" name="save" class="button-primary"
782
  value="<?php _e( 'Save Input Settings', 'my-calendar' ); ?>"/>
784
  </form>
785
  </div>
786
  </div>
 
787
 
788
  <?php if ( current_user_can( 'manage_network' ) ) { ?>
789
+ <div class="wptab postbox" aria-labelledby="tab_multi" role="tabpanel" aria-live="assertive" id="my-calendar-multisite">
 
790
  <h3><?php _e( 'Multisite Settings (Network Administrators only)', 'my-calendar' ); ?></h3>
791
 
792
  <div class="inside">
793
+ <p><?php _e( 'The central calendar is the calendar associated with the primary site in your WordPress Multisite network.', 'my-calendar' ); ?></p>
794
+ <form method="post" action="<?php echo admin_url( "admin.php?page=my-calendar-config#my-calendar-multisite" ); ?>">
795
+ <div>
796
+ <input type="hidden" name="_wpnonce" value="<?php echo wp_create_nonce( 'my-calendar-nonce' ); ?>"/>
797
+ <input type='hidden' name='mc_network' value='true'/>
798
+ </div>
799
  <fieldset>
800
  <legend><?php _e( 'WP MultiSite configurations', 'my-calendar' ); ?></legend>
 
801
  <ul>
802
+ <li>
803
+ <input type="radio" value="0" id="ms0" name="mc_multisite"<?php echo jd_option_selected( get_site_option( 'mc_multisite' ), '0' ); ?> /> <label for="ms0"><?php _e( 'Site owners may only post to their local calendar', 'my-calendar' ); ?></label>
 
 
804
  </li>
805
+ <li>
806
+ <input type="radio" value="1" id="ms1" name="mc_multisite"<?php echo jd_option_selected( get_site_option( 'mc_multisite' ), '1' ); ?> /> <label for="ms1"><?php _e( 'Site owners may only post to the central calendar', 'my-calendar' ); ?></label>
 
 
807
  </li>
808
+ <li>
809
+ <input type="radio" value="2" id="ms2" name="mc_multisite"<?php echo jd_option_selected( get_site_option( 'mc_multisite' ), 2 ); ?> /> <label for="ms2"><?php _e( 'Site owners may manage either calendar', 'my-calendar' ); ?></label>
 
 
810
  </li>
811
  </ul>
812
  <p class="notice">
832
  </form>
833
  </div>
834
  </div>
 
835
  <?php } ?>
836
 
837
+ <div class="wptab postbox" aria-labelledby="tab_permissions" role="tabpanel" aria-live="assertive" id="my-calendar-permissions">
 
838
  <h3><?php _e( 'My Calendar Permissions', 'my-calendar' ); ?></h3>
839
 
840
+ <div class="inside">
841
  <?php if ( current_user_can( 'administrator' ) ) { ?>
842
 
843
+ <form method="post" action="<?php echo admin_url( "admin.php?page=my-calendar-config#my-calendar-permissions" ); ?>">
844
  <div><input type="hidden" name="_wpnonce"
845
  value="<?php echo wp_create_nonce( 'my-calendar-nonce' ); ?>"/></div>
846
  <?php
858
  'mc_edit_settings' => __( 'Edit Settings', 'my-calendar' ),
859
  'mc_view_help' => __( 'View Help', 'my-calendar' )
860
  );
861
+ $role_container = '';
862
  foreach ( $roles as $role => $rolename ) {
863
  if ( $role == 'administrator' ) {
864
  continue;
865
  }
866
+ $role_container .= "<div class='mc_$role mc_permissions' id='mc_$role'><fieldset id='mc_$role' class='roles'><legend>$rolename</legend>";
 
867
  $role_container .= "<input type='hidden' value='none' name='mc_caps[" . $role . "][none]' />
868
  <ul class='mc-settings checkboxes'>";
869
  foreach ( $caps as $cap => $name ) {
872
  $role_container .= "
873
  </ul></fieldset></div>\n";
874
  }
875
+ echo "$role_container";
 
 
 
 
 
876
  ?>
877
  <p>
878
  <input type="submit" name="mc_permissions" class="button-primary"
884
  <?php } ?>
885
  </div>
886
  </div>
 
887
 
888
+ <div class="wptab postbox" aria-labelledby="tab_email" role="tabpanel" aria-live="assertive" id="my-calendar-email">
 
889
  <h3><?php _e( 'Calendar Email Settings', 'my-calendar' ); ?></h3>
890
 
891
  <div class="inside">
892
+ <form method="post" action="<?php echo admin_url( "admin.php?page=my-calendar-config#my-calendar-email" ); ?>">
893
  <div><input type="hidden" name="_wpnonce"
894
  value="<?php echo wp_create_nonce( 'my-calendar-nonce' ); ?>"/></div>
895
  <fieldset>
my-calendar-shortcodes.php CHANGED
@@ -13,10 +13,13 @@ function my_calendar_insert( $atts, $content = null ) {
13
  'lvalue' => '',
14
  'author' => 'all',
15
  'host' => 'all',
16
- 'id' => 'jd-calendar',
17
  'template' => '',
18
  'above' => '',
19
- 'below' => ''
 
 
 
20
  ), $atts, 'my_calendar' ) );
21
  if ( $format != 'mini' ) {
22
  if ( isset( $_GET['format'] ) ) {
@@ -31,7 +34,7 @@ function my_calendar_insert( $atts, $content = null ) {
31
  $host = apply_filters( 'mc_display_host', $user_ID, 'main' );
32
  }
33
 
34
- return my_calendar( $name, $format, $category, $time, $ltype, $lvalue, $id, $template, $content, $author, $host, $above, $below );
35
  }
36
 
37
  function my_calendar_insert_upcoming( $atts ) {
@@ -48,7 +51,9 @@ function my_calendar_insert_upcoming( $atts ) {
48
  'author' => 'default',
49
  'host' => 'default',
50
  'ltype' => '',
51
- 'lvalue' => ''
 
 
52
  ), $atts, 'my_calendar_upcoming' ) );
53
  global $user_ID;
54
  if ( $author == 'current' ) {
@@ -58,7 +63,7 @@ function my_calendar_insert_upcoming( $atts ) {
58
  $host = apply_filters( 'mc_display_host', $user_ID, 'upcoming' );
59
  }
60
 
61
- return my_calendar_upcoming_events( $before, $after, $type, $category, $template, $fallback, $order, $skip, $show_today, $author, $host, $ltype, $lvalue );
62
  }
63
 
64
  function my_calendar_insert_today( $atts ) {
@@ -67,7 +72,8 @@ function my_calendar_insert_today( $atts ) {
67
  'author' => 'default',
68
  'host' => 'default',
69
  'template' => 'default',
70
- 'fallback' => ''
 
71
  ), $atts, 'my_calendar_today' ) );
72
  global $user_ID;
73
  if ( $author == 'current' ) {
@@ -77,7 +83,7 @@ function my_calendar_insert_today( $atts ) {
77
  $host = apply_filters( 'mc_display_host', $user_ID, 'today' );
78
  }
79
 
80
- return my_calendar_todays_events( $category, $template, $fallback, $author, $host );
81
  }
82
 
83
  function my_calendar_locations( $atts ) {
13
  'lvalue' => '',
14
  'author' => 'all',
15
  'host' => 'all',
16
+ 'id' => '',
17
  'template' => '',
18
  'above' => '',
19
+ 'below' => '',
20
+ 'year' => false,
21
+ 'month' => false,
22
+ 'day' => false
23
  ), $atts, 'my_calendar' ) );
24
  if ( $format != 'mini' ) {
25
  if ( isset( $_GET['format'] ) ) {
34
  $host = apply_filters( 'mc_display_host', $user_ID, 'main' );
35
  }
36
 
37
+ return my_calendar( $name, $format, $category, $time, $ltype, $lvalue, $id, $template, $content, $author, $host, $above, $below, $year, $month, $day );
38
  }
39
 
40
  function my_calendar_insert_upcoming( $atts ) {
51
  'author' => 'default',
52
  'host' => 'default',
53
  'ltype' => '',
54
+ 'lvalue' => '',
55
+ 'from' => false,
56
+ 'to' => false
57
  ), $atts, 'my_calendar_upcoming' ) );
58
  global $user_ID;
59
  if ( $author == 'current' ) {
63
  $host = apply_filters( 'mc_display_host', $user_ID, 'upcoming' );
64
  }
65
 
66
+ return my_calendar_upcoming_events( $before, $after, $type, $category, $template, $fallback, $order, $skip, $show_today, $author, $host, $ltype, $lvalue, $from, $to );
67
  }
68
 
69
  function my_calendar_insert_today( $atts ) {
72
  'author' => 'default',
73
  'host' => 'default',
74
  'template' => 'default',
75
+ 'fallback' => '',
76
+ 'date' => false
77
  ), $atts, 'my_calendar_today' ) );
78
  global $user_ID;
79
  if ( $author == 'current' ) {
83
  $host = apply_filters( 'mc_display_host', $user_ID, 'today' );
84
  }
85
 
86
+ return my_calendar_todays_events( $category, $template, $fallback, $author, $host, $date );
87
  }
88
 
89
  function my_calendar_locations( $atts ) {
my-calendar-styles.php CHANGED
@@ -98,6 +98,9 @@ function mc_write_styles( $stylefile, $my_calendar_style ) {
98
  }
99
 
100
  function edit_my_calendar_styles() {
 
 
 
101
  $dir = plugin_dir_path( __FILE__ );
102
  if ( isset( $_POST['mc_edit_style'] ) ) {
103
  $nonce = $_REQUEST['_wpnonce'];
@@ -193,7 +196,7 @@ function edit_my_calendar_styles() {
193
  if ( $path['extension'] == 'css' ) {
194
  $test = "mc_custom_" . $value;
195
  $selected = ( get_option( 'mc_css_file' ) == $test ) ? " selected='selected'" : "";
196
- echo "<option value='" . esc_attr( 'mc_custom_' . $value ) . "'$selected>$value</option>\n";
197
  }
198
  }
199
  echo "</optgroup>";
@@ -205,7 +208,7 @@ function edit_my_calendar_styles() {
205
  $path = pathinfo( $filepath );
206
  if ( $path['extension'] == 'css' ) {
207
  $selected = ( get_option( 'mc_css_file' ) == $value ) ? " selected='selected'" : "";
208
- echo "<option value='" . esc_attr( $value ) . "'$selected>$value</option>\n";
209
  }
210
  }
211
  echo "</optgroup>"; ?>
@@ -237,7 +240,7 @@ function edit_my_calendar_styles() {
237
  name="reset_styles" <?php if ( mc_is_custom_style( get_option( 'mc_css_file' ) ) ) {
238
  echo "disabled='disabled'";
239
  } ?> /> <label
240
- for="reset_styles"><?php _e( 'Restore My Calendar stylesheet', 'my-calendar' ); ?></label>
241
  <input type="checkbox" id="use_styles"
242
  name="use_styles" <?php mc_is_checked( 'mc_use_styles', 'true' ); ?> />
243
  <label
@@ -245,7 +248,7 @@ function edit_my_calendar_styles() {
245
  </p>
246
  <p>
247
  <?php if ( mc_is_custom_style( get_option( 'mc_css_file' ) ) ) {
248
- _e( 'The editor is not available for custom CSS files. You should edit your custom CSS locally, then upload your changes.', 'my-calendar' );
249
  } else {
250
  ?>
251
  <label
@@ -269,9 +272,10 @@ function edit_my_calendar_styles() {
269
  if ( $right_string ) { // if right string is blank, there is no default
270
  if ( isset( $_GET['diff'] ) ) {
271
  echo '<div class="wrap jd-my-calendar" id="diff">';
272
- echo wp_text_diff( $left_string, $right_string, array( 'title' => __( 'Comparing Your Style with latest installed version of My Calendar', 'my-calendar' ),
273
- 'title_right' => __( 'Latest (from plugin)', 'my-calendar' ),
274
- 'title_left' => __( 'Current (in use)', 'my-calendar' )
 
275
  ) );
276
  echo '</div>';
277
  } else if ( trim( $left_string ) != trim( $right_string ) ) {
@@ -293,4 +297,50 @@ function edit_my_calendar_styles() {
293
  </div>
294
  <?php mc_show_sidebar(); ?>
295
  </div><?php
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
296
  }
98
  }
99
 
100
  function edit_my_calendar_styles() {
101
+ if ( defined( 'DISALLOW_FILE_EDIT' ) && DISALLOW_FILE_EDIT == true ) {
102
+ exit;
103
+ }
104
  $dir = plugin_dir_path( __FILE__ );
105
  if ( isset( $_POST['mc_edit_style'] ) ) {
106
  $nonce = $_REQUEST['_wpnonce'];
196
  if ( $path['extension'] == 'css' ) {
197
  $test = "mc_custom_" . $value;
198
  $selected = ( get_option( 'mc_css_file' ) == $test ) ? " selected='selected'" : "";
199
+ echo "<option value='mc_custom_$value'$selected>$value</option>\n";
200
  }
201
  }
202
  echo "</optgroup>";
208
  $path = pathinfo( $filepath );
209
  if ( $path['extension'] == 'css' ) {
210
  $selected = ( get_option( 'mc_css_file' ) == $value ) ? " selected='selected'" : "";
211
+ echo "<option value='$value'$selected>$value</option>\n";
212
  }
213
  }
214
  echo "</optgroup>"; ?>
240
  name="reset_styles" <?php if ( mc_is_custom_style( get_option( 'mc_css_file' ) ) ) {
241
  echo "disabled='disabled'";
242
  } ?> /> <label
243
+ for="reset_styles"><?php _e( 'Reset to default', 'my-calendar' ); ?></label>
244
  <input type="checkbox" id="use_styles"
245
  name="use_styles" <?php mc_is_checked( 'mc_use_styles', 'true' ); ?> />
246
  <label
248
  </p>
249
  <p>
250
  <?php if ( mc_is_custom_style( get_option( 'mc_css_file' ) ) ) {
251
+ _e( 'The editor is not available for custom CSS files. Edit your custom CSS locally, then upload your changes.', 'my-calendar' );
252
  } else {
253
  ?>
254
  <label
272
  if ( $right_string ) { // if right string is blank, there is no default
273
  if ( isset( $_GET['diff'] ) ) {
274
  echo '<div class="wrap jd-my-calendar" id="diff">';
275
+ echo mc_text_diff( $left_string, $right_string, array(
276
+ 'title' => __( 'Comparing Your Style with latest installed version of My Calendar', 'my-calendar' ),
277
+ 'title_right' => __( 'Latest (from plugin)', 'my-calendar' ),
278
+ 'title_left' => __( 'Current (in use)', 'my-calendar' )
279
  ) );
280
  echo '</div>';
281
  } else if ( trim( $left_string ) != trim( $right_string ) ) {
297
  </div>
298
  <?php mc_show_sidebar(); ?>
299
  </div><?php
300
+ }
301
+
302
+ // fixed wp_text_diff
303
+ function mc_text_diff( $left_string, $right_string, $args = null ) {
304
+ $defaults = array( 'title' => '', 'title_left' => '', 'title_right' => '' );
305
+ $args = wp_parse_args( $args, $defaults );
306
+
307
+ if ( !class_exists( 'WP_Text_Diff_Renderer_Table' ) )
308
+ require( ABSPATH . WPINC . '/wp-diff.php' );
309
+
310
+ $left_string = normalize_whitespace($left_string);
311
+ $right_string = normalize_whitespace($right_string);
312
+
313
+ $left_lines = explode("\n", $left_string);
314
+ $right_lines = explode("\n", $right_string);
315
+ $text_diff = new Text_Diff($left_lines, $right_lines);
316
+ $renderer = new WP_Text_Diff_Renderer_Table( $args );
317
+ $diff = $renderer->render($text_diff);
318
+ $r = '';
319
+
320
+ if ( !$diff )
321
+ return '';
322
+ if ( $args['title'] ) {
323
+ $r .= "<h3>$args[title]</h3>\n";
324
+ }
325
+
326
+ $r .= "<table class='diff'>\n";
327
+ $r .= "<col class='content diffsplit left' /><col class='content diffsplit middle' /><col class='content diffsplit right' />";
328
+
329
+
330
+ if ( $args['title'] || $args['title_left'] || $args['title_right'] )
331
+ $r .= "<thead>";
332
+
333
+ if ( $args['title_left'] || $args['title_right'] ) {
334
+ $r .= "<tr class='diff-sub-title'>\n";
335
+ $r .= "\t<th scope='col'>$args[title_left]</th><td></td>\n";
336
+ $r .= "\t<th scope='col'>$args[title_right]</th>\n";
337
+ $r .= "</tr>\n";
338
+ }
339
+ if ( $args['title'] || $args['title_left'] || $args['title_right'] )
340
+ $r .= "</thead>\n";
341
+
342
+ $r .= "<tbody>\n$diff\n</tbody>\n";
343
+ $r .= "</table>";
344
+
345
+ return $r;
346
  }
my-calendar-templates.php CHANGED
@@ -20,7 +20,7 @@ function jd_draw_template( $array, $template, $type = 'list' ) {
20
  }
21
  }
22
  if ( strpos( $template, "{" . $key . " " ) !== false ) { // only do preg_match if appropriate
23
- preg_match_all( '/{' . $key . '\b(?>\s+(?:before="([^"]*)"|after="([^"]*)"|format="([^"]*)")|[^\s]+|\s+){0,2}}/', $template, $matches, PREG_PATTERN_ORDER );
24
  if ( $matches ) {
25
  $number = count( $matches[0] );
26
  for ( $i=0; $i<=$number; $i++ ) {
@@ -208,7 +208,7 @@ function mc_hcard( $event, $address = 'true', $map = 'true', $source = 'event',
208
  }
209
  $hcard .= "</div>";
210
 
211
- return apply_filters( 'mt_hcard', $hcard, $event, $address, $map, $source, $context );
212
  }
213
 
214
  // Produces the array of event details used for drawing templates
@@ -227,23 +227,24 @@ function mc_create_tags( $event, $context = 'filters' ) {
227
  $e['access'] = mc_expand( get_post_meta( $event->event_post, '_mc_event_access', true ) );
228
 
229
  // date & time fields
 
230
  $dtstart = mc_format_timestamp( strtotime( $event->occur_begin ) );
231
- $dtend = mc_format_timestamp( strtotime( $event->occur_end ) );
232
 
233
- $real_end_date = $event->occur_end;
234
  $e['date_utc'] = date_i18n( apply_filters( 'mc_date_format', $date_format, 'template_begin_ts' ), $event->ts_occur_begin );
235
  $e['date_end_utc'] = date_i18n( apply_filters( 'mc_date_format', $date_format, 'template_end_ts' ), $event->ts_occur_end );
236
- $e['time'] = ( date( 'H:i:s', strtotime( $event->occur_begin ) ) == '00:00:00' ) ? get_option( 'mc_notime_text' ) : date( get_option( 'mc_time_format' ), strtotime( $event->occur_begin ) );
237
- $e['time24'] = ( date( 'G:i', strtotime( $event->occur_begin ) ) == '00:00:00' ) ? get_option( 'mc_notime_text' ) : date( get_option( 'mc_time_format' ), strtotime( $event->occur_begin ) );
238
- $endtime = date( 'H:i:s', strtotime( $event->occur_end ) );
239
- $e['endtime'] = ( $event->occur_end == $event->occur_begin || $event->event_hide_end == 1 ) ? '' : date_i18n( get_option( 'mc_time_format' ), strtotime( $endtime ) );
 
240
  $e['runtime'] = mc_runtime( $event->ts_occur_begin, $event->ts_occur_end, $event );
241
  $e['dtstart'] = date( 'Y-m-d\TH:i:s', strtotime( $event->occur_begin ) );// hcal formatted
242
- $e['dtend'] = date( 'Y-m-d\TH:i:s', strtotime( $event->occur_end ) ); //hcal formatted end
243
  $e['rssdate'] = date( 'D, d M Y H:i:s +0000', strtotime( $event->event_added ) );
244
  $date = date_i18n( apply_filters( 'mc_date_format', $date_format, 'template_begin' ), strtotime( $event->occur_begin ) );
245
  $date_end = date_i18n( apply_filters( 'mc_date_format', $date_format, 'template_end' ), strtotime( $real_end_date ) );
246
- $date_arr = array( 'occur_begin' => $event->occur_begin, 'occur_end' => $event->occur_end );
247
  $date_obj = (object) $date_arr;
248
  if ( $event->event_span == 1 ) {
249
  $dates = mc_event_date_span( $event->event_group_id, $event->event_span, array( 0 => $date_obj ) );
@@ -253,7 +254,7 @@ function mc_create_tags( $event, $context = 'filters' ) {
253
  $e['date'] = ( $event->event_span != 1 ) ? $date : mc_format_date_span( $dates, 'simple', $date );
254
  $e['enddate'] = $date_end;
255
  $e['daterange'] = ( $date == $date_end ) ? $date : "<span class='mc_db'>$date</span> <span>&ndash;</span> <span class='mc_de'>$date_end</span>";
256
- $e['timerange'] = ( ( $e['time'] == $e['endtime'] ) || $event->event_hide_end == 1 ) ? $e['time'] : "<span class='mc_tb'>" . $e['time'] . "</span> <span>&ndash;</span> <span class='mc_te'>" . $e['endtime'] . "</span>";
257
  $e['datespan'] = ( $event->event_span == 1 || ( $e['date'] != $e['enddate'] ) ) ? mc_format_date_span( $dates ) : $date;
258
  $e['multidate'] = mc_format_date_span( $dates, 'complex', "<span class='fallback-date'>$date</span><span class='separator'>,</span> <span class='fallback-time'>$e[time]</span>&ndash;<span class='fallback-endtime'>$e[endtime]</span>" );
259
  $e['began'] = $event->event_begin; // returns date of first occurrence of an event.
@@ -261,11 +262,13 @@ function mc_create_tags( $event, $context = 'filters' ) {
261
  $e['repeats'] = $event->event_repeats;
262
 
263
  // category fields
264
- $e['cat_id'] = $event->event_category;
265
- $e['category'] = stripslashes( $event->category_name );
266
- $e['icon'] = mc_category_icon( $event, 'img' );
267
- $e['icon_html'] = "<img src='$e[icon]' class='mc-category-icon' alt='" . __( 'Category', 'my-calendar' ) . ": " . esc_attr( $event->category_name ) . "' />";
268
- $e['color'] = $event->category_color;
 
 
269
 
270
  // special
271
  $e['skip_holiday'] = ( $event->event_holiday == 0 ) ? 'false' : 'true';
@@ -273,10 +276,10 @@ function mc_create_tags( $event, $context = 'filters' ) {
273
 
274
  // general text fields
275
  $e['title'] = stripslashes( $event->event_title );
276
- $e['description'] = ( get_option( 'mc_process_shortcodes' ) == 'true' && $context == 'filters' ) ? apply_filters( 'the_content', $event->event_desc ) : wpautop( stripslashes( $event->event_desc ) );
277
  $e['description_raw'] = stripslashes( $event->event_desc );
278
  $e['description_stripped'] = strip_tags( stripslashes( $event->event_desc ) );
279
- $e['shortdesc'] = ( get_option( 'mc_process_shortcodes' ) == 'true' && $context == 'filters' ) ? apply_filters( 'the_content', $event->event_short ) : wpautop( stripslashes( $event->event_short ) );
280
  $e['shortdesc_raw'] = stripslashes( $event->event_short );
281
  $e['shortdesc_stripped'] = strip_tags( stripslashes( $event->event_short ) );
282
 
@@ -366,6 +369,12 @@ function mc_create_tags( $event, $context = 'filters' ) {
366
  return $e;
367
  }
368
 
 
 
 
 
 
 
369
  function mc_get_details_label( $event, $e ) {
370
  $templates = get_option( 'mc_templates' );
371
  $e_template = ( ! empty( $templates['label'] ) ) ? stripcslashes( $templates['label'] ) : sprintf( __( 'Event Details %s', 'my-calendar' ), '<span class="screen-reader-text">about {title}</span> &raquo;' );
@@ -386,7 +395,7 @@ function mc_format_timestamp( $os ) {
386
  }
387
 
388
  function mc_runtime( $start, $end, $event ) {
389
- if ( $event->event_hide_end || $start == $end ) {
390
  return '';
391
  } else {
392
  return human_time_diff( $start, $end );
20
  }
21
  }
22
  if ( strpos( $template, "{" . $key . " " ) !== false ) { // only do preg_match if appropriate
23
+ preg_match_all( '/{' . $key . '\b(?>\s+(?:before="([^"]*)"|after="([^"]*)"|format="([^"]*)")|[^\s]+|\s+){0,3}}/', $template, $matches, PREG_PATTERN_ORDER );
24
  if ( $matches ) {
25
  $number = count( $matches[0] );
26
  for ( $i=0; $i<=$number; $i++ ) {
208
  }
209
  $hcard .= "</div>";
210
 
211
+ return apply_filters( 'mc_hcard', $hcard, $event, $address, $map, $source, $context );
212
  }
213
 
214
  // Produces the array of event details used for drawing templates
227
  $e['access'] = mc_expand( get_post_meta( $event->event_post, '_mc_event_access', true ) );
228
 
229
  // date & time fields
230
+ $real_end_date = $event->occur_end;
231
  $dtstart = mc_format_timestamp( strtotime( $event->occur_begin ) );
232
+ $dtend = mc_format_timestamp( strtotime( $real_end_date ) );
233
 
 
234
  $e['date_utc'] = date_i18n( apply_filters( 'mc_date_format', $date_format, 'template_begin_ts' ), $event->ts_occur_begin );
235
  $e['date_end_utc'] = date_i18n( apply_filters( 'mc_date_format', $date_format, 'template_end_ts' ), $event->ts_occur_end );
236
+ $notime = mc_notime_label( $event );
237
+ $e['time'] = ( date( 'H:i:s', strtotime( $event->occur_begin ) ) == '00:00:00' ) ? $notime : date( get_option( 'mc_time_format' ), strtotime( $event->occur_begin ) );
238
+ $e['time24'] = ( date( 'G:i', strtotime( $event->occur_begin ) ) == '00:00:00' ) ? $notime : date( get_option( 'mc_time_format' ), strtotime( $event->occur_begin ) );
239
+ $endtime = ( $event->event_end == '23:59:59' ) ? '00:00:00' : date( 'H:i:s', strtotime( $real_end_date ) );
240
+ $e['endtime'] = ( $real_end_date == $event->occur_begin || $event->event_hide_end == 1 || date( 'H:i:s', strtotime( $real_end_date ) ) == '23:59:59' ) ? '' : date_i18n( get_option( 'mc_time_format' ), strtotime( $endtime ) );
241
  $e['runtime'] = mc_runtime( $event->ts_occur_begin, $event->ts_occur_end, $event );
242
  $e['dtstart'] = date( 'Y-m-d\TH:i:s', strtotime( $event->occur_begin ) );// hcal formatted
243
+ $e['dtend'] = date( 'Y-m-d\TH:i:s', strtotime( $real_end_date ) ); //hcal formatted end
244
  $e['rssdate'] = date( 'D, d M Y H:i:s +0000', strtotime( $event->event_added ) );
245
  $date = date_i18n( apply_filters( 'mc_date_format', $date_format, 'template_begin' ), strtotime( $event->occur_begin ) );
246
  $date_end = date_i18n( apply_filters( 'mc_date_format', $date_format, 'template_end' ), strtotime( $real_end_date ) );
247
+ $date_arr = array( 'occur_begin' => $event->occur_begin, 'occur_end' => $real_end_date );
248
  $date_obj = (object) $date_arr;
249
  if ( $event->event_span == 1 ) {
250
  $dates = mc_event_date_span( $event->event_group_id, $event->event_span, array( 0 => $date_obj ) );
254
  $e['date'] = ( $event->event_span != 1 ) ? $date : mc_format_date_span( $dates, 'simple', $date );
255
  $e['enddate'] = $date_end;
256
  $e['daterange'] = ( $date == $date_end ) ? $date : "<span class='mc_db'>$date</span> <span>&ndash;</span> <span class='mc_de'>$date_end</span>";
257
+ $e['timerange'] = ( ( $e['time'] == $e['endtime'] ) || $event->event_hide_end == 1 || date( 'H:i:s', strtotime( $real_end_date ) ) == '23:59:59' ) ? $e['time'] : "<span class='mc_tb'>" . $e['time'] . "</span> <span>&ndash;</span> <span class='mc_te'>" . $e['endtime'] . "</span>";
258
  $e['datespan'] = ( $event->event_span == 1 || ( $e['date'] != $e['enddate'] ) ) ? mc_format_date_span( $dates ) : $date;
259
  $e['multidate'] = mc_format_date_span( $dates, 'complex', "<span class='fallback-date'>$date</span><span class='separator'>,</span> <span class='fallback-time'>$e[time]</span>&ndash;<span class='fallback-endtime'>$e[endtime]</span>" );
260
  $e['began'] = $event->event_begin; // returns date of first occurrence of an event.
262
  $e['repeats'] = $event->event_repeats;
263
 
264
  // category fields
265
+ $e['cat_id'] = $event->event_category;
266
+ $e['category'] = stripslashes( $event->category_name );
267
+ $e['icon'] = mc_category_icon( $event, 'img' );
268
+ $e['icon_html'] = "<img src='$e[icon]' class='mc-category-icon' alt='" . __( 'Category', 'my-calendar' ) . ": " . esc_attr( $event->category_name ) . "' />";
269
+ $e['color'] = $event->category_color;
270
+ $e['color_css'] = "<span style='background-color: $event->category_color'>"; // this is because widgets now strip out style attributes.
271
+ $e['close_color_css'] = "</span>";
272
 
273
  // special
274
  $e['skip_holiday'] = ( $event->event_holiday == 0 ) ? 'false' : 'true';
276
 
277
  // general text fields
278
  $e['title'] = stripslashes( $event->event_title );
279
+ $e['description'] = wpautop( stripslashes( $event->event_desc ) );
280
  $e['description_raw'] = stripslashes( $event->event_desc );
281
  $e['description_stripped'] = strip_tags( stripslashes( $event->event_desc ) );
282
+ $e['shortdesc'] = wpautop( stripslashes( $event->event_short ) );
283
  $e['shortdesc_raw'] = stripslashes( $event->event_short );
284
  $e['shortdesc_stripped'] = strip_tags( stripslashes( $event->event_short ) );
285
 
369
  return $e;
370
  }
371
 
372
+ function mc_notime_label( $event ) {
373
+ $notime = get_post_meta( $event->event_post, '_event_time_label', true );
374
+ $notime = ( $notime != '' ) ? $notime : get_option( 'mc_notime_text' );
375
+ return apply_filters( 'mc_notime_label', $notime, $event );
376
+ }
377
+
378
  function mc_get_details_label( $event, $e ) {
379
  $templates = get_option( 'mc_templates' );
380
  $e_template = ( ! empty( $templates['label'] ) ) ? stripcslashes( $templates['label'] ) : sprintf( __( 'Event Details %s', 'my-calendar' ), '<span class="screen-reader-text">about {title}</span> &raquo;' );
395
  }
396
 
397
  function mc_runtime( $start, $end, $event ) {
398
+ if ( $event->event_hide_end || $start == $end || date( 'H:i:s', strtotime( $end ) ) == '23:59:59' ) {
399
  return '';
400
  } else {
401
  return human_time_diff( $start, $end );
my-calendar-widgets.php CHANGED
@@ -4,8 +4,8 @@ if ( ! defined( 'ABSPATH' ) ) {
4
  } // Exit if accessed directly
5
 
6
  class my_calendar_simple_search extends WP_Widget {
7
- function my_calendar_simple_search() {
8
- parent::WP_Widget( false, $name = __( 'My Calendar: Simple Event Search', 'my-calendar' ) );
9
  }
10
 
11
  function widget( $args, $instance ) {
@@ -28,7 +28,7 @@ class my_calendar_simple_search extends WP_Widget {
28
  <label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Title', 'my-calendar' ); ?>
29
  :</label><br/>
30
  <input class="widefat" type="text" id="<?php echo $this->get_field_id( 'title' ); ?>"
31
- name="<?php echo $this->get_field_name( 'title' ); ?>" value="<?php echo esc_attr( $widget_title ); ?>"/>
32
  </p>
33
  <p>
34
  <label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Search Results Page', 'my-calendar' ); ?>
@@ -50,8 +50,8 @@ class my_calendar_simple_search extends WP_Widget {
50
 
51
  class my_calendar_today_widget extends WP_Widget {
52
 
53
- function my_calendar_today_widget() {
54
- parent::WP_Widget( false, $name = __( 'My Calendar: Today\'s Events', 'my-calendar' ) );
55
  }
56
 
57
  function widget( $args, $instance ) {
@@ -66,13 +66,14 @@ class my_calendar_today_widget extends WP_Widget {
66
  $widget_link = ( ! empty( $instance['my_calendar_today_linked'] ) && $instance['my_calendar_today_linked'] == 'yes' ) ? $default_link : '';
67
  $widget_link = ( ! empty( $instance['mc_link'] ) ) ? esc_url( $instance['mc_link'] ) : $widget_link;
68
  $widget_title = empty( $the_title ) ? '' : $the_title;
 
69
  $offset = ( 60 * 60 * get_option( 'gmt_offset' ) );
70
  if ( strpos( $widget_title, '{date}' ) !== false ) {
71
  $widget_title = str_replace( '{date}', date_i18n( get_option( 'mc_date_format' ), time() + $offset ), $widget_title );
72
  }
73
  $widget_title = ( $widget_link == '' ) ? $widget_title : "<a href='$widget_link'>$widget_title</a>";
74
  $widget_title = ( $widget_title != '' ) ? $before_title . $widget_title . $after_title : '';
75
- $the_events = my_calendar_todays_events( $the_category, $the_template, $the_substitute, $author, $host );
76
  if ( $the_events != '' ) {
77
  echo $before_widget;
78
  echo $widget_title;
@@ -91,6 +92,7 @@ class my_calendar_today_widget extends WP_Widget {
91
  $widget_text = ( isset( $instance['my_calendar_no_events_text'] ) ) ? esc_attr( $instance['my_calendar_no_events_text'] ) : '';
92
  $widget_category = ( isset( $instance['my_calendar_today_category'] ) ) ? esc_attr( $instance['my_calendar_today_category'] ) : '';
93
  $widget_linked = ( isset( $instance['my_calendar_today_linked'] ) ) ? esc_attr( $instance['my_calendar_today_linked'] ) : '';
 
94
  if ( $widget_linked == 'yes' ) {
95
  $default_link = ( is_numeric( get_option( 'mc_uri' ) ) ) ? get_permalink( get_option( 'mc_uri' ) ) : get_option( 'mc_uri' );
96
  } else {
@@ -129,6 +131,13 @@ class my_calendar_today_widget extends WP_Widget {
129
  name="<?php echo $this->get_field_name( 'my_calendar_no_events_text' ); ?>"
130
  value="<?php echo $widget_text; ?>"/>
131
  </p>
 
 
 
 
 
 
 
132
  <p>
133
  <label
134
  for="<?php echo $this->get_field_id( 'my_calendar_today_category' ); ?>"><?php _e( 'Category or categories to display:', 'my-calendar' ); ?></label><br/>
@@ -161,8 +170,8 @@ class my_calendar_today_widget extends WP_Widget {
161
 
162
  class my_calendar_upcoming_widget extends WP_Widget {
163
 
164
- function my_calendar_upcoming_widget() {
165
- parent::WP_Widget( false, $name = __( 'My Calendar: Upcoming Events', 'my-calendar' ) );
166
  }
167
 
168
  function widget( $args, $instance ) {
@@ -184,9 +193,12 @@ class my_calendar_upcoming_widget extends WP_Widget {
184
  $widget_title = empty( $the_title ) ? '' : $the_title;
185
  $widget_title = ( $widget_link == '' ) ? $widget_title : "<a href='$widget_link'>$widget_title</a>";
186
  $widget_title = ( $widget_title != '' ) ? $before_title . $widget_title . $after_title : '';
187
- $month = ( $type == 'month+1' ) ? date_i18n( 'F', strtotime( '+1 month' ) ) : date_i18n( 'F', current_time( 'timestamp' ) );
188
  $widget_title = str_replace( '{month}', $month, $widget_title );
189
- $the_events = my_calendar_upcoming_events( $before, $after, $type, $the_category, $the_template, $the_substitute, $order, $skip, $show_today, $author, $host );
 
 
 
190
  if ( $the_events != '' ) {
191
  echo $before_widget;
192
  echo $widget_title;
@@ -212,6 +224,9 @@ class my_calendar_upcoming_widget extends WP_Widget {
212
  $type = ( isset( $instance['my_calendar_upcoming_type'] ) ) ? esc_attr( $instance['my_calendar_upcoming_type'] ) : 'events';
213
  $order = ( isset( $instance['my_calendar_upcoming_order'] ) ) ? esc_attr( $instance['my_calendar_upcoming_order'] ) : 'asc';
214
  $linked = ( isset( $instance['my_calendar_upcoming_linked'] ) ) ? esc_attr( $instance['my_calendar_upcoming_linked'] ) : '';
 
 
 
215
  if ( $linked == 'yes' ) {
216
  $default_link = ( is_numeric( get_option( 'mc_uri' ) ) ) ? get_permalink( get_option( 'mc_uri' ) ) : get_option( 'mc_uri' );
217
  } else {
@@ -281,8 +296,26 @@ class my_calendar_upcoming_widget extends WP_Widget {
281
  value="month+12" <?php echo ( $type == 'month+12' ) ? 'selected="selected"' : ''; ?>><?php _e( 'Show 12th month out', 'my-calendar' ) ?></option>
282
  <option
283
  value="year" <?php echo ( $type == 'year' ) ? 'selected="selected"' : ''; ?>><?php _e( 'Show current year', 'my-calendar' ) ?></option>
284
- </select>
 
 
285
  </p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
286
  <p>
287
  <label
288
  for="<?php echo $this->get_field_id( 'my_calendar_upcoming_skip' ); ?>"><?php _e( 'Skip the first <em>n</em> events', 'my-calendar' ); ?></label>
@@ -361,12 +394,13 @@ class my_calendar_upcoming_widget extends WP_Widget {
361
  }
362
 
363
  // Widget upcoming events
364
- function my_calendar_upcoming_events( $before = 'default', $after = 'default', $type = 'default', $category = 'default', $template = 'default', $substitute = '', $order = 'asc', $skip = 0, $show_today = 'yes', $author = 'default', $host = 'default', $ltype = '', $lvalue = '' ) {
365
  global $default_template;
 
366
  $output = '';
367
  $widget_defaults = ( array ) get_option( 'mc_widget_defaults' );
368
  $display_upcoming_type = ( $type == 'default' ) ? $widget_defaults['upcoming']['type'] : $type;
369
- $display_upcoming_type = ( $display_upcoming_type == '' ) ? 'event' : $display_upcoming_type;
370
  // Get number of units we should go into the future
371
  $after = ( $after == 'default' ) ? $widget_defaults['upcoming']['after'] : $after;
372
  $after = ( $after == '' ) ? 10 : $after;
@@ -383,7 +417,7 @@ function my_calendar_upcoming_events( $before = 'default', $after = 'default', $
383
  $no_event_text = ( $substitute == '' ) ? $widget_defaults['upcoming']['text'] : $substitute;
384
  $header = "<ul id='upcoming-events'>";
385
  $footer = "</ul>";
386
- if ( $display_upcoming_type == "days" || $display_upcoming_type == "month" || $display_upcoming_type == 'month+1' || $display_upcoming_type == "year" ) {
387
  $temp_array = array();
388
  if ( $display_upcoming_type == "days" ) {
389
  $from = date( 'Y-m-d', strtotime( "-$before days" ) );
@@ -393,6 +427,10 @@ function my_calendar_upcoming_events( $before = 'default', $after = 'default', $
393
  $from = date( 'Y-m-1' );
394
  $to = date( 'Y-m-t' );
395
  }
 
 
 
 
396
  /* Yes, this is crude. But sometimes simplicity works best. There are only 12 possibilities, after all. */
397
  if ( $display_upcoming_type == 'month+1' ) {
398
  $from = date( 'Y-m-1', strtotime( '+1 month' ) );
@@ -446,8 +484,8 @@ function my_calendar_upcoming_events( $before = 'default', $after = 'default', $
446
  $from = date( 'Y-1-1' );
447
  $to = date( 'Y-12-31' );
448
  }
449
- $from = apply_filters( 'mc_upcoming_date_from', $from );
450
- $to = apply_filters( 'mc_upcoming_date_to', $to );
451
  $event_array = my_calendar_events( $from, $to, $category, $ltype, $lvalue, 'upcoming', $author, $host );
452
  if ( count( $event_array ) != 0 ) {
453
  foreach ( $event_array as $key => $value ) {
@@ -526,7 +564,7 @@ function my_calendar_upcoming_events( $before = 'default', $after = 'default', $
526
  if ( $output != '' ) {
527
  $output = $header . $output . $footer;
528
 
529
- return $output;
530
  } else {
531
  return stripcslashes( $no_event_text );
532
  }
@@ -603,10 +641,14 @@ function mc_produce_upcoming_events( $events, $template, $type = 'list', $order
603
  $same_event = ( in_array( $e->occur_id, $last_events ) ) ? true : false;
604
  $same_group = ( in_array( $e->occur_group_id, $last_group ) ) ? true : false;
605
  if ( $show_today == 'yes' && my_calendar_date_equal( $beginning, $current ) ) {
606
- $in_total = 'yes'; // count todays events in total
607
  if ( $in_total != 'no' ) {
608
  $near_events[] = $e;
609
- $future ++;
 
 
 
 
610
  } else {
611
  $near_events[] = $e;
612
  }
@@ -667,8 +709,9 @@ function mc_produce_upcoming_events( $events, $template, $type = 'list', $order
667
 
668
  foreach ( reverse_array( $temp_array, true, $order ) as $details ) {
669
  if ( ! in_array( $details['group'], $groups ) ) {
670
- $date = date( 'Y-m-d', strtotime( $details['dtstart'] ) );
671
- $class = ( my_calendar_date_comp( $date, $today ) === true ) ? "past-event" : "future-event";
 
672
  if ( my_calendar_date_equal( $date, $today ) ) {
673
  $class = "today";
674
  }
@@ -676,7 +719,7 @@ function mc_produce_upcoming_events( $events, $template, $type = 'list', $order
676
  $class = "multiday";
677
  }
678
  if ( $type == 'list' ) {
679
- $prepend = "\n<li class=\"$class\">";
680
  $append = "</li>\n";
681
  } else {
682
  $prepend = $append = '';
@@ -712,7 +755,7 @@ function mc_produce_upcoming_events( $events, $template, $type = 'list', $order
712
  }
713
 
714
  // Widget todays events
715
- function my_calendar_todays_events( $category = 'default', $template = 'default', $substitute = '', $author = 'all', $host = 'all' ) {
716
  $caching = apply_filters( 'mc_cache_enabled', false );
717
  $todays_cache = ( $caching ) ? get_transient( 'mc_todays_cache' ) : '';
718
  if ( $caching && is_array( $todays_cache ) && @$todays_cache[ $category ] ) {
@@ -730,7 +773,11 @@ function my_calendar_todays_events( $category = 'default', $template = 'default'
730
  $category = ( $category == 'default' ) ? $defaults['today']['category'] : $category;
731
  $no_event_text = ( $substitute == '' ) ? $defaults['today']['text'] : $substitute;
732
 
733
- $from = $to = date( 'Y-m-d', current_time( 'timestamp' ) );
 
 
 
 
734
  $events = my_calendar_events( $from, $to, $category, '', '', 'upcoming', $author, $host );
735
  $today = ( isset( $events[ $from ] ) ) ? $events[ $from ] : false;
736
  $header = "<ul id='todays-events'>";
@@ -744,12 +791,22 @@ function my_calendar_todays_events( $category = 'default', $template = 'default'
744
  if ( ! in_array( $e->event_group_id, $groups ) ) {
745
  $event_details = mc_create_tags( $e );
746
  $ts = $e->ts_occur_begin;
 
 
 
 
 
 
 
 
 
 
747
  if ( get_option( 'mc_event_approve' ) == 'true' ) {
748
  if ( $e->event_approved != 0 ) {
749
- $todays_events[ $ts ][] = "<li>" . jd_draw_template( $event_details, $template ) . "</li>";
750
  }
751
  } else {
752
- $todays_events[ $ts ][] = "<li>" . jd_draw_template( $event_details, $template ) . "</li>";
753
  }
754
  }
755
  }
@@ -775,13 +832,14 @@ function my_calendar_todays_events( $category = 'default', $template = 'default'
775
  $return = stripcslashes( $no_event_text );
776
  }
777
 
778
- return $return;
 
779
  }
780
 
781
  class my_calendar_mini_widget extends WP_Widget {
782
 
783
- function my_calendar_mini_widget() {
784
- parent::WP_Widget( false, $name = __( 'My Calendar: Mini Calendar', 'my-calendar' ) );
785
  }
786
 
787
  function widget( $args, $instance ) {
@@ -802,18 +860,18 @@ class my_calendar_mini_widget extends WP_Widget {
802
  $title = empty( $the_title ) ? __( 'Calendar', 'my-calendar' ) : $the_title;
803
  $title = ( $widget_link != '' ) ? "<a href='$widget_link'>$title</a>" : $title;
804
  $title = ( $title != '' ) ? $before_title . $title . $after_title : '';
805
- $the_events = my_calendar( $name, $format, $category, $time, '', '', 'jd-calendar', '', '', $author, $host, $above, $below );
806
  if ( $the_events != '' ) {
807
  echo $before_widget . $title . $the_events . $after_widget;
808
  }
809
  }
810
 
811
  function form( $instance ) {
812
- $title = esc_attr( empty( $instance['my_calendar_mini_title'] ) ? '' : $instance['my_calendar_mini_title'] );
813
- $widget_time = esc_attr( empty( $instance['my_calendar_mini_time'] ) ? '' : $instance['my_calendar_mini_time'] );
814
- $widget_category = esc_attr( empty( $instance['my_calendar_mini_category'] ) ? '' : $instance['my_calendar_mini_category'] );
815
- $above = ( isset( $instance['above'] ) ) ? esc_attr( $instance['above'] ) : 'none';
816
- $below = ( isset( $instance['below'] ) ) ? esc_attr( $instance['below'] ) : 'none';
817
  $widget_link = ( isset( $instance['mc_link'] ) ) ? esc_url( $instance['mc_link'] ) : '';
818
  $host = ( isset( $instance['host'] ) ) ? $instance['host'] : '';
819
  $author = ( isset( $instance['author'] ) ) ? $instance['author'] : '';
@@ -824,28 +882,28 @@ class my_calendar_mini_widget extends WP_Widget {
824
  :</label><br/>
825
  <input class="widefat" type="text" id="<?php echo $this->get_field_id( 'my_calendar_mini_title' ); ?>"
826
  name="<?php echo $this->get_field_name( 'my_calendar_mini_title' ); ?>"
827
- value="<?php echo $title; ?>"/>
828
  </p>
829
  <p>
830
  <label
831
  for="<?php echo $this->get_field_id( 'mc_link' ); ?>"><?php _e( 'Widget Title Link', 'my-calendar' ); ?>
832
  :</label><br/>
833
  <input class="widefat" type="text" id="<?php echo $this->get_field_id( 'mc_link' ); ?>"
834
- name="<?php echo $this->get_field_name( 'mc_link' ); ?>" value="<?php echo $widget_link; ?>"/>
835
  </p>
836
  <p>
837
  <label
838
  for="<?php echo $this->get_field_id( 'my_calendar_mini_category' ); ?>"><?php _e( 'Category or categories to display:', 'my-calendar' ); ?></label><br/>
839
  <input class="widefat" type="text" id="<?php echo $this->get_field_id( 'my_calendar_mini_category' ); ?>"
840
  name="<?php echo $this->get_field_name( 'my_calendar_mini_category' ); ?>"
841
- value="<?php echo $widget_category; ?>"/>
842
  </p>
843
  <p>
844
  <label
845
  for="<?php echo $this->get_field_name( 'above' ); ?>"><?php _e( 'Navigation above calendar', 'my-calendar' ); ?></label>
846
  <input type="text" class="widefat" name="<?php echo $this->get_field_name( 'above' ); ?>"
847
  id="<?php echo $this->get_field_name( 'above' ); ?>"
848
- value="<?php echo ( $above == '' ) ? 'nav,jump,print' : $above; ?>"
849
  aria-describedby='<?php echo $this->get_field_name( 'below' ); ?>-navigation-fields' />
850
  </p>
851
  <p>
@@ -853,7 +911,7 @@ class my_calendar_mini_widget extends WP_Widget {
853
  for="<?php echo $this->get_field_name( 'below' ); ?>"><?php _e( 'Navigation below calendar', 'my-calendar' ); ?></label>
854
  <input type="text" class="widefat" name="<?php echo $this->get_field_name( 'below' ); ?>"
855
  id="<?php echo $this->get_field_name( 'below' ); ?>"
856
- value="<?php echo ( $below == '' ) ? 'key' : $below; ?>"
857
  aria-describedby='<?php echo $this->get_field_name( 'below' ); ?>-navigation-fields' />
858
  </p>
859
  <p id='<?php echo $this->get_field_name( 'below' ); ?>-navigation-fields'>
4
  } // Exit if accessed directly
5
 
6
  class my_calendar_simple_search extends WP_Widget {
7
+ function __construct() {
8
+ parent::__construct( false, $name = __( 'My Calendar: Simple Event Search', 'my-calendar' ) );
9
  }
10
 
11
  function widget( $args, $instance ) {
28
  <label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Title', 'my-calendar' ); ?>
29
  :</label><br/>
30
  <input class="widefat" type="text" id="<?php echo $this->get_field_id( 'title' ); ?>"
31
+ name="<?php echo $this->get_field_name( 'title' ); ?>" value="<?php esc_attr_e( $widget_title ); ?>"/>
32
  </p>
33
  <p>
34
  <label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Search Results Page', 'my-calendar' ); ?>
50
 
51
  class my_calendar_today_widget extends WP_Widget {
52
 
53
+ function __construct() {
54
+ parent::__construct( false, $name = __( 'My Calendar: Today\'s Events', 'my-calendar' ) );
55
  }
56
 
57
  function widget( $args, $instance ) {
66
  $widget_link = ( ! empty( $instance['my_calendar_today_linked'] ) && $instance['my_calendar_today_linked'] == 'yes' ) ? $default_link : '';
67
  $widget_link = ( ! empty( $instance['mc_link'] ) ) ? esc_url( $instance['mc_link'] ) : $widget_link;
68
  $widget_title = empty( $the_title ) ? '' : $the_title;
69
+ $date = ( ! empty( $instance['mc_date'] ) ) ? $instance['mc_date'] : false;
70
  $offset = ( 60 * 60 * get_option( 'gmt_offset' ) );
71
  if ( strpos( $widget_title, '{date}' ) !== false ) {
72
  $widget_title = str_replace( '{date}', date_i18n( get_option( 'mc_date_format' ), time() + $offset ), $widget_title );
73
  }
74
  $widget_title = ( $widget_link == '' ) ? $widget_title : "<a href='$widget_link'>$widget_title</a>";
75
  $widget_title = ( $widget_title != '' ) ? $before_title . $widget_title . $after_title : '';
76
+ $the_events = my_calendar_todays_events( $the_category, $the_template, $the_substitute, $author, $host, $date );
77
  if ( $the_events != '' ) {
78
  echo $before_widget;
79
  echo $widget_title;
92
  $widget_text = ( isset( $instance['my_calendar_no_events_text'] ) ) ? esc_attr( $instance['my_calendar_no_events_text'] ) : '';
93
  $widget_category = ( isset( $instance['my_calendar_today_category'] ) ) ? esc_attr( $instance['my_calendar_today_category'] ) : '';
94
  $widget_linked = ( isset( $instance['my_calendar_today_linked'] ) ) ? esc_attr( $instance['my_calendar_today_linked'] ) : '';
95
+ $date = ( isset( $instance['mc_date'] ) ) ? esc_attr( $instance['mc_date'] ) : '';
96
  if ( $widget_linked == 'yes' ) {
97
  $default_link = ( is_numeric( get_option( 'mc_uri' ) ) ) ? get_permalink( get_option( 'mc_uri' ) ) : get_option( 'mc_uri' );
98
  } else {
131
  name="<?php echo $this->get_field_name( 'my_calendar_no_events_text' ); ?>"
132
  value="<?php echo $widget_text; ?>"/>
133
  </p>
134
+ <p>
135
+ <label
136
+ for="<?php echo $this->get_field_id( 'mc_date' ); ?>"><?php _e( 'Custom date', 'my-calendar' ); ?></label><br/>
137
+ <input class="widefat" type="text" id="<?php echo $this->get_field_id( 'mc_date' ); ?>"
138
+ name="<?php echo $this->get_field_name( 'mc_date' ); ?>"
139
+ value="<?php echo $date; ?>"/>
140
+ </p>
141
  <p>
142
  <label
143
  for="<?php echo $this->get_field_id( 'my_calendar_today_category' ); ?>"><?php _e( 'Category or categories to display:', 'my-calendar' ); ?></label><br/>
170
 
171
  class my_calendar_upcoming_widget extends WP_Widget {
172
 
173
+ function __construct() {
174
+ parent::__construct( false, $name = __( 'My Calendar: Upcoming Events', 'my-calendar' ) );
175
  }
176
 
177
  function widget( $args, $instance ) {
193
  $widget_title = empty( $the_title ) ? '' : $the_title;
194
  $widget_title = ( $widget_link == '' ) ? $widget_title : "<a href='$widget_link'>$widget_title</a>";
195
  $widget_title = ( $widget_title != '' ) ? $before_title . $widget_title . $after_title : '';
196
+ $month = ( strpos( $type, 'month+' ) === 0 ) ? date_i18n( 'F', strtotime( $type ) ) : date_i18n( 'F', current_time( 'timestamp' ) );
197
  $widget_title = str_replace( '{month}', $month, $widget_title );
198
+ $from = ( isset( $instance['mc_from'] ) ) ? $instance['mc_from'] : false;
199
+ $to = ( isset( $instance['mc_to'] ) ) ? $instance['mc_to'] : false;
200
+
201
+ $the_events = my_calendar_upcoming_events( $before, $after, $type, $the_category, $the_template, $the_substitute, $order, $skip, $show_today, $author, $host, false, false, $from, $to );
202
  if ( $the_events != '' ) {
203
  echo $before_widget;
204
  echo $widget_title;
224
  $type = ( isset( $instance['my_calendar_upcoming_type'] ) ) ? esc_attr( $instance['my_calendar_upcoming_type'] ) : 'events';
225
  $order = ( isset( $instance['my_calendar_upcoming_order'] ) ) ? esc_attr( $instance['my_calendar_upcoming_order'] ) : 'asc';
226
  $linked = ( isset( $instance['my_calendar_upcoming_linked'] ) ) ? esc_attr( $instance['my_calendar_upcoming_linked'] ) : '';
227
+ $from = ( isset( $instance['mc_from'] ) ) ? esc_attr( $instance['mc_from'] ) : '';
228
+ $to = ( isset( $instance['mc_to'] ) ) ? esc_attr( $instance['mc_to'] ) : '';
229
+
230
  if ( $linked == 'yes' ) {
231
  $default_link = ( is_numeric( get_option( 'mc_uri' ) ) ) ? get_permalink( get_option( 'mc_uri' ) ) : get_option( 'mc_uri' );
232
  } else {
296
  value="month+12" <?php echo ( $type == 'month+12' ) ? 'selected="selected"' : ''; ?>><?php _e( 'Show 12th month out', 'my-calendar' ) ?></option>
297
  <option
298
  value="year" <?php echo ( $type == 'year' ) ? 'selected="selected"' : ''; ?>><?php _e( 'Show current year', 'my-calendar' ) ?></option>
299
+ <option
300
+ value="custom" <?php echo ( $type == 'custom' ) ? 'selected="selected"' : ''; ?>><?php _e( 'Custom Dates', 'my-calendar' ) ?></option>
301
+ </select>
302
  </p>
303
+ <?php if ( $type == 'custom' ) { ?>
304
+ <p>
305
+ <label
306
+ for="<?php echo $this->get_field_id( 'mc_from' ); ?>"><?php _e( 'Start date', 'my-calendar' ); ?>:</label>
307
+ <input type="text" id="<?php echo $this->get_field_id( 'mc_from' ); ?>"
308
+ name="<?php echo $this->get_field_name( 'mc_from' ); ?>"
309
+ value="<?php echo $from; ?>"/>
310
+ </p>
311
+ <p>
312
+ <label
313
+ for="<?php echo $this->get_field_id( 'mc_to' ); ?>"><?php _e( 'End date', 'my-calendar' ); ?>:</label>
314
+ <input type="text" id="<?php echo $this->get_field_id( 'mc_to' ); ?>"
315
+ name="<?php echo $this->get_field_name( 'mc_to' ); ?>"
316
+ value="<?php echo $to; ?>"/>
317
+ </p>
318
+ <?php } ?>
319
  <p>
320
  <label
321
  for="<?php echo $this->get_field_id( 'my_calendar_upcoming_skip' ); ?>"><?php _e( 'Skip the first <em>n</em> events', 'my-calendar' ); ?></label>
394
  }
395
 
396
  // Widget upcoming events
397
+ function my_calendar_upcoming_events( $before = 'default', $after = 'default', $type = 'default', $category = 'default', $template = 'default', $substitute = '', $order = 'asc', $skip = 0, $show_today = 'yes', $author = 'default', $host = 'default', $ltype = '', $lvalue = '', $from = '', $to = '' ) {
398
  global $default_template;
399
+ $args = array( 'before'=>$before, 'after'=>$after, 'type'=>$type, 'category'=>$category, 'template'=>$template, 'fallback'=> $substitute, 'order' => $order, 'skip' => $skip, 'show_today'=> $show_today, 'author'=> $author, 'host'=>$host, 'ltype'=>$ltype, 'lvalue'=>$lvalue );
400
  $output = '';
401
  $widget_defaults = ( array ) get_option( 'mc_widget_defaults' );
402
  $display_upcoming_type = ( $type == 'default' ) ? $widget_defaults['upcoming']['type'] : $type;
403
+ $display_upcoming_type = ( $display_upcoming_type == '' ) ? 'events' : $display_upcoming_type;
404
  // Get number of units we should go into the future
405
  $after = ( $after == 'default' ) ? $widget_defaults['upcoming']['after'] : $after;
406
  $after = ( $after == '' ) ? 10 : $after;
417
  $no_event_text = ( $substitute == '' ) ? $widget_defaults['upcoming']['text'] : $substitute;
418
  $header = "<ul id='upcoming-events'>";
419
  $footer = "</ul>";
420
+ if ( $display_upcoming_type != 'events' ) {
421
  $temp_array = array();
422
  if ( $display_upcoming_type == "days" ) {
423
  $from = date( 'Y-m-d', strtotime( "-$before days" ) );
427
  $from = date( 'Y-m-1' );
428
  $to = date( 'Y-m-t' );
429
  }
430
+ if ( $display_upcoming_type == 'custom' && $from != '' && $to != '' ) {
431
+ $from = date( 'Y-m-d', strtotime( $from ) );
432
+ $to = date( 'Y-m-d', strtotime( $to ) );
433
+ }
434
  /* Yes, this is crude. But sometimes simplicity works best. There are only 12 possibilities, after all. */
435
  if ( $display_upcoming_type == 'month+1' ) {
436
  $from = date( 'Y-m-1', strtotime( '+1 month' ) );
484
  $from = date( 'Y-1-1' );
485
  $to = date( 'Y-12-31' );
486
  }
487
+ $from = apply_filters( 'mc_upcoming_date_from', $from, $args );
488
+ $to = apply_filters( 'mc_upcoming_date_to', $to, $args );
489
  $event_array = my_calendar_events( $from, $to, $category, $ltype, $lvalue, 'upcoming', $author, $host );
490
  if ( count( $event_array ) != 0 ) {
491
  foreach ( $event_array as $key => $value ) {
564
  if ( $output != '' ) {
565
  $output = $header . $output . $footer;
566
 
567
+ return ( get_option( 'mc_process_shortcodes' ) == 'true' ) ? do_shortcode( $output ) : $output;
568
  } else {
569
  return stripcslashes( $no_event_text );
570
  }
641
  $same_event = ( in_array( $e->occur_id, $last_events ) ) ? true : false;
642
  $same_group = ( in_array( $e->occur_group_id, $last_group ) ) ? true : false;
643
  if ( $show_today == 'yes' && my_calendar_date_equal( $beginning, $current ) ) {
644
+ $in_total = apply_filters( 'mc_include_today_in_total', 'yes' ); // count todays events in total
645
  if ( $in_total != 'no' ) {
646
  $near_events[] = $e;
647
+ if ( $before > $after ) {
648
+ $future ++;
649
+ } else {
650
+ $past ++;
651
+ }
652
  } else {
653
  $near_events[] = $e;
654
  }
709
 
710
  foreach ( reverse_array( $temp_array, true, $order ) as $details ) {
711
  if ( ! in_array( $details['group'], $groups ) ) {
712
+ $date = date( 'Y-m-d H:i:s', strtotime( $details['dtstart'] ) );
713
+ $class = ( my_calendar_date_comp( $date, $today . date( 'H:i', current_time( 'timestamp' ) ) ) === true ) ? "past-event" : "future-event";
714
+ $category = 'mc_' . sanitize_title( $details['category'] );
715
  if ( my_calendar_date_equal( $date, $today ) ) {
716
  $class = "today";
717
  }
719
  $class = "multiday";
720
  }
721
  if ( $type == 'list' ) {
722
+ $prepend = "\n<li class=\"$class $category\">";
723
  $append = "</li>\n";
724
  } else {
725
  $prepend = $append = '';
755
  }
756
 
757
  // Widget todays events
758
+ function my_calendar_todays_events( $category = 'default', $template = 'default', $substitute = '', $author = 'all', $host = 'all', $date = false ) {
759
  $caching = apply_filters( 'mc_cache_enabled', false );
760
  $todays_cache = ( $caching ) ? get_transient( 'mc_todays_cache' ) : '';
761
  if ( $caching && is_array( $todays_cache ) && @$todays_cache[ $category ] ) {
773
  $category = ( $category == 'default' ) ? $defaults['today']['category'] : $category;
774
  $no_event_text = ( $substitute == '' ) ? $defaults['today']['text'] : $substitute;
775
 
776
+ if ( $date ) {
777
+ $from = $to = date( 'Y-m-d', strtotime( $date ) );
778
+ } else {
779
+ $from = $to = date( 'Y-m-d', current_time( 'timestamp' ) );
780
+ }
781
  $events = my_calendar_events( $from, $to, $category, '', '', 'upcoming', $author, $host );
782
  $today = ( isset( $events[ $from ] ) ) ? $events[ $from ] : false;
783
  $header = "<ul id='todays-events'>";
791
  if ( ! in_array( $e->event_group_id, $groups ) ) {
792
  $event_details = mc_create_tags( $e );
793
  $ts = $e->ts_occur_begin;
794
+ $end = $e->ts_occur_end;
795
+ $now = current_time( 'timestamp' );
796
+ $category = 'mc_' . sanitize_title( $e->category_name );
797
+ if ( $ts < $now && $end > $now ) {
798
+ $class = 'on-now';
799
+ } else if ( $now < $ts ) {
800
+ $class = 'future-event';
801
+ } else if ( $now > $ts ) {
802
+ $class = 'past-event';
803
+ }
804
  if ( get_option( 'mc_event_approve' ) == 'true' ) {
805
  if ( $e->event_approved != 0 ) {
806
+ $todays_events[ $ts ][] = "<li class='$class $category'>" . jd_draw_template( $event_details, $template ) . "</li>";
807
  }
808
  } else {
809
+ $todays_events[ $ts ][] = "<li class='$class $category'>" . jd_draw_template( $event_details, $template ) . "</li>";
810
  }
811
  }
812
  }
832
  $return = stripcslashes( $no_event_text );
833
  }
834
 
835
+ return ( get_option( 'mc_process_shortcodes' ) == 'true' ) ? do_shortcode( $return ) : $return;
836
+
837
  }
838
 
839
  class my_calendar_mini_widget extends WP_Widget {
840
 
841
+ function __construct() {
842
+ parent::__construct( false, $name = __( 'My Calendar: Mini Calendar', 'my-calendar' ) );
843
  }
844
 
845
  function widget( $args, $instance ) {
860
  $title = empty( $the_title ) ? __( 'Calendar', 'my-calendar' ) : $the_title;
861
  $title = ( $widget_link != '' ) ? "<a href='$widget_link'>$title</a>" : $title;
862
  $title = ( $title != '' ) ? $before_title . $title . $after_title : '';
863
+ $the_events = my_calendar( $name, $format, $category, $time, '', '', 'mini-calendar', '', '', $author, $host, $above, $below );
864
  if ( $the_events != '' ) {
865
  echo $before_widget . $title . $the_events . $after_widget;
866
  }
867
  }
868
 
869
  function form( $instance ) {
870
+ $title = empty( $instance['my_calendar_mini_title'] ) ? '' : $instance['my_calendar_mini_title'];
871
+ $widget_time = empty( $instance['my_calendar_mini_time'] ) ? '' : $instance['my_calendar_mini_time'];
872
+ $widget_category = empty( $instance['my_calendar_mini_category'] ) ? '' : $instance['my_calendar_mini_category'];
873
+ $above = ( isset( $instance['above'] ) ) ? $instance['above'] : 'none';
874
+ $below = ( isset( $instance['below'] ) ) ? $instance['below'] : 'none';
875
  $widget_link = ( isset( $instance['mc_link'] ) ) ? esc_url( $instance['mc_link'] ) : '';
876
  $host = ( isset( $instance['host'] ) ) ? $instance['host'] : '';
877
  $author = ( isset( $instance['author'] ) ) ? $instance['author'] : '';
882
  :</label><br/>
883
  <input class="widefat" type="text" id="<?php echo $this->get_field_id( 'my_calendar_mini_title' ); ?>"
884
  name="<?php echo $this->get_field_name( 'my_calendar_mini_title' ); ?>"
885
+ value="<?php esc_attr_e( $title ); ?>"/>
886
  </p>
887
  <p>
888
  <label
889
  for="<?php echo $this->get_field_id( 'mc_link' ); ?>"><?php _e( 'Widget Title Link', 'my-calendar' ); ?>
890
  :</label><br/>
891
  <input class="widefat" type="text" id="<?php echo $this->get_field_id( 'mc_link' ); ?>"
892
+ name="<?php echo $this->get_field_name( 'mc_link' ); ?>" value="<?php echo esc_url( $widget_link ); ?>"/>
893
  </p>
894
  <p>
895
  <label
896
  for="<?php echo $this->get_field_id( 'my_calendar_mini_category' ); ?>"><?php _e( 'Category or categories to display:', 'my-calendar' ); ?></label><br/>
897
  <input class="widefat" type="text" id="<?php echo $this->get_field_id( 'my_calendar_mini_category' ); ?>"
898
  name="<?php echo $this->get_field_name( 'my_calendar_mini_category' ); ?>"
899
+ value="<?php esc_attr_e( $widget_category ); ?>"/>
900
  </p>
901
  <p>
902
  <label
903
  for="<?php echo $this->get_field_name( 'above' ); ?>"><?php _e( 'Navigation above calendar', 'my-calendar' ); ?></label>
904
  <input type="text" class="widefat" name="<?php echo $this->get_field_name( 'above' ); ?>"
905
  id="<?php echo $this->get_field_name( 'above' ); ?>"
906
+ value="<?php echo ( $above == '' ) ? 'nav,jump,print' : esc_attr( $above ); ?>"
907
  aria-describedby='<?php echo $this->get_field_name( 'below' ); ?>-navigation-fields' />
908
  </p>
909
  <p>
911
  for="<?php echo $this->get_field_name( 'below' ); ?>"><?php _e( 'Navigation below calendar', 'my-calendar' ); ?></label>
912
  <input type="text" class="widefat" name="<?php echo $this->get_field_name( 'below' ); ?>"
913
  id="<?php echo $this->get_field_name( 'below' ); ?>"
914
+ value="<?php echo ( $below == '' ) ? 'key' : esc_attr( $below ); ?>"
915
  aria-describedby='<?php echo $this->get_field_name( 'below' ); ?>-navigation-fields' />
916
  </p>
917
  <p id='<?php echo $this->get_field_name( 'below' ); ?>-navigation-fields'>
my-calendar.php CHANGED
@@ -7,7 +7,7 @@ Author: Joseph C Dolson
7
  Author URI: http://www.joedolson.com
8
  Text Domain: my-calendar
9
  Domain Path: lang
10
- Version: 2.3.32
11
  */
12
  /* Copyright 2009-2015 Joe Dolson (email : joe@joedolson.com)
13
 
@@ -30,7 +30,7 @@ if ( ! defined( 'ABSPATH' ) ) {
30
  } // Exit if accessed directly
31
 
32
  global $mc_version, $wpdb;
33
- $mc_version = '2.3.32';
34
 
35
  // Define the tables used in My Calendar
36
  if ( is_multisite() && get_site_option( 'mc_multisite_show' ) == 1 ) {
@@ -82,7 +82,6 @@ include( dirname( __FILE__ ) . '/my-calendar-widgets.php' );
82
  include( dirname( __FILE__ ) . '/my-calendar-upgrade-db.php' );
83
  include( dirname( __FILE__ ) . '/my-calendar-output.php' );
84
  include( dirname( __FILE__ ) . '/my-calendar-templates.php' );
85
- include( dirname( __FILE__ ) . '/my-calendar-ical.php' );
86
  include( dirname( __FILE__ ) . '/my-calendar-limits.php' );
87
  include( dirname( __FILE__ ) . '/my-calendar-shortcodes.php' );
88
  include( dirname( __FILE__ ) . '/my-calendar-templating.php' );
@@ -91,7 +90,10 @@ include( dirname( __FILE__ ) . '/my-calendar-api.php' );
91
  include( dirname( __FILE__ ) . '/my-calendar-generator.php' );
92
 
93
  // Enable internationalisation
94
- load_plugin_textdomain( 'my-calendar', false, dirname( plugin_basename( __FILE__ ) ) . '/lang' );
 
 
 
95
 
96
  if ( version_compare( get_bloginfo( 'version' ), '3.0', '<' ) && is_ssl() ) {
97
  $wp_content_url = str_replace( 'http://', 'https://', get_option( 'siteurl' ) );
@@ -116,11 +118,42 @@ add_action( 'init', 'mc_export_vcal', 200 );
116
  add_filter( 'widget_text', 'do_shortcode', 9 );
117
  add_filter( 'plugin_action_links', 'mc_plugin_action', - 10, 2 );
118
  add_filter( 'wp_title', 'mc_event_filter', 10, 3 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
119
 
120
  function mc_event_filter( $title, $sep = ' | ', $seplocation = 'right' ) {
121
- if ( isset( $_GET['mc_id'] ) ) {
122
  $id = (int) $_GET['mc_id'];
123
  $event = mc_get_event( $id );
 
 
 
124
  $array = mc_create_tags( $event );
125
  $left_sep = ( $seplocation != 'right' ? ' ' . $sep . ' ' : '' );
126
  $right_sep = ( $seplocation != 'right' ? '' : ' ' . $sep . ' ' );
@@ -162,12 +195,12 @@ function mc_show_sidebar( $show = '', $add = false, $remove = false ) {
162
  <?php if ( ! function_exists( 'mcs_submit_exists' ) ) { ?>
163
  <div class="ui-sortable meta-box-sortables">
164
  <div class="postbox support">
165
- <h3 class='sales'><strong><?php _e( 'My Calendar: Submissions', 'my-calendar' ); ?></strong></h3>
166
 
167
  <div class="inside resources">
168
- <p class="mcsbuy"><?php _e( "Buy the <a href='https://www.joedolson.com/my-calendar/submissions/' rel='external'>My Calendar Submissions add-on</a> &mdash; let your audience build your calendar.", 'my-calendar' ); ?></p>
169
 
170
- <p class="mc-button"><a href="http://www.joedolson.com/my-calendar/submissions/" rel="external"><?php _e( 'Learn more!', 'my-calendar' ); ?></a>
171
  </p>
172
  </div>
173
  </div>
@@ -401,7 +434,7 @@ function my_calendar_menu() {
401
  }
402
  if ( function_exists( 'add_submenu_page' ) ) {
403
  add_action( "admin_head", 'my_calendar_write_js' );
404
- add_action( "admin_head", 'my_calendar_add_styles' );
405
  if ( get_option( 'mc_remote' ) == 'true' ) {
406
  } else { // if we're accessing a remote page, remove these pages.
407
  $edit = add_submenu_page( apply_filters( 'mc_locate_events_page', 'my-calendar' ), __( 'Add New Event', 'my-calendar' ), __( 'Add New Event', 'my-calendar' ), 'mc_add_events', 'my-calendar', 'edit_my_calendar' );
@@ -423,8 +456,8 @@ function my_calendar_menu() {
423
  $permission = apply_filters( 'mcs_submission_permissions', 'manage_options' );
424
  add_action( "admin_head", 'my_calendar_sub_js' );
425
  add_action( "admin_head", 'my_calendar_sub_styles' );
426
- add_submenu_page( 'my-calendar', __( 'Event Submissions', 'my-calendar' ), __( 'Event Submissions', 'my-calendar' ), $permission, 'my-calendar-submissions', 'mcs_settings' );
427
- add_submenu_page( 'my-calendar', __( 'Payments', 'my-calendar' ), __( 'Payments', 'my-calendar' ), $permission, 'my-calendar-payments', 'mcs_sales_page' );
428
  }
429
  }
430
 
@@ -458,7 +491,8 @@ function mc_show_event_editing( $status, $args ) {
458
  'event_open' => __( 'Event Registration options', 'my-calendar' ),
459
  'event_location' => __( 'Event Location fields', 'my-calendar' ),
460
  'event_specials' => __( 'Set Special Scheduling options', 'my-calendar' ),
461
- 'event_access' => __( 'Event Accessibility' )
 
462
  );
463
  $output = '';
464
  foreach ( $input_options as $key => $value ) {
7
  Author URI: http://www.joedolson.com
8
  Text Domain: my-calendar
9
  Domain Path: lang
10
+ Version: 2.4.0
11
  */
12
  /* Copyright 2009-2015 Joe Dolson (email : joe@joedolson.com)
13
 
30
  } // Exit if accessed directly
31
 
32
  global $mc_version, $wpdb;
33
+ $mc_version = '2.4.0';
34
 
35
  // Define the tables used in My Calendar
36
  if ( is_multisite() && get_site_option( 'mc_multisite_show' ) == 1 ) {
82
  include( dirname( __FILE__ ) . '/my-calendar-upgrade-db.php' );
83
  include( dirname( __FILE__ ) . '/my-calendar-output.php' );
84
  include( dirname( __FILE__ ) . '/my-calendar-templates.php' );
 
85
  include( dirname( __FILE__ ) . '/my-calendar-limits.php' );
86
  include( dirname( __FILE__ ) . '/my-calendar-shortcodes.php' );
87
  include( dirname( __FILE__ ) . '/my-calendar-templating.php' );
90
  include( dirname( __FILE__ ) . '/my-calendar-generator.php' );
91
 
92
  // Enable internationalisation
93
+ add_action( 'plugins_loaded', 'mc_load_textdomain' );
94
+ function mc_load_textdomain() {
95
+ load_plugin_textdomain( 'my-calendar', false, dirname( plugin_basename( __FILE__ ) ) . '/lang' );
96
+ }
97
 
98
  if ( version_compare( get_bloginfo( 'version' ), '3.0', '<' ) && is_ssl() ) {
99
  $wp_content_url = str_replace( 'http://', 'https://', get_option( 'siteurl' ) );
118
  add_filter( 'widget_text', 'do_shortcode', 9 );
119
  add_filter( 'plugin_action_links', 'mc_plugin_action', - 10, 2 );
120
  add_filter( 'wp_title', 'mc_event_filter', 10, 3 );
121
+ // Customize canonical URL
122
+ add_action( 'init', 'mc_custom_canonical' );
123
+ function mc_custom_canonical() {
124
+ add_action( 'wp_head', 'mc_canonical' );
125
+ remove_action( 'wp_head', 'rel_canonical' );
126
+ }
127
+
128
+ function mc_canonical() {
129
+ // original code
130
+ if ( !is_singular() ) {
131
+ return;
132
+ }
133
+ global $wp_the_query;
134
+ if ( !$id = $wp_the_query->get_queried_object_id() ) {
135
+ return;
136
+ }
137
+
138
+ // original code
139
+ $link = get_permalink( $id );
140
+ if ( $page = get_query_var('cpage') ) {
141
+ $link = get_comments_pagenum_link( $page );
142
+ }
143
+ if ( isset( $_GET['mc_id'] ) ) {
144
+ $mc_id = ( is_numeric( $_GET['mc_id'] ) ) ? $_GET['mc_id'] : false;
145
+ $link = add_query_arg( 'mc_id', $mc_id, $link );
146
+ }
147
+ echo "<link rel='canonical' href='$link' />\n";
148
+ }
149
 
150
  function mc_event_filter( $title, $sep = ' | ', $seplocation = 'right' ) {
151
+ if ( isset( $_GET['mc_id'] ) && is_numeric( $_GET['mc_id'] ) ) {
152
  $id = (int) $_GET['mc_id'];
153
  $event = mc_get_event( $id );
154
+ if ( mc_event_is_hidden( $event ) ) {
155
+ return $title;
156
+ }
157
  $array = mc_create_tags( $event );
158
  $left_sep = ( $seplocation != 'right' ? ' ' . $sep . ' ' : '' );
159
  $right_sep = ( $seplocation != 'right' ? '' : ' ' . $sep . ' ' );
195
  <?php if ( ! function_exists( 'mcs_submit_exists' ) ) { ?>
196
  <div class="ui-sortable meta-box-sortables">
197
  <div class="postbox support">
198
+ <h3 class='sales'><strong><?php _e( 'My Calendar Pro', 'my-calendar' ); ?></strong></h3>
199
 
200
  <div class="inside resources">
201
+ <p class="mcsbuy"><?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>
202
 
203
+ <p class="mc-button"><a href="http://www.joedolson.com/my-calendar/pro/" rel="external"><?php _e( 'Learn more!', 'my-calendar' ); ?></a>
204
  </p>
205
  </div>
206
  </div>
434
  }
435
  if ( function_exists( 'add_submenu_page' ) ) {
436
  add_action( "admin_head", 'my_calendar_write_js' );
437
+ add_action( "admin_enqueue_scripts", 'my_calendar_add_styles' );
438
  if ( get_option( 'mc_remote' ) == 'true' ) {
439
  } else { // if we're accessing a remote page, remove these pages.
440
  $edit = add_submenu_page( apply_filters( 'mc_locate_events_page', 'my-calendar' ), __( 'Add New Event', 'my-calendar' ), __( 'Add New Event', 'my-calendar' ), 'mc_add_events', 'my-calendar', 'edit_my_calendar' );
456
  $permission = apply_filters( 'mcs_submission_permissions', 'manage_options' );
457
  add_action( "admin_head", 'my_calendar_sub_js' );
458
  add_action( "admin_head", 'my_calendar_sub_styles' );
459
+ add_submenu_page( 'my-calendar', __( 'My Calendar Pro Settings', 'my-calendar' ), __( 'My Calendar Pro', 'my-calendar' ), $permission, 'my-calendar-submissions', 'mcs_settings' );
460
+ add_submenu_page( 'my-calendar', __( 'Payments Received', 'my-calendar' ), __( 'Payments', 'my-calendar' ), $permission, 'my-calendar-payments', 'mcs_sales_page' );
461
  }
462
  }
463
 
491
  'event_open' => __( 'Event Registration options', 'my-calendar' ),
492
  'event_location' => __( 'Event Location fields', 'my-calendar' ),
493
  'event_specials' => __( 'Set Special Scheduling options', 'my-calendar' ),
494
+ 'event_access' => __( 'Event Accessibility', 'my-calendar' ),
495
+ 'event_host' => __( 'Event Host', 'my-calendar' )
496
  );
497
  $output = '';
498
  foreach ( $input_options as $key => $value ) {
readme.txt CHANGED
@@ -2,10 +2,10 @@
2
  Contributors: joedolson
3
  Donate link: http://www.joedolson.com/donate.php
4
  Tags: calendar, dates, times, event, events, scheduling, schedule, event manager, event calendar, class, concert, conference, meeting, venue, location, box office, tickets, registration
5
- Requires at least: 3.8.5
6
- Tested up to: 4.2.2
7
  License: GPLv2 or later
8
- Stable tag: 2.3.31
9
 
10
  Accessible WordPress event calendar plugin. Show events from multiple calendars on pages, in posts, or in widgets.
11
 
@@ -16,7 +16,7 @@ My Calendar does WordPress event management with richly customizable ways to dis
16
  Easy to use for anybody, My Calendar provides enormous flexibility for designers and developers needing a custom calendar.
17
 
18
  * [Buy the User's Guide](http://www.joedolson.com/my-calendar/users-guide/) for extensive help with set up and use.
19
- * [Buy My Calendar: Submissions](https://www.joedolson.com/my-calendar/submissions/), the PRO extension for front-end event submissions
20
  * [Use My Tickets](https://wordpress.org/plugins/my-tickets/) and sell tickets to your My Calendar events
21
 
22
  = Features: =
@@ -41,10 +41,18 @@ Easy to use for anybody, My Calendar provides enormous flexibility for designers
41
  * Shortcode Generator to help create customized views of My Calendar
42
  * [Developer Documentation](http://www.joedolson.com/doc-category/my-calendar-3/)
43
 
 
 
 
 
 
 
 
 
44
  = Translations =
45
 
46
  Available translations (in order of completeness):
47
- Polish, Spanish (Spain), Portuguese (Portugal), French, Danish, Czech, Japanese, German, Russian, Dutch, Swedish, Italian, Hebrew, Galician, Portuguese (Brazil), Hindi, Turkish, Slovak, Finnish, Slovenian, Ukrainian, Romanian, Norwegian (Bokmal), Catalan, Afrikaans, Icelandic, Hungarian
48
 
49
  Visit the [My Calendar translations site](http://translate.joedolson.com/projects/my-calendar) to check the progress of a translation.
50
 
@@ -58,9 +66,10 @@ Translating my plug-ins is always appreciated. Visit <a href="http://translate.j
58
 
59
  2. Activate the plugin on your WordPress plugins page
60
 
61
- 3. Configure My Calendar using the following pages in the admin panel:
62
 
63
- My Calendar -> Add/Manage Events
 
64
  My Calendar -> Manage Categories
65
  My Calendar -> Manage Locations
66
  My Calendar -> Manage Event Groups
@@ -76,9 +85,77 @@ Translating my plug-ins is always appreciated. Visit <a href="http://translate.j
76
 
77
  == Changelog ==
78
 
 
 
 
 
 
 
 
 
79
  = 2.4.0 =
80
 
81
- [2.4.0 is currently in development.]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
 
83
  = 2.3.32 =
84
 
@@ -99,7 +176,7 @@ Translating my plug-ins is always appreciated. Visit <a href="http://translate.j
99
 
100
  = 2.3.29 =
101
 
102
- * Security Fix: XSS issue with add_query_arg: https://yoast.com/tools/wrong-use-of-add_query_arg-and-remove_query_arg-causing-xss/
103
 
104
  = 2.3.28 =
105
 
@@ -436,1031 +513,6 @@ This is a major revision.
436
  * Scheduled removal of showkey, shownav, toggle, and showjump shortcode attributes.
437
  * Removed upgrade support for 1.6.x & 1.7.x series of My Calendar.
438
 
439
- = 2.2.13 =
440
-
441
- * Bug fix: Threw error if network-activated (wp_is_mobile() not defined yet)
442
- * Bug fix: Calendar URI could be saved as integer instead of as URL.
443
- * Bug fix: hide screen options that current user can't use.
444
- * Improved localization of Calendrical jQuery plug-in.
445
- * Feature: my_calendar_upcoming and my_calendar_today shortcodes now support filtering by host.
446
- * New filter: mc_send_notification -- passes event and user data to determine whether a new event email notification should be sent. Return true|false.
447
-
448
- = 2.2.12 =
449
-
450
- * Bug fix: jquery.calendrical time rendering.
451
-
452
- = 2.2.11 =
453
-
454
- * Required deleted file.
455
-
456
- = 2.2.10 =
457
-
458
- * Bug fix: date comparison in grouped event date output.
459
- * Bug fix: editing a single occurrence of an event when location fields not displayed could result in duplicating the event.
460
- * Bug fix: Duplicated <a> on event title in events manager.
461
- * Bug fix: Generated WP to Twitter empty sentence error.
462
- * Bug fix: Grouped events within a single day in upcoming events list.
463
- * Bug fix: Run My Calendar upgrade stylesheet archiving only when My Calendar is updated.
464
- * Bug fix:
465
- * Changed: replaced mc_is_mobile() functionality with native wp_is_mobile(). Filterable for My Calendar using 'mc_is_mobile' filter.
466
- * Changed: properly registered and enqueue most front-end styles.
467
- * Changed: Removed classes 'prevMonth' and 'nextMonth' from navigation.
468
- * Misc. minor style changes to front and back end UI.
469
- * Added: special value for 'author' and 'host' attributes of 'current' to only show events created by the logged-in user. Filter via 'mc_display_author' and 'mc_display_host'
470
- * Added: date and time to title field for My Calendar RSS feed.
471
- * Preparation: permission filtering for submissions and registrations add-ons.
472
- * Updated: German & Slovenian Translations.
473
-
474
- = 2.2.9 =
475
-
476
- * Bug fix: Reversed argument in $details filter, breaking custom template editor.
477
-
478
- = 2.2.8 =
479
-
480
- * Bug fix: Fix in mini calendar scripting with AJAX.
481
- * Bug fix: Strict error in My Calendar Search widget.
482
- * Bug fix: My Calendar screen options disabled other screen options.
483
- * Updated: Slovenian
484
- * Documentation error: cat_id, not category_id
485
- * Added support for <a href="http://wordpress.org/plugins/botsmasher/">BotSmasher</a> as a spam filter for events.
486
- * Removed location region from Google Maps string (Google Maps choked on that data.)
487
- * Removed EasyDrag jQuery plug-in due to compatibility issues.
488
- * Eliminated 4 filters: mc_event_content_{$type}; replaced with single filter mc_event_content with $type parameter.
489
- * Added support for WP 3.6 shortcode attribute filters.
490
- * Added more filters & actions. Lots and lots of filters. Actions. Yeah.
491
- * Maybe I'm the only one excited about the last thing.
492
-
493
- = 2.2.7 =
494
-
495
- * Bug fix: map links could render links with no data.
496
-
497
- = 2.2.6 =
498
-
499
- * Bug fix: Link to single day events from mini calendar broken.
500
- * Bug fix: Return to calendar link from print view
501
- * Bug fix: some map links missing 'external' class.
502
- * Updated: couple missing i18n strings
503
- * Bug fix: widget title link could not be saved.
504
- * Bug fix: Changing the event time on individual occurrences of a recurring event showed wrong time in upcoming events list.
505
- * Bug fix: rewrite of AJAX scripting to clear bugs.
506
- * Bug fix: Event authors with "add" capability could not edit their own events or copy events from the admin.
507
- * Bug fix: Time frame toggles triggered beginning of month instead of current week/day if no params set.
508
- * Deprecated upgrade paths from versions prior to 1.5.0.
509
- * Eliminated single-day timeline URL settings field (no longer required.)
510
- * Added filter mc_modify_day_uri to allow above target URL to be customized.
511
- * Removed caching option; caching accessible only via filtering.
512
- * Updated: French, Italian, French, Slovenian
513
- * Added: Galician
514
-
515
- = 2.2.5 =
516
-
517
- * Bug fix: better bug fix in 2.2.3 event duplication bug.
518
- * Updated: Japanese translation.
519
-
520
- = 2.2.4 =
521
-
522
- * Bug fix: event duplication bug in 2.2.3
523
-
524
- = 2.2.3 =
525
-
526
- * Bug fix: duplicate attribute 'rel' in prev/next nav.
527
- * Bug fix: category color associations on event titles when no color assigned.
528
- * Bug fix: print view would not always display all categories if no limits set.
529
- * Bug fix: Group editor lost multi-day settings.
530
- * Improvement: throw a warning on events set up with problem settings, e.g. recurring events where the next occurrence begins before the current event has ended.
531
- * Added template tag: {map_url} for Google Map URL.
532
- * New filters: filters for calendar year/month/day (to change the default start date for the calendar.)
533
- * Language updates: Japanese, Italian, Dutch, Romanian, and Slovenian
534
-
535
- = 2.2.2 =
536
-
537
- * Bug fix to importer from Calendar
538
- * Another fix to link_map (this time, in the standard calendar view.)
539
- * Bug fix: location preset being assigned didn't allow changes to location details when editing events.
540
-
541
- = 2.2.1 =
542
-
543
- * Bug fix: Pull multi-day events in upcoming events list that happen today, but started on a previous day when past events set to 0.
544
- * Bug fix: broken {link_map} template tag.
545
- * Update to Italian translation.
546
-
547
- = 2.2.0 =
548
-
549
- * New feature: event search (widget).
550
- * New feature: with <a href="http://wordpress.org/extend/plugins/wp-to-twitter">WP to Twitter</a> installed, auto post events to Twitter when published or approved.
551
- * New feature: toggle timeframe between month/week/day view
552
- * New setting: ensure best possible color contrast between background color and title link.
553
- * Split manage events page and add event page into two separate interfaces.
554
- * Removed non-sortable fields from display for manage events interface.
555
- * Moved setting for number of events on manage events page to screen options.
556
- * New screen option: on event manager screen, users can turn off areas of the event manager they don't use.
557
- * New template tag: {image_url}, to pull an event's associated image without HTML
558
- * New template tag: {linking}, event URL with fallback to details link
559
- * New template tags: {gravatar} and {host_gravatar} to show author/host gravatar images.
560
- * New filter: mc_event_mail_to.
561
- * New filter: mc_past_search_results.
562
- * New filter: mc_future_search_results.
563
- * New filter: mc_search_template
564
- * Added support for variable increments (e.g., every 3 weeks, every 4 months, etc.)
565
- * Added template tag support to notification email subject line
566
- * Added option to send HTML notification emails
567
- * Added option to set sending address for notification emails
568
- * Added template tag to add event to Google Calendar
569
- * Added 'check all' option to event manager.
570
- * Accessibility Improvement: added aria-live attributes.
571
- * New shortcode attributes: 'above' and 'below'. (Control order and display of elements above/below calendar.)
572
- * Deprecated shortcode attributes: showkey, shownav, toggle, showjump. Will be removed in My Calendar 2.3.0.
573
- * Updated shortcode generator to use new attributes. Also added support for author and host attributes.
574
- * Miscellaneous tweaks to all My Calendar themes.
575
- * jQuery improvements. (jQuery version 1.7 minimum requirement.)
576
- * Bug fix: multi-day events incorrectly displayed in Upcoming Events by dates view
577
- * Bug fix: Open events to details page briefly rendered empty details pop-up (requires script update)
578
- * Bug fix: <title> element filter didn't strip all HTML tags.
579
- * Bug fix: hcal end time
580
- * Bug fix: upcoming events miscounted number of events with overlapping multiday single events.
581
- * Bug fix: today's events are now counted towards total events in upcoming events list
582
- * Bug fix: retention of location data when location fields disabled in manager
583
- * Bug fix: documentation correction for remote DB
584
- * Bug fix: caching issue when filtering by location
585
- * Language updates: German, Spanish, French, Japanese, Dutch, Polish, Italian, Slovenian
586
- * Deprecated support for WordPress versions up to 3.3.0 due to jQuery version change.
587
-
588
- = 2.1.5 =
589
-
590
- * Bug fix: upcoming events timestamps were converted to UTC.
591
-
592
- = 2.1.4 =
593
-
594
- * Bug fix: weekly view when crossing years jumped to next year
595
- * Bug fix: Upcoming events sorting fix
596
- * Bug fix: Upcoming events count fix
597
- * Bug fix: print stylesheet directory fix.
598
-
599
- = 2.1.3 =
600
-
601
- * Bug fix: My Calendar stripped title elements from singular posts unless an SEO plug-in was installed.
602
-
603
- = 2.1.2 =
604
-
605
- * Bug fix: Miscounted number of events in upcoming events view when events were multiple days.
606
- * Bug fix: My Calendar URL guessing now only selects from published Pages/posts
607
- * Tweak: Minor change to HTML output in print view
608
- * Added: Option to display current month or current year using Upcoming Events widget.
609
- * Added: Filter to display a custom <title> on single event details pages with settings field to configure that title. (Improves SEO)
610
- * Language updates: Italian, Russian, Basque
611
-
612
- = 2.1.1 =
613
-
614
- * Bug fix: users without 'Approve Event' ability submitted unapproved events even when event approval was disabled.
615
-
616
- = 2.1.0 =
617
-
618
- * Miscellaneous filepath fixes for custom icons
619
- * Fixed filepath issue for custom content directory in loading calendar generator
620
- * Added templating options to RSS feed event format
621
- * Added two new template tags: description_stripped and shortdesc_stripped; returns the description fields with HTML removed.
622
- * Re-organized settings to provide better grouping.
623
- * Removed jumpbox default setting; jumpbox now only configurable via shortcode.
624
- * Bug fix: titles missing in list view when open to details link enabled.
625
- * Bug fix: Multi-day events listed only once in upcoming events lists.
626
- * Minor stylesheet tweaks.
627
-
628
- = 2.0.12 =
629
-
630
- * I horribly screwed up the Upcoming Events widget in 2.0.11. Please accept my apologies.
631
-
632
- = 2.0.11 =
633
-
634
- * Fixed Broken custom stylesheets editing/selection.
635
- * Added Custom links for widget title links
636
- * Fixed issue with event links expiring immediately
637
- * Fixed issue with holiday collisions restricted in Upcoming Events/events only when holiday category is displayed.
638
- * Added full year output option for iCal downloads.
639
- * Added setting for calendar heading month formatting.
640
- * Updated language files: Japanese, Italian, German, Turkish
641
-
642
- = 2.0.10 =
643
-
644
- * Updated Japanese, Turkish, and Italian translations
645
- * Bug fix: Upcoming Events list could not be limited to a single author.
646
- * Bug fix: Un-approved events were being displayed in some public contexts.
647
- * Bug fix: Problem with RSS feed template elements not rendering in some cases.
648
- * Bug fix: Upcoming Events removed events inappropriately in certain situations when 'skip on holidays' was checked
649
- * Bug fix: Updated method for getting current plugin URL.
650
- * Deprecated support for WordPress versions before 3.0.6.
651
-
652
- = 2.0.9 =
653
-
654
- * Bug fix: Email notification on event addition to admin did not receive event data.
655
- * Bug fix: Accidentally eliminated weekend class. Now it's back!
656
- * Bug fix: Events crossing multiple dates need per-date unique IDs
657
- * Code change: Some code simplification for current URL and plugin URL references.
658
- * Updated languages: Portuguese, Dutch, Italian
659
-
660
- = 2.0.8 =
661
-
662
- * Re-written (simplified) holiday exclusion mechanism.
663
- * Performance improvements to templating and event processing.
664
- * Bug fix: Import from Kieran's "Calendar" plug-in was broken.
665
- * Bug fix: 'nextmonth' class was attached to events in weekly view; not appropriate to view.
666
- * Bug fix: Deleting single instance deleted entire event series.
667
- * Added option: number of events per page in admin events list
668
-
669
- = 2.0.7 =
670
-
671
- * Bug fix: Show list view on mobile devices option did not work.
672
- * Bug fix: No longer forcing links on titles in list or mini view.
673
- * Bug fix: All-day events came up with random end times.
674
- * Change: All-day checkbox added.
675
- * Change: All-day events automatically forced to hide end times.
676
- * Change: removed X-WR-CALNAME field from iCal output for improved compatibility
677
- * Updates: Partial updates to Spanish, Italian, and Dutch translations.
678
-
679
- = 2.0.6 =
680
-
681
- * Bug fix: Mini calendar links pointed to current display month regardless of current display date.
682
- * Bug fix: if day parameter was set, the main calendar views showed events for month starting from that date.
683
- * Bug fix: if day view was targeted from mini calendar with default cid parameter set, would not react
684
- * Bug fix: Calendar could not show events which had start and end dates which spanned the displayed period but were not included in the displayed period.
685
- * Moved screenshots into assets folder in version repository.
686
- * Translation source updated at http://translate.joedolson.com/ - now the translations need refreshing!
687
-
688
- = 2.0.5 =
689
-
690
- * Bug fix: Date links were eliminated in mini calendar if option to link to day-view was enabled.
691
- * Bug fix: Today's events drew events based on UTC instead of current timezone.
692
-
693
- = 2.0.4 =
694
-
695
- * Bug fix: template variable misassigned in the Today's Events shortcode.
696
- * Change: Added option to output iCal either in UTC or with times as entered. (Previously only UTC)
697
-
698
- = 2.0.3 =
699
-
700
- * Bug fix: Upcoming events widget did not support the "show_today's events" option correctly.
701
- * Bug fix: Was not possible to set 12:00 am as the end time for an event.
702
- * Bug fix: prevented blank title in main calendar due to faulty template.
703
-
704
- = 2.0.2 =
705
-
706
- * Bug fix: My Calendar did not enqueue jQuery
707
- * Bug fix: Grid view did not display last day of month if first day of week and last day of month were both Sunday
708
-
709
- = 2.0.1 =
710
-
711
- * Bug fix: Error in default settings for event titles.
712
- * Bug fix: Single Event iCal export broken
713
- * Bug fix: Today's Events shortcode broken if author not specified
714
- * Change: Deleting or updating categories now refreshes the cache.
715
-
716
- = 2.0.0 =
717
-
718
- * Completely re-written database model for events.
719
- * Added: pagination on event manager list of events.
720
- * Added: Restrict groups manager lists to currently grouped/ungrouped lists of events.
721
- * Added links to other event instances visible when editing events with multiple instances.
722
- * Added default category selection.
723
- * Added feature: limit calendar views by event author.
724
- * Added feature: filter event manager view by location, author, or category.
725
- * Added feature: mark categories as private, to only show those events to logged-in users.
726
- * Added templating to locations list so user can produce list of any set of location data.
727
- * Added option in event manager to copy location data into Locations table
728
- * Added [my_calendar_event] shortcode to fetch information for a single event.
729
- * Added template tag {timerange} to display start-end times.
730
- * Change: all events now have an end time. Option to hide end times to maintain current display.
731
- * Bug fix: iCal had missing newline; events now return labeled UTC time
732
- * Bug fix: RSS does better job of clearing non-XML special characters.
733
- * Bug fix: If preset location was selected, no other edits to locations could be done.
734
- * Bug fix: when copying an event, the new event was grouped in the same group as the source event.
735
- * Bug fix: if stylesheet was disabled, stylesheet was erased on next save of style settings.
736
- * Bug fix to category limiting which matched category names like 'baseball' to show 'all' categories.
737
-
738
- = 1.11.3 =
739
-
740
- * Fatal error in PHP 5.4+ https://bugs.php.net/bug.php?id=54657
741
- * Bug fix: {date} and {time} template tags not rendered in details link when run in a template.
742
- * Bug fix: upgrade database button placement off-screen
743
- * Bug fix: layout on stylesheet editor caused usability problems
744
- * Bug fix: added line break in iCal output.
745
- * Change: added alt attribute to category icons in appropriate contexts.
746
- * [My Calendar 2.0 beta](http://downloads.wordpress.org/plugin/my-calendar.2.0.0.zip) added to subversion repository. Here there be bugs.
747
-
748
- = 1.11.2 =
749
-
750
- * Bug fix: Called wp_editor on versions below 3.3
751
- * Bug fix: assorted PHP notices cleaned up.
752
-
753
- = 1.11.1 =
754
-
755
- * HTML validation issue fixed in calendar output.
756
- * Added option to hide display of external event links in calendar output.
757
- * Bug fix: Mini calendar should not toggle from mini view when main view switched.
758
- * Bug fix: Week time frame of list view did not return the 'no events' message.
759
- * Feature: No events message can be customized by using an enclosing shortcode: [my_calendar]No events this week![/my_calendar]
760
-
761
- = 1.11.0 =
762
-
763
- * Added option to use {date} in Today's Events widget title.
764
- * Events with the same time are now sub-sorted by title in Upcoming Events lists.
765
- * Template tag {endtime} returns empty string if same as start time
766
- * Standard event output returns empty string for event end time if same as start time.
767
- * Can only check 'multi-day event' option if event has multiple occurrences.
768
- * Categories in editor now sortable by either ID or category name.
769
- * Categories in input now sorted by category name.
770
- * Updated mobile detection class.
771
- * Major revision to permissions handling to use custom capabilities
772
- * Redesign of settings pages.
773
- * Can target tablet devices with CSS by adding a stylesheet called mc-tablet.css to your theme directory.
774
- * Can target other mobile devices with CSS by adding a stylesheet called mc-mobile.css to your theme directory.
775
- * Template tags now support before and after attributes: {tag before=&quot;&lt;p&gt;&quot; after=&quot;&lt;/p&gt;&quot;}
776
- * Added option to retrieve events, categories, and locations from a remote database. (e.g., to share calendar information between 3 related sites.)
777
- * Eliminated details arrow; forcing anchor element on clickable title.
778
- * Added 'id' attribute to My Calendar shortcode, to customize unique ID for calendar and avoid non-compliant duplication of IDs
779
- * Added 'template' attribute to My Calendar shortcode, so specific calendars can use their own individual custom templates. Templates should be text files (.txt) placed in your theme directory.
780
- * Reduced specificity in stylesheets by eliminating ID-based references.
781
- * Fixed bug with day/date consistency in 5-day grid calendars.
782
- * Added day class to date boxes without dates.
783
- * Jumpbox is now switchable from the shortcode.
784
- * Fixed google maps link to use the correct directions targeting method
785
- * Various changes for WP 3.4 compatibility.
786
- * Updated Danish Translation
787
- * Updated Czech Translation
788
- * Added Hindi Translation
789
-
790
- = 1.10.12 =
791
-
792
- * Bug fix: List format showed all dates, regardless of whether there were events for that date.
793
- * Bug fix: List format showed incorrect classes.
794
- * Bug fix: Pipe separator for categories not supported with caching.
795
- * ARRRRGGGGHHHH!!! I'm sure you're as frustrated about all these little releases as I am. But who wants to sit on known bugs?
796
-
797
- = 1.10.11 =
798
-
799
- * Bug fix: Variable not checked for type threw usort warning.
800
- * Bug fix: Details links rendered incorrect page if linked from a single post location with permalinks not enabled.
801
- * Bug fix: Fixed bug where calendar returned no information if cache reached max size.
802
- * Settings change: Caching is now defaulted to off.
803
-
804
- = 1.10.10 =
805
-
806
- * Bug fix: Upcoming events list did not respect category limits.
807
- * Validation error/bug fix: Date for ID for first of month was incorrect.
808
- * Validation error: unencoded ampersand in iCal link if permalinks disabled.
809
-
810
- = 1.10.9 =
811
-
812
- * Added option to clear cache from settings.
813
- * Bug fix: Error in caching where cache returned false for multi-category limited calendars.
814
- * Bug fix: Error in caching where cache returned false for category limited calendars using category name as delimiter. Thanks to [Antti Palosaari](crope@iki.fi) for reporting this bug and for testing fixes.
815
- * Bug fix: Error notices if user is deleted who is assigned as host of some events. Thanks to Florian Edelmann for reporting this bug and contributing solution.
816
- * Bug fix: Upcoming events in dates mode returned null for cached dates.
817
-
818
- = 1.10.8 =
819
-
820
- * Bug fix: upcoming events list breaks if 'This is a multi-day event' is checked for an event with only a single occurrence.
821
- * Bug fix: Upcoming events caching did not cache correct data.
822
- * Modification: eliminated some extraneous database calls
823
- * Modified: clarifying text edits
824
- * Added: category classes on calendar date cells
825
-
826
- = 1.10.7 =
827
-
828
- * Made 'to' value in Google Maps links a translatable value.
829
- * Feature change: iCal download now respects currently selected month.
830
- * Added a phone number field to the Location manager
831
- * Added a setting to display only the core site's calendar on child sites in multisite mode.
832
- * Added a setting for the link target for mini calendar dates
833
- * Re-wrote labels for URL link target settings fields.
834
- * Bug fix: Location selector did not respect currently selected categories.
835
- * Bug fix: "Add another occurrence" option available in Edit mode, but not functional. Removed option.
836
- * Bug fix: Limiting by categories didn't trim whitespace from category names.
837
- * Bug fix: Fixed RSS/ICS/Print permalinks if PATHINFO permalinks are enabled.
838
- * Improved cache handling. Cache limit relative to amount of memory available to PHP. Cache stores information more efficiently.
839
- * Revised RSS/iCal handling to avoid .htaccess problems.
840
-
841
- = 1.10.6 =
842
-
843
- * Revised template tags so the description tags are run through wpautop(), and added _raw versions which are not.
844
- * Fixed a bug in URL generation so that URLs with ports are correctly constructed.
845
- * Fixed a bug iin Print output which did not allow restriction to multiple categories
846
- * Added option to use {date} in previous/next navigation links to indicate what date set is being navigated to.
847
-
848
- = 1.10.5 =
849
-
850
- * I made a truly bone-headed error in the last update, and I'm not even going to say what. If you didn't notice it, lucky for you!
851
-
852
- = 1.10.4 =
853
-
854
- * In my rush to fix the security issue, I broke an aspect of the event navigation. Apologies for this! Now fixed.
855
-
856
- = 1.10.3 =
857
-
858
- * Incorrectly called wp_kses(). Apologies for the frequent updates!
859
-
860
- = 1.10.2 =
861
-
862
- * Critical security update. Please upgrade promptly. Big thank you to Dean Batha for the bug report.
863
-
864
- = 1.10.1 =
865
-
866
- * Bug fix: undeclared array in widget manager
867
- * Renamed overly-generic constant.
868
-
869
- = 1.10.0 =
870
-
871
- * New feature: option to link dates in mini calendar to separate daily view instead of pop-up.
872
- * New feature: no longer necessary to manually edit behaviors in order to open main calendar event titles to separate page.
873
- * New feature: Ability to define grouped events as a single multi-day event and remove duplicates from events lists (upcoming events and today's events widgets)
874
- * New feature: group-association classes assigned to multi-day events in grid display.
875
- * New template tags: {daterange} and {multidate} for displaying a beginning and ending date range for a single event and for displaying each date in a multi-day event, respectively.
876
- * Week-view calendar caption now editable.
877
- * Added printable version.
878
- * Submit buttons in forms are now duplicated at top and bottom of long editing sections, to improve usability.
879
- * Minor style change to group editor to avoid group list colliding with editor textarea.
880
- * Removed angle brackets from Previous/Next events links.
881
- * Added custom action hooks for event save and event delete
882
- * Added ability to prevent today's events from showing up in upcoming events listings.
883
- * Added categories to iCal output.
884
- * iCal should return times in local time, not in UTC.
885
- * Bug fix: iCal output not correctly encoded
886
- * Bug fix: mc_next_link filter did not exist.
887
- * Bug fix: placed limit on maximum size of cached calendar data.
888
- * Bug fix: Upcoming events list will no longer occasionally display more items than expected.
889
- * Bug fix: menu icon not aware of custom content locations
890
-
891
- = 1.9.8 =
892
-
893
- * This is just a convenience update due to a warning appearing in 1.9.7 that I missed.
894
-
895
- = 1.9.7 =
896
-
897
- * Cache was not cleared when events were approved, rejected, or deleted.
898
- * Fixed bug with slashed characters in time and date formats
899
- * Fixed bug where previous/next links did not work on category pages
900
- * Fixed bug where event description was deleted if edited in groups manager.
901
- * Easydrag.js now respects conditional loading by page ID.
902
- * Small change to upcoming events list: events with an end time specifie and not crossing days will move off the list after they end rather than after they start.
903
-
904
- = 1.9.6 =
905
-
906
- * Fixed bug in Event Manager where information about whether an event was open for registration saved incorrectly.
907
- * Added raw details_link template tag.
908
- * Fixed Google Maps link error when using Long/Lat coordinates.
909
- * Associated image option was not available if HTML editor was enabled.
910
-
911
- = 1.9.5 =
912
-
913
- * Bug fix: Caching of Today's events did not account for category limits
914
- * Bug fix: Upcoming events listed by day duplication
915
-
916
- = 1.9.4 =
917
-
918
- * Bug fix: month-by-day recurring events in upcoming events list
919
- * Bug fix: duplication of events in upcoming events list
920
- * Bug fix: when editing a single event with indefinite recurrences, future events set up without continuing recurrence.
921
- * Function error when data not present fixed.
922
- * Added display of sending name/address for support messages
923
-
924
- = 1.9.3 =
925
-
926
- * Stylesheet saving can write longer files. Solves problem with occasional truncation of stylesheets.
927
- * Added transient caching for calendar events to improve performance, plus other various performance improvements
928
- * Small html output change.
929
- * 1.9.0 made details boxes draggable; made this optional.
930
- * Added plug-in support request form.
931
- * Added updated French translation to 1.9.2
932
- * Fixed bug with date switcher duplicating/skipping months.
933
- * Updated User's Guide (not included with plug-in)
934
-
935
- = 1.9.2 =
936
-
937
- * Bug fix: Fixed sort error returned by calendar if no events are in array.
938
- * Bug fix: Fixed incorrect URLs for icons in custom directory in category key.
939
- * Bug fix: Caption text did not display.
940
- * Added {date} and {time} to details link text templating.
941
- * Bug fix: Fixed {icon} URL in template output.
942
- * Bug fix: Fixed bug with table layout of dates when weekends are disabled on grid calendar.
943
- * Bug fix: Fixed bug with generation of details link when not using permalinks.
944
- * Bug fix: Fixed bug with HTML editor converting HTML entities.
945
- * Bug fix: Fixed bug where weekly view showed the wrong dates if the current week started in the previous month.
946
-
947
- = 1.9.1 =
948
-
949
- * Bug fix: Incorrect title template tag auto-generated if title template is empty.
950
- * Bug fix: Create events permissions broken
951
- * Bug fix: Host list broken in WordPress versions lower than 3.1
952
- * Bug fix: My Calendar not using WordPress defaults for customizable date and time settings if not set by user.
953
- * Bug fix: Turning off calendar icons did not turn off icons in key
954
- * Bug fix: details links used current URL instead of stored URL
955
- * Bug fix: default widget settings not loaded on upgrade.
956
- * Bug fix: next/previous links not working on home page if permalinks not set.
957
- * Bug fix: event title shown in date field in list mode was not for the first event of the day.
958
- * Style change: Minor change to my-calendar.css to adjust for the green background on weekends. (Which showed up as the result of a fix to an HTML problem in 1.8.9.)
959
- * Bug fix/Option add: Added option to remove individual iCal link
960
- * Option add: Added option to conceal first event title/number of events with date in list mode.
961
-
962
- = 1.9.0 =
963
-
964
- Additions:
965
-
966
- * template editing for list, grid, mini, and single event output.
967
- * pop-up box is now draggable.
968
- * date format option for grid mode, week view.
969
- * templating for details link text.
970
- * templating for event URL link text.
971
- * location filtering from shortcode.
972
- * image upload option for events
973
- * day class to calendar date headings and cells
974
- * individual instances of repeating events can be edited
975
- * feature to add multiple occurrences of an event simultaneously. (concept from Dave Heitzman)
976
- * feature to mass edit information for groups of events (concept from Dave Heitzman)
977
- * stored URL for locations (contrib by John Colvin)
978
- * recurring daily events on weekdays only (based on contrib by John Colvin)
979
- * optional templating for all event output formats
980
- * individual event occurrence iCal export
981
- * numerous additional template tags
982
- * Option to use custom location filter fields as data control
983
- * Shortcode to generate list of saved locations
984
- * Network administrators can control whether sub-site calendars contribute only to a central calendar, only to their own calendar, or whether site administrators can make that choice.
985
- * Upgrade notice information in dashboard for future upgrades.
986
- * implementation of WordPress text diff to compare your styles and scripts against my current released versions
987
- * Option to skip a defined number of events in upcoming events lists.
988
-
989
- Bug fixes:
990
-
991
- * jump box was displaying in week/grid view.
992
- * some potentially repeatable IDs (code validation).
993
- * 'Administrators see all options' did not work.
994
- * Fixed timestamps on main calendar objects
995
- * Squashed e_notice errors.
996
- * category limiting did not work without permalinks due to GET variable conflict with WordPress core
997
- * Missing nonce in database upgrade routine
998
- * Mini calendar simultaneously displayed single event view when visited.
999
- * Link generation for details view did not work if calendar link parameterized
1000
- * Issue with weekdays only calendar if day of week set to start on Sunday
1001
- * Issue with retrieval of user-specific settings
1002
- * Issue with accessing styles and javascript if My Calendar installed in non-standard directory.
1003
- * Problem in Today's Events widget when Holiday restrictions are enabled.
1004
-
1005
- Changes:
1006
-
1007
- * replaced all default icons with 24-bit transparent PNGs
1008
- * jumpbox output to automatically scope to the oldest dates in the database.
1009
- * iCal output changed to output all events for complete current month
1010
- * RSS output to prioritze newly added events
1011
- * holiday skipping/fifth week customization moved into event manager function
1012
- * new 'close' icon for pop-up box; added close icon and scripting to mini calendar pop-up
1013
- * copy in several places; updated template tags.
1014
- * location lists sorted by location label (contrib by John Colvin)
1015
- * Eliminated calendar heading option
1016
- * default style resets no longer stored in global variables, instead stored as files.
1017
- * Map links now trigger the driving directions dialog in Google Maps
1018
- * New default stylesheet, refresh.css
1019
-
1020
- = 1.8.9 =
1021
-
1022
- * Fixed bug with database upgrade in multi-user additional calendars
1023
- * Fixed bug where calendar picked up current month labeling using current day of the month
1024
- * Added French translation
1025
-
1026
- = 1.8.8 =
1027
-
1028
- * Fixed bug in locations filtering that disabled feature if user not logged in.
1029
- * Re-arranged settings and added notices about options which will be removed in a future release.
1030
- * Revised RSS feed to use event permalinks when they are available.
1031
-
1032
- = 1.8.7 =
1033
-
1034
- * One very minor change in 1.8.6 caused some plug-in conflicts, so I rolled that change back. Will find another solution to the problem it solved. This change affects very few users.
1035
-
1036
- = 1.8.6 =
1037
-
1038
- * Fixed bug with {details} template tag when Upcoming widgets configured as Events
1039
- * Location and category filters now do not display forms/lists if there isn't more than one choice.
1040
- * Extended details link feature to main calendar output and added to output options.
1041
- * Minor changes to time-entry jQuery plug-in to improve usability.
1042
- * Updated Japanese translation to 1.8.5
1043
- * Added Russian translation to 1.8.5
1044
-
1045
- = 1.8.5 =
1046
-
1047
- * Another bug fix to monthly-by-day recurrence.
1048
- * Fixed minor problem with default template not being visible in widget.
1049
- * Fixed 'widget title linked' bug.
1050
- * Added Turkish translation by Mehmet Ko&231;ali
1051
-
1052
- = 1.8.4 =
1053
-
1054
- * Mini calendar widget had a mis-labeled option field
1055
- * Custom User settings for event region didn't function correctly.
1056
- * A variety of bug fixes applied to events repeating on a monthly-by-day basis
1057
-
1058
- = 1.8.3 =
1059
-
1060
- * Turned on spam flag toggle, which I had commented out and failed to restore...
1061
- * Default return false ('not spam') for privileged users when checking Akismet
1062
-
1063
- = 1.8.2 =
1064
-
1065
- * Fixed bug with {icon} template tag, for real.
1066
- * Fixed RSS missing argument
1067
- * Fixed empty list rendering in upcoming events widget
1068
-
1069
- = 1.8.1 =
1070
-
1071
- * Fixed bug with region saving on edit of location
1072
- * Fixed bug with single-event view receiving date as array
1073
- * Fixed bug with {icon} template tag
1074
- * Fixed bug with calendar output if user settings are enabled but not applied by user
1075
- * Fixed bug with list/grid format toggle
1076
- * Fixed bug with upcoming events limited by category names
1077
-
1078
- = 1.8.0 =
1079
-
1080
- * Added event region as a location field
1081
- * Added time selector and altered calendar range selector.
1082
- * Added visual editor for event description textarea.
1083
- * Added templating tag to add a link to the single event view.
1084
- * Added option to not display weekends in grid format.
1085
- * Added unique ID for each event in calendar.
1086
- * Added default sort order option for admin events list.
1087
- * Added admin events list to screen while editing or copying event.
1088
- * Added shortcode generator for Page and Post editor.
1089
- * Added spam protection: New events are now checked through Akismet if installed and configured.
1090
- * Added category selection shortcode.
1091
- * Added mini calendar widget.
1092
- * Added external link class.
1093
- * Added list/grid view toggle.
1094
- * Added mobile detection so mobile devices receive list format without JavaScript for easier reading.
1095
- * Added Upcoming Events widget sort order option.
1096
- * Added Option to link widget title to main calendar page.
1097
- * Change: Minor reorganization of settings page.
1098
- * Change: Altered time input to use non-military format time, added JavaScript time input.
1099
- * Change: Moved My Calendar menu items into the content menu.
1100
- * Change: When calendar is limited by categories, only the displayed categories are listed in the category key.
1101
- * Change: If widget title is left blank, widget will have no title.
1102
- * Change: Moved translation files into a subdirectory (/lang/)
1103
- * Bug fix: hcal dates
1104
- * Bug fix: problem where restoring styles referenced out of date styles
1105
- * Bug fix: error in primary stylesheet
1106
- * Bug fix: issue with month-by-day recurring events when recurrance set at 0
1107
- * Bug fix: issue with end dates when recurrance set at 0
1108
- * Bug fix: DB installed to match WPDB chararacter set and collation.
1109
- * Bug fix: turn-of-year page navigation in week view.
1110
- * Bug fix: entries not remembered in error condition post
1111
- * Updated German Translation to version 1.7.0 (Christopher Schauer)
1112
- * Updated German Translation to version 1.7.8 (Uwe Jonas)
1113
- * Note: during this update cycle, I received two German translations, and am using the most up to date version.
1114
- * Added Swedish Translation to version 1.7.8
1115
-
1116
- = 1.7.8 =
1117
-
1118
- * Bug fix: Behaviors page limits lost on settings refresh
1119
- * Bug fix: Fix {enddate} shortcode output.
1120
- * Bug fix: iCal output improvements
1121
- * Modification: RSS and iCal output are disabled entirely when turned off, rather than just hidden.
1122
- * Modification: Added styles for days out of current month
1123
-
1124
- = 1.7.7 =
1125
-
1126
- * Bug fix: Upcoming Events widget fault in 'dates' mode.
1127
-
1128
- = 1.7.6 =
1129
-
1130
- * Bug fix: Upcoming Events widget in days mode was not offsetting time using GMT reference. (Committed silently in 1.7.5)
1131
- * Bug fix: Default template not rendered in Today's Events when template left blank
1132
- * Bug fix: Slashes not stripped in category key.
1133
- * Bug fix: Upcoming Events widget if no upcoming events
1134
- * Bug fix: Error with retrieval of Author's ID
1135
- * Fixed some non-translatable text strings
1136
- * Logic change: Upcoming Events now bases choice on time rather than date (events happening later today are future, rather than only events happening tomorrow or later.)
1137
- * Enhancement: respects custom wp-content location definitions
1138
-
1139
- = 1.7.5 =
1140
-
1141
- * Bug fix: Error with upcoming events when selected by dates and holiday skipping enabled.
1142
- * Bug fix: Upcoming Events widget title defaulted to 'Today's Events'
1143
- * Change: Reversed order of Latitude/Longitude on forms to match Google's implementation.
1144
-
1145
- = 1.7.4 =
1146
-
1147
- * Bug fix: Upcoming events templates ran htmlentities on output
1148
-
1149
- = 1.7.3 =
1150
-
1151
- * Bug fix: upcoming events substitute text still not appearing in some contexts.
1152
- * Bug fix: Today's event substitute text had assignment in place of comparison
1153
- * Bug fix: Event location not saved properly on edit if Location Fields are disabled on input
1154
- * Bug fix: Fixed date and time issues in iCal output
1155
- * Bug fix: Fixed character set issue in RSS output
1156
- * Bug fix: Major problem with Holiday category event delimiting
1157
- * Danish translation updated to 1.7.0
1158
- * Japanese translation updated to 1.7.1
1159
- * Minor documentation and readme.txt updates
1160
- * Added additional fallback settings for widgets
1161
- * Fixed minor installation issue with version detection.
1162
- * Added CSS hook .nextmonth on dates occurring past the end of the currently displayed month.
1163
- * Added check for '#' symbol on hex colors in category management.
1164
-
1165
- = 1.7.2 =
1166
-
1167
- * Bug fix: Fixed import from Calendar feature.
1168
- * Bug fixed: Upcoming events widget default text fixed
1169
- * Italian translation updated to 1.7.0
1170
-
1171
- = 1.7.1 =
1172
-
1173
- * Default setting for custom user location type not set
1174
- * Reset for inherit.css styles missing
1175
- * Widget shortcodes stripped HTML
1176
- * Added a fallback function for exif_imagetype 'cuz some servers don't have it available by default.
1177
- * Nonce missing in database upgrade
1178
- * Ability to edit text for shortcode fallback (No events text) lost.
1179
- * Widget defaults not installed on new installation
1180
- * Mini and List jQuery did not prevent default link action
1181
- * Changed install action to default User settings to off.
1182
-
1183
- = 1.7.0 =
1184
-
1185
- * Fix in AJAX navigation for IE
1186
- * Fix in JavaScript to re-activate close button
1187
- * Fixed bug with locations list not registering current location type in form mode
1188
- * Fixed bug with upcoming events and today's events output when regions limits were set
1189
- * Fixed bug with upcoming events producing incorrect dates for events recurring on a specific day of the month.
1190
- * Revision of Widgeting setup to offer multi-widget support (will require you to re-setup your widgets)
1191
- * Revision of style editor to use external stylesheets.
1192
- * Revision of style support to add option for custom stylesheets stored outside of plugin directory
1193
- * Added: multiple base stylesheets
1194
- * Added: Event markup in hCal format
1195
- * Added Weekly mode for list and grid view
1196
- * Added RSS and iCal exports for upcoming events (enable and disable in settings)
1197
- * Added option to block display of an event if there is an event that day which is in a designated 'Holiday' category.
1198
- * Added permission setting to allow non-administrators to edit or delete any event.
1199
- * Added Czech translation (to 1.6.3)
1200
- * Updated Italian and Danish translations
1201
- * Security: Implemented nonces
1202
-
1203
- = 1.6.3 =
1204
-
1205
- * Updated jQuery to fix conflicts in previous versions and so behaviors would work with AJAX navigation. Not updated by upgrade; use Behaviors reset to apply.
1206
- * Incorporated option to enable AJAX navigation for next/previous navigation.
1207
- * Fixed bug with multi-month display in list format where January could not be displayed.
1208
- * Revised settings page for clarity.
1209
- * Fixed some default settings issues.
1210
- * Fixed a bug where the locations lists didn't respect the datatype parameter.
1211
- * Added templating to event titles for calendar grid or list output.
1212
-
1213
- = 1.6.2 =
1214
-
1215
- * Fixed broken style editor. (The way it was broken was awfully weird...kinda wonder how I did it!)
1216
- * Fixed missing div in calendar list output.
1217
- * Removed debugging call which had been left from testing.
1218
- * Fixed storage of initial settings for user settings (array did not store probably initially.)
1219
- * Added Italian translation by [Sabir Musta](http://mustaphasabir.altervista.org)
1220
-
1221
- = 1.6.1 =
1222
-
1223
- * Bug fix in event saving
1224
-
1225
- = 1.6.0 =
1226
-
1227
- * Feature: User profile defined time zone preference
1228
- * Feature: User profile defined location preference
1229
- * Feature: Define event host as separate from event author
1230
- * Feature: Added ability to hide Prev/Next links as shortcode attribute
1231
- * Change: Separated Style editing from JS editing
1232
-
1233
- = 1.5.4 =
1234
-
1235
- * Fixed: Bug with permissions in event approval process.
1236
-
1237
- = 1.5.3 =
1238
-
1239
- * Fixed: Bug which broke the {category} template tag
1240
- * Fixed: Bug which moved extra parameters before the "?" in URLs
1241
- * Fixed: Bug which produced an incorrect date with day/month recurring events on dates with no remainder
1242
- * Added: Japanese translation by [Daisuke Abe](http://www.alter-ego.jp/)
1243
-
1244
- = 1.5.2 =
1245
-
1246
- * Fixed: Bug where event data wasn't remembered if an error was triggered on submission.
1247
-
1248
- = 1.5.1 =
1249
-
1250
- * Fixed: Bug where events recurring monthly by days appeared on wrong date when month begins on Sunday.
1251
- * Fixed: Bug where events recurring monthly by days appeared on dates prior to the scheduled event start.
1252
- * Performance improvement: Added SQL join to incorporate category data in event object
1253
- * Added quicktag to provide access to category color and icon in widget templates
1254
- * Changed link expiration to be associated with the end date of events rather than the beginning date.
1255
- * Updated readme plugin description, help files, and screenshots.
1256
-
1257
- = 1.5.0 =
1258
-
1259
- * Added: German translation.
1260
- * Updated: Danish translation.
1261
- * Added: Administrator notification by email feature [Contributions by Roland]
1262
- * Added: Reservations and Approval system for events. [Contributions by Roland]
1263
- * Added: Events can be recurring on x day of month, e.g. 3rd Monday of the month.
1264
-
1265
- = 1.4.10 =
1266
-
1267
- * Fixed: Failed to increment internal version pointer in previous version.
1268
- * Fixed: Invalid styles created if category color set to default.
1269
- * Fixed: (Performance) Default calendar view attempted to select invalid category.
1270
- * Updated: Danish translation.
1271
-
1272
- = 1.4.9 =
1273
-
1274
- * Fixed: Bug where location edits couldn't be saved if location fields were on and dropdown was off
1275
- * Fixed: Bug where latitude and longitude were switched on Google Maps links
1276
- * Fixed: Bug where map link would not be provided if no location data was entered except Lat/Long coordinates.
1277
-
1278
- = 1.4.8 =
1279
-
1280
- * Added: Ability to copy events to create a new instance of that event
1281
- * Added: Customization of which input elements are visible separate from what output is shown.
1282
- * Fixed: Issue where one JS element could not be fully disabled
1283
- * Fixed: Internationalization fault with Today's Events showing events from previous day
1284
- * Fixed some assorted text errors and missing internationalization strings.
1285
- * Fixed issue where the 'Help' link was added to all plug-in listings.
1286
- * Reorganized settings page UI.
1287
-
1288
- = 1.4.7 =
1289
-
1290
- * Fixed: Bug where infinitely recurring events whose first occurrence was in the future were not rendered in upcoming events
1291
- * Fixed: Bug where infinitely recurring bi-weekly events only rendered their first event in calendar view
1292
- * Added: Option to indicate whether registration for an event is open or closed, with customizable text.
1293
- * Added: Option to supply a short description alternative to the full description.
1294
-
1295
- = 1.4.6 =
1296
-
1297
- * Fixed: Flash of unstyled content prevention scripts weren't disabled when other scripting was disabled.
1298
- * Fixed: Categories which started with numerals couldn't have custom styles.
1299
- * Fixed: Locations required valid 0 float value to save records on some servers; now supplied by default.
1300
-
1301
- = 1.4.5 =
1302
-
1303
- * Fixed a bug with editing and adding locations
1304
- * Fixed a bug with error messages when adding categories
1305
- * Fixed a bug with identification of current day (again?)
1306
- * Added Danish translation (Thanks to Jakob Smith)
1307
-
1308
- = 1.4.4 =
1309
-
1310
- * Fixed a bug where event end times tags were not rendered when blank in widget templates
1311
- * Fixed a bug with event adding and updating for Windows IIS
1312
- * Fixed a bug with international characters
1313
- * Reduced number of SQL queries made.
1314
- * Moved JavaScript output to footer.
1315
- * Improved error messages.
1316
- * Significant edits to basic codebase to improve efficiency.
1317
- * Fixed bug where full default styles didn't initially load on new installs.
1318
- * Re-organized default styles to make it easier for users to customize colors.
1319
-
1320
- = 1.4.3 =
1321
-
1322
- * Fixed a bug where event end times were displaying the start time instead when editing.
1323
- * Fixed a bug introduced by the mini calendar option which displayed titles twice in list format.
1324
- * Fixed a bunch of typos.
1325
- * Added a loop which automatically adds the mini calendar styles if you don't already have them.
1326
- * Fixed a bug where JS didn't run if the 'show only on certain pages' option was used.
1327
- * Added a qualifier for upgrading databases when you haven't added any events.
1328
-
1329
- = 1.4.2 =
1330
-
1331
- * Fixed a bug in the widget display code which caused problems displaying multiple categories.
1332
-
1333
- = 1.4.1 =
1334
-
1335
- * Database upgrade didn't run for some users in 1.4.0. Added manual check and upgrade if necessary.
1336
-
1337
- = 1.4.0 =
1338
-
1339
- * Bug fixed: Today's Events widget was not taking internationalized time as it's argument
1340
- * Added end time field for events
1341
- * Added option for links to expire after events have occurred.
1342
- * Added options for alternate applications of category colors in output.
1343
- * Added ability to use My Calendar shortcodes in text widgets.
1344
- * Added GPS location option for locations
1345
- * Added zoom selection options for map links
1346
- * Lengthened maximum length for category and event titles
1347
- * Added a close link on opened events details boxes.
1348
- * Added an option for a mini calendar display type in shortcode
1349
- * Optimized some SQL queries and reduced total number of queries significantly.
1350
- * Extended the featured to show CSS only on certain pages to include JavaScript as well.
1351
- * Upcoming events widget only allowed up to 99 events to be shown forward or back. Changed to 999.
1352
- * Attempted to solve a problem with infinitely recurring events not appearing in upcoming events. Let me know.
1353
- * Added setting to change Previous Month/Next Month text.
1354
- * Yeah, that's enough for now.
1355
-
1356
- = 1.3.8 =
1357
-
1358
- * Fixed problem with CSS editing which effectively disabled CSS unless a specific choice had been made for pages to show CSS
1359
-
1360
- = 1.3.7 =
1361
-
1362
- * Aren't you enjoying the daily upgrades? I made a mistake in 1.3.5 which hid text in an incorrect way, causing problems in some contexts.
1363
-
1364
- = 1.3.6 =
1365
-
1366
- * Fixed an issue where not having defined Pages to show CSS resulted in a PHP warning for some configs.
1367
-
1368
- = 1.3.5 =
1369
-
1370
- * Fix for flash of unstyled content issue.
1371
- * Added configuration for time text on events with non-specific time.
1372
- * Fixed bug where, in list views with multiple months, events occurring on days which did not exist in the previous month were not rendered. (Such as March 30th where previous month was February.)
1373
- * Fixed bug where the multi-month view setting for lists caused previous/next events buttons to skip months in calendar view.
1374
- * Added option to disable category icons.
1375
- * Added option to insert text in calendar caption/title area, appended to the month/year information.
1376
- * Fixed a bug where it was not possible to choose the "Show by days" option in the upcoming events widget.
1377
- * Updated documentation to match
1378
- * Fixed a bug where upcoming events in Days mode did not display correct date
1379
- * Added an option to define text to be displayed in place of Today's Events widget if there are no events scheduled.
1380
- * Minor changes to default CSS
1381
- * Ability to show CSS and JavaScript only on selected pages.
1382
-
1383
- = 1.3.4 =
1384
-
1385
- * Fixed a bug with map link and address display which I forgot to deal with in previous release.
1386
-
1387
- = 1.3.3 =
1388
-
1389
- * Fixed bug with upgrade path which caused locations database to be created on every activation (also cause of errors with some other plugins). (Thanks to Steven J. Kiernan)
1390
- * Made clone object PHP 4 compatible (Thanks to Peder Lindkvist)
1391
- * Corrected errors in shortcode functions for today's events
1392
- * Corrected rendering of non-specific time events as happening at midnight in widget output
1393
-
1394
- = 1.3.2 =
1395
-
1396
- * Fixed bugs with unstripped slashes in output
1397
- * Fixed a bug where users could not add location information in events if they had not added any recurring locations
1398
- * Removed requirement that address string must be five characters to display a link
1399
-
1400
- = 1.3.1 =
1401
-
1402
- * Corrected incorrect primary key in upgrade path.
1403
- * Added version incrementing in upgrade path.
1404
-
1405
- = 1.3.0 =
1406
-
1407
- * Fixed a CSS class which was applied to an incorrect element.
1408
- * Revisions to the Calendar import methods
1409
- * Moved style editing to its own page
1410
- * Added JavaScript editing to allow for customization of jQuery behaviors.
1411
- * Internationalized date formats
1412
- * Shortcode support for multiple categories.
1413
- * Shortcode support for custom templates in upcoming and today's events
1414
- * Added a settings option to eliminate the heading in list format display.
1415
- * Fixed a bug which treated the event repetition value as a string on event adding or updating, not allowing some users to use '0' as an event repetition.
1416
- * Made events listing sortable in admin view
1417
- * Minor revisions in admin UI.
1418
- * Added database storage for frequently used venues or event locations.
1419
- * Modified JavaScript for list display to automatically expand events scheduled for today.
1420
-
1421
- = 1.2.1 =
1422
-
1423
- * Corrected a typo which broke the upcoming events widget.
1424
-
1425
- = 1.2.0 =
1426
-
1427
- * Added shortcodes to support inserting upcoming events and todays events lists into page/post content.
1428
- * Added option to restrict upcoming events widgets by category
1429
- * More superficial CSS changes
1430
- * Added Brazilian Portuguese language files
1431
- * Fixed bug where I reversed the future and past variable values for upcoming events widgets
1432
- * Fixed bug in multi-user permissions.
1433
- * Added feature to look for a custom location for icons to prevent overwriting of custom icons on upgrade.
1434
-
1435
- = 1.1.0 =
1436
-
1437
- * Fixed some problems with Upcoming Events past events not scrolling off; hopefully all!
1438
- * Fixed some problems with fuzzy interpretations of the numbers of past/future events displayed in Upcoming Events.
1439
- * Added Bi-weekly events
1440
- * Added restrictions so that admin level users can edit any events but other users can only edit their own events
1441
- * Removed character restrictions on event titles
1442
- * Revised default stylesheet
1443
-
1444
- = 1.0.2 =
1445
-
1446
- * Fixed problems with editing and deleting events or categories in multiblog installation
1447
- * Fixed escaping/character set issue
1448
- * Fixed issue when blog address and wp address did not match (introduced in 1.0.1)
1449
- * Added import method to transfer events and categories from Kieran O'Shea's Calendar plugin
1450
-
1451
- = 1.0.1 =
1452
-
1453
- * Added missing template code for event end dates.
1454
- * Changed defaults so that styles and javascript are initially turned on.
1455
- * Removed function collisions with Calendar
1456
- * Fixed bug where My Calendar didn't respect the timezone offset in identifying the current day.
1457
- * Fixed bug where multiblog installations in WP 3.0 were unable to save events and settings.
1458
- * Added Spanish translation, courtesy of [Esteban Truelsegaard](http://www.netmdp.com). Thanks!
1459
-
1460
- = 1.0.0 =
1461
-
1462
- * Initial launch.
1463
-
1464
  == Frequently Asked Questions ==
1465
 
1466
  = Hey! Why don't you have any Frequently Asked Questions here! =
@@ -1469,11 +521,15 @@ Because the majority of users end up on my web site asking for help anyway -- an
1469
 
1470
  = This plug-in is really complicated. Why can't you personally help me figure out how to use it? =
1471
 
1472
- I can! Just not in person. I've written a User's Guide for My Calendar, which you can [purchase at my web site](https://www.joedolson.com/my-calendar/users-guide/) for $25. This helps defray the thousand plus hours I've spent in developing the plug-in and providing support. Please, consider buying the User's Guide or [making a donation](https://www.joedolson.com/donate.php) before asking for support!
1473
 
1474
  = Can my visitors or members submit events? =
1475
 
1476
- I've written a paid plug-in that adds this feature to My Calendar, called My Calendar: Submissions. [Buy it today](https://www.joedolson.com/my-calendar/submissions/)!
 
 
 
 
1477
 
1478
  == Screenshots ==
1479
 
2
  Contributors: joedolson
3
  Donate link: http://www.joedolson.com/donate.php
4
  Tags: calendar, dates, times, event, events, scheduling, schedule, event manager, event calendar, class, concert, conference, meeting, venue, location, box office, tickets, registration
5
+ Requires at least: 3.9.8
6
+ Tested up to: 4.3.0
7
  License: GPLv2 or later
8
+ Stable tag: 2.3.32
9
 
10
  Accessible WordPress event calendar plugin. Show events from multiple calendars on pages, in posts, or in widgets.
11
 
16
  Easy to use for anybody, My Calendar provides enormous flexibility for designers and developers needing a custom calendar.
17
 
18
  * [Buy the User's Guide](http://www.joedolson.com/my-calendar/users-guide/) for extensive help with set up and use.
19
+ * [Buy My Calendar Pro](https://www.joedolson.com/my-calendar/pro/), the premium extension for My Calendar
20
  * [Use My Tickets](https://wordpress.org/plugins/my-tickets/) and sell tickets to your My Calendar events
21
 
22
  = Features: =
41
  * Shortcode Generator to help create customized views of My Calendar
42
  * [Developer Documentation](http://www.joedolson.com/doc-category/my-calendar-3/)
43
 
44
+ = What's in My Calendar Pro? =
45
+
46
+ * Let your site visitors submit events to your site (pay to post or free!).
47
+ * Let logged-in users edit their events from the front-end.
48
+ * Create events when you publish a blog post
49
+ * Publish a blog post when you create an event
50
+ * Advanced search features
51
+
52
  = Translations =
53
 
54
  Available translations (in order of completeness):
55
+ Czech, Polish, Spanish (Spain), Portuguese (Portugal), French, Danish, Japanese, German, Russian, Dutch, Swedish, Italian, Hebrew, Galician, Portuguese (Brazil), Hindi, Turkish, Slovak, Finnish, Slovenian, Ukrainian, Romanian, Norwegian (Bokmal), Catalan, Hungarian, Afrikaans, Persian, Icelandic
56
 
57
  Visit the [My Calendar translations site](http://translate.joedolson.com/projects/my-calendar) to check the progress of a translation.
58
 
66
 
67
  2. Activate the plugin on your WordPress plugins page
68
 
69
+ 3. Configure My Calendar using the settings pages in the admin panel:
70
 
71
+ My Calendar -> Manage Events
72
+ My Calendar -> Add New Event
73
  My Calendar -> Manage Categories
74
  My Calendar -> Manage Locations
75
  My Calendar -> Manage Event Groups
85
 
86
  == Changelog ==
87
 
88
+ = Future =
89
+
90
+ * Refactor options storage
91
+ * Update event taxonomies if category changed/source event taxonomy data from post
92
+ * Custom link targets using mc_customize_details_link & template_redirect filter as pointer.
93
+ * Handle stylesheet editing as additive (child styles), rather than editing the original stylesheet.
94
+ * Update pickadate to version 3.6, when it's out. 3.5.6 has a regression that makes it useless for me.
95
+
96
  = 2.4.0 =
97
 
98
+ New features:
99
+ * Set upcoming event class based on time, rather than date.
100
+ * Add past/present classes to today's events widget
101
+ * Assign Custom All Day label for each event.
102
+ * Support hiding 'Host' field as option.
103
+ * Made primary sort order of events filterable: 'mc_primary_sort'
104
+ * Added action to location saving handling updated locations
105
+ * Added arguments to from/to filters in Upcoming Events
106
+ * Enabled option to turn on permalinks
107
+ * Custom canonical URL for event pages
108
+ * Added 'date' parameter to today's events list & shortcode accepting any string usable in strtotime()
109
+ * Added 'from' and 'to' parameter to upcoming events list & shortcode accepting any string usable in strtotime
110
+ * Added year/month/day parameter to main shortcode to target specific months for initial display.
111
+ * Make BCC field filterable
112
+ * Add filters to search query parameters
113
+ * New option: switch to mini calendar on mobile devices instead of list view.
114
+ * Add [day] select field to date switcher if in 'day' view.
115
+ * Option to set default sort direction
116
+ * Ability to set three separate event title templates: grid, list, and single.
117
+ * Added admin-bar link to view calendar.
118
+ * Added option to customize permalink slug on permalink page
119
+ * Single event pages as permalinks use the same template as main if custom template isn't enabled.
120
+ * New template tag: {color_css} and {close_color_css} to wrap a block with the category background color.
121
+ * Add category classes to Upcoming & Today's events widgets
122
+ * Redirect page to main calendar if event is private
123
+ * Improved labeling of cell dates
124
+
125
+ Bug fixes:
126
+ * Stop setting all day events to end at midnight; use 11:59:59 and filter output
127
+ * Rewrite iCal output so that the iCal download eliminates Holiday cancellations [todo]
128
+ * Bug fix: Prevent extraneous variables from leaking into the navigation output.
129
+ * Rendering post template in permalinks only applies within Loop.
130
+ * Template attribute preg_match could only pick up 2 parameters
131
+ * Prevent an invalid mc_id value from returning errors.
132
+ * Prevent deprecation notice when getting text_direction
133
+ * Default to not showing navigation options in print view.
134
+ * Better loading of text domain.
135
+ * Prevent mini calendar from switching to list format.
136
+ * Change class construction to PHP 5 syntax
137
+ * Close button is now a button rather than a link.
138
+ * Fixed display of text diff for stylesheet comparisons
139
+ * Two different filters with different names.
140
+ * mc_after_event filter not running with custom templates.
141
+ * With My Tickets active, enter key did not submit Add/Edit event form
142
+ * Fixed documentation error with ical template tags.
143
+ * Improved efficiency of WP shortcode processing in templates.
144
+ * A multi-day event crossing the current day was counted as a future event in upcoming events
145
+ * If event instance was split from recurring event, showed same recurring settings as original event.
146
+ * If events were mass deleted, the corresponding event post was not also deleted.
147
+ * Prevent single event pages from displaying content if the event is in a private category.
148
+
149
+ Important Changes:
150
+ * Removed references to #jd_calendar and generate custom IDs. [breaking change
151
+ * Revision of settings page [reorganize settings into tabs]
152
+ * Reorganized settings pages.
153
+
154
+ Other:
155
+ * Moved changelog for versions prior to 2.3.0 into changelog.txt
156
+
157
+ Translations:
158
+ * Updated Polish, Portuguese (Portugal), Dutch, Turkish, Slovak, Norwegian, Hungarian, German, Spanish, Persian, Czech, Danish
159
 
160
  = 2.3.32 =
161
 
176
 
177
  = 2.3.29 =
178
 
179
+ * Security Fix: XSS issue applying to improper use of add_query_arg(). See https://yoast.com/tools/wrong-use-of-add_query_arg-and-remove_query_arg-causing-xss/
180
 
181
  = 2.3.28 =
182
 
513
  * Scheduled removal of showkey, shownav, toggle, and showjump shortcode attributes.
514
  * Removed upgrade support for 1.6.x & 1.7.x series of My Calendar.
515
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
516
  == Frequently Asked Questions ==
517
 
518
  = Hey! Why don't you have any Frequently Asked Questions here! =
521
 
522
  = This plug-in is really complicated. Why can't you personally help me figure out how to use it? =
523
 
524
+ I can! Just not in person. I've written a User's Guide for My Calendar, which you can [purchase at my web site](https://www.joedolson.com/my-calendar/users-guide/) for $25. This helps defray the thousands of hours I've spent developing the plug-in and providing support. Please, consider buying the User's Guide or [making a donation](https://www.joedolson.com/donate.php) before asking for support!
525
 
526
  = Can my visitors or members submit events? =
527
 
528
+ I've written a paid plug-in that adds this feature to My Calendar, called My Calendar Pro. [Buy it today](https://www.joedolson.com/my-calendar/pro/)!
529
+
530
+ = Is there an advanced search feature? =
531
+
532
+ The search feature in My Calendar is pretty basic; but buying My Calendar Pro gives you a richer search feature, where you can narrow by dates, categories, authors, and more to refine your event search.
533
 
534
  == Screenshots ==
535
 
styles/twentyfifteen.css CHANGED
@@ -1,5 +1,4 @@
1
  /* New theme for 2015 */
2
- @import url(../css/reset.css);
3
  .my-calendar-header *, .mc_bottomnav * {
4
  line-height: 1.5;
5
  }
@@ -194,7 +193,7 @@
194
  }
195
 
196
  .mc-main .close:hover, .mc-main .close:focus {
197
- background: rgba( 255, 255, 255, .8 );
198
  }
199
 
200
  .mc-main .details img {
@@ -270,7 +269,7 @@
270
  background: rgba( 255, 255, 255, .7 );
271
  padding: 0 10px !important;
272
  }
273
- .mc-main .single-event .time-block p {
274
  position: static;
275
  padding: 0!important;
276
  }
@@ -433,6 +432,15 @@
433
  font-weight: 600;
434
  }
435
 
 
 
 
 
 
 
 
 
 
436
  .mc-main .list-event .details img {
437
  width: auto;
438
  max-width: 100%;
1
  /* New theme for 2015 */
 
2
  .my-calendar-header *, .mc_bottomnav * {
3
  line-height: 1.5;
4
  }
193
  }
194
 
195
  .mc-main .close:hover, .mc-main .close:focus {
196
+ background: rgba( 240, 240, 240, .8 );
197
  }
198
 
199
  .mc-main .details img {
269
  background: rgba( 255, 255, 255, .7 );
270
  padding: 0 10px !important;
271
  }
272
+ .mc-main .single-event .time-block p, .mc-main.list .time-block p {
273
  position: static;
274
  padding: 0!important;
275
  }
432
  font-weight: 600;
433
  }
434
 
435
+ .mc-main .list-event {
436
+ margin-top: 1em;
437
+ }
438
+
439
+ .mc-main .mc-list-extended {
440
+ font-size: .9em;
441
+ font-style: italic;
442
+ }
443
+
444
  .mc-main .list-event .details img {
445
  width: auto;
446
  max-width: 100%;
templates/my-calendar.css CHANGED
@@ -191,9 +191,9 @@
191
  }
192
 
193
  .mc-main .details .close {
194
- float: right;
195
- width: 16px !important;
196
- padding: 2px 2px 7px 7px;
197
  }
198
 
199
  .mc-main.mini .details .close {
@@ -271,15 +271,18 @@
271
  padding: 0;
272
  }
273
 
 
 
 
 
 
 
274
  .mc-main .calendar-event .event-time, .mc-main .list-event .event-time {
275
- display: block;
276
- float: left;
277
  height: 100%;
278
  margin-right: 10px;
279
  margin-bottom: 10px;
280
  font-weight: 700;
281
  font-size: .9em;
282
- width: 6em;
283
  }
284
 
285
  .mc-main p {
191
  }
192
 
193
  .mc-main .details .close {
194
+ position: absolute;
195
+ top: 10px;
196
+ right: 10px;
197
  }
198
 
199
  .mc-main.mini .details .close {
271
  padding: 0;
272
  }
273
 
274
+
275
+ .mc-event-date {
276
+ display: block;
277
+ font-size: .8em;
278
+ }
279
+
280
  .mc-main .calendar-event .event-time, .mc-main .list-event .event-time {
 
 
281
  height: 100%;
282
  margin-right: 10px;
283
  margin-bottom: 10px;
284
  font-weight: 700;
285
  font-size: .9em;
 
286
  }
287
 
288
  .mc-main p {
templates/twentyfifteen.css CHANGED
@@ -1,5 +1,4 @@
1
  /* New theme for 2015 */
2
- @import url(../css/reset.css);
3
  .my-calendar-header *, .mc_bottomnav * {
4
  line-height: 1.5;
5
  }
@@ -194,7 +193,7 @@
194
  }
195
 
196
  .mc-main .close:hover, .mc-main .close:focus {
197
- background: rgba( 255, 255, 255, .8 );
198
  }
199
 
200
  .mc-main .details img {
@@ -270,7 +269,7 @@
270
  background: rgba( 255, 255, 255, .7 );
271
  padding: 0 10px !important;
272
  }
273
- .mc-main .single-event .time-block p {
274
  position: static;
275
  padding: 0!important;
276
  }
@@ -433,6 +432,15 @@
433
  font-weight: 600;
434
  }
435
 
 
 
 
 
 
 
 
 
 
436
  .mc-main .list-event .details img {
437
  width: auto;
438
  max-width: 100%;
1
  /* New theme for 2015 */
 
2
  .my-calendar-header *, .mc_bottomnav * {
3
  line-height: 1.5;
4
  }
193
  }
194
 
195
  .mc-main .close:hover, .mc-main .close:focus {
196
+ background: rgba( 240, 240, 240, .8 );
197
  }
198
 
199
  .mc-main .details img {
269
  background: rgba( 255, 255, 255, .7 );
270
  padding: 0 10px !important;
271
  }
272
+ .mc-main .single-event .time-block p, .mc-main.list .time-block p {
273
  position: static;
274
  padding: 0!important;
275
  }
432
  font-weight: 600;
433
  }
434
 
435
+ .mc-main .list-event {
436
+ margin-top: 1em;
437
+ }
438
+
439
+ .mc-main .mc-list-extended {
440
+ font-size: .9em;
441
+ font-style: italic;
442
+ }
443
+
444
  .mc-main .list-event .details img {
445
  width: auto;
446
  max-width: 100%;
uninstall.php CHANGED
@@ -110,5 +110,6 @@ if ( ! defined( 'ABSPATH' ) && ! defined( 'WP_UNINSTALL_PLUGIN' ) ) {
110
  delete_option( 'mc_api_enabled' );
111
  delete_option( 'mc_use_custom_js' );
112
  delete_option( 'mc_update_notice' );
 
113
  add_option( 'mc_uninstalled', 'true' );
114
  }
110
  delete_option( 'mc_api_enabled' );
111
  delete_option( 'mc_use_custom_js' );
112
  delete_option( 'mc_update_notice' );
113
+ delete_option( 'mc_default_direction' );
114
  add_option( 'mc_uninstalled', 'true' );
115
  }