Add upstream plugins

Signed-off-by: Adrian Nöthlich <git@promasu.tech>
This commit is contained in:
2019-10-25 22:42:20 +02:00
parent 5d3c2ec184
commit 290736650a
1186 changed files with 302577 additions and 0 deletions

View File

@@ -0,0 +1,117 @@
<?php
/**
* The abstract command class.
*
* @author Time.ly Network Inc.
* @since 2.0
*
* @package AI1EC
* @subpackage AI1EC.Command
*/
abstract class Ai1ec_Command {
/**
* @var Ai1ec_Registry_Object
*/
protected $_registry;
/**
* @var Ai1ec_Request_Parser
*/
protected $_request;
/**
* @var Ai1ec_Http_Response_Render_Strategy
*/
protected $_render_strategy;
/**
* Public constructor.
*
* @param Ai1ec_Registry_Object $registry
* @param Ai1ec_Request_Parser $request
*/
public function __construct(
Ai1ec_Registry_Object $registry,
Ai1ec_Request_Parser $request
) {
$this->_registry = $registry;
$this->_request = $request;
}
/**
* Gets parameters from the request object.
*
* @return array|boolean
*/
public function get_parameters() {
$plugin = $controller = $action = null;
$plugin = Ai1ec_Request_Parser::get_param( 'plugin', $plugin );
$controller = Ai1ec_Request_Parser::get_param( 'controller', $controller );
$action = Ai1ec_Request_Parser::get_param( 'action', $action );
if (
is_scalar( $plugin ) &&
(string)AI1EC_PLUGIN_NAME === (string)$plugin &&
null !== $controller &&
null !== $action
) {
return array(
'controller' => $controller,
'action' => $action
);
}
return false;
}
/**
* Execute the command.
*
* @return void
*/
public function execute() {
// Set the render strategy
$this->set_render_strategy( $this->_request );
// get the data from the concrete implementation
$data = $this->do_execute();
// render it.
$this->_render_strategy->render( $data );
}
/**
* Defines whether to stop execution of command loop or not.
*
* @return bool True or false.
*/
public function stop_execution() {
return false;
}
/**
* The abstract method concrete command must implement.
*
* Retrieve whats needed and returns it
*
* @return array
*/
abstract public function do_execute();
/**
* Returns whether this is the command to be executed.
*
* I handle the logi of execution at this levele, which is not usual for
* The front controller pattern, because othe extensions need to inject
* logic into the resolver ( oAuth or ics export for instance )
* and this seems to me to be the most logical way to do this.
*
* @return boolean
*/
abstract public function is_this_to_execute();
/**
* Sets the render strategy.
*
* @param Ai1ec_Request_Parser $request
*/
abstract public function set_render_strategy( Ai1ec_Request_Parser $request );
}

View File

@@ -0,0 +1,38 @@
<?php
/**
* The concrete command that sends sign up data to API
*
* @author Time.ly Network Inc.
* @since 2.4
*
* @package AI1EC
* @subpackage AI1EC.Command
*/
class Ai1ec_Command_Api_Ticketing_Signup extends Ai1ec_Command_Save_Abstract {
/* (non-PHPdoc)
* @see Ai1ec_Command::is_this_to_execute()
*/
public function do_execute() {
$api = $this->_registry->get( 'model.api.api-registration' );
if ( true === isset($_POST['ai1ec_signout']) && '1' === $_POST['ai1ec_signout'] ) {
$api->signout();
} else {
if ( '1' === $_POST['ai1ec_signing'] ) {
$api->signup();
} else {
$api->signin();
}
}
return array(
'url' => ai1ec_admin_url(
'edit.php?post_type=ai1ec_event&page=all-in-one-event-calendar-settings'
),
'query_args' => array(
'message' => ''
),
);
}
}

View File

@@ -0,0 +1,73 @@
<?php
/**
* The concrete command that change active theme.
*
* @author Time.ly Network Inc.
* @since 2.0
*
* @package AI1EC
* @subpackage AI1EC.Command
*/
class Ai1ec_Command_Change_Theme extends Ai1ec_Command {
/**
* Executes the command to change the active theme.
*
* NOTE: {@see self::is_this_to_execute} must return true for this command
* to execute; we can trust that input has been checked for injections.
*/
public function do_execute() {
// Update the active theme in the options table.
$stylesheet = preg_replace(
'|[^a-z_\-]+|i',
'',
$_GET['ai1ec_stylesheet']
);
$this->_registry->get( 'theme.loader' )->switch_theme( array(
'theme_root' => realpath( $_GET['ai1ec_theme_root'] ),
'theme_dir' => realpath( $_GET['ai1ec_theme_dir'] ),
'theme_url' => $_GET['ai1ec_theme_url'],
'stylesheet' => $stylesheet,
'legacy' => false
) );
// Return user to themes list page with success message.
return array(
'url' => ai1ec_admin_url(
'edit.php?post_type=ai1ec_event&page=all-in-one-event-calendar-themes'
),
'query_args' => array(
'activated' => 1
)
);
}
/* (non-PHPdoc)
* @see Ai1ec_Command_Save_Abstract::set_render_strategy()
*/
public function set_render_strategy( Ai1ec_Request_Parser $request ) {
$this->_render_strategy = $this->_registry->get(
'http.response.render.strategy.redirect'
);
}
/* (non-PHPdoc)
* @see Ai1ec_Command::is_this_to_execute()
*/
public function is_this_to_execute() {
if (
isset( $_GET['ai1ec_action'] ) &&
$_GET['ai1ec_action'] === 'activate_theme' &&
current_user_can( 'switch_ai1ec_themes' ) &&
is_dir( $_GET['ai1ec_theme_dir'] ) &&
is_dir( $_GET['ai1ec_theme_root'] )
) {
check_admin_referer(
'switch-ai1ec_theme_' . $_GET['ai1ec_stylesheet']
);
return true;
}
return false;
}
}

View File

@@ -0,0 +1,41 @@
<?php
/**
* The concrete command that compiles CSS.
*
* @author Time.ly Network Inc.
* @since 2.3
*
* @package AI1EC
* @subpackage AI1EC.Command
*/
class Ai1ec_Command_Check_Updates extends Ai1ec_Command {
/*
* (non-PHPdoc) @see Ai1ec_Command::is_this_to_execute()
*/
public function is_this_to_execute() {
return isset( $_GET['ai1ec_force_updates'] );
}
/* (non-PHPdoc)
* @see Ai1ec_Command::set_render_strategy()
*/
public function set_render_strategy( Ai1ec_Request_Parser $request ) {
$this->_render_strategy = $this->_registry->get(
'http.response.render.strategy.redirect'
);
}
/* (non-PHPdoc)
* @see Ai1ec_Command::do_execute()
*/
public function do_execute() {
$this->_registry->get( 'calendar.updates' )->clear_transients();
return array (
'url' => ai1ec_admin_url( 'plugins.php' ),
'query_args' => array ()
);
}
}

View File

@@ -0,0 +1,384 @@
<?php
/**
* The concrete command that clone events.
*
* @author Time.ly Network Inc.
* @since 2.0
*
* @package AI1EC
* @subpackage AI1EC.Command
*/
class Ai1ec_Command_Clone extends Ai1ec_Command {
/**
* @var array The posts that must be cloned
*/
protected $_posts = array();
/**
* @var bool Whether to redirect or not
*/
protected $_redirect = false;
/**
* The abstract method concrete command must implement.
*
* Retrieve whats needed and returns it
*
* @return array
*/
public function do_execute() {
$id = 0;
foreach ( $this->_posts as $post ) {
$id = $this->ai1ec_duplicate_post_create_duplicate(
$post['post'],
$post['status']
);
}
if ( true === $this->_redirect ) {
if ( '' === $post['status'] ) {
return array(
'url' => ai1ec_admin_url(
'edit.php?post_type=' . AI1EC_POST_TYPE
),
'query_args' => array()
);
} else {
return array(
'url' => ai1ec_admin_url(
'post.php?action=edit&post=' . $id
),
'query_args' => array()
);
}
}
// no redirect, just go on with the page
return array();
}
/**
* Returns whether this is the command to be executed.
*
* I handle the logi of execution at this levele, which is not usual for
* The front controller pattern, because othe extensions need to inject
* logic into the resolver ( oAuth or ics export for instance )
* and this seems to me to be the most logical way to do this.
*
* @return boolean
*/
public function is_this_to_execute() {
$current_action = $this->_registry->get(
'http.request'
)->get_current_action();
if (
current_user_can( 'edit_ai1ec_events' ) &&
'clone' === $current_action &&
! empty( $_REQUEST['post'] ) &&
! empty( $_REQUEST['_wpnonce'] ) &&
wp_verify_nonce( $_REQUEST['_wpnonce'], 'bulk-posts' )
) {
foreach ( $_REQUEST['post'] as $post_id ) {
$this->_posts[] = array(
'status' => '',
'post' => get_post( $post_id )
);
}
return true;
}
// other actions need the nonce to be verified
// duplicate single post
if (
$current_action === 'ai1ec_duplicate_post_save_as_new_post' &&
! empty( $_REQUEST['post'] )
) {
check_admin_referer( 'ai1ec_clone_'. $_REQUEST['post'] );
$this->_posts[] = array(
'status' => '',
'post' => get_post( $_REQUEST['post'] )
);
$this->_redirect = true;
return true;
}
// duplicate single post as draft
if (
$current_action === 'ai1ec_duplicate_post_save_as_new_post_draft' &&
! empty( $_REQUEST['post'] )
) {
check_admin_referer( 'ai1ec_clone_'. $_REQUEST['post'] );
$this->_posts[] = array(
'status' => 'draft',
'post' => get_post( $_REQUEST['post'] )
);
$this->_redirect = true;
return true;
}
return false;
}
/**
* Sets the render strategy.
*
* @param Ai1ec_Request_Parser $request
*/
public function set_render_strategy( Ai1ec_Request_Parser $request ) {
if ( true === $this->_redirect ) {
$this->_render_strategy = $this->_registry
->get( 'http.response.render.strategy.redirect' );
} else {
$this->_render_strategy = $this->_registry
->get( 'http.response.render.strategy.void' );
}
}
/**
* Create a duplicate from a posts' instance
*/
public function ai1ec_duplicate_post_create_duplicate( $post, $status = '' ) {
$post = get_post( $post );
$new_post_author = $this->_ai1ec_duplicate_post_get_current_user();
$new_post_status = $status;
if ( empty( $new_post_status ) ) {
$new_post_status = $post->post_status;
}
$new_post_status = $this->_get_new_post_status( $new_post_status );
$new_post = array(
'menu_order' => $post->menu_order,
'comment_status' => $post->comment_status,
'ping_status' => $post->ping_status,
'pinged' => $post->pinged,
'post_author' => $new_post_author->ID,
'post_content' => $post->post_content,
'post_date' => $post->post_date,
'post_date_gmt' => get_gmt_from_date( $post->post_date ),
'post_excerpt' => $post->post_excerpt,
'post_parent' => $post->post_parent,
'post_password' => $post->post_password,
'post_status' => $new_post_status,
'post_title' => $post->post_title,
'post_type' => $post->post_type,
'to_ping' => $post->to_ping,
);
$new_post_id = wp_insert_post( $new_post );
$edit_event_url = esc_attr(
ai1ec_admin_url( "post.php?post={$new_post_id}&action=edit" )
);
$message = sprintf(
__( '<p>The event <strong>%s</strong> was cloned succesfully. <a href="%s">Edit cloned event</a></p>', AI1EC_PLUGIN_NAME ),
$post->post_title,
$edit_event_url
);
$notification = $this->_registry->get( 'notification.admin' );
$notification->store( $message );
$this->_ai1ec_duplicate_post_copy_post_taxonomies( $new_post_id, $post );
$this->_ai1ec_duplicate_post_copy_attachments( $new_post_id, $post );
$this->_ai1ec_duplicate_post_copy_post_meta_info( $new_post_id, $post );
$api = $this->_registry->get( 'model.api.api-ticketing' );
$api->clear_event_metadata( $new_post_id );
if ( $this->_registry->get( 'acl.aco' )->is_our_post_type( $post ) ) {
try {
$old_event = $this->_registry->get( 'model.event', $post->ID );
$old_event->set( 'post_id', $new_post_id );
$old_event->set( 'post', null );
$old_event->set( 'ical_feed_url', null );
$old_event->set( 'ical_source_url', null );
$old_event->set( 'ical_organizer', null );
$old_event->set( 'ical_contact', null );
$old_event->set( 'ical_uid', null );
$old_event->save();
} catch ( Ai1ec_Event_Not_Found_Exception $exception ) {
/* ignore */
}
}
$meta_post = $this->_registry->get( 'model.meta-post' );
$meta_post->delete( $new_post_id, '_dp_original' );
$meta_post->add( $new_post_id, '_dp_original', $post->ID );
// If the copy gets immediately published, we have to set a proper slug.
if (
$new_post_status == 'publish' ||
$new_post_status == 'future'
) {
$post_name = wp_unique_post_slug(
$post->post_name,
$new_post_id,
$new_post_status,
$post->post_type,
$post->post_parent
);
$new_post = array();
$new_post['ID'] = $new_post_id;
$new_post['post_name'] = $post_name;
// Update the post into the database
wp_update_post( $new_post );
}
return $new_post_id;
}
/**
* Copy the meta information of a post to another post
*/
protected function _ai1ec_duplicate_post_copy_post_meta_info( $new_id, $post ) {
$post_meta_keys = get_post_custom_keys( $post->ID );
if ( empty( $post_meta_keys ) ) {
return;
}
foreach ( $post_meta_keys as $meta_key ) {
$meta_values = get_post_custom_values( $meta_key, $post->ID );
foreach ( $meta_values as $meta_value ) {
$meta_value = maybe_unserialize( $meta_value );
$meta_value = apply_filters(
'ai1ec_duplicate_post_meta_value',
$meta_value,
$meta_key,
$post,
$new_id
);
if ( null !== $meta_value ) {
add_post_meta( $new_id, $meta_key, $meta_value );
}
}
}
}
/**
* Copy the attachments
* It simply copies the table entries, actual file won't be duplicated
*/
protected function _ai1ec_duplicate_post_copy_attachments( $new_id, $post ) {
//if (get_option('ai1ec_duplicate_post_copyattachments') == 0) return;
// get old attachments
$attachments = get_posts(
array(
'post_type' => 'attachment',
'numberposts' => -1,
'post_status' => null,
'post_parent' => $post->ID,
)
);
// clone old attachments
foreach ( $attachments as $att ) {
$new_att_author = $this->_ai1ec_duplicate_post_get_current_user();
$new_att = array(
'menu_order' => $att->menu_order,
'comment_status' => $att->comment_status,
'guid' => $att->guid,
'ping_status' => $att->ping_status,
'pinged' => $att->pinged,
'post_author' => $new_att_author->ID,
'post_content' => $att->post_content,
'post_date' => $att->post_date,
'post_date_gmt' => get_gmt_from_date( $att->post_date ),
'post_excerpt' => $att->post_excerpt,
'post_mime_type' => $att->post_mime_type,
'post_parent' => $new_id,
'post_password' => $att->post_password,
'post_status' => $this->_get_new_post_status(
$att->post_status
),
'post_title' => $att->post_title,
'post_type' => $att->post_type,
'to_ping' => $att->to_ping,
);
$new_att_id = wp_insert_post( $new_att );
// get and apply a unique slug
$att_name = wp_unique_post_slug(
$att->post_name,
$new_att_id,
$att->post_status,
$att->post_type,
$new_id
);
$new_att = array();
$new_att['ID'] = $new_att_id;
$new_att['post_name'] = $att_name;
wp_update_post( $new_att );
}
}
/**
* Copy the taxonomies of a post to another post
*/
protected function _ai1ec_duplicate_post_copy_post_taxonomies( $new_id, $post ) {
$db = $this->_registry->get( 'dbi.dbi' );
if ( $db->are_terms_set() ) {
// Clear default category (added by wp_insert_post)
wp_set_object_terms( $new_id, NULL, 'category' );
$post_taxonomies = get_object_taxonomies( $post->post_type );
$taxonomies_blacklist = array();
$taxonomies = array_diff( $post_taxonomies, $taxonomies_blacklist );
foreach ( $taxonomies as $taxonomy ) {
$post_terms = wp_get_object_terms(
$post->ID,
$taxonomy,
array( 'orderby' => 'term_order' )
);
$terms = array();
for ( $i = 0; $i < count( $post_terms ); $i++ ) {
$terms[] = $post_terms[ $i ]->slug;
}
wp_set_object_terms( $new_id, $terms, $taxonomy );
}
}
}
/**
* Get the currently registered user
*/
protected function _ai1ec_duplicate_post_get_current_user() {
if ( function_exists( 'wp_get_current_user' ) ) {
return wp_get_current_user();
} else {
$db = $this->_registry->get( 'dbi.dbi' );
$query = $db->prepare(
'SELECT * FROM ' . $wpdb->users . ' WHERE user_login = %s',
$_COOKIE[ USER_COOKIE ]
);
$current_user = $db->get_results( $query );
return $current_user;
}
}
/**
* Get the status for `duplicate' post
*
* If user cannot publish post (event), and original post status is
* *publish*, then it will be duplicated with *pending* status.
* In other cases original status will remain.
*
* @param string $old_status Status of old post
*
* @return string Status for new post
*/
protected function _get_new_post_status( $old_status ) {
if (
'publish' === $old_status &&
! current_user_can( 'publish_ai1ec_events' )
) {
return 'pending';
}
return $old_status;
}
}

View File

@@ -0,0 +1,100 @@
<?php
/**
* The concrete command that compiles CSS.
*
* @author Time.ly Network Inc.
* @since 2.1
*
* @package AI1EC
* @subpackage AI1EC.Command
*/
class Ai1ec_Command_Compile_Core_Css extends Ai1ec_Command {
/*
* (non-PHPdoc) @see Ai1ec_Command::is_this_to_execute()
*/
public function is_this_to_execute() {
if ( isset( $_GET['ai1ec_compile_css'] ) &&
AI1EC_DEBUG
) {
return true;
}
return false;
}
/* (non-PHPdoc)
* @see Ai1ec_Command::set_render_strategy()
*/
public function set_render_strategy( Ai1ec_Request_Parser $request ) {
$this->_render_strategy = $this->_registry->get(
'http.response.render.strategy.void'
);
}
/* (non-PHPdoc)
* @see Ai1ec_Command::do_execute()
*/
public function do_execute() {
$message = $this->_process_files();
echo $message;
return Ai1ec_Http_Response_Helper::stop( 0 );
}
/**
* Returns calendar theme structure.
*
* @param string $stylesheet Calendar stylesheet. Expects one of
* ['vortex','plana','umbra','gamma'].
* @return array Calendar themes.
*
* @throws Ai1ec_Invalid_Argument_Exception
*/
protected function _get_theme( $stylesheet ) {
return $this->_registry->get(
'filesystem.misc'
)->build_theme_structure( $stylesheet );
}
/**
* Returns PHP code with hashmap array.
*
* @param $hashmap Array with compilation hashes.
*
* @return string PHP code.
*/
protected function _get_hashmap_array( $hashmap ) {
return '<?php return ' . var_export( $hashmap, true ) . ';';
}
protected function _process_files() {
$less = $frontend = $this->_registry->get( 'less.lessphp' );
$option = $this->_registry->get( 'model.option' );
$theme = $this->_get_theme( $_GET['theme'] );
if ( isset( $_GET['switch'] ) ) {
$option->delete( 'ai1ec_less_variables' );
$option->set( 'ai1ec_current_theme', $theme );
return 'Theme switched to "' . $theme['stylesheet'] . '".';
}
$css = $less->parse_less_files( null, true );
$hashmap = $less->get_less_hashmap();
$hashmap = $this->_get_hashmap_array( $hashmap );
$filename = $theme['theme_dir'] . DIRECTORY_SEPARATOR .
'css' . DIRECTORY_SEPARATOR . 'ai1ec_parsed_css.css';
$hashmap_file = $theme['theme_dir'] . DIRECTORY_SEPARATOR .
'less.sha1.map.php';
$css_written = file_put_contents( $filename, $css );
$hashmap_written = file_put_contents( $hashmap_file, $hashmap );
if (
false === $css_written ||
false === $hashmap_written
) {
return 'There has been an error writing theme CSS';
}
return 'Theme CSS compiled succesfully and written in ' .
$filename . ' and classmap stored in ' . $hashmap_file;
}
}

View File

@@ -0,0 +1,41 @@
<?php
/**
* (Re)compile themes for shipping.
*
* @author Time.ly Network Inc.
* @since 2.1
*
* @package AI1EC
* @subpackage AI1EC.Command
*/
class Ai1ec_Command_Compile_Themes extends Ai1ec_Command {
/*
* (non-PHPdoc) @see Ai1ec_Command::is_this_to_execute()
*/
public function is_this_to_execute() {
return (
AI1EC_DEBUG &&
isset( $_GET['ai1ec_recompile_templates'] )
);
}
/* (non-PHPdoc)
* @see Ai1ec_Command::set_render_strategy()
*/
public function set_render_strategy( Ai1ec_Request_Parser $request ) {
$this->_render_strategy = $this->_registry->get(
'http.response.render.strategy.void'
);
}
/* (non-PHPdoc)
* @see Ai1ec_Command::do_execute()
*/
public function do_execute() {
$this->_registry->get( 'theme.compiler' )->generate();
return Ai1ec_Http_Response_Helper::stop( 0 );
}
}

View File

@@ -0,0 +1,47 @@
<?php
/**
* The concrete command that disabel gzip.
*
* @author Time.ly Network Inc.
* @since 2.0
*
* @package AI1EC
* @subpackage AI1EC.Command
*/
class Ai1ec_Command_Disable_Gzip extends Ai1ec_Command {
/* (non-PHPdoc)
* @see Ai1ec_Command::is_this_to_execute()
*/
public function is_this_to_execute() {
if ( isset( $_GET['ai1ec_disable_gzip_compression'] ) ) {
check_admin_referer( 'ai1ec_disable_gzip_compression' );
return true;
}
return false;
}
/* (non-PHPdoc)
* @see Ai1ec_Command::do_execute()
*/
public function do_execute() {
$this->_registry->get( 'model.settings' )
->set( 'disable_gzip_compression', true );
return array(
'url' => ai1ec_admin_url( 'edit.php' ),
'query_args' => array(
'post_type' => 'ai1ec_event',
'page' => 'all-in-one-event-calendar-settings',
),
);
}
/* (non-PHPdoc)
* @see Ai1ec_Command::set_render_strategy()
*/
public function set_render_strategy( Ai1ec_Request_Parser $request ) {
$this->_render_strategy = $this->_registry->get(
'http.response.render.strategy.redirect'
);
}
}

View File

@@ -0,0 +1,159 @@
<?php
/**
* The concrete command that export events.
*
* @author Time.ly Network Inc.
* @since 2.0
*
* @package AI1EC
* @subpackage AI1EC.Command
*/
class Ai1ec_Command_Export_Events extends Ai1ec_Command {
/**
* @var string The name of the old exporter controller.
*/
const EXPORT_CONTROLLER = 'ai1ec_exporter_controller';
/**
* @var string The name of the old export method.
*/
const EXPORT_METHOD = 'export_events';
/**
* @var array Request parameters
*/
protected $_params;
/* (non-PHPdoc)
* @see Ai1ec_Command::is_this_to_execute()
*/
public function is_this_to_execute() {
$params = $this->get_parameters();
if ( false === $params ) {
return false;
}
if ( $params['action'] === self::EXPORT_METHOD &&
$params['controller'] === self::EXPORT_CONTROLLER ) {
$params['tag_ids'] = Ai1ec_Request_Parser::get_param(
'ai1ec_tag_ids',
false
);
$params['cat_ids'] = Ai1ec_Request_Parser::get_param(
'ai1ec_cat_ids',
false
);
$params['post_ids'] = Ai1ec_Request_Parser::get_param(
'ai1ec_post_ids',
false
);
$params['lang'] = Ai1ec_Request_Parser::get_param(
'lang',
false
);
$params['no_html'] = (bool)Ai1ec_Request_Parser::get_param(
'no_html',
false
);
$params['xml'] = (bool)Ai1ec_Request_Parser::get_param(
'xml',
false
);
$this->_params = $params;
return true;
}
return false;
}
/* (non-PHPdoc)
* @see Ai1ec_Command::set_render_strategy()
*/
public function set_render_strategy( Ai1ec_Request_Parser $request ) {
if ( isset( $_GET['xml']) ) {
$this->_render_strategy = $this->_registry->get(
'http.response.render.strategy.xcal'
);
} else {
$this->_render_strategy = $this->_registry->get(
'http.response.render.strategy.ical'
);
}
}
/* (non-PHPdoc)
* @see Ai1ec_Command::do_execute()
*/
public function do_execute() {
$ai1ec_cat_ids = $this->_params['cat_ids'];
$ai1ec_tag_ids = $this->_params['tag_ids'];
$ai1ec_post_ids = $this->_params['post_ids'];
if ( ! empty( $this->_params['lang'] ) ) {
$loc_helper = $this->_registry->get( 'p28n.wpml' );
$loc_helper->set_language( $this->_params['lang'] );
}
$args = array( 'do_not_export_as_calendar' => false );
$filter = array();
if ( $ai1ec_cat_ids ) {
$filter['cat_ids'] = Ai1ec_Primitive_Int::convert_to_int_list(
',',
$ai1ec_cat_ids
);
}
if ( $ai1ec_tag_ids ) {
$filter['tag_ids'] = Ai1ec_Primitive_Int::convert_to_int_list(
',',
$ai1ec_tag_ids
);
}
if ( $ai1ec_post_ids ) {
$args['do_not_export_as_calendar'] = true;
$filter['post_ids'] = Ai1ec_Primitive_Int::convert_to_int_list(
',',
$ai1ec_post_ids
);
}
$filter = apply_filters( 'ai1ec_export_filter', $filter );
$start = $this->_registry->get( 'date.time', '-3 years' );
$end = $this->_registry->get( 'date.time', '+3 years' );
$search = $this->_registry->get( 'model.search' );
$params = array(
'no_html' => $this->_params['no_html'],
'xml' => $this->_params['xml'],
);
$export_controller = $this->_registry->get(
'controller.import-export',
array( 'ics' ),
$params
);
$args['events'] = $this->unique_events(
$search->get_events_between( $start, $end, $filter )
);
$ics = $export_controller->export_events( 'ics', $args );
return array( 'data' => $ics );
}
/**
* Return unique events list.
*
* @param array $events List of Ai1ec_Event objects.
*
* @return array Unique Ai1ec_Events from input.
*/
public function unique_events( array $events ) {
$ids = array();
$output = array();
foreach ( $events as $event ) {
$id = (int)$event->get( 'post_id' );
if ( ! isset( $ids[$id] ) ) {
$output[] = $event;
$ids[$id] = true;
}
}
return $output;
}
}

View File

@@ -0,0 +1,83 @@
<?php
/**
* The concrete command that renders the calendar.
*
* @author Time.ly Network Inc.
* @since 2.0
*
* @package AI1EC
* @subpackage AI1EC.Command
*/
class Ai1ec_Command_Render_Calendar extends Ai1ec_Command {
/**
* @var string
*/
protected $_request_type;
/* (non-PHPdoc)
* @see Ai1ec_Command::is_this_to_execute()
*/
public function is_this_to_execute() {
$settings = $this->_registry->get( 'model.settings' );
$calendar_page_id = $settings->get( 'calendar_page_id' );
if ( empty( $calendar_page_id ) ) {
return false;
}
$localization = $this->_registry->get( 'p28n.wpml' );
$aco = $this->_registry->get( 'acl.aco' );
$page_ids_to_match = array( $calendar_page_id ) +
$localization->get_translations_of_page(
$calendar_page_id
);
foreach ( $page_ids_to_match as $page_id ) {
if ( is_page( $page_id ) ) {
$this->_request->set_current_page( $page_id );
if ( ! post_password_required( $page_id ) ) {
return true;
}
}
}
return false;
}
/* (non-PHPdoc)
* @see Ai1ec_Command::set_render_strategy()
*/
public function set_render_strategy( Ai1ec_Request_Parser $request ) {
try {
$this->_request_type = $request->get( 'request_type' );
$this->_render_strategy = $this->_registry->get(
'http.response.render.strategy.' . $this->_request_type
);
} catch ( Ai1ec_Bootstrap_Exception $e ) {
$this->_request_type = 'html';
$this->_render_strategy = $this->_registry->get(
'http.response.render.strategy.' . $this->_request_type
);
}
}
/* (non-PHPdoc)
* @see Ai1ec_Command::do_execute()
*/
public function do_execute() {
// get the calendar html
$calendar = $this->_registry->get( 'view.calendar.page' );
$css = $this->_registry->get( 'css.frontend' )
->add_link_to_html_for_frontend();
$js = $this->_registry->get( 'controller.javascript' )
->load_frontend_js( true );
return array(
'data' => $calendar->get_content( $this->_request ),
'callback' => Ai1ec_Request_Parser::get_param(
'callback',
null
),
'caller' => 'calendar',
);
}
}

View File

@@ -0,0 +1,75 @@
<?php
/**
* The concrete command that renders the event.
*
* @author Time.ly Network Inc.
* @since 2.0
*
* @package AI1EC
* @subpackage AI1EC.Command
*/
class Ai1ec_Command_Render_Event extends Ai1ec_Command_Render_Calendar {
/* (non-PHPdoc)
* @see Ai1ec_Command::is_this_to_execute()
*/
public function is_this_to_execute() {
global $post;
if (
! isset( $post ) ||
! is_object( $post ) ||
(int)$post->ID <= 0 ||
post_password_required( $post->ID )
) {
return false;
}
return $this->_registry->get( 'acl.aco' )->is_our_post_type();
}
/* (non-PHPdoc)
* @see Ai1ec_Command::do_execute()
*/
public function do_execute() {
// If not on the single event page, return nothing.
if ( ! is_single() ) {
return array(
'data' => '',
'is_event' => true,
);
}
// Else proceed with rendering valid event. Fetch all relevant details.
$instance = -1;
if ( isset( $_REQUEST['instance_id'] ) ) {
$instance = (int)$_REQUEST['instance_id'];
}
$event = $this->_registry->get(
'model.event',
get_the_ID(),
$instance
);
$event_page = $this->_registry->get( 'view.event.single' );
$footer_html = $event_page->get_footer( $event );
$css = $this->_registry->get( 'css.frontend' )
->add_link_to_html_for_frontend();
$js = $this->_registry->get( 'controller.javascript' )
->load_frontend_js( false );
// If requesting event by JSON (remotely), return fully rendered event.
if ( 'html' !== $this->_request_type ) {
return array(
'data' => array(
'html' => $event_page->get_full_article( $event, $footer_html )
),
'callback' => Ai1ec_Request_Parser::get_param( 'callback', null ),
);
}
// Else return event details as components.
return array(
'data' => $event_page->get_content( $event ),
'is_event' => true,
'footer' => $footer_html,
);
}
}

View File

@@ -0,0 +1,154 @@
<?php
/**
* The command resolver class that handles command.
*
* @author Time.ly Network Inc.
* @since 2.0
*
* @package AI1EC
* @subpackage AI1EC.Command
*/
class Ai1ec_Command_Resolver {
/**
* @var array The available commands.
*/
private $_commands = array();
/**
* @var Ai1ec_Registry_Object The Object registry.
*/
private $_registry;
/**
* @var Ai1ec_Request_Parser The Request parser.
*/
private $_request;
/**
* Public constructor
*
* @param Ai1ec_Registry_Object $registry
* @param Ai1ec_Request_Parser $request
*
* @return void
*/
public function __construct(
Ai1ec_Registry_Object $registry,
Ai1ec_Request_Parser $request
) {
$this->add_command(
$registry->get(
'command.compile-themes', $request
)
);
$this->add_command(
$registry->get(
'command.disable-gzip', $request
)
);
$this->add_command(
$registry->get(
'command.export-events', $request
)
);
$this->add_command(
$registry->get(
'command.render-event', $request
)
);
$this->add_command(
$registry->get(
'command.render-calendar', $request
)
);
$this->add_command(
$registry->get(
'command.change-theme', $request
)
);
$this->add_command(
$registry->get(
'command.save-settings',
$request,
array(
'action' => 'ai1ec_save_settings',
'nonce_action' => Ai1ec_View_Admin_Settings::NONCE_ACTION,
'nonce_name' => Ai1ec_View_Admin_Settings::NONCE_NAME,
)
)
);
$this->add_command(
$registry->get(
'command.save-theme-options',
$request,
array(
'action' => 'ai1ec_save_theme_options',
'nonce_action' => Ai1ec_View_Theme_Options::NONCE_ACTION,
'nonce_name' => Ai1ec_View_Theme_Options::NONCE_NAME,
)
)
);
$this->add_command(
$registry->get(
'command.api-ticketing-signup',
$request,
array(
'action' => 'ai1ec_api_ticketing_signup',
'nonce_action' => Ai1ec_View_Tickets::NONCE_ACTION,
'nonce_name' => Ai1ec_View_Tickets::NONCE_NAME,
)
)
);
$this->add_command(
$registry->get(
'command.clone', $request
)
);
$this->add_command(
$registry->get(
'command.compile-core-css', $request
)
);
if (
is_admin() &&
current_user_can( 'activate_plugins' )
) {
$this->add_command(
$registry->get(
'command.check-updates', $request
)
);
}
$request->parse();
$this->_registry = $registry;
$this->_request = $request;
}
/**
* Add a command.
*
* @param Ai1ec_Command $command
*
* @return Ai1ec_Comment_Resolver Self for calls chaining
*/
public function add_command( Ai1ec_Command $command ) {
$this->_commands[] = $command;
return $this;
}
/**
* Return the command to execute or false.
*
* @return Ai1ec_Command|null
*/
public function get_commands() {
$commands = array();
foreach ( $this->_commands as $command ) {
if ( $command->is_this_to_execute() ) {
$commands[] = $command;
}
}
return $commands;
}
}

View File

@@ -0,0 +1,74 @@
<?php
/**
* The abstract command that save something in the admin.
*
* @author Time.ly Network Inc.
* @since 2.0
*
* @package AI1EC
* @subpackage AI1EC.Command
*/
abstract class Ai1ec_Command_Save_Abstract extends Ai1ec_Command {
protected $_controller = 'front';
protected $_action;
protected $_nonce_name;
protected $_nonce_action;
/**
* Public constructor, set the strategy according to the type.
*
* @param Ai1ec_Registry_Object $registry
* @param Ai1ec_Request_Parser $request
*/
public function __construct(
Ai1ec_Registry_Object $registry,
Ai1ec_Request_Parser $request,
array $args
) {
parent::__construct( $registry, $request );
if ( ! is_array( $args['action'] ) ) {
$args['action'] = array(
$args['action'] => true,
);
}
$this->_action = $args['action'];
$this->_nonce_action = $args['nonce_action'];
$this->_nonce_name = $args['nonce_name'];
}
/* (non-PHPdoc)
* @see Ai1ec_Command::is_this_to_execute()
*/
public function is_this_to_execute() {
$params = $this->get_parameters();
if ( false === $params ) {
return false;
}
if ( $params['controller'] === $this->_controller &&
isset( $this->_action[$params['action']] ) ) {
$pass = wp_verify_nonce(
$_POST[$this->_nonce_name],
$this->_nonce_action
);
if ( ! $pass ) {
wp_die( "Failed security check" );
}
return true;
}
return false;
}
/* (non-PHPdoc)
* @see Ai1ec_Command::set_render_strategy()
*/
public function set_render_strategy( Ai1ec_Request_Parser $request ) {
$this->_render_strategy = $this->_registry->get(
'http.response.render.strategy.redirect'
);
}
}

View File

@@ -0,0 +1,175 @@
<?php
/**
* The concrete command that save settings.
*
* @author Time.ly Network Inc.
* @since 2.0
*
* @package AI1EC
* @subpackage AI1EC.Command
*/
class Ai1ec_Command_Save_Settings extends Ai1ec_Command_Save_Abstract {
/* (non-PHPdoc)
* @see Ai1ec_Command::do_execute()
*/
public function do_execute() {
$settings = $this->_registry->get( 'model.settings' );
$options = $settings->get_options();
$_POST['default_tags_categories'] = (
isset( $_POST['default_tags_categories_default_categories'] ) ||
isset( $_POST['default_tags_categories_default_tags'] )
);
// set some a variable to true to trigger the saving.
$_POST['enabled_views'] = true;
// let other plugin modify the post
$_POST = apply_filters( 'ai1ec_before_save_settings', $_POST );
foreach ( $options as $name => $data ) {
$value = null;
if ( isset( $_POST[$name] ) ) {
// if a validator is pecified, use it.
if ( isset( $data['renderer']['validator'] ) ) {
$validator = $this->_registry->get(
'validator.' . $data['renderer']['validator'],
$_POST[$name]
);
try {
$value = $validator->validate();
} catch ( Ai1ec_Value_Not_Valid_Exception $e ) {
// don't save
continue;
}
} else {
switch ( $data['type'] ) {
case 'bool':
$value = true;
break;
case 'int':
$value = (int)$_POST[$name];
break;
case 'string':
$value = (string)$_POST[$name];
break;
case 'array':
$method = '_handle_saving_' . $name;
$value = null;
if ( method_exists( $this, $method ) ) {
$value = $this->$method();
}
$value = apply_filters(
'ai1ec' . $method,
$value,
$_REQUEST
);
break;
case 'mixed':
$method = '_handle_saving_' . $name;
$value = null;
if ( method_exists( $this, $method ) ) {
$value = $this->$method( $_POST[$name] );
}
$value = apply_filters(
'ai1ec' . $method,
$value,
$_REQUEST
);
break;
case 'wp_option': // set the corresponding WP option
$this->_registry->get( 'model.option' )
->set( $name, $_POST[$name], true );
$value = (string)$_POST[$name];
}
}
} else {
if ( isset( $data['type'] ) && 'bool' === $data['type'] ) {
$value = false;
}
}
if ( null !== $value ) {
$settings->set( $name, stripslashes_deep( $value ) );
}
}
$new_options = $settings->get_options();
// let extension manipulate things if needed.
do_action( 'ai1ec_settings_updated', $options, $new_options );
$settings->persist();
$api = $this->_registry->get( 'model.api.api-registration' );
$api->check_settings( true );
return array(
'url' => ai1ec_admin_url(
'edit.php?post_type=ai1ec_event&page=all-in-one-event-calendar-settings'
),
'query_args' => array(
'updated' => 1
)
);
}
/**
* Handle saving enabled_views.
*
* @return array
*/
protected function _handle_saving_enabled_views() {
$settings = $this->_registry->get( 'model.settings' );
$enabled_views = $settings->get( 'enabled_views' );
foreach ( $enabled_views as $view => &$options ) {
$options['enabled'] = isset( $_POST['view_' . $view . '_enabled'] );
$options['default'] = isset( $_POST['default_calendar_view'] )
? $_POST['default_calendar_view'] === $view
: false;
$options['enabled_mobile'] =
isset( $_POST['view_' . $view . '_enabled_mobile'] );
$options['default_mobile'] =
isset( $_POST['default_calendar_view_mobile'] ) &&
$_POST['default_calendar_view_mobile'] === $view;
}
return $enabled_views;
}
/**
* Handle saving default_tag_categories option
*
* @return array
*/
protected function _handle_saving_default_tags_categories() {
return array(
'tags' => isset( $_POST['default_tags_categories_default_tags'] ) ?
$_POST['default_tags_categories_default_tags'] :
array(),
'categories' => isset( $_POST['default_tags_categories_default_categories'] ) ?
$_POST['default_tags_categories_default_categories'] :
array(),
);
}
/**
* Creates the calendar page if a string is passed.
*
* @param int|string $calendar_page
*
* @return int
*/
protected function _handle_saving_calendar_page_id( $calendar_page ) {
if (
! is_numeric( $calendar_page ) &&
preg_match( '#^__auto_page:(.*?)$#', $calendar_page, $matches )
) {
return wp_insert_post(
array(
'post_title' => $matches[1],
'post_type' => 'page',
'post_status' => 'publish',
'comment_status' => 'closed'
)
);
} else {
return (int)$calendar_page;
}
}
}

View File

@@ -0,0 +1,70 @@
<?php
/**
* The concrete command that save theme options.
*
* @author Time.ly Network Inc.
* @since 2.0
*
* @package AI1EC
* @subpackage AI1EC.Command
*/
class Ai1ec_Command_Save_Theme_Options extends Ai1ec_Command_Save_Abstract {
/* (non-PHPdoc)
* @see Ai1ec_Command::is_this_to_execute()
*/
public function do_execute() {
$variables = array();
// Handle updating of theme options.
if ( isset( $_POST[Ai1ec_View_Theme_Options::SUBMIT_ID] ) ) {
$_POST = stripslashes_deep( $_POST );
$lessphp = $this->_registry->get( 'less.lessphp' );
$variables = $lessphp->get_saved_variables();
foreach ( $variables as $variable_name => $variable_params ) {
if ( isset( $_POST[$variable_name] ) ) {
// Avoid problems for those who are foolish enough to leave php.ini
// settings at their defaults, which has magic quotes enabled.
if ( get_magic_quotes_gpc() ) {
$_POST[$variable_name] = stripslashes( $_POST[$variable_name] );
}
if (
Ai1ec_Less_Variable_Font::CUSTOM_FONT === $_POST[$variable_name]
) {
$_POST[$variable_name] = $_POST[$variable_name .
Ai1ec_Less_Variable_Font::CUSTOM_FONT_ID_SUFFIX];
}
// update the original array
$variables[$variable_name]['value'] = $_POST[$variable_name];
}
}
$_POST = add_magic_quotes( $_POST );
}
// Handle reset of theme options.
elseif ( isset( $_POST[Ai1ec_View_Theme_Options::RESET_ID] ) ) {
$option = $this->_registry->get( 'model.option' );
$option->delete( 'ai1ec_less_variables' );
$option->delete( 'ai1ec_render_css' );
do_action( 'ai1ec_reset_less_variables' );
}
$css = $this->_registry->get( 'css.frontend' );
$css->update_variables_and_compile_css(
$variables,
isset(
$_POST[Ai1ec_View_Theme_Options::RESET_ID]
)
);
return array(
'url' => ai1ec_admin_url(
'edit.php?post_type=ai1ec_event&page=all-in-one-event-calendar-edit-css'
),
'query_args' => array(),
);
}
}