@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user