_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( __( '

The event %s was cloned succesfully. Edit cloned event

', 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; } }