Create New Item
Item Type
File
Folder
Item Name
Search file in folder and subfolders...
Are you sure want to rename?
File Manager
/
wp-content
/
plugins
/
the-events-calendar
/
src
/
Tribe
/
Views
/
V2
/
Views
:
Day_View.php
Advanced Search
Upload
New Item
Settings
Back
Back Up
Advanced Editor
Save
<?php /** * The Day View. * * @package Tribe\Events\Views\V2\Views * @since 4.9.2 */ namespace Tribe\Events\Views\V2\Views; use Tribe\Events\Views\V2\Messages; use Tribe\Events\Views\V2\Url; use Tribe\Events\Views\V2\View; use Tribe\Events\Views\V2\Views\Traits\With_Fast_Forward_Link; use Tribe__Date_Utils as Dates; use Tribe__Utils__Array as Arr; use Tribe__Context; use Tribe\Events\Views\V2\Views\Traits\With_Noindex; use DateTime; class Day_View extends View { use With_Fast_Forward_Link; use With_Noindex; /** * Slug for this view * * @since 4.9.4 * @deprecated 6.0.7 * * @var string */ protected $slug = 'day'; /** * Statically accessible slug for this view. * * @since 6.0.7 * * @var string */ protected static $view_slug = 'day'; /** * Cached dates for the prev/next links. * * @since 5.16.1 * * @var array */ protected array $memoized_dates = []; /** * Visibility for this view. * * @since 4.9.4 * @since 4.9.11 Made the property static. * * @var bool */ protected static $publicly_visible = true; /** * Default untranslated value for the label of this view. * * @since 6.0.4 * * @var string */ protected static $label = 'Day'; /** * @inheritDoc */ public static function get_view_label(): string { static::$label = _x( 'Day', 'The text label for the Day View.', 'the-events-calendar' ); return static::filter_view_label( static::$label ); } /** * Get the date of the event immediately previous to the current view date. * * @since 5.16.1 * * @param DateTime|false $current_date A DateTime object signifying the current date for the view. * * @return DateTime|false Either the previous event chronologically, the previous month, or false if no next event found. */ public function get_previous_event_date( $current_date ) { $context = $this->context instanceof Tribe__Context ? $this->context : null; $args = $this->filter_repository_args( $this->setup_repository_args( $context ) ); // This value will mess up our query. unset( $args['date_overlaps'] ); // Use cache to reduce the performance impact. $cache_key = __METHOD__ . '_' . substr( md5( wp_json_encode( [ $current_date, $args ] ) ), 10 ); if ( isset( $this->memoized_dates[ $cache_key ] ) ) { return $this->memoized_dates[ $cache_key ]; } // When dealing with previous event date we only fetch one. $args['posts_per_page'] = 1; // Find the first event that starts before the start of today. $prev_event = tribe_events() ->by_args( $args ) ->where( 'starts_before', tribe_beginning_of_day( $current_date->format( 'Y-m-d' ) ) ) ->order( 'DESC' ) ->first(); if ( ! $prev_event instanceof \WP_Post ) { $this->memoized_dates[ $cache_key ] = false; return false; } // Show the closest date on which that event appears (but not the current date). $prev_event_date = Dates::build_date_object( $prev_event->dates->start ); $prev_date = min( $prev_event_date, $current_date->sub( new \DateInterval( 'P1D' ) ) ); $this->memoized_dates[ $cache_key ] = $prev_date; return $prev_date; } /** * {@inheritDoc} */ public function prev_url( $canonical = false, array $passthru_vars = [] ) { $cache_key = __METHOD__ . '_' . md5( wp_json_encode( func_get_args() ) ); if ( isset( $this->cached_urls[ $cache_key ] ) ) { return $this->cached_urls[ $cache_key ]; } $date = $this->context->get( 'event_date', $this->context->get( 'today', 'today' ) ); $one_day = new \DateInterval( 'P1D' ); $url_date = Dates::build_date_object( $date )->sub( $one_day ); $earliest = $this->context->get( 'earliest_event_date', $url_date ); $earliest_date = Dates::build_date_object( $earliest )->setTime( 0, 0, 0 ); if ( $url_date < $earliest_date ) { $url = ''; } else { $url = $this->build_url_for_date( $url_date, $canonical, $passthru_vars ); } $url = $this->filter_prev_url( $canonical, $url ); $this->cached_urls[ $cache_key ] = $url; return $url; } /** * Get the date of the event immediately after to the current view date. * * @since 5.16.1 * * @param DateTime|false $current_date A DateTime object signifying the current date for the view. * * @return DateTime|false Either the next event chronologically, the next month, or false if no next event found. */ public function get_next_event_date( $current_date ) { $context = $this->context instanceof Tribe__Context ? $this->context : null; $args = $this->filter_repository_args( $this->setup_repository_args( $context ) ); // This value will mess up our query. unset( $args['date_overlaps'] ); // Use cache to reduce the performance impact. $cache_key = __METHOD__ . '_' . substr( md5( wp_json_encode( [ $current_date, $args ] ) ), 10 ); if ( isset( $this->memoized_dates[ $cache_key ] ) ) { return $this->memoized_dates[ $cache_key ]; } if ( isset( $args['past'] ) && tribe_is_truthy( $args['past'] ) ) { return false; } // For the next event date we only care about 1 item. $args['posts_per_page'] = 1; // The first event that ends after the end of the month; it could still begin in this month. $next_event = tribe_events() ->by_args( $args ) ->where( 'starts_after', tribe_end_of_day( $current_date->format( 'Y-m-d' ) ) ) ->order( 'ASC' ) ->first(); if ( ! $next_event instanceof \WP_Post ) { $this->memoized_dates[ $cache_key ] = false; return false; } // At a minimum pick the next month or the month the next event starts in. $next_date = max( Dates::build_date_object( $next_event->dates->start ), $current_date->add( new \DateInterval( 'P1D' ) ) ); $this->memoized_dates[ $cache_key ] = $next_date; return $next_date; } /** * {@inheritDoc} */ public function next_url( $canonical = false, array $passthru_vars = [] ) { $cache_key = __METHOD__ . '_' . md5( wp_json_encode( func_get_args() ) ); if ( isset( $this->cached_urls[ $cache_key ] ) ) { return $this->cached_urls[ $cache_key ]; } $date = $this->context->get( 'event_date', $this->context->get( 'today', 'today' ) ); $one_day = new \DateInterval( 'P1D' ); $url_date = Dates::build_date_object( $date )->add( $one_day ); $latest = $this->context->get( 'latest_event_date', $url_date ); $latest_date = Dates::build_date_object( $latest )->setTime( 0, 0, 0 ); if ( $url_date > $latest_date ) { $url = ''; } else { $url = $this->build_url_for_date( $url_date, $canonical, $passthru_vars ); } $url = $this->filter_next_url( $canonical, $url ); $this->cached_urls[ $cache_key ] = $url; return $url; } /** * {@inheritDoc} */ protected function setup_repository_args( \Tribe__Context $context = null ) { $context = null !== $context ? $context : $this->context; $args = parent::setup_repository_args( $context ); $context_arr = $context->to_array(); $date = Arr::get( $context_arr, 'event_date', 'now' ); $current_date = Dates::build_date_object( $date ); $args['date_overlaps'] = [ tribe_beginning_of_day( $current_date->format( 'Y-m-d' ) ), tribe_end_of_day( $current_date->format( 'Y-m-d' ) ) ]; /** * @todo @bordoni We need to consider fetching events on a given day from a cache * base on what @lucatume suggested on dev meeting for caching more efficiently. */ $args['posts_per_page'] = -1; return $args; } /** * Builds the Day View URL for a specific date. * * This is the method underlying the construction of the previous and next URLs. * * @since 4.9.10 * * @param mixed $url_date The date to build the URL for, a \DateTime object, a string or a timestamp. * @param bool $canonical Whether to return the canonical (pretty) version of the URL or not. * @param array $passthru_vars An optional array of query variables that should pass thru the method untouched * in key and value. * * @return string The Day View URL for the date. */ protected function build_url_for_date( $url_date, $canonical, array $passthru_vars = [] ) { $url_date = Dates::build_date_object( $url_date ); $url = new Url( $this->get_url() ); $date_query_args = (array) $url->get_query_args_aliases_of( 'event_date', $this->context ); $url = add_query_arg( [ 'eventDate' => $url_date->format( Dates::DBDATEFORMAT ) ], remove_query_arg( $date_query_args, $this->get_url() ) ); if ( ! empty( $url ) && $canonical ) { $input_url = $url; if ( ! empty( $passthru_vars ) ) { $input_url = remove_query_arg( array_keys( $passthru_vars ), $url ); } // Make sure the view slug is always set to correctly match rewrites. $input_url = add_query_arg( [ 'eventDisplay' => static::$view_slug ], $input_url ); $canonical_url = tribe( 'events.rewrite' )->get_clean_url( $input_url ); if ( ! empty( $passthru_vars ) ) { $canonical_url = add_query_arg( $passthru_vars, $canonical_url ); } $url = $canonical_url; } return $url; } /** * {@inheritDoc} */ protected function setup_template_vars() { $template_vars = parent::setup_template_vars(); $sorted_events = $this->sort_events( $template_vars['events'] ); $next_date = Dates::build_date_object( $template_vars['url_event_date'] )->add( new \DateInterval( 'P1D' ) )->format( 'Y-m-d' ); $prev_date = Dates::build_date_object( $template_vars['url_event_date'] )->sub( new \DateInterval( 'P1D' ) )->format( 'Y-m-d' ); $next_event_date = $this->get_next_event_date( Dates::build_date_object( $template_vars['url_event_date'] ) ); $prev_event_date = $this->get_previous_event_date( Dates::build_date_object( $template_vars['url_event_date'] ) ); $index_next_rel = $next_event_date && $next_date === $next_event_date->format( 'Y-m-d' ); $index_prev_rel = $prev_event_date && $prev_date === $prev_event_date->format( 'Y-m-d' ); $next_rel = $index_next_rel ? 'next' : 'noindex'; $prev_rel = $index_prev_rel ? 'prev' : 'noindex'; $template_vars['events'] = $sorted_events; $template_vars['next_rel'] = $next_rel; $template_vars['prev_rel'] = $prev_rel; return $template_vars; } /** * Add time slot and sort events for the day view. * * Iterate over the day events to add time slots and sort them. * * @since 4.9.11 * * @param array $events An array of events. * * @return array The sorted and modified array. */ protected function sort_events( $events ) { $all_day = []; $ongoing = []; $hourly = []; $today = Dates::build_date_object( $this->context->get( 'today', 'today' ) ); $request_date = $this->context->get( 'event_date', $today->format( Dates::DBDATEFORMAT ) ); foreach ( $events as $i => $event ) { if ( ! empty( $event->all_day ) ) { $event->timeslot = 'all_day'; $all_day[ $i ] = $event; } elseif ( ! empty( $event->multiday ) && $event->dates->start_display->format( Dates::DBDATEFORMAT ) !== $request_date ) { $event->timeslot = 'multiday'; $ongoing[ $i ] = $event; } else { $event->timeslot = null; $hourly[ $i ] = $event; } } return array_values( $all_day + $ongoing + $hourly ); } /** * Overrides the base View method to implement logic tailored to the Day View. * * @since 4.9.11 * * @param array $events An array of the View events, if any. */ protected function setup_messages( array $events ) { if ( empty( $events ) ) { $keyword = $this->context->get( 'keyword', false ); if ( $keyword ) { $this->messages->insert( Messages::TYPE_NOTICE, Messages::for_key( 'no_results_found_w_keyword', esc_html( trim( $keyword ) ) ) ); return; } $date_time = Dates::build_date_object( $this->context->get( 'event_date', 'today' ) ); $date_label = date_i18n( tribe_get_date_format( true ), $date_time->getTimestamp() + $date_time->getOffset() ); $fast_forward_link = $this->get_fast_forward_link( true ); if ( ! empty( $fast_forward_link ) ) { $this->messages->insert( Messages::TYPE_NOTICE, Messages::for_key( 'day_no_results_found_w_ff_link', $date_label, $fast_forward_link ) ); return; } $message_key = $this->upcoming_events_count() ? 'day_no_results_found' : 'no_upcoming_events'; $this->messages->insert( Messages::TYPE_NOTICE, Messages::for_key( $message_key, $date_label ) ); } } }