2017-03-16 16:59:53 +01:00
< ? php
/**
* The front controller of the plugin .
*
* @ author Time . ly Network Inc .
* @ since 2.0
*
* @ package AI1EC
* @ subpackage AI1EC . Controller
*/
class Ai1ec_Front_Controller {
2017-11-09 17:36:04 +01:00
/**
* @ var Ai1ec_Registry_Object The Object registry .
*/
protected $_registry ;
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
/**
* @ var bool Whether the domain has alredy been loaded or not .
*/
protected $_domain_loaded = false ;
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
/**
* @ var string The pagebase used by Ai1ec_Href_Helper .
*/
protected $_pagebase_for_href ;
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
/**
* @ var Ai1ec_Request_Parser Instance of the request pa
*/
protected $_request ;
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
/**
* @ var array
*/
protected $_default_theme ;
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
/**
* Initializes the default theme property .
*/
public function __construct () {
// Initialize default theme.
$this -> _default_theme = array (
'theme_dir' => AI1EC_DEFAULT_THEME_PATH ,
'theme_root' => AI1EC_DEFAULT_THEME_ROOT ,
'theme_url' => AI1EC_THEMES_URL . '/' . AI1EC_DEFAULT_THEME_NAME ,
'stylesheet' => AI1EC_DEFAULT_THEME_NAME ,
'legacy' => false ,
);
}
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
/**
* Initialize the controller .
*
* @ param Ai1ec_Loader $ai1ec_loader Instance of Ai1EC classes loader
*
* @ return void
*/
public function initialize ( $ai1ec_loader ) {
ai1ec_start ();
$this -> _init ( $ai1ec_loader );
$this -> _initialize_dispatcher ();
$lessphp = $this -> _registry -> get ( 'less.lessphp' );
$lessphp -> initialize_less_variables_if_not_set ();
$this -> _registry -> get ( 'controller.shutdown' )
-> register ( 'ai1ec_stop' );
add_action ( 'plugins_loaded' , array ( $this , 'register_extensions' ), 1 );
add_action ( 'after_setup_theme' , array ( $this , 'register_themes' ), 1 );
add_action ( 'init' , array ( $lessphp , 'invalidate_css_cache_if_requested' ) );
}
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
/**
* Let other objects access default theme
*
* @ return array
*/
public function get_default_theme () {
return $this -> _default_theme ;
}
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
/**
* Remove unwanted menus
*/
public function admin_menu () {
remove_submenu_page (
'edit.php?post_type=ai1ec_event' ,
'edit-tags.php?taxonomy=events_tags&post_type=ai1ec_event'
);
}
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
/**
* Notify extensions and pass them instance of objects registry .
*
* @ return void
*/
public function register_extensions () {
do_action ( 'ai1ec_loaded' , $this -> _registry );
}
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
/**
* Notify themes and pass them instance of objects registry .
*
* @ return void
*/
public function register_themes () {
do_action ( 'ai1ec_after_themes_setup' , $this -> _registry );
}
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
/**
* Returns the registry object
*
* @ param mixed $discard not used . Always return the registry .
*
* @ return Ai1ec_Registry_Object
*/
public function return_registry ( $discard ) {
return $this -> _registry ;
}
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
/**
* If WIDGET_PARAMETER is set .
*
* @ return boolean
*/
protected function is_widget () {
return isset (
$_GET [ Ai1ec_Controller_Javascript_Widget :: WIDGET_PARAMETER ]
);
}
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
/**
* If Advanced JS cache enabled .
*
* @ return boolean
*/
protected function if_js_cache_enabled () {
$settings = $this -> _registry -> get ( 'model.settings' );
return $settings -> get ( 'cache_dynamic_js' );
}
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
/**
* If LEGACY_WIDGET_PARAMETER is set .
*
* @ return boolean
*/
protected function is_legacy_widget () {
return isset (
$_GET [ Ai1ec_Controller_Javascript_Widget :: LEGACY_WIDGET_PARAMETER ]
);
}
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
/**
* Execute commands if our plugin must handle the request .
*
* @ wp_hook init
*
* @ return void
*/
public function route_request () {
$this -> _process_request ();
// get the resolver
$resolver = $this -> _registry -> get (
'command.resolver' ,
$this -> _request
);
// get the command
$commands = $resolver -> get_commands ();
// if we have a command
if ( ! empty ( $commands ) ) {
foreach ( $commands as $command ) {
$result = $command -> execute ();
if ( $command -> stop_execution () ) {
return $result ;
}
}
}
}
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
/**
* Initializes the URL router used by our plugin .
*
* @ wp_hook init
*
* @ return void
*/
public function initialize_router () {
/* @var $cal_state Ai1ec_Calendar_State */
$cal_state = $this -> _registry -> get ( 'calendar.state' );
$cal_state -> set_routing_initialization ( true );
$settings = $this -> _registry -> get ( 'model.settings' );
$cal_page = $settings -> get ( 'calendar_page_id' );
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
if (
! $cal_page ||
$cal_page < 1
) { // Routing may not be affected in any way if no calendar page exists.
$cal_state -> set_routing_initialization ( false );
return null ;
}
$router = $this -> _registry -> get ( 'routing.router' );
$localization_helper = $this -> _registry -> get ( 'p28n.wpml' );
$page_base = '' ;
$clang = '' ;
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
if ( $localization_helper -> is_wpml_active () ) {
$trans = $localization_helper
-> get_wpml_translations_of_page (
$cal_page ,
true
);
$clang = $localization_helper -> get_language ();
if ( isset ( $trans [ $clang ] ) ) {
$cal_page = $trans [ $clang ];
}
}
$template_link_helper = $this -> _registry -> get ( 'template.link.helper' );
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
if ( ! get_post ( $cal_page ) ) {
$cal_state -> set_routing_initialization ( false );
return null ;
}
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
$page_base = $template_link_helper -> get_page_link (
$cal_page
);
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
$page_base = Ai1ec_Wp_Uri_Helper :: get_pagebase ( $page_base );
$page_link = 'index.php?page_id=' .
$cal_page ;
$pagebase_for_href = Ai1ec_Wp_Uri_Helper :: get_pagebase_for_links (
get_page_link ( $cal_page ),
$clang
);
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
// save the pagebase to set up the factory later
$application = $this -> _registry -> get ( 'bootstrap.registry.application' );
$application -> set ( 'calendar_base_page' , $pagebase_for_href );
$option = $this -> _registry -> get ( 'model.option' );
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
// If the calendar is set as the front page, disable permalinks.
// They would not be legal under a Windows server. See:
// https://issues.apache.org/bugzilla/show_bug.cgi?id=41441
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
if (
$option -> get ( 'permalink_structure' ) &&
( int ) get_option ( 'page_on_front' ) !==
( int ) $cal_page
) {
$application -> set ( 'permalinks_enabled' , true );
}
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
$router -> asset_base ( $page_base )
-> register_rewrite ( $page_link );
$cal_state -> set_routing_initialization ( false );
}
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
/**
* Initialize the system .
*
* Perform all the inizialization needed for the system .
* Throws some uncatched exception for critical failures .
* Plugin will be disabled by the exception handler on those failures .
*
* @ param Ai1ec_Loader $ai1ec_loader Instance of Ai1EC classes loader
*
* @ throws Ai1ec_Constants_Not_Set_Exception
* @ throws Ai1ec_Database_Update_Exception
* @ throws Ai1ec_Database_Schema_Exception
*
* @ return void Method does not return
*/
protected function _init ( $ai1ec_loader ) {
$exception = null ;
// Load the textdomain
add_action ( 'plugins_loaded' , array ( $this , 'load_textdomain' ) );
try {
// Initialize the registry object
$this -> _initialize_registry ( $ai1ec_loader );
$this -> _registry -> get ( 'event.dispatcher' ) -> register_filter (
'ai1ec_perform_scheme_update' ,
array ( 'database.datetime-migration' , 'filter_scheme_update' )
);
// Procedures to take when upgrading plugin version
$this -> _plugin_upgrade_procedures ();
// Load the css if needed
$this -> _load_css_if_needed ();
// Initialize the crons
$this -> _install_crons ();
// Register the activation hook
$this -> _initialize_schema ();
// set the default theme if not set
$this -> _add_default_theme_if_not_set ();
} catch ( Ai1ec_Constants_Not_Set_Exception $e ) {
// This is blocking, throw it and disable the plugin
$exception = $e ;
} catch ( Ai1ec_Database_Update_Exception $e ) {
// Blocking throw it so that the plugin is disabled
$exception = $e ;
} catch ( Ai1ec_Database_Schema_Exception $e ) {
// Blocking throw it so that the plugin is disabled
$exception = $e ;
} catch ( Ai1ec_Scheduling_Exception $e ) {
// not blocking
}
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
if ( null !== $exception ) {
throw $exception ;
}
}
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
/**
* Set the default theme if no theme is set , or populate theme info array if
* insufficient information is currently being stored .
*
* @ uses apply_filters () Calls 'ai1ec_pre_save_current_theme' hook to allow
* overwriting of theme information before being stored .
*/
protected function _add_default_theme_if_not_set () {
$option = $this -> _registry -> get ( 'model.option' );
$theme = $option -> get ( 'ai1ec_current_theme' , array () );
$update = false ;
// Theme setting is undefined; default to Vortex.
if ( empty ( $theme ) ) {
$theme = $this -> _default_theme ;
$update = true ;
}
// Legacy settings; in 1.x the active theme was stored as a bare string,
// and they were located in a different folder than they are now.
else if ( is_string ( $theme ) ) {
$theme_name = strtolower ( $theme );
$core_themes = explode ( ',' , AI1EC_CORE_THEMES );
$legacy = ! in_array ( $theme_name , $core_themes );
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
if ( $legacy ) {
$root = WP_CONTENT_DIR . DIRECTORY_SEPARATOR . AI1EC_THEME_FOLDER ;
$url = WP_CONTENT_URL . '/' . AI1EC_THEME_FOLDER . '/' . $theme_name ;
} else {
$root = AI1EC_DEFAULT_THEME_ROOT ;
$url = AI1EC_THEMES_URL . '/' . $theme_name ;
}
// if it's from 1.x, move folders to avoid confusion
if ( apply_filters ( 'ai1ec_move_themes_to_backup' , true ) ) {
$this -> _registry -> get ( 'theme.search' )
-> move_themes_to_backup ( $core_themes );
}
// Ensure existence of theme directory.
if ( ! is_dir ( $root . DIRECTORY_SEPARATOR . $theme_name ) ) {
// It's missing; something is wrong with this theme. Reset theme to
// Vortex and warn the user accordingly.
$option -> set ( 'ai1ec_current_theme' , $this -> _default_theme );
$notification = $this -> _registry -> get ( 'notification.admin' );
$notification -> store (
sprintf (
Ai1ec_I18n :: __ (
'Your active calendar theme could not be properly initialized. The default theme has been activated instead. Please visit %s and try reactivating your theme manually.'
),
'<a href="' . ai1ec_admin_url ( AI1EC_THEME_SELECTION_BASE_URL ) . '">' .
Ai1ec_I18n :: __ ( 'Calendar Themes' ) . '</a>'
),
'error' ,
1
);
}
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
$theme = array (
'theme_dir' => $root . DIRECTORY_SEPARATOR . $theme_name ,
'theme_root' => $root ,
'theme_url' => $url ,
'stylesheet' => $theme_name ,
'legacy' => $legacy ,
);
$update = true ;
}
// Ensure 'theme_url' is defined, as this property was added after the first
// public beta release.
else if ( ! isset ( $theme [ 'theme_url' ] ) ) {
if ( $theme [ 'legacy' ] ) {
$theme [ 'theme_url' ] = WP_CONTENT_URL . '/' . AI1EC_THEME_FOLDER . '/' .
$theme [ 'stylesheet' ];
} else {
$theme [ 'theme_url' ] = AI1EC_THEMES_URL . '/' . $theme [ 'stylesheet' ];
}
$update = true ;
}
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
if ( $update ) {
$theme = apply_filters ( 'ai1ec_pre_save_current_theme' , $theme );
$option -> set ( 'ai1ec_current_theme' , $theme );
}
}
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
/**
* Adds actions handled by the front controller .
*/
protected function _add_front_controller_actions () {
// Initialize router. I use add_action as the dispatcher would just add
// overhead.
add_action (
'init' ,
array ( $this , 'initialize_router' ),
PHP_INT_MAX - 1
);
add_action (
'widgets_init' ,
array ( 'Ai1ec_View_Admin_Widget' , 'register_widget' )
);
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
if (
$this -> is_widget () ||
$this -> is_legacy_widget ()
) {
$this -> _registry -> get ( 'event.dispatcher' ) -> register_action (
'init' ,
array ( 'controller.javascript-widget' , 'render_js_widget' ),
PHP_INT_MAX
);
}
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
// Route the request.
$action = 'template_redirect' ;
if ( is_admin () ) {
$action = 'init' ;
add_action ( 'admin_menu' , array ( $this , 'admin_menu' ) );
}
add_action ( $action , array ( $this , 'route_request' ) );
add_filter ( 'ai1ec_registry' , array ( $this , 'return_registry' ) );
}
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
/**
* Initialize the dispatcher .
*
* Complete this when writing the dispatcher .
*
* @ return void
*/
protected function _initialize_dispatcher () {
$dispatcher = $this -> _registry -> get ( 'event.dispatcher' );
$dispatcher -> register_action (
'init' ,
array ( 'post.custom-type' , 'register' )
);
$this -> _add_front_controller_actions ();
if ( isset ( $_GET [ Ai1ec_Javascript_Controller :: LOAD_JS_PARAMETER ] ) ) {
$dispatcher -> register_action (
'wp_loaded' ,
array ( 'controller.javascript' , 'render_js' )
);
}
$dispatcher -> register_action (
'before_delete_post' ,
array ( 'model.event.trashing' , 'before_delete_post' ),
0 ,
3
);
$dispatcher -> register_action (
'delete_post' ,
array ( 'model.event.trashing' , 'delete' )
);
$dispatcher -> register_action (
'wp_trash_post' ,
array ( 'model.event.trashing' , 'trash_post' )
);
$dispatcher -> register_action (
'trashed_post' ,
array ( 'model.event.trashing' , 'trashed_post' )
);
$dispatcher -> register_action (
'untrash_post' ,
array ( 'model.event.trashing' , 'untrash_post' )
);
$dispatcher -> register_action (
'untrashed_post' ,
array ( 'model.event.trashing' , 'untrashed_post' )
);
$dispatcher -> register_action (
'pre_http_request' ,
array ( 'http.request' , 'pre_http_request' ),
10 ,
3
);
$dispatcher -> register_action (
'http_request_args' ,
array ( 'http.request' , 'init_certificate' ),
10 ,
2
);
// add the filter to let the organize page work
$dispatcher -> register_action (
'admin_init' ,
array ( 'view.admin.organize' , 'add_taxonomy_actions' ),
10000
);
$dispatcher -> register_action (
'plugins_loaded' ,
array ( 'theme.loader' , 'clean_cache_on_upgrade' ),
PHP_INT_MAX
);
$dispatcher -> register_filter (
'get_the_excerpt' ,
array ( 'view.event.content' , 'event_excerpt' ),
11
);
remove_filter ( 'the_excerpt' , 'wpautop' , 10 );
$dispatcher -> register_filter (
'the_excerpt' ,
array ( 'view.event.content' , 'event_excerpt_noautop' ),
11
);
$dispatcher -> register_filter (
'robots_txt' ,
array ( 'robots.helper' , 'rules' ),
10 ,
2
);
$dispatcher -> register_filter (
'ai1ec_dbi_debug' ,
array ( 'http.request' , 'debug_filter' )
);
$dispatcher -> register_filter (
'ai1ec_dbi_debug' ,
array ( 'compatibility.cli' , 'disable_db_debug' )
);
// editing a child instance
if ( isset ( $_SERVER [ 'SCRIPT_NAME' ] ) && basename ( $_SERVER [ 'SCRIPT_NAME' ] ) === 'post.php' ) {
$dispatcher -> register_action (
'admin_action_editpost' ,
array ( 'model.event.parent' , 'admin_init_post' )
);
$dispatcher -> register_filter (
'user_has_cap' ,
array ( 'content.filter' , 'display_trash_link' ),
10 ,
2
);
}
// post row action for parent/child
$dispatcher -> register_action (
'post_row_actions' ,
array ( 'model.event.parent' , 'post_row_actions' ),
100 ,
2
);
// Category colors
$dispatcher -> register_action (
'events_categories_add_form_fields' ,
array ( 'view.admin.event-category' , 'events_categories_add_form_fields' )
);
$dispatcher -> register_action (
'events_categories_edit_form_fields' ,
array ( 'view.admin.event-category' , 'events_categories_edit_form_fields' )
);
$dispatcher -> register_action (
'created_events_categories' ,
array ( 'view.admin.event-category' , 'created_events_categories' )
);
$dispatcher -> register_action (
'edited_events_categories' ,
array ( 'view.admin.event-category' , 'edited_events_categories' )
);
$dispatcher -> register_action (
'manage_edit-events_categories_columns' ,
array ( 'view.admin.event-category' , 'manage_event_categories_columns' )
);
$dispatcher -> register_action (
'manage_events_categories_custom_column' ,
array ( 'view.admin.event-category' , 'manage_events_categories_custom_column' ),
10 ,
3
);
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
// register ICS cron action
$dispatcher -> register_action (
Ai1ecIcsConnectorPlugin :: HOOK_NAME ,
array ( 'calendar-feed.ics' , 'cron' )
);
$dispatcher -> register_shortcode (
'ai1ec' ,
array ( 'view.calendar.shortcode' , 'shortcode' )
);
$dispatcher -> register_action (
'updated_option' ,
array ( 'model.settings' , 'wp_options_observer' ),
PHP_INT_MAX - 1 ,
3
);
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
$dispatcher -> register_action (
'ai1ec_settings_updated' ,
array ( 'compatibility.check' , 'ai1ec_settings_observer' ),
PHP_INT_MAX - 1 ,
2
);
if ( $this -> if_js_cache_enabled () ) {
$dispatcher -> register_action (
'ai1ec_settings_updated' ,
array ( 'controller.javascript' , 'revalidate_cache' ),
PHP_INT_MAX - 1
);
$dispatcher -> register_action (
'ai1ec_settings_updated' ,
array ( 'controller.javascript-widget' , 'revalidate_cache' ),
PHP_INT_MAX - 1
);
}
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
if ( is_admin () ) {
// Import suggested event
$dispatcher -> register_action (
'wp_ajax_ai1ec_import_suggested_event' ,
array ( 'calendar-feed.ics' , 'add_discover_events_feed_subscription' )
);
// Remove suggested event
$dispatcher -> register_action (
'wp_ajax_ai1ec_remove_suggested_event' ,
array ( 'calendar-feed.ics' , 'delete_individual_event_subscription' )
);
// Search for events
$dispatcher -> register_action (
'wp_ajax_ai1ec_search_events' ,
array ( 'calendar-feed.suggested' , 'search_events' )
);
// get the repeat box
$dispatcher -> register_action (
'wp_ajax_ai1ec_get_repeat_box' ,
array ( 'view.admin.get-repeat-box' , 'get_repeat_box' )
);
// get the tax options box
$dispatcher -> register_action (
'wp_ajax_ai1ec_get_tax_box' ,
array ( 'view.admin.get-tax-box' , 'get_tax_box' )
);
// add dismissable notice handler
$dispatcher -> register_action (
'wp_ajax_ai1ec_dismiss_notice' ,
array ( 'notification.admin' , 'dismiss_notice' )
);
// save rrurle and convert it to text
$dispatcher -> register_action (
'wp_ajax_ai1ec_rrule_to_text' ,
array ( 'view.admin.get-repeat-box' , 'convert_rrule_to_text' )
);
// display ticketing details in the events list
$dispatcher -> register_action (
'wp_ajax_ai1ec_show_ticket_details' ,
array ( 'view.admin.all-events' , 'show_ticket_details' )
);
// display attendees list
$dispatcher -> register_action (
'wp_ajax_ai1ec_show_attendees' ,
array ( 'view.admin.all-events' , 'show_attendees' )
);
// CSS and templates for ticketing options
$dispatcher -> register_action (
'restrict_manage_posts' ,
array ( 'view.admin.all-events' , 'add_ticketing_styling' )
);
// taxonomy filter
$dispatcher -> register_action (
'restrict_manage_posts' ,
array ( 'view.admin.all-events' , 'taxonomy_filter_restrict_manage_posts' )
);
$dispatcher -> register_action (
'parse_query' ,
array ( 'view.admin.all-events' , 'taxonomy_filter_post_type_request' )
);
$dispatcher -> register_action (
'admin_menu' ,
array ( 'view.admin.calendar-feeds' , 'add_page' )
);
$dispatcher -> register_action (
'current_screen' ,
array ( 'view.admin.calendar-feeds' , 'add_meta_box' )
);
$dispatcher -> register_action (
'admin_menu' ,
array ( 'view.admin.add-ons' , 'add_page' )
);
$dispatcher -> register_action (
'admin_menu' ,
array ( 'view.admin.theme-switching' , 'add_page' )
);
$dispatcher -> register_action (
'admin_menu' ,
array ( 'view.admin.theme-options' , 'add_page' )
);
$dispatcher -> register_action (
'current_screen' ,
array ( 'view.admin.theme-options' , 'add_meta_box' )
);
$dispatcher -> register_action (
'admin_menu' ,
array ( 'view.admin.settings' , 'add_page' )
);
$dispatcher -> register_action (
'current_screen' ,
array ( 'view.admin.settings' , 'add_meta_box' )
);
$dispatcher -> register_action (
'init' ,
array ( 'controller.javascript' , 'load_admin_js' )
);
$dispatcher -> register_action (
'admin_menu' ,
array ( 'view.admin.samples' , 'add_page' ),
100 ,
1
);
$dispatcher -> register_action (
'wp_ajax_ai1ec_add_ics' ,
array ( 'calendar-feed.ics' , 'add_ics_feed' )
);
$dispatcher -> register_action (
'wp_ajax_ai1ec_delete_ics' ,
array ( 'calendar-feed.ics' , 'delete_feeds_and_events' )
);
$dispatcher -> register_action (
'wp_ajax_ai1ec_update_ics' ,
array ( 'calendar-feed.ics' , 'update_ics_feed' )
);
$dispatcher -> register_action (
'wp_ajax_ai1ec_feeds_page_post' ,
array ( 'calendar-feed.ics' , 'handle_feeds_page_post' )
);
$dispatcher -> register_action (
'wp_ajax_ai1ec_send_feedback_message' ,
array ( 'model.review' , 'send_feedback_message' )
);
$dispatcher -> register_action (
'wp_ajax_ai1ec_save_feedback_review' ,
array ( 'model.review' , 'save_feedback_review' )
);
$dispatcher -> register_action (
'network_admin_notices' ,
array ( 'notification.admin' , 'send' )
);
$dispatcher -> register_action (
'admin_notices' ,
array ( 'notification.admin' , 'send' )
);
$dispatcher -> register_action (
'admin_footer-edit.php' ,
array ( 'clone.renderer-helper' , 'duplicate_custom_bulk_admin_footer' )
);
$dispatcher -> register_filter (
'post_row_actions' ,
array ( 'clone.renderer-helper' , 'ai1ec_duplicate_post_make_duplicate_link_row' ),
100 ,
2
);
$dispatcher -> register_action (
'add_meta_boxes' ,
array ( 'view.admin.add-new-event' , 'event_meta_box_container' )
);
$dispatcher -> register_action (
'edit_form_after_title' ,
array ( 'view.admin.add-new-event' , 'event_inline_alert' )
);
$dispatcher -> register_action (
'save_post' ,
array ( 'model.event.creating' , 'save_post' ),
10 ,
3
);
$dispatcher -> register_action (
'pre_post_update' ,
array ( 'model.event.creating' , 'pre_post_update' ),
0 ,
2
);
$dispatcher -> register_action (
'wp_insert_post_data' ,
array ( 'model.event.creating' , 'wp_insert_post_data' )
);
$dispatcher -> register_action (
'manage_ai1ec_event_posts_custom_column' ,
array ( 'view.admin.all-events' , 'custom_columns' ),
10 ,
2
);
$dispatcher -> register_filter (
'manage_ai1ec_event_posts_columns' ,
array ( 'view.admin.all-events' , 'change_columns' )
);
$dispatcher -> register_filter (
'manage_edit-ai1ec_event_sortable_columns' ,
array ( 'view.admin.all-events' , 'sortable_columns' )
);
$dispatcher -> register_filter (
'posts_orderby' ,
array ( 'view.admin.all-events' , 'orderby' ),
10 ,
2
);
$dispatcher -> register_filter (
'ai1ec_count_future_events' ,
array ( 'view.admin.all-events' , 'count_future_events' ),
10 ,
1
);
$dispatcher -> register_filter (
'post_updated_messages' ,
array ( 'view.event.post' , 'post_updated_messages' )
);
add_action ( 'admin_head' , array ( $this , 'admin_head' ) );
$dispatcher -> register_action (
'plugin_action_links_' . AI1EC_PLUGIN_BASENAME ,
array ( 'view.admin.nav' , 'plugin_action_links' )
);
$dispatcher -> register_action (
'wp_ajax_ai1ec_rescan_cache' ,
array ( 'twig.cache' , 'rescan' )
);
$dispatcher -> register_action (
'admin_init' ,
array ( 'environment.check' , 'run_checks' )
);
$dispatcher -> register_action (
'activated_plugin' ,
array ( 'environment.check' , 'check_addons_activation' )
);
$dispatcher -> register_filter (
'upgrader_post_install' ,
array ( 'environment.check' , 'check_bulk_addons_activation' )
);
if ( $this -> if_js_cache_enabled () ) {
$dispatcher -> register_action (
'activated_plugin' ,
array ( 'controller.javascript' , 'revalidate_cache' )
);
$dispatcher -> register_action (
'deactivated_plugin' ,
array ( 'controller.javascript' , 'revalidate_cache' )
);
$dispatcher -> register_action (
'upgrader_post_install' ,
array ( 'controller.javascript' , 'revalidate_cache' )
);
$dispatcher -> register_action (
'activated_plugin' ,
array ( 'controller.javascript-widget' , 'revalidate_cache' )
);
$dispatcher -> register_action (
'deactivated_plugin' ,
array ( 'controller.javascript-widget' , 'revalidate_cache' )
);
$dispatcher -> register_action (
'upgrader_post_install' ,
array ( 'controller.javascript-widget' , 'revalidate_cache' )
);
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
}
// Widget Creator
$dispatcher -> register_action (
'admin_enqueue_scripts' ,
array ( 'css.admin' , 'admin_enqueue_scripts' )
);
$dispatcher -> register_action (
'current_screen' ,
array ( 'view.admin.widget-creator' , 'add_meta_box' )
);
$dispatcher -> register_action (
'admin_menu' ,
array ( 'view.admin.widget-creator' , 'add_page' )
);
$dispatcher -> register_filter (
'pre_set_site_transient_update_plugins' ,
array ( 'calendar.updates' , 'check_updates' )
);
$dispatcher -> register_filter (
'plugins_api' ,
array ( 'calendar.updates' , 'plugins_api_filter' ),
10 ,
3
);
$dispatcher -> register_action (
'admin_menu' ,
array ( 'view.admin.tickets' , 'add_page' )
);
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
} else { // ! is_admin()
$dispatcher -> register_action (
'after_setup_theme' ,
array ( 'theme.loader' , 'execute_theme_functions' )
);
$dispatcher -> register_action (
'the_post' ,
array ( 'post.content' , 'check_content' ),
PHP_INT_MAX
);
$dispatcher -> register_action (
'send_headers' ,
array ( 'request.redirect' , 'handle_categories_and_tags' )
);
$dispatcher -> register_action (
'wp_head' ,
array ( 'view.event.single' , 'add_meta_tags' )
);
}
}
/**
* Outputs menu icon between head tags
*/
public function admin_head () {
global $wp_version ;
$argv = array (
'before_font_icons' => version_compare ( $wp_version , '3.8' , '<' ),
'admin_theme_img_url' => AI1EC_ADMIN_THEME_IMG_URL ,
'admin_theme_font_url' => AI1EC_ADMIN_THEME_FONT_URL ,
);
$this -> _registry -> get ( 'theme.loader' )
-> get_file ( 'timely-menu-icon.twig' , $argv , true )
-> render ();
}
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
/**
* _add_defaults method
*
* Add ( merge ) default options to given query variable .
*
* @ param string settingsquery variable to ammend
*
* @ return string | NULL Modified variable values or NULL on failure
*
* @ global Ai1ec_Settings $ai1ec_settings Instance of settings object
* to pull data from
* @ staticvar array $mapper Mapping of query names to
* default in settings
*/
protected function _add_defaults ( $name ) {
$settings = $this -> _registry -> get ( 'model.settings' );
static $mapper = array (
'cat' => 'categories' ,
'tag' => 'tags' ,
);
$rq_name = 'ai1ec_' . $name . '_ids' ;
if (
! isset ( $mapper [ $name ] ) ||
! array_key_exists ( $rq_name , $this -> _request )
) {
return NULL ;
}
$options = explode ( ',' , $this -> _request [ $rq_name ] );
$property = 'default_' . $mapper [ $name ];
$options = array_merge (
$options ,
$settings -> get ( $property )
);
$filtered = array ();
foreach ( $options as $item ) { // avoid array_filter + is_numeric
$item = ( int ) $item ;
if ( $item > 0 ) {
$filtered [] = $item ;
}
}
unset ( $options );
if ( empty ( $filtered ) ) {
return NULL ;
}
return implode ( ',' , $filtered );
}
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
/**
* Process_request function .
*
* Initialize / validate custom request array , based on contents of $_REQUEST ,
* to keep track of this component ' s request variables .
*
* @ return void
**/
protected function _process_request () {
$settings = $this -> _registry -> get ( 'model.settings' );
$this -> _request = $this -> _registry -> get ( 'http.request.parser' );
$aco = $this -> _registry -> get ( 'acl.aco' );
$page_id = $settings -> get ( 'calendar_page_id' );
if (
! $aco -> is_admin () &&
$page_id &&
is_page ( $page_id )
) {
foreach ( array ( 'cat' , 'tag' ) as $name ) {
$implosion = $this -> _add_defaults ( $name );
if ( $implosion ) {
$this -> request [ 'ai1ec_' . $name . '_ids' ] = $implosion ;
$_REQUEST [ 'ai1ec_' . $name . '_ids' ] = $implosion ;
}
}
}
}
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
/**
* Initialize cron functions .
*
* @ throws Ai1ec_Scheduling_Exception
*
* @ return void
*/
protected function _install_crons () {
$scheduling = $this -> _registry -> get ( 'scheduling.utility' );
$hook_name = 'ai1ec_n_cron' ;
$scheduling -> delete ( $hook_name );
}
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
/**
* Initialize the registry object .
*
* @ param Ai1ec_Loader $ai1ec_loader Instance of Ai1EC classes loader
*
* @ return void Method does not return
*/
protected function _initialize_registry ( $ai1ec_loader ) {
global $ai1ec_registry ;
$this -> _registry = new Ai1ec_Registry_Object ( $ai1ec_loader );
Ai1ec_Time_Utility :: set_registry ( $this -> _registry );
$ai1ec_registry = $this -> _registry ;
}
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
/**
* Loads the CSS for the plugin
*
*/
protected function _load_css_if_needed () {
// ==================================
// = Add the hook to render the css =
// ==================================
if ( isset ( $_GET [ Ai1ec_Css_Frontend :: QUERY_STRING_PARAM ] ) ) {
// we need to wait for the extension to be registered if the css
// needs to be compiled. Will find a better way when compiling css.
$css_controller = $this -> _registry -> get ( 'css.frontend' );
add_action ( 'plugins_loaded' , array ( $css_controller , 'render_css' ), 2 );
}
}
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
/**
* Load the texdomain for the plugin .
*
* @ wp_hook plugins_loaded
*
* @ return void
*/
public function load_textdomain () {
if ( false === $this -> _domain_loaded ) {
load_plugin_textdomain (
AI1EC_PLUGIN_NAME , false , AI1EC_LANGUAGE_PATH
);
$this -> _domain_loaded = true ;
}
}
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
/**
* Check if the schema is up to date .
*
* @ throws Ai1ec_Database_Schema_Exception
* @ throws Ai1ec_Database_Update_Exception
*
* @ return void
*/
protected function _initialize_schema () {
$option = $this -> _registry -> get ( 'model.option' );
$schema_sql = $this -> get_current_db_schema ();
$version = sha1 ( $schema_sql );
// If existing DB version is not consistent with current plugin's version,
// or does not exist, then create/update table structure using dbDelta().
if ( $option -> get ( 'ai1ec_db_version' ) != $version ) {
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
$errors = $this -> _registry -> get ( 'database.applicator' )
-> check_db_consistency_for_date_migration () ;
if ( ! empty ( $errors ) ) {
$message = Ai1ec_I18n :: __ (
'Your database is found to be corrupt. Likely previous update has failed. Please restore All-in-One Event Calendar tables from a backup and retry.<br>Following errors were found:<br>%s'
);
$message = sprintf ( $message , implode ( $errors , '<br>' ) );
throw new Ai1ec_Database_Update_Exception ( $message );
}
$this -> _registry -> get ( 'database.applicator' )
-> remove_instance_duplicates ();
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
if (
apply_filters ( 'ai1ec_perform_scheme_update' , true ) &&
$this -> _registry -> get ( 'database.helper' ) -> apply_delta (
$schema_sql
)
) {
$option -> set ( 'ai1ec_db_version' , $version );
} else {
throw new Ai1ec_Database_Update_Exception ();
}
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
// If the schema structure upgrade is complete move contents
$categories_key = 'ai1ec_category_meta_ported' ;
if ( ! $option -> get ( $categories_key ) ) {
$this -> _migrate_categories_meta ();
$option -> set ( $categories_key , true );
}
}
}
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
/**
* Transform categories meta information .
*
* Use new `meta` table instead of legacy `colors` table .
*
* @ return void Method does not return .
*/
protected function _migrate_categories_meta () {
$db = $this -> _registry -> get ( 'dbi.dbi' );
$table_name = $db -> get_table_name ( 'ai1ec_event_category_colors' );
$db_h = $this -> _registry -> get ( 'database.helper' );
if ( $db_h -> table_exists ( $table_name ) ) { // if old table exists otherwise ignore it
// Migrate color information
$dest_table = $db -> get_table_name ( 'ai1ec_event_category_meta' );
$colors = $db -> select (
$table_name ,
array ( 'term_id' , 'term_color' ),
ARRAY_A
);
if ( ! empty ( $colors ) ) {
foreach ( $colors as $color ) {
$db -> insert ( $dest_table , $color );
}
}
// Drop the old table
$db -> query ( 'DROP TABLE IF EXISTS ' . $table_name );
}
}
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
/**
* Procedures to take when upgrading plugin version
*
* @ return void
*/
protected function _plugin_upgrade_procedures () {
$option = $this -> _registry -> get ( 'model.option' );
$version = AI1EC_VERSION ;
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
if ( $option -> get ( 'ai1ec_version' ) != $version ) {
try {
// Force regeneration of JS cache
$this -> _registry -> get ( 'controller.javascript' ) -> revalidate_cache ();
$this -> _registry -> get ( 'controller.javascript-widget' ) -> revalidate_cache ();
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
// Run upgrade commands
$settings = $this -> _registry -> get ( 'model.settings' );
$settings -> perform_upgrade_actions ();
} catch ( Exception $e ) {
}
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
// Update plugin version
$option -> set ( 'ai1ec_version' , $version );
}
}
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
/**
* Get current database schema as a multi SQL statement .
*
* @ return string Multiline SQL statement .
*/
public function get_current_db_schema () {
$dbi = $this -> _registry -> get ( 'dbi.dbi' );
// =======================
// = Create table events =
// =======================
$table_name = $dbi -> get_table_name ( 'ai1ec_events' );
$sql = " CREATE TABLE $table_name (
post_id bigint ( 20 ) NOT NULL ,
start int ( 10 ) UNSIGNED NOT NULL ,
end int ( 10 ) UNSIGNED ,
timezone_name varchar ( 50 ),
allday tinyint ( 1 ) NOT NULL ,
instant_event tinyint ( 1 ) NOT NULL DEFAULT 0 ,
recurrence_rules longtext ,
exception_rules longtext ,
recurrence_dates longtext ,
exception_dates longtext ,
venue varchar ( 255 ),
country varchar ( 255 ),
address varchar ( 255 ),
city varchar ( 255 ),
province varchar ( 255 ),
postal_code varchar ( 32 ),
show_map tinyint ( 1 ),
contact_name varchar ( 255 ),
contact_phone varchar ( 32 ),
contact_email varchar ( 128 ),
contact_url varchar ( 255 ),
cost varchar ( 255 ),
ticket_url varchar ( 255 ),
ical_feed_url varchar ( 255 ),
ical_source_url varchar ( 255 ),
ical_organizer varchar ( 255 ),
ical_contact varchar ( 255 ),
ical_uid varchar ( 255 ),
show_coordinates tinyint ( 1 ),
latitude decimal ( 20 , 15 ),
longitude decimal ( 20 , 15 ),
force_regenerate tinyint ( 1 ) NOT NULL DEFAULT 0 ,
PRIMARY KEY ( post_id ),
KEY feed_source ( ical_feed_url )
) CHARACTER SET utf8 ; " ;
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
// ==========================
// = Create table instances =
// ==========================
$table_name = $dbi -> get_table_name ( 'ai1ec_event_instances' );
$sql .= " CREATE TABLE $table_name (
id bigint ( 20 ) NOT NULL AUTO_INCREMENT ,
post_id bigint ( 20 ) NOT NULL ,
start int ( 10 ) UNSIGNED NOT NULL ,
end int ( 10 ) UNSIGNED NOT NULL ,
PRIMARY KEY ( id ),
UNIQUE KEY evt_instance ( post_id , start )
) CHARACTER SET utf8 ; " ;
2017-03-16 16:59:53 +01:00
2017-11-09 17:36:04 +01:00
// ================================
// = Create table category colors =
// ================================
$table_name = $dbi -> get_table_name ( 'ai1ec_event_category_meta' );
$sql .= " CREATE TABLE $table_name (
term_id bigint ( 20 ) NOT NULL ,
term_color varchar ( 255 ) NOT NULL ,
term_image varchar ( 254 ) NULL DEFAULT NULL ,
PRIMARY KEY ( term_id )
) CHARACTER SET utf8 ; " ;
return $sql ;
}
2017-03-16 16:59:53 +01:00
}