/**
     * Create a new WordPress Archive.
     *
     * If the query mode is set to "layouts-loop", also automatically create new Loop template.
     *
     * @param string $title New WPA title. Must be unique and valid (see validate_title()).
     * @param array $args (
     *          @type array $view_settings View settings that should override the default ones. Optional.
     *          @type array $loop_settings Loop settings that should override the default ones. Optional.
     *          @type bool $forbid_loop_template Never create a Loop template for this View. Optional, default is false.
     *     )
     *
     * @return WPV_WordPress_Archive New WPA object.
     *
     * @throws InvalidArgumentException
     * @throws RuntimeException
     * @throws WPV_RuntimeExceptionWithMessage
     *
     * @note overriding default Views settings and layout settings must provide complete data when the element is an
     * array, because it overrides them all. For example, $args['settings']['pagination'] can not override just the
     * "postsper page" options: it must provide a complete pagination implementation. This might change and be corrected
     * in the future, keeping backwards compatibility.
     *
     * @since 1.10
     */
    public static function create( $title, $args ) {

        $wpa_id = WPV_View_Base::create_post( $title );

        $wpa = new WPV_WordPress_Archive( $wpa_id );

        $wpa->defer_after_update_actions();

        // Construct default View settings and Loop settings
        $view_settings = wpv_getarr( $args, 'view_settings', array() );

        $query_mode = wpv_getarr( $view_settings, WPV_View_Base::VIEW_SETTINGS_QUERY_MODE, 'archive', array( 'archive', 'layouts-loop' ) );
        $view_settings[ WPV_View_Base::VIEW_SETTINGS_QUERY_MODE ] = $query_mode;
        $is_layouts_loop = ( 'layouts-loop' == $query_mode );

        $view_settings_default = wpv_wordpress_archives_defaults( 'view_settings' );
        $view_settings = wp_parse_args( $view_settings, $view_settings_default );

        $wpa->update_postmeta( WPV_View_Base::POSTMETA_VIEW_SETTINGS, $view_settings );

        $loop_settings_default = wpv_wordpress_archives_defaults( 'view_layout_settings' );

        // Modify default loop output for Layouts loop
        if ( $is_layouts_loop ) {
            $loop_settings_default[ WPV_View_Base::LOOP_SETTINGS_META_HTML ] = str_replace(
                "[/wpv-items-found]",
                "[wpv-archive-pager-prev-page]\n"
                . "\t\t[wpml-string context=\"wpv-views\"]Older posts[/wpml-string]\n"
                . "\t[/wpv-archive-pager-prev-page]\n"
                . "\t[wpv-archive-pager-next-page]\n"
                . "\t\t[wpml-string context=\"wpv-views\"]Newer posts[/wpml-string]\n"
                . "\t[/wpv-archive-pager-next-page]\n"
                . "\t[/wpv-items-found]",
                $loop_settings_default[ WPV_View_Base::LOOP_SETTINGS_META_HTML ]
            );
        }

        $loop_settings = wpv_getarr( $args, 'loop_settings', array() );
        $loop_settings = wp_parse_args( $loop_settings, $loop_settings_default );

        $wpa->update_postmeta( WPV_View_Base::POSTMETA_LOOP_SETTINGS, $loop_settings );

        // Create Loop template for Layouts loop
        $forbid_loop_template = wpv_getarr( $args, 'forbid_loop_template', false );
        if( ! $forbid_loop_template && $is_layouts_loop ) {

            $ct_title = sprintf( '%s - %s', $title, __( 'loop item', 'wpv-views' ) );
            $ct_content = sprintf(
                "<h1>[wpv-post-title]</h1>\n[wpv-post-body view_template=\"None\"]\n[wpv-post-featured-image]\n%s",
                sprintf(__('Posted by %s on %s', 'wpv-views'), '[wpv-post-author]', '[wpv-post-date]' )
            );
            $wpa->create_loop_template( $ct_title, $ct_content );
        }


        $wpa->resume_after_update_actions();

        return $wpa;
    }
 /**
  * Show information about how a CT is being used.
  *
  * @param $item WPV_Content_Template_Embedded Content template.
  *
  * @return string Content of the table cell.
  */
 public function column_used_on($item)
 {
     if ($item->is_owned_by_view) {
         // This CT is used as a template for Loop Output in a View or WPA.
         // Get a View or WPA object. We'll be using only methods from their base, so it doesn't matter which one is it.
         $owner_view = WPV_View_Base::create($item->loop_output_id);
         if ($owner_view == null) {
             // Something is wrong - most probably the owner doesn't exist.
             return '';
         }
         // Display the appropriate message.
         if ($owner_view->is_published) {
             return sprintf('<span>%s</span>', sprintf(__('This Content Template is used as the loop block for the %s <a href="%s" target="_blank">%s</a>', 'wpv-views'), $owner_view->query_mode_display_name, esc_url(add_query_arg(array('page' => 'views-embedded', 'view_id' => $owner_view->id), admin_url('admin.php'))), $owner_view->title));
         } else {
             return sprintf('<span>%s</span>', sprintf(__('This Content Template is used as the loop block for the trashed %s <strong>%s</strong>', 'wpv-views'), $owner_view->query_mode_display_name, $owner_view->title));
         }
     } else {
         // This is a normal CT. Obtain information about assignments and display them in a tag-like list.
         $list = array();
         // "single posts"
         $assigned_single_pts = $item->get_assigned_single_post_types();
         foreach ($assigned_single_pts as $loop) {
             $list[] = sprintf('<li>%s%s</li>', $loop['display_name'], __(' (single)', 'wpv-views'));
         }
         // post type archives
         $assigned_pt_loops = $item->get_assigned_loops('post_type');
         foreach ($assigned_pt_loops as $loop) {
             $list[] = sprintf('<li>%s%s</li>', $loop['display_name'], __(' (post type archive)', 'wpv-views'));
         }
         // taxonomy archives
         $assigned_ta_loops = $item->get_assigned_loops('taxonomy');
         foreach ($assigned_ta_loops as $loop) {
             $list[] = sprintf('<li>%s%s</li>', $loop['display_name'], __(' (taxonomy archive)', 'wpv-views'));
         }
         if (!empty($list)) {
             return sprintf('<ul class="wpv-taglike-list">%s</ul>', implode($list));
         } else {
             return sprintf('<span>%s</span>', __('No Post types/Taxonomies assigned', 'wpv-views'));
         }
     }
 }
Example #3
0
    /**
     * Create a duplicate of this View.
     *
     * Clone the View and most of it's postmeta. If there is a Loop Template assigned,
     * duplicate that as well and update references (in the appropriate postmeta,
     * in shortcodes in loop output, etc.) in the duplicated View.
     *
     * @todo more detailed description
     *
     * @param string $new_post_title Title of the new View. Must not be used in any
     *     existing View or WPA.
     *
     * @return bool|int ID of the new View or false on error.
     */
    public function duplicate( $new_post_title ) {

        // Sanitize and validate
        $new_post_title = sanitize_text_field( $new_post_title );
        if( empty( $new_post_title ) ) {
            return false;
        }

        if( WPV_View_Base::is_name_used( $new_post_title ) ) {
            return false;
        }

        // Clone existing View post object
        $new_post = (array) clone( $this->post() );
        $new_post['post_title'] = $new_post_title;

        $keys_to_unset = array( 'ID', 'post_name', 'post_date', 'post_date_gmt' );
        foreach( $keys_to_unset as $key ) {
            unset( $new_post[ $key ] );
        }

        $new_post_id = wp_insert_post( $new_post );

        // Clone existing View postmeta
        $postmeta_keys_to_copy = array( '_wpv_settings', '_wpv_layout_settings', '_wpv_description' );

        $new_postmeta_values = array();
        foreach ( $postmeta_keys_to_copy as $key ) {
            $new_postmeta_values[ $key ] = $this->get_postmeta( $key );
        }

        // If this View has a loop Template, we need to clone it and adjust the layout settings.
        if ( $this->has_loop_template ) {
            $new_postmeta_values = $this->duplicate_loop_template( $new_postmeta_values, $new_post_id, $new_post_title );
        }

        // Update postmeta of the new View.
        foreach ( $new_postmeta_values as $meta_key => $meta_value ) {
            update_post_meta( $new_post_id, $meta_key, $meta_value );
        }

        return $new_post_id;
    }
Example #4
0
/**
 * View duplicate callback function.
 *
 * Expects following POST arguments:
 * - wpnonce: A valid wpv_duplicate_view_nonce.
 * - id: View ID.
 * - name: Name of the new View.
 *
 * Refer to WPV_View::duplicate() for more information about the duplication itself.
 *
 * @since unknown
 */
function wpv_duplicate_this_view_callback() {
	wpv_ajax_authenticate( 'wpv_duplicate_view_nonce', array( 'parameter_source' => 'post', 'type_of_death' => 'data' ) );
	
    $post_id = (int) wpv_getpost( 'id', 0 );
    $post_name= sanitize_text_field( wpv_getpost( 'name', '' ) );
	if ( ( 0 == $post_id ) || empty( $post_name ) ) {
		$data = array(
			'message' => __('Wrong data', 'wpv-views')
		);
		wp_send_json_error( $data );
	}

    if ( WPV_View_Base::is_name_used( $post_name ) ) {
        $data = array(
			'message' => __( 'A View with that name already exists. Please use another name', 'wpv-views' )
		);
		wp_send_json_error( $data );
	}

    // Get the original View.
    $original_view = WPV_View::get_instance( $post_id );
    if( null == $original_view ) {
		$data = array(
			'message' => __('Wrong data', 'wpv-views')
		);
		wp_send_json_error( $data );
    }
    
    $duplicate_view_id = $original_view->duplicate( $post_name );
    if ( $duplicate_view_id ) {
        // original post id (shouldn't we rather return new id?)
        wp_send_json_success();
    } else {
        $data = array(
			'message' => __( 'Unexpected error', 'wpv-views' )
		);
		wp_send_json_error( $data );
    }

}
/**
 * Render list items with information about usage of this Content Template.
 *
 * Also render "Bind posts" buttons where applicable.
 * Different info shows when CT is a loop template of some View/WPA.
 *
 * @param int $ct_id Content template ID
 * @return string Rendered HTML code.
 *
 * @since unknown
 *
 * @todo this needs refactoring to get rid of wpv_get_pt_tax_array() etc.
 */
function wpv_content_template_used_for_list( $ct_id ) {
	global $WPV_settings;

    $list = '';

    $ct = WPV_Content_Template::get_instance( $ct_id );

    if( null == $ct ) {
        // this should never happen; still, there is a serious lack of error handling
        return '';
    }

	if ( ! $ct->is_owned_by_view ) {
		$post_types_array = wpv_get_pt_tax_array();
		$count_single_post = count( $post_types_array['single_post'] );
		$count_archive_post = count( $post_types_array['archive_post'] );
		$count_taxonomy_post = count( $post_types_array['taxonomy_post'] );

		for ( $i=0; $i<$count_single_post; $i++ ) {
			$type = $post_types_array['single_post'][$i][0];
			$label = $post_types_array['single_post'][$i][1];
			if ( isset( $WPV_settings['views_template_for_' . $type] ) && $WPV_settings['views_template_for_' . $type] == $ct_id ) {
                $list .= '<li>' . $label . __(' (single)', 'wpv-views');

				// @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 ) {
                    $list .= sprintf(
                        '<span class="%s"><a class="%s" data-type="%s" data-id="%s" data-nonce="%s"> %s</a></span>',
                        'js-wpv-apply-ct-to-cpt-single-' . $type,
                        '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 )
                    );
                }

				$list .= '</li>';
			}
		}

		for ( $i=0; $i < $count_archive_post; $i++ ) {
			$type = $post_types_array['archive_post'][$i][0];
			$label = $post_types_array['archive_post'][$i][1];
			if ( isset( $WPV_settings['views_template_archive_for_' . $type] ) && $WPV_settings['views_template_archive_for_' . $type] == $ct_id ) {
                $list .= '<li>' . $label . __(' (post type archive)','wpv-views') . '</li>';
			 }
		}

		for ( $i=0; $i < $count_taxonomy_post; $i++ ) {
			$type = $post_types_array['taxonomy_post'][$i][0];
			$label = $post_types_array['taxonomy_post'][$i][1];
			if ( isset( $WPV_settings['views_template_loop_' . $type] ) && $WPV_settings['views_template_loop_' . $type] == $ct_id ) {
                $list .= '<li>' . $label . __(' (taxonomy archive)','wpv-views') . '</li>';
			 }
		}
		
		if ( ! empty( $list ) ) {
			$list = '<ul class="wpv-taglike-list">' . $list . '</ul>';
		} else {
		   $list = '<span>' . __( 'No Post types/Taxonomies assigned', 'wpv-views' ) . '</span>';
		}
	} else {
        // This CT is owned by a View/WPA and used as a loop template

        $owner_view = WPV_View_Base::get_instance( $ct->loop_output_id );
        if( null == $owner_view ) {
            // again, there was no check for missing View before!
            return '';
        }

        // Show usage information depending on owner View post status.
		if ( $owner_view->is_published ) {
			$edit_page = 'views-editor';
			if ( WPV_View_Base::is_archive_view( $owner_view->id ) ) {
				$edit_page = 'view-archives-editor';
			}
			$list = sprintf(
                __( 'This Content Template is used as the loop block for the %s <a href="%s" target="_blank">%s</a>', 'wpv-views' ),
                $owner_view->query_mode_display_name,
                add_query_arg(
                    array(
                        'page' => $edit_page,
                        'view_id' => $owner_view->id
                    ),
                    admin_url( 'admin.php' )
                ),
                $owner_view->title
            );

		} else {

			$list = sprintf(
                __( 'This Content Template is used as the loop block for the trashed %s <strong>%s</strong>', 'wpv-views' ),
                $owner_view->query_mode_display_name,
                $owner_view->title
            );

		}
	}
	return "<span>$list</span>";
}
 /**
  * Get default postmeta for a View.
  *
  * Combine self::$postmeta_defaults with defaults common for Views and WPAs.
  *
  * @return array
  */
 protected function get_postmeta_defaults() {
     $parent_postmeta = parent::get_postmeta_defaults();
     $this_postmeta = WPV_View_Embedded::$postmeta_defaults;
     return wpv_array_merge_recursive_distinct( $parent_postmeta, $this_postmeta );
 }
function wpv_generate_view_loop_output_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"], 'layout_wizard_nonce' ) 
	) {
		$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 );
	}
	if (
		! isset( $_POST["view_id"] )
		|| ! is_numeric( $_POST["view_id"] )
		|| intval( $_POST['view_id'] ) < 1 
	) {
		$data = array(
			'type' => 'id',
			'message' => __( 'Wrong or missing ID.', 'wpv-views' )
		);
		wp_send_json_error( $data );
	}

	$view_id = $_POST['view_id'];
	$style = sanitize_text_field( $_POST['style'] );
	
	// @todo better validation
	$fields = json_decode( stripslashes( $_POST['fields'] ), true );
	$args = json_decode( stripslashes( $_POST['args'] ), true );

    // Translate field data from non-associative arrays into something that WPV_View_Base::generate_loop_output() understands.
    $fields_normalized = array();
    foreach( $fields as $field ) {
	    $fields_normalized[] = array(
				'prefix' => $field[0],
				'shortcode' => $field[1],
				'suffix' => $field[2],
				'field_name' => $field[3],
				'header_name' => $field[4],
				'row_title' => $field[5] );
	}
	
	$loop_output = WPV_View_Base::generate_loop_output( $style, $fields_normalized, $args );

	// Forward the fail when loop output couldn't have been generated. 
	if ( null == $loop_output ) {
		$data = array(
			'type' => 'error',
			'message' => __( 'Could not generate the Loop Output. Please reload and try again.', 'wpv-views' )
		);
		wp_send_json_error( $data );
	}
		
	// Merge new settings to existing ones (overwrite keys from $layout_settings but keep the rest).
	$loop_output_settings = $loop_output['loop_output_settings'];
	$prev_settings = get_post_meta( $view_id, '_wpv_layout_settings', true );
	if( ! is_array( $prev_settings ) ) {
		// Handle missing _wpv_layout_settings for given View.
		$prev_settings = array();
	}
	$loop_output_settings = array_merge( $prev_settings, $loop_output_settings );
	
	if ( 
		isset( $loop_output_settings['fields'] )
		&& is_array( $loop_output_settings['fields'] )
	) {
		$loop_output_settings['fields'] = array_values( $loop_output_settings['fields'] );
	}

	// Return the results.
	$data = array(
		'loop_output_settings' => $loop_output_settings,
		'ct_content' => $loop_output['ct_content'] 
	);
	wp_send_json_success( $data );
}
    /**
     * Generate Bootstrap grid View layout.
     *
     * @see generate_view_loop_output()
     *
     * @param array $fields Array of fields to be used inside this layout.
     * @param array $args Additional arguments (expected: bootstrap_column_count, bootstrap_version, add_container,
     *     add_row_class, render_individual_columns).
     *
     * @return null|array Null on error (missing bootstrap version), otherwise the array:
     *     array (
     *         @type string $loop_template Loop Output code.
     *         @type string $ct_content Content of the Content Template or an empty string if it's not being used.
     *     )
     *
     * @since 1.10
     */
    private static function generate_bootstrap_grid_layout( $fields, $args ) {

        $column_count = $args['bootstrap_column_count'];

        // Fail if we don't have valid bootstrap version
        $bootstrap_version = wpv_getarr( $args, 'bootstrap_version', 'undefined', array( 2, 3 ) );
        if( 'undefined' == $bootstrap_version ) {
            return null;
        }

        $indent = $args['use_loop_template'] ? "" : "\t\t\t\t";
        $field_codes = WPV_View_Base::generate_field_codes( $fields, $indent );

        // Prevent division by zero
        if( $column_count < 1 ) {
            return null;
        }

        $column_offset = 12 / $column_count;

        $output = '';

        // Row style and cols class for bootstrap 2
        $row_style = ( $bootstrap_version == 2 ) ? ' row-fluid' : '';
        $col_style = ( $bootstrap_version == 2 ) ? 'span' : 'col-sm-';
        $col_class = $col_style . $column_offset;

        // Add row class (optional for bootstrap 2)
        $row_class = ( $args['add_row_class'] || ( 3 == $bootstrap_version ) ) ? 'row' : '';

        if( $args['use_loop_template'] ) {
            $ct_content = $field_codes;
            $loop_item = "<div class=\"$col_class\">[wpv-post-body view_template=\"{$args['loop_template_title']}\"]</div>";
        } else {
            $ct_content = '';
            $loop_item = "<div class=\"$col_class\">\n$field_codes\n\t\t\t</div>";
        }

        if( $args['add_container'] ) {
            $output .= "\t<div class=\"container\">\n";
        }

        $output .= "\t<wpv-loop wrap=\"{$column_count}\" pad=\"true\">\n";

        // If the first column is also a last column, close the div tag.
        $ifone = ( 1 == $column_count ) ? "\n\t\t</div>" : '';

        if( $args['render_individual_columns'] ) {
            // Render items for each column.
            $output .=
                "\t\t[wpv-item index=1]\n"
                . "\t\t<div class=\"{$row_class} {$row_style}\">\n"
                . "\t\t\t$loop_item$ifone\n";
            for( $i = 2; $i < $column_count; ++$i ) {
                $output .=
                    "\t\t[wpv-item index=$i]\n" .
                    "\t\t\t$loop_item\n";
            }
        } else {
            // Render compact HTML
            $output .=
                "\t\t[wpv-item index=1]\n"
                . "\t\t<div class=\"{$row_class} {$row_style}\">\n"
                . "\t\t\t$loop_item$ifone\n"
                . "\t\t[wpv-item index=other]\n"
                . "\t\t\t$loop_item\n";
        }

        // Render item for last column.
        if ( $column_count > 1) {
            $output .=
                "\t\t[wpv-item index=$column_count]\n"
                . "\t\t\t$loop_item\n"
                . "\t\t</div>\n";
        }

        // Padding items
        $output .=
            "\t\t[wpv-item index=pad]\n"
            . "\t\t\t<div class=\"{$col_class}\"></div>\n"
            . "\t\t[wpv-item index=pad-last]\n"
            . "\t\t\t<div class=\"{$col_class}\"></div>\n"
            . "\t\t</div>\n"
            . "\t</wpv-loop>\n\t";

        if ( $args['add_container'] ) {
            $output .= "</div>\n\t";
        }

        return array(
            'loop_template' => $output,
            'ct_content' => $ct_content );
    }
 /**
  * Get the post object representing this Content Template.
  *
  * @return WP_Post Post object.
  *
  * @throws InvalidArgumentException if the post object cannot be retrieved or is invalid.
  */
 protected function &post()
 {
     if (null == $this->post) {
         // Requesting WP_Post object, but we haven't got it yet.
         $post = WP_Post::get_instance($this->object_id);
         if (WPV_View_Base::is_wppost_ct($post)) {
             $this->post = $post;
         } else {
             throw new InvalidArgumentException('Invalid Content Template ID');
         }
     }
     return $this->post;
 }
Example #10
0
/**
 * Set default WordPress Archives settings and layout settings
 *
 * @param string $settings field: view_settings or view_layout_settings
 * @return array with desired values
 * @since unknown
 */
function wpv_wordpress_archives_defaults( $settings = 'view_settings' ) {

    $empty_loop_output = WPV_View_Base::generate_loop_output();

	$defaults = array(
		'view_settings' => array(
			'view-query-mode' => 'archive',
			'sections-show-hide' => array(
                'content' => 'off',
            )
		),
		'view_layout_settings' => array(
		    // almost all of this settings are only needed to create the layout on the fly, so they are not needed here
			'additional_js' => '',
			'layout_meta_html' => $empty_loop_output['loop_output_settings']['layout_meta_html'],
		),
	);
	return $defaults[ $settings ];
}
function wpv_update_layout_extra_callback() {

    // Authentication
	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"], 'wpv_view_layout_extra_nonce' ) 
	) {
		$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 );
	}

    $view_id = (int) wpv_getpost( 'id', 0 );

    // This will give us a View, a WPA or null.
    $view = WPV_View_Base::get_instance( $view_id );

    if ( $view_id < 1 || ( null == $view ) ) {
		$data = array(
			'type' => 'id',
			'message' => __( 'Wrong or missing ID.', 'wpv-views' )
		);
		wp_send_json_error( $data );
	}

    try {

        // We're updating multiple properties at once.
        $view->defer_after_update_actions();

        // Actually we're changing only View settings and loop settings here.
        // If any of those changes fails, the database will not be updated.
        $view->begin_modifying_view_settings();
        $view->begin_modifying_loop_settings();

        $view->css = wpv_getpost( 'layout_css_val' );
        $view->js = wpv_getpost( 'layout_js_val' );

        $view->loop_meta_html = wpv_getpost( 'layout_val' );

        // Save the wizard settings
        if ( isset( $_POST['include_wizard_data'] ) ) {

            $view->loop_style = wpv_getpost( 'style' );
            $view->loop_table_column_count = wpv_getpost( 'table_cols' );
            $view->loop_bs_column_count = wpv_getpost( 'bootstrap_grid_cols' );
            $view->loop_bs_grid_container = wpv_getpost( 'bootstrap_grid_container' );
            $view->loop_row_class = wpv_getpost( 'bootstrap_grid_row_class' );
            $view->loop_bs_individual = wpv_getpost( 'bootstrap_grid_individual' );
            $view->loop_include_field_names = wpv_getpost( 'include_field_names' );
            $view->loop_fields = wpv_getpost( 'fields' ); // @todo sanitize this
            $view->loop_real_fields = wpv_getpost( 'real_fields' ); // @todo sanitize this

            // Remove unused Content Template
            $ct_to_delete = (int) wpv_getpost( 'delete_view_loop_template', 0 );
            if( $ct_to_delete > 0 ) {
                $view->delete_unused_loop_template( $ct_to_delete );
            }

        }

        // Now store changes.
        $view->finish_modifying_view_settings();
        $view->finish_modifying_loop_settings();
        $view->resume_after_update_actions();


    } catch ( WPV_RuntimeExceptionWithMessage $e ) {

        // Validation errors go here.
        wp_send_json_error( array( 'type' => 'update', 'message' => $e->getUserMessage() ) );

    } catch ( Exception $e ) {

        wp_send_json_error( array( 'type' => 'update', 'message' => __( 'An unexpected error ocurred.', 'wpv-views' ) ) );
    }

    // Success!
    $data = array(
        'id' => $view_id,
        'message' => __( 'Loop Output saved', 'wpv-views' )
    );
	wp_send_json_success( $data );
}
Example #12
0
function wpv_ct_editor_usage_section( $ct ) {
	ob_start();

    $parent_view = null;
    if( $ct->is_owned_by_view ) {
        $parent_view = WPV_View_Base::get_instance($ct->loop_output_id);
    }

    if( null != $parent_view ) {

        if( $parent_view->is_published ) {
			$edit_page = 'views-editor';
			if ( WPV_View_Base::is_archive_view( $parent_view->id ) ) {
				$edit_page = 'view-archives-editor';
			}
            $loop_template_notice = sprintf(
                __( 'This Content Template is used as the loop block for the %s <a href="%s" target="_blank">%s</a>.', 'wpv-views' ),
                $parent_view->query_mode_display_name,
                esc_attr( add_query_arg(
                    array(
                        'page' => $edit_page,
                        'view_id' => $parent_view->id
                    ),
                    admin_url( 'admin.php' )
                ) ),
                $parent_view->title
            );

        } else {

            $loop_template_notice = sprintf(
                __( 'This Content Template is used as the loop block for the trashed %s %s.', 'wpv-views' ),
                $parent_view->query_mode_display_name,
                "<strong>{$parent_view->title}</strong>"
            );
        }

        printf( '<div class="wpv-advanced-setting"><p>%s</p></div>', $loop_template_notice );

    } else {

        $asterisk_explanation =
            '<span data-bind="fadeVisibility: isAsteriskExplanationVisible(\'%s\', \'%s\')"><span style="color:red">*</span> '
            . __('A different Content Template is already assigned to this item.', 'wpv-views')
            . '</span>';


        // Render checkboxes for each type of assignment.
        $single_post_types_with_other_ct = wpv_ct_editor_usage_section_single_pages($ct, $asterisk_explanation);
        $cpt_archives_with_other_ct = wpv_ct_editor_usage_section_post_archives($ct, $asterisk_explanation);
        $taxonomy_archives_with_other_ct = wpv_ct_editor_usage_section_taxonomy_archives($ct, $asterisk_explanation);

        // Print information about other CT assignments for JS
        $other_assignments = array(
            'single_posts' => $single_post_types_with_other_ct,
            'cpt_archives' => $cpt_archives_with_other_ct,
            'taxonomy_archives' => $taxonomy_archives_with_other_ct
        );


        printf(
            '<span style="visibility: hidden" class="js-wpv-usage-other-assignments" data-value="%s"></span>',
            htmlentities(json_encode($other_assignments))
        );
        ?>

        <p class="update-button-wrap">
            <span class="update-action-wrap">
                <span class="js-wpv-message-container"></span>
                <span class="spinner ajax-loader" data-bind="spinnerActive: isUsageSectionUpdating"></span>
            </span>
            <button data-bind="
                        enable: isUsageSectionUpdateNeeded,
                        attr: { class: isUsageSectionUpdateNeeded() ? 'button-primary' : 'button-secondary' },
                        click: usageSectionUpdate">
                <?php _e('Update', 'wpv-views'); ?>
            </button>
        </p>

    <?php
    }

	$content = ob_get_contents();
	ob_end_clean();

	wpv_ct_editor_render_section(
        __( 'Usage', 'wpv-views' ),
        'js-wpv-usage-section',
        $content,
        false,
        '',
        '',
        array( 'section' => 'usage_section', 'pointer_slug' => 'ptr_section' ) );
}