Files
wordpress-preseed/wp-content/plugins/all-in-one-event-calendar/app/view/calendar/view/agenda.php
Adrian Nöthlich 290736650a Add upstream plugins
Signed-off-by: Adrian Nöthlich <git@promasu.tech>
2019-10-25 22:42:20 +02:00

583 lines
24 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* The concrete class for agenda view.
*
* @author Time.ly Network Inc.
* @since 2.0
*
* @package AI1EC
* @subpackage AI1EC.View
*/
class Ai1ec_Calendar_View_Agenda extends Ai1ec_Calendar_View_Abstract {
/* (non-PHPdoc)
* @see Ai1ec_Calendar_View_Abstract::get_name()
*/
public function get_name() {
return 'agenda';
}
/* (non-PHPdoc)
* @see Ai1ec_Calendar_View_Abstract::get_content()
*/
public function get_content( array $view_args ) {
$type = $this->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' => '<i class="ai1ec-fa ai1ec-fa-chevron-left"></i>',
'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' => '<i class="ai1ec-fa ai1ec-fa-chevron-right"></i>',
'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' => '<i class="ai1ec-fa ai1ec-fa-chevron-left"></i>',
'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' => '<i class="ai1ec-fa ai1ec-fa-chevron-right"></i>',
'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 )
);
}
}