public function for_post($type, $name = false)
 {
     if (!$this->needed_components_loaded()) {
         return false;
     }
     global $WPV_settings;
     $option = sanitize_text_field(sprintf('views_template_for_%s', $type));
     // already has an content template
     if (isset($WPV_settings[$option]) && is_numeric($WPV_settings[$option]) && $WPV_settings[$option] > 0) {
         return $WPV_settings[$option];
     }
     if (!$name) {
         $type_object = get_post_type_object($type);
         $name = sprintf(__('Template for %s', 'types'), $type_object->labels->name);
     }
     $name = $this->validate_name($name);
     if (!$name) {
         return false;
     }
     $ct = WPV_Content_Template::create($name);
     $ct_post = get_post($ct->id);
     if ($ct_post === null) {
         return false;
     }
     $WPV_settings[$option] = $ct_post->ID;
     $WPV_settings->save();
     $posts = get_posts('post_type=' . $type . '&post_status=any&posts_per_page=-1&fields=ids');
     foreach ($posts as $id) {
         $ct = get_post_meta($id, '_views_template', true);
         if (empty($ct)) {
             update_post_meta($id, '_views_template', $ct_post->ID);
         }
     }
     return $ct_post->ID;
 }
 /**
  * Creates a content template for a given post type
  *
  * @param $type
  * @param bool|string $name Name for the Content Template
  *
  * @return bool
  * @since 2.0
  */
 public function for_post($type, $name = false)
 {
     // abort if any needed dependency is not available
     if (!$this->needed_components_loaded()) {
         return false;
     }
     global $WPV_settings;
     // option key for Views Content Templates is "views_template_for_{post-type-name}"
     $option = sanitize_text_field(sprintf('views_template_for_%s', $type));
     // already has an content template
     if (isset($WPV_settings[$option]) && is_numeric($WPV_settings[$option]) && $WPV_settings[$option] > 0) {
         return $WPV_settings[$option];
     }
     // create name if not given
     if (!$name) {
         $type_object = get_post_type_object($type);
         $name = sprintf(__('Template for %s', 'types'), $type_object->labels->name);
     }
     $name = $this->validate_name($name);
     // abort if name not valid (shouldn't happen, see validate_name())
     if (!$name) {
         return false;
     }
     // create template
     $ct = WPV_Content_Template::create($name);
     $ct_post = get_post($ct->id);
     if ($ct_post === null) {
         return false;
     }
     $WPV_settings[$option] = $ct_post->ID;
     $WPV_settings->save();
     // get all posts of post type to assign the new content template
     $posts = get_posts('post_type=' . $type . '&post_status=any&posts_per_page=-1&fields=ids');
     foreach ($posts as $id) {
         $ct = get_post_meta($id, '_views_template', true);
         // only assign if there is not already an assigned content template
         if (empty($ct)) {
             update_post_meta($id, '_views_template', $ct_post->ID);
         }
     }
     return $ct_post->ID;
 }
    /**
     * 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;
    }
/**
 * Bind specific posts to a Content Template.
 *
 * Following POST parameters are expected:
 * - id: Content Template ID
 * - wpnonce: A valid wpv_ct_{$id}_bind_posts_by_{$user_id} nonce.
 * - posts_to_bind: An array of post IDs that should be bound.
 *
 * Returns a default WP json response (error/success), possibly with a debug message
 * on error.
 *
 * @since 1.9
 */
function wpv_ct_bind_posts_callback() {
    // Authentication and validation
    if ( ! current_user_can( 'manage_options' ) ) {
        wp_send_json_error( 'Untrusted user' );
    }
    $ct_id = (int) wpv_getpost( 'id' );
    $uid = get_current_user_id();

    $nonce_name = "wpv_ct_{$ct_id}_bind_posts_by_{$uid}";
    if ( ! wp_verify_nonce( wpv_getpost( 'wpnonce' ), $nonce_name ) ) {
        wp_send_json_error( "Security check ($nonce_name)" );
    }

    $ct = WPV_Content_Template::get_instance( $ct_id );
    if( null == $ct ) {
        wp_send_json_error( 'Invalid Content Template' );
    }

    $posts_to_bind = wpv_getpost( 'posts_to_bind' );
    if( !is_array( $posts_to_bind ) ) {
        wp_send_json_error( 'Invalid arguments (' . print_r( $posts_to_bind, true ) . ')' );
    }

    // Post binding
    $updated = $ct->bind_posts( $posts_to_bind );

    if( false === $updated ) {
        wp_send_json_error( 'bind_posts failed' );
    }

    wp_send_json_success( array( 'updated' => $updated ) );
}
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;
}
    /**
     * Clone a Content Template.
     *
     * @param string $title Title of the new CT.
     * @param bool $adjust_duplicate_title If true, the title might get changed in order to ensure it's uniqueness.
     *     Otherwise, if $title is not unique, the cloning will fail.
     * @return null|WPV_Content_Template The cloned CT or null on failure.
     *
     * @since 1.9
     */
    public function clone_this( $title, $adjust_duplicate_title = true ) {

        // Create new CT
        $cloned_ct = WPV_Content_Template::create( $title, $adjust_duplicate_title );
        if( null == $cloned_ct ) {
            return null;
        }


        // Copy postmeta
        $cloned_ct->defer_after_update_actions();
        $postmeta_defaults = $this->get_postmeta_defaults();
        foreach( $postmeta_defaults as $meta_key => $ignored_value ) {
            if( !in_array( $meta_key, WPV_Content_Template::$postmeta_keys_not_to_clone ) ) {
                $cloned_ct->update_postmeta( $meta_key, $this->get_postmeta( $meta_key ) );
            }
        }
        $cloned_ct->resume_after_update_actions();

        // Copy content
        $cloned_ct->content_raw = $this->content_raw;

        return $cloned_ct;
    }
    /**
     * Create new Content Template and set it as this View's Loop template.
     *
     * Note that this method doesn't care about existing Loop template. That should be handled separately before it
     * is called.
     *
     * @param string $title Valid title for the Content Template (will be adjusted if not unique).
     * @param string $content Content of the CT
     * @throws RuntimeException
     * @return WPV_Content_Template Newly created CT.
     * @since 1.10
     */
    public function create_loop_template( $title, $content = '[wpv-post-link]' ) {

        $ct = WPV_Content_Template::create( $title, true );
        if( null == $ct ) {
            throw new RuntimeException( 'couldn\'t create the loop template' );
        }

        $ct->defer_after_update_actions();

        // Update Loop output and content of the Loop template
        $ct->content = $content;

        $this->loop_meta_html = str_replace(
            '<wpv-loop>',
            sprintf( "<wpv-loop>\n\t\t\t[wpv-post-body view_template=\"%s\"]", $ct->title ),
            $this->loop_meta_html
        );

        // Create bindings between View and Loop template
        $this->loop_included_ct_ids = $ct->id;

        $this->loop_template_id = $ct->id;
        $ct->loop_output_id = $this->id;

        $ct->resume_after_update_actions();

        return $ct;
    }
/**
 * wpv_create_content_template
 *
 * Creates a new Content Template given a title and an optional suffix.
 *
 * Consider using WPV_Content_Template::create_new directly.
 *
 * @note Used by Layouts plugin.
 *
 * @param string $title
 * @param string $suffix
 * @param bool $force Whether to force the creation of the Template by incremental numbers added to the title in case it is already in use
 * @param string $content
 *
 * @return array {
 *     'success' => (int) The ID of the CT created
 *      'error' => (string) Error message
 *      'title' => (string) The title of the CT created or the one that made this fail
 *
 * @since 1.7
 */
function wpv_create_content_template( $title, $suffix = '', $force = true, $content = '' ) {

	$real_suffix = '';
	if ( ! empty( $suffix ) ) {
		$real_suffix = ' - ' . $suffix;
	}
    $template_title = $title . $real_suffix;

    $result = array();

    if( $force ) {
        $ct = WPV_Content_Template::create( $template_title, true );
    } else {

        if( WPV_Content_Template::is_name_used( $template_title ) ) {
            $result['error'] = __( 'A Content Template with that title already exists. Please use another title.', 'wpv-views' );
            $result['title'] = $template_title;
            return $result;
        }

        $ct = WPV_Content_Template::create( $template_title, false );
    }

    if( null == $ct ) {
        $return['title'] = $template_title;
        $return['error'] = __( 'An error occurred while creating a Content Template.', 'wpv-views' );
    } else {

        $return['title'] = $ct->title;

        try {
            $ct->content_raw = $content;
            $return['success'] = $ct->id;
        } catch( Exception $e ) {
            $return['error'] = __( 'An error occurred while creating a Content Template.', 'wpv-views' );
        }

    }

    return $return;
}
Beispiel #9
0
/**
 * Adjust link to Content Template edit page for full Views.
 *
 * See icl_post_link for parameter description.
 *
 * @param $link
 * @param $post_type
 * @param $post_id
 * @param $link_purpose
 * @return array
 *
 * @since 1.10
 */
function wpv_ct_post_link( $link, $post_type, $post_id, $link_purpose ) {
    global $WP_Views;
    if( !$WP_Views->is_embedded() && ( WPV_Content_Template_Embedded::POST_TYPE == $post_type ) && ( 'edit' == $link_purpose ) ) {
        // Full Views, CT edit link is requested
        if( !is_array( $link ) ) {
            $link = array();
        }

        // If CT is trashed or non-existent, disable the link.
        $ct = WPV_Content_Template::get_instance( $post_id );
        if( ( null == $ct ) || $ct->is_trashed ) {
            $link['is_disabled'] = true;
        } else {
            $link['is_disabled'] = false;
            $link['url'] = wpv_ct_editor_url( $post_id, false );
        }
    }
    return $link;
}