get_name(); $time = $this->_registry->get( 'date.system' ); // Get localized time $timestamp = $time->current_time(); // Get events, then classify into date array $per_page_setting = $type . '_events_per_page'; $search = $this->_registry->get( 'model.search' ); $settings = $this->_registry->get( 'model.settings' ); $events_limit = is_numeric( $view_args['events_limit'] ) ? $view_args['events_limit'] : $settings->get( $per_page_setting ); $events_limit = apply_filters( 'ai1ec_events_limit', $events_limit ); $relative_to_reference = in_array( $this->get_name(), array( 'agenda', 'posterboard', 'stream' ) ); if ( $relative_to_reference ) { $results = $search->get_events_relative_to_reference( $view_args['time_limit'], $events_limit, $view_args['page_offset'], apply_filters( 'ai1ec_get_events_relative_to_filter', array( 'post_ids' => $view_args['post_ids'], 'auth_ids' => $view_args['auth_ids'], 'cat_ids' => $view_args['cat_ids'], 'tag_ids' => $view_args['tag_ids'], 'instance_ids' => $view_args['instance_ids'], ), $view_args ), apply_filters( 'ai1ec_show_unique_events', false ) ); } else { $results = $search->get_events_relative_to( $timestamp, $events_limit, $view_args['page_offset'], apply_filters( 'ai1ec_get_events_relative_to_filter', array( 'post_ids' => $view_args['post_ids'], 'auth_ids' => $view_args['auth_ids'], 'cat_ids' => $view_args['cat_ids'], 'tag_ids' => $view_args['tag_ids'], 'instance_ids' => $view_args['instance_ids'], ), $view_args ), $view_args['time_limit'], apply_filters( 'ai1ec_show_unique_events', false ) ); } $this->_update_meta( $results['events'] ); $dates = $this->get_agenda_like_date_array( $results['events'], $view_args['request'] ); // Generate title of view based on date range month & year. $range_start = $results['date_first'] && false === $results['date_first']->is_empty() ? $results['date_first'] : $this->_registry->get( 'date.time', $timestamp ); $range_end = $results['date_last'] && false === $results['date_last']->is_empty() ? $results['date_last'] : $this->_registry->get( 'date.time', $timestamp ); $range_start = $this->_registry->get( 'date.time', $range_start ); $range_end = $this->_registry->get( 'date.time', $range_end ); $start_year = $range_start->format_i18n( 'Y' ); $end_year = $range_end->format_i18n( 'Y' ); $start_month = $range_start->format_i18n( 'F' ); $start_month_short = $range_start->format_i18n( 'M' ); $end_month = $range_end->format_i18n( 'F' ); $end_month_short = $range_end->format_i18n( 'M' ); if ( $start_year === $end_year && $start_month === $end_month ) { $title = "$start_month $start_year"; $title_short = "$start_month_short $start_year"; } elseif ( $start_year === $end_year ) { $title = "$start_month – $end_month $end_year"; $title_short = "$start_month_short – $end_month_short $end_year"; } else { $title = "$start_month $start_year – $end_month $end_year"; $title_short = "$start_month_short $start_year – $end_month_short $end_year"; } // Create navigation bar if requested. $navigation = ''; $loader = $this->_registry->get( 'theme.loader' ); $pagination_links = ''; if ( ! $view_args['no_navigation'] ) { if ( $relative_to_reference ) { $pagination_links = $this->_get_pagination_links( $view_args, $results['prev'], $results['next'], $results['date_first'], $results['date_last'], $title, $title_short, $view_args['page_offset'] + -1, $view_args['page_offset'] + 1 ); } else { $pagination_links = $this->_get_agenda_like_pagination_links( $view_args, $results['prev'], $results['next'], $results['date_first'], $results['date_last'], $title, $title_short, null === $view_args['time_limit'] || 0 === $view_args['time_limit'] ? $timestamp : $view_args['time_limit'] ); } $pagination_links = $loader->get_file( 'pagination.twig', array( 'links' => $pagination_links, 'data_type' => $view_args['data_type'], ), false )->get_content(); // Get HTML for navigation bar. $nav_args = array( 'no_navigation' => $view_args['no_navigation'], 'pagination_links' => $pagination_links, 'views_dropdown' => $view_args['views_dropdown'], 'below_toolbar' => apply_filters( 'ai1ec_below_toolbar', '', $type, $view_args ), ); // Add extra buttons to Agenda view's nav bar if events were returned. if ( $type === 'agenda' && $dates ) { $button_args = array( 'text_collapse_all' => __( 'Collapse All', AI1EC_PLUGIN_NAME ), 'text_expand_all' => __( 'Expand All', AI1EC_PLUGIN_NAME ), ); $nav_args['after_pagination'] = $loader ->get_file( 'agenda-buttons.twig', $button_args, false ) ->get_content(); } $navigation = $this->_get_navigation( $nav_args ); } $is_ticket_button_enabled = apply_filters( 'ai1ec_' . $type . '_ticket_button', false ); $args = array( 'title' => $title, 'dates' => $dates, 'type' => $type, 'show_year_in_agenda_dates' => $settings->get( 'show_year_in_agenda_dates' ), 'expanded' => $settings->get( 'agenda_events_expanded' ), 'show_location_in_title' => $settings->get( 'show_location_in_title' ), 'page_offset' => $view_args['page_offset'], 'navigation' => $navigation, 'pagination_links' => $pagination_links, 'post_ids' => join( ',', $view_args['post_ids'] ), 'data_type' => $view_args['data_type'], 'is_ticket_button_enabled' => $is_ticket_button_enabled, 'text_upcoming_events' => __( 'There are no upcoming events to display at this time.', AI1EC_PLUGIN_NAME ), 'text_edit' => __( 'Edit', AI1EC_PLUGIN_NAME ), 'text_read_more' => __( 'Read more', AI1EC_PLUGIN_NAME ), 'text_categories' => __( 'Categories:', AI1EC_PLUGIN_NAME ), 'text_tags' => __( 'Tags:', AI1EC_PLUGIN_NAME ), 'text_venue_separator' => __( '@ %s', AI1EC_PLUGIN_NAME ), ); // Allow child views to modify arguments passed to template. $args = $this->get_extra_template_arguments( $args ); return $this->_registry->get( 'http.request' )->is_json_required( $view_args['request_format'], $type ) ? $loader->apply_filters_to_args( $args, $type . '.twig', false ) : $this->_get_view( $args ); } /* (non-PHPdoc) * @see Ai1ec_Calendar_View_Abstract::get_extra_arguments() */ public function get_extra_arguments( array $view_args, $exact_date ) { $view_args += $this->_request->get_dict( array( 'page_offset', 'time_limit', ) ); if( false !== $exact_date ) { $view_args['time_limit'] = $exact_date; } return $view_args; } /** * Breaks down the given ordered array of event objects into dates, and * outputs an ordered array of two-element associative arrays in the * following format: * key: localized UNIX timestamp of date * value: * ['events'] => two-element associatative array broken down thus: * ['allday'] => all-day events occurring on this day * ['notallday'] => all other events occurring on this day * ['today'] => whether or not this date is today * * @param array $events Event results * @param Ai1ec_Abstract_Query|null $query Current calendar page request, if * any (null for widget) * * @return array */ public function get_agenda_like_date_array( $events, Ai1ec_Abstract_Query $query = null ) { $dates = array(); $time = $this->_registry->get( 'date.system' ); $settings = $this->_registry->get( 'model.settings' ); $this->_registry->get( 'controller.content-filter' ) ->clear_the_content_filters(); // Classify each event into a date/allday category foreach ( $events as $event ) { $start_time = $this->_registry ->get( 'date.time', $event->get( 'start' )->format( 'Y-m-d\T00:00:00' ), 'sys.default' ); $exact_date = $time->format_datetime_for_url( $start_time, $settings->get( 'input_date_format' ) ); $href_for_date = $this->_create_link_for_day_view( $exact_date ); // timestamp is used to have correctly sorted array as UNIX // timestamp never goes in decreasing order for increasing dates. $timestamp = $start_time->format(); // Ensure all-day & non all-day categories are created in correct // order: "allday" preceding "notallday". if ( ! isset( $dates[$timestamp]['events'] ) ) { $dates[$timestamp]['events'] = array( 'allday' => array(), 'notallday' => array(), ); } $this->_add_runtime_properties( $event ); // Add the event. $category = $event->is_allday() ? 'allday' : 'notallday'; $event_props = array(); $event_props['post_id'] = $event->get( 'post_id' ); $event_props['instance_id'] = $event->get( 'instance_id' ); $event_props['venue'] = $event->get( 'venue' ); $event_props['ticket_url'] = $event->get( 'ticket_url' ); $event_props['filtered_title'] = $event->get_runtime( 'filtered_title' ); $event_props['edit_post_link'] = $event->get_runtime( 'edit_post_link' ); $event_props['content_img_url'] = $event->get_runtime( 'content_img_url' ); $event_props['filtered_content'] = $event->get_runtime( 'filtered_content' ); $event_props['ticket_url_label'] = $event->get_runtime( 'ticket_url_label' ); $event_props['permalink'] = $event->get_runtime( 'instance_permalink' ); $event_props['categories_html'] = $event->get_runtime( 'categories_html' ); $event_props['category_bg_color'] = $event->get_runtime( 'category_bg_color' ); $event_props['category_text_color'] = $event->get_runtime( 'category_text_color' ); $event_props['tags_html'] = $event->get_runtime( 'tags_html' ); $event_props['post_excerpt'] = $event->get_runtime( 'post_excerpt' ); $event_props['short_start_time'] = $event->get_runtime( 'short_start_time' ); $event_props['is_allday'] = $event->is_allday(); $event_props['is_multiday'] = $event->is_multiday(); $event_props['enddate_info'] = $event->getenddate_info(); $event_props['timespan_short'] = $event->_registry-> get( 'view.event.time' )->get_timespan_html( $event, 'short' ); $event_props['avatar'] = $event->getavatar(); $event_props['avatar_not_wrapped'] = $event->getavatar( false ); $event_props['avatar_url'] = $this->_registry ->get( 'view.event.avatar' )->get_event_avatar_url( $event ); $event_props['category_divider_color'] = $event->get_runtime( 'category_divider_color' ); $meta = $this->_registry->get( 'model.meta-post' ); if ( ! $event_props['ticket_url'] ) { $timely_tickets = $meta->get( $event->get( 'post_id' ), '_ai1ec_timely_tickets_url', null ); if ( $timely_tickets ) { $event_props['ticket_url'] = $timely_tickets; $event->set( 'ticket_url', $event_props['ticket_url'] ); } } if ( true === apply_filters( 'ai1ec_buy_button_product', false ) ) { $full_details = $meta->get( $event->get( 'post_id' ), '_ai1ec_ep_product_details', null ); if ( is_array( $full_details ) && isset( $full_details['show_buy_button'] ) && true === $full_details['show_buy_button'] && $event_props['ticket_url'] ) { // Tickets button is shown by default in this case. } else { // Otherwise not. $event_props['ticket_url'] = false; } $event->set( 'ticket_url', $event_props['ticket_url'] ); } $event_object = $event_props; if ( $this->_compatibility->use_backward_compatibility() ) { $event_object = $event; } $months = apply_filters( 'ai1ec_i18n_months', array() ); $weekdays = apply_filters( 'ai1ec_i18n_weekdays', array() ); $dates[$timestamp]['events'][$category][] = $event_object; $dates[$timestamp]['href'] = $href_for_date; $dates[$timestamp]['day'] = $this->_registry-> get( 'date.time', $timestamp )->format_i18n( 'j' ); $w = $this-> _registry->get( 'date.time', $timestamp )->format_i18n( 'D' ); $dates[$timestamp]['weekday'] = array_key_exists( $w, $weekdays ) ? $weekdays[$w] : $w; $m = $this-> _registry->get( 'date.time', $timestamp )->format_i18n( 'M' ); $dates[$timestamp]['month'] = array_key_exists( $m, $months ) ? $months[$m] : $m; $this->_registry-> get( 'date.time', $timestamp )->format_i18n( 'M' ); $dates[$timestamp]['full_month'] = $this->_registry-> get( 'date.time', $timestamp )->format_i18n( 'F' ); $dates[$timestamp]['full_weekday'] = $this->_registry-> get( 'date.time', $timestamp )->format_i18n( 'l' ); $dates[$timestamp]['year'] = $this->_registry-> get( 'date.time', $timestamp )->format_i18n( 'Y' ); } $this->_registry->get( 'controller.content-filter' ) ->restore_the_content_filters(); // Flag today $today = $this->_registry->get( 'date.time', 'now', 'sys.default' ) ->set_time( 0, 0, 0 ) ->format(); if ( isset( $dates[$today] ) ) { $dates[$today]['today'] = true; } return $dates; } /** * Returns an associative array of two links for any agenda-like view of the * calendar: * previous page (if previous events exist), * next page (if next events exist). * Each element is an associative array containing the link's enabled status * ['enabled'], CSS class ['class'], text ['text'] and value to assign to * link's href ['href']. * * @param array $args Current request arguments * * @param bool $prev Whether there are more events before * the current page * @param bool $next Whether there are more events after * the current page * @param Ai1ec_Date_Time|null $date_first * @param Ai1ec_Date_Time|null $date_last * @param string $title Title to display in datepicker button * @param string $title_short Short month names. * @param int|null $default_time_limit The default time limit in the case of pagination ends. * @return array Array of links */ protected function _get_agenda_like_pagination_links( $args, $prev = false, $next = false, $date_first = null, $date_last = null, $title = '', $title_short = '', $default_time_limit = 0 ) { $links = array(); if ( $this->_registry->get( 'model.settings' )->get( 'ai1ec_use_frontend_rendering' ) ) { $args['request_format'] = 'json'; } $args['page_offset'] = -1; if ( null === $date_first || $date_first->is_empty() ) { $args['time_limit'] = $default_time_limit; } else { $args['time_limit'] = $this->_registry ->get( 'date.time', $date_first )->set_time( $date_first->format( 'H' ), $date_first->format( 'i' ), $date_first->format( 's' ) - 1 )->format_to_gmt(); } $href = $this->_registry->get( 'html.element.href', $args ); $links[] = array( 'class' => 'ai1ec-prev-page', 'text' => '', 'href' => $href->generate_href(), 'enabled' => $prev, ); // Minical datepicker. $factory = $this->_registry->get( 'factory.html' ); $links[] = $factory->create_datepicker_link( $args, $date_first->format_to_gmt(), $title, $title_short ); $args['page_offset'] = 1; if ( null === $date_last || $date_last->is_empty() ) { $args['time_limit'] = $default_time_limit; } else { $args['time_limit'] = $this->_registry ->get( 'date.time', $date_last )->set_time( $date_last->format( 'H' ), $date_last->format( 'i' ), $date_last->format( 's' ) + 1 )->format_to_gmt(); } $href = $this->_registry->get( 'html.element.href', $args ); $links[] = array( 'class' => 'ai1ec-next-page', 'text' => '', 'href' => $href->generate_href(), 'enabled' => $next, ); return $links; } /** * Returns an associative array of two links for any agenda-like view of the * calendar: * previous page (if previous events exist), * next page (if next events exist). * Each element is an associative array containing the link's enabled status * ['enabled'], CSS class ['class'], text ['text'] and value to assign to * link's href ['href']. * * @param array $args Current request arguments * * @param bool $prev Whether there are more events before * the current page * @param bool $next Whether there are more events after * the current page * @param Ai1ec_Date_Time|null $date_first * @param Ai1ec_Date_Time|null $date_last * @param string $title Title to display in datepicker button * @param string $title_short Short month names. * @param int|null $default_time_limit The default time limit in the case of pagination ends. * @return array Array of links */ protected function _get_pagination_links( $args, $prev = false, $next = false, $date_first = null, $date_last = null, $title = '', $title_short = '', $prev_offset = -1, $next_offset = 1) { $links = array(); if ( $this->_registry->get( 'model.settings' )->get( 'ai1ec_use_frontend_rendering' ) ) { $args['request_format'] = 'json'; } $args['page_offset'] = $prev_offset; $href = $this->_registry->get( 'html.element.href', $args ); $links[] = array( 'class' => 'ai1ec-prev-page', 'text' => '', 'href' => $href->generate_href(), 'enabled' => $prev ); // Minical datepicker. $factory = $this->_registry->get( 'factory.html' ); $links[] = $factory->create_datepicker_link( $args, $date_first->format_to_gmt(), $title, $title_short ); $args['page_offset'] = $next_offset; $href = $this->_registry->get( 'html.element.href', $args ); $links[] = array( 'class' => 'ai1ec-next-page', 'text' => '', 'href' => $href->generate_href(), 'enabled' => $next ); return $links; } /* (non-PHPdoc) * @see Ai1ec_Calendar_View_Abstract::_add_view_specific_runtime_properties() */ protected function _add_view_specific_runtime_properties( Ai1ec_Event $event ) { $taxonomy = $this->_registry->get( 'view.event.taxonomy' ); $avatar = $this->_registry->get( 'view.event.avatar' ); $event->set_runtime( 'categories_html', $taxonomy->get_categories_html( $event ) ); $event->set_runtime( 'tags_html', $taxonomy->get_tags_html( $event ) ); $event->set_runtime( 'content_img_url', $avatar->get_content_img_url( $event ) ); } }