/**
     * Duplicate a loop template of a View and update references to it.
     *
     * @todo detailed description
     *
     * @param array $new_postmeta_values Array of postmeta of the View.
     * @param int $new_post_id ID of the View.
     * @param string $new_post_title Post title of the View.
     *
     * @return array Updated array of postmeta values of the View.
     */
    private function duplicate_loop_template( $new_postmeta_values, $new_post_id, $new_post_title ) {

        // This will throw an exception if the original CT can't be accessed
        $original_ct = new WPV_Content_Template( $this->loop_template_id );

        // Clone the Content Template acting as a Loop template
        $cloned_ct = $original_ct->clone_this( sprintf( __( 'Loop item in %s', 'wpv-views' ), $new_post_title ), true );

        if( null == $cloned_ct ) {
            throw new RuntimeException( 'unable to clone loop template' );
        }

        // Cloning was successful.

        // Create reference from new View to new Loop template.
        $new_postmeta_values[ WPV_View_Base::POSTMETA_LOOP_TEMPLATE_ID ] = $cloned_ct->id;

        // Create reference from new Loop template to new View.
        $cloned_ct->loop_output_id = $new_post_id;

        // Process inline Content templates if there are any.
        // @todo can this be done cleaner?
        $inline_templates = wpv_getarr( $new_postmeta_values['_wpv_layout_settings'], 'included_ct_ids', '' );
        if ( !empty( $inline_templates ) ) {
            $inline_templates = explode( ',', $inline_templates );

            // Go through all inline templates (referenced in original View) and if we find a reference
            // to original Loop template, we will replace it with new one.
            foreach ( $inline_templates as $inline_template_key => $inline_template_id ) {

                if ( $inline_template_id == $this->loop_template_id ) {
                    // Replace with new Loop template.
                    $inline_templates[ $inline_template_key ] = $cloned_ct->id;
                }
            }

            // Update the array of inline Content templates.
            $new_postmeta_values['_wpv_layout_settings']['included_ct_ids'] = implode( ',', $inline_templates );
        }


        // Replace name of the old Loop template with new name in Loop output.
        $loop_output = wpv_getarr( $new_postmeta_values['_wpv_layout_settings'], 'layout_meta_html', '' );
        if ( !empty( $loop_output ) ) {

            // Search and replace Loop template titles
            // todo we also need to check for slugs
            // todo consider allways replacing by slug, title could contain quotes at this point
            $new_loop_output = str_replace(
                sprintf( 'view_template="%s"', $original_ct->title ),
                sprintf( 'view_template="%s"', sanitize_text_field( $cloned_ct->title ) ),
                $loop_output
            );

            // Save new value
            $new_postmeta_values['_wpv_layout_settings']['layout_meta_html'] = $new_loop_output;
        }

        return $new_postmeta_values;
    }
function wpv_duplicate_ct_callback() {
	if ( ! current_user_can( 'manage_options' ) ) {
		$data = array(
			'type' => 'capability',
			'message' => __( 'You do not have permissions for that.', 'wpv-views' )
		);
		wp_send_json_error( $data );
	}
	if ( 
		! isset( $_POST["wpnonce"] )
		|| ! wp_verify_nonce( $_POST["wpnonce"], 'work_view_template' )
	) {
		$data = array(
			'type' => 'nonce',
			'message' => __( 'Your security credentials have expired. Please reload the page to get new ones.', 'wpv-views' )
		);
		wp_send_json_error( $data );
	}
	
	$title = '';
	if ( isset( $_POST['title'] ) ) {
	   $title = sanitize_text_field( $_POST['title'] );
	}
	if ( empty( $title ) ) {
		$data = array(
			'type' => 'title',
			'message' => __( 'You can not create a Content Template with an empty name.', 'wpv-views' )
		);
		wp_send_json_error( $data );
	}

    // Load the original CT.
    $original_ct_id = $_POST["id"];
    try {
        $original_ct = new WPV_Content_Template( $original_ct_id );
    } catch( Exception $e ) {
		$data = array(
			'type' => 'error',
			'message' => __( 'An unexpected error happened.', 'wpv-views' )
		);
		wp_send_json_error( $data );
    }

    // Check for uniqueness of the new title.
    if( WPV_Content_Template_Embedded::is_name_used( $title ) ) {
		$data = array(
			'type' => 'title',
			'message' => __( 'A Content Template with that name already exists. Please use another name.', 'wpv-views' )
		);
		wp_send_json_error( $data );
    }

    // Clone and report the result.
    $cloned_ct = $original_ct->clone_this( $title, false );

    if ( null == $cloned_ct ) {
		$data = array(
			'type' => 'error',
			'message' => __( 'An unexpected error happened.', 'wpv-views' )
		);
		wp_send_json_error( $data );
    } else {
        wp_send_json_success();
    }
}