Last active
March 25, 2017 04:45
-
-
Save westonruter/5e8fc5b2a972392d85af4d7befcbb8da to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Plugin Name: WP Trac #39254: Allow starter content posts to display in The Loop | |
* Version: 0.1.0 | |
* Author: Weston Ruter, XWP | |
* Plugin URI: https://core.trac.wordpress.org/ticket/39254 | |
* | |
* This program is free software; you can redistribute it and/or modify | |
* it under the terms of the GNU General Public License, version 2 or, at | |
* your discretion, any later version, as published by the Free | |
* Software Foundation. | |
* | |
* This program is distributed in the hope that it will be useful, | |
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
* GNU General Public License for more details. | |
* | |
* You should have received a copy of the GNU General Public License | |
* along with this program; if not, write to the Free Software | |
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
* | |
* @package WordPress | |
*/ | |
/** | |
* Class WP_Trac_39254 | |
* | |
* The methods in this class would likely go into `WP_Customize_Nav_Menus`, | |
* perhaps replacing the `make_auto_draft_status_previewable` method. | |
* | |
* @see WP_Customize_Nav_Menus::make_auto_draft_status_previewable() | |
*/ | |
class WP_Trac_39254 { | |
/** | |
* Auto draft post IDs in the current changeset. | |
* | |
* @var array | |
*/ | |
protected $changeset_auto_draft_post_ids = array(); | |
/** | |
* Constructor. | |
*/ | |
function __construct() { | |
add_action( 'customize_preview_init', array( $this, 'make_auto_draft_post_stubs_queryable' ) ); | |
} | |
/** | |
* Add hooks to ensure auto-draft posts from the current changeset are included in WP_Query results. | |
* | |
* @param WP_Customize_Manager $wp_customize Manager. | |
*/ | |
function make_auto_draft_post_stubs_queryable( WP_Customize_Manager $wp_customize ) { | |
global $wp_post_statuses; | |
// WordPress 4.7 required. | |
if ( ! method_exists( $wp_customize, 'changeset_data' ) ) { | |
return; | |
} | |
/* | |
* Note that we cannot use $wp_customize->get_setting( 'nav_menus_created_posts' )->value() | |
* for the sake of unauthenticated users who may be previewing the changeset on the | |
* frontend. The WP_Customize_Nav_Menus::sanitize_nav_menus_created_posts() function | |
* removes IDs from the list for which the current user cannot edit. | |
*/ | |
$changeset_data = $wp_customize->changeset_data(); | |
if ( isset( $changeset_data['nav_menus_created_posts']['value'] ) && is_array( $changeset_data['nav_menus_created_posts']['value'] ) ) { | |
$this->changeset_auto_draft_post_ids = array_merge( | |
$this->changeset_auto_draft_post_ids, | |
$changeset_data['nav_menus_created_posts']['value'] | |
); | |
} | |
/* | |
* Now merge the starter content post IDs from the changeset with any additional | |
* IDs for page/post stubs created for nav menus which may not have been written | |
* into the changeset yet (which are still being sent in POST data). | |
*/ | |
$nav_menus_created_posts_setting = $wp_customize->get_setting( 'nav_menus_created_posts' ); | |
if ( $nav_menus_created_posts_setting ) { | |
$this->changeset_auto_draft_post_ids = array_merge( | |
$this->changeset_auto_draft_post_ids, | |
$nav_menus_created_posts_setting->value() | |
); | |
} | |
// If there are no auto-draft posts in the current changeset, then there is nothing to do here. | |
if ( empty( $this->changeset_auto_draft_post_ids ) ) { | |
return; | |
} | |
/* | |
* Ensure that starter content posts (with auto-draft status) will be considered | |
* to have a public post status in in WP_Query::get_posts(), at: | |
* https://github.com/WordPress/wordpress-develop/blob/4.7.3/src/wp-includes/class-wp-query.php#L2351-L2357 | |
* Compare this with WP_Customize_Nav_Menus::make_auto_draft_status_previewable(), | |
* which apparently did not go far enough. | |
*/ | |
$wp_post_statuses['auto-draft']->public = true; | |
add_action( 'pre_get_posts', array( $this, 'prevent_filter_suppression' ), 100, 2 ); | |
add_filter( 'posts_where', array( $this, 'filter_posts_where_to_include_post_stubs' ) ); | |
} | |
/** | |
* Make sure that the posts_where filter will be applied. | |
* | |
* @param WP_Query $query The WP_Query instance. | |
*/ | |
function prevent_filter_suppression( WP_Query $query ) { | |
$query->set( 'suppress_filters', false ); | |
} | |
/** | |
* Filter SQL WHERE clause for posts queries to exclude auto-draft posts that aren't part of the current changeset. | |
* | |
* @param string $where The WHERE clause of the query. | |
* @return string Amended SQL WHERE. | |
*/ | |
function filter_posts_where_to_include_post_stubs( $where ) { | |
global $wpdb; | |
/* | |
* This could be improved if WP_Query::get_posts() would allow for the | |
* post statuses to be queried to be individually filtered before it is | |
* added to the WHERE string for filtering. Perhaps there could be a | |
* `posts_where_statuses` filter which was passed an array of the | |
* conditions before they are AND'ed together. | |
* See https://github.com/WordPress/wordpress-develop/blob/4.7.3/src/wp-includes/class-wp-query.php#L2289-L2376 | |
*/ | |
$old_condition = "{$wpdb->posts}.post_status = 'publish'"; | |
$new_condition = "( $old_condition OR ( "; | |
$new_condition .= "{$wpdb->posts}.post_status = 'auto-draft' "; | |
$new_condition .= ' AND '; | |
$new_condition .= sprintf( | |
"{$wpdb->posts}.ID IN ( %s )", | |
join( ', ', array_map( 'intval', $this->changeset_auto_draft_post_ids ) ) | |
); | |
$new_condition .= '))'; | |
// @todo This is somewhat brittle. | |
$where = str_replace( $old_condition, $new_condition, $where ); | |
return $where; | |
} | |
} | |
$wp_trac_39254_plugin = new WP_Trac_39254(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment