The Events Calendar - Version 3.12.2

Version Description

Download this release

Release Info

Developer zbtirrell
Plugin Icon The Events Calendar
Version 3.12.2
Comparing to
See all releases

Code changes from version 3.12.1 to 3.12.2

readme.txt CHANGED
@@ -5,7 +5,7 @@ Tags: events, calendar, event, venue, organizer, dates, date, google maps, confe
5
  Donate link: http://m.tri.be/29
6
  Requires at least: 3.9
7
  Tested up to: 4.3
8
- Stable tag: 3.12.1
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
@@ -315,6 +315,11 @@ At no point during the 3.0 lifecycle will the major version change. But you can
315
 
316
  == Changelog ==
317
 
 
 
 
 
 
318
 
319
  = [3.12.1] 2015-09-09 =
320
  * Tweak - text domains updated for consistency with the plugin slug
5
  Donate link: http://m.tri.be/29
6
  Requires at least: 3.9
7
  Tested up to: 4.3
8
+ Stable tag: 3.12.2
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
315
 
316
  == Changelog ==
317
 
318
+ = [3.12.2] 2015-09-22 =
319
+ * Fix - restore expected functionality for the Hide from Event Listings option
320
+ * Fix - ensure the correct day is highlighted in month view, regardless of the site's timezone (our thanks to @james for making us aware of this)
321
+ * Fix - improve compatibility with the standard WordPress import tool (our thanks to @joelgoodman for highlighting this)
322
+ * Fix - ensure our URLs are compatible with pathinfo-style permalink structures (thanks to @mill.joes and others for make us aware of this)
323
 
324
  = [3.12.1] 2015-09-09 =
325
  * Tweak - text domains updated for consistency with the plugin slug
src/Tribe/Main.php CHANGED
@@ -24,7 +24,7 @@ if ( ! class_exists( 'Tribe__Events__Main' ) ) {
24
  const VENUE_POST_TYPE = 'tribe_venue';
25
  const ORGANIZER_POST_TYPE = 'tribe_organizer';
26
 
27
- const VERSION = '3.12.1';
28
  const MIN_ADDON_VERSION = '3.12';
29
  const FEED_URL = 'https://theeventscalendar.com/feed/';
30
  const INFO_API_URL = 'http://wpapi.org/api/plugin/the-events-calendar.php';
@@ -2432,7 +2432,7 @@ if ( ! class_exists( 'Tribe__Events__Main' ) ) {
2432
 
2433
  // account for semi-pretty permalinks
2434
  if ( false !== strpos( get_option( 'permalink_structure' ), 'index.php' ) ) {
2435
- $event_url = home_url( '/index.php' );
2436
  } else {
2437
  $event_url = home_url( '/' );
2438
  }
@@ -4379,17 +4379,34 @@ if ( ! class_exists( 'Tribe__Events__Main' ) ) {
4379
  }
4380
 
4381
  /**
4382
- * If recurring events are imported using the WP importer, WP will flag
4383
- * each instance as a duplicate. Here we alter the title so that
4384
- * WP sees them as distinct posts.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4385
  *
4386
  * @param array $post
4387
  *
4388
  * @return array
4389
- * @see Tribe__Events__Main::filter_wp_import_data_after()
4390
  */
4391
  public function filter_wp_import_data_before( $post ) {
4392
- if ( $post['post_type'] == self::POSTTYPE && ! empty( $post['post_parent'] ) ) {
4393
  $start_date = '';
4394
  if ( isset( $post['postmeta'] ) && is_array( $post['postmeta'] ) ) {
4395
  foreach ( $post['postmeta'] as $meta ) {
24
  const VENUE_POST_TYPE = 'tribe_venue';
25
  const ORGANIZER_POST_TYPE = 'tribe_organizer';
26
 
27
+ const VERSION = '3.12.2';
28
  const MIN_ADDON_VERSION = '3.12';
29
  const FEED_URL = 'https://theeventscalendar.com/feed/';
30
  const INFO_API_URL = 'http://wpapi.org/api/plugin/the-events-calendar.php';
2432
 
2433
  // account for semi-pretty permalinks
2434
  if ( false !== strpos( get_option( 'permalink_structure' ), 'index.php' ) ) {
2435
+ $event_url = home_url( '/index.php/' );
2436
  } else {
2437
  $event_url = home_url( '/' );
2438
  }
4379
  }
4380
 
4381
  /**
4382
+ * Facilitates the import of events in WXR format (ie, via the core WP importer).
4383
+ *
4384
+ * When WP imports posts it avoids duplication by comparing the post name, date and
4385
+ * type of each. Once a post has been imported, if another post matching the above
4386
+ * criteria is found it is discarded.
4387
+ *
4388
+ * In the case of recurring events this would cause all but the first in a series
4389
+ * to be discarded and so we workaround the problem by altering the title (and
4390
+ * restoring it afterwards - during "wp_import_post_data_processed").
4391
+ *
4392
+ * We apply this to *all* events being imported because we also need to cater for
4393
+ * a scenario where events that were originally created as part of a set of
4394
+ * recurring events may later have been broken out of the chain into standalone
4395
+ * events (otherwise we could restrict this operation to only those events with
4396
+ * a post parent).
4397
+ *
4398
+ * We're retaining this logic in core (rather than move it to PRO) since it's
4399
+ * posible for data from a site running PRO to be imported into a site running only
4400
+ * core.
4401
+ *
4402
+ * @see Tribe__Events__Main::filter_wp_import_data_after()
4403
  *
4404
  * @param array $post
4405
  *
4406
  * @return array
 
4407
  */
4408
  public function filter_wp_import_data_before( $post ) {
4409
+ if ( $post['post_type'] === self::POSTTYPE ) {
4410
  $start_date = '';
4411
  if ( isset( $post['postmeta'] ) && is_array( $post['postmeta'] ) ) {
4412
  foreach ( $post['postmeta'] as $meta ) {
src/Tribe/Rewrite.php CHANGED
@@ -213,12 +213,19 @@ if ( ! class_exists( 'Tribe__Events__Rewrite' ) ) {
213
  /**
214
  * If you want to modify the base slugs before the i18n happens filter this use this filter
215
  * All the bases need to have a key and a value, they might be the same or not.
 
 
 
 
 
 
 
216
  */
217
  $bases = apply_filters( 'tribe_events_rewrite_base_slugs', array(
218
- 'month' => (array) Tribe__Events__Main::instance()->monthSlug,
219
- 'list' => (array) Tribe__Events__Main::instance()->listSlug,
220
- 'today' => (array) Tribe__Events__Main::instance()->todaySlug,
221
- 'day' => (array) Tribe__Events__Main::instance()->daySlug,
222
  'tag' => (array) 'tag',
223
  'tax' => (array) 'category',
224
  'page' => (array) 'page',
@@ -227,6 +234,9 @@ if ( ! class_exists( 'Tribe__Events__Rewrite' ) ) {
227
  'archive' => (array) Tribe__Events__Main::instance()->getOption( 'eventsSlug', 'events' ),
228
  ) );
229
 
 
 
 
230
  // By default we always have `en_US` to avoid 404 with older URLs
231
  $languages = apply_filters( 'tribe_events_rewrite_i18n_languages', array_unique( array( 'en_US', get_locale() ) ) );
232
 
213
  /**
214
  * If you want to modify the base slugs before the i18n happens filter this use this filter
215
  * All the bases need to have a key and a value, they might be the same or not.
216
+ *
217
+ * Each value is an array of possible slugs: to improve robustness the "original" English
218
+ * slug is supported in addition to translated forms for month, list, today and day: this
219
+ * way if the forms are altered (whether through i18n or other custom mods) *after* links
220
+ * have already been promulgated, there will be less chance of visitors hitting 404s.
221
+ *
222
+ * @var array $bases
223
  */
224
  $bases = apply_filters( 'tribe_events_rewrite_base_slugs', array(
225
+ 'month' => array( 'month', Tribe__Events__Main::instance()->monthSlug ),
226
+ 'list' => array( 'list', Tribe__Events__Main::instance()->listSlug ),
227
+ 'today' => array( 'today', Tribe__Events__Main::instance()->todaySlug ),
228
+ 'day' => array( 'day', Tribe__Events__Main::instance()->daySlug ),
229
  'tag' => (array) 'tag',
230
  'tax' => (array) 'category',
231
  'page' => (array) 'page',
234
  'archive' => (array) Tribe__Events__Main::instance()->getOption( 'eventsSlug', 'events' ),
235
  ) );
236
 
237
+ // Remove duplicates (no need to have 'month' twice if no translations are in effect, etc)
238
+ $bases = array_map( 'array_unique', $bases );
239
+
240
  // By default we always have `en_US` to avoid 404 with older URLs
241
  $languages = apply_filters( 'tribe_events_rewrite_i18n_languages', array_unique( array( 'en_US', get_locale() ) ) );
242
 
src/Tribe/Template/Month.php CHANGED
@@ -393,6 +393,7 @@ if ( ! class_exists( 'Tribe__Events__Template__Month' ) ) {
393
  }
394
 
395
  $post_stati = implode( "','", $post_stati );
 
396
 
397
  $events_request = $wpdb->prepare(
398
  "SELECT tribe_event_start.post_id as ID,
@@ -401,7 +402,7 @@ if ( ! class_exists( 'Tribe__Events__Template__Month' ) ) {
401
  FROM $wpdb->postmeta AS tribe_event_start
402
  LEFT JOIN $wpdb->posts ON tribe_event_start.post_id = $wpdb->posts.ID
403
  LEFT JOIN $wpdb->postmeta as tribe_event_end_date ON ( tribe_event_start.post_id = tribe_event_end_date.post_id AND tribe_event_end_date.meta_key = '_EventEndDate' )
404
- WHERE tribe_event_start.meta_key = '_EventStartDate'
405
  AND ( (tribe_event_start.meta_value >= '%1\$s' AND tribe_event_start.meta_value <= '%2\$s')
406
  OR (tribe_event_start.meta_value <= '%1\$s' AND tribe_event_end_date.meta_value >= '%1\$s')
407
  OR ( tribe_event_start.meta_value >= '%1\$s' AND tribe_event_start.meta_value <= '%2\$s')
@@ -424,6 +425,30 @@ if ( ! class_exists( 'Tribe__Events__Template__Month' ) ) {
424
  $cache->set( $cache_key, $this->events_in_month, 0, 'save_post' );
425
  }
426
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
427
  /**
428
  * Retrieves beginning/end times for a given date
429
  *
@@ -849,7 +874,7 @@ if ( ! class_exists( 'Tribe__Events__Template__Month' ) ) {
849
 
850
  $calendar_day = self::get_current_day();
851
  $calendar_day_timestamp = strtotime( $calendar_day['date'] );
852
- $today = strtotime( 'today' );
853
 
854
  // Start by determining which month we're looking at
855
  if ( $calendar_day['month'] == self::CURRENT_MONTH ) {
393
  }
394
 
395
  $post_stati = implode( "','", $post_stati );
396
+ $ignore_hidden_events_AND = $this->hidden_events_fragment();
397
 
398
  $events_request = $wpdb->prepare(
399
  "SELECT tribe_event_start.post_id as ID,
402
  FROM $wpdb->postmeta AS tribe_event_start
403
  LEFT JOIN $wpdb->posts ON tribe_event_start.post_id = $wpdb->posts.ID
404
  LEFT JOIN $wpdb->postmeta as tribe_event_end_date ON ( tribe_event_start.post_id = tribe_event_end_date.post_id AND tribe_event_end_date.meta_key = '_EventEndDate' )
405
+ WHERE $ignore_hidden_events_AND tribe_event_start.meta_key = '_EventStartDate'
406
  AND ( (tribe_event_start.meta_value >= '%1\$s' AND tribe_event_start.meta_value <= '%2\$s')
407
  OR (tribe_event_start.meta_value <= '%1\$s' AND tribe_event_end_date.meta_value >= '%1\$s')
408
  OR ( tribe_event_start.meta_value >= '%1\$s' AND tribe_event_start.meta_value <= '%2\$s')
425
  $cache->set( $cache_key, $this->events_in_month, 0, 'save_post' );
426
  }
427
 
428
+ /**
429
+ * Returns a posts-not-in SQL fragment for use in a WHERE clause or else an empty
430
+ * string if it is unneeded.
431
+ *
432
+ * @return string
433
+ */
434
+ protected function hidden_events_fragment() {
435
+ global $wpdb;
436
+
437
+ // Despite the method name, this obtains a list of post IDs to be hidden from *all* event listings
438
+ $ignore_events = Tribe__Events__Query::getHideFromUpcomingEvents();
439
+
440
+ // If it is empty we don't need to do anything further
441
+ if ( empty( $ignore_events ) ) {
442
+ return '';
443
+ }
444
+
445
+ // Let's ensure they are all absolute integers then collapse into a string
446
+ $ignore_events = implode( ',', array_map( 'absint', $ignore_events ) );
447
+
448
+ // Terminate with AND so it can easily be combined with the rest of the WHERE clause
449
+ return " $wpdb->posts.ID NOT IN ( $ignore_events ) AND ";
450
+ }
451
+
452
  /**
453
  * Retrieves beginning/end times for a given date
454
  *
874
 
875
  $calendar_day = self::get_current_day();
876
  $calendar_day_timestamp = strtotime( $calendar_day['date'] );
877
+ $today = strtotime( current_time( 'Y-m-d' ) );
878
 
879
  // Start by determining which month we're looking at
880
  if ( $calendar_day['month'] == self::CURRENT_MONTH ) {
src/Tribe/View_Helpers.php CHANGED
@@ -422,7 +422,6 @@ if ( ! class_exists( 'Tribe__Events__View_Helpers' ) ) {
422
  * @return string a set of HTML options with minutes (current minute selected)
423
  */
424
  public static function getMinuteOptions( $date = '', $isStart = false ) {
425
- $minutes = self::minutes();
426
  $options = '';
427
 
428
  if ( empty( $date ) ) {
@@ -432,6 +431,7 @@ if ( ! class_exists( 'Tribe__Events__View_Helpers' ) ) {
432
  }
433
 
434
  $minute = apply_filters( 'tribe_get_minute_options', $minute, $date, $isStart );
 
435
 
436
  foreach ( $minutes as $minuteText ) {
437
  if ( $minute == $minuteText ) {
@@ -501,17 +501,36 @@ if ( ! class_exists( 'Tribe__Events__View_Helpers' ) ) {
501
  /**
502
  * Helper method to return an array of 00-59 for minutes
503
  *
 
 
504
  * @return array The minutes array.
505
  */
506
- private static function minutes() {
507
  $minutes = array();
 
 
 
 
 
 
 
 
508
  /**
509
  * Filters the amount of minutes to increment the minutes drop-down by
510
  *
511
  * @param int Increment amount (defaults to 5)
512
  */
513
- $increment = apply_filters( 'tribe_minutes_increment', 5 );
 
 
 
 
514
  for ( $minute = 0; $minute < 60; $minute += $increment ) {
 
 
 
 
 
515
  if ( $minute < 10 ) {
516
  $minute = '0' . $minute;
517
  }
422
  * @return string a set of HTML options with minutes (current minute selected)
423
  */
424
  public static function getMinuteOptions( $date = '', $isStart = false ) {
 
425
  $options = '';
426
 
427
  if ( empty( $date ) ) {
431
  }
432
 
433
  $minute = apply_filters( 'tribe_get_minute_options', $minute, $date, $isStart );
434
+ $minutes = self::minutes( $minute );
435
 
436
  foreach ( $minutes as $minuteText ) {
437
  if ( $minute == $minuteText ) {
501
  /**
502
  * Helper method to return an array of 00-59 for minutes
503
  *
504
+ * @param int $exact_minute optionally specify an exact minute to be included (outwith the default intervals)
505
+ *
506
  * @return array The minutes array.
507
  */
508
+ private static function minutes( $exact_minute = 0 ) {
509
  $minutes = array();
510
+
511
+ // The exact minute should be an absint between 0 and 59
512
+ $exact_minute = absint( $exact_minute );
513
+
514
+ if ( $exact_minute < 0 || $exact_minute > 59 ) {
515
+ $exact_minute = 0;
516
+ }
517
+
518
  /**
519
  * Filters the amount of minutes to increment the minutes drop-down by
520
  *
521
  * @param int Increment amount (defaults to 5)
522
  */
523
+ $default_increment = apply_filters( 'tribe_minutes_increment', 5 );
524
+
525
+ // Unless an exact minute has been specified we can minimize the amount of looping we do
526
+ $increment = ( 0 === $exact_minute ) ? $default_increment : 1;
527
+
528
  for ( $minute = 0; $minute < 60; $minute += $increment ) {
529
+ // Skip if this $minute doesn't meet the increment pattern and isn't an additional exact minute
530
+ if ( 0 !== $minute % $default_increment && $exact_minute !== $minute ) {
531
+ continue;
532
+ }
533
+
534
  if ( $minute < 10 ) {
535
  $minute = '0' . $minute;
536
  }
the-events-calendar.php CHANGED
@@ -2,7 +2,7 @@
2
  /*
3
  Plugin Name: The Events Calendar
4
  Description: The Events Calendar is a carefully crafted, extensible plugin that lets you easily share your events. Beautiful. Solid. Awesome.
5
- Version: 3.12.1
6
  Author: Modern Tribe, Inc.
7
  Author URI: http://m.tri.be/1x
8
  Text Domain: the-events-calendar
2
  /*
3
  Plugin Name: The Events Calendar
4
  Description: The Events Calendar is a carefully crafted, extensible plugin that lets you easily share your events. Beautiful. Solid. Awesome.
5
+ Version: 3.12.2
6
  Author: Modern Tribe, Inc.
7
  Author URI: http://m.tri.be/1x
8
  Text Domain: the-events-calendar