post_type ) { return $actions; } if ( ! current_user_can( 'edit_post', $post->ID ) ) { return $actions; } $post_type_obj = get_post_type_object( 'stacklar' ); $create_cap = ( $post_type_obj && isset( $post_type_obj->cap->create_posts ) ) ? $post_type_obj->cap->create_posts : 'edit_posts'; if ( ! current_user_can( $create_cap ) ) { return $actions; } $url = add_query_arg( array( 'action' => self::ACTION_DUPLICATE, 'form_id' => $post->ID, ), admin_url( 'admin-post.php' ) ); $url = wp_nonce_url( $url, self::ACTION_DUPLICATE . '_' . $post->ID ); $actions['stacklar_duplicate'] = '' . esc_html__( 'Duplicate', 'stacklar-forms' ) . ''; return $actions; } public function handle_duplicate() { $form_id = isset( $_REQUEST['form_id'] ) ? absint( $_REQUEST['form_id'] ) : 0; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- the nonce below is bound to this form ID. check_admin_referer( self::ACTION_DUPLICATE . '_' . $form_id ); if ( ! $form_id ) { wp_die( esc_html__( 'Missing form ID.', 'stacklar-forms' ) ); } if ( ! current_user_can( 'edit_post', $form_id ) ) { wp_die( esc_html__( 'You are not allowed to duplicate this form.', 'stacklar-forms' ) ); } $post_type_obj = get_post_type_object( 'stacklar' ); $create_cap = ( $post_type_obj && isset( $post_type_obj->cap->create_posts ) ) ? $post_type_obj->cap->create_posts : 'edit_posts'; if ( ! current_user_can( $create_cap ) ) { wp_die( esc_html__( 'You are not allowed to create new forms.', 'stacklar-forms' ) ); } $post = get_post( $form_id ); if ( ! $post || 'stacklar' !== $post->post_type ) { wp_die( esc_html__( 'Form not found.', 'stacklar-forms' ) ); } $new_id = $this->duplicate_form( $post ); if ( is_wp_error( $new_id ) ) { wp_die( esc_html( $new_id->get_error_message() ) ); } $redirect = add_query_arg( array( 'post' => $new_id, 'action' => 'edit', self::NOTICE_FLAG => 1, 'source_form_id' => $form_id, ), admin_url( 'post.php' ) ); wp_safe_redirect( $redirect ); exit; } protected function duplicate_form( WP_Post $post ) { $title = $post->post_title ? $post->post_title : __( 'Untitled Form', 'stacklar-forms' ); $copy_title = $this->build_copy_title( $title ); $post_arr = array( 'post_type' => 'stacklar', 'post_title' => $copy_title, 'post_content' => $post->post_content, 'post_status' => 'draft', 'post_author' => get_current_user_id(), ); /** * Filter the post array used to create a duplicated form. * * @param array $post_arr Post data passed to wp_insert_post(). * @param WP_Post $post Source form post. */ $post_arr = apply_filters( 'stacklar_duplicate_post_arr', $post_arr, $post ); $new_id = wp_insert_post( wp_slash( $post_arr ), true ); if ( is_wp_error( $new_id ) ) { return $new_id; } $this->copy_post_meta( $post->ID, $new_id ); /** * Fires after a form has been duplicated. * * @param int $new_id New form post ID. * @param WP_Post $post Source form post. */ do_action( 'stacklar_after_duplicate_form', intval( $new_id ), $post ); return intval( $new_id ); } protected function build_copy_title( $title ) { $title = sanitize_text_field( (string) $title ); $title = $title ? $title : __( 'Untitled Form', 'stacklar-forms' ); $copy_title = sprintf( /* translators: %s: form title */ __( '%s (Copy)', 'stacklar-forms' ), $title ); return $copy_title; } protected function copy_post_meta( $from_id, $to_id ) { $from_id = absint( $from_id ); $to_id = absint( $to_id ); if ( ! $from_id || ! $to_id ) { return; } $meta = get_post_meta( $from_id ); if ( empty( $meta ) || ! is_array( $meta ) ) { return; } $skip = array_fill_keys( $this->get_meta_keys_to_skip(), true ); foreach ( $meta as $key => $values ) { if ( ! is_string( $key ) || '' === $key ) { continue; } if ( isset( $skip[ $key ] ) ) { continue; } if ( ! is_array( $values ) ) { continue; } foreach ( $values as $value ) { // get_post_meta() without a key returns raw serialized strings; // unserialize to avoid double serialization, and slash because // add_post_meta() unslashes its value. add_post_meta( $to_id, $key, wp_slash( maybe_unserialize( $value ) ) ); } } } protected function get_meta_keys_to_skip() { return array( '_edit_lock', '_edit_last', '_wp_old_slug', '_wp_trash_meta_status', '_wp_trash_meta_time', '_wp_desired_post_slug', ); } public function render_notice() { // The duplicate handler verified its nonce and redirected here; these // query args only choose which notice to show. // phpcs:disable WordPress.Security.NonceVerification.Recommended $flag = isset( $_GET[ self::NOTICE_FLAG ] ) ? sanitize_key( wp_unslash( $_GET[ self::NOTICE_FLAG ] ) ) : ''; $new_id = isset( $_GET['post'] ) ? absint( $_GET['post'] ) : 0; // phpcs:enable WordPress.Security.NonceVerification.Recommended if ( '1' !== $flag ) { return; } if ( ! $new_id || 'stacklar' !== get_post_type( $new_id ) ) { return; } $message = __( 'Form duplicated successfully.', 'stacklar-forms' ); printf( '

%s

', esc_html( $message ) ); } }