Skip to content
This repository has been archived by the owner on Dec 16, 2022. It is now read-only.

Add initial support for previewing meta queries #174

Merged
merged 25 commits into from
Jul 5, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
b0989f4
Add failing tests for meta queries with previewed meta values
westonruter Jun 10, 2016
a017f22
Add initial support for previewing meta queries
westonruter Jun 10, 2016
f7e53ff
Merge pull request #179 from xwp/release/0.6.1
valendesigns Jun 16, 2016
986c7f4
Ensure that plugin-support and theme-support are included in build
westonruter Jun 18, 2016
d41a4f6
Remove unrecognized Text Domain readme meta
westonruter Jun 18, 2016
e0589bc
Merge pull request #184 from xwp/bugfix/release-0.6.1
westonruter Jun 18, 2016
1ba5017
Fix location of readme change
westonruter Jun 18, 2016
bfdb6c7
Merge pull request #185 from xwp/bugfix/readme-0.6.1
westonruter Jun 18, 2016
78ba03a
Merge branch 'feature/meta-queries' of https://github.com/xwp/wp-cust…
PatelUtkarsh Jun 27, 2016
d63bb4e
Improve meta query preview support
PatelUtkarsh Jun 28, 2016
4bec8d6
Add test case for Meta query support
PatelUtkarsh Jun 29, 2016
134ef60
Add filter for customize previewed posts
PatelUtkarsh Jun 29, 2016
2ed7f3b
Merge branch 'develop' of https://github.com/xwp/wp-customize-posts i…
westonruter Jun 30, 2016
95688a7
Merge branch 'develop' of https://github.com/xwp/wp-customize-posts i…
westonruter Jun 30, 2016
5412264
Merge branch 'master' of https://github.com/xwp/wp-customize-posts in…
westonruter Jun 30, 2016
c6b898c
Merge branch 'feature/meta-queries' of https://github.com/xwp/wp-cust…
westonruter Jun 30, 2016
f5a7369
Change filter name to customize_previewed_posts_for_query
PatelUtkarsh Jun 30, 2016
74ddaa9
Merge pull request #191 from xwp/feature/meta-queries-update
westonruter Jun 30, 2016
8c05b22
Customize preview: allow meta values to be array for filtering
PatelUtkarsh Jul 1, 2016
b88150e
Merge pull request #193 from xwp/feature/meta-queries-update
westonruter Jul 1, 2016
4f6ff41
Add test case for customize preview meta value as array :white_check_…
PatelUtkarsh Jul 1, 2016
8cfb62a
Restore intval to fix in_array() matching for post__in
westonruter Jul 2, 2016
42e7f76
Add missing typecast to customize preview query filter,
PatelUtkarsh Jul 2, 2016
ca73eb2
Merge branch 'develop' of https://github.com/xwp/wp-customize-posts i…
westonruter Jul 4, 2016
06560ab
Merge branch 'develop' into feature/meta-queries
westonruter Jul 5, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ module.exports = function( grunt ) {
'*.php',
'css/*',
'js/*',
'php/*',
'php/**',
'readme.txt'
],
dest: 'build',
Expand Down
132 changes: 115 additions & 17 deletions php/class-wp-customize-posts-preview.php
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,8 @@ public function filter_the_posts_to_preview_settings( array $posts ) {
/**
* Get current posts being previewed which should be included in the given query.
*
* @todo The $published flag is likely a vestigate of when this was specifically for post_status. Refactoring needed.
*
* @access public
*
* @param \WP_Query $query The query.
Expand All @@ -257,45 +259,140 @@ public function get_previewed_posts_for_query( WP_Query $query, $published = tru

$post_ids = array();
$settings = $this->component->manager->unsanitized_post_values();
if ( ! empty( $settings ) ) {
foreach ( (array) $settings as $id => $post_data ) {
if ( ! preg_match( WP_Customize_Post_Setting::SETTING_ID_PATTERN, $id, $matches ) ) {
continue;
}
$post_id = intval( $matches['post_id'] );
$statuses = $query_vars['post_status'];

foreach ( $settings as $id => $setting_value ) {
$is_match = (
preg_match( WP_Customize_Postmeta_Setting::SETTING_ID_PATTERN, $id, $matches )
||
preg_match( WP_Customize_Post_Setting::SETTING_ID_PATTERN, $id, $matches )
);
if ( ! $is_match ) {
continue;
}
$statuses = $query_vars['post_status'];
$setting_post_id = intval( $matches['post_id'] );
$setting_post_type = $matches['post_type'];
$setting_post_meta_key = isset( $matches['meta_key'] ) ? $matches['meta_key'] : null;
$setting_type = $setting_post_meta_key ? 'postmeta' : 'post';

if ( 'post' === $setting_type ) {
// Post type match.
$post_type_match = (
empty( $query_vars['post_type'] )
||
in_array( $matches['post_type'], $query_vars['post_type'], true )
in_array( $setting_post_type, $query_vars['post_type'], true )
||
(
in_array( 'any', $query_vars['post_type'], true )
&&
in_array( $matches['post_type'], get_post_types( array( 'exclude_from_search' => false ) ), true )
in_array( $setting_post_type, get_post_types( array( 'exclude_from_search' => false ) ), true )
)
);

$post_type_obj = get_post_type_object( $matches['post_type'] );
if ( $post_type_obj && current_user_can( $post_type_obj->cap->read_private_posts, $post_id ) ) {
// Post status match.
$post_type_obj = get_post_type_object( $setting_post_type );
if ( $post_type_obj && current_user_can( $post_type_obj->cap->read_private_posts, $setting_post_id ) ) {
$statuses[] = 'private';
}

if ( empty( $query_vars['post_status'] ) ) {
$post_status_match = true;
} elseif ( false === $published ) {
$post_status_match = ! in_array( $post_data['post_status'], array( 'publish', 'private' ), true );
$post_status_match = ! in_array( $setting_value['post_status'], array( 'publish', 'private' ), true );
} else {
$post_status_match = in_array( $post_data['post_status'], $statuses, true );
$post_status_match = in_array( $setting_value['post_status'], $statuses, true );
}

$post__in_match = empty( $query_vars['post__in'] ) || in_array( $post_id, $query_vars['post__in'], true );
// Post IN match.
$post__in_match = empty( $query_vars['post__in'] ) || in_array( $setting_post_id, $query_vars['post__in'], true );
if ( $post_status_match && $post_type_match && $post__in_match ) {
$post_ids[] = $post_id;
$post_ids[] = $setting_post_id;
}
} elseif ( ! empty( $query->meta_query ) && ! empty( $query->meta_query->queries ) ) { // @todo The $published flag is probably an indication of something awry.
$meta_queries = $query->meta_query->queries;
$relation = $meta_queries['relation'];
unset( $meta_queries['relation'] );
$matched_queries = array();

foreach ( $meta_queries as $meta_query ) {
if ( empty( $meta_query['key'] ) || $meta_query['key'] !== $setting_post_meta_key ) {
continue;
}

if ( ! isset( $meta_query['value'] ) || '' === $meta_query['value'] ) {
$matched_queries[] = true;
continue;
}

if ( is_array( $meta_query['value'] ) && ! empty( $meta_query['compare'] ) && 'IN' !== $meta_query['compare'] ) {
continue;
}

if ( empty( $meta_query['compare'] ) ) {
if ( is_array( $meta_query['value'] ) ) {
$meta_query['compare'] = 'IN';
} else {
$meta_query['compare'] = '=';
}
}
$is_setting_value_array = is_array( $setting_value );
if ( '=' === $meta_query['compare'] ) {
$values = $is_setting_value_array ? $setting_value : array( $setting_value );
$compared_flag = in_array( (string) $meta_query['value'], array_map( 'strval', $values ), true );
} elseif ( '>=' === $meta_query['compare'] && ! $is_setting_value_array ) {
$compared_flag = ( (string) $setting_value >= (string) $meta_query['value'] );
} elseif ( '<=' === $meta_query['compare'] && ! $is_setting_value_array ) {
$compared_flag = ( (string) $setting_value <= (string) $meta_query['value'] );
} elseif ( '>' === $meta_query['compare'] && ! $is_setting_value_array ) {
$compared_flag = ( (string) (string) $setting_value > $meta_query['value'] );
} elseif ( '<' === $meta_query['compare'] && ! $is_setting_value_array ) {
$compared_flag = ( (string) $setting_value < (string) $meta_query['value'] );
} elseif ( 'IN' === $meta_query['compare'] && is_array( $meta_query['value'] ) ) {
$values = $is_setting_value_array ? $setting_value : array( $setting_value );
$common_values = array_intersect( array_map( 'strval', $values ), array_map( 'strval', $meta_query['value'] ) );
$compared_flag = empty( $common_values ) ? false : true;
}

if ( isset( $compared_flag ) ) {
// Check should we include this in IN query or NOT IN query.
if ( true === $published ) {
$matched_queries[] = $compared_flag;
} else {
$matched_queries[] = ! $compared_flag;
}
} else {
$matched_queries[] = false;
}
}

if ( 'AND' === $relation ) {
if ( in_array( false, $matched_queries, true ) ) {
$matched_queries = array();
}
} else {
$matched_queries = array_filter( $matched_queries );
}

if ( ! empty( $matched_queries ) ) {
$post_ids[] = $setting_post_id;
}
}
}
/**
* Filter customize preview posts.
*
* @param array $post_ids Post ids being filtered.
* @param array array {
* Args.
*
* @type \WP_Query $query WP_Query obj.
* @type array $settings Field Values in snapshot.
* @type bool $publish IN query or NOT IN query.
* }
*/
$post_ids = apply_filters( 'customize_previewed_posts_for_query', $post_ids, array(
'query' => $query,
'settings' => $settings,
'publish' => $published,
) );

return $post_ids;
}
Expand All @@ -313,6 +410,7 @@ public function get_previewed_posts_for_query( WP_Query $query, $published = tru
public function filter_posts_where_to_include_previewed_posts( $where, $query ) {
global $wpdb;

// @todo There are undoubtedly hundreds of possible conditions that are not being accounted for in regards to all of the possible query vars a WP_Query can take.
if ( ! $query->is_singular() ) {
$post__not_in = implode( ',', array_map( 'absint', $this->get_previewed_posts_for_query( $query, false ) ) );
if ( ! empty( $post__not_in ) ) {
Expand Down
2 changes: 1 addition & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ Edit posts and postmeta in the Customizer. Stop editing your posts/postmeta blin
**Tested up to:** 4.6-alpha
**Stable tag:** 0.6.1
**License:** [GPLv2 or later](http://www.gnu.org/licenses/gpl-2.0.html)
**Text Domain:** customize-posts

[![Build Status](https://travis-ci.org/xwp/wp-customize-posts.svg?branch=master)](https://travis-ci.org/xwp/wp-customize-posts) [![Coverage Status](https://coveralls.io/repos/xwp/wp-customize-posts/badge.svg?branch=master)](https://coveralls.io/github/xwp/wp-customize-posts) [![Built with Grunt](https://cdn.gruntjs.com/builtwith.svg)](http://gruntjs.com) [![devDependency Status](https://david-dm.org/xwp/wp-customize-posts/dev-status.svg)](https://david-dm.org/xwp/wp-customize-posts#info=devDependencies)

Expand Down Expand Up @@ -75,6 +74,7 @@ The following are listed in reverse chronological order. The first, more recent
* Add support for focusing on controls for setting properties when those properties are invalid
* Prevent `customized-posts` messages sent via `selective-refresh` from effecting `post-navigation` state
* Improve feature detection for including customize-controls patched for trac-36521
* Included plugin-support and theme-support PHP files that were inadvertantly omitted from the 0.6.0 build.

See full commit log: [`0.6.0...0.6.1`](https://github.com/xwp/wp-customize-posts/compare/0.6.0...0.6.1)

Expand Down
2 changes: 1 addition & 1 deletion readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ Tested up to: 4.6-alpha
Stable tag: 0.6.1
License: GPLv2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: customize-posts

Edit posts and postmeta in the Customizer. Stop editing your posts/postmeta blind!

Expand Down Expand Up @@ -73,6 +72,7 @@ The following are listed in reverse chronological order. The first, more recent
* Add support for focusing on controls for setting properties when those properties are invalid
* Prevent `customized-posts` messages sent via `selective-refresh` from effecting `post-navigation` state
* Improve feature detection for including customize-controls patched for trac-36521
* Included plugin-support and theme-support PHP files that were inadvertantly omitted from the 0.6.0 build.

See full commit log: [`0.6.0...0.6.1`](https://github.com/xwp/wp-customize-posts/compare/0.6.0...0.6.1)

Expand Down
134 changes: 133 additions & 1 deletion tests/php/test-class-wp-customize-posts-preview.php
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ public function filter_the_posts_to_add_dynamic_post_settings_and_sections() {
}

/**
* Test get_previewed_drafts method.
* Test get_previewed_posts_for_query method.
*
* @see WP_Customize_Posts_Preview::get_previewed_posts_for_query()
*/
Expand Down Expand Up @@ -318,6 +318,138 @@ public function test_get_previewed_posts_for_query() {
$this->assertEquals( array( $post->ID, $page->ID ), $this->posts_component->preview->get_previewed_posts_for_query( $query ) );
}

/**
* Test querying posts based on meta queries.
*
* @see WP_Customize_Posts_Preview::get_previewed_posts_for_query()
* @see WP_Customize_Posts_Preview::filter_posts_where_to_include_previewed_posts()
*/
public function test_get_previewed_post_for_meta_query() {
$meta_key = 'index';
$post_type = 'post';
$this->posts_component->register_post_type_meta( $post_type, $meta_key );

$post_data = array();
foreach ( array( 'foo', 'bar', 'baz', 'qux', 'multi' ) as $i => $name ) {
$post_id = $this->factory()->post->create( array( 'post_title' => $name ) );
$post = get_post( $post_id );
$postmeta_setting_id = WP_Customize_Postmeta_Setting::get_post_meta_setting_id( $post, $meta_key );
if ( 'qux' === $name ) {
$i = 2;
}
if ( 'multi' === $name ) {
$this->wp_customize->set_post_value( $postmeta_setting_id, array( '10', '11', '12' ) );
} else {
$this->wp_customize->set_post_value( $postmeta_setting_id, (string) $i );
}
list( $postmeta_setting ) = $this->wp_customize->add_dynamic_settings( array( $postmeta_setting_id ) );
$this->assertEquals( $postmeta_setting_id, $postmeta_setting->id );
if ( 'multi' === $name ) {
$post_data[ $name ] = array(
'post' => $post,
'postmeta_setting' => $postmeta_setting,
'index' => array( '10', '11', '12' ),
);
} else {
$post_data[ $name ] = array(
'post' => $post,
'postmeta_setting' => $postmeta_setting,
'index' => (string) $i,
);
}
if ( 'qux' === $name ) {
add_post_meta( $post_id, $meta_key, '0', true );
}
$postmeta_setting->preview();
if ( 'multi' === $name ) {
$d = get_post_meta( $post_id, $meta_key );
$this->assertEquals( $post_data[ $name ][ $meta_key ], array_shift( $d ) );
} else {
$this->assertEquals( $post_data[ $name ][ $meta_key ], get_post_meta( $post_id, $meta_key, true ) );
}
}

$query_post_with_index_meta = new WP_Query( array(
'post_type' => $post_type,
'meta_key' => $meta_key,
) );
$this->assertCount( count( $post_data ), $query_post_with_index_meta->posts );

$query_post_with_index_1 = new WP_Query( array(
'post_type' => $post_type,
'meta_key' => $meta_key,
'meta_value' => '1',
) );
$this->assertCount( 1, $query_post_with_index_1->posts );

$query_post_with_index_gte_1 = new WP_Query( array(
'post_type' => $post_type,
'meta_key' => $meta_key,
'meta_value' => '1',
'meta_compare' => '>='
) );
$this->assertCount( 4, $query_post_with_index_gte_1->posts );

$query_post_with_compound_meta_query = new WP_Query( array(
'post_type' => $post_type,
'meta_query' => array(
'relation' => 'AND',
array(
'key' => $meta_key,
'value' => '0',
'compare' => '>',
),
array(
'key' => $meta_key,
'value' => '2',
'compare' => '<',
)
),
) );
$this->assertCount( 1, $query_post_with_compound_meta_query->posts );

$query_post_with_in_query = new WP_Query( array(
'post_type' => $post_type,
'meta_query' => array(
'relation' => 'AND',
array(
'key' => $meta_key,
'value' => array( '11', '1', '2' ),
'compare' => 'IN',
),
),
) );

$this->assertCount( 4, $query_post_with_in_query->posts );

$query_post_where_actual_meta_and_snapshot_with_zero = new WP_Query( array(
'post_type' => $post_type,
'meta_query' => array(
'relation' => 'AND',
array(
'key' => $meta_key,
'value' => '0',
),
),
) );

$this->assertCount( 1, $query_post_where_actual_meta_and_snapshot_with_zero->posts );

$query_post_with_meta_value_as_array_compare_equals = new WP_Query( array(
'post_type' => $post_type,
'meta_query' => array(
'relation' => 'AND',
array(
'key' => $meta_key,
'value' => '11',
'compare' => '=',
),
),
) );

$this->assertCount( 1, $query_post_with_meta_value_as_array_compare_equals->posts );
}

/**
* Test filter_nav_menu_item_to_set_url().
*
Expand Down