Advertisement
Guest User

Untitled

a guest
Sep 19th, 2019
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 13.16 KB | None | 0 0
  1. <?php
  2. /**
  3.  * Functions and template tags dedicated to Events.
  4.  *
  5.  * @since 4.9.7
  6.  */
  7.  
  8. use Tribe\Utils\Lazy_Collection;
  9. use Tribe\Utils\Lazy_String;
  10. use Tribe\Utils\Post_Thumbnail;
  11. use Tribe__Date_Utils as Dates;
  12. use Tribe__Events__Timezones as Timezones;
  13.  
  14. if ( ! function_exists( 'tribe_get_event' ) ) {
  15.     /**
  16.      * Fetches and returns a dedcorated post object representing an Event.
  17.      *
  18.      * @since 4.9.7
  19.      *
  20.      * @param null|int|WP_Post $event  The event ID or post object or `null` to use the global one.
  21.      * @param string|null      $output The required return type. One of `OBJECT`, `ARRAY_A`, or `ARRAY_N`, which
  22.      *                                 correspond to a WP_Post object, an associative array, or a numeric array,
  23.      *                                 respectively. Defaults to `OBJECT`.
  24.      * @param string           $filter Type of filter to apply. Accepts 'raw', a valid date string or
  25.      *                                 object to localize the event in a specific time-frame.
  26.      *
  27.      * @return array|mixed|void|WP_Post|null {
  28.      *                              The Event post object or array, `null` if not found.
  29.      *
  30.      *                              @type string $start_date The event start date, in `Y-m-d H:i:s` format.
  31.      *                              @type string $start_date_utc The event UTC start date, in `Y-m-d H:i:s` format.
  32.      *                              @type string $end_date The event end date, in `Y-m-d H:i:s` format.
  33.      *                              @type string $end_date_utc The event UTC end date, in `Y-m-d H:i:s` format.
  34.      *                              @type array $dates An array containing the event.start, end and UTC date objects. {
  35.      *                                              @type DateTimeImmutable $start The event start date object.
  36.      *                                              @type DateTimeImmutable $start_utc The event UTC start date object.
  37.      *                                              @type DateTimeImmutable $end The event end date object.
  38.      *                                              @type DateTimeImmutable $end_utc The event UTC end date object.
  39.      *                                          }
  40.      *                              @type string $timezone The event timezone string.
  41.      *                              @type int $duration The event duration in seconds.
  42.      *                              @type false|int $multiday Whether the event is multi-day or not and its day.
  43.      *                                                        duration if it is.
  44.      *                              @type bool $all_day Whether the event is an all-day one or not.
  45.      *                              @type null|bool $starts_this_week Whether the event starts on the week of the date
  46.      *                                                                specified in the `$filter` argument or not, `null`
  47.      *                                                                if no date is specified in the filter.
  48.      *                              @type null|bool $ends_this_week Whether the event ends on the week of the date
  49.      *                                                              specified in the `$filter` argument or not, `null`
  50.      *                                                              if no date is specified in the filter.
  51.      *                              @type null|bool $happens_this_week Whether the event happens on the week of the date
  52.      *                                                              specified in the `$filter` argument or not, `null`
  53.      *                                                              if no date is specified in the filter.
  54.      *                              @type null|int $this_week_duration The days duration of the event on the week
  55.      *                                                                 specified in the `$filter` argument, `null`
  56.      *                                                                 if no date is specified in the filter.
  57.      *                              @type bool $featured Whether the event is a featured one or not.
  58.      *                              @type string $cost The event formatted cost string, as returned by the `tribe_get_cost`
  59.      *                                                 `tribe_get_cost` function.
  60.      *                              @type Lazy_Collection $organizers A collection of Organizers, lazily fetched and
  61.      *                                                                eventually resolved to an array.
  62.      *                              @type Lazy_Collection $venues A collection of Venues, lazily fetched and
  63.      *                                                            eventually resolved to an array.
  64.      *                              @type Post_Thumbnail $thumbnail The post thumbnail information.
  65.      *                              @type Lazy_String $schedule_details The event schedule details, as produced by the
  66.      *                                                                  `tribe_events_event_schedule_details` function.
  67.      *                          }
  68.      */
  69.     function tribe_get_event( $event = null, $output = OBJECT, $filter = 'raw' ) {
  70.         /**
  71.          * Filters the event result before any logic applies.
  72.          *
  73.          * Returning a non `null` value here will short-circuit the function and return the value.
  74.          * Note: this value will not be cached and the caching of this value is a duty left to the filtering function.
  75.          *
  76.          * @since 4.9.7
  77.          *
  78.          * @param mixed       $return      The event object to return.
  79.          * @param mixed       $event       The event object to fetch.
  80.          * @param string|null $output      The required return type. One of OBJECT, ARRAY_A, or ARRAY_N, which
  81.          *                                 correspond to a `WP_Post` object, an associative array, or a numeric array,
  82.          *                                 respectively. Defaults to `OBJECT`.
  83.          * @param string      $filter      Type of filter to apply. Accepts 'raw', a valid date string or
  84.          *                                 object to localize the event in a specific time-frame.
  85.          */
  86.         $return = apply_filters( 'tribe_get_event_before', null, $event, $output, $filter );
  87.  
  88.         if ( null !== $return ) {
  89.             return $return;
  90.         }
  91.  
  92.         $post = get_post( $event );
  93.  
  94.         if ( ! $post instanceof WP_Post ) {
  95.             return null;
  96.         }
  97.  
  98.         // Cache by post ID and filter.
  99.         $cache_key = 'events_' . $post->ID . '_' . $filter;
  100.         $cache     = new Tribe__Cache();
  101.         $cached    = $cache->get( $cache_key, Tribe__Cache_Listener::TRIGGER_SAVE_POST );
  102.  
  103.         // Define a function to cache this event when, and if, one of the lazy properties is loaded.
  104.         $cache_this = static function () use ( $cache, $cache_key, $post ) {
  105.             /*
  106.              * Cache without expiration, but only until a post of the types managed by The Events Calendar is
  107.              * updated or created.
  108.              */
  109.             $cache->set( $cache_key, $post, 0, Tribe__Cache_Listener::TRIGGER_SAVE_POST );
  110.         };
  111.  
  112.         if ( false !== $cached ) {
  113.             switch ( $output ) {
  114.                 case ARRAY_A:
  115.                     return (array) $cached;
  116.                 case ARRAY_N:
  117.                     return array_values( (array) $cached );
  118.                 case OBJECT:
  119.                 default;
  120.                     return $cached;
  121.             }
  122.         }
  123.  
  124.         $post_id         = $post->ID;
  125.         $start_date      = get_post_meta( $post_id, '_EventStartDate', true );
  126.         $start_date_utc  = get_post_meta( $post_id, '_EventStartDateUTC', true );
  127.         $end_date        = get_post_meta( $post_id, '_EventEndDate', true );
  128.         $end_date_utc    = get_post_meta( $post_id, '_EventEndDateUTC', true );
  129.         $duration        = (int) get_post_meta( $post_id, '_EventDuration', true );
  130.         $timezone_string = Timezones::get_event_timezone_string( $post_id );
  131.         $all_day         = tribe_is_truthy( get_post_meta( $post_id, '_EventAllDay', true ) );
  132.  
  133.         // An event is multi-day if its end date is after the end-of-day cutoff of the start date.
  134.         $end_of_day        = tribe_end_of_day( $start_date );
  135.         $timezone          = Timezones::build_timezone_object( $timezone_string );
  136.         $utc_timezone = new DateTimezone('UTC');
  137.         $start_date_object = new DateTimeImmutable( $start_date, $timezone );
  138.         $end_date_object = new DateTimeImmutable( $end_date, $timezone );
  139.         $start_date_utc_object = new DateTimeImmutable( $start_date_utc, $utc_timezone );
  140.         $end_date_utc_object = new DateTimeImmutable( $end_date_utc, $utc_timezone );
  141.         $end_of_day_object = new DateTimeImmutable( $end_of_day, $timezone );
  142.         $is_multiday       = $end_of_day_object < $end_date_object;
  143.         $multiday          = false;
  144.         // Without a context these values will not make sense; we'll set them if the `$filter` argument is a date.
  145.         $starts_this_week   = null;
  146.         $ends_this_week     = null;
  147.         $happens_this_week  = null;
  148.         $this_week_duration = null;
  149.         if ( Dates::is_valid_date( $filter ) ) {
  150.             $week_start = Dates::build_date_object( $filter, $timezone );
  151.             // Sunday is 0.
  152.             $week_start_day = (int) get_option( 'start_of_week' );
  153.             $offset         = (int) $week_start->format( 'N' ) >= $week_start_day
  154.                 ? $week_start_day
  155.                 : $week_start->format( 'N' ) - $week_start_day;
  156.  
  157.             $week_start->setISODate( (int) $week_start->format( 'o' ), (int) $week_start->format( 'W' ), $offset );
  158.             $week_end = clone $week_start;
  159.             // 7 days later the week ends.
  160.             $week_end->add( new DateInterval( 'P7D' ) );
  161.             // Inclusive in respect to the start, exclusive to the end.
  162.             $starts_this_week   = $week_start <= $start_date_object && $start_date_object < $week_end;
  163.             $ends_this_week     = $week_start <= $end_date_object && $end_date_object < $week_end;
  164.             $happens_this_week = $week_start <= $end_date_object && $start_date_object <= $week_end;
  165.             if ( $happens_this_week ) {
  166.                 $this_week_duration = 1;
  167.                 if ( $is_multiday ) {
  168.                     /*
  169.                      * We add one second during this calculation to cope with all-day events starting on 12:00 AM.
  170.                      * Due to how DateTime diff works diffing two following midnights would yield a diff of 2 days.
  171.                      */
  172.                     $one_second = new \DateInterval( 'PT1S' );
  173.  
  174.                     $this_week_duration = min(
  175.                         7,
  176.                         $week_end->diff( $start_date_object->add( $one_second ) )->days + 1,
  177.                         $end_date_object->diff( $week_start )->days + 1,
  178.                         $end_date_object->diff( $start_date_object->add( $one_second ) )->days + 1
  179.                     );
  180.                 }
  181.             }
  182.         }
  183.         // Multi-day events will span at least two days: the day they start on and the following one.
  184.         if ( $is_multiday ) {
  185.             /*
  186.              * Count the number of cut-offs happening before the end date and add 1.
  187.              * Do not add 1 for all-day events as they span cut-off to cut-off.
  188.              */
  189.             $multiday = $all_day ? 0 : 1;
  190.             $one_day  = new DateInterval( 'P1D' );
  191.             // The end date should be inclusive, since it's not in the DatePeriod we work-around it adding a second.
  192.             $period = new DatePeriod( $end_of_day_object, $one_day, $end_date_object );
  193.             foreach ( $period as $date ) {
  194.                 ++ $multiday;
  195.             };
  196.         }
  197.         $featured = tribe_is_truthy( get_post_meta( $post_id, Tribe__Events__Featured_Events::FEATURED_EVENT_KEY, true ) );
  198.  
  199.         $organizer_fetch = Tribe__Events__Organizer::get_fetch_callback( $post_id );
  200.         $venue_fetch     = Tribe__Events__Venue::get_fetch_callback( $post_id );
  201.  
  202.         $properties = [
  203.             'start_date'         => $start_date,
  204.             'start_date_utc'     => $start_date_utc,
  205.             'end_date'           => $end_date,
  206.             'end_date_utc'       => $end_date_utc,
  207.             'dates'              => (object) [
  208.                 'start'     => $start_date_object,
  209.                 'start_utc' => $start_date_utc_object,
  210.                 'end'       => $end_date_object,
  211.                 'end_utc'   => $end_date_utc_object,
  212.             ],
  213.             'timezone'           => $timezone_string,
  214.             'duration'           => $duration,
  215.             'multiday'           => $multiday,
  216.             'all_day'            => $all_day,
  217.             'starts_this_week'   => $starts_this_week,
  218.             'ends_this_week'     => $ends_this_week,
  219.             'this_week_duration' => $this_week_duration,
  220.             'happens_this_week'  => $happens_this_week,
  221.             'featured'           => $featured,
  222.             'cost'               => tribe_get_cost( $post_id ),
  223.             'organizers'         => ( new Lazy_Collection( $organizer_fetch ) )->on_resolve( $cache_this ),
  224.             'venues'             => ( new Lazy_Collection( $venue_fetch ) )->on_resolve( $cache_this ),
  225.             'thumbnail'          => ( new Post_Thumbnail( $post_id ) )->on_resolve( $cache_this ),
  226.             'permalink'          => get_permalink( $post_id ),
  227.             'schedule_details'   => ( new Lazy_String(
  228.                 static function () use ( $post_id ) {
  229.                     return tribe_events_event_schedule_details( $post_id );
  230.                 },
  231.                 false
  232.             ) )->on_resolve( $cache_this )
  233.         ];
  234.  
  235.         foreach ( $properties as $key => $value ) {
  236.             $post->{$key} = $value;
  237.         }
  238.  
  239.         /**
  240.          * Filters the event post object before caching it and returning it.
  241.          *
  242.          * Note: this value will be cached; as such this filter might not run on each request.
  243.          * If you need to filter the output value on each call of this function then use the `tribe_get_event_before`
  244.          * filter.
  245.          *
  246.          * @since 4.9.7
  247.          *
  248.          * @param WP_Post $post   The event post object, decorated with a set of custom properties.
  249.          * @param string  $output The output format to use.
  250.          * @param string  $filter The filter, or context of the fetch.
  251.          */
  252.         $post = apply_filters( 'tribe_get_event', $post, $output, $filter );
  253.  
  254.         if ( OBJECT !== $output ) {
  255.             $post = ARRAY_A === $output ? (array) $post : array_values( (array) $post );
  256.         }
  257.  
  258.         return $post;
  259.     }
  260. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement