all-in-one-event-calendar/app/view/calendar/widget.php
2017-11-09 17:36:04 +01:00

428 lines
16 KiB
PHP

<?php
/**
* Calendar Widget class
*
* A widget that displays the next X upcoming events (similar to Agenda view).
*/
class Ai1ec_View_Admin_Widget extends Ai1ec_Embeddable {
/**
* @var boolean
*/
protected $_css_loaded = false;
/**
* @return string
*/
public function get_id() {
return 'ai1ec_agenda_widget';
}
/**
* Register the widget class.
*/
public static function register_widget() {
register_widget( 'Ai1ec_View_Admin_Widget' );
}
/**
* Constructor for widget.
*/
public function __construct() {
parent::__construct(
$this->get_id(),
__( 'Upcoming Events', AI1EC_PLUGIN_NAME ),
array(
'description' => __( 'All-in-One Event Calendar: Lists upcoming events in Agenda view', AI1EC_PLUGIN_NAME ),
'class' => 'ai1ec-agenda-widget',
)
);
}
/* (non-PHPdoc)
* @see Ai1ec_Embeddable::register_javascript_widget()
*/
public function register_javascript_widget( $id_base ) {
$this->_registry->get( 'controller.javascript-widget' )
->add_widget( $id_base, 'view.calendar.widget' );
}
/* (non-PHPdoc)
* @see Ai1ec_Embeddable::get_defaults()
*/
public function get_defaults() {
return array(
'title' => __( 'Upcoming Events', AI1EC_PLUGIN_NAME ),
'events_seek_type' => 'events',
'events_per_page' => 10,
'days_per_page' => 10,
'show_subscribe_buttons' => true,
'show_calendar_button' => true,
'hide_on_calendar_page' => true,
'limit_by_cat' => false,
'limit_by_tag' => false,
'cat_ids' => array(),
'tag_ids' => array(),
'link_for_days' => true,
);
}
/* (non-PHPdoc)
* @see Ai1ec_Embeddable::get_configurable_for_widget_creation()
*/
public function get_configurable_for_widget_creation() {
$defaults = $this->get_js_widget_configurable_defaults();
return array(
'events_seek_type' => array(
'renderer' => array(
'class' => 'select',
'label' => __(
'Choose how to limit the upcoming events',
AI1EC_PLUGIN_NAME
),
'options' => array(
array(
'text' => __(
'Events',
AI1EC_PLUGIN_NAME
),
'value' => 'events'
),
array(
'text' => __(
'Days',
AI1EC_PLUGIN_NAME
),
'value' => 'days'
),
),
),
'value' => $defaults['events_seek_type']
),
'events_per_page' => array(
'renderer' => array(
'class' => 'input',
'label' => Ai1ec_I18n::__( 'Number of events to show' ),
'type' => 'append',
'append' => 'events',
),
'value' => $defaults['events_per_page'],
),
'days_per_page' => array(
'renderer' => array(
'class' => 'input',
'label' => Ai1ec_I18n::__( 'Number of days to show' ),
'type' => 'append',
'append' => 'days',
),
'value' => $defaults['days_per_page'],
),
'upcoming_widgets_default_tags_categories' => array(
'renderer' => array(
'class' => 'tags-categories',
'label' => __(
'Show events filtered for the following tags/categories',
AI1EC_PLUGIN_NAME
),
'help' => __(
'To clear, hold &#8984;/<abbr class="initialism">CTRL</abbr> and click selection.',
AI1EC_PLUGIN_NAME
)
),
'value' => array(
'categories' => array(),
'tags' => array(),
),
),
'show_subscribe_buttons' => array(
'renderer' => array(
'class' => 'checkbox',
'label' => Ai1ec_I18n::__( 'Show the subscribe button in the widget' ),
),
'value' => $defaults['show_subscribe_buttons'],
),
);
}
/* (non-PHPdoc)
* @see Ai1ec_Calendar_View_Abstract::get_name()
*/
public function get_name() {
return 'Upcoming Events';
}
/**
* The icon class associated with the widget.
*
* @return string
*/
public function get_icon() {
return 'ai1ec-fa ai1ec-fa-clock-o';
}
/**
* Form function.
*
* Renders the widget's configuration form for the Manage Widgets page.
*
* @param array $instance The data array for the widget instance being configured.
* @return void
*/
public function form( $instance ) {
$default = $this->get_defaults();
$instance = wp_parse_args( (array) $instance, $default );
// Get available cats, tags, events to allow user to limit widget to certain categories
$events_categories = get_terms( 'events_categories', array( 'orderby' => 'name', "hide_empty" => false ) );
$events_tags = get_terms( 'events_tags', array( 'orderby' => 'name', "hide_empty" => false ) );
// Generate unique IDs and NAMEs of all needed form fields
$fields = array(
'title' => array('value' => $instance['title']),
'events_seek_type' => array('value' => $instance['events_seek_type']),
'events_per_page' => array('value' => $instance['events_per_page']),
'days_per_page' => array('value' => $instance['days_per_page']),
'show_subscribe_buttons' => array('value' => $instance['show_subscribe_buttons']),
'show_calendar_button' => array('value' => $instance['show_calendar_button']),
'hide_on_calendar_page' => array('value' => $instance['hide_on_calendar_page']),
'limit_by_cat' => array('value' => $instance['limit_by_cat']),
'limit_by_tag' => array('value' => $instance['limit_by_tag']),
'cat_ids' => array(
'value' => (array)$instance['cat_ids'],
'options' => $events_categories
),
'tag_ids' => array(
'value' => (array)$instance['tag_ids'],
'options' => $events_tags
),
);
foreach ( $fields as $field => $data ) {
$fields[$field]['id'] = $this->get_field_id( $field );
$fields[$field]['name'] = $this->get_field_name( $field );
$fields[$field]['value'] = $data['value'];
if ( isset($data['options']) ) {
$fields[$field]['options'] = $data['options'];
}
}
// Display theme
$this->_registry->get( 'theme.loader' )->get_file(
'agenda-widget-form.php',
$fields,
true
)->render();
}
/**
* Update function.
*
* Called when a user submits the widget configuration form.
* The data should be validated and returned.
*
* @param array $new_instance The new data that was submitted.
* @param array $old_instance The widget's old data.
* @return array The new data to save for this widget instance.
*/
public function update( $new_instance, $old_instance ) {
// Save existing data as a base to modify with new data
$instance = $old_instance;
$instance['title'] = strip_tags( $new_instance['title'] );
$instance['events_per_page'] = Ai1ec_Primitive_Int::index(
$new_instance['events_per_page'],
1,
1
);
$instance['days_per_page'] = Ai1ec_Primitive_Int::index(
$new_instance['days_per_page'],
1,
1
);
$instance['events_seek_type'] = $this->_valid_seek_type(
$new_instance['events_seek_type']
);
$instance['show_subscribe_buttons'] = isset( $new_instance['show_subscribe_buttons'] ) ? true : false;
$instance['show_calendar_button'] = isset( $new_instance['show_calendar_button'] ) ? true : false;
$instance['hide_on_calendar_page'] = isset( $new_instance['hide_on_calendar_page'] ) ? true : false;
// For limits, set the limit to False if no IDs were selected, or set the respective IDs to empty if "limit by" was unchecked
$instance['limit_by_cat'] = false;
$instance['cat_ids'] = array();
if ( isset( $new_instance['cat_ids'] ) && $new_instance['cat_ids'] != false ) {
$instance['limit_by_cat'] = true;
}
if ( isset( $new_instance['limit_by_cat'] ) && $new_instance['limit_by_cat'] != false ) {
$instance['limit_by_cat'] = true;
}
if ( isset( $new_instance['cat_ids'] ) && $instance['limit_by_cat'] === true ) {
$instance['cat_ids'] = $new_instance['cat_ids'];
}
$instance['limit_by_tag'] = false;
$instance['tag_ids'] = array();
if ( isset( $new_instance['tag_ids'] ) && $new_instance['tag_ids'] != false ) {
$instance['limit_by_tag'] = true;
}
if ( isset( $new_instance['limit_by_tag'] ) && $new_instance['limit_by_tag'] != false ) {
$instance['limit_by_tag'] = true;
}
if ( isset( $new_instance['tag_ids'] ) && $instance['limit_by_tag'] === true ) {
$instance['tag_ids'] = $new_instance['tag_ids'];
}
return $instance;
}
/* (non-PHPdoc)
* @see Ai1ec_Embeddable::add_js()
*/
public function add_js() {
$this->_registry->get( 'controller.javascript' )->add_link_to_render_js(
Ai1ec_Javascript_Controller::LOAD_ONLY_FRONTEND_SCRIPTS,
false
);
}
/* (non-PHPdoc)
* @see Ai1ec_Embeddable::get_content()
*/
public function get_content( array $args_for_widget, $remote = false ) {
$agenda = $this->_registry->get(
'view.calendar.view.agenda',
$this->_registry->get( 'http.request.parser' )
);
$time = $this->_registry->get( 'date.time' );
$search = $this->_registry->get( 'model.search' );
$settings = $this->_registry->get( 'model.settings' );
$html = $this->_registry->get( 'factory.html' );
$is_calendar_page = is_page( $settings->get( 'calendar_page_id' ) );
if ( $args_for_widget['hide_on_calendar_page'] &&
$is_calendar_page ) {
return;
}
// Add params to the subscribe_url for filtering by Limits (category, tag)
$subscribe_filter = '';
if ( ! is_array( $args_for_widget['cat_ids'] ) ) {
$args_for_widget['cat_ids'] = explode( ',', $args_for_widget['cat_ids'] );
}
if ( ! is_array( $args_for_widget['tag_ids'] ) ) {
$args_for_widget['tag_ids'] = explode( ',', $args_for_widget['tag_ids'] );
}
$subscribe_filter .= $args_for_widget['cat_ids'] ? '&ai1ec_cat_ids=' . join( ',', $args_for_widget['cat_ids'] ) : '';
$subscribe_filter .= $args_for_widget['tag_ids'] ? '&ai1ec_tag_ids=' . join( ',', $args_for_widget['tag_ids'] ) : '';
// Get localized time
$timestamp = $time->format_to_gmt();
// Set $limit to the specified category/tag
$limit = array(
'cat_ids' => $args_for_widget['cat_ids'],
'tag_ids' => $args_for_widget['tag_ids'],
);
$limit = apply_filters( 'ai1ec_add_filters_upcoming_widget', $limit );
// Get events, then classify into date array
// JB: apply seek check here
$seek_days = ( 'days' === $args_for_widget['events_seek_type'] );
$seek_count = $args_for_widget['events_per_page'];
$last_day = false;
if ( $seek_days ) {
$seek_count = $args_for_widget['days_per_page'] * 5;
$last_day = strtotime(
'+' . $args_for_widget['days_per_page'] . ' days'
);
}
$event_results = $search->get_events_relative_to(
$timestamp,
$seek_count,
0,
$limit
);
if ( $seek_days ) {
foreach ( $event_results['events'] as $ek => $event ) {
if ( $event->get( 'start' )->format() >= $last_day ) {
unset( $event_results['events'][$ek] );
}
}
}
$dates = $agenda->get_agenda_like_date_array( $event_results['events'] );
$args_for_widget['dates'] = $dates;
// load CSS just once for all widgets.
// Do not load it on the calendar page as it's already loaded.
if ( false === $this->_css_loaded && ! $is_calendar_page ) {
if ( true === $remote ) {
$args_for_widget['css'] = $this->_registry->get( 'css.frontend' )->get_compiled_css();
}
$this->_css_loaded = true;
}
$args_for_widget['show_location_in_title'] = $settings->get( 'show_location_in_title' );
$args_for_widget['show_year_in_agenda_dates'] = $settings->get( 'show_year_in_agenda_dates' );
$args_for_widget['calendar_url'] = $html->create_href_helper_instance( $limit )->generate_href();
$args_for_widget['subscribe_url'] = AI1EC_EXPORT_URL . $subscribe_filter;
$args_for_widget['subscribe_url_no_html'] = AI1EC_EXPORT_URL . '&no_html=true' . $subscribe_filter;
$args_for_widget['text_upcoming_events'] = __( 'There are no upcoming events.', AI1EC_PLUGIN_NAME );
$args_for_widget['text_all_day'] = __( 'all-day', AI1EC_PLUGIN_NAME );
$args_for_widget['text_view_calendar'] = __( 'View Calendar', AI1EC_PLUGIN_NAME );
$args_for_widget['text_edit'] = __( 'Edit', AI1EC_PLUGIN_NAME );
$args_for_widget['text_venue_separator'] = __( '@ %s', AI1EC_PLUGIN_NAME );
$args_for_widget['text_subscribe_label'] = __( 'Add', AI1EC_PLUGIN_NAME );
$args_for_widget['subscribe_buttons_text'] = $this->_registry
->get( 'view.calendar.subscribe-button' )
->get_labels();
// Display theme
return $this->_registry->get( 'theme.loader' )->get_file(
'agenda-widget.twig',
$args_for_widget
)->get_content();
}
/* (non-PHPdoc)
* @see Ai1ec_Embeddable::get_js_widget_configurable_defaults()
*/
public function get_js_widget_configurable_defaults() {
$def = $this->get_defaults();
unset( $def['title'] );
unset( $def['link_for_days'] );
return $def;
}
/* (non-PHPdoc)
* @see Ai1ec_Embeddable::javascript_widget()
*/
public function javascript_widget( $args ) {
$args['show_calendar_button'] = false;
$args['link_for_days'] = false;
return parent::javascript_widget( $args );
}
/* (non-PHPdoc)
* @see Ai1ec_Embeddable::check_requirements()
*/
public function check_requirements() {
return null;
}
/**
* _valid_seek_type method.
*
* Return valid seek type for given user input (selection).
*
* @param string $value User selection for seek type
* @return string Seek type to use
*/
protected function _valid_seek_type( $value ) {
static $list = array( 'events', 'days' );
if ( ! in_array( $value, $list ) ) {
return (string)reset( $list );
}
return $value;
}
}