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();
    }
}
/**
 * Adjust post links for embedded Views.
 *
 * Currently only CT edit links are supported. See icl_post_link filter for parameter description.
 *
 * @param $link
 * @param $post_type
 * @param $post_id
 * @param $link_purpose
 * @return array
 *
 * @since 1.10
 */
function wpv_embedded_post_link($link, $post_type, $post_id, $link_purpose)
{
    global $WP_Views;
    // Skip if we're in full Views
    if ($WP_Views->is_embedded()) {
        if (!is_array($link)) {
            $link = array();
        }
        switch ($post_type) {
            // Content Templates
            case WPV_Content_Template_Embedded::POST_TYPE:
                if ('edit' == $link_purpose) {
                    // Content Template edit page
                    // Check that CT exists and is not trashed.
                    $ct = WPV_Content_Template_Embedded::get_instance($post_id);
                    if (null == $ct || $ct->is_trashed) {
                        $link['is_disabled'] = true;
                    } else {
                        // Generate the URL to the read-only page.
                        $link['is_disabled'] = false;
                        $link['url'] = esc_url(add_query_arg(array('page' => 'view-templates-embedded', 'view_id' => $post_id), admin_url('admin.php')));
                    }
                }
                break;
        }
    }
    return $link;
}
function wpv_admin_menu_content_template_listing_by_type_row( $sort, $page = 0 ) {
	global $WPV_settings, $post;

	$post_types_array = wpv_get_pt_tax_array();

	ob_start();
	if ( $sort == 'usage-single' ){

		$counter = count( $post_types_array['single_post'] );
		$alternate = '';
		for ( $i = 0; $i < $counter; ++$i ) {
			$type = $post_types_array['single_post'][ $i ][0];
			$label = $post_types_array['single_post'][ $i ][1];
			$alternate = ' alternate' == $alternate ? '' : ' alternate';

			?>
			<tr id="wpv_ct_list_row_<?php echo $type; ?>" class="js-wpv-ct-list-row<?php echo $alternate; ?>">

				<td class="wpv-admin-listing-col-usage post-title page-title column-title">
					<span class="row-title">
						<?php echo $label;?>
					</span>
					<?php
						$row_actions = array(
								"change_pt js-wpv-change-ct-assigned-to-something-popup" => sprintf( '<a href="#">%s</a>', __('Change Content Template','wpv-views') ) );

						echo wpv_admin_table_row_actions( $row_actions,	array(
								"data-pt" => 'views_template_for_' . $type ) );
					?>
				</td>

				<td class="wpv-admin-listing-col-used-title">
					<ul>
						<?php
							$add_button = wpv_ct_listing_render_create_ct_button(
                                sprintf( __( 'Create a Content Template for single %s', 'wpv-views' ), $label ),
                                $label,
                                array( 'single_post_types' => array( $type ) )
                            );


							if ( isset( $WPV_settings[ 'views_template_for_' . $type ] ) && $WPV_settings[ 'views_template_for_' . $type ] != 0 ) {

                                // There is a Content Template assigned for single posts of this type

                                $ct_id = $WPV_settings[ 'views_template_for_' . $type ];
                                $ct = WPV_Content_Template::get_instance( $ct_id );

                                if ( null != $ct ) {
                                    printf(
                                        '<a href="%s">%s</a>',
                                        esc_url(
                                            add_query_arg(
                                                array( 'page' => WPV_CT_EDITOR_PAGE_NAME, 'ct_id' => $ct->id, 'action' => 'edit' ),
                                                admin_url( 'admin.php' )
                                            )
                                        ),
                                        $ct->title
                                    );

									// @todo We do not need the exact number here, let's create a has_dissident_posts method instead with a LIMITed query
                                    $dissident_post_count = $ct->get_dissident_posts( $type, 'count' );

                                    if ( $dissident_post_count > 0 ) {
                                        ?>
                                        <span class="js-wpv-apply-ct-to-cpt-single-<?php echo $type; ?>">
                                            <?php
                                                printf(
                                                    '<a class="%s" data-type="%s" data-id="%s" data-nonce="%s"> %s</a>',
                                                    'button button-small button-leveled icon-warning-sign js-wpv-apply-ct-to-all-cpt-single-dialog',
													$type,
													$ct->id,
													wp_create_nonce( 'work_view_template' ),
                                                    sprintf( __( 'Bind %u %s ', 'wpv-views' ), $dissident_post_count, $label )
                                                );
                                            ?>
                                        </span>
                                        <?php
                                    }
                                    //}
                                } else {
                                    echo $add_button;
                                }
                            } else {

                                // Single posts of this type have no Content Template assigned

                                echo $add_button;

                                $assigned_posts_count = WPV_Content_Template_Embedded::get_posts_using_content_template_by_type( $type, 'count' );

                                if ( $assigned_posts_count > 0 ) {
                                    ?>
                                    <a class="button button-small js-wpv-clear-cpt-from-ct-popup" href="#"
                                            data-unclear="<?php echo $assigned_posts_count; ?>"
                                            data-slug="<?php echo $type; ?>"
                                            data-label="<?php echo htmlentities( $label, ENT_QUOTES ); ?>">
                                        <i class="icon-unlink"></i>
                                        <?php echo sprintf( __('Clear %d %s', 'wpv-views'), $assigned_posts_count, $label ); ?>
                                    </a>
                                    <?php
                                }

                            }
						?>
					</ul>
				</td>
			</tr>
			<?php
		}

	} else if ( $sort == 'usage-post-archives' ){

		$alternate = '';
		$counter = count( $post_types_array['archive_post'] );
		for ( $i = 0; $i < $counter; ++$i ) {

			$type = $post_types_array['archive_post'][ $i ][0];
			$label = $post_types_array['archive_post'][ $i ][1];

			$add_button = wpv_ct_listing_render_create_ct_button(
                __( 'Add a new Content Template for this post type', 'wpv-views' ),
                $label,
                array( 'post_archives' => array( $type ) )
            );

			$alternate = ' alternate' == $alternate ? '' : ' alternate';
			?>
			<tr id="wpv_ct_list_row_<?php echo $type; ?>" class="js-wpv-ct-list-row<?php echo $alternate; ?>">
				<td class="post-title page-title column-title">
					<span class="row-title">
						<?php echo $label; ?>
					</span>
					<?php
						$row_actions = array(
								"change_pt js-wpv-change-ct-assigned-to-something-popup" => sprintf( '<a href="#">%s</a>', __( 'Change Content Template', 'wpv-views' ) ) );

						echo wpv_admin_table_row_actions( $row_actions,	array(
								"data-pt" => 'views_template_archive_for_' . $type ) );
					?>
				</td>
				<td>
					<ul>
						<?php
							if ( isset( $WPV_settings[ 'views_template_archive_for_' . $type ] )
									&& $WPV_settings[ 'views_template_archive_for_' . $type ] != 0) {
								$post = get_post( $WPV_settings[ 'views_template_archive_for_' . $type ] );
								if ( is_object( $post ) ) {
                                    wpv_ct_editor_render_link( $post->ID, esc_html( $post->post_title ) );
								} else {
									echo $add_button;
								}
							} else {
								echo $add_button;
							}
						?>
					</ul>
				</td>
			</tr>
			<?php
		}

	} else if ( $sort == 'usage-taxonomy-archives' ){

		$counter = count( $post_types_array['taxonomy_post'] );
		$alternate = '';

		for ( $i = 0; $i < $counter; ++$i ) {
			$type = $post_types_array['taxonomy_post'][ $i ][0];
			$label = $post_types_array['taxonomy_post'][ $i ][1];

			$add_button = wpv_ct_listing_render_create_ct_button(
                __( 'Add a new Content Template for this taxonomy', 'wpv-views' ),
                $label,
                array( 'taxonomy_archives' => array( $type ) )
            );

			$alternate = ' alternate' == $alternate ? '' : ' alternate';

			?>
			<tr id="wpv_ct_list_row_<?php echo $type; ?>" class="js-wpv-ct-list-row<?php echo $alternate; ?>">
				<td class="post-title page-title column-title">
					<span class="row-title">
						<?php echo $label;?>
					</span>
					<?php
						$row_actions = array(
								"change_pt js-wpv-change-ct-assigned-to-something-popup" => sprintf( '<a href="#">%s</a>', __( 'Change Content Template', 'wpv-views' ) ) );

						echo wpv_admin_table_row_actions( $row_actions,	array(
								"data-pt" => 'views_template_loop_' . $type ) );
					?>
				</td>
				<td>
					<ul>
						<?php
							if ( isset( $WPV_settings[ 'views_template_loop_' . $type ] )
									&& $WPV_settings[ 'views_template_loop_' . $type ] != 0 ) {
								$post = get_post( $WPV_settings['views_template_loop_' . $type] );
								if ( is_object( $post ) ) {
                                    wpv_ct_editor_render_link( $post->ID, esc_html( $post->post_title ) );
								} else {
									echo $add_button;
								}
							} else {
								echo $add_button;
							}
						?>
					</ul>
				</td>
			</tr>
			<?php
		}
	}

	$row = ob_get_contents();
	ob_end_clean();

	return $row;
}
/**
 * Counts the amount of posts of a given type that do not use a given Template and creates the HTML structure to notify about it
 * Used on the Views popups for the Content Templates listing page on single usage
 *
 * @param int $template_id the ID of the Content Template we want to check against
 * @param string $content_type the post type to check
 * @param string $message_header (optional) to override the default message on the HTML structure header "Do you want to apply to all?"
 *
 * @return void
 *
 * @since 1.5.1
 *
 * @deprecated since 1.10
 */
function wpv_count_dissident_posts_from_template( $template_id, $content_type, $message_header = null ) {
	
    try {
        $ct = new WPV_Content_Template_Embedded( $template_id );
    } catch( Exception $e ) {
        // well, we were not handling non-existent CTs before and I am not sure how to do that now...
        return;
    }

    $dissident_post_count = $ct->get_dissident_posts( $content_type, 'count' );

    if ( $dissident_post_count > 0 ) {
        $ptype = get_post_type_object( $content_type );

        if ( $dissident_post_count > 1 ){
            $type_label = $ptype->labels->name;
            $message = sprintf( __( '<strong>%d %s</strong> use a different Content Template.', 'wpv-views' ), $dissident_post_count , $type_label );
        } else {
            $type_label = $ptype->labels->singular_name;
            $message = sprintf(__('<strong>%d %s</strong> uses a different Content Template.', 'wpv-views'), $dissident_post_count, $type_label);
        }

        ?>
        <div class="wpv-dialog wpv-shortcode-gui-content-wrapper">
			<?php echo $message; ?>
        </div>
    <?php
    }

}
 /**
  * Get language code of this Content Template.
  *
  * Works only with WPML active.
  *
  * @return null|string Language code or null if it can't be obtained.
  * @since 1.10
  */
 protected function _get_wpml_language() {
     return apply_filters( 'wpml_element_language_code', null, array( 'element_id' => $this->id, 'element_type' => WPV_Content_Template_Embedded::get_wpml_element_type() ) );
 }
    /**
     * Post slug validation.
     *
     * Accepts a non-empty value containing only lowercase letters, numbers or dashes.
     *
     * @param string $value New post slug.
     * @return string Sanitized value safe to be used.
     * @throws WPV_RuntimeExceptionWithMessage
     * @since 1.9
     */
    protected function _validate_slug( $value ) {

        $sanitized_value = sanitize_title( $value );
        if( $value != $sanitized_value ) {
            throw new WPV_RuntimeExceptionWithMessage(
                '_validate_slug failed: invalid characters',
                __( 'The slug can only contain lowercase latin letters, numbers or dashes.', 'wpv-views' )
            );
        }

        if( empty( $sanitized_value ) ) {
            throw new WPV_RuntimeExceptionWithMessage(
                '_validate_slug failed: empty value',
                __( 'You can not leave the slug empty.', 'wpv-views' )
            );
        }

        $collision_data = array();
        if( WPV_Content_Template_Embedded::is_name_used( $sanitized_value, $this->id, $collision_data ) ) {
            switch( $collision_data['colliding_field'] ) {
                case 'post_name':
                    $exception_message = sprintf(
                        __( 'Another Content Template (%s) with that slug already exists. Please use another slug.', 'wpv-views' ),
                        sanitize_text_field( $collision_data['post_title'] )
                    );
                    break;
                case 'post_title':
                    $exception_message = __( 'Another Content Template already uses this slug value as it\'s title. Please use another slug.', 'wpv-views' );
                    break;
                case 'both':
                    $exception_message = __( 'Another Content Template already uses this slug value as it\'s slug and title. Please use another slug.', 'wpv-views' );
                    break;
                default:
                    $exception_message = __( 'Another item with that slug or title already exists. Please use another slug.', 'wpv-views' );
                    break;
            }
            throw new WPV_RuntimeExceptionWithMessage(
                '_validate_slug failed: name is already being used for another CT',
                $exception_message,
                WPV_RuntimeExceptionWithMessage::EXCEPTION_VALUE_ALREADY_USED
            );
        }

        return $sanitized_value;
    }
 /**
  * Determine whether CT with given ID exists.
  *
  * @param int $ct_id ID of the CT to check.
  *
  * @return bool True if post with given ID exists and if it's a CT.
  */
 public static function is_valid($ct_id)
 {
     /* Note: This should not cause a redundant database query. Post objects are cached by WP core, so this one was
      * either already loaded or it has to be loaded now and will be reused in the future. */
     return WPV_Content_Template_Embedded::is_wppost_ct(WP_Post::get_instance($ct_id));
 }
	/**
	 * get the template id from the name and include caching.
	 *
     * @deprecated Consider using WPV_Content_Template_Embedded::get_template_id_by_name directly.
	 */
	function get_template_id( $template_name ) {
        return WPV_Content_Template_Embedded::get_template_id_by_name( $template_name );
	}