2017-03-16 16:59:53 +01:00
< ? php
/**
* The concrete class for the calendar page .
*
* @ author Time . ly Network Inc .
* @ since 2.0
*
* @ package AI1EC
* @ subpackage AI1EC . View
*/
class Ai1ec_Calendar_Page extends Ai1ec_Base {
2017-11-09 17:36:04 +01:00
/**
* @ var Ai1ec_Memory_Utility Instance of memory to hold exact dates
*/
protected $_exact_dates = NULL ;
/**
* Public constructor
*
* @ param Ai1ec_Registry_Object $registry The registry object
*/
public function __construct ( Ai1ec_Registry_Object $registry ) {
parent :: __construct ( $registry );
$this -> _exact_dates = $registry -> get ( 'cache.memory' );
}
/**
* Get the content if the calendar page
*
* @ param Ai1ec_Request_Parser $request Request object .
* @ param string $caller Method caller , expected one of
* [ 'shortcode' , 'render-command' ]
* Defaults to 'render-command' .
*
* @ return string Content .
*/
public function get_content (
Ai1ec_Request_Parser $request ,
$caller = 'render-command'
) {
// Get args for the current view; required to generate HTML for views
// dropdown list, categories, tags, subscribe buttons, and of course the
// view itself.
$view_args = $this -> get_view_args_for_view ( $request );
try {
$action = $this -> _registry -> get ( 'model.settings-view' )
-> get_configured ( $view_args [ 'action' ] );
} catch ( Ai1ec_Settings_Exception $exception ) {
// short-circuit and return error message
return '<div id="ai1ec-container"><div class="timely"><p>' .
Ai1ec_I18n :: __ (
'There was an error loading calendar. Please contact site administrator and inform him to configure calendar views.'
) .
'</p></div></div>' ;
}
$type = $request -> get ( 'request_type' );
$is_json = $this -> _registry -> get ( 'http.request' ) -> is_json_required (
$view_args [ 'request_format' ], $action
);
// Add view-specific args to the current view args.
$exact_date = $this -> get_exact_date ( $request );
try {
$view_obj = $this -> _registry -> get (
'view.calendar.view.' . $action ,
$request
);
} catch ( Ai1ec_Bootstrap_Exception $exc ) {
$this -> _registry -> get ( 'notification.admin' ) -> store (
sprintf (
Ai1ec_I18n :: __ ( 'Calendar was unable to initialize %s view and has reverted to Agenda view. Please check if you have installed the latest versions of calendar add-ons.' ),
ucfirst ( $action )
),
'error' ,
0 ,
array ( Ai1ec_Notification_Admin :: RCPT_ADMIN ),
true
);
// don't disable calendar - just switch to agenda which should
// always exists
$action = 'agenda' ;
$view_obj = $this -> _registry -> get (
'view.calendar.view.' . $action ,
$request
);
}
$view_args = $view_obj -> get_extra_arguments ( $view_args , $exact_date );
// Get HTML for views dropdown list.
$dropdown_args = $view_args ;
if (
isset ( $dropdown_args [ 'time_limit' ] ) &&
false !== $exact_date
) {
$dropdown_args [ 'exact_date' ] = $exact_date ;
}
$views_dropdown =
$this -> get_html_for_views_dropdown ( $dropdown_args , $view_obj );
// Add views dropdown markup to view args.
$view_args [ 'views_dropdown' ] = $views_dropdown ;
$settings = $this -> _registry -> get ( 'model.settings' );
if ( $settings -> get ( 'ai1ec_use_frontend_rendering' ) ) {
$view_args [ 'request_format' ] = 'json' ;
}
// Get HTML for subscribe buttons.
$subscribe_buttons = $this -> get_html_for_subscribe_buttons ( $view_args );
// Get HTML for view itself.
$view = $view_obj -> get_content ( $view_args );
$router = $this -> _registry -> get ( 'routing.router' );
$are_filters_set = $router -> is_at_least_one_filter_set_in_request (
$view_args
);
if (
$is_json &&
( $view_args [ 'no_navigation' ] || $type !== 'html' )
) {
// send data both for json and jsonp as shortcodes are jsonp
return array (
'html' => $view ,
'views_dropdown' => $views_dropdown ,
'subscribe_buttons' => $subscribe_buttons ,
'are_filters_set' => $are_filters_set ,
'is_json' => $is_json ,
);
} else {
$loader = $this -> _registry -> get ( 'theme.loader' );
$empty = $loader -> get_file ( 'empty.twig' , array (), false );
// Get HTML for categories and for tags
$taxonomy = $this -> _registry -> get ( 'view.calendar.taxonomy' );
$categories = $taxonomy -> get_html_for_categories (
$view_args
);
$tags = $taxonomy -> get_html_for_tags (
$view_args ,
true
);
// option to show filters in the super widget
// Define new arguments for overall calendar view
$filter_args = array (
'views_dropdown' => $views_dropdown ,
'categories' => $categories ,
'tags' => $tags ,
'contribution_buttons' => apply_filters (
'ai1ec_contribution_buttons' ,
'' ,
$type ,
$caller
),
'additional_buttons' => apply_filters (
'ai1ec_additional_buttons' ,
'' ,
$view_args
),
'show_dropdowns' => apply_filters (
'ai1ec_show_dropdowns' ,
true
),
'show_select2' => apply_filters (
'ai1ec_show_select2' ,
false
),
'span_for_select2' => apply_filters (
'ai1ec_span_for_select2' ,
''
),
'authors' => apply_filters (
'ai1ec_authors' ,
''
),
'save_view_btngroup' => apply_filters (
'ai1ec_save_view_btngroup' ,
$empty
),
'view_args' => $view_args ,
'request' => $request ,
);
$filter_menu = $loader -> get_file (
'filter-menu.twig' ,
$filter_args ,
false
) -> get_content ();
// hide filters in the SW
if ( 'true' !== $request -> get ( 'display_filters' ) && 'jsonp' === $type ) {
$filter_menu = '' ;
}
$calendar_args = array (
'version' => AI1EC_VERSION ,
'filter_menu' => $filter_menu ,
'view' => $view ,
'subscribe_buttons' => $subscribe_buttons ,
'disable_standard_filter_menu' => apply_filters (
'ai1ec_disable_standard_filter_menu' ,
false
),
'inline_js_calendar' => apply_filters (
'ai1ec_inline_js_calendar' ,
''
),
'after_view' => apply_filters (
'ai1ec_after_view' ,
''
),
'ai1ec_above_calendar' => apply_filters (
'ai1ec_above_calendar' ,
''
),
);
if ( is_array ( $calendar_args [ 'view' ] ) ) {
$view_args [ 'request_format' ] = 'html' ;
$calendar_args [ 'view' ] = $view_obj -> get_content ( $view_args );
}
$calendar = $loader -> get_file ( 'calendar.twig' , $calendar_args , false );
// if it's just html, only the calendar html must be returned.
if ( 'html' === $type ) {
return $calendar -> get_content ();
}
// send data both for json and jsonp as shortcodes are jsonp
return array (
'html' => $calendar -> get_content (),
'views_dropdown' => $views_dropdown ,
'subscribe_buttons' => $subscribe_buttons ,
'are_filters_set' => $are_filters_set ,
'is_json' => $is_json
);
}
}
/**
* Render the HTML for the ` subscribe ' buttons .
*
* @ param array $view_args Args to pass .
*
* @ return string Rendered HTML to include in output .
*/
public function get_html_for_subscribe_buttons ( array $view_args ) {
$settings = $this -> _registry -> get ( 'model.settings' );
$turn_off_subscribe = $settings -> get ( 'turn_off_subscription_buttons' );
if ( $turn_off_subscribe ) {
return '' ;
}
$args = array (
'url_args' => '' ,
'is_filtered' => false ,
'export_url' => AI1EC_EXPORT_URL ,
'export_url_no_html' => AI1EC_EXPORT_URL . '&no_html=true' ,
'text_filtered' => Ai1ec_I18n :: __ ( 'Subscribe to filtered calendar' ),
'text_subscribe' => Ai1ec_I18n :: __ ( 'Subscribe' ),
'text_get_calendar' => Ai1ec_I18n :: __ ( 'Get a Timely Calendar' ),
'show_get_calendar' => ! $settings -> get ( 'disable_get_calendar_button' ),
'text' => $this -> _registry
-> get ( 'view.calendar.subscribe-button' )
-> get_labels (),
'placement' => 'up' ,
);
if ( ! empty ( $view_args [ 'cat_ids' ] ) ) {
$args [ 'url_args' ] .= '&ai1ec_cat_ids=' .
implode ( ',' , $view_args [ 'cat_ids' ] );
$args [ 'is_filtered' ] = true ;
}
if ( ! empty ( $view_args [ 'tag_ids' ] ) ) {
$args [ 'url_args' ] .= '&ai1ec_tag_ids=' .
implode ( ',' , $view_args [ 'tag_ids' ] );
$args [ 'is_filtered' ] = true ;
}
if ( ! empty ( $view_args [ 'post_ids' ] ) ) {
$args [ 'url_args' ] .= '&ai1ec_post_ids=' .
implode ( ',' , $view_args [ 'post_ids' ] );
$args [ 'is_filtered' ] = true ;
}
$args = apply_filters (
'ai1ec_subscribe_buttons_arguments' ,
$args ,
$view_args
);
$localization = $this -> _registry -> get ( 'p28n.wpml' );
if (
NULL !== ( $use_lang = $localization -> get_language () )
) {
$args [ 'url_args' ] .= '&lang=' . $use_lang ;
}
$subscribe = $this -> _registry -> get ( 'theme.loader' )
-> get_file ( 'subscribe-buttons.twig' , $args , false );
return $subscribe -> get_content ();
}
/**
* This function generates the html for the view dropdowns .
*
* @ param array $view_args Args passed to view
* @ param Ai1ec_Calendar_View_Abstract $view View object
*/
protected function get_html_for_views_dropdown (
array $view_args ,
Ai1ec_Calendar_View_Abstract $view
) {
$settings = $this -> _registry -> get ( 'model.settings' );
$available_views = array ();
$enabled_views = ( array ) $settings -> get ( 'enabled_views' , array () );
$view_names = array ();
$mode = wp_is_mobile () ? '_mobile' : '' ;
foreach ( $enabled_views as $key => $val ) {
$view_names [ $key ] = translate_nooped_plural (
$val [ 'longname' ],
1
);
// Find out if view is enabled in requested mode (mobile or desktop). If
// no mode-specific setting is available, fall back to desktop setting.
$view_enabled = isset ( $enabled_views [ $key ][ 'enabled' . $mode ] ) ?
$enabled_views [ $key ][ 'enabled' . $mode ] :
$enabled_views [ $key ][ 'enabled' ];
$values = array ();
$options = $view_args ;
if ( $view_enabled ) {
if ( $view instanceof Ai1ec_Calendar_View_Agenda ) {
if (
isset ( $options [ 'exact_date' ] ) &&
! isset ( $options [ 'time_limit' ] )
) {
$options [ 'time_limit' ] = $options [ 'exact_date' ];
}
unset ( $options [ 'exact_date' ] );
} else {
unset ( $options [ 'time_limit' ] );
}
unset ( $options [ 'month_offset' ] );
unset ( $options [ 'week_offset' ] );
unset ( $options [ 'oneday_offset' ] );
$options [ 'action' ] = $key ;
$values [ 'desc' ] = translate_nooped_plural (
$val [ 'longname' ],
1
);
if ( $settings -> get ( 'ai1ec_use_frontend_rendering' ) ) {
$options [ 'request_format' ] = 'json' ;
}
$href = $this -> _registry -> get ( 'html.element.href' , $options );
$values [ 'href' ] = $href -> generate_href ();
$available_views [ $key ] = $values ;
}
};
$args = array (
'view_names' => $view_names ,
'available_views' => $available_views ,
'current_view' => $view_args [ 'action' ],
'data_type' => $view_args [ 'data_type' ],
);
$views_dropdown = $this -> _registry -> get ( 'theme.loader' )
-> get_file ( 'views_dropdown.twig' , $args , false );
return $views_dropdown -> get_content ();
}
/**
* Get the exact date from request if available , or else from settings .
*
* @ param Ai1ec_Abstract_Query settings
*
* @ return boolean | int
*/
private function get_exact_date ( Ai1ec_Abstract_Query $request ) {
$settings = $this -> _registry -> get ( 'model.settings' );
// Preprocess exact_date.
// Check to see if a date has been specified.
$exact_date = $request -> get ( 'exact_date' );
$use_key = $exact_date ;
if ( null === ( $exact_date = $this -> _exact_dates -> get ( $use_key ) ) ) {
$exact_date = $use_key ;
// Let's check if we have a date
if ( false !== $exact_date ) {
// If it's not a timestamp
if ( ! Ai1ec_Validation_Utility :: is_valid_time_stamp ( $exact_date ) ) {
// Try to parse it
$exact_date = $this -> return_gmtime_from_exact_date ( $exact_date );
if ( false === $exact_date ) {
return null ;
}
}
}
// Last try, let's see if an exact date is set in settings.
if ( false === $exact_date && $settings -> get ( 'exact_date' ) !== '' ) {
$exact_date = $this -> return_gmtime_from_exact_date (
$settings -> get ( 'exact_date' )
);
}
$this -> _exact_dates -> set ( $use_key , $exact_date );
}
return $exact_date ;
}
/**
* Decomposes an 'exact_date' parameter into month , day , year components based
* on date pattern defined in settings ( assumed to be in local time zone ),
* then returns a timestamp in GMT .
*
* @ param string $exact_date 'exact_date' parameter passed to a view
* @ return bool | int false if argument not provided or invalid ,
* else UNIX timestamp in GMT
*/
private function return_gmtime_from_exact_date ( $exact_date ) {
$input_format = $this -> _registry -> get ( 'model.settings' )
-> get ( 'input_date_format' );
$date = Ai1ec_Validation_Utility :: format_as_iso (
$exact_date ,
$input_format
);
if ( false === $date ) {
$exact_date = false ;
} else {
$exact_date = $this -> _registry -> get (
'date.time' ,
$date ,
'sys.default'
) -> format_to_gmt ();
if ( $exact_date < 0 ) {
return false ;
}
}
return $exact_date ;
}
/**
* Returns the correct data attribute to use in views
*
* @ param string $type
*/
private function return_data_type_for_request_type ( $type ) {
$data_type = 'data-type="json"' ;
if ( $type === 'jsonp' ) {
$data_type = 'data-type="jsonp"' ;
}
return $data_type ;
}
/**
* Get the parameters for the view from the request object
*
* @ param Ai1ec_Abstract_Query $request
*
* @ return array
*/
protected function get_view_args_for_view ( Ai1ec_Abstract_Query $request ) {
$settings = $this -> _registry -> get ( 'model.settings' );
// Define arguments for specific calendar sub-view (month, agenda, etc.)
// Preprocess action.
// Allow action w/ or w/o ai1ec_ prefix. Remove ai1ec_ if provided.
$action = $request -> get ( 'action' );
if ( 0 === strncmp ( $action , 'ai1ec_' , 6 ) ) {
$action = substr ( $action , 6 );
}
$view_args = $request -> get_dict (
apply_filters (
'ai1ec_view_args_for_view' ,
array (
'post_ids' ,
'auth_ids' ,
'cat_ids' ,
'tag_ids' ,
'events_limit' ,
'instance_ids' ,
)
)
);
$type = $request -> get ( 'request_type' );
if ( 'html' === $type ) {
$add_defaults = array (
'cat_ids' => 'categories' ,
'tag_ids' => 'tags' ,
);
foreach ( $add_defaults as $query => $default ) {
if ( empty ( $view_args [ $query ] ) ) {
$setting = $settings -> get ( 'default_tags_categories' );
if ( isset ( $setting [ $default ] ) ) {
$view_args [ $query ] = $setting [ $default ];
}
}
}
}
$view_args [ 'data_type' ] = $this -> return_data_type_for_request_type (
$type
);
$view_args [ 'request_format' ] = $request -> get ( 'request_format' );
$exact_date = $this -> get_exact_date ( $request );
$view_args [ 'no_navigation' ] = $request -> get ( 'no_navigation' ) == true ;
// Find out which view of the calendar page was requested, and render it
// accordingly.
$view_args [ 'action' ] = $action ;
$view_args [ 'request' ] = $request ;
$view_args = apply_filters (
'ai1ec_view_args_array' ,
$view_args
);
if ( null === $exact_date ) {
$href = $this -> _registry -> get ( 'html.element.href' , $view_args )
-> generate_href ();
return Ai1ec_Http_Response_Helper :: redirect ( $href , 307 );
}
return $view_args ;
}
2017-03-16 16:59:53 +01:00
}