The Events Calendar - Version 4.0.1

Version Description

Download this release

Release Info

Developer borkweb
Plugin Icon The Events Calendar
Version 4.0.1
Comparing to
See all releases

Code changes from version 4.0 to 4.0.1

Files changed (47) hide show
  1. common/src/Tribe/Admin/Notice/Plugin_Upgrade_Notice.php +239 -0
  2. common/src/Tribe/Date_Utils.php +62 -0
  3. common/src/Tribe/Main.php +1 -1
  4. common/src/resources/css/tribe-common-admin.css +26 -3
  5. common/src/resources/images/tribe-loading@2x.gif +0 -0
  6. common/tribe-autoload.php +7 -0
  7. readme.txt +22 -5
  8. src/Tribe/Admin/Bar/Admin_Bar.php +68 -0
  9. src/Tribe/Admin/Bar/Configurator_Interface.php +14 -0
  10. src/Tribe/Admin/Bar/Default_Configurator.php +113 -0
  11. src/Tribe/Admin/Notices/Base_Notice.php +29 -0
  12. src/Tribe/Admin/Notices/Notice_Interface.php +25 -0
  13. src/Tribe/Admin/Timezone_Updater.php +1 -1
  14. src/Tribe/Admin_List.php +15 -10
  15. src/Tribe/Constants.php +76 -0
  16. src/Tribe/Event_Tickets/Attendees_Report.php +94 -0
  17. src/Tribe/Event_Tickets/Main.php +59 -0
  18. src/Tribe/Importer/File_Importer_Events.php +5 -0
  19. src/Tribe/Main.php +40 -134
  20. src/Tribe/Timezones.php +1 -3
  21. src/Tribe/Utils/DST.php +73 -0
  22. src/Tribe/iCal.php +7 -3
  23. src/admin-views/new-organizer-meta-section.php +6 -0
  24. src/functions/template-tags/date.php +14 -61
  25. src/functions/template-tags/general.php +32 -4
  26. src/functions/utils/array.php +23 -0
  27. src/resources/js/tribe-events-ajax-calendar.js +6 -11
  28. src/resources/js/tribe-events-ajax-calendar.min.js +1 -1
  29. src/resources/js/tribe-events-bar.js +4 -4
  30. src/resources/js/tribe-events.js +96 -96
  31. src/resources/js/tribe-settings.min.js +1 -1
  32. src/views/modules/meta/details.php +1 -1
  33. src/views/single-event.php +1 -1
  34. tests.md +4 -0
  35. the-events-calendar.php +1 -1
  36. vendor/tickets/common/codeception.dist.yml +0 -63
  37. vendor/tickets/common/src/Tribe/Admin/Notice/Plugin_Upgrade_Notice.php +239 -0
  38. vendor/tickets/common/src/Tribe/Date_Utils.php +62 -0
  39. vendor/tickets/common/src/Tribe/Main.php +1 -1
  40. vendor/tickets/common/src/resources/css/tribe-common-admin.css +26 -3
  41. vendor/tickets/common/src/resources/images/tribe-loading@2x.gif +0 -0
  42. vendor/tickets/common/tribe-autoload.php +7 -0
  43. vendor/tickets/event-tickets.php +1 -1
  44. vendor/tickets/readme.txt +54 -7
  45. vendor/tickets/src/Tribe/Main.php +1 -1
  46. vendor/tickets/src/Tribe/RSVP.php +1 -1
  47. vendor/tickets/src/admin-views/attendees.php +18 -56
common/src/Tribe/Admin/Notice/Plugin_Upgrade_Notice.php ADDED
@@ -0,0 +1,239 @@
1
+ <?php
2
+ /**
3
+ * When appropriate, displays a plugin upgrade message "inline" within the plugin
4
+ * admin screen.
5
+ *
6
+ * This is drawn from the Upgrade Notice section of the plugin readme.txt file (ie,
7
+ * the one belonging to the current stable accessible via WP SVN - at least by
8
+ * default).
9
+ */
10
+ class Tribe__Admin__Notice__Plugin_Upgrade_Notice {
11
+ /**
12
+ * Currently installed version of the plugin
13
+ *
14
+ * @var string
15
+ */
16
+ protected $current_version = '';
17
+
18
+ /**
19
+ * The plugin path as it is within the plugins directory, ie
20
+ * "some-plugin/main-file.php".
21
+ *
22
+ * @var string
23
+ */
24
+ protected $plugin_path = '';
25
+
26
+ /**
27
+ * Contains the plugin upgrade notice (empty if none are available).
28
+ *
29
+ * @var string
30
+ */
31
+ protected $upgrade_notice = '';
32
+
33
+
34
+ /**
35
+ * Test for and display any plugin upgrade messages (if any are available) inline
36
+ * beside the plugin listing itself.
37
+ *
38
+ * The optional third param is the object which actually checks to see if there
39
+ * are any upgrade notices worth displaying. If not provided, an object of the
40
+ * default type will be created (which connects to WP SVN).
41
+ *
42
+ * @param string $current_version
43
+ * @param string $plugin_path (ie "plugin-dir/main-file.php")
44
+ */
45
+ public function __construct( $current_version, $plugin_path ) {
46
+ $this->current_version = $current_version;
47
+ $this->plugin_path = $plugin_path;
48
+
49
+ add_action( "in_plugin_update_message-$plugin_path", array( $this, 'maybe_run' ) );
50
+ }
51
+
52
+ /**
53
+ * Test if there is a plugin upgrade notice and displays it if so.
54
+ *
55
+ * Expects to fire during "in_plugin_update_message-{plugin_path}", therefore
56
+ * this should only run if WordPress has detected that an upgrade is indeed
57
+ * available.
58
+ */
59
+ public function maybe_run() {
60
+ $this->test_for_upgrade_notice();
61
+
62
+ if ( $this->upgrade_notice ) {
63
+ $this->display_message();
64
+ }
65
+ }
66
+
67
+ /**
68
+ * Tests to see if an upgrade notice is available.
69
+ */
70
+ protected function test_for_upgrade_notice() {
71
+ $cache_key = $this->cache_key();
72
+ $this->upgrade_notice = get_transient( $cache_key );
73
+
74
+ if ( false === $this->upgrade_notice ) {
75
+ $this->discover_upgrade_notice();
76
+ }
77
+
78
+ set_transient( $cache_key, $this->upgrade_notice, $this->cache_expiration() );
79
+ }
80
+
81
+ /**
82
+ * Returns a cache key unique to the current plugin path and version, that
83
+ * still fits within the 45-char limit of regular WP transient keys.
84
+ *
85
+ * @return string
86
+ */
87
+ protected function cache_key() {
88
+ return 'tribe_plugin_upgrade_notice-' . hash( 'crc32b', $this->plugin_path . $this->current_version );
89
+ }
90
+
91
+ /**
92
+ * Returns the period of time (in seconds) for which to cache plugin upgrade messages.
93
+ *
94
+ * @return int
95
+ */
96
+ protected function cache_expiration() {
97
+ /**
98
+ * Number of seconds to cache plugin upgrade messages for.
99
+ *
100
+ * Defaults to one day, which provides a decent balance between efficiency savings
101
+ * and allowing for the possibility that some upgrade messages may be changed or
102
+ * rescinded.
103
+ *
104
+ * @var int $cache_expiration
105
+ */
106
+ return (int) apply_filters( 'tribe_plugin_upgrade_notice_expiration', DAY_IN_SECONDS, $this->plugin_path );
107
+ }
108
+
109
+ /**
110
+ * Looks at the current stable plugin readme.txt and parses to try and find the first
111
+ * available upgrade notice relating to a plugin version higher than this one.
112
+ *
113
+ * By default, WP SVN is the source.
114
+ */
115
+ protected function discover_upgrade_notice() {
116
+ /**
117
+ * The URL for the current plugin readme.txt file.
118
+ *
119
+ * @var string $url
120
+ * @var string $plugin_path
121
+ */
122
+ $readme_url = apply_filters( 'tribe_plugin_upgrade_readme_url',
123
+ $this->form_wp_svn_readme_url(),
124
+ $this->plugin_path
125
+ );
126
+
127
+ if ( ! empty( $readme_url ) ) {
128
+ $response = wp_safe_remote_get( $readme_url );
129
+ }
130
+
131
+ if ( ! empty( $response ) && ! is_wp_error( $response ) ) {
132
+ $readme = $response['body'];
133
+ }
134
+
135
+ if ( ! empty( $readme ) ) {
136
+ $this->parse_for_upgrade_notice( $readme );
137
+ $this->format_upgrade_notice();
138
+ }
139
+
140
+ /**
141
+ * The upgrade notice for the current plugin (may be empty).
142
+ *
143
+ * @var string $upgrade_notice
144
+ * @var string $plugin_path
145
+ */
146
+ return apply_filters( 'tribe_plugin_upgrade_notice',
147
+ $this->upgrade_notice,
148
+ $this->plugin_path
149
+ );
150
+ }
151
+
152
+ /**
153
+ * Forms the expected URL to the trunk readme.txt file as it is on WP SVN
154
+ * or an empty string if for any reason it cannot be determined.
155
+ *
156
+ * @return string
157
+ */
158
+ protected function form_wp_svn_readme_url() {
159
+ $parts = explode( '/', $this->plugin_path );
160
+ $slug = empty( $parts[0] ) ? '' : $parts[0];
161
+ return esc_url( "https://plugins.svn.wordpress.org/$slug/trunk/readme.txt" );
162
+ }
163
+
164
+ /**
165
+ * Given a standard Markdown-format WP readme.txt file, finds the first upgrade
166
+ * notice (if any) for a version higher than $this->current_version.
167
+ *
168
+ * @param string $readme
169
+ * @return string
170
+ */
171
+ protected function parse_for_upgrade_notice( $readme ) {
172
+ $in_upgrade_notice = false;
173
+ $in_version_notice = false;
174
+ $readme_text = fopen( "data:://text/plain,$readme", 'r' );
175
+
176
+ while ( $line = fgets( $readme_text ) ) {
177
+ // Once we leave the Upgrade Notice section (ie, we encounter a new section header), bail
178
+ if ( $in_upgrade_notice && 0 === strpos( $line, '==' ) ) {
179
+ break;
180
+ }
181
+
182
+ // Look out for the start of the Upgrade Notice section
183
+ if ( ! $in_upgrade_notice && preg_match( '/^==\s*Upgrade\s+Notice\s*==/i', $line ) ) {
184
+ $in_upgrade_notice = true;
185
+ }
186
+
187
+ // Also test to see if we have left the version specific note (ie, we encounter a new sub heading or header)
188
+ if ( $in_upgrade_notice && $in_version_notice && 0 === strpos( $line, '=' ) ) {
189
+ break;
190
+ }
191
+
192
+ // Look out for the first applicable version-specific note within the Upgrade Notice section
193
+ if ( $in_upgrade_notice && ! $in_version_notice && preg_match( '/^=\s*([0-9\.]{3,})\s*=/', $line, $matches ) ) {
194
+ // Is this a higher version than currently installed?
195
+ if ( version_compare( $matches[1], $this->current_version, '>' ) ) {
196
+ $in_version_notice = true;
197
+ }
198
+ }
199
+
200
+ // Copy the details of the upgrade notice for the first higher version we find
201
+ if ( $in_upgrade_notice && $in_version_notice ) {
202
+ $this->upgrade_notice .= $line;
203
+ }
204
+ }
205
+ }
206
+
207
+ /**
208
+ * Convert the plugin version header and any links from Markdown to HTML.
209
+ */
210
+ protected function format_upgrade_notice() {
211
+ // Convert [links](http://...) to <a href="..."> tags
212
+ $this->upgrade_notice = preg_replace(
213
+ '/\[([^\]]*)\]\(([^\)]*)\)/',
214
+ '<a href="${2}">${1}</a>',
215
+ $this->upgrade_notice
216
+ );
217
+
218
+ // Convert =4.0= headings to <h4 class="version">4.0</h4> tags
219
+ $this->upgrade_notice = preg_replace(
220
+ '/=\s*([a-zA-Z0-9\.]{3,})\s*=/',
221
+ '<h4 class="version">${1}</h4>',
222
+ $this->upgrade_notice
223
+ );
224
+ }
225
+
226
+ /**
227
+ * Render the actual upgrade notice.
228
+ *
229
+ * Please note if plugin-specific styling is required for the message, you can
230
+ * use an ID generated by WordPress for one of the message's parent elements
231
+ * which takes the form "{plugin_name}-update". Example:
232
+ *
233
+ * #the-events-calendar-update .tribe-plugin-update-message { ... }
234
+ */
235
+ public function display_message() {
236
+ $notice = wp_kses_post( $this->upgrade_notice );
237
+ echo "<div class='tribe-plugin-update-message'> $notice </div>";
238
+ }
239
+ }
common/src/Tribe/Date_Utils.php CHANGED
@@ -721,6 +721,68 @@ if ( ! class_exists( 'Tribe__Date_Utils' ) ) {
721
_deprecated_function( __METHOD__, '3.11', __CLASS__ . '::is_timestamp' );
722
return self::is_timestamp( $timestamp );
723
}
724
// @codingStandardsIgnoreEnd
725
}
726
}
721
_deprecated_function( __METHOD__, '3.11', __CLASS__ . '::is_timestamp' );
722
return self::is_timestamp( $timestamp );
723
}
724
+
725
+ /**
726
+ * Gets the timestamp of a day in week, month and year context.
727
+ *
728
+ * Kudos to [icedwater StackOverflow user](http://stackoverflow.com/users/1091386/icedwater) in
729
+ * [his answer](http://stackoverflow.com/questions/924246/get-the-first-or-last-friday-in-a-month).
730
+ *
731
+ * Usage examples:
732
+ * "The second Wednesday of March 2015" - `get_day_timestamp( 3, 2, 3, 2015, 1)`
733
+ * "The last Friday of December 2015" - `get_day_timestamp( 5, 1, 12, 2015, -1)`
734
+ * "The first Monday of April 2016 - `get_day_timestamp( 1, 1, 4, 2016, 1)`
735
+ * "The penultimate Thursday of January 2012" - `get_day_timestamp( 4, 2, 1, 2012, -1)`
736
+ *
737
+ * @param int $day_of_week The day representing the number in the week, Monday is `1`, Tuesday is `2`, Sunday is `7`
738
+ * @param int $week_in_month The week number in the month; first week is `1`, second week is `2`; when direction is reverse
739
+ * then `1` is last week of the month, `2` is penultimate week of the month and so on.
740
+ * @param int $month The month number in the year, January is `1`
741
+ * @param int $year The year number, e.g. "2015"
742
+ * @param int $week_direction Either `1` or `-1`; the direction for the search referring to the week, defaults to `1`
743
+ * to specify weeks in natural order so:
744
+ * $week_direction `1` and $week_in_month `1` means "first week of the month"
745
+ * $week_direction `1` and $week_in_month `3` means "third week of the month"
746
+ * $week_direction `-1` and $week_in_month `1` means "last week of the month"
747
+ * $week_direction `-1` and $week_in_month `2` means "penultimmate week of the month"
748
+ *
749
+ * @return int The day timestamp
750
+ */
751
+ public static function get_weekday_timestamp( $day_of_week, $week_in_month, $month, $year, $week_direction = 1 ) {
752
+ if (
753
+ ! (
754
+ is_numeric( $day_of_week )
755
+ && is_numeric( $week_in_month )
756
+ && is_numeric( $month )
757
+ && is_numeric( $year )
758
+ && is_numeric( $week_direction )
759
+ && in_array( $week_direction, array( - 1, 1 ) )
760
+ )
761
+ ) {
762
+ return false;
763
+ }
764
+
765
+ if ( $week_direction > 0 ) {
766
+ $startday = 1;
767
+ } else {
768
+ $startday = date( 't', mktime( 0, 0, 0, $month, 1, $year ) );
769
+ }
770
+
771
+ $start = mktime( 0, 0, 0, $month, $startday, $year );
772
+ $weekday = date( 'N', $start );
773
+
774
+ if ( $week_direction * $day_of_week >= $week_direction * $weekday ) {
775
+ $offset = - $week_direction * 7;
776
+ } else {
777
+ $offset = 0;
778
+ }
779
+
780
+ $offset += $week_direction * ( $week_in_month * 7 ) + ( $day_of_week - $weekday );
781
+
782
+ return mktime( 0, 0, 0, $month, $startday + $offset, $year );
783
+ }
784
+
785
// @codingStandardsIgnoreEnd
786
}
787
+
788
}
common/src/Tribe/Main.php CHANGED
@@ -17,7 +17,7 @@ class Tribe__Main {
17
const OPTIONNAME = 'tribe_events_calendar_options';
18
const OPTIONNAMENETWORK = 'tribe_events_calendar_network_options';
19
20
- const VERSION = '3.12a1';
21
const FEED_URL = 'https://theeventscalendar.com/feed/';
22
23
protected $plugin_context;
17
const OPTIONNAME = 'tribe_events_calendar_options';
18
const OPTIONNAMENETWORK = 'tribe_events_calendar_network_options';
19
20
+ const VERSION = '4.0.1';
21
const FEED_URL = 'https://theeventscalendar.com/feed/';
22
23
protected $plugin_context;
common/src/resources/css/tribe-common-admin.css CHANGED
@@ -20,6 +20,32 @@ td.tribe_message {padding-bottom: 10px !important;}
20
#tribe-upgrade {margin:20px 0 30px; border:1px solid #ccc; -moz-border-radius:5px; -webkit-border-radius:5px; border-radius:5px; padding:0 20px 20px; background:#f6f6f6;}
21
#tribe-upgrade .message {border-style:solid; border-width:1px; padding:6px 12px; -moz-border-radius:3px; -webkit-border-radius:3px; border-radius:3px; background-color:#FFFFE0; border-color:#E6DB55;}
22
23
/* = Settings Screen
24
=============================================*/
25
.tribe-settings-form { max-width: 1000px; }
@@ -346,9 +372,6 @@ only screen and (min--moz-device-pixel-ratio: 2),
346
only screen and (-o-min-device-pixel-ratio: 2/1),
347
only screen and (-webkit-min-device-pixel-ratio: 2),
348
only screen and (min-device-pixel-ratio: 2) {
349
- .events-cal #icon-edit {
350
- background-image: url(../images/events-screen-icon@2x.png);
351
- }
352
#tribe-loading span {
353
background-image: url(../images/tribe-loading@2x.gif);
354
}
20
#tribe-upgrade {margin:20px 0 30px; border:1px solid #ccc; -moz-border-radius:5px; -webkit-border-radius:5px; border-radius:5px; padding:0 20px 20px; background:#f6f6f6;}
21
#tribe-upgrade .message {border-style:solid; border-width:1px; padding:6px 12px; -moz-border-radius:3px; -webkit-border-radius:3px; border-radius:3px; background-color:#FFFFE0; border-color:#E6DB55;}
22
23
+ /* = Plugin Screen
24
+ =============================================*/
25
+ table.plugins .tribe-plugin-update-message {
26
+ background: #d54e21; /* taken from colour scheme in list-tables.css */
27
+ color: white;
28
+ display: inline-table;
29
+ padding: 10px 12px;
30
+ margin: 6px 0px;
31
+ }
32
+
33
+ table.plugins .tribe-plugin-update-message h4 {
34
+ display: inline;
35
+ font-weight: bold;
36
+ margin-right: 8px;
37
+ }
38
+
39
+ table.plugins .tribe-plugin-update-message h4:after {
40
+ content: ' \00BB ';
41
+ }
42
+
43
+
44
+ table.plugins .tribe-plugin-update-message a {
45
+ color: white;
46
+ text-decoration: underline;
47
+ }
48
+
49
/* = Settings Screen
50
=============================================*/
51
.tribe-settings-form { max-width: 1000px; }
372
only screen and (-o-min-device-pixel-ratio: 2/1),
373
only screen and (-webkit-min-device-pixel-ratio: 2),
374
only screen and (min-device-pixel-ratio: 2) {
375
#tribe-loading span {
376
background-image: url(../images/tribe-loading@2x.gif);
377
}
common/src/resources/images/tribe-loading@2x.gif ADDED
Binary file
common/tribe-autoload.php ADDED
@@ -0,0 +1,7 @@
1
+ <?php
2
+ $src = dirname( __FILE__ ) . '/src';
3
+ require_once $src . '/Tribe/Autoloader.php';
4
+
5
+ $autoloader = Tribe__Autoloader::instance();
6
+ $autoloader->register_prefix('Tribe__',$src);
7
+ $autoloader->register_autoloader();
readme.txt CHANGED
@@ -4,8 +4,8 @@ Contributors: ModernTribe, borkweb, zbtirrell, barry.hughes, bordoni, brianjesse
4
Tags: events, calendar, event, venue, organizer, dates, date, google maps, conference, workshop, concert, meeting, seminar, summit, class, modern tribe, tribe, widget
5
Donate link: http://m.tri.be/29
6
Requires at least: 3.9
7
- Tested up to: 4.3.1
8
- Stable tag: 4.0
9
License: GPLv2 or later
10
License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
@@ -207,7 +207,7 @@ The plugin is produced by <a href="http://m.tri.be/2s">Modern Tribe Inc</a>.
207
<a href="https://profiles.wordpress.org/borkweb">Matthew Batchelder</a>
208
<a href="https://profiles.wordpress.org/neillmcshea">Neill McShea</a>
209
<a href="https://profiles.wordpress.org/mastromktg">Nick Mastromattei</a>
210
- <a href="https://profiles.wordpress.org/nicosantos”>Nico Santo</a>
211
<a href="https://profiles.wordpress.org/peterchester">Peter Chester</a>
212
<a href="https://profiles.wordpress.org/roblagatta">Rob La Gatta</a>
213
<a href="https://profiles.wordpress.org/reid.peifer">Reid Peifer</a>
@@ -309,6 +309,24 @@ At no point during the 3.0 lifecycle will the major version change. But you can
309
310
== Changelog ==
311
312
= [4.0] 2015-12-02 =
313
314
* Security - A TON of escaping was added to our codebase thanks to the efforts of the always-helpful Andy Fragen (@afragen)
@@ -334,9 +352,9 @@ At no point during the 3.0 lifecycle will the major version change. But you can
334
* Tweak - Drop the use of the generic CSS class "placeholder" in favor of "tribe-event-placeholder" (Thanks to Marc on the forums!)
335
* Tweak - Adjusted the CSS padding on Admin Menu items for Events
336
* Tweak - Various codesniffer fixes
337
* Tweak - Error messages for empty Venue names
338
* Tweak - Improve our responsiveness for the widget mini calendar, allowing smaller sidebars.
339
- * Tweak - tribe_get_vanue_link() no longer echoes if you ask it to return an <a> element
340
* Tweak - No longer retrieve empty costs when fetching all costs for all events
341
* Tweak - Change the priority of bootstrapping the-events-calendar to ensure it occurs before any of the TEC addons in the event some addons are upgraded to v4.0 later than TEC
342
* Tweak - Adjust the logic used for adding a noindex/follow tag to event views
@@ -1070,4 +1088,3 @@ Please see the changelog for the complete list of changes in this release. Remem
1070
= 2.0.3 =
1071
1072
2.0.3 is a minor bug patch for 2.0. Are you upgrading from 1.6.5? Events 2.0 is a MAJOR upgrade, please backup your data and plan a little time in case you have to make any theme edits. Check out the upgrade tutorials in support on the tri.be website.
1073
-
4
Tags: events, calendar, event, venue, organizer, dates, date, google maps, conference, workshop, concert, meeting, seminar, summit, class, modern tribe, tribe, widget
5
Donate link: http://m.tri.be/29
6
Requires at least: 3.9
7
+ Tested up to: 4.4
8
+ Stable tag: 4.0.1
9
License: GPLv2 or later
10
License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
207
<a href="https://profiles.wordpress.org/borkweb">Matthew Batchelder</a>
208
<a href="https://profiles.wordpress.org/neillmcshea">Neill McShea</a>
209
<a href="https://profiles.wordpress.org/mastromktg">Nick Mastromattei</a>
210
+ <a href="https://profiles.wordpress.org/nicosantos">Nico Santo</a>
211
<a href="https://profiles.wordpress.org/peterchester">Peter Chester</a>
212
<a href="https://profiles.wordpress.org/roblagatta">Rob La Gatta</a>
213
<a href="https://profiles.wordpress.org/reid.peifer">Reid Peifer</a>
309
310
== Changelog ==
311
312
+ = [4.0.1] 2015-12-10 =
313
+
314
+ * Tweak - Add a warning message for major updates
315
+ * Tweak - For SEO reasons, use an h1 for the title rather than an h2 (props to wpexplorer for this fix)
316
+ * Tweak - Target the calendar view grid in JS using a simpler selector
317
+ * Fix - Resolved WP 4.4 related fatal on the Nav Menu page that prevented the admin footer from rendering/enqueuing JS
318
+ * Fix - Resolved bug where visiting /events/upcoming could sometimes result in an infinite redirect loop
319
+ * Fix - Removed `wp_trim_excerpt` and use only it's powers, fixing the excerpt problem
320
+ * Fix - Fixed bug where the mobile calendar view did not display the date for the date being viewed
321
+ * Fix - Fixed bug where the admin toolbar's Events > Import > CSV did not link to the CSV importer page
322
+ * Fix - Fixed issue where the events list in the admin dashboard were not ordered in an intuitive manner
323
+ * Fix - Resolved bug where sorting by event category or tag resulted in an error
324
+ * Fix - Fixed bug where full event content text was displayed where excerpts should have been displayed
325
+ * Fix - Resolved issue where events imported via CSV were excluded from single event navigation
326
+ * Fix - Fixed bug where /events/list would sometimes 404 on a new install
327
+ * Fix - Resolved bug where multiday all-day events displayed the end date as one day later than it should be when the End of Day Cut-off was set to something other than 12am
328
+ * Fix - Timezone handling fixed within generated iCal feeds
329
+
330
= [4.0] 2015-12-02 =
331
332
* Security - A TON of escaping was added to our codebase thanks to the efforts of the always-helpful Andy Fragen (@afragen)
352
* Tweak - Drop the use of the generic CSS class "placeholder" in favor of "tribe-event-placeholder" (Thanks to Marc on the forums!)
353
* Tweak - Adjusted the CSS padding on Admin Menu items for Events
354
* Tweak - Various codesniffer fixes
355
+ * Tweak - tribe_get_venue_link() no longer echoes if you ask it to return an <a> element
356
* Tweak - Error messages for empty Venue names
357
* Tweak - Improve our responsiveness for the widget mini calendar, allowing smaller sidebars.
358
* Tweak - No longer retrieve empty costs when fetching all costs for all events
359
* Tweak - Change the priority of bootstrapping the-events-calendar to ensure it occurs before any of the TEC addons in the event some addons are upgraded to v4.0 later than TEC
360
* Tweak - Adjust the logic used for adding a noindex/follow tag to event views
1088
= 2.0.3 =
1089
1090
2.0.3 is a minor bug patch for 2.0. Are you upgrading from 1.6.5? Events 2.0 is a MAJOR upgrade, please backup your data and plan a little time in case you have to make any theme edits. Check out the upgrade tutorials in support on the tri.be website.
src/Tribe/Admin/Bar/Admin_Bar.php ADDED
@@ -0,0 +1,68 @@
1
+ <?php
2
+
3
+
4
+ class Tribe__Events__Admin__Bar__Admin_Bar {
5
+
6
+ /**
7
+ * @var Tribe__Events__Admin__Bar__Admin_Bar
8
+ */
9
+ protected static $instance;
10
+ /**
11
+ * @var Tribe__Events__Constants
12
+ */
13
+ protected $constants;
14
+ /**
15
+ * @var Tribe__Events__Admin__Bar__Configurator_Interface
16
+ */
17
+ protected $config;
18
+
19
+ /**
20
+ * Singleton constructor for the class.
21
+ *
22
+ * @return Tribe__Events__Admin__Bar__Admin_Bar
23
+ */
24
+ public static function instance() {
25
+ if ( empty( self::$instance ) ) {
26
+ self::$instance = new self();
27
+ }
28
+
29
+ return self::$instance;
30
+ }
31
+
32
+ /**
33
+ * Tribe__Events__Admin__Bar__Admin_Bar constructor.
34
+ *
35
+ * @param Tribe__Events__Admin__Bar__Configurator_Interface $config An admin bar configurator.
36
+ * @param Tribe__Events__Constants $constants A constants access proxy.
37
+ */
38
+ public function __construct( Tribe__Events__Admin__Bar__Configurator_Interface $config = null, Tribe__Events__Constants $constants = null ) {
39
+ $this->config = $config ? $config : new Tribe__Events__Admin__Bar__Default_Configurator();
40
+ $this->constants = $constants ? $constants : new Tribe__Events__Constants();
41
+ }
42
+
43
+ /**
44
+ * Whether the Tribe Admin Bar is enabled or not.
45
+ *
46
+ * @return bool `false` if the `TRIBE_DISABLE_TOOLBAR_ITEMS` constant is `true` or the current screen is the network
47
+ * admin one, `true` otherwise.
48
+ */
49
+ public function is_enabled() {
50
+ $disabled = isset( $this->constants['TRIBE_DISABLE_TOOLBAR_ITEMS'] ) && $this->constants['TRIBE_DISABLE_TOOLBAR_ITEMS'];
51
+
52
+ return ( ! ( $disabled || is_network_admin() ) );
53
+ }
54
+
55
+ /**
56
+ * Adds menus, groups and nodes to the admin bar according the configuration.
57
+ *
58
+ * @param WP_Admin_Bar|null $wp_admin_bar
59
+ */
60
+ public function init( WP_Admin_Bar $wp_admin_bar = null ) {
61
+ if ( empty( $wp_admin_bar ) ) {
62
+ global /** @var WP_Admin_Bar $wp_admin_bar */
63
+ $wp_admin_bar;
64
+ }
65
+
66
+ $this->config->configure( $wp_admin_bar );
67
+ }
68
+ }
src/Tribe/Admin/Bar/Configurator_Interface.php ADDED
@@ -0,0 +1,14 @@
1
+ <?php
2
+
3
+
4
+ interface Tribe__Events__Admin__Bar__Configurator_Interface {
5
+
6
+ /**
7
+ * Configures an admin bar object adding menus, groups and nodes to it.
8
+ *
9
+ * @param WP_Admin_Bar $wp_admin_bar
10
+ *
11
+ * @return mixed
12
+ */
13
+ public function configure( WP_Admin_Bar $wp_admin_bar );
14
+ }
src/Tribe/Admin/Bar/Default_Configurator.php ADDED
@@ -0,0 +1,113 @@
1
+ <?php
2
+
3
+
4
+ class Tribe__Events__Admin__Bar__Default_Configurator implements Tribe__Events__Admin__Bar__Configurator_Interface {
5
+
6
+ /**
7
+ * Configures an admin bar object adding menus, groups and nodes to it.
8
+ *
9
+ * @param WP_Admin_Bar $wp_admin_bar
10
+ *
11
+ * @return array An array of menus to add to the admin bar.
12
+ */
13
+ public function configure( WP_Admin_Bar $wp_admin_bar ) {
14
+ $main = Tribe__Events__Main::instance();
15
+
16
+ $wp_admin_bar->add_menu( array(
17
+ 'id' => 'tribe-events',
18
+ 'title' => '<span class="ab-icon dashicons-before dashicons-calendar"></span>' . sprintf( __( '%s', 'the-events-calendar' ), $main->plural_event_label ),
19
+ 'href' => $main->getLink( 'home' ),
20
+ ) );
21
+
22
+ $wp_admin_bar->add_group( array(
23
+ 'id' => 'tribe-events-group',
24
+ 'parent' => 'tribe-events',
25
+ ) );
26
+
27
+ $wp_admin_bar->add_group( array(
28
+ 'id' => 'tribe-events-add-ons-group',
29
+ 'parent' => 'tribe-events',
30
+ ) );
31
+
32
+ $wp_admin_bar->add_group( array(
33
+ 'id' => 'tribe-events-settings-group',
34
+ 'parent' => 'tribe-events',
35
+ ) );
36
+ if ( current_user_can( 'edit_tribe_events' ) ) {
37
+ $wp_admin_bar->add_group( array(
38
+ 'id' => 'tribe-events-import-group',
39
+ 'parent' => 'tribe-events-add-ons-group',
40
+ ) );
41
+ }
42
+
43
+ $wp_admin_bar->add_menu( array(
44
+ 'id' => 'tribe-events-view-calendar',
45
+ 'title' => esc_html__( 'View Calendar', 'the-events-calendar' ),
46
+ 'href' => $main->getLink( 'home' ),
47
+ 'parent' => 'tribe-events-group',
48
+ ) );
49
+
50
+ if ( current_user_can( 'edit_tribe_events' ) ) {
51
+ $wp_admin_bar->add_menu( array(
52
+ 'id' => 'tribe-events-add-event',
53
+ 'title' => sprintf( esc_html__( 'Add %s', 'the-events-calendar' ), $main->singular_event_label ),
54
+ 'href' => trailingslashit( get_admin_url() ) . 'post-new.php?post_type=' . Tribe__Events__Main::POSTTYPE,
55
+ 'parent' => 'tribe-events-group',
56
+ ) );
57
+ }
58
+
59
+ if ( current_user_can( 'edit_tribe_events' ) ) {
60
+ $wp_admin_bar->add_menu( array(
61
+ 'id' => 'tribe-events-edit-events',
62
+ 'title' => sprintf( esc_html__( 'Edit %s', 'the-events-calendar' ), $main->plural_event_label ),
63
+ 'href' => trailingslashit( get_admin_url() ) . 'edit.php?post_type=' . Tribe__Events__Main::POSTTYPE,
64
+ 'parent' => 'tribe-events-group',
65
+ ) );
66
+ }
67
+
68
+ if ( current_user_can( 'publish_tribe_events' ) ) {
69
+ $import_node = $wp_admin_bar->get_node( 'tribe-events-import' );
70
+ if ( ! is_object( $import_node ) ) {
71
+ $wp_admin_bar->add_menu( array(
72
+ 'id' => 'tribe-events-import',
73
+ 'title' => esc_html__( 'Import', 'the-events-calendar' ),
74
+ 'parent' => 'tribe-events-import-group',
75
+ ) );
76
+ }
77
+ $wp_admin_bar->add_menu( array(
78
+ 'id' => 'tribe-csv-import',
79
+ 'title' => esc_html__( 'CSV', 'the-events-calendar' ),
80
+ 'href' => esc_url( add_query_arg( array(
81
+ 'post_type' => Tribe__Events__Main::POSTTYPE,
82
+ 'page' => 'events-importer',
83
+ 'tab' => 'csv-importer',
84
+ ), admin_url( 'edit.php' ) ) ),
85
+ 'parent' => 'tribe-events-import',
86
+ ) );
87
+ }
88
+
89
+ if ( current_user_can( 'manage_options' ) ) {
90
+
91
+ $hide_all_settings = Tribe__Settings_Manager::get_network_option( 'allSettingsTabsHidden', '0' );
92
+ if ( $hide_all_settings == '0' ) {
93
+ $wp_admin_bar->add_menu( array(
94
+ 'id' => 'tribe-events-settings',
95
+ 'title' => esc_html__( 'Settings', 'the-events-calendar' ),
96
+ 'href' => Tribe__Settings::instance()->get_url(),
97
+ 'parent' => 'tribe-events-settings-group',
98
+ ) );
99
+ }
100
+
101
+ // Only show help link if it's not blocked in network admin.
102
+ $hidden_settings_tabs = Tribe__Settings_Manager::get_network_option( 'hideSettingsTabs', array() );
103
+ if ( ! in_array( 'help', $hidden_settings_tabs ) ) {
104
+ $wp_admin_bar->add_menu( array(
105
+ 'id' => 'tribe-events-help',
106
+ 'title' => esc_html__( 'Help', 'the-events-calendar' ),
107
+ 'href' => Tribe__Settings::instance()->get_url( array( 'tab' => 'help' ) ),
108
+ 'parent' => 'tribe-events-settings-group',
109
+ ) );
110
+ }
111
+ }
112
+ }
113
+ }
src/Tribe/Admin/Notices/Base_Notice.php ADDED
@@ -0,0 +1,29 @@
1
+ <?php
2
+
3
+
4
+ class Tribe__Events__Admin__Notices__Base_Notice implements Tribe__Events__Admin__Notices__Notice_Interface {
5
+
6
+ /**
7
+ * Echoes the notice.
8
+ *
9
+ * @param string $message
10
+ * @param string $class
11
+ *
12
+ * @return void
13
+ */
14
+ public function render( $message, $class = 'updated' ) {
15
+ echo $this->get( $message, $class );
16
+ }
17
+
18
+ /**
19
+ * Return the notice content.
20
+ *
21
+ * @param string $message
22
+ * @param string $class
23
+ *
24
+ * @return string
25
+ */
26
+ public function get( $message, $class ) {
27
+ return sprintf( '<div class="%s"><p>%s</p></div>', esc_attr( $class ), $message );
28
+ }
29
+ }
src/Tribe/Admin/Notices/Notice_Interface.php ADDED
@@ -0,0 +1,25 @@
1
+ <?php
2
+
3
+
4
+ interface Tribe__Events__Admin__Notices__Notice_Interface {
5
+
6
+ /**
7
+ * Echoes the notice.
8
+ *
9
+ * @param string $message
10
+ * @param string $class
11
+ *
12
+ * @return void
13
+ */
14
+ public function render( $message, $class = 'updated' );
15
+
16
+ /**
17
+ * Return the notice content.
18
+ *
19
+ * @param string $message
20
+ * @param string $class
21
+ *
22
+ * @return string
23
+ */
24
+ public function get( $message, $class );
25
+ }
src/Tribe/Admin/Timezone_Updater.php CHANGED
@@ -95,7 +95,7 @@ class Tribe__Events__Admin__Timezone_Updater {
95
* Sets up the Javascript needed to facilitate the ajax loop on the frontend.
96
*/
97
public function notice_assets() {
98
- $plugin = Tribe__Main::instance();
99
$script = trailingslashit( $plugin->plugin_url ) . 'src/resources/js/events-admin-timezone-updater.js';
100
$handle = 'tribe-events-ajax-timezone-update';
101
95
* Sets up the Javascript needed to facilitate the ajax loop on the frontend.
96
*/
97
public function notice_assets() {
98
+ $plugin = Tribe__Events__Main::instance();
99
$script = trailingslashit( $plugin->plugin_url ) . 'src/resources/js/events-admin-timezone-updater.js';
100
$handle = 'tribe-events-ajax-timezone-update';
101
src/Tribe/Admin_List.php CHANGED
@@ -99,7 +99,7 @@ if ( ! class_exists( 'Tribe__Events__Admin_List' ) ) {
99
}
100
101
if ( ! empty( $clauses['orderby'] ) ) {
102
- $clauses['orderby'] .= ',';
103
}
104
105
$start_orderby = "tribe_event_start_date.meta_value {$sort_direction}";
@@ -111,7 +111,12 @@ if ( ! class_exists( 'Tribe__Events__Admin_List' ) ) {
111
$date_orderby = "{$end_orderby}, {$start_orderby}";
112
}
113
114
- $clauses['orderby'] .= $date_orderby;
115
116
return $clauses;
117
}
@@ -148,17 +153,17 @@ if ( ! class_exists( 'Tribe__Events__Admin_List' ) ) {
148
// collect the terms in the desired taxonomy for the given post into a single string
149
$smashed_terms_sql = "
150
SELECT
151
- GROUP_CONCAT( wp_terms.name ORDER BY name ASC ) smashed_terms
152
FROM
153
- wp_term_relationships
154
- LEFT JOIN wp_term_taxonomy ON (
155
- wp_term_relationships.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id
156
AND taxonomy = '%s'
157
)
158
- LEFT JOIN wp_terms ON (
159
- wp_term_taxonomy.term_id = wp_terms.term_id
160
)
161
- WHERE wp_term_relationships.object_id = wp_posts.ID
162
";
163
164
$smashed_terms_sql = $wpdb->prepare( $smashed_terms_sql, $taxonomy );
@@ -276,7 +281,7 @@ if ( ! class_exists( 'Tribe__Events__Admin_List' ) ) {
276
break;
277
278
case 'end-date':
279
- echo tribe_get_end_date( $post_id, false );
280
break;
281
}
282
}
99
}
100
101
if ( ! empty( $clauses['orderby'] ) ) {
102
+ $original_orderby = $clauses['orderby'];
103
}
104
105
$start_orderby = "tribe_event_start_date.meta_value {$sort_direction}";
111
$date_orderby = "{$end_orderby}, {$start_orderby}";
112
}
113
114
+ // Add the date orderby rules *before* any pre-existing orderby rules (to stop them being "trumped")
115
+ $revised_orderby = empty( $original_orderby )
116
+ ? $date_orderby
117
+ : "$date_orderby, $original_orderby";
118
+
119
+ $clauses['orderby'] = $revised_orderby;
120
121
return $clauses;
122
}
153
// collect the terms in the desired taxonomy for the given post into a single string
154
$smashed_terms_sql = "
155
SELECT
156
+ GROUP_CONCAT( $wpdb->terms.name ORDER BY name ASC ) smashed_terms
157
FROM
158
+ $wpdb->term_relationships
159
+ LEFT JOIN $wpdb->term_taxonomy ON (
160
+ $wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id
161
AND taxonomy = '%s'
162
)
163
+ LEFT JOIN $wpdb->terms ON (
164
+ $wpdb->term_taxonomy.term_id = $wpdb->terms.term_id
165
)
166
+ WHERE $wpdb->term_relationships.object_id = $wpdb->posts.ID
167
";
168
169
$smashed_terms_sql = $wpdb->prepare( $smashed_terms_sql, $taxonomy );
281
break;
282
283
case 'end-date':
284
+ echo tribe_get_display_end_date( $post_id, false );
285
break;
286
}
287
}
src/Tribe/Constants.php ADDED
@@ -0,0 +1,76 @@
1
+ <?php
2
+
3
+
4
+ class Tribe__Events__Constants implements ArrayAccess {
5
+
6
+ /**
7
+ * @var bool Whether the class will define and read real constants or not.
8
+ */
9
+ protected $volatile;
10
+
11
+ /**
12
+ * @var array An array that will store volatile values if the class is used in volatile mode.
13
+ */
14
+ protected $volatile_values;
15
+
16
+ /**
17
+ * Tribe__Events__Constants constructor.
18
+ *
19
+ * @param bool $volatile If `true` the class will not define and read real constants.
20
+ */
21
+ public function __construct( $volatile = false ) {
22
+ $this->volatile = $volatile;
23
+ $this->volatile_values = array();
24
+ }
25
+
26
+ /**
27
+ * Whether a constant is defined or not.
28
+ *
29
+ * @param string $offset
30
+ *
31
+ * @return bool
32
+ */
33
+ public function offsetExists( $offset ) {
34
+ return $this->volatile ? isset( $this->volatile_values[ $offset ] ) : defined( $offset );
35
+ }
36
+
37
+ /**
38
+ * Gets a constant value.
39
+ *
40
+ * @param string $offset
41
+ *
42
+ * @return mixed
43
+ */
44
+ public function offsetGet( $offset ) {
45
+ return $this->volatile ? $this->volatile_values[ $offset ] : constant( $offset );
46
+ }
47
+
48
+ /**
49
+ * Sets the value of a constant if not already defined.
50
+ *
51
+ * @param string $offset
52
+ * @param mixed $value
53
+ */
54
+ public function offsetSet( $offset, $value ) {
55
+ if ( $this->volatile && ! isset( $this->volatile_values[ $offset ] ) ) {
56
+ $this->volatile_values[ $offset ] = $value;
57
+ } else {
58
+ if ( ! defined( $offset ) ) {
59
+ define( $offset, $value );
60
+ }
61
+ }
62
+ }
63
+
64
+ /**
65
+ * Unsets a constant if in volatile mode.
66
+ *
67
+ * @param string $offset
68
+ */
69
+ public function offsetUnset( $offset ) {
70
+ if ( $this->volatile ) {
71
+ $this->volatile_values = array_diff( $this->volatile_values, array( $offset ) );
72
+ } else {
73
+ // no op
74
+ }
75
+ }
76
+ }
src/Tribe/Event_Tickets/Attendees_Report.php ADDED
@@ -0,0 +1,94 @@
1
+ <?php
2
+ /**
3
+ * The Events Calendar integration with Event Tickets Attendees Report class
4
+ *
5
+ * @package The Events Calendar
6
+ * @subpackage Event Tickets
7
+ * @since 4.0.1
8
+ */
9
+ class Tribe__Events__Event_Tickets__Attendees_Report {
10
+ /**
11
+ * Constructor
12
+ */
13
+ public function __construct() {
14
+ $this->add_hooks();
15
+ }
16
+
17
+ /**
18
+ * Adds hooks for injecting/overriding aspects of the Attendees Report from Event Tickets
19
+ *
20
+ * @since 4.0.1
21
+ */
22
+ public function add_hooks() {
23
+ add_action( 'tribe_tickets_attendees_event_details_list_top', array( $this, 'event_details_top' ) );
24
+ }
25
+
26
+ /**
27
+ * Injects event meta data into the Attendees report
28
+ */
29
+ public function event_details_top( $event_id ) {
30
+ if ( Tribe__Events__Main::POSTTYPE !== get_post_type( $event_id ) ) {
31
+ return;
32
+ }
33
+
34
+ $url = null;
35
+ if ( tribe_has_venue( $event_id ) ) {
36
+ $venue_id = tribe_get_venue_id( $event_id );
37
+
38
+ $url = get_post_meta( $venue_id, '_VenueURL', true );
39
+ if ( $url ) {
40
+ $url_path = @parse_url( $url, PHP_URL_PATH );
41
+ $display_url = @parse_url( $url, PHP_URL_HOST );
42
+ $display_url .= empty( $url_path ) && $url_path !== '/' ? '/&hellip;' : '';
43
+ $display_url = apply_filters( 'tribe_venue_display_url', $display_url, $url, $venue_id );
44
+ }
45
+ }
46
+
47
+ ?>
48
+ <li>
49
+ <strong><?php esc_html_e( 'Start Date / Time:', 'event-tickets' ) ?></strong>
50
+ <?php echo tribe_get_start_date( $event_id, false, tribe_get_datetime_format( true ) ) ?>
51
+ </li>
52
+
53
+ <li>
54
+ <strong><?php esc_html_e( 'End Date / Time:', 'event-tickets' ) ?></strong>
55
+ <?php echo tribe_get_end_date( $event_id, false, tribe_get_datetime_format( true ) ); ?>
56
+ </li>
57
+ <?php
58
+
59
+ if ( tribe_has_venue( $event_id ) ) {
60
+ ?>
61
+
62
+ <li class="venue-name">
63
+ <strong><?php echo tribe_get_venue_label_singular(); ?>: </strong>
64
+ <a href="<?php echo get_edit_post_link( $venue_id ); ?>" title="<?php esc_html_e( 'Edit Venue', 'the-events-calendar' ); ?>"><?php echo tribe_get_venue( $event_id ) ?></a>
65
+ </li>
66
+
67
+ <li class="venue-address">
68
+ <strong><?php _e( 'Address:', 'the-events-calendar' ); ?> </strong>
69
+ <?php echo tribe_get_full_address( $venue_id ); ?>
70
+ </li>
71
+
72
+ <?php
73
+ if ( $phone = tribe_get_phone( $venue_id ) ) {
74
+ ?>
75
+ <li class="venue-phone">
76
+ <strong><?php echo esc_html( __( 'Phone:', 'the-events-calendar' ) ); ?> </strong>
77
+ <?php echo esc_html( $phone ); ?>
78
+ </li>
79
+ <?php
80
+ }//end if
81
+
82
+ if ( $url ) {
83
+ ?>
84
+ <li class="venue-url">
85
+ <strong><?php echo esc_html( __( 'Website:', 'the-events-calendar' ) ); ?> </strong>
86
+ <a target="_blank" href="<?php echo esc_url( $url ); ?>">
87
+ <?php echo esc_html( $display_url ); ?>
88
+ </a>
89
+ </li>
90
+ <?php
91
+ }//end if
92
+ }
93
+ }
94
+ }
src/Tribe/Event_Tickets/Main.php ADDED
@@ -0,0 +1,59 @@
1
+ <?php
2
+ /**
3
+ * The Events Calendar integration with Event Tickets class
4
+ *
5
+ * @package The Events Calendar
6
+ * @subpackage Event Tickets
7
+ * @since 4.0.1
8
+ */
9
+ class Tribe__Events__Event_Tickets__Main {
10
+ /**
11
+ * Private variable holding the class instance
12
+ *
13
+ * @since 4.0.1
14
+ *
15
+ * @var Tribe__Events__Event_Tickets__Main
16
+ */
17
+ private static $instance;
18
+
19
+ /**
20
+ * Contains an instance of the Attendees Report integration class
21
+ * @since 4.0.1
22
+ * @var Tribe__Events__Event_Tickets__Attendees_Report
23
+ */
24
+ private $attendees_report;
25
+
26
+ /**
27
+ * Method to return the private instance of the class
28
+ *
29
+ * @since 4.0.1
30
+ * @return Tribe__Events__Event_Tickets__Main
31
+ */
32
+ public static function instance() {
33
+ if ( ! self::$instance ) {
34
+ self::$instance = new self;
35
+ }
36
+
37
+ return self::$instance;
38
+ }
39
+
40
+ /**
41
+ * Constructor
42
+ */
43
+ public function __construct() {
44
+ $this->attendees_report();
45
+ }
46
+
47
+ /**
48
+ * Attendees Report integration class object accessor method
49
+ */
50
+ public function attendees_report( $object = null ) {
51
+ if ( $object ) {
52
+ $this->attendees_report = $object;
53
+ } elseif ( ! $this->attendees_report ) {
54
+ $this->attendees_report = new Tribe__Events__Event_Tickets__Attendees_Report;
55
+ }
56
+
57
+ return $this->attendees_report;
58
+ }
59
+ }
src/Tribe/Importer/File_Importer_Events.php CHANGED
@@ -166,6 +166,11 @@ class Tribe__Events__Importer__File_Importer_Events extends Tribe__Events__Impor
166
$event['tax_input']['post_tag'] = $tags;
167
}
168
169
$additional_fields = apply_filters( 'tribe_events_csv_import_event_additional_fields', array() );
170
if ( ! empty ( $additional_fields ) ) {
171
foreach ( $additional_fields as $key => $csv_column ) {
166
$event['tax_input']['post_tag'] = $tags;
167
}
168
169
+ // don't create the _EventHideFromUpcoming meta key/value pair if it doesn't need to be created
170
+ if ( ! $event['EventHideFromUpcoming'] ) {
171
+ unset( $event['EventHideFromUpcoming'] );
172
+ }
173
+
174
$additional_fields = apply_filters( 'tribe_events_csv_import_event_additional_fields', array() );
175
if ( ! empty ( $additional_fields ) ) {
176
foreach ( $additional_fields as $key => $csv_column ) {
src/Tribe/Main.php CHANGED
@@ -32,7 +32,7 @@ if ( ! class_exists( 'Tribe__Events__Main' ) ) {
32
const VENUE_POST_TYPE = 'tribe_venue';
33
const ORGANIZER_POST_TYPE = 'tribe_organizer';
34
35
- const VERSION = '4.0';
36
const MIN_ADDON_VERSION = '4.0';
37
const WP_PLUGIN_URL = 'http://wordpress.org/extend/plugins/the-events-calendar/';
38
@@ -323,6 +323,7 @@ if ( ! class_exists( 'Tribe__Events__Main' ) ) {
323
require_once $this->plugin_path . 'src/functions/advanced-functions/event.php';
324
require_once $this->plugin_path . 'src/functions/advanced-functions/venue.php';
325
require_once $this->plugin_path . 'src/functions/advanced-functions/organizer.php';
326
327
// Load Deprecated Template Tags
328
if ( ! defined( 'TRIBE_DISABLE_DEPRECATED_TAGS' ) ) {
@@ -521,7 +522,7 @@ if ( ! class_exists( 'Tribe__Events__Main' ) ) {
521
add_action( 'admin_notices', array( $this, 'checkAddOnCompatibility' ) );
522
}
523
524
- add_action( 'wp_before_admin_bar_render', array( $this, 'addToolbarItems' ), 10 );
525
add_action( 'all_admin_notices', array( $this, 'addViewCalendar' ) );
526
add_action( 'admin_head', array( $this, 'setInitialMenuMetaBoxes' ), 500 );
527
add_action( 'plugin_action_links_' . trailingslashit( $this->plugin_dir ) . 'the-events-calendar.php', array( $this, 'addLinksToPluginActions' ) );
@@ -548,6 +549,8 @@ if ( ! class_exists( 'Tribe__Events__Main' ) ) {
548
549
add_action( 'init', array( $this, 'filter_cron_schedules' ) );
550
551
// Add support for tickets plugin
552
add_action( 'tribe_tickets_ticket_added', array( 'Tribe__Events__API', 'update_event_cost' ) );
553
add_action( 'tribe_tickets_ticket_deleted', array( 'Tribe__Events__API', 'update_event_cost' ) );
@@ -808,7 +811,17 @@ if ( ! class_exists( 'Tribe__Events__Main' ) ) {
808
* Initializes any admin-specific code (expects to be called when admin_init fires).
809
*/
810
public function admin_init() {
811
$this->timezone_settings = new Tribe__Events__Admin__Timezone_Settings;
812
}
813
814
/**
@@ -1126,13 +1139,22 @@ if ( ! class_exists( 'Tribe__Events__Main' ) ) {
1126
$_nav_menu_placeholder = ( 0 > $_nav_menu_placeholder ) ? intval( $_nav_menu_placeholder ) - 1 : - 1;
1127
$archive_slug = $this->getLink();
1128
1129
array_unshift(
1130
$posts, (object) array(
1131
'ID' => 0,
1132
'object_id' => $_nav_menu_placeholder,
1133
'post_content' => '',
1134
'post_excerpt' => '',
1135
- 'post_title' => $post_type['args']->labels->all_items,
1136
'post_type' => 'nav_menu_item',
1137
'type' => 'custom',
1138
'url' => $archive_slug,
@@ -2572,10 +2594,17 @@ if ( ! class_exists( 'Tribe__Events__Main' ) ) {
2572
public function redirect_past_upcoming_view_urls() {
2573
2574
if ( strpos( $_SERVER['REQUEST_URI'], $this->getRewriteSlug() . '/' . $this->pastSlug ) !== false ) {
2575
- wp_redirect( esc_url_raw( add_query_arg( array( 'tribe_event_display' => 'past' ), str_replace( '/' . $this->pastSlug . '/', '/' . $this->listSlug . '/', $_SERVER['REQUEST_URI'] ) ) ) );
2576
die;
2577
} elseif ( strpos( $_SERVER['REQUEST_URI'], $this->getRewriteSlug() . '/' . $this->upcomingSlug ) !== false ) {
2578
- wp_redirect( str_replace( '/' . $this->upcomingSlug . '/', '/' . $this->listSlug . '/', $_SERVER['REQUEST_URI'] ) );
2579
die;
2580
}
2581
@@ -4093,136 +4122,13 @@ if ( ! class_exists( 'Tribe__Events__Main' ) ) {
4093
*
4094
* @return null
4095
*/
4096
- public function addToolbarItems() {
4097
- if ( ( ! defined( 'TRIBE_DISABLE_TOOLBAR_ITEMS' ) || ! TRIBE_DISABLE_TOOLBAR_ITEMS ) && ! is_network_admin() ) {
4098
- global $wp_admin_bar;
4099
-
4100
- $wp_admin_bar->add_menu(
4101
- array(
4102
- 'id' => 'tribe-events',
4103
- 'title' => '<span class="ab-icon dashicons-before dashicons-calendar"></span>' . sprintf( __( '%s', 'the-events-calendar' ), $this->plural_event_label ),
4104
- 'href' => $this->getLink( 'home' ),
4105
- )
4106
- );
4107
-
4108
- $wp_admin_bar->add_group(
4109
- array(
4110
- 'id' => 'tribe-events-group',
4111
- 'parent' => 'tribe-events',
4112
- )
4113
- );
4114
-
4115
- $wp_admin_bar->add_group(
4116
- array(
4117
- 'id' => 'tribe-events-add-ons-group',
4118
- 'parent' => 'tribe-events',
4119
- )
4120
- );
4121
-
4122
- $wp_admin_bar->add_group(
4123
- array(
4124
- 'id' => 'tribe-events-settings-group',
4125
- 'parent' => 'tribe-events',
4126
- )
4127
- );
4128
- if ( current_user_can( 'edit_tribe_events' ) ) {
4129
- $wp_admin_bar->add_group(
4130
- array(
4131
- 'id' => 'tribe-events-import-group',
4132
- 'parent' => 'tribe-events-add-ons-group',
4133
- )
4134
- );
4135
- }
4136
-
4137
- $wp_admin_bar->add_menu(
4138
- array(
4139
- 'id' => 'tribe-events-view-calendar',
4140
- 'title' => esc_html__( 'View Calendar', 'the-events-calendar' ),
4141
- 'href' => $this->getLink( 'home' ),
4142
- 'parent' => 'tribe-events-group',
4143
- )
4144
- );
4145
-
4146
- if ( current_user_can( 'edit_tribe_events' ) ) {
4147
- $wp_admin_bar->add_menu(
4148
- array(
4149
- 'id' => 'tribe-events-add-event',
4150
- 'title' => sprintf( esc_html__( 'Add %s', 'the-events-calendar' ), $this->singular_event_label ),
4151
- 'href' => trailingslashit( get_admin_url() ) . 'post-new.php?post_type=' . self::POSTTYPE,
4152
- 'parent' => 'tribe-events-group',
4153
- )
4154
- );
4155
- }
4156
-
4157
- if ( current_user_can( 'edit_tribe_events' ) ) {
4158
- $wp_admin_bar->add_menu(
4159
- array(
4160
- 'id' => 'tribe-events-edit-events',
4161
- 'title' => sprintf( esc_html__( 'Edit %s', 'the-events-calendar' ), $this->plural_event_label ),
4162
- 'href' => trailingslashit( get_admin_url() ) . 'edit.php?post_type=' . self::POSTTYPE,
4163
- 'parent' => 'tribe-events-group',
4164
- )
4165
- );
4166
- }
4167
-
4168
- if ( current_user_can( 'publish_tribe_events' ) ) {
4169
- $import_node = $wp_admin_bar->get_node( 'tribe-events-import' );
4170
- if ( ! is_object( $import_node ) ) {
4171
- $wp_admin_bar->add_menu(
4172
- array(
4173
- 'id' => 'tribe-events-import',
4174
- 'title' => esc_html__( 'Import', 'the-events-calendar' ),
4175
- 'parent' => 'tribe-events-import-group',
4176
- )
4177
- );
4178
- }
4179
- $wp_admin_bar->add_menu(
4180
- array(
4181
- 'id' => 'tribe-csv-import',
4182
- 'title' => esc_html__( 'CSV', 'the-events-calendar' ),
4183
- 'href' => esc_url(
4184
- add_query_arg(
4185
- array(
4186
- 'post_type' => self::POSTTYPE,
4187
- 'page' => 'events-importer',
4188
- 'tab' => 'csv',
4189
- ),
4190
- admin_url( 'edit.php' )
4191
- )
4192
- ),
4193
- 'parent' => 'tribe-events-import',
4194
- )
4195
- );
4196
- }
4197
-
4198
- if ( current_user_can( 'manage_options' ) ) {
4199
-
4200
- $hide_all_settings = Tribe__Settings_Manager::get_network_option( 'allSettingsTabsHidden', '0' );
4201
- if ( $hide_all_settings == '0' ) {
4202
- $wp_admin_bar->add_menu(
4203
- array(
4204
- 'id' => 'tribe-events-settings',
4205
- 'title' => esc_html__( 'Settings', 'the-events-calendar' ),
4206
- 'href' => Tribe__Settings::instance()->get_url(),
4207
- 'parent' => 'tribe-events-settings-group',
4208
- )
4209
- );
4210
- }
4211
-
4212
- // Only show help link if it's not blocked in network admin.
4213
- $hidden_settings_tabs = Tribe__Settings_Manager::get_network_option( 'hideSettingsTabs', array() );
4214
- if ( ! in_array( 'help', $hidden_settings_tabs ) ) {
4215
- $wp_admin_bar->add_menu(
4216
- array(
4217
- 'id' => 'tribe-events-help',
4218
- 'title' => esc_html__( 'Help', 'the-events-calendar' ),
4219
- 'href' => Tribe__Settings::instance()->get_url( array( 'tab' => 'help' ) ),
4220
- 'parent' => 'tribe-events-settings-group',
4221
- )
4222
- );
4223
- }
4224
- }
4225
}
4226
}
4227
4228
/**
32
const VENUE_POST_TYPE = 'tribe_venue';
33
const ORGANIZER_POST_TYPE = 'tribe_organizer';
34
35
+ const VERSION = '4.0.1';
36
const MIN_ADDON_VERSION = '4.0';
37
const WP_PLUGIN_URL = 'http://wordpress.org/extend/plugins/the-events-calendar/';
38
323
require_once $this->plugin_path . 'src/functions/advanced-functions/event.php';
324
require_once $this->plugin_path . 'src/functions/advanced-functions/venue.php';
325
require_once $this->plugin_path . 'src/functions/advanced-functions/organizer.php';
326
+ require_once $this->plugin_path . 'src/functions/utils/array.php';
327
328
// Load Deprecated Template Tags
329
if ( ! defined( 'TRIBE_DISABLE_DEPRECATED_TAGS' ) ) {
522
add_action( 'admin_notices', array( $this, 'checkAddOnCompatibility' ) );
523
}
524
525
+ add_action( 'wp_before_admin_bar_render', array( $this, 'add_toolbar_items' ), 10 );
526
add_action( 'all_admin_notices', array( $this, 'addViewCalendar' ) );
527
add_action( 'admin_head', array( $this, 'setInitialMenuMetaBoxes' ), 500 );
528
add_action( 'plugin_action_links_' . trailingslashit( $this->plugin_dir ) . 'the-events-calendar.php', array( $this, 'addLinksToPluginActions' ) );
549
550
add_action( 'init', array( $this, 'filter_cron_schedules' ) );
551
552
+ add_action( 'plugins_loaded', array( 'Tribe__Events__Event_Tickets__Main', 'instance' ) );
553
+
554
// Add support for tickets plugin
555
add_action( 'tribe_tickets_ticket_added', array( 'Tribe__Events__API', 'update_event_cost' ) );
556
add_action( 'tribe_tickets_ticket_deleted', array( 'Tribe__Events__API', 'update_event_cost' ) );
811
* Initializes any admin-specific code (expects to be called when admin_init fires).
812
*/
813
public function admin_init() {
814
+ global $pagenow;
815
+
816
$this->timezone_settings = new Tribe__Events__Admin__Timezone_Settings;
817
+
818
+ // Right now it only makes sense to add these extra upgrade notices within the plugins.php screen
819
+ if ( 'plugins.php' === $pagenow ) {
820
+ new Tribe__Admin__Notice__Plugin_Upgrade_Notice(
821
+ self::VERSION,
822
+ $this->plugin_dir . 'the-events-calendar.php'
823
+ );
824
+ }
825
}
826
827
/**
1139
$_nav_menu_placeholder = ( 0 > $_nav_menu_placeholder ) ? intval( $_nav_menu_placeholder ) - 1 : - 1;
1140
$archive_slug = $this->getLink();
1141
1142
+ // In WP 4.4, $post_type is an object rather than an array
1143
+ if ( is_array( $post_type ) ) {
1144
+ // support pre WP 4.4
1145
+ $all_items = $post_type['args']->labels->all_items;
1146
+ } else {
1147
+ // support WP 4.4+
1148
+ $all_items = $post_type->labels->all_items;
1149
+ }
1150
+
1151
array_unshift(
1152
$posts, (object) array(
1153
'ID' => 0,
1154
'object_id' => $_nav_menu_placeholder,
1155
'post_content' => '',
1156
'post_excerpt' => '',
1157
+ 'post_title' => $all_items,
1158
'post_type' => 'nav_menu_item',
1159
'type' => 'custom',
1160
'url' => $archive_slug,
2594
public function redirect_past_upcoming_view_urls() {
2595
2596
if ( strpos( $_SERVER['REQUEST_URI'], $this->getRewriteSlug() . '/' . $this->pastSlug ) !== false ) {
2597
+ $search = '#/' . $this->pastSlug . '/?#';
2598
+ $replace = '/' . $this->listSlug . '/';
2599
+ $redirect_url = preg_replace( $search, $replace, $_SERVER['REQUEST_URI'] );
2600
+ $redirect_url = esc_url_raw( add_query_arg( array( 'tribe_event_display' => 'past' ), $redirect_url ) );
2601
+ wp_redirect( $redirect_url );
2602
die;
2603
} elseif ( strpos( $_SERVER['REQUEST_URI'], $this->getRewriteSlug() . '/' . $this->upcomingSlug ) !== false ) {
2604
+ $search = '#/' . $this->upcomingSlug . '/?#';
2605
+ $replace = '/' . $this->listSlug . '/';
2606
+ $redirect_url = preg_replace( $search, $replace, $_SERVER['REQUEST_URI'] );
2607
+ wp_redirect( $redirect_url );
2608
die;
2609
}
2610
4122
*
4123
* @return null
4124
*/
4125
+ public function add_toolbar_items() {
4126
+ $admin_bar = Tribe__Events__Admin__Bar__Admin_Bar::instance();
4127
+ if ( ! $admin_bar->is_enabled() ) {
4128
+ return;
4129
}
4130
+ global $wp_admin_bar;
4131
+ $admin_bar->init( $wp_admin_bar );
4132
}
4133
4134
/**
src/Tribe/Timezones.php CHANGED
@@ -314,9 +314,7 @@ class Tribe__Events__Timezones extends Tribe__Timezones {
314
315
// If the event-specific timezone is suitable, we can obtain it without any conversion work
316
if ( $use_event_tz || ( $use_site_tz && $site_zone_is_event_zone ) ) {
317
- $datetime = isset( $event->{"Event{$type}Date"} )
318
- ? $event->{"Event{$type}Date"}
319
- : get_post_meta( $event->ID, "_Event{$type}Date", true );
320
321
return strtotime( $datetime );
322
}
314
315
// If the event-specific timezone is suitable, we can obtain it without any conversion work
316
if ( $use_event_tz || ( $use_site_tz && $site_zone_is_event_zone ) ) {
317
+ $datetime = get_post_meta( $event->ID, "_Event{$type}Date", true );
318
319
return strtotime( $datetime );
320
}
src/Tribe/Utils/DST.php ADDED
@@ -0,0 +1,73 @@
1
+ <?php
2
+
3
+
4
+ class Tribe__Events__Utils__DST {
5
+
6
+ /**
7
+ * Whether the time is in DST or not.
8
+ *
9
+ * @var bool
10
+ */
11
+ protected $_in_dst;
12
+
13
+ /**
14
+ * @var string A UNIX timestamp
15
+ */
16
+ protected $time;
17
+
18
+ /**
19
+ * @var bool
20
+ */
21
+ protected $is_dst_cache;
22
+
23
+ /**
24
+ * Tribe__Events__Utils__DST constructor.
25
+ *
26
+ * @param int|string $time Either a UNIX timestamp or an english format date.
27
+ * @param null|bool $_in_dst An injectable DST status, meant for tests.
28
+ */
29
+ public function __construct( $time, $_in_dst = null ) {
30
+ if ( ! is_numeric( $time ) ) {
31
+ $time = strtotime( $time );
32
+ }
33
+
34
+ $this->time = $time;
35
+ $this->_in_dst = $_in_dst;
36
+ }
37
+
38
+ /**
39
+ * Whether the current time is in DST or not.
40
+ *
41
+ * @return bool
42
+ */
43
+ public function is_in_dst() {
44
+ if ( is_null($this->is_dst_cache) ) {
45
+ $default_timezone_backup = date_default_timezone_get();
46
+ $wp_timezone_string = get_option( 'timezone_string' );
47
+ $wp_timezone_string = empty( $wp_timezone_string ) ? $default_timezone_backup : $wp_timezone_string;
48
+
49
+ date_default_timezone_set( $wp_timezone_string );
50
+ $this->is_dst_cache = is_null( $this->_in_dst ) ? (bool) date( 'I', $this->time ) : $this->_in_dst;
51
+ date_default_timezone_set( $default_timezone_backup );
52
+ }
53
+
54
+ return $this->is_dst_cache;
55
+ }
56
+
57
+ /**
58
+ * Returns the time of the object aligned with another date object.
59
+ *
60
+ * If both in date or both not in DST the same time; if this time is in DST and the
61
+ * target date is not in DST then the time +1hr, else the time -1 hr.
62
+ *
63
+ * @param Tribe__Events__Utils__DST $dst Another DST object this one should be aligned with.
64
+ *
65
+ * @return int The DST aligned UNIX timestamp.
66
+ */
67
+ public function get_time_aligned_with( Tribe__Events__Utils__DST $dst ) {
68
+ $dst_aligned = $this->is_in_dst() == $dst->is_in_dst();
69
+ $offset = $dst->is_in_dst() - $this->is_in_dst();
70
+
71
+ return $dst_aligned ? $this->time : $this->time + $offset * 3600;
72
+ }
73
+ }
src/Tribe/iCal.php CHANGED
@@ -229,8 +229,8 @@ class Tribe__Events__iCal {
229
230
$full_format = 'Ymd\THis';
231
$time = (object) array(
232
- 'start' => self::wp_strtotime( $event_post->EventStartDate ),
233
- 'end' => self::wp_strtotime( $event_post->EventEndDate ),
234
'modified' => self::wp_strtotime( $event_post->post_modified ),
235
'created' => self::wp_strtotime( $event_post->post_date ),
236
);
@@ -254,7 +254,11 @@ class Tribe__Events__iCal {
254
$item[] = "DTSTART;VALUE=$type:" . $tzoned->start;
255
$item[] = "DTEND;VALUE=$type:" . $tzoned->end;
256
} else {
257
- $tz = get_option( 'timezone_string' );
258
$item[] = 'DTSTART;TZID="'.$tz.'":' . $tzoned->start;
259
$item[] = 'DTEND;TZID="'.$tz.'":' . $tzoned->end;
260
}
229
230
$full_format = 'Ymd\THis';
231
$time = (object) array(
232
+ 'start' => tribe_get_start_date( $event_post->ID, false, 'U' ),
233
+ 'end' => tribe_get_end_date( $event_post->ID, false, 'U' ),
234
'modified' => self::wp_strtotime( $event_post->post_modified ),
235
'created' => self::wp_strtotime( $event_post->post_date ),
236
);
254
$item[] = "DTSTART;VALUE=$type:" . $tzoned->start;
255
$item[] = "DTEND;VALUE=$type:" . $tzoned->end;
256
} else {
257
+ // Are we using the sitewide timezone or the local event timezone?
258
+ $tz = Tribe__Events__Timezones::EVENT_TIMEZONE === Tribe__Events__Timezones::mode()
259
+ ? Tribe__Events__Timezones::get_event_timezone_string( $event_post->ID )
260
+ : Tribe__Events__Timezones::wp_timezone_string();
261
+
262
$item[] = 'DTSTART;TZID="'.$tz.'":' . $tzoned->start;
263
$item[] = 'DTEND;TZID="'.$tz.'":' . $tzoned->end;
264
}
src/admin-views/new-organizer-meta-section.php CHANGED
@@ -56,6 +56,12 @@ $organizer_pto = get_post_type_object( Tribe__Events__Main::ORGANIZER_POST_TYPE
56
$('#event_organizer').on('blur', '.organizer-name', function () {
57
var input = $(this);
58
var group = input.parents('tbody');
59
$.post(ajaxurl,
60
{
61
action: 'tribe_event_validation',
56
$('#event_organizer').on('blur', '.organizer-name', function () {
57
var input = $(this);
58
var group = input.parents('tbody');
59
+
60
+ // Not actually populated with anything? Don't bother validating
61
+ if ( ! input.val().length ) {
62
+ return;
63
+ }
64
+
65
$.post(ajaxurl,
66
{
67
action: 'tribe_event_validation',
src/functions/template-tags/date.php CHANGED
@@ -96,76 +96,29 @@ if ( ! function_exists( 'tribe_get_end_time' ) ) {
96
}
97
}
98
99
- if ( ! function_exists( 'tribe_get_start_date' ) ) {
100
/**
101
- * Start Date
102
*
103
- * Returns the event start date and time
104
*
105
* @category Events
106
- * @param int $event (optional)
107
- * @param bool $displayTime If true shows date and time, if false only shows date
108
- * @param string $dateFormat Allows date and time formating using standard php syntax (http://php.net/manual/en/function.date.php)
109
- * @param string $timezone Timezone in which to present the date/time (or default behaviour if not set)
110
- * @return string|null Date
111
- */
112
- function tribe_get_start_date( $event = null, $displayTime = true, $dateFormat = '', $timezone = null ) {
113
- if ( is_null( $event ) ) {
114
- global $post;
115
- $event = $post;
116
- }
117
-
118
- if ( is_numeric( $event ) ) {
119
- $event = get_post( $event );
120
- }
121
-
122
- if ( ! is_object( $event ) ) {
123
- return '';
124
- }
125
-
126
- if ( tribe_event_is_all_day( $event ) ) {
127
- $displayTime = false;
128
- }
129
-
130
- $start_date = Tribe__Events__Timezones::event_start_timestamp( $event->ID, $timezone );
131
- return tribe_format_date( $start_date, $displayTime, $dateFormat );
132
- }
133
- }
134
-
135
- if ( ! function_exists( 'tribe_get_end_date' ) ) {
136
- /**
137
- * End Date
138
- *
139
- * Returns the event end date
140
- *
141
- * @category Events
142
- * @param int $event (optional)
143
- * @param bool $displayTime If true shows date and time, if false only shows date
144
- * @param string $dateFormat Allows date and time formating using standard php syntax (http://php.net/manual/en/function.date.php)
145
- * @param string $timezone Timezone in which to present the date/time (or default behaviour if not set)
146
*
147
* @return string|null Date
148
*/
149
- function tribe_get_end_date( $event = null, $displayTime = true, $dateFormat = '', $timezone = null ) {
150
- if ( is_null( $event ) ) {
151
- global $post;
152
- $event = $post;
153
- }
154
-
155
- if ( is_numeric( $event ) ) {
156
- $event = get_post( $event );
157
- }
158
159
- if ( ! is_object( $event ) ) {
160
- return '';
161
}
162
163
- if ( tribe_event_is_all_day( $event ) ) {
164
- $displayTime = false;
165
- }
166
-
167
- $end_date = Tribe__Events__Timezones::event_end_timestamp( $event->ID, $timezone );
168
- return tribe_format_date( $end_date, $displayTime, $dateFormat );
169
}
170
}
171
@@ -216,4 +169,4 @@ if ( ! function_exists( 'tribe_event_is_on_date' ) ) {
216
217
return apply_filters( 'tribe_event_is_on_date', $event_is_on_date, $date, $event );
218
}
219
- }
96
}
97
}
98
99
+ if ( ! function_exists( 'tribe_get_display_end_date' ) ) {
100
/**
101
+ * End Date formatted for display
102
*
103
+ * Returns the event end date that observes the end of day cutoff
104
*
105
* @category Events
106
+ * @param int $event (optional)
107
+ * @param bool $display_time If true shows date and time, if false only shows date
108
+ * @param string $date_format Allows date and time formating using standard php syntax (http://php.net/manual/en/function.date.php)
109
+ * @param string $timezone Timezone in which to present the date/time (or default behaviour if not set)
110
*
111
* @return string|null Date
112
*/
113
+ function tribe_get_display_end_date( $event = null, $display_time = true, $date_format = '', $timezone = null ) {
114
+ $end_date = tribe_get_end_date( $event, true, 'U', $timezone );
115
+ $beginning_of_day = tribe_beginning_of_day( date( Tribe__Date_Utils::DBDATETIMEFORMAT, $end_date ) );
116
117
+ if ( tribe_event_is_multiday( $event ) && $end_date < strtotime( $beginning_of_day ) ) {
118
+ $end_date -= DAY_IN_SECONDS;
119
}
120
121
+ return tribe_format_date( $end_date, $display_time, $date_format );
122
}
123
}
124
169
170
return apply_filters( 'tribe_event_is_on_date', $event_is_on_date, $date, $event );
171
}
172
+ }
src/functions/template-tags/general.php CHANGED
@@ -913,7 +913,18 @@ if ( class_exists( 'Tribe__Events__Main' ) ) {
913
$inner .= tribe_get_start_date( $event, true, $format );
914
$inner .= '</span>' . $time_range_separator;
915
$inner .= '<span class="tribe-event-date-end">';
916
- $inner .= tribe_get_end_date( $event, true, $format2ndday );
917
} else {
918
$inner .= tribe_get_start_date( $event, false, $format ) . ( $time ? $datetime_separator . tribe_get_start_date( $event, false, $time_format ) : '' );
919
$inner .= '</span>' . $time_range_separator;
@@ -1111,7 +1122,10 @@ if ( class_exists( 'Tribe__Events__Main' ) ) {
1111
if ( isset( $deprecated ) ) {
1112
_deprecated_argument( __FUNCTION__, '3.10' );
1113
}
1114
- return tribe_get_option( 'tribeEnableViews', array( 'month' ) );
1115
}
1116
1117
/**
@@ -1316,8 +1330,22 @@ if ( class_exists( 'Tribe__Events__Main' ) ) {
1316
// Remove "all" HTML based on what is allowed
1317
$excerpt = wp_kses( $excerpt, $allowed_html );
1318
1319
- // Still treat this as an Excerpt on WP
1320
- $excerpt = wp_trim_excerpt( $excerpt );
1321
1322
return wpautop( $excerpt );
1323
}
913
$inner .= tribe_get_start_date( $event, true, $format );
914
$inner .= '</span>' . $time_range_separator;
915
$inner .= '<span class="tribe-event-date-end">';
916
+
917
+ $end_date_full = tribe_get_end_date( $event, true, Tribe__Date_Utils::DBDATETIMEFORMAT );
918
+ $end_date_full_timestamp = strtotime( $end_date_full );
919
+
920
+ // if the end date is <= the beginning of the day, consider it the previous day
921
+ if ( $end_date_full_timestamp <= strtotime( tribe_beginning_of_day( $end_date_full ) ) ) {
922
+ $end_date = tribe_format_date( $end_date_full_timestamp - DAY_IN_SECONDS, false, $format2ndday );
923
+ } else {
924
+ $end_date = tribe_get_end_date( $event, false, $format2ndday );
925
+ }
926
+
927
+ $inner .= $end_date;
928
} else {
929
$inner .= tribe_get_start_date( $event, false, $format ) . ( $time ? $datetime_separator . tribe_get_start_date( $event, false, $time_format ) : '' );
930
$inner .= '</span>' . $time_range_separator;
1122
if ( isset( $deprecated ) ) {
1123
_deprecated_argument( __FUNCTION__, '3.10' );
1124
}
1125
+ return tribe_get_option( 'tribeEnableViews', array(
1126
+ 'list',
1127
+ 'month',
1128
+ ) );
1129
}
1130
1131
/**
1330
// Remove "all" HTML based on what is allowed
1331
$excerpt = wp_kses( $excerpt, $allowed_html );
1332
1333
+ /**
1334
+ * Filter the number of words in an excerpt.
1335
+ *
1336
+ * @param int $number The number of words. Default 55.
1337
+ */
1338
+ $excerpt_length = apply_filters( 'excerpt_length', 55 );
1339
+
1340
+ /**
1341
+ * Filter the string in the "more" link displayed after a trimmed excerpt.
1342
+ *
1343
+ * @param string $more_string The string shown within the more link.
1344
+ */
1345
+ $excerpt_more = apply_filters( 'excerpt_more', ' [&hellip;]' );
1346
+
1347
+ // Now we actually trim it
1348
+ $excerpt = wp_trim_words( $excerpt, $excerpt_length, $excerpt_more );
1349
1350
return wpautop( $excerpt );
1351
}
src/functions/utils/array.php ADDED
@@ -0,0 +1,23 @@
1
+ <?php
2
+ /**
3
+ * Utility functions dealing with arrays
4
+ */
5
+
6
+ /**
7
+ * Drop-in replacement for array_unique(), designed to operate on an array of arrays
8
+ * where each inner array is populated with strings (or types that can be stringified
9
+ * while essentially keeping their unique value).
10
+ *
11
+ * @param array $original array_of_arrays
12
+ *
13
+ * @return array
14
+ */
15
+ function tribe_array_unique( array $original ) {
16
+ $unique = array();
17
+
18
+ foreach( $original as $inner ) {
19
+ $unique[ join( '|', $inner ) ] = $inner;
20
+ }
21
+
22
+ return array_values( $unique );
23
+ }
src/resources/js/tribe-events-ajax-calendar.js CHANGED
@@ -155,12 +155,6 @@
155
156
data.has_events = $date.hasClass( 'tribe-events-has-events' );
157
158
- // Backwards compatibility
159
- // @todo "Check if we can remove this check"
160
- if ( data.has_events ) {
161
- data.date_name = '';
162
- }
163
-
164
$triggers.removeClass( 'mobile-active' )
165
// If full_date_name is empty then default to highlighting the first day of the current month
166
.filter( _active ).addClass( 'mobile-active' );
@@ -180,7 +174,7 @@
180
181
var $today = $wrapper.find( '.tribe-events-present' ),
182
$mobile_trigger = $wrapper.find( '.mobile-trigger' ),
183
- $tribe_grid = $wrapper.find( '#tribe-events-content > .tribe-events-calendar' );
184
185
if ( !$( '#tribe-mobile-container' ).length ) {
186
$( '<div id="tribe-mobile-container" />' ).insertAfter( $tribe_grid );
@@ -408,12 +402,13 @@
408
eventDate: ts.date
409
};
410
411
if ( ts.category ) {
412
- ts.params['tribe_event_category'] = ts.category;
413
}
414
415
- ts.url_params = {};
416
-
417
if ( td.default_permalinks ) {
418
if( !ts.url_params.hasOwnProperty( 'post_type' ) ){
419
ts.url_params['post_type'] = config.events_post_type;
@@ -430,7 +425,7 @@
430
431
$( te ).trigger( 'tribe_ev_collectParams' );
432
433
- if ( ts.pushcount > 0 || ts.filters || td.default_permalinks ) {
434
ts.do_string = true;
435
ts.pushstate = false;
436
}
155
156
data.has_events = $date.hasClass( 'tribe-events-has-events' );
157
158
$triggers.removeClass( 'mobile-active' )
159
// If full_date_name is empty then default to highlighting the first day of the current month
160
.filter( _active ).addClass( 'mobile-active' );
174
175
var $today = $wrapper.find( '.tribe-events-present' ),
176
$mobile_trigger = $wrapper.find( '.mobile-trigger' ),
177
+ $tribe_grid = $wrapper.find( document.getElementById( 'tribe-events-content' ) ).find( '.tribe-events-calendar' );
178
179
if ( !$( '#tribe-mobile-container' ).length ) {
180
$( '<div id="tribe-mobile-container" />' ).insertAfter( $tribe_grid );
402
eventDate: ts.date
403
};
404
405
+ ts.url_params = {};
406
+
407
if ( ts.category ) {
408
+ ts.params.tribe_event_category = ts.category;
409
+ ts.url_params.tribe_events_cat = ts.category;
410
}
411
412
if ( td.default_permalinks ) {
413
if( !ts.url_params.hasOwnProperty( 'post_type' ) ){
414
ts.url_params['post_type'] = config.events_post_type;
425
426
$( te ).trigger( 'tribe_ev_collectParams' );
427
428
+ if ( ts.pushcount > 0 || ts.filters || td.default_permalinks || ts.category ) {
429
ts.do_string = true;
430
ts.pushstate = false;
431
}
src/resources/js/tribe-events-ajax-calendar.min.js CHANGED
@@ -1 +1 @@
1
- !function(a,b,c,d,e,f,g,h,i,j){c(b).ready(function(){function j(a){var b=c('.tribe-mobile-day[data-day="'+a+'"]'),d=c('.tribe-events-calendar td[data-day="'+a+'"]'),e=d.find(".tribe-events-viewmore"),f=d.find(".hentry");f.length&&(f.each(function(){var a=c(this);if(a.tribe_has_attr("data-tribejson")){var d=a.data("tribejson");b.append(tribe_tmpl("tribe_tmpl_month_mobile",d))}}),e.length&&b.append(e.clone()))}function k(a){var b=a.data("tribejson");b.date=a.attr("data-day");var c=a.parents(".tribe-events-calendar"),d=c.next("#tribe-mobile-container"),e=d.find(".tribe-mobile-day"),f=c.find(".mobile-trigger"),g='[data-day="'+b.date+'"]',h=e.filter(g);b.has_events=a.hasClass("tribe-events-has-events"),b.has_events&&(b.date_name=""),f.removeClass("mobile-active").filter(g).addClass("mobile-active"),e.hide(),h.length?h.show():(d.append(tribe_tmpl("tribe_tmpl_month_mobile_day_header",b)),j(b.date))}function l(){var a=t.find(".tribe-events-present"),b=t.find(".mobile-trigger"),d=t.find("#tribe-events-content > .tribe-events-calendar");if(c("#tribe-mobile-container").length||c('<div id="tribe-mobile-container" />').insertAfter(d),a.length&&a.is(".tribe-events-thismonth"))k(a);else{var e=b.filter(".tribe-events-thismonth").first();k(e)}}function m(){t.find(".tribe-events-calendar th").each(function(){var a=c(this),b=a.attr("data-day-abbr"),d=a.attr("title");q.is(".tribe-mobile")?a.text(b):a.text(d)})}function n(a){q.is(".tribe-mobile")?(m(),l()):a&&m()}function o(a){if("change_view"!=tribe_events_bar_action){if(a.preventDefault(),g.ajax_running)return;u.val().length?"0"!==g.datepicker_format?g.date=tribeDateFormat(u.bootstrapDatepicker("getDate"),"tribeMonthQuery"):g.date=u.val():v||(g.date=d.cur_date.slice(0,-3)),g.filter_cats?d.cur_url=c("#tribe-events-header").data("baseurl")+g.date+"/":d.default_permalinks?d.cur_url=w:d.cur_url=w+g.date+"/",g.popping=!1,f.pre_ajax(function(){p()})}}function p(){f.invalid_date(g.date)||(c(".tribe-events-calendar").tribe_spin(),g.pushcount=0,g.ajax_running=!0,g.popping||(g.params={action:"tribe_calendar",eventDate:g.date},g.category&&(g.params.tribe_event_category=g.category),g.url_params={},d.default_permalinks&&(g.url_params.hasOwnProperty("post_type")||(g.url_params.post_type=i.events_post_type),g.url_params.hasOwnProperty("eventDisplay")||(g.url_params.eventDisplay=g.view)),c(e).trigger("tribe_ev_serializeBar"),g.params=c.param(g.params),g.url_params=c.param(g.url_params),c(e).trigger("tribe_ev_collectParams"),g.pushcount>0||g.filters||d.default_permalinks?(g.do_string=!0,g.pushstate=!1):(g.do_string=!1,g.pushstate=!0)),h.pushstate&&!g.filter_cats?(c(e).trigger("tribe_ev_ajaxStart").trigger("tribe_ev_monthView_AjaxStart"),c.post(TribeCalendar.ajaxurl,g.params,function(a){if(g.initial_load=!1,f.enable_inputs("#tribe_events_filters_form","input, select"),a.success){g.ajax_running=!1,d.ajax_response={total_count:"",view:a.view,max_pages:"",tribe_paged:"",timestamp:(new Date).getTime()};var h="";h=c.isFunction(c.fn.parseHTML)?c.parseHTML(a.html):a.html,c("#tribe-events-content").replaceWith(h),n(!0),g.page_title=c("#tribe-events-header").data("title"),b.title=g.page_title,g.do_string&&(d.cur_url=d.cur_url+"?"+g.url_params,history.pushState({tribe_date:g.date,tribe_params:g.params},g.page_title,d.cur_url)),g.pushstate&&history.pushState({tribe_date:g.date,tribe_params:g.params},g.page_title,d.cur_url),c(e).trigger("tribe_ev_ajaxSuccess").trigger("tribe_ev_monthView_ajaxSuccess")}})):g.url_params.length?a.location=d.cur_url+"?"+g.url_params:a.location=d.cur_url)}var q=c("body"),r=c('[class^="tribe-events-nav-"] a'),s=f.get_url_param("tribe-bar-date"),t=c("#tribe-events"),u=c("#tribe-bar-date"),v=!1,w="/";"undefined"!=typeof i.events_base?w=i.events_base:r.length&&(w=r.first().attr("href").slice(0,-8)),d.default_permalinks&&(w=w.split("?")[0]),c(".tribe-events-calendar").length&&c("#tribe-events-bar").length&&s&&s.length>7&&(c("#tribe-bar-date-day").val(s.slice(-3)),u.val(s.substring(0,7)));var x="yyyy-mm";if("0"!==g.datepicker_format){var y=parseInt(g.datepicker_format),z="m"+g.datepicker_format.toString();x=d.datepicker_formats.month[y],s&&(s.length<=7&&(s+="-01"),u.val(tribeDateFormat(s,z)))}if(d.datepicker_opts={format:x,minViewMode:"months",autoclose:!0},u.bootstrapDatepicker(d.datepicker_opts).on("changeDate",function(a){g.mdate=a.date;var b=a.date.getFullYear(),e=("0"+(a.date.getMonth()+1)).slice(-2);if(v=!0,g.date=b+"-"+e,h.no_bar()||h.live_ajax()&&h.pushstate){if(g.ajax_running||g.updating_picker)return;g.filter_cats?d.cur_url=c("#tribe-events-header").data("baseurl")+g.date+"/":d.default_permalinks?d.cur_url=w:d.cur_url=w+g.date+"/",g.popping=!1,f.pre_ajax(function(){p()})}}),n(!0),c(e).on("tribe_ev_resizeComplete",function(){n(!0)}),h.pushstate&&!h.map_view()){var A="action=tribe_calendar&eventDate="+c("#tribe-events-header").data("date");d.params.length&&(A=A+"&"+d.params),g.category&&(A=A+"&tribe_event_category="+g.category),history.replaceState({tribe_params:A},g.page_title,location.href),c(a).on("popstate",function(a){var b=a.originalEvent.state;b&&(g.do_string=!1,g.pushstate=!1,g.popping=!0,g.params=b.tribe_params,f.pre_ajax(function(){p()}),f.set_form(g.params))})}c("#tribe-events").on("click",".tribe-events-nav-previous, .tribe-events-nav-next",function(a){if(a.preventDefault(),!g.ajax_running){var b=c(this).find("a");g.date=b.data("month"),g.mdate=g.date+"-01","0"!==g.datepicker_format?f.update_picker(tribeDateFormat(g.mdate,z)):f.update_picker(g.date),g.filter_cats?d.cur_url=c("#tribe-events-header").data("baseurl"):d.cur_url=b.attr("href"),d.default_permalinks&&(d.cur_url=d.cur_url.split("?")[0]),g.popping=!1,f.pre_ajax(function(){p()})}}).on("click","td.tribe-events-thismonth a",function(a){a.stopPropagation()}).on("click",'[id*="tribe-events-daynum-"] a',function(a){if(q.is(".tribe-mobile")){a.preventDefault();var b=c(this).closest(".mobile-trigger");k(b)}}).on("click",".mobile-trigger",function(a){q.is(".tribe-mobile")&&(a.preventDefault(),a.stopPropagation(),k(c(this)))}),f.snap("#tribe-bar-form","body","#tribe-events-footer .tribe-events-nav-previous, #tribe-events-footer .tribe-events-nav-next"),c("form#tribe-bar-form").on("submit",function(a){o(a)}),c(e).on("tribe_ev_runAjax",function(){p()}),c(e).on("tribe_ev_updatingRecurrence",function(){g.date=c("#tribe-events-header").data("date"),g.filter_cats?d.cur_url=c("#tribe-events-header").data("baseurl")+g.date+"/":d.default_permalinks?d.cur_url=w:d.cur_url=w+g.date+"/",g.popping=!1})})}(window,document,jQuery,tribe_ev.data,tribe_ev.events,tribe_ev.fn,tribe_ev.state,tribe_ev.tests,tribe_js_config,tribe_debug);
1
+ !function(a,b,c,d,e,f,g,h,i,j){c(b).ready(function(){function j(a){var b=c('.tribe-mobile-day[data-day="'+a+'"]'),d=c('.tribe-events-calendar td[data-day="'+a+'"]'),e=d.find(".tribe-events-viewmore"),f=d.find(".hentry");f.length&&(f.each(function(){var a=c(this);if(a.tribe_has_attr("data-tribejson")){var d=a.data("tribejson");b.append(tribe_tmpl("tribe_tmpl_month_mobile",d))}}),e.length&&b.append(e.clone()))}function k(a){var b=a.data("tribejson");b.date=a.attr("data-day");var c=a.parents(".tribe-events-calendar"),d=c.next("#tribe-mobile-container"),e=d.find(".tribe-mobile-day"),f=c.find(".mobile-trigger"),g='[data-day="'+b.date+'"]',h=e.filter(g);b.has_events=a.hasClass("tribe-events-has-events"),f.removeClass("mobile-active").filter(g).addClass("mobile-active"),e.hide(),h.length?h.show():(d.append(tribe_tmpl("tribe_tmpl_month_mobile_day_header",b)),j(b.date))}function l(){var a=t.find(".tribe-events-present"),d=t.find(".mobile-trigger"),e=t.find(b.getElementById("tribe-events-content")).find(".tribe-events-calendar");if(c("#tribe-mobile-container").length||c('<div id="tribe-mobile-container" />').insertAfter(e),a.length&&a.is(".tribe-events-thismonth"))k(a);else{var f=d.filter(".tribe-events-thismonth").first();k(f)}}function m(){t.find(".tribe-events-calendar th").each(function(){var a=c(this),b=a.attr("data-day-abbr"),d=a.attr("title");q.is(".tribe-mobile")?a.text(b):a.text(d)})}function n(a){q.is(".tribe-mobile")?(m(),l()):a&&m()}function o(a){if("change_view"!=tribe_events_bar_action){if(a.preventDefault(),g.ajax_running)return;u.val().length?"0"!==g.datepicker_format?g.date=tribeDateFormat(u.bootstrapDatepicker("getDate"),"tribeMonthQuery"):g.date=u.val():v||(g.date=d.cur_date.slice(0,-3)),g.filter_cats?d.cur_url=c("#tribe-events-header").data("baseurl")+g.date+"/":d.default_permalinks?d.cur_url=w:d.cur_url=w+g.date+"/",g.popping=!1,f.pre_ajax(function(){p()})}}function p(){f.invalid_date(g.date)||(c(".tribe-events-calendar").tribe_spin(),g.pushcount=0,g.ajax_running=!0,g.popping||(g.params={action:"tribe_calendar",eventDate:g.date},g.url_params={},g.category&&(g.params.tribe_event_category=g.category,g.url_params.tribe_events_cat=g.category),d.default_permalinks&&(g.url_params.hasOwnProperty("post_type")||(g.url_params.post_type=i.events_post_type),g.url_params.hasOwnProperty("eventDisplay")||(g.url_params.eventDisplay=g.view)),c(e).trigger("tribe_ev_serializeBar"),g.params=c.param(g.params),g.url_params=c.param(g.url_params),c(e).trigger("tribe_ev_collectParams"),g.pushcount>0||g.filters||d.default_permalinks||g.category?(g.do_string=!0,g.pushstate=!1):(g.do_string=!1,g.pushstate=!0)),h.pushstate&&!g.filter_cats?(c(e).trigger("tribe_ev_ajaxStart").trigger("tribe_ev_monthView_AjaxStart"),c.post(TribeCalendar.ajaxurl,g.params,function(a){if(g.initial_load=!1,f.enable_inputs("#tribe_events_filters_form","input, select"),a.success){g.ajax_running=!1,d.ajax_response={total_count:"",view:a.view,max_pages:"",tribe_paged:"",timestamp:(new Date).getTime()};var h="";h=c.isFunction(c.fn.parseHTML)?c.parseHTML(a.html):a.html,c("#tribe-events-content").replaceWith(h),n(!0),g.page_title=c("#tribe-events-header").data("title"),b.title=g.page_title,g.do_string&&(d.cur_url=d.cur_url+"?"+g.url_params,history.pushState({tribe_date:g.date,tribe_params:g.params},g.page_title,d.cur_url)),g.pushstate&&history.pushState({tribe_date:g.date,tribe_params:g.params},g.page_title,d.cur_url),c(e).trigger("tribe_ev_ajaxSuccess").trigger("tribe_ev_monthView_ajaxSuccess")}})):g.url_params.length?a.location=d.cur_url+"?"+g.url_params:a.location=d.cur_url)}var q=c("body"),r=c('[class^="tribe-events-nav-"] a'),s=f.get_url_param("tribe-bar-date"),t=c("#tribe-events"),u=c("#tribe-bar-date"),v=!1,w="/";"undefined"!=typeof i.events_base?w=i.events_base:r.length&&(w=r.first().attr("href").slice(0,-8)),d.default_permalinks&&(w=w.split("?")[0]),c(".tribe-events-calendar").length&&c("#tribe-events-bar").length&&s&&s.length>7&&(c("#tribe-bar-date-day").val(s.slice(-3)),u.val(s.substring(0,7)));var x="yyyy-mm";if("0"!==g.datepicker_format){var y=parseInt(g.datepicker_format),z="m"+g.datepicker_format.toString();x=d.datepicker_formats.month[y],s&&(s.length<=7&&(s+="-01"),u.val(tribeDateFormat(s,z)))}if(d.datepicker_opts={format:x,minViewMode:"months",autoclose:!0},u.bootstrapDatepicker(d.datepicker_opts).on("changeDate",function(a){g.mdate=a.date;var b=a.date.getFullYear(),e=("0"+(a.date.getMonth()+1)).slice(-2);if(v=!0,g.date=b+"-"+e,h.no_bar()||h.live_ajax()&&h.pushstate){if(g.ajax_running||g.updating_picker)return;g.filter_cats?d.cur_url=c("#tribe-events-header").data("baseurl")+g.date+"/":d.default_permalinks?d.cur_url=w:d.cur_url=w+g.date+"/",g.popping=!1,f.pre_ajax(function(){p()})}}),n(!0),c(e).on("tribe_ev_resizeComplete",function(){n(!0)}),h.pushstate&&!h.map_view()){var A="action=tribe_calendar&eventDate="+c("#tribe-events-header").data("date");d.params.length&&(A=A+"&"+d.params),g.category&&(A=A+"&tribe_event_category="+g.category),history.replaceState({tribe_params:A},g.page_title,location.href),c(a).on("popstate",function(a){var b=a.originalEvent.state;b&&(g.do_string=!1,g.pushstate=!1,g.popping=!0,g.params=b.tribe_params,f.pre_ajax(function(){p()}),f.set_form(g.params))})}c("#tribe-events").on("click",".tribe-events-nav-previous, .tribe-events-nav-next",function(a){if(a.preventDefault(),!g.ajax_running){var b=c(this).find("a");g.date=b.data("month"),g.mdate=g.date+"-01","0"!==g.datepicker_format?f.update_picker(tribeDateFormat(g.mdate,z)):f.update_picker(g.date),g.filter_cats?d.cur_url=c("#tribe-events-header").data("baseurl"):d.cur_url=b.attr("href"),d.default_permalinks&&(d.cur_url=d.cur_url.split("?")[0]),g.popping=!1,f.pre_ajax(function(){p()})}}).on("click","td.tribe-events-thismonth a",function(a){a.stopPropagation()}).on("click",'[id*="tribe-events-daynum-"] a',function(a){if(q.is(".tribe-mobile")){a.preventDefault();var b=c(this).closest(".mobile-trigger");k(b)}}).on("click",".mobile-trigger",function(a){q.is(".tribe-mobile")&&(a.preventDefault(),a.stopPropagation(),k(c(this)))}),f.snap("#tribe-bar-form","body","#tribe-events-footer .tribe-events-nav-previous, #tribe-events-footer .tribe-events-nav-next"),c("form#tribe-bar-form").on("submit",function(a){o(a)}),c(e).on("tribe_ev_runAjax",function(){p()}),c(e).on("tribe_ev_updatingRecurrence",function(){g.date=c("#tribe-events-header").data("date"),g.filter_cats?d.cur_url=c("#tribe-events-header").data("baseurl")+g.date+"/":d.default_permalinks?d.cur_url=w:d.cur_url=w+g.date+"/",g.popping=!1})})}(window,document,jQuery,tribe_ev.data,tribe_ev.events,tribe_ev.fn,tribe_ev.state,tribe_ev.tests,tribe_js_config,tribe_debug);
src/resources/js/tribe-events-bar.js CHANGED
@@ -165,10 +165,10 @@ var tribe_events_bar_action;
165
'data-tribe-bar-order': i,
166
'data-view' : displaying
167
} ).html( [
168
- ' <a href="#">',
169
- ' <span class="tribe-icon-' + displaying + '">' + $view.text() + '</span>',
170
- '</a>'].join( "" )
171
- ).appendTo( '.tribe-bar-views-list' );
172
173
} );
174
165
'data-tribe-bar-order': i,
166
'data-view' : displaying
167
} ).html( [
168
+ ' <a href="#">',
169
+ ' <span class="tribe-icon-' + displaying + '">' + $view.text() + '</span>',
170
+ '</a>'].join( "" )
171
+ ).appendTo( '.tribe-bar-views-list' );
172
173
} );
174
src/resources/js/tribe-events.js CHANGED
@@ -37,104 +37,104 @@ var tribe_debug = true;
37
38
// @ifdef DEBUG
39
40
- /*!
41
- * JavaScript Debug - v0.4 - 6/22/2010
42
- * http://benalman.com/projects/javascript-debug-console-log/
43
- *
44
- * Copyright (c) 2010 "Cowboy" Ben Alman
45
- * Dual licensed under the MIT and GPL licenses.
46
- * http://benalman.com/about/license/
47
- *
48
- * With lots of help from Paul Irish!
49
- * http://paulirish.com/
50
- */
51
52
- window.debug = (function() {
53
- var window = this,
54
- aps = Array.prototype.slice,
55
- con = window.console,
56
- that = {},
57
- callback_func,
58
- callback_force,
59
- log_level = 9,
60
- log_methods = [ 'error', 'warn', 'info', 'debug', 'log' ],
61
- pass_methods = 'assert clear count dir dirxml exception group groupCollapsed groupEnd profile profileEnd table time timeEnd trace'.split( ' ' ),
62
- idx = pass_methods.length,
63
- logs = [];
64
-
65
- while ( --idx >= 0 ) {
66
- (function( method ) {
67
-
68
- that[ method ] = function() {
69
- log_level !== 0 && con && con[ method ]
70
- && con[ method ].apply( con, arguments );
71
- }
72
73
- })( pass_methods[idx] );
74
- }
75
76
- idx = log_methods.length;
77
- while ( --idx >= 0 ) {
78
- (function( idx, level ) {
79
80
- that[ level ] = function() {
81
- var args = aps.call( arguments ),
82
- log_arr = [ level ].concat( args );
83
84
- logs.push( log_arr );
85
- exec_callback( log_arr );
86
87
- if ( !con || !is_level( idx ) ) {
88
- return;
89
- }
90
91
- con.firebug ? con[ level ].apply( window, args )
92
- : con[ level ] ? con[ level ]( args )
93
- : con.log( args );
94
- };
95
96
- })( idx, log_methods[idx] );
97
- }
98
99
- function exec_callback( args ) {
100
- if ( callback_func && (callback_force || !con || !con.log) ) {
101
- callback_func.apply( window, args );
102
- }
103
}
104
105
- that.setLevel = function( level ) {
106
- log_level = typeof level === 'number' ? level : 9;
107
- };
108
109
- function is_level( level ) {
110
- return log_level > 0
111
- ? log_level > level
112
- : log_methods.length + log_level <= level;
113
- }
114
115
- that.setCallback = function() {
116
- var args = aps.call( arguments ),
117
- max = logs.length,
118
- i = max;
119
120
- callback_func = args.shift() || null;
121
- callback_force = typeof args[0] === 'boolean' ? args.shift() : false;
122
123
- i -= typeof args[0] === 'number' ? args.shift() : max;
124
125
- while ( i < max ) {
126
- exec_callback( logs[i++] );
127
- }
128
- };
129
130
- return that;
131
- })();
132
133
- if ( Object.prototype.hasOwnProperty.call( window, 'tribe_ev' ) ) {
134
- tribe_ev.diagnostics = {
135
- init: []
136
- };
137
- }
138
// @endif
139
140
/**
@@ -318,22 +318,22 @@ Date.prototype.format = function( mask, utc ) {
318
var name = id, string = /^[\w\-]+#x2F;.test( id ) ? me.get( id ) : (name = 'template(string)', id); // no warnings
319
var line = 1, body = (
320
"try { " +
321
- (me.variable ? "var " + me.variable + " = this.stash;" : "with (this.stash) { ") +
322
- "this.ret += '" +
323
- string.
324
- replace( /\[\[/g, '\x11' ).replace( /\]\]/g, '\x13' ). // if you want other tag, just edit this line
325
- replace( /'(?![^\x11\x13]+?\x13)/g, '\\x27' ).
326
- replace( /^\s*|\s*#x2F;g, '' ).
327
- replace( /\n/g,function() {
328
- return "';\nthis.line = " + (++line) + "; this.ret += '\\n"
329
- } ).
330
- replace( /\x11=raw(.+?)\x13/g, "' + ($1) + '" ).
331
- replace( /\x11=(.+?)\x13/g, "' + this.escapeHTML($1) + '" ).
332
- replace( /\x11(.+?)\x13/g, "'; $1; this.ret += '" ) +
333
- "'; " + (me.variable ? "" : "}") + "return this.ret;" +
334
- "} catch (e) { throw 'TemplateError: ' + e + ' (on " + name + "' + ' line ' + this.line + ')'; } " +
335
- "//@ sourceURL=" + name + "\n" // source map
336
- ).replace( /this\.ret \+= '';/g, '' );
337
var func = new Function( body );
338
var map = { '&': '&amp;', '<': '&lt;', '>': '&gt;', '\x22': '&#x22;', '\x27': '&#x27;' };
339
var escapeHTML = function( string ) {
37
38
// @ifdef DEBUG
39
40
+ /*!
41
+ * JavaScript Debug - v0.4 - 6/22/2010
42
+ * http://benalman.com/projects/javascript-debug-console-log/
43
+ *
44
+ * Copyright (c) 2010 "Cowboy" Ben Alman
45
+ * Dual licensed under the MIT and GPL licenses.
46
+ * http://benalman.com/about/license/
47
+ *
48
+ * With lots of help from Paul Irish!
49
+ * http://paulirish.com/
50
+ */
51
52
+ window.debug = (function() {
53
+ var window = this,
54
+ aps = Array.prototype.slice,
55
+ con = window.console,
56
+ that = {},
57
+ callback_func,
58
+ callback_force,
59
+ log_level = 9,
60
+ log_methods = [ 'error', 'warn', 'info', 'debug', 'log' ],
61
+ pass_methods = 'assert clear count dir dirxml exception group groupCollapsed groupEnd profile profileEnd table time timeEnd trace'.split( ' ' ),
62
+ idx = pass_methods.length,
63
+ logs = [];
64
+
65
+ while ( --idx >= 0 ) {
66
+ (function( method ) {
67
+
68
+ that[ method ] = function() {
69
+ log_level !== 0 && con && con[ method ]
70
+ && con[ method ].apply( con, arguments );
71
+ }
72
73
+ })( pass_methods[idx] );
74
+ }
75
76
+ idx = log_methods.length;
77
+ while ( --idx >= 0 ) {
78
+ (function( idx, level ) {
79
80
+ that[ level ] = function() {
81
+ var args = aps.call( arguments ),
82
+ log_arr = [ level ].concat( args );
83
84
+ logs.push( log_arr );
85
+ exec_callback( log_arr );
86
87
+ if ( !con || !is_level( idx ) ) {
88
+ return;
89
+ }
90
91
+ con.firebug ? con[ level ].apply( window, args )
92
+ : con[ level ] ? con[ level ]( args )
93
+ : con.log( args );
94
+ };
95
96
+ })( idx, log_methods[idx] );
97
+ }
98
99
+ function exec_callback( args ) {
100
+ if ( callback_func && (callback_force || !con || !con.log) ) {
101
+ callback_func.apply( window, args );
102
}
103
+ }
104
105
+ that.setLevel = function( level ) {
106
+ log_level = typeof level === 'number' ? level : 9;
107
+ };
108
109
+ function is_level( level ) {
110
+ return log_level > 0
111
+ ? log_level > level
112
+ : log_methods.length + log_level <= level;
113
+ }
114
115
+ that.setCallback = function() {
116
+ var args = aps.call( arguments ),
117
+ max = logs.length,
118
+ i = max;
119
120
+ callback_func = args.shift() || null;
121
+ callback_force = typeof args[0] === 'boolean' ? args.shift() : false;
122
123
+ i -= typeof args[0] === 'number' ? args.shift() : max;
124
125
+ while ( i < max ) {
126
+ exec_callback( logs[i++] );
127
+ }
128
+ };
129
130
+ return that;
131
+ })();
132
133
+ if ( Object.prototype.hasOwnProperty.call( window, 'tribe_ev' ) ) {
134
+ tribe_ev.diagnostics = {
135
+ init: []
136
+ };
137
+ }
138
// @endif
139
140
/**
318
var name = id, string = /^[\w\-]+#x2F;.test( id ) ? me.get( id ) : (name = 'template(string)', id); // no warnings
319
var line = 1, body = (
320
"try { " +
321
+ (me.variable ? "var " + me.variable + " = this.stash;" : "with (this.stash) { ") +
322
+ "this.ret += '" +
323
+ string.
324
+ replace( /\[\[/g, '\x11' ).replace( /\]\]/g, '\x13' ). // if you want other tag, just edit this line
325
+ replace( /'(?![^\x11\x13]+?\x13)/g, '\\x27' ).
326
+ replace( /^\s*|\s*#x2F;g, '' ).
327
+ replace( /\n/g,function() {
328
+ return "';\nthis.line = " + (++line) + "; this.ret += '\\n"
329
+ } ).
330
+ replace( /\x11=raw(.+?)\x13/g, "' + ($1) + '" ).
331
+ replace( /\x11=(.+?)\x13/g, "' + this.escapeHTML($1) + '" ).
332
+ replace( /\x11(.+?)\x13/g, "'; $1; this.ret += '" ) +
333
+ "'; " + (me.variable ? "" : "}") + "return this.ret;" +
334
+ "} catch (e) { throw 'TemplateError: ' + e + ' (on " + name + "' + ' line ' + this.line + ')'; } " +
335
+ "//@ sourceURL=" + name + "\n" // source map
336
+ ).replace( /this\.ret \+= '';/g, '' );
337
var func = new Function( body );
338
var map = { '&': '&amp;', '<': '&lt;', '>': '&gt;', '\x22': '&#x22;', '\x27': '&#x27;' };
339
var escapeHTML = function( string ) {
src/resources/js/tribe-settings.min.js CHANGED
@@ -1 +1 @@
1
- jQuery(document).ready(function(a){function b(){a(".google-embed-size input").attr("checked")?a(".google-embed-field").slideDown():a(".google-embed-field").slideUp()}a(".tribe-field-dropdown_chosen select").chosen(),b(),a('[name="eventsDefaultVenueID"]').change(function(){}),a(".google-embed-size input").change(function(){b()})});
1
+ jQuery(document).ready(function(a){function b(){a(".google-embed-size input").attr("checked")?a(".google-embed-field").slideDown():a(".google-embed-field").slideUp()}a(".tribe-field-dropdown_chosen select").chosen(),b(),a(".google-embed-size input").change(b)});
src/views/modules/meta/details.php CHANGED
@@ -18,7 +18,7 @@ $start_time = tribe_get_start_date( null, false, $time_format );
18
$start_ts = tribe_get_start_date( null, false, Tribe__Date_Utils::DBDATEFORMAT );
19
20
$end_datetime = tribe_get_end_date();
21
- $end_date = tribe_get_end_date( null, false );
22
$end_time = tribe_get_end_date( null, false, $time_format );
23
$end_ts = tribe_get_end_date( null, false, Tribe__Date_Utils::DBDATEFORMAT );
24
18
$start_ts = tribe_get_start_date( null, false, Tribe__Date_Utils::DBDATEFORMAT );
19
20
$end_datetime = tribe_get_end_date();
21
+ $end_date = tribe_get_display_end_date( null, false );
22
$end_time = tribe_get_end_date( null, false, $time_format );
23
$end_ts = tribe_get_end_date( null, false, Tribe__Date_Utils::DBDATEFORMAT );
24
src/views/single-event.php CHANGED
@@ -30,7 +30,7 @@ $event_id = get_the_ID();
30
<!-- Notices -->
31
<?php tribe_the_notices() ?>
32
33
- <?php the_title( '<h2 class="tribe-events-single-event-title">', '</h2>' ); ?>
34
35
<div class="tribe-events-schedule tribe-clearfix">
36
<?php echo tribe_events_event_schedule_details( $event_id, '<h2>', '</h2>' ); ?>
30
<!-- Notices -->
31
<?php tribe_the_notices() ?>
32
33
+ <?php the_title( '<h1 class="tribe-events-single-event-title"&