/** * 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 ) ); }
/** * Create a new Content Template with default settings. * * @param string $title Content Template title. * @param bool $adjust_duplicate_title If true, change the title if it's not unique among Content Templates. You can (and * should) check for the value that was actually saved to database through the returned $ct->title. If this is * false and the title is not unique (determined by is_name_used()), the operation will fail. * * @return null|WPV_Content_Template CT object or null if creating has failed. * * @since 1.9 */ public static function create( $title, $adjust_duplicate_title = true ) { $sanitized_title = sanitize_text_field( $title ); // Handle empty title if( empty( $sanitized_title ) ) { if( $adjust_duplicate_title ) { $sanitized_title = sanitize_text_field( __( 'Content Template', 'wpv-views' ) ); } else { // empty title, but we're not allowed to adjust it -> fail return null; } } // Ensure title uniqueness (or fail) $is_title_unique = ! WPV_Content_Template_Embedded::is_name_used( $sanitized_title ); if( !$is_title_unique ) { if( $adjust_duplicate_title ) { $sanitized_title = WPV_Content_Template::get_unique_title( $sanitized_title ); } else { // Non-unique title & we're not allowed to re-use it -> fail return null; } } // Insert the post in database. $post_id = wp_insert_post( array( 'post_title' => $sanitized_title, 'post_status' => 'publish', 'post_type' => WPV_Content_Template_Embedded::POST_TYPE, 'post_content' => '' ), false ); // Create the CT object or fail $ct = WPV_Content_Template::get_instance( $post_id ); if( null == $ct ) { return null; } $ct->defer_after_update_actions(); // Save default postmeta values foreach( WPV_Content_Template_Embedded::$postmeta_defaults as $meta_key => $meta_value ) { $ct->update_postmeta( $meta_key, $meta_value ); } // After update action will be called exactly once. $ct->maybe_after_update_action(); $ct->resume_after_update_actions(); return $ct; }
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; }
/** * 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; }